Sync to Wine-0_9_3:
Huw Davies <huw(a)codeweavers.com>
- msi: Fix MsiProvideQualifiedComponentW spec file entry.
Christian Gmeiner <christian.gmeiner(a)students.fh-vorarlberg.ac.at>
- msi: Implemented DllCanUnloadNow.
Robert Shearman <rob(a)codeweavers.com>
- The buffer sizes in the documentation for MsiDecomposeDescriptorW
don't
include the NULL terminator, so fix this.
Mike McCormack <mike(a)codeweavers.com>
- 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.
Modified: trunk/reactos/lib/msi/dialog.c
Modified: trunk/reactos/lib/msi/helpers.c
Modified: trunk/reactos/lib/msi/msi.c
Modified: trunk/reactos/lib/msi/msi.spec
Modified: trunk/reactos/lib/msi/registry.c
_____
Modified: trunk/reactos/lib/msi/dialog.c
--- trunk/reactos/lib/msi/dialog.c 2005-12-12 22:57:45 UTC (rev
20132)
+++ trunk/reactos/lib/msi/dialog.c 2005-12-12 23:01:12 UTC (rev
20133)
@@ -939,6 +939,7 @@
case '&':
case '`':
case '?':
+ case '^':
return TRUE;
}
return FALSE;
@@ -1156,6 +1157,7 @@
/*
* office 2003 uses "73931<````=````=````=````=`````>@@@@@"
* delphi 7 uses "<????-??????-??????-????>" and
"<???-???>"
+ * filemaker pro 7 uses "<^^^^=^^^^=^^^^=^^^^=^^^^=^^^^=^^^^^>"
*/
static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD
*rec )
{
_____
Modified: trunk/reactos/lib/msi/helpers.c
--- trunk/reactos/lib/msi/helpers.c 2005-12-12 22:57:45 UTC (rev
20132)
+++ trunk/reactos/lib/msi/helpers.c 2005-12-12 23:01:12 UTC (rev
20133)
@@ -210,6 +210,24 @@
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 @@
if (!name)
return NULL;
- /* source directories appear to always be at the root */
- if (source)
+ /* special resolving for Target and Source root dir */
+ if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0)
{
- path = msi_dup_property( package, cszSourceDir );
- if (!path)
+ if (!source)
{
- path = msi_dup_property( package, cszDatabase );
- if (path)
+ LPWSTR check_path;
+ check_path = msi_dup_property( package, cszTargetDir );
+ if (!check_path)
{
- p = strrchrW(path,'\\');
- if (p)
- *(p+1) = 0;
+ check_path = msi_dup_property( package, cszRootDrive );
+ if (set_prop)
+ MSI_SetPropertyW(package,cszTargetDir,check_path);
}
- }
- 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)
- {
- 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,14 +273,20 @@
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 );
TRACE(" internally set to %s\n",debugstr_w(path));
@@ -292,13 +302,34 @@
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;
_____
Modified: trunk/reactos/lib/msi/msi.c
--- trunk/reactos/lib/msi/msi.c 2005-12-12 22:57:45 UTC (rev 20132)
+++ trunk/reactos/lib/msi/msi.c 2005-12-12 23:01:12 UTC (rev 20133)
@@ -53,8 +53,24 @@
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 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_LockServer(LPCLASSFACTORY iface, BOOL
dolock)
{
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ TRACE("(%p)->(%d)\n", iface, dolock);
- FIXME("%p %d\n", This, dolock);
+ if(dolock)
+ LockModule();
+ else
+ UnlockModule();
+
return S_OK;
}
@@ -1365,7 +1387,7 @@
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
- return S_FALSE;
+ return dll_count == 0 ? S_OK : S_FALSE;
}
/***********************************************************************
_____
Modified: trunk/reactos/lib/msi/msi.spec
--- trunk/reactos/lib/msi/msi.spec 2005-12-12 22:57:45 UTC (rev
20132)
+++ trunk/reactos/lib/msi/msi.spec 2005-12-12 23:01:12 UTC (rev
20133)
@@ -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)
_____
Modified: trunk/reactos/lib/msi/registry.c
--- trunk/reactos/lib/msi/registry.c 2005-12-12 22:57:45 UTC (rev
20132)
+++ trunk/reactos/lib/msi/registry.c 2005-12-12 23:01:12 UTC (rev
20133)
@@ -502,9 +502,9 @@
*
* 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