2 * Unit test suite for Background Copy Job Interface
4 * Copyright 2007 Google (Roy Shea)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 /* Globals used by many tests */
33 static WCHAR test_remotePathA
[MAX_PATH
];
34 static WCHAR test_remotePathB
[MAX_PATH
];
35 static WCHAR test_localPathA
[MAX_PATH
];
36 static WCHAR test_localPathB
[MAX_PATH
];
37 static IBackgroundCopyManager
*test_manager
;
38 static IBackgroundCopyJob
*test_job
;
39 static GUID test_jobId
;
40 static BG_JOB_TYPE test_type
;
42 typedef struct IBackgroundCopyCallback2Impl
{
43 IBackgroundCopyCallback2 IBackgroundCopyCallback2_iface
;
45 } IBackgroundCopyCallback2Impl
;
47 static inline IBackgroundCopyCallback2Impl
*impl_from_IBackgroundCopyCallback2(IBackgroundCopyCallback2
*iface
)
49 return CONTAINING_RECORD(iface
, IBackgroundCopyCallback2Impl
, IBackgroundCopyCallback2_iface
);
52 static HRESULT WINAPI
IBackgroundCopyCallback2Impl_QueryInterface(IBackgroundCopyCallback2
*iface
, REFIID riid
, void **ppv
)
54 IBackgroundCopyCallback2Impl
*This
= impl_from_IBackgroundCopyCallback2(iface
);
63 if (IsEqualIID(riid
, &IID_IUnknown
) ||
64 IsEqualIID(riid
, &IID_IBackgroundCopyCallback
) ||
65 IsEqualIID(riid
, &IID_IBackgroundCopyCallback2
))
67 *ppv
= &This
->IBackgroundCopyCallback2_iface
;
74 IUnknown_AddRef((IUnknown
*)*ppv
);
78 static ULONG WINAPI
IBackgroundCopyCallback2Impl_AddRef(IBackgroundCopyCallback2
*iface
)
80 IBackgroundCopyCallback2Impl
*This
= impl_from_IBackgroundCopyCallback2(iface
);
81 ULONG ref
= InterlockedIncrement(&This
->ref
);
83 trace("IBackgroundCopyCallback2Impl_AddRef called (%p, ref = %ld)\n", This
, ref
);
87 static ULONG WINAPI
IBackgroundCopyCallback2Impl_Release(IBackgroundCopyCallback2
*iface
)
89 IBackgroundCopyCallback2Impl
*This
= impl_from_IBackgroundCopyCallback2(iface
);
90 ULONG ref
= InterlockedDecrement(&This
->ref
);
92 trace("IBackgroundCopyCallback2Impl_Release called (%p, ref = %ld)\n", This
, ref
);
96 HeapFree(GetProcessHeap(), 0, This
);
102 static HRESULT WINAPI
IBackgroundCopyCallback2Impl_JobError(IBackgroundCopyCallback2
*iface
, IBackgroundCopyJob
*pJob
, IBackgroundCopyError
*pError
)
104 trace("IBackgroundCopyCallback2Impl_JobError called (%p, %p, %p)\n", iface
, pJob
, pError
);
108 static HRESULT WINAPI
IBackgroundCopyCallback2Impl_JobModification(IBackgroundCopyCallback2
*iface
, IBackgroundCopyJob
*pJob
, DWORD dwReserved
)
110 trace("IBackgroundCopyCallback2Impl_JobModification called (%p, %p)\n", iface
, pJob
);
114 static HRESULT WINAPI
IBackgroundCopyCallback2Impl_JobTransferred(IBackgroundCopyCallback2
*iface
, IBackgroundCopyJob
*pJob
)
116 trace("IBackgroundCopyCallback2Impl_JobTransferred called (%p, %p)\n", iface
, pJob
);
120 static HRESULT WINAPI
IBackgroundCopyCallback2Impl_FileTransferred(IBackgroundCopyCallback2
*iface
, IBackgroundCopyJob
*pJob
, IBackgroundCopyFile
*pFile
)
122 trace("IBackgroundCopyCallback2Impl_FileTransferred called (%p, %p, %p)\n", iface
, pJob
, pFile
);
127 static const IBackgroundCopyCallback2Vtbl copyCallback_vtbl
=
129 IBackgroundCopyCallback2Impl_QueryInterface
,
130 IBackgroundCopyCallback2Impl_AddRef
,
131 IBackgroundCopyCallback2Impl_Release
,
132 IBackgroundCopyCallback2Impl_JobTransferred
,
133 IBackgroundCopyCallback2Impl_JobError
,
134 IBackgroundCopyCallback2Impl_JobModification
,
135 IBackgroundCopyCallback2Impl_FileTransferred
138 static BOOL
create_background_copy_callback2(IBackgroundCopyCallback2
**copyCallback
)
140 IBackgroundCopyCallback2Impl
*obj
;
141 *copyCallback
= NULL
;
143 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*obj
));
147 trace("Out of memory creating IBackgroundCopyCallback2\n");
151 obj
->IBackgroundCopyCallback2_iface
.lpVtbl
= ©Callback_vtbl
;
154 *copyCallback
= &obj
->IBackgroundCopyCallback2_iface
;
159 static HRESULT
test_create_manager(void)
162 IBackgroundCopyManager
*manager
= NULL
;
164 /* Creating BITS instance */
165 hres
= CoCreateInstance(&CLSID_BackgroundCopyManager
, NULL
, CLSCTX_LOCAL_SERVER
,
166 &IID_IBackgroundCopyManager
, (void **) &manager
);
168 if(hres
== HRESULT_FROM_WIN32(ERROR_SERVICE_DISABLED
)) {
169 win_skip("Needed Service is disabled\n");
174 IBackgroundCopyManager_Release(manager
);
179 static void init_paths(void)
181 WCHAR tmpDir
[MAX_PATH
];
182 WCHAR prefix
[] = L
"qmgr";
184 GetTempPathW(MAX_PATH
, tmpDir
);
186 GetTempFileNameW(tmpDir
, prefix
, 0, test_localPathA
);
187 GetTempFileNameW(tmpDir
, prefix
, 0, test_localPathB
);
188 GetTempFileNameW(tmpDir
, prefix
, 0, test_remotePathA
);
189 GetTempFileNameW(tmpDir
, prefix
, 0, test_remotePathB
);
192 /* Generic test setup */
193 static BOOL
setup(void)
196 IBackgroundCopyJob5
* test_job_5
;
197 BITS_JOB_PROPERTY_VALUE prop_val
;
201 memset(&test_jobId
, 0, sizeof test_jobId
);
202 test_type
= BG_JOB_TYPE_DOWNLOAD
;
204 hres
= CoCreateInstance(&CLSID_BackgroundCopyManager
, NULL
,
206 &IID_IBackgroundCopyManager
,
207 (void **) &test_manager
);
211 hres
= IBackgroundCopyManager_CreateJob(test_manager
, L
"Test", test_type
, &test_jobId
, &test_job
);
214 IBackgroundCopyManager_Release(test_manager
);
218 /* The Wine TestBot Windows 10 VMs disable Windows Update by putting
219 the network connection in metered mode.
221 Unfortunately, this will make BITS jobs fail, since the default transfer policy
222 on Windows 10 prevents BITs job from running over a metered network
224 To allow these tests in this file to run on the testbot, we
225 set the BITS_JOB_PROPERTY_ID_COST_FLAGS property to BITS_COST_STATE_TRANSFER_ALWAYS,
226 ensuring that BITS will still try to run the job on a metered network */
227 prop_val
.Dword
= BITS_COST_STATE_TRANSFER_ALWAYS
;
228 hres
= IBackgroundCopyJob_QueryInterface(test_job
, &IID_IBackgroundCopyJob5
, (void **)&test_job_5
);
229 /* BackgroundCopyJob5 was added in Windows 8, so this may not exist. The metered connection
230 workaround is only applied on Windows 10, so it's fine if this fails. */
231 if (SUCCEEDED(hres
)) {
232 hres
= IBackgroundCopyJob5_SetProperty(test_job_5
, BITS_JOB_PROPERTY_ID_COST_FLAGS
, prop_val
);
233 ok(hres
== S_OK
, "Failed to set the cost flags: %08lx\n", hres
);
234 IBackgroundCopyJob5_Release(test_job_5
);
240 /* Generic test cleanup */
241 static void teardown(void)
243 IBackgroundCopyJob_Cancel(test_job
);
244 IBackgroundCopyJob_Release(test_job
);
245 IBackgroundCopyManager_Release(test_manager
);
248 static BOOL
check_bits20(void)
251 IBackgroundCopyManager
*manager
;
252 IBackgroundCopyJob
*job
, *job3
;
254 hres
= CoCreateInstance(&CLSID_BackgroundCopyManager
, NULL
,
255 CLSCTX_LOCAL_SERVER
, &IID_IBackgroundCopyManager
,
257 if (hres
!= S_OK
) return FALSE
;
259 hres
= IBackgroundCopyManager_CreateJob(manager
, L
"Test", test_type
, &test_jobId
, &job
);
262 IBackgroundCopyManager_Release(manager
);
266 hres
= IBackgroundCopyJob_QueryInterface(job
, &IID_IBackgroundCopyJob3
, (void **)&job3
);
267 IBackgroundCopyJob_Cancel(job
);
268 IBackgroundCopyJob_Release(job
);
271 IBackgroundCopyManager_Release(manager
);
275 IBackgroundCopyJob_Release(job3
);
276 IBackgroundCopyManager_Release(manager
);
280 static BOOL
check_bits25(void)
283 IBackgroundCopyManager
*manager
;
284 IBackgroundCopyJob
*job
;
285 IBackgroundCopyJobHttpOptions
*options
;
287 hres
= CoCreateInstance(&CLSID_BackgroundCopyManager
, NULL
,
288 CLSCTX_LOCAL_SERVER
, &IID_IBackgroundCopyManager
,
290 if (hres
!= S_OK
) return FALSE
;
292 hres
= IBackgroundCopyManager_CreateJob(manager
, L
"Test", test_type
, &test_jobId
, &job
);
295 IBackgroundCopyManager_Release(manager
);
299 hres
= IBackgroundCopyJob_QueryInterface(job
, &IID_IBackgroundCopyJobHttpOptions
, (void **)&options
);
300 IBackgroundCopyJob_Cancel(job
);
301 IBackgroundCopyJob_Release(job
);
304 IBackgroundCopyManager_Release(manager
);
308 IBackgroundCopyJobHttpOptions_Release(options
);
309 IBackgroundCopyManager_Release(manager
);
313 /* Test that the jobId is properly set */
314 static void test_GetId(void)
319 hres
= IBackgroundCopyJob_GetId(test_job
, &tmpId
);
320 ok(hres
== S_OK
, "GetId failed: %08lx\n", hres
);
321 ok(memcmp(&tmpId
, &test_jobId
, sizeof tmpId
) == 0, "Got incorrect GUID\n");
324 /* Test that the type is properly set */
325 static void test_GetType(void)
330 hres
= IBackgroundCopyJob_GetType(test_job
, &type
);
331 ok(hres
== S_OK
, "GetType failed: %08lx\n", hres
);
332 ok(type
== test_type
, "Got incorrect type\n");
335 /* Test that the display name is properly set */
336 static void test_GetName(void)
341 hres
= IBackgroundCopyJob_GetDisplayName(test_job
, &displayName
);
342 ok(hres
== S_OK
, "GetName failed: %08lx\n", hres
);
343 ok(lstrcmpW(displayName
, L
"Test") == 0, "Got incorrect type\n");
344 CoTaskMemFree(displayName
);
347 /* Test adding a file */
348 static void test_AddFile(void)
352 hres
= IBackgroundCopyJob_AddFile(test_job
, test_remotePathA
,
354 ok(hres
== S_OK
, "First call to AddFile failed: 0x%08lx\n", hres
);
356 hres
= IBackgroundCopyJob_AddFile(test_job
, test_remotePathB
,
358 ok(hres
== S_OK
, "Second call to AddFile failed: 0x%08lx\n", hres
);
361 /* Test adding a set of files */
362 static void test_AddFileSet(void)
365 BG_FILE_INFO files
[2] =
367 {test_remotePathA
, test_localPathA
},
368 {test_remotePathB
, test_localPathB
}
370 hres
= IBackgroundCopyJob_AddFileSet(test_job
, 2, files
);
371 ok(hres
== S_OK
, "AddFileSet failed: 0x%08lx\n", hres
);
374 /* Test creation of a job enumerator */
375 static void test_EnumFiles(void)
378 IEnumBackgroundCopyFiles
*enumFiles
;
381 hres
= IBackgroundCopyJob_AddFile(test_job
, test_remotePathA
,
383 ok(hres
== S_OK
, "got 0x%08lx\n", hres
);
385 hres
= IBackgroundCopyJob_EnumFiles(test_job
, &enumFiles
);
386 ok(hres
== S_OK
, "EnumFiles failed: 0x%08lx\n", hres
);
388 res
= IEnumBackgroundCopyFiles_Release(enumFiles
);
389 ok(res
== 0, "Bad ref count on release: %lu\n", res
);
392 /* Test getting job progress */
393 static void test_GetProgress_preTransfer(void)
396 BG_JOB_PROGRESS progress
;
398 hres
= IBackgroundCopyJob_GetProgress(test_job
, &progress
);
399 ok(hres
== S_OK
, "GetProgress failed: 0x%08lx\n", hres
);
401 ok(progress
.BytesTotal
== 0, "Incorrect BytesTotal: %s\n",
402 wine_dbgstr_longlong(progress
.BytesTotal
));
403 ok(progress
.BytesTransferred
== 0, "Incorrect BytesTransferred: %s\n",
404 wine_dbgstr_longlong(progress
.BytesTransferred
));
405 ok(progress
.FilesTotal
== 0, "Incorrect FilesTotal: %lu\n", progress
.FilesTotal
);
406 ok(progress
.FilesTransferred
== 0, "Incorrect FilesTransferred %lu\n", progress
.FilesTransferred
);
409 /* Test getting job state */
410 static void test_GetState(void)
415 state
= BG_JOB_STATE_ERROR
;
416 hres
= IBackgroundCopyJob_GetState(test_job
, &state
);
417 ok(hres
== S_OK
, "GetState failed: 0x%08lx\n", hres
);
418 ok(state
== BG_JOB_STATE_SUSPENDED
, "Incorrect job state: %d\n", state
);
421 /* Test resuming a job */
422 static void test_ResumeEmpty(void)
427 hres
= IBackgroundCopyJob_Resume(test_job
);
428 ok(hres
== BG_E_EMPTY
, "Resume failed to return BG_E_EMPTY error: 0x%08lx\n", hres
);
430 state
= BG_JOB_STATE_ERROR
;
431 hres
= IBackgroundCopyJob_GetState(test_job
, &state
);
432 ok(hres
== S_OK
, "got 0x%08lx\n", hres
);
433 ok(state
== BG_JOB_STATE_SUSPENDED
, "Incorrect job state: %d\n", state
);
436 static void makeFile(WCHAR
*name
, const char *contents
)
439 DWORD w
, len
= strlen(contents
);
442 file
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
443 FILE_ATTRIBUTE_NORMAL
, NULL
);
444 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile\n");
445 ok(WriteFile(file
, contents
, len
, &w
, NULL
), "WriteFile\n");
449 static void compareFiles(WCHAR
*n1
, WCHAR
*n2
)
456 f1
= CreateFileW(n1
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
457 FILE_ATTRIBUTE_NORMAL
, NULL
);
458 ok(f1
!= INVALID_HANDLE_VALUE
, "CreateFile\n");
460 f2
= CreateFileW(n2
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
461 FILE_ATTRIBUTE_NORMAL
, NULL
);
462 ok(f2
!= INVALID_HANDLE_VALUE
, "CreateFile\n");
464 /* Neither of these files is very big */
465 ok(ReadFile(f1
, b1
, sizeof b1
, &s1
, NULL
), "ReadFile\n");
466 ok(ReadFile(f2
, b2
, sizeof b2
, &s2
, NULL
), "ReadFile\n");
471 ok(s1
== s2
, "Files differ in length\n");
472 ok(memcmp(b1
, b2
, s1
) == 0, "Files differ in contents\n");
475 /* Handles a timeout in the BG_JOB_STATE_ERROR or BG_JOB_STATE_TRANSIENT_ERROR state */
476 static void handle_job_err(void)
479 IBackgroundCopyError
*err
;
480 BG_ERROR_CONTEXT errContext
;
485 hres
= IBackgroundCopyJob_GetError(test_job
, &err
);
486 if (SUCCEEDED(hres
)) {
487 hres
= IBackgroundCopyError_GetError(err
, &errContext
, &errCode
);
488 if (SUCCEEDED(hres
)) {
489 ok(0, "Got context: %d code: %ld\n", errContext
, errCode
);
491 ok(0, "Failed to get error info: 0x%08lx\n", hres
);
494 hres
= IBackgroundCopyError_GetErrorContextDescription(err
, MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), &contextDesc
);
495 if (SUCCEEDED(hres
)) {
496 ok(0, "Got context desc: %s\n", wine_dbgstr_w(contextDesc
));
498 ok(0, "Failed to get context desc: 0x%08lx\n", hres
);
501 hres
= IBackgroundCopyError_GetErrorDescription(err
, MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), &errDesc
);
502 if (SUCCEEDED(hres
)) {
503 ok(0, "Got error desc: %s\n", wine_dbgstr_w(errDesc
));
505 ok(0, "Failed to get error desc: 0x%08lx\n", hres
);
508 ok(0, "Failed to get error: 0x%08lx\n", hres
);
512 /* Test a complete transfer for local files */
513 static void test_CompleteLocal(void)
515 static const int timeout_sec
= 30;
520 DeleteFileW(test_localPathA
);
521 DeleteFileW(test_localPathB
);
522 makeFile(test_remotePathA
, "This is a WINE test file for BITS\n");
523 makeFile(test_remotePathB
, "This is another WINE test file for BITS\n");
525 hres
= IBackgroundCopyJob_AddFile(test_job
, test_remotePathA
,
527 ok(hres
== S_OK
, "got 0x%08lx\n", hres
);
529 hres
= IBackgroundCopyJob_AddFile(test_job
, test_remotePathB
,
531 ok(hres
== S_OK
, "got 0x%08lx\n", hres
);
533 hres
= IBackgroundCopyJob_Resume(test_job
);
534 ok(hres
== S_OK
, "IBackgroundCopyJob_Resume\n");
536 for (i
= 0; i
< timeout_sec
; ++i
)
538 hres
= IBackgroundCopyJob_GetState(test_job
, &state
);
539 ok(hres
== S_OK
, "IBackgroundCopyJob_GetState\n");
540 ok(state
== BG_JOB_STATE_QUEUED
|| state
== BG_JOB_STATE_CONNECTING
541 || state
== BG_JOB_STATE_TRANSFERRING
|| state
== BG_JOB_STATE_TRANSFERRED
542 || state
== BG_JOB_STATE_TRANSIENT_ERROR
,
543 "Bad state: %d\n", state
);
545 if (state
== BG_JOB_STATE_TRANSIENT_ERROR
) {
546 hres
= IBackgroundCopyJob_Resume(test_job
);
547 ok(hres
== S_OK
, "IBackgroundCopyJob_Resume\n");
550 if (state
== BG_JOB_STATE_TRANSFERRED
)
555 if (state
== BG_JOB_STATE_ERROR
|| state
== BG_JOB_STATE_TRANSIENT_ERROR
)
558 ok(i
< timeout_sec
, "BITS jobs timed out\n");
559 hres
= IBackgroundCopyJob_Complete(test_job
);
560 ok(hres
== S_OK
, "IBackgroundCopyJob_Complete\n");
561 hres
= IBackgroundCopyJob_GetState(test_job
, &state
);
562 ok(hres
== S_OK
, "IBackgroundCopyJob_GetState\n");
563 ok(state
== BG_JOB_STATE_ACKNOWLEDGED
, "Bad state: %d\n", state
);
565 compareFiles(test_remotePathA
, test_localPathA
);
566 compareFiles(test_remotePathB
, test_localPathB
);
568 ok(DeleteFileW(test_remotePathA
), "DeleteFile\n");
569 ok(DeleteFileW(test_remotePathB
), "DeleteFile\n");
570 DeleteFileW(test_localPathA
);
571 DeleteFileW(test_localPathB
);
574 /* Test a complete transfer for local files */
575 static void test_CompleteLocalURL(void)
577 static const int timeout_sec
= 30;
583 DeleteFileW(test_localPathA
);
584 DeleteFileW(test_localPathB
);
585 makeFile(test_remotePathA
, "This is a WINE test file for BITS\n");
586 makeFile(test_remotePathB
, "This is another WINE test file for BITS\n");
588 urlA
= HeapAlloc(GetProcessHeap(), 0,
589 (7 + lstrlenW(test_remotePathA
) + 1) * sizeof urlA
[0]);
590 urlB
= HeapAlloc(GetProcessHeap(), 0,
591 (7 + lstrlenW(test_remotePathB
) + 1) * sizeof urlB
[0]);
594 skip("Unable to allocate memory for URLs\n");
595 HeapFree(GetProcessHeap(), 0, urlA
);
596 HeapFree(GetProcessHeap(), 0, urlB
);
600 lstrcpyW(urlA
, L
"file://");
601 lstrcatW(urlA
, test_remotePathA
);
602 lstrcpyW(urlB
, L
"file://");
603 lstrcatW(urlB
, test_remotePathB
);
605 hres
= IBackgroundCopyJob_AddFile(test_job
, urlA
, test_localPathA
);
606 ok(hres
== S_OK
, "got 0x%08lx\n", hres
);
608 hres
= IBackgroundCopyJob_AddFile(test_job
, urlB
, test_localPathB
);
609 ok(hres
== S_OK
, "got 0x%08lx\n", hres
);
611 hres
= IBackgroundCopyJob_Resume(test_job
);
612 ok(hres
== S_OK
, "IBackgroundCopyJob_Resume\n");
614 for (i
= 0; i
< timeout_sec
; ++i
)
616 hres
= IBackgroundCopyJob_GetState(test_job
, &state
);
617 ok(hres
== S_OK
, "IBackgroundCopyJob_GetState\n");
618 ok(state
== BG_JOB_STATE_QUEUED
|| state
== BG_JOB_STATE_CONNECTING
619 || state
== BG_JOB_STATE_TRANSFERRING
|| state
== BG_JOB_STATE_TRANSFERRED
620 || state
== BG_JOB_STATE_TRANSIENT_ERROR
,
621 "Bad state: %d\n", state
);
623 if (state
== BG_JOB_STATE_TRANSIENT_ERROR
) {
624 hres
= IBackgroundCopyJob_Resume(test_job
);
625 ok(hres
== S_OK
, "IBackgroundCopyJob_Resume\n");
628 if (state
== BG_JOB_STATE_TRANSFERRED
)
633 if (state
== BG_JOB_STATE_ERROR
|| state
== BG_JOB_STATE_TRANSIENT_ERROR
)
637 ok(i
< timeout_sec
, "BITS jobs timed out\n");
638 hres
= IBackgroundCopyJob_Complete(test_job
);
639 ok(hres
== S_OK
, "IBackgroundCopyJob_Complete\n");
640 hres
= IBackgroundCopyJob_GetState(test_job
, &state
);
641 ok(hres
== S_OK
, "IBackgroundCopyJob_GetState\n");
642 ok(state
== BG_JOB_STATE_ACKNOWLEDGED
, "Bad state: %d\n", state
);
644 compareFiles(test_remotePathA
, test_localPathA
);
645 compareFiles(test_remotePathB
, test_localPathB
);
647 ok(DeleteFileW(test_remotePathA
), "DeleteFile\n");
648 ok(DeleteFileW(test_remotePathB
), "DeleteFile\n");
649 DeleteFileW(test_localPathA
);
650 DeleteFileW(test_localPathB
);
652 HeapFree(GetProcessHeap(), 0, urlA
);
653 HeapFree(GetProcessHeap(), 0, urlB
);
656 static void test_NotifyFlags(void)
661 /* check default flags */
663 hr
= IBackgroundCopyJob_GetNotifyFlags(test_job
, &flags
);
664 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
665 ok(flags
== (BG_NOTIFY_JOB_ERROR
| BG_NOTIFY_JOB_TRANSFERRED
), "flags 0x%08lx\n", flags
);
668 static void test_NotifyInterface(void)
673 unk
= (IUnknown
*)0xdeadbeef;
674 hr
= IBackgroundCopyJob_GetNotifyInterface(test_job
, &unk
);
675 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
676 ok(unk
== NULL
, "got %p\n", unk
);
679 static void test_Cancel(void)
684 state
= BG_JOB_STATE_ERROR
;
685 hr
= IBackgroundCopyJob_GetState(test_job
, &state
);
686 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
687 ok(state
!= BG_JOB_STATE_CANCELLED
, "got %u\n", state
);
689 hr
= IBackgroundCopyJob_Cancel(test_job
);
690 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
692 state
= BG_JOB_STATE_ERROR
;
693 hr
= IBackgroundCopyJob_GetState(test_job
, &state
);
694 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
695 ok(state
== BG_JOB_STATE_CANCELLED
, "got %u\n", state
);
697 hr
= IBackgroundCopyJob_Cancel(test_job
);
698 ok(hr
== BG_E_INVALID_STATE
, "got 0x%08lx\n", hr
);
701 static void test_HttpOptions(void)
703 static const WCHAR winetestW
[] = L
"Wine: test\r\n";
704 static const unsigned int timeout
= 30;
706 IBackgroundCopyJobHttpOptions
*options
;
707 IBackgroundCopyError
*error
;
711 ULONG flags
, orig_flags
;
712 IBackgroundCopyCallback2
*copyCallback
;
713 IUnknown
*copyCallbackUnknown
;
715 ok(create_background_copy_callback2(©Callback
) == TRUE
, "create_background_copy_callback2 failed\n");
717 hr
= IBackgroundCopyCallback2_QueryInterface(copyCallback
, &IID_IUnknown
, (LPVOID
*)©CallbackUnknown
);
718 ok(hr
== S_OK
,"IBackgroundCopyCallback_QueryInterface(IID_IUnknown) failed: %08lx\n", hr
);
720 hr
= IBackgroundCopyJob_SetNotifyInterface(test_job
, copyCallbackUnknown
);
721 ok(hr
== S_OK
,"IBackgroundCopyCallback_SetNotifyInterface failed: %08lx\n", hr
);
723 hr
= IBackgroundCopyJob_SetNotifyFlags(test_job
, BG_NOTIFY_JOB_TRANSFERRED
| BG_NOTIFY_JOB_ERROR
| BG_NOTIFY_DISABLE
| BG_NOTIFY_JOB_MODIFICATION
| BG_NOTIFY_FILE_TRANSFERRED
);
724 ok(hr
== S_OK
,"IBackgroundCopyCallback_SetNotifyFlags failed: %08lx\n", hr
);
727 DeleteFileW(test_localPathA
);
728 hr
= IBackgroundCopyJob_AddFile(test_job
, L
"http://test.winehq.org/", test_localPathA
);
729 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
731 hr
= IBackgroundCopyJob_QueryInterface(test_job
, &IID_IBackgroundCopyJobHttpOptions
, (void **)&options
);
732 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
736 headers
= (WCHAR
*)0xdeadbeef;
737 hr
= IBackgroundCopyJobHttpOptions_GetCustomHeaders(options
, &headers
);
738 ok(hr
== S_FALSE
, "got 0x%08lx\n", hr
);
739 ok(headers
== NULL
, "got %p\n", headers
);
741 hr
= IBackgroundCopyJobHttpOptions_SetCustomHeaders(options
, winetestW
);
742 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
744 headers
= (WCHAR
*)0xdeadbeef;
745 hr
= IBackgroundCopyJobHttpOptions_GetCustomHeaders(options
, &headers
);
746 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
749 ok(!lstrcmpW(headers
, winetestW
), "got %s\n", wine_dbgstr_w(headers
));
750 CoTaskMemFree(headers
);
753 hr
= IBackgroundCopyJobHttpOptions_SetCustomHeaders(options
, NULL
);
754 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
756 headers
= (WCHAR
*)0xdeadbeef;
757 hr
= IBackgroundCopyJobHttpOptions_GetCustomHeaders(options
, &headers
);
758 ok(hr
== S_FALSE
, "got 0x%08lx\n", hr
);
759 ok(headers
== NULL
, "got %p\n", headers
);
761 orig_flags
= 0xdeadbeef;
762 hr
= IBackgroundCopyJobHttpOptions_GetSecurityFlags(options
, &orig_flags
);
763 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
764 ok(!orig_flags
, "got 0x%08lx\n", orig_flags
);
766 hr
= IBackgroundCopyJobHttpOptions_SetSecurityFlags(options
, 0);
767 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
770 hr
= IBackgroundCopyJobHttpOptions_GetSecurityFlags(options
, &flags
);
771 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
772 ok(!flags
, "got 0x%08lx\n", flags
);
775 hr
= IBackgroundCopyJob_Resume(test_job
);
776 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
778 for (i
= 0; i
< timeout
; i
++)
780 hr
= IBackgroundCopyJob_GetState(test_job
, &state
);
781 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
783 ok(state
== BG_JOB_STATE_QUEUED
||
784 state
== BG_JOB_STATE_CONNECTING
||
785 state
== BG_JOB_STATE_TRANSFERRING
||
786 state
== BG_JOB_STATE_TRANSFERRED
||
787 state
== BG_JOB_STATE_TRANSIENT_ERROR
, "unexpected state: %u\n", state
);
789 if (state
== BG_JOB_STATE_TRANSIENT_ERROR
) {
790 hr
= IBackgroundCopyJob_Resume(test_job
);
791 ok(hr
== S_OK
, "IBackgroundCopyJob_Resume\n");
794 if (state
== BG_JOB_STATE_TRANSFERRED
) break;
798 if (state
== BG_JOB_STATE_ERROR
|| state
== BG_JOB_STATE_TRANSIENT_ERROR
)
802 ok(i
< timeout
, "BITS job timed out\n");
805 hr
= IBackgroundCopyJob_GetError(test_job
, &error
);
806 ok(hr
== BG_E_ERROR_INFORMATION_UNAVAILABLE
, "got 0x%08lx\n", hr
);
811 headers
= (WCHAR
*)0xdeadbeef;
812 hr
= IBackgroundCopyJobHttpOptions_GetCustomHeaders(options
, &headers
);
813 ok(hr
== S_FALSE
, "got 0x%08lx\n", hr
);
814 ok(headers
== NULL
, "got %p\n", headers
);
816 hr
= IBackgroundCopyJobHttpOptions_SetCustomHeaders(options
, NULL
);
817 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
819 hr
= IBackgroundCopyJobHttpOptions_GetCustomHeaders(options
, &headers
);
820 ok(hr
== S_FALSE
, "got 0x%08lx\n", hr
);
823 hr
= IBackgroundCopyJobHttpOptions_GetSecurityFlags(options
, &flags
);
824 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
825 ok(!flags
, "got 0x%08lx\n", flags
);
827 hr
= IBackgroundCopyJobHttpOptions_SetSecurityFlags(options
, orig_flags
);
828 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
830 IBackgroundCopyJobHttpOptions_Release(options
);
833 hr
= IBackgroundCopyJob_Complete(test_job
);
834 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
836 hr
= IBackgroundCopyJob_GetState(test_job
, &state
);
837 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
838 ok(state
== BG_JOB_STATE_ACKNOWLEDGED
, "unexpected state: %u\n", state
);
840 hr
= IBackgroundCopyJob_Complete(test_job
);
841 ok(hr
== BG_E_INVALID_STATE
, "got 0x%08lx\n", hr
);
843 DeleteFileW(test_localPathA
);
845 hr
= IBackgroundCopyJob_SetNotifyInterface(test_job
, NULL
);
846 ok(hr
== BG_E_INVALID_STATE
, "got 0x%08lx\n", hr
);
848 IUnknown_Release(copyCallbackUnknown
);
849 IBackgroundCopyCallback2_Release(copyCallback
);
852 typedef void (*test_t
)(void);
856 static const test_t tests
[] = {
860 test_GetProgress_preTransfer
,
864 test_NotifyInterface
,
867 static const test_t tests_bits20
[] = {
872 test_CompleteLocalURL
,
873 test_Cancel
, /* must be last */
876 static const test_t tests_bits25
[] = {
886 /* CoInitializeEx and CoInitializeSecurity with RPC_C_IMP_LEVEL_IMPERSONATE
887 * are required to set the job transfer policy
889 hres
= CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
891 ok(0, "CoInitializeEx failed: %0lx\n", hres
);
895 hres
= CoInitializeSecurity(NULL
, -1, NULL
, NULL
,
896 RPC_C_AUTHN_LEVEL_CONNECT
,
897 RPC_C_IMP_LEVEL_IMPERSONATE
,
900 ok(0, "CoInitializeSecurity failed: %0lx\n", hres
);
904 if (FAILED(test_create_manager()))
907 win_skip("Failed to create Manager instance, skipping tests\n");
911 for (test
= tests
, i
= 0; *test
; ++test
, ++i
)
913 /* Keep state separate between tests. */
916 ok(0, "tests:%d: Unable to setup test\n", i
);
925 for (test
= tests_bits20
, i
= 0; *test
; ++test
, ++i
)
927 /* Keep state separate between tests. */
930 ok(0, "tests_bits20:%d: Unable to setup test\n", i
);
939 win_skip("Tests need BITS 2.0 or higher\n");
944 for (test
= tests_bits25
, i
= 0; *test
; ++test
, ++i
)
946 /* Keep state separate between tests. */
949 ok(0, "tests_bits25:%d: Unable to setup test\n", i
);
958 win_skip("Tests need BITS 2.5 or higher\n");