xref: /reactos/dll/win32/qmgr/qmgr.c (revision 017748ce)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Queue Manager (BITS) core functions
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2007, 2008 Google (Roy Shea, Dan Hipschman)
5c2c66affSColin Finck  *
6c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14c2c66affSColin Finck  * Lesser General Public License for more details.
15c2c66affSColin Finck  *
16c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck  */
20c2c66affSColin Finck 
21c2c66affSColin Finck #include "qmgr.h"
22*017748ceSAmine Khaldi #include "wine/debug.h"
23*017748ceSAmine Khaldi 
24*017748ceSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
25c2c66affSColin Finck 
26c2c66affSColin Finck BackgroundCopyManagerImpl globalMgr;
27c2c66affSColin Finck 
BackgroundCopyManager_QueryInterface(IBackgroundCopyManager * iface,REFIID riid,void ** ppv)28c2c66affSColin Finck static HRESULT WINAPI BackgroundCopyManager_QueryInterface(IBackgroundCopyManager *iface,
29c2c66affSColin Finck         REFIID riid, void **ppv)
30c2c66affSColin Finck {
31c2c66affSColin Finck     TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
32c2c66affSColin Finck 
33c2c66affSColin Finck     if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IBackgroundCopyManager))
34c2c66affSColin Finck     {
35c2c66affSColin Finck         *ppv = iface;
36c2c66affSColin Finck         IBackgroundCopyManager_AddRef(iface);
37c2c66affSColin Finck         return S_OK;
38c2c66affSColin Finck     }
39c2c66affSColin Finck 
40c2c66affSColin Finck     *ppv = NULL;
41c2c66affSColin Finck     return E_NOINTERFACE;
42c2c66affSColin Finck }
43c2c66affSColin Finck 
BackgroundCopyManager_AddRef(IBackgroundCopyManager * iface)44c2c66affSColin Finck static ULONG WINAPI BackgroundCopyManager_AddRef(IBackgroundCopyManager *iface)
45c2c66affSColin Finck {
46c2c66affSColin Finck     return 2;
47c2c66affSColin Finck }
48c2c66affSColin Finck 
BackgroundCopyManager_Release(IBackgroundCopyManager * iface)49c2c66affSColin Finck static ULONG WINAPI BackgroundCopyManager_Release(IBackgroundCopyManager *iface)
50c2c66affSColin Finck {
51c2c66affSColin Finck     return 1;
52c2c66affSColin Finck }
53c2c66affSColin Finck 
54c2c66affSColin Finck /*** IBackgroundCopyManager interface methods ***/
55c2c66affSColin Finck 
BackgroundCopyManager_CreateJob(IBackgroundCopyManager * iface,LPCWSTR DisplayName,BG_JOB_TYPE Type,GUID * pJobId,IBackgroundCopyJob ** ppJob)56c2c66affSColin Finck static HRESULT WINAPI BackgroundCopyManager_CreateJob(IBackgroundCopyManager *iface,
57c2c66affSColin Finck         LPCWSTR DisplayName, BG_JOB_TYPE Type, GUID *pJobId, IBackgroundCopyJob **ppJob)
58c2c66affSColin Finck {
59c2c66affSColin Finck     BackgroundCopyJobImpl *job;
60c2c66affSColin Finck     HRESULT hres;
61c2c66affSColin Finck 
62c2c66affSColin Finck     TRACE("(%s %d %p %p)\n", debugstr_w(DisplayName), Type, pJobId, ppJob);
63c2c66affSColin Finck 
64c2c66affSColin Finck     hres = BackgroundCopyJobConstructor(DisplayName, Type, pJobId, &job);
65c2c66affSColin Finck     if (FAILED(hres))
66c2c66affSColin Finck         return hres;
67c2c66affSColin Finck 
68c2c66affSColin Finck     /* Add a reference to the job to job list */
69c2c66affSColin Finck     *ppJob = (IBackgroundCopyJob *)&job->IBackgroundCopyJob3_iface;
70c2c66affSColin Finck     IBackgroundCopyJob_AddRef(*ppJob);
71c2c66affSColin Finck     EnterCriticalSection(&globalMgr.cs);
72c2c66affSColin Finck     list_add_head(&globalMgr.jobs, &job->entryFromQmgr);
73c2c66affSColin Finck     LeaveCriticalSection(&globalMgr.cs);
74c2c66affSColin Finck     return S_OK;
75c2c66affSColin Finck }
76c2c66affSColin Finck 
BackgroundCopyManager_GetJob(IBackgroundCopyManager * iface,REFGUID jobID,IBackgroundCopyJob ** job)77c2c66affSColin Finck static HRESULT WINAPI BackgroundCopyManager_GetJob(IBackgroundCopyManager *iface,
78c2c66affSColin Finck         REFGUID jobID, IBackgroundCopyJob **job)
79c2c66affSColin Finck {
80c2c66affSColin Finck     BackgroundCopyManagerImpl *qmgr = &globalMgr;
81c2c66affSColin Finck     HRESULT hr = BG_E_NOT_FOUND;
82c2c66affSColin Finck     BackgroundCopyJobImpl *cur;
83c2c66affSColin Finck 
84c2c66affSColin Finck     TRACE("(%s %p)\n", debugstr_guid(jobID), job);
85c2c66affSColin Finck 
86c2c66affSColin Finck     if (!job || !jobID) return E_INVALIDARG;
87c2c66affSColin Finck 
88c2c66affSColin Finck     *job = NULL;
89c2c66affSColin Finck 
90c2c66affSColin Finck     EnterCriticalSection(&qmgr->cs);
91c2c66affSColin Finck 
92c2c66affSColin Finck     LIST_FOR_EACH_ENTRY(cur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
93c2c66affSColin Finck     {
94c2c66affSColin Finck         if (IsEqualGUID(&cur->jobId, jobID))
95c2c66affSColin Finck         {
96c2c66affSColin Finck             *job = (IBackgroundCopyJob *)&cur->IBackgroundCopyJob3_iface;
97c2c66affSColin Finck             IBackgroundCopyJob3_AddRef(&cur->IBackgroundCopyJob3_iface);
98c2c66affSColin Finck             hr = S_OK;
99c2c66affSColin Finck             break;
100c2c66affSColin Finck         }
101c2c66affSColin Finck     }
102c2c66affSColin Finck 
103c2c66affSColin Finck     LeaveCriticalSection(&qmgr->cs);
104c2c66affSColin Finck 
105c2c66affSColin Finck     return hr;
106c2c66affSColin Finck }
107c2c66affSColin Finck 
BackgroundCopyManager_EnumJobs(IBackgroundCopyManager * iface,DWORD flags,IEnumBackgroundCopyJobs ** ppEnum)108c2c66affSColin Finck static HRESULT WINAPI BackgroundCopyManager_EnumJobs(IBackgroundCopyManager *iface,
109c2c66affSColin Finck         DWORD flags, IEnumBackgroundCopyJobs **ppEnum)
110c2c66affSColin Finck {
111c2c66affSColin Finck     TRACE("(0x%x %p)\n", flags, ppEnum);
112c2c66affSColin Finck     return enum_copy_job_create(&globalMgr, ppEnum);
113c2c66affSColin Finck }
114c2c66affSColin Finck 
BackgroundCopyManager_GetErrorDescription(IBackgroundCopyManager * iface,HRESULT hr,DWORD langid,LPWSTR * error_description)115c2c66affSColin Finck static HRESULT WINAPI BackgroundCopyManager_GetErrorDescription(IBackgroundCopyManager *iface,
116c2c66affSColin Finck         HRESULT hr, DWORD langid, LPWSTR *error_description)
117c2c66affSColin Finck {
118c2c66affSColin Finck     FIXME("(0x%08x 0x%x %p): stub\n", hr, langid, error_description);
119c2c66affSColin Finck     return E_NOTIMPL;
120c2c66affSColin Finck }
121c2c66affSColin Finck 
122c2c66affSColin Finck static const IBackgroundCopyManagerVtbl BackgroundCopyManagerVtbl =
123c2c66affSColin Finck {
124c2c66affSColin Finck     BackgroundCopyManager_QueryInterface,
125c2c66affSColin Finck     BackgroundCopyManager_AddRef,
126c2c66affSColin Finck     BackgroundCopyManager_Release,
127c2c66affSColin Finck     BackgroundCopyManager_CreateJob,
128c2c66affSColin Finck     BackgroundCopyManager_GetJob,
129c2c66affSColin Finck     BackgroundCopyManager_EnumJobs,
130c2c66affSColin Finck     BackgroundCopyManager_GetErrorDescription
131c2c66affSColin Finck };
132c2c66affSColin Finck 
133c2c66affSColin Finck BackgroundCopyManagerImpl globalMgr = {
134c2c66affSColin Finck     { &BackgroundCopyManagerVtbl },
135c2c66affSColin Finck     { NULL, -1, 0, 0, 0, 0 },
136c2c66affSColin Finck     NULL,
137c2c66affSColin Finck     LIST_INIT(globalMgr.jobs)
138c2c66affSColin Finck };
139c2c66affSColin Finck 
140c2c66affSColin Finck /* Constructor for instances of background copy manager */
BackgroundCopyManagerConstructor(LPVOID * ppObj)141c2c66affSColin Finck HRESULT BackgroundCopyManagerConstructor(LPVOID *ppObj)
142c2c66affSColin Finck {
143c2c66affSColin Finck     TRACE("(%p)\n", ppObj);
144c2c66affSColin Finck     *ppObj = &globalMgr;
145c2c66affSColin Finck     return S_OK;
146c2c66affSColin Finck }
147c2c66affSColin Finck 
fileTransfer(void * param)148c2c66affSColin Finck DWORD WINAPI fileTransfer(void *param)
149c2c66affSColin Finck {
150c2c66affSColin Finck     BackgroundCopyManagerImpl *qmgr = &globalMgr;
151c2c66affSColin Finck     HANDLE events[2];
152c2c66affSColin Finck 
153c2c66affSColin Finck     events[0] = stop_event;
154c2c66affSColin Finck     events[1] = qmgr->jobEvent;
155c2c66affSColin Finck 
156c2c66affSColin Finck     for (;;)
157c2c66affSColin Finck     {
158c2c66affSColin Finck         BackgroundCopyJobImpl *job, *jobCur;
159c2c66affSColin Finck         BOOL haveJob = FALSE;
160c2c66affSColin Finck 
161c2c66affSColin Finck         /* Check if it's the stop_event */
162c2c66affSColin Finck         if (WaitForMultipleObjects(2, events, FALSE, INFINITE) == WAIT_OBJECT_0)
163c2c66affSColin Finck         {
164c2c66affSColin Finck             LIST_FOR_EACH_ENTRY_SAFE(job, jobCur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
165c2c66affSColin Finck             {
166c2c66affSColin Finck                 list_remove(&job->entryFromQmgr);
167c2c66affSColin Finck                 IBackgroundCopyJob3_Release(&job->IBackgroundCopyJob3_iface);
168c2c66affSColin Finck             }
169c2c66affSColin Finck             return 0;
170c2c66affSColin Finck         }
171c2c66affSColin Finck 
172c2c66affSColin Finck         /* Note that other threads may add files to the job list, but only
173c2c66affSColin Finck            this thread ever deletes them so we don't need to worry about jobs
174c2c66affSColin Finck            magically disappearing from the list.  */
175c2c66affSColin Finck         EnterCriticalSection(&qmgr->cs);
176c2c66affSColin Finck 
177c2c66affSColin Finck         LIST_FOR_EACH_ENTRY_SAFE(job, jobCur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
178c2c66affSColin Finck         {
179c2c66affSColin Finck             if (job->state == BG_JOB_STATE_ACKNOWLEDGED || job->state == BG_JOB_STATE_CANCELLED)
180c2c66affSColin Finck             {
181c2c66affSColin Finck                 list_remove(&job->entryFromQmgr);
182c2c66affSColin Finck                 IBackgroundCopyJob3_Release(&job->IBackgroundCopyJob3_iface);
183c2c66affSColin Finck             }
184c2c66affSColin Finck             else if (job->state == BG_JOB_STATE_QUEUED)
185c2c66affSColin Finck             {
186c2c66affSColin Finck                 haveJob = TRUE;
187c2c66affSColin Finck                 break;
188c2c66affSColin Finck             }
189c2c66affSColin Finck             else if (job->state == BG_JOB_STATE_CONNECTING
190c2c66affSColin Finck                      || job->state == BG_JOB_STATE_TRANSFERRING)
191c2c66affSColin Finck             {
192c2c66affSColin Finck                 ERR("Invalid state for job %p: %d\n", job, job->state);
193c2c66affSColin Finck             }
194c2c66affSColin Finck         }
195c2c66affSColin Finck 
196c2c66affSColin Finck         if (!haveJob)
197c2c66affSColin Finck             ResetEvent(qmgr->jobEvent);
198c2c66affSColin Finck 
199c2c66affSColin Finck         LeaveCriticalSection(&qmgr->cs);
200c2c66affSColin Finck 
201c2c66affSColin Finck         if (haveJob)
202c2c66affSColin Finck             processJob(job);
203c2c66affSColin Finck     }
204c2c66affSColin Finck }
205