From 048ad653f47ed796c2567fd4152b5b5c73a8bcf8 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 2 Apr 2017 20:47:48 +0000 Subject: [PATCH] [SCHEDSVC] Implement NetsJobEnum. svn path=/trunk/; revision=74272 --- reactos/base/services/schedsvc/rpcserver.c | 121 ++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/reactos/base/services/schedsvc/rpcserver.c b/reactos/base/services/schedsvc/rpcserver.c index d5198eb12cb..f35180201cd 100644 --- a/reactos/base/services/schedsvc/rpcserver.c +++ b/reactos/base/services/schedsvc/rpcserver.c @@ -21,7 +21,7 @@ * PROJECT: ReactOS Services * FILE: base/services/schedsvc/rpcserver.c * PURPOSE: Scheduler service - * PROGRAMMER: Eric Kohl + * PROGRAMMER: Eric Kohl */ /* INCLUDES *****************************************************************/ @@ -32,6 +32,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(schedsvc); +#define DWORD_MAX 0xffffffffUL + typedef struct _JOB { LIST_ENTRY Entry; @@ -196,9 +198,124 @@ NetrJobEnum( 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); - return ERROR_SUCCESS; + + 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, Entry); + + 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 != DWORD_MAX) && + (dwRequiredSize + dwEntrySize > PreferedMaximumLength)) + break; + + dwRequiredSize += dwEntrySize; + dwEntriesToRead++; + } + + JobEntry = JobEntry->Flink; + dwIndex++; + } + TRACE("dwEntriesToRead: %lu\n", dwEntriesToRead); + TRACE("dwRequiredSize: %lu\n", dwRequiredSize); + + if (PreferedMaximumLength != DWORD_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, Entry); + + 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; }