1 /* 2 * Copyright 2012 Andrew Eikum for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #define COBJMACROS 20 21 #include <stdio.h> 22 23 #include "windows.h" 24 #include "winnetwk.h" 25 #include "wine/test.h" 26 27 static void test_WNetGetUniversalName(void) 28 { 29 DWORD ret; 30 char buffer[1024]; 31 DWORD drive_type, info_size, fail_size; 32 char driveA[] = "A:\\"; 33 char driveandpathA[] = "A:\\file.txt"; 34 WCHAR driveW[] = {'A',':','\\',0}; 35 36 for(; *driveA <= 'Z'; ++*driveA, ++*driveandpathA, ++*driveW){ 37 drive_type = GetDriveTypeW(driveW); 38 39 info_size = sizeof(buffer); 40 ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, 41 buffer, &info_size); 42 43 if(drive_type == DRIVE_REMOTE) 44 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 45 else 46 /* WN_NO_NET_OR_BAD_PATH (DRIVE_FIXED) returned from the virtual drive (usual Q:) 47 created by the microsoft application virtualization client */ 48 ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH), 49 "WNetGetUniversalNameA(%s, ...) returned %u (drive_type: %u)\n", 50 driveA, ret, drive_type); 51 52 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 53 54 fail_size = 1; 55 ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, 56 buffer, &fail_size); 57 if(drive_type == DRIVE_REMOTE) 58 { 59 todo_wine ok(ret == WN_BAD_VALUE || ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 60 ok(fail_size > 1, "Got %d\n", fail_size); 61 } 62 else 63 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 64 "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret); 65 66 fail_size = ARRAY_SIZE(driveA) - 1; 67 ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, 68 buffer, &fail_size); 69 if(drive_type == DRIVE_REMOTE) 70 ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 71 72 ret = WNetGetUniversalNameA(driveandpathA, UNIVERSAL_NAME_INFO_LEVEL, 73 buffer, &info_size); 74 if(drive_type == DRIVE_REMOTE) 75 todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 76 77 info_size = sizeof(buffer); 78 ret = WNetGetUniversalNameW(driveW, UNIVERSAL_NAME_INFO_LEVEL, 79 buffer, &info_size); 80 81 if(drive_type == DRIVE_REMOTE) 82 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret); 83 else 84 ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH), 85 "WNetGetUniversalNameW(%s, ...) returned %u (drive_type: %u)\n", 86 wine_dbgstr_w(driveW), ret, drive_type); 87 if(drive_type != DRIVE_REMOTE) 88 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 89 } 90 } 91 92 static void test_WNetGetRemoteName(void) 93 { 94 DWORD ret; 95 char buffer[1024]; 96 DWORD drive_type, info_size, fail_size; 97 char driveA[] = "A:\\"; 98 char driveandpathA[] = "A:\\file.txt"; 99 WCHAR driveW[] = {'A',':','\\',0}; 100 101 for(; *driveA <= 'Z'; ++*driveA, ++*driveandpathA, ++*driveW){ 102 drive_type = GetDriveTypeW(driveW); 103 104 info_size = sizeof(buffer); 105 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 106 buffer, &info_size); 107 if(drive_type == DRIVE_REMOTE) 108 todo_wine 109 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 110 else 111 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 112 "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); 113 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 114 115 fail_size = 0; 116 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 117 buffer, &fail_size); 118 if(drive_type == DRIVE_REMOTE) 119 todo_wine 120 ok(ret == WN_BAD_VALUE || ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 121 else 122 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 123 "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); 124 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 125 buffer, NULL); 126 todo_wine ok(ret == WN_BAD_POINTER, "WNetGetUniversalNameA failed: %08x\n", ret); 127 128 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 129 NULL, &info_size); 130 131 if(drive_type == DRIVE_REMOTE) 132 todo_wine 133 ok(ret == WN_BAD_POINTER || ret == WN_BAD_VALUE, "WNetGetUniversalNameA failed: %08x\n", ret); 134 else 135 ok(ret == WN_NOT_CONNECTED || ret == WN_BAD_VALUE, 136 "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); 137 138 fail_size = ARRAY_SIZE(driveA) - 1; 139 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 140 buffer, &fail_size); 141 if(drive_type == DRIVE_REMOTE) 142 todo_wine ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 143 144 ret = WNetGetUniversalNameA(driveandpathA, REMOTE_NAME_INFO_LEVEL, 145 buffer, &info_size); 146 if(drive_type == DRIVE_REMOTE) 147 todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 148 149 info_size = sizeof(buffer); 150 ret = WNetGetUniversalNameW(driveW, REMOTE_NAME_INFO_LEVEL, 151 buffer, &info_size); 152 todo_wine{ 153 if(drive_type == DRIVE_REMOTE) 154 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret); 155 else 156 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 157 "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret); 158 } 159 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 160 } 161 } 162 163 static DWORD (WINAPI *pWNetCachePassword)( LPSTR, WORD, LPSTR, WORD, BYTE, WORD ); 164 static DWORD (WINAPI *pWNetGetCachedPassword)( LPSTR, WORD, LPSTR, LPWORD, BYTE ); 165 static UINT (WINAPI *pWNetEnumCachedPasswords)( LPSTR, WORD, BYTE, ENUMPASSWORDPROC, DWORD); 166 static UINT (WINAPI *pWNetRemoveCachedPassword)( LPSTR, WORD, BYTE ); 167 static DWORD (WINAPI *pWNetUseConnectionA)( HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD, LPDWORD ); 168 169 #define MPR_GET_PROC(func) \ 170 p ## func = (void*)GetProcAddress(hmpr, #func) 171 172 static void InitFunctionPtrs(void) 173 { 174 HMODULE hmpr = GetModuleHandleA("mpr.dll"); 175 176 MPR_GET_PROC(WNetCachePassword); 177 MPR_GET_PROC(WNetGetCachedPassword); 178 MPR_GET_PROC(WNetEnumCachedPasswords); 179 MPR_GET_PROC(WNetRemoveCachedPassword); 180 MPR_GET_PROC(WNetUseConnectionA); 181 } 182 183 static const char* m_resource = "wine-test-resource"; 184 static const char* m_password = "wine-test-password"; 185 static const BYTE m_type = 1; 186 static const DWORD m_param = 8; 187 static BOOL m_callback_reached; 188 189 static BOOL CALLBACK enum_password_proc(PASSWORD_CACHE_ENTRY* pce, DWORD param) 190 { 191 WORD size = 0; 192 char* buf; 193 194 ok(param == m_param, "param, got %d, got %d\n", param, m_param); 195 196 size = offsetof( PASSWORD_CACHE_ENTRY, abResource[pce->cbResource + pce->cbPassword] ); 197 ok(pce->cbEntry == size, "cbEntry, got %d, expected %d\n", pce->cbEntry, size); 198 ok(pce->cbResource == strlen(m_resource), "cbResource, got %d\n", pce->cbResource); 199 ok(pce->cbPassword == strlen(m_password), "cbPassword, got %d\n", pce->cbPassword); 200 ok(pce->iEntry == 0, "iEntry, got %d, got %d\n", pce->iEntry, 0); 201 ok(pce->nType == m_type, "nType, got %d, got %d\n", pce->nType, m_type); 202 203 buf = (char*)pce->abResource; 204 ok(strncmp(buf, m_resource, pce->cbResource)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbResource, buf, m_resource); 205 206 buf += pce->cbResource; 207 ok(strncmp(buf, m_password, pce->cbPassword)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbPassword, buf, m_password); 208 209 m_callback_reached = 1; 210 return TRUE; 211 } 212 213 static void test_WNetCachePassword(void) 214 { 215 char resource_buf[32]; 216 char password_buf[32]; 217 char prefix_buf[32]; 218 WORD resource_len; 219 WORD password_len; 220 WORD prefix_len; 221 DWORD ret; 222 223 InitFunctionPtrs(); 224 225 if (pWNetCachePassword && 226 pWNetGetCachedPassword && 227 pWNetEnumCachedPasswords && 228 pWNetRemoveCachedPassword) 229 { 230 strcpy(resource_buf, m_resource); 231 resource_len = strlen(m_resource); 232 strcpy(password_buf, m_password); 233 password_len = strlen(m_password); 234 ret = pWNetCachePassword(resource_buf, resource_len, password_buf, password_len, m_type, 0); 235 ok(ret == WN_SUCCESS, "WNetCachePassword failed: got %d, expected %d\n", ret, WN_SUCCESS); 236 237 strcpy(resource_buf, m_resource); 238 resource_len = strlen(m_resource); 239 strcpy(password_buf, "------"); 240 password_len = sizeof(password_buf); 241 ret = pWNetGetCachedPassword(resource_buf, resource_len, password_buf, &password_len, m_type); 242 ok(ret == WN_SUCCESS, "WNetGetCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS); 243 ok(password_len == strlen(m_password), "password length different, got %d\n", password_len); 244 ok(strncmp(password_buf, m_password, password_len)==0, "passwords different, got %.*s, expected %s\n", password_len, password_buf, m_password); 245 246 prefix_len = 9; 247 strcpy(prefix_buf, m_resource); 248 prefix_buf[prefix_len] = '0'; 249 ret = pWNetEnumCachedPasswords(prefix_buf, prefix_len, m_type, enum_password_proc, m_param); 250 ok(ret == WN_SUCCESS, "WNetEnumCachedPasswords failed: got %d, expected %d\n", ret, WN_SUCCESS); 251 ok(m_callback_reached == 1, "callback was not reached\n"); 252 253 strcpy(resource_buf, m_resource); 254 resource_len = strlen(m_resource); 255 ret = pWNetRemoveCachedPassword(resource_buf, resource_len, m_type); 256 ok(ret == WN_SUCCESS, "WNetRemoveCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS); 257 } else { 258 win_skip("WNetCachePassword() is not supported.\n"); 259 } 260 } 261 262 static void test_WNetUseConnection(void) 263 { 264 DWORD ret, bufSize, outRes; 265 LPNETRESOURCEA netRes; 266 char outBuf[4], drive[] = "J:", letter; 267 268 if (!pWNetUseConnectionA) 269 { 270 win_skip("WNetUseConnection() is not supported.\n"); 271 return; 272 } 273 netRes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETRESOURCEA) + sizeof("\\\\127.0.0.1\\c$") + sizeof("J:")); 274 netRes->dwType = RESOURCETYPE_DISK; 275 netRes->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; 276 netRes->dwUsage = RESOURCEUSAGE_CONNECTABLE; 277 netRes->lpLocalName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA)); 278 netRes->lpRemoteName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA) + sizeof("J:")); 279 280 for (letter = 'J'; letter <= 'Z'; letter++) 281 { 282 drive[0] = letter; 283 strcpy(netRes->lpLocalName, drive); 284 strcpy(netRes->lpRemoteName, "\\\\127.0.0.1\\c$"); 285 bufSize = 0; 286 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, NULL, &bufSize, &outRes); 287 if (ret != ERROR_ALREADY_ASSIGNED) break; 288 } 289 if (ret == ERROR_ALREADY_ASSIGNED) goto end; /* no drives available */ 290 todo_wine ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); 291 ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); 292 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 293 294 bufSize = 0; 295 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); 296 todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return: %u\n", ret); 297 ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); 298 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 299 300 todo_wine { 301 bufSize = 1; 302 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); 303 ok(ret == ERROR_MORE_DATA, "Unexpected return: %u\n", ret); 304 ok(bufSize == 3, "Unexpected buffer size: %u\n", bufSize); 305 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 306 307 bufSize = 4; 308 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); 309 ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); 310 } 311 ok(bufSize == 4, "Unexpected buffer size: %u\n", bufSize); 312 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 313 314 end: 315 HeapFree(GetProcessHeap(), 0, netRes); 316 } 317 318 START_TEST(mpr) 319 { 320 test_WNetGetUniversalName(); 321 test_WNetGetRemoteName(); 322 test_WNetCachePassword(); 323 test_WNetUseConnection(); 324 } 325