[SPOOLSS, SPOOLSV, WINSPOOL]
authorColin Finck <colin@reactos.org>
Sat, 27 Jun 2015 12:36:45 +0000 (12:36 +0000)
committerColin Finck <colin@reactos.org>
Sat, 27 Jun 2015 12:36:45 +0000 (12:36 +0000)
Connect AddJobW, EnumJobsW, GetJobW and SetJobW from winspool.drv over spoolsv.exe and spoolss.dll to the implemented functions in localspl.dll (including marshalling the involved structures down and up).
I decided to not use my recently implemented MarshallDownStructure API here and rather do the pointer math in place as this is simpler and faster.

svn path=/branches/colins-printing-for-freedom/; revision=68288

reactos/win32ss/printing/base/spoolss/jobs.c
reactos/win32ss/printing/base/spoolss/spoolss.spec
reactos/win32ss/printing/base/spoolsv/jobs.c
reactos/win32ss/printing/base/spoolsv/rpcstubs.c
reactos/win32ss/printing/base/winspool/jobs.c
reactos/win32ss/printing/base/winspool/winspool.spec

index a44b776..2ecaba1 100644 (file)
@@ -8,13 +8,25 @@
 #include "precomp.h"
 
 BOOL WINAPI
-AddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
+AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
 {
     return LocalSplFuncs.fpAddJob(hPrinter, Level, pData, cbBuf, pcbNeeded);
 }
 
 BOOL WINAPI
-GetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded)
+EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+{
+    return LocalSplFuncs.fpEnumJobs(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
+}
+
+BOOL WINAPI
+GetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded)
 {
     return LocalSplFuncs.fpGetJob(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
 }
+
+BOOL WINAPI
+SetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
+{
+    return LocalSplFuncs.fpSetJob(hPrinter, JobId, Level, pJobInfo, Command);
+}
index 4fcd3be..e453921 100644 (file)
@@ -59,7 +59,7 @@
 @ stdcall EndDocPrinter(long)
 @ stdcall EndPagePrinter(long)
 @ stub EnumFormsW
-@ stub EnumJobsW
+@ stdcall EnumJobsW(long long long long ptr long ptr ptr)
 @ stub EnumMonitorsW
 @ stub EnumPerMachineConnectionsW
 @ stub EnumPortsW
 @ stub SendRecvBidiData
 @ stub SetAllocFailCount
 @ stub SetFormW
-@ stub SetJobW
+@ stdcall SetJobW(long long long ptr long)
 @ stub SetPortW
 @ stub SetPrinterDataExW
 @ stub SetPrinterDataW
index 15f56d6..29d3692 100644 (file)
@@ -7,10 +7,53 @@
 
 #include "precomp.h"
 
+static void
+_MarshallDownJobInfo(PBYTE pJobInfo, DWORD Level)
+{
+    PJOB_INFO_1W pJobInfo1;
+    PJOB_INFO_2W pJobInfo2;
+
+    // Replace absolute pointer addresses in the output by relative offsets.
+    if (Level == 1)
+    {
+        pJobInfo1 = (PJOB_INFO_1W)pJobInfo;
+        pJobInfo1->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo1->pDatatype - (ULONG_PTR)pJobInfo1);
+        pJobInfo1->pDocument = (PWSTR)((ULONG_PTR)pJobInfo1->pDocument - (ULONG_PTR)pJobInfo1);
+        pJobInfo1->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo1->pMachineName - (ULONG_PTR)pJobInfo1);
+        pJobInfo1->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo1->pPrinterName - (ULONG_PTR)pJobInfo1);
+
+        if (pJobInfo1->pStatus)
+            pJobInfo1->pStatus = (PWSTR)((ULONG_PTR)pJobInfo1->pStatus - (ULONG_PTR)pJobInfo1);
+
+        pJobInfo1->pUserName = (PWSTR)((ULONG_PTR)pJobInfo1->pUserName - (ULONG_PTR)pJobInfo1);
+    }
+    else if (Level == 2)
+    {
+        pJobInfo2 = (PJOB_INFO_2W)pJobInfo;
+        pJobInfo2->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo2->pDatatype - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pJobInfo2->pDevMode - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pDocument = (PWSTR)((ULONG_PTR)pJobInfo2->pDocument - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pDriverName = (PWSTR)((ULONG_PTR)pJobInfo2->pDriverName - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo2->pMachineName - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pNotifyName = (PWSTR)((ULONG_PTR)pJobInfo2->pNotifyName - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo2->pPrinterName - (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pJobInfo2->pPrintProcessor - (ULONG_PTR)pJobInfo2);
+
+        if (pJobInfo2->pParameters)
+            pJobInfo2->pParameters = (PWSTR)((ULONG_PTR)pJobInfo2->pParameters - (ULONG_PTR)pJobInfo2);
+
+        if (pJobInfo2->pStatus)
+            pJobInfo2->pStatus = (PWSTR)((ULONG_PTR)pJobInfo2->pStatus - (ULONG_PTR)pJobInfo2);
+
+        pJobInfo2->pUserName = (PWSTR)((ULONG_PTR)pJobInfo2->pUserName - (ULONG_PTR)pJobInfo2);
+    }
+}
+
 DWORD
 _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD cbBuf, DWORD* pcbNeeded)
 {
     DWORD dwErrorCode;
+    PADDJOB_INFO_1W pAddJobInfo1;
 
     dwErrorCode = RpcImpersonateClient(NULL);
     if (dwErrorCode != ERROR_SUCCESS)
@@ -22,6 +65,48 @@ _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD c
     AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
     dwErrorCode = GetLastError();
 
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace absolute pointer addresses in the output by relative offsets.
+        pAddJobInfo1 = (PADDJOB_INFO_1W)pAddJob;
+        pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path - (ULONG_PTR)pAddJobInfo1);
+    }
+
+    RpcRevertToSelf();
+    return dwErrorCode;
+}
+
+DWORD
+_RpcEnumJobs(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, BYTE* pJob, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
+{
+    DWORD dwErrorCode;
+    DWORD i;
+    PBYTE p = pJob;
+
+    dwErrorCode = RpcImpersonateClient(NULL);
+    if (dwErrorCode != ERROR_SUCCESS)
+    {
+        ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
+        return dwErrorCode;
+    }
+
+    EnumJobsW(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
+    dwErrorCode = GetLastError();
+
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace absolute pointer addresses in the output by relative offsets.
+        for (i = 0; i < *pcReturned; i++)
+        {
+            _MarshallDownJobInfo(p, Level);
+
+            if (Level == 1)
+                p += sizeof(JOB_INFO_1W);
+            else if (Level == 2)
+                p += sizeof(JOB_INFO_2W);
+        }
+    }
+
     RpcRevertToSelf();
     return dwErrorCode;
 }
@@ -41,6 +126,12 @@ _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, DWORD Level, BYTE* pJo
     GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
     dwErrorCode = GetLastError();
 
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace absolute pointer addresses in the output by relative offsets.
+        _MarshallDownJobInfo(pJob, Level);
+    }
+
     RpcRevertToSelf();
     return dwErrorCode;
 }
@@ -55,6 +146,19 @@ _RpcScheduleJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId)
 DWORD
 _RpcSetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, WINSPOOL_JOB_CONTAINER* pJobContainer, DWORD Command)
 {
-    UNIMPLEMENTED;
-    return ERROR_INVALID_FUNCTION;
+    DWORD dwErrorCode;
+
+    dwErrorCode = RpcImpersonateClient(NULL);
+    if (dwErrorCode != ERROR_SUCCESS)
+    {
+        ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
+        return dwErrorCode;
+    }
+
+    // pJobContainer->JobInfo is a union of pointers, so we can just convert any element to our BYTE pointer.
+    SetJobW(hPrinter, JobId, pJobContainer->Level, (PBYTE)pJobContainer->JobInfo.Level1, Command);
+    dwErrorCode = GetLastError();
+
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
index 897a100..209f529 100644 (file)
@@ -7,13 +7,6 @@
 
 #include "precomp.h"
 
-DWORD
-_RpcEnumJobs(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, BYTE *pJob, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned)
-{
-    UNIMPLEMENTED;
-    return ERROR_INVALID_FUNCTION;
-}
-
 DWORD
 _RpcAddPrinter(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER *pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER *pDevModeContainer, WINSPOOL_SECURITY_CONTAINER *pSecurityContainer, WINSPOOL_PRINTER_HANDLE *pHandle)
 {
index 5866141..890bab9 100644 (file)
 
 #include "precomp.h"
 
+static void
+_MarshallUpJobInfo(PBYTE pJobInfo, DWORD Level)
+{
+    PJOB_INFO_1W pJobInfo1;
+    PJOB_INFO_2W pJobInfo2;
+
+    // Replace absolute pointer addresses in the output by relative offsets.
+    if (Level == 1)
+    {
+        pJobInfo1 = (PJOB_INFO_1W)pJobInfo;
+        pJobInfo1->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo1->pDatatype + (ULONG_PTR)pJobInfo1);
+        pJobInfo1->pDocument = (PWSTR)((ULONG_PTR)pJobInfo1->pDocument + (ULONG_PTR)pJobInfo1);
+        pJobInfo1->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo1->pMachineName + (ULONG_PTR)pJobInfo1);
+        pJobInfo1->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo1->pPrinterName + (ULONG_PTR)pJobInfo1);
+
+        if (pJobInfo1->pStatus)
+            pJobInfo1->pStatus = (PWSTR)((ULONG_PTR)pJobInfo1->pStatus + (ULONG_PTR)pJobInfo1);
+
+        pJobInfo1->pUserName = (PWSTR)((ULONG_PTR)pJobInfo1->pUserName + (ULONG_PTR)pJobInfo1);
+    }
+    else if (Level == 2)
+    {
+        pJobInfo2 = (PJOB_INFO_2W)pJobInfo;
+        pJobInfo2->pDatatype = (PWSTR)((ULONG_PTR)pJobInfo2->pDatatype + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pJobInfo2->pDevMode + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pDocument = (PWSTR)((ULONG_PTR)pJobInfo2->pDocument + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pDriverName = (PWSTR)((ULONG_PTR)pJobInfo2->pDriverName + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pMachineName = (PWSTR)((ULONG_PTR)pJobInfo2->pMachineName + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pNotifyName = (PWSTR)((ULONG_PTR)pJobInfo2->pNotifyName + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pJobInfo2->pPrinterName + (ULONG_PTR)pJobInfo2);
+        pJobInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pJobInfo2->pPrintProcessor + (ULONG_PTR)pJobInfo2);
+
+        if (pJobInfo2->pParameters)
+            pJobInfo2->pParameters = (PWSTR)((ULONG_PTR)pJobInfo2->pParameters + (ULONG_PTR)pJobInfo2);
+
+        if (pJobInfo2->pStatus)
+            pJobInfo2->pStatus = (PWSTR)((ULONG_PTR)pJobInfo2->pStatus + (ULONG_PTR)pJobInfo2);
+
+        pJobInfo2->pUserName = (PWSTR)((ULONG_PTR)pJobInfo2->pUserName + (ULONG_PTR)pJobInfo2);
+    }
+}
+
 BOOL WINAPI
-AddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
+AddJobA(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
+{
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
+BOOL WINAPI
+AddJobW(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
 {
-    BOOL bReturnValue = FALSE;
     DWORD dwErrorCode;
+    PADDJOB_INFO_1W pAddJobInfo1;
 
     // Do the RPC call
     RpcTryExcept
     {
         dwErrorCode = _RpcAddJob(hPrinter, Level, pData, cbBuf, pcbNeeded);
-        SetLastError(dwErrorCode);
-        bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
-        ERR("_RpcAddJob failed with exception code %lu!\n", RpcExceptionCode());
+        dwErrorCode = RpcExceptionCode();
+        ERR("_RpcAddJob failed with exception code %lu!\n", dwErrorCode);
+    }
+    RpcEndExcept;
+
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace relative offset addresses in the output by absolute pointers.
+        pAddJobInfo1 = (PADDJOB_INFO_1W)pData;
+        pAddJobInfo1->Path = (PWSTR)((ULONG_PTR)pAddJobInfo1->Path + (ULONG_PTR)pAddJobInfo1);
+    }
+
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
+}
+
+BOOL WINAPI
+EnumJobsA(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+{
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
+BOOL WINAPI
+EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+{
+    DWORD dwErrorCode;
+    DWORD i;
+    PBYTE p = pJob;
+
+    // Do the RPC call
+    RpcTryExcept
+    {
+        dwErrorCode = _RpcEnumJobs(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwErrorCode = RpcExceptionCode();
+        ERR("_RpcEnumJobs failed with exception code %lu!\n", dwErrorCode);
     }
     RpcEndExcept;
 
-    return bReturnValue;
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace relative offset addresses in the output by absolute pointers.
+        for (i = 0; i < *pcReturned; i++)
+        {
+            _MarshallUpJobInfo(p, Level);
+
+            if (Level == 1)
+                p += sizeof(JOB_INFO_1W);
+            else if (Level == 2)
+                p += sizeof(JOB_INFO_2W);
+        }
+    }
+
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
+}
+
+BOOL WINAPI
+GetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded)
+{
+    UNIMPLEMENTED;
+    return FALSE;
 }
 
 BOOL WINAPI
-GetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded)
+GetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD pcbNeeded)
 {
-    BOOL bReturnValue = FALSE;
     DWORD dwErrorCode;
 
     // Do the RPC call
     RpcTryExcept
     {
         dwErrorCode = _RpcGetJob(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
-        SetLastError(dwErrorCode);
-        bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
-        ERR("_RpcGetJob failed with exception code %lu!\n", RpcExceptionCode());
+        dwErrorCode = RpcExceptionCode();
+        ERR("_RpcGetJob failed with exception code %lu!\n", dwErrorCode);
+    }
+    RpcEndExcept;
+
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace relative offset addresses in the output by absolute pointers.
+        _MarshallUpJobInfo(pJob, Level);
+    }
+
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
+}
+
+BOOL WINAPI
+SetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
+{
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
+BOOL WINAPI
+SetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
+{
+    DWORD dwErrorCode;
+    WINSPOOL_JOB_CONTAINER JobContainer;
+
+    // pJobContainer->JobInfo is a union of pointers, so we can just set any element to our BYTE pointer.
+    JobContainer.Level = Level;
+    JobContainer.JobInfo.Level1 = (WINSPOOL_JOB_INFO_1*)pJobInfo;
+
+    // Do the RPC call
+    RpcTryExcept
+    {
+        dwErrorCode = _RpcSetJob(hPrinter, JobId, &JobContainer, Command);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwErrorCode = RpcExceptionCode();
+        ERR("_RpcSetJob failed with exception code %lu!\n", dwErrorCode);
     }
     RpcEndExcept;
 
-    return bReturnValue;
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
index 8989261..09cb690 100644 (file)
@@ -9,7 +9,7 @@
 108 stub AbortPrinter
 109 stub AddFormA
 110 stub AddFormW
-111 stub AddJobA
+111 stdcall AddJobA(long long ptr long ptr)
 112 stdcall AddJobW(long long ptr long ptr)
 113 stub AddMonitorA
 114 stub AddMonitorW
@@ -83,8 +83,8 @@
 182 stdcall EndPagePrinter(long)
 183 stub EnumFormsA
 184 stub EnumFormsW
-185 stub EnumJobsA
-186 stub EnumJobsW
+185 stdcall EnumJobsA(long long long long ptr long ptr ptr)
+186 stdcall EnumJobsW(long long long long ptr long ptr ptr)
 187 stub EnumMonitorsA
 188 stub EnumMonitorsW
 189 stub EnumPortsA
 241 stub FreePrinterNotifyInfo
 242 stub GetFormA
 243 stub GetFormW
-244 stub GetJobA
+244 stdcall GetJobA(long long long ptr long ptr)
 245 stdcall GetJobW(long long long ptr long ptr)
 246 stub GetPrintProcessorDirectoryA
 247 stdcall GetPrintProcessorDirectoryW(wstr wstr long ptr long ptr)
 275 stub SetAllocFailCount
 276 stub SetFormA
 277 stub SetFormW
-278 stub SetJobA
-279 stub SetJobW
+278 stdcall SetJobA(long long long ptr long)
+279 stdcall SetJobW(long long long ptr long)
 280 stub SetPortA
 281 stub SetPortW
 282 stub SetPrinterA