From 15f852015a0332313821804cc1fbad79216408c6 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 20 Mar 2019 09:43:44 +0100 Subject: [PATCH] msi: Disable filesystem redirection only when really needed. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46846 Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/msi/action.c | 236 ++++++++++---------------------- dlls/msi/appsearch.c | 172 ++++++++++------------- dlls/msi/custom.c | 2 +- dlls/msi/files.c | 319 +++++++++++++++++++++++++++++++++++-------- dlls/msi/font.c | 20 +-- dlls/msi/install.c | 2 +- dlls/msi/media.c | 13 +- dlls/msi/msi.c | 11 +- dlls/msi/msipriv.h | 31 ++++- dlls/msi/package.c | 7 + 10 files changed, 467 insertions(+), 346 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index d95960590cd..b51a21d4577 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -718,50 +718,6 @@ MSIFOLDER *msi_get_loaded_folder( MSIPACKAGE *package, const WCHAR *dir ) 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 ) { MSIRECORD *row; @@ -843,8 +799,9 @@ static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param) TRACE("folder is %s\n", debugstr_w(full_path)); 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; + return ERROR_SUCCESS; } @@ -2054,37 +2011,6 @@ static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param) 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 ) { DWORD ms, ls; @@ -2110,33 +2036,6 @@ int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 ) 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 UINT id; @@ -2262,17 +2161,17 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) set_target_path( package, file ); 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; 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); 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) { @@ -2281,7 +2180,7 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) msi_free( file_version ); 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) { @@ -2296,6 +2195,7 @@ static UINT calculate_file_cost( MSIPACKAGE *package ) comp->Cost += file->FileSize - file_size; } } + return ERROR_SUCCESS; } @@ -3754,6 +3654,24 @@ static BOOL CALLBACK Typelib_EnumResNameProc( HMODULE hModule, LPCWSTR lpszType, 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) { MSIPACKAGE* package = param; @@ -3784,7 +3702,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) } 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) { LPCWSTR guid; @@ -3821,7 +3739,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param) } else { - hr = LoadTypeLibEx(file->TargetPath, REGKIND_REGISTER, &tlib); + hr = msi_load_typelib( package, file->TargetPath, REGKIND_REGISTER, &tlib ); if (FAILED(hr)) { ERR("Failed to load type library: %08x\n", hr); @@ -3932,7 +3850,7 @@ static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row ) return NULL; } /* 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 ); msi_reduce_to_long_filename( filename ); @@ -3965,7 +3883,7 @@ WCHAR *msi_build_icon_path( MSIPACKAGE *package, const WCHAR *icon_name ) msi_free( appdata ); } 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 ); msi_free( folder ); msi_free( dest ); @@ -4069,10 +3987,14 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param) full_path = msi_get_target_folder( package, wkdir ); 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)); + + msi_disable_fs_redirection( package ); IPersistFile_Save(pf, link_file, FALSE); + msi_revert_fs_redirection( package ); + msi_free(link_file); err: @@ -4130,12 +4052,8 @@ static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param ) MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row); link_file = get_link_file( package, row ); - TRACE("Removing shortcut file %s\n", debugstr_w( link_file )); - if (!DeleteFileW( link_file )) - { - WARN("Failed to remove shortcut file %u\n", GetLastError()); - } + if (!msi_delete_file( package, link_file )) WARN("Failed to remove shortcut file %u\n", GetLastError()); msi_free( link_file ); return ERROR_SUCCESS; @@ -4163,51 +4081,49 @@ static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package ) static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param) { - MSIPACKAGE* package = param; - HANDLE the_file; - LPWSTR FilePath; - LPCWSTR FileName; - CHAR buffer[1024]; + MSIPACKAGE *package = param; + HANDLE handle; + WCHAR *icon_path; + const WCHAR *filename; + char buffer[1024]; DWORD sz; UINT rc; - FileName = MSI_RecordGetString(row,1); - if (!FileName) + filename = MSI_RecordGetString( row, 1 ); + if (!filename) { - ERR("Unable to get FileName\n"); + ERR("Unable to get filename\n"); 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)); + TRACE("Creating icon file at %s\n", debugstr_w(icon_path)); - the_file = CreateFileW(FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - 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)); - msi_free(FilePath); + ERR("Unable to create file %s\n", debugstr_w(icon_path)); + msi_free( icon_path ); return ERROR_SUCCESS; } - do + do { - DWORD write; + DWORD count; sz = 1024; - rc = MSI_RecordReadStream(row,2,buffer,&sz); + rc = MSI_RecordReadStream( row, 2, buffer, &sz ); if (rc != ERROR_SUCCESS) { ERR("Failed to get stream\n"); - DeleteFileW(FilePath); + msi_delete_file( package, icon_path ); break; } - WriteFile(the_file,buffer,sz,&write,NULL); + WriteFile( handle, buffer, sz, &count, NULL ); } while (sz == 1024); - msi_free(FilePath); - CloseHandle(the_file); + msi_free( icon_path ); + CloseHandle( handle ); return ERROR_SUCCESS; } @@ -5405,11 +5321,11 @@ static UINT ITERATE_UnpublishIcon( MSIRECORD *row, LPVOID param ) if ((icon_path = msi_build_icon_path( package, icon ))) { TRACE("removing icon file %s\n", debugstr_w(icon_path)); - DeleteFileW( icon_path ); + msi_delete_file( package, icon_path ); if ((p = strrchrW( icon_path, '\\' ))) { *p = 0; - RemoveDirectoryW( icon_path ); + msi_remove_directory( package, icon_path ); } msi_free( icon_path ); } @@ -7827,9 +7743,18 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package ) 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()); } @@ -7851,8 +7776,9 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param ) return ERROR_SUCCESS; } if (!(filenameA = strdupWtoA( file->TargetPath ))) return ERROR_SUCCESS; + path_list = msi_split_string( paths, ';' ); - if (!path_list) bind_image( filenameA, NULL ); + if (!path_list) bind_image( package, filenameA, NULL ); else { for (i = 0; path_list[i] && path_list[i][0]; i++) @@ -7860,7 +7786,7 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param ) deformat_string( package, path_list[i], &pathW ); if ((pathA = strdupWtoA( pathW ))) { - bind_image( filenameA, pathA ); + bind_image( package, filenameA, pathA ); msi_free( pathA ); } msi_free( pathW ); @@ -7868,6 +7794,7 @@ static UINT ITERATE_BindImage( MSIRECORD *rec, LPVOID param ) } msi_free( path_list ); msi_free( filenameA ); + return ERROR_SUCCESS; } @@ -7884,10 +7811,8 @@ static UINT ACTION_BindImage( MSIPACKAGE *package ) { r = MSI_IterateRecords( view, NULL, ITERATE_BindImage, package ); 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 ) @@ -8034,12 +7959,8 @@ StandardActions[] = static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action) { UINT rc = ERROR_FUNCTION_NOT_CALLED; - void *cookie; UINT i; - if (is_wow64 && package->platform == PLATFORM_X64) - Wow64DisableWow64FsRedirection(&cookie); - i = 0; while (StandardActions[i].action != NULL) { @@ -8075,9 +7996,6 @@ static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action) i++; } - if (is_wow64 && package->platform == PLATFORM_X64) - Wow64RevertWow64FsRedirection(cookie); - return rc; } @@ -8087,12 +8005,6 @@ UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *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; rc = ACTION_HandleStandardAction(package, action); diff --git a/dlls/msi/appsearch.c b/dlls/msi/appsearch.c index 806365191d0..047085d1f39 100644 --- a/dlls/msi/appsearch.c +++ b/dlls/msi/appsearch.c @@ -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 * 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[] = { 's','e','l','e','c','t',' ','*',' ', @@ -155,16 +155,16 @@ static UINT ACTION_AppSearchGetSignature(MSIPACKAGE *package, MSISIGNATURE *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->Languages); } -static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig) +static WCHAR *search_file( MSIPACKAGE *package, WCHAR *path, MSISIGNATURE *sig ) { VS_FIXEDFILEINFO *info; - DWORD attr, handle, size; + DWORD attr, size; LPWSTR val = NULL; LPBYTE buffer; @@ -173,20 +173,18 @@ static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig) PathRemoveFileSpecW(path); PathAddBackslashW(path); - attr = GetFileAttributesW(path); - if (attr != INVALID_FILE_ATTRIBUTES && - (attr & FILE_ATTRIBUTE_DIRECTORY)) + attr = msi_get_file_attributes( package, path ); + if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) return strdupW(path); return NULL; } - attr = GetFileAttributesW(path); - if (attr == INVALID_FILE_ATTRIBUTES || - (attr & FILE_ATTRIBUTE_DIRECTORY)) + attr = msi_get_file_attributes( package, path ); + if (attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) return NULL; - size = GetFileVersionInfoSizeW(path, &handle); + size = msi_get_file_version_info( package, path, 0, NULL ); if (!size) return strdupW(path); @@ -194,7 +192,8 @@ static LPWSTR app_search_file(LPWSTR path, MSISIGNATURE *sig) if (!buffer) return NULL; - if (!GetFileVersionInfoW(path, 0, size, buffer)) + size = msi_get_file_version_info( package, path, size, buffer ); + if (!size) goto done; if (!VerQueryValueW(buffer, szBackSlash, (LPVOID)&info, &size) || !info) @@ -227,7 +226,7 @@ done: 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[] = { 'S','E','L','E','C','T',' ','*',' ', @@ -240,7 +239,6 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS '`','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; LPCWSTR signature, guid; BOOL sigpresent = TRUE; @@ -275,7 +273,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS if (!*path) goto done; - attr = GetFileAttributesW(path); + attr = msi_get_file_attributes( package, path ); if (attr == INVALID_FILE_ATTRIBUTES) goto done; @@ -283,7 +281,7 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS if (type != msidbLocatorTypeDirectory && sigpresent && !isdir) { - *appValue = app_search_file(path, sig); + *appValue = search_file( package, path, sig ); } else if (!sigpresent && (type != msidbLocatorTypeDirectory || isdir)) { @@ -302,9 +300,8 @@ static UINT ACTION_AppSearchComponents(MSIPACKAGE *package, LPWSTR *appValue, MS PathAddBackslashW(path); lstrcatW(path, MSI_RecordGetString(rec, 2)); - attr = GetFileAttributesW(path); - if (attr != INVALID_FILE_ATTRIBUTES && - !(attr & FILE_ATTRIBUTE_DIRECTORY)) + attr = msi_get_file_attributes( package, path ); + if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY)) *appValue = strdupW(path); } @@ -314,8 +311,7 @@ done: return ERROR_SUCCESS; } -static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz, - LPWSTR *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' }; @@ -365,10 +361,9 @@ static void ACTION_ConvertRegValue(DWORD regType, const BYTE *value, DWORD sz, } } -static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, - LPCWSTR path, int depth, LPWSTR *appValue); +static UINT search_directory( MSIPACKAGE *, MSISIGNATURE *, const WCHAR *, int, WCHAR ** ); -static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *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',' ', @@ -473,13 +468,13 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT switch (type & 0x0f) { case msidbLocatorTypeDirectory: - ACTION_SearchDirectory(package, sig, ptr, 0, appValue); + search_directory( package, sig, ptr, 0, appValue ); break; case msidbLocatorTypeFileName: - *appValue = app_search_file(ptr, sig); + *appValue = search_file( package, ptr, sig ); break; case msidbLocatorTypeRawValue: - ACTION_ConvertRegValue(regType, value, sz, appValue); + convert_reg_value( regType, value, sz, appValue ); break; default: FIXME("unimplemented for type %d (key path %s, value %s)\n", @@ -520,8 +515,7 @@ static LPWSTR get_ini_field(LPWSTR buf, int field) return strdupW(beg); } -static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, - MSISIGNATURE *sig) +static UINT search_ini( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', @@ -561,10 +555,10 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, switch (type & 0x0f) { case msidbLocatorTypeDirectory: - ACTION_SearchDirectory(package, sig, buf, 0, appValue); + search_directory( package, sig, buf, 0, appValue ); break; case msidbLocatorTypeFileName: - *appValue = app_search_file(buf, sig); + *appValue = search_file( package, buf, sig ); break; case msidbLocatorTypeRawValue: *appValue = get_ini_field(buf, field); @@ -590,8 +584,7 @@ static UINT ACTION_AppSearchIni(MSIPACKAGE *package, LPWSTR *appValue, * - what does AppSearch return if the table values are invalid? * - what if dst is too small? */ -static void ACTION_ExpandAnyPath(MSIPACKAGE *package, WCHAR *src, WCHAR *dst, - size_t len) +static void expand_any_path( MSIPACKAGE *package, WCHAR *src, WCHAR *dst, size_t len ) { WCHAR *ptr, *deformatted; @@ -685,20 +678,20 @@ done: * Return ERROR_SUCCESS in case of success (whether or not the file matches), * something else if an install-halting error occurs. */ -static UINT ACTION_FileVersionMatches(const MSISIGNATURE *sig, LPCWSTR filePath, - BOOL *matches) +static UINT file_version_matches( MSIPACKAGE *package, const MSISIGNATURE *sig, const WCHAR *filePath, + BOOL *matches ) { UINT len; void *version; VS_FIXEDFILEINFO *info = NULL; - DWORD zero, size = GetFileVersionInfoSizeW( filePath, &zero ); + DWORD size = msi_get_file_version_info( package, filePath, 0, NULL ); *matches = FALSE; if (!size) return ERROR_SUCCESS; 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 ); if (info) @@ -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), * something else if an install-halting error occurs. */ -static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig, - const WIN32_FIND_DATAW *findData, LPCWSTR fullFilePath, BOOL *matches) +static UINT file_matches_sig( MSIPACKAGE *package, const MSISIGNATURE *sig, const WIN32_FIND_DATAW *findData, + const WCHAR *fullFilePath, BOOL *matches ) { UINT rc = ERROR_SUCCESS; @@ -778,7 +771,7 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig, *matches = FALSE; if (*matches && (sig->MinVersionMS || sig->MinVersionLS || sig->MaxVersionMS || sig->MaxVersionLS)) - rc = ACTION_FileVersionMatches(sig, fullFilePath, matches); + rc = file_version_matches( package, sig, fullFilePath, matches ); return rc; } @@ -790,9 +783,10 @@ static UINT ACTION_FileMatchesSig(const MSISIGNATURE *sig, * Returns ERROR_SUCCESS on success (which may include non-critical errors), * something else on failures which should halt the install. */ -static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, - MSISIGNATURE *sig, LPCWSTR dir, int depth) +static UINT recurse_search_directory( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig, const WCHAR *dir, + int depth ) { + static const WCHAR starDotStarW[] = { '*','.','*',0 }; HANDLE hFind; WIN32_FIND_DATAW findData; UINT rc = ERROR_SUCCESS; @@ -801,10 +795,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, WCHAR *buf; 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) return ERROR_SUCCESS; @@ -823,14 +814,14 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, PathAddBackslashW(buf); lstrcatW(buf, sig->File); - hFind = FindFirstFileW(buf, &findData); + hFind = msi_find_first_file( package, buf, &findData ); if (hFind != INVALID_HANDLE_VALUE) { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { BOOL matches; - rc = ACTION_FileMatchesSig(sig, &findData, buf, &matches); + rc = file_matches_sig( package, sig, &findData, buf, &matches ); if (rc == ERROR_SUCCESS && matches) { TRACE("found file, returning %s\n", debugstr_w(buf)); @@ -846,7 +837,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, PathAddBackslashW(buf); lstrcatW(buf, starDotStarW); - hFind = FindFirstFileW(buf, &findData); + hFind = msi_find_first_file( package, buf, &findData ); if (hFind != INVALID_HANDLE_VALUE) { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && @@ -855,12 +846,10 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, { lstrcpyW(subpath, dir); PathAppendW(subpath, findData.cFileName); - rc = ACTION_RecurseSearchDirectory(package, appValue, sig, - subpath, depth - 1); + rc = recurse_search_directory( package, appValue, sig, subpath, depth - 1 ); } - while (rc == ERROR_SUCCESS && !*appValue && - FindNextFileW(hFind, &findData) != 0) + while (rc == ERROR_SUCCESS && !*appValue && msi_find_next_file( package, hFind, &findData )) { if (!strcmpW( findData.cFileName, szDot ) || !strcmpW( findData.cFileName, szDotDot )) @@ -869,8 +858,7 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, lstrcpyW(subpath, dir); PathAppendW(subpath, findData.cFileName); if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - rc = ACTION_RecurseSearchDirectory(package, appValue, - sig, subpath, depth - 1); + rc = recurse_search_directory( package, appValue, sig, subpath, depth - 1 ); } FindClose(hFind); @@ -883,10 +871,9 @@ static UINT ACTION_RecurseSearchDirectory(MSIPACKAGE *package, LPWSTR *appValue, return rc; } -static UINT ACTION_CheckDirectory(MSIPACKAGE *package, LPCWSTR dir, - LPWSTR *appValue) +static UINT check_directory( MSIPACKAGE *package, const WCHAR *dir, WCHAR **appValue ) { - DWORD attr = GetFileAttributesW(dir); + DWORD attr = msi_get_file_attributes( package, dir ); if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) { @@ -897,7 +884,7 @@ static UINT ACTION_CheckDirectory(MSIPACKAGE *package, LPCWSTR dir, return ERROR_SUCCESS; } -static BOOL ACTION_IsFullPath(LPCWSTR path) +static BOOL is_full_path( const WCHAR *path ) { WCHAR first = toupperW(path[0]); BOOL ret; @@ -911,26 +898,24 @@ static BOOL ACTION_IsFullPath(LPCWSTR path) return ret; } -static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, - LPCWSTR path, int depth, LPWSTR *appValue) +static UINT search_directory( MSIPACKAGE *package, MSISIGNATURE *sig, const WCHAR *path, int depth, WCHAR **appValue ) { UINT rc; DWORD attr; LPWSTR val = NULL; - TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth, - appValue); + TRACE("%p, %p, %s, %d, %p\n", package, sig, debugstr_w(path), depth, appValue); - if (ACTION_IsFullPath(path)) + if (is_full_path( path )) { if (sig->File) - rc = ACTION_RecurseSearchDirectory(package, &val, sig, path, depth); + rc = recurse_search_directory( package, &val, sig, path, depth ); else { /* Recursively searching a directory makes no sense when the * directory to search is the thing you're trying to find. */ - rc = ACTION_CheckDirectory(package, path, &val); + rc = check_directory( package, path, &val ); } } else @@ -952,16 +937,14 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, lstrcpynW(pathWithDrive + 3, path, ARRAY_SIZE(pathWithDrive) - 3); if (sig->File) - rc = ACTION_RecurseSearchDirectory(package, &val, sig, - pathWithDrive, depth); + rc = recurse_search_directory( package, &val, sig, pathWithDrive, depth ); else - rc = ACTION_CheckDirectory(package, pathWithDrive, &val); + rc = check_directory( package, pathWithDrive, &val ); } } - attr = GetFileAttributesW(val); - if (attr != INVALID_FILE_ATTRIBUTES && - (attr & FILE_ATTRIBUTE_DIRECTORY) && + attr = msi_get_file_attributes( package, val ); + if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) && val && val[lstrlenW(val) - 1] != '\\') { val = msi_realloc(val, (lstrlenW(val) + 2) * sizeof(WCHAR)); @@ -977,10 +960,9 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig, return rc; } -static UINT ACTION_AppSearchSigName(MSIPACKAGE *package, LPCWSTR sigName, - MSISIGNATURE *sig, LPWSTR *appValue); +static UINT search_sig_name( MSIPACKAGE *, const WCHAR *, MSISIGNATURE *, WCHAR ** ); -static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATURE *sig) +static UINT search_dr( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', @@ -1014,8 +996,8 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU { MSISIGNATURE parentSig; - ACTION_AppSearchSigName(package, parentName, &parentSig, &parent); - ACTION_FreeSignature(&parentSig); + search_sig_name( package, parentName, &parentSig, &parent ); + free_signature( &parentSig ); if (!parent) { msiobj_release(&row->hdr); @@ -1032,13 +1014,13 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU depth = MSI_RecordGetInteger(row,4); if (sz) - ACTION_ExpandAnyPath(package, path, expanded, MAX_PATH); + expand_any_path( package, path, expanded, MAX_PATH ); else strcpyW(expanded, path); if (parent) { - attr = GetFileAttributesW(parent); + attr = msi_get_file_attributes( package, parent ); if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY)) { @@ -1049,45 +1031,42 @@ static UINT ACTION_AppSearchDr(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNATU strcpyW(path, parent); strcatW(path, expanded); } - else if (sz) - strcpyW(path, expanded); + else if (sz) strcpyW(path, expanded); PathAddBackslashW(path); - rc = ACTION_SearchDirectory(package, sig, path, depth, appValue); + rc = search_directory( package, sig, path, depth, appValue ); msi_free(parent); msiobj_release(&row->hdr); - TRACE("returning %d\n", rc); return rc; } -static UINT ACTION_AppSearchSigName(MSIPACKAGE *package, LPCWSTR sigName, - MSISIGNATURE *sig, LPWSTR *appValue) +static UINT search_sig_name( MSIPACKAGE *package, const WCHAR *sigName, MSISIGNATURE *sig, WCHAR **appValue ) { UINT rc; *appValue = NULL; - rc = ACTION_AppSearchGetSignature(package, sig, sigName); + rc = get_signature( package, sig, sigName ); if (rc == ERROR_SUCCESS) { - rc = ACTION_AppSearchComponents(package, appValue, sig); + rc = search_components( package, appValue, sig ); if (rc == ERROR_SUCCESS && !*appValue) { - rc = ACTION_AppSearchReg(package, appValue, sig); + rc = search_reg( package, appValue, sig ); if (rc == ERROR_SUCCESS && !*appValue) { - rc = ACTION_AppSearchIni(package, appValue, sig); + rc = search_ini( package, appValue, sig ); if (rc == ERROR_SUCCESS && !*appValue) - rc = ACTION_AppSearchDr(package, appValue, sig); + rc = search_dr( package, appValue, sig ); } } } return rc; } -static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) +static UINT ITERATE_AppSearch(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; LPCWSTR propName, sigName; @@ -1102,7 +1081,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) 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) { r = msi_set_property( package->db, propName, value, -1 ); @@ -1111,7 +1090,7 @@ static UINT iterate_appsearch(MSIRECORD *row, LPVOID param) msi_free(value); } - ACTION_FreeSignature(&sig); + free_signature( &sig ); uirow = MSI_CreateRecord( 2 ); MSI_RecordSetStringW( uirow, 1, propName ); @@ -1142,7 +1121,7 @@ UINT ACTION_AppSearch(MSIPACKAGE *package) if (r != 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 ); return r; } @@ -1161,7 +1140,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) TRACE("%s\n", debugstr_w(signature)); - ACTION_AppSearchSigName(package, signature, &sig, &value); + search_sig_name( package, signature, &sig, &value ); if (value) { TRACE("Found signature %s\n", debugstr_w(signature)); @@ -1170,8 +1149,7 @@ static UINT ITERATE_CCPSearch(MSIRECORD *row, LPVOID param) r = ERROR_NO_MORE_ITEMS; } - ACTION_FreeSignature(&sig); - + free_signature(&sig); return r; } diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index 3cb0f3170a7..8bf0902914f 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -1188,7 +1188,7 @@ static UINT HANDLE_CustomType21_22( MSIPACKAGE *package, const WCHAR *source, co 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; sz = GetFileSize(hFile, &szHighWord); diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 5a88c147e0b..92a98f1eca0 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ - /* * Actions dealing with files: * @@ -37,7 +36,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "wine/debug.h" #include "fdi.h" #include "msi.h" #include "msidefs.h" @@ -46,10 +44,202 @@ #include "winreg.h" #include "shlwapi.h" #include "patchapi.h" +#include "wine/debug.h" #include "wine/unicode.h" 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 ) { MSIRECORD *uirow; @@ -85,6 +275,19 @@ static BOOL is_obsoleted_by_patch( MSIPACKAGE *package, MSIFILE *file ) 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 ) { MSICOMPONENT *comp = file->Component; @@ -105,14 +308,14 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil return msifs_skipped; } 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)); return msifs_missing; } 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) { @@ -133,7 +336,7 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil msi_free( file_version ); 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) { @@ -151,14 +354,14 @@ static msi_file_state calculate_install_state( MSIPACKAGE *package, MSIFILE *fil 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); return msifs_overwrite; } 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)); return msifs_hashmatch; @@ -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; - ret = CopyFileW(source, file->TargetPath, FALSE); + ret = msi_copy_file( package, source, file->TargetPath, FALSE ); if (!ret) return GetLastError(); - SetFileAttributesW(file->TargetPath, FILE_ATTRIBUTE_NORMAL); + msi_set_file_attributes( package, file->TargetPath, FILE_ATTRIBUTE_NORMAL ); return ERROR_SUCCESS; } @@ -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)); - gle = copy_file(file, source); + gle = copy_file( package, file, source ); if (gle == ERROR_SUCCESS) return gle; @@ -220,9 +423,9 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) } 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); } 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) if (!GetTempFileNameW( pathW, szMsi, 0, tmpfileW )) tmpfileW[0] = 0; msi_free( pathW ); - if (CopyFileW(source, tmpfileW, FALSE) && - MoveFileExW(file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && - MoveFileExW(tmpfileW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT)) + if (msi_copy_file( package, source, tmpfileW, FALSE ) && + msi_move_file( package, file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) && + msi_move_file( package, tmpfileW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT )) { package->need_reboot_at_end = 1; gle = ERROR_SUCCESS; @@ -262,7 +465,7 @@ static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source) return gle; } -static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir ) +static UINT create_directory( MSIPACKAGE *package, const WCHAR *dir ) { MSIFOLDER *folder; const WCHAR *install_path; @@ -273,7 +476,7 @@ static UINT msi_create_directory( MSIPACKAGE *package, const WCHAR *dir ) folder = msi_get_loaded_folder( package, dir ); if (folder->State == FOLDER_STATE_UNINITIALIZED) { - msi_create_full_path( install_path ); + msi_create_full_path( package, install_path ); folder->State = FOLDER_STATE_CREATED; } return ERROR_SUCCESS; @@ -309,7 +512,7 @@ static BOOL installfiles_cb(MSIPACKAGE *package, LPCWSTR filename, DWORD action, if (!msi_is_global_assembly( file->Component )) { - msi_create_directory( package, file->Component->Directory ); + create_directory( package, file->Component->Directory ); } *path = strdupW( file->TargetPath ); *attrs = file->Attributes; @@ -334,7 +537,7 @@ WCHAR *msi_resolve_file_source( MSIPACKAGE *package, MSIFILE *file ) p = msi_resolve_source_folder( package, file->Component->Directory, NULL ); 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 ); path = msi_build_directory_name( 2, p, file->LongName ); @@ -418,7 +621,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) if (!is_global_assembly) { - msi_create_directory(package, file->Component->Directory); + create_directory(package, file->Component->Directory); } rc = copy_install_file(package, file, source); if (rc != ERROR_SUCCESS) @@ -513,10 +716,10 @@ static UINT patch_file( MSIPACKAGE *package, MSIFILEPATCH *patch ) WCHAR *tmpfile = msi_create_temp_file( package->db ); 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 ); - MoveFileW( tmpfile, patch->File->TargetPath ); + msi_delete_file( package, patch->File->TargetPath ); + msi_move_file( package, tmpfile, patch->File->TargetPath, 0 ); } else { @@ -557,7 +760,7 @@ static UINT patch_assembly( MSIPACKAGE *package, MSIASSEMBLY *assembly, MSIFILEP 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), debugstr_w(patch->File->TargetPath), GetLastError() ); @@ -679,12 +882,12 @@ typedef struct LPWSTR dest; } 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; - if (GetFileAttributesW(source) == FILE_ATTRIBUTE_DIRECTORY || - GetFileAttributesW(dest) == FILE_ATTRIBUTE_DIRECTORY) + if (msi_get_file_attributes( package, source ) == FILE_ATTRIBUTE_DIRECTORY || + msi_get_file_attributes( package, dest ) == FILE_ATTRIBUTE_DIRECTORY) { WARN("Source or dest is directory, not moving\n"); return FALSE; @@ -693,20 +896,20 @@ static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options) if (options == msidbMoveFileOptionsMove) { 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) { - WARN("MoveFile failed: %d\n", GetLastError()); + WARN("msi_move_file failed: %u\n", GetLastError()); return FALSE; } } else { 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) { - WARN("CopyFile failed: %d\n", GetLastError()); + WARN("msi_copy_file failed: %u\n", GetLastError()); return FALSE; } } @@ -714,16 +917,17 @@ static BOOL msi_move_file(LPCWSTR source, LPCWSTR dest, int options) 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; ptr = strrchrW(wildcard, '\\'); dirlen = ptr - wildcard + 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); lstrcatW(path, filename); @@ -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; - LPWSTR ptr, filename; + WCHAR *ptr, *filename; DWORD size; new = msi_alloc_zero(sizeof(FILE_LIST)); @@ -800,7 +1004,7 @@ static BOOL add_wildcard(FILE_LIST *files, LPWSTR source, LPWSTR dest) 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; HANDLE hfile; @@ -809,16 +1013,16 @@ static BOOL move_files_wildcard(LPWSTR source, LPWSTR dest, int options) FILE_LIST files, *file; DWORD size; - hfile = FindFirstFileW(source, &wfd); + hfile = msi_find_first_file( package, source, &wfd ); if (hfile == INVALID_HANDLE_VALUE) return FALSE; 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; - path = wildcard_to_file(source, wfd.cFileName); + path = wildcard_to_file( source, wfd.cFileName ); if (!path) { res = FALSE; @@ -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); - msi_move_file(file->source, file->dest, options); + move_file( package, file->source, file->dest, options ); list_remove(&file->entry); free_file_entry(file); @@ -910,7 +1114,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) if (!sourcename) { - if (GetFileAttributesW(sourcedir) == INVALID_FILE_ATTRIBUTES) + if (msi_get_file_attributes( package, sourcedir ) == INVALID_FILE_ATTRIBUTES) goto done; source = strdupW(sourcedir); @@ -969,9 +1173,9 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) if (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()); goto done; @@ -979,9 +1183,9 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) } if (!wildcards) - msi_move_file(source, dest, options); + move_file( package, source, dest, options ); else - move_files_wildcard(source, dest, options); + move_files_wildcard( package, source, dest, options ); done: uirow = MSI_CreateRecord( 9 ); @@ -1065,7 +1269,7 @@ static WCHAR *get_duplicate_filename( MSIPACKAGE *package, MSIRECORD *row, const } 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_path ); @@ -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)); - - if (!CopyFileW( file->TargetPath, dest, TRUE )) + if (!msi_copy_file( package, file->TargetPath, dest, TRUE )) { WARN("Failed to copy file %s -> %s (%u)\n", 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 ); MSI_RecordSetStringW( uirow, 1, MSI_RecordGetString( row, 1 ) ); @@ -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)); - - if (!DeleteFileW( dest )) + if (!msi_delete_file( package, dest )) { 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) lstrcatW(path, filename); TRACE("Deleting misc file: %s\n", debugstr_w(path)); - DeleteFileW(path); + msi_delete_file( package, path ); } else { TRACE("Removing misc directory: %s\n", debugstr_w(dir)); - RemoveDirectoryW(dir); + msi_remove_directory( package, dir ); } done: @@ -1400,7 +1601,7 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) 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) { TRACE("newer version detected, not removing file\n"); @@ -1415,8 +1616,8 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) TRACE("removing %s\n", debugstr_w(file->File) ); - SetFileAttributesW( file->TargetPath, FILE_ATTRIBUTE_NORMAL ); - if (!DeleteFileW( file->TargetPath )) + msi_set_file_attributes( package, file->TargetPath, FILE_ATTRIBUTE_NORMAL ); + if (!msi_delete_file( package, file->TargetPath )) { WARN("failed to delete %s (%u)\n", debugstr_w(file->TargetPath), GetLastError()); } diff --git a/dlls/msi/font.c b/dlls/msi/font.c index fc050060c0c..08dcc149579 100644 --- a/dlls/msi/font.c +++ b/dlls/msi/font.c @@ -84,7 +84,7 @@ static const WCHAR regfont2[] = * Code based off of code located here * 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; BOOL bFound = FALSE; @@ -96,8 +96,10 @@ static WCHAR *load_ttf_name_id( const WCHAR *filename, DWORD id ) LPWSTR ret = NULL; int i; - handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0 ); + if (package) + 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) { ERR("Unable to open font file %s\n", debugstr_w(filename)); @@ -175,12 +177,12 @@ end: 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}; 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]) { @@ -196,12 +198,12 @@ static WCHAR *font_name_from_file( const WCHAR *filename ) 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}; 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; if ((p = strchrW( version, ';' ))) *p = 0; @@ -258,7 +260,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param) RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2); if (MSI_RecordIsNull(row,2)) - name = font_name_from_file( file->TargetPath ); + name = font_name_from_file( package, file->TargetPath ); else name = msi_dup_record_field(row,2); @@ -341,7 +343,7 @@ static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param ) RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 ); if (MSI_RecordIsNull( row, 2 )) - name = font_name_from_file( file->TargetPath ); + name = font_name_from_file( package, file->TargetPath ); else name = msi_dup_record_field( row, 2 ); diff --git a/dlls/msi/install.c b/dlls/msi/install.c index 2cdebd2ad35..f4a231195bc 100644 --- a/dlls/msi/install.c +++ b/dlls/msi/install.c @@ -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)); - attrib = GetFileAttributesW(szFolderPath); + attrib = msi_get_file_attributes( package, szFolderPath ); /* native MSI tests writeability by making temporary files at each drive */ if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY)) diff --git a/dlls/msi/media.c b/dlls/msi/media.c index 09aac094183..e334c5b6eac 100644 --- a/dlls/msi/media.c +++ b/dlls/msi/media.c @@ -439,12 +439,11 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, attrs = attrs & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM); if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL; - 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) { DWORD err = GetLastError(); - DWORD attrs2 = GetFileAttributesW(path); + DWORD attrs2 = msi_get_file_attributes( data->package, path ); if (attrs2 == INVALID_FILE_ATTRIBUTES) { @@ -454,8 +453,8 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY)) { TRACE("removing read-only attribute on %s\n", debugstr_w(path)); - SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY ); - handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL); + msi_set_file_attributes( data->package, path, attrs2 & ~FILE_ATTRIBUTE_READONLY ); + handle = msi_create_file( data->package, path, GENERIC_READ | GENERIC_WRITE, 0, CREATE_ALWAYS, attrs ); if (handle != INVALID_HANDLE_VALUE) goto done; err = GetLastError(); @@ -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); if (handle != INVALID_HANDLE_VALUE && - MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) && - MoveFileExW(tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT)) + msi_move_file( data->package, path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT ) && + msi_move_file( data->package, tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT )) { data->package->need_reboot_at_end = 1; } diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 39b9354552a..3eca3bfb8d3 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -3298,7 +3298,7 @@ UINT WINAPI MsiGetFileVersionW( LPCWSTR path, LPWSTR verbuf, LPDWORD verlen, if (ret == ERROR_RESOURCE_DATA_NOT_FOUND && verlen) { 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; len = strlenW( version ); if (len >= *verlen) ret = ERROR_MORE_DATA; @@ -4107,14 +4107,17 @@ extern VOID WINAPI MD5Init( MD5_CTX *); extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int ); 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; void *p; DWORD length; 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) { WARN("can't open file %u\n", GetLastError()); @@ -4171,7 +4174,7 @@ UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions, if (pHash->dwFileHashInfoSize < sizeof *pHash) return ERROR_INVALID_PARAMETER; - return msi_get_filehash( szFilePath, pHash ); + return msi_get_filehash( NULL, szFilePath, pHash ); } /*********************************************************************** diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 39219a646fe..dbab8e22924 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -389,6 +389,7 @@ typedef struct tagMSIPACKAGE enum platform platform; UINT num_langids; LANGID *langids; + void *cookie; struct list patches; struct list components; struct list features; @@ -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 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_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_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value ) 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 WCHAR *msi_build_icon_path(MSIPACKAGE *, const WCHAR *) 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 WCHAR *msi_create_component_advertise_string(MSIPACKAGE *, MSICOMPONENT *, const WCHAR *) 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; extern BOOL msi_is_global_assembly(MSICOMPONENT *) 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_font_version_from_file(const 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 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 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; +/* 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 */ typedef BOOL (*PMSICABEXTRACTCB)(MSIPACKAGE *, LPCWSTR, DWORD, LPWSTR *, DWORD *, PVOID); diff --git a/dlls/msi/package.c b/dlls/msi/package.c index b57e89d077f..563f55a123e 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -1630,6 +1630,13 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage) package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, 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? */ data_row = MSI_CreateRecord(3); if (!data_row)