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