Commit 15f85201 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Disable filesystem redirection only when really needed.

parent 3d0cf846
...@@ -718,50 +718,6 @@ MSIFOLDER *msi_get_loaded_folder( MSIPACKAGE *package, const WCHAR *dir ) ...@@ -718,50 +718,6 @@ MSIFOLDER *msi_get_loaded_folder( MSIPACKAGE *package, const WCHAR *dir )
return NULL; return NULL;
} }
/*
* Recursively create all directories in the path.
* shamelessly stolen from setupapi/queue.c
*/
BOOL msi_create_full_path( const WCHAR *path )
{
BOOL ret = TRUE;
WCHAR *new_path;
int len;
new_path = msi_alloc( (strlenW( path ) + 1) * sizeof(WCHAR) );
strcpyW( new_path, path );
while ((len = strlenW( new_path )) && new_path[len - 1] == '\\')
new_path[len - 1] = 0;
while (!CreateDirectoryW( new_path, NULL ))
{
WCHAR *slash;
DWORD last_error = GetLastError();
if (last_error == ERROR_ALREADY_EXISTS) break;
if (last_error != ERROR_PATH_NOT_FOUND)
{
ret = FALSE;
break;
}
if (!(slash = strrchrW( new_path, '\\' )))
{
ret = FALSE;
break;
}
len = slash - new_path;
new_path[len] = 0;
if (!msi_create_full_path( new_path ))
{
ret = FALSE;
break;
}
new_path[len] = '\\';
}
msi_free( new_path );
return ret;
}
void msi_ui_progress( MSIPACKAGE *package, int a, int b, int c, int d ) void msi_ui_progress( MSIPACKAGE *package, int a, int b, int c, int d )
{ {
MSIRECORD *row; MSIRECORD *row;
...@@ -843,8 +799,9 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) ...@@ -843,8 +799,9 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
TRACE("folder is %s\n", debugstr_w(full_path)); TRACE("folder is %s\n", debugstr_w(full_path));
folder = msi_get_loaded_folder( package, dir ); folder = msi_get_loaded_folder( package, dir );
if (folder->State == FOLDER_STATE_UNINITIALIZED) msi_create_full_path( full_path ); if (folder->State == FOLDER_STATE_UNINITIALIZED) msi_create_full_path( package, full_path );
folder->State = FOLDER_STATE_CREATED; folder->State = FOLDER_STATE_CREATED;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -2054,37 +2011,6 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) ...@@ -2054,37 +2011,6 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
VS_FIXEDFILEINFO *msi_get_disk_file_version( LPCWSTR filename )
{
static const WCHAR name[] = {'\\',0};
VS_FIXEDFILEINFO *ptr, *ret;
LPVOID version;
DWORD versize, handle;
UINT sz;
versize = GetFileVersionInfoSizeW( filename, &handle );
if (!versize)
return NULL;
version = msi_alloc( versize );
if (!version)
return NULL;
GetFileVersionInfoW( filename, 0, versize, version );
if (!VerQueryValueW( version, name, (LPVOID *)&ptr, &sz ))
{
msi_free( version );
return NULL;
}
ret = msi_alloc( sz );
memcpy( ret, ptr, sz );
msi_free( version );
return ret;
}
int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version ) int msi_compare_file_versions( VS_FIXEDFILEINFO *fi, const WCHAR *version )
{ {
DWORD ms, ls; DWORD ms, ls;
...@@ -2110,33 +2036,6 @@ int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) ...@@ -2110,33 +2036,6 @@ int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 )
return 0; return 0;
} }
DWORD msi_get_disk_file_size( LPCWSTR filename )
{
HANDLE file;
DWORD size;
file = CreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
if (file == INVALID_HANDLE_VALUE)
return INVALID_FILE_SIZE;
size = GetFileSize( file, NULL );
CloseHandle( file );
return size;
}
BOOL msi_file_hash_matches( MSIFILE *file )
{
UINT r;
MSIFILEHASHINFO hash;
hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
r = msi_get_filehash( file->TargetPath, &hash );
if (r != ERROR_SUCCESS)
return FALSE;
return !memcmp( &hash, &file->hash, sizeof(MSIFILEHASHINFO) );
}
static WCHAR *create_temp_dir( MSIDATABASE *db ) static WCHAR *create_temp_dir( MSIDATABASE *db )
{ {
static UINT id; static UINT id;
...@@ -2262,17 +2161,17 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) ...@@ -2262,17 +2161,17 @@ static UINT calculate_file_cost( MSIPACKAGE *package )
set_target_path( package, file ); set_target_path( package, file );
if ((comp->assembly && !comp->assembly->installed) || if ((comp->assembly && !comp->assembly->installed) ||
GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES) msi_get_file_attributes( package, file->TargetPath ) == INVALID_FILE_ATTRIBUTES)
{ {
comp->Cost += file->FileSize; comp->Cost += file->FileSize;
continue; continue;
} }
file_size = msi_get_disk_file_size( file->TargetPath ); file_size = msi_get_disk_file_size( package, file->TargetPath );
TRACE("%s (size %u)\n", debugstr_w(file->TargetPath), file_size); TRACE("%s (size %u)\n", debugstr_w(file->TargetPath), file_size);
if (file->Version) if (file->Version)
{ {
if ((file_version = msi_get_disk_file_version( file->TargetPath ))) if ((file_version = msi_get_disk_file_version( package, file->TargetPath )))
{ {
if (msi_compare_file_versions( file_version, file->Version ) < 0) if (msi_compare_file_versions( file_version, file->Version ) < 0)
{ {
...@@ -2281,7 +2180,7 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) ...@@ -2281,7 +2180,7 @@ static UINT calculate_file_cost( MSIPACKAGE *package )
msi_free( file_version ); msi_free( file_version );
continue; continue;
} }
else if ((font_version = msi_font_version_from_file( file->TargetPath ))) else if ((font_version = msi_get_font_file_version( package, file->TargetPath )))
{ {
if (msi_compare_font_versions( font_version, file->Version ) < 0) if (msi_compare_font_versions( font_version, file->Version ) < 0)
{ {
...@@ -2296,6 +2195,7 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) ...@@ -2296,6 +2195,7 @@ static UINT calculate_file_cost( MSIPACKAGE *package )
comp->Cost += file->FileSize - file_size; comp->Cost += file->FileSize - file_size;
} }
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -3754,6 +3654,24 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType, ...@@ -3754,6 +3654,24 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType,
return TRUE; return TRUE;
} }
static HMODULE msi_load_library( MSIPACKAGE *package, const WCHAR *filename, DWORD flags )
{
HMODULE module;
msi_disable_fs_redirection( package );
module = LoadLibraryExW( filename, NULL, flags );
msi_revert_fs_redirection( package );
return module;
}
static HRESULT msi_load_typelib( MSIPACKAGE *package, const WCHAR *filename, REGKIND kind, ITypeLib **lib )
{
HRESULT hr;
msi_disable_fs_redirection( package );
hr = LoadTypeLibEx( filename, kind, lib );
msi_revert_fs_redirection( package );
return hr;
}
static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE* package = param; MSIPACKAGE* package = param;
...@@ -3784,7 +3702,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) ...@@ -3784,7 +3702,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
} }
MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row); MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);
module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE ); module = msi_load_library( package, file->TargetPath, LOAD_LIBRARY_AS_DATAFILE );
if (module) if (module)
{ {
LPCWSTR guid; LPCWSTR guid;
...@@ -3821,7 +3739,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) ...@@ -3821,7 +3739,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
} }
else else
{ {
hr = LoadTypeLibEx(file->TargetPath, REGKIND_REGISTER, &tlib); hr = msi_load_typelib( package, file->TargetPath, REGKIND_REGISTER, &tlib );
if (FAILED(hr)) if (FAILED(hr))
{ {
ERR("Failed to load type library: %08x\n", hr); ERR("Failed to load type library: %08x\n", hr);
...@@ -3932,7 +3850,7 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row ) ...@@ -3932,7 +3850,7 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
return NULL; return NULL;
} }
/* may be needed because of a bug somewhere else */ /* may be needed because of a bug somewhere else */
msi_create_full_path( link_folder ); msi_create_full_path( package, link_folder );
filename = msi_dup_record_field( row, 3 ); filename = msi_dup_record_field( row, 3 );
msi_reduce_to_long_filename( filename ); msi_reduce_to_long_filename( filename );
...@@ -3965,7 +3883,7 @@ WCHAR *msi_build_icon_path( MSIPACKAGE *package, const WCHAR *icon_name ) ...@@ -3965,7 +3883,7 @@ WCHAR *msi_build_icon_path( MSIPACKAGE *package, const WCHAR *icon_name )
msi_free( appdata ); msi_free( appdata );
} }
dest = msi_build_directory_name( 3, folder, szInstaller, package->ProductCode ); dest = msi_build_directory_name( 3, folder, szInstaller, package->ProductCode );
msi_create_full_path( dest ); msi_create_full_path( package, dest );
path = msi_build_directory_name( 2, dest, icon_name ); path = msi_build_directory_name( 2, dest, icon_name );
msi_free( folder ); msi_free( folder );
msi_free( dest ); msi_free( dest );
...@@ -4069,10 +3987,14 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) ...@@ -4069,10 +3987,14 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
full_path = msi_get_target_folder( package, wkdir ); full_path = msi_get_target_folder( package, wkdir );
if (full_path) IShellLinkW_SetWorkingDirectory( sl, full_path ); if (full_path) IShellLinkW_SetWorkingDirectory( sl, full_path );
} }
link_file = get_link_file(package, row);
link_file = get_link_file(package, row);
TRACE("Writing shortcut to %s\n", debugstr_w(link_file)); TRACE("Writing shortcut to %s\n", debugstr_w(link_file));
msi_disable_fs_redirection( package );
IPersistFile_Save(pf, link_file, FALSE); IPersistFile_Save(pf, link_file, FALSE);
msi_revert_fs_redirection( package );
msi_free(link_file); msi_free(link_file);
err: err:
...@@ -4130,12 +4052,8 @@ static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param ) ...@@ -4130,12 +4052,8 @@ static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param )
MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row); MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);
link_file = get_link_file( package, row ); link_file = get_link_file( package, row );
TRACE("Removing shortcut file %s\n", debugstr_w( link_file )); TRACE("Removing shortcut file %s\n", debugstr_w( link_file ));
if (!DeleteFileW( link_file )) if (!msi_delete_file( package, link_file )) WARN("Failed to remove shortcut file %u\n", GetLastError());
{
WARN("Failed to remove shortcut file %u\n", GetLastError());
}
msi_free( link_file ); msi_free( link_file );
return ERROR_SUCCESS; return ERROR_SUCCESS;
...@@ -4163,51 +4081,49 @@ static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package ) ...@@ -4163,51 +4081,49 @@ static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param) static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE* package = param; MSIPACKAGE *package = param;
HANDLE the_file; HANDLE handle;
LPWSTR FilePath; WCHAR *icon_path;
LPCWSTR FileName; const WCHAR *filename;
CHAR buffer[1024]; char buffer[1024];
DWORD sz; DWORD sz;
UINT rc; UINT rc;
FileName = MSI_RecordGetString(row,1); filename = MSI_RecordGetString( row, 1 );
if (!FileName) if (!filename)
{ {
ERR("Unable to get FileName\n"); ERR("Unable to get filename\n");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
FilePath = msi_build_icon_path(package, FileName); icon_path = msi_build_icon_path( package, filename );
TRACE("Creating icon file at %s\n",debugstr_w(FilePath));
the_file = CreateFileW(FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, TRACE("Creating icon file at %s\n", debugstr_w(icon_path));
FILE_ATTRIBUTE_NORMAL, NULL);
if (the_file == INVALID_HANDLE_VALUE) handle = msi_create_file( package, icon_path, GENERIC_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL );
if (handle == INVALID_HANDLE_VALUE)
{ {
ERR("Unable to create file %s\n",debugstr_w(FilePath)); ERR("Unable to create file %s\n", debugstr_w(icon_path));
msi_free(FilePath); msi_free( icon_path );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
do do
{ {
DWORD write; DWORD count;
sz = 1024; sz = 1024;
rc = MSI_RecordReadStream(row,2,buffer,&sz); rc = MSI_RecordReadStream( row, 2, buffer, &sz );
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
ERR("Failed to get stream\n"); ERR("Failed to get stream\n");
DeleteFileW(FilePath); msi_delete_file( package, icon_path );
break; break;
} }
WriteFile(the_file,buffer,sz,&write,NULL); WriteFile( handle, buffer, sz, &count, NULL );
} while (sz == 1024); } while (sz == 1024);
msi_free(FilePath); msi_free( icon_path );
CloseHandle(the_file); CloseHandle( handle );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -5405,11 +5321,11 @@ static UINT ITERATE_UnpublishIcon( MSIRECORD *row, LPVOID param ) ...@@ -5405,11 +5321,11 @@ static UINT ITERATE_UnpublishIcon( MSIRECORD *row, LPVOID param )
if ((icon_path = msi_build_icon_path( package, icon ))) if ((icon_path = msi_build_icon_path( package, icon )))
{ {
TRACE("removing icon file %s\n", debugstr_w(icon_path)); TRACE("removing icon file %s\n", debugstr_w(icon_path));
DeleteFileW( icon_path ); msi_delete_file( package, icon_path );
if ((p = strrchrW( icon_path, '\\' ))) if ((p = strrchrW( icon_path, '\\' )))
{ {
*p = 0; *p = 0;
RemoveDirectoryW( icon_path ); msi_remove_directory( package, icon_path );
} }
msi_free( icon_path ); msi_free( icon_path );
} }
...@@ -7827,9 +7743,18 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package ) ...@@ -7827,9 +7743,18 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static void bind_image( const char *filename, const char *path ) static BOOL msi_bind_image( MSIPACKAGE *package, const char *filename, const char *path )
{ {
if (!BindImageEx( 0, filename, path, NULL, NULL )) BOOL ret;
msi_disable_fs_redirection( package );
ret = BindImage( filename, path, NULL );
msi_revert_fs_redirection( package );
return ret;
}
static void bind_image( MSIPACKAGE *package, const char *filename, const char *path )
{
if (!msi_bind_image( package, filename, path ))
{ {
WARN("failed to bind image %u\n", GetLastError()); WARN("failed to bind image %u\n", GetLastError());
} }
...@@ -7851,8 +7776,9 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param ) ...@@ -7851,8 +7776,9 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
if (!(filenameA = strdupWtoA( file->TargetPath ))) return ERROR_SUCCESS; if (!(filenameA = strdupWtoA( file->TargetPath ))) return ERROR_SUCCESS;
path_list = msi_split_string( paths, ';' ); path_list = msi_split_string( paths, ';' );
if (!path_list) bind_image( filenameA, NULL ); if (!path_list) bind_image( package, filenameA, NULL );
else else
{ {
for (i = 0; path_list[i] && path_list[i][0]; i++) for (i = 0; path_list[i] && path_list[i][0]; i++)
...@@ -7860,7 +7786,7 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param ) ...@@ -7860,7 +7786,7 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param )
deformat_string( package, path_list[i], &pathW ); deformat_string( package, path_list[i], &pathW );
if ((pathA = strdupWtoA( pathW ))) if ((pathA = strdupWtoA( pathW )))
{ {
bind_image( filenameA, pathA ); bind_image( package, filenameA, pathA );
msi_free( pathA ); msi_free( pathA );
} }
msi_free( pathW ); msi_free( pathW );
...@@ -7868,6 +7794,7 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param ) ...@@ -7868,6 +7794,7 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param )
} }
msi_free( path_list ); msi_free( path_list );
msi_free( filenameA ); msi_free( filenameA );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -7884,10 +7811,8 @@ static UINT ACTION_BindImage( MSIPACKAGE *package ) ...@@ -7884,10 +7811,8 @@ static UINT ACTION_BindImage( MSIPACKAGE *package )
{ {
r = MSI_IterateRecords( view, NULL, ITERATE_BindImage, package ); r = MSI_IterateRecords( view, NULL, ITERATE_BindImage, package );
msiobj_release( &view->hdr ); msiobj_release( &view->hdr );
if (r != ERROR_SUCCESS)
return r;
} }
return ERROR_SUCCESS; return r;
} }
static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table ) static UINT msi_unimplemented_action_stub( MSIPACKAGE *package, LPCSTR action, LPCWSTR table )
...@@ -8034,12 +7959,8 @@ StandardActions[] = ...@@ -8034,12 +7959,8 @@ StandardActions[] =
static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action) static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action)
{ {
UINT rc = ERROR_FUNCTION_NOT_CALLED; UINT rc = ERROR_FUNCTION_NOT_CALLED;
void *cookie;
UINT i; UINT i;
if (is_wow64 && package->platform == PLATFORM_X64)
Wow64DisableWow64FsRedirection(&cookie);
i = 0; i = 0;
while (StandardActions[i].action != NULL) while (StandardActions[i].action != NULL)
{ {
...@@ -8075,9 +7996,6 @@ static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action) ...@@ -8075,9 +7996,6 @@ static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action)
i++; i++;
} }
if (is_wow64 && package->platform == PLATFORM_X64)
Wow64RevertWow64FsRedirection(cookie);
return rc; return rc;
} }
...@@ -8087,12 +8005,6 @@ UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action) ...@@ -8087,12 +8005,6 @@ UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action)
TRACE("Performing action (%s)\n", debugstr_w(action)); TRACE("Performing action (%s)\n", debugstr_w(action));
if (!msi_init_assembly_caches( package ))
{
ERR("can't initialize assembly caches\n");
return ERROR_FUNCTION_FAILED;
}
package->action_progress_increment = 0; package->action_progress_increment = 0;
rc = ACTION_HandleStandardAction(package, action); rc = ACTION_HandleStandardAction(package, action);
......
...@@ -81,7 +81,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls) ...@@ -81,7 +81,7 @@ void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
* Returns ERROR_SUCCESS upon success (where not finding the record counts as * Returns ERROR_SUCCESS upon success (where not finding the record counts as
* success), something else on error. * success), something else on error.
*/ */
static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig, LPCWSTR name) static UINT get_signature( MSIPACKAGE *package, MSISIGNATURE *sig, const WCHAR *name )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ', 's','e','l','e','c','t',' ','*',' ',
...@@ -155,16 +155,16 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig, ...@@ -155,16 +155,16 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *sig,
} }
/* Frees any memory allocated in sig */ /* Frees any memory allocated in sig */
static void ACTION_FreeSignature(MSISIGNATURE *sig) static void free_signature( MSISIGNATURE *sig )
{ {
msi_free(sig->File); msi_free(sig->File);
msi_free(sig->Languages); msi_free(sig->Languages);
} }
static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig) static WCHAR *search_file( MSIPACKAGE *package, WCHAR *path, MSISIGNATURE *sig )
{ {
VS_FIXEDFILEINFO *info; VS_FIXEDFILEINFO *info;
DWORD attr, handle, size; DWORD attr, size;
LPWSTR val = NULL; LPWSTR val = NULL;
LPBYTE buffer; LPBYTE buffer;
...@@ -173,20 +173,18 @@ static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig) ...@@ -173,20 +173,18 @@ static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig)
PathRemoveFileSpecW(path); PathRemoveFileSpecW(path);
PathAddBackslashW(path); PathAddBackslashW(path);
attr = GetFileAttributesW(path); attr = msi_get_file_attributes( package, path );
if (attr != INVALID_FILE_ATTRIBUTES && if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
(attr & FILE_ATTRIBUTE_DIRECTORY))
return strdupW(path); return strdupW(path);
return NULL; return NULL;
} }
attr = GetFileAttributesW(path); attr = msi_get_file_attributes( package, path );
if (attr == INVALID_FILE_ATTRIBUTES || if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY))
(attr & FILE_ATTRIBUTE_DIRECTORY))
return NULL; return NULL;
size = GetFileVersionInfoSizeW(path, &handle); size = msi_get_file_version_info( package, path, 0, NULL );
if (!size) if (!size)
return strdupW(path); return strdupW(path);
...@@ -194,7 +192,8 @@ static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig) ...@@ -194,7 +192,8 @@ static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig)
if (!buffer) if (!buffer)
return NULL; return NULL;
if (!GetFileVersionInfoW(path, 0, size, buffer)) size = msi_get_file_version_info( package, path, size, buffer );
if (!size)
goto done; goto done;
if (!VerQueryValueW(buffer, szBackSlash, (LPVOID)&info, &size) || !info) if (!VerQueryValueW(buffer, szBackSlash, (LPVOID)&info, &size) || !info)
...@@ -227,7 +226,7 @@ done: ...@@ -227,7 +226,7 @@ done:
return val; return val;
} }
static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) static UINT search_components( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ', 'S','E','L','E','C','T',' ','*',' ',
...@@ -240,7 +239,6 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS ...@@ -240,7 +239,6 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS
'`','S','i','g','n','a','t','u','r','e','`',' ', '`','S','i','g','n','a','t','u','r','e','`',' ',
'W','H','E','R','E',' ','`','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}; '\'','%','s','\'',0};
MSIRECORD *row, *rec; MSIRECORD *row, *rec;
LPCWSTR signature, guid; LPCWSTR signature, guid;
BOOL sigpresent = TRUE; BOOL sigpresent = TRUE;
...@@ -275,7 +273,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS ...@@ -275,7 +273,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS
if (!*path) if (!*path)
goto done; goto done;
attr = GetFileAttributesW(path); attr = msi_get_file_attributes( package, path );
if (attr == INVALID_FILE_ATTRIBUTES) if (attr == INVALID_FILE_ATTRIBUTES)
goto done; goto done;
...@@ -283,7 +281,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS ...@@ -283,7 +281,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS
if (type != msidbLocatorTypeDirectory && sigpresent && !isdir) if (type != msidbLocatorTypeDirectory && sigpresent && !isdir)
{ {
*appValue = app_search_file(path, sig); *appValue = search_file( package, path, sig );
} }
else if (!sigpresent && (type != msidbLocatorTypeDirectory || isdir)) else if (!sigpresent && (type != msidbLocatorTypeDirectory || isdir))
{ {
...@@ -302,9 +300,8 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS ...@@ -302,9 +300,8 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS
PathAddBackslashW(path); PathAddBackslashW(path);
lstrcatW(path, MSI_RecordGetString(rec, 2)); lstrcatW(path, MSI_RecordGetString(rec, 2));
attr = GetFileAttributesW(path); attr = msi_get_file_attributes( package, path );
if (attr != INVALID_FILE_ATTRIBUTES && if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY))
!(attr & FILE_ATTRIBUTE_DIRECTORY))
*appValue = strdupW(path); *appValue = strdupW(path);
} }
...@@ -314,8 +311,7 @@ done: ...@@ -314,8 +311,7 @@ done:
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz, static void convert_reg_value( DWORD regType, const BYTE *value, DWORD sz, WCHAR **appValue )
LPWSTR *appValue)
{ {
static const WCHAR dwordFmt[] = { '#','%','d','\0' }; static const WCHAR dwordFmt[] = { '#','%','d','\0' };
static const WCHAR binPre[] = { '#','x','\0' }; static const WCHAR binPre[] = { '#','x','\0' };
...@@ -365,10 +361,9 @@ static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz, ...@@ -365,10 +361,9 @@ static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz,
} }
} }
static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, static UINT search_directory( MSIPACKAGE *, MSISIGNATURE *, const WCHAR *, int, WCHAR ** );
LPCWSTR path, int depth, LPWSTR *appValue);
static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) static UINT search_reg( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
...@@ -473,13 +468,13 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT ...@@ -473,13 +468,13 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT
switch (type & 0x0f) switch (type & 0x0f)
{ {
case msidbLocatorTypeDirectory: case msidbLocatorTypeDirectory:
ACTION_SearchDirectory(package, sig, ptr, 0, appValue); search_directory( package, sig, ptr, 0, appValue );
break; break;
case msidbLocatorTypeFileName: case msidbLocatorTypeFileName:
*appValue = app_search_file(ptr, sig); *appValue = search_file( package, ptr, sig );
break; break;
case msidbLocatorTypeRawValue: case msidbLocatorTypeRawValue:
ACTION_ConvertRegValue(regType, value, sz, appValue); convert_reg_value( regType, value, sz, appValue );
break; break;
default: default:
FIXME("unimplemented for type %d (key path %s, value %s)\n", FIXME("unimplemented for type %d (key path %s, value %s)\n",
...@@ -520,8 +515,7 @@ static LPWSTR get_ini_field(LPWSTR buf, int field) ...@@ -520,8 +515,7 @@ static LPWSTR get_ini_field(LPWSTR buf, int field)
return strdupW(beg); return strdupW(beg);
} }
static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, static UINT search_ini( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
MSISIGNATURE *sig)
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ', 's','e','l','e','c','t',' ','*',' ',
...@@ -561,10 +555,10 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -561,10 +555,10 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue,
switch (type & 0x0f) switch (type & 0x0f)
{ {
case msidbLocatorTypeDirectory: case msidbLocatorTypeDirectory:
ACTION_SearchDirectory(package, sig, buf, 0, appValue); search_directory( package, sig, buf, 0, appValue );
break; break;
case msidbLocatorTypeFileName: case msidbLocatorTypeFileName:
*appValue = app_search_file(buf, sig); *appValue = search_file( package, buf, sig );
break; break;
case msidbLocatorTypeRawValue: case msidbLocatorTypeRawValue:
*appValue = get_ini_field(buf, field); *appValue = get_ini_field(buf, field);
...@@ -590,8 +584,7 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -590,8 +584,7 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue,
* - what does AppSearch return if the table values are invalid? * - what does AppSearch return if the table values are invalid?
* - what if dst is too small? * - what if dst is too small?
*/ */
static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst, static void expand_any_path( MSIPACKAGE *package, WCHAR *src, WCHAR *dst, size_t len )
size_t len)
{ {
WCHAR *ptr, *deformatted; WCHAR *ptr, *deformatted;
...@@ -685,20 +678,20 @@ done: ...@@ -685,20 +678,20 @@ done:
* Return ERROR_SUCCESS in case of success (whether or not the file matches), * Return ERROR_SUCCESS in case of success (whether or not the file matches),
* something else if an install-halting error occurs. * something else if an install-halting error occurs.
*/ */
static UINT ACTION_FileVersionMatches(const MSISIGNATURE *sig, LPCWSTR filePath, static UINT file_version_matches( MSIPACKAGE *package, const MSISIGNATURE *sig, const WCHAR *filePath,
BOOL *matches) BOOL *matches )
{ {
UINT len; UINT len;
void *version; void *version;
VS_FIXEDFILEINFO *info = NULL; VS_FIXEDFILEINFO *info = NULL;
DWORD zero, size = GetFileVersionInfoSizeW( filePath, &zero ); DWORD size = msi_get_file_version_info( package, filePath, 0, NULL );
*matches = FALSE; *matches = FALSE;
if (!size) return ERROR_SUCCESS; if (!size) return ERROR_SUCCESS;
if (!(version = msi_alloc( size ))) return ERROR_OUTOFMEMORY; if (!(version = msi_alloc( size ))) return ERROR_OUTOFMEMORY;
if (GetFileVersionInfoW( filePath, 0, size, version )) if (msi_get_file_version_info( package, filePath, size, version ))
VerQueryValueW( version, szBackSlash, (void **)&info, &len ); VerQueryValueW( version, szBackSlash, (void **)&info, &len );
if (info) if (info)
...@@ -745,8 +738,8 @@ static UINT ACTION_FileVersionMatches(const MSISIGNATURE *sig, LPCWSTR filePath, ...@@ -745,8 +738,8 @@ static UINT ACTION_FileVersionMatches(const MSISIGNATURE *sig, LPCWSTR filePath,
* Return ERROR_SUCCESS in case of success (whether or not the file matches), * Return ERROR_SUCCESS in case of success (whether or not the file matches),
* something else if an install-halting error occurs. * something else if an install-halting error occurs.
*/ */
static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig, static UINT file_matches_sig( MSIPACKAGE *package, const MSISIGNATURE *sig, const WIN32_FIND_DATAW *findData,
const WIN32_FIND_DATAW *findData, LPCWSTR fullFilePath, BOOL *matches) const WCHAR *fullFilePath, BOOL *matches )
{ {
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
...@@ -778,7 +771,7 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig, ...@@ -778,7 +771,7 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig,
*matches = FALSE; *matches = FALSE;
if (*matches && (sig->MinVersionMS || sig->MinVersionLS || if (*matches && (sig->MinVersionMS || sig->MinVersionLS ||
sig->MaxVersionMS || sig->MaxVersionLS)) sig->MaxVersionMS || sig->MaxVersionLS))
rc = ACTION_FileVersionMatches(sig, fullFilePath, matches); rc = file_version_matches( package, sig, fullFilePath, matches );
return rc; return rc;
} }
...@@ -790,9 +783,10 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig, ...@@ -790,9 +783,10 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig,
* Returns ERROR_SUCCESS on success (which may include non-critical errors), * Returns ERROR_SUCCESS on success (which may include non-critical errors),
* something else on failures which should halt the install. * something else on failures which should halt the install.
*/ */
static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig, const WCHAR *dir,
MSISIGNATURE *sig, LPCWSTR 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;
...@@ -801,10 +795,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -801,10 +795,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
WCHAR *buf; WCHAR *buf;
DWORD len; DWORD len;
static const WCHAR starDotStarW[] = { '*','.','*',0 }; TRACE("Searching directory %s for file %s, depth %d\n", debugstr_w(dir), debugstr_w(sig->File), depth);
TRACE("Searching directory %s for file %s, depth %d\n", debugstr_w(dir),
debugstr_w(sig->File), depth);
if (depth < 0) if (depth < 0)
return ERROR_SUCCESS; return ERROR_SUCCESS;
...@@ -823,14 +814,14 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -823,14 +814,14 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
PathAddBackslashW(buf); PathAddBackslashW(buf);
lstrcatW(buf, sig->File); lstrcatW(buf, sig->File);
hFind = FindFirstFileW(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))
{ {
BOOL matches; BOOL matches;
rc = ACTION_FileMatchesSig(sig, &findData, buf, &matches); rc = file_matches_sig( package, sig, &findData, buf, &matches );
if (rc == ERROR_SUCCESS && matches) if (rc == ERROR_SUCCESS && matches)
{ {
TRACE("found file, returning %s\n", debugstr_w(buf)); TRACE("found file, returning %s\n", debugstr_w(buf));
...@@ -846,7 +837,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -846,7 +837,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
PathAddBackslashW(buf); PathAddBackslashW(buf);
lstrcatW(buf, starDotStarW); lstrcatW(buf, starDotStarW);
hFind = FindFirstFileW(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 &&
...@@ -855,12 +846,10 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -855,12 +846,10 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
{ {
lstrcpyW(subpath, dir); lstrcpyW(subpath, dir);
PathAppendW(subpath, findData.cFileName); PathAppendW(subpath, findData.cFileName);
rc = ACTION_RecurseSearchDirectory(package, appValue, sig, rc = recurse_search_directory( package, appValue, sig, subpath, depth - 1 );
subpath, depth - 1);
} }
while (rc == ERROR_SUCCESS && !*appValue && while (rc == ERROR_SUCCESS && !*appValue && msi_find_next_file( package, hFind, &findData ))
FindNextFileW(hFind, &findData) != 0)
{ {
if (!strcmpW( findData.cFileName, szDot ) || if (!strcmpW( findData.cFileName, szDot ) ||
!strcmpW( findData.cFileName, szDotDot )) !strcmpW( findData.cFileName, szDotDot ))
...@@ -869,8 +858,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -869,8 +858,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
lstrcpyW(subpath, dir); lstrcpyW(subpath, dir);
PathAppendW(subpath, findData.cFileName); PathAppendW(subpath, findData.cFileName);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
rc = ACTION_RecurseSearchDirectory(package, appValue, rc = recurse_search_directory( package, appValue, sig, subpath, depth - 1 );
sig, subpath, depth - 1);
} }
FindClose(hFind); FindClose(hFind);
...@@ -883,10 +871,9 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, ...@@ -883,10 +871,9 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue,
return rc; return rc;
} }
static UINT ACTION_CheckDirectory(MSIPACKAGE *package, LPCWSTR dir, static UINT check_directory( MSIPACKAGE *package, const WCHAR *dir, WCHAR **appValue )
LPWSTR *appValue)
{ {
DWORD attr = GetFileAttributesW(dir); DWORD attr = msi_get_file_attributes( package, dir );
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
{ {
...@@ -897,7 +884,7 @@ static UINT ACTION_CheckDirectory(MSIPACKAGE *package, LPCWSTR dir, ...@@ -897,7 +884,7 @@ static UINT ACTION_CheckDirectory(MSIPACKAGE *package, LPCWSTR dir,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static BOOL ACTION_IsFullPath(LPCWSTR path) static BOOL is_full_path( const WCHAR *path )
{ {
WCHAR first = toupperW(path[0]); WCHAR first = toupperW(path[0]);
BOOL ret; BOOL ret;
...@@ -911,26 +898,24 @@ static BOOL ACTION_IsFullPath(LPCWSTR path) ...@@ -911,26 +898,24 @@ static BOOL ACTION_IsFullPath(LPCWSTR path)
return ret; return ret;
} }
static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, static UINT search_directory( MSIPACKAGE *package, MSISIGNATURE *sig, const WCHAR *path, int depth, WCHAR **appValue )
LPCWSTR path, int depth, LPWSTR *appValue)
{ {
UINT rc; UINT rc;
DWORD attr; DWORD attr;
LPWSTR val = NULL; LPWSTR val = NULL;
TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth, TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth, appValue);
appValue);
if (ACTION_IsFullPath(path)) if (is_full_path( path ))
{ {
if (sig->File) if (sig->File)
rc = ACTION_RecurseSearchDirectory(package, &val, sig, path, depth); rc = recurse_search_directory( package, &val, sig, path, depth );
else else
{ {
/* Recursively searching a directory makes no sense when the /* Recursively searching a directory makes no sense when the
* directory to search is the thing you're trying to find. * directory to search is the thing you're trying to find.
*/ */
rc = ACTION_CheckDirectory(package, path, &val); rc = check_directory( package, path, &val );
} }
} }
else else
...@@ -952,16 +937,14 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, ...@@ -952,16 +937,14 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
lstrcpynW(pathWithDrive + 3, path, ARRAY_SIZE(pathWithDrive) - 3); lstrcpynW(pathWithDrive + 3, path, ARRAY_SIZE(pathWithDrive) - 3);
if (sig->File) if (sig->File)
rc = ACTION_RecurseSearchDirectory(package, &val, sig, rc = recurse_search_directory( package, &val, sig, pathWithDrive, depth );
pathWithDrive, depth);
else else
rc = ACTION_CheckDirectory(package, pathWithDrive, &val); rc = check_directory( package, pathWithDrive, &val );
} }
} }
attr = GetFileAttributesW(val); attr = msi_get_file_attributes( package, val );
if (attr != INVALID_FILE_ATTRIBUTES && if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) &&
(attr & FILE_ATTRIBUTE_DIRECTORY) &&
val && val[lstrlenW(val) - 1] != '\\') val && val[lstrlenW(val) - 1] != '\\')
{ {
val = msi_realloc(val, (lstrlenW(val) + 2) * sizeof(WCHAR)); val = msi_realloc(val, (lstrlenW(val) + 2) * sizeof(WCHAR));
...@@ -977,10 +960,9 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, ...@@ -977,10 +960,9 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
return rc; return rc;
} }
static UINT ACTION_AppSearchSigName(MSIPACKAGE *package, LPCWSTR sigName, static UINT search_sig_name( MSIPACKAGE *, const WCHAR *, MSISIGNATURE *, WCHAR ** );
MSISIGNATURE *sig, LPWSTR *appValue);
static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) static UINT search_dr( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
's','e','l','e','c','t',' ','*',' ', 's','e','l','e','c','t',' ','*',' ',
...@@ -1014,8 +996,8 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU ...@@ -1014,8 +996,8 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU
{ {
MSISIGNATURE parentSig; MSISIGNATURE parentSig;
ACTION_AppSearchSigName(package, parentName, &parentSig, &parent); search_sig_name( package, parentName, &parentSig, &parent );
ACTION_FreeSignature(&parentSig); free_signature( &parentSig );
if (!parent) if (!parent)
{ {
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
...@@ -1032,13 +1014,13 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU ...@@ -1032,13 +1014,13 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU
depth = MSI_RecordGetInteger(row,4); depth = MSI_RecordGetInteger(row,4);
if (sz) if (sz)
ACTION_ExpandAnyPath(package, path, expanded, MAX_PATH); expand_any_path( package, path, expanded, MAX_PATH );
else else
strcpyW(expanded, path); strcpyW(expanded, path);
if (parent) if (parent)
{ {
attr = GetFileAttributesW(parent); attr = msi_get_file_attributes( package, parent );
if (attr != INVALID_FILE_ATTRIBUTES && if (attr != INVALID_FILE_ATTRIBUTES &&
!(attr & FILE_ATTRIBUTE_DIRECTORY)) !(attr & FILE_ATTRIBUTE_DIRECTORY))
{ {
...@@ -1049,45 +1031,42 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU ...@@ -1049,45 +1031,42 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU
strcpyW(path, parent); strcpyW(path, parent);
strcatW(path, expanded); strcatW(path, expanded);
} }
else if (sz) else if (sz) strcpyW(path, expanded);
strcpyW(path, expanded);
PathAddBackslashW(path); PathAddBackslashW(path);
rc = ACTION_SearchDirectory(package, sig, path, depth, appValue); rc = search_directory( package, sig, path, depth, appValue );
msi_free(parent); msi_free(parent);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
TRACE("returning %d\n", rc); TRACE("returning %d\n", rc);
return rc; return rc;
} }
static UINT ACTION_AppSearchSigName(MSIPACKAGE *package, LPCWSTR sigName, static UINT search_sig_name( MSIPACKAGE *package, const WCHAR *sigName, MSISIGNATURE *sig, WCHAR **appValue )
MSISIGNATURE *sig, LPWSTR *appValue)
{ {
UINT rc; UINT rc;
*appValue = NULL; *appValue = NULL;
rc = ACTION_AppSearchGetSignature(package, sig, sigName); rc = get_signature( package, sig, sigName );
if (rc == ERROR_SUCCESS) if (rc == ERROR_SUCCESS)
{ {
rc = ACTION_AppSearchComponents(package, appValue, sig); rc = search_components( package, appValue, sig );
if (rc == ERROR_SUCCESS && !*appValue) if (rc == ERROR_SUCCESS && !*appValue)
{ {
rc = ACTION_AppSearchReg(package, appValue, sig); rc = search_reg( package, appValue, sig );
if (rc == ERROR_SUCCESS && !*appValue) if (rc == ERROR_SUCCESS && !*appValue)
{ {
rc = ACTION_AppSearchIni(package, appValue, sig); rc = search_ini( package, appValue, sig );
if (rc == ERROR_SUCCESS && !*appValue) if (rc == ERROR_SUCCESS && !*appValue)
rc = ACTION_AppSearchDr(package, appValue, sig); rc = search_dr( package, appValue, sig );
} }
} }
} }
return rc; return rc;
} }
static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) static UINT ITERATE_AppSearch(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
LPCWSTR propName, sigName; LPCWSTR propName, sigName;
...@@ -1102,7 +1081,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) ...@@ -1102,7 +1081,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param)
TRACE("%s %s\n", debugstr_w(propName), debugstr_w(sigName)); TRACE("%s %s\n", debugstr_w(propName), debugstr_w(sigName));
r = ACTION_AppSearchSigName(package, sigName, &sig, &value); r = search_sig_name( package, sigName, &sig, &value );
if (value) if (value)
{ {
r = msi_set_property( package->db, propName, value, -1 ); r = msi_set_property( package->db, propName, value, -1 );
...@@ -1111,7 +1090,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) ...@@ -1111,7 +1090,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param)
msi_free(value); msi_free(value);
} }
ACTION_FreeSignature(&sig); free_signature( &sig );
uirow = MSI_CreateRecord( 2 ); uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, propName ); MSI_RecordSetStringW( uirow, 1, propName );
...@@ -1142,7 +1121,7 @@ UINT ACTION_AppSearch(MSIPACKAGE *package) ...@@ -1142,7 +1121,7 @@ UINT ACTION_AppSearch(MSIPACKAGE *package)
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return ERROR_SUCCESS; return ERROR_SUCCESS;
r = MSI_IterateRecords( view, NULL, iterate_appsearch, package ); r = MSI_IterateRecords( view, NULL, ITERATE_AppSearch, package );
msiobj_release( &view->hdr ); msiobj_release( &view->hdr );
return r; return r;
} }
...@@ -1161,7 +1140,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) ...@@ -1161,7 +1140,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param)
TRACE("%s\n", debugstr_w(signature)); TRACE("%s\n", debugstr_w(signature));
ACTION_AppSearchSigName(package, signature, &sig, &value); search_sig_name( package, signature, &sig, &value );
if (value) if (value)
{ {
TRACE("Found signature %s\n", debugstr_w(signature)); TRACE("Found signature %s\n", debugstr_w(signature));
...@@ -1170,8 +1149,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) ...@@ -1170,8 +1149,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param)
r = ERROR_NO_MORE_ITEMS; r = ERROR_NO_MORE_ITEMS;
} }
ACTION_FreeSignature(&sig); free_signature(&sig);
return r; return r;
} }
......
...@@ -1188,7 +1188,7 @@ static UINT HANDLE_CustomType21_22( MSIPACKAGE *package, const WCHAR *source, co ...@@ -1188,7 +1188,7 @@ static UINT HANDLE_CustomType21_22( MSIPACKAGE *package, const WCHAR *source, co
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
} }
hFile = CreateFileW(file->TargetPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); hFile = msi_create_file( package, file->TargetPath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 );
if (hFile == INVALID_HANDLE_VALUE) return ERROR_FUNCTION_FAILED; if (hFile == INVALID_HANDLE_VALUE) return ERROR_FUNCTION_FAILED;
sz = GetFileSize(hFile, &szHighWord); sz = GetFileSize(hFile, &szHighWord);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/* /*
* Actions dealing with files: * Actions dealing with files:
* *
...@@ -37,7 +36,6 @@ ...@@ -37,7 +36,6 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "wine/debug.h"
#include "fdi.h" #include "fdi.h"
#include "msi.h" #include "msi.h"
#include "msidefs.h" #include "msidefs.h"
...@@ -46,10 +44,202 @@ ...@@ -46,10 +44,202 @@
#include "winreg.h" #include "winreg.h"
#include "shlwapi.h" #include "shlwapi.h"
#include "patchapi.h" #include "patchapi.h"
#include "wine/debug.h"
#include "wine/unicode.h" #include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi); WINE_DEFAULT_DEBUG_CHANNEL(msi);
HANDLE msi_create_file( MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation,
DWORD flags )
{
HANDLE handle;
msi_disable_fs_redirection( package );
handle = CreateFileW( filename, access, sharing, NULL, creation, flags, NULL );
msi_revert_fs_redirection( package );
return handle;
}
static BOOL msi_copy_file( MSIPACKAGE *package, const WCHAR *src, const WCHAR *dst, BOOL fail_if_exists )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = CopyFileW( src, dst, fail_if_exists );
msi_revert_fs_redirection( package );
return ret;
}
BOOL msi_delete_file( MSIPACKAGE *package, const WCHAR *filename )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = DeleteFileW( filename );
msi_revert_fs_redirection( package );
return ret;
}
static BOOL msi_create_directory( MSIPACKAGE *package, const WCHAR *path )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = CreateDirectoryW( path, NULL );
msi_revert_fs_redirection( package );
return ret;
}
BOOL msi_remove_directory( MSIPACKAGE *package, const WCHAR *path )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = RemoveDirectoryW( path );
msi_revert_fs_redirection( package );
return ret;
}
BOOL msi_set_file_attributes( MSIPACKAGE *package, const WCHAR *filename, DWORD attrs )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = SetFileAttributesW( filename, attrs );
msi_revert_fs_redirection( package );
return ret;
}
DWORD msi_get_file_attributes( MSIPACKAGE *package, const WCHAR *path )
{
DWORD attrs;
msi_disable_fs_redirection( package );
attrs = GetFileAttributesW( path );
msi_revert_fs_redirection( package );
return attrs;
}
HANDLE msi_find_first_file( MSIPACKAGE *package, const WCHAR *filename, WIN32_FIND_DATAW *data )
{
HANDLE handle;
msi_disable_fs_redirection( package );
handle = FindFirstFileW( filename, data );
msi_revert_fs_redirection( package );
return handle;
}
BOOL msi_find_next_file( MSIPACKAGE *package, HANDLE handle, WIN32_FIND_DATAW *data )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = FindNextFileW( handle, data );
msi_revert_fs_redirection( package );
return ret;
}
BOOL msi_move_file( MSIPACKAGE *package, const WCHAR *from, const WCHAR *to, DWORD flags )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = MoveFileExW( from, to, flags );
msi_revert_fs_redirection( package );
return ret;
}
static BOOL msi_apply_filepatch( MSIPACKAGE *package, const WCHAR *patch, const WCHAR *old, const WCHAR *new )
{
BOOL ret;
msi_disable_fs_redirection( package );
ret = ApplyPatchToFileW( patch, old, new, 0 );
msi_revert_fs_redirection( package );
return ret;
}
DWORD msi_get_file_version_info( MSIPACKAGE *package, const WCHAR *path, DWORD buflen, BYTE *buffer )
{
DWORD size, handle;
msi_disable_fs_redirection( package );
if (buffer) size = GetFileVersionInfoW( path, 0, buflen, buffer );
else size = GetFileVersionInfoSizeW( path, &handle );
msi_revert_fs_redirection( package );
return size;
}
VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *package, const WCHAR *filename )
{
static const WCHAR name[] = {'\\',0};
VS_FIXEDFILEINFO *ptr, *ret;
DWORD version_size, size;
void *version;
if (!(version_size = msi_get_file_version_info( package, filename, 0, NULL ))) return NULL;
if (!(version = msi_alloc( version_size ))) return NULL;
msi_get_file_version_info( package, filename, version_size, version );
if (!VerQueryValueW( version, name, (void **)&ptr, &size ))
{
msi_free( version );
return NULL;
}
if (!(ret = msi_alloc( size )))
{
msi_free( version );
return NULL;
}
memcpy( ret, ptr, size );
msi_free( version );
return ret;
}
DWORD msi_get_disk_file_size( MSIPACKAGE *package, const WCHAR *filename )
{
DWORD size;
HANDLE file;
file = msi_create_file( package, filename, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 );
if (file == INVALID_HANDLE_VALUE) return INVALID_FILE_SIZE;
size = GetFileSize( file, NULL );
CloseHandle( file );
return size;
}
/* Recursively create all directories in the path. */
BOOL msi_create_full_path( MSIPACKAGE *package, const WCHAR *path )
{
BOOL ret = TRUE;
WCHAR *new_path;
int len;
if (!(new_path = msi_alloc( (strlenW( path ) + 1) * sizeof(WCHAR) ))) return FALSE;
strcpyW( new_path, path );
while ((len = strlenW( new_path )) && new_path[len - 1] == '\\')
new_path[len - 1] = 0;
while (!msi_create_directory( package, new_path ))
{
WCHAR *slash;
DWORD last_error = GetLastError();
if (last_error == ERROR_ALREADY_EXISTS) break;
if (last_error != ERROR_PATH_NOT_FOUND)
{
ret = FALSE;
break;
}
if (!(slash = strrchrW( new_path, '\\' )))
{
ret = FALSE;
break;
}
len = slash - new_path;
new_path[len] = 0;
if (!msi_create_full_path( package, new_path ))
{
ret = FALSE;
break;
}
new_path[len] = '\\';
}
msi_free( new_path );
return ret;
}
static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *action ) static void msi_file_update_ui( MSIPACKAGE *package, MSIFILE *f, const WCHAR *action )
{ {
MSIRECORD *uirow; MSIRECORD *uirow;
...@@ -85,6 +275,19 @@ static BOOL is_obsoleted_by_patch( MSIPACKAGE *package, MSIFILE *file ) ...@@ -85,6 +275,19 @@ static BOOL is_obsoleted_by_patch( MSIPACKAGE *package, MSIFILE *file )
return FALSE; return FALSE;
} }
static BOOL file_hash_matches( MSIPACKAGE *package, MSIFILE *file )
{
UINT r;
MSIFILEHASHINFO hash;
hash.dwFileHashInfoSize = sizeof(hash);
r = msi_get_filehash( package, file->TargetPath, &hash );
if (r != ERROR_SUCCESS)
return FALSE;
return !memcmp( &hash, &file->hash, sizeof(hash) );
}
static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *file ) static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *file )
{ {
MSICOMPONENT *comp = file->Component; MSICOMPONENT *comp = file->Component;
...@@ -105,14 +308,14 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil ...@@ -105,14 +308,14 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil
return msifs_skipped; return msifs_skipped;
} }
if ((msi_is_global_assembly( comp ) && !comp->assembly->installed) || if ((msi_is_global_assembly( comp ) && !comp->assembly->installed) ||
GetFileAttributesW( file->TargetPath ) == INVALID_FILE_ATTRIBUTES) msi_get_file_attributes( package, file->TargetPath ) == INVALID_FILE_ATTRIBUTES)
{ {
TRACE("installing %s (missing)\n", debugstr_w(file->File)); TRACE("installing %s (missing)\n", debugstr_w(file->File));
return msifs_missing; return msifs_missing;
} }
if (file->Version) if (file->Version)
{ {
if ((file_version = msi_get_disk_file_version( file->TargetPath ))) if ((file_version = msi_get_disk_file_version( package, file->TargetPath )))
{ {
if (msi_compare_file_versions( file_version, file->Version ) < 0) if (msi_compare_file_versions( file_version, file->Version ) < 0)
{ {
...@@ -133,7 +336,7 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil ...@@ -133,7 +336,7 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil
msi_free( file_version ); msi_free( file_version );
return state; return state;
} }
else if ((font_version = msi_font_version_from_file( file->TargetPath ))) else if ((font_version = msi_get_font_file_version( package, file->TargetPath )))
{ {
if (msi_compare_font_versions( font_version, file->Version ) < 0) if (msi_compare_font_versions( font_version, file->Version ) < 0)
{ {
...@@ -151,14 +354,14 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil ...@@ -151,14 +354,14 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil
return state; return state;
} }
} }
if ((size = msi_get_disk_file_size( file->TargetPath )) != file->FileSize) if ((size = msi_get_disk_file_size( package, file->TargetPath )) != file->FileSize)
{ {
TRACE("overwriting %s (old size %u new size %u)\n", debugstr_w(file->File), size, file->FileSize); TRACE("overwriting %s (old size %u new size %u)\n", debugstr_w(file->File), size, file->FileSize);
return msifs_overwrite; return msifs_overwrite;
} }
if (file->hash.dwFileHashInfoSize) if (file->hash.dwFileHashInfoSize)
{ {
if (msi_file_hash_matches( file )) if (file_hash_matches( package, file ))
{ {
TRACE("keeping %s (hash match)\n", debugstr_w(file->File)); TRACE("keeping %s (hash match)\n", debugstr_w(file->File));
return msifs_hashmatch; return msifs_hashmatch;
...@@ -191,15 +394,15 @@ static void schedule_install_files(MSIPACKAGE *package) ...@@ -191,15 +394,15 @@ static void schedule_install_files(MSIPACKAGE *package)
} }
} }
static UINT copy_file(MSIFILE *file, LPWSTR source) static UINT copy_file( MSIPACKAGE *package, MSIFILE *file, WCHAR *source )
{ {
BOOL ret; BOOL ret;
ret = CopyFileW(source, file->TargetPath, FALSE); ret = msi_copy_file( package, source, file->TargetPath, FALSE );
if (!ret) if (!ret)
return GetLastError(); return GetLastError();
SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL); msi_set_file_attributes( package, file->TargetPath, FILE_ATTRIBUTE_NORMAL );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
...@@ -209,7 +412,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) ...@@ -209,7 +412,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
TRACE("Copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath)); TRACE("Copying %s to %s\n", debugstr_w(source), debugstr_w(file->TargetPath));
gle = copy_file(file, source); gle = copy_file( package, file, source );
if (gle == ERROR_SUCCESS) if (gle == ERROR_SUCCESS)
return gle; return gle;
...@@ -220,9 +423,9 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) ...@@ -220,9 +423,9 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
} }
else if (gle == ERROR_ACCESS_DENIED) else if (gle == ERROR_ACCESS_DENIED)
{ {
SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL); msi_set_file_attributes( package, file->TargetPath, FILE_ATTRIBUTE_NORMAL );
gle = copy_file(file, source); gle = copy_file( package, file, source );
TRACE("Overwriting existing file: %d\n", gle); TRACE("Overwriting existing file: %d\n", gle);
} }
if (gle == ERROR_SHARING_VIOLATION || gle == ERROR_USER_MAPPED_FILE) if (gle == ERROR_SHARING_VIOLATION || gle == ERROR_USER_MAPPED_FILE)
...@@ -243,9 +446,9 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) ...@@ -243,9 +446,9 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
if (!GetTempFileNameW( pathW, szMsi, 0, tmpfileW )) tmpfileW[0] = 0; if (!GetTempFileNameW( pathW, szMsi, 0, tmpfileW )) tmpfileW[0] = 0;
msi_free( pathW ); msi_free( pathW );
if (CopyFileW(source, tmpfileW, FALSE) && if (msi_copy_file( package, source, tmpfileW, FALSE ) &&
MoveFileExW(file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && msi_move_file( package, file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) &&
MoveFileExW(tmpfileW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT)) msi_move_file( package, tmpfileW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT ))
{ {
package->need_reboot_at_end = 1; package->need_reboot_at_end = 1;
gle = ERROR_SUCCESS; gle = ERROR_SUCCESS;
...@@ -262,7 +465,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) ...@@ -262,7 +465,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
return gle; return gle;
} }
static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir ) static UINT create_directory( MSIPACKAGE *package, const WCHAR *dir )
{ {
MSIFOLDER *folder; MSIFOLDER *folder;
const WCHAR *install_path; const WCHAR *install_path;
...@@ -273,7 +476,7 @@ static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir ) ...@@ -273,7 +476,7 @@ static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir )
folder = msi_get_loaded_folder( package, dir ); folder = msi_get_loaded_folder( package, dir );
if (folder->State == FOLDER_STATE_UNINITIALIZED) if (folder->State == FOLDER_STATE_UNINITIALIZED)
{ {
msi_create_full_path( install_path ); msi_create_full_path( package, install_path );
folder->State = FOLDER_STATE_CREATED; folder->State = FOLDER_STATE_CREATED;
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
...@@ -309,7 +512,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR filename, DWORD action, ...@@ -309,7 +512,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR filename, DWORD action,
if (!msi_is_global_assembly( file->Component )) if (!msi_is_global_assembly( file->Component ))
{ {
msi_create_directory( package, file->Component->Directory ); create_directory( package, file->Component->Directory );
} }
*path = strdupW( file->TargetPath ); *path = strdupW( file->TargetPath );
*attrs = file->Attributes; *attrs = file->Attributes;
...@@ -334,7 +537,7 @@ WCHAR *msi_resolve_file_source( MSIPACKAGE *package, MSIFILE *file ) ...@@ -334,7 +537,7 @@ WCHAR *msi_resolve_file_source( MSIPACKAGE *package, MSIFILE *file )
p = msi_resolve_source_folder( package, file->Component->Directory, NULL ); p = msi_resolve_source_folder( package, file->Component->Directory, NULL );
path = msi_build_directory_name( 2, p, file->ShortName ); path = msi_build_directory_name( 2, p, file->ShortName );
if (file->LongName && GetFileAttributesW( path ) == INVALID_FILE_ATTRIBUTES) if (file->LongName && msi_get_file_attributes( package, path ) == INVALID_FILE_ATTRIBUTES)
{ {
msi_free( path ); msi_free( path );
path = msi_build_directory_name( 2, p, file->LongName ); path = msi_build_directory_name( 2, p, file->LongName );
...@@ -418,7 +621,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) ...@@ -418,7 +621,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
if (!is_global_assembly) if (!is_global_assembly)
{ {
msi_create_directory(package, file->Component->Directory); create_directory(package, file->Component->Directory);
} }
rc = copy_install_file(package, file, source); rc = copy_install_file(package, file, source);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
...@@ -513,10 +716,10 @@ static UINT patch_file( MSIPACKAGE *package, MSIFILEPATCH *patch ) ...@@ -513,10 +716,10 @@ static UINT patch_file( MSIPACKAGE *package, MSIFILEPATCH *patch )
WCHAR *tmpfile = msi_create_temp_file( package->db ); WCHAR *tmpfile = msi_create_temp_file( package->db );
if (!tmpfile) return ERROR_INSTALL_FAILURE; if (!tmpfile) return ERROR_INSTALL_FAILURE;
if (ApplyPatchToFileW( patch->path, patch->File->TargetPath, tmpfile, 0 )) if (msi_apply_filepatch( package, patch->path, patch->File->TargetPath, tmpfile ))
{ {
DeleteFileW( patch->File->TargetPath ); msi_delete_file( package, patch->File->TargetPath );
MoveFileW( tmpfile, patch->File->TargetPath ); msi_move_file( package, tmpfile, patch->File->TargetPath, 0 );
} }
else else
{ {
...@@ -557,7 +760,7 @@ static UINT patch_assembly( MSIPACKAGE *package, MSIASSEMBLY *assembly, MSIFILEP ...@@ -557,7 +760,7 @@ static UINT patch_assembly( MSIPACKAGE *package, MSIASSEMBLY *assembly, MSIFILEP
if ((path = msi_get_assembly_path( package, displayname ))) if ((path = msi_get_assembly_path( package, displayname )))
{ {
if (!CopyFileW( path, patch->File->TargetPath, FALSE )) if (!msi_copy_file( package, path, patch->File->TargetPath, FALSE ))
{ {
ERR("Failed to copy file %s -> %s (%u)\n", debugstr_w(path), ERR("Failed to copy file %s -> %s (%u)\n", debugstr_w(path),
debugstr_w(patch->File->TargetPath), GetLastError() ); debugstr_w(patch->File->TargetPath), GetLastError() );
...@@ -679,12 +882,12 @@ typedef struct ...@@ -679,12 +882,12 @@ typedef struct
LPWSTR dest; LPWSTR dest;
} FILE_LIST; } FILE_LIST;
static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options) static BOOL move_file( MSIPACKAGE *package, const WCHAR *source, const WCHAR *dest, int options )
{ {
BOOL ret; BOOL ret;
if (GetFileAttributesW(source) == FILE_ATTRIBUTE_DIRECTORY || if (msi_get_file_attributes( package, source ) == FILE_ATTRIBUTE_DIRECTORY ||
GetFileAttributesW(dest) == FILE_ATTRIBUTE_DIRECTORY) msi_get_file_attributes( package, dest ) == FILE_ATTRIBUTE_DIRECTORY)
{ {
WARN("Source or dest is directory, not moving\n"); WARN("Source or dest is directory, not moving\n");
return FALSE; return FALSE;
...@@ -693,20 +896,20 @@ static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options) ...@@ -693,20 +896,20 @@ static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options)
if (options == msidbMoveFileOptionsMove) if (options == msidbMoveFileOptionsMove)
{ {
TRACE("moving %s -> %s\n", debugstr_w(source), debugstr_w(dest)); TRACE("moving %s -> %s\n", debugstr_w(source), debugstr_w(dest));
ret = MoveFileExW(source, dest, MOVEFILE_REPLACE_EXISTING); ret = msi_move_file( package, source, dest, MOVEFILE_REPLACE_EXISTING );
if (!ret) if (!ret)
{ {
WARN("MoveFile failed: %d\n", GetLastError()); WARN("msi_move_file failed: %u\n", GetLastError());
return FALSE; return FALSE;
} }
} }
else else
{ {
TRACE("copying %s -> %s\n", debugstr_w(source), debugstr_w(dest)); TRACE("copying %s -> %s\n", debugstr_w(source), debugstr_w(dest));
ret = CopyFileW(source, dest, FALSE); ret = msi_copy_file( package, source, dest, FALSE );
if (!ret) if (!ret)
{ {
WARN("CopyFile failed: %d\n", GetLastError()); WARN("msi_copy_file failed: %u\n", GetLastError());
return FALSE; return FALSE;
} }
} }
...@@ -714,16 +917,17 @@ static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options) ...@@ -714,16 +917,17 @@ static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options)
return TRUE; return TRUE;
} }
static LPWSTR wildcard_to_file(LPWSTR wildcard, LPWSTR filename) static WCHAR *wildcard_to_file( const WCHAR *wildcard, const WCHAR *filename )
{ {
LPWSTR path, ptr; const WCHAR *ptr;
WCHAR *path;
DWORD dirlen, pathlen; DWORD dirlen, pathlen;
ptr = strrchrW(wildcard, '\\'); ptr = strrchrW(wildcard, '\\');
dirlen = ptr - wildcard + 1; dirlen = ptr - wildcard + 1;
pathlen = dirlen + lstrlenW(filename) + 1; pathlen = dirlen + lstrlenW(filename) + 1;
path = msi_alloc(pathlen * sizeof(WCHAR)); if (!(path = msi_alloc(pathlen * sizeof(WCHAR)))) return NULL;
lstrcpynW(path, wildcard, dirlen + 1); lstrcpynW(path, wildcard, dirlen + 1);
lstrcatW(path, filename); lstrcatW(path, filename);
...@@ -749,10 +953,10 @@ static void free_list(FILE_LIST *list) ...@@ -749,10 +953,10 @@ static void free_list(FILE_LIST *list)
} }
} }
static BOOL add_wildcard(FILE_LIST *files, LPWSTR source, LPWSTR dest) static BOOL add_wildcard( FILE_LIST *files, const WCHAR *source, WCHAR *dest )
{ {
FILE_LIST *new, *file; FILE_LIST *new, *file;
LPWSTR ptr, filename; WCHAR *ptr, *filename;
DWORD size; DWORD size;
new = msi_alloc_zero(sizeof(FILE_LIST)); new = msi_alloc_zero(sizeof(FILE_LIST));
...@@ -800,7 +1004,7 @@ static BOOL add_wildcard(FILE_LIST *files, LPWSTR source, LPWSTR dest) ...@@ -800,7 +1004,7 @@ static BOOL add_wildcard(FILE_LIST *files, LPWSTR source, LPWSTR dest)
return TRUE; return TRUE;
} }
static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options) static BOOL move_files_wildcard( MSIPACKAGE *package, const WCHAR *source, WCHAR *dest, int options )
{ {
WIN32_FIND_DATAW wfd; WIN32_FIND_DATAW wfd;
HANDLE hfile; HANDLE hfile;
...@@ -809,16 +1013,16 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options) ...@@ -809,16 +1013,16 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options)
FILE_LIST files, *file; FILE_LIST files, *file;
DWORD size; DWORD size;
hfile = FindFirstFileW(source, &wfd); hfile = msi_find_first_file( package, source, &wfd );
if (hfile == INVALID_HANDLE_VALUE) return FALSE; if (hfile == INVALID_HANDLE_VALUE) return FALSE;
list_init(&files.entry); list_init(&files.entry);
for (res = TRUE; res; res = FindNextFileW(hfile, &wfd)) for (res = TRUE; res; res = msi_find_next_file( package, hfile, &wfd ))
{ {
if (is_dot_dir(wfd.cFileName)) continue; if (is_dot_dir(wfd.cFileName)) continue;
path = wildcard_to_file(source, wfd.cFileName); path = wildcard_to_file( source, wfd.cFileName );
if (!path) if (!path)
{ {
res = FALSE; res = FALSE;
...@@ -854,7 +1058,7 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options) ...@@ -854,7 +1058,7 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options)
{ {
file = LIST_ENTRY(list_head(&files.entry), FILE_LIST, entry); file = LIST_ENTRY(list_head(&files.entry), FILE_LIST, entry);
msi_move_file(file->source, file->dest, options); move_file( package, file->source, file->dest, options );
list_remove(&file->entry); list_remove(&file->entry);
free_file_entry(file); free_file_entry(file);
...@@ -910,7 +1114,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) ...@@ -910,7 +1114,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
if (!sourcename) if (!sourcename)
{ {
if (GetFileAttributesW(sourcedir) == INVALID_FILE_ATTRIBUTES) if (msi_get_file_attributes( package, sourcedir ) == INVALID_FILE_ATTRIBUTES)
goto done; goto done;
source = strdupW(sourcedir); source = strdupW(sourcedir);
...@@ -969,9 +1173,9 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) ...@@ -969,9 +1173,9 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
if (destname) if (destname)
lstrcatW(dest, destname); lstrcatW(dest, destname);
if (GetFileAttributesW(destdir) == INVALID_FILE_ATTRIBUTES) if (msi_get_file_attributes( package, destdir ) == INVALID_FILE_ATTRIBUTES)
{ {
if (!msi_create_full_path(destdir)) if (!msi_create_full_path( package, destdir ))
{ {
WARN("failed to create directory %u\n", GetLastError()); WARN("failed to create directory %u\n", GetLastError());
goto done; goto done;
...@@ -979,9 +1183,9 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) ...@@ -979,9 +1183,9 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param )
} }
if (!wildcards) if (!wildcards)
msi_move_file(source, dest, options); move_file( package, source, dest, options );
else else
move_files_wildcard(source, dest, options); move_files_wildcard( package, source, dest, options );
done: done:
uirow = MSI_CreateRecord( 9 ); uirow = MSI_CreateRecord( 9 );
...@@ -1065,7 +1269,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const ...@@ -1065,7 +1269,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const
} }
dst = msi_build_directory_name( 2, dst_path, dst_name ); dst = msi_build_directory_name( 2, dst_path, dst_name );
msi_create_full_path( dst_path ); msi_create_full_path( package, dst_path );
msi_free( dst_name ); msi_free( dst_name );
msi_free( dst_path ); msi_free( dst_path );
...@@ -1115,14 +1319,12 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param) ...@@ -1115,14 +1319,12 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
} }
TRACE("Duplicating file %s to %s\n", debugstr_w(file->TargetPath), debugstr_w(dest)); TRACE("Duplicating file %s to %s\n", debugstr_w(file->TargetPath), debugstr_w(dest));
if (!msi_copy_file( package, file->TargetPath, dest, TRUE ))
if (!CopyFileW( file->TargetPath, dest, TRUE ))
{ {
WARN("Failed to copy file %s -> %s (%u)\n", WARN("Failed to copy file %s -> %s (%u)\n",
debugstr_w(file->TargetPath), debugstr_w(dest), GetLastError()); debugstr_w(file->TargetPath), debugstr_w(dest), GetLastError());
} }
FIXME("We should track these duplicate files as well\n");
FIXME("We should track these duplicate files as well\n");
uirow = MSI_CreateRecord( 9 ); uirow = MSI_CreateRecord( 9 );
MSI_RecordSetStringW( uirow, 1, MSI_RecordGetString( row, 1 ) ); MSI_RecordSetStringW( uirow, 1, MSI_RecordGetString( row, 1 ) );
...@@ -1198,8 +1400,7 @@ static UINT ITERATE_RemoveDuplicateFiles( MSIRECORD *row, LPVOID param ) ...@@ -1198,8 +1400,7 @@ static UINT ITERATE_RemoveDuplicateFiles( MSIRECORD *row, LPVOID param )
} }
TRACE("Removing duplicate %s of %s\n", debugstr_w(dest), debugstr_w(file->TargetPath)); TRACE("Removing duplicate %s of %s\n", debugstr_w(dest), debugstr_w(file->TargetPath));
if (!msi_delete_file( package, dest ))
if (!DeleteFileW( dest ))
{ {
WARN("Failed to delete duplicate file %s (%u)\n", debugstr_w(dest), GetLastError()); WARN("Failed to delete duplicate file %s (%u)\n", debugstr_w(dest), GetLastError());
} }
...@@ -1320,12 +1521,12 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param) ...@@ -1320,12 +1521,12 @@ static UINT ITERATE_RemoveFiles(MSIRECORD *row, LPVOID param)
lstrcatW(path, filename); lstrcatW(path, filename);
TRACE("Deleting misc file: %s\n", debugstr_w(path)); TRACE("Deleting misc file: %s\n", debugstr_w(path));
DeleteFileW(path); msi_delete_file( package, path );
} }
else else
{ {
TRACE("Removing misc directory: %s\n", debugstr_w(dir)); TRACE("Removing misc directory: %s\n", debugstr_w(dir));
RemoveDirectoryW(dir); msi_remove_directory( package, dir );
} }
done: done:
...@@ -1400,7 +1601,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) ...@@ -1400,7 +1601,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
if (file->Version) if (file->Version)
{ {
ver = msi_get_disk_file_version( file->TargetPath ); ver = msi_get_disk_file_version( package, file->TargetPath );
if (ver && msi_compare_file_versions( ver, file->Version ) > 0) if (ver && msi_compare_file_versions( ver, file->Version ) > 0)
{ {
TRACE("newer version detected, not removing file\n"); TRACE("newer version detected, not removing file\n");
...@@ -1415,8 +1616,8 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) ...@@ -1415,8 +1616,8 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
TRACE("removing %s\n", debugstr_w(file->File) ); TRACE("removing %s\n", debugstr_w(file->File) );
SetFileAttributesW( file->TargetPath, FILE_ATTRIBUTE_NORMAL ); msi_set_file_attributes( package, file->TargetPath, FILE_ATTRIBUTE_NORMAL );
if (!DeleteFileW( file->TargetPath )) if (!msi_delete_file( package, file->TargetPath ))
{ {
WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError()); WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError());
} }
......
...@@ -84,7 +84,7 @@ static const WCHAR regfont2[] = ...@@ -84,7 +84,7 @@ static const WCHAR regfont2[] =
* 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
*/ */
static WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id ) static WCHAR *load_ttf_name_id( MSIPACKAGE *package, const WCHAR *filename, DWORD id )
{ {
TT_TABLE_DIRECTORY tblDir; TT_TABLE_DIRECTORY tblDir;
BOOL bFound = FALSE; BOOL bFound = FALSE;
...@@ -96,8 +96,10 @@ static WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id ) ...@@ -96,8 +96,10 @@ static WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id )
LPWSTR ret = NULL; LPWSTR ret = NULL;
int i; int i;
handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING, if (package)
FILE_ATTRIBUTE_NORMAL, 0 ); handle = msi_create_file( package, filename, GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL );
else
handle = CreateFileW( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
ERR("Unable to open font file %s\n", debugstr_w(filename)); ERR("Unable to open font file %s\n", debugstr_w(filename));
...@@ -175,12 +177,12 @@ end: ...@@ -175,12 +177,12 @@ end:
return ret; return ret;
} }
static WCHAR *font_name_from_file( 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}; 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( filename, NAME_ID_FULL_FONT_NAME ))) if ((name = load_ttf_name_id( package, filename, NAME_ID_FULL_FONT_NAME )))
{ {
if (!name[0]) if (!name[0])
{ {
...@@ -196,12 +198,12 @@ static WCHAR *font_name_from_file( const WCHAR *filename ) ...@@ -196,12 +198,12 @@ static WCHAR *font_name_from_file( const WCHAR *filename )
return ret; return ret;
} }
WCHAR *msi_font_version_from_file( const WCHAR *filename ) WCHAR *msi_get_font_file_version( MSIPACKAGE *package, const WCHAR *filename )
{ {
static const WCHAR fmtW[] = {'%','u','.','%','u','.','0','.','0',0}; 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( filename, NAME_ID_VERSION ))) if ((version = load_ttf_name_id( package, filename, NAME_ID_VERSION )))
{ {
int len, major = 0, minor = 0; int len, major = 0, minor = 0;
if ((p = strchrW( version, ';' ))) *p = 0; if ((p = strchrW( version, ';' ))) *p = 0;
...@@ -258,7 +260,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) ...@@ -258,7 +260,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
if (MSI_RecordIsNull(row,2)) if (MSI_RecordIsNull(row,2))
name = font_name_from_file( file->TargetPath ); name = font_name_from_file( package, file->TargetPath );
else else
name = msi_dup_record_field(row,2); name = msi_dup_record_field(row,2);
...@@ -341,7 +343,7 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param ) ...@@ -341,7 +343,7 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param )
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 ); RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 );
if (MSI_RecordIsNull( row, 2 )) if (MSI_RecordIsNull( row, 2 ))
name = font_name_from_file( file->TargetPath ); name = font_name_from_file( package, file->TargetPath );
else else
name = msi_dup_record_field( row, 2 ); name = msi_dup_record_field( row, 2 );
......
...@@ -571,7 +571,7 @@ UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolder ...@@ -571,7 +571,7 @@ UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolder
TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath)); TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath));
attrib = GetFileAttributesW(szFolderPath); attrib = msi_get_file_attributes( package, szFolderPath );
/* native MSI tests writeability by making temporary files at each drive */ /* native MSI tests writeability by making temporary files at each drive */
if (attrib != INVALID_FILE_ATTRIBUTES && if (attrib != INVALID_FILE_ATTRIBUTES &&
(attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY)) (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY))
......
...@@ -439,12 +439,11 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, ...@@ -439,12 +439,11 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
attrs = attrs & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); attrs = attrs & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL; if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, handle = msi_create_file( data->package, path, GENERIC_READ | GENERIC_WRITE, 0, CREATE_ALWAYS, attrs );
NULL, CREATE_ALWAYS, attrs, NULL);
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
DWORD err = GetLastError(); DWORD err = GetLastError();
DWORD attrs2 = GetFileAttributesW(path); DWORD attrs2 = msi_get_file_attributes( data->package, path );
if (attrs2 == INVALID_FILE_ATTRIBUTES) if (attrs2 == INVALID_FILE_ATTRIBUTES)
{ {
...@@ -454,8 +453,8 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, ...@@ -454,8 +453,8 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY)) else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY))
{ {
TRACE("removing read-only attribute on %s\n", debugstr_w(path)); TRACE("removing read-only attribute on %s\n", debugstr_w(path));
SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY ); msi_set_file_attributes( data->package, path, attrs2 & ~FILE_ATTRIBUTE_READONLY );
handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); handle = msi_create_file( data->package, path, GENERIC_READ | GENERIC_WRITE, 0, CREATE_ALWAYS, attrs );
if (handle != INVALID_HANDLE_VALUE) goto done; if (handle != INVALID_HANDLE_VALUE) goto done;
err = GetLastError(); err = GetLastError();
...@@ -481,8 +480,8 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, ...@@ -481,8 +480,8 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
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);
if (handle != INVALID_HANDLE_VALUE && if (handle != INVALID_HANDLE_VALUE &&
MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && msi_move_file( data->package, path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) &&
MoveFileExW(tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT)) msi_move_file( data->package, tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT ))
{ {
data->package->need_reboot_at_end = 1; data->package->need_reboot_at_end = 1;
} }
......
...@@ -3298,7 +3298,7 @@ UINT WINAPI MsiGetFileVersionW( LPCWSTR path, LPWSTR verbuf, LPDWORD verlen, ...@@ -3298,7 +3298,7 @@ UINT WINAPI MsiGetFileVersionW( LPCWSTR path, LPWSTR verbuf, LPDWORD verlen,
if (ret == ERROR_RESOURCE_DATA_NOT_FOUND && verlen) if (ret == ERROR_RESOURCE_DATA_NOT_FOUND && verlen)
{ {
int len; int len;
WCHAR *version = msi_font_version_from_file( path ); WCHAR *version = msi_get_font_file_version( NULL, path );
if (!version) return ERROR_FILE_INVALID; if (!version) return ERROR_FILE_INVALID;
len = strlenW( version ); len = strlenW( version );
if (len >= *verlen) ret = ERROR_MORE_DATA; if (len >= *verlen) ret = ERROR_MORE_DATA;
...@@ -4107,14 +4107,17 @@ extern VOID WINAPI MD5Init( MD5_CTX *); ...@@ -4107,14 +4107,17 @@ extern VOID WINAPI MD5Init( MD5_CTX *);
extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int ); extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
extern VOID WINAPI MD5Final( MD5_CTX *); extern VOID WINAPI MD5Final( MD5_CTX *);
UINT msi_get_filehash( const WCHAR *path, MSIFILEHASHINFO *hash ) UINT msi_get_filehash( MSIPACKAGE *package, const WCHAR *path, MSIFILEHASHINFO *hash )
{ {
HANDLE handle, mapping; HANDLE handle, mapping;
void *p; void *p;
DWORD length; DWORD length;
UINT r = ERROR_FUNCTION_FAILED; UINT r = ERROR_FUNCTION_FAILED;
handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL ); if (package)
handle = msi_create_file( package, path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, OPEN_EXISTING, 0 );
else
handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
WARN("can't open file %u\n", GetLastError()); WARN("can't open file %u\n", GetLastError());
...@@ -4171,7 +4174,7 @@ UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions, ...@@ -4171,7 +4174,7 @@ UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
if (pHash->dwFileHashInfoSize < sizeof *pHash) if (pHash->dwFileHashInfoSize < sizeof *pHash)
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
return msi_get_filehash( szFilePath, pHash ); return msi_get_filehash( NULL, szFilePath, pHash );
} }
/*********************************************************************** /***********************************************************************
......
...@@ -389,6 +389,7 @@ typedef struct tagMSIPACKAGE ...@@ -389,6 +389,7 @@ typedef struct tagMSIPACKAGE
enum platform platform; enum platform platform;
UINT num_langids; UINT num_langids;
LANGID *langids; LANGID *langids;
void *cookie;
struct list patches; struct list patches;
struct list components; struct list components;
struct list features; struct list features;
...@@ -937,12 +938,8 @@ extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val) DECLSPEC ...@@ -937,12 +938,8 @@ extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val) DECLSPEC
extern DWORD msi_version_str_to_dword(LPCWSTR p) DECLSPEC_HIDDEN; extern DWORD msi_version_str_to_dword(LPCWSTR p) DECLSPEC_HIDDEN;
extern void msi_parse_version_string(LPCWSTR, PDWORD, PDWORD) DECLSPEC_HIDDEN; extern void msi_parse_version_string(LPCWSTR, PDWORD, PDWORD) DECLSPEC_HIDDEN;
extern VS_FIXEDFILEINFO *msi_get_disk_file_version(LPCWSTR) DECLSPEC_HIDDEN;
extern int msi_compare_file_versions(VS_FIXEDFILEINFO *, const WCHAR *) DECLSPEC_HIDDEN; extern int msi_compare_file_versions(VS_FIXEDFILEINFO *, const WCHAR *) DECLSPEC_HIDDEN;
extern int msi_compare_font_versions(const WCHAR *, const WCHAR *) DECLSPEC_HIDDEN; extern int msi_compare_font_versions(const WCHAR *, const WCHAR *) DECLSPEC_HIDDEN;
extern DWORD msi_get_disk_file_size(LPCWSTR) DECLSPEC_HIDDEN;
extern BOOL msi_file_hash_matches(MSIFILE *) DECLSPEC_HIDDEN;
extern UINT msi_get_filehash(const WCHAR *, MSIFILEHASHINFO *) DECLSPEC_HIDDEN;
extern LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value ) DECLSPEC_HIDDEN; extern LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value ) DECLSPEC_HIDDEN;
extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value ) DECLSPEC_HIDDEN; extern LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value ) DECLSPEC_HIDDEN;
...@@ -1034,7 +1031,6 @@ extern WCHAR *msi_create_temp_file(MSIDATABASE *db) DECLSPEC_HIDDEN; ...@@ -1034,7 +1031,6 @@ extern WCHAR *msi_create_temp_file(MSIDATABASE *db) DECLSPEC_HIDDEN;
extern void msi_free_action_script(MSIPACKAGE *package, UINT script) DECLSPEC_HIDDEN; extern void msi_free_action_script(MSIPACKAGE *package, UINT script) DECLSPEC_HIDDEN;
extern WCHAR *msi_build_icon_path(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_build_icon_path(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR *msi_build_directory_name(DWORD , ...) DECLSPEC_HIDDEN; extern WCHAR *msi_build_directory_name(DWORD , ...) DECLSPEC_HIDDEN;
extern BOOL msi_create_full_path(const WCHAR *path) DECLSPEC_HIDDEN;
extern void msi_reduce_to_long_filename(WCHAR *) DECLSPEC_HIDDEN; extern void msi_reduce_to_long_filename(WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR *msi_create_component_advertise_string(MSIPACKAGE *, MSICOMPONENT *, const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_create_component_advertise_string(MSIPACKAGE *, MSICOMPONENT *, const WCHAR *) DECLSPEC_HIDDEN;
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, MSIFEATURE *feature) DECLSPEC_HIDDEN; extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, MSIFEATURE *feature) DECLSPEC_HIDDEN;
...@@ -1052,7 +1048,6 @@ extern void msi_destroy_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN; ...@@ -1052,7 +1048,6 @@ extern void msi_destroy_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN;
extern BOOL msi_is_global_assembly(MSICOMPONENT *) DECLSPEC_HIDDEN; extern BOOL msi_is_global_assembly(MSICOMPONENT *) DECLSPEC_HIDDEN;
extern IAssemblyEnum *msi_create_assembly_enum(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN; extern IAssemblyEnum *msi_create_assembly_enum(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR *msi_get_assembly_path(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN; extern WCHAR *msi_get_assembly_path(MSIPACKAGE *, const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR *msi_font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN; extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN;
extern UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *) DECLSPEC_HIDDEN; extern UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR *msi_get_error_message(MSIDATABASE *, int) DECLSPEC_HIDDEN; extern WCHAR *msi_get_error_message(MSIDATABASE *, int) DECLSPEC_HIDDEN;
...@@ -1060,6 +1055,30 @@ extern UINT msi_strncpyWtoA(const WCHAR *str, int len, char *buf, DWORD *sz, BOO ...@@ -1060,6 +1055,30 @@ extern UINT msi_strncpyWtoA(const WCHAR *str, int len, char *buf, DWORD *sz, BOO
extern UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz) DECLSPEC_HIDDEN; extern UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz) DECLSPEC_HIDDEN;
extern WCHAR *msi_get_package_code(MSIDATABASE *db) DECLSPEC_HIDDEN; extern WCHAR *msi_get_package_code(MSIDATABASE *db) DECLSPEC_HIDDEN;
/* wrappers for filesystem functions */
static inline void msi_disable_fs_redirection( MSIPACKAGE *package )
{
if (is_wow64 && package->platform == PLATFORM_X64) Wow64DisableWow64FsRedirection( &package->cookie );
}
static inline void msi_revert_fs_redirection( MSIPACKAGE *package )
{
if (is_wow64 && package->platform == PLATFORM_X64) Wow64RevertWow64FsRedirection( package->cookie );
}
extern HANDLE msi_create_file( MSIPACKAGE *, const WCHAR *, DWORD, DWORD, DWORD, DWORD ) DECLSPEC_HIDDEN;
extern BOOL msi_delete_file( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
extern BOOL msi_remove_directory( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
extern DWORD msi_get_file_attributes( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
extern BOOL msi_set_file_attributes( MSIPACKAGE *, const WCHAR *, DWORD ) DECLSPEC_HIDDEN;
extern HANDLE msi_find_first_file( MSIPACKAGE *, const WCHAR *, WIN32_FIND_DATAW * ) DECLSPEC_HIDDEN;
extern BOOL msi_find_next_file( MSIPACKAGE *, HANDLE, WIN32_FIND_DATAW * ) DECLSPEC_HIDDEN;
extern BOOL msi_move_file( MSIPACKAGE *, const WCHAR *, const WCHAR *, DWORD ) DECLSPEC_HIDDEN;
extern DWORD msi_get_file_version_info( MSIPACKAGE *, const WCHAR *, DWORD, BYTE * ) DECLSPEC_HIDDEN;
extern BOOL msi_create_full_path( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
extern DWORD msi_get_disk_file_size( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
extern VS_FIXEDFILEINFO *msi_get_disk_file_version( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
extern UINT msi_get_filehash( MSIPACKAGE *, const WCHAR *, MSIFILEHASHINFO * ) DECLSPEC_HIDDEN;
extern WCHAR *msi_get_font_file_version( MSIPACKAGE *, const WCHAR * ) DECLSPEC_HIDDEN;
/* media */ /* media */
typedef BOOL (*PMSICABEXTRACTCB)(MSIPACKAGE *, LPCWSTR, DWORD, LPWSTR *, DWORD *, PVOID); typedef BOOL (*PMSICABEXTRACTCB)(MSIPACKAGE *, LPCWSTR, DWORD, LPWSTR *, DWORD *, PVOID);
......
...@@ -1630,6 +1630,13 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage) ...@@ -1630,6 +1630,13 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage)
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (!msi_init_assembly_caches( package ))
{
ERR("can't initialize assembly caches\n");
msiobj_release( &package->hdr );
return ERROR_FUNCTION_FAILED;
}
/* FIXME: when should these messages be sent? */ /* FIXME: when should these messages be sent? */
data_row = MSI_CreateRecord(3); data_row = MSI_CreateRecord(3);
if (!data_row) if (!data_row)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment