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 = 0; 55 ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, 56 buffer, &fail_size); 57 if(drive_type == DRIVE_REMOTE) 58 todo_wine ok(ret == WN_BAD_VALUE || ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 59 else 60 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 61 "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret); 62 63 fail_size = sizeof(driveA) / sizeof(char) - 1; 64 ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, 65 buffer, &fail_size); 66 if(drive_type == DRIVE_REMOTE) 67 ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 68 69 ret = WNetGetUniversalNameA(driveandpathA, UNIVERSAL_NAME_INFO_LEVEL, 70 buffer, &info_size); 71 if(drive_type == DRIVE_REMOTE) 72 todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 73 74 info_size = sizeof(buffer); 75 ret = WNetGetUniversalNameW(driveW, UNIVERSAL_NAME_INFO_LEVEL, 76 buffer, &info_size); 77 78 if(drive_type == DRIVE_REMOTE) 79 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret); 80 else 81 ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH), 82 "WNetGetUniversalNameW(%s, ...) returned %u (drive_type: %u)\n", 83 wine_dbgstr_w(driveW), ret, drive_type); 84 if(drive_type != DRIVE_REMOTE) 85 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 86 } 87 } 88 89 static void test_WNetGetRemoteName(void) 90 { 91 DWORD ret; 92 char buffer[1024]; 93 DWORD drive_type, info_size, fail_size; 94 char driveA[] = "A:\\"; 95 char driveandpathA[] = "A:\\file.txt"; 96 WCHAR driveW[] = {'A',':','\\',0}; 97 98 for(; *driveA <= 'Z'; ++*driveA, ++*driveandpathA, ++*driveW){ 99 drive_type = GetDriveTypeW(driveW); 100 101 info_size = sizeof(buffer); 102 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 103 buffer, &info_size); 104 if(drive_type == DRIVE_REMOTE) 105 todo_wine 106 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 107 else 108 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 109 "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); 110 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 111 112 fail_size = 0; 113 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 114 buffer, &fail_size); 115 if(drive_type == DRIVE_REMOTE) 116 todo_wine 117 ok(ret == WN_BAD_VALUE || ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 118 else 119 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 120 "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); 121 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 122 buffer, NULL); 123 todo_wine ok(ret == WN_BAD_POINTER, "WNetGetUniversalNameA failed: %08x\n", ret); 124 125 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 126 NULL, &info_size); 127 128 if(drive_type == DRIVE_REMOTE) 129 todo_wine 130 ok(ret == WN_BAD_POINTER || ret == WN_BAD_VALUE, "WNetGetUniversalNameA failed: %08x\n", ret); 131 else 132 ok(ret == WN_NOT_CONNECTED || ret == WN_BAD_VALUE, 133 "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); 134 135 fail_size = sizeof(driveA) / sizeof(char) - 1; 136 ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, 137 buffer, &fail_size); 138 if(drive_type == DRIVE_REMOTE) 139 todo_wine ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); 140 141 ret = WNetGetUniversalNameA(driveandpathA, REMOTE_NAME_INFO_LEVEL, 142 buffer, &info_size); 143 if(drive_type == DRIVE_REMOTE) 144 todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); 145 146 info_size = sizeof(buffer); 147 ret = WNetGetUniversalNameW(driveW, REMOTE_NAME_INFO_LEVEL, 148 buffer, &info_size); 149 todo_wine{ 150 if(drive_type == DRIVE_REMOTE) 151 ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret); 152 else 153 ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, 154 "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret); 155 } 156 ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); 157 } 158 } 159 160 static DWORD (WINAPI *pWNetCachePassword)( LPSTR, WORD, LPSTR, WORD, BYTE, WORD ); 161 static DWORD (WINAPI *pWNetGetCachedPassword)( LPSTR, WORD, LPSTR, LPWORD, BYTE ); 162 static UINT (WINAPI *pWNetEnumCachedPasswords)( LPSTR, WORD, BYTE, ENUMPASSWORDPROC, DWORD); 163 static UINT (WINAPI *pWNetRemoveCachedPassword)( LPSTR, WORD, BYTE ); 164 static DWORD (WINAPI *pWNetUseConnectionA)( HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD, LPDWORD ); 165 166 #define MPR_GET_PROC(func) \ 167 p ## func = (void*)GetProcAddress(hmpr, #func) 168 169 static void InitFunctionPtrs(void) 170 { 171 HMODULE hmpr = GetModuleHandleA("mpr.dll"); 172 173 MPR_GET_PROC(WNetCachePassword); 174 MPR_GET_PROC(WNetGetCachedPassword); 175 MPR_GET_PROC(WNetEnumCachedPasswords); 176 MPR_GET_PROC(WNetRemoveCachedPassword); 177 MPR_GET_PROC(WNetUseConnectionA); 178 } 179 180 static const char* m_resource = "wine-test-resource"; 181 static const char* m_password = "wine-test-password"; 182 static const BYTE m_type = 1; 183 static const DWORD m_param = 8; 184 static BOOL m_callback_reached; 185 186 static BOOL CALLBACK enum_password_proc(PASSWORD_CACHE_ENTRY* pce, DWORD param) 187 { 188 WORD size = 0; 189 char* buf; 190 191 ok(param == m_param, "param, got %d, got %d\n", param, m_param); 192 193 size = offsetof( PASSWORD_CACHE_ENTRY, abResource[pce->cbResource + pce->cbPassword] ); 194 ok(pce->cbEntry == size, "cbEntry, got %d, expected %d\n", pce->cbEntry, size); 195 ok(pce->cbResource == strlen(m_resource), "cbResource, got %d\n", pce->cbResource); 196 ok(pce->cbPassword == strlen(m_password), "cbPassword, got %d\n", pce->cbPassword); 197 ok(pce->iEntry == 0, "iEntry, got %d, got %d\n", pce->iEntry, 0); 198 ok(pce->nType == m_type, "nType, got %d, got %d\n", pce->nType, m_type); 199 200 buf = (char*)pce->abResource; 201 ok(strncmp(buf, m_resource, pce->cbResource)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbResource, buf, m_resource); 202 203 buf += pce->cbResource; 204 ok(strncmp(buf, m_password, pce->cbPassword)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbPassword, buf, m_password); 205 206 m_callback_reached = 1; 207 return TRUE; 208 } 209 210 static void test_WNetCachePassword(void) 211 { 212 char resource_buf[32]; 213 char password_buf[32]; 214 char prefix_buf[32]; 215 WORD resource_len; 216 WORD password_len; 217 WORD prefix_len; 218 DWORD ret; 219 220 InitFunctionPtrs(); 221 222 if (pWNetCachePassword && 223 pWNetGetCachedPassword && 224 pWNetEnumCachedPasswords && 225 pWNetRemoveCachedPassword) 226 { 227 strcpy(resource_buf, m_resource); 228 resource_len = strlen(m_resource); 229 strcpy(password_buf, m_password); 230 password_len = strlen(m_password); 231 ret = pWNetCachePassword(resource_buf, resource_len, password_buf, password_len, m_type, 0); 232 ok(ret == WN_SUCCESS, "WNetCachePassword failed: got %d, expected %d\n", ret, WN_SUCCESS); 233 234 strcpy(resource_buf, m_resource); 235 resource_len = strlen(m_resource); 236 strcpy(password_buf, "------"); 237 password_len = sizeof(password_buf); 238 ret = pWNetGetCachedPassword(resource_buf, resource_len, password_buf, &password_len, m_type); 239 ok(ret == WN_SUCCESS, "WNetGetCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS); 240 ok(password_len == strlen(m_password), "password length different, got %d\n", password_len); 241 ok(strncmp(password_buf, m_password, password_len)==0, "passwords different, got %.*s, expected %s\n", password_len, password_buf, m_password); 242 243 prefix_len = 9; 244 strcpy(prefix_buf, m_resource); 245 prefix_buf[prefix_len] = '0'; 246 ret = pWNetEnumCachedPasswords(prefix_buf, prefix_len, m_type, enum_password_proc, m_param); 247 ok(ret == WN_SUCCESS, "WNetEnumCachedPasswords failed: got %d, expected %d\n", ret, WN_SUCCESS); 248 ok(m_callback_reached == 1, "callback was not reached\n"); 249 250 strcpy(resource_buf, m_resource); 251 resource_len = strlen(m_resource); 252 ret = pWNetRemoveCachedPassword(resource_buf, resource_len, m_type); 253 ok(ret == WN_SUCCESS, "WNetRemoveCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS); 254 } else { 255 win_skip("WNetCachePassword() is not supported.\n"); 256 } 257 } 258 259 static void test_WNetUseConnection(void) 260 { 261 DWORD ret, bufSize, outRes; 262 LPNETRESOURCEA netRes; 263 char outBuf[4], drive[] = "J:", letter; 264 265 if (!pWNetUseConnectionA) 266 { 267 win_skip("WNetUseConnection() is not supported.\n"); 268 return; 269 } 270 netRes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETRESOURCEA) + sizeof("\\\\127.0.0.1\\c$") + sizeof("J:")); 271 netRes->dwType = RESOURCETYPE_DISK; 272 netRes->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; 273 netRes->dwUsage = RESOURCEUSAGE_CONNECTABLE; 274 netRes->lpLocalName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA)); 275 netRes->lpRemoteName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA) + sizeof("J:")); 276 277 for (letter = 'J'; letter <= 'Z'; letter++) 278 { 279 drive[0] = letter; 280 strcpy(netRes->lpLocalName, drive); 281 strcpy(netRes->lpRemoteName, "\\\\127.0.0.1\\c$"); 282 bufSize = 0; 283 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, NULL, &bufSize, &outRes); 284 if (ret != ERROR_ALREADY_ASSIGNED) break; 285 } 286 if (ret == ERROR_ALREADY_ASSIGNED) goto end; /* no drives available */ 287 todo_wine ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); 288 ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); 289 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 290 291 bufSize = 0; 292 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); 293 todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return: %u\n", ret); 294 ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); 295 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 296 297 todo_wine { 298 bufSize = 1; 299 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); 300 ok(ret == ERROR_MORE_DATA, "Unexpected return: %u\n", ret); 301 ok(bufSize == 3, "Unexpected buffer size: %u\n", bufSize); 302 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 303 304 bufSize = 4; 305 ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); 306 ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); 307 } 308 ok(bufSize == 4, "Unexpected buffer size: %u\n", bufSize); 309 if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); 310 311 end: 312 HeapFree(GetProcessHeap(), 0, netRes); 313 } 314 315 START_TEST(mpr) 316 { 317 test_WNetGetUniversalName(); 318 test_WNetGetRemoteName(); 319 test_WNetCachePassword(); 320 test_WNetUseConnection(); 321 } 322