setupapi: Check all INF files in SetupCopyOEMInf().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
097e224af7
commit
29f65bc6a2
|
@ -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))
|
||||
if (find_existing_inf( source, target ))
|
||||
{
|
||||
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 ))
|
||||
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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue