[PATCH 2/4] setupapi: Check all INF files in SetupCopyOEMInf().

Zebediah Figura z.figura12 at gmail.com
Thu May 23 18:00:46 CDT 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/setupapi/misc.c       | 138 ++++++++++++++++++++++---------------
 dlls/setupapi/tests/misc.c |   8 ---
 2 files changed, 83 insertions(+), 63 deletions(-)

diff --git a/dlls/setupapi/misc.c b/dlls/setupapi/misc.c
index c83df698adf..7298ac65b62 100644
--- a/dlls/setupapi/misc.c
+++ b/dlls/setupapi/misc.c
@@ -903,23 +903,80 @@ static int compare_files( HANDLE file1, HANDLE file2 )
     return 0;
 }
 
+static BOOL find_existing_inf(const WCHAR *source, WCHAR *target)
+{
+    static const WCHAR infW[] = {'\\','i','n','f','\\',0};
+    static const WCHAR wildcardW[] = {'*',0};
+
+    LARGE_INTEGER source_file_size, dest_file_size;
+    HANDLE source_file, dest_file;
+    WIN32_FIND_DATAW find_data;
+    HANDLE find_handle;
+
+    source_file = CreateFileW( source, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
+                               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                               NULL, OPEN_EXISTING, 0, NULL );
+    if (source_file == INVALID_HANDLE_VALUE)
+        return FALSE;
+
+    if (!GetFileSizeEx( source_file, &source_file_size ))
+    {
+        CloseHandle( source_file );
+        return FALSE;
+    }
+
+    GetWindowsDirectoryW( target, MAX_PATH );
+    strcatW( target, infW );
+    strcatW( target, wildcardW );
+    if ((find_handle = FindFirstFileW( target, &find_data )) != INVALID_HANDLE_VALUE)
+    {
+        do {
+            GetWindowsDirectoryW( target, MAX_PATH );
+            strcatW( target, infW );
+            strcatW( target, find_data.cFileName );
+            dest_file = CreateFileW( target, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
+                                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                                     NULL, OPEN_EXISTING, 0, NULL );
+            if (dest_file == INVALID_HANDLE_VALUE)
+                continue;
+
+            if (GetFileSizeEx( dest_file, &dest_file_size )
+                    && dest_file_size.QuadPart == source_file_size.QuadPart
+                    && !compare_files( source_file, dest_file ))
+            {
+                CloseHandle( dest_file );
+                CloseHandle( source_file );
+                FindClose( find_handle );
+                return TRUE;
+            }
+            CloseHandle( dest_file );
+        } while (FindNextFileW( find_handle, &find_data ));
+
+        FindClose( find_handle );
+    }
+
+    CloseHandle( source_file );
+    return FALSE;
+}
+
 /***********************************************************************
  *      SetupCopyOEMInfW  (SETUPAPI.@)
  */
 BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location,
                               DWORD media_type, DWORD style, PWSTR dest,
-                              DWORD buffer_size, PDWORD required_size, PWSTR *component )
+                              DWORD buffer_size, DWORD *required_size, WCHAR **filepart )
 {
     BOOL ret = FALSE;
     WCHAR target[MAX_PATH], catalog_file[MAX_PATH], *p;
     static const WCHAR inf[] = { '\\','i','n','f','\\',0 };
     static const WCHAR wszVersion[] = { 'V','e','r','s','i','o','n',0 };
     static const WCHAR wszCatalogFile[] = { 'C','a','t','a','l','o','g','F','i','l','e',0 };
+    unsigned int i;
     DWORD size;
     HINF hinf;
 
     TRACE("%s, %s, %d, %d, %p, %d, %p, %p\n", debugstr_w(source), debugstr_w(location),
-          media_type, style, dest, buffer_size, required_size, component);
+          media_type, style, dest, buffer_size, required_size, filepart);
 
     if (!source)
     {
@@ -934,65 +991,35 @@ BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location,
         return FALSE;
     }
 
-    if (!GetWindowsDirectoryW( target, ARRAY_SIZE( target ))) return FALSE;
-
-    strcatW( target, inf );
-    if ((p = strrchrW( source, '\\' )))
-        strcatW( target, p + 1 );
-
-    /* does the file exist already? */
-    if ((GetFileAttributesW( target ) != INVALID_FILE_ATTRIBUTES) &&
-        !(style & SP_COPY_NOOVERWRITE))
-    {
-        static const WCHAR oem[] = { 'o','e','m',0 };
-        unsigned int i;
-        LARGE_INTEGER source_file_size;
-        HANDLE source_file;
-
-        source_file = CreateFileW( source, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
-                                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                                   NULL, OPEN_EXISTING, 0, NULL );
-        if (source_file == INVALID_HANDLE_VALUE)
-            return FALSE;
-
-        if (!GetFileSizeEx( source_file, &source_file_size ))
+    if (find_existing_inf( source, target ))
+    {
+        TRACE("Found existing INF %s.\n", debugstr_w(target));
+        if (style & SP_COPY_NOOVERWRITE)
         {
-            CloseHandle( source_file );
-            return FALSE;
+            SetLastError( ERROR_FILE_EXISTS );
+            ret = FALSE;
         }
+        else
+            ret = TRUE;
+        goto done;
+    }
 
-        p = strrchrW( target, '\\' ) + 1;
-        memcpy( p, oem, sizeof(oem) );
-        p += ARRAY_SIZE( oem ) - 1;
-
-        /* generate OEMnnn.inf ending */
+    GetWindowsDirectoryW( target, ARRAY_SIZE(target) );
+    strcatW( target, inf );
+    strcatW( target, strrchrW( source, '\\' ) + 1 );
+    if (GetFileAttributesW( target ) != INVALID_FILE_ATTRIBUTES)
+    {
         for (i = 0; i < OEM_INDEX_LIMIT; i++)
         {
-            static const WCHAR format[] = { '%','u','.','i','n','f',0 };
-            HANDLE dest_file;
-            LARGE_INTEGER dest_file_size;
+            static const WCHAR formatW[] = {'o','e','m','%','u','.','i','n','f',0};
 
-            wsprintfW( p, format, i );
-            dest_file = CreateFileW( target, FILE_READ_DATA | FILE_READ_ATTRIBUTES,
-                                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                                     NULL, OPEN_EXISTING, 0, NULL );
-            /* if we found a file name that doesn't exist then we're done */
-            if (dest_file == INVALID_HANDLE_VALUE)
+            GetWindowsDirectoryW( target, ARRAY_SIZE(target) );
+            strcatW( target, inf );
+            sprintfW( target + strlenW(target), formatW, i );
+
+            if (GetFileAttributesW( target ) == INVALID_FILE_ATTRIBUTES)
                 break;
-            /* now check if the same inf file has already been copied to the inf
-             * directory. if so, use that file and don't create a new one */
-            if (!GetFileSizeEx( dest_file, &dest_file_size ) ||
-                (dest_file_size.QuadPart != source_file_size.QuadPart) ||
-                compare_files( source_file, dest_file ))
-            {
-                CloseHandle( dest_file );
-                continue;
-            }
-            CloseHandle( dest_file );
-            break;
         }
-
-        CloseHandle( source_file );
         if (i == OEM_INDEX_LIMIT)
         {
             SetLastError( ERROR_FILENAME_EXCED_RANGE );
@@ -1040,9 +1067,10 @@ BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location,
     else
         SetupCloseInfFile( hinf );
 
-    if (!(ret = CopyFileW( source, target, (style & SP_COPY_NOOVERWRITE) != 0 )))
+    if (!(ret = CopyFileW( source, target, TRUE )))
         return ret;
 
+done:
     if (style & SP_COPY_DELETESOURCE)
         DeleteFileW( source );
 
@@ -1060,7 +1088,7 @@ BOOL WINAPI SetupCopyOEMInfW( PCWSTR source, PCWSTR location,
         }
     }
 
-    if (component) *component = p + 1;
+    if (filepart) *filepart = strrchrW( target, '\\' ) + 1;
     if (required_size) *required_size = size;
     if (ret) SetLastError(ERROR_SUCCESS);
 
diff --git a/dlls/setupapi/tests/misc.c b/dlls/setupapi/tests/misc.c
index 157edd82a7c..e2dd12fa3f6 100644
--- a/dlls/setupapi/tests/misc.c
+++ b/dlls/setupapi/tests/misc.c
@@ -119,7 +119,6 @@ static void test_original_file_name(LPCSTR original, LPCSTR dest)
     res = pSetupQueryInfOriginalFileInformationA(pspii, 0, NULL, &spofi);
     ok(res, "SetupQueryInfOriginalFileInformationA failed with error %d\n", GetLastError());
     ok(!spofi.OriginalCatalogName[0], "spofi.OriginalCatalogName should have been \"\" instead of \"%s\"\n", spofi.OriginalCatalogName);
-    todo_wine
     ok(!strcmp(original, spofi.OriginalInfName), "spofi.OriginalInfName of %s didn't match real original name %s\n", spofi.OriginalInfName, original);
 
     HeapFree(GetProcessHeap(), 0, pspii);
@@ -230,7 +229,6 @@ static void test_SetupCopyOEMInf(void)
     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
     ok(file_exists(path), "Expected source inf to exist.\n");
     ok(file_exists(dest), "Expected dest file to exist.\n");
-todo_wine
     ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest);
 
     /* try SP_COPY_REPLACEONLY, dest exists */
@@ -240,7 +238,6 @@ todo_wine
     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
     ok(file_exists(path), "Expected source inf to exist.\n");
     ok(file_exists(dest), "Expected dest file to exist.\n");
-todo_wine
     ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest);
 
     strcpy(dest, "aaa");
@@ -269,14 +266,12 @@ todo_wine
     ok(file_exists(path), "Expected source inf to exist\n");
     ok(file_exists(orig_dest), "Expected dest inf to exist\n");
     ok(!strcmp(dest, "aaa"), "Expected dest to be unchanged\n");
-todo_wine
     ok(size == strlen(orig_dest) + 1, "Expected size %d, got %d.\n", strlen(orig_dest) + 1, size);
 
     SetLastError(0xdeadbeef);
     res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), &size, NULL);
     ok(res == TRUE, "Expected TRUE, got %d\n", res);
     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
-todo_wine
     ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest);
     ok(size == strlen(dest) + 1, "Expected size %d, got %d.\n", strlen(dest) + 1, size);
 
@@ -286,7 +281,6 @@ todo_wine
     res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, &filepart);
     ok(res == TRUE, "Expected TRUE, got %d\n", res);
     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
-todo_wine
     ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest);
     ok(filepart == strrchr(dest, '\\') + 1, "Got unexpected file part %s.\n", filepart);
 
@@ -341,13 +335,11 @@ todo_wine
     strcat(orig_dest, "\\inf\\");
     strcat(orig_dest, tmpfile);
     res = CopyFileA(tmpfile, orig_dest, TRUE);
-todo_wine
     ok(res, "Failed to copy file, error %u.\n", GetLastError());
     SetLastError(0xdeadbeef);
     res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL);
     ok(res == TRUE, "Expected TRUE, got %d\n", res);
     ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
-todo_wine
     ok(!strcasecmp(dest, orig_dest), "Expected '%s', got '%s'.\n", orig_dest, dest);
 
     /* Since it wasn't actually installed, SetupUninstallOEMInf would fail here. */
-- 
2.21.0




More information about the wine-devel mailing list