1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 //#include <stdio.h>
24 
25 #ifdef _MSC_VER
26 #pragma warning(push, 1) /* disable warnings within system headers */
27 #endif
28 #include <windows.h>
29 #include <msi.h>
30 #include <msiquery.h>
31 #ifdef _MSC_VER
32 #pragma warning(pop)
33 #endif
34 
35 #if defined UNICODE
36 #define _UNICODE
37 #endif
38 #include <tchar.h>
39 
40 //Simple function prototypes
41 bool update_activesync_regvalues(bool, bool, char** );
42 void createKeys(HKEY hKey, char **);
43 void deleteKeys(HKEY hKey, char **);
44 bool isMulti(MSIHANDLE);
45 
46 //Simple data arrays for registry values
47 TCHAR *pxlData[8]= {
48 	"{C6AB3E74-9F4F-4370-8120-A8A6FABB7A7C}", //CLSID 1 - key name at InstalledFilters Key
49 	"{43887C67-4D5D-4127-BAAC-87A288494C7C}", //CLSID 2 - key value for Default Export
50 	".pxl",									  //Registry key for device type - already there if ActiveSync installerd
51 	".sxc",									  //New registry key for SO docs
52 	"InstalledFilters",						  //Sub-key of device/so doc key
53 	"DefaultImport",						  //Key name added at device/so level key
54 	"DefaultExport",						  //Key name added at device/so level key
55 	"Binary Copy",							  //Key value for DefaultImport
56 };
57 
58 TCHAR *pswData[8] = {
59 	"{BDD611C3-7BAB-460F-8711-5B9AC9EF6020}", //CLSID 1 - key name at InstalledFilters Key
60 	"{CB43F086-838D-4FA4-B5F6-3406B9A57439}", //CLSID 2 - key value for Default Export
61 	".psw",									  //Registry key for device type - already there if ActiveSync installe
62 	".sxw",									  //New registry key for SO docs
63 	"InstalledFilters",						  //Sub-key of device/so doc key
64 	"DefaultImport",						  //Key name added at device/so level key
65 	"DefaultExport",						  //Key name added at device/so level key
66 	"Binary Copy",							  //Key value for DefaultImport
67 };
68 
69 
70 //index into registry value arrays
71 #define CLSID1 0
72 #define CLSID2 1
73 #define DEVICE_PATH 2
74 #define SO_PATH 3
75 #define IF_PATH 4
76 #define DEFIMPORT_KEY 5
77 #define DEFEXPORT_KEY 6
78 #define BC_VALUE 7
79 
80 //Constants for Registry buffers
81 const int MAX_KEY_LENGTH=255;
82 const int MAX_VALUE_NAME=16383;
83 
DllMain(HANDLE,DWORD ul_reason,LPVOID)84 BOOL APIENTRY DllMain( HANDLE,
85                        DWORD  ul_reason,
86                        LPVOID
87 					 )
88 {
89     switch (ul_reason)
90 	{
91 		case DLL_PROCESS_ATTACH:
92 		case DLL_THREAD_ATTACH:
93 		case DLL_THREAD_DETACH:
94 		case DLL_PROCESS_DETACH:
95 			break;
96     }
97     return TRUE;
98 }
99 
install_jf(MSIHANDLE hModule)100 extern "C" UINT install_jf ( MSIHANDLE hModule ) {
101 	bool bMulti = isMulti(hModule);
102 #ifdef _JRGREG_DEBUG
103 	MessageBox(NULL, bMulti ? "Multi" : "Single", "Install", MB_OK);
104 #endif
105 	update_activesync_regvalues(bMulti, true, pxlData);
106 	update_activesync_regvalues(bMulti, true, pswData);
107 
108     return ERROR_SUCCESS;
109 }
110 
uninstall_jf(MSIHANDLE hModule)111 extern "C" UINT uninstall_jf ( MSIHANDLE hModule ) {
112 	bool bMulti = isMulti(hModule);
113 #ifdef _JRGREG_DEBUG
114 	MessageBox(NULL, bMulti ? "Multi" : "Single", "Uninstall", MB_OK);
115 #endif
116 	update_activesync_regvalues(false, bMulti, pxlData);
117 	update_activesync_regvalues(false, bMulti, pswData);
118 
119     return ERROR_SUCCESS;
120 }
121 
122 /**
123 	Determines if this is being installed on a per user or a machine wide basis
124     @param hModule
125     [in] a valid msi handle.
126 
127 
128     @returns
129     <TRUE/>if this is a multi-user install.
130 */
isMulti(MSIHANDLE hModule)131 bool isMulti( MSIHANDLE hModule ) {
132     TCHAR* szValueBuf = NULL;
133     DWORD cchValueBuf = 0;
134 	bool bRet = false;
135     UINT uiStat =  MsiGetProperty(hModule, TEXT("ALLUSERS"), TEXT(""), &cchValueBuf);
136     if (ERROR_MORE_DATA == uiStat)
137     {
138         ++cchValueBuf; // on output does not include terminating null, so add 1
139         szValueBuf = new TCHAR[cchValueBuf];
140         if (szValueBuf)
141         {
142             uiStat = MsiGetProperty(hModule, TEXT("ALLUSERS"), szValueBuf, &cchValueBuf);
143         }
144     }
145     if (ERROR_SUCCESS != uiStat)
146     {
147         return false;
148     }
149 	bRet = _tcscmp(szValueBuf, TEXT("1")) == 0;
150     delete [] szValueBuf;
151 
152     return bRet;
153 }
154 
155 /**
156 	Add or remove ActiveSync integration entries from the registry
157     @param bMultiUser
158     [in] <TRUE/>if this is a multiuser install (<FALSE/> for single user install)
159 
160 	@param bInstall
161 	[in] <TRUE/>if installing
162 
163 	@param data
164 	[in] an array of string containing names of registry keys and values
165 
166 
167     @returns
168     <TRUE/>if this is a multi-user install.
169 */
170 
update_activesync_regvalues(bool bMultiUser,bool bInstall,char ** data)171 bool update_activesync_regvalues(bool bMultiUser, bool bInstall, char **data) {
172 	bool bReturn = false;
173 	CHAR SUKey[]    = "Software\\Microsoft\\Windows CE Services\\Partners";
174 	CHAR MUKey[]    = "Software\\Microsoft\\Windows CE Services\\Filters";
175 	HKEY hKey;
176 
177 	if (bMultiUser) {
178 		if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)MUKey, 0, KEY_ALL_ACCESS, &hKey)) {
179 			return false;
180 		}
181 		if (bInstall) {
182 			createKeys(hKey, data);
183 		} else {
184 			deleteKeys(hKey, data);
185 		}
186 		bReturn = true;
187 	} else {
188 		if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, (LPCSTR)SUKey, 0, KEY_ALL_ACCESS, &hKey)) {
189 			return false;
190 		}
191 
192 		CHAR     achKey[MAX_KEY_LENGTH];   // buffer for subkey name
193 		DWORD    cbName;                   // size of name string
194 		CHAR     achClass[MAX_PATH] = "";  // buffer for class name
195 		DWORD    cchClassName = MAX_PATH;  // size of class string
196 		DWORD    cSubKeys=0;               // number of subkeys
197 		DWORD    cbMaxSubKey;              // longest subkey size
198 		DWORD    cchMaxClass;              // longest class string
199 		DWORD    cValues;              // number of values for key
200 		DWORD    cchMaxValue;          // longest value name
201 		DWORD    cbMaxValueData;       // longest value data
202 		DWORD    cbSecurityDescriptor; // size of security descriptor
203 		FILETIME ftLastWriteTime;      // last write time
204 
205 		// Get the class name and the value count.
206 		if (ERROR_SUCCESS == RegQueryInfoKey(
207 			hKey,                    // key handle
208 			achClass,                // buffer for class name
209 			&cchClassName,           // size of class string
210 			NULL,                    // reserved
211 			&cSubKeys,               // number of subkeys
212 			&cbMaxSubKey,            // longest subkey size
213 			&cchMaxClass,            // longest class string
214 			&cValues,                // number of values for this key
215 			&cchMaxValue,            // longest value name
216 			&cbMaxValueData,         // longest value data
217 			&cbSecurityDescriptor,   // security descriptor
218 			&ftLastWriteTime)) {       // last write time
219 
220 			if (cSubKeys) {
221 				for (DWORD i=0; i<cSubKeys; i++) {
222 					cbName = 1024;
223 					if (ERROR_SUCCESS == RegEnumKeyEx(hKey,i,achKey,&cbName,NULL,NULL,NULL,&ftLastWriteTime)) {
224 						HKEY subKey;
225 						if (ERROR_SUCCESS == RegOpenKeyEx(hKey, achKey, 0, KEY_ALL_ACCESS, &subKey)) {
226 							if (ERROR_SUCCESS == RegOpenKeyEx(subKey, "Filters", 0, KEY_ALL_ACCESS, &subKey)) {
227 								if (bInstall) {
228 									createKeys(subKey, data);
229 								} else {
230 									deleteKeys(subKey, data);
231 								}
232 								RegCloseKey(subKey);
233 							}
234 						}
235 					}
236 				}
237 			}
238 
239 			bReturn = true;
240 		}
241 	}
242 	if (hKey != NULL) {
243 		RegCloseKey(hKey);
244 	}
245 
246 	return bReturn;
247 }
248 
249 /**
250 	Create Registry Keys
251 
252     @param hKey
253     [in] Handle to the parent registry key
254 
255 	@param data
256 	[in] an array of string containing names of registry keys and values
257 */
258 
createKeys(HKEY hKey,char ** data)259 void createKeys(HKEY hKey, char **data) {
260 
261 	LPCSTR clsid1     = data[CLSID1];
262 	LPCSTR clsid2     = data[CLSID2];
263 	LPCSTR devicePath = data[DEVICE_PATH];
264 	LPCSTR soPath     = data[SO_PATH];
265 	LPCSTR defImport  = data[DEFIMPORT_KEY];
266 	LPCSTR defExport  = data[DEFEXPORT_KEY];
267 	LPCSTR binaryCopy = data[BC_VALUE];
268 	LPCSTR IFPath     = data[IF_PATH];
269 
270 	HKEY deviceKey, deviceIFKey, soKey, soIFKey;
271 
272 	if (ERROR_SUCCESS == RegOpenKeyEx(hKey,devicePath,0,KEY_ALL_ACCESS, &deviceKey)) {
273 		if (ERROR_SUCCESS == RegOpenKeyEx(deviceKey,IFPath,0,KEY_ALL_ACCESS, &deviceIFKey)) {
274 			RegSetValueEx(deviceIFKey, clsid1, 0, REG_SZ, NULL, NULL);
275 		}
276 	}
277 
278 	if (ERROR_SUCCESS == RegCreateKeyEx(hKey, soPath, 0, NULL,
279 							REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &soKey, NULL)) {
280 		RegSetValueEx(soKey, defExport, 0, REG_SZ, (LPBYTE)binaryCopy, strlen(binaryCopy));
281 		RegSetValueEx(soKey, defImport, 0, REG_SZ, (LPBYTE)clsid2, strlen(clsid2));
282 
283 
284 		if (ERROR_SUCCESS == RegCreateKeyEx(soKey, IFPath, 0, NULL,
285 							REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &soIFKey, NULL)) {
286 			RegSetValueEx(soIFKey, clsid2, 0, REG_SZ, NULL, NULL);
287 		}
288 	}
289 }
290 
291 /**
292 	Delete registry keys
293 
294     @param hKey
295     [in] Handle to the parent registry key
296 */
deleteKeys(HKEY hKey,TCHAR ** data)297 void deleteKeys(HKEY hKey, TCHAR **data) {
298 	LPCSTR clsid1     = data[CLSID1];
299 	LPCSTR clsid2     = data[CLSID2];
300 	LPCSTR devicePath = data[DEVICE_PATH];
301 	LPCSTR soPath     = data[SO_PATH];
302 	LPCSTR defImport  = data[DEFIMPORT_KEY];
303 	LPCSTR defExport  = data[DEFEXPORT_KEY];
304 	LPCSTR IFPath     = data[IF_PATH];
305 
306 	HKEY deviceKey, deviceIFKey, soKey, soIFKey;
307 
308 	if (ERROR_SUCCESS == RegOpenKeyEx(hKey,devicePath,0,KEY_ALL_ACCESS, &deviceKey)) {
309 		if (ERROR_SUCCESS == RegOpenKeyEx(deviceKey,IFPath,0,KEY_ALL_ACCESS, &deviceIFKey)) {
310 			RegDeleteValue(deviceIFKey, clsid1);
311 		}
312 	}
313 
314 	if (ERROR_SUCCESS == RegOpenKeyEx(hKey, soPath, 0, KEY_ALL_ACCESS, &soKey)) {
315 		RegDeleteValue(soKey, defExport);
316 		RegDeleteValue(soKey, defImport);
317 
318 		if (ERROR_SUCCESS == RegOpenKeyEx(soKey, IFPath, 0, KEY_ALL_ACCESS, &soIFKey)) {
319 			RegDeleteValue(soIFKey, clsid2);
320 			RegCloseKey(soIFKey);
321 			RegDeleteKey(soKey, IFPath);
322 		}
323 		RegCloseKey(soKey);
324 		RegDeleteKey(hKey, soPath);
325 	}
326 }
327