/* * Unit test suite for the Spooler-Service helper DLL * * Copyright 2007 Detlef Riekenberg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * */ #include <stdarg.h> #include "windef.h" #include "winbase.h" #include "winerror.h" #include "wine/test.h" /* ##### */ static HMODULE hwinspool; static HMODULE hspl; static BOOL (WINAPI * pBuildOtherNamesFromMachineName)(LPWSTR **, LPDWORD); static DWORD (WINAPI * pSplInitializeWinSpoolDrv)(LPVOID *); #define WINSPOOL_TABLESIZE 16 static LPVOID fn_spl[WINSPOOL_TABLESIZE]; static LPVOID fn_w2k[WINSPOOL_TABLESIZE]; static LPVOID fn_xp[WINSPOOL_TABLESIZE]; static LPVOID fn_v[WINSPOOL_TABLESIZE]; /* ########################### */ static LPCSTR load_functions(void) { LPCSTR ptr; ptr = "spoolss.dll"; hspl = LoadLibraryA(ptr); if (!hspl) return ptr; ptr = "BuildOtherNamesFromMachineName"; pBuildOtherNamesFromMachineName = (void *) GetProcAddress(hspl, ptr); if (!pBuildOtherNamesFromMachineName) return ptr; ptr = "SplInitializeWinSpoolDrv"; pSplInitializeWinSpoolDrv = (void *) GetProcAddress(hspl, ptr); if (!pSplInitializeWinSpoolDrv) return ptr; /* Calling BuildOtherNamesFromMachineName or SplInitializeWinSpoolDrv on * Win7 results in a breakpoint exception. If you continue after hitting * the breakpoint, the functions fail with ERROR_NOT_SUPPORTED. So we * just skip the tests on Win7, since they won't provide any useful info. * To detect Win7, we check whether UnloadDriver exists (it doesn't on * Win7, but does exist on earlier Windows versions) */ ptr = "UnloadDriver"; if (GetProcAddress(hspl, ptr) == NULL) return ptr; ptr = "winspool.drv"; hwinspool = LoadLibraryA(ptr); if (!hwinspool) return ptr; memset(fn_w2k, 0xff, sizeof(fn_w2k)); fn_w2k[0] = (void *) GetProcAddress(hwinspool, "OpenPrinterW"); fn_w2k[1] = (void *) GetProcAddress(hwinspool, "ClosePrinter"); fn_w2k[2] = (void *) GetProcAddress(hwinspool, "SpoolerDevQueryPrintW"); fn_w2k[3] = (void *) GetProcAddress(hwinspool, "SpoolerPrinterEvent"); fn_w2k[4] = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW"); fn_w2k[5] = (void *) GetProcAddress(hwinspool, (LPSTR) 212); /* LoadPrinterDriver */ fn_w2k[6] = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterW"); fn_w2k[7] = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterW"); fn_w2k[8] = (void *) GetProcAddress(hwinspool, (LPSTR) 213); /* RefCntLoadDriver */ fn_w2k[9] = (void *) GetProcAddress(hwinspool, (LPSTR) 214); /* RefCntUnloadDriver */ fn_w2k[10] = (void *) GetProcAddress(hwinspool, (LPSTR) 215); /* ForceUnloadDriver */ memset(fn_xp, 0xff, sizeof(fn_xp)); fn_xp[0] = (void *) GetProcAddress(hwinspool, "OpenPrinterW"); fn_xp[1] = (void *) GetProcAddress(hwinspool, "ClosePrinter"); fn_xp[2] = (void *) GetProcAddress(hwinspool, "SpoolerDevQueryPrintW"); fn_xp[3] = (void *) GetProcAddress(hwinspool, "SpoolerPrinterEvent"); fn_xp[4] = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW"); fn_xp[5] = (void *) GetProcAddress(hwinspool, (LPSTR) 212); /* LoadPrinterDriver */ fn_xp[6] = (void *) GetProcAddress(hwinspool, (LPSTR) 213); /* RefCntLoadDriver */ fn_xp[7] = (void *) GetProcAddress(hwinspool, (LPSTR) 214); /* RefCntUnloadDriver */ fn_xp[8] = (void *) GetProcAddress(hwinspool, (LPSTR) 215); /* ForceUnloadDriver */ memset(fn_v, 0xff, sizeof(fn_v)); fn_v[0] = (void *) GetProcAddress(hwinspool, "OpenPrinterW"); fn_v[1] = (void *) GetProcAddress(hwinspool, "ClosePrinter"); fn_v[2] = (void *) GetProcAddress(hwinspool, "SpoolerDevQueryPrintW"); fn_v[3] = (void *) GetProcAddress(hwinspool, "SpoolerPrinterEvent"); fn_v[4] = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW"); fn_v[5] = (void *) GetProcAddress(hwinspool, (LPSTR) 212); /* LoadPrinterDriver */ fn_v[6] = (void *) GetProcAddress(hwinspool, (LPSTR) 213); /* RefCntLoadDriver */ fn_v[7] = (void *) GetProcAddress(hwinspool, (LPSTR) 214); /* RefCntUnloadDriver */ fn_v[8] = (void *) GetProcAddress(hwinspool, (LPSTR) 215); /* ForceUnloadDriver */ fn_v[9] = (void *) GetProcAddress(hwinspool, (LPSTR) 251); /* 0xfb */ return NULL; } /* ########################### */ static void test_BuildOtherNamesFromMachineName(void) { LPWSTR *buffers; DWORD numentries; DWORD res; buffers = NULL; numentries = 0; SetLastError(0xdeadbeef); res = pBuildOtherNamesFromMachineName(&buffers, &numentries); /* An array with a number of stringpointers is returned (minimum of 3): entry_#0: "" (empty String) entry_#1: <hostname> (this is the same as the computername) 1 entry per Ethernet adapter : <ip-address> (string with a IPv4 ip-address) As of Vista: IPv6 fully disabled (lan interfaces, connections, tunnel interfaces and loopback interfaces) entry_#0: "" (empty String) entry_#1: <hostname> (this is the same as the computername) 1 entry per Ethernet adapter : <ip-address> (string with a IPv4 ip-address) entry_#x: "::1" IPv6 partly disabled (lan interfaces, connections): entry_#0: "" (empty String) entry_#1: <hostname> (this is the same as the computername) entry_#2: "::1" 1 entry per Ethernet adapter : <ip-address> (string with a IPv4 ip-address) IPv6 fully enabled but not on all lan interfaces: entry_#0: "" (empty String) entry_#1: <hostname> (this is the same as the computername) 1 entry per IPv6 enabled Ethernet adapter : <ip-address> (string with a Link-local IPv6 ip-address) 1 entry per IPv4 enabled Ethernet adapter : <ip-address> (string with a IPv4 ip-address) IPv6 fully enabled on all lan interfaces: entry_#0: "" (empty String) entry_#1: <hostname> (this is the same as the computername) 1 entry per IPv6 enabled Ethernet adapter : <ip-address> (string with a Link-local IPv6 ip-address) entry_#x: <ip-address> Tunnel adapter (string with a Link-local IPv6 ip-address) 1 entry per IPv4 enabled Ethernet adapter : <ip-address> (string with a IPv4 ip-address) entry_#y: <ip-address> Tunnel adapter (string with a IPv6 ip-address) */ todo_wine ok( res && (buffers != NULL) && (numentries >= 3) && (buffers[0] != NULL) && (buffers[0][0] == '\0'), "got %u with %u and %p,%u (%p:%d)\n", res, GetLastError(), buffers, numentries, ((numentries > 0) && buffers) ? buffers[0] : NULL, ((numentries > 0) && buffers && buffers[0]) ? lstrlenW(buffers[0]) : -1); } /* ########################### */ static void test_SplInitializeWinSpoolDrv(VOID) { LPVOID *fn_ref = fn_xp; DWORD res; LONG id; memset(fn_spl, 0xff, sizeof(fn_spl)); SetLastError(0xdeadbeef); res = pSplInitializeWinSpoolDrv(fn_spl); ok(res, "got %u with %u (expected '!= 0')\n", res, GetLastError()); /* functions 0 to 5 are the same in "spoolss.dll" from w2k and above */ if (fn_spl[6] == fn_w2k[6]) { fn_ref = fn_w2k; } if (fn_spl[9] == fn_v[9]) { fn_ref = fn_v; } id = 0; while (id < WINSPOOL_TABLESIZE) { ok( fn_spl[id] == fn_ref[id], "(#%02u) spoolss: %p (vista: %p, xp: %p, w2k: %p)\n", id, fn_spl[id], fn_v[id], fn_xp[id], fn_w2k[id]); id++; } } /* ########################### */ START_TEST(spoolss) { LPCSTR ptr; /* The tests fail on Win7 (see comments in load_function() */ ptr = load_functions(); if (ptr) { win_skip("%s not found\n", ptr); return; } test_BuildOtherNamesFromMachineName(); test_SplInitializeWinSpoolDrv(); }