| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| //#include <stdio.h> |
| |
| #ifdef _MSC_VER |
| #pragma warning(push, 1) /* disable warnings within system headers */ |
| #endif |
| #include <windows.h> |
| #include <msi.h> |
| #include <msiquery.h> |
| #ifdef _MSC_VER |
| #pragma warning(pop) |
| #endif |
| |
| #if defined UNICODE |
| #define _UNICODE |
| #endif |
| #include <tchar.h> |
| |
| //Simple function prototypes |
| bool update_activesync_regvalues(bool, bool, char** ); |
| void createKeys(HKEY hKey, char **); |
| void deleteKeys(HKEY hKey, char **); |
| bool isMulti(MSIHANDLE); |
| |
| //Simple data arrays for registry values |
| TCHAR *pxlData[8]= { |
| "{C6AB3E74-9F4F-4370-8120-A8A6FABB7A7C}", //CLSID 1 - key name at InstalledFilters Key |
| "{43887C67-4D5D-4127-BAAC-87A288494C7C}", //CLSID 2 - key value for Default Export |
| ".pxl", //Registry key for device type - already there if ActiveSync installerd |
| ".sxc", //New registry key for SO docs |
| "InstalledFilters", //Sub-key of device/so doc key |
| "DefaultImport", //Key name added at device/so level key |
| "DefaultExport", //Key name added at device/so level key |
| "Binary Copy", //Key value for DefaultImport |
| }; |
| |
| TCHAR *pswData[8] = { |
| "{BDD611C3-7BAB-460F-8711-5B9AC9EF6020}", //CLSID 1 - key name at InstalledFilters Key |
| "{CB43F086-838D-4FA4-B5F6-3406B9A57439}", //CLSID 2 - key value for Default Export |
| ".psw", //Registry key for device type - already there if ActiveSync installe |
| ".sxw", //New registry key for SO docs |
| "InstalledFilters", //Sub-key of device/so doc key |
| "DefaultImport", //Key name added at device/so level key |
| "DefaultExport", //Key name added at device/so level key |
| "Binary Copy", //Key value for DefaultImport |
| }; |
| |
| |
| //index into registry value arrays |
| #define CLSID1 0 |
| #define CLSID2 1 |
| #define DEVICE_PATH 2 |
| #define SO_PATH 3 |
| #define IF_PATH 4 |
| #define DEFIMPORT_KEY 5 |
| #define DEFEXPORT_KEY 6 |
| #define BC_VALUE 7 |
| |
| //Constants for Registry buffers |
| const int MAX_KEY_LENGTH=255; |
| const int MAX_VALUE_NAME=16383; |
| |
| BOOL APIENTRY DllMain( HANDLE, |
| DWORD ul_reason, |
| LPVOID |
| ) |
| { |
| switch (ul_reason) |
| { |
| case DLL_PROCESS_ATTACH: |
| case DLL_THREAD_ATTACH: |
| case DLL_THREAD_DETACH: |
| case DLL_PROCESS_DETACH: |
| break; |
| } |
| return TRUE; |
| } |
| |
| extern "C" UINT install_jf ( MSIHANDLE hModule ) { |
| bool bMulti = isMulti(hModule); |
| #ifdef _JRGREG_DEBUG |
| MessageBox(NULL, bMulti ? "Multi" : "Single", "Install", MB_OK); |
| #endif |
| update_activesync_regvalues(bMulti, true, pxlData); |
| update_activesync_regvalues(bMulti, true, pswData); |
| |
| return ERROR_SUCCESS; |
| } |
| |
| extern "C" UINT uninstall_jf ( MSIHANDLE hModule ) { |
| bool bMulti = isMulti(hModule); |
| #ifdef _JRGREG_DEBUG |
| MessageBox(NULL, bMulti ? "Multi" : "Single", "Uninstall", MB_OK); |
| #endif |
| update_activesync_regvalues(false, bMulti, pxlData); |
| update_activesync_regvalues(false, bMulti, pswData); |
| |
| return ERROR_SUCCESS; |
| } |
| |
| /** |
| Determines if this is being installed on a per user or a machine wide basis |
| @param hModule |
| [in] a valid msi handle. |
| |
| |
| @returns |
| <TRUE/>if this is a multi-user install. |
| */ |
| bool isMulti( MSIHANDLE hModule ) { |
| TCHAR* szValueBuf = NULL; |
| DWORD cchValueBuf = 0; |
| bool bRet = false; |
| UINT uiStat = MsiGetProperty(hModule, TEXT("ALLUSERS"), TEXT(""), &cchValueBuf); |
| if (ERROR_MORE_DATA == uiStat) |
| { |
| ++cchValueBuf; // on output does not include terminating null, so add 1 |
| szValueBuf = new TCHAR[cchValueBuf]; |
| if (szValueBuf) |
| { |
| uiStat = MsiGetProperty(hModule, TEXT("ALLUSERS"), szValueBuf, &cchValueBuf); |
| } |
| } |
| if (ERROR_SUCCESS != uiStat) |
| { |
| return false; |
| } |
| bRet = _tcscmp(szValueBuf, TEXT("1")) == 0; |
| delete [] szValueBuf; |
| |
| return bRet; |
| } |
| |
| /** |
| Add or remove ActiveSync integration entries from the registry |
| @param bMultiUser |
| [in] <TRUE/>if this is a multiuser install (<FALSE/> for single user install) |
| |
| @param bInstall |
| [in] <TRUE/>if installing |
| |
| @param data |
| [in] an array of string containing names of registry keys and values |
| |
| |
| @returns |
| <TRUE/>if this is a multi-user install. |
| */ |
| |
| bool update_activesync_regvalues(bool bMultiUser, bool bInstall, char **data) { |
| bool bReturn = false; |
| CHAR SUKey[] = "Software\\Microsoft\\Windows CE Services\\Partners"; |
| CHAR MUKey[] = "Software\\Microsoft\\Windows CE Services\\Filters"; |
| HKEY hKey; |
| |
| if (bMultiUser) { |
| if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)MUKey, 0, KEY_ALL_ACCESS, &hKey)) { |
| return false; |
| } |
| if (bInstall) { |
| createKeys(hKey, data); |
| } else { |
| deleteKeys(hKey, data); |
| } |
| bReturn = true; |
| } else { |
| if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, (LPCSTR)SUKey, 0, KEY_ALL_ACCESS, &hKey)) { |
| return false; |
| } |
| |
| CHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name |
| DWORD cbName; // size of name string |
| CHAR achClass[MAX_PATH] = ""; // buffer for class name |
| DWORD cchClassName = MAX_PATH; // size of class string |
| DWORD cSubKeys=0; // number of subkeys |
| DWORD cbMaxSubKey; // longest subkey size |
| DWORD cchMaxClass; // longest class string |
| DWORD cValues; // number of values for key |
| DWORD cchMaxValue; // longest value name |
| DWORD cbMaxValueData; // longest value data |
| DWORD cbSecurityDescriptor; // size of security descriptor |
| FILETIME ftLastWriteTime; // last write time |
| |
| // Get the class name and the value count. |
| if (ERROR_SUCCESS == RegQueryInfoKey( |
| hKey, // key handle |
| achClass, // buffer for class name |
| &cchClassName, // size of class string |
| NULL, // reserved |
| &cSubKeys, // number of subkeys |
| &cbMaxSubKey, // longest subkey size |
| &cchMaxClass, // longest class string |
| &cValues, // number of values for this key |
| &cchMaxValue, // longest value name |
| &cbMaxValueData, // longest value data |
| &cbSecurityDescriptor, // security descriptor |
| &ftLastWriteTime)) { // last write time |
| |
| if (cSubKeys) { |
| for (DWORD i=0; i<cSubKeys; i++) { |
| cbName = 1024; |
| if (ERROR_SUCCESS == RegEnumKeyEx(hKey,i,achKey,&cbName,NULL,NULL,NULL,&ftLastWriteTime)) { |
| HKEY subKey; |
| if (ERROR_SUCCESS == RegOpenKeyEx(hKey, achKey, 0, KEY_ALL_ACCESS, &subKey)) { |
| if (ERROR_SUCCESS == RegOpenKeyEx(subKey, "Filters", 0, KEY_ALL_ACCESS, &subKey)) { |
| if (bInstall) { |
| createKeys(subKey, data); |
| } else { |
| deleteKeys(subKey, data); |
| } |
| RegCloseKey(subKey); |
| } |
| } |
| } |
| } |
| } |
| |
| bReturn = true; |
| } |
| } |
| if (hKey != NULL) { |
| RegCloseKey(hKey); |
| } |
| |
| return bReturn; |
| } |
| |
| /** |
| Create Registry Keys |
| |
| @param hKey |
| [in] Handle to the parent registry key |
| |
| @param data |
| [in] an array of string containing names of registry keys and values |
| */ |
| |
| void createKeys(HKEY hKey, char **data) { |
| |
| LPCSTR clsid1 = data[CLSID1]; |
| LPCSTR clsid2 = data[CLSID2]; |
| LPCSTR devicePath = data[DEVICE_PATH]; |
| LPCSTR soPath = data[SO_PATH]; |
| LPCSTR defImport = data[DEFIMPORT_KEY]; |
| LPCSTR defExport = data[DEFEXPORT_KEY]; |
| LPCSTR binaryCopy = data[BC_VALUE]; |
| LPCSTR IFPath = data[IF_PATH]; |
| |
| HKEY deviceKey, deviceIFKey, soKey, soIFKey; |
| |
| if (ERROR_SUCCESS == RegOpenKeyEx(hKey,devicePath,0,KEY_ALL_ACCESS, &deviceKey)) { |
| if (ERROR_SUCCESS == RegOpenKeyEx(deviceKey,IFPath,0,KEY_ALL_ACCESS, &deviceIFKey)) { |
| RegSetValueEx(deviceIFKey, clsid1, 0, REG_SZ, NULL, NULL); |
| } |
| } |
| |
| if (ERROR_SUCCESS == RegCreateKeyEx(hKey, soPath, 0, NULL, |
| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &soKey, NULL)) { |
| RegSetValueEx(soKey, defExport, 0, REG_SZ, (LPBYTE)binaryCopy, strlen(binaryCopy)); |
| RegSetValueEx(soKey, defImport, 0, REG_SZ, (LPBYTE)clsid2, strlen(clsid2)); |
| |
| |
| if (ERROR_SUCCESS == RegCreateKeyEx(soKey, IFPath, 0, NULL, |
| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &soIFKey, NULL)) { |
| RegSetValueEx(soIFKey, clsid2, 0, REG_SZ, NULL, NULL); |
| } |
| } |
| } |
| |
| /** |
| Delete registry keys |
| |
| @param hKey |
| [in] Handle to the parent registry key |
| */ |
| void deleteKeys(HKEY hKey, TCHAR **data) { |
| LPCSTR clsid1 = data[CLSID1]; |
| LPCSTR clsid2 = data[CLSID2]; |
| LPCSTR devicePath = data[DEVICE_PATH]; |
| LPCSTR soPath = data[SO_PATH]; |
| LPCSTR defImport = data[DEFIMPORT_KEY]; |
| LPCSTR defExport = data[DEFEXPORT_KEY]; |
| LPCSTR IFPath = data[IF_PATH]; |
| |
| HKEY deviceKey, deviceIFKey, soKey, soIFKey; |
| |
| if (ERROR_SUCCESS == RegOpenKeyEx(hKey,devicePath,0,KEY_ALL_ACCESS, &deviceKey)) { |
| if (ERROR_SUCCESS == RegOpenKeyEx(deviceKey,IFPath,0,KEY_ALL_ACCESS, &deviceIFKey)) { |
| RegDeleteValue(deviceIFKey, clsid1); |
| } |
| } |
| |
| if (ERROR_SUCCESS == RegOpenKeyEx(hKey, soPath, 0, KEY_ALL_ACCESS, &soKey)) { |
| RegDeleteValue(soKey, defExport); |
| RegDeleteValue(soKey, defImport); |
| |
| if (ERROR_SUCCESS == RegOpenKeyEx(soKey, IFPath, 0, KEY_ALL_ACCESS, &soIFKey)) { |
| RegDeleteValue(soIFKey, clsid2); |
| RegCloseKey(soIFKey); |
| RegDeleteKey(soKey, IFPath); |
| } |
| RegCloseKey(soKey); |
| RegDeleteKey(hKey, soPath); |
| } |
| } |