+++ /dev/null
-/*
- * ReactOS Services
- * Copyright (C) 2015 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Services
- * FILE: base/services/schedsvc/rpcserver.c
- * PURPOSE: Scheduler service
- * PROGRAMMER: Eric Kohl <eric.kohl@reactos.org>
- */
-
-/* INCLUDES *****************************************************************/
-
-#include "precomp.h"
-
-#include "lmerr.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
-
-
-/* FUNCTIONS *****************************************************************/
-
-DWORD
-WINAPI
-RpcThreadRoutine(
- LPVOID lpParameter)
-{
- RPC_STATUS Status;
-
- Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\atsvc", NULL);
- if (Status != RPC_S_OK)
- {
- ERR("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
- return 0;
- }
-
- Status = RpcServerRegisterIf(atsvc_v1_0_s_ifspec, NULL, NULL);
- if (Status != RPC_S_OK)
- {
- ERR("RpcServerRegisterIf() failed (Status %lx)\n", Status);
- return 0;
- }
-
- Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
- if (Status != RPC_S_OK)
- {
- ERR("RpcServerListen() failed (Status %lx)\n", Status);
- }
-
- return 0;
-}
-
-
-void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
-{
- return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
-}
-
-
-void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
-{
- HeapFree(GetProcessHeap(), 0, ptr);
-}
-
-
-/* Function 0 */
-NET_API_STATUS
-WINAPI
-NetrJobAdd(
- ATSVC_HANDLE ServerName,
- LPAT_INFO pAtInfo,
- LPDWORD pJobId)
-{
- PJOB pJob;
-
- TRACE("NetrJobAdd(%S %p %p)\n",
- ServerName, pAtInfo, pJobId);
-
- /* Allocate a new job object */
- pJob = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(JOB) + wcslen(pAtInfo->Command) * sizeof(WCHAR));
- if (pJob == NULL)
- return ERROR_OUTOFMEMORY;
-
- /* Initialize the job object */
- pJob->JobTime = pAtInfo->JobTime;
- pJob->DaysOfMonth = pAtInfo->DaysOfMonth;
- pJob->DaysOfWeek = pAtInfo->DaysOfWeek;
- pJob->Flags = pAtInfo->Flags;
- wcscpy(pJob->Command, pAtInfo->Command);
-
- /* Acquire the job list lock exclusively */
- RtlAcquireResourceExclusive(&JobListLock, TRUE);
-
- /* Assign a new job ID */
- pJob->JobId = dwNextJobId++;
- dwJobCount++;
-
- // Cancel the start timer
-
- /* Append the new job to the job list */
- InsertTailList(&JobListHead, &pJob->JobEntry);
-
- /* Save the job in the registry */
- SaveJob(pJob);
-
- /* Calculate the next start time */
- CalculateNextStartTime(pJob);
-
- /* Insert the job into the start list */
- InsertJobIntoStartList(&StartListHead, pJob);
-#if 0
- DumpStartList(&StartListHead);
-#endif
-
- // Update the start timer
-
- /* Release the job list lock */
- RtlReleaseResource(&JobListLock);
-
- /* Return the new job ID */
- *pJobId = pJob->JobId;
-
- return ERROR_SUCCESS;
-}
-
-
-/* Function 1 */
-NET_API_STATUS
-WINAPI
-NetrJobDel(
- ATSVC_HANDLE ServerName,
- DWORD MinJobId,
- DWORD MaxJobId)
-{
- PLIST_ENTRY JobEntry, NextEntry;
- PJOB CurrentJob;
-
- TRACE("NetrJobDel(%S %lu %lu)\n",
- ServerName, MinJobId, MaxJobId);
-
- /* Check the job IDs */
- if (MinJobId > MaxJobId)
- return ERROR_INVALID_PARAMETER;
-
- /* Acquire the job list lock exclusively */
- RtlAcquireResourceExclusive(&JobListLock, TRUE);
-
- // Cancel the start timer
-
- JobEntry = JobListHead.Flink;
- while (JobEntry != &JobListHead)
- {
- CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
-
- if ((CurrentJob->JobId >= MinJobId) && (CurrentJob->JobId <= MaxJobId))
- {
- /* Remove the job from the start list */
- RemoveEntryList(&CurrentJob->StartEntry);
-#if 0
- DumpStartList(&StartListHead);
-#endif
-
- /* Remove the job from the registry */
- DeleteJob(CurrentJob);
-
- NextEntry = JobEntry->Flink;
- if (RemoveEntryList(JobEntry))
- {
- dwJobCount--;
- HeapFree(GetProcessHeap(), 0, CurrentJob);
- JobEntry = NextEntry;
- continue;
- }
- }
-
- JobEntry = JobEntry->Flink;
- }
-
- // Update the start timer
-
- /* Release the job list lock */
- RtlReleaseResource(&JobListLock);
-
- return ERROR_SUCCESS;
-}
-
-
-/* Function 2 */
-NET_API_STATUS
-__stdcall
-NetrJobEnum(
- ATSVC_HANDLE ServerName,
- LPAT_ENUM_CONTAINER pEnumContainer,
- DWORD PreferedMaximumLength,
- LPDWORD pTotalEntries,
- LPDWORD pResumeHandle)
-{
- PLIST_ENTRY JobEntry;
- PJOB CurrentJob;
- PAT_ENUM pEnum;
- DWORD dwStartIndex, dwIndex;
- DWORD dwEntriesToRead, dwEntriesRead;
- DWORD dwRequiredSize, dwEntrySize;
- PWSTR pString;
- DWORD dwError = ERROR_SUCCESS;
-
- TRACE("NetrJobEnum(%S %p %lu %p %p)\n",
- ServerName, pEnumContainer, PreferedMaximumLength, pTotalEntries, pResumeHandle);
-
- if (pEnumContainer == NULL)
- {
- *pTotalEntries = 0;
- return ERROR_INVALID_PARAMETER;
- }
-
- if (*pResumeHandle >= dwJobCount)
- {
- *pTotalEntries = 0;
- return ERROR_SUCCESS;
- }
-
- dwStartIndex = *pResumeHandle;
- TRACE("dwStartIndex: %lu\n", dwStartIndex);
-
- /* Acquire the job list lock exclusively */
- RtlAcquireResourceShared(&JobListLock, TRUE);
-
- dwEntriesToRead = 0;
- dwRequiredSize = 0;
- dwIndex = 0;
- JobEntry = JobListHead.Flink;
- while (JobEntry != &JobListHead)
- {
- CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
-
- if (dwIndex >= dwStartIndex)
- {
- TRACE("dwIndex: %lu\n", dwIndex);
- dwEntrySize = sizeof(AT_ENUM) +
- (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR);
- TRACE("dwEntrySize: %lu\n", dwEntrySize);
-
- if ((PreferedMaximumLength != ULONG_MAX) &&
- (dwRequiredSize + dwEntrySize > PreferedMaximumLength))
- break;
-
- dwRequiredSize += dwEntrySize;
- dwEntriesToRead++;
- }
-
- JobEntry = JobEntry->Flink;
- dwIndex++;
- }
- TRACE("dwEntriesToRead: %lu\n", dwEntriesToRead);
- TRACE("dwRequiredSize: %lu\n", dwRequiredSize);
-
- if (PreferedMaximumLength != ULONG_MAX)
- dwRequiredSize = PreferedMaximumLength;
-
- TRACE("Allocating dwRequiredSize: %lu\n", dwRequiredSize);
- pEnum = midl_user_allocate(dwRequiredSize);
- if (pEnum == NULL)
- {
- dwError = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- pString = (PWSTR)((ULONG_PTR)pEnum + dwEntriesToRead * sizeof(AT_ENUM));
-
- dwEntriesRead = 0;
- dwIndex = 0;
- JobEntry = JobListHead.Flink;
- while (JobEntry != &JobListHead)
- {
- CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
-
- if (dwIndex >= dwStartIndex)
- {
- pEnum[dwIndex].JobId = CurrentJob->JobId;
- pEnum[dwIndex].JobTime = CurrentJob->JobTime;
- pEnum[dwIndex].DaysOfMonth = CurrentJob->DaysOfMonth;
- pEnum[dwIndex].DaysOfWeek = CurrentJob->DaysOfWeek;
- pEnum[dwIndex].Flags = CurrentJob->Flags;
- pEnum[dwIndex].Command = pString;
- wcscpy(pString, CurrentJob->Command);
-
- pString = (PWSTR)((ULONG_PTR)pString + (wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
-
- dwEntriesRead++;
- }
-
- if (dwEntriesRead == dwEntriesToRead)
- break;
-
- /* Next job */
- JobEntry = JobEntry->Flink;
- dwIndex++;
- }
-
- pEnumContainer->EntriesRead = dwEntriesRead;
- pEnumContainer->Buffer = pEnum;
-
- *pTotalEntries = dwJobCount;
- *pResumeHandle = dwIndex;
-
- if (dwEntriesRead + dwStartIndex < dwJobCount)
- dwError = ERROR_MORE_DATA;
- else
- dwError = ERROR_SUCCESS;
-
-done:
- /* Release the job list lock */
- RtlReleaseResource(&JobListLock);
-
- return dwError;
-}
-
-
-/* Function 3 */
-NET_API_STATUS
-WINAPI
-NetrJobGetInfo(
- ATSVC_HANDLE ServerName,
- DWORD JobId,
- LPAT_INFO *ppAtInfo)
-{
- PLIST_ENTRY JobEntry;
- PJOB CurrentJob;
- PAT_INFO pInfo;
- DWORD dwError = ERROR_FILE_NOT_FOUND;
-
- TRACE("NetrJobGetInfo(%S %lu %p)\n",
- ServerName, JobId, ppAtInfo);
-
- /* Acquire the job list lock exclusively */
- RtlAcquireResourceShared(&JobListLock, TRUE);
-
- /* Traverse the job list */
- JobEntry = JobListHead.Flink;
- while (JobEntry != &JobListHead)
- {
- CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry);
-
- /* Do we have the right job? */
- if (CurrentJob->JobId == JobId)
- {
- pInfo = midl_user_allocate(sizeof(AT_INFO));
- if (pInfo == NULL)
- {
- dwError = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- pInfo->Command = midl_user_allocate((wcslen(CurrentJob->Command) + 1) * sizeof(WCHAR));
- if (pInfo->Command == NULL)
- {
- midl_user_free(pInfo);
- dwError = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- pInfo->JobTime = CurrentJob->JobTime;
- pInfo->DaysOfMonth = CurrentJob->DaysOfMonth;
- pInfo->DaysOfWeek = CurrentJob->DaysOfWeek;
- pInfo->Flags = CurrentJob->Flags;
- wcscpy(pInfo->Command, CurrentJob->Command);
-
- *ppAtInfo = pInfo;
-
- dwError = ERROR_SUCCESS;
- goto done;
- }
-
- /* Next job */
- JobEntry = JobEntry->Flink;
- }
-
-done:
- /* Release the job list lock */
- RtlReleaseResource(&JobListLock);
-
- return dwError;
-}
-
-/* EOF */