[WINESYNC] msi: Use wide character string literals in the remaining files.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id c4fc91f4bf0ffdc4a7dc2e582e5bd3fddca85222 by Hans Leidekker <hans@codeweavers.com>
This commit is contained in:
winesync 2022-03-13 21:31:42 +01:00 committed by Mark Jansen
parent d012037f17
commit 74f53b4bcb
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
30 changed files with 422 additions and 866 deletions

View file

@ -82,13 +82,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
*/ */
static UINT get_signature( MSIPACKAGE *package, MSISIGNATURE *sig, const WCHAR *name ) static UINT get_signature( MSIPACKAGE *package, MSISIGNATURE *sig, const WCHAR *name )
{ {
static const WCHAR query[] = { WCHAR *minVersion, *maxVersion, *p;
's','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ',
'S','i','g','n','a','t','u','r','e',' ',
'w','h','e','r','e',' ','S','i','g','n','a','t','u','r','e',' ','=',' ',
'\'','%','s','\'',0};
LPWSTR minVersion, maxVersion, p;
MSIRECORD *row; MSIRECORD *row;
DWORD time; DWORD time;
@ -96,7 +90,7 @@ static UINT get_signature( MSIPACKAGE *package, MSISIGNATURE *sig, const WCHAR *
memset(sig, 0, sizeof(*sig)); memset(sig, 0, sizeof(*sig));
sig->Name = name; sig->Name = name;
row = MSI_QueryGetRecord( package->db, query, name ); row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `Signature` WHERE `Signature` = '%s'", name );
if (!row) if (!row)
{ {
TRACE("failed to query signature for %s\n", debugstr_w(name)); TRACE("failed to query signature for %s\n", debugstr_w(name));
@ -195,7 +189,7 @@ static WCHAR *search_file( MSIPACKAGE *package, WCHAR *path, MSISIGNATURE *sig )
if (!size) if (!size)
goto done; goto done;
if (!VerQueryValueW(buffer, szBackSlash, (LPVOID)&info, &size) || !info) if (!VerQueryValueW(buffer, L"\\", (LPVOID)&info, &size) || !info)
goto done; goto done;
if (sig->MinVersionLS || sig->MinVersionMS) if (sig->MinVersionLS || sig->MinVersionMS)
@ -227,17 +221,6 @@ done:
static UINT search_components( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) static UINT search_components( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ',
'F','R','O','M',' ',
'`','C','o','m','p','L','o','c','a','t','o','r','`',' ',
'W','H','E','R','E',' ','`','S','i','g','n','a','t','u','r','e','_','`',' ','=',' ',
'\'','%','s','\'',0};
static const WCHAR sigquery[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','S','i','g','n','a','t','u','r','e','`',' ',
'W','H','E','R','E',' ','`','S','i','g','n','a','t','u','r','e','`',' ','=',' ',
'\'','%','s','\'',0};
MSIRECORD *row, *rec; MSIRECORD *row, *rec;
LPCWSTR signature, guid; LPCWSTR signature, guid;
BOOL sigpresent = TRUE; BOOL sigpresent = TRUE;
@ -252,7 +235,7 @@ static UINT search_components( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATU
*appValue = NULL; *appValue = NULL;
row = MSI_QueryGetRecord(package->db, query, sig->Name); row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `CompLocator` WHERE `Signature_` = '%s'", sig->Name);
if (!row) if (!row)
{ {
TRACE("failed to query CompLocator for %s\n", debugstr_w(sig->Name)); TRACE("failed to query CompLocator for %s\n", debugstr_w(sig->Name));
@ -263,7 +246,7 @@ static UINT search_components( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATU
guid = MSI_RecordGetString(row, 2); guid = MSI_RecordGetString(row, 2);
type = MSI_RecordGetInteger(row, 3); type = MSI_RecordGetInteger(row, 3);
rec = MSI_QueryGetRecord(package->db, sigquery, signature); rec = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Signature` WHERE `Signature` = '%s'", signature);
if (!rec) if (!rec)
sigpresent = FALSE; sigpresent = FALSE;
@ -312,9 +295,6 @@ done:
static void convert_reg_value( DWORD regType, const BYTE *value, DWORD sz, WCHAR **appValue ) static void convert_reg_value( DWORD regType, const BYTE *value, DWORD sz, WCHAR **appValue )
{ {
static const WCHAR dwordFmt[] = { '#','%','d','\0' };
static const WCHAR binPre[] = { '#','x','\0' };
static const WCHAR binFmt[] = { '%','0','2','X','\0' };
LPWSTR ptr; LPWSTR ptr;
DWORD i; DWORD i;
@ -339,7 +319,7 @@ static void convert_reg_value( DWORD regType, const BYTE *value, DWORD sz, WCHAR
* char if needed * char if needed
*/ */
*appValue = msi_alloc(10 * sizeof(WCHAR)); *appValue = msi_alloc(10 * sizeof(WCHAR));
swprintf(*appValue, 10, dwordFmt, *(const DWORD *)value); swprintf(*appValue, 10, L"#%d", *(const DWORD *)value);
break; break;
case REG_EXPAND_SZ: case REG_EXPAND_SZ:
sz = ExpandEnvironmentStringsW((LPCWSTR)value, NULL, 0); sz = ExpandEnvironmentStringsW((LPCWSTR)value, NULL, 0);
@ -349,10 +329,10 @@ static void convert_reg_value( DWORD regType, const BYTE *value, DWORD sz, WCHAR
case REG_BINARY: case REG_BINARY:
/* #x<nibbles>\0 */ /* #x<nibbles>\0 */
*appValue = msi_alloc((sz * 2 + 3) * sizeof(WCHAR)); *appValue = msi_alloc((sz * 2 + 3) * sizeof(WCHAR));
lstrcpyW(*appValue, binPre); lstrcpyW(*appValue, L"#x");
ptr = *appValue + lstrlenW(binPre); ptr = *appValue + lstrlenW(L"#x");
for (i = 0; i < sz; i++, ptr += 2) for (i = 0; i < sz; i++, ptr += 2)
swprintf(ptr, 3, binFmt, value[i]); swprintf(ptr, 3, L"%02X", value[i]);
break; break;
default: default:
WARN("unimplemented for values of type %d\n", regType); WARN("unimplemented for values of type %d\n", regType);
@ -364,10 +344,6 @@ static UINT search_directory( MSIPACKAGE *, MSISIGNATURE *, const WCHAR *, int,
static UINT search_reg( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) static UINT search_reg( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'R','e','g','L','o','c','a','t','o','r',' ','W','H','E','R','E',' ',
'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0};
const WCHAR *keyPath, *valueName; const WCHAR *keyPath, *valueName;
WCHAR *deformatted = NULL, *ptr = NULL, *end; WCHAR *deformatted = NULL, *ptr = NULL, *end;
int root, type; int root, type;
@ -382,7 +358,7 @@ static UINT search_reg( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig
*appValue = NULL; *appValue = NULL;
row = MSI_QueryGetRecord( package->db, query, sig->Name ); row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `RegLocator` WHERE `Signature_` = '%s'", sig->Name );
if (!row) if (!row)
{ {
TRACE("failed to query RegLocator for %s\n", debugstr_w(sig->Name)); TRACE("failed to query RegLocator for %s\n", debugstr_w(sig->Name));
@ -519,12 +495,6 @@ static LPWSTR get_ini_field(LPWSTR buf, int field)
static UINT search_ini( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) static UINT search_ini( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ',
'I','n','i','L','o','c','a','t','o','r',' ',
'w','h','e','r','e',' ',
'S','i','g','n','a','t','u','r','e','_',' ','=',' ','\'','%','s','\'',0};
MSIRECORD *row; MSIRECORD *row;
LPWSTR fileName, section, key; LPWSTR fileName, section, key;
int field, type; int field, type;
@ -534,7 +504,7 @@ static UINT search_ini( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig
*appValue = NULL; *appValue = NULL;
row = MSI_QueryGetRecord( package->db, query, sig->Name ); row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `IniLocator` WHERE `Signature_` = '%s'", sig->Name );
if (!row) if (!row)
{ {
TRACE("failed to query IniLocator for %s\n", debugstr_w(sig->Name)); TRACE("failed to query IniLocator for %s\n", debugstr_w(sig->Name));
@ -657,7 +627,7 @@ static BOOL match_languages( const void *version, const WCHAR *languages )
LANGID *ids; LANGID *ids;
if (!languages || !languages[0]) return TRUE; if (!languages || !languages[0]) return TRUE;
if (!VerQueryValueW( version, szLangResource, (void **)&lang, &len )) return FALSE; if (!VerQueryValueW( version, L"\\VarFileInfo\\Translation", (void **)&lang, &len )) return FALSE;
if (!(ids = parse_languages( languages, &num_ids ))) return FALSE; if (!(ids = parse_languages( languages, &num_ids ))) return FALSE;
for (i = 0; i < num_ids; i++) for (i = 0; i < num_ids; i++)
@ -694,7 +664,7 @@ static UINT file_version_matches( MSIPACKAGE *package, const MSISIGNATURE *sig,
if (!(version = msi_alloc( size ))) return ERROR_OUTOFMEMORY; if (!(version = msi_alloc( size ))) return ERROR_OUTOFMEMORY;
if (msi_get_file_version_info( package, filePath, size, version )) if (msi_get_file_version_info( package, filePath, size, version ))
VerQueryValueW( version, szBackSlash, (void **)&info, &len ); VerQueryValueW( version, L"\\", (void **)&info, &len );
if (info) if (info)
{ {
@ -788,7 +758,6 @@ static UINT file_matches_sig( MSIPACKAGE *package, const MSISIGNATURE *sig, cons
static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig, const WCHAR *dir, static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig, const WCHAR *dir,
int depth ) int depth )
{ {
static const WCHAR starDotStarW[] = { '*','.','*',0 };
HANDLE hFind; HANDLE hFind;
WIN32_FIND_DATAW findData; WIN32_FIND_DATAW findData;
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
@ -807,7 +776,7 @@ static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSI
* here. Add two because we might need to add a backslash if the dir name * here. Add two because we might need to add a backslash if the dir name
* isn't backslash-terminated. * isn't backslash-terminated.
*/ */
len = dirLen + max(fileLen, lstrlenW(starDotStarW)) + 2; len = dirLen + max(fileLen, lstrlenW(L"*.*")) + 2;
buf = msi_alloc(len * sizeof(WCHAR)); buf = msi_alloc(len * sizeof(WCHAR));
if (!buf) if (!buf)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -837,14 +806,14 @@ static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSI
{ {
lstrcpyW(buf, dir); lstrcpyW(buf, dir);
PathAddBackslashW(buf); PathAddBackslashW(buf);
lstrcatW(buf, starDotStarW); lstrcatW(buf, L"*.*");
hFind = msi_find_first_file( package, buf, &findData ); hFind = msi_find_first_file( package, buf, &findData );
if (hFind != INVALID_HANDLE_VALUE) if (hFind != INVALID_HANDLE_VALUE)
{ {
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
wcscmp( findData.cFileName, szDot ) && wcscmp( findData.cFileName, L"." ) &&
wcscmp( findData.cFileName, szDotDot )) wcscmp( findData.cFileName, L".." ))
{ {
lstrcpyW(subpath, dir); lstrcpyW(subpath, dir);
PathAppendW(subpath, findData.cFileName); PathAppendW(subpath, findData.cFileName);
@ -853,8 +822,8 @@ static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSI
while (rc == ERROR_SUCCESS && !*appValue && msi_find_next_file( package, hFind, &findData )) while (rc == ERROR_SUCCESS && !*appValue && msi_find_next_file( package, hFind, &findData ))
{ {
if (!wcscmp( findData.cFileName, szDot ) || if (!wcscmp( findData.cFileName, L"." ) ||
!wcscmp( findData.cFileName, szDotDot )) !wcscmp( findData.cFileName, L".." ))
continue; continue;
lstrcpyW(subpath, dir); lstrcpyW(subpath, dir);
@ -966,12 +935,6 @@ static UINT search_sig_name( MSIPACKAGE *, const WCHAR *, MSISIGNATURE *, WCHAR
static UINT search_dr( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) static UINT search_dr( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ',
'D','r','L','o','c','a','t','o','r',' ',
'w','h','e','r','e',' ',
'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0};
LPWSTR parent = NULL; LPWSTR parent = NULL;
LPCWSTR parentName; LPCWSTR parentName;
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
@ -985,7 +948,7 @@ static UINT search_dr( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig
*appValue = NULL; *appValue = NULL;
row = MSI_QueryGetRecord( package->db, query, sig->Name ); row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `DrLocator` WHERE `Signature_` = '%s'", sig->Name );
if (!row) if (!row)
{ {
TRACE("failed to query DrLocator for %s\n", debugstr_w(sig->Name)); TRACE("failed to query DrLocator for %s\n", debugstr_w(sig->Name));
@ -1087,7 +1050,7 @@ static UINT ITERATE_AppSearch(MSIRECORD *row, LPVOID param)
if (value) if (value)
{ {
r = msi_set_property( package->db, propName, value, -1 ); r = msi_set_property( package->db, propName, value, -1 );
if (r == ERROR_SUCCESS && !wcscmp( propName, szSourceDir )) if (r == ERROR_SUCCESS && !wcscmp( propName, L"SourceDir" ))
msi_reset_source_folders( package ); msi_reset_source_folders( package );
msi_free(value); msi_free(value);
@ -1105,21 +1068,18 @@ static UINT ITERATE_AppSearch(MSIRECORD *row, LPVOID param)
UINT ACTION_AppSearch(MSIPACKAGE *package) UINT ACTION_AppSearch(MSIPACKAGE *package)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'A','p','p','S','e','a','r','c','h',0};
MSIQUERY *view; MSIQUERY *view;
UINT r; UINT r;
if (msi_action_is_unique(package, szAppSearch)) if (msi_action_is_unique(package, L"AppSearch"))
{ {
TRACE("Skipping AppSearch action: already done in UI sequence\n"); TRACE("Skipping AppSearch action: already done in UI sequence\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
else else
msi_register_unique_action(package, szAppSearch); msi_register_unique_action(package, L"AppSearch");
r = MSI_OpenQuery( package->db, &view, query ); r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `AppSearch`" );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -1136,8 +1096,6 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param)
MSISIGNATURE sig; MSISIGNATURE sig;
UINT r = ERROR_SUCCESS; UINT r = ERROR_SUCCESS;
static const WCHAR success[] = {'C','C','P','_','S','u','c','c','e','s','s',0};
signature = MSI_RecordGetString(row, 1); signature = MSI_RecordGetString(row, 1);
TRACE("%s\n", debugstr_w(signature)); TRACE("%s\n", debugstr_w(signature));
@ -1146,7 +1104,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param)
if (value) if (value)
{ {
TRACE("Found signature %s\n", debugstr_w(signature)); TRACE("Found signature %s\n", debugstr_w(signature));
msi_set_property( package->db, success, szOne, -1 ); msi_set_property( package->db, L"CCP_Success", L"1", -1 );
msi_free(value); msi_free(value);
r = ERROR_NO_MORE_ITEMS; r = ERROR_NO_MORE_ITEMS;
} }
@ -1157,21 +1115,18 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param)
UINT ACTION_CCPSearch(MSIPACKAGE *package) UINT ACTION_CCPSearch(MSIPACKAGE *package)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'C','C','P','S','e','a','r','c','h',0};
MSIQUERY *view; MSIQUERY *view;
UINT r; UINT r;
if (msi_action_is_unique(package, szCCPSearch)) if (msi_action_is_unique(package, L"CCPSearch"))
{ {
TRACE("Skipping AppSearch action: already done in UI sequence\n"); TRACE("Skipping AppSearch action: already done in UI sequence\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
else else
msi_register_unique_action(package, szCCPSearch); msi_register_unique_action(package, L"CCPSearch");
r = MSI_OpenQuery(package->db, &view, query); r = MSI_OpenQuery(package->db, &view, L"SELECT * FROM `CCPSearch`");
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;

View file

@ -32,17 +32,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
static BOOL load_fusion_dlls( MSIPACKAGE *package ) static BOOL load_fusion_dlls( MSIPACKAGE *package )
{ {
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
static const WCHAR szMscoree[] = {'\\','m','s','c','o','r','e','e','.','d','l','l',0};
static const WCHAR szVersion10[] = {'v','1','.','0','.','3','7','0','5',0};
static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0};
static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0};
HRESULT (WINAPI *pLoadLibraryShim)( const WCHAR *, const WCHAR *, void *, HMODULE * ); HRESULT (WINAPI *pLoadLibraryShim)( const WCHAR *, const WCHAR *, void *, HMODULE * );
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
DWORD len = GetSystemDirectoryW( path, MAX_PATH ); DWORD len = GetSystemDirectoryW( path, MAX_PATH );
lstrcpyW( path + len, szMscoree ); lstrcpyW( path + len, L"\\mscoree.dll" );
if (package->hmscoree || !(package->hmscoree = LoadLibraryW( path ))) return TRUE; if (package->hmscoree || !(package->hmscoree = LoadLibraryW( path ))) return TRUE;
if (!(pLoadLibraryShim = (void *)GetProcAddress( package->hmscoree, "LoadLibraryShim" ))) if (!(pLoadLibraryShim = (void *)GetProcAddress( package->hmscoree, "LoadLibraryShim" )))
{ {
@ -51,10 +45,10 @@ static BOOL load_fusion_dlls( MSIPACKAGE *package )
return TRUE; return TRUE;
} }
pLoadLibraryShim( szFusion, szVersion10, NULL, &package->hfusion10 ); pLoadLibraryShim( L"fusion.dll", L"v1.0.3705", NULL, &package->hfusion10 );
pLoadLibraryShim( szFusion, szVersion11, NULL, &package->hfusion11 ); pLoadLibraryShim( L"fusion.dll", L"v1.1.4322", NULL, &package->hfusion11 );
pLoadLibraryShim( szFusion, szVersion20, NULL, &package->hfusion20 ); pLoadLibraryShim( L"fusion.dll", L"v2.0.50727", NULL, &package->hfusion20 );
pLoadLibraryShim( szFusion, szVersion40, NULL, &package->hfusion40 ); pLoadLibraryShim( L"fusion.dll", L"v4.0.30319", NULL, &package->hfusion40 );
return TRUE; return TRUE;
} }
@ -129,16 +123,11 @@ void msi_destroy_assembly_caches( MSIPACKAGE *package )
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp ) static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','M','s','i','A','s','s','e','m','b','l','y','`',' ',
'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
' ','=',' ','\'','%','s','\'',0};
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
UINT r; UINT r;
r = MSI_OpenQuery( package->db, &view, query, comp ); r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `MsiAssembly` WHERE `Component_` = '%s'", comp );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return NULL; return NULL;
@ -170,36 +159,28 @@ struct assembly_name
static UINT get_assembly_name_attribute( MSIRECORD *rec, LPVOID param ) static UINT get_assembly_name_attribute( MSIRECORD *rec, LPVOID param )
{ {
static const WCHAR fmtW[] = {'%','s','=','"','%','s','"',0};
static const WCHAR nameW[] = {'n','a','m','e',0};
struct assembly_name *name = param; struct assembly_name *name = param;
const WCHAR *attr = MSI_RecordGetString( rec, 2 ); const WCHAR *attr = MSI_RecordGetString( rec, 2 );
const WCHAR *value = MSI_RecordGetString( rec, 3 ); const WCHAR *value = MSI_RecordGetString( rec, 3 );
int len = lstrlenW( fmtW ) + lstrlenW( attr ) + lstrlenW( value ); int len = lstrlenW( L"%s=\"%s\"" ) + lstrlenW( attr ) + lstrlenW( value );
if (!(name->attrs[name->index] = msi_alloc( len * sizeof(WCHAR) ))) if (!(name->attrs[name->index] = msi_alloc( len * sizeof(WCHAR) )))
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
if (!wcsicmp( attr, nameW )) lstrcpyW( name->attrs[name->index++], value ); if (!wcsicmp( attr, L"name" )) lstrcpyW( name->attrs[name->index++], value );
else swprintf( name->attrs[name->index++], len, fmtW, attr, value ); else swprintf( name->attrs[name->index++], len, L"%s=\"%s\"", attr, value );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static WCHAR *get_assembly_display_name( MSIDATABASE *db, const WCHAR *comp, MSIASSEMBLY *assembly ) static WCHAR *get_assembly_display_name( MSIDATABASE *db, const WCHAR *comp, MSIASSEMBLY *assembly )
{ {
static const WCHAR commaW[] = {',',0};
static const WCHAR queryW[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','M','s','i','A','s','s','e','m','b','l','y','N','a','m','e','`',' ',
'W','H','E','R','E',' ','`','C','o','m','p','o','n','e','n','t','_','`',
' ','=',' ','\'','%','s','\'',0};
struct assembly_name name; struct assembly_name name;
WCHAR *display_name = NULL; WCHAR *display_name = NULL;
MSIQUERY *view; MSIQUERY *view;
UINT i, r; UINT i, r;
int len; int len;
r = MSI_OpenQuery( db, &view, queryW, comp ); r = MSI_OpenQuery( db, &view, L"SELECT * FROM `MsiAssemblyName` WHERE `Component_` = '%s'", comp );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return NULL; return NULL;
@ -224,7 +205,7 @@ static WCHAR *get_assembly_display_name( MSIDATABASE *db, const WCHAR *comp, MSI
for (i = 0; i < name.count; i++) for (i = 0; i < name.count; i++)
{ {
lstrcatW( display_name, name.attrs[i] ); lstrcatW( display_name, name.attrs[i] );
if (i < name.count - 1) lstrcatW( display_name, commaW ); if (i < name.count - 1) lstrcatW( display_name, L"," );
} }
} }
@ -320,23 +301,17 @@ IAssemblyEnum *msi_create_assembly_enum( MSIPACKAGE *package, const WCHAR *displ
return ret; return ret;
} }
static const WCHAR clr_version_v10[] = {'v','1','.','0','.','3','7','0','5',0};
static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0};
static const WCHAR clr_version_v40[] = {'v','4','.','0','.','3','0','3','1','9',0};
static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0};
static const WCHAR *clr_version[] = static const WCHAR *clr_version[] =
{ {
clr_version_v10, L"v1.0.3705",
clr_version_v11, L"v1.2.4322",
clr_version_v20, L"v2.0.50727",
clr_version_v40 L"v4.0.30319"
}; };
static const WCHAR *get_clr_version_str( enum clr_version version ) static const WCHAR *get_clr_version_str( enum clr_version version )
{ {
if (version >= ARRAY_SIZE( clr_version )) return clr_version_unknown; if (version >= ARRAY_SIZE( clr_version )) return L"unknown";
return clr_version[version]; return clr_version[version];
} }
@ -539,30 +514,20 @@ static WCHAR *build_local_assembly_path( const WCHAR *filename )
static LONG open_assemblies_key( UINT context, BOOL win32, HKEY *hkey ) static LONG open_assemblies_key( UINT context, BOOL win32, HKEY *hkey )
{ {
static const WCHAR path_win32[] =
{'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','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0};
static const WCHAR path_dotnet[] =
{'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','\\','A','s','s','e','m','b','l','i','e','s','\\',0};
static const WCHAR classes_path_win32[] =
{'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',0};
static const WCHAR classes_path_dotnet[] =
{'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\',0};
HKEY root; HKEY root;
const WCHAR *path; const WCHAR *path;
if (context == MSIINSTALLCONTEXT_MACHINE) if (context == MSIINSTALLCONTEXT_MACHINE)
{ {
root = HKEY_CLASSES_ROOT; root = HKEY_CLASSES_ROOT;
if (win32) path = classes_path_win32; if (win32) path = L"Installer\\Win32Assemblies\\";
else path = classes_path_dotnet; else path = L"Installer\\Assemblies\\";
} }
else else
{ {
root = HKEY_CURRENT_USER; root = HKEY_CURRENT_USER;
if (win32) path = path_win32; if (win32) path = L"Software\\Microsoft\\Installer\\Win32Assemblies\\";
else path = path_dotnet; else path = L"Software\\Microsoft\\Installer\\Assemblies\\";
} }
return RegCreateKeyW( root, path, hkey ); return RegCreateKeyW( root, path, hkey );
} }
@ -609,33 +574,20 @@ static LONG delete_local_assembly_key( UINT context, BOOL win32, const WCHAR *fi
static LONG open_global_assembly_key( UINT context, BOOL win32, HKEY *hkey ) static LONG open_global_assembly_key( UINT context, BOOL win32, HKEY *hkey )
{ {
static const WCHAR path_win32[] =
{'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','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',
'G','l','o','b','a','l',0};
static const WCHAR path_dotnet[] =
{'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','\\','A','s','s','e','m','b','l','i','e','s','\\',
'G','l','o','b','a','l',0};
static const WCHAR classes_path_win32[] =
{'I','n','s','t','a','l','l','e','r','\\','W','i','n','3','2','A','s','s','e','m','b','l','i','e','s','\\',
'G','l','o','b','a','l',0};
static const WCHAR classes_path_dotnet[] =
{'I','n','s','t','a','l','l','e','r','\\','A','s','s','e','m','b','l','i','e','s','\\','G','l','o','b','a','l',0};
HKEY root; HKEY root;
const WCHAR *path; const WCHAR *path;
if (context == MSIINSTALLCONTEXT_MACHINE) if (context == MSIINSTALLCONTEXT_MACHINE)
{ {
root = HKEY_CLASSES_ROOT; root = HKEY_CLASSES_ROOT;
if (win32) path = classes_path_win32; if (win32) path = L"Installer\\Win32Assemblies\\Global";
else path = classes_path_dotnet; else path = L"Installer\\Assemblies\\Global";
} }
else else
{ {
root = HKEY_CURRENT_USER; root = HKEY_CURRENT_USER;
if (win32) path = path_win32; if (win32) path = L"Software\\Microsoft\\Installer\\Win32Assemblies\\Global";
else path = path_dotnet; else path = L"Software\\Microsoft\\Installer\\Assemblies\\Global";
} }
return RegCreateKeyW( root, path, hkey ); return RegCreateKeyW( root, path, hkey );
} }
@ -645,7 +597,7 @@ UINT ACTION_MsiPublishAssemblies( MSIPACKAGE *package )
MSICOMPONENT *comp; MSICOMPONENT *comp;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szMsiPublishAssemblies); return msi_schedule_action(package, SCRIPT_INSTALL, L"MsiPublishAssemblies");
LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
{ {
@ -718,7 +670,7 @@ UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
MSICOMPONENT *comp; MSICOMPONENT *comp;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szMsiUnpublishAssemblies); return msi_schedule_action(package, SCRIPT_INSTALL, L"MsiUnpublishAssemblies");
LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry) LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
{ {

View file

@ -95,8 +95,7 @@ HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
hr = LoadRegTypeLib(&LIBID_WindowsInstaller, 1, 0, LOCALE_NEUTRAL, &lib); hr = LoadRegTypeLib(&LIBID_WindowsInstaller, 1, 0, LOCALE_NEUTRAL, &lib);
if (FAILED(hr)) { if (FAILED(hr)) {
static const WCHAR msiserverW[] = {'m','s','i','s','e','r','v','e','r','.','t','l','b',0}; hr = LoadTypeLib(L"msiserver.tlb", &lib);
hr = LoadTypeLib(msiserverW, &lib);
if (FAILED(hr)) { if (FAILED(hr)) {
ERR("Could not load msiserver.tlb\n"); ERR("Could not load msiserver.tlb\n");
return hr; return hr;
@ -376,8 +375,6 @@ static HRESULT WINAPI AutomationObject_Invoke(
else if (pExcepInfo && else if (pExcepInfo &&
(hr == DISP_E_PARAMNOTFOUND || (hr == DISP_E_PARAMNOTFOUND ||
hr == DISP_E_EXCEPTION)) { hr == DISP_E_EXCEPTION)) {
static const WCHAR szComma[] = { ',',0 };
static const WCHAR szExceptionSource[] = {'M','s','i',' ','A','P','I',' ','E','r','r','o','r',0};
WCHAR szExceptionDescription[MAX_PATH]; WCHAR szExceptionDescription[MAX_PATH];
BSTR bstrParamNames[MAX_FUNC_PARAMS]; BSTR bstrParamNames[MAX_FUNC_PARAMS];
unsigned namesNo, i; unsigned namesNo, i;
@ -395,7 +392,7 @@ static HRESULT WINAPI AutomationObject_Invoke(
{ {
if (bFirst) bFirst = FALSE; if (bFirst) bFirst = FALSE;
else { else {
lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], szComma); lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], L",");
} }
lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], bstrParamNames[i]); lstrcpyW(&szExceptionDescription[lstrlenW(szExceptionDescription)], bstrParamNames[i]);
SysFreeString(bstrParamNames[i]); SysFreeString(bstrParamNames[i]);
@ -403,7 +400,7 @@ static HRESULT WINAPI AutomationObject_Invoke(
memset(pExcepInfo, 0, sizeof(EXCEPINFO)); memset(pExcepInfo, 0, sizeof(EXCEPINFO));
pExcepInfo->wCode = 1000; pExcepInfo->wCode = 1000;
pExcepInfo->bstrSource = SysAllocString(szExceptionSource); pExcepInfo->bstrSource = SysAllocString(L"Msi API Error");
pExcepInfo->bstrDescription = SysAllocString(szExceptionDescription); pExcepInfo->bstrDescription = SysAllocString(szExceptionDescription);
hr = DISP_E_EXCEPTION; hr = DISP_E_EXCEPTION;
} }
@ -1599,8 +1596,6 @@ static HRESULT session_invoke(
* registry value type. Used by Installer::RegistryValue. */ * registry value type. Used by Installer::RegistryValue. */
static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYTE lpData, DWORD dwSize) static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYTE lpData, DWORD dwSize)
{ {
static const WCHAR szREG_BINARY[] = { '(','R','E','G','_','B','I','N','A','R','Y',')',0 };
static const WCHAR szREG_[] = { '(','R','E','G','_','?','?',')',0 };
WCHAR *szString = (WCHAR *)lpData; WCHAR *szString = (WCHAR *)lpData;
LPWSTR szNewString = NULL; LPWSTR szNewString = NULL;
DWORD dwNewSize = 0; DWORD dwNewSize = 0;
@ -1642,12 +1637,12 @@ static void variant_from_registry_value(VARIANT *pVarResult, DWORD dwType, LPBYT
case REG_QWORD: case REG_QWORD:
V_VT(pVarResult) = VT_BSTR; V_VT(pVarResult) = VT_BSTR;
V_BSTR(pVarResult) = SysAllocString(szREG_); /* Weird string, don't know why native returns it */ V_BSTR(pVarResult) = SysAllocString(L"(REG_\?\?)"); /* Weird string, don't know why native returns it */
break; break;
case REG_BINARY: case REG_BINARY:
V_VT(pVarResult) = VT_BSTR; V_VT(pVarResult) = VT_BSTR;
V_BSTR(pVarResult) = SysAllocString(szREG_BINARY); V_BSTR(pVarResult) = SysAllocString(L"(REG_BINARY)");
break; break;
case REG_NONE: case REG_NONE:
@ -1950,9 +1945,6 @@ static HRESULT InstallerImpl_Version(WORD wFlags,
DLLVERSIONINFO verinfo; DLLVERSIONINFO verinfo;
WCHAR version[MAX_PATH]; WCHAR version[MAX_PATH];
static const WCHAR format[] = {
'%','d','.','%','d','.','%','d','.','%','d',0};
if (!(wFlags & DISPATCH_PROPERTYGET)) if (!(wFlags & DISPATCH_PROPERTYGET))
return DISP_E_MEMBERNOTFOUND; return DISP_E_MEMBERNOTFOUND;
@ -1961,7 +1953,7 @@ static HRESULT InstallerImpl_Version(WORD wFlags,
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
swprintf(version, ARRAY_SIZE(version), format, verinfo.dwMajorVersion, verinfo.dwMinorVersion, swprintf(version, ARRAY_SIZE(version), L"%d.%d.%d.%d", verinfo.dwMajorVersion, verinfo.dwMinorVersion,
verinfo.dwBuildNumber, verinfo.dwPlatformID); verinfo.dwBuildNumber, verinfo.dwPlatformID);
V_VT(pVarResult) = VT_BSTR; V_VT(pVarResult) = VT_BSTR;

View file

@ -145,7 +145,7 @@ static void value_free( struct value val )
%% %%
condition: condition:
expression expression
{ {
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
cond->result = $1; cond->result = $1;
@ -158,7 +158,7 @@ condition:
; ;
expression: expression:
boolean_term boolean_term
{ {
$$ = $1; $$ = $1;
} }
@ -319,7 +319,7 @@ value:
{ {
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
if(MSI_GetComponentStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS) if(MSI_GetComponentStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS)
{ {
$$.type = VALUE_LITERAL; $$.type = VALUE_LITERAL;
@ -336,7 +336,7 @@ value:
{ {
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
if(MSI_GetComponentStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS) if(MSI_GetComponentStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS)
{ {
$$.type = VALUE_LITERAL; $$.type = VALUE_LITERAL;
@ -353,7 +353,7 @@ value:
{ {
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install, action; INSTALLSTATE install, action;
if (MSI_GetFeatureStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS) if (MSI_GetFeatureStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS)
{ {
$$.type = VALUE_LITERAL; $$.type = VALUE_LITERAL;
@ -370,7 +370,7 @@ value:
{ {
COND_input* cond = (COND_input*) info; COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN; INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
if(MSI_GetFeatureStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS) if(MSI_GetFeatureStateW(cond->package, $2, &install, &action ) != ERROR_SUCCESS)
{ {
$$.type = VALUE_LITERAL; $$.type = VALUE_LITERAL;
@ -502,8 +502,8 @@ static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert )
return compare_substring( a, operator, b ); return compare_substring( a, operator, b );
/* null and empty string are equivalent */ /* null and empty string are equivalent */
if (!a) a = szEmpty; if (!a) a = L"";
if (!b) b = szEmpty; if (!b) b = L"";
if (convert && str_is_number(a) && str_is_number(b)) if (convert && str_is_number(a) && str_is_number(b))
return compare_int( wcstol(a, NULL, 10), operator, wcstol(b, NULL, 10) ); return compare_int( wcstol(a, NULL, 10), operator, wcstol(b, NULL, 10) );
@ -582,7 +582,7 @@ static INT compare_int( INT a, INT operator, INT b )
static int COND_IsIdent( WCHAR x ) static int COND_IsIdent( WCHAR x )
{ {
return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' )
|| ( x == '#' ) || (x == '.') ); || ( x == '#' ) || (x == '.') );
} }
@ -592,24 +592,24 @@ static int COND_GetOperator( COND_input *cond )
const WCHAR str[4]; const WCHAR str[4];
int id; int id;
} table[] = { } table[] = {
{ {'~','<','=',0}, COND_ILE }, { L"~<=", COND_ILE },
{ {'~','>','<',0}, COND_ISS }, { L"~><", COND_ISS },
{ {'~','>','>',0}, COND_IRHS }, { L"~>>", COND_IRHS },
{ {'~','<','>',0}, COND_INE }, { L"~<>", COND_INE },
{ {'~','>','=',0}, COND_IGE }, { L"~>=", COND_IGE },
{ {'~','<','<',0}, COND_ILHS }, { L"~<<", COND_ILHS },
{ {'~','=',0}, COND_IEQ }, { L"~=", COND_IEQ },
{ {'~','<',0}, COND_ILT }, { L"~<", COND_ILT },
{ {'~','>',0}, COND_IGT }, { L"~>", COND_IGT },
{ {'>','=',0}, COND_GE }, { L">=", COND_GE },
{ {'>','<',0}, COND_SS }, { L"><", COND_SS },
{ {'<','<',0}, COND_LHS }, { L"<<", COND_LHS },
{ {'<','>',0}, COND_NE }, { L"<>", COND_NE },
{ {'<','=',0}, COND_LE }, { L"<=", COND_LE },
{ {'>','>',0}, COND_RHS }, { L">>", COND_RHS },
{ {'>',0}, COND_GT }, { L">", COND_GT },
{ {'<',0}, COND_LT }, { L"<", COND_LT },
{ {0}, 0 } { L"", 0 }
}; };
LPCWSTR p = &cond->str[cond->n]; LPCWSTR p = &cond->str[cond->n];
int i = 0, len; int i = 0, len;
@ -673,31 +673,24 @@ static int COND_GetOne( struct cond_str *str, COND_input *cond )
} }
else if( COND_IsAlpha( ch ) ) else if( COND_IsAlpha( ch ) )
{ {
static const WCHAR szNot[] = {'N','O','T',0};
static const WCHAR szAnd[] = {'A','N','D',0};
static const WCHAR szXor[] = {'X','O','R',0};
static const WCHAR szEqv[] = {'E','Q','V',0};
static const WCHAR szImp[] = {'I','M','P',0};
static const WCHAR szOr[] = {'O','R',0};
while( COND_IsIdent( str->data[len] ) ) while( COND_IsIdent( str->data[len] ) )
len++; len++;
rc = COND_IDENT; rc = COND_IDENT;
if ( len == 3 ) if ( len == 3 )
{ {
if ( !wcsnicmp( str->data, szNot, len ) ) if ( !wcsnicmp( str->data, L"NOT", len ) )
rc = COND_NOT; rc = COND_NOT;
else if( !wcsnicmp( str->data, szAnd, len ) ) else if( !wcsnicmp( str->data, L"AND", len ) )
rc = COND_AND; rc = COND_AND;
else if( !wcsnicmp( str->data, szXor, len ) ) else if( !wcsnicmp( str->data, L"XOR", len ) )
rc = COND_XOR; rc = COND_XOR;
else if( !wcsnicmp( str->data, szEqv, len ) ) else if( !wcsnicmp( str->data, L"EQV", len ) )
rc = COND_EQV; rc = COND_EQV;
else if( !wcsnicmp( str->data, szImp, len ) ) else if( !wcsnicmp( str->data, L"IMP", len ) )
rc = COND_IMP; rc = COND_IMP;
} }
else if( (len == 2) && !wcsnicmp( str->data, szOr, len ) ) else if( (len == 2) && !wcsnicmp( str->data, L"OR", len ) )
rc = COND_OR; rc = COND_OR;
} }
else if( COND_IsNumber( ch ) ) else if( COND_IsNumber( ch ) )
@ -726,7 +719,7 @@ static int cond_lex( void *COND_lval, COND_input *cond )
do { do {
rc = COND_GetOne( str, cond ); rc = COND_GetOne( str, cond );
} while (rc == COND_SPACE); } while (rc == COND_SPACE);
return rc; return rc;
} }

View file

@ -182,37 +182,32 @@ static LPWSTR msi_get_deferred_action(LPCWSTR action, LPCWSTR actiondata,
LPWSTR deferred; LPWSTR deferred;
DWORD len; DWORD len;
static const WCHAR format[] = {
'[','%','s','<','=','>','%','s','<','=','>','%','s',']','%','s',0
};
if (!actiondata) if (!actiondata)
return strdupW(action); return strdupW(action);
len = lstrlenW(action) + lstrlenW(actiondata) + len = lstrlenW(action) + lstrlenW(actiondata) +
lstrlenW(usersid) + lstrlenW(prodcode) + lstrlenW(usersid) + lstrlenW(prodcode) +
lstrlenW(format) - 7; lstrlenW(L"[%s<=>%s<=>%s]%s") - 7;
deferred = msi_alloc(len * sizeof(WCHAR)); deferred = msi_alloc(len * sizeof(WCHAR));
swprintf(deferred, len, format, actiondata, usersid, prodcode, action); swprintf(deferred, len, L"[%s<=>%s<=>%s]%s", actiondata, usersid, prodcode, action);
return deferred; return deferred;
} }
static void set_deferred_action_props( MSIPACKAGE *package, const WCHAR *deferred_data ) static void set_deferred_action_props( MSIPACKAGE *package, const WCHAR *deferred_data )
{ {
static const WCHAR sep[] = {'<','=','>',0};
const WCHAR *end, *beg = deferred_data + 1; const WCHAR *end, *beg = deferred_data + 1;
end = wcsstr(beg, sep); end = wcsstr(beg, L"<=>");
msi_set_property( package->db, szCustomActionData, beg, end - beg ); msi_set_property( package->db, L"CustomActionData", beg, end - beg );
beg = end + 3; beg = end + 3;
end = wcsstr(beg, sep); end = wcsstr(beg, L"<=>");
msi_set_property( package->db, szUserSID, beg, end - beg ); msi_set_property( package->db, L"UserSID", beg, end - beg );
beg = end + 3; beg = end + 3;
end = wcschr(beg, ']'); end = wcschr(beg, ']');
msi_set_property( package->db, szProductCode, beg, end - beg ); msi_set_property( package->db, L"ProductCode", beg, end - beg );
} }
WCHAR *msi_create_temp_file( MSIDATABASE *db ) WCHAR *msi_create_temp_file( MSIDATABASE *db )
@ -224,7 +219,7 @@ WCHAR *msi_create_temp_file( MSIDATABASE *db )
WCHAR tmp[MAX_PATH]; WCHAR tmp[MAX_PATH];
UINT len = ARRAY_SIZE( tmp ); UINT len = ARRAY_SIZE( tmp );
if (msi_get_property( db, szTempFolder, tmp, &len ) || if (msi_get_property( db, L"TempFolder", tmp, &len ) ||
GetFileAttributesW( tmp ) != FILE_ATTRIBUTE_DIRECTORY) GetFileAttributesW( tmp ) != FILE_ATTRIBUTE_DIRECTORY)
{ {
GetTempPathW( MAX_PATH, tmp ); GetTempPathW( MAX_PATH, tmp );
@ -234,7 +229,7 @@ WCHAR *msi_create_temp_file( MSIDATABASE *db )
if ((ret = msi_alloc( (lstrlenW( db->tempfolder ) + 20) * sizeof(WCHAR) ))) if ((ret = msi_alloc( (lstrlenW( db->tempfolder ) + 20) * sizeof(WCHAR) )))
{ {
if (!GetTempFileNameW( db->tempfolder, szMsi, 0, ret )) if (!GetTempFileNameW( db->tempfolder, L"msi", 0, ret ))
{ {
msi_free( ret ); msi_free( ret );
return NULL; return NULL;
@ -246,10 +241,6 @@ WCHAR *msi_create_temp_file( MSIDATABASE *db )
static MSIBINARY *create_temp_binary(MSIPACKAGE *package, LPCWSTR source) static MSIBINARY *create_temp_binary(MSIPACKAGE *package, LPCWSTR source)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ',
'`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0};
MSIRECORD *row; MSIRECORD *row;
MSIBINARY *binary = NULL; MSIBINARY *binary = NULL;
HANDLE file; HANDLE file;
@ -260,7 +251,7 @@ static MSIBINARY *create_temp_binary(MSIPACKAGE *package, LPCWSTR source)
if (!(tmpfile = msi_create_temp_file( package->db ))) return NULL; if (!(tmpfile = msi_create_temp_file( package->db ))) return NULL;
if (!(row = MSI_QueryGetRecord( package->db, query, source ))) goto error; if (!(row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `Binary` WHERE `Name` = '%s'", source ))) goto error;
if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) ))) goto error; if (!(binary = msi_alloc_zero( sizeof(MSIBINARY) ))) goto error;
file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); file = CreateFileW( tmpfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
@ -480,9 +471,6 @@ static void handle_msi_break(LPCSTR target)
DebugBreak(); DebugBreak();
} }
static WCHAR ncalrpcW[] = {'n','c','a','l','r','p','c',0};
static WCHAR endpoint_fmtW[] = {'m','s','i','%','x',0};
#if defined __i386__ && defined _MSC_VER #if defined __i386__ && defined _MSC_VER
__declspec(naked) UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, MSIHANDLE hinst) __declspec(naked) UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, MSIHANDLE hinst)
{ {
@ -539,8 +527,8 @@ UINT CDECL __wine_msi_call_dll_function(DWORD client_pid, const GUID *guid)
{ {
WCHAR endpoint[12]; WCHAR endpoint[12];
swprintf(endpoint, ARRAY_SIZE(endpoint), endpoint_fmtW, client_pid); swprintf(endpoint, ARRAY_SIZE(endpoint), L"msi%x", client_pid);
status = RpcStringBindingComposeW(NULL, ncalrpcW, NULL, endpoint, NULL, &binding_str); status = RpcStringBindingComposeW(NULL, (WCHAR *)L"ncalrpc", NULL, endpoint, NULL, &binding_str);
if (status != RPC_S_OK) if (status != RPC_S_OK)
{ {
ERR("RpcStringBindingCompose failed: %#x\n", status); ERR("RpcStringBindingCompose failed: %#x\n", status);
@ -609,10 +597,6 @@ UINT CDECL __wine_msi_call_dll_function(DWORD client_pid, const GUID *guid)
static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch) static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch)
{ {
static const WCHAR pipe_name[] = {'\\','\\','.','\\','p','i','p','e','\\','m','s','i','c','a','_','%','x','_','%','d',0};
static const WCHAR msiexecW[] = {'\\','m','s','i','e','x','e','c','.','e','x','e',0};
static const WCHAR argsW[] = {'%','s',' ','-','E','m','b','e','d','d','i','n','g',' ','%','d',0};
WCHAR path[MAX_PATH], cmdline[MAX_PATH + 23]; WCHAR path[MAX_PATH], cmdline[MAX_PATH + 23];
PROCESS_INFORMATION pi = {0}; PROCESS_INFORMATION pi = {0};
STARTUPINFOW si = {0}; STARTUPINFOW si = {0};
@ -625,7 +609,7 @@ static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch)
(arch == SCS_64BIT_BINARY && package->custom_server_64_process)) (arch == SCS_64BIT_BINARY && package->custom_server_64_process))
return ERROR_SUCCESS; return ERROR_SUCCESS;
swprintf(buffer, ARRAY_SIZE(buffer), pipe_name, swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d",
GetCurrentProcessId(), arch == SCS_32BIT_BINARY ? 32 : 64); GetCurrentProcessId(), arch == SCS_32BIT_BINARY ? 32 : 64);
pipe = CreateNamedPipeW(buffer, PIPE_ACCESS_DUPLEX, 0, 1, sizeof(DWORD64), pipe = CreateNamedPipeW(buffer, PIPE_ACCESS_DUPLEX, 0, 1, sizeof(DWORD64),
sizeof(GUID), 0, NULL); sizeof(GUID), 0, NULL);
@ -636,11 +620,11 @@ static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch)
wow64 = FALSE; wow64 = FALSE;
if ((sizeof(void *) == 8 || wow64) && arch == SCS_32BIT_BINARY) if ((sizeof(void *) == 8 || wow64) && arch == SCS_32BIT_BINARY)
GetSystemWow64DirectoryW(path, MAX_PATH - ARRAY_SIZE(msiexecW)); GetSystemWow64DirectoryW(path, MAX_PATH - ARRAY_SIZE(L"\\msiexec.exe"));
else else
GetSystemDirectoryW(path, MAX_PATH - ARRAY_SIZE(msiexecW)); GetSystemDirectoryW(path, MAX_PATH - ARRAY_SIZE(L"\\msiexec.exe"));
lstrcatW(path, msiexecW); lstrcatW(path, L"\\msiexec.exe");
swprintf(cmdline, ARRAY_SIZE(cmdline), argsW, path, GetCurrentProcessId()); swprintf(cmdline, ARRAY_SIZE(cmdline), L"%s -Embedding %d", path, GetCurrentProcessId());
if (wow64 && arch == SCS_64BIT_BINARY) if (wow64 && arch == SCS_64BIT_BINARY)
{ {
@ -765,8 +749,8 @@ static msi_custom_action_info *do_msidbCustomActionTypeDll(
{ {
WCHAR endpoint[12]; WCHAR endpoint[12];
swprintf(endpoint, ARRAY_SIZE(endpoint), endpoint_fmtW, GetCurrentProcessId()); swprintf(endpoint, ARRAY_SIZE(endpoint), L"msi%x", GetCurrentProcessId());
status = RpcServerUseProtseqEpW(ncalrpcW, RPC_C_PROTSEQ_MAX_REQS_DEFAULT, status = RpcServerUseProtseqEpW((WCHAR *)L"ncalrpc", RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
endpoint, NULL); endpoint, NULL);
if (status != RPC_S_OK) if (status != RPC_S_OK)
{ {
@ -818,7 +802,6 @@ static UINT HANDLE_CustomType1( MSIPACKAGE *package, const WCHAR *source, const
static HANDLE execute_command( const WCHAR *app, WCHAR *arg, const WCHAR *dir ) static HANDLE execute_command( const WCHAR *app, WCHAR *arg, const WCHAR *dir )
{ {
static const WCHAR dotexeW[] = {'.','e','x','e',0};
STARTUPINFOW si; STARTUPINFOW si;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
WCHAR *exe = NULL, *cmd = NULL, *p; WCHAR *exe = NULL, *cmd = NULL, *p;
@ -830,12 +813,12 @@ static HANDLE execute_command( const WCHAR *app, WCHAR *arg, const WCHAR *dir )
DWORD len_exe; DWORD len_exe;
if (!(exe = msi_alloc( MAX_PATH * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE; if (!(exe = msi_alloc( MAX_PATH * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE;
len_exe = SearchPathW( NULL, app, dotexeW, MAX_PATH, exe, NULL ); len_exe = SearchPathW( NULL, app, L".exe", MAX_PATH, exe, NULL );
if (len_exe >= MAX_PATH) if (len_exe >= MAX_PATH)
{ {
msi_free( exe ); msi_free( exe );
if (!(exe = msi_alloc( len_exe * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE; if (!(exe = msi_alloc( len_exe * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE;
len_exe = SearchPathW( NULL, app, dotexeW, len_exe, exe, NULL ); len_exe = SearchPathW( NULL, app, L".exe", len_exe, exe, NULL );
} }
if (!len_exe) if (!len_exe)
{ {
@ -897,7 +880,7 @@ static UINT HANDLE_CustomType2( MSIPACKAGE *package, const WCHAR *source, const
deformat_string( package, target, &arg ); deformat_string( package, target, &arg );
TRACE("exe %s arg %s\n", debugstr_w(binary->tmpfile), debugstr_w(arg)); TRACE("exe %s arg %s\n", debugstr_w(binary->tmpfile), debugstr_w(arg));
handle = execute_command( binary->tmpfile, arg, szCRoot ); handle = execute_command( binary->tmpfile, arg, L"C:\\" );
msi_free( arg ); msi_free( arg );
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS; if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
return wait_process_handle( package, type, handle, action ); return wait_process_handle( package, type, handle, action );
@ -934,7 +917,7 @@ static UINT HANDLE_CustomType18( MSIPACKAGE *package, const WCHAR *source, const
deformat_string( package, target, &arg ); deformat_string( package, target, &arg );
TRACE("exe %s arg %s\n", debugstr_w(file->TargetPath), debugstr_w(arg)); TRACE("exe %s arg %s\n", debugstr_w(file->TargetPath), debugstr_w(arg));
handle = execute_command( file->TargetPath, arg, szCRoot ); handle = execute_command( file->TargetPath, arg, L"C:\\" );
msi_free( arg ); msi_free( arg );
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS; if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
return wait_process_handle( package, type, handle, action ); return wait_process_handle( package, type, handle, action );
@ -943,19 +926,13 @@ static UINT HANDLE_CustomType18( MSIPACKAGE *package, const WCHAR *source, const
static UINT HANDLE_CustomType19( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, static UINT HANDLE_CustomType19( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
INT type, const WCHAR *action ) INT type, const WCHAR *action )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
'F','R','O','M',' ','`','E','r','r','o','r','`',' ',
'W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ',
'%','s',0
};
MSIRECORD *row = 0; MSIRECORD *row = 0;
LPWSTR deformated = NULL; LPWSTR deformated = NULL;
deformat_string( package, target, &deformated ); deformat_string( package, target, &deformated );
/* first try treat the error as a number */ /* first try treat the error as a number */
row = MSI_QueryGetRecord( package->db, query, deformated ); row = MSI_QueryGetRecord( package->db, L"SELECT `Message` FROM `Error` WHERE `Error` = '%s'", deformated );
if( row ) if( row )
{ {
LPCWSTR error = MSI_RecordGetString( row, 1 ); LPCWSTR error = MSI_RecordGetString( row, 1 );
@ -995,7 +972,7 @@ static UINT HANDLE_CustomType23( MSIPACKAGE *package, const WCHAR *source, const
UINT len_dir, len_source = lstrlenW( source ); UINT len_dir, len_source = lstrlenW( source );
HANDLE handle; HANDLE handle;
if (!(dir = msi_dup_property( package->db, szOriginalDatabase ))) return ERROR_OUTOFMEMORY; if (!(dir = msi_dup_property( package->db, L"OriginalDatabase" ))) return ERROR_OUTOFMEMORY;
if (!(p = wcsrchr( dir, '\\' )) && !(p = wcsrchr( dir, '/' ))) if (!(p = wcsrchr( dir, '\\' )) && !(p = wcsrchr( dir, '/' )))
{ {
msi_free( dir ); msi_free( dir );
@ -1112,7 +1089,7 @@ static UINT HANDLE_CustomType50( MSIPACKAGE *package, const WCHAR *source, const
deformat_string( package, target, &arg ); deformat_string( package, target, &arg );
TRACE("exe %s arg %s\n", debugstr_w(exe), debugstr_w(arg)); TRACE("exe %s arg %s\n", debugstr_w(exe), debugstr_w(arg));
handle = execute_command( exe, arg, szCRoot ); handle = execute_command( exe, arg, L"C:\\" );
msi_free( exe ); msi_free( exe );
msi_free( arg ); msi_free( arg );
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS; if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
@ -1230,10 +1207,6 @@ static UINT HANDLE_CustomType37_38( MSIPACKAGE *package, const WCHAR *source, co
static UINT HANDLE_CustomType5_6( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, static UINT HANDLE_CustomType5_6( MSIPACKAGE *package, const WCHAR *source, const WCHAR *target,
INT type, const WCHAR *action ) INT type, const WCHAR *action )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','B','i' ,'n','a','r','y','`',' ','W','H','E','R','E',' ',
'`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0};
MSIRECORD *row = NULL; MSIRECORD *row = NULL;
msi_custom_action_info *info; msi_custom_action_info *info;
CHAR *buffer = NULL; CHAR *buffer = NULL;
@ -1243,7 +1216,7 @@ static UINT HANDLE_CustomType5_6( MSIPACKAGE *package, const WCHAR *source, cons
TRACE("%s %s\n", debugstr_w(source), debugstr_w(target)); TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
row = MSI_QueryGetRecord(package->db, query, source); row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Binary` WHERE `Name` = '%s'", source);
if (!row) if (!row)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
@ -1375,8 +1348,8 @@ static BOOL action_type_matches_script( UINT type, UINT script )
static UINT defer_custom_action( MSIPACKAGE *package, const WCHAR *action, UINT type ) static UINT defer_custom_action( MSIPACKAGE *package, const WCHAR *action, UINT type )
{ {
WCHAR *actiondata = msi_dup_property( package->db, action ); WCHAR *actiondata = msi_dup_property( package->db, action );
WCHAR *usersid = msi_dup_property( package->db, szUserSID ); WCHAR *usersid = msi_dup_property( package->db, L"UserSID" );
WCHAR *prodcode = msi_dup_property( package->db, szProductCode ); WCHAR *prodcode = msi_dup_property( package->db, L"ProductCode" );
WCHAR *deferred = msi_get_deferred_action( action, actiondata, usersid, prodcode ); WCHAR *deferred = msi_get_deferred_action( action, actiondata, usersid, prodcode );
if (!deferred) if (!deferred)
@ -1411,10 +1384,6 @@ static UINT defer_custom_action( MSIPACKAGE *package, const WCHAR *action, UINT
UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action) UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','C','u','s','t','o','m','A','c','t','i','o','n','`',' ','W','H','E','R','E',' ',
'`','A','c','t','i' ,'o','n','`',' ','=',' ','\'','%','s','\'',0};
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
MSIRECORD *row; MSIRECORD *row;
UINT type; UINT type;
@ -1429,7 +1398,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action)
action = ptr + 1; action = ptr + 1;
} }
row = MSI_QueryGetRecord( package->db, query, action ); row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `CustomAction` WHERE `Action` = '%s'", action );
if (!row) if (!row)
return ERROR_FUNCTION_NOT_CALLED; return ERROR_FUNCTION_NOT_CALLED;
@ -1470,9 +1439,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action)
if (deferred_data) if (deferred_data)
set_deferred_action_props(package, deferred_data); set_deferred_action_props(package, deferred_data);
else if (actiondata) else if (actiondata)
msi_set_property( package->db, szCustomActionData, actiondata, -1 ); msi_set_property( package->db, L"CustomActionData", actiondata, -1 );
else else
msi_set_property( package->db, szCustomActionData, szEmpty, -1 ); msi_set_property( package->db, L"CustomActionData", L"", -1 );
msi_free(actiondata); msi_free(actiondata);
} }
@ -1537,7 +1506,7 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action)
if (!source) break; if (!source) break;
len = deformat_string( package, target, &deformated ); len = deformat_string( package, target, &deformated );
rc = msi_set_property( package->db, source, deformated, len ); rc = msi_set_property( package->db, source, deformated, len );
if (rc == ERROR_SUCCESS && !wcscmp( source, szSourceDir )) msi_reset_source_folders( package ); if (rc == ERROR_SUCCESS && !wcscmp( source, L"SourceDir" )) msi_reset_source_folders( package );
msi_free( deformated ); msi_free( deformated );
break; break;
case 53: /* JScript/VBScript text specified by a property value */ case 53: /* JScript/VBScript text specified by a property value */

View file

@ -103,7 +103,6 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
static HRESULT db_initialize( IStorage *stg, const GUID *clsid ) static HRESULT db_initialize( IStorage *stg, const GUID *clsid )
{ {
static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
HRESULT hr; HRESULT hr;
hr = IStorage_SetClass( stg, clsid ); hr = IStorage_SetClass( stg, clsid );
@ -114,7 +113,7 @@ static HRESULT db_initialize( IStorage *stg, const GUID *clsid )
} }
/* create the _Tables stream */ /* create the _Tables stream */
hr = write_stream_data( stg, szTables, NULL, 0, TRUE ); hr = write_stream_data( stg, L"_Tables", NULL, 0, TRUE );
if (FAILED( hr )) if (FAILED( hr ))
{ {
WARN("failed to create _Tables stream 0x%08x\n", hr); WARN("failed to create _Tables stream 0x%08x\n", hr);
@ -257,7 +256,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
if (!wcschr( save_path, '\\' )) if (!wcschr( save_path, '\\' ))
{ {
GetCurrentDirectoryW( MAX_PATH, path ); GetCurrentDirectoryW( MAX_PATH, path );
lstrcatW( path, szBackSlash ); lstrcatW( path, L"\\" );
lstrcatW( path, save_path ); lstrcatW( path, save_path );
} }
else else
@ -452,14 +451,12 @@ static LPWSTR msi_build_createsql_prelude(LPWSTR table)
LPWSTR prelude; LPWSTR prelude;
DWORD size; DWORD size;
static const WCHAR create_fmt[] = {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','%','s','`',' ','(',' ',0}; size = ARRAY_SIZE(L"CREATE TABLE `%s` ( ") + lstrlenW(table) - 2;
size = ARRAY_SIZE(create_fmt) + lstrlenW(table) - 2;
prelude = msi_alloc(size * sizeof(WCHAR)); prelude = msi_alloc(size * sizeof(WCHAR));
if (!prelude) if (!prelude)
return NULL; return NULL;
swprintf(prelude, size, create_fmt, table); swprintf(prelude, size, L"CREATE TABLE `%s` ( ", table);
return prelude; return prelude;
} }
@ -471,15 +468,6 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
WCHAR expanded[128], *ptr; WCHAR expanded[128], *ptr;
WCHAR size[10], comma[2], extra[30]; WCHAR size[10], comma[2], extra[30];
static const WCHAR column_fmt[] = {'`','%','s','`',' ','%','s','%','s','%','s','%','s',' ',0};
static const WCHAR size_fmt[] = {'(','%','s',')',0};
static const WCHAR type_char[] = {'C','H','A','R',0};
static const WCHAR type_int[] = {'I','N','T',0};
static const WCHAR type_long[] = {'L','O','N','G',0};
static const WCHAR type_object[] = {'O','B','J','E','C','T',0};
static const WCHAR type_notnull[] = {' ','N','O','T',' ','N','U','L','L',0};
static const WCHAR localizable[] = {' ','L','O','C','A','L','I','Z','A','B','L','E',0};
columns = msi_alloc_zero(sql_size * sizeof(WCHAR)); columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
if (!columns) if (!columns)
return NULL; return NULL;
@ -501,28 +489,28 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
switch (types[i][0]) switch (types[i][0])
{ {
case 'l': case 'l':
lstrcpyW(extra, type_notnull); lstrcpyW(extra, L" NOT NULL");
/* fall through */ /* fall through */
case 'L': case 'L':
lstrcatW(extra, localizable); lstrcatW(extra, L" LOCALIZABLE");
type = type_char; type = L"CHAR";
swprintf(size, ARRAY_SIZE(size), size_fmt, ptr); swprintf(size, ARRAY_SIZE(size), L"(%s)", ptr);
break; break;
case 's': case 's':
lstrcpyW(extra, type_notnull); lstrcpyW(extra, L" NOT NULL");
/* fall through */ /* fall through */
case 'S': case 'S':
type = type_char; type = L"CHAR";
swprintf(size, ARRAY_SIZE(size), size_fmt, ptr); swprintf(size, ARRAY_SIZE(size), L"(%s)", ptr);
break; break;
case 'i': case 'i':
lstrcpyW(extra, type_notnull); lstrcpyW(extra, L" NOT NULL");
/* fall through */ /* fall through */
case 'I': case 'I':
if (len <= 2) if (len <= 2)
type = type_int; type = L"INT";
else if (len == 4) else if (len == 4)
type = type_long; type = L"LONG";
else else
{ {
WARN("invalid int width %u\n", len); WARN("invalid int width %u\n", len);
@ -531,10 +519,10 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
} }
break; break;
case 'v': case 'v':
lstrcpyW(extra, type_notnull); lstrcpyW(extra, L" NOT NULL");
/* fall through */ /* fall through */
case 'V': case 'V':
type = type_object; type = L"OBJECT";
break; break;
default: default:
ERR("Unknown type: %c\n", types[i][0]); ERR("Unknown type: %c\n", types[i][0]);
@ -542,7 +530,7 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
return NULL; return NULL;
} }
swprintf(expanded, ARRAY_SIZE(expanded), column_fmt, columns_data[i], type, size, extra, comma); swprintf(expanded, ARRAY_SIZE(expanded), L"`%s` %s%s%s%s ", columns_data[i], type, size, extra, comma);
sql_size += lstrlenW(expanded); sql_size += lstrlenW(expanded);
p = msi_realloc(columns, sql_size * sizeof(WCHAR)); p = msi_realloc(columns, sql_size * sizeof(WCHAR));
@ -564,11 +552,8 @@ static LPWSTR msi_build_createsql_postlude(LPWSTR *primary_keys, DWORD num_keys)
LPWSTR postlude, keys, ptr; LPWSTR postlude, keys, ptr;
DWORD size, i; DWORD size, i;
static const WCHAR key_fmt[] = {'`','%','s','`',',',' ',0};
static const WCHAR postlude_fmt[] = {'P','R','I','M','A','R','Y',' ','K','E','Y',' ','%','s',')',0};
for (i = 0, size = 1; i < num_keys; i++) for (i = 0, size = 1; i < num_keys; i++)
size += lstrlenW(key_fmt) + lstrlenW(primary_keys[i]) - 2; size += lstrlenW(L"`%s`, ") + lstrlenW(primary_keys[i]) - 2;
keys = msi_alloc(size * sizeof(WCHAR)); keys = msi_alloc(size * sizeof(WCHAR));
if (!keys) if (!keys)
@ -576,18 +561,18 @@ static LPWSTR msi_build_createsql_postlude(LPWSTR *primary_keys, DWORD num_keys)
for (i = 0, ptr = keys; i < num_keys; i++) for (i = 0, ptr = keys; i < num_keys; i++)
{ {
ptr += swprintf(ptr, size - (ptr - keys), key_fmt, primary_keys[i]); ptr += swprintf(ptr, size - (ptr - keys), L"`%s`, ", primary_keys[i]);
} }
/* remove final ', ' */ /* remove final ', ' */
*(ptr - 2) = '\0'; *(ptr - 2) = '\0';
size = lstrlenW(postlude_fmt) + size - 1; size = lstrlenW(L"PRIMARY KEY %s)") + size - 1;
postlude = msi_alloc(size * sizeof(WCHAR)); postlude = msi_alloc(size * sizeof(WCHAR));
if (!postlude) if (!postlude)
goto done; goto done;
swprintf(postlude, size, postlude_fmt, keys); swprintf(postlude, size, L"PRIMARY KEY %s)", keys);
done: done:
msi_free(keys); msi_free(keys);
@ -712,12 +697,7 @@ static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *t
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
static const WCHAR select[] = { r = MSI_OpenQuery(db, &view, L"SELECT * FROM `%s`", labels[0]);
'S','E','L','E','C','T',' ','*',' ',
'F','R','O','M',' ','`','%','s','`',0
};
r = MSI_OpenQuery(db, &view, select, labels[0]);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
@ -753,31 +733,21 @@ done:
static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file) static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
{ {
UINT r; UINT r;
DWORD len, i; DWORD len, i, num_labels, num_types, num_columns, num_records = 0;
DWORD num_labels, num_types; WCHAR **columns, **types, **labels, *path, *ptr, *data, ***records = NULL, ***temp_records;
DWORD num_columns, num_records = 0;
LPWSTR *columns, *types, *labels;
LPWSTR path, ptr, data;
LPWSTR **records = NULL;
LPWSTR **temp_records;
static const WCHAR suminfo[] =
{'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
static const WCHAR forcecodepage[] =
{'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0};
TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) ); TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
if( folder == NULL || file == NULL ) if (!folder || !file)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
len = lstrlenW(folder) + lstrlenW(szBackSlash) + lstrlenW(file) + 1; len = lstrlenW(folder) + lstrlenW(L"\\") + lstrlenW(file) + 1;
path = msi_alloc( len * sizeof(WCHAR) ); path = msi_alloc( len * sizeof(WCHAR) );
if (!path) if (!path)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
lstrcpyW( path, folder ); lstrcpyW( path, folder );
lstrcatW( path, szBackSlash ); lstrcatW( path, L"\\" );
lstrcatW( path, file ); lstrcatW( path, file );
data = msi_read_text_archive( path, &len ); data = msi_read_text_archive( path, &len );
@ -793,7 +763,7 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
msi_parse_line( &ptr, &labels, &num_labels, &len ); msi_parse_line( &ptr, &labels, &num_labels, &len );
if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] && if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] &&
num_types == 2 && !wcscmp( types[1], forcecodepage )) num_types == 2 && !wcscmp( types[1], L"_ForceCodepage" ))
{ {
r = msi_set_string_table_codepage( db->strings, wcstol( types[0], NULL, 10 ) ); r = msi_set_string_table_codepage( db->strings, wcstol( types[0], NULL, 10 ) );
goto done; goto done;
@ -805,7 +775,7 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
goto done; goto done;
} }
records = msi_alloc(sizeof(LPWSTR *)); records = msi_alloc(sizeof(WCHAR **));
if (!records) if (!records)
{ {
r = ERROR_OUTOFMEMORY; r = ERROR_OUTOFMEMORY;
@ -818,7 +788,7 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
msi_parse_line( &ptr, &records[num_records], NULL, &len ); msi_parse_line( &ptr, &records[num_records], NULL, &len );
num_records++; num_records++;
temp_records = msi_realloc(records, (num_records + 1) * sizeof(LPWSTR *)); temp_records = msi_realloc(records, (num_records + 1) * sizeof(WCHAR **));
if (!temp_records) if (!temp_records)
{ {
r = ERROR_OUTOFMEMORY; r = ERROR_OUTOFMEMORY;
@ -827,7 +797,7 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
records = temp_records; records = temp_records;
} }
if (!wcscmp(labels[0], suminfo)) if (!wcscmp(labels[0], L"_SummaryInformation"))
{ {
r = msi_add_suminfo( db, records, num_records, num_columns ); r = msi_add_suminfo( db, records, num_records, num_columns );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
@ -862,7 +832,6 @@ done:
msi_free(records[i]); msi_free(records[i]);
msi_free(records); msi_free(records);
return r; return r;
} }
@ -957,7 +926,6 @@ static UINT msi_export_field( HANDLE handle, MSIRECORD *row, UINT field )
static UINT msi_export_stream( const WCHAR *folder, const WCHAR *table, MSIRECORD *row, UINT field, UINT start ) static UINT msi_export_stream( const WCHAR *folder, const WCHAR *table, MSIRECORD *row, UINT field, UINT start )
{ {
static const WCHAR fmt[] = {'%','s','\\','%','s',0};
WCHAR stream[MAX_STREAM_NAME_LEN + 1], *path; WCHAR stream[MAX_STREAM_NAME_LEN + 1], *path;
DWORD sz, read_size, write_size; DWORD sz, read_size, write_size;
char buffer[1024]; char buffer[1024];
@ -969,11 +937,11 @@ static UINT msi_export_stream( const WCHAR *folder, const WCHAR *table, MSIRECOR
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
len = sz + lstrlenW( folder ) + lstrlenW( table ) + ARRAY_SIZE( fmt ) + 1; len = sz + lstrlenW( folder ) + lstrlenW( table ) + ARRAY_SIZE( L"%s\\%s" ) + 1;
if (!(path = msi_alloc( len * sizeof(WCHAR) ))) if (!(path = msi_alloc( len * sizeof(WCHAR) )))
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
len = swprintf( path, len, fmt, folder, table ); len = swprintf( path, len, L"%s\\%s", folder, table );
if (!CreateDirectoryW( path, NULL ) && GetLastError() != ERROR_ALREADY_EXISTS) if (!CreateDirectoryW( path, NULL ) && GetLastError() != ERROR_ALREADY_EXISTS)
{ {
msi_free( path ); msi_free( path );
@ -1078,22 +1046,16 @@ static UINT msi_export_summaryinformation( MSIDATABASE *db, HANDLE handle )
static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file ) static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file )
{ {
static const WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 };
static const WCHAR forcecodepage[] = {
'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0 };
static const WCHAR summaryinformation[] = {
'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0 };
MSIRECORD *rec = NULL; MSIRECORD *rec = NULL;
MSIQUERY *view = NULL; MSIQUERY *view = NULL;
LPWSTR filename; WCHAR *filename;
HANDLE handle; HANDLE handle;
UINT len, r; UINT len, r;
TRACE("%p %s %s %s\n", db, debugstr_w(table), TRACE("%p %s %s %s\n", db, debugstr_w(table),
debugstr_w(folder), debugstr_w(file) ); debugstr_w(folder), debugstr_w(file) );
if( folder == NULL || file == NULL ) if (!folder || !file)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
len = lstrlenW(folder) + lstrlenW(file) + 2; len = lstrlenW(folder) + lstrlenW(file) + 2;
@ -1102,7 +1064,7 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder,
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
lstrcpyW( filename, folder ); lstrcpyW( filename, folder );
lstrcatW( filename, szBackSlash ); lstrcatW( filename, L"\\" );
lstrcatW( filename, file ); lstrcatW( filename, file );
handle = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0, handle = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0,
@ -1111,20 +1073,20 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder,
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
if (!wcscmp( table, forcecodepage )) if (!wcscmp( table, L"_ForceCodepage" ))
{ {
UINT codepage = msi_get_string_table_codepage( db->strings ); UINT codepage = msi_get_string_table_codepage( db->strings );
r = msi_export_forcecodepage( handle, codepage ); r = msi_export_forcecodepage( handle, codepage );
goto done; goto done;
} }
if (!wcscmp( table, summaryinformation )) if (!wcscmp( table, L"_SummaryInformation" ))
{ {
r = msi_export_summaryinformation( db, handle ); r = msi_export_summaryinformation( db, handle );
goto done; goto done;
} }
r = MSI_OpenQuery( db, &view, query, table ); r = MSI_OpenQuery( db, &view, L"SELECT * FROM %s", table );
if (r == ERROR_SUCCESS) if (r == ERROR_SUCCESS)
{ {
struct row_export_info row_export_info = { handle, folder, table }; struct row_export_info row_export_info = { handle, folder, table };
@ -1424,20 +1386,19 @@ static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
if (MSI_RecordGetString(rec, i)) /* check record field is a string */ if (MSI_RecordGetString(rec, i)) /* check record field is a string */
{ {
/* quote string record fields */ /* quote string record fields */
static const WCHAR szQuote[] = {'\'', 0};
sz += 2; sz += 2;
val = msi_alloc(sz*sizeof(WCHAR)); val = msi_alloc(sz * sizeof(WCHAR));
if (!val) if (!val)
return NULL; return NULL;
lstrcpyW(val, szQuote); lstrcpyW(val, L"'");
r = MSI_RecordGetStringW(rec, i, val+1, &sz); r = MSI_RecordGetStringW(rec, i, val + 1, &sz);
lstrcpyW(val+1+sz, szQuote); lstrcpyW(val + 1 + sz, L"'");
} }
else else
{ {
/* do not quote integer record fields */ /* do not quote integer record fields */
val = msi_alloc(sz*sizeof(WCHAR)); val = msi_alloc(sz * sizeof(WCHAR));
if (!val) if (!val)
return NULL; return NULL;
@ -1463,14 +1424,6 @@ static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view,
MSIRECORD *keys; MSIRECORD *keys;
UINT r, i, count; UINT r, i, count;
static const WCHAR keyset[] = {
'`','%','s','`',' ','=',' ','%','s',' ','A','N','D',' ',0};
static const WCHAR lastkeyset[] = {
'`','%','s','`',' ','=',' ','%','s',' ',0};
static const WCHAR fmt[] = {'S','E','L','E','C','T',' ','*',' ',
'F','R','O','M',' ','`','%','s','`',' ',
'W','H','E','R','E',' ','%','s',0};
r = MSI_DatabaseGetPrimaryKeys(merge, table, &keys); r = MSI_DatabaseGetPrimaryKeys(merge, table, &keys);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return NULL; return NULL;
@ -1487,9 +1440,9 @@ static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view,
val = get_key_value(view, key, rec); val = get_key_value(view, key, rec);
if (i == count) if (i == count)
setptr = lastkeyset; setptr = L"`%s` = %s ";
else else
setptr = keyset; setptr = L"`%s` = %s AND ";
oldsize = size; oldsize = size;
size += lstrlenW(setptr) + lstrlenW(key) + lstrlenW(val) - 4; size += lstrlenW(setptr) + lstrlenW(key) + lstrlenW(val) - 4;
@ -1504,12 +1457,12 @@ static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view,
msi_free(val); msi_free(val);
} }
size = lstrlenW(fmt) + lstrlenW(table) + lstrlenW(clause) + 1; size = lstrlenW(L"SELECT * FROM `%s` WHERE %s") + lstrlenW(table) + lstrlenW(clause) + 1;
query = msi_alloc(size * sizeof(WCHAR)); query = msi_alloc(size * sizeof(WCHAR));
if (!query) if (!query)
goto done; goto done;
swprintf(query, size, fmt, table, clause); swprintf(query, size, L"SELECT * FROM `%s` WHERE %s", table, clause);
done: done:
msi_free(clause); msi_free(clause);
@ -1717,9 +1670,6 @@ static UINT msi_get_merge_table (MSIDATABASE *db, LPCWSTR name, MERGETABLE **pta
MERGETABLE *table; MERGETABLE *table;
MSIQUERY *mergeview = NULL; MSIQUERY *mergeview = NULL;
static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
'F','R','O','M',' ','`','%','s','`',0};
table = msi_alloc_zero(sizeof(MERGETABLE)); table = msi_alloc_zero(sizeof(MERGETABLE));
if (!table) if (!table)
{ {
@ -1731,7 +1681,7 @@ static UINT msi_get_merge_table (MSIDATABASE *db, LPCWSTR name, MERGETABLE **pta
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto err; goto err;
r = MSI_OpenQuery(db, &mergeview, query, name); r = MSI_OpenQuery(db, &mergeview, L"SELECT * FROM `%s`", name);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto err; goto err;
@ -1768,18 +1718,15 @@ static UINT merge_diff_tables(MSIRECORD *rec, LPVOID param)
LPCWSTR name; LPCWSTR name;
UINT r; UINT r;
static const WCHAR query[] = {'S','E','L','E','C','T',' ','*',' ',
'F','R','O','M',' ','`','%','s','`',0};
name = MSI_RecordGetString(rec, 1); name = MSI_RecordGetString(rec, 1);
r = MSI_OpenQuery(data->merge, &mergeview, query, name); r = MSI_OpenQuery(data->merge, &mergeview, L"SELECT * FROM `%s`", name);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
if (TABLE_Exists(data->db, name)) if (TABLE_Exists(data->db, name))
{ {
r = MSI_OpenQuery(data->db, &dbview, query, name); r = MSI_OpenQuery(data->db, &dbview, L"SELECT * FROM `%s`", name);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
@ -1816,14 +1763,11 @@ done:
static UINT gather_merge_data(MSIDATABASE *db, MSIDATABASE *merge, static UINT gather_merge_data(MSIDATABASE *db, MSIDATABASE *merge,
struct list *tabledata) struct list *tabledata)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','_','T','a','b','l','e','s','`',0};
MSIQUERY *view; MSIQUERY *view;
MERGEDATA data; MERGEDATA data;
UINT r; UINT r;
r = MSI_DatabaseOpenViewW(merge, query, &view); r = MSI_DatabaseOpenViewW(merge, L"SELECT * FROM `_Tables`", &view);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
@ -1871,24 +1815,10 @@ static UINT update_merge_errors(MSIDATABASE *db, LPCWSTR error,
UINT r; UINT r;
MSIQUERY *view; MSIQUERY *view;
static const WCHAR create[] = {
'C','R','E','A','T','E',' ','T','A','B','L','E',' ',
'`','%','s','`',' ','(','`','T','a','b','l','e','`',' ',
'C','H','A','R','(','2','5','5',')',' ','N','O','T',' ',
'N','U','L','L',',',' ','`','N','u','m','R','o','w','M','e','r','g','e',
'C','o','n','f','l','i','c','t','s','`',' ','S','H','O','R','T',' ',
'N','O','T',' ','N','U','L','L',' ','P','R','I','M','A','R','Y',' ',
'K','E','Y',' ','`','T','a','b','l','e','`',')',0};
static const WCHAR insert[] = {
'I','N','S','E','R','T',' ','I','N','T','O',' ',
'`','%','s','`',' ','(','`','T','a','b','l','e','`',',',' ',
'`','N','u','m','R','o','w','M','e','r','g','e',
'C','o','n','f','l','i','c','t','s','`',')',' ','V','A','L','U','E','S',
' ','(','\'','%','s','\'',',',' ','%','d',')',0};
if (!TABLE_Exists(db, error)) if (!TABLE_Exists(db, error))
{ {
r = MSI_OpenQuery(db, &view, create, error); r = MSI_OpenQuery(db, &view, L"CREATE TABLE `%s` (`Table` CHAR(255) NOT NULL, `NumRowMergeConflicts` SHORT "
"NOT NULL PRIMARY KEY `Table`)" , error);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
@ -1898,7 +1828,8 @@ static UINT update_merge_errors(MSIDATABASE *db, LPCWSTR error,
return r; return r;
} }
r = MSI_OpenQuery(db, &view, insert, error, table, numconflicts); r = MSI_OpenQuery(db, &view, L"INSERT INTO `%s` (`Table`, `NumRowMergeConflicts`) VALUES ('%s', %d)", error,
table, numconflicts);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
@ -1907,8 +1838,7 @@ static UINT update_merge_errors(MSIDATABASE *db, LPCWSTR error,
return r; return r;
} }
UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, LPCWSTR szTableName)
LPCWSTR szTableName)
{ {
struct list tabledata = LIST_INIT(tabledata); struct list tabledata = LIST_INIT(tabledata);
struct list *item, *cursor; struct list *item, *cursor;
@ -1917,8 +1847,7 @@ UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge,
BOOL conflicts; BOOL conflicts;
UINT r; UINT r;
TRACE("(%d, %d, %s)\n", hDatabase, hDatabaseMerge, TRACE("(%d, %d, %s)\n", hDatabase, hDatabaseMerge, debugstr_w(szTableName));
debugstr_w(szTableName));
if (szTableName && !*szTableName) if (szTableName && !*szTableName)
return ERROR_INVALID_TABLE; return ERROR_INVALID_TABLE;

View file

@ -196,7 +196,7 @@ UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
dv = msi_alloc_zero( sizeof *dv ); dv = msi_alloc_zero( sizeof *dv );
if( !dv ) if( !dv )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
/* fill the structure */ /* fill the structure */
dv->view.ops = &delete_ops; dv->view.ops = &delete_ops;
dv->db = db; dv->db = db;

View file

@ -287,7 +287,7 @@ UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
dv = msi_alloc_zero( sizeof *dv ); dv = msi_alloc_zero( sizeof *dv );
if( !dv ) if( !dv )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
/* fill the structure */ /* fill the structure */
dv->view.ops = &distinct_ops; dv->view.ops = &distinct_ops;
msiobj_addref( &db->hdr ); msiobj_addref( &db->hdr );

View file

@ -160,7 +160,6 @@ DWORD msi_get_file_version_info( MSIPACKAGE *package, const WCHAR *path, DWORD b
VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *package, const WCHAR *filename ) VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *package, const WCHAR *filename )
{ {
static const WCHAR name[] = {'\\',0};
VS_FIXEDFILEINFO *ptr, *ret; VS_FIXEDFILEINFO *ptr, *ret;
DWORD version_size, size; DWORD version_size, size;
void *version; void *version;
@ -170,7 +169,7 @@ VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *package, const WCHAR *f
msi_get_file_version_info( package, filename, version_size, version ); msi_get_file_version_info( package, filename, version_size, version );
if (!VerQueryValueW( version, name, (void **)&ptr, &size )) if (!VerQueryValueW( version, L"\\", (void **)&ptr, &size ))
{ {
msi_free( version ); msi_free( version );
return NULL; return NULL;
@ -267,7 +266,7 @@ static BOOL is_obsoleted_by_patch( MSIPACKAGE *package, MSIFILE *file )
{ {
if (!list_empty( &package->patches ) && file->disk_id < MSI_INITIAL_MEDIA_TRANSFORM_DISKID) if (!list_empty( &package->patches ) && file->disk_id < MSI_INITIAL_MEDIA_TRANSFORM_DISKID)
{ {
if (!msi_get_property_int( package->db, szInstalled, 0 )) return FALSE; if (!msi_get_property_int( package->db, L"Installed", 0 )) return FALSE;
return TRUE; return TRUE;
} }
if (is_registered_patch_media( package, file->disk_id )) return TRUE; if (is_registered_patch_media( package, file->disk_id )) return TRUE;
@ -442,7 +441,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
msi_free( pathW ); msi_free( pathW );
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
if (!GetTempFileNameW( pathW, szMsi, 0, tmpfileW )) tmpfileW[0] = 0; if (!GetTempFileNameW( pathW, L"msi", 0, tmpfileW )) tmpfileW[0] = 0;
msi_free( pathW ); msi_free( pathW );
if (msi_copy_file( package, source, tmpfileW, FALSE ) && if (msi_copy_file( package, source, tmpfileW, FALSE ) &&
@ -548,7 +547,7 @@ WCHAR *msi_resolve_file_source( MSIPACKAGE *package, MSIFILE *file )
/* /*
* ACTION_InstallFiles() * ACTION_InstallFiles()
* *
* For efficiency, this is done in two passes: * For efficiency, this is done in two passes:
* 1) Correct all the TargetPaths and determine what files are to be installed. * 1) Correct all the TargetPaths and determine what files are to be installed.
* 2) Extract Cabinets and copy files. * 2) Extract Cabinets and copy files.
@ -562,7 +561,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
msi_set_sourcedir_props(package, FALSE); msi_set_sourcedir_props(package, FALSE);
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szInstallFiles); return msi_schedule_action(package, SCRIPT_INSTALL, L"InstallFiles");
schedule_install_files(package); schedule_install_files(package);
mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) ); mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) );
@ -571,7 +570,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
{ {
BOOL is_global_assembly = msi_is_global_assembly( file->Component ); BOOL is_global_assembly = msi_is_global_assembly( file->Component );
msi_file_update_ui( package, file, szInstallFiles ); msi_file_update_ui( package, file, L"InstallFiles" );
rc = msi_load_media_info( package, file->Sequence, mi ); rc = msi_load_media_info( package, file->Sequence, mi );
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
@ -583,7 +582,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
if (file->state != msifs_hashmatch && if (file->state != msifs_hashmatch &&
file->state != msifs_skipped && file->state != msifs_skipped &&
(file->state != msifs_present || !msi_get_property_int( package->db, szInstalled, 0 )) && (file->state != msifs_present || !msi_get_property_int( package->db, L"Installed", 0 )) &&
(rc = ready_media( package, file->IsCompressed, mi ))) (rc = ready_media( package, file->IsCompressed, mi )))
{ {
ERR("Failed to ready media for %s\n", debugstr_w(file->File)); ERR("Failed to ready media for %s\n", debugstr_w(file->File));
@ -790,7 +789,7 @@ UINT ACTION_PatchFiles( MSIPACKAGE *package )
TRACE("%p\n", package); TRACE("%p\n", package);
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szPatchFiles); return msi_schedule_action(package, SCRIPT_INSTALL, L"PatchFiles");
mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) ); mi = msi_alloc_zero( sizeof(MSIMEDIAINFO) );
@ -1129,7 +1128,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
lstrcpyW(source, sourcedir); lstrcpyW(source, sourcedir);
if (source[lstrlenW(source) - 1] != '\\') if (source[lstrlenW(source) - 1] != '\\')
lstrcatW(source, szBackSlash); lstrcatW(source, L"\\");
lstrcatW(source, sourcename); lstrcatW(source, sourcename);
} }
@ -1167,7 +1166,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
lstrcpyW(dest, destdir); lstrcpyW(dest, destdir);
if (dest[lstrlenW(dest) - 1] != '\\') if (dest[lstrlenW(dest) - 1] != '\\')
lstrcatW(dest, szBackSlash); lstrcatW(dest, L"\\");
if (destname) if (destname)
lstrcatW(dest, destname); lstrcatW(dest, destname);
@ -1205,16 +1204,13 @@ done:
UINT ACTION_MoveFiles( MSIPACKAGE *package ) UINT ACTION_MoveFiles( MSIPACKAGE *package )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','M','o','v','e','F','i','l','e','`',0};
MSIQUERY *view; MSIQUERY *view;
UINT rc; UINT rc;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szMoveFiles); return msi_schedule_action(package, SCRIPT_INSTALL, L"MoveFiles");
rc = MSI_DatabaseOpenViewW(package->db, query, &view); rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `MoveFile`", &view);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -1338,16 +1334,13 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
UINT ACTION_DuplicateFiles(MSIPACKAGE *package) UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','D','u','p','l','i','c','a','t','e','F','i','l','e','`',0};
MSIQUERY *view; MSIQUERY *view;
UINT rc; UINT rc;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szDuplicateFiles); return msi_schedule_action(package, SCRIPT_INSTALL, L"DuplicateFiles");
rc = MSI_DatabaseOpenViewW(package->db, query, &view); rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `DuplicateFile`", &view);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -1416,16 +1409,13 @@ static UINT ITERATE_RemoveDuplicateFiles( MSIRECORD *row, LPVOID param )
UINT ACTION_RemoveDuplicateFiles( MSIPACKAGE *package ) UINT ACTION_RemoveDuplicateFiles( MSIPACKAGE *package )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','D','u','p','l','i','c','a','t','e','F','i','l','e','`',0};
MSIQUERY *view; MSIQUERY *view;
UINT rc; UINT rc;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveDuplicateFiles); return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveDuplicateFiles");
rc = MSI_DatabaseOpenViewW( package->db, query, &view ); rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `DuplicateFile`", &view );
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -1557,18 +1547,15 @@ static void remove_folder( MSIFOLDER *folder )
UINT ACTION_RemoveFiles( MSIPACKAGE *package ) UINT ACTION_RemoveFiles( MSIPACKAGE *package )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','R','e','m','o','v','e','F','i','l','e','`',0};
MSIQUERY *view; MSIQUERY *view;
MSICOMPONENT *comp; MSICOMPONENT *comp;
MSIFILE *file; MSIFILE *file;
UINT r; UINT r;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szRemoveFiles); return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveFiles");
r = MSI_DatabaseOpenViewW(package->db, query, &view); r = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `RemoveFile`", &view);
if (r == ERROR_SUCCESS) if (r == ERROR_SUCCESS)
{ {
r = MSI_IterateRecords(view, NULL, ITERATE_RemoveFiles, package); r = MSI_IterateRecords(view, NULL, ITERATE_RemoveFiles, package);
@ -1583,7 +1570,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
VS_FIXEDFILEINFO *ver; VS_FIXEDFILEINFO *ver;
comp = file->Component; comp = file->Component;
msi_file_update_ui( package, file, szRemoveFiles ); msi_file_update_ui( package, file, L"RemoveFiles" );
comp->Action = msi_get_component_action( package, comp ); comp->Action = msi_get_component_action( package, comp );
if (comp->Action != INSTALLSTATE_ABSENT || comp->Installed == INSTALLSTATE_SOURCE) if (comp->Action != INSTALLSTATE_ABSENT || comp->Installed == INSTALLSTATE_SOURCE)

View file

@ -66,19 +66,6 @@ typedef struct _tagTT_NAME_RECORD {
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x))) #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
static const WCHAR regfont1[] =
{'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s',' ','N','T','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'F','o','n','t','s',0};
static const WCHAR regfont2[] =
{'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','\\',
'F','o','n','t','s',0};
/* /*
* Code based off of code located here * Code based off of code located here
* http://www.codeproject.com/gdi/fontnamefromfile.asp * http://www.codeproject.com/gdi/fontnamefromfile.asp
@ -178,7 +165,6 @@ end:
static WCHAR *font_name_from_file( MSIPACKAGE *package, const WCHAR *filename ) static WCHAR *font_name_from_file( MSIPACKAGE *package, const WCHAR *filename )
{ {
static const WCHAR truetypeW[] = {' ','(','T','r','u','e','T','y','p','e',')',0};
WCHAR *name, *ret = NULL; WCHAR *name, *ret = NULL;
if ((name = load_ttf_name_id( package, filename, NAME_ID_FULL_FONT_NAME ))) if ((name = load_ttf_name_id( package, filename, NAME_ID_FULL_FONT_NAME )))
@ -189,9 +175,9 @@ static WCHAR *font_name_from_file( MSIPACKAGE *package, const WCHAR *filename )
msi_free( name ); msi_free( name );
return NULL; return NULL;
} }
ret = msi_alloc( (lstrlenW( name ) + lstrlenW( truetypeW ) + 1 ) * sizeof(WCHAR) ); ret = msi_alloc( (lstrlenW( name ) + lstrlenW( L" (TrueType)" ) + 1 ) * sizeof(WCHAR) );
lstrcpyW( ret, name ); lstrcpyW( ret, name );
lstrcatW( ret, truetypeW ); lstrcatW( ret, L" (TrueType)" );
msi_free( name ); msi_free( name );
} }
return ret; return ret;
@ -199,7 +185,6 @@ static WCHAR *font_name_from_file( MSIPACKAGE *package, const WCHAR *filename )
WCHAR *msi_get_font_file_version( MSIPACKAGE *package, const WCHAR *filename ) WCHAR *msi_get_font_file_version( MSIPACKAGE *package, const WCHAR *filename )
{ {
static const WCHAR fmtW[] = {'%','u','.','%','u','.','0','.','0',0};
WCHAR *version, *p, *q, *ret = NULL; WCHAR *version, *p, *q, *ret = NULL;
if ((version = load_ttf_name_id( package, filename, NAME_ID_VERSION ))) if ((version = load_ttf_name_id( package, filename, NAME_ID_VERSION )))
@ -216,9 +201,9 @@ WCHAR *msi_get_font_file_version( MSIPACKAGE *package, const WCHAR *filename )
if (!*q || *q == ' ') minor = wcstol( p, NULL, 10 ); if (!*q || *q == ' ') minor = wcstol( p, NULL, 10 );
else major = 0; else major = 0;
} }
len = lstrlenW( fmtW ) + 20; len = lstrlenW( L"%u.%u.0.0" ) + 20;
ret = msi_alloc( len * sizeof(WCHAR) ); ret = msi_alloc( len * sizeof(WCHAR) );
swprintf( ret, len, fmtW, major, minor ); swprintf( ret, len, L"%u.%u.0.0", major, minor );
msi_free( version ); msi_free( version );
} }
return ret; return ret;
@ -255,8 +240,8 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1); RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" ,&hkey1 );
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts", &hkey2 );
if (MSI_RecordIsNull(row,2)) if (MSI_RecordIsNull(row,2))
name = font_name_from_file( package, file->TargetPath ); name = font_name_from_file( package, file->TargetPath );
@ -290,15 +275,13 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
UINT ACTION_RegisterFonts(MSIPACKAGE *package) UINT ACTION_RegisterFonts(MSIPACKAGE *package)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','F','o','n','t','`',0};
MSIQUERY *view; MSIQUERY *view;
UINT rc; UINT rc;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szRegisterFonts); return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterFonts");
rc = MSI_DatabaseOpenViewW(package->db, query, &view); rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Font`", &view);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -338,8 +321,8 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont1, &hkey1 ); RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", &hkey1 );
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 ); RegCreateKeyW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts", &hkey2 );
if (MSI_RecordIsNull( row, 2 )) if (MSI_RecordIsNull( row, 2 ))
name = font_name_from_file( package, file->TargetPath ); name = font_name_from_file( package, file->TargetPath );
@ -373,15 +356,13 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param )
UINT ACTION_UnregisterFonts( MSIPACKAGE *package ) UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','F','o','n','t','`',0};
MSIQUERY *view; MSIQUERY *view;
UINT r; UINT r;
if (package->script == SCRIPT_NONE) if (package->script == SCRIPT_NONE)
return msi_schedule_action(package, SCRIPT_INSTALL, szUnregisterFonts); return msi_schedule_action(package, SCRIPT_INSTALL, L"UnregisterFonts");
r = MSI_DatabaseOpenViewW( package->db, query, &view ); r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Font`", &view );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;

View file

@ -341,7 +341,6 @@ static WCHAR *deformat_literal( FORMAT *format, FORMSTR *str, BOOL *propfound,
static WCHAR *build_default_format( const MSIRECORD *record ) static WCHAR *build_default_format( const MSIRECORD *record )
{ {
static const WCHAR fmt[] = {'%','i',':',' ','[','%','i',']',' ',0};
int i, count = MSI_RecordGetFieldCount( record ); int i, count = MSI_RecordGetFieldCount( record );
WCHAR *ret, *tmp, buf[26]; WCHAR *ret, *tmp, buf[26];
DWORD size = 1; DWORD size = 1;
@ -351,7 +350,7 @@ static WCHAR *build_default_format( const MSIRECORD *record )
for (i = 1; i <= count; i++) for (i = 1; i <= count; i++)
{ {
size += swprintf( buf, ARRAY_SIZE(buf), fmt, i, i ); size += swprintf( buf, ARRAY_SIZE(buf), L"%d: [%d] ", i, i );
if (!(tmp = msi_realloc( ret, size * sizeof(*ret) ))) if (!(tmp = msi_realloc( ret, size * sizeof(*ret) )))
{ {
msi_free( ret ); msi_free( ret );
@ -754,7 +753,7 @@ static BOOL verify_format(LPWSTR data)
return TRUE; return TRUE;
} }
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr,
WCHAR** data, DWORD *len, WCHAR** data, DWORD *len,
MSIRECORD* record) MSIRECORD* record)
{ {
@ -898,7 +897,7 @@ end:
return rc; return rc;
} }
UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord,
LPWSTR szResult, LPDWORD sz ) LPWSTR szResult, LPDWORD sz )
{ {
UINT r = ERROR_INVALID_HANDLE; UINT r = ERROR_INVALID_HANDLE;

View file

@ -52,7 +52,7 @@ UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
szwAction = strdupAtoW(szAction); szwAction = strdupAtoW(szAction);
if (szAction && !szwAction) if (szAction && !szwAction)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
ret = MsiDoActionW( hInstall, szwAction ); ret = MsiDoActionW( hInstall, szwAction );
msi_free( szwAction ); msi_free( szwAction );
@ -92,7 +92,7 @@ UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
return ret; return ret;
} }
ret = ACTION_PerformAction(package, szAction); ret = ACTION_PerformAction(package, szAction);
msiobj_release( &package->hdr ); msiobj_release( &package->hdr );
@ -111,7 +111,7 @@ UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode
szwTable = strdupAtoW(szTable); szwTable = strdupAtoW(szTable);
if (szTable && !szwTable) if (szTable && !szwTable)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
ret = MsiSequenceW( hInstall, szwTable, iSequenceMode ); ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
msi_free( szwTable ); msi_free( szwTable );
@ -166,7 +166,7 @@ UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD *
return ERROR_SUCCESS; return ERROR_SUCCESS;
if (len < 0) len = lstrlenW( str ); if (len < 0) len = lstrlenW( str );
if (awbuf->unicode && awbuf->str.w) if (awbuf->unicode && awbuf->str.w)
{ {
memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) ); memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) );
@ -359,7 +359,7 @@ UINT WINAPI MsiGetTargetPathW(MSIHANDLE hinst, const WCHAR *folder, WCHAR *buf,
static WCHAR *get_source_root( MSIPACKAGE *package ) static WCHAR *get_source_root( MSIPACKAGE *package )
{ {
msi_set_sourcedir_props( package, FALSE ); msi_set_sourcedir_props( package, FALSE );
return msi_dup_property( package->db, szSourceDir ); return msi_dup_property( package->db, L"SourceDir" );
} }
WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder ) WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder )
@ -369,11 +369,11 @@ WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOL
TRACE("working to resolve %s\n", debugstr_w(name)); TRACE("working to resolve %s\n", debugstr_w(name));
if (!wcscmp( name, szSourceDir )) name = szTargetDir; if (!wcscmp( name, L"SourceDir" )) name = L"TARGETDIR";
if (!(f = msi_get_loaded_folder( package, name ))) return NULL; if (!(f = msi_get_loaded_folder( package, name ))) return NULL;
/* special resolving for root dir */ /* special resolving for root dir */
if (!wcscmp( name, szTargetDir ) && !f->ResolvedSource) if (!wcscmp( name, L"TARGETDIR" ) && !f->ResolvedSource)
{ {
f->ResolvedSource = get_source_root( package ); f->ResolvedSource = get_source_root( package );
} }
@ -598,7 +598,7 @@ UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolder
/*********************************************************************** /***********************************************************************
* MsiSetTargetPathW (MSI.@) * MsiSetTargetPathW (MSI.@)
*/ */
UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
LPCWSTR szFolderPath) LPCWSTR szFolderPath)
{ {
MSIPACKAGE *package; MSIPACKAGE *package;
@ -730,11 +730,11 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
break; break;
case MSIRUNMODE_MAINTENANCE: case MSIRUNMODE_MAINTENANCE:
r = msi_get_property_int( package->db, szInstalled, 0 ) != 0; r = msi_get_property_int( package->db, L"Installed", 0 ) != 0;
break; break;
case MSIRUNMODE_ROLLBACKENABLED: case MSIRUNMODE_ROLLBACKENABLED:
r = msi_get_property_int( package->db, szRollbackDisabled, 0 ) == 0; r = msi_get_property_int( package->db, L"RollbackDisabled", 0 ) == 0;
break; break;
case MSIRUNMODE_REBOOTATEND: case MSIRUNMODE_REBOOTATEND:
@ -823,7 +823,7 @@ UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
szwFeature = strdupAtoW(szFeature); szwFeature = strdupAtoW(szFeature);
rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
msi_free(szwFeature); msi_free(szwFeature);
@ -924,7 +924,7 @@ UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE
if (!feature) if (!feature)
return ERROR_UNKNOWN_FEATURE; return ERROR_UNKNOWN_FEATURE;
if (iState == INSTALLSTATE_ADVERTISED && if (iState == INSTALLSTATE_ADVERTISED &&
feature->Attributes & msidbFeatureAttributesDisallowAdvertise) feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
@ -938,7 +938,7 @@ UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE
if (child->Feature_Parent && !wcscmp( szFeature, child->Feature_Parent )) if (child->Feature_Parent && !wcscmp( szFeature, child->Feature_Parent ))
MSI_SetFeatureStateW(package, child->Feature, iState); MSI_SetFeatureStateW(package, child->Feature, iState);
} }
return rc; return rc;
} }
@ -1029,8 +1029,8 @@ UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attr
if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ))) if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
costing = msi_dup_property( package->db, szCostingComplete ); costing = msi_dup_property( package->db, L"CostingComplete" );
if (!costing || !wcscmp( costing, szOne )) if (!costing || !wcscmp( costing, L"1" ))
{ {
msi_free( costing ); msi_free( costing );
msiobj_release( &package->hdr ); msiobj_release( &package->hdr );
@ -1055,7 +1055,7 @@ UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
{ {
LPWSTR szwFeature = NULL; LPWSTR szwFeature = NULL;
UINT rc; UINT rc;
if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY; if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY;
rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction); rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction);
@ -1400,7 +1400,7 @@ UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
{ {
LPWSTR szwComponent= NULL; LPWSTR szwComponent= NULL;
UINT rc; UINT rc;
szwComponent= strdupAtoW(szComponent); szwComponent= strdupAtoW(szComponent);
rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction); rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
@ -1567,14 +1567,13 @@ LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
return langid; return langid;
} }
langid = msi_get_property_int( package->db, szProductLanguage, 0 ); langid = msi_get_property_int( package->db, L"ProductLanguage", 0 );
msiobj_release( &package->hdr ); msiobj_release( &package->hdr );
return langid; return langid;
} }
UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel ) UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
{ {
static const WCHAR fmt[] = { '%','d',0 };
WCHAR level[6]; WCHAR level[6];
int len; int len;
UINT r; UINT r;
@ -1587,8 +1586,8 @@ UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
if (iInstallLevel < 1) if (iInstallLevel < 1)
return MSI_SetFeatureStates( package ); return MSI_SetFeatureStates( package );
len = swprintf( level, ARRAY_SIZE(level), fmt, iInstallLevel ); len = swprintf( level, ARRAY_SIZE(level), L"%d", iInstallLevel );
r = msi_set_property( package->db, szInstallLevel, level, len ); r = msi_set_property( package->db, L"INSTALLLEVEL", level, len );
if ( r == ERROR_SUCCESS ) if ( r == ERROR_SUCCESS )
r = MSI_SetFeatureStates( package ); r = MSI_SetFeatureStates( package );

View file

@ -82,7 +82,7 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
LPWSTR source_dir; LPWSTR source_dir;
UINT r = IDRETRY; UINT r = IDRETRY;
source_dir = msi_dup_property(package->db, szSourceDir); source_dir = msi_dup_property(package->db, L"SourceDir");
record = MSI_CreateRecord(2); record = MSI_CreateRecord(2);
while (r == IDRETRY && !source_matches_volume(mi, source_dir)) while (r == IDRETRY && !source_matches_volume(mi, source_dir))
@ -275,12 +275,7 @@ static UINT CDECL msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi)
{ {
MSIRECORD *row; MSIRECORD *row;
static const WCHAR query[] = { row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `DiskId` = %d", mi->disk_id);
'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
'`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
'`','D','i','s','k','I','d','`',' ','=',' ','%','i',0};
row = MSI_QueryGetRecord(package->db, query, mi->disk_id);
if (!row) if (!row)
{ {
TRACE("Unable to query row\n"); TRACE("Unable to query row\n");
@ -473,7 +468,7 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
msi_free( tmppathW ); msi_free( tmppathW );
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
if (!GetTempFileNameW(tmppathW, szMsi, 0, tmpfileW)) tmpfileW[0] = 0; if (!GetTempFileNameW(tmppathW, L"msi", 0, tmpfileW)) tmpfileW[0] = 0;
msi_free( tmppathW ); msi_free( tmppathW );
handle = CreateFileW(tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); handle = CreateFileW(tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
@ -679,7 +674,7 @@ static UINT get_drive_type(const WCHAR *path)
static WCHAR *get_base_url( MSIDATABASE *db ) static WCHAR *get_base_url( MSIDATABASE *db )
{ {
WCHAR *p, *ret = NULL, *orig_db = msi_dup_property( db, szOriginalDatabase ); WCHAR *p, *ret = NULL, *orig_db = msi_dup_property( db, L"OriginalDatabase" );
if (UrlIsW( orig_db, URLIS_URL ) && (ret = strdupW( orig_db )) && (p = wcsrchr( ret, '/'))) p[1] = 0; if (UrlIsW( orig_db, URLIS_URL ) && (ret = strdupW( orig_db )) && (p = wcsrchr( ret, '/'))) p[1] = 0;
msi_free( orig_db ); msi_free( orig_db );
return ret; return ret;
@ -687,10 +682,6 @@ static WCHAR *get_base_url( MSIDATABASE *db )
UINT msi_load_media_info(MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi) UINT msi_load_media_info(MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','M','e','d','i','a','`',' ',
'W','H','E','R','E',' ','`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ',
'>','=',' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ','`','D','i','s','k','I','d','`',0};
MSIRECORD *row; MSIRECORD *row;
WCHAR *source_dir, *source, *base_url = NULL; WCHAR *source_dir, *source, *base_url = NULL;
DWORD options; DWORD options;
@ -698,7 +689,7 @@ UINT msi_load_media_info(MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi)
if (Sequence <= mi->last_sequence) /* already loaded */ if (Sequence <= mi->last_sequence) /* already loaded */
return ERROR_SUCCESS; return ERROR_SUCCESS;
row = MSI_QueryGetRecord(package->db, query, Sequence); row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `LastSequence` >= %d ORDER BY `DiskId`", Sequence);
if (!row) if (!row)
{ {
TRACE("Unable to query row\n"); TRACE("Unable to query row\n");
@ -717,7 +708,7 @@ UINT msi_load_media_info(MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi)
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
msi_set_sourcedir_props(package, FALSE); msi_set_sourcedir_props(package, FALSE);
source_dir = msi_dup_property(package->db, szSourceDir); source_dir = msi_dup_property(package->db, L"SourceDir");
lstrcpyW(mi->sourcedir, source_dir); lstrcpyW(mi->sourcedir, source_dir);
PathAddBackslashW(mi->sourcedir); PathAddBackslashW(mi->sourcedir);
mi->type = get_drive_type(source_dir); mi->type = get_drive_type(source_dir);
@ -902,7 +893,7 @@ UINT ready_media( MSIPACKAGE *package, BOOL compressed, MSIMEDIAINFO *mi )
/* assume first volume is in the drive */ /* assume first volume is in the drive */
if (mi->last_volume && wcsicmp( mi->last_volume, mi->volume_label )) if (mi->last_volume && wcsicmp( mi->last_volume, mi->volume_label ))
{ {
WCHAR *source = msi_dup_property( package->db, szSourceDir ); WCHAR *source = msi_dup_property( package->db, L"SourceDir" );
BOOL match = source_matches_volume( mi, source ); BOOL match = source_matches_volume( mi, source );
msi_free( source ); msi_free( source );

View file

@ -2469,7 +2469,7 @@ UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uTyp
{ {
FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption), FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
uType, wLanguageId, f); uType, wLanguageId, f);
return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId); return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
} }
UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
@ -2477,7 +2477,7 @@ UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uT
{ {
FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption), FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
uType, wLanguageId, f); uType, wLanguageId, f);
return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId); return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
} }
UINT WINAPI MsiMessageBoxExA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, UINT WINAPI MsiMessageBoxExA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
@ -3522,7 +3522,7 @@ UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf, LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
LPDWORD pcchPathBuf) LPDWORD pcchPathBuf)
{ {
return MsiProvideQualifiedComponentExW(szComponent, szQualifier, return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf); dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
} }
@ -3989,7 +3989,7 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, DWORD dw
if (dwReinstallMode & REINSTALLMODE_PACKAGE) if (dwReinstallMode & REINSTALLMODE_PACKAGE)
*ptr++ = 'v'; *ptr++ = 'v';
*ptr = 0; *ptr = 0;
sz = sizeof(sourcepath); sz = sizeof(sourcepath);
MsiSourceListGetInfoW( szProduct, NULL, context, MSICODE_PRODUCT, MsiSourceListGetInfoW( szProduct, NULL, context, MSICODE_PRODUCT,
INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz ); INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz );

View file

@ -1137,111 +1137,6 @@ extern DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR f
/* User interface messages from the actions */ /* User interface messages from the actions */
extern void msi_ui_progress(MSIPACKAGE *, int, int, int, int) DECLSPEC_HIDDEN; extern void msi_ui_progress(MSIPACKAGE *, int, int, int, int) DECLSPEC_HIDDEN;
/* common strings */
static const WCHAR szSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
static const WCHAR szSOURCEDIR[] = {'S','O','U','R','C','E','D','I','R',0};
static const WCHAR szRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
static const WCHAR szTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};
static const WCHAR szLocalSid[] = {'S','-','1','-','5','-','1','8',0};
static const WCHAR szAllSid[] = {'S','-','1','-','1','-','0',0};
static const WCHAR szEmpty[] = {0};
static const WCHAR szAll[] = {'A','L','L',0};
static const WCHAR szOne[] = {'1',0};
static const WCHAR szZero[] = {'0',0};
static const WCHAR szSpace[] = {' ',0};
static const WCHAR szBackSlash[] = {'\\',0};
static const WCHAR szForwardSlash[] = {'/',0};
static const WCHAR szDot[] = {'.',0};
static const WCHAR szDotDot[] = {'.','.',0};
static const WCHAR szSemiColon[] = {';',0};
static const WCHAR szPreselected[] = {'P','r','e','s','e','l','e','c','t','e','d',0};
static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
static const WCHAR szState[] = {'S','t','a','t','e',0};
static const WCHAR szMsi[] = {'m','s','i',0};
static const WCHAR szPatch[] = {'P','A','T','C','H',0};
static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};
static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
static const WCHAR szRemove[] = {'R','E','M','O','V','E',0};
static const WCHAR szUserSID[] = {'U','s','e','r','S','I','D',0};
static const WCHAR szProductCode[] = {'P','r','o','d','u','c','t','C','o','d','e',0};
static const WCHAR szRegisterClassInfo[] = {'R','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};
static const WCHAR szRegisterProgIdInfo[] = {'R','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};
static const WCHAR szRegisterExtensionInfo[] = {'R','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0};
static const WCHAR szRegisterMIMEInfo[] = {'R','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
static const WCHAR szDuplicateFiles[] = {'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
static const WCHAR szRemoveDuplicateFiles[] = {'R','e','m','o','v','e','D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
static const WCHAR szInstallFiles[] = {'I','n','s','t','a','l','l','F','i','l','e','s',0};
static const WCHAR szPatchFiles[] = {'P','a','t','c','h','F','i','l','e','s',0};
static const WCHAR szRemoveFiles[] = {'R','e','m','o','v','e','F','i','l','e','s',0};
static const WCHAR szFindRelatedProducts[] = {'F','i','n','d','R','e','l','a','t','e','d','P','r','o','d','u','c','t','s',0};
static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0};
static const WCHAR szCustomActionData[] = {'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0};
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0};
static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0};
static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
static const WCHAR szSumInfo[] = {5 ,'S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
static const WCHAR szHCR[] = {'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T','\\',0};
static const WCHAR szHCU[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',0};
static const WCHAR szHLM[] = {'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E','\\',0};
static const WCHAR szHU[] = {'H','K','E','Y','_','U','S','E','R','S','\\',0};
static const WCHAR szWindowsFolder[] = {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
static const WCHAR szAppSearch[] = {'A','p','p','S','e','a','r','c','h',0};
static const WCHAR szMoveFiles[] = {'M','o','v','e','F','i','l','e','s',0};
static const WCHAR szCCPSearch[] = {'C','C','P','S','e','a','r','c','h',0};
static const WCHAR szUnregisterClassInfo[] = {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};
static const WCHAR szUnregisterExtensionInfo[] = {'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0};
static const WCHAR szUnregisterMIMEInfo[] = {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
static const WCHAR szUnregisterProgIdInfo[] = {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};
static const WCHAR szRegisterFonts[] = {'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
static const WCHAR szUnregisterFonts[] = {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};
static const WCHAR szCLSID[] = {'C','L','S','I','D',0};
static const WCHAR szProgID[] = {'P','r','o','g','I','D',0};
static const WCHAR szVIProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','n','d','e','n','t','P','r','o','g','I','D',0};
static const WCHAR szAppID[] = {'A','p','p','I','D',0};
static const WCHAR szDefaultIcon[] = {'D','e','f','a','u','l','t','I','c','o','n',0};
static const WCHAR szInprocHandler[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
static const WCHAR szInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
static const WCHAR szMIMEDatabase[] = {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t',' ','T','y','p','e','\\',0};
static const WCHAR szLocalPackage[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
static const WCHAR szOriginalDatabase[] = {'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
static const WCHAR szUpgradeCode[] = {'U','p','g','r','a','d','e','C','o','d','e',0};
static const WCHAR szAdminUser[] = {'A','d','m','i','n','U','s','e','r',0};
static const WCHAR szIntel[] = {'I','n','t','e','l',0};
static const WCHAR szIntel64[] = {'I','n','t','e','l','6','4',0};
static const WCHAR szX64[] = {'x','6','4',0};
static const WCHAR szAMD64[] = {'A','M','D','6','4',0};
static const WCHAR szARM[] = {'A','r','m',0};
static const WCHAR szARM64[] = {'A','r','m','6','4',0};
static const WCHAR szStreams[] = {'_','S','t','r','e','a','m','s',0};
static const WCHAR szStorages[] = {'_','S','t','o','r','a','g','e','s',0};
static const WCHAR szMsiPublishAssemblies[] = {'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szMsiUnpublishAssemblies[] = {'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};
static const WCHAR szCostingComplete[] = {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0};
static const WCHAR szTempFolder[] = {'T','e','m','p','F','o','l','d','e','r',0};
static const WCHAR szDatabase[] = {'D','A','T','A','B','A','S','E',0};
static const WCHAR szCRoot[] = {'C',':','\\',0};
static const WCHAR szProductLanguage[] = {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
static const WCHAR szProductVersion[] = {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
static const WCHAR szWindowsInstaller[] = {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
static const WCHAR szStringData[] = {'_','S','t','r','i','n','g','D','a','t','a',0};
static const WCHAR szStringPool[] = {'_','S','t','r','i','n','g','P','o','o','l',0};
static const WCHAR szInstallLevel[] = {'I','N','S','T','A','L','L','L','E','V','E','L',0};
static const WCHAR szCostInitialize[] = {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
static const WCHAR szAppDataFolder[] = {'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
static const WCHAR szRollbackDisabled[] = {'R','o','l','l','b','a','c','k','D','i','s','a','b','l','e','d',0};
static const WCHAR szName[] = {'N','a','m','e',0};
static const WCHAR szData[] = {'D','a','t','a',0};
static const WCHAR szLangResource[] = {'\\','V','a','r','F','i','l','e','I','n','f','o','\\','T','r','a','n','s','l','a','t','i','o','n',0};
static const WCHAR szInstallLocation[] = {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0};
static const WCHAR szProperty[] = {'P','r','o','p','e','r','t','y',0};
static const WCHAR szUninstallable[] = {'U','n','i','n','s','t','a','l','l','a','b','l','e',0};
static const WCHAR szEXECUTEACTION[] = {'E','X','E','C','U','T','E','A','C','T','I','O','N',0};
static const WCHAR szProductToBeRegistered[] = {'P','r','o','d','u','c','t','T','o','B','e','R','e','g','i','s','t','e','r','e','d',0};
/* memory allocation macro functions */ /* memory allocation macro functions */
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1); static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
static inline void *msi_alloc( size_t len ) static inline void *msi_alloc( size_t len )

View file

@ -517,7 +517,7 @@ UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
MSIQUERY *query; MSIQUERY *query;
MSIRECORD *rec = NULL; MSIRECORD *rec = NULL;
UINT ret; UINT ret;
TRACE("%d %d\n", hView, hRec); TRACE("%d %d\n", hView, hRec);
if( hRec ) if( hRec )
@ -564,7 +564,6 @@ UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field, static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field,
UINT type, BOOL temporary ) UINT type, BOOL temporary )
{ {
static const WCHAR fmt[] = { '%','d',0 };
WCHAR szType[0x10]; WCHAR szType[0x10];
if (MSITYPE_IS_BINARY(type)) if (MSITYPE_IS_BINARY(type))
@ -591,7 +590,7 @@ static UINT msi_set_record_type_string( MSIRECORD *rec, UINT field,
if (type & MSITYPE_NULLABLE) if (type & MSITYPE_NULLABLE)
szType[0] &= ~0x20; szType[0] &= ~0x20;
swprintf( &szType[1], ARRAY_SIZE(szType) - 1, fmt, (type&0xff) ); swprintf( &szType[1], ARRAY_SIZE(szType) - 1, L"%d", (type&0xff) );
TRACE("type %04x -> %s\n", type, debugstr_w(szType) ); TRACE("type %04x -> %s\n", type, debugstr_w(szType) );
@ -798,7 +797,7 @@ MSIDBERROR WINAPI MsiViewGetErrorW( MSIHANDLE handle, LPWSTR buffer, LPDWORD buf
} }
__ENDTRY; __ENDTRY;
if (msi_strncpyW(remote_column ? remote_column : szEmpty, -1, buffer, buflen) == ERROR_MORE_DATA) if (msi_strncpyW(remote_column ? remote_column : L"", -1, buffer, buflen) == ERROR_MORE_DATA)
r = MSIDBERROR_MOREDATA; r = MSIDBERROR_MOREDATA;
if (remote_column) if (remote_column)
@ -808,7 +807,7 @@ MSIDBERROR WINAPI MsiViewGetErrorW( MSIHANDLE handle, LPWSTR buffer, LPDWORD buf
} }
if ((r = query->view->error)) column = query->view->error_column; if ((r = query->view->error)) column = query->view->error_column;
else column = szEmpty; else column = L"";
if (msi_strncpyW(column, -1, buffer, buflen) == ERROR_MORE_DATA) if (msi_strncpyW(column, -1, buffer, buflen) == ERROR_MORE_DATA)
r = MSIDBERROR_MOREDATA; r = MSIDBERROR_MOREDATA;
@ -849,7 +848,7 @@ MSIDBERROR WINAPI MsiViewGetErrorA( MSIHANDLE handle, LPSTR buffer, LPDWORD bufl
} }
__ENDTRY; __ENDTRY;
if (msi_strncpyWtoA(remote_column ? remote_column : szEmpty, -1, buffer, buflen, FALSE) == ERROR_MORE_DATA) if (msi_strncpyWtoA(remote_column ? remote_column : L"", -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
r = MSIDBERROR_MOREDATA; r = MSIDBERROR_MOREDATA;
if (remote_column) if (remote_column)
@ -859,7 +858,7 @@ MSIDBERROR WINAPI MsiViewGetErrorA( MSIHANDLE handle, LPSTR buffer, LPDWORD bufl
} }
if ((r = query->view->error)) column = query->view->error_column; if ((r = query->view->error)) column = query->view->error_column;
else column = szEmpty; else column = L"";
if (msi_strncpyWtoA(column, -1, buffer, buflen, FALSE) == ERROR_MORE_DATA) if (msi_strncpyWtoA(column, -1, buffer, buflen, FALSE) == ERROR_MORE_DATA)
r = MSIDBERROR_MOREDATA; r = MSIDBERROR_MOREDATA;
@ -1045,11 +1044,6 @@ static UINT msi_primary_key_iterator( MSIRECORD *rec, LPVOID param )
UINT MSI_DatabaseGetPrimaryKeys( MSIDATABASE *db, UINT MSI_DatabaseGetPrimaryKeys( MSIDATABASE *db,
LPCWSTR table, MSIRECORD **prec ) LPCWSTR table, MSIRECORD **prec )
{ {
static const WCHAR sql[] = {
's','e','l','e','c','t',' ','*',' ',
'f','r','o','m',' ','`','_','C','o','l','u','m','n','s','`',' ',
'w','h','e','r','e',' ',
'`','T','a','b','l','e','`',' ','=',' ','\'','%','s','\'',0 };
struct msi_primary_key_record_info info; struct msi_primary_key_record_info info;
MSIQUERY *query = NULL; MSIQUERY *query = NULL;
UINT r; UINT r;
@ -1057,7 +1051,7 @@ UINT MSI_DatabaseGetPrimaryKeys( MSIDATABASE *db,
if (!TABLE_Exists( db, table )) if (!TABLE_Exists( db, table ))
return ERROR_INVALID_TABLE; return ERROR_INVALID_TABLE;
r = MSI_OpenQuery( db, &query, sql, table ); r = MSI_OpenQuery( db, &query, L"SELECT * FROM `_Columns` WHERE `Table` = '%s'", table );
if( r != ERROR_SUCCESS ) if( r != ERROR_SUCCESS )
return r; return r;
@ -1133,7 +1127,7 @@ UINT WINAPI MsiDatabaseGetPrimaryKeysW( MSIHANDLE hdb,
return r; return r;
} }
UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb,
LPCSTR table, MSIHANDLE* phRec) LPCSTR table, MSIHANDLE* phRec)
{ {
LPWSTR szwTable = NULL; LPWSTR szwTable = NULL;

View file

@ -179,7 +179,7 @@ static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform
} }
if (wanted_flags & MSITRANSFORM_VALIDATE_PRODUCT) if (wanted_flags & MSITRANSFORM_VALIDATE_PRODUCT)
{ {
WCHAR *product_code_installed = msi_dup_property( package->db, szProductCode ); WCHAR *product_code_installed = msi_dup_property( package->db, L"ProductCode" );
if (!product_code_installed) if (!product_code_installed)
{ {
@ -197,7 +197,7 @@ static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform
msi_free( template ); msi_free( template );
if (wanted_flags & MSITRANSFORM_VALIDATE_MAJORVERSION) if (wanted_flags & MSITRANSFORM_VALIDATE_MAJORVERSION)
{ {
WCHAR *product_version_installed = msi_dup_property( package->db, szProductVersion ); WCHAR *product_version_installed = msi_dup_property( package->db, L"ProductVersion" );
DWORD major_installed, minor_installed, major, minor; DWORD major_installed, minor_installed, major, minor;
if (!product_version_installed) if (!product_version_installed)
@ -218,7 +218,7 @@ static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform
} }
else if (wanted_flags & MSITRANSFORM_VALIDATE_MINORVERSION) else if (wanted_flags & MSITRANSFORM_VALIDATE_MINORVERSION)
{ {
WCHAR *product_version_installed = msi_dup_property( package->db, szProductVersion ); WCHAR *product_version_installed = msi_dup_property( package->db, L"ProductVersion" );
DWORD major_installed, minor_installed, major, minor; DWORD major_installed, minor_installed, major, minor;
if (!product_version_installed) if (!product_version_installed)
@ -236,7 +236,7 @@ static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform
} }
if (wanted_flags & MSITRANSFORM_VALIDATE_UPGRADECODE) if (wanted_flags & MSITRANSFORM_VALIDATE_UPGRADECODE)
{ {
WCHAR *upgrade_code_installed = msi_dup_property( package->db, szUpgradeCode ); WCHAR *upgrade_code_installed = msi_dup_property( package->db, L"UpgradeCode" );
if (!upgrade_code_installed) if (!upgrade_code_installed)
{ {
@ -296,7 +296,7 @@ UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
LPWSTR guid_list, *guids, product_code; LPWSTR guid_list, *guids, product_code;
UINT i, ret = ERROR_FUNCTION_FAILED; UINT i, ret = ERROR_FUNCTION_FAILED;
product_code = msi_dup_property( package->db, szProductCode ); product_code = msi_dup_property( package->db, L"ProductCode" );
if (!product_code) if (!product_code)
{ {
/* FIXME: the property ProductCode should be written into the DB somewhere */ /* FIXME: the property ProductCode should be written into the DB somewhere */
@ -368,17 +368,13 @@ static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
static UINT patch_set_media_source_prop( MSIPACKAGE *package ) static UINT patch_set_media_source_prop( MSIPACKAGE *package )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','`','S','o','u','r','c','e','`',' ','F','R','O','M',' ',
'`','M','e','d','i','a','`',' ','W','H','E','R','E',' ','`','S','o','u','r','c','e','`',' ',
'I','S',' ','N','O','T',' ','N','U','L','L',0};
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
const WCHAR *property; const WCHAR *property;
WCHAR *patch; WCHAR *patch;
UINT r; UINT r;
r = MSI_DatabaseOpenViewW( package->db, query, &view ); r = MSI_DatabaseOpenViewW( package->db, L"SELECT `Source` FROM `Media` WHERE `Source` IS NOT NULL", &view );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; return r;
@ -389,7 +385,7 @@ static UINT patch_set_media_source_prop( MSIPACKAGE *package )
if (MSI_ViewFetch( view, &rec ) == ERROR_SUCCESS) if (MSI_ViewFetch( view, &rec ) == ERROR_SUCCESS)
{ {
property = MSI_RecordGetString( rec, 1 ); property = MSI_RecordGetString( rec, 1 );
patch = msi_dup_property( package->db, szPatch ); patch = msi_dup_property( package->db, L"PATCH" );
msi_set_property( package->db, property, patch, -1 ); msi_set_property( package->db, property, patch, -1 );
msi_free( patch ); msi_free( patch );
msiobj_release( &rec->hdr ); msiobj_release( &rec->hdr );
@ -444,15 +440,11 @@ static void patch_offset_list_free( struct patch_offset_list *pos )
static void patch_offset_get_filepatches( MSIDATABASE *db, UINT last_sequence, struct patch_offset_list *pos ) static void patch_offset_get_filepatches( MSIDATABASE *db, UINT last_sequence, struct patch_offset_list *pos )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','P','a','t','c','h',' ',
'W','H','E','R','E',' ','S','e','q','u','e','n','c','e',' ','<','=',' ','?',' ',
'O','R','D','E','R',' ','B','Y',' ','S','e','q','u','e','n','c','e',0};
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
UINT r; UINT r;
r = MSI_DatabaseOpenViewW( db, query, &view ); r = MSI_DatabaseOpenViewW( db, L"SELECT * FROM `Patch` WHERE `Sequence` <= ? ORDER BY `Sequence`", &view );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return; return;
@ -482,15 +474,11 @@ static void patch_offset_get_filepatches( MSIDATABASE *db, UINT last_sequence, s
static void patch_offset_get_files( MSIDATABASE *db, UINT last_sequence, struct patch_offset_list *pos ) static void patch_offset_get_files( MSIDATABASE *db, UINT last_sequence, struct patch_offset_list *pos )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','F','i','l','e',' ',
'W','H','E','R','E',' ','S','e','q','u','e','n','c','e',' ','<','=',' ','?',' ',
'O','R','D','E','R',' ','B','Y',' ','S','e','q','u','e','n','c','e',0};
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
UINT r; UINT r;
r = MSI_DatabaseOpenViewW( db, query, &view ); r = MSI_DatabaseOpenViewW( db, L"SELECT * FROM `File` WHERE `Sequence` <= ? ORDER BY `Sequence`", &view );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return; return;
@ -545,16 +533,6 @@ static UINT patch_update_file_sequence( MSIDATABASE *db, const struct patch_offs
static UINT patch_update_filepatch_sequence( MSIDATABASE *db, const struct patch_offset_list *pos, static UINT patch_update_filepatch_sequence( MSIDATABASE *db, const struct patch_offset_list *pos,
MSIQUERY *view, MSIRECORD *rec ) MSIQUERY *view, MSIRECORD *rec )
{ {
static const WCHAR delete_query[] = {
'D','E','L','E','T','E',' ','F','R','O','M',' ','`','P','a','t','c','h','`',' ',
'W','H','E','R','E',' ','`','F','i','l','e','_','`',' ','=',' ','?',' ',
'A','N','D',' ','`','S','e','q','u','e','n','c','e','`',' ','=',' ','?',0};
static const WCHAR insert_query[] = {
'I','N','S','E','R','T',' ','I','N','T','O',' ','`','P','a','t','c','h','`',' ',
'(','`','F','i','l','e','_','`',',','`','S','e','q','u','e','n','c','e','`',',',
'`','P','a','t','c','h','S','i','z','e','`',',','`','A','t','t','r','i','b','u','t','e','s','`',',',
'`','H','e','a','d','e','r','`',',','`','S','t','r','e','a','m','R','e','f','_','`',')',' ',
'V','A','L','U','E','S',' ','(','?',',','?',',','?',',','?',',','?',',','?',')',0};
struct patch_offset *po; struct patch_offset *po;
const WCHAR *file = MSI_RecordGetString( rec, 1 ); const WCHAR *file = MSI_RecordGetString( rec, 1 );
UINT r = ERROR_SUCCESS, seq = MSI_RecordGetInteger( rec, 2 ); UINT r = ERROR_SUCCESS, seq = MSI_RecordGetInteger( rec, 2 );
@ -566,7 +544,7 @@ static UINT patch_update_filepatch_sequence( MSIDATABASE *db, const struct patch
MSIQUERY *delete_view, *insert_view; MSIQUERY *delete_view, *insert_view;
MSIRECORD *rec2; MSIRECORD *rec2;
r = MSI_DatabaseOpenViewW( db, delete_query, &delete_view ); r = MSI_DatabaseOpenViewW( db, L"DELETE FROM `Patch` WHERE `File_` = ? AND `Sequence` = ?", &delete_view );
if (r != ERROR_SUCCESS) return r; if (r != ERROR_SUCCESS) return r;
rec2 = MSI_CreateRecord( 2 ); rec2 = MSI_CreateRecord( 2 );
@ -577,7 +555,8 @@ static UINT patch_update_filepatch_sequence( MSIDATABASE *db, const struct patch
msiobj_release( &rec2->hdr ); msiobj_release( &rec2->hdr );
if (r != ERROR_SUCCESS) return r; if (r != ERROR_SUCCESS) return r;
r = MSI_DatabaseOpenViewW( db, insert_query, &insert_view ); r = MSI_DatabaseOpenViewW( db, L"INSERT INTO `Patch` (`File_`,`Sequence`,`PatchSize`,`Attributes`,"
L"`Header`,`StreamRef_`) VALUES (?,?,?,?,?,?)", &insert_view );
if (r != ERROR_SUCCESS) return r; if (r != ERROR_SUCCESS) return r;
MSI_RecordSetInteger( rec, 2, po->sequence + pos->offset_to_apply ); MSI_RecordSetInteger( rec, 2, po->sequence + pos->offset_to_apply );
@ -594,21 +573,13 @@ static UINT patch_update_filepatch_sequence( MSIDATABASE *db, const struct patch
static UINT patch_offset_modify_db( MSIDATABASE *db, struct patch_offset_list *pos ) static UINT patch_offset_modify_db( MSIDATABASE *db, struct patch_offset_list *pos )
{ {
static const WCHAR file_query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','F','i','l','e','`',' ',
'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ','>','=',' ','?',' ',
'A','N','D',' ','`','S','e','q','u','e','n','c','e','`',' ','<','=',' ','?',' ',
'O','R','D','E','R',' ','B','Y',' ','`','S','e','q','u','e','n','c','e','`',0};
static const WCHAR patch_query[] = {
'S','E','L','E','C','T',' ','*','F','R','O','M',' ','`','P','a','t','c','h','`',' ',
'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ','>','=',' ','?',' ',
'A','N','D',' ','`','S','e','q','u','e','n','c','e','`',' ','<','=',' ','?',' ',
'O','R','D','E','R',' ','B','Y',' ','`','S','e','q','u','e','n','c','e','`',0};
MSIRECORD *rec; MSIRECORD *rec;
MSIQUERY *view; MSIQUERY *view;
UINT r, min = pos->min, max = pos->max, r_fetch; UINT r, min = pos->min, max = pos->max, r_fetch;
r = MSI_DatabaseOpenViewW( db, file_query, &view ); r = MSI_DatabaseOpenViewW( db,
L"SELECT * FROM `File` WHERE `Sequence` >= ? AND `Sequence` <= ? ORDER BY `Sequence`",
&view );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -629,7 +600,9 @@ static UINT patch_offset_modify_db( MSIDATABASE *db, struct patch_offset_list *p
} }
msiobj_release( &view->hdr ); msiobj_release( &view->hdr );
r = MSI_DatabaseOpenViewW( db, patch_query, &view ); r = MSI_DatabaseOpenViewW( db,
L"SELECT *FROM `Patch` WHERE `Sequence` >= ? AND `Sequence` <= ? ORDER BY `Sequence`",
&view );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -654,11 +627,8 @@ done:
return r; return r;
} }
static const WCHAR patch_media_query[] = { static const WCHAR patch_media_query[] =
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','M','e','d','i','a','`',' ', L"SELECT * FROM `Media` WHERE `Source` IS NOT NULL AND `Cabinet` IS NOT NULL ORDER BY `DiskId`";
'W','H','E','R','E',' ','`','S','o','u','r','c','e','`',' ','I','S',' ','N','O','T',' ','N','U','L','L',' ',
'A','N','D',' ','`','C','a','b','i','n','e','t','`',' ','I','S',' ','N','O','T',' ','N','U','L','L',' ',
'O','R','D','E','R',' ','B','Y',' ','`','D','i','s','k','I','d','`',0};
struct patch_media struct patch_media
{ {
@ -673,15 +643,6 @@ struct patch_media
static UINT patch_add_media( MSIPACKAGE *package, IStorage *storage, MSIPATCHINFO *patch ) static UINT patch_add_media( MSIPACKAGE *package, IStorage *storage, MSIPATCHINFO *patch )
{ {
static const WCHAR delete_query[] = {
'D','E','L','E','T','E',' ','F','R','O','M',' ','`','M','e','d','i','a','`',' ',
'W','H','E','R','E',' ','`','D','i','s','k','I','d','`','=','?',0};
static const WCHAR insert_query[] = {
'I','N','S','E','R','T',' ','I','N','T','O',' ','`','M','e','d','i','a','`',' ',
'(','`','D','i','s','k','I','d','`',',','`','L','a','s','t','S','e','q','u','e','n','c','e','`',',',
'`','D','i','s','k','P','r','o','m','p','t','`',',','`','C','a','b','i','n','e','t','`',',',
'`','V','o','l','u','m','e','L','a','b','e','l','`',',','`','S','o','u','r','c','e','`',')',' ',
'V','A','L','U','E','S',' ','(','?',',','?',',','?',',','?',',','?',',','?',')',0};
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
UINT r, disk_id; UINT r, disk_id;
@ -708,10 +669,11 @@ static UINT patch_add_media( MSIPACKAGE *package, IStorage *storage, MSIPATCHINF
msiobj_release( &rec->hdr ); msiobj_release( &rec->hdr );
continue; continue;
} }
if (!(media = msi_alloc( sizeof( *media )))) { if (!(media = msi_alloc( sizeof( *media ))))
{
msiobj_release( &rec->hdr ); msiobj_release( &rec->hdr );
goto done; goto done;
} }
media->disk_id = disk_id; media->disk_id = disk_id;
media->last_sequence = MSI_RecordGetInteger( rec, 2 ); media->last_sequence = MSI_RecordGetInteger( rec, 2 );
media->prompt = msi_dup_record_field( rec, 3 ); media->prompt = msi_dup_record_field( rec, 3 );
@ -726,7 +688,7 @@ static UINT patch_add_media( MSIPACKAGE *package, IStorage *storage, MSIPATCHINF
{ {
MSIQUERY *delete_view, *insert_view; MSIQUERY *delete_view, *insert_view;
r = MSI_DatabaseOpenViewW( package->db, delete_query, &delete_view ); r = MSI_DatabaseOpenViewW( package->db, L"DELETE FROM `Media` WHERE `DiskId`=?", &delete_view );
if (r != ERROR_SUCCESS) goto done; if (r != ERROR_SUCCESS) goto done;
rec = MSI_CreateRecord( 1 ); rec = MSI_CreateRecord( 1 );
@ -737,7 +699,9 @@ static UINT patch_add_media( MSIPACKAGE *package, IStorage *storage, MSIPATCHINF
msiobj_release( &rec->hdr ); msiobj_release( &rec->hdr );
if (r != ERROR_SUCCESS) goto done; if (r != ERROR_SUCCESS) goto done;
r = MSI_DatabaseOpenViewW( package->db, insert_query, &insert_view ); r = MSI_DatabaseOpenViewW( package->db, L"INSERT INTO `Media` (`DiskId`,`LastSequence`,`DiskPrompt`,"
L"`Cabinet`,`VolumeLabel`,`Source`) VALUES (?,?,?,?,?,?)",
&insert_view );
if (r != ERROR_SUCCESS) goto done; if (r != ERROR_SUCCESS) goto done;
disk_id = package->db->media_transform_disk_id; disk_id = package->db->media_transform_disk_id;
@ -842,17 +806,12 @@ done:
static DWORD is_uninstallable( MSIDATABASE *db ) static DWORD is_uninstallable( MSIDATABASE *db )
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ','F','R','O','M',' ',
'`','M','s','i','P','a','t','c','h','M','e','t','a','d','a','t','a','`',' ',
'W','H','E','R','E',' ','`','C','o','m','p','a','n','y','`',' ','I','S',' ',
'N','U','L','L',' ','A','N','D',' ','`','P','r','o','p','e','r','t','y','`','=',
'\'','A','l','l','o','w','R','e','m','o','v','a','l','\'',0};
MSIQUERY *view; MSIQUERY *view;
MSIRECORD *rec; MSIRECORD *rec;
DWORD ret = 0; DWORD ret = 0;
if (MSI_DatabaseOpenViewW( db, query, &view ) != ERROR_SUCCESS) return 0; if (MSI_DatabaseOpenViewW( db, L"SELECT `Value` FROM `MsiPatchMetadata` WHERE `Company` IS NULL "
L"AND `Property`='AllowRemoval'", &view ) != ERROR_SUCCESS) return 0;
if (MSI_ViewExecute( view, 0 ) != ERROR_SUCCESS) if (MSI_ViewExecute( view, 0 ) != ERROR_SUCCESS)
{ {
msiobj_release( &view->hdr ); msiobj_release( &view->hdr );
@ -915,7 +874,6 @@ void msi_free_patchinfo( MSIPATCHINFO *patch )
static UINT msi_apply_patch_package( MSIPACKAGE *package, const WCHAR *file ) static UINT msi_apply_patch_package( MSIPACKAGE *package, const WCHAR *file )
{ {
static const WCHAR dotmsp[] = {'.','m','s','p',0};
MSIDATABASE *patch_db = NULL; MSIDATABASE *patch_db = NULL;
WCHAR localfile[MAX_PATH]; WCHAR localfile[MAX_PATH];
MSISUMMARYINFO *si; MSISUMMARYINFO *si;
@ -947,7 +905,7 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, const WCHAR *file )
if ( r != ERROR_SUCCESS ) if ( r != ERROR_SUCCESS )
goto done; goto done;
r = msi_create_empty_local_file( localfile, dotmsp ); r = msi_create_empty_local_file( localfile, L".msp" );
if ( r != ERROR_SUCCESS ) if ( r != ERROR_SUCCESS )
goto done; goto done;
@ -976,7 +934,7 @@ UINT msi_apply_patches( MSIPACKAGE *package )
LPWSTR patch_list, *patches; LPWSTR patch_list, *patches;
UINT i, r = ERROR_SUCCESS; UINT i, r = ERROR_SUCCESS;
patch_list = msi_dup_property( package->db, szPatch ); patch_list = msi_dup_property( package->db, L"PATCH" );
TRACE("patches to be applied: %s\n", debugstr_w(patch_list)); TRACE("patches to be applied: %s\n", debugstr_w(patch_list));
@ -991,11 +949,10 @@ UINT msi_apply_patches( MSIPACKAGE *package )
UINT msi_apply_transforms( MSIPACKAGE *package ) UINT msi_apply_transforms( MSIPACKAGE *package )
{ {
static const WCHAR szTransforms[] = {'T','R','A','N','S','F','O','R','M','S',0};
LPWSTR xform_list, *xforms; LPWSTR xform_list, *xforms;
UINT i, r = ERROR_SUCCESS; UINT i, r = ERROR_SUCCESS;
xform_list = msi_dup_property( package->db, szTransforms ); xform_list = msi_dup_property( package->db, L"TRANSFORMS" );
xforms = msi_split_string( xform_list, ';' ); xforms = msi_split_string( xform_list, ';' );
for (i = 0; xforms && xforms[i] && r == ERROR_SUCCESS; i++) for (i = 0; xforms && xforms[i] && r == ERROR_SUCCESS; i++)

View file

@ -147,7 +147,7 @@ static BOOL string2intW( LPCWSTR str, int *out )
if( str[0] == '-' ) /* check if it's negative */ if( str[0] == '-' ) /* check if it's negative */
x = -x; x = -x;
*out = x; *out = x;
return TRUE; return TRUE;
} }
@ -439,7 +439,6 @@ const WCHAR *MSI_RecordGetString( const MSIRECORD *rec, UINT iField )
UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField, UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField,
LPWSTR szValue, LPDWORD pcchValue) LPWSTR szValue, LPDWORD pcchValue)
{ {
static const WCHAR szFormat[] = {'%','d',0};
UINT len = 0, ret = ERROR_SUCCESS; UINT len = 0, ret = ERROR_SUCCESS;
WCHAR buffer[16]; WCHAR buffer[16];
@ -457,7 +456,7 @@ UINT MSI_RecordGetStringW(MSIRECORD *rec, UINT iField,
switch( rec->fields[iField].type ) switch( rec->fields[iField].type )
{ {
case MSIFIELD_INT: case MSIFIELD_INT:
wsprintfW(buffer, szFormat, rec->fields[iField].u.iVal); wsprintfW(buffer, L"%d", rec->fields[iField].u.iVal);
len = lstrlenW( buffer ); len = lstrlenW( buffer );
if (szValue) if (szValue)
lstrcpynW(szValue, buffer, *pcchValue); lstrcpynW(szValue, buffer, *pcchValue);

View file

@ -773,8 +773,8 @@ UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
if (!squash_guid( szPatch, squashed_pc )) return ERROR_FUNCTION_FAILED; if (!squash_guid( szPatch, squashed_pc )) return ERROR_FUNCTION_FAILED;
TRACE("%s squashed %s\n", debugstr_w(szPatch), debugstr_w(squashed_pc)); TRACE("%s squashed %s\n", debugstr_w(szPatch), debugstr_w(squashed_pc));
swprintf( keypath, ARRAY_SIZE(keypath), L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Patches", lstrcpyW( keypath, L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Patches\\" );
squashed_pc ); lstrcatW( keypath, squashed_pc );
if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL); if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key); return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);

View file

@ -49,10 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
#endif #endif
static const WCHAR szJScript[] = { 'J','S','c','r','i','p','t',0};
static const WCHAR szVBScript[] = { 'V','B','S','c','r','i','p','t',0};
static const WCHAR szSession[] = {'S','e','s','s','i','o','n',0};
/* /*
* MsiActiveScriptSite - Our IActiveScriptSite implementation. * MsiActiveScriptSite - Our IActiveScriptSite implementation.
*/ */
@ -135,7 +131,7 @@ static HRESULT WINAPI MsiActiveScriptSite_GetItemInfo(IActiveScriptSite* iface,
} }
/* Are we looking for the session object? */ /* Are we looking for the session object? */
if (!wcscmp(szSession, pstrName)) { if (!wcscmp(L"Session", pstrName)) {
if (dwReturnMask & SCRIPTINFO_ITYPEINFO) { if (dwReturnMask & SCRIPTINFO_ITYPEINFO) {
HRESULT hr = get_typeinfo(Session_tid, ppti); HRESULT hr = get_typeinfo(Session_tid, ppti);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -319,9 +315,9 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
/* Create the scripting engine */ /* Create the scripting engine */
type &= msidbCustomActionTypeJScript|msidbCustomActionTypeVBScript; type &= msidbCustomActionTypeJScript|msidbCustomActionTypeVBScript;
if (type == msidbCustomActionTypeJScript) if (type == msidbCustomActionTypeJScript)
hr = CLSIDFromProgID(szJScript, &clsid); hr = CLSIDFromProgID(L"JScript", &clsid);
else if (type == msidbCustomActionTypeVBScript) else if (type == msidbCustomActionTypeVBScript)
hr = CLSIDFromProgID(szVBScript, &clsid); hr = CLSIDFromProgID(L"VBScript", &clsid);
else { else {
ERR("Unknown script type %d\n", type); ERR("Unknown script type %d\n", type);
goto done; goto done;
@ -345,7 +341,7 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
hr = IActiveScriptParse_InitNew(pActiveScriptParse); hr = IActiveScriptParse_InitNew(pActiveScriptParse);
if (FAILED(hr)) goto done; if (FAILED(hr)) goto done;
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS|SCRIPTITEM_ISVISIBLE); hr = IActiveScript_AddNamedItem(pActiveScript, L"Session", SCRIPTITEM_GLOBALMEMBERS|SCRIPTITEM_ISVISIBLE);
if (FAILED(hr)) goto done; if (FAILED(hr)) goto done;
hr = IActiveScriptParse_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL); hr = IActiveScriptParse_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);

View file

@ -236,10 +236,10 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *na
n = sv->cols[ n - 1 ]; n = sv->cols[ n - 1 ];
if( !n ) if( !n )
{ {
if (name) *name = szEmpty; if (name) *name = L"";
if (type) *type = MSITYPE_UNKNOWN | MSITYPE_VALID; if (type) *type = MSITYPE_UNKNOWN | MSITYPE_VALID;
if (temporary) *temporary = FALSE; if (temporary) *temporary = FALSE;
if (table_name) *table_name = szEmpty; if (table_name) *table_name = L"";
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
return sv->table->ops->get_column_info( sv->table, n, name, return sv->table->ops->get_column_info( sv->table, n, name,
@ -404,7 +404,7 @@ static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name,
} }
sv->cols[sv->num_cols] = n; sv->cols[sv->num_cols] = n;
TRACE("Translating column %s from %d -> %d\n", TRACE("Translating column %s from %d -> %d\n",
debugstr_w( name ), sv->num_cols, n); debugstr_w( name ), sv->num_cols, n);
sv->num_cols++; sv->num_cols++;
@ -433,7 +433,7 @@ UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
sv = msi_alloc_zero( FIELD_OFFSET( MSISELECTVIEW, cols[count] )); sv = msi_alloc_zero( FIELD_OFFSET( MSISELECTVIEW, cols[count] ));
if( !sv ) if( !sv )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
/* fill the structure */ /* fill the structure */
sv->view.ops = &select_ops; sv->view.ops = &select_ops;
sv->db = db; sv->db = db;

View file

@ -53,7 +53,7 @@ typedef struct tagMediaInfo
static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions, static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions,
MSIINSTALLCONTEXT context, BOOL create) MSIINSTALLCONTEXT context, BOOL create)
{ {
HKEY rootkey = 0; HKEY rootkey = 0;
UINT rc = ERROR_FUNCTION_FAILED; UINT rc = ERROR_FUNCTION_FAILED;
if (context == MSIINSTALLCONTEXT_USERUNMANAGED) if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
@ -90,10 +90,10 @@ static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions,
} }
if (create) if (create)
rc = RegCreateKeyW(rootkey, szSourceList, key); rc = RegCreateKeyW(rootkey, L"SourceList", key);
else else
{ {
rc = RegOpenKeyW(rootkey,szSourceList, key); rc = RegOpenKeyW(rootkey, L"SourceList", key);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
rc = ERROR_BAD_CONFIGURATION; rc = ERROR_BAD_CONFIGURATION;
} }
@ -105,12 +105,11 @@ static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, DWORD dwOptions,
static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create) static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
{ {
UINT rc; UINT rc;
static const WCHAR media[] = {'M','e','d','i','a',0};
if (create) if (create)
rc = RegCreateKeyW(rootkey, media, key); rc = RegCreateKeyW(rootkey, L"Media", key);
else else
rc = RegOpenKeyW(rootkey,media, key); rc = RegOpenKeyW(rootkey, L"Media", key);
return rc; return rc;
} }
@ -118,12 +117,11 @@ static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create) static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
{ {
UINT rc; UINT rc;
static const WCHAR net[] = {'N','e','t',0};
if (create) if (create)
rc = RegCreateKeyW(rootkey, net, key); rc = RegCreateKeyW(rootkey, L"Net", key);
else else
rc = RegOpenKeyW(rootkey, net, key); rc = RegOpenKeyW(rootkey, L"Net", key);
return rc; return rc;
} }
@ -131,12 +129,11 @@ static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create) static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
{ {
UINT rc; UINT rc;
static const WCHAR URL[] = {'U','R','L',0};
if (create) if (create)
rc = RegCreateKeyW(rootkey, URL, key); rc = RegCreateKeyW(rootkey, L"URL", key);
else else
rc = RegOpenKeyW(rootkey, URL, key); rc = RegOpenKeyW(rootkey, L"URL", key);
return rc; return rc;
} }
@ -208,7 +205,6 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
LPWSTR szVolumeLabel, LPDWORD pcchVolumeLabel, LPWSTR szVolumeLabel, LPDWORD pcchVolumeLabel,
LPWSTR szDiskPrompt, LPDWORD pcchDiskPrompt) LPWSTR szDiskPrompt, LPDWORD pcchDiskPrompt)
{ {
static const WCHAR fmt[] = {'#','%','d',0};
WCHAR squashed_pc[SQUASHED_GUID_SIZE], convert[11]; WCHAR squashed_pc[SQUASHED_GUID_SIZE], convert[11];
WCHAR *value = NULL, *data = NULL, *ptr, *ptr2; WCHAR *value = NULL, *data = NULL, *ptr, *ptr2;
HKEY source, media; HKEY source, media;
@ -285,7 +281,7 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
{ {
if (type == REG_DWORD) if (type == REG_DWORD)
{ {
swprintf(convert, ARRAY_SIZE(convert), fmt, *data); swprintf(convert, ARRAY_SIZE(convert), L"#%d", *data);
size = lstrlenW(convert); size = lstrlenW(convert);
ptr2 = convert; ptr2 = convert;
} }
@ -307,7 +303,7 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode,
if (type == REG_DWORD) if (type == REG_DWORD)
{ {
swprintf(convert, ARRAY_SIZE(convert), fmt, *ptr); swprintf(convert, ARRAY_SIZE(convert), L"#%d", *ptr);
size = lstrlenW(convert); size = lstrlenW(convert);
ptr = convert; ptr = convert;
} }
@ -412,7 +408,6 @@ UINT WINAPI MsiSourceListEnumSourcesW(LPCWSTR szProductCodeOrPatch, LPCWSTR szUs
DWORD dwOptions, DWORD dwIndex, DWORD dwOptions, DWORD dwIndex,
LPWSTR szSource, LPDWORD pcchSource) LPWSTR szSource, LPDWORD pcchSource)
{ {
static const WCHAR format[] = {'%','d',0};
WCHAR squashed_pc[SQUASHED_GUID_SIZE], name[32]; WCHAR squashed_pc[SQUASHED_GUID_SIZE], name[32];
HKEY source = NULL, subkey = NULL; HKEY source = NULL, subkey = NULL;
LONG res; LONG res;
@ -458,7 +453,7 @@ UINT WINAPI MsiSourceListEnumSourcesW(LPCWSTR szProductCodeOrPatch, LPCWSTR szUs
goto done; goto done;
} }
swprintf(name, ARRAY_SIZE(name), format, dwIndex + 1); swprintf(name, ARRAY_SIZE(name), L"%d", dwIndex + 1);
res = RegQueryValueExW(subkey, name, 0, 0, (LPBYTE)szSource, pcchSource); res = RegQueryValueExW(subkey, name, 0, 0, (LPBYTE)szSource, pcchSource);
if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
@ -536,10 +531,9 @@ done:
*/ */
UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid, UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions, MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
LPCWSTR szProperty, LPWSTR szValue, LPCWSTR szProperty, LPWSTR szValue,
LPDWORD pcchValue) LPDWORD pcchValue)
{ {
static const WCHAR mediapack[] = {'M','e','d','i','a','P','a','c','k','a','g','e',0};
WCHAR *source, *ptr, squashed_pc[SQUASHED_GUID_SIZE]; WCHAR *source, *ptr, squashed_pc[SQUASHED_GUID_SIZE];
HKEY sourcekey, media; HKEY sourcekey, media;
DWORD size; DWORD size;
@ -579,7 +573,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
} }
if (!wcscmp( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW )) if (!wcscmp( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ))
szProperty = mediapack; szProperty = L"MediaPackage";
RegQueryValueExW(media, szProperty, 0, 0, (LPBYTE)szValue, pcchValue); RegQueryValueExW(media, szProperty, 0, 0, (LPBYTE)szValue, pcchValue);
RegCloseKey(media); RegCloseKey(media);
@ -591,7 +585,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
0, 0, NULL, &size); 0, 0, NULL, &size);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
static WCHAR szEmpty[1] = { '\0' }; static WCHAR szEmpty[] = {0};
rc = ERROR_SUCCESS; rc = ERROR_SUCCESS;
source = NULL; source = NULL;
ptr = szEmpty; ptr = szEmpty;
@ -709,8 +703,6 @@ UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
UINT r; UINT r;
int index = 1; int index = 1;
static const WCHAR format[] = {'%','c',';','%','i',';','%','s',0};
if (options & MSISOURCETYPE_NETWORK) if (options & MSISOURCETYPE_NETWORK)
typechar = 'n'; typechar = 'n';
else if (options & MSISOURCETYPE_URL) else if (options & MSISOURCETYPE_URL)
@ -736,7 +728,7 @@ UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
return r; return r;
} }
size = lstrlenW(format) + lstrlenW(value) + 7; size = lstrlenW(L"%c;%d;%s") + lstrlenW(value) + 7;
buffer = msi_alloc(size * sizeof(WCHAR)); buffer = msi_alloc(size * sizeof(WCHAR));
if (!buffer) if (!buffer)
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -748,7 +740,7 @@ UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
return r; return r;
} }
swprintf(buffer, size, format, typechar, index, value); swprintf(buffer, size, L"%c;%d;%s", typechar, index, value);
size = (lstrlenW(buffer) + 1) * sizeof(WCHAR); size = (lstrlenW(buffer) + 1) * sizeof(WCHAR);
r = RegSetValueExW(source, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, r = RegSetValueExW(source, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
@ -766,7 +758,6 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions, MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
LPCWSTR szProperty, LPCWSTR szValue) LPCWSTR szProperty, LPCWSTR szValue)
{ {
static const WCHAR media_package[] = {'M','e','d','i','a','P','a','c','k','a','g','e',0};
WCHAR squashed_pc[SQUASHED_GUID_SIZE]; WCHAR squashed_pc[SQUASHED_GUID_SIZE];
HKEY sourcekey, media; HKEY sourcekey, media;
LPCWSTR property; LPCWSTR property;
@ -795,7 +786,7 @@ UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
property = szProperty; property = szProperty;
if (!wcscmp( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW )) if (!wcscmp( szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW ))
property = media_package; property = L"MediaPackage";
rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE); rc = OpenSourceKey(szProduct, &sourcekey, MSICODE_PRODUCT, dwContext, FALSE);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
@ -896,7 +887,7 @@ UINT WINAPI MsiSourceListAddSourceW( LPCWSTR szProduct, LPCWSTR szUserName,
RegCloseKey(hkey); RegCloseKey(hkey);
} }
ret = MsiSourceListAddSourceExW(szProduct, sidstr, ret = MsiSourceListAddSourceExW(szProduct, sidstr,
context, MSISOURCETYPE_NETWORK, szSource, 0); context, MSISOURCETYPE_NETWORK, szSource, 0);
if (sidstr) if (sidstr)
@ -968,7 +959,6 @@ static void add_source_to_list(struct list *sourcelist, media_info *info,
{ {
media_info *iter; media_info *iter;
BOOL found = FALSE; BOOL found = FALSE;
static const WCHAR fmt[] = {'%','i',0};
if (index) *index = 0; if (index) *index = 0;
@ -988,7 +978,7 @@ static void add_source_to_list(struct list *sourcelist, media_info *info,
/* update the rest of the list */ /* update the rest of the list */
if (found) if (found)
swprintf(iter->szIndex, ARRAY_SIZE(iter->szIndex), fmt, ++iter->index); swprintf(iter->szIndex, ARRAY_SIZE(iter->szIndex), L"%d", ++iter->index);
else if (index) else if (index)
(*index)++; (*index)++;
} }
@ -1052,10 +1042,9 @@ error:
* MsiSourceListAddSourceExW (MSI.@) * MsiSourceListAddSourceExW (MSI.@)
*/ */
UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid, UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
DWORD dwIndex) DWORD dwIndex)
{ {
static const WCHAR fmt[] = {'%','i',0};
HKEY sourcekey, typekey; HKEY sourcekey, typekey;
UINT rc; UINT rc;
struct list sourcelist; struct list sourcelist;
@ -1108,7 +1097,7 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
return rc; return rc;
} }
postfix = (dwOptions & MSISOURCETYPE_NETWORK) ? szBackSlash : szForwardSlash; postfix = (dwOptions & MSISOURCETYPE_NETWORK) ? L"\\" : L"/";
if (szSource[lstrlenW(szSource) - 1] == *postfix) if (szSource[lstrlenW(szSource) - 1] == *postfix)
source = strdupW(szSource); source = strdupW(szSource);
else else
@ -1128,18 +1117,18 @@ UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
if (count == 0) if (count == 0)
{ {
rc = RegSetValueExW(typekey, szOne, 0, REG_EXPAND_SZ, (LPBYTE)source, size); rc = RegSetValueExW(typekey, L"1", 0, REG_EXPAND_SZ, (LPBYTE)source, size);
goto done; goto done;
} }
else if (dwIndex > count || dwIndex == 0) else if (dwIndex > count || dwIndex == 0)
{ {
swprintf(name, ARRAY_SIZE(name), fmt, count + 1); swprintf(name, ARRAY_SIZE(name), L"%d", count + 1);
rc = RegSetValueExW(typekey, name, 0, REG_EXPAND_SZ, (LPBYTE)source, size); rc = RegSetValueExW(typekey, name, 0, REG_EXPAND_SZ, (LPBYTE)source, size);
goto done; goto done;
} }
else else
{ {
swprintf(name, ARRAY_SIZE(name), fmt, dwIndex); swprintf(name, ARRAY_SIZE(name), L"%d", dwIndex);
info = msi_alloc(sizeof(media_info)); info = msi_alloc(sizeof(media_info));
if (!info) if (!info)
{ {
@ -1205,11 +1194,10 @@ UINT WINAPI MsiSourceListAddMediaDiskA(LPCSTR szProduct, LPCSTR szUserSid,
/****************************************************************** /******************************************************************
* MsiSourceListAddMediaDiskW (MSI.@) * MsiSourceListAddMediaDiskW (MSI.@)
*/ */
UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid, UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt) LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
{ {
static const WCHAR fmt[] = {'%','i',0};
HKEY sourcekey, mediakey; HKEY sourcekey, mediakey;
UINT rc; UINT rc;
WCHAR *buffer, squashed_pc[SQUASHED_GUID_SIZE], szIndex[10]; WCHAR *buffer, squashed_pc[SQUASHED_GUID_SIZE], szIndex[10];
@ -1243,7 +1231,7 @@ UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
OpenMediaSubkey(sourcekey, &mediakey, TRUE); OpenMediaSubkey(sourcekey, &mediakey, TRUE);
swprintf(szIndex, ARRAY_SIZE(szIndex), fmt, dwDiskId); swprintf(szIndex, ARRAY_SIZE(szIndex), L"%d", dwDiskId);
size = 2; size = 2;
if (szVolumeLabel) size += lstrlenW(szVolumeLabel); if (szVolumeLabel) size += lstrlenW(szVolumeLabel);
@ -1254,7 +1242,7 @@ UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
*buffer = '\0'; *buffer = '\0';
if (szVolumeLabel) lstrcpyW(buffer, szVolumeLabel); if (szVolumeLabel) lstrcpyW(buffer, szVolumeLabel);
lstrcatW(buffer, szSemiColon); lstrcatW(buffer, L";");
if (szDiskPrompt) lstrcatW(buffer, szDiskPrompt); if (szDiskPrompt) lstrcatW(buffer, szDiskPrompt);
RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size); RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);

View file

@ -740,7 +740,6 @@ number:
static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table ) static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table )
{ {
static const WCHAR space[] = {' ',0};
DWORD len = lstrlenW( list ) + lstrlenW( table ) + 2; DWORD len = lstrlenW( list ) + lstrlenW( table ) + 2;
LPWSTR ret; LPWSTR ret;
@ -748,7 +747,7 @@ static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table )
if( ret ) if( ret )
{ {
lstrcpyW( ret, list ); lstrcpyW( ret, list );
lstrcatW( ret, space ); lstrcatW( ret, L" " );
lstrcatW( ret, table ); lstrcatW( ret, table );
} }
return ret; return ret;

View file

@ -316,16 +316,16 @@ static UINT STORAGES_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *
switch (n) switch (n)
{ {
case 1: case 1:
if (name) *name = szName; if (name) *name = L"Name";
if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MAX_STORAGES_NAME_LEN; if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MAX_STORAGES_NAME_LEN;
break; break;
case 2: case 2:
if (name) *name = szData; if (name) *name = L"Data";
if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MSITYPE_NULLABLE; if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MSITYPE_NULLABLE;
break; break;
} }
if (table_name) *table_name = szStorages; if (table_name) *table_name = L"_Storages";
if (temporary) *temporary = FALSE; if (temporary) *temporary = FALSE;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View file

@ -278,16 +278,16 @@ static UINT STREAMS_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *n
switch (n) switch (n)
{ {
case 1: case 1:
if (name) *name = szName; if (name) *name = L"Name";
if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MAX_STREAM_NAME_LEN; if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MAX_STREAM_NAME_LEN;
break; break;
case 2: case 2:
if (name) *name = szData; if (name) *name = L"Data";
if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MSITYPE_NULLABLE; if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MSITYPE_NULLABLE;
break; break;
} }
if (table_name) *table_name = szStreams; if (table_name) *table_name = L"_Streams";
if (temporary) *temporary = FALSE; if (temporary) *temporary = FALSE;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -614,7 +614,7 @@ UINT msi_commit_streams( MSIDATABASE *db )
for (i = 0; i < db->num_streams; i++) for (i = 0; i < db->num_streams; i++)
{ {
name = msi_string_lookup( db->strings, db->streams[i].str_index, NULL ); name = msi_string_lookup( db->strings, db->streams[i].str_index, NULL );
if (!wcscmp( name, szSumInfo )) continue; if (!wcscmp( name, L"\5SummaryInformation" )) continue;
if (!(encname = encode_streamname( FALSE, name ))) return ERROR_OUTOFMEMORY; if (!(encname = encode_streamname( FALSE, name ))) return ERROR_OUTOFMEMORY;
TRACE("saving stream %s as %s\n", debugstr_w(name), debugstr_w(encname)); TRACE("saving stream %s as %s\n", debugstr_w(name), debugstr_w(encname));

View file

@ -77,7 +77,7 @@ static string_table *init_stringtable( int entries, UINT codepage )
st = msi_alloc( sizeof (string_table) ); st = msi_alloc( sizeof (string_table) );
if( !st ) if( !st )
return NULL; return NULL;
if( entries < 1 ) if( entries < 1 )
entries = 1; entries = 1;
@ -85,7 +85,7 @@ static string_table *init_stringtable( int entries, UINT codepage )
if( !st->strings ) if( !st->strings )
{ {
msi_free( st ); msi_free( st );
return NULL; return NULL;
} }
st->sorted = msi_alloc( sizeof (UINT) * entries ); st->sorted = msi_alloc( sizeof (UINT) * entries );
@ -347,7 +347,7 @@ const WCHAR *msi_string_lookup( const string_table *st, UINT id, int *len )
if( id == 0 ) if( id == 0 )
{ {
if (len) *len = 0; if (len) *len = 0;
return szEmpty; return L"";
} }
if( id >= st->maxcount ) if( id >= st->maxcount )
return NULL; return NULL;
@ -465,12 +465,12 @@ HRESULT msi_init_string_table( IStorage *stg )
UINT ret; UINT ret;
/* create the StringPool stream... add the zero string to it*/ /* create the StringPool stream... add the zero string to it*/
ret = write_stream_data(stg, szStringPool, zero, sizeof zero, TRUE); ret = write_stream_data(stg, L"_StringPool", zero, sizeof zero, TRUE);
if (ret != ERROR_SUCCESS) if (ret != ERROR_SUCCESS)
return E_FAIL; return E_FAIL;
/* create the StringData stream... make it zero length */ /* create the StringData stream... make it zero length */
ret = write_stream_data(stg, szStringData, NULL, 0, TRUE); ret = write_stream_data(stg, L"_StringData", NULL, 0, TRUE);
if (ret != ERROR_SUCCESS) if (ret != ERROR_SUCCESS)
return E_FAIL; return E_FAIL;
@ -485,10 +485,10 @@ string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref )
UINT r, datasize = 0, poolsize = 0, codepage; UINT r, datasize = 0, poolsize = 0, codepage;
DWORD i, count, offset, len, n, refs; DWORD i, count, offset, len, n, refs;
r = read_stream_data( stg, szStringPool, TRUE, (BYTE **)&pool, &poolsize ); r = read_stream_data( stg, L"_StringPool", TRUE, (BYTE **)&pool, &poolsize );
if( r != ERROR_SUCCESS) if( r != ERROR_SUCCESS)
goto end; goto end;
r = read_stream_data( stg, szStringData, TRUE, (BYTE **)&data, &datasize ); r = read_stream_data( stg, L"_StringData", TRUE, (BYTE **)&data, &datasize );
if( r != ERROR_SUCCESS) if( r != ERROR_SUCCESS)
goto end; goto end;
@ -652,11 +652,11 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *byt
} }
/* write the streams */ /* write the streams */
r = write_stream_data( storage, szStringData, data, datasize, TRUE ); r = write_stream_data( storage, L"_StringData", data, datasize, TRUE );
TRACE("Wrote StringData r=%08x\n", r); TRACE("Wrote StringData r=%08x\n", r);
if( r ) if( r )
goto err; goto err;
r = write_stream_data( storage, szStringPool, pool, poolsize, TRUE ); r = write_stream_data( storage, L"_StringPool", pool, poolsize, TRUE );
TRACE("Wrote StringPool r=%08x\n", r); TRACE("Wrote StringPool r=%08x\n", r);
if( r ) if( r )
goto err; goto err;

View file

@ -44,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
#include "pshpack1.h" #include "pshpack1.h"
typedef struct { typedef struct {
WORD wByteOrder; WORD wByteOrder;
WORD wFormat; WORD wFormat;
DWORD dwOSVer; DWORD dwOSVer;
@ -52,20 +52,20 @@ typedef struct {
DWORD reserved; DWORD reserved;
} PROPERTYSETHEADER; } PROPERTYSETHEADER;
typedef struct { typedef struct {
FMTID fmtid; FMTID fmtid;
DWORD dwOffset; DWORD dwOffset;
} FORMATIDOFFSET; } FORMATIDOFFSET;
typedef struct { typedef struct {
DWORD cbSection; DWORD cbSection;
DWORD cProperties; DWORD cProperties;
} PROPERTYSECTIONHEADER; } PROPERTYSECTIONHEADER;
typedef struct { typedef struct {
DWORD propid; DWORD propid;
DWORD dwOffset; DWORD dwOffset;
} PROPERTYIDOFFSET; } PROPERTYIDOFFSET;
typedef struct { typedef struct {
DWORD type; DWORD type;
@ -79,7 +79,7 @@ typedef struct {
} str; } str;
} u; } u;
} PROPERTY_DATA; } PROPERTY_DATA;
#include "poppack.h" #include "poppack.h"
static HRESULT (WINAPI *pPropVariantChangeType) static HRESULT (WINAPI *pPropVariantChangeType)
@ -466,7 +466,7 @@ UINT msi_get_suminfo( IStorage *stg, UINT uiUpdateCount, MSISUMMARYINFO **ret )
if (!(si = create_suminfo( stg, uiUpdateCount ))) return ERROR_OUTOFMEMORY; if (!(si = create_suminfo( stg, uiUpdateCount ))) return ERROR_OUTOFMEMORY;
hr = IStorage_OpenStream( si->storage, szSumInfo, 0, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stm ); hr = IStorage_OpenStream( si->storage, L"\5SummaryInformation", 0, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stm );
if (FAILED( hr )) if (FAILED( hr ))
{ {
msiobj_release( &si->hdr ); msiobj_release( &si->hdr );
@ -493,7 +493,7 @@ UINT msi_get_db_suminfo( MSIDATABASE *db, UINT uiUpdateCount, MSISUMMARYINFO **r
if (!(si = create_suminfo( db->storage, uiUpdateCount ))) return ERROR_OUTOFMEMORY; if (!(si = create_suminfo( db->storage, uiUpdateCount ))) return ERROR_OUTOFMEMORY;
r = msi_get_stream( db, szSumInfo, &stm ); r = msi_get_stream( db, L"\5SummaryInformation", &stm );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{ {
msiobj_release( &si->hdr ); msiobj_release( &si->hdr );
@ -512,7 +512,7 @@ UINT msi_get_db_suminfo( MSIDATABASE *db, UINT uiUpdateCount, MSISUMMARYINFO **r
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase, UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle ) LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle )
{ {
MSISUMMARYINFO *si; MSISUMMARYINFO *si;
@ -583,7 +583,7 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
return ret; return ret;
} }
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase,
LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle) LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
{ {
LPWSTR szwDatabase = NULL; LPWSTR szwDatabase = NULL;
@ -979,7 +979,7 @@ static UINT suminfo_persist( MSISUMMARYINFO *si )
HRESULT r; HRESULT r;
grfMode = STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE; grfMode = STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
r = IStorage_CreateStream( si->storage, szSumInfo, grfMode, 0, 0, &stm ); r = IStorage_CreateStream( si->storage, L"\5SummaryInformation", grfMode, 0, 0, &stm );
if( SUCCEEDED(r) ) if( SUCCEEDED(r) )
{ {
ret = save_summary_info( si, stm ); ret = save_summary_info( si, stm );
@ -1266,7 +1266,6 @@ UINT WINAPI MsiCreateTransformSummaryInfoW( MSIHANDLE db, MSIHANDLE db_ref, LPCW
UINT msi_load_suminfo_properties( MSIPACKAGE *package ) UINT msi_load_suminfo_properties( MSIPACKAGE *package )
{ {
static const WCHAR packagecodeW[] = {'P','a','c','k','a','g','e','C','o','d','e',0};
MSISUMMARYINFO *si; MSISUMMARYINFO *si;
WCHAR *package_code; WCHAR *package_code;
UINT r, len; UINT r, len;
@ -1307,7 +1306,7 @@ UINT msi_load_suminfo_properties( MSIPACKAGE *package )
return r; return r;
} }
r = msi_set_property( package->db, packagecodeW, package_code, len ); r = msi_set_property( package->db, L"PackageCode", package_code, len );
msi_free( package_code ); msi_free( package_code );
count = 0; count = 0;

View file

@ -71,21 +71,15 @@ struct tagMSITABLE
}; };
/* information for default tables */ /* information for default tables */
static const WCHAR szTables[] = {'_','T','a','b','l','e','s',0};
static const WCHAR szTable[] = {'T','a','b','l','e',0};
static const WCHAR szColumns[] = {'_','C','o','l','u','m','n','s',0};
static const WCHAR szNumber[] = {'N','u','m','b','e','r',0};
static const WCHAR szType[] = {'T','y','p','e',0};
static const MSICOLUMNINFO _Columns_cols[4] = { static const MSICOLUMNINFO _Columns_cols[4] = {
{ szColumns, 1, szTable, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, NULL }, { L"_Columns", 1, L"Table", MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, NULL },
{ szColumns, 2, szNumber, MSITYPE_VALID | MSITYPE_KEY | 2, 2, NULL }, { L"_Columns", 2, L"Number", MSITYPE_VALID | MSITYPE_KEY | 2, 2, NULL },
{ szColumns, 3, szName, MSITYPE_VALID | MSITYPE_STRING | 64, 4, NULL }, { L"_Columns", 3, L"Name", MSITYPE_VALID | MSITYPE_STRING | 64, 4, NULL },
{ szColumns, 4, szType, MSITYPE_VALID | 2, 6, NULL }, { L"_Columns", 4, L"Type", MSITYPE_VALID | 2, 6, NULL },
}; };
static const MSICOLUMNINFO _Tables_cols[1] = { static const MSICOLUMNINFO _Tables_cols[1] = {
{ szTables, 1, szName, MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, NULL }, { L"_Tables", 1, L"Name", MSITYPE_VALID | MSITYPE_STRING | MSITYPE_KEY | 64, 0, NULL },
}; };
#define MAX_STREAM_NAME 0x1f #define MAX_STREAM_NAME 0x1f
@ -138,7 +132,7 @@ LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
*p++ = 0x4840; *p++ = 0x4840;
count --; count --;
} }
while( count -- ) while( count -- )
{ {
ch = *in++; ch = *in++;
if( !ch ) if( !ch )
@ -251,7 +245,7 @@ UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table,
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname)); TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
r = IStorage_OpenStream(stg, encname, NULL, r = IStorage_OpenStream(stg, encname, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm); STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
msi_free( encname ); msi_free( encname );
if( FAILED( r ) ) if( FAILED( r ) )
@ -272,7 +266,7 @@ UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table,
WARN("Too big!\n"); WARN("Too big!\n");
goto end; goto end;
} }
sz = stat.cbSize.QuadPart; sz = stat.cbSize.QuadPart;
data = msi_alloc( sz ); data = msi_alloc( sz );
if( !data ) if( !data )
@ -281,7 +275,7 @@ UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table,
ret = ERROR_NOT_ENOUGH_MEMORY; ret = ERROR_NOT_ENOUGH_MEMORY;
goto end; goto end;
} }
r = IStream_Read(stm, data, sz, &count ); r = IStream_Read(stm, data, sz, &count );
if( FAILED( r ) || ( count != sz ) ) if( FAILED( r ) || ( count != sz ) )
{ {
@ -312,7 +306,7 @@ UINT write_stream_data( IStorage *stg, LPCWSTR stname,
LPWSTR encname; LPWSTR encname;
encname = encode_streamname(bTable, stname ); encname = encode_streamname(bTable, stname );
r = IStorage_OpenStream( stg, encname, NULL, r = IStorage_OpenStream( stg, encname, NULL,
STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &stm); STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
if( FAILED(r) ) if( FAILED(r) )
{ {
@ -520,12 +514,12 @@ static UINT get_defaulttablecolumns( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINF
TRACE("%s\n", debugstr_w(name)); TRACE("%s\n", debugstr_w(name));
if (!wcscmp( name, szTables )) if (!wcscmp( name, L"_Tables" ))
{ {
p = _Tables_cols; p = _Tables_cols;
n = 1; n = 1;
} }
else if (!wcscmp( name, szColumns )) else if (!wcscmp( name, L"_Columns" ))
{ {
p = _Columns_cols; p = _Columns_cols;
n = 4; n = 4;
@ -603,7 +597,7 @@ static UINT get_table( MSIDATABASE *db, LPCWSTR name, MSITABLE **table_ret )
table->persistent = MSICONDITION_TRUE; table->persistent = MSICONDITION_TRUE;
lstrcpyW( table->name, name ); lstrcpyW( table->name, name );
if (!wcscmp( name, szTables ) || !wcscmp( name, szColumns )) if (!wcscmp( name, L"_Tables" ) || !wcscmp( name, L"_Columns" ))
table->persistent = MSICONDITION_NONE; table->persistent = MSICONDITION_NONE;
r = table_get_column_info( db, name, &table->colinfo, &table->col_count ); r = table_get_column_info( db, name, &table->colinfo, &table->col_count );
@ -645,7 +639,7 @@ static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINF
if (r == ERROR_SUCCESS && *sz) if (r == ERROR_SUCCESS && *sz)
return r; return r;
r = get_table( db, szColumns, &table ); r = get_table( db, L"_Columns", &table );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{ {
ERR("couldn't load _Columns table\n"); ERR("couldn't load _Columns table\n");
@ -766,7 +760,7 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info,
} }
table_calc_column_offsets( db, table->colinfo, table->col_count); table_calc_column_offsets( db, table->colinfo, table->col_count);
r = TABLE_CreateView( db, szTables, &tv ); r = TABLE_CreateView( db, L"_Tables", &tv );
TRACE("CreateView returned %x\n", r); TRACE("CreateView returned %x\n", r);
if( r ) if( r )
{ {
@ -801,7 +795,7 @@ UINT msi_create_table( MSIDATABASE *db, LPCWSTR name, column_info *col_info,
if( persistent != MSICONDITION_FALSE ) if( persistent != MSICONDITION_FALSE )
{ {
/* add each column to the _Columns table */ /* add each column to the _Columns table */
r = TABLE_CreateView( db, szColumns, &tv ); r = TABLE_CreateView( db, L"_Columns", &tv );
if( r ) if( r )
goto err; goto err;
@ -969,8 +963,8 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name )
UINT r, table_id, i; UINT r, table_id, i;
MSITABLE *table; MSITABLE *table;
if( !wcscmp( name, szTables ) || !wcscmp( name, szColumns ) || if( !wcscmp( name, L"_Tables" ) || !wcscmp( name, L"_Columns" ) ||
!wcscmp( name, szStreams ) || !wcscmp( name, szStorages ) ) !wcscmp( name, L"_Streams" ) || !wcscmp( name, L"_Storages" ) )
return TRUE; return TRUE;
r = msi_string2id( db->strings, name, -1, &table_id ); r = msi_string2id( db->strings, name, -1, &table_id );
@ -980,10 +974,10 @@ BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name )
return FALSE; return FALSE;
} }
r = get_table( db, szTables, &table ); r = get_table( db, L"_Tables", &table );
if( r != ERROR_SUCCESS ) if( r != ERROR_SUCCESS )
{ {
ERR("table %s not available\n", debugstr_w(szTables)); ERR("table _Tables not available\n");
return FALSE; return FALSE;
} }
@ -1088,16 +1082,15 @@ static UINT get_stream_name( const MSITABLEVIEW *tv, UINT row, WCHAR **pstname )
} }
else else
{ {
static const WCHAR fmt[] = { '%','d',0 };
UINT n = bytes_per_column( tv->db, &tv->columns[i], LONG_STR_BYTES ); UINT n = bytes_per_column( tv->db, &tv->columns[i], LONG_STR_BYTES );
switch( n ) switch( n )
{ {
case 2: case 2:
swprintf( number, ARRAY_SIZE(number), fmt, ival-0x8000 ); swprintf( number, ARRAY_SIZE(number), L"%d", ival-0x8000 );
break; break;
case 4: case 4:
swprintf( number, ARRAY_SIZE(number), fmt, ival^0x80000000 ); swprintf( number, ARRAY_SIZE(number), L"%d", ival^0x80000000 );
break; break;
default: default:
ERR( "oops - unknown column width %d\n", n ); ERR( "oops - unknown column width %d\n", n );
@ -1107,7 +1100,7 @@ static UINT get_stream_name( const MSITABLEVIEW *tv, UINT row, WCHAR **pstname )
sval = number; sval = number;
} }
len += lstrlenW( szDot ) + lstrlenW( sval ); len += lstrlenW( L"." ) + lstrlenW( sval );
p = msi_realloc ( stname, len*sizeof(WCHAR) ); p = msi_realloc ( stname, len*sizeof(WCHAR) );
if ( !p ) if ( !p )
{ {
@ -1116,7 +1109,7 @@ static UINT get_stream_name( const MSITABLEVIEW *tv, UINT row, WCHAR **pstname )
} }
stname = p; stname = p;
lstrcatW( stname, szDot ); lstrcatW( stname, L"." );
lstrcatW( stname, sval ); lstrcatW( stname, sval );
} }
else else
@ -1295,15 +1288,6 @@ static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
static UINT add_stream( MSIDATABASE *db, const WCHAR *name, IStream *data ) static UINT add_stream( MSIDATABASE *db, const WCHAR *name, IStream *data )
{ {
static const WCHAR insert[] = {
'I','N','S','E','R','T',' ','I','N','T','O',' ',
'`','_','S','t','r','e','a','m','s','`',' ',
'(','`','N','a','m','e','`',',','`','D','a','t','a','`',')',' ',
'V','A','L','U','E','S',' ','(','?',',','?',')',0};
static const WCHAR update[] = {
'U','P','D','A','T','E',' ','`','_','S','t','r','e','a','m','s','`',' ',
'S','E','T',' ','`','D','a','t','a','`',' ','=',' ','?',' ',
'W','H','E','R','E',' ','`','N','a','m','e','`',' ','=',' ','?',0};
MSIQUERY *query; MSIQUERY *query;
MSIRECORD *rec; MSIRECORD *rec;
UINT r; UINT r;
@ -1321,7 +1305,7 @@ static UINT add_stream( MSIDATABASE *db, const WCHAR *name, IStream *data )
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
r = MSI_DatabaseOpenViewW( db, insert, &query ); r = MSI_DatabaseOpenViewW( db, L"INSERT INTO `_Streams` (`Name`,`Data`) VALUES (?,?)", &query );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
@ -1342,7 +1326,7 @@ static UINT add_stream( MSIDATABASE *db, const WCHAR *name, IStream *data )
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
r = MSI_DatabaseOpenViewW( db, update, &query ); r = MSI_DatabaseOpenViewW( db, L"UPDATE `_Streams` SET `Data` = ? WHERE `Name` = ?", &query );
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
@ -1560,7 +1544,7 @@ static UINT TABLE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
static UINT TABLE_close( struct tagMSIVIEW *view ) static UINT TABLE_close( struct tagMSIVIEW *view )
{ {
TRACE("%p\n", view ); TRACE("%p\n", view );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -1977,7 +1961,7 @@ static UINT TABLE_remove_column(struct tagMSIVIEW *view, UINT number)
MSI_RecordSetStringW(rec, 1, tv->name); MSI_RecordSetStringW(rec, 1, tv->name);
MSI_RecordSetInteger(rec, 2, number); MSI_RecordSetInteger(rec, 2, number);
r = TABLE_CreateView(tv->db, szColumns, &columns); r = TABLE_CreateView(tv->db, L"_Columns", &columns);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{ {
msiobj_release(&rec->hdr); msiobj_release(&rec->hdr);
@ -2110,7 +2094,7 @@ static UINT TABLE_add_column(struct tagMSIVIEW *view, LPCWSTR column,
MSI_RecordSetStringW(rec, 3, column); MSI_RecordSetStringW(rec, 3, column);
MSI_RecordSetInteger(rec, 4, type); MSI_RecordSetInteger(rec, 4, type);
r = TABLE_CreateView(tv->db, szColumns, &columns); r = TABLE_CreateView(tv->db, L"_Columns", &columns);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{ {
tv->table->col_count--; tv->table->col_count--;
@ -2155,7 +2139,7 @@ static UINT TABLE_drop(struct tagMSIVIEW *view)
MSI_RecordSetStringW(rec, 1, tv->name); MSI_RecordSetStringW(rec, 1, tv->name);
r = TABLE_CreateView(tv->db, szTables, &tables); r = TABLE_CreateView(tv->db, L"_Tables", &tables);
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
{ {
msiobj_release(&rec->hdr); msiobj_release(&rec->hdr);
@ -2210,9 +2194,9 @@ UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view )
TRACE("%p %s %p\n", db, debugstr_w(name), view ); TRACE("%p %s %p\n", db, debugstr_w(name), view );
if ( !wcscmp( name, szStreams ) ) if ( !wcscmp( name, L"_Streams" ) )
return STREAMS_CreateView( db, view ); return STREAMS_CreateView( db, view );
else if ( !wcscmp( name, szStorages ) ) else if ( !wcscmp( name, L"_Storages" ) )
return STORAGES_CreateView( db, view ); return STORAGES_CreateView( db, view );
sz = FIELD_OFFSET( MSITABLEVIEW, name[lstrlenW( name ) + 1] ); sz = FIELD_OFFSET( MSITABLEVIEW, name[lstrlenW( name ) + 1] );
@ -2345,13 +2329,13 @@ static UINT TransformView_set_row( MSIVIEW *view, UINT row, MSIRECORD *rec, UINT
WCHAR *key; WCHAR *key;
UINT i, p, r, len, qlen; UINT i, p, r, len, qlen;
if (!wcscmp( tv->name, szColumns )) if (!wcscmp( tv->name, L"_Columns" ))
{ {
ERR( "trying to modify existing column\n" ); ERR( "trying to modify existing column\n" );
return ERROR_INSTALL_TRANSFORM_FAILURE; return ERROR_INSTALL_TRANSFORM_FAILURE;
} }
if (!wcscmp( tv->name, szTables )) if (!wcscmp( tv->name, L"_Tables" ))
{ {
ERR( "trying to modify existing table\n" ); ERR( "trying to modify existing table\n" );
return ERROR_INSTALL_TRANSFORM_FAILURE; return ERROR_INSTALL_TRANSFORM_FAILURE;
@ -2578,10 +2562,10 @@ static UINT TransformView_insert_row( MSIVIEW *view, MSIRECORD *rec, UINT row, B
int len; int len;
UINT r; UINT r;
if (!wcscmp(tv->name, szTables)) if (!wcscmp(tv->name, L"_Tables"))
return TransformView_create_table( tv, rec ); return TransformView_create_table( tv, rec );
if (!wcscmp(tv->name, szColumns)) if (!wcscmp(tv->name, L"_Columns"))
return TransformView_add_column( tv, rec ); return TransformView_add_column( tv, rec );
key = create_key_string( tv, rec ); key = create_key_string( tv, rec );
@ -2671,13 +2655,13 @@ static UINT TransformView_delete_row( MSIVIEW *view, UINT row )
MSIRECORD *rec; MSIRECORD *rec;
MSIQUERY *q; MSIQUERY *q;
if (!wcscmp( tv->name, szColumns )) if (!wcscmp( tv->name, L"_Columns" ))
{ {
ERR("trying to remove column\n"); ERR("trying to remove column\n");
return ERROR_INSTALL_TRANSFORM_FAILURE; return ERROR_INSTALL_TRANSFORM_FAILURE;
} }
if (!wcscmp( tv->name, szTables )) if (!wcscmp( tv->name, L"_Tables" ))
return TransformView_drop_table( tv, row ); return TransformView_drop_table( tv, row );
r = msi_view_get_row( tv->db, view, row, &rec ); r = msi_view_get_row( tv->db, view, row, &rec );
@ -3296,7 +3280,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
UINT number = MSI_NULL_INTEGER; UINT number = MSI_NULL_INTEGER;
UINT row = 0; UINT row = 0;
if (!wcscmp( name, szColumns )) if (!wcscmp( name, L"_Columns" ))
{ {
MSI_RecordGetStringW( rec, 1, table, &sz ); MSI_RecordGetStringW( rec, 1, table, &sz );
number = MSI_RecordGetInteger( rec, 2 ); number = MSI_RecordGetInteger( rec, 2 );
@ -3358,7 +3342,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
} }
if (!(err_cond & MSITRANSFORM_ERROR_VIEWTRANSFORM) && if (!(err_cond & MSITRANSFORM_ERROR_VIEWTRANSFORM) &&
!wcscmp( name, szColumns )) !wcscmp( name, L"_Columns" ))
msi_update_table_columns( db, table ); msi_update_table_columns( db, table );
msiobj_release( &rec->hdr ); msiobj_release( &rec->hdr );
@ -3422,8 +3406,8 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg, int err_cond )
if ( name[0] != 0x4840 ) if ( name[0] != 0x4840 )
continue; continue;
if ( !wcscmp( name+1, szStringPool ) || if ( !wcscmp( name+1, L"_StringPool" ) ||
!wcscmp( name+1, szStringData ) ) !wcscmp( name+1, L"_StringData" ) )
continue; continue;
transform = msi_alloc_zero( sizeof(TRANSFORMDATA) ); transform = msi_alloc_zero( sizeof(TRANSFORMDATA) );
@ -3434,11 +3418,11 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg, int err_cond )
transform->name = strdupW( name + 1 ); transform->name = strdupW( name + 1 );
if ( !wcscmp( transform->name, szTables ) ) if ( !wcscmp( transform->name, L"_Tables" ) )
tables = transform; tables = transform;
else if (!wcscmp( transform->name, szColumns ) ) else if (!wcscmp( transform->name, L"_Columns" ) )
columns = transform; columns = transform;
else if (!wcscmp( transform->name, szProperty )) else if (!wcscmp( transform->name, L"Property" ))
property_update = TRUE; property_update = TRUE;
TRACE("transform contains stream %s\n", debugstr_w(name)); TRACE("transform contains stream %s\n", debugstr_w(name));
@ -3462,6 +3446,7 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg, int err_cond )
L"`Table` CHAR(0) NOT NULL TEMPORARY, `Column` CHAR(0) NOT NULL TEMPORARY, " L"`Table` CHAR(0) NOT NULL TEMPORARY, `Column` CHAR(0) NOT NULL TEMPORARY, "
L"`Row` CHAR(0) TEMPORARY, `Data` CHAR(0) TEMPORARY, `Current` CHAR(0) TEMPORARY " L"`Row` CHAR(0) TEMPORARY, `Data` CHAR(0) TEMPORARY, `Current` CHAR(0) TEMPORARY "
L"PRIMARY KEY `Table`, `Column`, `Row` ) HOLD"; L"PRIMARY KEY `Table`, `Column`, `Row` ) HOLD";
MSIQUERY *query; MSIQUERY *query;
UINT r; UINT r;
@ -3506,8 +3491,8 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg, int err_cond )
{ {
transform = LIST_ENTRY( list_head( &transforms ), TRANSFORMDATA, entry ); transform = LIST_ENTRY( list_head( &transforms ), TRANSFORMDATA, entry );
if ( wcscmp( transform->name, szColumns ) && if ( wcscmp( transform->name, L"_Columns" ) &&
wcscmp( transform->name, szTables ) && wcscmp( transform->name, L"_Tables" ) &&
ret == ERROR_SUCCESS ) ret == ERROR_SUCCESS )
{ {
ret = msi_table_load_transform( db, stg, strings, transform, bytes_per_strref, err_cond ); ret = msi_table_load_transform( db, stg, strings, transform, bytes_per_strref, err_cond );

View file

@ -97,13 +97,13 @@ static void append_productcode( MSIPACKAGE *package, const WCHAR *action_prop, c
if (prop) if (prop)
{ {
lstrcpyW( newprop, prop ); lstrcpyW( newprop, prop );
lstrcatW( newprop, szSemiColon ); lstrcatW( newprop, L";" );
} }
else newprop[0] = 0; else newprop[0] = 0;
lstrcatW( newprop, product ); lstrcatW( newprop, product );
r = msi_set_property( package->db, action_prop, newprop, -1 ); r = msi_set_property( package->db, action_prop, newprop, -1 );
if (r == ERROR_SUCCESS && !wcscmp( action_prop, szSourceDir )) if (r == ERROR_SUCCESS && !wcscmp( action_prop, L"SourceDir" ))
msi_reset_source_folders( package ); msi_reset_source_folders( package );
TRACE( "related product property %s now %s\n", debugstr_w(action_prop), debugstr_w(newprop) ); TRACE( "related product property %s now %s\n", debugstr_w(action_prop), debugstr_w(newprop) );
@ -210,35 +210,32 @@ static UINT ITERATE_FindRelatedProducts(MSIRECORD *rec, LPVOID param)
} }
RegCloseKey(hkey); RegCloseKey(hkey);
msiobj_release( &uirow->hdr); msiobj_release( &uirow->hdr);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
UINT ACTION_FindRelatedProducts(MSIPACKAGE *package) UINT ACTION_FindRelatedProducts(MSIPACKAGE *package)
{ {
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','U','p','g','r','a','d','e','`',0};
MSIQUERY *view; MSIQUERY *view;
UINT rc; UINT rc;
if (msi_get_property_int(package->db, szInstalled, 0)) if (msi_get_property_int(package->db, L"Installed", 0))
{ {
TRACE("Skipping FindRelatedProducts action: product already installed\n"); TRACE("Skipping FindRelatedProducts action: product already installed\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
if (msi_action_is_unique(package, szFindRelatedProducts)) if (msi_action_is_unique(package, L"FindRelatedProducts"))
{ {
TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n"); TRACE("Skipping FindRelatedProducts action: already done in UI sequence\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
else else
msi_register_unique_action(package, szFindRelatedProducts); msi_register_unique_action(package, L"FindRelatedProducts");
rc = MSI_DatabaseOpenViewW(package->db, query, &view); rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Upgrade`", &view);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
rc = MSI_IterateRecords(view, NULL, ITERATE_FindRelatedProducts, package); rc = MSI_IterateRecords(view, NULL, ITERATE_FindRelatedProducts, package);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
return rc; return rc;

View file

@ -1235,7 +1235,7 @@ UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR tables,
wv = msi_alloc_zero( sizeof *wv ); wv = msi_alloc_zero( sizeof *wv );
if( !wv ) if( !wv )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
/* fill the structure */ /* fill the structure */
wv->view.ops = &where_ops; wv->view.ops = &where_ops;
msiobj_addref( &db->hdr ); msiobj_addref( &db->hdr );