[WINSPOOL]
[reactos.git] / reactos / win32ss / printing / base / winspool / printers.c
index c4b95ea..ef447d9 100644 (file)
@@ -7,6 +7,45 @@
 
 #include "precomp.h"
 
+static void
+_MarshallUpPrinterInfo(PBYTE pPrinterInfo, DWORD Level)
+{
+    PPRINTER_INFO_1W pPrinterInfo1;
+    PPRINTER_INFO_2W pPrinterInfo2;
+
+    // Replace relative offset addresses in the output by absolute pointers.
+    if (Level == 1)
+    {
+        pPrinterInfo1 = (PPRINTER_INFO_1W)pPrinterInfo;
+
+        pPrinterInfo1->pName = (PWSTR)((ULONG_PTR)pPrinterInfo1->pName + (ULONG_PTR)pPrinterInfo1);
+        pPrinterInfo1->pDescription = (PWSTR)((ULONG_PTR)pPrinterInfo1->pDescription + (ULONG_PTR)pPrinterInfo1);
+        pPrinterInfo1->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo1->pComment + (ULONG_PTR)pPrinterInfo1);
+    }
+    else if (Level == 2)
+    {
+        pPrinterInfo2 = (PPRINTER_INFO_2W)pPrinterInfo;
+
+        pPrinterInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPrinterName + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pShareName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pShareName + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPortName + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pDriverName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDriverName + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo2->pComment + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pLocation = (PWSTR)((ULONG_PTR)pPrinterInfo2->pLocation + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo2->pDevMode + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pSepFile = (PWSTR)((ULONG_PTR)pPrinterInfo2->pSepFile + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPrintProcessor + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pDatatype = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDatatype + (ULONG_PTR)pPrinterInfo2);
+        pPrinterInfo2->pParameters = (PWSTR)((ULONG_PTR)pPrinterInfo2->pParameters + (ULONG_PTR)pPrinterInfo2);
+
+        if (pPrinterInfo2->pServerName)
+            pPrinterInfo2->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pServerName + (ULONG_PTR)pPrinterInfo2);
+
+        if (pPrinterInfo2->pSecurityDescriptor)
+            pPrinterInfo2->pSecurityDescriptor = (PWSTR)((ULONG_PTR)pPrinterInfo2->pSecurityDescriptor + (ULONG_PTR)pPrinterInfo2);
+    }
+}
+
 static DWORD
 _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, PADDJOB_INFO_1W pAddJobInfo1)
 {
@@ -24,7 +63,7 @@ _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, PADDJOB
     }
 
     // Get the size of the job information.
-    GetJobW(pHandle->hPrinter, pAddJobInfo1->JobId, 1, NULL, 0, &cbNeeded);
+    GetJobW((HANDLE)pHandle, pAddJobInfo1->JobId, 1, NULL, 0, &cbNeeded);
     if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
     {
         dwErrorCode = GetLastError();
@@ -42,7 +81,7 @@ _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, PADDJOB
     }
 
     // Get the job information.
-    if (!GetJobW(pHandle->hPrinter, pAddJobInfo1->JobId, 1, (PBYTE)pJobInfo1, cbNeeded, &cbNeeded))
+    if (!GetJobW((HANDLE)pHandle, pAddJobInfo1->JobId, 1, (PBYTE)pJobInfo1, cbNeeded, &cbNeeded))
     {
         dwErrorCode = GetLastError();
         ERR("GetJobW failed with error %lu!\n", dwErrorCode);
@@ -54,7 +93,7 @@ _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, PADDJOB
     pJobInfo1->pDocument = pDocInfo1->pDocName;
 
     // Set the new job information.
-    if (!SetJobW(pHandle->hPrinter, pAddJobInfo1->JobId, 1, (PBYTE)pJobInfo1, 0))
+    if (!SetJobW((HANDLE)pHandle, pAddJobInfo1->JobId, 1, (PBYTE)pJobInfo1, 0))
     {
         dwErrorCode = GetLastError();
         ERR("SetJobW failed with error %lu!\n", dwErrorCode);
@@ -95,33 +134,6 @@ _StartDocPrinterWithRPC(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1)
     return dwErrorCode;
 }
 
-BOOL WINAPI
-EnumPrintersA(DWORD Flags, LPSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
-{
-    return FALSE;
-}
-
-BOOL WINAPI
-EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
-{
-    DWORD dwErrorCode;
-
-    // Do the RPC call
-    RpcTryExcept
-    {
-        dwErrorCode = _RpcEnumPrinters(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
-    }
-    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
-    {
-        dwErrorCode = RpcExceptionCode();
-        ERR("_RpcEnumPrinters failed with exception code %lu!\n", dwErrorCode);
-    }
-    RpcEndExcept;
-
-    SetLastError(dwErrorCode);
-    return (dwErrorCode == ERROR_SUCCESS);
-}
-
 BOOL WINAPI
 ClosePrinter(HANDLE hPrinter)
 {
@@ -275,6 +287,49 @@ Cleanup:
     return (dwErrorCode == ERROR_SUCCESS);
 }
 
+BOOL WINAPI
+EnumPrintersA(DWORD Flags, PSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+{
+    return FALSE;
+}
+
+BOOL WINAPI
+EnumPrintersW(DWORD Flags, PWSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
+{
+    DWORD dwErrorCode;
+    DWORD i;
+    PBYTE p = pPrinterEnum;
+
+    // Do the RPC call
+    RpcTryExcept
+    {
+        dwErrorCode = _RpcEnumPrinters(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwErrorCode = RpcExceptionCode();
+        ERR("_RpcEnumPrinters failed with exception code %lu!\n", dwErrorCode);
+    }
+    RpcEndExcept;
+
+    if (dwErrorCode == ERROR_SUCCESS)
+    {
+        // Replace relative offset addresses in the output by absolute pointers.
+        for (i = 0; i < *pcReturned; i++)
+        {
+            _MarshallUpPrinterInfo(p, Level);
+
+            if (Level == 1)
+                p += sizeof(PRINTER_INFO_1W);
+            else if (Level == 2)
+                p += sizeof(PRINTER_INFO_2W);
+        }
+    }
+
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
+}
+
 BOOL WINAPI
 GetDefaultPrinterA(LPSTR pszBuffer, LPDWORD pcchBuffer)
 {
@@ -381,8 +436,7 @@ OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefau
     HANDLE hPrinter;
     PSPOOLER_HANDLE pHandle;
     PWSTR pDatatype = NULL;
-    WINSPOOL_DEVMODE_CONTAINER DevModeContainer;
-    WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer = NULL;
+    WINSPOOL_DEVMODE_CONTAINER DevModeContainer = { 0 };
     ACCESS_MASK AccessRequired = 0;
 
     // Prepare the additional parameters in the format required by _RpcOpenPrinter
@@ -391,14 +445,13 @@ OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefau
         pDatatype = pDefault->pDatatype;
         DevModeContainer.cbBuf = sizeof(DEVMODEW);
         DevModeContainer.pDevMode = (BYTE*)pDefault->pDevMode;
-        pDevModeContainer = &DevModeContainer;
         AccessRequired = pDefault->DesiredAccess;
     }
 
     // Do the RPC call
     RpcTryExcept
     {
-        dwErrorCode = _RpcOpenPrinter(pPrinterName, &hPrinter, pDatatype, pDevModeContainer, AccessRequired);
+        dwErrorCode = _RpcOpenPrinter(pPrinterName, &hPrinter, pDatatype, &DevModeContainer, AccessRequired);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -515,7 +568,7 @@ StartDocPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo)
 
         // Try to add a new job.
         // This only succeeds if the printer is set to do spooled printing.
-        if (AddJobW(pHandle->hPrinter, 1, (PBYTE)pAddJobInfo1, cbAddJobInfo1, &cbNeeded))
+        if (AddJobW((HANDLE)pHandle, 1, (PBYTE)pAddJobInfo1, cbAddJobInfo1, &cbNeeded))
         {
             // Do spooled printing.
             dwErrorCode = _StartDocPrinterSpooled(pHandle, pDocInfo1, pAddJobInfo1);