mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[WINESYNC] setupapi/tests: Add tests for source media path resolution.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org> wine commit id d5a6a2675c250cffd7b37a27d61fc2031b1d7b21 by Zebediah Figura <z.figura12@gmail.com> [WINESYNC] setupapi: Add magic bytes to struct file_queue and validate them in SetupCloseFileQueue(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=12332 Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org> wine commit id c65d98065c0038e0919f40bec4a9dc978fb2ade9 by Zebediah Figura <z.figura12@gmail.com>
This commit is contained in:
parent
07b9b00664
commit
1a68e54d1b
3 changed files with 756 additions and 1 deletions
|
@ -75,6 +75,7 @@ struct file_op_queue
|
|||
|
||||
struct file_queue
|
||||
{
|
||||
DWORD magic;
|
||||
struct file_op_queue copy_queue;
|
||||
struct file_op_queue delete_queue;
|
||||
struct file_op_queue rename_queue;
|
||||
|
@ -83,6 +84,7 @@ struct file_queue
|
|||
unsigned int source_count;
|
||||
};
|
||||
|
||||
#define FILE_QUEUE_MAGIC 0x21514653
|
||||
|
||||
/* append a file operation to a queue */
|
||||
static inline void queue_file_op( struct file_op_queue *queue, struct file_op *op )
|
||||
|
@ -522,6 +524,7 @@ HSPFILEQ WINAPI SetupOpenFileQueue(void)
|
|||
|
||||
if (!(queue = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*queue))))
|
||||
return INVALID_HANDLE_VALUE;
|
||||
queue->magic = FILE_QUEUE_MAGIC;
|
||||
return queue;
|
||||
}
|
||||
|
||||
|
@ -534,6 +537,14 @@ BOOL WINAPI SetupCloseFileQueue( HSPFILEQ handle )
|
|||
struct file_queue *queue = handle;
|
||||
unsigned int i;
|
||||
|
||||
/* Windows XP DDK installer passes the handle returned from
|
||||
* SetupInitDefaultQueueCallback() to this function. */
|
||||
if (queue->magic != FILE_QUEUE_MAGIC)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
free_file_op_queue( &queue->copy_queue );
|
||||
free_file_op_queue( &queue->rename_queue );
|
||||
free_file_op_queue( &queue->delete_queue );
|
||||
|
|
|
@ -1088,6 +1088,748 @@ 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 testmode;
|
||||
|
||||
static UINT WINAPI need_media_cb(void *context, UINT message, UINT_PTR param1, UINT_PTR param2)
|
||||
{
|
||||
if (winetest_debug > 1) trace("%p, %#x, %#lx, %#lx\n", context, message, param1, param2);
|
||||
|
||||
if (message == SPFILENOTIFY_NEEDMEDIA)
|
||||
{
|
||||
const SOURCE_MEDIA_A *media = (const SOURCE_MEDIA_A *)param1;
|
||||
char *path = (char *)param2;
|
||||
UINT ret;
|
||||
|
||||
/* The default callback will fill out SourcePath, but as long as DOIT
|
||||
* is returned, it's ignored. */
|
||||
ok(!path[0], "Test %u: got path '%s'.\n", testmode, path);
|
||||
ret = SetupDefaultQueueCallbackA(context, message, param1, param2);
|
||||
ok(!strcmp(path, media->SourcePath), "Test %u: got path '%s'.\n", testmode, path);
|
||||
ok(ret == FILEOP_DOIT, "Got unexpected return value %u.\n", ret);
|
||||
path[0] = 0;
|
||||
|
||||
if (testmode == 0)
|
||||
ok(media->Flags == SP_COPY_WARNIFSKIP, "Got Flags %#x.\n", media->Flags);
|
||||
else
|
||||
ok(!media->Flags, "Got Flags %#x for test %u.\n", media->Flags, testmode);
|
||||
|
||||
switch (testmode)
|
||||
{
|
||||
case 0:
|
||||
ok(!media->Tagfile, "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->Description, "File One"), "Got Description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 1:
|
||||
ok(!media->Tagfile, "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!media->Description, "Got Description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src\\beta"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "two.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 2:
|
||||
ok(!strcmp(media->Tagfile, "faketag"), "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->Description, "desc"), "Got Description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src\\beta"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "two.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 3:
|
||||
ok(!media->Tagfile, "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->Description, "heis"), "Got Description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 4:
|
||||
ok(!media->Tagfile, "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->Description, "heis"), "Got Description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src\\beta"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "two.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 5:
|
||||
ok(!media->Tagfile, "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->Description, "duo"), "Got Description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src\\alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "three.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 6:
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
testmode = 7;
|
||||
break;
|
||||
case 7:
|
||||
ok(!strcmp(media->SourcePath, "src/alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "three.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 8:
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
testmode = 9;
|
||||
break;
|
||||
case 9:
|
||||
ok(!strcmp(media->SourcePath, "src\\alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "three.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 10:
|
||||
ok(!strcmp(media->Description, "desc1"), "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
testmode = 11;
|
||||
break;
|
||||
case 11:
|
||||
ok(!media->Description, "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src\\beta"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "two.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 12:
|
||||
ok(!strcmp(media->Description, "desc1"), "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->Tagfile, "faketag"), "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
testmode = 13;
|
||||
break;
|
||||
case 13:
|
||||
ok(!strcmp(media->Description, "desc1"), "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->Tagfile, "faketag2"), "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->SourcePath, "src\\beta"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "two.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 14:
|
||||
ok(!strcmp(media->Description, "desc"), "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->Tagfile, "treis.cab"), "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->SourcePath, "src"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "four.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 15:
|
||||
ok(!strcmp(media->Description, "desc"), "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->Tagfile, "tessares.cab"), "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
ok(!strcmp(media->SourcePath, "src\\alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "seven.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
case 16:
|
||||
ok(!media->Description, "Got description '%s'.\n", media->Description);
|
||||
ok(!strcmp(media->SourcePath, "src/alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "six.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
break;
|
||||
}
|
||||
|
||||
++got_need_media;
|
||||
|
||||
return ret;
|
||||
}
|
||||
else if (message == SPFILENOTIFY_COPYERROR)
|
||||
{
|
||||
const FILEPATHS_A *paths = (const FILEPATHS_A *)param1;
|
||||
ok(0, "Got unexpected copy error %s -> %s.\n", paths->Source, paths->Target);
|
||||
}
|
||||
|
||||
return SetupDefaultQueueCallbackA(context, message, param1, param2);
|
||||
}
|
||||
|
||||
static UINT WINAPI need_media_newpath_cb(void *context, UINT message, UINT_PTR param1, UINT_PTR param2)
|
||||
{
|
||||
if (winetest_debug > 1) trace("%p, %#x, %#lx, %#lx\n", context, message, param1, param2);
|
||||
|
||||
if (message == SPFILENOTIFY_NEEDMEDIA)
|
||||
{
|
||||
const SOURCE_MEDIA_A *media = (const SOURCE_MEDIA_A *)param1;
|
||||
char *path = (char *)param2;
|
||||
|
||||
++got_need_media;
|
||||
|
||||
if (testmode == 1)
|
||||
strcpy(path, "src\\alpha");
|
||||
else if (testmode == 2)
|
||||
{
|
||||
if (got_need_media == 1)
|
||||
strcpy(path, "src\\alpha");
|
||||
else
|
||||
{
|
||||
ok(!strcmp(media->SourcePath, "src\\alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
strcpy(path, "src");
|
||||
}
|
||||
}
|
||||
else if (testmode == 5)
|
||||
{
|
||||
if (got_need_media == 1)
|
||||
{
|
||||
ok(!strcmp(media->SourcePath, "fake"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
return FILEOP_SKIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(!strcmp(media->SourcePath, "fake\\alpha"), "Got SourcePath '%s'.\n", media->SourcePath);
|
||||
ok(!strcmp(media->SourceFile, "three.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
strcpy(path, "src\\alpha");
|
||||
}
|
||||
}
|
||||
else if (testmode == 6)
|
||||
{
|
||||
/* SourcePath is not really consistent here, but it's not supplied
|
||||
* from the INF file. Usually it's a drive root, but not always. */
|
||||
ok(!strcmp(media->SourceFile, "one.txt"), "Got SourceFile '%s'.\n", media->SourceFile);
|
||||
ok(!media->Description, "Got Description '%s'.\n", media->Description);
|
||||
ok(!media->Tagfile, "Got Tagfile '%s'.\n", media->Tagfile);
|
||||
strcpy(path, "src");
|
||||
}
|
||||
else
|
||||
strcpy(path, "src");
|
||||
|
||||
return FILEOP_NEWPATH;
|
||||
}
|
||||
else if (message == SPFILENOTIFY_COPYERROR)
|
||||
{
|
||||
char *path = (char *)param2;
|
||||
|
||||
++got_copy_error;
|
||||
|
||||
if (testmode == 3)
|
||||
{
|
||||
strcpy(path, "src\\alpha");
|
||||
return FILEOP_NEWPATH;
|
||||
}
|
||||
else if (testmode == 4)
|
||||
{
|
||||
if (got_copy_error == 1)
|
||||
strcpy(path, "fake2");
|
||||
else
|
||||
strcpy(path, "src\\alpha");
|
||||
return FILEOP_NEWPATH;
|
||||
}
|
||||
else
|
||||
return FILEOP_SKIP;
|
||||
}
|
||||
|
||||
return SetupDefaultQueueCallbackA(context, message, param1, param2);
|
||||
}
|
||||
|
||||
#define run_queue(a,b) run_queue_(__LINE__,a,b)
|
||||
static void run_queue_(unsigned int line, HSPFILEQ queue, PSP_FILE_CALLBACK_A cb)
|
||||
{
|
||||
void *context = SetupInitDefaultQueueCallbackEx(NULL, INVALID_HANDLE_VALUE, 0, 0, 0);
|
||||
BOOL ret;
|
||||
ok_(__FILE__,line)(!!context, "Failed to create callback context, error %#x.\n", GetLastError());
|
||||
ret = SetupCommitFileQueueA(NULL, queue, cb, context);
|
||||
ok_(__FILE__,line)(ret, "Failed to commit queue, error %#x.\n", GetLastError());
|
||||
SetupTermDefaultQueueCallback(context);
|
||||
ret = SetupCloseFileQueue(queue);
|
||||
ok_(__FILE__,line)(ret, "Failed to close queue, error %#x.\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_need_media(void)
|
||||
{
|
||||
static const char inf_data[] = "[Version]\n"
|
||||
"Signature=\"$Chicago$\"\n"
|
||||
"[section1]\n"
|
||||
"one.txt\n"
|
||||
"[section2]\n"
|
||||
"two.txt\n"
|
||||
"[section3]\n"
|
||||
"three.txt\n"
|
||||
"[section4]\n"
|
||||
"one.txt\n"
|
||||
"two.txt\n"
|
||||
"three.txt\n"
|
||||
"[install_section]\n"
|
||||
"CopyFiles=section1\n"
|
||||
"[SourceDisksNames]\n"
|
||||
"1=heis\n"
|
||||
"2=duo,,,alpha\n"
|
||||
"[SourceDisksFiles]\n"
|
||||
"one.txt=1\n"
|
||||
"two.txt=1,beta\n"
|
||||
"three.txt=2\n"
|
||||
"[DestinationDirs]\n"
|
||||
"DefaultDestDir=40000,dst\n";
|
||||
|
||||
SP_FILE_COPY_PARAMS_A copy_params = {sizeof(copy_params)};
|
||||
char path[MAX_PATH];
|
||||
HSPFILEQ queue;
|
||||
HINF hinf;
|
||||
BOOL ret;
|
||||
|
||||
create_inf_file(inffile, inf_data);
|
||||
|
||||
sprintf(path, "%s\\%s", CURR_DIR, inffile);
|
||||
hinf = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL);
|
||||
ok(hinf != INVALID_HANDLE_VALUE, "Failed to open INF file, error %#x.\n", GetLastError());
|
||||
|
||||
ret = CreateDirectoryA("src", NULL);
|
||||
ok(ret, "Failed to create test directory, error %u.\n", GetLastError());
|
||||
ret = CreateDirectoryA("src/alpha", NULL);
|
||||
ok(ret, "Failed to create test directory, error %u.\n", GetLastError());
|
||||
ret = CreateDirectoryA("src/beta", NULL);
|
||||
ok(ret, "Failed to create test directory, 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/six.txt");
|
||||
create_cab_file("src/treis.cab", "four.txt\0five.txt\0");
|
||||
create_cab_file("src/alpha/tessares.cab", "seven.txt\0eight.txt\0");
|
||||
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", "File One", NULL, "dst", NULL, SP_COPY_WARNIFSKIP);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test with a subdirectory. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 1;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "beta", "two.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test with a tag file. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 2;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "beta", "two.txt", "desc", "faketag", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test from INF file. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 3;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopySectionA(queue, "src", hinf, NULL, "section1", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupInstallFilesFromInfSectionA(hinf, NULL, queue, "install_section", "src", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
|
||||
ret = SetupQueueDefaultCopyA(queue, hinf, "src", NULL, "one.txt", 0);
|
||||
ok(!ret, "Expected failure.\n");
|
||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got error %#x.\n", GetLastError());
|
||||
|
||||
ret = SetupQueueDefaultCopyA(queue, hinf, "src", "one.txt", "one.txt", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 4;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopySectionA(queue, "src", hinf, NULL, "section2", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueDefaultCopyA(queue, hinf, "src", "two.txt", "two.txt", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 5;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopySectionA(queue, "src", hinf, NULL, "section3", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueDefaultCopyA(queue, hinf, "src", "three.txt", "three.txt", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* One callback is sent per source directory. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 6;
|
||||
queue = SetupOpenFileQueue();
|
||||
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", "beta", "two.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src/alpha", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 2, "Got %u callbacks.\n", got_need_media);
|
||||
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");
|
||||
|
||||
/* The same rules apply to INF files. Here the subdir specified in the
|
||||
* SourceDisksNames counts as part of the root directory, but the subdir in
|
||||
* SourceDisksFiles does not. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 8;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopySectionA(queue, "src", hinf, NULL, "section4", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());\
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 2, "Got %u callbacks.\n", got_need_media);
|
||||
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");
|
||||
|
||||
/* Descriptions and tag files also distinguish source paths. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 10;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", "desc1", NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "beta", "two.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 2, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 12;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", NULL, "one.txt", "desc1", "faketag", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "beta", "two.txt", "desc1", "faketag2", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 2, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test from cabinets. Subdir is only relevant for the first argument. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 14;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", NULL, "four.txt", "desc", "treis.cab", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "alpha", "five.txt", "desc", "treis.cab", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/four.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/five.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 15;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "alpha", "seven.txt", "desc", "tessares.cab", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", NULL, "eight.txt", "desc", "tessares.cab", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/seven.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/eight.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 16;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueDefaultCopyA(queue, hinf, "src/alpha", "six.txt", "six.txt", 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/six.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test absolute paths. */
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 1;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "beta", "two.txt", NULL, NULL, "dst", NULL, SP_COPY_SOURCE_ABSOLUTE);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 1;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "src", "beta", "two.txt", NULL, NULL, "dst", NULL, SP_COPY_SOURCEPATH_ABSOLUTE);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 5;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopySectionA(queue, "src", hinf, NULL, "section3", SP_COPY_SOURCE_ABSOLUTE);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = 0;
|
||||
testmode = 5;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopySectionA(queue, "src", hinf, NULL, "section3", SP_COPY_SOURCEPATH_ABSOLUTE);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test returning a new path from the NEEDMEDIA callback. */
|
||||
|
||||
testmode = 0;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "alpha", "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
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");
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* setupapi expects the callback to return the path including the subdir
|
||||
* for the first file. It then strips off the final element. If the final
|
||||
* element doesn't match the given subdir exactly, then it's not stripped.
|
||||
* To make matters even stranger, the first file copied effectively has its
|
||||
* subdir removed. */
|
||||
|
||||
testmode = 1;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "alpha", "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "beta", "two.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
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/three.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/two.txt"), "Destination file should exist.\n");
|
||||
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "alpha\\", "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "six.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
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/three.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/six.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* If the source file does not exist (even if the path is valid),
|
||||
* SPFILENOTIFY_NEEDMEDIA is resent until it does. */
|
||||
|
||||
testmode = 2;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "alpha", "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_newpath_cb);
|
||||
ok(got_need_media == 2, "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");
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* If a following file doesn't exist, it results in a copy error instead. */
|
||||
|
||||
testmode = 0;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "fake.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_newpath_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(got_copy_error == 1, "Got %u copy errors.\n", got_copy_error);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test providing a new path from SPFILENOTIFY_COPYERROR. */
|
||||
|
||||
testmode = 3;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "six.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_newpath_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(got_copy_error == 1, "Got %u copy errors.\n", got_copy_error);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/six.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* SPFILENOTIFY_COPYERROR will also be resent until the copy is successful. */
|
||||
|
||||
testmode = 4;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "six.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_newpath_cb);
|
||||
ok(got_need_media == 1, "Got %u callbacks.\n", got_need_media);
|
||||
ok(got_copy_error == 2, "Got %u copy errors.\n", got_copy_error);
|
||||
ok(delete_file("dst/one.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/six.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test with cabinet. As above, subdir only matters for the first file. */
|
||||
|
||||
testmode = 0;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "four.txt", "desc", "treis.cab", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "alpha", "five.txt", "desc", "treis.cab", "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
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/four.txt"), "Destination file should exist.\n");
|
||||
ok(delete_file("dst/five.txt"), "Destination file should exist.\n");
|
||||
|
||||
/* Test returning FILEOP_SKIP from the NEEDMEDIA handler. */
|
||||
|
||||
testmode = 5;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", NULL, "one.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
ret = SetupQueueCopyA(queue, "fake", "alpha", "three.txt", NULL, NULL, "dst", NULL, 0);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
run_queue(queue, need_media_newpath_cb);
|
||||
ok(got_need_media == 2, "Got %u callbacks.\n", got_need_media);
|
||||
ok(!got_copy_error, "Got %u copy errors.\n", got_copy_error);
|
||||
ok(!file_exists("dst/one.txt"), "Destination file should not exist.\n");
|
||||
ok(delete_file("dst/three.txt"), "Destination file should exist.\n");
|
||||
|
||||
testmode = 6;
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
copy_params.QueueHandle = queue;
|
||||
copy_params.SourceFilename = "one.txt";
|
||||
/* Leaving TargetDirectory NULL causes it to be filled with garbage on
|
||||
* Windows, so the copy may succeed or fail. In any case it's not supplied
|
||||
* from LayoutInf. */
|
||||
copy_params.TargetDirectory = "dst";
|
||||
ret = SetupQueueCopyIndirectA(©_params);
|
||||
ok(ret, "Failed to queue copy, error %#x.\n", GetLastError());
|
||||
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");
|
||||
|
||||
got_need_media = got_copy_error = 0;
|
||||
queue = SetupOpenFileQueue();
|
||||
ok(queue != INVALID_HANDLE_VALUE, "Failed to open queue, error %#x.\n", GetLastError());
|
||||
copy_params.LayoutInf = hinf;
|
||||
/* In fact this fails with ERROR_INVALID_PARAMETER on 8+. */
|
||||
if (SetupQueueCopyIndirectA(©_params))
|
||||
{
|
||||
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");
|
||||
}
|
||||
else
|
||||
SetupCloseFileQueue(queue);
|
||||
|
||||
SetupCloseInfFile(hinf);
|
||||
delete_file("src/one.txt");
|
||||
delete_file("src/beta/two.txt");
|
||||
delete_file("src/beta/");
|
||||
delete_file("src/alpha/six.txt");
|
||||
delete_file("src/alpha/three.txt");
|
||||
delete_file("src/alpha/tessares.cab");
|
||||
delete_file("src/alpha/");
|
||||
delete_file("src/treis.cab");
|
||||
delete_file("src/");
|
||||
delete_file("dst/");
|
||||
ret = DeleteFileA(inffile);
|
||||
ok(ret, "Failed to delete INF file, error %u.\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_close_queue(void)
|
||||
{
|
||||
void *context;
|
||||
BOOL ret;
|
||||
|
||||
context = SetupInitDefaultQueueCallback(NULL);
|
||||
ok(!!context, "Failed to create callback context, error %#x.\n", GetLastError());
|
||||
|
||||
ret = SetupCloseFileQueue(context);
|
||||
ok(!ret, "Expected failure.\n");
|
||||
ok(GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected error %u.\n", GetLastError());
|
||||
|
||||
SetupTermDefaultQueueCallback(context);
|
||||
}
|
||||
|
||||
START_TEST(install)
|
||||
{
|
||||
char temp_path[MAX_PATH], prev_path[MAX_PATH];
|
||||
|
@ -1113,6 +1855,8 @@ START_TEST(install)
|
|||
test_driver_install();
|
||||
test_dirid();
|
||||
test_install_files_queue();
|
||||
test_need_media();
|
||||
test_close_queue();
|
||||
|
||||
UnhookWindowsHookEx(hhook);
|
||||
|
||||
|
|
|
@ -8,4 +8,4 @@ files:
|
|||
dlls/setupapi/setupcab.c: dll/win32/setupapi/setupcab.c
|
||||
dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable_wine.c
|
||||
tags:
|
||||
wine: 3e5c9798a80641e0e39e95e4467c60405b22b062
|
||||
wine: c65d98065c0038e0919f40bec4a9dc978fb2ade9
|
||||
|
|
Loading…
Reference in a new issue