msi: Create the local copy before opening the database.
authorHans Leidekker <hans@codeweavers.com>
Tue, 20 Oct 2009 12:09:53 +0000 (14:09 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 20 Oct 2009 12:39:55 +0000 (14:39 +0200)
dlls/msi/action.c
dlls/msi/database.c
dlls/msi/msipriv.h
dlls/msi/package.c

index e10870133c414480399f43f09a145aa2e5d25a77..b9b819995cd7dc4d1dec176bf86e576f8defa372 100644 (file)
@@ -3802,63 +3802,6 @@ static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package)
     return ERROR_SUCCESS;
 }
 
-static UINT msi_get_local_package_name( LPWSTR path )
-{
-    static const WCHAR szInstaller[] = {
-        '\\','I','n','s','t','a','l','l','e','r','\\',0};
-    static const WCHAR fmt[] = { '%','x','.','m','s','i',0};
-    DWORD time, len, i;
-    HANDLE handle;
-
-    time = GetTickCount();
-    GetWindowsDirectoryW( path, MAX_PATH );
-    lstrcatW( path, szInstaller );
-    CreateDirectoryW( path, NULL );
-
-    len = lstrlenW(path);
-    for (i=0; i<0x10000; i++)
-    {
-        snprintfW( &path[len], MAX_PATH - len, fmt, (time+i)&0xffff );
-        handle = CreateFileW( path, GENERIC_WRITE, 0, NULL,
-                              CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
-        if (handle != INVALID_HANDLE_VALUE)
-        {
-            CloseHandle(handle);
-            break;
-        }
-        if (GetLastError() != ERROR_FILE_EXISTS &&
-            GetLastError() != ERROR_SHARING_VIOLATION)
-            return ERROR_FUNCTION_FAILED;
-    }
-
-    return ERROR_SUCCESS;
-}
-
-static UINT msi_make_package_local( MSIPACKAGE *package, HKEY hkey )
-{
-    WCHAR packagefile[MAX_PATH];
-    UINT r;
-
-    r = msi_get_local_package_name( packagefile );
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    TRACE("Copying to local package %s\n",debugstr_w(packagefile));
-
-    r = CopyFileW( package->db->path, packagefile, FALSE);
-
-    if (!r)
-    {
-        ERR("Unable to copy package (%s -> %s) (error %d)\n",
-            debugstr_w(package->db->path), debugstr_w(packagefile), GetLastError());
-        return ERROR_FUNCTION_FAILED;
-    }
-
-    msi_reg_set_val_str( hkey, INSTALLPROPERTY_LOCALPACKAGEW, packagefile );
-
-    return ERROR_SUCCESS;
-}
-
 static UINT msi_publish_install_properties(MSIPACKAGE *package, HKEY hkey)
 {
     LPWSTR prop, val, key;
@@ -3990,7 +3933,9 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
     if (rc != ERROR_SUCCESS)
         goto done;
 
-    msi_make_package_local(package, props);
+    msi_reg_set_val_str( props, INSTALLPROPERTY_LOCALPACKAGEW, package->db->localfile );
+    msi_free( package->db->localfile );
+    package->db->localfile = NULL;
 
     rc = msi_publish_install_properties(package, hkey);
     if (rc != ERROR_SUCCESS)
index 8d0ee42ea025794ebc85fffb9a548a02ff22a86c..a75b8a8204e0736602ec7b16b72575bed1840072 100644 (file)
@@ -65,6 +65,11 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
         DeleteFileW( db->deletefile );
         msi_free( db->deletefile );
     }
+    if (db->localfile)
+    {
+        DeleteFileW( db->localfile );
+        msi_free( db->localfile );
+    }
 }
 
 UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
index 296e87d69ae9b24068f38ae5de0fef47042b0699..9692b64e14a48a1e4190990d28b40ee2efd3cb9d 100644 (file)
@@ -76,6 +76,7 @@ typedef struct tagMSIDATABASE
     UINT bytes_per_strref;
     LPWSTR path;
     LPWSTR deletefile;
+    LPWSTR localfile;
     LPCWSTR mode;
     struct list tables;
     struct list transforms;
index 1d34770916d9f316f7f227120d64186359f33def..1ab2afd1774ee8ace7940e1b2d095a1b8cfa9ceb 100644 (file)
@@ -870,6 +870,38 @@ LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename )
     return filename;
 }
 
+static UINT msi_get_local_package_name( LPWSTR path )
+{
+    static const WCHAR szInstaller[] = {
+        '\\','I','n','s','t','a','l','l','e','r','\\',0};
+    static const WCHAR fmt[] = { '%','x','.','m','s','i',0};
+    DWORD time, len, i;
+    HANDLE handle;
+
+    time = GetTickCount();
+    GetWindowsDirectoryW( path, MAX_PATH );
+    strcatW( path, szInstaller );
+    CreateDirectoryW( path, NULL );
+
+    len = strlenW(path);
+    for (i = 0; i < 0x10000; i++)
+    {
+        snprintfW( &path[len], MAX_PATH - len, fmt, (time + i)&0xffff );
+        handle = CreateFileW( path, GENERIC_WRITE, 0, NULL,
+                              CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+        if (handle != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(handle);
+            break;
+        }
+        if (GetLastError() != ERROR_FILE_EXISTS &&
+            GetLastError() != ERROR_SHARING_VIOLATION)
+            return ERROR_FUNCTION_FAILED;
+    }
+
+    return ERROR_SUCCESS;
+}
+
 UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
 {
     static const WCHAR OriginalDatabase[] =
@@ -880,7 +912,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
     MSIHANDLE handle;
     LPWSTR ptr, base_url = NULL;
     UINT r;
-    WCHAR temppath[MAX_PATH];
+    WCHAR temppath[MAX_PATH], localfile[MAX_PATH];
     LPCWSTR file = szPackage;
 
     TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
@@ -921,6 +953,19 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
         else
             file = copy_package_to_temp( szPackage, temppath );
 
+        r = msi_get_local_package_name( localfile );
+        if (r != ERROR_SUCCESS)
+            return r;
+
+        TRACE("Copying to local package %s\n", debugstr_w(localfile));
+
+        if (!CopyFileW( file, localfile, FALSE ))
+        {
+            ERR("Unable to copy package (%s -> %s) (error %u)\n",
+                debugstr_w(file), debugstr_w(localfile), GetLastError());
+            return GetLastError();
+        }
+
         r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &db );
         if( r != ERROR_SUCCESS )
         {
@@ -932,6 +977,8 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
 
             return r;
         }
+
+        db->localfile = strdupW( localfile );
     }
 
     package = MSI_CreatePackage( db, base_url );