reactos/win32ss/printing/providers/localspl/tools.c

131 lines
3.2 KiB
C
Raw Normal View History

Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
/*
* PROJECT: ReactOS Local Spooler
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
* PURPOSE: Various tools
* COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
*/
#include "precomp.h"
/**
* @name AllocAndRegQueryWSZ
*
* Queries a REG_SZ value in the registry, allocates memory for it and returns a buffer containing the value.
[LOCALSPL_APITEST] - Add more tests for fpEnumPrinters. For some reason, using SEH here works only once. We experience a hang in the testing process when you run the test again for a second time without restarting spoolsv. Needs more investigation. - Ensure that the spooler service is running before starting any testing. - Do proper cleanup in every case. [LOCALSPL] - Implement LocalEnumPrinters level 1 based on the API-Tests. - Use DllAllocSplMem/DllFreeSplMem instead of HeapAlloc/HeapFree. - Use AllocSplStr with DllFreeSplStr now that DuplicateStringW is gone. - Use _countof where applicable. [SPOOLSS] - Found out that I was not the only one needing a wcsdup equivalent. My DuplicateStringW from localspl is actually exported as AllocSplStr in spoolss. This is actually part of a range of undocumented memory functions in spoolss, so implement and document AllocSplStr, DllAllocSplMem, DllFreeSplMem, DllFreeSplStr, ReallocSplMem and ReallocSplStr. Information about some of them was gathered through black box testing and DDK samples (down to Win95 DDK), which at least contained prototypes of them. - Implement SplInitializeWinSpoolDrv based on the API-Test and simply return FALSE for SplIsUpgrade. [SPOOLSS_APITEST] - Add a test for ReallocSplStr, which was actually the most undocumented function of spoolss' memory functions. [WINSPOOL] SplInitializeWinSpoolDrv shows that we can't just auto-assign an ordinal to all winspool.drv functions. We even need to export some nameless functions by ordinal only. Redo the whole .spec file based on the ordinals found in Windows Server 2003's winspool.drv. Trust WINE for the nameless stubs. svn path=/branches/colins-printing-for-freedom/; revision=68089
2015-06-09 13:22:25 +00:00
* You have to free this buffer using DllFreeSplMem.
Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
*
* @param hKey
* HKEY variable of the key opened with RegOpenKeyExW.
*
* @param pwszValueName
* Name of the REG_SZ value to query.
*
* @return
* Pointer to the buffer containing the value or NULL in case of failure.
*/
PWSTR
AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName)
{
DWORD cbNeeded;
LONG lStatus;
PWSTR pwszValue;
// Determine the size of the required buffer.
lStatus = RegQueryValueExW(hKey, pwszValueName, NULL, NULL, NULL, &cbNeeded);
if (lStatus != ERROR_SUCCESS)
{
ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
return NULL;
}
// Allocate it.
[LOCALSPL_APITEST] - Add more tests for fpEnumPrinters. For some reason, using SEH here works only once. We experience a hang in the testing process when you run the test again for a second time without restarting spoolsv. Needs more investigation. - Ensure that the spooler service is running before starting any testing. - Do proper cleanup in every case. [LOCALSPL] - Implement LocalEnumPrinters level 1 based on the API-Tests. - Use DllAllocSplMem/DllFreeSplMem instead of HeapAlloc/HeapFree. - Use AllocSplStr with DllFreeSplStr now that DuplicateStringW is gone. - Use _countof where applicable. [SPOOLSS] - Found out that I was not the only one needing a wcsdup equivalent. My DuplicateStringW from localspl is actually exported as AllocSplStr in spoolss. This is actually part of a range of undocumented memory functions in spoolss, so implement and document AllocSplStr, DllAllocSplMem, DllFreeSplMem, DllFreeSplStr, ReallocSplMem and ReallocSplStr. Information about some of them was gathered through black box testing and DDK samples (down to Win95 DDK), which at least contained prototypes of them. - Implement SplInitializeWinSpoolDrv based on the API-Test and simply return FALSE for SplIsUpgrade. [SPOOLSS_APITEST] - Add a test for ReallocSplStr, which was actually the most undocumented function of spoolss' memory functions. [WINSPOOL] SplInitializeWinSpoolDrv shows that we can't just auto-assign an ordinal to all winspool.drv functions. We even need to export some nameless functions by ordinal only. Redo the whole .spec file based on the ordinals found in Windows Server 2003's winspool.drv. Trust WINE for the nameless stubs. svn path=/branches/colins-printing-for-freedom/; revision=68089
2015-06-09 13:22:25 +00:00
pwszValue = DllAllocSplMem(cbNeeded);
Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
if (!pwszValue)
{
[PRINTING] - Implement GetPrinterDataA, GetPrinterDataExA, GetPrinterDataExW, GetPrinterDataW, SetPrinterDataA, SetPrinterDataExA, SetPrinterDataExW, SetPrinterDataW. They support all features for Print Server and Printer Handles (minus security checks!) I've also added tests for them. - Store Printer data in SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers instead of SYSTEM\CurrentControlSet\Control\Print\Printers and create a registry symlink from the former path to the new one just like Windows does. According to https://social.technet.microsoft.com/Forums/windowsserver/en-US/a683ab54-c43c-4ebe-af8f-1f7a65af2a51, this is needed when having >900 printers to work around a size limit of the SYSTEM registry hive. And if Windows has both locations, we need both for compatibility anyway. - Add several settings which are queried by the new Printer Data APIs when working with Print Server Handles. - Store the job directory in the Windows-compatible "DefaultSpoolDirectory" setting and make use of it. - Revert the ASSERTs in LocalEnumPrinters again to let us verify the NULL pointer exceptions in localspl_apitest (thanks Serge! CORE-13433) - Translate ERROR_INVALID_NAME to ERROR_INVALID_PRINTER_NAME in all cases in OpenPrinterW (thanks Victor! CORE-13412) - Make EnumMonitorsW and EnumPortsW in spoolss more robust against failing Print Monitors. - Remove the wrong !phPrinter check in OpenPrinterW to make Print Server Handles work for real. - Fix error handling when memory allocation fails: HeapAlloc doesn't set last error, so it's just wrong to query or return it. One more item done from https://reactos.org/wiki/Printing ! This is all still a big Work-in-Progress, with many subtle bugs deep down in ReactOS, for which I need to open additional tickets. But I didn't want to make this commit even bigger.. svn path=/trunk/; revision=75125
2017-06-19 14:18:19 +00:00
ERR("DllAllocSplMem failed!\n");
Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
return NULL;
}
// Now get the actual value.
lStatus = RegQueryValueExW(hKey, pwszValueName, NULL, NULL, (PBYTE)pwszValue, &cbNeeded);
if (lStatus != ERROR_SUCCESS)
{
ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
[LOCALSPL_APITEST] - Add more tests for fpEnumPrinters. For some reason, using SEH here works only once. We experience a hang in the testing process when you run the test again for a second time without restarting spoolsv. Needs more investigation. - Ensure that the spooler service is running before starting any testing. - Do proper cleanup in every case. [LOCALSPL] - Implement LocalEnumPrinters level 1 based on the API-Tests. - Use DllAllocSplMem/DllFreeSplMem instead of HeapAlloc/HeapFree. - Use AllocSplStr with DllFreeSplStr now that DuplicateStringW is gone. - Use _countof where applicable. [SPOOLSS] - Found out that I was not the only one needing a wcsdup equivalent. My DuplicateStringW from localspl is actually exported as AllocSplStr in spoolss. This is actually part of a range of undocumented memory functions in spoolss, so implement and document AllocSplStr, DllAllocSplMem, DllFreeSplMem, DllFreeSplStr, ReallocSplMem and ReallocSplStr. Information about some of them was gathered through black box testing and DDK samples (down to Win95 DDK), which at least contained prototypes of them. - Implement SplInitializeWinSpoolDrv based on the API-Test and simply return FALSE for SplIsUpgrade. [SPOOLSS_APITEST] - Add a test for ReallocSplStr, which was actually the most undocumented function of spoolss' memory functions. [WINSPOOL] SplInitializeWinSpoolDrv shows that we can't just auto-assign an ordinal to all winspool.drv functions. We even need to export some nameless functions by ordinal only. Redo the whole .spec file based on the ordinals found in Windows Server 2003's winspool.drv. Trust WINE for the nameless stubs. svn path=/branches/colins-printing-for-freedom/; revision=68089
2015-06-09 13:22:25 +00:00
DllFreeSplMem(pwszValue);
Time to commit some Work-In-Progress stuff before my diff gets too large.. [LOCALSPL] - Begin work on the Local Spooler. Return a structure with function pointers in InitializePrintProvidor. - Design and document internal structures for managing LocalSpl Handles, Printer Handles, Printers, Print Jobs and Print Processors. Manage Printers and Print Processors in Generic Tables, with one Job Queue per Printer managed as a Doubly Linked List. - Implement LocalOpenPrinter, LocalEnumPrintProcessorDatatypes, LocalEnumPrintProcessors, LocalGetPrintProcessorDirectory, with focus on catching all corner cases. Currently working on LocalStartDocPrinter. - Build upon the documentation at http://www.undocprint.org/formats/winspool/shd to read and write .SHD files. [WINPRINT] Begin work on the Standard Print Processor. Implement EnumPrintProcessorDatatypesW. [WINSPOOL_APITEST] Add an API Test for winspool.drv, currently testing some corner cases of ClosePrinter, EnumPrintProcessorDatatypesW, GetPrintProcessorDirectoryW, OpenPrinterW, StartDocPrinterW. TODO: Find a way to actually test the localspl.dll functions instead of only winspool.drv. This DLL doesn't like to be tested standalone under Windows, e.g. without being used through spoolsv/spoolss. [SPOOLSS] Implement InitializeRouter by calling the InitializePrintProvidor function of localspl there. This function should later also initialize further Print Providers. [SPOOLSV] Call InitializeRouter when starting up the service. [WINSPOOL] Add dummy functions for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW. [All modules] Fix printf format specifiers for errors (%lu) and statuses (%ld). svn path=/branches/colins-printing-for-freedom/; revision=67847
2015-05-22 15:29:07 +00:00
return NULL;
}
return pwszValue;
}
PDEVMODEW
DuplicateDevMode(PDEVMODEW pInput)
{
PDEVMODEW pOutput;
// Allocate a buffer for this DevMode.
pOutput = DllAllocSplMem(pInput->dmSize + pInput->dmDriverExtra);
if (!pOutput)
{
[PRINTING] - Implement GetPrinterDataA, GetPrinterDataExA, GetPrinterDataExW, GetPrinterDataW, SetPrinterDataA, SetPrinterDataExA, SetPrinterDataExW, SetPrinterDataW. They support all features for Print Server and Printer Handles (minus security checks!) I've also added tests for them. - Store Printer data in SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers instead of SYSTEM\CurrentControlSet\Control\Print\Printers and create a registry symlink from the former path to the new one just like Windows does. According to https://social.technet.microsoft.com/Forums/windowsserver/en-US/a683ab54-c43c-4ebe-af8f-1f7a65af2a51, this is needed when having >900 printers to work around a size limit of the SYSTEM registry hive. And if Windows has both locations, we need both for compatibility anyway. - Add several settings which are queried by the new Printer Data APIs when working with Print Server Handles. - Store the job directory in the Windows-compatible "DefaultSpoolDirectory" setting and make use of it. - Revert the ASSERTs in LocalEnumPrinters again to let us verify the NULL pointer exceptions in localspl_apitest (thanks Serge! CORE-13433) - Translate ERROR_INVALID_NAME to ERROR_INVALID_PRINTER_NAME in all cases in OpenPrinterW (thanks Victor! CORE-13412) - Make EnumMonitorsW and EnumPortsW in spoolss more robust against failing Print Monitors. - Remove the wrong !phPrinter check in OpenPrinterW to make Print Server Handles work for real. - Fix error handling when memory allocation fails: HeapAlloc doesn't set last error, so it's just wrong to query or return it. One more item done from https://reactos.org/wiki/Printing ! This is all still a big Work-in-Progress, with many subtle bugs deep down in ReactOS, for which I need to open additional tickets. But I didn't want to make this commit even bigger.. svn path=/trunk/; revision=75125
2017-06-19 14:18:19 +00:00
ERR("DllAllocSplMem failed!\n");
return NULL;
}
// Copy it.
CopyMemory(pOutput, pInput, pInput->dmSize + pInput->dmDriverExtra);
return pOutput;
}
/******************************************************************
* copy_servername_from_name (internal)
*
* for an external server, the serverpart from the name is copied.
*
* RETURNS
* the length (in WCHAR) of the serverpart (0 for the local computer)
* (-length), when the name is too long
*
*/
LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
{
LPCWSTR server;
LPWSTR ptr;
WCHAR buffer[MAX_COMPUTERNAME_LENGTH +1];
DWORD len;
DWORD serverlen;
if (target) *target = '\0';
if (name == NULL) return 0;
if ((name[0] != '\\') || (name[1] != '\\')) return 0;
server = &name[2];
/* skip over both backslash, find separator '\' */
ptr = wcschr(server, '\\');
serverlen = (ptr) ? ptr - server : lstrlenW(server);
/* servername is empty */
if (serverlen == 0) return 0;
FIXME("found %s\n", debugstr_wn(server, serverlen));
if (serverlen > MAX_COMPUTERNAME_LENGTH) return -(LONG)serverlen;
if (target)
{
memcpy(target, server, serverlen * sizeof(WCHAR));
target[serverlen] = '\0';
}
len = ARRAYSIZE(buffer);
if (GetComputerNameW(buffer, &len))
{
if ((serverlen == len) && (_wcsnicmp(server, buffer, len) == 0))
{
/* The requested Servername is our computername */
return 0;
}
}
return serverlen;
}