ReactOS  0.4.12-dev-18-gf469aca
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
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 {
77  HeapFree(GetProcessHeap(), 0, ptr);
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  /* Insert the job into the start list */
126 #if 0
128 #endif
129 
130  /* Release the job list lock */
132 
133  /* Set the update event */
134  if (Events[1] != NULL)
135  SetEvent(Events[1]);
136 
137  /* Return the new job ID */
138  *pJobId = pJob->JobId;
139 
140  return ERROR_SUCCESS;
141 }
142 
143 
144 /* Function 1 */
146 WINAPI
148  ATSVC_HANDLE ServerName,
149  DWORD MinJobId,
150  DWORD MaxJobId)
151 {
152  PLIST_ENTRY JobEntry, NextEntry;
153  PJOB CurrentJob;
154 
155  TRACE("NetrJobDel(%S %lu %lu)\n",
156  ServerName, MinJobId, MaxJobId);
157 
158  /* Check the job IDs */
159  if (MinJobId > MaxJobId)
161 
162  /* Acquire the job list lock exclusively */
164 
165  JobEntry = JobListHead.Flink;
166  while (JobEntry != &JobListHead)
167  {
168  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
169 
170  if ((CurrentJob->JobId >= MinJobId) && (CurrentJob->JobId <= MaxJobId))
171  {
172  /* Remove the job from the start list */
173  RemoveEntryList(&CurrentJob->StartEntry);
174 #if 0
176 #endif
177 
178  /* Remove the job from the registry */
179  DeleteJob(CurrentJob);
180 
181  NextEntry = JobEntry->Flink;
182  if (RemoveEntryList(JobEntry))
183  {
184  dwJobCount--;
185  HeapFree(GetProcessHeap(), 0, CurrentJob);
186  JobEntry = NextEntry;
187  continue;
188  }
189  }
190 
191  JobEntry = JobEntry->Flink;
192  }
193 
194  /* Release the job list lock */
196 
197  /* Set the update event */
198  if (Events[1] != NULL)
199  SetEvent(Events[1]);
200 
201  return ERROR_SUCCESS;
202 }
203 
204 
205 /* Function 2 */
207 __stdcall
209  ATSVC_HANDLE ServerName,
210  LPAT_ENUM_CONTAINER pEnumContainer,
211  DWORD PreferedMaximumLength,
212  LPDWORD pTotalEntries,
213  LPDWORD pResumeHandle)
214 {
215  PLIST_ENTRY JobEntry;
216  PJOB CurrentJob;
217  PAT_ENUM pEnum;
218  DWORD dwStartIndex, dwIndex;
219  DWORD dwEntriesToRead, dwEntriesRead;
220  DWORD dwRequiredSize, dwEntrySize;
221  PWSTR pString;
222  DWORD dwError = ERROR_SUCCESS;
223 
224  TRACE("NetrJobEnum(%S %p %lu %p %p)\n",
225  ServerName, pEnumContainer, PreferedMaximumLength, pTotalEntries, pResumeHandle);
226 
227  if (pEnumContainer == NULL)
228  {
229  *pTotalEntries = 0;
231  }
232 
233  if (*pResumeHandle >= dwJobCount)
234  {
235  *pTotalEntries = 0;
236  return ERROR_SUCCESS;
237  }
238 
239  dwStartIndex = *pResumeHandle;
240  TRACE("dwStartIndex: %lu\n", dwStartIndex);
241 
242  /* Acquire the job list lock exclusively */
244 
245  dwEntriesToRead = 0;
246  dwRequiredSize = 0;
247  dwIndex = 0;
248  JobEntry = JobListHead.Flink;
249  while (JobEntry != &JobListHead)
250  {
251  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
252 
253  if (dwIndex >= dwStartIndex)
254  {
255  TRACE("dwIndex: %lu\n", dwIndex);
256  dwEntrySize = sizeof(AT_ENUM) +
257  (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR);
258  TRACE("dwEntrySize: %lu\n", dwEntrySize);
259 
260  if ((PreferedMaximumLength != ULONG_MAX) &&
261  (dwRequiredSize + dwEntrySize > PreferedMaximumLength))
262  break;
263 
264  dwRequiredSize += dwEntrySize;
265  dwEntriesToRead++;
266  }
267 
268  JobEntry = JobEntry->Flink;
269  dwIndex++;
270  }
271  TRACE("dwEntriesToRead: %lu\n", dwEntriesToRead);
272  TRACE("dwRequiredSize: %lu\n", dwRequiredSize);
273 
274  if (PreferedMaximumLength != ULONG_MAX)
275  dwRequiredSize = PreferedMaximumLength;
276 
277  TRACE("Allocating dwRequiredSize: %lu\n", dwRequiredSize);
278  pEnum = midl_user_allocate(dwRequiredSize);
279  if (pEnum == NULL)
280  {
281  dwError = ERROR_OUTOFMEMORY;
282  goto done;
283  }
284 
285  pString = (PWSTR)((ULONG_PTR)pEnum + dwEntriesToRead * sizeof(AT_ENUM));
286 
287  dwEntriesRead = 0;
288  dwIndex = 0;
289  JobEntry = JobListHead.Flink;
290  while (JobEntry != &JobListHead)
291  {
292  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
293 
294  if (dwIndex >= dwStartIndex)
295  {
296  pEnum[dwIndex].JobId = CurrentJob->JobId;
297  pEnum[dwIndex].JobTime = CurrentJob->JobTime;
298  pEnum[dwIndex].DaysOfMonth = CurrentJob->DaysOfMonth;
299  pEnum[dwIndex].DaysOfWeek = CurrentJob->DaysOfWeek;
300  pEnum[dwIndex].Flags = CurrentJob->Flags;
301  pEnum[dwIndex].Command = pString;
302  wcscpy(pString, CurrentJob->Command);
303 
304  pString = (PWSTR)((ULONG_PTR)pString + (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
305 
306  dwEntriesRead++;
307  }
308 
309  if (dwEntriesRead == dwEntriesToRead)
310  break;
311 
312  /* Next job */
313  JobEntry = JobEntry->Flink;
314  dwIndex++;
315  }
316 
317  pEnumContainer->EntriesRead = dwEntriesRead;
318  pEnumContainer->Buffer = pEnum;
319 
320  *pTotalEntries = dwJobCount;
321  *pResumeHandle = dwIndex;
322 
323  if (dwEntriesRead + dwStartIndex < dwJobCount)
324  dwError = ERROR_MORE_DATA;
325  else
326  dwError = ERROR_SUCCESS;
327 
328 done:
329  /* Release the job list lock */
331 
332  return dwError;
333 }
334 
335 
336 /* Function 3 */
338 WINAPI
340  ATSVC_HANDLE ServerName,
341  DWORD JobId,
342  LPAT_INFO *ppAtInfo)
343 {
344  PLIST_ENTRY JobEntry;
345  PJOB CurrentJob;
346  PAT_INFO pInfo;
347  DWORD dwError = ERROR_FILE_NOT_FOUND;
348 
349  TRACE("NetrJobGetInfo(%S %lu %p)\n",
350  ServerName, JobId, ppAtInfo);
351 
352  /* Acquire the job list lock exclusively */
354 
355  /* Traverse the job list */
356  JobEntry = JobListHead.Flink;
357  while (JobEntry != &JobListHead)
358  {
359  CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
360 
361  /* Do we have the right job? */
362  if (CurrentJob->JobId == JobId)
363  {
364  pInfo = midl_user_allocate(sizeof(AT_INFO));
365  if (pInfo == NULL)
366  {
367  dwError = ERROR_OUTOFMEMORY;
368  goto done;
369  }
370 
371  pInfo->Command = midl_user_allocate((wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
372  if (pInfo->Command == NULL)
373  {
374  midl_user_free(pInfo);
375  dwError = ERROR_OUTOFMEMORY;
376  goto done;
377  }
378 
379  pInfo->JobTime = CurrentJob->JobTime;
380  pInfo->DaysOfMonth = CurrentJob->DaysOfMonth;
381  pInfo->DaysOfWeek = CurrentJob->DaysOfWeek;
382  pInfo->Flags = CurrentJob->Flags;
383  wcscpy(pInfo->Command, CurrentJob->Command);
384 
385  *ppAtInfo = pInfo;
386 
387  dwError = ERROR_SUCCESS;
388  goto done;
389  }
390 
391  /* Next job */
392  JobEntry = JobEntry->Flink;
393  }
394 
395 done:
396  /* Release the job list lock */
398 
399  return dwError;
400 }
401 
402 /* EOF */
LIST_ENTRY JobEntry
Definition: precomp.h:33
RTL_RESOURCE JobListLock
Definition: job.c:30
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
DWORD JobId
Definition: precomp.h:39
#define TRUE
Definition: types.h:120
UCHAR Flags
Definition: lmat.h:19
#define ERROR_SUCCESS
Definition: deptool.c:10
LPWSTR Command
Definition: lmat.h:27
VOID InsertJobIntoStartList(_In_ PLIST_ENTRY StartListHead, _In_ PJOB pJob)
Definition: job.c:531
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint16_t * PWSTR
Definition: typedefs.h:54
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:679
DWORD JobTime
Definition: lmat.h:23
#define InsertTailList(ListHead, Entry)
LIST_ENTRY StartListHead
Definition: job.c:32
WCHAR Command[1]
Definition: precomp.h:44
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
LIST_ENTRY JobListHead
Definition: job.c:29
uint32_t ULONG_PTR
Definition: typedefs.h:63
NET_API_STATUS WINAPI NetrJobDel(ATSVC_HANDLE ServerName, DWORD MinJobId, DWORD MaxJobId)
Definition: rpcserver.c:147
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
long RPC_STATUS
Definition: rpc.h:52
UCHAR Flags
Definition: precomp.h:43
DWORD DaysOfMonth
Definition: lmat.h:24
RPC_STATUS WINAPI RpcServerListen(UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait)
Definition: rpc_server.c:1527
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:211
void __RPC_FAR *__RPC_USER midl_user_allocate(SIZE_T len)
Definition: rpcserver.c:69
UCHAR DaysOfWeek
Definition: lmat.h:18
smooth NULL
Definition: ftsmooth.c:416
#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:40
DWORD NET_API_STATUS
Definition: ms-dtyp.idl:91
LPWSTR Command
Definition: lmat.h:20
UCHAR DaysOfWeek
Definition: precomp.h:42
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: lmat.h:14
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static INT DeleteJob(PWSTR pszComputerName, ULONG ulJobId, BOOL bForceDelete)
Definition: at.c:726
DWORD JobTime
Definition: lmat.h:16
Definition: lmat.h:22
WINE_DEFAULT_DEBUG_CHANNEL(schedsvc)
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:1123
#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)
static const WCHAR L[]
Definition: oid.c:1087
LPVOID lpParameter
Definition: kernel32.h:232
GLenum GLsizei len
Definition: glext.h:6722
DWORD WINAPI RpcThreadRoutine(LPVOID lpParameter)
Definition: rpcserver.c:40
Definition: typedefs.h:117
NET_API_STATUS WINAPI NetrJobGetInfo(ATSVC_HANDLE ServerName, DWORD JobId, LPAT_INFO *ppAtInfo)
Definition: rpcserver.c:339
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define WINAPI
Definition: msvc.h:20
Status
Definition: gdiplustypes.h:24
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:934
NET_API_STATUS __stdcall NetrJobEnum(ATSVC_HANDLE ServerName, LPAT_ENUM_CONTAINER pEnumContainer, DWORD PreferedMaximumLength, LPDWORD pTotalEntries, LPDWORD pResumeHandle)
Definition: rpcserver.c:208
LIST_ENTRY StartEntry
Definition: precomp.h:35
#define ERR(fmt,...)
Definition: debug.h:109
UCHAR Flags
Definition: lmat.h:26
ULONG_PTR SIZE_T
Definition: typedefs.h:78
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
Definition: rpcserver.c:75
HANDLE Events[2]
Definition: schedsvc.c:40
DWORD EntriesRead
Definition: atsvc.idl:30
DWORD dwJobCount
Definition: job.c:28
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
DWORD DaysOfMonth
Definition: lmat.h:17
struct _AT_ENUM AT_ENUM
uint32_t * LPDWORD
Definition: typedefs.h:57
VOID DumpStartList(_In_ PLIST_ENTRY StartListHead)
Definition: job.c:582
DWORD DaysOfMonth
Definition: precomp.h:41
DWORD dwNextJobId
Definition: job.c:27
VOID CalculateNextStartTime(_In_ PJOB pJob)
Definition: job.c:468
Definition: precomp.h:31
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
#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)