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 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 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 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 */ 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 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 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 */ 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