1 /* 2 * Unit test suite for the Spooler-Service helper DLL 3 * 4 * Copyright 2007 Detlef Riekenberg 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 * 20 */ 21 22 #include <stdarg.h> 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "winerror.h" 27 #include "wine/test.h" 28 29 30 31 /* ##### */ 32 33 static HMODULE hwinspool; 34 35 static HMODULE hspl; 36 static BOOL (WINAPI * pBuildOtherNamesFromMachineName)(LPWSTR **, LPDWORD); 37 static DWORD (WINAPI * pSplInitializeWinSpoolDrv)(LPVOID *); 38 39 #define WINSPOOL_TABLESIZE 16 40 41 static LPVOID fn_spl[WINSPOOL_TABLESIZE]; 42 static LPVOID fn_w2k[WINSPOOL_TABLESIZE]; 43 static LPVOID fn_xp[WINSPOOL_TABLESIZE]; 44 static LPVOID fn_v[WINSPOOL_TABLESIZE]; 45 46 /* ########################### */ 47 48 static LPCSTR load_functions(void) 49 { 50 LPCSTR ptr; 51 52 ptr = "spoolss.dll"; 53 hspl = LoadLibraryA(ptr); 54 if (!hspl) return ptr; 55 56 ptr = "BuildOtherNamesFromMachineName"; 57 pBuildOtherNamesFromMachineName = (void *) GetProcAddress(hspl, ptr); 58 if (!pBuildOtherNamesFromMachineName) return ptr; 59 60 ptr = "SplInitializeWinSpoolDrv"; 61 pSplInitializeWinSpoolDrv = (void *) GetProcAddress(hspl, ptr); 62 if (!pSplInitializeWinSpoolDrv) return ptr; 63 64 65 /* Calling BuildOtherNamesFromMachineName or SplInitializeWinSpoolDrv on 66 * Win7 results in a breakpoint exception. If you continue after hitting 67 * the breakpoint, the functions fail with ERROR_NOT_SUPPORTED. So we 68 * just skip the tests on Win7, since they won't provide any useful info. 69 * To detect Win7, we check whether UnloadDriver exists (it doesn't on 70 * Win7, but does exist on earlier Windows versions) */ 71 ptr = "UnloadDriver"; 72 if (GetProcAddress(hspl, ptr) == NULL) return ptr; 73 74 75 ptr = "winspool.drv"; 76 hwinspool = LoadLibraryA(ptr); 77 if (!hwinspool) return ptr; 78 79 memset(fn_w2k, 0xff, sizeof(fn_w2k)); 80 fn_w2k[0] = (void *) GetProcAddress(hwinspool, "OpenPrinterW"); 81 fn_w2k[1] = (void *) GetProcAddress(hwinspool, "ClosePrinter"); 82 fn_w2k[2] = (void *) GetProcAddress(hwinspool, "SpoolerDevQueryPrintW"); 83 fn_w2k[3] = (void *) GetProcAddress(hwinspool, "SpoolerPrinterEvent"); 84 fn_w2k[4] = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW"); 85 fn_w2k[5] = (void *) GetProcAddress(hwinspool, (LPSTR) 212); /* LoadPrinterDriver */ 86 fn_w2k[6] = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterW"); 87 fn_w2k[7] = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterW"); 88 fn_w2k[8] = (void *) GetProcAddress(hwinspool, (LPSTR) 213); /* RefCntLoadDriver */ 89 fn_w2k[9] = (void *) GetProcAddress(hwinspool, (LPSTR) 214); /* RefCntUnloadDriver */ 90 fn_w2k[10] = (void *) GetProcAddress(hwinspool, (LPSTR) 215); /* ForceUnloadDriver */ 91 92 memset(fn_xp, 0xff, sizeof(fn_xp)); 93 fn_xp[0] = (void *) GetProcAddress(hwinspool, "OpenPrinterW"); 94 fn_xp[1] = (void *) GetProcAddress(hwinspool, "ClosePrinter"); 95 fn_xp[2] = (void *) GetProcAddress(hwinspool, "SpoolerDevQueryPrintW"); 96 fn_xp[3] = (void *) GetProcAddress(hwinspool, "SpoolerPrinterEvent"); 97 fn_xp[4] = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW"); 98 fn_xp[5] = (void *) GetProcAddress(hwinspool, (LPSTR) 212); /* LoadPrinterDriver */ 99 fn_xp[6] = (void *) GetProcAddress(hwinspool, (LPSTR) 213); /* RefCntLoadDriver */ 100 fn_xp[7] = (void *) GetProcAddress(hwinspool, (LPSTR) 214); /* RefCntUnloadDriver */ 101 fn_xp[8] = (void *) GetProcAddress(hwinspool, (LPSTR) 215); /* ForceUnloadDriver */ 102 103 memset(fn_v, 0xff, sizeof(fn_v)); 104 fn_v[0] = (void *) GetProcAddress(hwinspool, "OpenPrinterW"); 105 fn_v[1] = (void *) GetProcAddress(hwinspool, "ClosePrinter"); 106 fn_v[2] = (void *) GetProcAddress(hwinspool, "SpoolerDevQueryPrintW"); 107 fn_v[3] = (void *) GetProcAddress(hwinspool, "SpoolerPrinterEvent"); 108 fn_v[4] = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW"); 109 fn_v[5] = (void *) GetProcAddress(hwinspool, (LPSTR) 212); /* LoadPrinterDriver */ 110 fn_v[6] = (void *) GetProcAddress(hwinspool, (LPSTR) 213); /* RefCntLoadDriver */ 111 fn_v[7] = (void *) GetProcAddress(hwinspool, (LPSTR) 214); /* RefCntUnloadDriver */ 112 fn_v[8] = (void *) GetProcAddress(hwinspool, (LPSTR) 215); /* ForceUnloadDriver */ 113 fn_v[9] = (void *) GetProcAddress(hwinspool, (LPSTR) 251); /* 0xfb */ 114 115 return NULL; 116 117 } 118 119 /* ########################### */ 120 121 static void test_BuildOtherNamesFromMachineName(void) 122 { 123 LPWSTR *buffers; 124 DWORD numentries; 125 DWORD res; 126 127 buffers = NULL; 128 numentries = 0; 129 130 SetLastError(0xdeadbeef); 131 res = pBuildOtherNamesFromMachineName(&buffers, &numentries); 132 133 /* An array with a number of stringpointers is returned (minimum of 3): 134 entry_#0: "" (empty String) 135 entry_#1: <hostname> (this is the same as the computername) 136 1 entry per Ethernet adapter : <ip-address> (string with a IPv4 ip-address) 137 138 As of Vista: 139 140 IPv6 fully disabled (lan interfaces, connections, tunnel interfaces and loopback interfaces) 141 entry_#0: "" (empty String) 142 entry_#1: <hostname> (this is the same as the computername) 143 1 entry per Ethernet adapter : <ip-address> (string with a IPv4 ip-address) 144 entry_#x: "::1" 145 146 IPv6 partly disabled (lan interfaces, connections): 147 entry_#0: "" (empty String) 148 entry_#1: <hostname> (this is the same as the computername) 149 entry_#2: "::1" 150 1 entry per Ethernet adapter : <ip-address> (string with a IPv4 ip-address) 151 152 IPv6 fully enabled but not on all lan interfaces: 153 entry_#0: "" (empty String) 154 entry_#1: <hostname> (this is the same as the computername) 155 1 entry per IPv6 enabled Ethernet adapter : <ip-address> (string with a Link-local IPv6 ip-address) 156 1 entry per IPv4 enabled Ethernet adapter : <ip-address> (string with a IPv4 ip-address) 157 158 IPv6 fully enabled on all lan interfaces: 159 entry_#0: "" (empty String) 160 entry_#1: <hostname> (this is the same as the computername) 161 1 entry per IPv6 enabled Ethernet adapter : <ip-address> (string with a Link-local IPv6 ip-address) 162 entry_#x: <ip-address> Tunnel adapter (string with a Link-local IPv6 ip-address) 163 1 entry per IPv4 enabled Ethernet adapter : <ip-address> (string with a IPv4 ip-address) 164 entry_#y: <ip-address> Tunnel adapter (string with a IPv6 ip-address) 165 */ 166 167 todo_wine 168 ok( res && (buffers != NULL) && (numentries >= 3) && (buffers[0] != NULL) && (buffers[0][0] == '\0'), 169 "got %u with %u and %p,%u (%p:%d)\n", res, GetLastError(), buffers, numentries, 170 ((numentries > 0) && buffers) ? buffers[0] : NULL, 171 ((numentries > 0) && buffers && buffers[0]) ? lstrlenW(buffers[0]) : -1); 172 173 } 174 175 /* ########################### */ 176 177 static void test_SplInitializeWinSpoolDrv(VOID) 178 { 179 LPVOID *fn_ref = fn_xp; 180 DWORD res; 181 LONG id; 182 183 memset(fn_spl, 0xff, sizeof(fn_spl)); 184 SetLastError(0xdeadbeef); 185 res = pSplInitializeWinSpoolDrv(fn_spl); 186 ok(res, "got %u with %u (expected '!= 0')\n", res, GetLastError()); 187 188 /* functions 0 to 5 are the same in "spoolss.dll" from w2k and above */ 189 if (fn_spl[6] == fn_w2k[6]) { 190 fn_ref = fn_w2k; 191 } 192 if (fn_spl[9] == fn_v[9]) { 193 fn_ref = fn_v; 194 } 195 196 id = 0; 197 while (id < WINSPOOL_TABLESIZE) { 198 ok( fn_spl[id] == fn_ref[id], 199 "(#%02u) spoolss: %p (vista: %p, xp: %p, w2k: %p)\n", 200 id, fn_spl[id], fn_v[id], fn_xp[id], fn_w2k[id]); 201 id++; 202 } 203 } 204 205 /* ########################### */ 206 207 START_TEST(spoolss) 208 { 209 LPCSTR ptr; 210 211 /* The tests fail on Win7 (see comments in load_function() */ 212 ptr = load_functions(); 213 if (ptr) { 214 win_skip("%s not found\n", ptr); 215 return; 216 } 217 218 test_BuildOtherNamesFromMachineName(); 219 test_SplInitializeWinSpoolDrv(); 220 221 } 222