Index: dll/win32/CMakeLists.txt =================================================================== --- dll/win32/CMakeLists.txt (revision 56709) +++ dll/win32/CMakeLists.txt (working copy) @@ -84,7 +84,7 @@ add_subdirectory(msafd) add_subdirectory(mscat32) add_subdirectory(mscms) -add_subdirectory(mscoree) +#add_subdirectory(mscoree) add_subdirectory(msctf) add_subdirectory(msftedit) add_subdirectory(msg711.acm) @@ -182,6 +182,8 @@ add_subdirectory(stdole2.tlb) if(NOT MSVC) add_subdirectory(stdole32.tlb) # FIXME: msvc build. +else() + add_cd_file(FILE ${REACTOS_SOURCE_DIR}/modules/optional/stdole32.tlb DESTINATION reactos/system32 FOR all) endif() add_subdirectory(sti) add_subdirectory(sxs) Index: dll/win32/msi/action.c =================================================================== --- dll/win32/msi/action.c (revision 56709) +++ dll/win32/msi/action.c (working copy) @@ -2578,6 +2578,11 @@ return strdupW( path ); } +static BOOL is_special_entry( const WCHAR *name, const WCHAR *value ) +{ + return (name && (name[0] == '*' || name[0] == '+') && !name[1] && !value); +} + static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) { MSIPACKAGE *package = param; @@ -2612,10 +2617,8 @@ /* null values can have special meanings */ if (name[0]=='-' && name[1] == 0) return ERROR_SUCCESS; - else if ((name[0]=='+' && name[1] == 0) || - (name[0] == '*' && name[1] == 0)) - name = NULL; - check_first = TRUE; + if ((name[0] == '+' || name[0] == '*') && !name[1]) + check_first = TRUE; } root = MSI_RecordGetInteger(row,2); @@ -2652,28 +2655,30 @@ } deformat_string(package, name, &deformated); - - if (!check_first) + if (!is_special_entry( name , value )) { - TRACE("Setting value %s of %s\n",debugstr_w(deformated), - debugstr_w(uikey)); - RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size); - } - else - { - DWORD sz = 0; - rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz); - if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + if (!check_first) { - TRACE("value %s of %s checked already exists\n", - debugstr_w(deformated), debugstr_w(uikey)); + TRACE("Setting value %s of %s\n", debugstr_w(deformated), + debugstr_w(uikey)); + RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size); } else { - TRACE("Checked and setting value %s of %s\n", - debugstr_w(deformated), debugstr_w(uikey)); - if (deformated || size) - RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size); + DWORD sz = 0; + rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz); + if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) + { + TRACE("value %s of %s checked already exists\n", debugstr_w(deformated), + debugstr_w(uikey)); + } + else + { + TRACE("Checked and setting value %s of %s\n", debugstr_w(deformated), + debugstr_w(uikey)); + if (deformated || size) + RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size); + } } } RegCloseKey(hkey); @@ -2773,7 +2778,7 @@ { if (name[0] == '+' && !name[1]) return ERROR_SUCCESS; - else if ((name[0] == '-' && !name[1]) || (name[0] == '*' && !name[1])) + if ((name[0] == '-' || name[0] == '*') && !name[1]) { delete_key = TRUE; name = NULL; @@ -7340,6 +7345,7 @@ TRACE("Performing action (%s)\n", debugstr_w(action)); + package->action_progress_increment = 0; handled = ACTION_HandleStandardAction(package, action, &rc); if (!handled) Index: dll/win32/msi/assembly.c =================================================================== --- dll/win32/msi/assembly.c (revision 56709) +++ dll/win32/msi/assembly.c (working copy) @@ -34,11 +34,12 @@ static HRESULT (WINAPI *pCreateAssemblyCacheNet10)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD ); +static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * ); static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * ); -static HMODULE hfusion10, hfusion11, hfusion20, hmscoree, hsxs; +static HMODULE hfusion10, hfusion11, hfusion20, hfusion40, hmscoree, hsxs; static BOOL init_function_pointers( void ) { @@ -46,13 +47,23 @@ static const WCHAR szVersion10[] = {'v','1','.','0','.','3','7','0','5',0}; static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0}; static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0}; + static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0}; - if (pCreateAssemblyCacheNet10 || pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE; - - if (!(hmscoree = LoadLibraryA( "mscoree.dll" ))) return FALSE; + if (!hsxs && !(hsxs = LoadLibraryA( "sxs.dll" ))) return FALSE; + if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) + { + FreeLibrary( hsxs ); + hsxs = NULL; + return FALSE; + } + if (hmscoree || !(hmscoree = LoadLibraryA( "mscoree.dll" ))) return TRUE; pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */ - if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) goto error; - + if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) + { + FreeLibrary( hmscoree ); + hmscoree = NULL; + return TRUE; + } if (!pLoadLibraryShim( szFusion, szVersion10, NULL, &hfusion10 )) pCreateAssemblyCacheNet10 = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" ); @@ -62,65 +73,30 @@ if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 )) pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" ); - if (!pCreateAssemblyCacheNet10 && !pCreateAssemblyCacheNet11 && !pCreateAssemblyCacheNet20) goto error; + if (!pLoadLibraryShim( szFusion, szVersion40, NULL, &hfusion40 )) + pCreateAssemblyCacheNet40 = (void *)GetProcAddress( hfusion40, "CreateAssemblyCache" ); - if (!(hsxs = LoadLibraryA( "sxs.dll" ))) goto error; - if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) goto error; return TRUE; - -error: - pCreateAssemblyCacheNet10 = NULL; - pCreateAssemblyCacheNet11 = NULL; - pCreateAssemblyCacheNet20 = NULL; - FreeLibrary( hfusion10 ); - FreeLibrary( hfusion11 ); - FreeLibrary( hfusion20 ); - FreeLibrary( hmscoree ); - return FALSE; } BOOL msi_init_assembly_caches( MSIPACKAGE *package ) { if (!init_function_pointers()) return FALSE; - if (package->cache_net[CLR_VERSION_V10] || - package->cache_net[CLR_VERSION_V11] || - package->cache_net[CLR_VERSION_V20]) return TRUE; if (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE; - - if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V10], 0 ); + if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet10( &package->cache_net[CLR_VERSION_V10], 0 ); if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 ); if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 ); - - if (package->cache_net[CLR_VERSION_V10] || - package->cache_net[CLR_VERSION_V11] || - package->cache_net[CLR_VERSION_V20]) - { - return TRUE; - } - if (package->cache_net[CLR_VERSION_V10]) - { - IAssemblyCache_Release( package->cache_net[CLR_VERSION_V10] ); - package->cache_net[CLR_VERSION_V10] = NULL; - } - if (package->cache_net[CLR_VERSION_V11]) - { - IAssemblyCache_Release( package->cache_net[CLR_VERSION_V11] ); - package->cache_net[CLR_VERSION_V11] = NULL; - } - if (package->cache_net[CLR_VERSION_V20]) - { - IAssemblyCache_Release( package->cache_net[CLR_VERSION_V20] ); - package->cache_net[CLR_VERSION_V20] = NULL; - } - IAssemblyCache_Release( package->cache_sxs ); - package->cache_sxs = NULL; - return FALSE; + if (pCreateAssemblyCacheNet40) pCreateAssemblyCacheNet40( &package->cache_net[CLR_VERSION_V40], 0 ); + return TRUE; } void msi_destroy_assembly_caches( MSIPACKAGE *package ) { UINT i; + IAssemblyCache_Release( package->cache_sxs ); + package->cache_sxs = NULL; + for (i = 0; i < CLR_VERSION_MAX; i++) { if (package->cache_net[i]) @@ -129,19 +105,22 @@ package->cache_net[i] = NULL; } } - if (package->cache_sxs) - { - IAssemblyCache_Release( package->cache_sxs ); - package->cache_sxs = NULL; - } pCreateAssemblyCacheNet10 = NULL; pCreateAssemblyCacheNet11 = NULL; pCreateAssemblyCacheNet20 = NULL; + pCreateAssemblyCacheNet40 = NULL; FreeLibrary( hfusion10 ); FreeLibrary( hfusion11 ); FreeLibrary( hfusion20 ); + FreeLibrary( hfusion40 ); FreeLibrary( hmscoree ); FreeLibrary( hsxs ); + hfusion10 = NULL; + hfusion11 = NULL; + hfusion20 = NULL; + hfusion40 = NULL; + hmscoree = NULL; + hsxs = NULL; } static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp ) @@ -260,6 +239,8 @@ HRESULT hr; ASSEMBLY_INFO info; + if (!cache) return FALSE; + memset( &info, 0, sizeof(info) ); info.cbAssemblyInfo = sizeof(info); hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, display_name, &info ); @@ -274,13 +255,15 @@ static const WCHAR clr_version_v10[] = {'v','1','.','0','.','3','7','0','5',0}; static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0}; static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0}; +static const WCHAR clr_version_v40[] = {'v','4','.','0','.','3','0','3','1','9',0}; static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0}; static const WCHAR *clr_version[] = { clr_version_v10, clr_version_v11, - clr_version_v20 + clr_version_v20, + clr_version_v40 }; static const WCHAR *get_clr_version_str( enum clr_version version ) @@ -347,6 +330,7 @@ { TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i ))); a->installed = TRUE; + break; } } } @@ -411,6 +395,7 @@ { manifest = msi_get_loaded_file( package, comp->KeyPath )->TargetPath; cache = package->cache_net[get_clr_version( manifest )]; + if (!cache) return ERROR_SUCCESS; } TRACE("installing assembly %s\n", debugstr_w(manifest)); @@ -455,8 +440,11 @@ { if (!assembly->clr_version[i]) continue; cache = package->cache_net[i]; - hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); - if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr); + if (cache) + { + hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); + if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr); + } } } if (feature) feature->Action = INSTALLSTATE_ABSENT; Index: dll/win32/msi/custom.c =================================================================== --- dll/win32/msi/custom.c (revision 56709) +++ dll/win32/msi/custom.c (working copy) @@ -957,7 +957,7 @@ { msi_custom_action_info *info; MSIHANDLE hPackage; - UINT r; + UINT r = ERROR_FUNCTION_FAILED; info = find_action_by_guid( guid ); if (!info) @@ -979,13 +979,13 @@ ERR("failed to create handle for %p\n", info->package ); release_custom_action_data( info ); - return S_OK; + return r; } static DWORD WINAPI ScriptThread( LPVOID arg ) { LPGUID guid = arg; - DWORD rc = 0; + DWORD rc; TRACE("custom action (%x) started\n", GetCurrentThreadId() ); Index: dll/win32/msi/dialog.c =================================================================== --- dll/win32/msi/dialog.c (revision 56709) +++ dll/win32/msi/dialog.c (working copy) @@ -644,11 +644,11 @@ TRACE("progress: func %u val1 %u val2 %u\n", func, val1, val2); + units = val1 / 512; switch (func) { case 0: /* init */ SendMessageW( ctrl->hwnd, PBM_SETRANGE, 0, MAKELPARAM(0,100) ); - units = val1 / 512; if (val2) { ctrl->progress_max = units ? units : 100; @@ -664,10 +664,11 @@ SendMessageW( ctrl->hwnd, PBM_SETPOS, 0, 0 ); } break; - case 1: /* FIXME: not sure what this is supposed to do */ + case 1: /* action data increment */ + if (val2) dialog->package->action_progress_increment = val1; + else dialog->package->action_progress_increment = 0; break; case 2: /* move */ - units = val1 / 512; if (ctrl->progress_backwards) { if (units >= ctrl->progress_current) ctrl->progress_current -= units; @@ -680,6 +681,9 @@ } SendMessageW( ctrl->hwnd, PBM_SETPOS, MulDiv(100, ctrl->progress_current, ctrl->progress_max), 0 ); break; + case 3: /* add */ + ctrl->progress_max += units; + break; default: FIXME("Unknown progress message %u\n", func); break; Index: dll/win32/msi/msipriv.h =================================================================== --- dll/win32/msi/msipriv.h (revision 56709) +++ dll/win32/msi/msipriv.h (working copy) @@ -347,6 +347,7 @@ CLR_VERSION_V10, CLR_VERSION_V11, CLR_VERSION_V20, + CLR_VERSION_V40, CLR_VERSION_MAX }; @@ -369,6 +370,7 @@ struct list cabinet_streams; LPWSTR ActionFormat; LPWSTR LastAction; + UINT action_progress_increment; HANDLE log_file; IAssemblyCache *cache_net[CLR_VERSION_MAX]; IAssemblyCache *cache_sxs; Index: dll/win32/msi/package.c =================================================================== --- dll/win32/msi/package.c (revision 56709) +++ dll/win32/msi/package.c (working copy) @@ -1905,8 +1905,16 @@ msi_free(deformated); ControlEvent_FireSubscribedEvent(package, szActionData, uirow); + msiobj_release(&uirow->hdr); - msiobj_release(&uirow->hdr); + if (package->action_progress_increment) + { + uirow = MSI_CreateRecord(2); + MSI_RecordSetInteger(uirow, 1, 2); + MSI_RecordSetInteger(uirow, 2, package->action_progress_increment); + ControlEvent_FireSubscribedEvent(package, szSetProgress, uirow); + msiobj_release(&uirow->hdr); + } break; case INSTALLMESSAGE_ACTIONSTART: Index: dll/win32/msi/string.c =================================================================== --- dll/win32/msi/string.c (revision 56709) +++ dll/win32/msi/string.c (working copy) @@ -357,14 +357,12 @@ * [in/out] sz - number of bytes available in the buffer on input * number of bytes used on output * - * The size includes the terminating nul character. Short buffers - * will be filled, but not nul terminated. + * Returned string is not nul terminated. */ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT *sz ) { - UINT len; + UINT len, lenW; const WCHAR *str; - int n; TRACE("Finding string %d of %d\n", id, st->maxcount); @@ -372,26 +370,14 @@ if( !str ) return ERROR_FUNCTION_FAILED; - len = WideCharToMultiByte( st->codepage, 0, str, -1, NULL, 0, NULL, NULL ); - - if( !buffer ) + lenW = strlenW( str ); + len = WideCharToMultiByte( st->codepage, 0, str, lenW, NULL, 0, NULL, NULL ); + if( *sz < len ) { *sz = len; - return ERROR_SUCCESS; + return ERROR_MORE_DATA; } - - if( len > *sz ) - { - n = strlenW( str ) + 1; - while( n && (len > *sz) ) - len = WideCharToMultiByte( st->codepage, 0, - str, --n, NULL, 0, NULL, NULL ); - } - else - n = -1; - - *sz = WideCharToMultiByte( st->codepage, 0, str, n, buffer, len, NULL, NULL ); - + *sz = WideCharToMultiByte( st->codepage, 0, str, lenW, buffer, *sz, NULL, NULL ); return ERROR_SUCCESS; } @@ -588,7 +574,7 @@ data = msi_alloc( datasize ); if( ! data ) { - WARN("Failed to alloc data %d bytes\n", poolsize ); + WARN("Failed to alloc data %d bytes\n", datasize ); goto err; } @@ -622,8 +608,6 @@ ERR("failed to fetch string\n"); sz = 0; } - if( sz && (sz < (datasize - used ) ) ) - sz--; if (sz) pool[ n*2 + 1 ] = st->strings[i].persistent_refcount; Index: dll/win32/msi/tokenize.c =================================================================== --- dll/win32/msi/tokenize.c (revision 56709) +++ dll/win32/msi/tokenize.c (working copy) @@ -266,7 +266,7 @@ *tokenType = TK_DOT; return 1; } - /* Fall thru into the next case */ + /* Fall through */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *tokenType = TK_INTEGER;