mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 16:01:53 +00:00
[WINSPOOL]
Don't rely on pure magic to transmit the error code of the RPC call to the calling application. Instead use SetLastError on the return value of the call (this is what all these DWORD return values are for!) [SPOOLSV] For every RPC function, return the error code of the called Spooler Router function instead of the error code of RpcRevertToSelf. [LOCALSPL, WINPRINT] - Change the code structure in every function called from the Spooler Router to always set an error code, especially ERROR_SUCCESS on success. - Store Attributes and Status values for a local printer. - Fail in LocalAddJob if an invalid handle has been supplied or the printer is set to do direct printing. svn path=/branches/colins-printing-for-freedom/; revision=68247
This commit is contained in:
parent
5df5a009e2
commit
7e4bcf78c4
15 changed files with 303 additions and 261 deletions
|
@ -94,9 +94,10 @@ SplIsUpgrade()
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD WINAPI
|
||||
BOOL WINAPI
|
||||
SpoolerInit()
|
||||
{
|
||||
// Nothing to do here yet
|
||||
return ERROR_SUCCESS;
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -21,13 +21,9 @@ _RpcSpoolerInit()
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = SpoolerInit();
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("SpoolerInit failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
SpoolerInit();
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
|
|
@ -19,15 +19,11 @@ _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD c
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("AddJobW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
@ -42,15 +38,11 @@ _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, DWORD Level, BYTE* pJo
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("GetJobW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
|
|
@ -19,15 +19,11 @@ _RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD Level, BYTE* pPrinterE
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = EnumPrintersW(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("EnumPrintersW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
EnumPrintersW(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
@ -47,13 +43,9 @@ _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter
|
|||
Default.pDatatype = pDatatype;
|
||||
Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
|
||||
|
||||
dwErrorCode = OpenPrinterW(pPrinterName, phPrinter, &Default);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("OpenPrinterW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
OpenPrinterW(pPrinterName, phPrinter, &Default);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
|
|
@ -26,15 +26,11 @@ _RpcEnumPrintProcessorDatatypes(WINSPOOL_HANDLE pName, WCHAR *pPrintProcessorNam
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = EnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("EnumPrintProcessorDatatypesW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
EnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
@ -49,15 +45,11 @@ _RpcEnumPrintProcessors(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD Level,
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = EnumPrintProcessorsW(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("EnumPrintProcessorsW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
EnumPrintProcessorsW(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
@ -72,13 +64,9 @@ _RpcGetPrintProcessorDirectory(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD
|
|||
return dwErrorCode;
|
||||
}
|
||||
|
||||
dwErrorCode = GetPrintProcessorDirectoryW(pName, pEnvironment, Level, pPrintProcessorDirectory, cbBuf, pcbNeeded);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("EnumPrintProcessorsW failed with error %lu!\n", dwErrorCode);
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
GetPrintProcessorDirectoryW(pName, pEnvironment, Level, pPrintProcessorDirectory, cbBuf, pcbNeeded);
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
return RpcRevertToSelf();
|
||||
RpcRevertToSelf();
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,7 @@ AddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeede
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcAddJob(hPrinter, Level, pData, cbBuf, pcbNeeded);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcAddJob failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
@ -43,11 +39,7 @@ GetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDW
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcGetJob(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcGetJob failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
|
|
@ -68,19 +68,15 @@ midl_user_free(void __RPC_FAR* ptr)
|
|||
BOOL WINAPI
|
||||
SpoolerInit()
|
||||
{
|
||||
BOOL ReturnValue = FALSE;
|
||||
DWORD ErrorCode;
|
||||
BOOL bReturnValue = FALSE;
|
||||
DWORD dwErrorCode;
|
||||
|
||||
// Nothing to initialize here yet, but pass this call to the Spool Service as well.
|
||||
RpcTryExcept
|
||||
{
|
||||
ErrorCode = _RpcSpoolerInit();
|
||||
if (ErrorCode)
|
||||
{
|
||||
ERR("_RpcSpoolerInit failed with error %lu!\n", ErrorCode);
|
||||
}
|
||||
|
||||
ReturnValue = (ErrorCode == ERROR_SUCCESS);
|
||||
dwErrorCode = _RpcSpoolerInit();
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -88,5 +84,5 @@ SpoolerInit()
|
|||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return ReturnValue;
|
||||
return bReturnValue;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,7 @@ EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcEnumPrinters(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcEnumPrinters failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
@ -204,11 +200,7 @@ OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefau
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcOpenPrinter(pPrinterName, phPrinter, pDatatype, pDevModeContainer, AccessRequired);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcOpenPrinter failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
|
|
@ -23,11 +23,7 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcEnumPrintProcessorDatatypes(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcEnumPrintProcessorDatatypes failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
@ -49,11 +45,7 @@ EnumPrintProcessorsW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPri
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcEnumPrintProcessors(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcEnumPrintProcessors failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
@ -75,11 +67,7 @@ GetPrintProcessorDirectoryW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBY
|
|||
RpcTryExcept
|
||||
{
|
||||
dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
|
||||
if (dwErrorCode)
|
||||
{
|
||||
ERR("_RpcGetPrintProcessorDirectory failed with error %lu!\n", dwErrorCode);
|
||||
}
|
||||
|
||||
SetLastError(dwErrorCode);
|
||||
bReturnValue = (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
|
|
@ -49,13 +49,17 @@ BOOL WINAPI
|
|||
EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||
{
|
||||
DWORD cbDatatype;
|
||||
DWORD dwErrorCode;
|
||||
DWORD dwOffsets[_countof(pwszDatatypes)];
|
||||
PCWSTR* pCurrentDatatype;
|
||||
PDWORD pCurrentOffset = dwOffsets;
|
||||
|
||||
// Sanity checks
|
||||
if (Level != 1 || !pcbNeeded || !pcReturned)
|
||||
return FALSE;
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Count the required buffer size and the number of datatypes.
|
||||
*pcbNeeded = 0;
|
||||
|
@ -76,20 +80,24 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
|
|||
// Check if the supplied buffer is large enough.
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Check if a buffer was supplied at all.
|
||||
if (!pDatatypes)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Copy over all datatypes.
|
||||
*pCurrentOffset = MAXDWORD;
|
||||
PackStrings(pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
|
||||
|
||||
return TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -196,36 +196,54 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
const DWORD cchSpl = _countof("?????.SPL") - 1;
|
||||
|
||||
ADDJOB_INFO_1W AddJobInfo1;
|
||||
BOOL bReturnValue = FALSE;
|
||||
DWORD cchMachineName;
|
||||
DWORD cchUserName;
|
||||
DWORD dwErrorCode;
|
||||
PBYTE p;
|
||||
PLOCAL_HANDLE pHandle;
|
||||
PLOCAL_JOB pJob;
|
||||
PLOCAL_PRINTER_HANDLE pPrinterHandle;
|
||||
RPC_BINDING_HANDLE hServerBinding = NULL;
|
||||
RPC_STATUS Status;
|
||||
RPC_WSTR pwszBinding = NULL;
|
||||
RPC_WSTR pwszMachineName = NULL;
|
||||
|
||||
// Check if this is a printer handle.
|
||||
pHandle = (PLOCAL_HANDLE)hPrinter;
|
||||
if (pHandle->HandleType != Printer)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->SpecificHandle;
|
||||
|
||||
// This handle must not have started a job yet!
|
||||
if (pPrinterHandle->StartedJob)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Check if this is the right structure level.
|
||||
if (Level != 1)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// FIXME: This needs to fail if the printer is set to do direct printing.
|
||||
// Check if the printer is set to do direct printing.
|
||||
// The Job List isn't used in this case.
|
||||
if (pPrinterHandle->Printer->dwAttributes & PRINTER_ATTRIBUTE_DIRECT)
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_ACCESS;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Check if the supplied buffer is large enough.
|
||||
*pcbNeeded = sizeof(ADDJOB_INFO_1W) + (cchSpoolDirectory + cchPrintersPath + cchSpl + 1) * sizeof(WCHAR);
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -233,13 +251,17 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
|
||||
if (!pJob)
|
||||
{
|
||||
ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
|
||||
dwErrorCode = GetLastError();
|
||||
ERR("DllAllocSplMem failed with error %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Reserve an ID for this job.
|
||||
if (!GetNextJobID(&pJob->dwJobID))
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Copy over defaults to the LOCAL_JOB structure.
|
||||
pJob->Printer = pPrinterHandle->Printer;
|
||||
|
@ -254,7 +276,8 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
pJob->pwszUserName = DllAllocSplMem(cchUserName * sizeof(WCHAR));
|
||||
if (!GetUserNameW(pJob->pwszUserName, &cchUserName))
|
||||
{
|
||||
ERR("GetUserNameW failed with error %lu!\n", GetLastError());
|
||||
dwErrorCode = GetLastError();
|
||||
ERR("GetUserNameW failed with error %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -262,24 +285,24 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
pJob->pwszNotifyName = AllocSplStr(pJob->pwszUserName);
|
||||
|
||||
// Get the name of the machine that submitted the Job over RPC.
|
||||
Status = RpcBindingServerFromClient(NULL, &hServerBinding);
|
||||
if (Status != RPC_S_OK)
|
||||
dwErrorCode = RpcBindingServerFromClient(NULL, &hServerBinding);
|
||||
if (dwErrorCode != RPC_S_OK)
|
||||
{
|
||||
ERR("RpcBindingServerFromClient failed with status %lu!\n", Status);
|
||||
ERR("RpcBindingServerFromClient failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Status = RpcBindingToStringBindingW(hServerBinding, &pwszBinding);
|
||||
if (Status != RPC_S_OK)
|
||||
dwErrorCode = RpcBindingToStringBindingW(hServerBinding, &pwszBinding);
|
||||
if (dwErrorCode != RPC_S_OK)
|
||||
{
|
||||
ERR("RpcBindingToStringBindingW failed with status %lu!\n", Status);
|
||||
ERR("RpcBindingToStringBindingW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Status = RpcStringBindingParseW(pwszBinding, NULL, NULL, &pwszMachineName, NULL, NULL);
|
||||
if (Status != RPC_S_OK)
|
||||
dwErrorCode = RpcStringBindingParseW(pwszBinding, NULL, NULL, &pwszMachineName, NULL, NULL);
|
||||
if (dwErrorCode != RPC_S_OK)
|
||||
{
|
||||
ERR("RpcStringBindingParseW failed with status %lu!\n", Status);
|
||||
ERR("RpcStringBindingParseW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -291,6 +314,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
// Add the job to the Global Job List.
|
||||
if (!InsertElementSkiplist(&GlobalJobList, pJob))
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
@ -299,6 +323,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
// As all new jobs are created with default priority, we can be sure that it would always be inserted at the end.
|
||||
if (!InsertTailElementSkiplist(&pJob->Printer->JobList, pJob))
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
ERR("InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
@ -315,7 +340,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
|
|||
p += cchPrintersPath;
|
||||
swprintf((PWSTR)p, L"%05lu.SPL", pJob->dwJobID);
|
||||
|
||||
bReturnValue = TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
if (pwszMachineName)
|
||||
|
@ -327,11 +352,12 @@ Cleanup:
|
|||
if (hServerBinding)
|
||||
RpcBindingFree(&hServerBinding);
|
||||
|
||||
return bReturnValue;
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static BOOL
|
||||
static DWORD
|
||||
_LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE pOutput, DWORD cbBuf, PDWORD pcbNeeded)
|
||||
{
|
||||
DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
|
||||
|
@ -339,6 +365,7 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
|
||||
DWORD cbPrinterName = (wcslen(pJob->Printer->pwszPrinterName) + 1) * sizeof(WCHAR);
|
||||
DWORD cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
|
||||
DWORD dwErrorCode;
|
||||
JOB_INFO_1W JobInfo1 = { 0 };
|
||||
PBYTE pString;
|
||||
|
||||
|
@ -346,8 +373,8 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
*pcbNeeded = sizeof(JOB_INFO_1W) + cbDatatype + cbDocumentName + cbMachineName + cbPrinterName + cbUserName;
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Put the strings right after the JOB_INFO_1W structure.
|
||||
|
@ -381,10 +408,13 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
CopyMemory(&JobInfo1.Submitted, &pJob->stSubmitted, sizeof(SYSTEMTIME));
|
||||
CopyMemory(pOutput, &JobInfo1, sizeof(JOB_INFO_1W));
|
||||
|
||||
return TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
static DWORD
|
||||
_LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE pOutput, DWORD cbBuf, PDWORD pcbNeeded)
|
||||
{
|
||||
DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
|
||||
|
@ -395,6 +425,7 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
DWORD cbPrinterName = (wcslen(pJob->Printer->pwszPrinterName) + 1) * sizeof(WCHAR);
|
||||
DWORD cbPrintProcessor = (wcslen(pJob->Printer->pPrintProcessor->pwszName) + 1) * sizeof(WCHAR);
|
||||
DWORD cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
|
||||
DWORD dwErrorCode;
|
||||
FILETIME ftNow;
|
||||
FILETIME ftSubmitted;
|
||||
JOB_INFO_2W JobInfo2 = { 0 };
|
||||
|
@ -406,8 +437,8 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
*pcbNeeded = sizeof(JOB_INFO_2W) + cbDatatype + sizeof(DEVMODEW) + cbDocumentName + cbDriverName + cbMachineName + cbNotifyName + cbPrinterName + cbPrintProcessor + cbUserName;
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Put the strings right after the JOB_INFO_2W structure.
|
||||
|
@ -467,8 +498,9 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
// Retrieve this through the element index of the job in the Printer's Job List.
|
||||
if (!LookupElementSkiplist(&pJob->Printer->JobList, pJob, &JobInfo2.Position))
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
ERR("pJob could not be located in the Printer's Job List!\n");
|
||||
return FALSE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Make the index 1-based.
|
||||
|
@ -486,12 +518,16 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
|
|||
|
||||
// Finally copy the structure to the output pointer.
|
||||
CopyMemory(pOutput, &JobInfo2, sizeof(JOB_INFO_2W));
|
||||
return TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pOutput, DWORD cbBuf, LPDWORD pcbNeeded)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
PLOCAL_HANDLE pHandle;
|
||||
PLOCAL_JOB pJob;
|
||||
PLOCAL_PRINTER_HANDLE pPrinterHandle;
|
||||
|
@ -499,7 +535,10 @@ LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pOutput, DWORD cbB
|
|||
// Check if this is a printer handle.
|
||||
pHandle = (PLOCAL_HANDLE)hPrinter;
|
||||
if (pHandle->HandleType != Printer)
|
||||
return FALSE;
|
||||
{
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->SpecificHandle;
|
||||
|
||||
|
@ -507,17 +546,21 @@ LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pOutput, DWORD cbB
|
|||
pJob = LookupElementSkiplist(&GlobalJobList, &JobId, NULL);
|
||||
if (!pJob || pJob->Printer != pPrinterHandle->Printer)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// The function behaves differently for each level.
|
||||
if (Level == 1)
|
||||
return _LocalGetJobLevel1(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
|
||||
dwErrorCode = _LocalGetJobLevel1(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
|
||||
else if (Level == 2)
|
||||
return _LocalGetJobLevel2(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
|
||||
dwErrorCode = _LocalGetJobLevel2(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
|
||||
else
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
|
||||
return FALSE;
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
PLOCAL_JOB
|
||||
|
|
|
@ -156,5 +156,6 @@ InitializePrintProvidor(LPPRINTPROVIDOR pPrintProvidor, DWORD cbPrintProvidor, L
|
|||
{
|
||||
CopyMemory(pPrintProvidor, &_PrintProviderFunctions, min(cbPrintProvidor, sizeof(PRINTPROVIDOR)));
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ typedef struct _LOCAL_PRINTER
|
|||
// This sort key must be the first element for LookupElementSkiplist to work!
|
||||
PWSTR pwszPrinterName;
|
||||
|
||||
DWORD dwAttributes;
|
||||
DWORD dwStatus;
|
||||
PWSTR pwszPrinterDriver;
|
||||
PWSTR pwszDescription;
|
||||
PWSTR pwszDefaultDatatype;
|
||||
|
|
|
@ -38,7 +38,7 @@ InitializePrinterList()
|
|||
{
|
||||
const WCHAR wszPrintersKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Printers";
|
||||
|
||||
DWORD cbDevMode;
|
||||
DWORD cbData;
|
||||
DWORD cchPrinterName;
|
||||
DWORD dwSubKeys;
|
||||
DWORD i;
|
||||
|
@ -173,11 +173,29 @@ InitializePrinterList()
|
|||
}
|
||||
|
||||
// Get the default DevMode.
|
||||
cbDevMode = sizeof(DEVMODEW);
|
||||
lStatus = RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)&pPrinter->DefaultDevMode, &cbDevMode);
|
||||
if (lStatus != ERROR_SUCCESS || cbDevMode != sizeof(DEVMODEW))
|
||||
cbData = sizeof(DEVMODEW);
|
||||
lStatus = RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)&pPrinter->DefaultDevMode, &cbData);
|
||||
if (lStatus != ERROR_SUCCESS || cbData != sizeof(DEVMODEW))
|
||||
{
|
||||
ERR("Couldn't query a valid DevMode for Printer \"%S\", status is %ld, cbDevMode is %lu!\n", wszPrinterName, lStatus, cbDevMode);
|
||||
ERR("Couldn't query a valid DevMode for Printer \"%S\", status is %ld, cbData is %lu!\n", wszPrinterName, lStatus, cbData);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the Attributes.
|
||||
cbData = sizeof(DWORD);
|
||||
lStatus = RegQueryValueExW(hSubKey, L"Attributes", NULL, NULL, (PBYTE)&pPrinter->dwAttributes, &cbData);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Couldn't query Attributes for Printer \"%S\", status is %ld!\n", wszPrinterName, lStatus);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the Status.
|
||||
cbData = sizeof(DWORD);
|
||||
lStatus = RegQueryValueExW(hSubKey, L"Status", NULL, NULL, (PBYTE)&pPrinter->dwStatus, &cbData);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Couldn't query Status for Printer \"%S\", status is %ld!\n", wszPrinterName, lStatus);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -223,7 +241,7 @@ Cleanup:
|
|||
}
|
||||
|
||||
|
||||
BOOL
|
||||
DWORD
|
||||
_LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||
{
|
||||
const WCHAR wszComma[] = L",";
|
||||
|
@ -232,6 +250,7 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
DWORD cbComment;
|
||||
DWORD cbDescription;
|
||||
DWORD cchComputerName = 0;
|
||||
DWORD dwErrorCode;
|
||||
DWORD i;
|
||||
PBYTE pPrinterInfo;
|
||||
PBYTE pPrinterString;
|
||||
|
@ -263,8 +282,9 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
cchComputerName = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
if (!GetComputerNameW(&wszComputerName[2], &cchComputerName))
|
||||
{
|
||||
ERR("GetComputerNameW failed with error %lu!\n", GetLastError());
|
||||
return FALSE;
|
||||
dwErrorCode = GetLastError();
|
||||
ERR("GetComputerNameW failed with error %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Add the leading slashes to the total length.
|
||||
|
@ -273,8 +293,8 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
// Now compare this with the local computer name and reject if it doesn't match.
|
||||
if (wcsicmp(&Name[2], &wszComputerName[2]) != 0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_NAME);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INVALID_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Add a trailing backslash to wszComputerName, which will later be prepended in front of the printer names.
|
||||
|
@ -284,8 +304,8 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
else if (wcsicmp(Name, wszPrintProviderInfo[0]) != 0)
|
||||
{
|
||||
// The user supplied a name that cannot be processed by the local print provider.
|
||||
SetLastError(ERROR_INVALID_NAME);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INVALID_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -302,14 +322,15 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
// Check if the supplied buffer is large enough.
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Copy over the print processor information.
|
||||
((PPRINTER_INFO_1W)pPrinterEnum)->Flags = 0;
|
||||
PackStrings(wszPrintProviderInfo, pPrinterEnum, dwOffsets, &pPrinterEnum[*pcbNeeded]);
|
||||
return TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,8 +353,8 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
// Check if the supplied buffer is large enough.
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Put the strings right after the last PRINTER_INFO_1W structure.
|
||||
|
@ -381,12 +402,17 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
|||
pPrinterInfo += sizeof(PRINTER_INFO_1W);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
|
||||
// Do no sanity checks here. This is verified by localspl_apitest!
|
||||
|
||||
// Begin counting.
|
||||
|
@ -394,30 +420,36 @@ LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DW
|
|||
*pcReturned = 0;
|
||||
|
||||
// Think positive :)
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
// Treat it as success if the caller queried no information and we don't need to return any.
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
if (Flags & PRINTER_ENUM_LOCAL)
|
||||
{
|
||||
// The function behaves quite differently for each level.
|
||||
if (Level == 1)
|
||||
return _LocalEnumPrintersLevel1(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
|
||||
|
||||
// TODO: Handle other levels.
|
||||
|
||||
// The caller supplied an invalid level.
|
||||
return FALSE;
|
||||
{
|
||||
dwErrorCode = _LocalEnumPrintersLevel1(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Handle other levels.
|
||||
// The caller supplied an invalid level.
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Treat it as success if the caller queried no information and we don't need to return any.
|
||||
return TRUE;
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDefault)
|
||||
{
|
||||
BOOL bReturnValue = ROUTER_UNKNOWN;
|
||||
DWORD cchComputerName;
|
||||
DWORD cchPrinterName;
|
||||
DWORD dwErrorCode;
|
||||
DWORD dwJobID;
|
||||
PWSTR p = lpPrinterName;
|
||||
PWSTR pwszPrinterName = NULL;
|
||||
|
@ -430,7 +462,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
// Sanity checks
|
||||
if (!lpPrinterName || !phPrinter)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -445,7 +477,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
if (!p)
|
||||
{
|
||||
// We didn't get a proper server name.
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -456,14 +488,15 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
cchComputerName = _countof(wszComputerName);
|
||||
if (!GetComputerNameW(wszComputerName, &cchComputerName))
|
||||
{
|
||||
ERR("GetComputerNameW failed with error %lu!\n", GetLastError());
|
||||
dwErrorCode = GetLastError();
|
||||
ERR("GetComputerNameW failed with error %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Now compare this with the local computer name and reject if it doesn't match, because this print provider only supports local printers.
|
||||
if (wcsicmp(lpPrinterName, wszComputerName) != 0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -481,7 +514,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
// No printer name and no comma? This is invalid!
|
||||
if (!cchPrinterName && !p)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -498,7 +531,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
if (!pPrinter)
|
||||
{
|
||||
// The printer does not exist.
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -512,7 +545,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
// Use the datatype if it's valid.
|
||||
if (!FindDatatype(pPrinter->pPrintProcessor, pDefault->pDatatype))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATATYPE);
|
||||
dwErrorCode = ERROR_INVALID_DATATYPE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -545,7 +578,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
// The "Job " string has to follow now.
|
||||
if (wcscmp(p, L"Job ") != 0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -561,7 +594,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
if (!IS_VALID_JOB_ID(dwJobID))
|
||||
{
|
||||
// The user supplied an invalid Job ID.
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -570,7 +603,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
if (!pJob || pJob->Printer != pPrinter)
|
||||
{
|
||||
// The user supplied a non-existing Job ID or the Job ID does not belong to the supplied printer name.
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -618,13 +651,13 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
|
|||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
*phPrinter = (HANDLE)pHandle;
|
||||
bReturnValue = ROUTER_SUCCESS;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
// Don't let the cleanup routines free this.
|
||||
pPrinterHandle = NULL;
|
||||
|
@ -642,12 +675,15 @@ Cleanup:
|
|||
if (pwszPrinterName)
|
||||
DllFreeSplMem(pwszPrinterName);
|
||||
|
||||
return bReturnValue;
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
DWORD WINAPI
|
||||
LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
DWORD dwReturnValue = 0;
|
||||
PDOC_INFO_1W pDocumentInfo1;
|
||||
PLOCAL_HANDLE pHandle;
|
||||
PLOCAL_JOB pJob;
|
||||
|
@ -656,22 +692,22 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
|||
// Sanity checks
|
||||
if (!pDocInfo)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!hPrinter)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Check if this is a printer handle.
|
||||
pHandle = (PLOCAL_HANDLE)hPrinter;
|
||||
if (pHandle->HandleType != Printer)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
dwErrorCode = ERROR_INVALID_HANDLE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->SpecificHandle;
|
||||
|
@ -679,8 +715,8 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
|||
// Check if this is the right document information level.
|
||||
if (Level != 1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_LEVEL);
|
||||
return 0;
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pDocumentInfo1 = (PDOC_INFO_1W)pDocInfo;
|
||||
|
@ -696,8 +732,8 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
|||
// Use the datatype if it's valid.
|
||||
if (!FindDatatype(pJob->Printer->pPrintProcessor, pDocumentInfo1->pDatatype))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATATYPE);
|
||||
return 0;
|
||||
dwErrorCode = ERROR_INVALID_DATATYPE;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pJob->pwszDatatype = AllocSplStr(pDocumentInfo1->pDatatype);
|
||||
|
@ -720,25 +756,35 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
|||
|
||||
// Get an ID for the new job.
|
||||
if (!GetNextJobID(&pJob->dwJobID))
|
||||
return 0;
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Add the job to the Global Job List.
|
||||
if (!InsertElementSkiplist(&GlobalJobList, pJob))
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
|
||||
return 0;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Add the job at the end of the Printer's Job List.
|
||||
// As all new jobs are created with default priority, we can be sure that it would always be inserted at the end.
|
||||
if (!InsertTailElementSkiplist(&pJob->Printer->JobList, pJob))
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
ERR("InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
|
||||
return 0;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
pPrinterHandle->StartedJob = pJob;
|
||||
return pJob->dwJobID;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
dwReturnValue = pJob->dwJobID;
|
||||
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return dwReturnValue;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
|
|
|
@ -24,18 +24,16 @@ static LIST_ENTRY _PrintProcessorList;
|
|||
* You can use it for further tasks and have to close it with RegCloseKey.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the environment is valid and a registry key was opened, FALSE otherwise.
|
||||
* In case of failure, Last Error will be set to ERROR_INVALID_ENVIRONMENT.
|
||||
* A Windows Error Code indicating success or failure.
|
||||
*/
|
||||
static BOOL
|
||||
static DWORD
|
||||
_OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
|
||||
{
|
||||
const WCHAR wszEnvironmentsKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Environments\\";
|
||||
const DWORD cchEnvironmentsKey = _countof(wszEnvironmentsKey) - 1;
|
||||
|
||||
BOOL bReturnValue = FALSE;
|
||||
DWORD cchEnvironment;
|
||||
LONG lStatus;
|
||||
DWORD dwErrorCode;
|
||||
PWSTR pwszEnvironmentKey = NULL;
|
||||
|
||||
// Use the current environment if none was supplied.
|
||||
|
@ -55,25 +53,23 @@ _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
|
|||
CopyMemory(&pwszEnvironmentKey[cchEnvironmentsKey], pEnvironment, (cchEnvironment + 1) * sizeof(WCHAR));
|
||||
|
||||
// Open the registry key.
|
||||
lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszEnvironmentKey, 0, KEY_READ, hKey);
|
||||
if (lStatus == ERROR_FILE_NOT_FOUND)
|
||||
dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszEnvironmentKey, 0, KEY_READ, hKey);
|
||||
if (dwErrorCode == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_ENVIRONMENT);
|
||||
dwErrorCode = ERROR_INVALID_ENVIRONMENT;
|
||||
goto Cleanup;
|
||||
}
|
||||
else if (lStatus != ERROR_SUCCESS)
|
||||
else if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
|
||||
ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
bReturnValue = TRUE;
|
||||
|
||||
Cleanup:
|
||||
if (pwszEnvironmentKey)
|
||||
DllFreeSplMem(pwszEnvironmentKey);
|
||||
|
||||
return bReturnValue;
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -146,7 +142,7 @@ InitializePrintProcessorList()
|
|||
wszPrintProcessorPath[cchPrintProcessorPath++] = L'\\';
|
||||
|
||||
// Open the environment registry key.
|
||||
if (!_OpenEnvironment(NULL, &hKey))
|
||||
if (_OpenEnvironment(NULL, &hKey) != ERROR_SUCCESS)
|
||||
goto Cleanup;
|
||||
|
||||
// Open the "Print Processors" subkey.
|
||||
|
@ -372,25 +368,33 @@ Cleanup:
|
|||
BOOL WINAPI
|
||||
LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||
{
|
||||
DWORD dwErrorCode;
|
||||
PLOCAL_PRINT_PROCESSOR pPrintProcessor;
|
||||
|
||||
// Sanity checks
|
||||
if (Level != 1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_LEVEL);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Try to find the Print Processor.
|
||||
pPrintProcessor = FindPrintProcessor(pPrintProcessorName);
|
||||
if (!pPrintProcessor)
|
||||
{
|
||||
SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
|
||||
return FALSE;
|
||||
dwErrorCode = ERROR_UNKNOWN_PRINTPROCESSOR;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Call its EnumPrintProcessorDatatypesW function.
|
||||
return pPrintProcessor->pfnEnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
|
||||
if (pPrintProcessor->pfnEnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned))
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
else
|
||||
dwErrorCode = GetLastError();
|
||||
|
||||
Cleanup:
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -431,13 +435,12 @@ LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD
|
|||
BOOL WINAPI
|
||||
LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||
{
|
||||
BOOL bReturnValue = FALSE;
|
||||
DWORD cchMaxSubKey;
|
||||
DWORD cchPrintProcessor;
|
||||
DWORD dwErrorCode;
|
||||
DWORD i;
|
||||
HKEY hKey = NULL;
|
||||
HKEY hSubKey = NULL;
|
||||
LONG lStatus;
|
||||
PBYTE pCurrentOutputPrintProcessor;
|
||||
PBYTE pCurrentOutputPrintProcessorInfo;
|
||||
PRINTPROCESSOR_INFO_1W PrintProcessorInfo1;
|
||||
|
@ -446,35 +449,36 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
|||
// Sanity checks
|
||||
if (Level != 1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_LEVEL);
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!pcbNeeded || !pcReturned)
|
||||
{
|
||||
// This error must be caught by RPC and returned as RPC_X_NULL_REF_POINTER.
|
||||
ERR("pcbNeeded or pcReturned is NULL!\n");
|
||||
// This error is also caught by RPC and returned as RPC_X_NULL_REF_POINTER.
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Verify pEnvironment and open its registry key.
|
||||
// We use the registry and not the PrintProcessorList here, because the caller may request information about a different environment.
|
||||
if (!_OpenEnvironment(pEnvironment, &hKey))
|
||||
dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
goto Cleanup;
|
||||
|
||||
// Open the "Print Processors" subkey.
|
||||
lStatus = RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
|
||||
ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Get the number of Print Processors and maximum sub key length.
|
||||
lStatus = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, pcReturned, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, pcReturned, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegQueryInfoKeyW failed with status %ld!\n", lStatus);
|
||||
ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -482,6 +486,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
|||
pwszTemp = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
|
||||
if (!pwszTemp)
|
||||
{
|
||||
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
|
||||
goto Cleanup;
|
||||
}
|
||||
|
@ -494,10 +499,10 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
|||
// RegEnumKeyExW sucks! Unlike similar API functions, it only returns the actual numbers of characters copied when you supply a buffer large enough.
|
||||
// So use pwszTemp with its size cchMaxSubKey for this.
|
||||
cchPrintProcessor = cchMaxSubKey;
|
||||
lStatus = RegEnumKeyExW(hSubKey, i, pwszTemp, &cchPrintProcessor, NULL, NULL, NULL, NULL);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pwszTemp, &cchPrintProcessor, NULL, NULL, NULL, NULL);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegEnumKeyExW failed with status %ld!\n", lStatus);
|
||||
ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -507,7 +512,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
|||
// Check if the supplied buffer is large enough.
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -522,10 +527,10 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
|||
cchPrintProcessor = cchMaxSubKey;
|
||||
|
||||
// Copy the Print Processor name.
|
||||
lStatus = RegEnumKeyExW(hSubKey, i, (PWSTR)pCurrentOutputPrintProcessor, &cchPrintProcessor, NULL, NULL, NULL, NULL);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, (PWSTR)pCurrentOutputPrintProcessor, &cchPrintProcessor, NULL, NULL, NULL, NULL);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegEnumKeyExW failed with status %ld!\n", lStatus);
|
||||
ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -539,8 +544,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
|||
}
|
||||
|
||||
// We've finished successfully!
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
bReturnValue = TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
if (pwszTemp)
|
||||
|
@ -552,7 +556,8 @@ Cleanup:
|
|||
if (hKey)
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return bReturnValue;
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -592,34 +597,34 @@ LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
|
|||
const WCHAR wszPath[] = L"\\PRTPROCS\\";
|
||||
const DWORD cchPath = _countof(wszPath) - 1;
|
||||
|
||||
BOOL bReturnValue = FALSE;
|
||||
DWORD cbDataWritten;
|
||||
DWORD dwErrorCode;
|
||||
HKEY hKey = NULL;
|
||||
LONG lStatus;
|
||||
|
||||
// Sanity checks
|
||||
if (Level != 1)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_LEVEL);
|
||||
dwErrorCode = ERROR_INVALID_LEVEL;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
if (!pcbNeeded)
|
||||
{
|
||||
// This error must be caught by RPC and returned as RPC_X_NULL_REF_POINTER.
|
||||
ERR("pcbNeeded is NULL!\n");
|
||||
// This error is also caught by RPC and returned as RPC_X_NULL_REF_POINTER.
|
||||
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Verify pEnvironment and open its registry key.
|
||||
if (!_OpenEnvironment(pEnvironment, &hKey))
|
||||
dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
goto Cleanup;
|
||||
|
||||
// Determine the size of the required buffer.
|
||||
lStatus = RegQueryValueExW(hKey, L"Directory", NULL, NULL, NULL, pcbNeeded);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Directory", NULL, NULL, NULL, pcbNeeded);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
|
||||
ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -629,7 +634,7 @@ LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
|
|||
// Is the supplied buffer large enough?
|
||||
if (cbBuf < *pcbNeeded)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -638,20 +643,20 @@ LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
|
|||
CopyMemory(&pPrintProcessorInfo[cchSpoolDirectory], wszPath, cchPath * sizeof(WCHAR));
|
||||
|
||||
// Get the directory name from the registry.
|
||||
lStatus = RegQueryValueExW(hKey, L"Directory", NULL, NULL, &pPrintProcessorInfo[cchSpoolDirectory + cchPath], &cbDataWritten);
|
||||
if (lStatus != ERROR_SUCCESS)
|
||||
dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Directory", NULL, NULL, &pPrintProcessorInfo[cchSpoolDirectory + cchPath], &cbDataWritten);
|
||||
if (dwErrorCode != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
|
||||
ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// We've finished successfully!
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
bReturnValue = TRUE;
|
||||
dwErrorCode = ERROR_SUCCESS;
|
||||
|
||||
Cleanup:
|
||||
if (hKey)
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return bReturnValue;
|
||||
SetLastError(dwErrorCode);
|
||||
return (dwErrorCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue