mirror of
https://github.com/reactos/reactos.git
synced 2025-05-11 13:27:47 +00:00
[PRINTING]
- Implement GetDefaultPrinterA/W and SetDefaultPrinterA/W in winspool.drv. Also add tests for these functions. - Set our "Dummy Printer on LPT1" as the default printer in the user registry. - Return meaningful values for DeviceNotSelectedTimeout and TransmissionRetryTimeout in PRINTER_INFO_5 in localspl. The Print dialog now preselects "Dummy Printer on LPT1" in all applications. One more task done from the list at https://reactos.org/wiki/Printing :) svn path=/trunk/; revision=74513
This commit is contained in:
parent
f06734e55d
commit
5b6e082869
10 changed files with 338 additions and 12 deletions
|
@ -1837,13 +1837,13 @@ HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Run","kbswitch.exe",2,"kbswitch.
|
||||||
|
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT",,0x00000012
|
HKCU,"SOFTWARE\Microsoft\Windows NT",,0x00000012
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion",,0x00000012
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion",,0x00000012
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Devices",,0x00000012
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Devices","Dummy Printer On LPT1",2,"winspool,LPT1:"
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Network",,0x00000012
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Network",,0x00000012
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\PrinterPorts",,0x00000012
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\PrinterPorts","Dummy Printer On LPT1",2,"winspool,LPT1:,15,45"
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Program Manager",,0x00000012
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Program Manager",,0x00000012
|
||||||
|
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","DebugOptions",2,"2048"
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","DebugOptions",2,"2048"
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","device",2,""
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","Device",2,"Dummy Printer On LPT1,winspool,LPT1:"
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","Documents",2,""
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","Documents",2,""
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","DosPrint",2,"no"
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","DosPrint",2,"no"
|
||||||
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","load",2,""
|
HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows","load",2,""
|
||||||
|
|
|
@ -26,6 +26,6 @@ add_library(winspool SHARED
|
||||||
set_target_properties(winspool PROPERTIES SUFFIX ".drv")
|
set_target_properties(winspool PROPERTIES SUFFIX ".drv")
|
||||||
set_module_type(winspool win32dll UNICODE)
|
set_module_type(winspool win32dll UNICODE)
|
||||||
target_link_libraries(winspool wine ${PSEH_LIB})
|
target_link_libraries(winspool wine ${PSEH_LIB})
|
||||||
add_importlibs(winspool gdi32 rpcrt4 msvcrt kernel32 ntdll)
|
add_importlibs(winspool advapi32 gdi32 rpcrt4 msvcrt kernel32 ntdll)
|
||||||
add_pch(winspool precomp.h SOURCE)
|
add_pch(winspool precomp.h SOURCE)
|
||||||
add_cd_file(TARGET winspool DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET winspool DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -7,6 +7,13 @@
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
|
// Local Constants
|
||||||
|
|
||||||
|
/** And the award for the most confusingly named setting goes to "Device", for storing the default printer of the current user.
|
||||||
|
Ok, I admit that this has historical reasons. It's still not straightforward in any way though! */
|
||||||
|
static const WCHAR wszWindowsKey[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
|
||||||
|
static const WCHAR wszDeviceValue[] = L"Device";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_MarshallUpPrinterInfo(PBYTE* ppPrinterInfo, DWORD Level)
|
_MarshallUpPrinterInfo(PBYTE* ppPrinterInfo, DWORD Level)
|
||||||
{
|
{
|
||||||
|
@ -415,13 +422,131 @@ Cleanup:
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
GetDefaultPrinterA(LPSTR pszBuffer, LPDWORD pcchBuffer)
|
GetDefaultPrinterA(LPSTR pszBuffer, LPDWORD pcchBuffer)
|
||||||
{
|
{
|
||||||
return FALSE;
|
DWORD dwErrorCode;
|
||||||
|
PWSTR pwszBuffer = NULL;
|
||||||
|
|
||||||
|
// Sanity check.
|
||||||
|
if (!pcchBuffer)
|
||||||
|
{
|
||||||
|
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if an ANSI buffer was given and if so, allocate a Unicode buffer of the same size.
|
||||||
|
if (pszBuffer && *pcchBuffer)
|
||||||
|
{
|
||||||
|
pwszBuffer = HeapAlloc(hProcessHeap, 0, *pcchBuffer * sizeof(WCHAR));
|
||||||
|
if (!pwszBuffer)
|
||||||
|
{
|
||||||
|
dwErrorCode = GetLastError();
|
||||||
|
ERR("HeapAlloc failed with error %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetDefaultPrinterW(pwszBuffer, pcchBuffer))
|
||||||
|
{
|
||||||
|
dwErrorCode = GetLastError();
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (pwszBuffer)
|
||||||
|
HeapFree(hProcessHeap, 0, pwszBuffer);
|
||||||
|
|
||||||
|
SetLastError(dwErrorCode);
|
||||||
|
return (dwErrorCode == ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
GetDefaultPrinterW(LPWSTR pszBuffer, LPDWORD pcchBuffer)
|
GetDefaultPrinterW(LPWSTR pszBuffer, LPDWORD pcchBuffer)
|
||||||
{
|
{
|
||||||
return FALSE;
|
DWORD cbNeeded;
|
||||||
|
DWORD cchInputBuffer;
|
||||||
|
DWORD dwErrorCode;
|
||||||
|
HKEY hWindowsKey = NULL;
|
||||||
|
PWSTR pwszDevice = NULL;
|
||||||
|
PWSTR pwszComma;
|
||||||
|
|
||||||
|
// Sanity check.
|
||||||
|
if (!pcchBuffer)
|
||||||
|
{
|
||||||
|
dwErrorCode = ERROR_INVALID_PARAMETER;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cchInputBuffer = *pcchBuffer;
|
||||||
|
|
||||||
|
// Open the registry key where the default printer for the current user is stored.
|
||||||
|
dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_CURRENT_USER, wszWindowsKey, 0, KEY_READ, &hWindowsKey);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the size of the required buffer.
|
||||||
|
dwErrorCode = (DWORD)RegQueryValueExW(hWindowsKey, wszDeviceValue, NULL, NULL, NULL, &cbNeeded);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate it.
|
||||||
|
pwszDevice = HeapAlloc(hProcessHeap, 0, cbNeeded);
|
||||||
|
if (!pwszDevice)
|
||||||
|
{
|
||||||
|
dwErrorCode = GetLastError();
|
||||||
|
ERR("HeapAlloc failed with error %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now get the actual value.
|
||||||
|
dwErrorCode = RegQueryValueExW(hWindowsKey, wszDeviceValue, NULL, NULL, (PBYTE)pwszDevice, &cbNeeded);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We get a string "<Printer Name>,winspool,<Port>:".
|
||||||
|
// Extract the printer name from it.
|
||||||
|
pwszComma = wcschr(pwszDevice, L',');
|
||||||
|
if (!pwszComma)
|
||||||
|
{
|
||||||
|
ERR("Found no or invalid default printer: %S!\n", pwszDevice);
|
||||||
|
dwErrorCode = ERROR_INVALID_NAME;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the length of the Printer Name (including the terminating NUL character!) in *pcchBuffer.
|
||||||
|
*pcchBuffer = pwszComma - pwszDevice + 1;
|
||||||
|
|
||||||
|
// Check if the supplied buffer is large enough.
|
||||||
|
if (cchInputBuffer < *pcchBuffer)
|
||||||
|
{
|
||||||
|
dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the default printer.
|
||||||
|
*pwszComma = 0;
|
||||||
|
CopyMemory(pszBuffer, pwszDevice, *pcchBuffer * sizeof(WCHAR));
|
||||||
|
|
||||||
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (hWindowsKey)
|
||||||
|
RegCloseKey(hWindowsKey);
|
||||||
|
|
||||||
|
if (pwszDevice)
|
||||||
|
HeapFree(hProcessHeap, 0, pwszDevice);
|
||||||
|
|
||||||
|
SetLastError(dwErrorCode);
|
||||||
|
return (dwErrorCode == ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
|
@ -632,6 +757,147 @@ ResetPrinterW(HANDLE hPrinter, PPRINTER_DEFAULTSW pDefault)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
SetDefaultPrinterA(LPCSTR pszPrinter)
|
||||||
|
{
|
||||||
|
BOOL bReturnValue = FALSE;
|
||||||
|
DWORD cch;
|
||||||
|
PWSTR pwszPrinter = NULL;
|
||||||
|
|
||||||
|
if (pszPrinter)
|
||||||
|
{
|
||||||
|
// Convert pszPrinter to a Unicode string pwszPrinter
|
||||||
|
cch = strlen(pszPrinter);
|
||||||
|
|
||||||
|
pwszPrinter = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
|
||||||
|
if (!pwszPrinter)
|
||||||
|
{
|
||||||
|
ERR("HeapAlloc failed for pwszPrinter with last error %lu!\n", GetLastError());
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, pszPrinter, -1, pwszPrinter, cch + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bReturnValue = SetDefaultPrinterW(pwszPrinter);
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (pwszPrinter)
|
||||||
|
HeapFree(hProcessHeap, 0, pwszPrinter);
|
||||||
|
|
||||||
|
return bReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
SetDefaultPrinterW(LPCWSTR pszPrinter)
|
||||||
|
{
|
||||||
|
const WCHAR wszDevicesKey[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices";
|
||||||
|
|
||||||
|
DWORD cbDeviceValueData;
|
||||||
|
DWORD cbPrinterValueData = 0;
|
||||||
|
DWORD cchPrinter;
|
||||||
|
DWORD dwErrorCode;
|
||||||
|
HKEY hDevicesKey = NULL;
|
||||||
|
HKEY hWindowsKey = NULL;
|
||||||
|
PWSTR pwszDeviceValueData = NULL;
|
||||||
|
WCHAR wszPrinter[MAX_PRINTER_NAME + 1];
|
||||||
|
|
||||||
|
// Open the Devices registry key.
|
||||||
|
dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_CURRENT_USER, wszDevicesKey, 0, KEY_READ, &hDevicesKey);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did the caller give us a printer to set as default?
|
||||||
|
if (pszPrinter && *pszPrinter)
|
||||||
|
{
|
||||||
|
// Check if the given printer exists and query the value data size.
|
||||||
|
dwErrorCode = (DWORD)RegQueryValueExW(hDevicesKey, pszPrinter, NULL, NULL, NULL, &cbPrinterValueData);
|
||||||
|
if (dwErrorCode == ERROR_FILE_NOT_FOUND)
|
||||||
|
{
|
||||||
|
// The caller gave us an invalid printer name, return with ERROR_FILE_NOT_FOUND.
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
else if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cchPrinter = wcslen(pszPrinter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If there is already a default printer, we're done!
|
||||||
|
cchPrinter = _countof(wszPrinter);
|
||||||
|
if (GetDefaultPrinterW(wszPrinter, &cchPrinter))
|
||||||
|
{
|
||||||
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, get us the first printer from the "Devices" key to later set it as default and query the value data size.
|
||||||
|
cchPrinter = _countof(wszPrinter);
|
||||||
|
dwErrorCode = (DWORD)RegEnumValueW(hDevicesKey, 0, wszPrinter, &cchPrinter, NULL, NULL, NULL, &cbPrinterValueData);
|
||||||
|
if (dwErrorCode != ERROR_MORE_DATA)
|
||||||
|
goto Cleanup;
|
||||||
|
|
||||||
|
pszPrinter = wszPrinter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now need to query the value data, which has the format "winspool,<Port>:"
|
||||||
|
// and make "<Printer Name>,winspool,<Port>:" out of it.
|
||||||
|
// Allocate a buffer large enough for the final data.
|
||||||
|
cbDeviceValueData = (cchPrinter + 1) * sizeof(WCHAR) + cbPrinterValueData;
|
||||||
|
pwszDeviceValueData = HeapAlloc(hProcessHeap, 0, cbDeviceValueData);
|
||||||
|
if (!pwszDeviceValueData)
|
||||||
|
{
|
||||||
|
dwErrorCode = GetLastError();
|
||||||
|
ERR("HeapAlloc failed with error %lu\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the Printer Name and a comma into it.
|
||||||
|
CopyMemory(pwszDeviceValueData, pszPrinter, cchPrinter * sizeof(WCHAR));
|
||||||
|
pwszDeviceValueData[cchPrinter] = L',';
|
||||||
|
|
||||||
|
// Append the value data, which has the format "winspool,<Port>:"
|
||||||
|
dwErrorCode = (DWORD)RegQueryValueExW(hDevicesKey, pszPrinter, NULL, NULL, (PBYTE)&pwszDeviceValueData[cchPrinter + 1], &cbPrinterValueData);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
goto Cleanup;
|
||||||
|
|
||||||
|
// Open the Windows registry key.
|
||||||
|
dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_CURRENT_USER, wszWindowsKey, 0, KEY_SET_VALUE, &hWindowsKey);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store our new default printer.
|
||||||
|
dwErrorCode = (DWORD)RegSetValueExW(hWindowsKey, wszDeviceValue, 0, REG_SZ, (PBYTE)pwszDeviceValueData, cbDeviceValueData);
|
||||||
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RegSetValueExW failed with status %lu!\n", dwErrorCode);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (hDevicesKey)
|
||||||
|
RegCloseKey(hDevicesKey);
|
||||||
|
|
||||||
|
if (hWindowsKey)
|
||||||
|
RegCloseKey(hWindowsKey);
|
||||||
|
|
||||||
|
if (pwszDeviceValueData)
|
||||||
|
HeapFree(hProcessHeap, 0, pwszDeviceValueData);
|
||||||
|
|
||||||
|
SetLastError(dwErrorCode);
|
||||||
|
return (dwErrorCode == ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
SetPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pPrinter, DWORD Command)
|
SetPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pPrinter, DWORD Command)
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,9 +100,9 @@
|
||||||
199 stub EnumPrinterDriversA
|
199 stub EnumPrinterDriversA
|
||||||
200 stdcall EnumPrinterDriversW(wstr wstr long ptr long ptr ptr)
|
200 stdcall EnumPrinterDriversW(wstr wstr long ptr long ptr ptr)
|
||||||
201 stdcall GetDefaultPrinterA(ptr ptr)
|
201 stdcall GetDefaultPrinterA(ptr ptr)
|
||||||
202 stub SetDefaultPrinterA
|
202 stdcall SetDefaultPrinterA(str)
|
||||||
203 stdcall GetDefaultPrinterW(ptr ptr)
|
203 stdcall GetDefaultPrinterW(ptr ptr)
|
||||||
204 stub SetDefaultPrinterW
|
204 stdcall SetDefaultPrinterW(wstr)
|
||||||
205 stub -noname SplReadPrinter
|
205 stub -noname SplReadPrinter
|
||||||
206 stub -noname AddPerMachineConnectionA
|
206 stub -noname AddPerMachineConnectionA
|
||||||
207 stub -noname AddPerMachineConnectionW
|
207 stub -noname AddPerMachineConnectionW
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS Printing Include files
|
* PROJECT: ReactOS Printing Include files
|
||||||
* LICENSE: GNU LGPLv2 or any later version as published by the Free Software Foundation
|
* LICENSE: GNU LGPLv2 or any later version as published by the Free Software Foundation
|
||||||
* PURPOSE: Undocumented APIs of the Spooler Router "spoolss.dll"
|
* PURPOSE: Undocumented APIs of the Spooler Router "spoolss.dll" and internally shared interfaces
|
||||||
* COPYRIGHT: Copyright 2015-2017 Colin Finck <colin@reactos.org>
|
* COPYRIGHT: Copyright 2015-2017 Colin Finck <colin@reactos.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _REACTOS_SPOOLSS_H
|
#ifndef _REACTOS_SPOOLSS_H
|
||||||
#define _REACTOS_SPOOLSS_H
|
#define _REACTOS_SPOOLSS_H
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define MAX_PRINTER_NAME 220
|
||||||
|
|
||||||
typedef struct _MARSHALL_DOWN_INFO
|
typedef struct _MARSHALL_DOWN_INFO
|
||||||
{
|
{
|
||||||
DWORD dwOffset; /** Byte offset of this element within the structure or MAXDWORD to indicate the end of the array */
|
DWORD dwOffset; /** Byte offset of this element within the structure or MAXDWORD to indicate the end of the array */
|
||||||
|
|
|
@ -36,7 +36,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(localspl);
|
||||||
#define IS_VALID_PRIORITY(P) (P >= MIN_PRIORITY && P <= MAX_PRIORITY)
|
#define IS_VALID_PRIORITY(P) (P >= MIN_PRIORITY && P <= MAX_PRIORITY)
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
#define MAX_PRINTER_NAME 220
|
|
||||||
#define SHD_WIN2003_SIGNATURE 0x4968
|
#define SHD_WIN2003_SIGNATURE 0x4968
|
||||||
|
|
||||||
// Function pointers
|
// Function pointers
|
||||||
|
|
|
@ -75,6 +75,12 @@ static DWORD dwPrinterInfo5Offsets[] = {
|
||||||
MAXDWORD
|
MAXDWORD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** These values serve no purpose anymore, but are still used in PRINTER_INFO_5 and
|
||||||
|
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts */
|
||||||
|
static const DWORD dwDeviceNotSelectedTimeout = 15000;
|
||||||
|
static const DWORD dwTransmissionRetryTimeout = 45000;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name _PrinterListCompareRoutine
|
* @name _PrinterListCompareRoutine
|
||||||
*
|
*
|
||||||
|
@ -765,8 +771,8 @@ _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo,
|
||||||
|
|
||||||
// Set the general fields.
|
// Set the general fields.
|
||||||
(*ppPrinterInfo)->Attributes = pPrinter->dwAttributes;
|
(*ppPrinterInfo)->Attributes = pPrinter->dwAttributes;
|
||||||
(*ppPrinterInfo)->DeviceNotSelectedTimeout = 0;
|
(*ppPrinterInfo)->DeviceNotSelectedTimeout = dwDeviceNotSelectedTimeout;
|
||||||
(*ppPrinterInfo)->TransmissionRetryTimeout = 0;
|
(*ppPrinterInfo)->TransmissionRetryTimeout = dwTransmissionRetryTimeout;
|
||||||
|
|
||||||
// Set the pPrinterName field.
|
// Set the pPrinterName field.
|
||||||
pwszStrings[0] = DllAllocSplMem(cbPrinterName);
|
pwszStrings[0] = DllAllocSplMem(cbPrinterName);
|
||||||
|
|
|
@ -3,6 +3,7 @@ list(APPEND SOURCE
|
||||||
ClosePrinter.c
|
ClosePrinter.c
|
||||||
EnumPrinters.c
|
EnumPrinters.c
|
||||||
EnumPrintProcessorDatatypes.c
|
EnumPrintProcessorDatatypes.c
|
||||||
|
GetDefaultPrinter.c
|
||||||
GetPrintProcessorDirectory.c
|
GetPrintProcessorDirectory.c
|
||||||
IsValidDevmode.c
|
IsValidDevmode.c
|
||||||
OpenPrinter.c
|
OpenPrinter.c
|
||||||
|
|
49
rostests/apitests/winspool/GetDefaultPrinter.c
Normal file
49
rostests/apitests/winspool/GetDefaultPrinter.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Print Spooler DLL API Tests
|
||||||
|
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||||
|
* PURPOSE: Tests for GetDefaultPrinterA/GetDefaultPrinterW/SetDefaultPrinterA/SetDefaultPrinterW
|
||||||
|
* COPYRIGHT: Copyright 2017 Colin Finck <colin@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <apitest.h>
|
||||||
|
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include <windef.h>
|
||||||
|
#include <winbase.h>
|
||||||
|
#include <wingdi.h>
|
||||||
|
#include <winspool.h>
|
||||||
|
|
||||||
|
START_TEST(GetDefaultPrinter)
|
||||||
|
{
|
||||||
|
DWORD cchDefaultPrinter;
|
||||||
|
PWSTR pwszDefaultPrinter;
|
||||||
|
|
||||||
|
// Don't supply any parameters, this has to fail with ERROR_INVALID_PARAMETER.
|
||||||
|
SetLastError(0xDEADBEEF);
|
||||||
|
ok(!GetDefaultPrinterW(NULL, NULL), "GetDefaultPrinterW returns TRUE!\n");
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetDefaultPrinterW returns error %lu!\n", GetLastError());
|
||||||
|
|
||||||
|
// Determine the size of the required buffer. This has to bail out with ERROR_INSUFFICIENT_BUFFER.
|
||||||
|
cchDefaultPrinter = 0;
|
||||||
|
SetLastError(0xDEADBEEF);
|
||||||
|
ok(!GetDefaultPrinterW(NULL, &cchDefaultPrinter), "GetDefaultPrinterW returns TRUE!\n");
|
||||||
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetDefaultPrinterW returns error %lu!\n", GetLastError());
|
||||||
|
|
||||||
|
// Try with a buffer large enough.
|
||||||
|
pwszDefaultPrinter = HeapAlloc(GetProcessHeap(), 0, cchDefaultPrinter * sizeof(WCHAR));
|
||||||
|
SetLastError(0xDEADBEEF);
|
||||||
|
ok(GetDefaultPrinterW(pwszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterW returns FALSE!\n");
|
||||||
|
ok(GetLastError() == ERROR_SUCCESS, "GetDefaultPrinterW returns error %lu!\n", GetLastError());
|
||||||
|
|
||||||
|
// SetDefaultPrinterW with NULL needs to succeed and leave the default printer unchanged.
|
||||||
|
SetLastError(0xDEADBEEF);
|
||||||
|
ok(SetDefaultPrinterW(NULL), "SetDefaultPrinterW returns FALSE!\n");
|
||||||
|
ok(GetLastError() == ERROR_SUCCESS, "SetDefaultPrinterW returns error %lu!\n", GetLastError());
|
||||||
|
|
||||||
|
// SetDefaultPrinterW with the previous default printer also needs to succeed.
|
||||||
|
SetLastError(0xDEADBEEF);
|
||||||
|
ok(SetDefaultPrinterW(pwszDefaultPrinter), "SetDefaultPrinterW returns FALSE!\n");
|
||||||
|
ok(GetLastError() == ERROR_SUCCESS, "SetDefaultPrinterW returns error %lu!\n", GetLastError());
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, pwszDefaultPrinter);
|
||||||
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
extern void func_ClosePrinter(void);
|
extern void func_ClosePrinter(void);
|
||||||
extern void func_EnumPrinters(void);
|
extern void func_EnumPrinters(void);
|
||||||
extern void func_EnumPrintProcessorDatatypes(void);
|
extern void func_EnumPrintProcessorDatatypes(void);
|
||||||
|
extern void func_GetDefaultPrinter(void);
|
||||||
extern void func_GetPrintProcessorDirectoryA(void);
|
extern void func_GetPrintProcessorDirectoryA(void);
|
||||||
extern void func_GetPrintProcessorDirectoryW(void);
|
extern void func_GetPrintProcessorDirectoryW(void);
|
||||||
extern void func_IsValidDevmodeA(void);
|
extern void func_IsValidDevmodeA(void);
|
||||||
|
@ -25,6 +26,7 @@ const struct test winetest_testlist[] =
|
||||||
{ "ClosePrinter", func_ClosePrinter },
|
{ "ClosePrinter", func_ClosePrinter },
|
||||||
{ "EnumPrinters", func_EnumPrinters },
|
{ "EnumPrinters", func_EnumPrinters },
|
||||||
{ "EnumPrintProcessorDatatypes", func_EnumPrintProcessorDatatypes },
|
{ "EnumPrintProcessorDatatypes", func_EnumPrintProcessorDatatypes },
|
||||||
|
{ "GetDefaultPrinter", func_GetDefaultPrinter },
|
||||||
{ "GetPrintProcessorDirectoryA", func_GetPrintProcessorDirectoryA },
|
{ "GetPrintProcessorDirectoryA", func_GetPrintProcessorDirectoryA },
|
||||||
{ "GetPrintProcessorDirectoryW", func_GetPrintProcessorDirectoryW },
|
{ "GetPrintProcessorDirectoryW", func_GetPrintProcessorDirectoryW },
|
||||||
{ "IsValidDevmodeA", func_IsValidDevmodeA },
|
{ "IsValidDevmodeA", func_IsValidDevmodeA },
|
||||||
|
|
Loading…
Reference in a new issue