Author: ekohl
Date: Sun Apr 2 20:47:48 2017
New Revision: 74272
URL:
http://svn.reactos.org/svn/reactos?rev=74272&view=rev
Log:
[SCHEDSVC]
Implement NetsJobEnum.
Modified:
trunk/reactos/base/services/schedsvc/rpcserver.c
Modified: trunk/reactos/base/services/schedsvc/rpcserver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/schedsvc/rpc…
==============================================================================
--- trunk/reactos/base/services/schedsvc/rpcserver.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/schedsvc/rpcserver.c [iso-8859-1] Sun Apr 2 20:47:48
2017
@@ -21,7 +21,7 @@
* PROJECT: ReactOS Services
* FILE: base/services/schedsvc/rpcserver.c
* PURPOSE: Scheduler service
- * PROGRAMMER: Eric Kohl
+ * PROGRAMMER: Eric Kohl <eric.kohl(a)reactos.org>
*/
/* INCLUDES *****************************************************************/
@@ -31,6 +31,8 @@
#include "lmerr.h"
WINE_DEFAULT_DEBUG_CHANNEL(schedsvc);
+
+#define DWORD_MAX 0xffffffffUL
typedef struct _JOB
{
@@ -196,9 +198,124 @@
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;
}