From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 15 --------------- 1 file changed, 15 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 36983e2c8b8..284e792e729 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1315,7 +1315,6 @@ static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) { SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)}; SIP_INDIRECT_DATA *indirect_data; - const WCHAR *filepart = file; CRYPTCATMEMBER *member; WCHAR hash_buffer[100]; GUID subject_guid; @@ -1330,7 +1329,6 @@ static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) subject_info.pgSubjectType = &subject_guid; subject_info.pwsFileName = file; subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1; - subject_info.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG | SPC_EXC_PE_PAGE_HASHES_FLAG | 0x10000; ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL); todo_wine ok(ret, "Failed to get indirect data size, error %lu\n", GetLastError());
@@ -1346,19 +1344,6 @@ static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) member = CryptCATPutMemberInfo(catalog, (WCHAR *)file, hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data); ok(!!member, "Failed to write member, error %lu\n", GetLastError()); - - if (wcsrchr(file, '\')) - filepart = wcsrchr(file, '\') + 1; - - ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"File", - CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, - (wcslen(filepart) + 1) * 2, (BYTE *)filepart); - ok(ret, "Failed to write attr, error %lu\n", GetLastError()); - - ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"OSAttr", - CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, - sizeof(L"2:6.0"), (BYTE *)L"2:6.0"); - ok(ret, "Failed to write attr, error %lu\n", GetLastError()); }
free(indirect_data);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/setupapi/tests/devinst.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 1d8df5faea1..83cfbd287c6 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -41,8 +41,8 @@ static GUID guid2 = {0x6a55b5a5, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c, static GUID iface_guid = {0xdeadbeef, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}}; static GUID iface_guid2 = {0xdeadf00d, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
-BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD); -BOOL (WINAPI *pSetupDiGetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD); +static BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, SP_DEVINFO_DATA *, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD); +static BOOL (WINAPI *pSetupDiGetDevicePropertyW)(HDEVINFO, SP_DEVINFO_DATA *, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD);
static BOOL wow64;
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/setupapi/tests/devinst.c | 286 ++++++++++++++++++++++++++++++- dlls/setupapi/tests/misc.c | 305 ---------------------------------- 2 files changed, 284 insertions(+), 307 deletions(-)
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 83cfbd287c6..8b9346c3826 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -43,6 +43,7 @@ static GUID iface_guid2 = {0xdeadf00d, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95
static BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, SP_DEVINFO_DATA *, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD); static BOOL (WINAPI *pSetupDiGetDevicePropertyW)(HDEVINFO, SP_DEVINFO_DATA *, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD); +static BOOL (WINAPI *pSetupQueryInfOriginalFileInformationA)(SP_INF_INFORMATION *, UINT, SP_ALTPLATFORM_INFO *, SP_ORIGINAL_FILE_INFO_A *);
static BOOL wow64;
@@ -2106,7 +2107,7 @@ static void test_device_interface_key(void) ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL); - ok(dikey != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); + ok(dikey != INVALID_HANDLE_VALUE, "Got error %#lx\n", GetLastError());
ret = RegOpenKeyA(parent, "#\Device Parameters", &key); ok(!ret, "key should exist: %lu\n", ret); @@ -2122,7 +2123,7 @@ static void test_device_interface_key(void) RegCloseKey(key);
ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0); - ok(ret, "got error %lu\n", GetLastError()); + ok(ret, "Got error %#lx\n", GetLastError());
ret = RegOpenKeyA(parent, "#\Device Parameters", &key); ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n"); @@ -3407,12 +3408,293 @@ todo_wine { SetupDiDestroyDeviceInfoList(set); }
+static BOOL file_exists(const char *path) +{ + return GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES; +} + +static BOOL is_in_inf_dir(const char *path) +{ + char expect[MAX_PATH]; + + GetWindowsDirectoryA(expect, sizeof(expect)); + strcat(expect, "\inf\"); + return !strncasecmp(path, expect, strrchr(path, '\') - path); +} + +static void test_original_file_name(const char *original, const char *dest) +{ + SP_ORIGINAL_FILE_INFO_A orig_info; + SP_INF_INFORMATION *inf_info; + DWORD size; + HINF hinf; + BOOL res; + + if (!pSetupQueryInfOriginalFileInformationA) + { + win_skip("SetupQueryInfOriginalFileInformationA is not available\n"); + return; + } + + hinf = SetupOpenInfFileA(dest, NULL, INF_STYLE_WIN4, NULL); + ok(hinf != NULL, "Failed to open INF file, error %lu.\n", GetLastError()); + + res = SetupGetInfInformationA(hinf, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &size); + ok(res, "Failed to get INF information, error %lu.\n", GetLastError()); + + inf_info = malloc(size); + + res = SetupGetInfInformationA(hinf, INFINFO_INF_SPEC_IS_HINF, inf_info, size, NULL); + ok(res, "Failed to get INF information, error %lu.\n", GetLastError()); + + orig_info.cbSize = 0; + SetLastError(0xdeadbeef); + res = pSetupQueryInfOriginalFileInformationA(inf_info, 0, NULL, &orig_info); + ok(!res, "Got %d.\n", res); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got error %#lx.\n", GetLastError()); + + orig_info.cbSize = sizeof(orig_info); + SetLastError(0xdeadbeef); + res = pSetupQueryInfOriginalFileInformationA(inf_info, 0, NULL, &orig_info); + ok(res == TRUE, "Got %d.\n", res); + todo_wine ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(!orig_info.OriginalCatalogName[0], "Got original catalog name %s.\n", + debugstr_a(orig_info.OriginalCatalogName)); + ok(!strcmp(original, orig_info.OriginalInfName), "Expected orignal inf name %s, got %s.\n", + debugstr_a(original), debugstr_a(orig_info.OriginalInfName)); + + free(inf_info); + + SetupCloseInfFile(hinf); +} + +static void test_copy_oem_inf(void) +{ + char path[MAX_PATH * 2], dest[MAX_PATH], tmpfile[MAX_PATH], orig_dest[MAX_PATH]; + char *filepart, pnf[MAX_PATH]; + DWORD size; + BOOL ret; + + static const char inf_data1[] = + "[Version]\n" + "Signature="$Chicago$"\n" + "; This is a WINE test INF file\n"; + + static const char inf_data2[] = + "[Version]\n" + "Signature="$Chicago$"\n" + "; This is another WINE test INF file\n"; + + /* try NULL SourceInfFileName */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(NULL, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got error %#lx.\n", GetLastError()); + + /* try empty SourceInfFileName */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA("", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_FILE_NOT_FOUND + || GetLastError() == ERROR_INVALID_PARAMETER /* vista, 2k8 */, "Got error %#lx.\n", GetLastError()); + + /* try a relative nonexistent SourceInfFileName */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA("nonexistent", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); + + /* try an absolute nonexistent SourceInfFileName */ + GetCurrentDirectoryA(sizeof(path), path); + strcat(path, "\nonexistent"); + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); + + get_temp_filename(tmpfile); + create_file(tmpfile, inf_data1); + + /* try a relative SourceInfFileName */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(tmpfile, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); + ok(!ret, "Got %d.\n", ret); + if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */) + { + /* FIXME: + * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some + * popups during the installation though as it also needs a catalog file (signed?). + */ + win_skip("Needs a different inf file on Vista+.\n"); + ret = DeleteFileA(tmpfile); + ok(ret, "Failed to delete %s, error %#lx.\n", debugstr_a(tmpfile), GetLastError()); + return; + } + + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); + ok(file_exists(tmpfile), "Expected source inf to exist.\n"); + + /* try SP_COPY_REPLACEONLY, dest does not exist */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); + ok(file_exists(tmpfile), "Expected source inf to exist.\n"); + + /* Test a successful call. */ + GetCurrentDirectoryA(sizeof(path), path); + strcat(path, "\"); + strcat(path, tmpfile); + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Not enough permissions to copy INF.\n"); + DeleteFileA(tmpfile); + return; + } + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(file_exists(path), "Expected source inf to exist.\n"); + ok(file_exists(dest), "Expected dest file to exist.\n"); + ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); + strcpy(orig_dest, dest); + + /* Existing INF files are checked for a match. */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(file_exists(path), "Expected source inf to exist.\n"); + ok(file_exists(dest), "Expected dest file to exist.\n"); + ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); + + /* try SP_COPY_REPLACEONLY, dest exists */ + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, dest, sizeof(dest), NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(file_exists(path), "Expected source inf to exist.\n"); + ok(file_exists(dest), "Expected dest file to exist.\n"); + ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); + + strcpy(dest, "aaa"); + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_NOOVERWRITE, dest, sizeof(dest), NULL, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_FILE_EXISTS, "Got error %#lx.\n", GetLastError()); + ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); + + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, NULL, 0, NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(file_exists(path), "Expected source inf to exist.\n"); + ok(file_exists(orig_dest), "Expected dest file to exist.\n"); + + strcpy(dest, "aaa"); + size = 0; + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, 5, &size, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got error %#lx.\n", GetLastError()); + 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"); + ok(size == strlen(orig_dest) + 1, "Got %ld.\n", size); + + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), &size, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); + ok(size == strlen(dest) + 1, "Got %ld.\n", size); + + test_original_file_name(strrchr(path, '\') + 1, dest); + + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, &filepart); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + 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); + + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_DELETESOURCE, NULL, 0, NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(!file_exists(path), "Expected source inf not to exist.\n"); + + strcpy(pnf, dest); + *(strrchr(pnf, '.') + 1) = 'p'; + + ret = SetupUninstallOEMInfA(strrchr(dest, '\') + 1, 0, NULL); + ok(ret, "Failed to uninstall '%s', error %#lx.\n", dest, GetLastError()); + todo_wine ok(!file_exists(dest), "Expected inf '%s' not to exist.\n", dest); + DeleteFileA(dest); + ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf); + + create_file(tmpfile, inf_data1); + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); + strcpy(orig_dest, dest); + + create_file(tmpfile, inf_data2); + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); + ok(strcmp(dest, orig_dest), "Expected INF files to be copied to different paths.\n"); + + ret = SetupUninstallOEMInfA(strrchr(dest, '\') + 1, 0, NULL); + ok(ret, "Failed to uninstall '%s', error %#lx.\n", dest, GetLastError()); + todo_wine ok(!file_exists(dest), "Expected inf '%s' not to exist.\n", dest); + DeleteFileA(dest); + strcpy(pnf, dest); + *(strrchr(pnf, '.') + 1) = 'p'; + todo_wine ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf); + + ret = SetupUninstallOEMInfA(strrchr(orig_dest, '\') + 1, 0, NULL); + ok(ret, "Failed to uninstall '%s', error %#lx.\n", orig_dest, GetLastError()); + todo_wine ok(!file_exists(orig_dest), "Expected inf '%s' not to exist.\n", dest); + DeleteFileA(orig_dest); + strcpy(pnf, dest); + *(strrchr(pnf, '.') + 1) = 'p'; + todo_wine ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf); + + GetWindowsDirectoryA(orig_dest, sizeof(orig_dest)); + strcat(orig_dest, "\inf\"); + strcat(orig_dest, tmpfile); + ret = CopyFileA(tmpfile, orig_dest, TRUE); + ok(ret, "Failed to copy file, error %#lx.\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(!strcasecmp(dest, orig_dest), "Expected '%s', got '%s'.\n", orig_dest, dest); + + /* Since it wasn't actually installed, SetupUninstallOEMInf would fail here. */ + ret = DeleteFileA(dest); + ok(ret, "Failed to delete '%s', error %#lx.\n", tmpfile, GetLastError()); + + ret = DeleteFileA(tmpfile); + ok(ret, "Failed to delete '%s', error %#lx.\n", tmpfile, GetLastError()); +} + START_TEST(devinst) { static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); + HMODULE module = GetModuleHandleA("setupapi.dll"); HKEY hkey;
+ pSetupQueryInfOriginalFileInformationA = (void *)GetProcAddress(module, "SetupQueryInfOriginalFileInformationA"); + test_get_actual_section(); + test_copy_oem_inf();
if ((hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS)) == INVALID_HANDLE_VALUE) { diff --git a/dlls/setupapi/tests/misc.c b/dlls/setupapi/tests/misc.c index 6fda69f9e39..adace3324de 100644 --- a/dlls/setupapi/tests/misc.c +++ b/dlls/setupapi/tests/misc.c @@ -49,309 +49,6 @@ static CHAR CURR_DIR[MAX_PATH];
static void (WINAPI *pMyFree)(void*); static BOOL (WINAPI *pSetupGetFileCompressionInfoExA)(PCSTR, PSTR, DWORD, PDWORD, PDWORD, PDWORD, PUINT); -static BOOL (WINAPI *pSetupQueryInfOriginalFileInformationA)(PSP_INF_INFORMATION, UINT, PSP_ALTPLATFORM_INFO, PSP_ORIGINAL_FILE_INFO_A); - -static void create_file(const char *name, const char *data) -{ - HANDLE file; - DWORD size; - BOOL ret; - - file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - ok(file != INVALID_HANDLE_VALUE, "Failed to create %s, error %lu.\n", name, GetLastError()); - ret = WriteFile(file, data, strlen(data), &size, NULL); - ok(ret && size == strlen(data), "Failed to write %s, error %lu.\n", name, GetLastError()); - CloseHandle(file); -} - -static void get_temp_filename(LPSTR path) -{ - CHAR temp[MAX_PATH]; - LPSTR ptr; - - GetTempFileNameA(CURR_DIR, "set", 0, temp); - ptr = strrchr(temp, '\'); - - strcpy(path, ptr + 1); -} - -static BOOL file_exists(LPSTR path) -{ - return GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES; -} - -static BOOL is_in_inf_dir(const char *path) -{ - char expect[MAX_PATH]; - - GetWindowsDirectoryA(expect, sizeof(expect)); - strcat(expect, "\inf\"); - return !strncasecmp(path, expect, strrchr(path, '\') - path); -} - -static void test_original_file_name(LPCSTR original, LPCSTR dest) -{ - HINF hinf; - PSP_INF_INFORMATION pspii; - SP_ORIGINAL_FILE_INFO_A spofi; - BOOL res; - DWORD size; - - if (!pSetupQueryInfOriginalFileInformationA) - { - win_skip("SetupQueryInfOriginalFileInformationA is not available\n"); - return; - } - - hinf = SetupOpenInfFileA(dest, NULL, INF_STYLE_WIN4, NULL); - ok(hinf != NULL, "SetupOpenInfFileA failed with error %ld\n", GetLastError()); - - res = SetupGetInfInformationA(hinf, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &size); - ok(res, "SetupGetInfInformation failed with error %ld\n", GetLastError()); - - pspii = malloc(size); - - res = SetupGetInfInformationA(hinf, INFINFO_INF_SPEC_IS_HINF, pspii, size, NULL); - ok(res, "SetupGetInfInformation failed with error %ld\n", GetLastError()); - - spofi.cbSize = 0; - res = pSetupQueryInfOriginalFileInformationA(pspii, 0, NULL, &spofi); - ok(!res && GetLastError() == ERROR_INVALID_USER_BUFFER, - "SetupQueryInfOriginalFileInformationA should have failed with ERROR_INVALID_USER_BUFFER instead of %ld\n", GetLastError()); - - spofi.cbSize = sizeof(spofi); - res = pSetupQueryInfOriginalFileInformationA(pspii, 0, NULL, &spofi); - ok(res, "SetupQueryInfOriginalFileInformationA failed with error %ld\n", GetLastError()); - ok(!spofi.OriginalCatalogName[0], "spofi.OriginalCatalogName should have been "" instead of "%s"\n", spofi.OriginalCatalogName); - ok(!strcmp(original, spofi.OriginalInfName), "spofi.OriginalInfName of %s didn't match real original name %s\n", spofi.OriginalInfName, original); - - free(pspii); - - SetupCloseInfFile(hinf); -} - -static void test_SetupCopyOEMInf(void) -{ - char path[MAX_PATH * 2], dest[MAX_PATH], tmpfile[MAX_PATH], orig_dest[MAX_PATH]; - char *filepart, pnf[MAX_PATH]; - DWORD size; - BOOL res; - - static const char inf_data1[] = - "[Version]\n" - "Signature="$Chicago$"\n" - "; This is a WINE test INF file\n"; - - static const char inf_data2[] = - "[Version]\n" - "Signature="$Chicago$"\n" - "; This is another WINE test INF file\n"; - - /* try NULL SourceInfFileName */ - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(NULL, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); - - /* try empty SourceInfFileName */ - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA("", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_FILE_NOT_FOUND || - GetLastError() == ERROR_INVALID_PARAMETER, /* Vista, W2K8 */ - "Unexpected error : %ld\n", GetLastError()); - - /* try a relative nonexistent SourceInfFileName */ - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA("nonexistent", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError()); - - /* try an absolute nonexistent SourceInfFileName */ - strcpy(path, CURR_DIR); - strcat(path, "\nonexistent"); - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError()); - - get_temp_filename(tmpfile); - create_file(tmpfile, inf_data1); - - /* try a relative SourceInfFileName */ - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(tmpfile, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */) - { - /* FIXME: - * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some - * popups during the installation though as it also needs a catalog file (signed?). - */ - win_skip("Needs a different inf file on Vista+\n"); - DeleteFileA(tmpfile); - return; - } - - ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError()); - ok(file_exists(tmpfile), "Expected tmpfile to exist\n"); - - /* try SP_COPY_REPLACEONLY, dest does not exist */ - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError()); - ok(file_exists(tmpfile), "Expected source inf to exist\n"); - - /* Test a successful call. */ - strcpy(path, CURR_DIR); - strcat(path, "\"); - strcat(path, tmpfile); - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); - if (!res && GetLastError() == ERROR_ACCESS_DENIED) - { - skip("SetupCopyOEMInfA() failed on insufficient permissions\n"); - DeleteFileA(tmpfile); - return; - } - ok(res == TRUE, "Expected TRUE, got %d\n", res); - ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); - ok(file_exists(path), "Expected source inf to exist.\n"); - ok(file_exists(dest), "Expected dest file to exist.\n"); - ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); - strcpy(orig_dest, dest); - - /* Existing INF files are checked for a match. */ - 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 %ld\n", GetLastError()); - ok(file_exists(path), "Expected source inf to exist.\n"); - ok(file_exists(dest), "Expected dest file to exist.\n"); - ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); - - /* try SP_COPY_REPLACEONLY, dest exists */ - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, dest, sizeof(dest), NULL, NULL); - ok(res == TRUE, "Expected TRUE, got %d\n", res); - ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); - ok(file_exists(path), "Expected source inf to exist.\n"); - ok(file_exists(dest), "Expected dest file to exist.\n"); - ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); - - strcpy(dest, "aaa"); - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_NOOVERWRITE, dest, sizeof(dest), NULL, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_FILE_EXISTS, - "Expected ERROR_FILE_EXISTS, got %ld\n", GetLastError()); - ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); - - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, NULL, 0, NULL, NULL); - ok(res == TRUE, "Expected TRUE, got %d\n", res); - ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); - ok(file_exists(path), "Expected source inf to exist.\n"); - ok(file_exists(orig_dest), "Expected dest file to exist.\n"); - - strcpy(dest, "aaa"); - size = 0; - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, 5, &size, NULL); - ok(res == FALSE, "Expected FALSE, got %d\n", res); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, - "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); - 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"); - ok(size == strlen(orig_dest) + 1, "Got %ld.\n", 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 %ld\n", GetLastError()); - ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); - ok(size == strlen(dest) + 1, "Got %ld.\n", size); - - test_original_file_name(strrchr(path, '\') + 1, dest); - - SetLastError(0xdeadbeef); - 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 %ld\n", GetLastError()); - 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); - - SetLastError(0xdeadbeef); - res = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_DELETESOURCE, NULL, 0, NULL, NULL); - ok(res == TRUE, "Expected TRUE, got %d\n", res); - ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError()); - ok(!file_exists(path), "Expected source inf to not exist\n"); - - strcpy(pnf, dest); - *(strrchr(pnf, '.') + 1) = 'p'; - - res = SetupUninstallOEMInfA(strrchr(dest, '\') + 1, 0, NULL); - ok(res, "Failed to uninstall '%s', error %lu.\n", dest, GetLastError()); - todo_wine ok(!file_exists(dest), "Expected inf '%s' to not exist\n", dest); - DeleteFileA(dest); - ok(!file_exists(pnf), "Expected pnf '%s' to not exist\n", pnf); - - create_file(tmpfile, inf_data1); - 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 %ld\n", GetLastError()); - ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); - strcpy(orig_dest, dest); - - create_file(tmpfile, inf_data2); - 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 %ld\n", GetLastError()); - ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); - ok(strcmp(dest, orig_dest), "Expected INF files to be copied to different paths.\n"); - - res = SetupUninstallOEMInfA(strrchr(dest, '\') + 1, 0, NULL); - ok(res, "Failed to uninstall '%s', error %lu.\n", dest, GetLastError()); - todo_wine ok(!file_exists(dest), "Expected inf '%s' to not exist\n", dest); - DeleteFileA(dest); - strcpy(pnf, dest); - *(strrchr(pnf, '.') + 1) = 'p'; - todo_wine ok(!file_exists(pnf), "Expected pnf '%s' to not exist\n", pnf); - - res = SetupUninstallOEMInfA(strrchr(orig_dest, '\') + 1, 0, NULL); - ok(res, "Failed to uninstall '%s', error %lu.\n", orig_dest, GetLastError()); - todo_wine ok(!file_exists(orig_dest), "Expected inf '%s' to not exist\n", dest); - DeleteFileA(orig_dest); - strcpy(pnf, dest); - *(strrchr(pnf, '.') + 1) = 'p'; - todo_wine ok(!file_exists(pnf), "Expected pnf '%s' to not exist\n", pnf); - - GetWindowsDirectoryA(orig_dest, sizeof(orig_dest)); - strcat(orig_dest, "\inf\"); - strcat(orig_dest, tmpfile); - res = CopyFileA(tmpfile, orig_dest, TRUE); - ok(res, "Failed to copy file, error %lu.\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 %ld\n", GetLastError()); - ok(!strcasecmp(dest, orig_dest), "Expected '%s', got '%s'.\n", orig_dest, dest); - - /* Since it wasn't actually installed, SetupUninstallOEMInf would fail here. */ - res = DeleteFileA(dest); - ok(res, "Failed to delete '%s', error %lu.\n", tmpfile, GetLastError()); - - res = DeleteFileA(tmpfile); - ok(res, "Failed to delete '%s', error %lu.\n", tmpfile, GetLastError()); -}
static void create_source_file(LPSTR filename, const BYTE *data, DWORD size) { @@ -910,11 +607,9 @@ START_TEST(misc)
pMyFree = (void*)GetProcAddress(hsetupapi, "MyFree"); pSetupGetFileCompressionInfoExA = (void*)GetProcAddress(hsetupapi, "SetupGetFileCompressionInfoExA"); - pSetupQueryInfOriginalFileInformationA = (void*)GetProcAddress(hsetupapi, "SetupQueryInfOriginalFileInformationA");
GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
- test_SetupCopyOEMInf(); test_SetupGetFileCompressionInfo();
if (pSetupGetFileCompressionInfoExA)
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/setupapi/tests/devinst.c | 51 ++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 8b9346c3826..ec7a3e28387 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -3470,8 +3470,8 @@ static void test_original_file_name(const char *original, const char *dest)
static void test_copy_oem_inf(void) { - char path[MAX_PATH * 2], dest[MAX_PATH], tmpfile[MAX_PATH], orig_dest[MAX_PATH]; - char *filepart, pnf[MAX_PATH]; + char path[MAX_PATH * 2], dest[MAX_PATH], orig_dest[MAX_PATH]; + char orig_cwd[MAX_PATH], *cwd, *filepart, pnf[MAX_PATH]; DWORD size; BOOL ret;
@@ -3485,6 +3485,13 @@ static void test_copy_oem_inf(void) "Signature="$Chicago$"\n" "; This is another WINE test INF file\n";
+ GetCurrentDirectoryA(sizeof(orig_cwd), orig_cwd); + cwd = tempnam(NULL, "wine"); + ret = CreateDirectoryA(cwd, NULL); + ok(ret, "Failed to create %s, error %#lx.\n", debugstr_a(cwd), GetLastError()); + ret = SetCurrentDirectoryA(cwd); + ok(ret, "Failed to cd to %s, error %#lx.\n", debugstr_a(cwd), GetLastError()); + /* try NULL SourceInfFileName */ SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(NULL, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); @@ -3512,12 +3519,11 @@ static void test_copy_oem_inf(void) ok(!ret, "Got %d.\n", ret); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError());
- get_temp_filename(tmpfile); - create_file(tmpfile, inf_data1); + create_file("winetest.inf", inf_data1);
/* try a relative SourceInfFileName */ SetLastError(0xdeadbeef); - ret = SetupCopyOEMInfA(tmpfile, NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); + ret = SetupCopyOEMInfA("winetest.inf", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); ok(!ret, "Got %d.\n", ret); if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */) { @@ -3526,32 +3532,28 @@ static void test_copy_oem_inf(void) * popups during the installation though as it also needs a catalog file (signed?). */ win_skip("Needs a different inf file on Vista+.\n"); - ret = DeleteFileA(tmpfile); - ok(ret, "Failed to delete %s, error %#lx.\n", debugstr_a(tmpfile), GetLastError()); - return; + goto out; }
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); - ok(file_exists(tmpfile), "Expected source inf to exist.\n"); + ok(file_exists("winetest.inf"), "Expected source inf to exist.\n");
/* try SP_COPY_REPLACEONLY, dest does not exist */ SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL); ok(!ret, "Got %d.\n", ret); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); - ok(file_exists(tmpfile), "Expected source inf to exist.\n"); + ok(file_exists("winetest.inf"), "Expected source inf to exist.\n");
/* Test a successful call. */ GetCurrentDirectoryA(sizeof(path), path); - strcat(path, "\"); - strcat(path, tmpfile); + strcat(path, "\winetest.inf"); SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { skip("Not enough permissions to copy INF.\n"); - DeleteFileA(tmpfile); - return; + goto out; } ok(ret == TRUE, "Got %d.\n", ret); ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); @@ -3634,7 +3636,7 @@ static void test_copy_oem_inf(void) DeleteFileA(dest); ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf);
- create_file(tmpfile, inf_data1); + create_file("winetest.inf", inf_data1); SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); ok(ret == TRUE, "Got %d.\n", ret); @@ -3642,7 +3644,7 @@ static void test_copy_oem_inf(void) ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); strcpy(orig_dest, dest);
- create_file(tmpfile, inf_data2); + create_file("winetest.inf", inf_data2); SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); ok(ret == TRUE, "Got %d.\n", ret); @@ -3667,9 +3669,8 @@ static void test_copy_oem_inf(void) todo_wine ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf);
GetWindowsDirectoryA(orig_dest, sizeof(orig_dest)); - strcat(orig_dest, "\inf\"); - strcat(orig_dest, tmpfile); - ret = CopyFileA(tmpfile, orig_dest, TRUE); + strcat(orig_dest, "\inf\winetest.inf"); + ret = CopyFileA("winetest.inf", orig_dest, TRUE); ok(ret, "Failed to copy file, error %#lx.\n", GetLastError()); SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); @@ -3679,10 +3680,16 @@ static void test_copy_oem_inf(void)
/* Since it wasn't actually installed, SetupUninstallOEMInf would fail here. */ ret = DeleteFileA(dest); - ok(ret, "Failed to delete '%s', error %#lx.\n", tmpfile, GetLastError()); + ok(ret, "Failed to delete %s, error %#lx.\n", debugstr_a(dest), GetLastError()); + +out: + ret = DeleteFileA("winetest.inf"); + ok(ret, "Failed to delete winetest.inf, error %#lx.\n", GetLastError()); + + SetCurrentDirectoryA(orig_cwd); + ret = RemoveDirectoryA(cwd); + ok(ret, "Failed to delete %s, error %#lx.\n", cwd, GetLastError());
- ret = DeleteFileA(tmpfile); - ok(ret, "Failed to delete '%s', error %#lx.\n", tmpfile, GetLastError()); }
START_TEST(devinst)
From: Zebediah Figura zfigura@codeweavers.com
Alter the test a little to account for the behaviour of newer Windows. --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 11 +- dlls/setupapi/tests/Makefile.in | 2 +- dlls/setupapi/tests/devinst.c | 390 +++++++++++++++++++++++++---- 3 files changed, 352 insertions(+), 51 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 284e792e729..48deda7c455 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -59,9 +59,6 @@ static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *); static BOOL (WINAPI *pCancelIoEx)(HANDLE, OVERLAPPED *); static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR); -static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert, - SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, - const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data);
static void load_resource(const WCHAR *name, WCHAR *filename) { @@ -249,6 +246,10 @@ static void testsign_cleanup(struct testsign_context *ctx)
static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename) { + static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert, + SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, + const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data); + SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)}; SIGNER_SIGNATURE_INFO signature = {sizeof(signature)}; SIGNER_SUBJECT_INFO subject = {sizeof(subject)}; @@ -258,6 +259,9 @@ static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename) DWORD index = 0; HRESULT hr;
+ if (!pSignerSign) + pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign"); + subject.dwSubjectChoice = 1; subject.pdwIndex = &index; subject.pSignerFileInfo = &file; @@ -1890,7 +1894,6 @@ START_TEST(ntoskrnl) pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetFileCompletionNotificationModes"); - pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) { diff --git a/dlls/setupapi/tests/Makefile.in b/dlls/setupapi/tests/Makefile.in index 85be56de556..0c9ab9af3a9 100644 --- a/dlls/setupapi/tests/Makefile.in +++ b/dlls/setupapi/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = setupapi.dll -IMPORTS = advapi32 cabinet ole32 setupapi shell32 uuid user32 +IMPORTS = advapi32 cabinet crypt32 ole32 setupapi shell32 uuid user32 wintrust
selfreg_IMPORTS = uuid advapi32 ole32
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index ec7a3e28387..194fa50f6d0 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -20,12 +20,17 @@
#include <stdarg.h> #include <stdio.h> +#include <time.h>
#include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winnls.h" #include "winuser.h" #include "winreg.h" +#include "ntsecapi.h" +#include "wincrypt.h" +#include "mscat.h" #include "devguid.h" #include "initguid.h" #include "devpkey.h" @@ -34,6 +39,7 @@ #include "cguid.h"
#include "wine/test.h" +#include "wine/mssign.h"
/* This is a unique guid for testing purposes */ static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}}; @@ -78,6 +84,241 @@ static void load_resource(const char *name, const char *filename) CloseHandle( file ); }
+struct testsign_context +{ + HCRYPTPROV provider; + const CERT_CONTEXT *cert, *root_cert, *publisher_cert; + HCERTSTORE root_store, publisher_store; +}; + +static BOOL testsign_create_cert(struct testsign_context *ctx) +{ + BYTE encoded_name[100], encoded_key_id[200], public_key_info_buffer[1000]; + WCHAR container_name[26]; + BYTE hash_buffer[16], cert_buffer[1000], provider_nameA[100], serial[16]; + CERT_PUBLIC_KEY_INFO *public_key_info = (CERT_PUBLIC_KEY_INFO *)public_key_info_buffer; + CRYPT_KEY_PROV_INFO provider_info = {0}; + CRYPT_ALGORITHM_IDENTIFIER algid = {0}; + CERT_AUTHORITY_KEY_ID_INFO key_info; + CERT_INFO cert_info = {0}; + WCHAR provider_nameW[100]; + CERT_EXTENSION extension; + HCRYPTKEY key; + DWORD size; + BOOL ret; + + memset(ctx, 0, sizeof(*ctx)); + + srand(time(NULL)); + swprintf(container_name, ARRAY_SIZE(container_name), L"wine_testsign%u", rand()); + + ret = CryptAcquireContextW(&ctx->provider, container_name, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET); + ok(ret, "Failed to create container, error %#lx\n", GetLastError()); + + ret = CryptGenKey(ctx->provider, AT_SIGNATURE, CRYPT_EXPORTABLE, &key); + ok(ret, "Failed to create key, error %#lx\n", GetLastError()); + ret = CryptDestroyKey(key); + ok(ret, "Failed to destroy key, error %#lx\n", GetLastError()); + ret = CryptGetUserKey(ctx->provider, AT_SIGNATURE, &key); + ok(ret, "Failed to get user key, error %#lx\n", GetLastError()); + ret = CryptDestroyKey(key); + ok(ret, "Failed to destroy key, error %#lx\n", GetLastError()); + + size = sizeof(encoded_name); + ret = CertStrToNameA(X509_ASN_ENCODING, "CN=winetest_cert", CERT_X500_NAME_STR, NULL, encoded_name, &size, NULL); + ok(ret, "Failed to convert name, error %#lx\n", GetLastError()); + key_info.CertIssuer.cbData = size; + key_info.CertIssuer.pbData = encoded_name; + + size = sizeof(public_key_info_buffer); + ret = CryptExportPublicKeyInfo(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, public_key_info, &size); + ok(ret, "Failed to export public key, error %#lx\n", GetLastError()); + cert_info.SubjectPublicKeyInfo = *public_key_info; + + size = sizeof(hash_buffer); + ret = CryptHashPublicKeyInfo(ctx->provider, CALG_MD5, 0, X509_ASN_ENCODING, public_key_info, hash_buffer, &size); + ok(ret, "Failed to hash public key, error %#lx\n", GetLastError()); + + key_info.KeyId.cbData = size; + key_info.KeyId.pbData = hash_buffer; + + RtlGenRandom(serial, sizeof(serial)); + key_info.CertSerialNumber.cbData = sizeof(serial); + key_info.CertSerialNumber.pbData = serial; + + size = sizeof(encoded_key_id); + ret = CryptEncodeObject(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID, &key_info, encoded_key_id, &size); + ok(ret, "Failed to convert name, error %#lx\n", GetLastError()); + + extension.pszObjId = (char *)szOID_AUTHORITY_KEY_IDENTIFIER; + extension.fCritical = TRUE; + extension.Value.cbData = size; + extension.Value.pbData = encoded_key_id; + + cert_info.dwVersion = CERT_V3; + cert_info.SerialNumber = key_info.CertSerialNumber; + cert_info.SignatureAlgorithm.pszObjId = (char *)szOID_RSA_SHA1RSA; + cert_info.Issuer = key_info.CertIssuer; + GetSystemTimeAsFileTime(&cert_info.NotBefore); + GetSystemTimeAsFileTime(&cert_info.NotAfter); + cert_info.NotAfter.dwHighDateTime += 1; + cert_info.Subject = key_info.CertIssuer; + cert_info.cExtension = 1; + cert_info.rgExtension = &extension; + algid.pszObjId = (char *)szOID_RSA_SHA1RSA; + size = sizeof(cert_buffer); + ret = CryptSignAndEncodeCertificate(ctx->provider, AT_SIGNATURE, X509_ASN_ENCODING, + X509_CERT_TO_BE_SIGNED, &cert_info, &algid, NULL, cert_buffer, &size); + ok(ret, "Failed to create certificate, error %#lx\n", GetLastError()); + + ctx->cert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_buffer, size); + ok(!!ctx->cert, "Failed to create context, error %#lx\n", GetLastError()); + + size = sizeof(provider_nameA); + ret = CryptGetProvParam(ctx->provider, PP_NAME, provider_nameA, &size, 0); + ok(ret, "Failed to get prov param, error %#lx\n", GetLastError()); + MultiByteToWideChar(CP_ACP, 0, (char *)provider_nameA, -1, provider_nameW, ARRAY_SIZE(provider_nameW)); + + provider_info.pwszContainerName = (WCHAR *)container_name; + provider_info.pwszProvName = provider_nameW; + provider_info.dwProvType = PROV_RSA_FULL; + provider_info.dwKeySpec = AT_SIGNATURE; + ret = CertSetCertificateContextProperty(ctx->cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &provider_info); + ok(ret, "Failed to set provider info, error %#lx\n", GetLastError()); + + ctx->root_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "root"); + if (!ctx->root_store && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Failed to open root store.\n"); + + ret = CertFreeCertificateContext(ctx->cert); + ok(ret, "Failed to free certificate, error %lu\n", GetLastError()); + ret = CryptReleaseContext(ctx->provider, 0); + ok(ret, "failed to release context, error %lu\n", GetLastError()); + + return FALSE; + } + ok(!!ctx->root_store, "Failed to open store, error %lu\n", GetLastError()); + ret = CertAddCertificateContextToStore(ctx->root_store, ctx->cert, CERT_STORE_ADD_ALWAYS, &ctx->root_cert); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + skip("Failed to add self-signed certificate to store.\n"); + + ret = CertFreeCertificateContext(ctx->cert); + ok(ret, "Failed to free certificate, error %lu\n", GetLastError()); + ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG); + ok(ret, "Failed to close store, error %lu\n", GetLastError()); + ret = CryptReleaseContext(ctx->provider, 0); + ok(ret, "failed to release context, error %lu\n", GetLastError()); + + return FALSE; + } + ok(ret, "Failed to add certificate, error %lu\n", GetLastError()); + + ctx->publisher_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_A, 0, 0, + CERT_SYSTEM_STORE_LOCAL_MACHINE, "trustedpublisher"); + ok(!!ctx->publisher_store, "Failed to open store, error %lu\n", GetLastError()); + ret = CertAddCertificateContextToStore(ctx->publisher_store, ctx->cert, + CERT_STORE_ADD_ALWAYS, &ctx->publisher_cert); + ok(ret, "Failed to add certificate, error %lu\n", GetLastError()); + + return TRUE; +} + +static void testsign_cleanup(struct testsign_context *ctx) +{ + BOOL ret; + + ret = CertFreeCertificateContext(ctx->cert); + ok(ret, "Failed to free certificate, error %lu\n", GetLastError()); + + ret = CertFreeCertificateContext(ctx->root_cert); + ok(ret, "Failed to free certificate context, error %lu\n", GetLastError()); + ret = CertCloseStore(ctx->root_store, CERT_CLOSE_STORE_CHECK_FLAG); + ok(ret, "Failed to close store, error %lu\n", GetLastError()); + + ret = CertFreeCertificateContext(ctx->publisher_cert); + ok(ret, "Failed to free certificate context, error %lu\n", GetLastError()); + ret = CertCloseStore(ctx->publisher_store, CERT_CLOSE_STORE_CHECK_FLAG); + ok(ret, "Failed to close store, error %lu\n", GetLastError()); + + ret = CryptReleaseContext(ctx->provider, 0); + ok(ret, "failed to release context, error %lu\n", GetLastError()); +} + +static void testsign_sign(struct testsign_context *ctx, const WCHAR *filename) +{ + static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert, + SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, + const WCHAR *timestamp, CRYPT_ATTRIBUTES *attr, void *sip_data); + + SIGNER_ATTR_AUTHCODE authcode = {sizeof(authcode)}; + SIGNER_SIGNATURE_INFO signature = {sizeof(signature)}; + SIGNER_SUBJECT_INFO subject = {sizeof(subject)}; + SIGNER_CERT_STORE_INFO store = {sizeof(store)}; + SIGNER_CERT cert_info = {sizeof(cert_info)}; + SIGNER_FILE_INFO file = {sizeof(file)}; + DWORD index = 0; + HRESULT hr; + + if (!pSignerSign) + pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign"); + + subject.dwSubjectChoice = 1; + subject.pdwIndex = &index; + subject.pSignerFileInfo = &file; + file.pwszFileName = (WCHAR *)filename; + cert_info.dwCertChoice = 2; + cert_info.pCertStoreInfo = &store; + store.pSigningCert = ctx->cert; + store.dwCertPolicy = 0; + signature.algidHash = CALG_SHA_256; + signature.dwAttrChoice = SIGNER_AUTHCODE_ATTR; + signature.pAttrAuthcode = &authcode; + authcode.pwszName = L""; + authcode.pwszInfo = L""; + hr = pSignerSign(&subject, &cert_info, &signature, NULL, NULL, NULL, NULL); + todo_wine ok(hr == S_OK || broken(hr == NTE_BAD_ALGID) /* < 7 */, "Failed to sign, hr %#lx\n", hr); +} + +static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) +{ + SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)}; + SIP_INDIRECT_DATA *indirect_data; + CRYPTCATMEMBER *member; + WCHAR hash_buffer[100]; + GUID subject_guid; + unsigned int i; + DWORD size; + BOOL ret; + + ret = CryptSIPRetrieveSubjectGuidForCatalogFile(file, NULL, &subject_guid); + todo_wine ok(ret, "Failed to get subject guid, error %lu\n", GetLastError()); + + size = 0; + subject_info.pgSubjectType = &subject_guid; + subject_info.pwsFileName = file; + subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1; + ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL); + todo_wine ok(ret, "Failed to get indirect data size, error %lu\n", GetLastError()); + + indirect_data = malloc(size); + ret = CryptSIPCreateIndirectData(&subject_info, &size, indirect_data); + todo_wine ok(ret, "Failed to get indirect data, error %lu\n", GetLastError()); + if (ret) + { + memset(hash_buffer, 0, sizeof(hash_buffer)); + for (i = 0; i < indirect_data->Digest.cbData; ++i) + swprintf(&hash_buffer[i * 2], 2, L"%02X", indirect_data->Digest.pbData[i]); + + member = CryptCATPutMemberInfo(catalog, (WCHAR *)file, + hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data); + ok(!!member, "Failed to write member, error %lu\n", GetLastError()); + } + + free(indirect_data); +} + static void test_create_device_list_ex(void) { static const WCHAR machine[] = { 'd','u','m','m','y',0 }; @@ -3422,7 +3663,7 @@ static BOOL is_in_inf_dir(const char *path) return !strncasecmp(path, expect, strrchr(path, '\') - path); }
-static void test_original_file_name(const char *original, const char *dest) +static void check_original_file_name(const char *dest_inf, const char *src_inf, const char *src_catalog) { SP_ORIGINAL_FILE_INFO_A orig_info; SP_INF_INFORMATION *inf_info; @@ -3436,7 +3677,7 @@ static void test_original_file_name(const char *original, const char *dest) return; }
- hinf = SetupOpenInfFileA(dest, NULL, INF_STYLE_WIN4, NULL); + hinf = SetupOpenInfFileA(dest_inf, NULL, INF_STYLE_WIN4, NULL); ok(hinf != NULL, "Failed to open INF file, error %lu.\n", GetLastError());
res = SetupGetInfInformationA(hinf, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &size); @@ -3457,34 +3698,49 @@ static void test_original_file_name(const char *original, const char *dest) SetLastError(0xdeadbeef); res = pSetupQueryInfOriginalFileInformationA(inf_info, 0, NULL, &orig_info); ok(res == TRUE, "Got %d.\n", res); - todo_wine ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); - ok(!orig_info.OriginalCatalogName[0], "Got original catalog name %s.\n", - debugstr_a(orig_info.OriginalCatalogName)); - ok(!strcmp(original, orig_info.OriginalInfName), "Expected orignal inf name %s, got %s.\n", - debugstr_a(original), debugstr_a(orig_info.OriginalInfName)); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(!strcmp(orig_info.OriginalCatalogName, src_catalog), "Expected original catalog name %s, got %s.\n", + debugstr_a(src_catalog), debugstr_a(orig_info.OriginalCatalogName)); + ok(!strcmp(orig_info.OriginalInfName, src_inf), "Expected orignal inf name %s, got %s.\n", + debugstr_a(src_inf), debugstr_a(orig_info.OriginalInfName));
free(inf_info);
SetupCloseInfFile(hinf); }
-static void test_copy_oem_inf(void) +static void test_copy_oem_inf(struct testsign_context *ctx) { char path[MAX_PATH * 2], dest[MAX_PATH], orig_dest[MAX_PATH]; char orig_cwd[MAX_PATH], *cwd, *filepart, pnf[MAX_PATH]; + SYSTEM_INFO system_info; + HANDLE catalog; DWORD size; BOOL ret;
static const char inf_data1[] = "[Version]\n" "Signature="$Chicago$"\n" + "CatalogFile=winetest.cat\n" + /* Windows 10 needs a non-empty Manufacturer section, otherwise + * SetupUninstallOEMInf() fails with ERROR_INVALID_PARAMETER. */ + "[Manufacturer]\n" + "mfg1=mfg_section,NT" MYEXT "\n" "; This is a WINE test INF file\n";
static const char inf_data2[] = "[Version]\n" "Signature="$Chicago$"\n" + "CatalogFile=winetest2.cat\n" + "[Manufacturer]\n" + "mfg1=mfg_section,NT" MYEXT "\n" "; This is another WINE test INF file\n";
+ if (wow64) + return; + + GetSystemInfo(&system_info); + GetCurrentDirectoryA(sizeof(orig_cwd), orig_cwd); cwd = tempnam(NULL, "wine"); ret = CreateDirectoryA(cwd, NULL); @@ -3521,22 +3777,46 @@ static void test_copy_oem_inf(void)
create_file("winetest.inf", inf_data1);
- /* try a relative SourceInfFileName */ + catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0); + ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#lx\n", GetLastError()); + + add_file_to_catalog(catalog, L"winetest.inf"); + + ret = CryptCATPersistStore(catalog); + todo_wine ok(ret, "Failed to write catalog, error %#lx\n", GetLastError()); + + ret = CryptCATClose(catalog); + ok(ret, "Failed to close catalog, error %#lx\n", GetLastError()); + + testsign_sign(ctx, L"winetest.cat"); + + /* Test with a relative path. */ SetLastError(0xdeadbeef); - ret = SetupCopyOEMInfA("winetest.inf", NULL, 0, SP_COPY_NOOVERWRITE, NULL, 0, NULL, NULL); - ok(!ret, "Got %d.\n", ret); - if (GetLastError() == ERROR_WRONG_INF_TYPE || GetLastError() == ERROR_UNSUPPORTED_TYPE /* Win7 */) + memset(dest, 0xcc, sizeof(dest)); + ret = SetupCopyOEMInfA("winetest.inf", NULL, 0, SP_COPY_NOOVERWRITE, dest, sizeof(dest), NULL, &filepart); + todo_wine ok(ret == TRUE, "Got %d.\n", ret); + todo_wine ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(file_exists("winetest.inf"), "Expected source inf to exist.\n"); + if (ret) { - /* FIXME: - * Vista needs a [Manufacturer] entry in the inf file. Doing this will give some - * popups during the installation though as it also needs a catalog file (signed?). - */ - win_skip("Needs a different inf file on Vista+.\n"); - goto out; - } + ok(file_exists(dest), "Expected dest file to exist.\n"); + ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); + ok(filepart == strrchr(dest, '\') + 1, "Got unexpected file part %s.\n", filepart);
- ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); - ok(file_exists("winetest.inf"), "Expected source inf to exist.\n"); + ret = SetupUninstallOEMInfA("bogus.inf", 0, NULL); + ok(!ret, "Got %d.\n", ret); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Got error %#lx.\n", GetLastError()); + + strcpy(pnf, dest); + *(strrchr(pnf, '.') + 1) = 'p'; + SetLastError(0xdeadbeef); + ret = SetupUninstallOEMInfA(filepart, 0, NULL); + ok(ret == TRUE, "Got %d.\n", ret); + ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); + ok(!file_exists(dest), "Expected inf '%s' not to exist.\n", dest); + DeleteFileA(dest); + ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf); + }
/* try SP_COPY_REPLACEONLY, dest does not exist */ SetLastError(0xdeadbeef); @@ -3550,11 +3830,6 @@ static void test_copy_oem_inf(void) strcat(path, "\winetest.inf"); SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); - if (!ret && GetLastError() == ERROR_ACCESS_DENIED) - { - skip("Not enough permissions to copy INF.\n"); - goto out; - } ok(ret == TRUE, "Got %d.\n", ret); ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); ok(file_exists(path), "Expected source inf to exist.\n"); @@ -3562,7 +3837,8 @@ static void test_copy_oem_inf(void) ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); strcpy(orig_dest, dest);
- /* Existing INF files are checked for a match. */ + check_original_file_name(dest, "winetest.inf", "winetest.cat"); + SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); ok(ret == TRUE, "Got %d.\n", ret); @@ -3571,7 +3847,14 @@ static void test_copy_oem_inf(void) ok(file_exists(dest), "Expected dest file to exist.\n"); ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest);
+ /* On Windows 7 and earlier, trying to install the same file with a + * different base name does nothing and returns the existing driver store + * location and INF directory file. + * On Windows 8 and later, it's installed to a new location. */ + /* try SP_COPY_REPLACEONLY, dest exists */ + GetCurrentDirectoryA(sizeof(path), path); + strcat(path, "\winetest.inf"); SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, SP_COPY_REPLACEONLY, dest, sizeof(dest), NULL, NULL); ok(ret == TRUE, "Got %d.\n", ret); @@ -3612,8 +3895,6 @@ static void test_copy_oem_inf(void) ok(!strcmp(orig_dest, dest), "Expected '%s', got '%s'.\n", orig_dest, dest); ok(size == strlen(dest) + 1, "Got %ld.\n", size);
- test_original_file_name(strrchr(path, '\') + 1, dest); - SetLastError(0xdeadbeef); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, &filepart); ok(ret == TRUE, "Got %d.\n", ret); @@ -3634,7 +3915,7 @@ static void test_copy_oem_inf(void) ok(ret, "Failed to uninstall '%s', error %#lx.\n", dest, GetLastError()); todo_wine ok(!file_exists(dest), "Expected inf '%s' not to exist.\n", dest); DeleteFileA(dest); - ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf); + todo_wine ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf);
create_file("winetest.inf", inf_data1); SetLastError(0xdeadbeef); @@ -3644,8 +3925,24 @@ static void test_copy_oem_inf(void) ok(is_in_inf_dir(dest), "Got unexpected path '%s'.\n", dest); strcpy(orig_dest, dest);
- create_file("winetest.inf", inf_data2); + create_file("winetest2.inf", inf_data2); + + catalog = CryptCATOpen((WCHAR *)L"winetest2.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0); + ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#lx\n", GetLastError()); + + add_file_to_catalog(catalog, L"winetest2.inf"); + + ret = CryptCATPersistStore(catalog); + todo_wine ok(ret, "Failed to write catalog, error %#lx\n", GetLastError()); + + ret = CryptCATClose(catalog); + ok(ret, "Failed to close catalog, error %#lx\n", GetLastError()); + + testsign_sign(ctx, L"winetest2.cat"); + SetLastError(0xdeadbeef); + GetCurrentDirectoryA(sizeof(path), path); + strcat(path, "\winetest2.inf"); ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); ok(ret == TRUE, "Got %d.\n", ret); ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); @@ -3668,23 +3965,17 @@ static void test_copy_oem_inf(void) *(strrchr(pnf, '.') + 1) = 'p'; todo_wine ok(!file_exists(pnf), "Expected pnf '%s' not to exist.\n", pnf);
- GetWindowsDirectoryA(orig_dest, sizeof(orig_dest)); - strcat(orig_dest, "\inf\winetest.inf"); - ret = CopyFileA("winetest.inf", orig_dest, TRUE); - ok(ret, "Failed to copy file, error %#lx.\n", GetLastError()); - SetLastError(0xdeadbeef); - ret = SetupCopyOEMInfA(path, NULL, SPOST_NONE, 0, dest, sizeof(dest), NULL, NULL); - ok(ret == TRUE, "Got %d.\n", ret); - ok(!GetLastError(), "Got error %#lx.\n", GetLastError()); - ok(!strcasecmp(dest, orig_dest), "Expected '%s', got '%s'.\n", orig_dest, dest); + ret = DeleteFileA("winetest2.cat"); + ok(ret, "Failed to delete file, error %#lx.\n", GetLastError());
- /* Since it wasn't actually installed, SetupUninstallOEMInf would fail here. */ - ret = DeleteFileA(dest); - ok(ret, "Failed to delete %s, error %#lx.\n", debugstr_a(dest), GetLastError()); + ret = DeleteFileA("winetest2.inf"); + ok(ret, "Failed to delete file, error %#lx.\n", GetLastError()); + + ret = DeleteFileA("winetest.cat"); + ok(ret, "Failed to delete file, error %#lx.\n", GetLastError());
-out: ret = DeleteFileA("winetest.inf"); - ok(ret, "Failed to delete winetest.inf, error %#lx.\n", GetLastError()); + ok(ret, "Failed to delete file, error %#lx.\n", GetLastError());
SetCurrentDirectoryA(orig_cwd); ret = RemoveDirectoryA(cwd); @@ -3696,12 +3987,12 @@ START_TEST(devinst) { static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); HMODULE module = GetModuleHandleA("setupapi.dll"); + struct testsign_context ctx; HKEY hkey;
pSetupQueryInfOriginalFileInformationA = (void *)GetProcAddress(module, "SetupQueryInfOriginalFileInformationA");
test_get_actual_section(); - test_copy_oem_inf();
if ((hkey = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS)) == INVALID_HANDLE_VALUE) { @@ -3735,4 +4026,11 @@ START_TEST(devinst) test_driver_list(); test_call_class_installer(); test_get_class_devs(); + + if (!testsign_create_cert(&ctx)) + return; + + test_copy_oem_inf(&ctx); + + testsign_cleanup(&ctx); }