| /* | |
| * Copyright 2012 Andrew Eikum for CodeWeavers | |
| * | |
| * 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 | |
| */ | |
| #define COBJMACROS | |
| #include <stdio.h> | |
| #include "windows.h" | |
| #include "winnetwk.h" | |
| #include "wine/test.h" | |
| static void test_WNetGetUniversalName(void) | |
| { | |
| DWORD ret; | |
| char buffer[1024]; | |
| DWORD drive_type, info_size, fail_size; | |
| char driveA[] = "A:\\"; | |
| char driveandpathA[] = "A:\\file.txt"; | |
| WCHAR driveW[] = {'A',':','\\',0}; | |
| for(; *driveA <= 'Z'; ++*driveA, ++*driveandpathA, ++*driveW){ | |
| drive_type = GetDriveTypeW(driveW); | |
| info_size = sizeof(buffer); | |
| ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, | |
| buffer, &info_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| else | |
| /* WN_NO_NET_OR_BAD_PATH (DRIVE_FIXED) returned from the virtual drive (usual Q:) | |
| created by the microsoft application virtualization client */ | |
| ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH), | |
| "WNetGetUniversalNameA(%s, ...) returned %u (drive_type: %u)\n", | |
| driveA, ret, drive_type); | |
| ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); | |
| fail_size = 0; | |
| ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, | |
| buffer, &fail_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| todo_wine ok(ret == WN_BAD_VALUE, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| else | |
| ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, | |
| "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret); | |
| fail_size = sizeof(driveA) / sizeof(char) - 1; | |
| ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL, | |
| buffer, &fail_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| ret = WNetGetUniversalNameA(driveandpathA, UNIVERSAL_NAME_INFO_LEVEL, | |
| buffer, &info_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| info_size = sizeof(buffer); | |
| ret = WNetGetUniversalNameW(driveW, UNIVERSAL_NAME_INFO_LEVEL, | |
| buffer, &info_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret); | |
| else | |
| ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH), | |
| "WNetGetUniversalNameW(%s, ...) returned %u (drive_type: %u)\n", | |
| wine_dbgstr_w(driveW), ret, drive_type); | |
| if(drive_type != DRIVE_REMOTE) | |
| ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); | |
| } | |
| } | |
| static void test_WNetGetRemoteName(void) | |
| { | |
| DWORD ret; | |
| char buffer[1024]; | |
| DWORD drive_type, info_size, fail_size; | |
| char driveA[] = "A:\\"; | |
| char driveandpathA[] = "A:\\file.txt"; | |
| WCHAR driveW[] = {'A',':','\\',0}; | |
| for(; *driveA <= 'Z'; ++*driveA, ++*driveandpathA, ++*driveW){ | |
| drive_type = GetDriveTypeW(driveW); | |
| info_size = sizeof(buffer); | |
| ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, | |
| buffer, &info_size); | |
| todo_wine{ | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| else | |
| ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, | |
| "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); | |
| } | |
| ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); | |
| fail_size = 0; | |
| ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, | |
| buffer, &fail_size); | |
| todo_wine{ | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_BAD_VALUE, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| else | |
| ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, | |
| "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); | |
| } | |
| ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, | |
| buffer, NULL); | |
| todo_wine ok(ret == WN_BAD_POINTER, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, | |
| NULL, &info_size); | |
| todo_wine { | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_BAD_POINTER, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| else | |
| ok(ret == WN_NOT_CONNECTED || ret == WN_BAD_VALUE, | |
| "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret); | |
| } | |
| fail_size = sizeof(driveA) / sizeof(char) - 1; | |
| ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL, | |
| buffer, &fail_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| todo_wine ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| ret = WNetGetUniversalNameA(driveandpathA, REMOTE_NAME_INFO_LEVEL, | |
| buffer, &info_size); | |
| if(drive_type == DRIVE_REMOTE) | |
| todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret); | |
| info_size = sizeof(buffer); | |
| ret = WNetGetUniversalNameW(driveW, REMOTE_NAME_INFO_LEVEL, | |
| buffer, &info_size); | |
| todo_wine{ | |
| if(drive_type == DRIVE_REMOTE) | |
| ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret); | |
| else | |
| ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH, | |
| "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret); | |
| } | |
| ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size); | |
| } | |
| } | |
| static DWORD (WINAPI *pWNetCachePassword)( LPSTR, WORD, LPSTR, WORD, BYTE, WORD ); | |
| static DWORD (WINAPI *pWNetGetCachedPassword)( LPSTR, WORD, LPSTR, LPWORD, BYTE ); | |
| static UINT (WINAPI *pWNetEnumCachedPasswords)( LPSTR, WORD, BYTE, ENUMPASSWORDPROC, DWORD); | |
| static UINT (WINAPI *pWNetRemoveCachedPassword)( LPSTR, WORD, BYTE ); | |
| static DWORD (WINAPI *pWNetUseConnectionA)( HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD, LPDWORD ); | |
| #define MPR_GET_PROC(func) \ | |
| p ## func = (void*)GetProcAddress(hmpr, #func) | |
| static void InitFunctionPtrs(void) | |
| { | |
| HMODULE hmpr = GetModuleHandleA("mpr.dll"); | |
| MPR_GET_PROC(WNetCachePassword); | |
| MPR_GET_PROC(WNetGetCachedPassword); | |
| MPR_GET_PROC(WNetEnumCachedPasswords); | |
| MPR_GET_PROC(WNetRemoveCachedPassword); | |
| MPR_GET_PROC(WNetUseConnectionA); | |
| } | |
| static const char* m_resource = "wine-test-resource"; | |
| static const char* m_password = "wine-test-password"; | |
| static const BYTE m_type = 1; | |
| static const DWORD m_param = 8; | |
| static BOOL m_callback_reached; | |
| static BOOL CALLBACK enum_password_proc(PASSWORD_CACHE_ENTRY* pce, DWORD param) | |
| { | |
| WORD size = 0; | |
| char* buf; | |
| ok(param == m_param, "param, got %d, got %d\n", param, m_param); | |
| size = offsetof( PASSWORD_CACHE_ENTRY, abResource[pce->cbResource + pce->cbPassword] ); | |
| ok(pce->cbEntry == size, "cbEntry, got %d, expected %d\n", pce->cbEntry, size); | |
| ok(pce->cbResource == strlen(m_resource), "cbResource, got %d\n", pce->cbResource); | |
| ok(pce->cbPassword == strlen(m_password), "cbPassword, got %d\n", pce->cbPassword); | |
| ok(pce->iEntry == 0, "iEntry, got %d, got %d\n", pce->iEntry, 0); | |
| ok(pce->nType == m_type, "nType, got %d, got %d\n", pce->nType, m_type); | |
| buf = (char*)pce->abResource; | |
| ok(strncmp(buf, m_resource, pce->cbResource)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbResource, buf, m_resource); | |
| buf += pce->cbResource; | |
| ok(strncmp(buf, m_password, pce->cbPassword)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbPassword, buf, m_password); | |
| m_callback_reached = 1; | |
| return TRUE; | |
| } | |
| static void test_WNetCachePassword(void) | |
| { | |
| char resource_buf[32]; | |
| char password_buf[32]; | |
| char prefix_buf[32]; | |
| WORD resource_len; | |
| WORD password_len; | |
| WORD prefix_len; | |
| DWORD ret; | |
| InitFunctionPtrs(); | |
| if (pWNetCachePassword && | |
| pWNetGetCachedPassword && | |
| pWNetEnumCachedPasswords && | |
| pWNetRemoveCachedPassword) | |
| { | |
| strcpy(resource_buf, m_resource); | |
| resource_len = strlen(m_resource); | |
| strcpy(password_buf, m_password); | |
| password_len = strlen(m_password); | |
| ret = pWNetCachePassword(resource_buf, resource_len, password_buf, password_len, m_type, 0); | |
| ok(ret == WN_SUCCESS, "WNetCachePassword failed: got %d, expected %d\n", ret, WN_SUCCESS); | |
| strcpy(resource_buf, m_resource); | |
| resource_len = strlen(m_resource); | |
| strcpy(password_buf, "------"); | |
| password_len = sizeof(password_buf); | |
| ret = pWNetGetCachedPassword(resource_buf, resource_len, password_buf, &password_len, m_type); | |
| ok(ret == WN_SUCCESS, "WNetGetCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS); | |
| ok(password_len == strlen(m_password), "password length different, got %d\n", password_len); | |
| ok(strncmp(password_buf, m_password, password_len)==0, "passwords different, got %.*s, expected %s\n", password_len, password_buf, m_password); | |
| prefix_len = 9; | |
| strcpy(prefix_buf, m_resource); | |
| prefix_buf[prefix_len] = '0'; | |
| ret = pWNetEnumCachedPasswords(prefix_buf, prefix_len, m_type, enum_password_proc, m_param); | |
| ok(ret == WN_SUCCESS, "WNetEnumCachedPasswords failed: got %d, expected %d\n", ret, WN_SUCCESS); | |
| ok(m_callback_reached == 1, "callback was not reached\n"); | |
| strcpy(resource_buf, m_resource); | |
| resource_len = strlen(m_resource); | |
| ret = pWNetRemoveCachedPassword(resource_buf, resource_len, m_type); | |
| ok(ret == WN_SUCCESS, "WNetRemoveCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS); | |
| } else { | |
| win_skip("WNetCachePassword() is not supported.\n"); | |
| } | |
| } | |
| static void test_WNetUseConnection(void) | |
| { | |
| DWORD ret, bufSize, outRes; | |
| LPNETRESOURCEA netRes; | |
| char outBuf[4], drive[] = "J:", letter; | |
| if (!pWNetUseConnectionA) | |
| { | |
| win_skip("WNetUseConnection() is not supported.\n"); | |
| return; | |
| } | |
| netRes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETRESOURCEA) + sizeof("\\\\127.0.0.1\\c$") + sizeof("J:")); | |
| netRes->dwType = RESOURCETYPE_DISK; | |
| netRes->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; | |
| netRes->dwUsage = RESOURCEUSAGE_CONNECTABLE; | |
| netRes->lpLocalName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA)); | |
| netRes->lpRemoteName = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA) + sizeof("J:")); | |
| for (letter = 'J'; letter <= 'Z'; letter++) | |
| { | |
| drive[0] = letter; | |
| strcpy(netRes->lpLocalName, drive); | |
| strcpy(netRes->lpRemoteName, "\\\\127.0.0.1\\c$"); | |
| bufSize = 0; | |
| ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, NULL, &bufSize, &outRes); | |
| if (ret == ERROR_ALREADY_ASSIGNED) continue; | |
| } | |
| todo_wine ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); | |
| ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); | |
| if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); | |
| bufSize = 0; | |
| ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); | |
| todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return: %u\n", ret); | |
| ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize); | |
| if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); | |
| todo_wine { | |
| bufSize = 1; | |
| ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); | |
| ok(ret == ERROR_MORE_DATA, "Unexpected return: %u\n", ret); | |
| ok(bufSize == 3, "Unexpected buffer size: %u\n", bufSize); | |
| if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); | |
| bufSize = 4; | |
| ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes); | |
| ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret); | |
| } | |
| ok(bufSize == 4, "Unexpected buffer size: %u\n", bufSize); | |
| if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE); | |
| HeapFree(GetProcessHeap(), 0, netRes); | |
| } | |
| START_TEST(mpr) | |
| { | |
| test_WNetGetUniversalName(); | |
| test_WNetGetRemoteName(); | |
| test_WNetCachePassword(); | |
| test_WNetUseConnection(); | |
| } |