blob: 5d009bf8932e54e7c4b23be89490af451e27ac67 [file] [log] [blame]
/**************************************************************
*
* 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);
}
}