From: Aleksey Bragin Date: Tue, 8 Jul 2008 20:52:29 +0000 (+0000) Subject: Autosyncing with Wine HEAD X-Git-Tag: ReactOS-0.3.6~432 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=5d786c8989796f70cce52f8aadd3f2e0c38c4c21 Autosyncing with Wine HEAD svn path=/trunk/; revision=34375 --- diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index 6867e93a5bf..cde5c9802ec 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -648,6 +648,30 @@ static UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) return ERROR_SUCCESS; } +static UINT msi_set_context(MSIPACKAGE *package) +{ + WCHAR val[10]; + DWORD sz = 10; + DWORD num; + UINT r; + + static const WCHAR szOne[] = {'1',0}; + static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0}; + + package->Context = MSIINSTALLCONTEXT_USERUNMANAGED; + + r = MSI_GetPropertyW(package, szAllUsers, val, &sz); + if (r == ERROR_SUCCESS) + { + num = atolW(val); + if (num == 1 || num == 2) + package->Context = MSIINSTALLCONTEXT_MACHINE; + } + + MSI_SetPropertyW(package, szAllUsers, szOne); + return ERROR_SUCCESS; +} + /**************************************************** * TOP level entry points *****************************************************/ @@ -710,6 +734,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath, /* properties may have been added by a transform */ msi_clone_properties( package ); + msi_set_context( package ); if ( (msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED ) { @@ -1464,6 +1489,25 @@ static UINT load_file(MSIRECORD *row, LPVOID param) file->IsCompressed = package->WordCount & MSIWORDCOUNT_COMPRESSED; } + if (!file->IsCompressed) + { + LPWSTR p, path; + + p = resolve_folder(package, file->Component->Directory, + TRUE, FALSE, TRUE, NULL); + path = build_directory_name(2, p, file->ShortName); + + if (file->LongName && + GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES) + { + msi_free(path); + path = build_directory_name(2, p, file->LongName); + } + + file->SourcePath = path; + msi_free(p); + } + load_file_hash(package, file); TRACE("File Loaded (%s)\n",debugstr_w(file->File)); @@ -1601,10 +1645,10 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package) MSI_SetPropertyW(package, szCosting, szZero); MSI_SetPropertyW(package, cszRootDrive, c_colon); + load_all_folders( package ); load_all_components( package ); load_all_features( package ); load_all_files( package ); - load_all_folders( package ); return ERROR_SUCCESS; } @@ -1780,9 +1824,6 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) * 9) FILEADDLOCAL * 10) FILEADDSOURCE * 11) FILEADDDEFAULT - * I have confirmed that if ADDLOCAL is stated then the INSTALLLEVEL is - * ignored for all the features. seems strange, especially since it is not - * documented anywhere, but it is how it works. * * I am still ignoring a lot of these. But that is ok for now, ADDLOCAL and * REMOVE are the big ones, since we don't handle administrative installs @@ -1840,8 +1881,11 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) { ComponentList *cl; - TRACE("Examining Feature %s (Installed %i, Action %i)\n", - debugstr_w(feature->Feature), feature->Installed, feature->Action); + TRACE("Examining Feature %s (Level %i, Installed %i, Action %i)\n", + debugstr_w(feature->Feature), feature->Level, feature->Installed, feature->Action); + + if (!feature->Level) + continue; /* features with components that have compressed files are made local */ LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry ) @@ -2003,7 +2047,7 @@ static LPWSTR msi_get_disk_file_version( LPCWSTR filename ) { static const WCHAR name_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; - static WCHAR name[] = {'\\',0}; + static const WCHAR name[] = {'\\',0}; VS_FIXEDFILEINFO *lpVer; WCHAR filever[0x100]; LPVOID version; @@ -2803,15 +2847,11 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) WCHAR squished_cc[GUID_SIZE]; UINT rc; MSICOMPONENT *comp; - HKEY hkey=0,hkey2=0; + HKEY hkey; TRACE("\n"); - /* writes the Component and Features values to the registry */ - - rc = MSIREG_OpenComponents(&hkey); - if (rc != ERROR_SUCCESS) - return rc; + /* writes the Component values to the registry */ squash_guid(package->ProductCode,squished_pc); ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0); @@ -2843,14 +2883,16 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) */ if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL)) { - rc = RegCreateKeyW(hkey,squished_cc,&hkey2); - if (rc != ERROR_SUCCESS) - continue; - if (!comp->FullKeypath) continue; - msi_reg_set_val_str( hkey2, squished_pc, comp->FullKeypath ); + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + rc = MSIREG_OpenLocalUserDataComponentKey(comp->ComponentId, &hkey, TRUE); + else + rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, &hkey, TRUE); + + if (rc != ERROR_SUCCESS) + continue; if (comp->Attributes & msidbComponentAttributesPermanent) { @@ -2859,35 +2901,18 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) '0','0','0','0','0','0','0','0','0','0','0','0', '0','0','0','0','0','0','0','0',0 }; - msi_reg_set_val_str( hkey2, szPermKey, comp->FullKeypath ); + msi_reg_set_val_str(hkey, szPermKey, comp->FullKeypath); } - RegCloseKey(hkey2); - - rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, &hkey2, TRUE); - if (rc != ERROR_SUCCESS) - continue; - - msi_reg_set_val_str(hkey2, squished_pc, comp->FullKeypath); - RegCloseKey(hkey2); + msi_reg_set_val_str(hkey, squished_pc, comp->FullKeypath); + RegCloseKey(hkey); } - else if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ABSENT)) + else if (ACTION_VerifyComponentForAction(comp, INSTALLSTATE_ABSENT)) { - DWORD res; - - rc = RegOpenKeyW(hkey,squished_cc,&hkey2); - if (rc != ERROR_SUCCESS) - continue; - - RegDeleteValueW(hkey2,squished_pc); - - /* if the key is empty delete it */ - res = RegEnumKeyExW(hkey2,0,NULL,0,0,NULL,0,NULL); - RegCloseKey(hkey2); - if (res == ERROR_NO_MORE_ITEMS) - RegDeleteKeyW(hkey,squished_cc); - - MSIREG_DeleteUserDataComponentKey(comp->ComponentId); + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + MSIREG_DeleteLocalUserDataComponentKey(comp->ComponentId); + else + MSIREG_DeleteUserDataComponentKey(comp->ComponentId); } /* UI stuff */ @@ -2898,8 +2923,8 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ui_actiondata(package,szProcessComponents,uirow); msiobj_release( &uirow->hdr ); } - RegCloseKey(hkey); - return rc; + + return ERROR_SUCCESS; } typedef struct { @@ -3236,7 +3261,7 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package) return rc; } -static UINT ITERATE_PublishProduct(MSIRECORD *row, LPVOID param) +static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param) { MSIPACKAGE* package = (MSIPACKAGE*)param; HANDLE the_file; @@ -3295,6 +3320,204 @@ static UINT ITERATE_PublishProduct(MSIRECORD *row, LPVOID param) return ERROR_SUCCESS; } +static UINT msi_publish_icons(MSIPACKAGE *package) +{ + UINT r; + MSIQUERY *view; + + static const WCHAR query[]= { + 'S','E','L','E','C','T',' ','*',' ', + 'F','R','O','M',' ','`','I','c','o','n','`',0}; + + r = MSI_DatabaseOpenViewW(package->db, query, &view); + if (r == ERROR_SUCCESS) + { + MSI_IterateRecords(view, NULL, ITERATE_PublishIcon, package); + msiobj_release(&view->hdr); + } + + return ERROR_SUCCESS; +} + +static UINT msi_publish_sourcelist(MSIPACKAGE *package, HKEY hkey) +{ + UINT r; + HKEY source; + LPWSTR buffer; + MSIMEDIADISK *disk; + MSISOURCELISTINFO *info; + + static const WCHAR szEmpty[] = {0}; + static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0}; + + r = RegCreateKeyW(hkey, szSourceList, &source); + if (r != ERROR_SUCCESS) + return r; + + RegCloseKey(source); + + buffer = strrchrW(package->PackagePath, '\\') + 1; + r = MsiSourceListSetInfoW(package->ProductCode, NULL, + package->Context, MSICODE_PRODUCT, + INSTALLPROPERTY_PACKAGENAMEW, buffer); + if (r != ERROR_SUCCESS) + return r; + + r = MsiSourceListSetInfoW(package->ProductCode, NULL, + package->Context, MSICODE_PRODUCT, + INSTALLPROPERTY_MEDIAPACKAGEPATHW, szEmpty); + if (r != ERROR_SUCCESS) + return r; + + r = MsiSourceListSetInfoW(package->ProductCode, NULL, + package->Context, MSICODE_PRODUCT, + INSTALLPROPERTY_DISKPROMPTW, szEmpty); + if (r != ERROR_SUCCESS) + return r; + + LIST_FOR_EACH_ENTRY(info, &package->sourcelist_info, MSISOURCELISTINFO, entry) + { + if (!lstrcmpW(info->property, INSTALLPROPERTY_LASTUSEDSOURCEW)) + msi_set_last_used_source(package->ProductCode, NULL, info->context, + info->options, info->value); + else + MsiSourceListSetInfoW(package->ProductCode, NULL, + info->context, info->options, + info->property, info->value); + } + + LIST_FOR_EACH_ENTRY(disk, &package->sourcelist_media, MSIMEDIADISK, entry) + { + MsiSourceListAddMediaDiskW(package->ProductCode, NULL, + disk->context, disk->options, + disk->disk_id, disk->volume_label, disk->disk_prompt); + } + + return ERROR_SUCCESS; +} + +static UINT msi_publish_product_properties(MSIPACKAGE *package, HKEY hkey) +{ + MSIHANDLE hdb, suminfo; + WCHAR guids[MAX_PATH]; + WCHAR packcode[SQUISH_GUID_SIZE]; + LPWSTR buffer; + LPWSTR ptr; + DWORD langid; + DWORD size; + UINT r; + + static const WCHAR szProductLanguage[] = + {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0}; + static const WCHAR szARPProductIcon[] = + {'A','R','P','P','R','O','D','U','C','T','I','C','O','N',0}; + static const WCHAR szProductVersion[] = + {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; + static const WCHAR szAssignment[] = + {'A','s','s','i','g','n','m','e','n','t',0}; + static const WCHAR szAdvertiseFlags[] = + {'A','d','v','e','r','t','i','s','e','F','l','a','g','s',0}; + static const WCHAR szClients[] = + {'C','l','i','e','n','t','s',0}; + static const WCHAR szColon[] = {':',0}; + + buffer = msi_dup_property(package, INSTALLPROPERTY_PRODUCTNAMEW); + msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTNAMEW, buffer); + msi_free(buffer); + + langid = msi_get_property_int(package, szProductLanguage, 0); + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid); + + ptr = strrchrW(package->PackagePath, '\\' ) + 1; + msi_reg_set_val_str(hkey, INSTALLPROPERTY_PACKAGENAMEW, ptr); + + /* FIXME */ + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0); + + buffer = msi_dup_property(package, szARPProductIcon); + if (buffer) + { + LPWSTR path = build_icon_path(package,buffer); + msi_reg_set_val_str(hkey, INSTALLPROPERTY_PRODUCTICONW, path); + msi_free(path); + msi_free(buffer); + } + + buffer = msi_dup_property(package, szProductVersion); + if (buffer) + { + DWORD verdword = msi_version_str_to_dword(buffer); + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONW, verdword); + msi_free(buffer); + } + + msi_reg_set_val_dword(hkey, szAssignment, 0); + msi_reg_set_val_dword(hkey, szAdvertiseFlags, 0x184); + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_INSTANCETYPEW, 0); + msi_reg_set_val_str(hkey, szClients, szColon); + + hdb = alloc_msihandle(&package->db->hdr); + if (!hdb) + return ERROR_NOT_ENOUGH_MEMORY; + + r = MsiGetSummaryInformationW(hdb, NULL, 0, &suminfo); + MsiCloseHandle(hdb); + if (r != ERROR_SUCCESS) + goto done; + + size = MAX_PATH; + r = MsiSummaryInfoGetPropertyW(suminfo, PID_REVNUMBER, NULL, NULL, + NULL, guids, &size); + if (r != ERROR_SUCCESS) + goto done; + + ptr = strchrW(guids, ';'); + if (ptr) *ptr = 0; + squash_guid(guids, packcode); + msi_reg_set_val_str(hkey, INSTALLPROPERTY_PACKAGECODEW, packcode); + +done: + MsiCloseHandle(suminfo); + return ERROR_SUCCESS; +} + +static UINT msi_publish_upgrade_code(MSIPACKAGE *package) +{ + UINT r; + HKEY hkey; + LPWSTR upgrade; + WCHAR squashed_pc[SQUISH_GUID_SIZE]; + + static const WCHAR szUpgradeCode[] = + {'U','p','g','r','a','d','e','C','o','d','e',0}; + + upgrade = msi_dup_property(package, szUpgradeCode); + if (!upgrade) + return ERROR_SUCCESS; + + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + { + r = MSIREG_OpenClassesUpgradeCodesKey(upgrade, &hkey, TRUE); + if (r != ERROR_SUCCESS) + goto done; + } + else + { + r = MSIREG_OpenUserUpgradeCodesKey(upgrade, &hkey, TRUE); + if (r != ERROR_SUCCESS) + goto done; + } + + squash_guid(package->ProductCode, squashed_pc); + msi_reg_set_val_str(hkey, squashed_pc, NULL); + + RegCloseKey(hkey); + +done: + msi_free(upgrade); + return r; +} + static BOOL msi_check_publish(MSIPACKAGE *package) { MSIFEATURE *feature; @@ -3308,6 +3531,19 @@ static BOOL msi_check_publish(MSIPACKAGE *package) return FALSE; } +static BOOL msi_check_unpublish(MSIPACKAGE *package) +{ + MSIFEATURE *feature; + + LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry) + { + if (feature->ActionRequest != INSTALLSTATE_ABSENT) + return FALSE; + } + + return TRUE; +} + /* * 99% of the work done here is only done for * advertised installs. However this is where the @@ -3317,191 +3553,51 @@ static BOOL msi_check_publish(MSIPACKAGE *package) static UINT ACTION_PublishProduct(MSIPACKAGE *package) { UINT rc; - LPWSTR packname; - MSIQUERY * view; - MSISOURCELISTINFO *info; - MSIMEDIADISK *disk; - static const WCHAR Query[]= - {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', - '`','I','c','o','n','`',0}; - /* for registry stuff */ - HKEY hkey=0; HKEY hukey=0; - HKEY hudkey=0, props=0; - HKEY source; - static const WCHAR szProductLanguage[] = - {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0}; - static const WCHAR szARPProductIcon[] = - {'A','R','P','P','R','O','D','U','C','T','I','C','O','N',0}; - static const WCHAR szProductVersion[] = - {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; - static const WCHAR szSourceList[] = - {'S','o','u','r','c','e','L','i','s','t',0}; - static const WCHAR szEmpty[] = {0}; - DWORD langid; - LPWSTR buffer; - DWORD size; - MSIHANDLE hDb, hSumInfo; + HKEY hudkey=0; /* FIXME: also need to publish if the product is in advertise mode */ if (!msi_check_publish(package)) return ERROR_SUCCESS; - /* write out icon files */ - - rc = MSI_DatabaseOpenViewW(package->db, Query, &view); - if (rc == ERROR_SUCCESS) - { - MSI_IterateRecords(view, NULL, ITERATE_PublishProduct, package); - msiobj_release(&view->hdr); - } - - /* ok there is a lot more done here but i need to figure out what */ - if (package->Context == MSIINSTALLCONTEXT_MACHINE) { rc = MSIREG_OpenLocalClassesProductKey(package->ProductCode, &hukey, TRUE); if (rc != ERROR_SUCCESS) goto end; - rc = MSIREG_OpenLocalSystemInstallProps(package->ProductCode, &props, TRUE); + rc = MSIREG_OpenLocalUserDataProductKey(package->ProductCode, &hudkey, TRUE); if (rc != ERROR_SUCCESS) goto end; } else { - rc = MSIREG_OpenProductsKey(package->ProductCode,&hkey,TRUE); + rc = MSIREG_OpenUserProductsKey(package->ProductCode, &hukey, TRUE); if (rc != ERROR_SUCCESS) goto end; - rc = MSIREG_OpenUserProductsKey(package->ProductCode,&hukey,TRUE); + rc = MSIREG_OpenUserDataProductKey(package->ProductCode, &hudkey, TRUE); if (rc != ERROR_SUCCESS) goto end; - - rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE); - if (rc != ERROR_SUCCESS) - goto end; - } - - rc = RegCreateKeyW(hukey, szSourceList, &source); - if (rc != ERROR_SUCCESS) - goto end; - - RegCloseKey(source); - - rc = MSIREG_OpenUserDataProductKey(package->ProductCode,&hudkey,TRUE); - if (rc != ERROR_SUCCESS) - goto end; - - buffer = msi_dup_property( package, INSTALLPROPERTY_PRODUCTNAMEW ); - msi_reg_set_val_str( hukey, INSTALLPROPERTY_PRODUCTNAMEW, buffer ); - msi_free(buffer); - - langid = msi_get_property_int( package, szProductLanguage, 0 ); - msi_reg_set_val_dword( hukey, INSTALLPROPERTY_LANGUAGEW, langid ); - - packname = strrchrW( package->PackagePath, '\\' ) + 1; - msi_reg_set_val_str( hukey, INSTALLPROPERTY_PACKAGENAMEW, packname ); - - /* FIXME */ - msi_reg_set_val_dword( hukey, INSTALLPROPERTY_AUTHORIZED_LUA_APPW, 0 ); - msi_reg_set_val_dword( props, INSTALLPROPERTY_INSTANCETYPEW, 0 ); - - buffer = msi_dup_property( package, szARPProductIcon ); - if (buffer) - { - LPWSTR path = build_icon_path(package,buffer); - msi_reg_set_val_str( hukey, INSTALLPROPERTY_PRODUCTICONW, path ); - msi_free( path ); - } - msi_free(buffer); - - buffer = msi_dup_property( package, szProductVersion ); - if (buffer) - { - DWORD verdword = msi_version_str_to_dword(buffer); - msi_reg_set_val_dword( hukey, INSTALLPROPERTY_VERSIONW, verdword ); } - msi_free(buffer); - buffer = strrchrW( package->PackagePath, '\\') + 1; - rc = MsiSourceListSetInfoW( package->ProductCode, NULL, - package->Context, MSICODE_PRODUCT, - INSTALLPROPERTY_PACKAGENAMEW, buffer ); + rc = msi_publish_upgrade_code(package); if (rc != ERROR_SUCCESS) goto end; - rc = MsiSourceListSetInfoW( package->ProductCode, NULL, - package->Context, MSICODE_PRODUCT, - INSTALLPROPERTY_MEDIAPACKAGEPATHW, szEmpty ); + rc = msi_publish_product_properties(package, hukey); if (rc != ERROR_SUCCESS) goto end; - rc = MsiSourceListSetInfoW( package->ProductCode, NULL, - package->Context, MSICODE_PRODUCT, - INSTALLPROPERTY_DISKPROMPTW, szEmpty ); + rc = msi_publish_sourcelist(package, hukey); if (rc != ERROR_SUCCESS) goto end; - /* FIXME: Need to write more keys to the user registry */ - - hDb= alloc_msihandle( &package->db->hdr ); - if (!hDb) { - rc = ERROR_NOT_ENOUGH_MEMORY; - goto end; - } - rc = MsiGetSummaryInformationW(hDb, NULL, 0, &hSumInfo); - MsiCloseHandle(hDb); - if (rc == ERROR_SUCCESS) - { - WCHAR guidbuffer[0x200]; - size = 0x200; - rc = MsiSummaryInfoGetPropertyW(hSumInfo, 9, NULL, NULL, NULL, - guidbuffer, &size); - if (rc == ERROR_SUCCESS) - { - /* for now we only care about the first guid */ - LPWSTR ptr = strchrW(guidbuffer,';'); - if (ptr) *ptr = 0; - msi_reg_set_val_str( hukey, INSTALLPROPERTY_PACKAGECODEW, guidbuffer ); - } - else - { - ERR("Unable to query Revision_Number...\n"); - rc = ERROR_SUCCESS; - } - MsiCloseHandle(hSumInfo); - } - else - { - ERR("Unable to open Summary Information\n"); - rc = ERROR_SUCCESS; - } - - /* publish the SourceList info */ - LIST_FOR_EACH_ENTRY(info, &package->sourcelist_info, MSISOURCELISTINFO, entry) - { - if (!lstrcmpW(info->property, INSTALLPROPERTY_LASTUSEDSOURCEW)) - msi_set_last_used_source(package->ProductCode, NULL, info->context, - info->options, info->value); - else - MsiSourceListSetInfoW(package->ProductCode, NULL, - info->context, info->options, - info->property, info->value); - } - - LIST_FOR_EACH_ENTRY(disk, &package->sourcelist_media, MSIMEDIADISK, entry) - { - MsiSourceListAddMediaDiskW(package->ProductCode, NULL, - disk->context, disk->options, - disk->disk_id, disk->volume_label, disk->disk_prompt); - } + rc = msi_publish_icons(package); end: - RegCloseKey(hkey); RegCloseKey(hukey); RegCloseKey(hudkey); - RegCloseKey(props); return rc; } @@ -3708,24 +3804,35 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) { MSIFEATURE *feature; UINT rc; - HKEY hkey=0; - HKEY hukey=0; - HKEY userdata=0; + HKEY hkey; + HKEY userdata; if (!msi_check_publish(package)) return ERROR_SUCCESS; - rc = MSIREG_OpenFeaturesKey(package->ProductCode,&hkey,TRUE); - if (rc != ERROR_SUCCESS) - goto end; + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + { + rc = MSIREG_OpenLocalClassesFeaturesKey(package->ProductCode, + &hkey, TRUE); + if (rc != ERROR_SUCCESS) + goto end; - rc = MSIREG_OpenUserFeaturesKey(package->ProductCode,&hukey,TRUE); - if (rc != ERROR_SUCCESS) - goto end; + rc = MSIREG_OpenLocalUserDataFeaturesKey(package->ProductCode, + &userdata, TRUE); + if (rc != ERROR_SUCCESS) + goto end; + } + else + { + rc = MSIREG_OpenUserFeaturesKey(package->ProductCode, &hkey, TRUE); + if (rc != ERROR_SUCCESS) + goto end; - rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, &userdata, TRUE); - if (rc != ERROR_SUCCESS) - goto end; + rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, + &userdata, TRUE); + if (rc != ERROR_SUCCESS) + goto end; + } /* here the guids are base 85 encoded */ LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry ) @@ -3776,7 +3883,6 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) strcatW(data,feature->Feature_Parent); } - msi_reg_set_val_str( hkey, feature->Feature, data ); msi_reg_set_val_str( userdata, feature->Feature, data ); msi_free(data); @@ -3787,7 +3893,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) { static const WCHAR emptyW[] = {0}; size += sizeof(WCHAR); - RegSetValueExW(hukey,feature->Feature,0,REG_SZ, + RegSetValueExW(hkey,feature->Feature,0,REG_SZ, (LPBYTE)(feature->Feature_Parent ? feature->Feature_Parent : emptyW),size); } else @@ -3798,7 +3904,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) data[1] = 0; if (feature->Feature_Parent) strcpyW( &data[1], feature->Feature_Parent ); - RegSetValueExW(hukey,feature->Feature,0,REG_SZ, + RegSetValueExW(hkey,feature->Feature,0,REG_SZ, (LPBYTE)data,size); msi_free(data); } @@ -3813,7 +3919,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) end: RegCloseKey(hkey); - RegCloseKey(hukey); + RegCloseKey(userdata); return rc; } @@ -3841,19 +3947,6 @@ static UINT msi_unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature) return ERROR_SUCCESS; } -static BOOL msi_check_unpublish(MSIPACKAGE *package) -{ - MSIFEATURE *feature; - - LIST_FOR_EACH_ENTRY(feature, &package->features, MSIFEATURE, entry) - { - if (feature->ActionRequest != INSTALLSTATE_ABSENT) - return FALSE; - } - - return TRUE; -} - static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package) { MSIFEATURE *feature; @@ -3904,7 +3997,6 @@ static UINT msi_get_local_package_name( LPWSTR path ) static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) { WCHAR packagefile[MAX_PATH]; - HKEY props; UINT r; r = msi_get_local_package_name( packagefile ); @@ -3924,18 +4016,42 @@ static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey ) msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile ); - r = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE); - if (r != ERROR_SUCCESS) - return r; - - msi_reg_set_val_str(props, INSTALLPROPERTY_LOCALPACKAGEW, packagefile); - RegCloseKey(props); return ERROR_SUCCESS; } -static UINT msi_write_uninstall_property_vals( MSIPACKAGE *package, HKEY hkey ) +static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey) { LPWSTR prop, val, key; + SYSTEMTIME systime; + DWORD size, langid; + WCHAR date[9]; + LPWSTR buffer; + + static const WCHAR date_fmt[] = {'%','i','%','0','2','i','%','0','2','i',0}; + static const WCHAR szWindowsInstaller[] = + {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0}; + static const WCHAR modpath_fmt[] = + {'M','s','i','E','x','e','c','.','e','x','e',' ', + '/','I','[','P','r','o','d','u','c','t','C','o','d','e',']',0}; + static const WCHAR szModifyPath[] = + {'M','o','d','i','f','y','P','a','t','h',0}; + static const WCHAR szUninstallString[] = + {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0}; + static const WCHAR szEstimatedSize[] = + {'E','s','t','i','m','a','t','e','d','S','i','z','e',0}; + static const WCHAR szProductLanguage[] = + {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0}; + static const WCHAR szProductVersion[] = + {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; + static const WCHAR szProductName[] = + {'P','r','o','d','u','c','t','N','a','m','e',0}; + static const WCHAR szDisplayName[] = + {'D','i','s','p','l','a','y','N','a','m','e',0}; + static const WCHAR szDisplayVersion[] = + {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; + static const WCHAR szManufacturer[] = + {'M','a','n','u','f','a','c','t','u','r','e','r',0}; + static const LPCSTR propval[] = { "ARPAUTHORIZEDCDFPREFIX", "AuthorizedCDFPrefix", "ARPCONTACT", "Contact", @@ -3955,62 +4071,77 @@ static UINT msi_write_uninstall_property_vals( MSIPACKAGE *package, HKEY hkey ) }; const LPCSTR *p = propval; - while( *p ) + while (*p) { - prop = strdupAtoW( *p++ ); - key = strdupAtoW( *p++ ); - val = msi_dup_property( package, prop ); - msi_reg_set_val_str( hkey, key, val ); + prop = strdupAtoW(*p++); + key = strdupAtoW(*p++); + val = msi_dup_property(package, prop); + msi_reg_set_val_str(hkey, key, val); msi_free(val); msi_free(key); msi_free(prop); } + + msi_reg_set_val_dword(hkey, szWindowsInstaller, 1); + + size = deformat_string(package, modpath_fmt, &buffer); + RegSetValueExW(hkey, szModifyPath, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size); + RegSetValueExW(hkey, szUninstallString, 0, REG_EXPAND_SZ, (LPBYTE)buffer, size); + msi_free(buffer); + + /* FIXME: Write real Estimated Size when we have it */ + msi_reg_set_val_dword(hkey, szEstimatedSize, 0); + + buffer = msi_dup_property(package, szProductName); + msi_reg_set_val_str(hkey, szDisplayName, buffer); + msi_free(buffer); + + buffer = msi_dup_property(package, cszSourceDir); + msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLSOURCEW, buffer); + msi_free(buffer); + + buffer = msi_dup_property(package, szManufacturer); + msi_reg_set_val_str(hkey, INSTALLPROPERTY_PUBLISHERW, buffer); + msi_free(buffer); + + GetLocalTime(&systime); + sprintfW(date, date_fmt, systime.wYear, systime.wMonth, systime.wDay); + msi_reg_set_val_str(hkey, INSTALLPROPERTY_INSTALLDATEW, date); + + langid = msi_get_property_int(package, szProductLanguage, 0); + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_LANGUAGEW, langid); + + buffer = msi_dup_property(package, szProductVersion); + msi_reg_set_val_str(hkey, szDisplayVersion, buffer); + if (buffer) + { + DWORD verdword = msi_version_str_to_dword(buffer); + + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONW, verdword); + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONMAJORW, verdword >> 24); + msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONMINORW, (verdword >> 16) & 0xFF); + msi_free(buffer); + } + return ERROR_SUCCESS; } static UINT ACTION_RegisterProduct(MSIPACKAGE *package) { - HKEY hkey=0; - HKEY hudkey=0, props=0; - LPWSTR buffer = NULL; + WCHAR squashed_pc[SQUISH_GUID_SIZE]; + LPWSTR upgrade_code; + HKEY hkey, props; + HKEY upgrade; UINT rc; - DWORD size, langid; - static const WCHAR szWindowsInstaller[] = - {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0}; - static const WCHAR szUpgradeCode[] = - {'U','p','g','r','a','d','e','C','o','d','e',0}; - static const WCHAR modpath_fmt[] = - {'M','s','i','E','x','e','c','.','e','x','e',' ', - '/','I','[','P','r','o','d','u','c','t','C','o','d','e',']',0}; - static const WCHAR szModifyPath[] = - {'M','o','d','i','f','y','P','a','t','h',0}; - static const WCHAR szUninstallString[] = - {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0}; - static const WCHAR szEstimatedSize[] = - {'E','s','t','i','m','a','t','e','d','S','i','z','e',0}; - static const WCHAR szProductLanguage[] = - {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0}; - static const WCHAR szProductVersion[] = - {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0}; - static const WCHAR szProductName[] = - {'P','r','o','d','u','c','t','N','a','m','e',0}; - static const WCHAR szDisplayName[] = - {'D','i','s','p','l','a','y','N','a','m','e',0}; - static const WCHAR szDisplayVersion[] = - {'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0}; - static const WCHAR szManufacturer[] = - {'M','a','n','u','f','a','c','t','u','r','e','r',0}; - SYSTEMTIME systime; - static const WCHAR date_fmt[] = {'%','i','%','0','2','i','%','0','2','i',0}; - LPWSTR upgrade_code; - WCHAR szDate[9]; + static const WCHAR szUpgradeCode[] = { + 'U','p','g','r','a','d','e','C','o','d','e',0}; /* FIXME: also need to publish if the product is in advertise mode */ if (!msi_check_publish(package)) return ERROR_SUCCESS; - rc = MSIREG_OpenUninstallKey(package->ProductCode,&hkey,TRUE); + rc = MSIREG_OpenUninstallKey(package->ProductCode, &hkey, TRUE); if (rc != ERROR_SUCCESS) return rc; @@ -4018,97 +4149,38 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package) { rc = MSIREG_OpenLocalSystemInstallProps(package->ProductCode, &props, TRUE); if (rc != ERROR_SUCCESS) - return rc; + goto done; } else { rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &props, TRUE); if (rc != ERROR_SUCCESS) - return rc; + goto done; } - /* dump all the info i can grab */ - /* FIXME: Flesh out more information */ - - msi_write_uninstall_property_vals( package, hkey ); + msi_make_package_local(package, props); - msi_reg_set_val_dword( hkey, szWindowsInstaller, 1 ); - - msi_make_package_local( package, hkey ); - - /* do ModifyPath and UninstallString */ - size = deformat_string(package,modpath_fmt,&buffer); - RegSetValueExW(hkey,szModifyPath,0,REG_EXPAND_SZ,(LPBYTE)buffer,size); - RegSetValueExW(hkey,szUninstallString,0,REG_EXPAND_SZ,(LPBYTE)buffer,size); - msi_free(buffer); - - /* FIXME: Write real Estimated Size when we have it */ - msi_reg_set_val_dword( hkey, szEstimatedSize, 0 ); - - buffer = msi_dup_property( package, szProductName ); - msi_reg_set_val_str( props, szDisplayName, buffer ); - msi_free(buffer); - - buffer = msi_dup_property( package, cszSourceDir ); - msi_reg_set_val_str( props, INSTALLPROPERTY_INSTALLSOURCEW, buffer); - msi_free(buffer); + rc = msi_publish_install_properties(package, hkey); + if (rc != ERROR_SUCCESS) + goto done; - buffer = msi_dup_property( package, szManufacturer ); - msi_reg_set_val_str( props, INSTALLPROPERTY_PUBLISHERW, buffer); - msi_free(buffer); - - GetLocalTime(&systime); - sprintfW(szDate,date_fmt,systime.wYear,systime.wMonth,systime.wDay); - msi_reg_set_val_str( hkey, INSTALLPROPERTY_INSTALLDATEW, szDate ); - msi_reg_set_val_str( props, INSTALLPROPERTY_INSTALLDATEW, szDate ); - - langid = msi_get_property_int( package, szProductLanguage, 0 ); - msi_reg_set_val_dword( hkey, INSTALLPROPERTY_LANGUAGEW, langid ); - - buffer = msi_dup_property( package, szProductVersion ); - msi_reg_set_val_str( props, szDisplayVersion, buffer ); - if (buffer) - { - DWORD verdword = msi_version_str_to_dword(buffer); + rc = msi_publish_install_properties(package, props); + if (rc != ERROR_SUCCESS) + goto done; - msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONW, verdword ); - msi_reg_set_val_dword( props, INSTALLPROPERTY_VERSIONW, verdword ); - msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONMAJORW, verdword>>24 ); - msi_reg_set_val_dword( props, INSTALLPROPERTY_VERSIONMAJORW, verdword>>24 ); - msi_reg_set_val_dword( hkey, INSTALLPROPERTY_VERSIONMINORW, (verdword>>16)&0x00FF ); - msi_reg_set_val_dword( props, INSTALLPROPERTY_VERSIONMINORW, (verdword>>16)&0x00FF ); - } - msi_free(buffer); - - /* Handle Upgrade Codes */ - upgrade_code = msi_dup_property( package, szUpgradeCode ); + upgrade_code = msi_dup_property(package, szUpgradeCode); if (upgrade_code) { - HKEY hkey2; - WCHAR squashed[33]; - MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey2, TRUE); - squash_guid(package->ProductCode,squashed); - msi_reg_set_val_str( hkey2, squashed, NULL ); - RegCloseKey(hkey2); - MSIREG_OpenUserUpgradeCodesKey(upgrade_code, &hkey2, TRUE); - squash_guid(package->ProductCode,squashed); - msi_reg_set_val_str( hkey2, squashed, NULL ); - RegCloseKey(hkey2); - + MSIREG_OpenUpgradeCodesKey(upgrade_code, &upgrade, TRUE); + squash_guid(package->ProductCode, squashed_pc); + msi_reg_set_val_str(upgrade, squashed_pc, NULL); + RegCloseKey(upgrade); msi_free(upgrade_code); } +done: RegCloseKey(hkey); - rc = MSIREG_OpenUserDataProductKey(package->ProductCode, &hudkey, TRUE); - if (rc != ERROR_SUCCESS) - return rc; - - RegCloseKey(hudkey); - - msi_reg_set_val_dword( props, szWindowsInstaller, 1 ); - RegCloseKey(props); - return ERROR_SUCCESS; } @@ -4119,6 +4191,7 @@ static UINT ACTION_InstallExecute(MSIPACKAGE *package) static UINT msi_unpublish_product(MSIPACKAGE *package) { + LPWSTR upgrade; LPWSTR remove = NULL; LPWSTR *features = NULL; BOOL full_uninstall = TRUE; @@ -4126,6 +4199,8 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) static const WCHAR szRemove[] = {'R','E','M','O','V','E',0}; static const WCHAR szAll[] = {'A','L','L',0}; + static const WCHAR szUpgradeCode[] = + {'U','p','g','r','a','d','e','C','o','d','e',0}; remove = msi_dup_property(package, szRemove); if (!remove) @@ -4159,6 +4234,13 @@ static UINT msi_unpublish_product(MSIPACKAGE *package) MSIREG_DeleteUserFeaturesKey(package->ProductCode); MSIREG_DeleteUninstallKey(package->ProductCode); + upgrade = msi_dup_property(package, szUpgradeCode); + if (upgrade) + { + MSIREG_DeleteUserUpgradeCodesKey(upgrade); + msi_free(upgrade); + } + done: msi_free(remove); msi_free(features); @@ -4323,7 +4405,11 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package) if (!productid) return ERROR_SUCCESS; - rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &hkey, TRUE); + if (package->Context == MSIINSTALLCONTEXT_MACHINE) + rc = MSIREG_OpenLocalSystemInstallProps(package->ProductCode, &hkey, TRUE); + else + rc = MSIREG_OpenCurrentUserInstallProps(package->ProductCode, &hkey, TRUE); + if (rc != ERROR_SUCCESS) goto end; @@ -5663,6 +5749,11 @@ static UINT ITERATE_PublishAssembly( MSIRECORD *rec, LPVOID param ) /* FIXME: extract all files belonging to this component */ file = msi_find_file(package, comp->KeyPath); + if (!file) + { + ERR("File %s not found\n", debugstr_w(comp->KeyPath)); + return ERROR_FUNCTION_FAILED; + } GetTempPathW(MAX_PATH, path); diff --git a/reactos/dll/win32/msi/automation.c b/reactos/dll/win32/msi/automation.c index 7f59b4ec844..e919b0d240c 100644 --- a/reactos/dll/win32/msi/automation.c +++ b/reactos/dll/win32/msi/automation.c @@ -405,7 +405,7 @@ static HRESULT WINAPI AutomationObject_Invoke( (hr == DISP_E_PARAMNOTFOUND || hr == DISP_E_EXCEPTION)) { static const WCHAR szComma[] = { ',',0 }; - static WCHAR szExceptionSource[] = {'M','s','i',' ','A','P','I',' ','E','r','r','o','r',0}; + static const WCHAR szExceptionSource[] = {'M','s','i',' ','A','P','I',' ','E','r','r','o','r',0}; WCHAR szExceptionDescription[MAX_PATH]; BSTR bstrParamNames[MAX_FUNC_PARAMS]; unsigned namesNo, i; diff --git a/reactos/dll/win32/msi/database.c b/reactos/dll/win32/msi/database.c index 875d2d0b681..eaf8ebdec07 100644 --- a/reactos/dll/win32/msi/database.c +++ b/reactos/dll/win32/msi/database.c @@ -83,7 +83,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb) WCHAR path[MAX_PATH]; static const WCHAR backslash[] = {'\\',0}; - static WCHAR szTables[] = { '_','T','a','b','l','e','s',0 }; + static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 }; TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) ); diff --git a/reactos/dll/win32/msi/files.c b/reactos/dll/win32/msi/files.c index d2bef7c8190..08c1959225a 100644 --- a/reactos/dll/win32/msi/files.c +++ b/reactos/dll/win32/msi/files.c @@ -459,24 +459,22 @@ done: return ret; } -static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, LPCWSTR path) +/* compares the version of a file read from the filesystem and + * the version specified in the File table + */ +static int msi_compare_file_version(MSIFILE *file) { - if (!file->IsCompressed) - { - LPWSTR p, path; - p = resolve_folder(package, file->Component->Directory, TRUE, FALSE, TRUE, NULL); - path = build_directory_name(2, p, file->ShortName); - if (file->LongName && - INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path )) - { - msi_free(path); - path = build_directory_name(2, p, file->LongName); - } - file->SourcePath = path; - msi_free(p); - } - else - file->SourcePath = build_directory_name(2, path, file->File); + WCHAR version[MAX_PATH]; + DWORD size; + UINT r; + + size = MAX_PATH; + version[0] = '\0'; + r = MsiGetFileVersionW(file->TargetPath, version, &size, NULL, NULL); + if (r != ERROR_SUCCESS) + return 0; + + return lstrcmpW(version, file->Version); } void msi_free_media_info( MSIMEDIAINFO *mi ) @@ -564,10 +562,9 @@ UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) options |= MSISOURCETYPE_NETWORK; } - if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE) - msi_package_add_media_disk(package, package->Context, - MSICODE_PRODUCT, mi->disk_id, - mi->volume_label, mi->disk_prompt); + msi_package_add_media_disk(package, package->Context, + MSICODE_PRODUCT, mi->disk_id, + mi->volume_label, mi->disk_prompt); msi_package_add_info(package, package->Context, options, INSTALLPROPERTY_LASTUSEDSOURCEW, source); @@ -577,7 +574,7 @@ UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi) } /* FIXME: search NETWORK and URL sources as well */ -static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) +UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) { WCHAR source[MAX_PATH]; WCHAR volume[MAX_PATH]; @@ -586,6 +583,7 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi) DWORD index, size, id; UINT r; + size = MAX_PATH; r = MsiSourceListGetInfoW(package->ProductCode, NULL, package->Context, MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, source, &size); @@ -822,6 +820,13 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) continue; } + if (MsiGetFileVersionW(file->TargetPath, NULL, NULL, NULL, NULL) == ERROR_SUCCESS && + msi_compare_file_version(file) >= 0) + { + TRACE("Destination file version greater, not overwriting\n"); + continue; + } + if (file->Sequence > mi->last_sequence || mi->is_continuous || (file->IsCompressed && !mi->is_extracted)) { @@ -846,13 +851,11 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package) } } - set_file_source(package, file, mi->source); - - TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath), - debugstr_w(file->TargetPath)); - if (!file->IsCompressed) { + TRACE("file paths %s to %s\n", debugstr_w(file->SourcePath), + debugstr_w(file->TargetPath)); + msi_file_update_ui(package, file, szInstallFiles); rc = copy_install_file(file); if (rc != ERROR_SUCCESS) @@ -994,24 +997,6 @@ UINT ACTION_DuplicateFiles(MSIPACKAGE *package) return rc; } -/* compares the version of a file read from the filesystem and - * the version specified in the File table - */ -static int msi_compare_file_version( MSIFILE *file ) -{ - WCHAR version[MAX_PATH]; - DWORD size; - UINT r; - - size = MAX_PATH; - version[0] = '\0'; - r = MsiGetFileVersionW( file->TargetPath, version, &size, NULL, NULL ); - if ( r != ERROR_SUCCESS ) - return 0; - - return lstrcmpW( version, file->Version ); -} - UINT ACTION_RemoveFiles( MSIPACKAGE *package ) { MSIFILE *file; diff --git a/reactos/dll/win32/msi/helpers.c b/reactos/dll/win32/msi/helpers.c index 223cacd5ad2..cffc09a7ae8 100644 --- a/reactos/dll/win32/msi/helpers.c +++ b/reactos/dll/win32/msi/helpers.c @@ -921,6 +921,8 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) ComponentList *clist; MSIFEATURE *f; + component->hasLocalFeature = FALSE; + msi_component_set_state( component, newstate ); /*if any other feature wants is local we need to set it local*/ @@ -939,6 +941,7 @@ void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature) f->ActionRequest == INSTALLSTATE_SOURCE) ) { TRACE("Saved by %s\n", debugstr_w(f->Feature)); + component->hasLocalFeature = TRUE; if (component->Attributes & msidbComponentAttributesOptional) { @@ -1160,6 +1163,16 @@ UINT msi_extract_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR destdir) if (r != ERROR_SUCCESS) goto done; + if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) + { + r = find_published_source(package, mi); + if (r != ERROR_SUCCESS) + { + ERR("Cabinet not found: %s\n", debugstr_w(mi->source)); + return ERROR_INSTALL_FAILURE; + } + } + data.package = package; data.mi = mi; data.file = file; diff --git a/reactos/dll/win32/msi/msi.c b/reactos/dll/win32/msi/msi.c index 1aaf4d93121..f903d058fda 100644 --- a/reactos/dll/win32/msi/msi.c +++ b/reactos/dll/win32/msi/msi.c @@ -1812,6 +1812,7 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) HKEY hkey; INSTALLSTATE r; BOOL missing = FALSE; + BOOL machine = FALSE; TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature)); @@ -1821,10 +1822,15 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) if (!squash_guid( szProduct, squishProduct )) return INSTALLSTATE_INVALIDARG; - /* check that it's installed at all */ - rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE); - if (rc != ERROR_SUCCESS) - return INSTALLSTATE_UNKNOWN; + if (MSIREG_OpenManagedFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS && + MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS) + { + rc = MSIREG_OpenLocalClassesFeaturesKey(szProduct, &hkey, FALSE); + if (rc != ERROR_SUCCESS) + return INSTALLSTATE_UNKNOWN; + + machine = TRUE; + } parent_feature = msi_reg_get_val_str( hkey, szFeature ); RegCloseKey(hkey); @@ -1837,8 +1843,11 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) if (r == INSTALLSTATE_ABSENT) return r; - /* now check if it's complete or advertised */ - rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE); + if (machine) + rc = MSIREG_OpenLocalUserDataFeaturesKey(szProduct, &hkey, FALSE); + else + rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE); + if (rc != ERROR_SUCCESS) return INSTALLSTATE_ADVERTISED; @@ -1862,7 +1871,12 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature) } StringFromGUID2(&guid, comp, GUID_SIZE); - rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE); + + if (machine) + rc = MSIREG_OpenLocalUserDataComponentKey(comp, &hkey, FALSE); + else + rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE); + if (rc != ERROR_SUCCESS) { msi_free(components); @@ -2281,57 +2295,93 @@ static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct, awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf, awstring *lpSerialBuf, LPDWORD pcchSerialBuf) { - HKEY hkey; + WCHAR squished_pc[SQUISH_GUID_SIZE]; LPWSTR user, org, serial; - UINT r; USERINFOSTATE state; + HKEY hkey, props; + LPCWSTR orgptr; + UINT r; + + static const WCHAR szEmpty[] = {0}; - TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf, + TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf, pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf, pcchSerialBuf); - if (!szProduct) + if (!szProduct || !squash_guid(szProduct, squished_pc)) return USERINFOSTATE_INVALIDARG; - r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE); - if (r != ERROR_SUCCESS) + if (MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS && + MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS && + MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS) + { return USERINFOSTATE_UNKNOWN; + } - user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW ); - org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW ); - serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW ); + if (MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS && + MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS) + { + RegCloseKey(hkey); + return USERINFOSTATE_ABSENT; + } + + user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW); + org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW); + serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW); + state = USERINFOSTATE_ABSENT; RegCloseKey(hkey); + RegCloseKey(props); - state = USERINFOSTATE_PRESENT; + if (user && serial) + state = USERINFOSTATE_PRESENT; - if (user) + if (pcchUserNameBuf) { - r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf ); + if (lpUserNameBuf && !user) + { + (*pcchUserNameBuf)--; + goto done; + } + + r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf); if (r == ERROR_MORE_DATA) + { state = USERINFOSTATE_MOREDATA; + goto done; + } } - else - state = USERINFOSTATE_ABSENT; - if (org) + + if (pcchOrgNameBuf) { - r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf ); - if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT) + orgptr = org; + if (!orgptr) orgptr = szEmpty; + + r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf); + if (r == ERROR_MORE_DATA) + { state = USERINFOSTATE_MOREDATA; + goto done; + } } - /* msdn states: The user information is considered to be present even in the absence of a company name. */ - if (serial) + + if (pcchSerialBuf) { - r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf ); - if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT) + if (!serial) + { + (*pcchSerialBuf)--; + goto done; + } + + r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf); + if (r == ERROR_MORE_DATA) state = USERINFOSTATE_MOREDATA; } - else - state = USERINFOSTATE_ABSENT; - msi_free( user ); - msi_free( org ); - msi_free( serial ); +done: + msi_free(user); + msi_free(org); + msi_free(serial); return state; } @@ -2346,6 +2396,11 @@ USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, { awstring user, org, serial; + if ((lpUserNameBuf && !pcchUserNameBuf) || + (lpOrgNameBuf && !pcchOrgNameBuf) || + (lpSerialBuf && !pcchSerialBuf)) + return USERINFOSTATE_INVALIDARG; + user.unicode = TRUE; user.str.w = lpUserNameBuf; org.unicode = TRUE; @@ -2367,6 +2422,11 @@ USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPWSTR prod; UINT r; + if ((lpUserNameBuf && !pcchUserNameBuf) || + (lpOrgNameBuf && !pcchOrgNameBuf) || + (lpSerialBuf && !pcchSerialBuf)) + return USERINFOSTATE_INVALIDARG; + prod = strdupAtoW( szProduct ); if (szProduct && !prod) return ERROR_OUTOFMEMORY; diff --git a/reactos/dll/win32/msi/msi.spec b/reactos/dll/win32/msi/msi.spec index 1bba6d499cc..fd1ff552884 100644 --- a/reactos/dll/win32/msi/msi.spec +++ b/reactos/dll/win32/msi/msi.spec @@ -187,8 +187,8 @@ 191 stub MsiInvalidateFeatureCache 192 stdcall MsiUseFeatureExA(str str long long) 193 stdcall MsiUseFeatureExW(wstr wstr long long) -194 stdcall MsiGetFileVersionA(str str ptr str ptr) -195 stdcall MsiGetFileVersionW(wstr wstr ptr wstr ptr) +194 stdcall MsiGetFileVersionA(str ptr ptr ptr ptr) +195 stdcall MsiGetFileVersionW(wstr ptr ptr ptr ptr) 196 stdcall MsiLoadStringA(long long long long long) 197 stdcall MsiLoadStringW(long long long long long) 198 stdcall MsiMessageBoxA(long long long long long long) diff --git a/reactos/dll/win32/msi/msi_Sv.rc b/reactos/dll/win32/msi/msi_Sv.rc index 31571a54dc1..dc1f2ed36db 100644 --- a/reactos/dll/win32/msi/msi_Sv.rc +++ b/reactos/dll/win32/msi/msi_Sv.rc @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT +LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL STRINGTABLE DISCARDABLE { diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 90eaa198c46..fe880c621aa 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -767,12 +767,13 @@ extern UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create extern UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create); extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create); -extern UINT MSIREG_OpenComponents(HKEY* key); extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create); +extern UINT MSIREG_OpenLocalUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create); extern UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create); extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY* key, BOOL create); +extern UINT MSIREG_OpenLocalUserDataProductKey(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY* key, BOOL create); extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create); @@ -785,9 +786,15 @@ extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct); extern UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create); extern UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create); extern UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create); +extern UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create); extern UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create); +extern UINT MSIREG_OpenManagedFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create); +extern UINT MSIREG_OpenLocalUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create); extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct); +extern UINT MSIREG_DeleteLocalUserDataComponentKey(LPCWSTR szComponent); extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent); +extern UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode); +extern UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create); extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name ); extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val); @@ -908,6 +915,7 @@ extern UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO extern void msi_free_media_info(MSIMEDIAINFO *mi); extern BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, PFNFDINOTIFY notify, LPVOID data); extern UINT msi_extract_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR destdir); +extern UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi); /* control event stuff */ extern VOID ControlEvent_FireSubscribedEvent(MSIPACKAGE *package, LPCWSTR event, diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index f11b0688424..0b9dacfae75 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -760,30 +760,6 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package) return r; } -static UINT msi_set_context(MSIPACKAGE *package) -{ - WCHAR val[10]; - DWORD sz = 10; - DWORD num; - UINT r; - - static const WCHAR szOne[] = {'1',0}; - static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0}; - - package->Context = MSIINSTALLCONTEXT_USERUNMANAGED; - - r = MSI_GetPropertyW(package, szAllUsers, val, &sz); - if (r == ERROR_SUCCESS) - { - num = atolW(val); - if (num == 1 || num == 2) - package->Context = MSIINSTALLCONTEXT_MACHINE; - } - - MSI_SetPropertyW(package, szAllUsers, szOne); - return ERROR_SUCCESS; -} - MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) { static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 }; @@ -823,8 +799,6 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) if (package->WordCount & MSIWORDCOUNT_ADMINISTRATIVE) msi_load_admin_properties( package ); - - msi_set_context( package ); } return package; diff --git a/reactos/dll/win32/msi/registry.c b/reactos/dll/win32/msi/registry.c index b95d5bb48cc..a12a825f343 100644 --- a/reactos/dll/win32/msi/registry.c +++ b/reactos/dll/win32/msi/registry.c @@ -204,6 +204,12 @@ static const WCHAR szInstaller_LocalClassesProd_fmt[] = { 'I','n','s','t','a','l','l','e','r','\\', 'P','r','o','d','u','c','t','s','\\','%','s',0}; +static const WCHAR szInstaller_LocalClassesFeat_fmt[] = { +'S','o','f','t','w','a','r','e','\\', +'C','l','a','s','s','e','s','\\', +'I','n','s','t','a','l','l','e','r','\\', +'F','e','a','t','u','r','e','s','\\','%','s',0}; + static const WCHAR szInstaller_LocalManagedProd_fmt[] = { 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', @@ -214,6 +220,23 @@ static const WCHAR szInstaller_LocalManagedProd_fmt[] = { 'I','n','s','t','a','l','l','e','r','\\', 'P','r','o','d','u','c','t','s','\\','%','s',0}; +static const WCHAR szInstaller_LocalManagedFeat_fmt[] = { +'S','o','f','t','w','a','r','e','\\', +'M','i','c','r','o','s','o','f','t','\\', +'W','i','n','d','o','w','s','\\', +'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', +'I','n','s','t','a','l','l','e','r','\\', +'M','a','n','a','g','e','d','\\','%','s','\\', +'I','n','s','t','a','l','l','e','r','\\', +'F','e','a','t','u','r','e','s','\\','%','s',0}; + +static const WCHAR szInstaller_ClassesUpgrade_fmt[] = { +'I','n','s','t','a','l','l','e','r','\\', +'U','p','g','r','a','d','e','C','o','d','e','s','\\', +'%','s',0}; + +static const WCHAR localsid[] = {'S','-','1','-','5','-','1','8',0}; + BOOL unsquash_guid(LPCWSTR in, LPWSTR out) { DWORD i,n=0; @@ -645,9 +668,22 @@ UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create) return rc; } -UINT MSIREG_OpenComponents(HKEY* key) +UINT MSIREG_OpenLocalUserDataFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create) { - return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Components,key); + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szProduct)); + if (!squash_guid(szProduct, squished_pc)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + sprintfW(keypath, szUserDataFeatures_fmt, localsid, squished_pc); + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); } UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) @@ -671,6 +707,38 @@ UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create) return rc; } +UINT MSIREG_OpenLocalUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create) +{ + WCHAR comp[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szComponent)); + if (!squash_guid(szComponent, comp)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(comp)); + + sprintfW(keypath, szUserDataComp_fmt, localsid, comp); + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + +UINT MSIREG_DeleteLocalUserDataComponentKey(LPCWSTR szComponent) +{ + WCHAR comp[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szComponent)); + if (!squash_guid(szComponent, comp)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(comp)); + + sprintfW(keypath, szUserDataComp_fmt, localsid, comp); + return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath); +} + UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create) { UINT rc; @@ -756,6 +824,24 @@ UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create) return rc; } +UINT MSIREG_OpenLocalUserDataProductKey(LPCWSTR szProduct, HKEY *key, BOOL create) +{ + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szProduct)); + if (!squash_guid(szProduct, squished_pc)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + sprintfW(keypath, szUserDataProd_fmt, localsid, squished_pc); + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + static UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, LPCWSTR szUserSID, HKEY *key, BOOL create) { @@ -800,8 +886,6 @@ UINT MSIREG_OpenCurrentUserInstallProps(LPCWSTR szProduct, HKEY *key, UINT MSIREG_OpenLocalSystemInstallProps(LPCWSTR szProduct, HKEY *key, BOOL create) { - static const WCHAR localsid[] = {'S','-','1','-','5','-','1','8',0}; - return MSIREG_OpenInstallProps(szProduct, localsid, key, create); } @@ -929,6 +1013,21 @@ UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL creat return rc; } +UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode) +{ + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n",debugstr_w(szUpgradeCode)); + if (!squash_guid(szUpgradeCode,squished_pc)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + sprintfW(keypath,szInstaller_UserUpgradeCodes_fmt,squished_pc); + + return RegDeleteTreeW(HKEY_CURRENT_USER, keypath); +} + UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create) { WCHAR squished_pc[GUID_SIZE]; @@ -989,6 +1088,26 @@ UINT MSIREG_OpenLocalClassesProductKey(LPCWSTR szProductCode, HKEY *key, BOOL cr return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); } +UINT MSIREG_OpenLocalClassesFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create) +{ + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szProductCode)); + + if (!squash_guid(szProductCode, squished_pc)) + return ERROR_FUNCTION_FAILED; + + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + sprintfW(keypath, szInstaller_LocalClassesFeat_fmt, squished_pc); + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create) { WCHAR squished_pc[GUID_SIZE]; @@ -1019,6 +1138,54 @@ UINT MSIREG_OpenLocalManagedProductKey(LPCWSTR szProductCode, HKEY *key, BOOL cr return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); } +UINT MSIREG_OpenManagedFeaturesKey(LPCWSTR szProductCode, HKEY *key, BOOL create) +{ + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + LPWSTR usersid; + UINT r; + + TRACE("%s\n", debugstr_w(szProductCode)); + + if (!squash_guid(szProductCode, squished_pc)) + return ERROR_FUNCTION_FAILED; + + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + r = get_user_sid(&usersid); + if (r != ERROR_SUCCESS || !usersid) + { + ERR("Failed to retrieve user SID: %d\n", r); + return r; + } + + sprintfW(keypath, szInstaller_LocalManagedFeat_fmt, usersid, squished_pc); + LocalFree(usersid); + + if (create) + return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key); + + return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key); +} + +UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create) +{ + WCHAR squished_pc[GUID_SIZE]; + WCHAR keypath[0x200]; + + TRACE("%s\n", debugstr_w(szUpgradeCode)); + if (!squash_guid(szUpgradeCode, squished_pc)) + return ERROR_FUNCTION_FAILED; + TRACE("squished (%s)\n", debugstr_w(squished_pc)); + + sprintfW(keypath, szInstaller_ClassesUpgrade_fmt, squished_pc); + + if (create) + return RegCreateKeyW(HKEY_CLASSES_ROOT, keypath, key); + + return RegOpenKeyW(HKEY_CLASSES_ROOT, keypath, key); +} + /************************************************************************* * MsiDecomposeDescriptorW [MSI.@] * @@ -1240,7 +1407,7 @@ UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid) TRACE("%d %p\n", index, lpguid); - r = MSIREG_OpenComponents(&hkeyComponents); + r = RegCreateKeyW(HKEY_LOCAL_MACHINE, szInstaller_Components, &hkeyComponents); if( r != ERROR_SUCCESS ) return ERROR_NO_MORE_ITEMS; diff --git a/reactos/dll/win32/msi/source.c b/reactos/dll/win32/msi/source.c index 4c3811661fd..d416f0f7850 100644 --- a/reactos/dll/win32/msi/source.c +++ b/reactos/dll/win32/msi/source.c @@ -304,15 +304,14 @@ UINT WINAPI MsiSourceListEnumMediaDisksW(LPCWSTR szProductCodeOrPatchCode, if (pcchDiskPrompt) { - data = ptr; - if (!*data) - data++; + if (!*ptr) + ptr++; - size = lstrlenW(data); + size = lstrlenW(ptr); if (size >= *pcchDiskPrompt) r = ERROR_MORE_DATA; else if (szDiskPrompt) - lstrcpyW(szDiskPrompt, data); + lstrcpyW(szDiskPrompt, ptr); *pcchDiskPrompt = size; } diff --git a/reactos/dll/win32/msvfw32/drawdib.c b/reactos/dll/win32/msvfw32/drawdib.c index 137716de3ed..902f0ca0664 100644 --- a/reactos/dll/win32/msvfw32/drawdib.c +++ b/reactos/dll/win32/msvfw32/drawdib.c @@ -458,7 +458,6 @@ HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) { WINE_HDD *whdd; - HPALETTE oldPal; UINT ret = 0; FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground); @@ -475,7 +474,7 @@ UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) if (!whdd->hpal) whdd->hpal = CreateHalftonePalette(hdc); - oldPal = SelectPalette(hdc, whdd->hpal, fBackground); + SelectPalette(hdc, whdd->hpal, fBackground); ret = RealizePalette(hdc); out: diff --git a/reactos/dll/win32/msvfw32/msvfw32_Da.rc b/reactos/dll/win32/msvfw32/msvfw32_Da.rc new file mode 100644 index 00000000000..32b54892a75 --- /dev/null +++ b/reactos/dll/win32/msvfw32/msvfw32_Da.rc @@ -0,0 +1,53 @@ +/* + * Danish language support + * + * Copyright (C) 2008 Jens Albretsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT + +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Video komprimering" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,129,2,49,14 + PUSHBUTTON "Annuller",IDCANCEL,129,18,49,14 + + LTEXT "&Komprimerer:",-1,9,6,105,8 + COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + + PUSHBUTTON "&Opsætning...",882,129,36,49,14 + PUSHBUTTON "O&m...",883,129,52,49,14 + + SCROLLBAR 884,9,44,111,9,WS_TABSTOP + + LTEXT "Komprimeringskvalite&t:",886,9,34,80,8 + + CONTROL "Keyframe for hvert",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + EDITTEXT 888,78,60,22,12 + LTEXT "billede",889,103,62,26,10 + + CONTROL "&Datahastighed",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + EDITTEXT 895,78,76,22,12 + LTEXT "KB/s",896,102,78,26,10 +} + +STRINGTABLE DISCARDABLE +{ + IDS_FULLFRAMES "Fulde billeder (ukomprimeret)" +} diff --git a/reactos/dll/win32/msvfw32/msvfw32_Es.rc b/reactos/dll/win32/msvfw32/msvfw32_Es.rc index 07e857c9917..aa4d3f0159b 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Es.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Es.rc @@ -1,5 +1,6 @@ /* * Copyright 2007 Luis Carlos Busquets Pérez + * Copyright 2008 José Manuel Ferrer Ortiz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,11 +37,11 @@ FONT 8, "MS Shell Dlg" LTEXT "C&alidad de compresión:",886,9,34,80,8 - CONTROL "C&uadro clave cada",887,"Botón",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + CONTROL "C&uadro clave cada",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 EDITTEXT 888,78,60,22,12 LTEXT "cuadros",889,103,62,26,10 - CONTROL "&Velocidad de datos",894,"Botón",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + CONTROL "&Tasa de datos",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 EDITTEXT 895,78,76,22,12 LTEXT "KB/s",896,102,78,26,10 } diff --git a/reactos/dll/win32/msvfw32/msvfw32_No.rc b/reactos/dll/win32/msvfw32/msvfw32_No.rc index 9be9e5114f1..41a24e393db 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_No.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_No.rc @@ -29,8 +29,8 @@ FONT 8, "MS Shell Dlg" LTEXT "&Komprimerer:",-1,9,6,105,8 COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP - PUSHBUTTON "&Oppsett . . .",882,129,36,49,14 - PUSHBUTTON "O&m . . .",883,129,52,49,14 + PUSHBUTTON "&Oppsett...",882,129,36,49,14 + PUSHBUTTON "O&m...",883,129,52,49,14 SCROLLBAR 884,9,44,111,9,WS_TABSTOP diff --git a/reactos/dll/win32/msvfw32/msvfw32_Ru.rc b/reactos/dll/win32/msvfw32/msvfw32_Ru.rc new file mode 100644 index 00000000000..96c8a814d64 --- /dev/null +++ b/reactos/dll/win32/msvfw32/msvfw32_Ru.rc @@ -0,0 +1,51 @@ +/* + * Copyright 2008 Vitaliy Margolen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Ñæàòèå âèäåî" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "OK",IDOK,129,2,49,14 + PUSHBUTTON "Îòìåíà",IDCANCEL,129,18,49,14 + + LTEXT "&Àëãîðèòì ñæàòèÿ:",-1,9,6,105,8 + COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + + PUSHBUTTON "&Íàñòðîéêè...",882,129,36,49,14 + PUSHBUTTON "&Èíôîðìàöèÿ...",883,129,52,49,14 + + SCROLLBAR 884,9,44,111,9,WS_TABSTOP + + LTEXT "&Êà÷åñòâî ñæàòèÿ:",886,9,34,80,8 + + CONTROL "Êë&þ÷åâîé êàäð êàæäûå",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + EDITTEXT 888,78,60,22,12 + LTEXT "êàäðîâ",889,103,62,26,10 + + CONTROL "&Ïîòîê äàííûõ",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + EDITTEXT 895,78,76,22,12 + LTEXT "ÊÁ/ñåê",896,102,78,26,10 +} + +STRINGTABLE DISCARDABLE +{ + IDS_FULLFRAMES "Êàäðû öåëèêîì (Áåç êîìïðåññèè)" +} diff --git a/reactos/dll/win32/msvfw32/msvfw32_Si.rc b/reactos/dll/win32/msvfw32/msvfw32_Si.rc new file mode 100644 index 00000000000..05d1ba588ef --- /dev/null +++ b/reactos/dll/win32/msvfw32/msvfw32_Si.rc @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Rok Mandeljc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma code_page(65001) + +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT + +ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Stiskanje videa" +FONT 8, "MS Shell Dlg" +{ + DEFPUSHBUTTON "V redu",IDOK,129,2,49,14 + PUSHBUTTON "Prekliči",IDCANCEL,129,18,49,14 + + LTEXT "&Kodek za stiskanje:",-1,9,6,105,8 + COMBOBOX 880,9,16,111,67,CBS_DROPDOWNLIST|WS_VSCROLL|WS_TABSTOP + + PUSHBUTTON "&Nastavitve ...",882,129,36,49,14 + PUSHBUTTON "&O ...",883,129,52,49,14 + + SCROLLBAR 884,9,44,111,9,WS_TABSTOP + + LTEXT "Kakovost &stiskanja:",886,9,34,80,8 + + CONTROL "&Ključna slika na vsakih",887,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,60,66,12 + EDITTEXT 888,78,60,22,12 + LTEXT "slik",889,103,62,26,10 + + CONTROL "&Pretok podatkov",894,"Button",BS_AUTOCHECKBOX|WS_TABSTOP,9,76,66,12 + EDITTEXT 895,78,76,22,12 + LTEXT "kb/s",896,102,78,26,10 +} + +STRINGTABLE DISCARDABLE +{ + IDS_FULLFRAMES "Polne slike (nestisnjeno)" +} + +#pragma code_page(default) diff --git a/reactos/dll/win32/msvfw32/msvfw32_Sv.rc b/reactos/dll/win32/msvfw32/msvfw32_Sv.rc index 5413bf567c5..68f51677212 100644 --- a/reactos/dll/win32/msvfw32/msvfw32_Sv.rc +++ b/reactos/dll/win32/msvfw32/msvfw32_Sv.rc @@ -16,7 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT +LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL ICM_CHOOSE_COMPRESSOR DIALOG DISCARDABLE 36, 24, 187, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU diff --git a/reactos/dll/win32/msvfw32/rsrc.rc b/reactos/dll/win32/msvfw32/rsrc.rc index 442ee4cdda1..4246fdf8a6e 100644 --- a/reactos/dll/win32/msvfw32/rsrc.rc +++ b/reactos/dll/win32/msvfw32/rsrc.rc @@ -20,6 +20,7 @@ #include "winuser.h" #include "msvideo_private.h" +#include "msvfw32_Da.rc" #include "msvfw32_De.rc" #include "msvfw32_En.rc" #include "msvfw32_Es.rc" @@ -29,5 +30,7 @@ #include "msvfw32_Nl.rc" #include "msvfw32_No.rc" #include "msvfw32_Pl.rc" +#include "msvfw32_Ru.rc" +#include "msvfw32_Si.rc" #include "msvfw32_Sv.rc" #include "msvfw32_Tr.rc" diff --git a/reactos/dll/win32/netapi32/access.c b/reactos/dll/win32/netapi32/access.c index f79323918f6..4fdf60a26b5 100644 --- a/reactos/dll/win32/netapi32/access.c +++ b/reactos/dll/win32/netapi32/access.c @@ -105,6 +105,34 @@ static struct sam_user* NETAPI_FindUser(LPCWSTR UserName) return NULL; } +static BOOL NETAPI_IsCurrentUser(LPCWSTR username) +{ + LPWSTR curr_user = NULL; + DWORD dwSize; + BOOL ret = FALSE; + + dwSize = LM20_UNLEN+1; + curr_user = HeapAlloc(GetProcessHeap(), 0, dwSize); + if(!curr_user) + { + ERR("Failed to allocate memory for user name.\n"); + goto end; + } + if(!GetUserNameW(curr_user, &dwSize)) + { + ERR("Failed to get current user's user name.\n"); + goto end; + } + if (!lstrcmpW(curr_user, username)) + { + ret = TRUE; + } + +end: + HeapFree(GetProcessHeap(), 0, curr_user); + return ret; +} + /************************************************************ * NetUserAdd (NETAPI32.@) */ @@ -226,7 +254,7 @@ NetUserGetInfo(LPCWSTR servername, LPCWSTR username, DWORD level, return NERR_InvalidComputer; } - if(!NETAPI_FindUser(username)) + if(!NETAPI_FindUser(username) && !NETAPI_IsCurrentUser(username)) { TRACE("User %s is unknown.\n", debugstr_w(username)); return NERR_UserNotFound; diff --git a/reactos/dll/win32/netapi32/ds.c b/reactos/dll/win32/netapi32/ds.c index 819dc23be3e..386e222ca01 100644 --- a/reactos/dll/win32/netapi32/ds.c +++ b/reactos/dll/win32/netapi32/ds.c @@ -77,7 +77,7 @@ VOID WINAPI DsRoleFreeMemory(PVOID Buffer) * DsRoleGetPrimaryDomainInformation (NETAPI32.@) * * PARAMS - * lpServer [I] Pointer to UNICODE string with Computername + * lpServer [I] Pointer to UNICODE string with ComputerName * InfoLevel [I] Type of data to retrieve * Buffer [O] Pointer to to the requested data * @@ -99,6 +99,7 @@ DWORD WINAPI DsRoleGetPrimaryDomainInformation( if (!Buffer) return ERROR_INVALID_PARAMETER; if ((InfoLevel < DsRolePrimaryDomainInfoBasic) || (InfoLevel > DsRoleOperationState)) return ERROR_INVALID_PARAMETER; + *Buffer = NULL; switch (InfoLevel) { case DsRolePrimaryDomainInfoBasic: diff --git a/reactos/dll/win32/netapi32/nbnamecache.h b/reactos/dll/win32/netapi32/nbnamecache.h index 987c6c4946b..b227ed641e6 100644 --- a/reactos/dll/win32/netapi32/nbnamecache.h +++ b/reactos/dll/win32/netapi32/nbnamecache.h @@ -45,7 +45,7 @@ typedef struct _NBNameCacheEntry /* Functions that create, manipulate, and destroy a name cache. Thread-safe, * with the exception of NBNameCacheDestroy--ensure that no other threads are - * manipulating the cache before destoying it. + * manipulating the cache before destroying it. */ /* Allocates a new name cache from heap, and sets the expire time on new diff --git a/reactos/dll/win32/netapi32/wksta.c b/reactos/dll/win32/netapi32/wksta.c index 9a4d5310e5e..6914d028124 100644 --- a/reactos/dll/win32/netapi32/wksta.c +++ b/reactos/dll/win32/netapi32/wksta.c @@ -103,7 +103,7 @@ static void wprint_mac(WCHAR* buffer, int len, const MIB_IFROW *ifRow) /* Theoretically this could be too short, except that MS defines * MAX_ADAPTER_NAME as 128, and MAX_INTERFACE_NAME_LEN as 256, and both - * represent a count of WCHARs, so even with an extroardinarily long header + * represent a count of WCHARs, so even with an extraordinarily long header * this will be plenty */ #define MAX_TRANSPORT_NAME MAX_INTERFACE_NAME_LEN @@ -348,7 +348,6 @@ NET_API_STATUS WINAPI NetWkstaUserGetInfo(LMSTR reserved, DWORD level, { PWKSTA_USER_INFO_1 ui; PWKSTA_USER_INFO_0 ui0; - DWORD dwSize; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo; @@ -405,7 +404,6 @@ NET_API_STATUS WINAPI NetWkstaUserGetInfo(LMSTR reserved, DWORD level, oth_domains_sz * sizeof(WCHAR)); /* get data */ - dwSize = username_sz; lstrcpyW(ui->wkui1_username, ui0->wkui0_username); NetApiBufferFree(ui0);