[SCEDSVC]
[reactos.git] / reactos / base / services / schedsvc / rpcserver.c
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
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include "precomp.h"
30
31 #include "lmerr.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
34
35 typedef struct _JOB
36 {
37 LIST_ENTRY Entry;
38 DWORD JobId;
39
40 DWORD_PTR JobTime;
41 DWORD DaysOfMonth;
42 UCHAR DaysOfWeek;
43 UCHAR Flags;
44 WCHAR Command[1];
45 } JOB, *PJOB;
46
47 DWORD dwNextJobId = 0;
48 DWORD dwJobCount = 0;
49 LIST_ENTRY JobListHead;
50 RTL_RESOURCE JobListLock;
51
52
53 /* FUNCTIONS *****************************************************************/
54
55 DWORD
56 WINAPI
57 RpcThreadRoutine(
58 LPVOID lpParameter)
59 {
60 RPC_STATUS Status;
61
62 Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\atsvc", NULL);
63 if (Status != RPC_S_OK)
64 {
65 ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
66 return 0;
67 }
68
69 Status = RpcServerRegisterIf(atsvc_v1_0_s_ifspec, NULL, NULL);
70 if (Status != RPC_S_OK)
71 {
72 ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status);
73 return 0;
74 }
75
76 Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
77 if (Status != RPC_S_OK)
78 {
79 ERR("RpcServerListen() failed (Status %lx)\n", Status);
80 }
81
82 return 0;
83 }
84
85
86 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
87 {
88 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
89 }
90
91
92 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
93 {
94 HeapFree(GetProcessHeap(), 0, ptr);
95 }
96
97
98 /* Function 0 */
99 NET_API_STATUS
100 WINAPI
101 NetrJobAdd(
102 ATSVC_HANDLE ServerName,
103 LPAT_INFO pAtInfo,
104 LPDWORD pJobId)
105 {
106 PJOB pJob;
107
108 TRACE("NetrJobAdd(%S %p %p)\n",
109 ServerName, pAtInfo, pJobId);
110
111 /* Allocate a new job object */
112 pJob = HeapAlloc(GetProcessHeap(),
113 HEAP_ZERO_MEMORY,
114 sizeof(JOB) + wcslen(pAtInfo->Command) * sizeof(WCHAR));
115 if (pJob == NULL)
116 return ERROR_OUTOFMEMORY;
117
118 /* Initialize the job object */
119 pJob->JobTime = pAtInfo->JobTime;
120 pJob->DaysOfMonth = pAtInfo->DaysOfMonth;
121 pJob->DaysOfWeek = pAtInfo->DaysOfWeek;
122 pJob->Flags = pAtInfo->Flags;
123 wcscpy(pJob->Command, pAtInfo->Command);
124
125 /* Acquire the job list lock exclusively */
126 RtlAcquireResourceExclusive(&JobListLock, TRUE);
127
128 /* Assign a new job ID */
129 pJob->JobId = dwNextJobId++;
130 dwJobCount++;
131
132 /* Append the new job to the job list */
133 InsertTailList(&JobListHead, &pJob->Entry);
134
135 /* Release the job list lock */
136 RtlReleaseResource(&JobListLock);
137
138 /* Return the new job ID */
139 *pJobId = pJob->JobId;
140
141 return ERROR_SUCCESS;
142 }
143
144
145 /* Function 1 */
146 NET_API_STATUS
147 WINAPI
148 NetrJobDel(
149 ATSVC_HANDLE ServerName,
150 DWORD MinJobId,
151 DWORD MaxJobId)
152 {
153 PLIST_ENTRY JobEntry, NextEntry;
154 PJOB CurrentJob;
155
156 TRACE("NetrJobDel(%S %lu %lu)\n",
157 ServerName, MinJobId, MaxJobId);
158
159 /* Acquire the job list lock exclusively */
160 RtlAcquireResourceExclusive(&JobListLock, TRUE);
161
162 JobEntry = JobListHead.Flink;
163 while (JobEntry != &JobListHead)
164 {
165 CurrentJob = CONTAINING_RECORD(JobEntry, JOB, Entry);
166
167 if ((CurrentJob->JobId >= MinJobId) && (CurrentJob->JobId <= MaxJobId))
168 {
169 NextEntry = JobEntry->Flink;
170 if (RemoveEntryList(JobEntry))
171 {
172 dwJobCount--;
173 HeapFree(GetProcessHeap(), 0, CurrentJob);
174 JobEntry = NextEntry;
175 continue;
176 }
177 }
178
179 JobEntry = JobEntry->Flink;
180 }
181
182 /* Release the job list lock */
183 RtlReleaseResource(&JobListLock);
184
185 return ERROR_SUCCESS;
186 }
187
188
189 /* Function 2 */
190 NET_API_STATUS
191 __stdcall
192 NetrJobEnum(
193 ATSVC_HANDLE ServerName,
194 LPAT_ENUM_CONTAINER pEnumContainer,
195 DWORD PreferedMaximumLength,
196 LPDWORD pTotalEntries,
197 LPDWORD pResumeHandle)
198 {
199 TRACE("NetrJobEnum(%S %p %lu %p %p)\n",
200 ServerName, pEnumContainer, PreferedMaximumLength, pTotalEntries, pResumeHandle);
201 return ERROR_SUCCESS;
202 }
203
204
205 /* Function 3 */
206 NET_API_STATUS
207 WINAPI
208 NetrJobGetInfo(
209 ATSVC_HANDLE ServerName,
210 DWORD JobId,
211 LPAT_INFO *ppAtInfo)
212 {
213 PLIST_ENTRY JobEntry;
214 PJOB CurrentJob;
215 PAT_INFO pInfo;
216 DWORD dwError = ERROR_FILE_NOT_FOUND;
217
218 TRACE("NetrJobGetInfo(%S %lu %p)\n",
219 ServerName, JobId, ppAtInfo);
220
221 /* Acquire the job list lock exclusively */
222 RtlAcquireResourceShared(&JobListLock, TRUE);
223
224 /* Traverse the job list */
225 JobEntry = JobListHead.Flink;
226 while (JobEntry != &JobListHead)
227 {
228 CurrentJob = CONTAINING_RECORD(JobEntry, JOB, Entry);
229
230 /* Do we have the right job? */
231 if (CurrentJob->JobId == JobId)
232 {
233 pInfo = midl_user_allocate(sizeof(AT_INFO));
234 if (pInfo == NULL)
235 {
236 dwError = ERROR_OUTOFMEMORY;
237 goto done;
238 }
239
240 pInfo->Command = midl_user_allocate((wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
241 if (pInfo->Command == NULL)
242 {
243 midl_user_free(pInfo);
244 dwError = ERROR_OUTOFMEMORY;
245 goto done;
246 }
247
248 pInfo->JobTime = CurrentJob->JobTime;
249 pInfo->DaysOfMonth = CurrentJob->DaysOfMonth;
250 pInfo->DaysOfWeek = CurrentJob->DaysOfWeek;
251 pInfo->Flags = CurrentJob->Flags;
252 wcscpy(pInfo->Command, CurrentJob->Command);
253
254 *ppAtInfo = pInfo;
255
256 dwError = ERROR_SUCCESS;
257 goto done;
258 }
259
260 /* Next job */
261 JobEntry = JobEntry->Flink;
262 }
263
264 done:
265 /* Release the job list lock */
266 RtlReleaseResource(&JobListLock);
267
268 return dwError;
269 }
270
271 /* EOF */