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 '&':
     case '`':
     case '?':
+    case '^':
         return TRUE;
     }
     return FALSE;
         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 "<???-???>"
 /*
  * office 2003 uses "73931<````=````=````=````=`````>@@@@@"
  * delphi 7 uses "<????-??????-??????-????>" and "<???-???>"
+ * filemaker pro 7 uses "<^^^^=^^^^=^^^^=^^^^=^^^^=^^^^=^^^^^>"
  */
 static UINT msi_dialog_maskedit_control( msi_dialog *dialog, MSIRECORD *rec )
 {
  */
 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;
 }
 
     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)
 {
 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;
 
     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;
         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 (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;
     }
     {
         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 );
                     
     {
         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(" ! 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;
         msi_free(p);
     }
     return path;
index bfbc384..edea3d7 100644 (file)
@@ -53,8 +53,24 @@ LPVOID gUIContext = NULL;
 WCHAR gszLogFile[MAX_PATH];
 HINSTANCE msi_hInstance;
 
 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};
 
 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;
 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)
 {
 
 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
 {
+    LockModule();
     return 2;
 }
 
 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
 {
     return 2;
 }
 
 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
 {
+    UnlockModule();
     return 1;
 }
 
     return 1;
 }
 
@@ -1306,9 +1324,13 @@ static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
 
 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
 {
 
 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;
 }
 
     return S_OK;
 }
 
@@ -1365,7 +1387,7 @@ HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
  */
 HRESULT WINAPI DllCanUnloadNow(void)
 {
  */
 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)
 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)
 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
  *
  * 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
  *   pUsed         [O]  the length of the descriptor
  *
  * RETURNS