Move the guid squishing functions out of msi.c and make a new
registry.c file. Also clean up all the various registry keys we need to open and create to this module and modify the functions for msi.c to call these functions.
This commit is contained in:
parent
935549f5d8
commit
a26aa0af4c
|
@ -18,6 +18,7 @@ C_SRCS = \
|
||||||
package.c \
|
package.c \
|
||||||
preview.c \
|
preview.c \
|
||||||
record.c \
|
record.c \
|
||||||
|
registry.c \
|
||||||
regsvr.c \
|
regsvr.c \
|
||||||
select.c \
|
select.c \
|
||||||
string.c \
|
string.c \
|
||||||
|
|
398
dlls/msi/msi.c
398
dlls/msi/msi.c
|
@ -54,18 +54,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||||
DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
|
DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
|
||||||
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
|
||||||
|
|
||||||
static const WCHAR szInstaller[] = {
|
|
||||||
'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'W','i','n','d','o','w','s','\\',
|
|
||||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
||||||
'I','n','s','t','a','l','l','e','r',0 };
|
|
||||||
|
|
||||||
static const WCHAR szFeatures[] = {
|
|
||||||
'F','e','a','t','u','r','e','s',0 };
|
|
||||||
static const WCHAR szComponents[] = {
|
|
||||||
'C','o','m','p','o','n','e','n','t','s',0 };
|
|
||||||
|
|
||||||
/* the UI level */
|
/* the UI level */
|
||||||
INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
|
INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
|
||||||
HWND gUIhwnd = 0;
|
HWND gUIhwnd = 0;
|
||||||
|
@ -82,151 +70,6 @@ WCHAR gszLogFile[MAX_PATH];
|
||||||
* It should contain a number of streams.
|
* It should contain a number of streams.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
|
|
||||||
{
|
|
||||||
DWORD i,n=0;
|
|
||||||
|
|
||||||
out[n++]='{';
|
|
||||||
for(i=0; i<8; i++)
|
|
||||||
out[n++] = in[7-i];
|
|
||||||
out[n++]='-';
|
|
||||||
for(i=0; i<4; i++)
|
|
||||||
out[n++] = in[11-i];
|
|
||||||
out[n++]='-';
|
|
||||||
for(i=0; i<4; i++)
|
|
||||||
out[n++] = in[15-i];
|
|
||||||
out[n++]='-';
|
|
||||||
for(i=0; i<2; i++)
|
|
||||||
{
|
|
||||||
out[n++] = in[17+i*2];
|
|
||||||
out[n++] = in[16+i*2];
|
|
||||||
}
|
|
||||||
out[n++]='-';
|
|
||||||
for( ; i<8; i++)
|
|
||||||
{
|
|
||||||
out[n++] = in[17+i*2];
|
|
||||||
out[n++] = in[16+i*2];
|
|
||||||
}
|
|
||||||
out[n++]='}';
|
|
||||||
out[n]=0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL squash_guid(LPCWSTR in, LPWSTR out)
|
|
||||||
{
|
|
||||||
DWORD i,n=0;
|
|
||||||
|
|
||||||
if(in[n++] != '{')
|
|
||||||
return FALSE;
|
|
||||||
for(i=0; i<8; i++)
|
|
||||||
out[7-i] = in[n++];
|
|
||||||
if(in[n++] != '-')
|
|
||||||
return FALSE;
|
|
||||||
for(i=0; i<4; i++)
|
|
||||||
out[11-i] = in[n++];
|
|
||||||
if(in[n++] != '-')
|
|
||||||
return FALSE;
|
|
||||||
for(i=0; i<4; i++)
|
|
||||||
out[15-i] = in[n++];
|
|
||||||
if(in[n++] != '-')
|
|
||||||
return FALSE;
|
|
||||||
for(i=0; i<2; i++)
|
|
||||||
{
|
|
||||||
out[17+i*2] = in[n++];
|
|
||||||
out[16+i*2] = in[n++];
|
|
||||||
}
|
|
||||||
if(in[n++] != '-')
|
|
||||||
return FALSE;
|
|
||||||
for( ; i<8; i++)
|
|
||||||
{
|
|
||||||
out[17+i*2] = in[n++];
|
|
||||||
out[16+i*2] = in[n++];
|
|
||||||
}
|
|
||||||
out[32]=0;
|
|
||||||
if(in[n++] != '}')
|
|
||||||
return FALSE;
|
|
||||||
if(in[n])
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tables for encoding and decoding base85 */
|
|
||||||
static const unsigned char table_dec85[0x80] = {
|
|
||||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
|
||||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
|
||||||
0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
|
|
||||||
0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
|
|
||||||
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
|
|
||||||
0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
|
|
||||||
0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
|
|
||||||
0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char table_enc85[] =
|
|
||||||
"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
|
|
||||||
"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
|
|
||||||
"yz{}~";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Converts a base85 encoded guid into a GUID pointer
|
|
||||||
* Base85 encoded GUIDs should be 20 characters long.
|
|
||||||
*
|
|
||||||
* returns TRUE if successful, FALSE if not
|
|
||||||
*/
|
|
||||||
BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
|
|
||||||
{
|
|
||||||
DWORD i, val = 0, base = 1, *p;
|
|
||||||
|
|
||||||
p = (DWORD*) guid;
|
|
||||||
for( i=0; i<20; i++ )
|
|
||||||
{
|
|
||||||
if( (i%5) == 0 )
|
|
||||||
{
|
|
||||||
val = 0;
|
|
||||||
base = 1;
|
|
||||||
}
|
|
||||||
val += table_dec85[str[i]] * base;
|
|
||||||
if( str[i] >= 0x80 )
|
|
||||||
return FALSE;
|
|
||||||
if( table_dec85[str[i]] == 0xff )
|
|
||||||
return FALSE;
|
|
||||||
if( (i%5) == 4 )
|
|
||||||
p[i/5] = val;
|
|
||||||
base *= 85;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Encodes a base85 guid given a GUID pointer
|
|
||||||
* Caller should provide a 21 character buffer for the encoded string.
|
|
||||||
*
|
|
||||||
* returns TRUE if successful, FALSE if not
|
|
||||||
*/
|
|
||||||
BOOL encode_base85_guid( GUID *guid, LPWSTR str )
|
|
||||||
{
|
|
||||||
unsigned int x, *p, i;
|
|
||||||
|
|
||||||
p = (unsigned int*) guid;
|
|
||||||
for( i=0; i<4; i++ )
|
|
||||||
{
|
|
||||||
x = p[i];
|
|
||||||
*str++ = table_enc85[x%85];
|
|
||||||
x = x/85;
|
|
||||||
*str++ = table_enc85[x%85];
|
|
||||||
x = x/85;
|
|
||||||
*str++ = table_enc85[x%85];
|
|
||||||
x = x/85;
|
|
||||||
*str++ = table_enc85[x%85];
|
|
||||||
x = x/85;
|
|
||||||
*str++ = table_enc85[x%85];
|
|
||||||
}
|
|
||||||
*str = 0;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
||||||
{
|
{
|
||||||
MSIDATABASE *db = (MSIDATABASE *) arg;
|
MSIDATABASE *db = (MSIDATABASE *) arg;
|
||||||
|
@ -416,27 +259,17 @@ UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
|
||||||
|
|
||||||
UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
|
UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
|
||||||
{
|
{
|
||||||
static const WCHAR szKey[] = {
|
|
||||||
'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'W','i','n','d','o','w','s','\\',
|
|
||||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
||||||
'U','n','i','n','s','t','a','l','l',0 };
|
|
||||||
static const WCHAR szLocalPackage[] = {
|
static const WCHAR szLocalPackage[] = {
|
||||||
'L','o','c','a','l','P','a','c','k','a','g','e', 0
|
'L','o','c','a','l','P','a','c','k','a','g','e', 0
|
||||||
};
|
};
|
||||||
LPWSTR path = NULL;
|
LPWSTR path = NULL;
|
||||||
UINT r;
|
UINT r;
|
||||||
HKEY hKeyProduct = NULL, hKeyUninstall = NULL;
|
HKEY hKeyProduct = NULL;
|
||||||
DWORD count, type;
|
DWORD count, type;
|
||||||
|
|
||||||
TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
|
TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
|
||||||
|
|
||||||
r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
|
r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
return ERROR_UNKNOWN_PRODUCT;
|
|
||||||
|
|
||||||
r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
|
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
{
|
{
|
||||||
r = ERROR_UNKNOWN_PRODUCT;
|
r = ERROR_UNKNOWN_PRODUCT;
|
||||||
|
@ -472,7 +305,6 @@ end:
|
||||||
HeapFree( GetProcessHeap(), 0, path );
|
HeapFree( GetProcessHeap(), 0, path );
|
||||||
if( hKeyProduct )
|
if( hKeyProduct )
|
||||||
RegCloseKey( hKeyProduct );
|
RegCloseKey( hKeyProduct );
|
||||||
RegCloseKey( hKeyUninstall );
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -604,14 +436,7 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||||
MSIHANDLE handle;
|
MSIHANDLE handle;
|
||||||
MSIPACKAGE* package;
|
MSIPACKAGE* package;
|
||||||
UINT rc;
|
UINT rc;
|
||||||
WCHAR squished_pc[0x100];
|
HKEY hkey=0,hkey1=0;
|
||||||
HKEY hkey=0,hkey2=0,hkey3=0,hkey4=0;
|
|
||||||
static const WCHAR szInstaller[] = {
|
|
||||||
'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'I','n','s','t','a','l','l','e','r',0 };
|
|
||||||
static const WCHAR szProducts[] = {
|
|
||||||
'P','r','o','d','u','c','t','s',0 };
|
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
static const WCHAR szSouceList[] = {
|
static const WCHAR szSouceList[] = {
|
||||||
'S','o','u','r','c','e','L','i','s','t',0};
|
'S','o','u','r','c','e','L','i','s','t',0};
|
||||||
|
@ -625,37 +450,27 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||||
FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
|
FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
|
||||||
debugstr_w(szCommandLine));
|
debugstr_w(szCommandLine));
|
||||||
|
|
||||||
if (eInstallState != INSTALLSTATE_LOCAL)
|
if (eInstallState != INSTALLSTATE_LOCAL &&
|
||||||
|
eInstallState != INSTALLSTATE_DEFAULT)
|
||||||
{
|
{
|
||||||
FIXME("Not implemented for anything other than local installs\n");
|
FIXME("Not implemented for anything other than local installs\n");
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
squash_guid(szProduct,squished_pc);
|
rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
|
||||||
|
|
||||||
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(HKEY_CURRENT_USER,szInstaller,&hkey);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* check the products key for the product */
|
rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
|
||||||
rc = RegOpenKeyW(hkey,szProducts,&hkey2);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey2,squished_pc,&hkey3);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey3,szSouceList,&hkey4);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
sz = sizeof(sourcepath);
|
sz = sizeof(sourcepath);
|
||||||
rc = RegQueryValueExW(hkey4, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
|
rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
RegCloseKey(hkey1);
|
||||||
/*
|
/*
|
||||||
* ok 1, we need to find the msi file for this product.
|
* ok 1, we need to find the msi file for this product.
|
||||||
* 2, find the source dir for the files
|
* 2, find the source dir for the files
|
||||||
|
@ -668,8 +483,8 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
|
package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
|
||||||
|
|
||||||
sz = strlenW(szInstalled);
|
sz = strlenW(szInstalled);
|
||||||
|
|
||||||
if (szCommandLine)
|
if (szCommandLine)
|
||||||
sz += strlenW(szCommandLine);
|
sz += strlenW(szCommandLine);
|
||||||
|
@ -681,20 +496,52 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
|
||||||
else
|
else
|
||||||
commandline[0] = 0;
|
commandline[0] = 0;
|
||||||
|
|
||||||
if (MsiQueryProductStateW(szProduct) == iInstallLevel)
|
if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
|
||||||
strcatW(commandline,szInstalled);
|
strcatW(commandline,szInstalled);
|
||||||
|
|
||||||
rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
|
rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(),0,commandline);
|
HeapFree(GetProcessHeap(),0,commandline);
|
||||||
end:
|
end:
|
||||||
RegCloseKey(hkey3);
|
|
||||||
RegCloseKey(hkey2);
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
|
||||||
|
INSTALLSTATE eInstallState, LPCSTR szCommandLine)
|
||||||
|
{
|
||||||
|
LPWSTR szwProduct = NULL;
|
||||||
|
LPWSTR szwCommandLine = NULL;
|
||||||
|
UINT hr = ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
if( szProduct )
|
||||||
|
{
|
||||||
|
UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
|
||||||
|
szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
||||||
|
if( !szwProduct )
|
||||||
|
goto end;
|
||||||
|
MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( szCommandLine)
|
||||||
|
{
|
||||||
|
UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
|
||||||
|
szwCommandLine= HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
||||||
|
if( !szwCommandLine)
|
||||||
|
goto end;
|
||||||
|
MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommandLine, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
|
||||||
|
szwCommandLine );
|
||||||
|
end:
|
||||||
|
HeapFree( GetProcessHeap(), 0, szwProduct );
|
||||||
|
HeapFree( GetProcessHeap(), 0, szwCommandLine);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
|
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
|
||||||
INSTALLSTATE eInstallState)
|
INSTALLSTATE eInstallState)
|
||||||
{
|
{
|
||||||
|
@ -919,59 +766,27 @@ INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
|
||||||
|
|
||||||
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
||||||
{
|
{
|
||||||
WCHAR squished_pc[0x100];
|
|
||||||
UINT rc;
|
UINT rc;
|
||||||
INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
|
INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
|
||||||
HKEY hkey=0,hkey2=0,hkey3=0;
|
HKEY hkey=0;
|
||||||
static const WCHAR szInstaller[] = {
|
|
||||||
'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'I','n','s','t','a','l','l','e','r',0 };
|
|
||||||
static const WCHAR szUninstaller[] = {
|
|
||||||
'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'W','i','n','d','o','w','s','\\',
|
|
||||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
||||||
'U','n','i','n','s','t','a','l','l',0 };
|
|
||||||
static const WCHAR szProducts[] = {
|
|
||||||
'P','r','o','d','u','c','t','s',0 };
|
|
||||||
static const WCHAR szWindowsInstaller[] = {
|
static const WCHAR szWindowsInstaller[] = {
|
||||||
'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
|
'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
|
||||||
DWORD sz;
|
DWORD sz;
|
||||||
|
|
||||||
TRACE("%s\n", debugstr_w(szProduct));
|
TRACE("%s\n", debugstr_w(szProduct));
|
||||||
|
|
||||||
squash_guid(szProduct,squished_pc);
|
rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
|
||||||
|
|
||||||
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(HKEY_CURRENT_USER,szInstaller,&hkey);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* check the products key for the product */
|
|
||||||
rc = RegOpenKeyW(hkey,szProducts,&hkey2);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey2,squished_pc,&hkey3);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
RegCloseKey(hkey3);
|
|
||||||
RegCloseKey(hkey2);
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,szUninstaller,&hkey);
|
rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey,szProduct,&hkey2);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
sz = sizeof(rrc);
|
sz = sizeof(rrc);
|
||||||
rc = RegQueryValueExW(hkey2,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
|
rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -987,8 +802,6 @@ INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
RegCloseKey(hkey3);
|
|
||||||
RegCloseKey(hkey2);
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
return rrc;
|
return rrc;
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +911,7 @@ UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
|
||||||
|
|
||||||
UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
|
UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
|
||||||
{
|
{
|
||||||
HKEY hkey = 0, hkeyFeatures = 0;
|
HKEY hkeyFeatures = 0;
|
||||||
DWORD r;
|
DWORD r;
|
||||||
WCHAR szKeyName[33];
|
WCHAR szKeyName[33];
|
||||||
|
|
||||||
|
@ -1107,11 +920,7 @@ UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
|
||||||
if (NULL == lpguid)
|
if (NULL == lpguid)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
|
r = MSIREG_OpenFeatures(&hkeyFeatures);
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
|
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -1123,8 +932,6 @@ end:
|
||||||
|
|
||||||
if( hkeyFeatures )
|
if( hkeyFeatures )
|
||||||
RegCloseKey(hkeyFeatures);
|
RegCloseKey(hkeyFeatures);
|
||||||
if( hkey )
|
|
||||||
RegCloseKey(hkey);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1165,24 +972,12 @@ UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index,
|
||||||
UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
|
UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
|
||||||
LPWSTR szFeature, LPWSTR szParent)
|
LPWSTR szFeature, LPWSTR szParent)
|
||||||
{
|
{
|
||||||
HKEY hkey = 0, hkeyFeatures = 0, hkeyProduct = 0;
|
HKEY hkeyProduct = 0;
|
||||||
DWORD r, sz;
|
DWORD r, sz;
|
||||||
WCHAR szRegName[GUID_SIZE];
|
|
||||||
|
|
||||||
TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
|
TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
|
||||||
|
|
||||||
if( !squash_guid(szProduct, szRegName) )
|
r = MSIREG_OpenFeaturesKey(szProduct,&hkeyProduct,FALSE);
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
|
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
|
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(hkeyFeatures, szRegName, &hkeyProduct);
|
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -1192,10 +987,6 @@ UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
|
||||||
end:
|
end:
|
||||||
if( hkeyProduct )
|
if( hkeyProduct )
|
||||||
RegCloseKey(hkeyProduct);
|
RegCloseKey(hkeyProduct);
|
||||||
if( hkeyFeatures )
|
|
||||||
RegCloseKey(hkeyFeatures);
|
|
||||||
if( hkey )
|
|
||||||
RegCloseKey(hkey);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1216,17 +1007,13 @@ UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)
|
||||||
|
|
||||||
UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
|
UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
|
||||||
{
|
{
|
||||||
HKEY hkey = 0, hkeyComponents = 0;
|
HKEY hkeyComponents = 0;
|
||||||
DWORD r;
|
DWORD r;
|
||||||
WCHAR szKeyName[33];
|
WCHAR szKeyName[33];
|
||||||
|
|
||||||
TRACE("%ld %p\n",index,lpguid);
|
TRACE("%ld %p\n",index,lpguid);
|
||||||
|
|
||||||
r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
|
r = MSIREG_OpenComponents(&hkeyComponents);
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
|
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -1238,8 +1025,6 @@ end:
|
||||||
|
|
||||||
if( hkeyComponents )
|
if( hkeyComponents )
|
||||||
RegCloseKey(hkeyComponents);
|
RegCloseKey(hkeyComponents);
|
||||||
if( hkey )
|
|
||||||
RegCloseKey(hkey);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1276,24 +1061,13 @@ UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
|
||||||
|
|
||||||
UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
|
UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
|
||||||
{
|
{
|
||||||
HKEY hkey = 0, hkeyComponents = 0, hkeyComp = 0;
|
HKEY hkeyComp = 0;
|
||||||
DWORD r, sz;
|
DWORD r, sz;
|
||||||
WCHAR szRegName[GUID_SIZE], szValName[GUID_SIZE];
|
WCHAR szValName[GUID_SIZE];
|
||||||
|
|
||||||
TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
|
TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
|
||||||
|
|
||||||
if( !squash_guid(szComponent, szRegName) )
|
r = MSIREG_OpenComponentsKey(szComponent,&hkeyComp,FALSE);
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
|
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
|
|
||||||
if( r != ERROR_SUCCESS )
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
r = RegOpenKeyW(hkeyComponents, szRegName, &hkeyComp);
|
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -1307,10 +1081,6 @@ UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
|
||||||
end:
|
end:
|
||||||
if( hkeyComp )
|
if( hkeyComp )
|
||||||
RegCloseKey(hkeyComp);
|
RegCloseKey(hkeyComp);
|
||||||
if( hkeyComponents )
|
|
||||||
RegCloseKey(hkeyComponents);
|
|
||||||
if( hkey )
|
|
||||||
RegCloseKey(hkey);
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1489,66 +1259,36 @@ INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
|
||||||
INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
|
INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
|
||||||
LPWSTR lpPathBuf, DWORD* pcchBuf)
|
LPWSTR lpPathBuf, DWORD* pcchBuf)
|
||||||
{
|
{
|
||||||
WCHAR squished_pc[0x100];
|
WCHAR squished_pc[GUID_SIZE];
|
||||||
WCHAR squished_cc[0x100];
|
|
||||||
UINT rc;
|
UINT rc;
|
||||||
INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
|
INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
|
||||||
HKEY hkey=0,hkey2=0,hkey3=0;
|
HKEY hkey=0;
|
||||||
static const WCHAR szInstaller[] = {
|
|
||||||
'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'W','i','n','d','o','w','s','\\',
|
|
||||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
||||||
'I','n','s','t','a','l','l','e','r',0 };
|
|
||||||
static const WCHAR szComponents[] = {
|
|
||||||
'C','o','m','p','o','n','e','n','t','s',0 };
|
|
||||||
static const WCHAR szProducts[] = {
|
|
||||||
'P','r','o','d','u','c','t','s',0 };
|
|
||||||
|
|
||||||
TRACE("%s %s %p %p\n", debugstr_w(szProduct),
|
TRACE("%s %s %p %p\n", debugstr_w(szProduct),
|
||||||
debugstr_w(szComponent), lpPathBuf, pcchBuf);
|
debugstr_w(szComponent), lpPathBuf, pcchBuf);
|
||||||
|
|
||||||
squash_guid(szProduct,squished_pc);
|
squash_guid(szProduct,squished_pc);
|
||||||
squash_guid(szComponent,squished_cc);
|
|
||||||
|
|
||||||
TRACE("squished (%s:%s)\n", debugstr_w(squished_cc),
|
rc = MSIREG_OpenProductsKey(szProduct,&hkey,FALSE);
|
||||||
debugstr_w(squished_pc));
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* check the products key for the product */
|
RegCloseKey(hkey);
|
||||||
rc = RegOpenKeyW(hkey,szProducts,&hkey2);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey2,squished_pc,&hkey3);
|
rc = MSIREG_OpenComponentsKey(szComponent,&hkey,FALSE);
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
|
|
||||||
RegCloseKey(hkey3);
|
|
||||||
RegCloseKey(hkey2);
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey,szComponents,&hkey2);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
rc = RegOpenKeyW(hkey2,squished_cc,&hkey3);
|
|
||||||
if (rc != ERROR_SUCCESS)
|
if (rc != ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
*pcchBuf *= sizeof(WCHAR);
|
*pcchBuf *= sizeof(WCHAR);
|
||||||
rc = RegQueryValueExW(hkey3,squished_pc,NULL,NULL,(LPVOID)lpPathBuf,
|
rc = RegQueryValueExW(hkey,squished_pc,NULL,NULL,(LPVOID)lpPathBuf,
|
||||||
pcchBuf);
|
pcchBuf);
|
||||||
*pcchBuf /= sizeof(WCHAR);
|
*pcchBuf /= sizeof(WCHAR);
|
||||||
|
|
||||||
if (rc!= ERROR_SUCCESS)
|
if (rc!= ERROR_SUCCESS)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
TRACE("found path of (%s:%s)(%s)\n", debugstr_w(squished_cc),
|
TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
|
||||||
debugstr_w(squished_pc), debugstr_w(lpPathBuf));
|
debugstr_w(szProduct), debugstr_w(lpPathBuf));
|
||||||
|
|
||||||
FIXME("Only working for installed files, not registry keys\n");
|
FIXME("Only working for installed files, not registry keys\n");
|
||||||
if (GetFileAttributesW(lpPathBuf) != INVALID_FILE_ATTRIBUTES)
|
if (GetFileAttributesW(lpPathBuf) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
@ -1557,8 +1297,6 @@ INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
|
||||||
rrc = INSTALLSTATE_ABSENT;
|
rrc = INSTALLSTATE_ABSENT;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
RegCloseKey(hkey3);
|
|
||||||
RegCloseKey(hkey2);
|
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
return rrc;
|
return rrc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,6 +334,14 @@ BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
|
||||||
BOOL squash_guid(LPCWSTR in, LPWSTR out);
|
BOOL squash_guid(LPCWSTR in, LPWSTR out);
|
||||||
BOOL encode_base85_guid(GUID *,LPWSTR);
|
BOOL encode_base85_guid(GUID *,LPWSTR);
|
||||||
BOOL decode_base85_guid(LPCWSTR,GUID*);
|
BOOL decode_base85_guid(LPCWSTR,GUID*);
|
||||||
|
UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create);
|
||||||
|
UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
|
||||||
|
UINT MSIREG_OpenFeatures(HKEY* key);
|
||||||
|
UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
|
||||||
|
UINT MSIREG_OpenComponents(HKEY* key);
|
||||||
|
UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
|
||||||
|
UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
|
||||||
|
UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
|
||||||
|
|
||||||
/* UI globals */
|
/* UI globals */
|
||||||
extern INSTALLUILEVEL gUILevel;
|
extern INSTALLUILEVEL gUILevel;
|
||||||
|
|
|
@ -0,0 +1,390 @@
|
||||||
|
/*
|
||||||
|
* Implementation of the Microsoft Installer (msi.dll)
|
||||||
|
*
|
||||||
|
* Copyright 2005 Mike McCormak for CodeWeavers
|
||||||
|
* Copyright 2005 Aric Stewart for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
#define NONAMELESSUNION
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winreg.h"
|
||||||
|
#include "winnls.h"
|
||||||
|
#include "shlwapi.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "msi.h"
|
||||||
|
#include "msipriv.h"
|
||||||
|
#include "wincrypt.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
#include "winver.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This module will be all the helper functions for registry access by the
|
||||||
|
* installer bits.
|
||||||
|
*/
|
||||||
|
static const WCHAR szUserFeatures_fmt[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'F','e','a','t','u','r','e','s','\\',
|
||||||
|
'%','s',0};
|
||||||
|
|
||||||
|
static const WCHAR szInstaller_Features[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'F','e','a','t','u','r','e','s',0 };
|
||||||
|
|
||||||
|
static const WCHAR szInstaller_Features_fmt[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'F','e','a','t','u','r','e','s','\\',
|
||||||
|
'%','s',0};
|
||||||
|
|
||||||
|
static const WCHAR szInstaller_Components[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'C','o','m','p','o','n','e','n','t','s',0 };
|
||||||
|
|
||||||
|
static const WCHAR szInstaller_Components_fmt[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'C','o','m','p','o','n','e','n','t','s','\\',
|
||||||
|
'%','s',0};
|
||||||
|
|
||||||
|
static const WCHAR szUninstall_fmt[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'U','n','i','n','s','t','a','l','l','\\',
|
||||||
|
'%','s',0 };
|
||||||
|
|
||||||
|
static const WCHAR szUserProduct_fmt[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'P','r','o','d','u','c','t','s','\\',
|
||||||
|
'%','s',0};
|
||||||
|
|
||||||
|
static const WCHAR szInstaller_Products[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'P','r','o','d','u','c','t','s',0};
|
||||||
|
|
||||||
|
static const WCHAR szInstaller_Products_fmt[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'P','r','o','d','u','c','t','s','\\',
|
||||||
|
'%','s',0};
|
||||||
|
|
||||||
|
BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
|
||||||
|
{
|
||||||
|
DWORD i,n=0;
|
||||||
|
|
||||||
|
out[n++]='{';
|
||||||
|
for(i=0; i<8; i++)
|
||||||
|
out[n++] = in[7-i];
|
||||||
|
out[n++]='-';
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
out[n++] = in[11-i];
|
||||||
|
out[n++]='-';
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
out[n++] = in[15-i];
|
||||||
|
out[n++]='-';
|
||||||
|
for(i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
out[n++] = in[17+i*2];
|
||||||
|
out[n++] = in[16+i*2];
|
||||||
|
}
|
||||||
|
out[n++]='-';
|
||||||
|
for( ; i<8; i++)
|
||||||
|
{
|
||||||
|
out[n++] = in[17+i*2];
|
||||||
|
out[n++] = in[16+i*2];
|
||||||
|
}
|
||||||
|
out[n++]='}';
|
||||||
|
out[n]=0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL squash_guid(LPCWSTR in, LPWSTR out)
|
||||||
|
{
|
||||||
|
DWORD i,n=0;
|
||||||
|
|
||||||
|
if(in[n++] != '{')
|
||||||
|
return FALSE;
|
||||||
|
for(i=0; i<8; i++)
|
||||||
|
out[7-i] = in[n++];
|
||||||
|
if(in[n++] != '-')
|
||||||
|
return FALSE;
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
out[11-i] = in[n++];
|
||||||
|
if(in[n++] != '-')
|
||||||
|
return FALSE;
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
out[15-i] = in[n++];
|
||||||
|
if(in[n++] != '-')
|
||||||
|
return FALSE;
|
||||||
|
for(i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
out[17+i*2] = in[n++];
|
||||||
|
out[16+i*2] = in[n++];
|
||||||
|
}
|
||||||
|
if(in[n++] != '-')
|
||||||
|
return FALSE;
|
||||||
|
for( ; i<8; i++)
|
||||||
|
{
|
||||||
|
out[17+i*2] = in[n++];
|
||||||
|
out[16+i*2] = in[n++];
|
||||||
|
}
|
||||||
|
out[32]=0;
|
||||||
|
if(in[n++] != '}')
|
||||||
|
return FALSE;
|
||||||
|
if(in[n])
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tables for encoding and decoding base85 */
|
||||||
|
static const unsigned char table_dec85[0x80] = {
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
|
0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
|
||||||
|
0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
|
||||||
|
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
|
||||||
|
0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
|
||||||
|
0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
|
||||||
|
0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char table_enc85[] =
|
||||||
|
"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
|
||||||
|
"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
|
||||||
|
"yz{}~";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts a base85 encoded guid into a GUID pointer
|
||||||
|
* Base85 encoded GUIDs should be 20 characters long.
|
||||||
|
*
|
||||||
|
* returns TRUE if successful, FALSE if not
|
||||||
|
*/
|
||||||
|
BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
|
||||||
|
{
|
||||||
|
DWORD i, val = 0, base = 1, *p;
|
||||||
|
|
||||||
|
p = (DWORD*) guid;
|
||||||
|
for( i=0; i<20; i++ )
|
||||||
|
{
|
||||||
|
if( (i%5) == 0 )
|
||||||
|
{
|
||||||
|
val = 0;
|
||||||
|
base = 1;
|
||||||
|
}
|
||||||
|
val += table_dec85[str[i]] * base;
|
||||||
|
if( str[i] >= 0x80 )
|
||||||
|
return FALSE;
|
||||||
|
if( table_dec85[str[i]] == 0xff )
|
||||||
|
return FALSE;
|
||||||
|
if( (i%5) == 4 )
|
||||||
|
p[i/5] = val;
|
||||||
|
base *= 85;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encodes a base85 guid given a GUID pointer
|
||||||
|
* Caller should provide a 21 character buffer for the encoded string.
|
||||||
|
*
|
||||||
|
* returns TRUE if successful, FALSE if not
|
||||||
|
*/
|
||||||
|
BOOL encode_base85_guid( GUID *guid, LPWSTR str )
|
||||||
|
{
|
||||||
|
unsigned int x, *p, i;
|
||||||
|
|
||||||
|
p = (unsigned int*) guid;
|
||||||
|
for( i=0; i<4; i++ )
|
||||||
|
{
|
||||||
|
x = p[i];
|
||||||
|
*str++ = table_enc85[x%85];
|
||||||
|
x = x/85;
|
||||||
|
*str++ = table_enc85[x%85];
|
||||||
|
x = x/85;
|
||||||
|
*str++ = table_enc85[x%85];
|
||||||
|
x = x/85;
|
||||||
|
*str++ = table_enc85[x%85];
|
||||||
|
x = x/85;
|
||||||
|
*str++ = table_enc85[x%85];
|
||||||
|
}
|
||||||
|
*str = 0;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create)
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
WCHAR keypath[0x200];
|
||||||
|
TRACE("%s\n",debugstr_w(szProduct));
|
||||||
|
|
||||||
|
sprintfW(keypath,szUninstall_fmt,szProduct);
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
else
|
||||||
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
WCHAR squished_pc[GUID_SIZE];
|
||||||
|
WCHAR keypath[0x200];
|
||||||
|
|
||||||
|
TRACE("%s\n",debugstr_w(szProduct));
|
||||||
|
squash_guid(szProduct,squished_pc);
|
||||||
|
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
||||||
|
|
||||||
|
sprintfW(keypath,szUserProduct_fmt,squished_pc);
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
|
||||||
|
else
|
||||||
|
rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
WCHAR squished_pc[GUID_SIZE];
|
||||||
|
WCHAR keypath[0x200];
|
||||||
|
|
||||||
|
TRACE("%s\n",debugstr_w(szProduct));
|
||||||
|
squash_guid(szProduct,squished_pc);
|
||||||
|
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
||||||
|
|
||||||
|
sprintfW(keypath,szUserFeatures_fmt,squished_pc);
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
|
||||||
|
else
|
||||||
|
rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenFeatures(HKEY* key)
|
||||||
|
{
|
||||||
|
return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Features,key);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
WCHAR squished_pc[GUID_SIZE];
|
||||||
|
WCHAR keypath[0x200];
|
||||||
|
|
||||||
|
TRACE("%s\n",debugstr_w(szProduct));
|
||||||
|
squash_guid(szProduct,squished_pc);
|
||||||
|
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
||||||
|
|
||||||
|
sprintfW(keypath,szInstaller_Features_fmt,squished_pc);
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
|
||||||
|
else
|
||||||
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenComponents(HKEY* key)
|
||||||
|
{
|
||||||
|
return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Components,key);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create)
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
WCHAR squished_cc[GUID_SIZE];
|
||||||
|
WCHAR keypath[0x200];
|
||||||
|
|
||||||
|
TRACE("%s\n",debugstr_w(szComponent));
|
||||||
|
squash_guid(szComponent,squished_cc);
|
||||||
|
TRACE("squished (%s)\n", debugstr_w(squished_cc));
|
||||||
|
|
||||||
|
sprintfW(keypath,szInstaller_Components_fmt,squished_cc);
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
|
||||||
|
else
|
||||||
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
WCHAR squished_pc[GUID_SIZE];
|
||||||
|
WCHAR keypath[0x200];
|
||||||
|
|
||||||
|
TRACE("%s\n",debugstr_w(szProduct));
|
||||||
|
squash_guid(szProduct,squished_pc);
|
||||||
|
TRACE("squished (%s)\n", debugstr_w(squished_pc));
|
||||||
|
|
||||||
|
sprintfW(keypath,szInstaller_Products_fmt,squished_pc);
|
||||||
|
|
||||||
|
if (create)
|
||||||
|
rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
|
||||||
|
else
|
||||||
|
rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
Loading…
Reference in New Issue