Sync to Wine-0_9_3:
authorGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 23:01:12 +0000 (23:01 +0000)
committerGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 23:01:12 +0000 (23:01 +0000)
Huw Davies <huw@codeweavers.com>
- msi: Fix MsiProvideQualifiedComponentW spec file entry.
Christian Gmeiner <christian.gmeiner@students.fh-vorarlberg.ac.at>
- msi: Implemented DllCanUnloadNow.
Robert Shearman <rob@codeweavers.com>
- The buffer sizes in the documentation for MsiDecomposeDescriptorW don't
  include the NULL terminator, so fix this.
Mike McCormack <mike@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.

svn path=/trunk/; revision=20133

reactos/lib/msi/dialog.c
reactos/lib/msi/helpers.c
reactos/lib/msi/msi.c
reactos/lib/msi/msi.spec
reactos/lib/msi/registry.c

index 3975891..87e14e8 100644 (file)
@@ -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 )
 {
index a2bfb0d..2b2ba06 100644 (file)
@@ -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)
+    /* 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,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;
index bfbc384..edea3d7 100644 (file)
@@ -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;
 }
 
 /***********************************************************************
index 28b2628..ee28694 100644 (file)
 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)
index 3af662b..528070e 100644 (file)
@@ -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