From 8e9944e310ae65fbacbb85bbebfe6b4676fc49f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Mon, 12 Dec 2005 23:01:12 +0000 Subject: [PATCH] Sync to Wine-0_9_3: Huw Davies - msi: Fix MsiProvideQualifiedComponentW spec file entry. Christian Gmeiner - msi: Implemented DllCanUnloadNow. Robert Shearman - The buffer sizes in the documentation for MsiDecomposeDescriptorW don't include the NULL terminator, so fix this. Mike McCormack - If a source directory doesn't exist, use the install root instead. - Make all source directories at the root of the install. - Handle the ^ character in MaskEdit controls. svn path=/trunk/; revision=20133 --- reactos/lib/msi/dialog.c | 2 + reactos/lib/msi/helpers.c | 109 ++++++++++++++++++++++++------------- reactos/lib/msi/msi.c | 28 +++++++++- reactos/lib/msi/msi.spec | 2 +- reactos/lib/msi/registry.c | 6 +- 5 files changed, 101 insertions(+), 46 deletions(-) diff --git a/reactos/lib/msi/dialog.c b/reactos/lib/msi/dialog.c index 3975891ec13..87e14e87f35 100644 --- a/reactos/lib/msi/dialog.c +++ b/reactos/lib/msi/dialog.c @@ -939,6 +939,7 @@ static BOOL msi_mask_editable( WCHAR type ) case '&': case '`': case '?': + case '^': return TRUE; } return FALSE; @@ -1156,6 +1157,7 @@ msi_maskedit_create_children( struct msi_maskedit_info *info, LPCWSTR font ) /* * office 2003 uses "73931<````=````=````=````=`````>@@@@@" * delphi 7 uses "" and "" + * filemaker pro 7 uses "<^^^^=^^^^=^^^^=^^^^=^^^^=^^^^=^^^^^>" */ static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec ) { diff --git a/reactos/lib/msi/helpers.c b/reactos/lib/msi/helpers.c index a2bfb0d7d67..2b2ba06155d 100644 --- a/reactos/lib/msi/helpers.c +++ b/reactos/lib/msi/helpers.c @@ -210,6 +210,24 @@ MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir ) return NULL; } +static LPWSTR get_source_root( MSIPACKAGE *package ) +{ + LPWSTR path, p; + + path = msi_dup_property( package, cszSourceDir ); + if (path) + return path; + + path = msi_dup_property( package, cszDatabase ); + if (path) + { + p = strrchrW(path,'\\'); + if (p) + *(p+1) = 0; + } + return path; +} + LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, BOOL set_prop, MSIFOLDER **folder) { @@ -221,42 +239,28 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, if (!name) return NULL; - /* source directories appear to always be at the root */ - if (source) - { - path = msi_dup_property( package, cszSourceDir ); - if (!path) - { - path = msi_dup_property( package, cszDatabase ); - if (path) - { - p = strrchrW(path,'\\'); - if (p) - *(p+1) = 0; - } - } - if (folder) - *folder = get_loaded_folder( package, name ); - return path; - } - /* special resolving for Target and Source root dir */ if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0) { - LPWSTR check_path; - check_path = msi_dup_property( package, cszTargetDir ); - if (!check_path) + if (!source) { - check_path = msi_dup_property( package, cszRootDrive ); - if (set_prop) - MSI_SetPropertyW(package,cszTargetDir,check_path); - } + LPWSTR check_path; + check_path = msi_dup_property( package, cszTargetDir ); + if (!check_path) + { + check_path = msi_dup_property( package, cszRootDrive ); + if (set_prop) + MSI_SetPropertyW(package,cszTargetDir,check_path); + } - /* correct misbuilt target dir */ - path = build_directory_name(2, check_path, NULL); - if (strcmpiW(path,check_path)!=0) - MSI_SetPropertyW(package,cszTargetDir,path); - msi_free(check_path); + /* correct misbuilt target dir */ + path = build_directory_name(2, check_path, NULL); + if (strcmpiW(path,check_path)!=0) + MSI_SetPropertyW(package,cszTargetDir,path); + msi_free(check_path); + } + else + path = get_source_root( package ); if (folder) *folder = get_loaded_folder( package, name ); return path; @@ -269,13 +273,19 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, if (folder) *folder = f; - if (f->ResolvedTarget) + if (!source && f->ResolvedTarget) { path = strdupW( f->ResolvedTarget ); TRACE(" already resolved to %s\n",debugstr_w(path)); return path; } - else if (f->Property) + else if (source && f->ResolvedSource) + { + path = strdupW( f->ResolvedSource ); + TRACE(" (source)already resolved to %s\n",debugstr_w(path)); + return path; + } + else if (!source && f->Property) { path = build_directory_name( 2, f->Property, NULL ); @@ -292,13 +302,34 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, TRACE(" ! Parent is %s\n", debugstr_w(parent)); p = resolve_folder(package, parent, source, set_prop, NULL); - TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault)); + if (!source) + { + TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault)); - path = build_directory_name( 3, p, f->TargetDefault, NULL ); - f->ResolvedTarget = strdupW( path ); - TRACE(" resolved into %s\n",debugstr_w(path)); - if (set_prop) - MSI_SetPropertyW(package,name,path); + path = build_directory_name( 3, p, f->TargetDefault, NULL ); + f->ResolvedTarget = strdupW( path ); + TRACE("target -> %s\n", debugstr_w(path)); + if (set_prop) + MSI_SetPropertyW(package,name,path); + } + else + { + if (f->SourceDefault && f->SourceDefault[0]!='.') + path = build_directory_name( 3, p, f->SourceDefault, NULL ); + else + path = strdupW(p); + TRACE("source -> %s\n", debugstr_w(path)); + + /* if the directory doesn't exist, use the root */ + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path )) + { + msi_free( path ); + path = get_source_root( package ); + TRACE("defaulting to %s\n", debugstr_w(path)); + } + else + f->ResolvedSource = strdupW( path ); + } msi_free(p); } return path; diff --git a/reactos/lib/msi/msi.c b/reactos/lib/msi/msi.c index bfbc3849299..edea3d75af6 100644 --- a/reactos/lib/msi/msi.c +++ b/reactos/lib/msi/msi.c @@ -53,8 +53,24 @@ LPVOID gUIContext = NULL; WCHAR gszLogFile[MAX_PATH]; HINSTANCE msi_hInstance; +static LONG dll_count; + static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0}; +/********************************************************************** + * Dll lifetime tracking declaration + */ +static void LockModule(void) +{ + InterlockedIncrement(&dll_count); +} + +static void UnlockModule(void) +{ + InterlockedDecrement(&dll_count); +} + + UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct) { UINT r; @@ -1287,11 +1303,13 @@ static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface, static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface) { + LockModule(); return 2; } static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface) { + UnlockModule(); return 1; } @@ -1306,9 +1324,13 @@ static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface, static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + TRACE("(%p)->(%d)\n", iface, dolock); + + if(dolock) + LockModule(); + else + UnlockModule(); - FIXME("%p %d\n", This, dolock); return S_OK; } @@ -1365,7 +1387,7 @@ HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi) */ HRESULT WINAPI DllCanUnloadNow(void) { - return S_FALSE; + return dll_count == 0 ? S_OK : S_FALSE; } /*********************************************************************** diff --git a/reactos/lib/msi/msi.spec b/reactos/lib/msi/msi.spec index 28b26289ada..ee286942ef2 100644 --- a/reactos/lib/msi/msi.spec +++ b/reactos/lib/msi/msi.spec @@ -102,7 +102,7 @@ 106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr) 107 stub MsiProvideComponentW 108 stdcall MsiProvideQualifiedComponentA(str str long ptr ptr) -109 stdcall MsiProvideQualifiedComponentW(str str long ptr ptr) +109 stdcall MsiProvideQualifiedComponentW(wstr wstr long ptr ptr) 110 stdcall MsiQueryFeatureStateA(str str) 111 stdcall MsiQueryFeatureStateW(wstr wstr) 112 stdcall MsiQueryProductStateA(str) diff --git a/reactos/lib/msi/registry.c b/reactos/lib/msi/registry.c index 3af662b5ae4..528070e0ffd 100644 --- a/reactos/lib/msi/registry.c +++ b/reactos/lib/msi/registry.c @@ -502,9 +502,9 @@ UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL creat * * PARAMS * szDescriptor [I] the descriptor to decompose - * szProduct [O] buffer of MAX_FEATURE_CHARS for the product guid - * szFeature [O] buffer of MAX_FEATURE_CHARS for the feature code - * szComponent [O] buffer of MAX_FEATURE_CHARS for the component guid + * szProduct [O] buffer of MAX_FEATURE_CHARS+1 for the product guid + * szFeature [O] buffer of MAX_FEATURE_CHARS+1 for the feature code + * szComponent [O] buffer of MAX_FEATURE_CHARS+1 for the component guid * pUsed [O] the length of the descriptor * * RETURNS