[LOCALSPL_APITEST]
authorColin Finck <colin@reactos.org>
Thu, 17 Nov 2016 22:23:28 +0000 (22:23 +0000)
committerColin Finck <colin@reactos.org>
Thu, 17 Nov 2016 22:23:28 +0000 (22:23 +0000)
Add a test for fpGetPrintProcessorDirectory, the actual worker function inside localspl.dll at the end of the call chain.
With that final test, we should have enough information to implement 100% compatible versions of GetPrintProcessorDirectoryA/W and fpGetPrintProcessorDirectory.

[WINSPOOL_APITEST]
Initialize some more variables with bogus values to verify that they have actually changed.

Next step for CORE-12399

svn path=/trunk/; revision=73264

rostests/apitests/localspl/dll/CMakeLists.txt
rostests/apitests/localspl/dll/fpGetPrintProcessorDirectory.c [new file with mode: 0644]
rostests/apitests/localspl/dll/main.c
rostests/apitests/localspl/testlist.c
rostests/apitests/localspl/tests.c
rostests/apitests/winspool/GetPrintProcessorDirectory.c

index 76e6a43..6505d6f 100644 (file)
@@ -3,6 +3,7 @@ include_directories(${REACTOS_SOURCE_DIR}/win32ss/printing/include)
 
 list(APPEND SOURCE
     fpEnumPrinters.c
+    fpGetPrintProcessorDirectory.c
     main.c)
 
 add_library(localspl_apitest.dll SHARED ${SOURCE})
diff --git a/rostests/apitests/localspl/dll/fpGetPrintProcessorDirectory.c b/rostests/apitests/localspl/dll/fpGetPrintProcessorDirectory.c
new file mode 100644 (file)
index 0000000..5050d60
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * PROJECT:     ReactOS Local Spooler API Tests Injected DLL
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Tests for fpGetPrintProcessorDirectory
+ * COPYRIGHT:   Copyright 2016 Colin Finck <colin@reactos.org>
+ */
+
+#include <apitest.h>
+
+#define WIN32_NO_STATUS
+#include <windef.h>
+#include <winbase.h>
+#include <wingdi.h>
+#include <winreg.h>
+#include <winspool.h>
+#include <winsplp.h>
+
+#include "../localspl_apitest.h"
+#include <spoolss.h>
+
+extern BOOL GetLocalsplFuncs(LPPRINTPROVIDOR pp);
+
+START_TEST(fpGetPrintProcessorDirectory)
+{
+    DWORD cbNeeded;
+    DWORD cbTemp;
+    DWORD dwReturned;
+    PRINTPROVIDOR pp;
+    PWSTR pwszBuffer;
+
+    if (!GetLocalsplFuncs(&pp))
+        return;
+
+    // In contrast to GetPrintProcessorDirectoryW, fpGetPrintProcessorDirectory needs an environment and doesn't just accept NULL.
+    SetLastError(0xDEADBEEF);
+    ok(!pp.fpGetPrintProcessorDirectory(NULL, NULL, 0, NULL, 0, NULL), "fpGetPrintProcessorDirectory returns TRUE!\n");
+    ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
+
+    // Try with an invalid environment as well.
+    SetLastError(0xDEADBEEF);
+    ok(!pp.fpGetPrintProcessorDirectory(NULL, L"invalid", 0, NULL, 0, NULL), "fpGetPrintProcessorDirectory returns TRUE!\n");
+    ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
+
+    // Now provide a valid environment and prove that it is checked case-insensitively.
+    // In contrast to GetPrintProcessorDirectoryW, the level isn't the next thing checked here, but fpGetPrintProcessorDirectory
+    // already tries to access the non-supplied pcbNeeded variable.
+    _SEH2_TRY
+    {
+        dwReturned = 0;
+        pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 0, NULL, 0, NULL);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwReturned = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu!\n", dwReturned);
+
+    // fpGetPrintProcessorDirectory doesn't care about the supplied level at all. Prove this here.
+    // With no buffer given, this needs to fail with ERROR_INSUFFICIENT_BUFFER.
+    SetLastError(0xDEADBEEF);
+    cbNeeded = 0;
+    ok(!pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1337, NULL, 0, &cbNeeded), "fpGetPrintProcessorDirectory returns TRUE!\n");
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
+    ok(cbNeeded > 0, "cbNeeded is %lu!\n", cbNeeded);
+
+    // Now provide the demanded size, but no buffer.
+    // Unlike GetPrintProcessorDirectoryW, fpGetPrintProcessorDirectory doesn't check for this case and tries to access the buffer.
+    _SEH2_TRY
+    {
+        dwReturned = 0;
+        pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1, NULL, cbNeeded, &cbTemp);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwReturned = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu!\n", dwReturned);
+
+    // Finally use the function as intended and aim for success!
+    // We only check success by the boolean return value though. GetLastError doesn't return anything meaningful here.
+    pwszBuffer = DllAllocSplMem(cbNeeded);
+    SetLastError(0xDEADBEEF);
+    ok(pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1, (PBYTE)pwszBuffer, cbNeeded, &cbTemp), "fpGetPrintProcessorDirectory returns FALSE!\n");
+    ok(wcslen(pwszBuffer) == cbNeeded / sizeof(WCHAR) - 1, "fpGetPrintProcessorDirectory string is %Iu characters long, but %lu characters expected!\n", wcslen(pwszBuffer), cbNeeded / sizeof(WCHAR) - 1);
+    DllFreeSplMem(pwszBuffer);
+}
index fc63db4..fb2885b 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:     ReactOS Local Spooler API Tests Injected DLL
  * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
  * PURPOSE:     Main functions
- * COPYRIGHT:   Copyright 2015 Colin Finck <colin@reactos.org>
+ * COPYRIGHT:   Copyright 2015-2016 Colin Finck <colin@reactos.org>
  */
 
 #define __ROS_LONG64__
 
 // Test list
 extern void func_fpEnumPrinters(void);
+extern void func_fpGetPrintProcessorDirectory(void);
 
 const struct test winetest_testlist[] =
 {
     { "fpEnumPrinters", func_fpEnumPrinters },
-
+    { "fpGetPrintProcessorDirectory", func_fpGetPrintProcessorDirectory },
     { 0, 0 }
 };
 
index 7102484..af67d98 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:     ReactOS Local Spooler 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>
+ * COPYRIGHT:   Copyright 2015-2016 Colin Finck <colin@reactos.org>
  */
 
 #define __ROS_LONG64__
 #include <apitest.h>
 
 extern void func_fpEnumPrinters(void);
+extern void func_fpGetPrintProcessorDirectory(void);
 extern void func_service(void);
 
 const struct test winetest_testlist[] =
 {
     { "fpEnumPrinters", func_fpEnumPrinters },
+    { "fpGetPrintProcessorDirectory", func_fpGetPrintProcessorDirectory },
     { "service", func_service },
 
     { 0, 0 }
index 040cde8..b763f37 100644 (file)
@@ -212,3 +212,8 @@ START_TEST(fpEnumPrinters)
 {
     _RunRemoteTest("fpEnumPrinters");
 }
+
+START_TEST(fpGetPrintProcessorDirectory)
+{
+    _RunRemoteTest("fpGetPrintProcessorDirectory");
+}
index f67b1bf..569ed8e 100644 (file)
@@ -31,6 +31,7 @@ START_TEST(GetPrintProcessorDirectoryA)
 
     // Try with an invalid environment as well.
     SetLastError(0xDEADBEEF);
+    cbNeeded = 0xDEADBEEF;
     ok(!GetPrintProcessorDirectoryA(NULL, "invalid", 1, NULL, 0, &cbNeeded), "GetPrintProcessorDirectoryA returns TRUE!\n");
     ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "GetPrintProcessorDirectoryA returns error %lu!\n", GetLastError());
     ok(cbNeeded == 0, "cbNeeded is %lu!\n", cbNeeded);
@@ -38,18 +39,21 @@ START_TEST(GetPrintProcessorDirectoryA)
     // Now get the required buffer size by supplying pcbNeeded. This needs to fail with ERROR_INSUFFICIENT_BUFFER.
     // Note for GetPrintProcessorDirectoryA: cbNeeded will be the same as for GetPrintProcessorDirectoryW, even though the ANSI string only needs half of it!
     SetLastError(0xDEADBEEF);
+    cbNeeded = 0;
     ok(!GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbNeeded), "GetPrintProcessorDirectoryA returns TRUE!\n");
     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetPrintProcessorDirectoryA returns error %lu!\n", GetLastError());
     ok(cbNeeded > 0, "cbNeeded is 0!\n");
 
     // Now provide the demanded size, but no buffer.
     SetLastError(0xDEADBEEF);
+    cbTemp = 0xDEADBEEF;
     ok(!GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, cbNeeded, &cbTemp), "GetPrintProcessorDirectoryA returns TRUE!\n");
     ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "GetPrintProcessorDirectoryA returns error %lu!\n", GetLastError());
     ok(cbTemp == 0, "cbTemp is %lu!\n", cbTemp);
 
     // Same error has to occur with a size too small.
     SetLastError(0xDEADBEEF);
+    cbTemp = 0xDEADBEEF;
     ok(!GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 1, &cbTemp), "GetPrintProcessorDirectoryA returns TRUE!\n");
     ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "GetPrintProcessorDirectoryA returns error %lu!\n", GetLastError());
     ok(cbTemp == 0, "cbTemp is %lu!\n", cbTemp);
@@ -83,24 +87,28 @@ START_TEST(GetPrintProcessorDirectoryW)
 
     // Try with an invalid environment as well.
     SetLastError(0xDEADBEEF);
+    cbNeeded = 0xDEADBEEF;
     ok(!GetPrintProcessorDirectoryW(NULL, L"invalid", 1, NULL, 0, &cbNeeded), "GetPrintProcessorDirectoryW returns TRUE!\n");
     ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "GetPrintProcessorDirectoryW returns error %lu!\n", GetLastError());
     ok(cbNeeded == 0, "cbNeeded is %lu!\n", cbNeeded);
 
     // Now get the required buffer size by supplying pcbNeeded. This needs to fail with ERROR_INSUFFICIENT_BUFFER.
     SetLastError(0xDEADBEEF);
+    cbNeeded = 0;
     ok(!GetPrintProcessorDirectoryW(NULL, NULL, 1, NULL, 0, &cbNeeded), "GetPrintProcessorDirectoryW returns TRUE!\n");
     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetPrintProcessorDirectoryW returns error %lu!\n", GetLastError());
     ok(cbNeeded > 0, "cbNeeded is 0!\n");
 
     // Now provide the demanded size, but no buffer.
     SetLastError(0xDEADBEEF);
+    cbTemp = 0xDEADBEEF;
     ok(!GetPrintProcessorDirectoryW(NULL, NULL, 1, NULL, cbNeeded, &cbTemp), "GetPrintProcessorDirectoryW returns TRUE!\n");
     ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "GetPrintProcessorDirectoryW returns error %lu!\n", GetLastError());
     ok(cbTemp == 0, "cbTemp is %lu!\n", cbTemp);
 
     // Same error has to occur with a size too small.
     SetLastError(0xDEADBEEF);
+    cbTemp = 0xDEADBEEF;
     ok(!GetPrintProcessorDirectoryW(NULL, NULL, 1, NULL, 1, &cbTemp), "GetPrintProcessorDirectoryW returns TRUE!\n");
     ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "GetPrintProcessorDirectoryW returns error %lu!\n", GetLastError());
     ok(cbTemp == 0, "cbTemp is %lu!\n", cbTemp);