[WINESYNC] setupapi: Use lowercase device paths.

Some games are doing case sensitive matches on the device paths obtained from
Setup API and expect them to be lowercase.

This fixes Virginia not being able to discover DualShock 4.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 30a026d2454b2de93257e9eb895573ce8c56dc05 by Arkadiusz Hiler <ahiler@codeweavers.com>

[WINESYNC] setupapi/tests: Add possible test_need_media results for Win10.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 68b83a8a093d59d9ee085574c4c1ef64e6b28807 by Rémi Bernon <rbernon@codeweavers.com>

[WINESYNC] setupapi/tests: Add some service installation flags tests.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 919ee014b93ba633ead2cfe44bcf475dbda55ecd by Rémi Bernon <rbernon@codeweavers.com>

[WINESYNC] setupapi/tests: Avoid "misleading indentation" warnings.

Signed-off-by: Fabian Maurer <dark.shadow4@web.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 87acd4021848afffc4c2060c0494db1045c060d6 by Fabian Maurer <dark.shadow4@web.de>

[WINESYNC] setupapi: Use correct integral type.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id fd8d0babe1ba8efde1d5a251deee43994d2d8eec by Eric Pouech <eric.pouech@gmail.com>

[WINESYNC] setupapi/tests: Test queuing the same copy operation twice.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id ef77468b5e041d55db3821778665a2a406ed72ea by Zebediah Figura <zfigura@codeweavers.com>

[WINESYNC] setupapi/tests: Add more tests for SetupInstallFilesFromInfSection().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 63cdb0b91a80d6e4bfd7528131157a3f20f2de6f by Zebediah Figura <zfigura@codeweavers.com>

[WINESYNC] setupapi: Use the source path if the target path is missing in SetupQueueRename().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 47111ff6b08dc019456d0f3c910a924deb1267d2 by Zebediah Figura <zfigura@codeweavers.com>

[WINESYNC] setupapi: Also handle DelFiles and RenFiles directives in SetupInstallFilesFromInfSection().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>

wine commit id 506ce2ae6bc2fc1395da402a8ed0de4527fa7e24 by Zebediah Figura <zfigura@codeweavers.com>
This commit is contained in:
winesync 2023-09-14 21:39:42 +02:00 committed by Hermès Bélusca-Maïto
parent 66d9b67c31
commit 7d6df771c8
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
4 changed files with 308 additions and 50 deletions

View file

@ -844,7 +844,7 @@ BOOL WINAPI SetupQueueRenameA( HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFi
if (!(op = heap_alloc_zero( sizeof(*op) ))) return FALSE;
op->src_path = strdupAtoW( SourcePath );
op->src_file = strdupAtoW( SourceFilename );
op->dst_path = strdupAtoW( TargetPath );
op->dst_path = strdupAtoW( TargetPath ? TargetPath : SourcePath );
op->dst_file = strdupAtoW( TargetFilename );
queue_file_op( &queue->rename_queue, op );
return TRUE;
@ -863,7 +863,7 @@ BOOL WINAPI SetupQueueRenameW( HSPFILEQ handle, PCWSTR SourcePath, PCWSTR Source
if (!(op = heap_alloc_zero( sizeof(*op) ))) return FALSE;
op->src_path = strdupW( SourcePath );
op->src_file = strdupW( SourceFilename );
op->dst_path = strdupW( TargetPath );
op->dst_path = strdupW( TargetPath ? TargetPath : SourcePath );
op->dst_file = strdupW( TargetFilename );
queue_file_op( &queue->rename_queue, op );
return TRUE;
@ -1531,7 +1531,7 @@ BOOL WINAPI SetupInstallFileExW( HINF hinf, PINFCONTEXT inf_context, PCWSTR sour
{
BOOL ret, absolute = (root && *root && !(style & SP_COPY_SOURCE_ABSOLUTE));
WCHAR *buffer, *p, *inf_source = NULL, dest_path[MAX_PATH];
unsigned int len;
DWORD len;
TRACE("%p %p %s %s %s %x %p %p %p\n", hinf, inf_context, debugstr_w(source), debugstr_w(root),
debugstr_w(dest), style, handler, context, in_use);

View file

@ -125,7 +125,7 @@ static void test_open_class_key(void)
SetLastError(0xdeadbeef);
class_key = SetupDiOpenClassRegKeyExA(&guid, KEY_ALL_ACCESS, DIOCR_INSTALLER, NULL, NULL);
ok(class_key == INVALID_HANDLE_VALUE, "Expected failure.\n");
todo_wine
todo_wine
ok(GetLastError() == ERROR_INVALID_CLASS, "Got unexpected error %#x.\n", GetLastError());
root_key = SetupDiOpenClassRegKey(NULL, KEY_ALL_ACCESS);
@ -1029,6 +1029,18 @@ static void test_register_device_info(void)
SetupDiDestroyDeviceInfoList(set);
}
static void check_all_lower_case(int line, const char* str)
{
const char *cur;
for (cur = str; *cur; cur++)
{
BOOL is_lower = (tolower(*cur) == *cur);
ok_(__FILE__, line)(is_lower, "Expected device path to be all lowercase but got %s.\n", str);
if (!is_lower) break;
}
}
static void check_device_iface_(int line, HDEVINFO set, SP_DEVINFO_DATA *device,
const GUID *class, int index, DWORD flags, const char *path)
{
@ -1050,6 +1062,7 @@ static void check_device_iface_(int line, HDEVINFO set, SP_DEVINFO_DATA *device,
ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, sizeof(buffer), NULL, NULL);
ok_(__FILE__, line)(ret, "Failed to get interface detail, error %#x.\n", GetLastError());
ok_(__FILE__, line)(!strcasecmp(detail->DevicePath, path), "Got unexpected path %s.\n", detail->DevicePath);
check_all_lower_case(line, detail->DevicePath);
}
else
{
@ -1558,7 +1571,7 @@ static void test_registry_property_a(void)
SetLastError(0xdeadbeef);
ret = SetupDiSetDeviceRegistryPropertyA(set, &device, -1, NULL, 0);
ok(!ret, "Expected failure.\n");
todo_wine
todo_wine
ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
ret = SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, 0);
@ -1583,7 +1596,7 @@ todo_wine
SetLastError(0xdeadbeef);
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, -1, NULL, NULL, 0, NULL);
ok(!ret, "Expected failure.\n");
todo_wine
todo_wine
ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
ret = SetupDiGetDeviceRegistryPropertyA(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, sizeof("Bogus"), NULL);
@ -1718,7 +1731,7 @@ static void test_registry_property_w(void)
SetLastError(0xdeadbeef);
ret = SetupDiSetDeviceRegistryPropertyW(set, &device, -1, NULL, 0);
ok(!ret, "Expected failure.\n");
todo_wine
todo_wine
ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
ret = SetupDiSetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, 0);
@ -1743,7 +1756,7 @@ todo_wine
SetLastError(0xdeadbeef);
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, -1, NULL, NULL, 0, NULL);
ok(!ret, "Expected failure.\n");
todo_wine
todo_wine
ok(GetLastError() == ERROR_INVALID_REG_PROPERTY, "Got unexpected error %#x.\n", GetLastError());
ret = SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_FRIENDLYNAME, NULL, NULL, sizeof(buf), NULL);

View file

@ -609,13 +609,26 @@ static void test_install_svc_from(void)
/* TODO: Test the Flags */
}
static void test_driver_install(void)
static void test_service_install(const char *executable, const char *argument)
{
HANDLE handle;
struct
{
const char *add_service_flags;
const char *service_type;
const char *start_type;
DWORD expect_start_error;
} tests[] =
{
{.add_service_flags = "", .service_type = "1", .start_type = "4", .expect_start_error = ERROR_SERVICE_DISABLED},
{.add_service_flags = "", .service_type = "0x10", .start_type = "2", .expect_start_error = 0},
{.add_service_flags = "0x800", .service_type = "0x10", .start_type = "2", .expect_start_error = ERROR_SERVICE_ALREADY_RUNNING},
};
SC_HANDLE scm_handle, svc_handle;
SERVICE_STATUS status;
BOOL ret;
char path[MAX_PATH + 9], windir[MAX_PATH], driver[MAX_PATH];
DWORD attrs;
DWORD i, attrs;
/* Minimal stuff needed */
static const char *inf =
"[Version]\n"
@ -625,14 +638,15 @@ static void test_driver_install(void)
"[DefaultInstall]\n"
"CopyFiles=Winetest.DriverFiles\n"
"[DefaultInstall.Services]\n"
"AddService=Winetest,,Winetest.Service\n"
"AddService=Winetest,%s,Winetest.Service\n"
"[Winetest.Service]\n"
"ServiceBinary=%12%\\winetest.sys\n"
"ServiceType=1\n"
"StartType=4\n"
"ServiceBinary=%%12%%\\winetest.sys %s service\n"
"ServiceType=%s\n"
"StartType=%s\n"
"ErrorControl=1\n"
"[Winetest.DriverFiles]\n"
"winetest.sys";
char buffer[1024];
/* Bail out if we don't have enough rights */
SetLastError(0xdeadbeef);
@ -649,36 +663,70 @@ static void test_driver_install(void)
lstrcpyA(driver, windir);
lstrcatA(driver, "\\system32\\drivers\\winetest.sys");
/* Create a dummy driver file */
handle = CreateFileA("winetest.sys", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(handle);
ret = CopyFileA(executable, "winetest.sys", TRUE);
ok(ret, "CopyFileA failed, error %u\n", GetLastError());
create_inf_file(inffile, inf);
sprintf(path, "%s\\%s", CURR_DIR, inffile);
run_cmdline("DefaultInstall", 128, path);
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
winetest_push_context("%u", i);
/* Driver should have been installed */
attrs = GetFileAttributesA(driver);
ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected driver to exist\n");
sprintf(buffer, inf, tests[i].add_service_flags, argument, tests[i].service_type, tests[i].start_type);
create_inf_file(inffile, buffer);
sprintf(path, "%s\\%s", CURR_DIR, inffile);
run_cmdline("DefaultInstall", 128, path);
scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
/* Driver should have been installed */
attrs = GetFileAttributesA(driver);
ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected driver to exist\n");
/* Open the service to see if it's really there */
svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE);
ok(svc_handle != NULL, "Service was not created\n");
scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
SetLastError(0xdeadbeef);
ret = DeleteService(svc_handle);
ok(ret, "Service could not be deleted : %d\n", GetLastError());
/* Open the service to see if it's really there */
svc_handle = OpenServiceA(scm_handle, "Winetest", SERVICE_START|SERVICE_STOP|SERVICE_QUERY_STATUS|DELETE);
ok(svc_handle != NULL, "Service was not created\n");
CloseServiceHandle(svc_handle);
CloseServiceHandle(scm_handle);
ret = StartServiceA(svc_handle, 0, NULL);
if (!tests[i].expect_start_error)
ok(ret, "StartServiceA failed, error %u\n", GetLastError());
else
{
ok(!ret, "StartServiceA succeeded\n");
ok(GetLastError() == tests[i].expect_start_error, "got error %u\n", GetLastError());
}
ret = QueryServiceStatus(svc_handle, &status);
ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
while (status.dwCurrentState == SERVICE_START_PENDING)
{
Sleep(100);
ret = QueryServiceStatus(svc_handle, &status);
ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
}
ret = ControlService(svc_handle, SERVICE_CONTROL_STOP, &status);
while (status.dwCurrentState == SERVICE_STOP_PENDING)
{
Sleep(100);
ret = QueryServiceStatus(svc_handle, &status);
ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
}
ok(status.dwCurrentState == SERVICE_STOPPED, "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
SetLastError(0xdeadbeef);
ret = DeleteService(svc_handle);
ok(ret, "Service could not be deleted : %d\n", GetLastError());
CloseServiceHandle(svc_handle);
CloseServiceHandle(scm_handle);
/* File cleanup */
DeleteFileA(inffile);
DeleteFileA(driver);
winetest_pop_context();
}
/* File cleanup */
DeleteFileA(inffile);
DeleteFileA("winetest.sys");
DeleteFileA(driver);
}
static void test_profile_items(void)
@ -1017,9 +1065,13 @@ static void test_install_files_queue(void)
{
static const char inf_data[] = "[Version]\n"
"Signature=\"$Chicago$\"\n"
"[DefaultInstall]\n"
"CopyFiles=files_section\n"
"[files_section]\n"
"CopyFiles=copy_section\n"
"DelFiles=delete_section\n"
"RenFiles=rename_section\n"
"[copy_section]\n"
"one.txt\n"
"two.txt\n"
"three.txt\n"
@ -1028,11 +1080,19 @@ static void test_install_files_queue(void)
"six.txt\n"
"seven.txt\n"
"eight.txt\n"
"[delete_section]\n"
"nine.txt\n"
"[rename_section]\n"
"eleven.txt,ten.txt\n"
"[SourceDisksNames]\n"
"1=heis\n"
"2=duo,,,alpha\n"
"3=treis,treis.cab\n"
"4=tessares,tessares.cab,,alpha\n"
"[SourceDisksFiles]\n"
"one.txt=1\n"
"two.txt=1,beta\n"
@ -1042,8 +1102,11 @@ static void test_install_files_queue(void)
"six.txt=3,beta\n"
"seven.txt=4\n"
"eight.txt=4,beta\n"
"[DestinationDirs]\n"
"files_section=40000,dst\n";
"copy_section=40000,dst\n"
"delete_section=40000,dst\n"
"rename_section=40000,dst\n";
char path[MAX_PATH + 9];
HSPFILEQ queue;
@ -1068,12 +1131,17 @@ static void test_install_files_queue(void)
ret = SetupSetDirectoryIdA(hinf, 40000, CURR_DIR);
ok(ret, "Failed to set directory ID, error %u.\n", GetLastError());
ret = CreateDirectoryA("dst", NULL);
ok(ret, "Failed to create test directory, error %u.\n", GetLastError());
create_file("src/one.txt");
create_file("src/beta/two.txt");
create_file("src/alpha/three.txt");
create_file("src/alpha/beta/four.txt");
create_cab_file("src/treis.cab", "src\\beta\\five.txt\0six.txt\0");
create_cab_file("src/alpha/tessares.cab", "seven.txt\0eight.txt\0");
create_file("dst/nine.txt");
create_file("dst/ten.txt");
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
@ -1099,6 +1167,9 @@ static void test_install_files_queue(void)
ok(delete_file("dst/six.txt"), "Destination file should exist.\n");
ok(delete_file("dst/seven.txt"), "Destination file should exist.\n");
ok(delete_file("dst/eight.txt"), "Destination file should exist.\n");
ok(!delete_file("dst/nine.txt"), "Destination file should not exist.\n");
ok(!delete_file("dst/ten.txt"), "Destination file should not exist.\n");
ok(delete_file("dst/eleven.txt"), "Destination file should exist.\n");
SetupTermDefaultQueueCallback(context);
ret = SetupCloseFileQueue(queue);
@ -1120,7 +1191,7 @@ static void test_install_files_queue(void)
ok(ret, "Failed to delete INF file, error %u.\n", GetLastError());
}
static unsigned int got_need_media, got_copy_error;
static unsigned int got_need_media, got_copy_error, got_start_copy;
static unsigned int testmode;
static UINT WINAPI need_media_cb(void *context, UINT message, UINT_PTR param1, UINT_PTR param2)
@ -1332,6 +1403,7 @@ static UINT WINAPI need_media_newpath_cb(void *context, UINT message, UINT_PTR p
else
return FILEOP_SKIP;
}
else if (message == SPFILENOTIFY_STARTCOPY) got_start_copy++;
return SetupDefaultQueueCallbackA(context, message, param1, param2);
}
@ -1901,7 +1973,7 @@ static void test_need_media(void)
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
testmode = 6;
got_need_media = got_copy_error = 0;
got_need_media = got_copy_error = got_start_copy = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
copy_params.QueueHandle = queue;
@ -1915,9 +1987,10 @@ static void test_need_media(void)
run_queue(queue, need_media_newpath_cb);
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
ok(!got_copy_error, "Got %u copy errors.\n", got_copy_error);
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
if (got_start_copy) ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
else ok(!file_exists("dst/one.txt"), "Destination file should not exist.\n");
got_need_media = got_copy_error = 0;
got_need_media = got_copy_error = got_start_copy = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
copy_params.LayoutInf = hinf;
@ -1928,7 +2001,8 @@ static void test_need_media(void)
run_queue(queue, need_media_newpath_cb);
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
ok(!got_copy_error, "Got %u copy errors.\n", got_copy_error);
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
if (got_start_copy) ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
else ok(!file_exists("dst/one.txt"), "Destination file should not exist.\n");
}
else
SetupCloseFileQueue(queue);
@ -1963,7 +2037,7 @@ static void test_close_queue(void)
SetupTermDefaultQueueCallback(context);
}
static unsigned int got_start_copy, start_copy_ret;
static unsigned int start_copy_ret;
static UINT WINAPI start_copy_cb(void *context, UINT message, UINT_PTR param1, UINT_PTR param2)
{
@ -2003,12 +2077,14 @@ static void test_start_copy(void)
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "two.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "src", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
run_queue(queue, start_copy_cb);
ok(got_start_copy == 3, "Got %u callbacks.\n", got_start_copy);
todo_wine ok(got_start_copy == 3, "Got %u callbacks.\n", got_start_copy);
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
@ -2129,11 +2205,179 @@ static void test_register_dlls(void)
ok(ret, "Failed to delete test DLL, error %u.\n", GetLastError());
}
static unsigned int start_rename_ret, got_start_rename;
static UINT WINAPI start_rename_cb(void *context, UINT message, UINT_PTR param1, UINT_PTR param2)
{
if (winetest_debug > 1) trace("%p, %#x, %#Ix, %#Ix\n", context, message, param1, param2);
if (message == SPFILENOTIFY_STARTRENAME)
{
const FILEPATHS_A *paths = (const FILEPATHS_A *)param1;
++got_start_rename;
if (strstr(paths->Source, "three.txt"))
{
SetLastError(0xdeadf00d);
return start_rename_ret;
}
}
return SetupDefaultQueueCallbackA(context, message, param1, param2);
}
static void test_rename(void)
{
HSPFILEQ queue;
BOOL ret;
ret = CreateDirectoryA("a", NULL);
ok(ret, "Failed to create test directory, error %u.\n", GetLastError());
ret = CreateDirectoryA("b", NULL);
ok(ret, "Failed to create test directory, error %u.\n", GetLastError());
create_file("a/one.txt");
create_file("b/three.txt");
create_file("a/five.txt");
create_file("b/six.txt");
start_rename_ret = FILEOP_DOIT;
got_start_rename = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
ret = SetupQueueCopyA(queue, "b", NULL, "one.txt", NULL, NULL, "b", "two.txt", 0);
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "a", "one.txt", "b", "one.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "b", "three.txt", NULL, "four.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "b", "six.txt", "b", "seven.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "a", "five.txt", "b", "six.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
run_queue(queue, start_rename_cb);
ok(got_start_rename == 4, "Got %u callbacks.\n", got_start_rename);
ok(!delete_file("a/one.txt"), "File should not exist.\n");
ok(!delete_file("a/five.txt"), "File should not exist.\n");
ok(delete_file("b/one.txt"), "File should exist.\n");
ok(delete_file("b/two.txt"), "File should exist.\n");
ok(!delete_file("b/three.txt"), "File should not exist.\n");
ok(delete_file("b/four.txt"), "File should exist.\n");
ok(!delete_file("b/five.txt"), "File should not exist.\n");
ok(delete_file("b/six.txt"), "File should exist.\n");
ok(delete_file("b/seven.txt"), "File should exist.\n");
SetupCloseFileQueue(queue);
create_file("a/one.txt");
create_file("a/three.txt");
create_file("a/five.txt");
start_rename_ret = FILEOP_SKIP;
got_start_rename = 0;
queue = SetupOpenFileQueue();
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "a", "one.txt", "a", "two.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "a", "three.txt", "a", "four.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
ret = SetupQueueRenameA(queue, "a", "five.txt", "a", "six.txt");
ok(ret, "Failed to queue rename, error %#x.\n", GetLastError());
run_queue(queue, start_rename_cb);
ok(got_start_rename == 3, "Got %u callbacks.\n", got_start_rename);
ok(!delete_file("a/one.txt"), "File should not exist.\n");
ok(delete_file("a/two.txt"), "File should exist.\n");
ok(delete_file("a/three.txt"), "File should exist.\n");
ok(!delete_file("a/four.txt"), "File should not exist.\n");
ok(!delete_file("a/five.txt"), "File should not exist.\n");
ok(delete_file("a/six.txt"), "File should exist.\n");
SetupCloseFileQueue(queue);
ok(delete_file("a/"), "Failed to delete directory, error %u.\n", GetLastError());
ok(delete_file("b/"), "Failed to delete directory, error %u.\n", GetLastError());
}
static WCHAR service_name[] = L"Wine Test Service";
static SERVICE_STATUS_HANDLE service_handle;
static HANDLE stop_event;
static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
{
SERVICE_STATUS status;
status.dwServiceType = SERVICE_WIN32;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
switch(ctrl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
trace( "shutting down\n" );
status.dwCurrentState = SERVICE_STOP_PENDING;
status.dwControlsAccepted = 0;
SetServiceStatus( service_handle, &status );
SetEvent( stop_event );
return NO_ERROR;
default:
trace( "got service ctrl %x\n", ctrl );
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus( service_handle, &status );
return NO_ERROR;
}
}
static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
{
SERVICE_STATUS status;
trace( "starting service\n" );
stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
service_handle = RegisterServiceCtrlHandlerExW( L"Wine Test Service", service_handler, NULL );
if (!service_handle)
return;
status.dwServiceType = SERVICE_WIN32;
status.dwCurrentState = SERVICE_RUNNING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 10000;
SetServiceStatus( service_handle, &status );
WaitForSingleObject( stop_event, INFINITE );
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = 0;
SetServiceStatus( service_handle, &status );
trace( "service stopped\n" );
}
START_TEST(install)
{
char temp_path[MAX_PATH], prev_path[MAX_PATH];
char temp_path[MAX_PATH], prev_path[MAX_PATH], path[MAX_PATH];
char **argv;
DWORD len;
int argc;
argc = winetest_get_mainargs(&argv);
if (argc > 2 && !strcmp( argv[2], "service" ))
{
static const SERVICE_TABLE_ENTRYW service_table[] =
{
{ service_name, ServiceMain },
{ NULL, NULL }
};
StartServiceCtrlDispatcherW( service_table );
return;
}
GetFullPathNameA(argv[0], ARRAY_SIZE(path), path, NULL);
GetCurrentDirectoryA(MAX_PATH, prev_path);
GetTempPathA(MAX_PATH, temp_path);
SetCurrentDirectoryA(temp_path);
@ -2151,7 +2395,7 @@ START_TEST(install)
test_registry();
test_install_from();
test_install_svc_from();
test_driver_install();
test_service_install(path, argv[1]);
test_dirid();
test_install_files_queue();
test_need_media();
@ -2159,6 +2403,7 @@ START_TEST(install)
test_install_file();
test_start_copy();
test_register_dlls();
test_rename();
UnhookWindowsHookEx(hhook);

View file

@ -10,4 +10,4 @@ files:
dlls/setupapi/setupcab.c: dll/win32/setupapi/setupcab.c
dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable_wine.c
tags:
wine: 5030f4cf26c31bc709d6565182b51af1165953a6
wine: 506ce2ae6bc2fc1395da402a8ed0de4527fa7e24