X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fbase%2Fservices%2Fschedsvc%2Frpcserver.c;h=1ca2b353ee219a21f43cbf6192c46ce1236acf8b;hp=d5198eb12cb9e961859ca71786a3fd0b47d99745;hb=6de65ddcea0c33887e86fd3dac02998b2967681e;hpb=0309c0644e868575b8624bff7ccafc36b60292f5 diff --git a/reactos/base/services/schedsvc/rpcserver.c b/reactos/base/services/schedsvc/rpcserver.c index d5198eb12cb..1ca2b353ee2 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,23 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(schedsvc); -typedef struct _JOB -{ - LIST_ENTRY Entry; - DWORD JobId; - - DWORD_PTR JobTime; - DWORD DaysOfMonth; - UCHAR DaysOfWeek; - UCHAR Flags; - WCHAR Command[1]; -} JOB, *PJOB; - -DWORD dwNextJobId = 0; -DWORD dwJobCount = 0; -LIST_ENTRY JobListHead; -RTL_RESOURCE JobListLock; - /* FUNCTIONS *****************************************************************/ @@ -129,8 +112,24 @@ NetrJobAdd( pJob->JobId = dwNextJobId++; dwJobCount++; + // Cancel the start timer + /* Append the new job to the job list */ - InsertTailList(&JobListHead, &pJob->Entry); + 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); @@ -156,16 +155,31 @@ NetrJobDel( 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, Entry); + 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)) { @@ -179,6 +193,8 @@ NetrJobDel( JobEntry = JobEntry->Flink; } + // Update the start timer + /* Release the job list lock */ RtlReleaseResource(&JobListLock); @@ -196,9 +212,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, 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; } @@ -225,7 +356,7 @@ NetrJobGetInfo( JobEntry = JobListHead.Flink; while (JobEntry != &JobListHead) { - CurrentJob = CONTAINING_RECORD(JobEntry, JOB, Entry); + CurrentJob = CONTAINING_RECORD(JobEntry, JOB, JobEntry); /* Do we have the right job? */ if (CurrentJob->JobId == JobId)