[SCEDSVC]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 1 Apr 2017 22:54:30 +0000 (22:54 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 1 Apr 2017 22:54:30 +0000 (22:54 +0000)
- Implement a simple job list.
- Implement NetrJobAdd, NetrJobDel and NetrJobGetInfo.

svn path=/trunk/; revision=74262

reactos/base/services/schedsvc/precomp.h
reactos/base/services/schedsvc/rpcserver.c
reactos/base/services/schedsvc/schedsvc.c

index 3fc6975..9f12c8c 100644 (file)
 #include <winreg.h>
 #include <winsvc.h>
 
+#include <ndk/rtlfuncs.h>
+
 #include <atsvc_s.h>
 
 #include <wine/debug.h>
 
+extern LIST_ENTRY JobListHead;
+extern RTL_RESOURCE JobListLock;
+
 DWORD
 WINAPI
 RpcThreadRoutine(
index 6797ce1..d5198eb 100644 (file)
 
 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 *****************************************************************/
 
 DWORD
@@ -85,6 +103,41 @@ NetrJobAdd(
     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++;
+
+    /* Append the new job to the job list */
+    InsertTailList(&JobListHead, &pJob->Entry);
+
+    /* Release the job list lock */
+    RtlReleaseResource(&JobListLock);
+
+    /* Return the new job ID */
+    *pJobId = pJob->JobId;
+
     return ERROR_SUCCESS;
 }
 
@@ -97,6 +150,38 @@ NetrJobDel(
     DWORD MinJobId,
     DWORD MaxJobId)
 {
+    PLIST_ENTRY JobEntry, NextEntry;
+    PJOB CurrentJob;
+
+    TRACE("NetrJobDel(%S %lu %lu)\n",
+          ServerName, MinJobId, MaxJobId);
+
+    /* Acquire the job list lock exclusively */
+    RtlAcquireResourceExclusive(&JobListLock, TRUE);
+
+    JobEntry = JobListHead.Flink;
+    while (JobEntry != &JobListHead)
+    {
+        CurrentJob = CONTAINING_RECORD(JobEntry, JOB, Entry);
+
+        if ((CurrentJob->JobId >= MinJobId) && (CurrentJob->JobId <= MaxJobId))
+        {
+            NextEntry = JobEntry->Flink;
+            if (RemoveEntryList(JobEntry))
+            {
+                dwJobCount--;
+                HeapFree(GetProcessHeap(), 0, CurrentJob);
+                JobEntry = NextEntry;
+                continue;
+            }
+        }
+
+        JobEntry = JobEntry->Flink;
+    }
+
+    /* Release the job list lock */
+    RtlReleaseResource(&JobListLock);
+
     return ERROR_SUCCESS;
 }
 
@@ -111,6 +196,8 @@ NetrJobEnum(
     LPDWORD pTotalEntries,
     LPDWORD pResumeHandle)
 {
+    TRACE("NetrJobEnum(%S %p %lu %p %p)\n",
+          ServerName, pEnumContainer, PreferedMaximumLength, pTotalEntries, pResumeHandle);
     return ERROR_SUCCESS;
 }
 
@@ -123,7 +210,62 @@ NetrJobGetInfo(
     DWORD JobId,
     LPAT_INFO *ppAtInfo)
 {
-    return ERROR_SUCCESS;
+    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, Entry);
+
+        /* 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 */
index 7f479c4..fa64969 100644 (file)
@@ -61,6 +61,7 @@ UpdateServiceStatus(DWORD dwState)
                      &ServiceStatus);
 }
 
+
 static DWORD WINAPI
 ServiceControlHandler(DWORD dwControl,
                       DWORD dwEventType,
@@ -114,20 +115,25 @@ ServiceInit(VOID)
 {
     HANDLE hThread;
 
+    /* Initialize the job list */
+    InitializeListHead(&JobListHead);
+
+    /* Initialize the job list lock */
+    RtlInitializeResource(&JobListLock);
+
     hThread = CreateThread(NULL,
                            0,
                            (LPTHREAD_START_ROUTINE)RpcThreadRoutine,
                            NULL,
                            0,
                            NULL);
-
     if (!hThread)
     {
         ERR("Can't create PortThread\n");
         return GetLastError();
     }
-    else
-        CloseHandle(hThread);
+
+    CloseHandle(hThread);
 
     return ERROR_SUCCESS;
 }