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