3 * Copyright (C) 2015 ReactOS Team
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.
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.
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.
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>
27 /* INCLUDES *****************************************************************/
33 WINE_DEFAULT_DEBUG_CHANNEL(schedsvc
);
36 /* FUNCTIONS *****************************************************************/
45 Status
= RpcServerUseProtseqEpW(L
"ncacn_np", 20, L
"\\pipe\\atsvc", NULL
);
46 if (Status
!= RPC_S_OK
)
48 ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
52 Status
= RpcServerRegisterIf(atsvc_v1_0_s_ifspec
, NULL
, NULL
);
53 if (Status
!= RPC_S_OK
)
55 ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
59 Status
= RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, FALSE
);
60 if (Status
!= RPC_S_OK
)
62 ERR("RpcServerListen() failed (Status %lx)\n", Status
);
69 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
71 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
75 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
77 HeapFree(GetProcessHeap(), 0, ptr
);
85 ATSVC_HANDLE ServerName
,
91 TRACE("NetrJobAdd(%S %p %p)\n",
92 ServerName
, pAtInfo
, pJobId
);
94 /* Allocate a new job object */
95 pJob
= HeapAlloc(GetProcessHeap(),
97 sizeof(JOB
) + wcslen(pAtInfo
->Command
) * sizeof(WCHAR
));
99 return ERROR_OUTOFMEMORY
;
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
);
108 /* Acquire the job list lock exclusively */
109 RtlAcquireResourceExclusive(&JobListLock
, TRUE
);
111 /* Assign a new job ID */
112 pJob
->JobId
= dwNextJobId
++;
115 /* Append the new job to the job list */
116 InsertTailList(&JobListHead
, &pJob
->JobEntry
);
118 /* Save the job in the registry */
121 /* Calculate the next start time */
122 CalculateNextStartTime(pJob
);
124 /* Insert the job into the start list */
125 InsertJobIntoStartList(&StartListHead
, pJob
);
127 DumpStartList(&StartListHead
);
130 /* Release the job list lock */
131 RtlReleaseResource(&JobListLock
);
133 /* Set the update event */
134 if (Events
[1] != NULL
)
137 /* Return the new job ID */
138 *pJobId
= pJob
->JobId
;
140 return ERROR_SUCCESS
;
148 ATSVC_HANDLE ServerName
,
152 PLIST_ENTRY JobEntry
, NextEntry
;
155 TRACE("NetrJobDel(%S %lu %lu)\n",
156 ServerName
, MinJobId
, MaxJobId
);
158 /* Check the job IDs */
159 if (MinJobId
> MaxJobId
)
160 return ERROR_INVALID_PARAMETER
;
162 /* Acquire the job list lock exclusively */
163 RtlAcquireResourceExclusive(&JobListLock
, TRUE
);
165 JobEntry
= JobListHead
.Flink
;
166 while (JobEntry
!= &JobListHead
)
168 CurrentJob
= CONTAINING_RECORD(JobEntry
, JOB
, JobEntry
);
170 if ((CurrentJob
->JobId
>= MinJobId
) && (CurrentJob
->JobId
<= MaxJobId
))
172 /* Remove the job from the start list */
173 RemoveEntryList(&CurrentJob
->StartEntry
);
175 DumpStartList(&StartListHead
);
178 /* Remove the job from the registry */
179 DeleteJob(CurrentJob
);
181 NextEntry
= JobEntry
->Flink
;
182 if (RemoveEntryList(JobEntry
))
185 HeapFree(GetProcessHeap(), 0, CurrentJob
);
186 JobEntry
= NextEntry
;
191 JobEntry
= JobEntry
->Flink
;
194 /* Release the job list lock */
195 RtlReleaseResource(&JobListLock
);
197 /* Set the update event */
198 if (Events
[1] != NULL
)
201 return ERROR_SUCCESS
;
209 ATSVC_HANDLE ServerName
,
210 LPAT_ENUM_CONTAINER pEnumContainer
,
211 DWORD PreferedMaximumLength
,
212 LPDWORD pTotalEntries
,
213 LPDWORD pResumeHandle
)
215 PLIST_ENTRY JobEntry
;
218 DWORD dwStartIndex
, dwIndex
;
219 DWORD dwEntriesToRead
, dwEntriesRead
;
220 DWORD dwRequiredSize
, dwEntrySize
;
222 DWORD dwError
= ERROR_SUCCESS
;
224 TRACE("NetrJobEnum(%S %p %lu %p %p)\n",
225 ServerName
, pEnumContainer
, PreferedMaximumLength
, pTotalEntries
, pResumeHandle
);
227 if (pEnumContainer
== NULL
)
230 return ERROR_INVALID_PARAMETER
;
233 if (*pResumeHandle
>= dwJobCount
)
236 return ERROR_SUCCESS
;
239 dwStartIndex
= *pResumeHandle
;
240 TRACE("dwStartIndex: %lu\n", dwStartIndex
);
242 /* Acquire the job list lock exclusively */
243 RtlAcquireResourceShared(&JobListLock
, TRUE
);
248 JobEntry
= JobListHead
.Flink
;
249 while (JobEntry
!= &JobListHead
)
251 CurrentJob
= CONTAINING_RECORD(JobEntry
, JOB
, JobEntry
);
253 if (dwIndex
>= dwStartIndex
)
255 TRACE("dwIndex: %lu\n", dwIndex
);
256 dwEntrySize
= sizeof(AT_ENUM
) +
257 (wcslen(CurrentJob
->Command
) + 1) * sizeof(WCHAR
);
258 TRACE("dwEntrySize: %lu\n", dwEntrySize
);
260 if ((PreferedMaximumLength
!= ULONG_MAX
) &&
261 (dwRequiredSize
+ dwEntrySize
> PreferedMaximumLength
))
264 dwRequiredSize
+= dwEntrySize
;
268 JobEntry
= JobEntry
->Flink
;
271 TRACE("dwEntriesToRead: %lu\n", dwEntriesToRead
);
272 TRACE("dwRequiredSize: %lu\n", dwRequiredSize
);
274 if (PreferedMaximumLength
!= ULONG_MAX
)
275 dwRequiredSize
= PreferedMaximumLength
;
277 TRACE("Allocating dwRequiredSize: %lu\n", dwRequiredSize
);
278 pEnum
= midl_user_allocate(dwRequiredSize
);
281 dwError
= ERROR_OUTOFMEMORY
;
285 pString
= (PWSTR
)((ULONG_PTR
)pEnum
+ dwEntriesToRead
* sizeof(AT_ENUM
));
289 JobEntry
= JobListHead
.Flink
;
290 while (JobEntry
!= &JobListHead
)
292 CurrentJob
= CONTAINING_RECORD(JobEntry
, JOB
, JobEntry
);
294 if (dwIndex
>= dwStartIndex
)
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
);
304 pString
= (PWSTR
)((ULONG_PTR
)pString
+ (wcslen(CurrentJob
->Command
) + 1) * sizeof(WCHAR
));
309 if (dwEntriesRead
== dwEntriesToRead
)
313 JobEntry
= JobEntry
->Flink
;
317 pEnumContainer
->EntriesRead
= dwEntriesRead
;
318 pEnumContainer
->Buffer
= pEnum
;
320 *pTotalEntries
= dwJobCount
;
321 *pResumeHandle
= dwIndex
;
323 if (dwEntriesRead
+ dwStartIndex
< dwJobCount
)
324 dwError
= ERROR_MORE_DATA
;
326 dwError
= ERROR_SUCCESS
;
329 /* Release the job list lock */
330 RtlReleaseResource(&JobListLock
);
340 ATSVC_HANDLE ServerName
,
344 PLIST_ENTRY JobEntry
;
347 DWORD dwError
= ERROR_FILE_NOT_FOUND
;
349 TRACE("NetrJobGetInfo(%S %lu %p)\n",
350 ServerName
, JobId
, ppAtInfo
);
352 /* Acquire the job list lock exclusively */
353 RtlAcquireResourceShared(&JobListLock
, TRUE
);
355 /* Traverse the job list */
356 JobEntry
= JobListHead
.Flink
;
357 while (JobEntry
!= &JobListHead
)
359 CurrentJob
= CONTAINING_RECORD(JobEntry
, JOB
, JobEntry
);
361 /* Do we have the right job? */
362 if (CurrentJob
->JobId
== JobId
)
364 pInfo
= midl_user_allocate(sizeof(AT_INFO
));
367 dwError
= ERROR_OUTOFMEMORY
;
371 pInfo
->Command
= midl_user_allocate((wcslen(CurrentJob
->Command
) + 1) * sizeof(WCHAR
));
372 if (pInfo
->Command
== NULL
)
374 midl_user_free(pInfo
);
375 dwError
= ERROR_OUTOFMEMORY
;
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
);
387 dwError
= ERROR_SUCCESS
;
392 JobEntry
= JobEntry
->Flink
;
396 /* Release the job list lock */
397 RtlReleaseResource(&JobListLock
);