ReactOS  0.4.15-dev-4916-gd519b11
rpcserver.c
Go to the documentation of this file.
1 /*
2  * ReactOS Services
3  * Copyright (C) 2015 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * COPYRIGHT: See COPYING in the top level directory
21  * PROJECT: ReactOS Services
22  * FILE: base/services/schedsvc/rpcserver.c
23  * PURPOSE: Scheduler service
24  * PROGRAMMER: Eric Kohl <eric.kohl@reactos.org>
25  */
26 
27 /* INCLUDES *****************************************************************/
28 
29 #include "precomp.h"
30 
31 #include "lmerr.h"
32 
34 
35 
36 /* FUNCTIONS *****************************************************************/
37 
38 DWORD
39 WINAPI
41  LPVOID lpParameter)
42 {
44 
45  Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\atsvc", NULL);
46  if (Status != RPC_S_OK)
47  {
48  ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
49  return 0;
50  }
51 
52  Status = RpcServerRegisterIf(atsvc_v1_0_s_ifspec, NULL, NULL);
53  if (Status != RPC_S_OK)
54  {
55  ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status);
56  return 0;
57  }
58 
60  if (Status != RPC_S_OK)
61  {
62  ERR("RpcServerListen() failed (Status %lx)\n", Status);
63  }
64 
65  return 0;
66 }
67 
68 
70 {
72 }
73 
74 
76 {
78 }
79 
80 
81 /* Function 0 */
83 WINAPI
85  ATSVC_HANDLE ServerName,
86  LPAT_INFO pAtInfo,
87  LPDWORD pJobId)
88 {
89  PJOB pJob;
90 
91  TRACE("NetrJobAdd(%S %p %p)\n",
92  ServerName, pAtInfo, pJobId);
93 
94  /* Allocate a new job object */
95  pJob = HeapAlloc(GetProcessHeap(),
97  sizeof(JOB) + wcslen(pAtInfo->Command) * sizeof(WCHAR));
98  if (pJob == NULL)
99  return ERROR_OUTOFMEMORY;
100 
101  /* Initialize the job object */
102  pJob->JobTime = pAtInfo->JobTime;
103  pJob->DaysOfMonth = pAtInfo->DaysOfMonth;
104  pJob->DaysOfWeek = pAtInfo->DaysOfWeek;
105  pJob->Flags = pAtInfo->Flags;
106  wcscpy(pJob->Command, pAtInfo->Command);
107 
108  /* Acquire the job list lock exclusively */
110 
111  /* Assign a new job ID */
112  pJob->JobId = dwNextJobId++;
113  dwJobCount++;
114 
115  /* Append the new job to the job list */
117 
118  /* Save the job in the registry */
119  SaveJob(pJob);
120 
121  /* Calculate the next start time */
123 
124 #if 0
126 #endif
127 
128  /* Release the job list lock */
130 
131  /* Set the update event */
132  if (Events[1] != NULL)
133  SetEvent(Events[1]);
134 
135  /* Return the new job ID */
136  *pJobId = pJob->JobId;
137 
138  return ERROR_SUCCESS;
139 }
140 
141 
142 /* Function 1 */
144 WINAPI
146  ATSVC_HANDLE ServerName,
147  DWORD MinJobId,
148  DWORD MaxJobId)
149 {
150  PLIST_ENTRY JobEntry, NextEntry;
151  PJOB CurrentJob;
152 
153  TRACE("NetrJobDel(%S %lu %lu)\n",
154  ServerName, MinJobId, MaxJobId);
155 
156  /* Check the job IDs */
157  if (MinJobId > MaxJobId)
159 
160  /* Acquire the job list lock exclusively */
162 
163  JobEntry = JobListHead.Flink;
164  while (JobEntry != &JobListHead)
165  {
166  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
167 
168  if ((CurrentJob->JobId >= MinJobId) && (CurrentJob->JobId <= MaxJobId))
169  {
170 #if 0
172 #endif
173 
174  /* Remove the job from the registry */
175  DeleteJob(CurrentJob);
176 
177  NextEntry = JobEntry->Flink;
178  if (RemoveEntryList(JobEntry))
179  {
180  dwJobCount--;
181  HeapFree(GetProcessHeap(), 0, CurrentJob);
182  JobEntry = NextEntry;
183  continue;
184  }
185  }
186 
187  JobEntry = JobEntry->Flink;
188  }
189 
190  /* Release the job list lock */
192 
193  /* Set the update event */
194  if (Events[1] != NULL)
195  SetEvent(Events[1]);
196 
197  return ERROR_SUCCESS;
198 }
199 
200 
201 /* Function 2 */
203 __stdcall
205  ATSVC_HANDLE ServerName,
206  LPAT_ENUM_CONTAINER pEnumContainer,
207  DWORD PreferedMaximumLength,
208  LPDWORD pTotalEntries,
209  LPDWORD pResumeHandle)
210 {
211  PLIST_ENTRY JobEntry;
212  PJOB CurrentJob;
213  PAT_ENUM pEnum;
214  DWORD dwStartIndex, dwIndex;
215  DWORD dwEntriesToRead, dwEntriesRead;
216  DWORD dwRequiredSize, dwEntrySize;
217  PWSTR pString;
218  DWORD dwError = ERROR_SUCCESS;
219 
220  TRACE("NetrJobEnum(%S %p %lu %p %p)\n",
221  ServerName, pEnumContainer, PreferedMaximumLength, pTotalEntries, pResumeHandle);
222 
223  if (pEnumContainer == NULL)
224  {
225  *pTotalEntries = 0;
227  }
228 
229  if (*pResumeHandle >= dwJobCount)
230  {
231  *pTotalEntries = 0;
232  return ERROR_SUCCESS;
233  }
234 
235  dwStartIndex = *pResumeHandle;
236  TRACE("dwStartIndex: %lu\n", dwStartIndex);
237 
238  /* Acquire the job list lock exclusively */
240 
241  dwEntriesToRead = 0;
242  dwRequiredSize = 0;
243  dwIndex = 0;
244  JobEntry = JobListHead.Flink;
245  while (JobEntry != &JobListHead)
246  {
247  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
248 
249  if (dwIndex >= dwStartIndex)
250  {
251  TRACE("dwIndex: %lu\n", dwIndex);
252  dwEntrySize = sizeof(AT_ENUM) +
253  (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR);
254  TRACE("dwEntrySize: %lu\n", dwEntrySize);
255 
256  if ((PreferedMaximumLength != ULONG_MAX) &&
257  (dwRequiredSize + dwEntrySize > PreferedMaximumLength))
258  break;
259 
260  dwRequiredSize += dwEntrySize;
261  dwEntriesToRead++;
262  }
263 
264  JobEntry = JobEntry->Flink;
265  dwIndex++;
266  }
267  TRACE("dwEntriesToRead: %lu\n", dwEntriesToRead);
268  TRACE("dwRequiredSize: %lu\n", dwRequiredSize);
269 
270  if (PreferedMaximumLength != ULONG_MAX)
271  dwRequiredSize = PreferedMaximumLength;
272 
273  TRACE("Allocating dwRequiredSize: %lu\n", dwRequiredSize);
274  pEnum = midl_user_allocate(dwRequiredSize);
275  if (pEnum == NULL)
276  {
277  dwError = ERROR_OUTOFMEMORY;
278  goto done;
279  }
280 
281  pString = (PWSTR)((ULONG_PTR)pEnum + dwEntriesToRead * sizeof(AT_ENUM));
282 
283  dwEntriesRead = 0;
284  dwIndex = 0;
285  JobEntry = JobListHead.Flink;
286  while (JobEntry != &JobListHead)
287  {
288  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
289 
290  if (dwIndex >= dwStartIndex)
291  {
292  pEnum[dwIndex].JobId = CurrentJob->JobId;
293  pEnum[dwIndex].JobTime = CurrentJob->JobTime;
294  pEnum[dwIndex].DaysOfMonth = CurrentJob->DaysOfMonth;
295  pEnum[dwIndex].DaysOfWeek = CurrentJob->DaysOfWeek;
296  pEnum[dwIndex].Flags = CurrentJob->Flags;
297  pEnum[dwIndex].Command = pString;
298  wcscpy(pString, CurrentJob->Command);
299 
300  pString = (PWSTR)((ULONG_PTR)pString + (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
301 
302  dwEntriesRead++;
303  }
304 
305  if (dwEntriesRead == dwEntriesToRead)
306  break;
307 
308  /* Next job */
309  JobEntry = JobEntry->Flink;
310  dwIndex++;
311  }
312 
313  pEnumContainer->EntriesRead = dwEntriesRead;
314  pEnumContainer->Buffer = pEnum;
315 
316  *pTotalEntries = dwJobCount;
317  *pResumeHandle = dwIndex;
318 
319  if (dwEntriesRead + dwStartIndex < dwJobCount)
320  dwError = ERROR_MORE_DATA;
321  else
322  dwError = ERROR_SUCCESS;
323 
324 done:
325  /* Release the job list lock */
327 
328  return dwError;
329 }
330 
331 
332 /* Function 3 */
334 WINAPI
336  ATSVC_HANDLE ServerName,
337  DWORD JobId,
338  LPAT_INFO *ppAtInfo)
339 {
340  PLIST_ENTRY JobEntry;
341  PJOB CurrentJob;
342  PAT_INFO pInfo;
343  DWORD dwError = ERROR_FILE_NOT_FOUND;
344 
345  TRACE("NetrJobGetInfo(%S %lu %p)\n",
346  ServerName, JobId, ppAtInfo);
347 
348  /* Acquire the job list lock exclusively */
350 
351  /* Traverse the job list */
352  JobEntry = JobListHead.Flink;
353  while (JobEntry != &JobListHead)
354  {
355  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
356 
357  /* Do we have the right job? */
358  if (CurrentJob->JobId == JobId)
359  {
360  pInfo = midl_user_allocate(sizeof(AT_INFO));
361  if (pInfo == NULL)
362  {
363  dwError = ERROR_OUTOFMEMORY;
364  goto done;
365  }
366 
367  pInfo->Command = midl_user_allocate((wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
368  if (pInfo->Command == NULL)
369  {
370  midl_user_free(pInfo);
371  dwError = ERROR_OUTOFMEMORY;
372  goto done;
373  }
374 
375  pInfo->JobTime = CurrentJob->JobTime;
376  pInfo->DaysOfMonth = CurrentJob->DaysOfMonth;
377  pInfo->DaysOfWeek = CurrentJob->DaysOfWeek;
378  pInfo->Flags = CurrentJob->Flags;
379  wcscpy(pInfo->Command, CurrentJob->Command);
380 
381  *ppAtInfo = pInfo;
382 
383  dwError = ERROR_SUCCESS;
384  goto done;
385  }
386 
387  /* Next job */
388  JobEntry = JobEntry->Flink;
389  }
390 
391 done:
392  /* Release the job list lock */
394 
395  return dwError;
396 }
397 
398 /* EOF */
LIST_ENTRY JobEntry
Definition: precomp.h:33
RTL_RESOURCE JobListLock
Definition: job.c:30
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
DWORD JobId
Definition: precomp.h:38
WINE_DEFAULT_DEBUG_CHANNEL(browser)
UCHAR Flags
Definition: lmat.h:19
#define ERROR_SUCCESS
Definition: deptool.c:10
LPWSTR Command
Definition: lmat.h:27
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
const wchar_t * ATSVC_HANDLE
Definition: atsvc.idl:7
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD JobTime
Definition: lmat.h:23
#define InsertTailList(ListHead, Entry)
LIST_ENTRY StartListHead
Definition: job.c:32
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
WCHAR Command[1]
Definition: precomp.h:43
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
LIST_ENTRY JobListHead
Definition: job.c:29
uint32_t ULONG_PTR
Definition: typedefs.h:65
NET_API_STATUS WINAPI NetrJobDel(ATSVC_HANDLE ServerName, DWORD MinJobId, DWORD MaxJobId)
Definition: rpcserver.c:145
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
long RPC_STATUS
Definition: rpc.h:52
#define L(x)
Definition: ntvdm.h:50
UCHAR Flags
Definition: precomp.h:42
#define FALSE
Definition: types.h:117
DWORD DaysOfMonth
Definition: lmat.h:24
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
Definition: rpcserver.c:55
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1520
static PVOID ptr
Definition: dispmode.c:27
#define RPC_C_LISTEN_MAX_CALLS_DEFAULT
Definition: rpcdce.h:122
LONG SaveJob(_In_ PJOB pJob)
Definition: job.c:214
UCHAR DaysOfWeek
Definition: lmat.h:18
#define __RPC_FAR
Definition: rpc.h:56
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define __RPC_USER
Definition: rpc.h:65
NET_API_STATUS WINAPI NetrJobAdd(ATSVC_HANDLE ServerName, LPAT_INFO pAtInfo, LPDWORD pJobId)
Definition: rpcserver.c:84
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
DWORD_PTR JobTime
Definition: precomp.h:39
HANDLE Events[3]
Definition: schedsvc.c:40
DWORD NET_API_STATUS
Definition: ms-dtyp.idl:91
Status
Definition: gdiplustypes.h:24
LPWSTR Command
Definition: lmat.h:20
UCHAR DaysOfWeek
Definition: precomp.h:41
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: lmat.h:14
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static INT DeleteJob(PWSTR pszComputerName, ULONG ulJobId, BOOL bForceDelete)
Definition: at.c:726
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD JobTime
Definition: lmat.h:16
Definition: lmat.h:22
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
RPC_STATUS WINAPI RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv)
Definition: rpc_server.c:1116
#define __stdcall
Definition: typedefs.h:25
DWORD JobId
Definition: lmat.h:15
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
NET_API_STATUS WINAPI NetrJobGetInfo(ATSVC_HANDLE ServerName, DWORD JobId, LPAT_INFO *ppAtInfo)
Definition: rpcserver.c:335
#define ERROR_MORE_DATA
Definition: dderror.h:13
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:927
NET_API_STATUS __stdcall NetrJobEnum(ATSVC_HANDLE ServerName, LPAT_ENUM_CONTAINER pEnumContainer, DWORD PreferedMaximumLength, LPDWORD pTotalEntries, LPDWORD pResumeHandle)
Definition: rpcserver.c:204
#define ERR(fmt,...)
Definition: debug.h:110
UCHAR Flags
Definition: lmat.h:26
ULONG_PTR SIZE_T
Definition: typedefs.h:80
FxString * pString
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
Definition: rpcserver.c:20
DWORD EntriesRead
Definition: atsvc.idl:30
DWORD dwJobCount
Definition: job.c:28
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD DaysOfMonth
Definition: lmat.h:17
struct _AT_ENUM AT_ENUM
void __RPC_FAR *__RPC_USER midl_user_allocate(SIZE_T len)
Definition: rpcserver.c:49
uint32_t * LPDWORD
Definition: typedefs.h:59
DWORD DaysOfMonth
Definition: precomp.h:40
DWORD dwNextJobId
Definition: job.c:27
VOID CalculateNextStartTime(_In_ PJOB pJob)
Definition: job.c:467
Definition: precomp.h:31
#define HeapFree(x, y, z)
Definition: compat.h:594
#define ULONG_MAX
Definition: limits.h:44
#define RPC_S_OK
Definition: rpcnterr.h:22
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
LPAT_ENUM Buffer
Definition: atsvc.idl:31
UCHAR DaysOfWeek
Definition: lmat.h:25
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)