X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fwin32ss%2Fprinting%2Fbase%2Fwinspool%2Fprinters.c;h=c82132c1bf8b3b5585724bcdbac34d54da4e0ee3;hp=c4b95ea8b8dbfca3a5a748827965168c4fc132d1;hb=9af0f5d061be7a29ed03881c38a8d560a193e215;hpb=30af6277610c4c60a6a8ac12548fce4ef81259d8 diff --git a/reactos/win32ss/printing/base/winspool/printers.c b/reactos/win32ss/printing/base/winspool/printers.c index c4b95ea8b8d..c82132c1bf8 100644 --- a/reactos/win32ss/printing/base/winspool/printers.c +++ b/reactos/win32ss/printing/base/winspool/printers.c @@ -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); @@ -50,11 +89,13 @@ _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, PADDJOB } // Add our document information. - pJobInfo1->pDatatype = pDocInfo1->pDatatype; + if (pDocInfo1->pDatatype) + pJobInfo1->pDatatype = pDocInfo1->pDatatype; + 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,31 +136,11 @@ _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) +HANDLE WINAPI +AddPrinterW(PWSTR pName, DWORD Level, PBYTE pPrinter) { - 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); + UNIMPLEMENTED; + return NULL; } BOOL WINAPI @@ -275,6 +296,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) { @@ -315,24 +379,23 @@ BOOL WINAPI OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefault) { BOOL bReturnValue = FALSE; + DWORD cch; PWSTR pwszPrinterName = NULL; - PWSTR pwszDatatype = NULL; PRINTER_DEFAULTSW wDefault = { 0 }; - size_t StringLength; if (pPrinterName) { // Convert pPrinterName to a Unicode string pwszPrinterName - StringLength = strlen(pPrinterName) + 1; + cch = strlen(pPrinterName); - pwszPrinterName = HeapAlloc(hProcessHeap, 0, StringLength * sizeof(WCHAR)); + pwszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); if (!pwszPrinterName) { ERR("HeapAlloc failed for pwszPrinterName with last error %lu!\n", GetLastError()); goto Cleanup; } - MultiByteToWideChar(CP_ACP, 0, pPrinterName, -1, pwszPrinterName, StringLength); + MultiByteToWideChar(CP_ACP, 0, pPrinterName, -1, pwszPrinterName, cch + 1); } if (pDefault) @@ -341,18 +404,17 @@ OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefaul if (pDefault->pDatatype) { - // Convert pDefault->pDatatype to a Unicode string pwszDatatype that later becomes wDefault.pDatatype - StringLength = strlen(pDefault->pDatatype) + 1; + // Convert pDefault->pDatatype to a Unicode string wDefault.pDatatype + cch = strlen(pDefault->pDatatype); - pwszDatatype = HeapAlloc(hProcessHeap, 0, StringLength * sizeof(WCHAR)); - if (!pwszDatatype) + wDefault.pDatatype = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); + if (!wDefault.pDatatype) { - ERR("HeapAlloc failed for pwszDatatype with last error %lu!\n", GetLastError()); + ERR("HeapAlloc failed for wDefault.pDatatype with last error %lu!\n", GetLastError()); goto Cleanup; } - MultiByteToWideChar(CP_ACP, 0, pDefault->pDatatype, -1, pwszDatatype, StringLength); - wDefault.pDatatype = pwszDatatype; + MultiByteToWideChar(CP_ACP, 0, pDefault->pDatatype, -1, wDefault.pDatatype, cch + 1); } if (pDefault->pDevMode) @@ -362,15 +424,15 @@ OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefaul bReturnValue = OpenPrinterW(pwszPrinterName, phPrinter, &wDefault); Cleanup: + if (wDefault.pDatatype) + HeapFree(hProcessHeap, 0, wDefault.pDatatype); + if (wDefault.pDevMode) HeapFree(hProcessHeap, 0, wDefault.pDevMode); if (pwszPrinterName) HeapFree(hProcessHeap, 0, pwszPrinterName); - if (pwszDatatype) - HeapFree(hProcessHeap, 0, pwszDatatype); - return bReturnValue; } @@ -381,8 +443,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 +452,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) { @@ -460,12 +520,112 @@ Cleanup: return (dwErrorCode == ERROR_SUCCESS); } +BOOL WINAPI +ResetPrinterW(HANDLE hPrinter, PPRINTER_DEFAULTSW pDefault) +{ + UNIMPLEMENTED; + return FALSE; +} + +BOOL WINAPI +SetPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pPrinter, DWORD Command) +{ + UNIMPLEMENTED; + return FALSE; +} + +DWORD WINAPI +StartDocPrinterA(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo) +{ + DOC_INFO_1W wDocInfo1 = { 0 }; + DWORD cch; + DWORD dwErrorCode; + DWORD dwReturnValue = 0; + PDOC_INFO_1A pDocInfo1 = (PDOC_INFO_1A)pDocInfo; + + // Only check the minimum required for accessing pDocInfo. + // Additional sanity checks are done in StartDocPrinterW. + if (!pDocInfo1) + { + dwErrorCode = ERROR_INVALID_PARAMETER; + goto Cleanup; + } + + if (Level != 1) + { + dwErrorCode = ERROR_INVALID_LEVEL; + goto Cleanup; + } + + if (pDocInfo1->pDatatype) + { + // Convert pDocInfo1->pDatatype to a Unicode string wDocInfo1.pDatatype + cch = strlen(pDocInfo1->pDatatype); + + wDocInfo1.pDatatype = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); + if (!wDocInfo1.pDatatype) + { + ERR("HeapAlloc failed for wDocInfo1.pDatatype with last error %lu!\n", GetLastError()); + goto Cleanup; + } + + MultiByteToWideChar(CP_ACP, 0, pDocInfo1->pDatatype, -1, wDocInfo1.pDatatype, cch + 1); + } + + if (pDocInfo1->pDocName) + { + // Convert pDocInfo1->pDocName to a Unicode string wDocInfo1.pDocName + cch = strlen(pDocInfo1->pDocName); + + wDocInfo1.pDocName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); + if (!wDocInfo1.pDocName) + { + ERR("HeapAlloc failed for wDocInfo1.pDocName with last error %lu!\n", GetLastError()); + goto Cleanup; + } + + MultiByteToWideChar(CP_ACP, 0, pDocInfo1->pDocName, -1, wDocInfo1.pDocName, cch + 1); + } + + if (pDocInfo1->pOutputFile) + { + // Convert pDocInfo1->pOutputFile to a Unicode string wDocInfo1.pOutputFile + cch = strlen(pDocInfo1->pOutputFile); + + wDocInfo1.pOutputFile = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); + if (!wDocInfo1.pOutputFile) + { + ERR("HeapAlloc failed for wDocInfo1.pOutputFile with last error %lu!\n", GetLastError()); + goto Cleanup; + } + + MultiByteToWideChar(CP_ACP, 0, pDocInfo1->pOutputFile, -1, wDocInfo1.pOutputFile, cch + 1); + } + + dwReturnValue = StartDocPrinterW(hPrinter, Level, (PBYTE)&wDocInfo1); + dwErrorCode = GetLastError(); + +Cleanup: + if (wDocInfo1.pDatatype) + HeapFree(hProcessHeap, 0, wDocInfo1.pDatatype); + + if (wDocInfo1.pDocName) + HeapFree(hProcessHeap, 0, wDocInfo1.pDocName); + + if (wDocInfo1.pOutputFile) + HeapFree(hProcessHeap, 0, wDocInfo1.pOutputFile); + + SetLastError(dwErrorCode); + return dwReturnValue; +} + DWORD WINAPI StartDocPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo) { DWORD cbAddJobInfo1; DWORD cbNeeded; DWORD dwErrorCode; + DWORD dwReturnValue = 0; PADDJOB_INFO_1W pAddJobInfo1 = NULL; PDOC_INFO_1W pDocInfo1 = (PDOC_INFO_1W)pDocInfo; PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; @@ -515,7 +675,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); @@ -535,14 +695,17 @@ StartDocPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo) } if (dwErrorCode == ERROR_SUCCESS) + { pHandle->bStartedDoc = TRUE; + dwReturnValue = pHandle->dwJobID; + } Cleanup: if (pAddJobInfo1) HeapFree(hProcessHeap, 0, pAddJobInfo1); SetLastError(dwErrorCode); - return pHandle->dwJobID; + return dwReturnValue; } BOOL WINAPI