mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 21:48:19 +00:00
[SPOOLSS]
In an attempt to simplify the code for further functions that return information structures, implement and document the undocumented PackStrings function. Hints were taken from an XP DDK sample and own testing. [SPOOLSS_APITEST] Add some tests for PackStrings that succeed under Windows Server 2003. svn path=/branches/colins-printing-for-freedom/; revision=68023
This commit is contained in:
parent
af0a3b64a9
commit
ecd7f83ffb
7 changed files with 152 additions and 2 deletions
|
@ -4,7 +4,8 @@ spec2def(spoolss.dll spoolss.spec ADD_IMPORTLIB)
|
|||
list(APPEND SOURCE
|
||||
context.c
|
||||
main.c
|
||||
precomp.h)
|
||||
precomp.h
|
||||
tools.c)
|
||||
|
||||
add_library(spoolss SHARED
|
||||
${SOURCE}
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
@ stub OpenPrinterExW
|
||||
@ stub OpenPrinterPortW
|
||||
@ stdcall OpenPrinterW(wstr ptr ptr)
|
||||
@ stub PackStrings
|
||||
@ stdcall PackStrings(ptr ptr ptr ptr)
|
||||
@ stub PartialReplyPrinterChangeNotification
|
||||
@ stub PlayGdiScriptOnPrinterIC
|
||||
@ stub PrinterHandleRundown
|
||||
|
|
70
reactos/win32ss/printing/base/spoolss/tools.c
Normal file
70
reactos/win32ss/printing/base/spoolss/tools.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Spooler Router
|
||||
* LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
|
||||
* PURPOSE: Miscellaneous tool functions
|
||||
* COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
|
||||
/**
|
||||
* @name PackStrings
|
||||
*
|
||||
* Takes an array of Unicode strings and fills an output buffer with these strings at the end and pointers to each string at specific offsets.
|
||||
* Useful helper for functions that copy an information structure including strings into a given buffer (like PRINTER_INFO_1).
|
||||
*
|
||||
* @param pSource
|
||||
* The array of Unicode strings to copy. Needs to have at least as many elements as the DestOffsets array.
|
||||
*
|
||||
* @param pDest
|
||||
* Pointer to the beginning of the output buffer.
|
||||
* The caller is responsible for verifying that this buffer is large enough to hold all strings and pointers.
|
||||
*
|
||||
* @param DestOffsets
|
||||
* Array of byte offsets in the output buffer. For each element of DestOffsets, the function will copy the address of the corresponding copied
|
||||
* string of pSource to this location in the output buffer. If a string in pSource is NULL, the function will set the pointer address to NULL
|
||||
* in the output buffer.
|
||||
* Use macros like FIELD_OFFSET to calculate the offsets for this array.
|
||||
* The last element of the array must have the value MAXDWORD to let the function detect the end of the array.
|
||||
*
|
||||
* @param pEnd
|
||||
* Pointer to the end of the output buffer. That means the first element outside of the buffer given in pDest.
|
||||
*
|
||||
* @return
|
||||
* Returns a pointer to the beginning of the strings in pDest.
|
||||
* The strings are copied in reverse order, so this pointer will point to the last copied string of pSource.
|
||||
*/
|
||||
PBYTE WINAPI
|
||||
PackStrings(PCWSTR* pSource, PBYTE pDest, PDWORD DestOffsets, PBYTE pEnd)
|
||||
{
|
||||
DWORD cbString;
|
||||
ULONG_PTR StringAddress;
|
||||
|
||||
// Loop until we reach an element with offset set to MAXDWORD.
|
||||
while (*DestOffsets != MAXDWORD)
|
||||
{
|
||||
StringAddress = 0;
|
||||
|
||||
if (*pSource)
|
||||
{
|
||||
// Determine the length of the source string.
|
||||
cbString = (wcslen(*pSource) + 1) * sizeof(WCHAR);
|
||||
|
||||
// Copy it before the last string.
|
||||
pEnd -= cbString;
|
||||
StringAddress = (ULONG_PTR)pEnd;
|
||||
CopyMemory(pEnd, *pSource, cbString);
|
||||
}
|
||||
|
||||
// Copy the address of the copied string to the location given by the offset.
|
||||
CopyMemory(&pDest[*DestOffsets], &StringAddress, sizeof(ULONG_PTR));
|
||||
|
||||
// Advance to the next source string and destination offset.
|
||||
pSource++;
|
||||
DestOffsets++;
|
||||
}
|
||||
|
||||
// pEnd is now at the last string we copied. Return this value as a pointer to the beginning of all strings in the output buffer.
|
||||
return pEnd;
|
||||
}
|
|
@ -17,6 +17,7 @@ add_subdirectory(powrprof)
|
|||
add_subdirectory(setupapi)
|
||||
add_subdirectory(shell32)
|
||||
add_subdirectory(psapi)
|
||||
add_subdirectory(spoolss)
|
||||
add_subdirectory(user32)
|
||||
if(NOT ARCH STREQUAL "amd64")
|
||||
add_subdirectory(w32kdll)
|
||||
|
|
10
rostests/apitests/spoolss/CMakeLists.txt
Normal file
10
rostests/apitests/spoolss/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
PackStrings.c
|
||||
testlist.c)
|
||||
|
||||
add_executable(spoolss_apitest ${SOURCE})
|
||||
target_link_libraries(spoolss_apitest wine ${PSEH_LIB})
|
||||
set_module_type(spoolss_apitest win32cui)
|
||||
add_importlibs(spoolss_apitest spoolss msvcrt kernel32 ntdll)
|
||||
add_cd_file(TARGET spoolss_apitest DESTINATION reactos/bin FOR all)
|
48
rostests/apitests/spoolss/PackStrings.c
Normal file
48
rostests/apitests/spoolss/PackStrings.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Spooler Router API Tests
|
||||
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||
* PURPOSE: Tests for PackStrings
|
||||
* COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
|
||||
PBYTE WINAPI PackStrings(PCWSTR*, PBYTE, PDWORD, PBYTE);
|
||||
|
||||
typedef struct _EXAMPLE_STRUCT
|
||||
{
|
||||
PWSTR String1;
|
||||
PWSTR String2;
|
||||
}
|
||||
EXAMPLE_STRUCT, *PEXAMPLE_STRUCT;
|
||||
|
||||
START_TEST(PackStrings)
|
||||
{
|
||||
PCWSTR Source1[] = { L"Test", L"String" };
|
||||
PCWSTR Source2[] = { L"Test", NULL };
|
||||
|
||||
BYTE Buffer[50];
|
||||
PBYTE pEnd;
|
||||
PEXAMPLE_STRUCT pStruct = (PEXAMPLE_STRUCT)Buffer;
|
||||
DWORD Offsets[] = {
|
||||
FIELD_OFFSET(EXAMPLE_STRUCT, String1),
|
||||
FIELD_OFFSET(EXAMPLE_STRUCT, String2),
|
||||
MAXDWORD
|
||||
};
|
||||
|
||||
// Try a usual case with two strings. Verify that they are copied in reverse order.
|
||||
pEnd = PackStrings(Source1, Buffer, Offsets, &Buffer[sizeof(Buffer)]);
|
||||
ok(wcscmp(pStruct->String1, Source1[0]) == 0, "String1 and Source1[0] don't match!\n");
|
||||
ok(wcscmp(pStruct->String2, Source1[1]) == 0, "String2 and Source1[1] don't match!\n");
|
||||
ok(wcscmp((PWSTR)pEnd, Source1[1]) == 0, "pEnd and Source1[1] don't match!\n");
|
||||
|
||||
// Now verify that the corresponding pointer is set to NULL if a string is NULL.
|
||||
pEnd = PackStrings(Source2, Buffer, Offsets, &Buffer[sizeof(Buffer)]);
|
||||
ok(wcscmp(pStruct->String1, Source2[0]) == 0, "String1 and Source2[0] don't match!\n");
|
||||
ok(!pStruct->String2, "String2 is %p!\n", pStruct->String2);
|
||||
ok(wcscmp((PWSTR)pEnd, Source2[0]) == 0, "pEnd and Source2[0] don't match!\n");
|
||||
}
|
20
rostests/apitests/spoolss/testlist.c
Normal file
20
rostests/apitests/spoolss/testlist.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Print Spooler Router API Tests
|
||||
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||
* PURPOSE: Test list
|
||||
* COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
|
||||
*/
|
||||
|
||||
#define __ROS_LONG64__
|
||||
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_PackStrings(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "PackStrings", func_PackStrings },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
Loading…
Reference in a new issue