2 * Queue Manager (BITS) core functions
4 * Copyright 2007, 2008 Google (Roy Shea, Dan Hipschman)
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
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(qmgr
);
26 BackgroundCopyManagerImpl globalMgr
;
28 static HRESULT WINAPI
BackgroundCopyManager_QueryInterface(IBackgroundCopyManager
*iface
,
29 REFIID riid
, void **ppv
)
31 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
33 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IBackgroundCopyManager
))
36 IBackgroundCopyManager_AddRef(iface
);
44 static ULONG WINAPI
BackgroundCopyManager_AddRef(IBackgroundCopyManager
*iface
)
49 static ULONG WINAPI
BackgroundCopyManager_Release(IBackgroundCopyManager
*iface
)
54 /*** IBackgroundCopyManager interface methods ***/
56 static HRESULT WINAPI
BackgroundCopyManager_CreateJob(IBackgroundCopyManager
*iface
,
57 LPCWSTR DisplayName
, BG_JOB_TYPE Type
, GUID
*pJobId
, IBackgroundCopyJob
**ppJob
)
59 BackgroundCopyJobImpl
*job
;
62 TRACE("(%s %d %p %p)\n", debugstr_w(DisplayName
), Type
, pJobId
, ppJob
);
64 hres
= BackgroundCopyJobConstructor(DisplayName
, Type
, pJobId
, &job
);
68 /* Add a reference to the job to job list */
69 *ppJob
= (IBackgroundCopyJob
*)&job
->IBackgroundCopyJob4_iface
;
70 IBackgroundCopyJob_AddRef(*ppJob
);
71 EnterCriticalSection(&globalMgr
.cs
);
72 list_add_head(&globalMgr
.jobs
, &job
->entryFromQmgr
);
73 LeaveCriticalSection(&globalMgr
.cs
);
77 static HRESULT WINAPI
BackgroundCopyManager_GetJob(IBackgroundCopyManager
*iface
,
78 REFGUID jobID
, IBackgroundCopyJob
**job
)
80 BackgroundCopyManagerImpl
*qmgr
= &globalMgr
;
81 HRESULT hr
= BG_E_NOT_FOUND
;
82 BackgroundCopyJobImpl
*cur
;
84 TRACE("(%s %p)\n", debugstr_guid(jobID
), job
);
86 if (!job
|| !jobID
) return E_INVALIDARG
;
90 EnterCriticalSection(&qmgr
->cs
);
92 LIST_FOR_EACH_ENTRY(cur
, &qmgr
->jobs
, BackgroundCopyJobImpl
, entryFromQmgr
)
94 if (IsEqualGUID(&cur
->jobId
, jobID
))
96 *job
= (IBackgroundCopyJob
*)&cur
->IBackgroundCopyJob4_iface
;
97 IBackgroundCopyJob_AddRef(*job
);
103 LeaveCriticalSection(&qmgr
->cs
);
108 static HRESULT WINAPI
BackgroundCopyManager_EnumJobs(IBackgroundCopyManager
*iface
,
109 DWORD flags
, IEnumBackgroundCopyJobs
**ppEnum
)
111 TRACE("(0x%lx %p)\n", flags
, ppEnum
);
112 return enum_copy_job_create(&globalMgr
, ppEnum
);
115 static HRESULT WINAPI
BackgroundCopyManager_GetErrorDescription(IBackgroundCopyManager
*iface
,
116 HRESULT hr
, DWORD langid
, LPWSTR
*error_description
)
118 FIXME("(0x%08lx 0x%lx %p): stub\n", hr
, langid
, error_description
);
122 static const IBackgroundCopyManagerVtbl BackgroundCopyManagerVtbl
=
124 BackgroundCopyManager_QueryInterface
,
125 BackgroundCopyManager_AddRef
,
126 BackgroundCopyManager_Release
,
127 BackgroundCopyManager_CreateJob
,
128 BackgroundCopyManager_GetJob
,
129 BackgroundCopyManager_EnumJobs
,
130 BackgroundCopyManager_GetErrorDescription
133 BackgroundCopyManagerImpl globalMgr
= {
134 { &BackgroundCopyManagerVtbl
},
135 { NULL
, -1, 0, 0, 0, 0 },
137 LIST_INIT(globalMgr
.jobs
)
140 /* Constructor for instances of background copy manager */
141 HRESULT
BackgroundCopyManagerConstructor(LPVOID
*ppObj
)
143 TRACE("(%p)\n", ppObj
);
148 DWORD WINAPI
fileTransfer(void *param
)
150 BackgroundCopyManagerImpl
*qmgr
= &globalMgr
;
153 events
[0] = stop_event
;
154 events
[1] = qmgr
->jobEvent
;
158 BackgroundCopyJobImpl
*job
, *jobCur
;
159 BOOL haveJob
= FALSE
;
161 /* Check if it's the stop_event */
162 if (WaitForMultipleObjects(2, events
, FALSE
, INFINITE
) == WAIT_OBJECT_0
)
164 LIST_FOR_EACH_ENTRY_SAFE(job
, jobCur
, &qmgr
->jobs
, BackgroundCopyJobImpl
, entryFromQmgr
)
166 list_remove(&job
->entryFromQmgr
);
167 IBackgroundCopyJob4_Release(&job
->IBackgroundCopyJob4_iface
);
172 /* Note that other threads may add files to the job list, but only
173 this thread ever deletes them so we don't need to worry about jobs
174 magically disappearing from the list. */
175 EnterCriticalSection(&qmgr
->cs
);
177 LIST_FOR_EACH_ENTRY_SAFE(job
, jobCur
, &qmgr
->jobs
, BackgroundCopyJobImpl
, entryFromQmgr
)
179 if (job
->state
== BG_JOB_STATE_ACKNOWLEDGED
|| job
->state
== BG_JOB_STATE_CANCELLED
)
181 list_remove(&job
->entryFromQmgr
);
182 IBackgroundCopyJob4_Release(&job
->IBackgroundCopyJob4_iface
);
184 else if (job
->state
== BG_JOB_STATE_QUEUED
)
189 else if (job
->state
== BG_JOB_STATE_CONNECTING
190 || job
->state
== BG_JOB_STATE_TRANSFERRING
)
192 ERR("Invalid state for job %p: %d\n", job
, job
->state
);
197 ResetEvent(qmgr
->jobEvent
);
199 LeaveCriticalSection(&qmgr
->cs
);