Author: cfinck
Date: Tue Jun 9 13:22:25 2015
New Revision: 68089
URL:
http://svn.reactos.org/svn/reactos?rev=68089&view=rev
Log:
[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.
Added:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c
(with props)
branches/colins-printing-for-freedom/rostests/apitests/spoolss/ReallocSplStr.c (with
props)
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/winspool/winspool.spec
branches/colins-printing-for-freedom/reactos/win32ss/printing/include/spoolss.h
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/tools.c
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/CMakeLists.txt
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/fpEnumPrinters.c
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/main.c
branches/colins-printing-for-freedom/rostests/apitests/localspl/tests.c
branches/colins-printing-for-freedom/rostests/apitests/spoolss/CMakeLists.txt
branches/colins-printing-for-freedom/rostests/apitests/spoolss/SplInitializeWinSpoolDrv.c
branches/colins-printing-for-freedom/rostests/apitests/spoolss/testlist.c
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -4,6 +4,7 @@
list(APPEND SOURCE
context.c
main.c
+ memory.c
precomp.h
tools.c)
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -7,6 +7,7 @@
#include "precomp.h"
+HANDLE hProcessHeap;
PRINTPROVIDOR LocalSplFuncs;
@@ -14,6 +15,20 @@
ClosePrinter(HANDLE hPrinter)
{
return FALSE;
+}
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ hProcessHeap = GetProcessHeap();
+ break;
+ }
+
+ return TRUE;
}
BOOL WINAPI
@@ -95,6 +110,44 @@
return 0;
}
+BOOL WINAPI
+SplInitializeWinSpoolDrv(PVOID* pTable)
+{
+ HINSTANCE hWinspool;
+ int i;
+
+ hWinspool = LoadLibraryW(L"winspool.drv");
+ if (!hWinspool)
+ {
+ ERR("Could not load winspool.drv, last error is %lu!\n",
GetLastError());
+ return FALSE;
+ }
+
+ // Get the function pointers which are meant to be returned by this function.
+ pTable[0] = GetProcAddress(hWinspool, "OpenPrinterW");
+ pTable[1] = GetProcAddress(hWinspool, "ClosePrinter");
+ pTable[2] = GetProcAddress(hWinspool, "SpoolerDevQueryPrintW");
+ pTable[3] = GetProcAddress(hWinspool, "SpoolerPrinterEvent");
+ pTable[4] = GetProcAddress(hWinspool, "DocumentPropertiesW");
+ pTable[5] = GetProcAddress(hWinspool, (LPSTR)212);
+ pTable[6] = GetProcAddress(hWinspool, (LPSTR)213);
+ pTable[7] = GetProcAddress(hWinspool, (LPSTR)214);
+ pTable[8] = GetProcAddress(hWinspool, (LPSTR)215);
+
+ // Verify that all calls succeeded.
+ for (i = 0; i < 9; i++)
+ if (!pTable[i])
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOL WINAPI
+SplIsUpgrade()
+{
+ return FALSE;
+}
+
DWORD WINAPI
SpoolerInit()
{
Added:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c (added)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -0,0 +1,168 @@
+/*
+ * PROJECT: ReactOS Spooler Router
+ * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software
Foundation
+ * PURPOSE: Functions for allocating and freeing memory
+ * COPYRIGHT: Copyright 2015 Colin Finck <colin(a)reactos.org>
+ */
+
+#include "precomp.h"
+
+
+/**
+* @name AllocSplStr
+*
+* Allocates memory for a Unicode string and copies the input string into it.
+* Equivalent of wcsdup, but the returned buffer is allocated from the spooler heap and
must be freed with DllFreeSplStr.
+*
+* @param pwszInput
+* The input string to copy
+*
+* @return
+* Pointer to the copied string or NULL if no memory could be allocated.
+*/
+PWSTR WINAPI
+AllocSplStr(PCWSTR pwszInput)
+{
+ DWORD cbInput;
+ PWSTR pwszOutput;
+
+ // Sanity check
+ if (!pwszInput)
+ return NULL;
+
+ // Get the length of the input string.
+ cbInput = (wcslen(pwszInput) + 1) * sizeof(WCHAR);
+
+ // Allocate it. We don't use DllAllocSplMem here, because it unnecessarily zeroes
the memory.
+ pwszOutput = HeapAlloc(hProcessHeap, 0, cbInput);
+ if (!pwszOutput)
+ {
+ ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ return NULL;
+ }
+
+ // Copy the string and return it.
+ CopyMemory(pwszOutput, pwszInput, cbInput);
+ return pwszOutput;
+}
+
+/**
+ * @name DllAllocSplMem
+ *
+ * Allocate a block of zeroed memory.
+ * Windows allocates from a separate spooler heap here while we just use the process
heap.
+ *
+ * @param dwBytes
+ * Number of bytes to allocate.
+ *
+ * @return
+ * A pointer to the allocated memory or NULL in case of an error.
+ * You have to free this memory using DllFreeSplMem.
+ */
+PVOID WINAPI
+DllAllocSplMem(DWORD dwBytes)
+{
+ return HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, dwBytes);
+}
+
+/**
+ * @name DllFreeSplMem
+ *
+ * Frees the memory allocated with DllAllocSplMem.
+ *
+ * @param pMem
+ * Pointer to the allocated memory.
+ *
+ * @return
+ * TRUE in case of success, FALSE otherwise.
+ */
+BOOL WINAPI
+DllFreeSplMem(PVOID pMem)
+{
+ return HeapFree(hProcessHeap, 0, pMem);
+}
+
+/**
+ * @name DllFreeSplStr
+ *
+ * Frees the string allocated with AllocSplStr.
+ *
+ * @param pwszString
+ * Pointer to the allocated string.
+ *
+ * @return
+ * TRUE in case of success, FALSE otherwise.
+ */
+BOOL WINAPI
+DllFreeSplStr(PWSTR pwszString)
+{
+ return HeapFree(hProcessHeap, 0, pwszString);
+}
+
+/**
+ * @name ReallocSplMem
+ *
+ * Allocates a new block of memory and copies the contents of the old block into the new
one.
+ *
+ * @param pOldMem
+ * Pointer to the old block of memory.
+ * If this parameter is NULL, ReallocSplMem behaves exactly like DllAllocSplMem.
+ *
+ * @param cbOld
+ * Number of bytes to copy from the old block into the new one.
+ *
+ * @param cbNew
+ * Number of bytes to allocate for the new block.
+ *
+ * @return
+ * A pointer to the allocated new block or NULL in case of an error.
+ * You have to free this memory using DllFreeSplMem.
+ */
+PVOID WINAPI
+ReallocSplMem(PVOID pOldMem, DWORD cbOld, DWORD cbNew)
+{
+ PVOID pNewMem;
+
+ // Always allocate the new block of memory.
+ pNewMem = DllAllocSplMem(cbNew);
+ if (!pNewMem)
+ {
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ return NULL;
+ }
+
+ // Copy the old memory into the new block and free it.
+ if (pOldMem)
+ {
+ CopyMemory(pNewMem, pOldMem, min(cbOld, cbNew));
+ DllFreeSplMem(pOldMem);
+ }
+
+ return pNewMem;
+}
+
+/**
+ * @name ReallocSplStr
+ *
+ * Frees a string allocated by AllocSplStr and copies the given Unicode string into a
newly allocated block of memory.
+ *
+ * @param ppwszString
+ * Pointer to the string pointer allocated by AllocSplStr.
+ * When the function returns, the variable receives the pointer to the copied string.
+ *
+ * @param pwszInput
+ * The Unicode string to copy into the new block of memory.
+ *
+ * @return
+ * Returns TRUE in any case.
+*/
+BOOL WINAPI
+ReallocSplStr(PWSTR* ppwszString, PCWSTR pwszInput)
+{
+ if (*ppwszString)
+ DllFreeSplStr(*ppwszString);
+
+ *ppwszString = AllocSplStr(pwszInput);
+
+ return TRUE;
+}
Propchange:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -16,10 +16,15 @@
#include <winspool.h>
#include <winsplp.h>
+#include <spoolss.h>
+
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(spoolss);
// Function pointer to InitializePrintProvidor of a provider DLL
typedef BOOL (WINAPI *PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR);
+// main.c
+extern HANDLE hProcessHeap;
+
#endif
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -17,7 +17,7 @@
@ stub AdjustPointersInStructuresArray
@ stub AlignKMPtr
@ stub AlignRpcPtr
-@ stub AllocSplStr
+@ stdcall AllocSplStr(ptr)
@ stub AllowRemoteCalls
@ stub AppendPrinterNotifyInfoData
@ stub bGetDevModePerUser
@@ -53,9 +53,9 @@
@ stub DeletePrinterKeyW
@ stub DeletePrintProcessorW
@ stub DeletePrintProvidorW
-@ stub DllAllocSplMem
-@ stub DllFreeSplMem
-@ stub DllFreeSplStr
+@ stdcall DllAllocSplMem(long)
+@ stdcall DllFreeSplMem(ptr)
+@ stdcall DllFreeSplStr(ptr)
@ stdcall EndDocPrinter(long)
@ stdcall EndPagePrinter(long)
@ stub EnumFormsW
@@ -115,8 +115,8 @@
@ stub ProvidorFindFirstPrinterChangeNotification
@ stub pszDbgAllocMsgA
@ stub ReadPrinter
-@ stub ReallocSplMem
-@ stub ReallocSplStr
+@ stdcall ReallocSplMem(ptr long long)
+@ stdcall ReallocSplStr(ptr ptr)
@ stub RemoteFindFirstPrinterChangeNotification
@ stub ReplyClosePrinter
@ stub ReplyOpenPrinter
@@ -146,9 +146,9 @@
@ stub SplCommitSpoolData
@ stub SplDriverUnloadComplete
@ stub SplGetSpoolFileInfo
-@ stub SplInitializeWinSpoolDrv
+@ stdcall SplInitializeWinSpoolDrv(ptr)
@ stub SplIsSessionZero
-@ stub SplIsUpgrade
+@ stdcall SplIsUpgrade()
@ stub SplPowerEvent
@ stub SplProcessPnPEvent
@ stub SplPromptUIInUsersSession
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/winspool/winspool.spec
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/winspool/winspool.spec [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/winspool/winspool.spec [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -1,169 +1,200 @@
-@ stub AbortPrinter
-@ stub AddFormA
-@ stub AddFormW
-@ stub AddJobA
-@ stub AddJobW
-@ stub AddMonitorA
-@ stub AddMonitorW
-@ stub AddPortA
-@ stub AddPortExA
-@ stub AddPortExW
-@ stub AddPortW
-@ stub AddPrinterA
-@ stub AddPrinterConnectionA
-@ stub AddPrinterConnectionW
-@ stub AddPrinterDriverA
-@ stub AddPrinterDriverExA
-@ stub AddPrinterDriverExW
-@ stub AddPrinterDriverW
-@ stub AddPrinterW
-@ stub AddPrintProcessorA
-@ stub AddPrintProcessorW
-@ stub AddPrintProvidorA
-@ stub AddPrintProvidorW
-@ stub AdvancedDocumentPropertiesA
-@ stub AdvancedDocumentPropertiesW
-@ stub ADVANCEDSETUPDIALOG
-@ stub AdvancedSetupDialog
-@ stdcall ClosePrinter(long)
-@ stub CloseSpoolFileHandle
-@ stub CommitSpoolData
-@ stub ConfigurePortA
-@ stub ConfigurePortW
-@ stub ConnectToPrinterDlg
-@ stub ConvertAnsiDevModeToUnicodeDevmode
-@ stub ConvertUnicodeDevModeToAnsiDevmode
-@ stub CreatePrinterIC
-@ stub DeleteFormA
-@ stub DeleteFormW
-@ stub DeleteMonitorA
-@ stub DeleteMonitorW
-@ stub DeletePortA
-@ stub DeletePortW
-@ stub DeletePrinter
-@ stub DeletePrinterConnectionA
-@ stub DeletePrinterConnectionW
-@ stub DeletePrinterDataA
-@ stub DeletePrinterDataExA
-@ stub DeletePrinterDataExW
-@ stub DeletePrinterDataW
-@ stub DeletePrinterDriverA
-@ stub DeletePrinterDriverExA
-@ stub DeletePrinterDriverExW
-@ stub DeletePrinterDriverW
-@ stub DeletePrinterIC
-@ stub DeletePrinterKeyA
-@ stub DeletePrinterKeyW
-@ stub DeletePrintProcessorA
-@ stub DeletePrintProcessorW
-@ stub DeletePrintProvidorA
-@ stub DeletePrintProvidorW
-@ stub DEVICECAPABILITIES
-@ stub DeviceCapabilities
-@ stdcall DeviceCapabilitiesA(str str long ptr ptr)
-@ stdcall DeviceCapabilitiesW(wstr wstr long ptr ptr)
-@ stub DEVICEMODE
-@ stub DeviceMode
-@ stub DevicePropertySheets
-@ stub DevQueryPrint
-@ stub DevQueryPrintEx
-@ stub DocumentEvent
-@ stdcall DocumentPropertiesA(long long ptr ptr ptr long)
-@ stdcall DocumentPropertiesW(long long ptr ptr ptr long)
-@ stub DocumentPropertySheets
-@ stdcall EndDocPrinter(long)
-@ stdcall EndPagePrinter(long)
-@ stub EnumFormsA
-@ stub EnumFormsW
-@ stub EnumJobsA
-@ stub EnumJobsW
-@ stub EnumMonitorsA
-@ stub EnumMonitorsW
-@ stub EnumPortsA
-@ stub EnumPortsW
-@ stub EnumPrinterDataA
-@ stub EnumPrinterDataExA
-@ stub EnumPrinterDataExW
-@ stub EnumPrinterDataW
-@ stub EnumPrinterDriversA
-@ stub EnumPrinterDriversW
-@ stub EnumPrinterKeyA
-@ stub EnumPrinterKeyW
-@ stdcall EnumPrintersA(long ptr long ptr long ptr ptr)
-@ stdcall EnumPrintersW(long ptr long ptr long ptr ptr)
-@ stdcall EnumPrintProcessorDatatypesA(ptr ptr long ptr long ptr ptr)
-@ stdcall EnumPrintProcessorDatatypesW(ptr ptr long ptr long ptr ptr)
-@ stub EnumPrintProcessorsA
-@ stub EnumPrintProcessorsW
-@ stub EXTDEVICEMODE
-@ stub ExtDeviceMode
-@ stub FindClosePrinterChangeNotification
-@ stub FindFirstPrinterChangeNotification
-@ stub FindNextPrinterChangeNotification
-@ stub FlushPrinter
-@ stub FreePrinterNotifyInfo
-@ stdcall GetDefaultPrinterA(ptr ptr)
-@ stdcall GetDefaultPrinterW(ptr ptr)
-@ stub GetFormA
-@ stub GetFormW
-@ stub GetJobA
-@ stub GetJobW
-@ stdcall GetPrinterA(long long ptr long ptr)
-@ stub GetPrinterDataA
-@ stub GetPrinterDataExA
-@ stub GetPrinterDataExW
-@ stub GetPrinterDataW
-@ stdcall GetPrinterDriverA(long str long ptr long ptr)
-@ stub GetPrinterDriverDirectoryA
-@ stub GetPrinterDriverDirectoryW
-@ stdcall GetPrinterDriverW(long wstr long ptr long ptr)
-@ stdcall GetPrinterW(long long ptr long ptr)
-@ stub GetPrintProcessorDirectoryA
-@ stdcall GetPrintProcessorDirectoryW(wstr wstr long ptr long ptr)
-@ stub GetSpoolFileHandle
-@ stub IsValidDevmodeA
-@ stub IsValidDevmodeW
-@ stdcall OpenPrinterA(str ptr ptr)
-@ stdcall OpenPrinterW(wstr ptr ptr)
-@ stub PerfClose
-@ stub PerfCollect
-@ stub PerfOpen
-@ stub PlayGdiScriptOnPrinterIC
-@ stub PrinterMessageBoxA
-@ stub PrinterMessageBoxW
-@ stub PrinterProperties
-@ stub QueryColorProfile
-@ stub QueryRemoteFonts
-@ stub QuerySpoolMode
-@ stub ReadPrinter
-@ stub ResetPrinterA
-@ stub ResetPrinterW
-@ stub ScheduleJob
-@ stub SeekPrinter
-@ stub SetAllocFailCount
-@ stub SetDefaultPrinterA
-@ stub SetDefaultPrinterW
-@ stub SetFormA
-@ stub SetFormW
-@ stub SetJobA
-@ stub SetJobW
-@ stub SetPortA
-@ stub SetPortW
-@ stub SetPrinterA
-@ stub SetPrinterDataA
-@ stub SetPrinterDataExA
-@ stub SetPrinterDataExW
-@ stub SetPrinterDataW
-@ stub SetPrinterW
-@ stub SplDriverUnloadComplete
-@ stub SpoolerDevQueryPrintW
-@ stdcall SpoolerInit()
-@ stub SpoolerPrinterEvent
-@ stub StartDocDlgA
-@ stub StartDocDlgW
-@ stub StartDocPrinterA
-@ stdcall StartDocPrinterW(long long ptr)
-@ stdcall StartPagePrinter(long)
-@ stub WaitForPrinterChange
-@ stdcall WritePrinter(long ptr long ptr)
-@ stdcall XcvDataW(long wstr ptr long ptr long ptr ptr)
+100 stub -noname EnumPrinterPropertySheets
+101 stub -noname ClusterSplOpen
+102 stub -noname ClusterSplClose
+103 stub -noname ClusterSplIsAlive
+104 stub PerfClose
+105 stub PerfCollect
+106 stub PerfOpen
+107 stub ADVANCEDSETUPDIALOG
+108 stub AbortPrinter
+109 stub AddFormA
+110 stub AddFormW
+111 stub AddJobA
+112 stub AddJobW
+113 stub AddMonitorA
+114 stub AddMonitorW
+115 stub AddPortA
+116 stub AddPortExA
+117 stub AddPortExW
+118 stub AddPortW
+119 stub AddPrintProcessorA
+120 stub AddPrintProcessorW
+121 stub AddPrintProvidorA
+122 stub AddPrintProvidorW
+123 stub AddPrinterA
+124 stub AddPrinterConnectionA
+125 stub AddPrinterConnectionW
+126 stub AddPrinterDriverA
+127 stub AddPrinterDriverExA
+128 stub AddPrinterDriverExW
+129 stub AddPrinterDriverW
+130 stub AddPrinterW
+131 stub AdvancedDocumentPropertiesA
+132 stub AdvancedDocumentPropertiesW
+133 stub AdvancedSetupDialog
+134 stdcall ClosePrinter(long)
+135 stub CloseSpoolFileHandle
+136 stub CommitSpoolData
+137 stub ConfigurePortA
+138 stub ConfigurePortW
+139 stub ConnectToPrinterDlg
+140 stub ConvertAnsiDevModeToUnicodeDevmode
+141 stub ConvertUnicodeDevModeToAnsiDevmode
+142 stub CreatePrinterIC
+143 stub DEVICECAPABILITIES
+144 stub DEVICEMODE
+145 stub DeleteFormA
+146 stub DeleteFormW
+147 stub DeleteMonitorA
+148 stub DeleteMonitorW
+149 stub DeletePortA
+150 stub DeletePortW
+151 stub DeletePrintProcessorA
+152 stub DeletePrintProcessorW
+153 stub DeletePrintProvidorA
+154 stub DeletePrintProvidorW
+155 stub DeletePrinter
+156 stub DeletePrinterConnectionA
+157 stub DeletePrinterConnectionW
+158 stub DeletePrinterDataA
+159 stub DeletePrinterDataExA
+160 stub DeletePrinterDataExW
+161 stub DeletePrinterDataW
+162 stub DeletePrinterDriverA
+163 stub DeletePrinterDriverExA
+164 stub DeletePrinterDriverExW
+165 stub DeletePrinterDriverW
+166 stub DeletePrinterIC
+167 stub DeletePrinterKeyA
+168 stub DeletePrinterKeyW
+169 stub DevQueryPrint
+170 stub DevQueryPrintEx
+171 stub DeviceCapabilities
+172 stdcall DeviceCapabilitiesA(str str long ptr ptr)
+173 stdcall DeviceCapabilitiesW(wstr wstr long ptr ptr)
+174 stub DeviceMode
+175 stub DevicePropertySheets
+176 stub DocumentEvent
+177 stdcall DocumentPropertiesA(long long ptr ptr ptr long)
+178 stdcall DocumentPropertiesW(long long ptr ptr ptr long)
+179 stub DocumentPropertySheets
+180 stub EXTDEVICEMODE
+181 stdcall EndDocPrinter(long)
+182 stdcall EndPagePrinter(long)
+183 stub EnumFormsA
+184 stub EnumFormsW
+185 stub EnumJobsA
+186 stub EnumJobsW
+187 stub EnumMonitorsA
+188 stub EnumMonitorsW
+189 stub EnumPortsA
+190 stub EnumPortsW
+191 stdcall EnumPrintProcessorDatatypesA(ptr ptr long ptr long ptr ptr)
+192 stdcall EnumPrintProcessorDatatypesW(ptr ptr long ptr long ptr ptr)
+193 stub EnumPrintProcessorsA
+194 stub EnumPrintProcessorsW
+195 stub EnumPrinterDataA
+196 stub EnumPrinterDataExA
+197 stub EnumPrinterDataExW
+198 stub EnumPrinterDataW
+199 stub EnumPrinterDriversA
+200 stub EnumPrinterDriversW
+201 stdcall GetDefaultPrinterA(ptr ptr)
+202 stub SetDefaultPrinterA
+203 stdcall GetDefaultPrinterW(ptr ptr)
+204 stub SetDefaultPrinterW
+205 stub -noname SplReadPrinter
+206 stub -noname AddPerMachineConnectionA
+207 stub -noname AddPerMachineConnectionW
+208 stub -noname DeletePerMachineConnectionA
+209 stub -noname DeletePerMachineConnectionW
+210 stub -noname EnumPerMachineConnectionsA
+211 stub -noname EnumPerMachineConnectionsW
+212 stub -noname LoadPrinterDriver
+213 stub -noname RefCntLoadDriver
+214 stub -noname RefCntUnloadDriver
+215 stub -noname ForceUnloadDriver
+216 stub -noname PublishPrinterA
+217 stub -noname PublishPrinterW
+218 stub -noname CallCommonPropertySheetUI
+219 stub -noname PrintUIQueueCreate
+220 stub -noname PrintUIPrinterPropPages
+221 stub -noname PrintUIDocumentDefaults
+222 stub -noname SendRecvBidiData
+223 stub -noname RouterFreeBidiResponseContainer
+224 stub -noname ExternalConnectToLd64In32Server
+225 stub EnumPrinterKeyA
+226 stub -noname PrintUIWebPnpEntry
+227 stub -noname PrintUIWebPnpPostEntry
+228 stub -noname PrintUICreateInstance
+229 stub -noname PrintUIDocumentPropertiesWrap
+230 stub -noname PrintUIPrinterSetup
+231 stub -noname PrintUIServerPropPages
+232 stub -noname AddDriverCatalog
+233 stub EnumPrinterKeyW
+234 stdcall EnumPrintersA(long ptr long ptr long ptr ptr)
+235 stdcall EnumPrintersW(long ptr long ptr long ptr ptr)
+236 stub ExtDeviceMode
+237 stub FindClosePrinterChangeNotification
+238 stub FindFirstPrinterChangeNotification
+239 stub FindNextPrinterChangeNotification
+240 stub FlushPrinter
+241 stub FreePrinterNotifyInfo
+242 stub GetFormA
+243 stub GetFormW
+244 stub GetJobA
+245 stub GetJobW
+246 stub GetPrintProcessorDirectoryA
+247 stdcall GetPrintProcessorDirectoryW(wstr wstr long ptr long ptr)
+248 stdcall GetPrinterA(long long ptr long ptr)
+249 stub GetPrinterDataA
+250 stub GetPrinterDataExA
+251 stub GetPrinterDataExW
+252 stub GetPrinterDataW
+253 stdcall GetPrinterDriverA(long str long ptr long ptr)
+254 stub GetPrinterDriverDirectoryA
+255 stub GetPrinterDriverDirectoryW
+256 stdcall GetPrinterDriverW(long wstr long ptr long ptr)
+257 stdcall GetPrinterW(long long ptr long ptr)
+258 stub GetSpoolFileHandle
+259 stub IsValidDevmodeA
+260 stub IsValidDevmodeW
+261 stdcall OpenPrinterA(str ptr ptr)
+262 stdcall OpenPrinterW(wstr ptr ptr)
+263 stub PlayGdiScriptOnPrinterIC
+264 stub PrinterMessageBoxA
+265 stub PrinterMessageBoxW
+266 stub PrinterProperties
+267 stub QueryColorProfile
+268 stub QueryRemoteFonts
+269 stub QuerySpoolMode
+270 stub ReadPrinter
+271 stub ResetPrinterA
+272 stub ResetPrinterW
+273 stub ScheduleJob
+274 stub SeekPrinter
+275 stub SetAllocFailCount
+276 stub SetFormA
+277 stub SetFormW
+278 stub SetJobA
+279 stub SetJobW
+280 stub SetPortA
+281 stub SetPortW
+282 stub SetPrinterA
+283 stub SetPrinterDataA
+284 stub SetPrinterDataExA
+285 stub SetPrinterDataExW
+286 stub SetPrinterDataW
+287 stub SetPrinterW
+288 stub SplDriverUnloadComplete
+289 stub SpoolerDevQueryPrintW
+290 stdcall SpoolerInit()
+291 stub SpoolerPrinterEvent
+292 stub StartDocDlgA
+293 stub StartDocDlgW
+294 stub StartDocPrinterA
+295 stdcall StartDocPrinterW(long long ptr)
+296 stdcall StartPagePrinter(long)
+297 stub WaitForPrinterChange
+298 stdcall WritePrinter(long ptr long ptr)
+299 stdcall XcvDataW(long wstr ptr long ptr long ptr ptr)
Modified: branches/colins-printing-for-freedom/reactos/win32ss/printing/include/spoolss.h
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/include/spoolss.h [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/include/spoolss.h [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -8,7 +8,13 @@
#ifndef _REACTOS_SPOOLSS_H
#define _REACTOS_SPOOLSS_H
-PBYTE WINAPI
-PackStrings(PCWSTR* pSource, PBYTE pDest, PDWORD DestOffsets, PBYTE pEnd);
+PWSTR WINAPI AllocSplStr(PCWSTR pwszInput);
+PVOID WINAPI DllAllocSplMem(DWORD dwBytes);
+BOOL WINAPI DllFreeSplMem(PVOID pMem);
+BOOL WINAPI DllFreeSplStr(PWSTR pwszString);
+PBYTE WINAPI PackStrings(PCWSTR* pSource, PBYTE pDest, PDWORD DestOffsets, PBYTE pEnd);
+PVOID WINAPI ReallocSplMem(PVOID pOldMem, DWORD cbOld, DWORD cbNew);
+BOOL WINAPI ReallocSplStr(PWSTR* ppwszString, PCWSTR pwszInput);
+BOOL WINAPI SplInitializeWinSpoolDrv(PVOID* pTable);
#endif
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -17,6 +17,6 @@
set_module_type(localspl win32dll UNICODE)
target_link_libraries(localspl wine)
-add_importlibs(localspl advapi32 msvcrt kernel32 ntdll)
+add_importlibs(localspl advapi32 spoolss msvcrt kernel32 ntdll)
add_pch(localspl precomp.h SOURCE)
add_cd_file(TARGET localspl DESTINATION reactos/system32 FOR all)
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -13,7 +13,7 @@
InitializeJobQueue()
{
const WCHAR wszPath[] = L"\\PRINTERS\\?????.SHD";
- const DWORD cchPath = sizeof(wszPath) / sizeof(WCHAR) - 1;
+ const DWORD cchPath = _countof(wszPath) - 1;
const DWORD cchFolders = sizeof("\\PRINTERS\\") - 1;
const DWORD cchPattern = sizeof("?????") - 1;
@@ -86,10 +86,10 @@
// Get its file size (small enough for a single DWORD) and allocate memory for all of
it.
cbFileSize = GetFileSize(hFile, NULL);
- pShadowFile = HeapAlloc(hProcessHeap, 0, cbFileSize);
+ pShadowFile = DllAllocSplMem(cbFileSize);
if (!pShadowFile)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -117,17 +117,17 @@
}
// Create a new job structure and copy over the relevant fields.
- pJob = HeapAlloc(hProcessHeap, 0, sizeof(LOCAL_JOB));
+ pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
if (!pJob)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
pJob->dwJobID = pShadowFile->dwJobID;
pJob->Printer = pPrinter;
- pJob->pwszDatatype = DuplicateStringW((PCWSTR)((ULONG_PTR)pShadowFile +
pShadowFile->offDatatype));
- pJob->pwszDocumentName = DuplicateStringW((PCWSTR)((ULONG_PTR)pShadowFile +
pShadowFile->offDocumentName));
+ pJob->pwszDatatype = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile +
pShadowFile->offDatatype));
+ pJob->pwszDocumentName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile +
pShadowFile->offDocumentName));
pJob->pwszOutputFile = NULL;
CopyMemory(&pJob->DevMode, (PDEVMODEW)((ULONG_PTR)pShadowFile +
pShadowFile->offDevMode), sizeof(DEVMODEW));
@@ -135,7 +135,7 @@
Cleanup:
if (pShadowFile)
- HeapFree(hProcessHeap, 0, pShadowFile);
+ DllFreeSplMem(pShadowFile);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
@@ -171,10 +171,10 @@
cbFileSize = sizeof(SHD_HEADER) + cbDatatype + cbDocumentName + cbPrinterName;
// Allocate memory for it.
- pShadowFile = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, cbFileSize);
+ pShadowFile = DllAllocSplMem(cbFileSize);
if (!pShadowFile)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -210,7 +210,7 @@
Cleanup:
if (pShadowFile)
- HeapFree(hProcessHeap, 0, pShadowFile);
+ DllFreeSplMem(pShadowFile);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
@@ -223,10 +223,10 @@
{
////////// TODO /////////
/// Add some checks
- HeapFree(hProcessHeap, 0, pJob->pwszDatatype);
- HeapFree(hProcessHeap, 0, pJob->pwszDocumentName);
- HeapFree(hProcessHeap, 0, pJob->pwszOutputFile);
- HeapFree(hProcessHeap, 0, pJob);
+ DllFreeSplStr(pJob->pwszDatatype);
+ DllFreeSplStr(pJob->pwszDocumentName);
+ DllFreeSplStr(pJob->pwszOutputFile);
+ DllFreeSplMem(pJob);
return TRUE;
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -8,7 +8,6 @@
#include "precomp.h"
// Global Variables
-HANDLE hProcessHeap;
WCHAR wszSpoolDirectory[MAX_PATH];
DWORD cchSpoolDirectory;
@@ -23,6 +22,12 @@
#else
#error Unsupported architecture
#endif
+
+const WCHAR* wszPrintProviderInfo[3] = {
+ L"Windows NT Local Print Providor", // Name
+ L"Windows NT Local Printers", // Description
+ L"Locally connected Printers" // Comment
+};
static const PRINTPROVIDOR PrintProviderFunctions = {
LocalOpenPrinter, // fpOpenPrinter
@@ -117,7 +122,7 @@
_GetSpoolDirectory()
{
const WCHAR wszSpoolPath[] = L"\\spool";
- const DWORD cchSpoolPath = sizeof(wszSpoolPath) / sizeof(WCHAR) - 1;
+ const DWORD cchSpoolPath = _countof(wszSpoolPath) - 1;
// Get the system directory and append the "spool" subdirectory.
// Forget about length checks here. If this doesn't fit into MAX_PATH, our OS has
more serious problems...
@@ -133,7 +138,6 @@
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
- hProcessHeap = GetProcessHeap();
_GetSpoolDirectory();
InitializePrintProcessorTable();
InitializePrinterTable();
@@ -146,14 +150,7 @@
BOOL WINAPI
InitializePrintProvidor(LPPRINTPROVIDOR pPrintProvidor, DWORD cbPrintProvidor, LPWSTR
pFullRegistryPath)
{
- DWORD cbCopy;
-
- if (cbPrintProvidor < sizeof(PRINTPROVIDOR))
- cbCopy = cbPrintProvidor;
- else
- cbCopy = sizeof(PRINTPROVIDOR);
-
- CopyMemory(pPrintProvidor, &PrintProviderFunctions, cbCopy);
+ CopyMemory(pPrintProvidor, &PrintProviderFunctions, min(cbPrintProvidor,
sizeof(PRINTPROVIDOR)));
return TRUE;
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -10,6 +10,7 @@
#define WIN32_NO_STATUS
#include <limits.h>
+#include <stdlib.h>
#include <wchar.h>
#include <windef.h>
@@ -19,6 +20,8 @@
#include <winspool.h>
#include <winsplp.h>
#include <ndk/rtlfuncs.h>
+
+#include <spoolss.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(localspl);
@@ -62,6 +65,8 @@
typedef struct _LOCAL_PRINTER
{
PWSTR pwszPrinterName;
+ PWSTR pwszPrinterDriver;
+ PWSTR pwszDescription;
PWSTR pwszDefaultDatatype;
DEVMODEW DefaultDevMode;
PLOCAL_PRINT_PROCESSOR pPrintProcessor;
@@ -157,7 +162,7 @@
// main.c
extern const WCHAR wszCurrentEnvironment[];
-extern HANDLE hProcessHeap;
+extern const WCHAR* wszPrintProviderInfo[3];
extern WCHAR wszSpoolDirectory[MAX_PATH];
extern DWORD cchSpoolDirectory;
@@ -182,7 +187,6 @@
// tools.c
PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName);
-PWSTR DuplicateStringW(PCWSTR pwszInput);
PVOID NTAPI GenericTableAllocateRoutine(PRTL_GENERIC_TABLE Table, CLONG ByteSize);
VOID NTAPI GenericTableFreeRoutine(PRTL_GENERIC_TABLE Table, PVOID Buffer);
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -90,20 +90,20 @@
if (pPrinter)
{
if (pPrinter->pwszDefaultDatatype)
- HeapFree(hProcessHeap, 0, pPrinter->pwszDefaultDatatype);
-
- HeapFree(hProcessHeap, 0, pPrinter);
+ DllFreeSplStr(pPrinter->pwszDefaultDatatype);
+
+ DllFreeSplMem(pPrinter);
pPrinter = NULL;
}
if (pwszPrintProcessor)
{
- HeapFree(hProcessHeap, 0, pwszPrintProcessor);
+ DllFreeSplStr(pwszPrintProcessor);
pwszPrintProcessor = NULL;
}
// Get the name of this printer.
- cchPrinterName = sizeof(wszPrinterName) / sizeof(WCHAR);
+ cchPrinterName = _countof(wszPrinterName);
lStatus = RegEnumKeyExW(hKey, i, wszPrinterName, &cchPrinterName, NULL, NULL,
NULL, NULL);
if (lStatus == ERROR_MORE_DATA)
{
@@ -138,16 +138,26 @@
}
// Create a new LOCAL_PRINTER structure for it.
- pPrinter = HeapAlloc(hProcessHeap, 0, sizeof(LOCAL_PRINTER));
+ pPrinter = DllAllocSplMem(sizeof(LOCAL_PRINTER));
if (!pPrinter)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
- pPrinter->pwszPrinterName = DuplicateStringW(wszPrinterName);
+ pPrinter->pwszPrinterName = AllocSplStr(wszPrinterName);
pPrinter->pPrintProcessor = pPrintProcessor;
InitializeListHead(&pPrinter->JobQueue);
+
+ // Get the printer driver.
+ pPrinter->pwszPrinterDriver = AllocAndRegQueryWSZ(hSubKey, L"Printer
Driver");
+ if (!pPrinter->pwszPrinterDriver)
+ continue;
+
+ // Get the description.
+ pPrinter->pwszDescription = AllocAndRegQueryWSZ(hSubKey,
L"Description");
+ if (!pPrinter->pwszDescription)
+ continue;
// Get the default datatype.
pPrinter->pwszDefaultDatatype = AllocAndRegQueryWSZ(hSubKey,
L"Datatype");
@@ -183,14 +193,14 @@
Cleanup:
if (pwszPrintProcessor)
- HeapFree(hProcessHeap, 0, pwszPrintProcessor);
+ DllFreeSplStr(pwszPrintProcessor);
if (pPrinter)
{
if (pPrinter->pwszDefaultDatatype)
- HeapFree(hProcessHeap, 0, pPrinter->pwszDefaultDatatype);
-
- HeapFree(hProcessHeap, 0, pPrinter);
+ DllFreeSplStr(pPrinter->pwszDefaultDatatype);
+
+ DllFreeSplMem(pPrinter);
}
if (hSubKey)
@@ -201,11 +211,189 @@
}
+BOOL
+_LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cbBuf,
LPDWORD pcbNeeded, LPDWORD pcReturned)
+{
+ const WCHAR wszComma[] = L",";
+
+ DWORD cbName;
+ DWORD cbComment;
+ DWORD cbDescription;
+ DWORD cchComputerName = 0;
+ DWORD i;
+ PBYTE pPrinterInfo;
+ PBYTE pPrinterString;
+ PLOCAL_PRINTER pPrinter;
+ PRINTER_INFO_1W PrinterInfo1;
+ PVOID pRestartKey = NULL;
+ WCHAR wszComputerName[2 + MAX_COMPUTERNAME_LENGTH + 1 + 1];
+
+ DWORD dwOffsets[] = {
+ FIELD_OFFSET(PRINTER_INFO_1W, pName),
+ FIELD_OFFSET(PRINTER_INFO_1W, pDescription),
+ FIELD_OFFSET(PRINTER_INFO_1W, pComment),
+ MAXDWORD
+ };
+
+ if (Flags & PRINTER_ENUM_NAME)
+ {
+ if (Name)
+ {
+ // The user supplied a Computer Name (with leading double backslashes) or
Print Provider Name.
+ // Only process what's directed at us and dismiss every other request
with ERROR_INVALID_NAME.
+ if (Name[0] == L'\\' && Name[1] == L'\\')
+ {
+ // Prepend slashes to the computer name.
+ wszComputerName[0] = L'\\';
+ wszComputerName[1] = L'\\';
+
+ // Get the local computer name for comparison.
+ cchComputerName = MAX_COMPUTERNAME_LENGTH + 1;
+ if (!GetComputerNameW(&wszComputerName[2], &cchComputerName))
+ {
+ ERR("GetComputerNameW failed with error %lu!\n",
GetLastError());
+ return FALSE;
+ }
+
+ // Add the leading slashes to the total length.
+ cchComputerName += 2;
+
+ // 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;
+ }
+
+ // Add a trailing backslash to wszComputerName, which will later be
prepended in front of the printer names.
+ wszComputerName[cchComputerName++] = L'\\';
+ wszComputerName[cchComputerName] = 0;
+ }
+ 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;
+ }
+ }
+ else
+ {
+ // The caller wants information about this Print Provider.
+ // spoolss packs this into an array of information about all Print
Providers.
+ *pcbNeeded = sizeof(PRINTER_INFO_1W);
+
+ for (i = 0; i < 3; i++)
+ *pcbNeeded += (wcslen(wszPrintProviderInfo[i]) + 1) * sizeof(WCHAR);
+
+ *pcReturned = 1;
+
+ // Check if the supplied buffer is large enough.
+ if (cbBuf < *pcbNeeded)
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+
+ // Copy over the print processor information.
+ ((PPRINTER_INFO_1W)pPrinterEnum)->Flags = 0;
+ PackStrings(wszPrintProviderInfo, pPrinterEnum, dwOffsets,
&pPrinterEnum[*pcbNeeded]);
+ return TRUE;
+ }
+ }
+
+ // Count the required buffer size and the number of printers.
+ for (pPrinter = RtlEnumerateGenericTableWithoutSplaying(&PrinterTable,
&pRestartKey); pPrinter; pPrinter =
RtlEnumerateGenericTableWithoutSplaying(&PrinterTable, &pRestartKey))
+ {
+ // This looks wrong, but is totally right. PRINTER_INFO_1W has three members
pName, pComment and pDescription.
+ // But pComment equals the "Description" registry value while
pDescription is concatenated out of pName and pComment.
+ // On top of this, the computer name is prepended to the printer name if the user
supplied the local computer name during the query.
+ cbName = (wcslen(pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR);
+ cbComment = (wcslen(pPrinter->pwszDescription) + 1) * sizeof(WCHAR);
+ cbDescription = cchComputerName * sizeof(WCHAR) + cbName + cbComment +
sizeof(WCHAR);
+
+ *pcbNeeded += sizeof(PRINTER_INFO_1W) + cchComputerName * sizeof(WCHAR) + cbName
+ cbComment + cbDescription;
+ *pcReturned++;
+ }
+
+ // Check if the supplied buffer is large enough.
+ if (cbBuf < *pcbNeeded)
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+
+ // Put the strings right after the last PRINTER_INFO_1W structure.
+ // Due to all the required string processing, we can't just use PackStrings here
:(
+ pPrinterInfo = pPrinterEnum;
+ pPrinterString = pPrinterEnum + *pcReturned * sizeof(PRINTER_INFO_1W);
+
+ // Copy over the printer information.
+ for (pPrinter = RtlEnumerateGenericTableWithoutSplaying(&PrinterTable,
&pRestartKey); pPrinter; pPrinter =
RtlEnumerateGenericTableWithoutSplaying(&PrinterTable, &pRestartKey))
+ {
+ // FIXME: As for now, the Flags member returns no information.
+ PrinterInfo1.Flags = 0;
+
+ // Copy the printer name.
+ PrinterInfo1.pName = (PWSTR)pPrinterString;
+ CopyMemory(pPrinterString, wszComputerName, cchComputerName * sizeof(WCHAR));
+ pPrinterString += cchComputerName * sizeof(WCHAR);
+ cbName = (wcslen(pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR);
+ CopyMemory(pPrinterString, pPrinter->pwszPrinterName, cbName);
+ pPrinterString += cbName;
+
+ // Copy the printer comment (equals the "Description" registry value).
+ PrinterInfo1.pComment = (PWSTR)pPrinterString;
+ cbComment = (wcslen(pPrinter->pwszDescription) + 1) * sizeof(WCHAR);
+ CopyMemory(pPrinterString, pPrinter->pwszDescription, cbComment);
+ pPrinterString += cbComment;
+
+ // Copy the description, which for PRINTER_INFO_1W has the form
"Name,Comment,"
+ PrinterInfo1.pDescription = (PWSTR)pPrinterString;
+ CopyMemory(pPrinterString, wszComputerName, cchComputerName * sizeof(WCHAR));
+ pPrinterString += cchComputerName * sizeof(WCHAR);
+ CopyMemory(pPrinterString, pPrinter->pwszPrinterName, cbName -
sizeof(WCHAR));
+ pPrinterString += cbName - sizeof(WCHAR);
+ CopyMemory(pPrinterString, wszComma, sizeof(WCHAR));
+ pPrinterString += sizeof(WCHAR);
+ CopyMemory(pPrinterString, pPrinter->pwszDescription, cbComment -
sizeof(WCHAR));
+ pPrinterString += cbComment - sizeof(WCHAR);
+ CopyMemory(pPrinterString, wszComma, sizeof(wszComma));
+ pPrinterString += sizeof(wszComma);
+
+ // Finally copy the structure and advance to the next one in the output buffer.
+ CopyMemory(pPrinterInfo, &PrinterInfo1, sizeof(PRINTER_INFO_1W));
+ pPrinterInfo += sizeof(PRINTER_INFO_1W);
+ }
+
+ return TRUE;
+}
+
BOOL WINAPI
LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD
cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
{
- ///////////// TODO /////////////////////
- return FALSE;
+ // Do no sanity checks here. This is verified by localspl_apitest!
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // Think positive :)
+ SetLastError(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;
+ }
+
+ // Treat it as success if the caller queried no information and we don't need to
return any.
+ return TRUE;
}
BOOL WINAPI
@@ -250,7 +438,7 @@
*p = 0;
// Get the local computer name for comparison.
- cchComputerName = sizeof(wszComputerName) / sizeof(WCHAR);
+ cchComputerName = _countof(wszComputerName);
if (!GetComputerNameW(wszComputerName, &cchComputerName))
{
ERR("GetComputerNameW failed with error %lu!\n", GetLastError());
@@ -286,7 +474,7 @@
if (cchPrinterName)
{
// Yes, extract it.
- pwszPrinterName = HeapAlloc(hProcessHeap, 0, (cchPrinterName + 1) *
sizeof(WCHAR));
+ pwszPrinterName = DllAllocSplMem((cchPrinterName + 1) * sizeof(WCHAR));
CopyMemory(pwszPrinterName, lpPrinterName, cchPrinterName * sizeof(WCHAR));
pwszPrinterName[cchPrinterName] = 0;
@@ -300,7 +488,7 @@
}
// Create a new printer handle.
- pPrinterHandle = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY,
sizeof(LOCAL_PRINTER_HANDLE));
+ pPrinterHandle = DllAllocSplMem(sizeof(LOCAL_PRINTER_HANDLE));
pPrinterHandle->Printer = pPrinter;
// Check if a datatype was given.
@@ -313,12 +501,12 @@
goto Cleanup;
}
- pPrinterHandle->pwszDatatype = DuplicateStringW(pDefault->pDatatype);
+ pPrinterHandle->pwszDatatype = AllocSplStr(pDefault->pDatatype);
}
else
{
// Use the default datatype.
- pPrinterHandle->pwszDatatype =
DuplicateStringW(pPrinter->pwszDefaultDatatype);
+ pPrinterHandle->pwszDatatype =
AllocSplStr(pPrinter->pwszDefaultDatatype);
}
// Check if a DevMode was given, otherwise use the default.
@@ -389,7 +577,7 @@
}
// Create a new handle that references a printer.
- pHandle = HeapAlloc(hProcessHeap, 0, sizeof(LOCAL_HANDLE));
+ pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
pHandle->HandleType = Printer;
pHandle->SpecificHandle = pPrinterHandle;
}
@@ -413,7 +601,7 @@
p += sizeof("XcvMonitor ") - 1;
///////////// TODO /////////////////////
- pHandle = HeapAlloc(hProcessHeap, 0, sizeof(LOCAL_HANDLE));
+ pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
pHandle->HandleType = Monitor;
//pHandle->SpecificHandle = pMonitorHandle;
}
@@ -423,7 +611,7 @@
p += sizeof("XcvPort ") - 1;
//////////// TODO //////////////////////
- pHandle = HeapAlloc(hProcessHeap, 0, sizeof(LOCAL_HANDLE));
+ pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
pHandle->HandleType = Port;
//pHandle->SpecificHandle = pPortHandle;
}
@@ -445,13 +633,13 @@
if (pPrinterHandle)
{
if (pPrinterHandle->pwszDatatype)
- HeapFree(hProcessHeap, 0, pPrinterHandle->pwszDatatype);
-
- HeapFree(hProcessHeap, 0, pPrinterHandle);
+ DllFreeSplStr(pPrinterHandle->pwszDatatype);
+
+ DllFreeSplMem(pPrinterHandle);
}
if (pwszPrinterName)
- HeapFree(hProcessHeap, 0, pwszPrinterName);
+ DllFreeSplMem(pwszPrinterName);
return bReturnValue;
}
@@ -498,7 +686,7 @@
pDocumentInfo1 = (PDOC_INFO_1W)pDocInfo;
// Create a new job.
- pJob = HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, sizeof(LOCAL_JOB));
+ pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
pJob->Printer = pPrinterHandle->Printer;
// Check if a datatype was given.
@@ -511,12 +699,12 @@
goto Cleanup;
}
- pJob->pwszDatatype = DuplicateStringW(pDocumentInfo1->pDatatype);
+ pJob->pwszDatatype = AllocSplStr(pDocumentInfo1->pDatatype);
}
else
{
// Use the printer handle datatype.
- pJob->pwszDatatype = DuplicateStringW(pPrinterHandle->pwszDatatype);
+ pJob->pwszDatatype = AllocSplStr(pPrinterHandle->pwszDatatype);
}
// Copy over printer defaults.
@@ -524,17 +712,17 @@
// Copy over supplied information.
if (pDocumentInfo1->pDocName)
- pJob->pwszDocumentName = DuplicateStringW(pDocumentInfo1->pDocName);
+ pJob->pwszDocumentName = AllocSplStr(pDocumentInfo1->pDocName);
if (pDocumentInfo1->pOutputFile)
- pJob->pwszOutputFile = DuplicateStringW(pDocumentInfo1->pOutputFile);
+ pJob->pwszOutputFile = AllocSplStr(pDocumentInfo1->pOutputFile);
// Enqueue the job.
///////////// TODO /////////////////////
Cleanup:
if (pJob)
- HeapFree(hProcessHeap, 0, pJob);
+ DllFreeSplMem(pJob);
return dwReturnValue;
}
@@ -584,7 +772,7 @@
/// Check the handle type, do thoroughful checks on all data fields and clean them.
////////////////////////////////////////
- HeapFree(hProcessHeap, 0, pHandle);
+ DllFreeSplMem(pHandle);
return TRUE;
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -31,7 +31,7 @@
_OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
{
const WCHAR wszEnvironmentsKey[] =
L"SYSTEM\\CurrentControlSet\\Control\\Print\\Environments\\";
- const DWORD cchEnvironmentsKey = sizeof(wszEnvironmentsKey) / sizeof(WCHAR) - 1;
+ const DWORD cchEnvironmentsKey = _countof(wszEnvironmentsKey) - 1;
BOOL bReturnValue = FALSE;
DWORD cchEnvironment;
@@ -44,10 +44,10 @@
// Construct the registry key of the demanded environment.
cchEnvironment = wcslen(pEnvironment);
- pwszEnvironmentKey = HeapAlloc(hProcessHeap, 0, (cchEnvironmentsKey + cchEnvironment
+ 1) * sizeof(WCHAR));
+ pwszEnvironmentKey = DllAllocSplMem((cchEnvironmentsKey + cchEnvironment + 1) *
sizeof(WCHAR));
if (!pwszEnvironmentKey)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -71,7 +71,7 @@
Cleanup:
if (pwszEnvironmentKey)
- HeapFree(hProcessHeap, 0, pwszEnvironmentKey);
+ DllFreeSplMem(pwszEnvironmentKey);
return bReturnValue;
}
@@ -182,10 +182,10 @@
}
// Allocate a temporary buffer for the Print Processor names.
- pwszPrintProcessorName = HeapAlloc(hProcessHeap, 0, (cchMaxSubKey + 1) *
sizeof(WCHAR));
+ pwszPrintProcessorName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
if (!pwszPrintProcessorName)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -202,15 +202,15 @@
if (pPrintProcessor)
{
if (pPrintProcessor->pwszName)
- HeapFree(hProcessHeap, 0, pPrintProcessor->pwszName);
-
- HeapFree(hProcessHeap, 0, pPrintProcessor);
+ DllFreeSplStr(pPrintProcessor->pwszName);
+
+ DllFreeSplMem(pPrintProcessor);
pPrintProcessor = NULL;
}
if (pDatatypesInfo1)
{
- HeapFree(hProcessHeap, 0, pDatatypesInfo1);
+ DllFreeSplMem(pDatatypesInfo1);
pDatatypesInfo1 = NULL;
}
@@ -259,8 +259,8 @@
}
// Create a new LOCAL_PRINT_PROCESSOR structure for it.
- pPrintProcessor = HeapAlloc(hProcessHeap, 0, sizeof(LOCAL_PRINT_PROCESSOR));
- pPrintProcessor->pwszName = DuplicateStringW(pwszPrintProcessorName);
+ pPrintProcessor = DllAllocSplMem(sizeof(LOCAL_PRINT_PROCESSOR));
+ pPrintProcessor->pwszName = AllocSplStr(pwszPrintProcessorName);
// Get and verify all its function pointers.
pPrintProcessor->pfnClosePrintProcessor =
(PClosePrintProcessor)GetProcAddress(hinstPrintProcessor,
"ClosePrintProcessor");
@@ -307,10 +307,10 @@
// Get all supported datatypes.
pPrintProcessor->pfnEnumPrintProcessorDatatypesW(NULL, NULL, 1, NULL, 0,
&cbDatatypes, &dwDatatypes);
- pDatatypesInfo1 = HeapAlloc(hProcessHeap, 0, cbDatatypes);
+ pDatatypesInfo1 = DllAllocSplMem(cbDatatypes);
if (!pDatatypesInfo1)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -325,7 +325,7 @@
for (j = 0; j < dwDatatypes; j++)
{
- pwszDatatype = DuplicateStringW(pDatatypesInfo1->pName);
+ pwszDatatype = AllocSplStr(pDatatypesInfo1->pName);
if (!RtlInsertElementGenericTable(&pPrintProcessor->DatatypeTable,
pDatatypesInfo1->pName, sizeof(PWSTR), NULL))
{
@@ -350,21 +350,21 @@
Cleanup:
if (pwszDatatype)
- HeapFree(hProcessHeap, 0, pwszDatatype);
+ DllFreeSplStr(pwszDatatype);
if (pDatatypesInfo1)
- HeapFree(hProcessHeap, 0, pDatatypesInfo1);
+ DllFreeSplMem(pDatatypesInfo1);
if (pPrintProcessor)
{
if (pPrintProcessor->pwszName)
- HeapFree(hProcessHeap, 0, pPrintProcessor->pwszName);
-
- HeapFree(hProcessHeap, 0, pPrintProcessor);
+ DllFreeSplStr(pPrintProcessor->pwszName);
+
+ DllFreeSplMem(pPrintProcessor);
}
if (pwszPrintProcessorName)
- HeapFree(hProcessHeap, 0, pwszPrintProcessorName);
+ DllFreeSplStr(pwszPrintProcessorName);
if (hSubSubKey)
RegCloseKey(hSubSubKey);
@@ -482,7 +482,6 @@
PBYTE pCurrentOutputPrintProcessor;
PBYTE pCurrentOutputPrintProcessorInfo;
PRINTPROCESSOR_INFO_1W PrintProcessorInfo1;
- PWSTR pwszEnvironmentKey = NULL;
PWSTR pwszTemp = NULL;
// Sanity checks
@@ -520,10 +519,10 @@
}
// Allocate a temporary buffer to let RegEnumKeyExW succeed.
- pwszTemp = HeapAlloc(hProcessHeap, 0, (cchMaxSubKey + 1) * sizeof(WCHAR));
+ pwszTemp = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
if (!pwszTemp)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -585,10 +584,7 @@
Cleanup:
if (pwszTemp)
- HeapFree(hProcessHeap, 0, pwszTemp);
-
- if (pwszEnvironmentKey)
- HeapFree(hProcessHeap, 0, pwszEnvironmentKey);
+ DllFreeSplMem(pwszTemp);
if (hSubKey)
RegCloseKey(hSubKey);
@@ -634,13 +630,12 @@
LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded)
{
const WCHAR wszPath[] = L"\\PRTPROCS\\";
- const DWORD cchPath = sizeof(wszPath) / sizeof(WCHAR) - 1;
+ const DWORD cchPath = _countof(wszPath) - 1;
BOOL bReturnValue = FALSE;
DWORD cbDataWritten;
HKEY hKey = NULL;
LONG lStatus;
- PWSTR pwszEnvironmentKey = NULL;
// Sanity checks
if (Level != 1)
@@ -695,9 +690,6 @@
bReturnValue = TRUE;
Cleanup:
- if (pwszEnvironmentKey)
- HeapFree(hProcessHeap, 0, pwszEnvironmentKey);
-
if (hKey)
RegCloseKey(hKey);
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/tools.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/tools.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/tools.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -11,7 +11,7 @@
* @name AllocAndRegQueryWSZ
*
* Queries a REG_SZ value in the registry, allocates memory for it and returns a buffer
containing the value.
- * You have to free this buffer using HeapFree.
+ * You have to free this buffer using DllFreeSplMem.
*
* @param hKey
* HKEY variable of the key opened with RegOpenKeyExW.
@@ -38,10 +38,10 @@
}
// Allocate it.
- pwszValue = HeapAlloc(hProcessHeap, 0, cbNeeded);
+ pwszValue = DllAllocSplMem(cbNeeded);
if (!pwszValue)
{
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
return NULL;
}
@@ -50,7 +50,7 @@
if (lStatus != ERROR_SUCCESS)
{
ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
- HeapFree(hProcessHeap, 0, pwszValue);
+ DllFreeSplMem(pwszValue);
return NULL;
}
@@ -58,55 +58,23 @@
}
/**
- * @name DuplicateStringW
- *
- * Allocates memory for a Unicode string and copies the input string into it.
- * Equivalent of wcsdup, but the returned buffer must be freed with HeapFree instead of
free.
- *
- * @param pwszInput
- * The input string to copy
- *
- * @return
- * Pointer to the copied string or NULL if no memory could be allocated.
- */
-PWSTR
-DuplicateStringW(PCWSTR pwszInput)
-{
- DWORD cchInput;
- PWSTR pwszOutput;
-
- cchInput = wcslen(pwszInput);
-
- pwszOutput = HeapAlloc(hProcessHeap, 0, (cchInput + 1) * sizeof(WCHAR));
- if (!pwszOutput)
- {
- ERR("HeapAlloc failed with error %lu!\n", GetLastError());
- return NULL;
- }
-
- CopyMemory(pwszOutput, pwszInput, (cchInput + 1) * sizeof(WCHAR));
-
- return pwszOutput;
-}
-
-/**
* @name GenericTableAllocateRoutine
*
- * RTL_GENERIC_ALLOCATE_ROUTINE for all our RTL_GENERIC_TABLEs, using HeapAlloc.
+ * RTL_GENERIC_ALLOCATE_ROUTINE for all our RTL_GENERIC_TABLEs, using DllAllocSplMem.
*/
PVOID NTAPI
GenericTableAllocateRoutine(PRTL_GENERIC_TABLE Table, CLONG ByteSize)
{
- return HeapAlloc(hProcessHeap, 0, ByteSize);
+ return DllAllocSplMem(ByteSize);
}
/**
* @name GenericTableFreeRoutine
*
- * RTL_GENERIC_FREE_ROUTINE for all our RTL_GENERIC_TABLEs, using HeapFree.
+ * RTL_GENERIC_FREE_ROUTINE for all our RTL_GENERIC_TABLEs, using DllFreeSplMem.
*/
VOID NTAPI
GenericTableFreeRoutine(PRTL_GENERIC_TABLE Table, PVOID Buffer)
{
- HeapFree(hProcessHeap, 0, Buffer);
+ DllFreeSplMem(Buffer);
}
Modified:
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
---
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/CMakeLists.txt [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/CMakeLists.txt [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -1,3 +1,5 @@
+
+include_directories(${REACTOS_SOURCE_DIR}/win32ss/printing/include)
list(APPEND SOURCE
fpEnumPrinters.c
@@ -6,6 +8,6 @@
add_library(localspl_apitest.dll SHARED ${SOURCE})
target_link_libraries(localspl_apitest.dll wine ${PSEH_LIB})
set_module_type(localspl_apitest.dll win32dll)
-add_importlibs(localspl_apitest.dll msvcrt kernel32 ntdll)
+add_importlibs(localspl_apitest.dll spoolss msvcrt kernel32 ntdll)
set_target_properties(localspl_apitest.dll PROPERTIES SUFFIX "")
add_cd_file(TARGET localspl_apitest.dll DESTINATION reactos/bin FOR all)
Modified:
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/fpEnumPrinters.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
---
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/fpEnumPrinters.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/fpEnumPrinters.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -16,15 +16,19 @@
#include <winsplp.h>
#include "../localspl_apitest.h"
+#include <spoolss.h>
START_TEST(fpEnumPrinters)
{
DWORD cbNeeded;
+ DWORD cbTemp;
DWORD dwReturned;
+ DWORD i;
HMODULE hLocalspl;
PInitializePrintProvidor pfnInitializePrintProvidor;
PRINTPROVIDOR pp;
PPRINTER_INFO_1W pPrinterInfo1;
+ PVOID pMem;
// Get us a handle to the loaded localspl.dll.
hLocalspl = GetModuleHandleW(L"localspl");
@@ -69,4 +73,88 @@
ok(wcscmp(pPrinterInfo1->pName, L"Windows NT Local Print Providor") ==
0, "pPrinterInfo1->pName is \"%S\"!\n", pPrinterInfo1->pName);
ok(wcscmp(pPrinterInfo1->pDescription, L"Windows NT Local Printers") ==
0, "pPrinterInfo1->pDescription is \"%S\"!\n",
pPrinterInfo1->pDescription);
ok(wcscmp(pPrinterInfo1->pComment, L"Locally connected Printers") == 0,
"pPrinterInfo1->pComment is \"%S\"!\n",
pPrinterInfo1->pComment);
+
+ // Level 7 is the highest supported for localspl under Windows Server 2003.
+ // Higher levels need to fail, but they don't set an error code, just cbNeeded to
0.
+ cbNeeded = 0xDEADBEEF;
+ dwReturned = 0xDEADBEEF;
+ SetLastError(0xDEADBEEF);
+ ok(!pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, 8, NULL, 0, &cbNeeded,
&dwReturned), "fpEnumPrinters returns TRUE!\n");
+ ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu!\n",
GetLastError());
+ ok(cbNeeded == 0, "cbNeeded is %lu!\n", cbNeeded);
+ ok(dwReturned == 0, "dwReturned is %lu!\n", dwReturned);
+
+ // Verify that all valid levels work.
+ // In contrast to EnumPrintersW, which only accepts levels 0, 1, 2, 4 and 5, localspl
returns information for level 0 to 7.
+ for (i = 0; i <= 7; i++)
+ {
+ // FIXME: 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.
+#if 0
+ // Try with no valid arguments at all.
+ // This scenario is usually caugt by RPC, so it just raises an exception here.
+ _SEH2_TRY
+ {
+ dwReturned = 0;
+ pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, NULL, 0, NULL, NULL);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwReturned = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu for Level
%lu!\n", dwReturned, i);
+#endif
+
+ // Now get the required buffer size.
+ cbNeeded = 0xDEADBEEF;
+ dwReturned = 0xDEADBEEF;
+ SetLastError(0xDEADBEEF);
+ ok(!pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, NULL, 0, &cbNeeded,
&dwReturned), "fpEnumPrinters returns TRUE for Level %lu!\n", i);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpEnumPrinters returns
error %lu for Level %lu!\n", GetLastError(), i);
+ ok(cbNeeded > 0, "cbNeeded is 0 for Level %lu!\n", i);
+ ok(dwReturned == 0, "dwReturned is %lu for Level %lu!\n", dwReturned,
i);
+
+#if 0
+ // Now provide the demanded size, but no buffer. This also mustn't touch
cbNeeded.
+ // This scenario is also caught by RPC and we just have an exception here.
+ _SEH2_TRY
+ {
+ dwReturned = 0;
+ pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, NULL, cbNeeded, &cbTemp,
&dwReturned);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwReturned = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu for Level
%lu!\n", dwReturned, i);
+ ok(cbNeeded == cbTemp, "cbNeeded is %lu, cbTemp is %lu for Level
%lu!\n", cbNeeded, cbTemp, i);
+#endif
+
+ // Finally use the function as intended and aim for success!
+ pMem = DllAllocSplMem(cbNeeded);
+ SetLastError(0xDEADBEEF);
+ ok(pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, pMem, cbNeeded, &cbTemp,
&dwReturned), "fpEnumPrinters returns FALSE for Level %lu!\n", i);
+
+ // This is crazy. For level 3, fpEnumPrinters always returns
ERROR_INSUFFICIENT_BUFFER even if we supply a buffer large enough.
+ if (i == 3)
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpEnumPrinters returns
error %lu for Level %lu!\n", GetLastError(), i);
+ else
+ ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu
for Level %lu!\n", GetLastError(), i);
+
+ DllFreeSplMem(pMem);
+ }
+
+ // fpEnumPrinters has to succeed independent of the level (valid or not) if we query
no information.
+ for (i = 0; i < 10; i++)
+ {
+ SetLastError(0xDEADBEEF);
+ ok(pp.fpEnumPrinters(0, NULL, i, NULL, 0, &cbNeeded, &dwReturned),
"fpEnumPrinters returns FALSE for Level %lu!\n", i);
+ ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu for
Level %lu!\n", GetLastError(), i);
+ ok(cbNeeded == 0, "cbNeeded is %lu for Level %lu!\n", cbNeeded, i);
+ ok(dwReturned == 0, "dwReturned is %lu for Level %lu!\n", dwReturned,
i);
+ }
}
Modified: branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
---
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/main.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/rostests/apitests/localspl/dll/main.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -18,7 +18,6 @@
#include <winreg.h>
#include <winspool.h>
#include <winsplp.h>
-
#include "../localspl_apitest.h"
Modified: branches/colins-printing-for-freedom/rostests/apitests/localspl/tests.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
--- branches/colins-printing-for-freedom/rostests/apitests/localspl/tests.c [iso-8859-1]
(original)
+++ branches/colins-printing-for-freedom/rostests/apitests/localspl/tests.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -40,14 +40,17 @@
static void
_RunRemoteTest(const char* szTestName)
{
+ BOOL bSuccessful = FALSE;
char szBuffer[1024];
DWORD cbRead;
DWORD cbWritten;
- HANDLE hCommandPipe;
- HANDLE hOutputPipe;
+ HANDLE hCommandPipe = INVALID_HANDLE_VALUE;
+ HANDLE hFind = NULL;
+ HANDLE hOutputPipe = INVALID_HANDLE_VALUE;
PWSTR p;
- SC_HANDLE hSC;
- SC_HANDLE hService;
+ SC_HANDLE hSC = NULL;
+ SC_HANDLE hService = NULL;
+ SERVICE_STATUS ServiceStatus;
WCHAR wszFilePath[MAX_PATH + 20];
WIN32_FIND_DATAW fd;
@@ -59,7 +62,7 @@
if (!GetModuleFileNameW(NULL, wszFilePath, MAX_PATH))
{
skip("GetModuleFileNameW failed with error %lu!\n", GetLastError());
- return;
+ goto Cleanup;
}
// Replace the extension.
@@ -67,16 +70,17 @@
if (!p)
{
skip("File path has no file extension: %S\n", wszFilePath);
- return;
+ goto Cleanup;
}
wcscpy(p, L".dll");
// Check if the corresponding DLL file exists.
- if (!FindFirstFileW(wszFilePath, &fd))
+ hFind = FindFirstFileW(wszFilePath, &fd);
+ if (!hFind)
{
skip("My DLL file \"%S\" does not exist!\n", wszFilePath);
- return;
+ goto Cleanup;
}
// Change the extension back to .exe and add the parameters.
@@ -87,8 +91,30 @@
if (!hSC)
{
skip("OpenSCManagerW failed with error %lu!\n", GetLastError());
- return;
- }
+ goto Cleanup;
+ }
+
+ // Ensure that the spooler service is running.
+ hService = OpenServiceW(hSC, L"spooler", SERVICE_QUERY_STATUS);
+ if (!hService)
+ {
+ skip("OpenServiceW failed for the spooler service with error %lu!\n",
GetLastError());
+ goto Cleanup;
+ }
+
+ if (!QueryServiceStatus(hService, &ServiceStatus))
+ {
+ skip("QueryServiceStatus failed for the spooler service with error
%lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ if (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
+ {
+ skip("Spooler Service is not running!\n");
+ goto Cleanup;
+ }
+
+ CloseServiceHandle(hService);
// Try to open the service if we've created it in a previous run.
hService = OpenServiceW(hSC, SERVICE_NAME, SERVICE_ALL_ACCESS);
@@ -101,13 +127,13 @@
if (!hService)
{
skip("CreateServiceW failed with error %lu!\n",
GetLastError());
- return;
+ goto Cleanup;
}
}
else
{
skip("OpenServiceW failed with error %lu!\n", GetLastError());
- return;
+ goto Cleanup;
}
}
@@ -116,57 +142,70 @@
if (hCommandPipe == INVALID_HANDLE_VALUE)
{
skip("CreateNamedPipeW failed for the command pipe with error %lu!\n",
GetLastError());
- return;
+ goto Cleanup;
}
hOutputPipe = CreateNamedPipeW(OUTPUT_PIPE_NAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, 10000, NULL);
if (hOutputPipe == INVALID_HANDLE_VALUE)
{
skip("CreateNamedPipeW failed for the output pipe with error %lu!\n",
GetLastError());
- return;
+ goto Cleanup;
}
// Start the service with "service" and a dummy parameter (to distinguish
it from a call by rosautotest to localspl_apitest:service)
if (!StartServiceW(hService, 0, NULL))
{
skip("StartServiceW failed with error %lu!\n", GetLastError());
- return;
- }
-
- CloseServiceHandle(hService);
- CloseServiceHandle(hSC);
+ goto Cleanup;
+ }
// Wait till it has injected the DLL and the DLL expects its test name.
if (!ConnectNamedPipe(hCommandPipe, NULL) && GetLastError() !=
ERROR_PIPE_CONNECTED)
{
skip("ConnectNamedPipe failed for the command pipe with error %lu!\n",
GetLastError());
- return;
+ goto Cleanup;
}
// Send the test name.
if (!WriteFile(hCommandPipe, szTestName, strlen(szTestName) + sizeof(char),
&cbWritten, NULL))
{
skip("WriteFile failed with error %lu!\n", GetLastError());
- return;
- }
-
- CloseHandle(hCommandPipe);
+ goto Cleanup;
+ }
// Now wait for the DLL to connect to the output pipe.
if (!ConnectNamedPipe(hOutputPipe, NULL))
{
skip("ConnectNamedPipe failed for the output pipe with error %lu!\n",
GetLastError());
- return;
+ goto Cleanup;
}
// Get all testing messages from the pipe and output them on stdout.
while (ReadFile(hOutputPipe, szBuffer, sizeof(szBuffer), &cbRead, NULL)
&& cbRead)
fwrite(szBuffer, sizeof(char), cbRead, stdout);
- CloseHandle(hOutputPipe);
-
- // Prevent the testing framework from outputting a "0 tests executed" line
here.
- ExitProcess(0);
+ bSuccessful = TRUE;
+
+Cleanup:
+ if (hCommandPipe)
+ CloseHandle(hCommandPipe);
+
+ if (hOutputPipe)
+ CloseHandle(hOutputPipe);
+
+ if (hFind)
+ FindClose(hFind);
+
+ if (hService)
+ CloseServiceHandle(hService);
+
+ if (hSC)
+ CloseServiceHandle(hSC);
+
+ // If we successfully received test output through the named pipe, we have also
output a summary line already.
+ // Prevent the testing framework from outputting another "0 tests executed"
line in this case.
+ if (bSuccessful)
+ ExitProcess(0);
}
START_TEST(fpEnumPrinters)
Modified: branches/colins-printing-for-freedom/rostests/apitests/spoolss/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
---
branches/colins-printing-for-freedom/rostests/apitests/spoolss/CMakeLists.txt [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/rostests/apitests/spoolss/CMakeLists.txt [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -3,6 +3,7 @@
list(APPEND SOURCE
PackStrings.c
+ ReallocSplStr.c
SplInitializeWinSpoolDrv.c
testlist.c)
Added: branches/colins-printing-for-freedom/rostests/apitests/spoolss/ReallocSplStr.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
---
branches/colins-printing-for-freedom/rostests/apitests/spoolss/ReallocSplStr.c (added)
+++
branches/colins-printing-for-freedom/rostests/apitests/spoolss/ReallocSplStr.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -0,0 +1,66 @@
+/*
+ * PROJECT: ReactOS Spooler Router API Tests
+ * LICENSE: GNU GPLv2 or any later version as published by the Free Software
Foundation
+ * PURPOSE: Tests for ReallocSplStr
+ * COPYRIGHT: Copyright 2015 Colin Finck <colin(a)reactos.org>
+ */
+
+#include <apitest.h>
+
+#define WIN32_NO_STATUS
+#include <windef.h>
+#include <winbase.h>
+#include <spoolss.h>
+
+START_TEST(ReallocSplStr)
+{
+ const WCHAR wszTestString1[] = L"Test";
+ const WCHAR wszTestString2[] = L"New";
+
+ DWORD dwResult;
+ PWSTR pwszBackup;
+ PWSTR pwszTest;
+
+ // Verify that ReallocSplStr raises an exception if all parameters are NULL.
+ _SEH2_TRY
+ {
+ dwResult = 0;
+ ReallocSplStr(NULL, NULL);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwResult = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ ok(dwResult == EXCEPTION_ACCESS_VIOLATION, "dwResult is %lx!\n",
dwResult);
+
+ // Allocate a string for testing.
+ pwszTest = AllocSplStr(wszTestString1);
+ if (!pwszTest)
+ {
+ skip("AllocSplStr failed with error %lu!\n", GetLastError());
+ return;
+ }
+
+ // Verify that ReallocSplStr frees the old string even if pwszInput is NULL.
+ ok(ReallocSplStr(&pwszTest, NULL), "ReallocSplStr is FALSE!\n");
+ ok(pwszTest == NULL, "pwszTest is %p\n", pwszTest);
+
+ // Now verify that ReallocSplStr copies the new string into a new block and frees the
old one.
+ pwszBackup = pwszTest;
+ ok(ReallocSplStr(&pwszTest, wszTestString2), "ReallocSplStr is
FALSE!\n");
+ ok(wcscmp(pwszTest, wszTestString2) == 0, "New string was not copied into
pwszTest!\n");
+
+ _SEH2_TRY
+ {
+ dwResult = (DWORD)wcscmp(pwszBackup, wszTestString1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ dwResult = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ ok(dwResult == EXCEPTION_ACCESS_VIOLATION, "dwResult is %lx!\n",
dwResult);
+}
Propchange:
branches/colins-printing-for-freedom/rostests/apitests/spoolss/ReallocSplStr.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
branches/colins-printing-for-freedom/rostests/apitests/spoolss/SplInitializeWinSpoolDrv.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
---
branches/colins-printing-for-freedom/rostests/apitests/spoolss/SplInitializeWinSpoolDrv.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/rostests/apitests/spoolss/SplInitializeWinSpoolDrv.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -15,9 +15,14 @@
START_TEST(SplInitializeWinSpoolDrv)
{
HINSTANCE hWinspool;
- void* Table[9];
+ PVOID Table[9];
hWinspool = LoadLibraryW(L"winspool.drv");
+ if (!hWinspool)
+ {
+ skip("Could not load winspool.drv, last error is %lu!\n",
GetLastError());
+ return;
+ }
ok(SplInitializeWinSpoolDrv(Table), "SplInitializeWinSpoolDrv returns
FALSE!\n");
ok(Table[0] == GetProcAddress(hWinspool, "OpenPrinterW"), "Table[0] is
%p\n", Table[0]);
Modified: branches/colins-printing-for-freedom/rostests/apitests/spoolss/testlist.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/ros…
==============================================================================
--- branches/colins-printing-for-freedom/rostests/apitests/spoolss/testlist.c [iso-8859-1]
(original)
+++ branches/colins-printing-for-freedom/rostests/apitests/spoolss/testlist.c [iso-8859-1]
Tue Jun 9 13:22:25 2015
@@ -11,11 +11,13 @@
#include <apitest.h>
extern void func_PackStrings(void);
+extern void func_ReallocSplStr(void);
extern void func_SplInitializeWinSpoolDrv(void);
const struct test winetest_testlist[] =
{
{ "PackStrings", func_PackStrings },
+ { "ReallocSplStr", func_ReallocSplStr },
{ "SplInitializeWinSpoolDrv", func_SplInitializeWinSpoolDrv },
{ 0, 0 }