wine/dlls/mpr/tests/mpr.c
Fabian Maurer 8ca2938757 wnet: Make WNetGetUniversalNameW return required size when buffer is too small and add test.
The pointer is set to the required size not only when the input size
is 0, but generally when it is too small.

Signed-off-by: Fabian Maurer <dark.shadow4@web.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
2018-08-14 14:51:34 +02:00

325 lines
13 KiB
C

/*
* 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 = 1;
ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL,
buffer, &fail_size);
if(drive_type == DRIVE_REMOTE)
{
todo_wine ok(ret == WN_BAD_VALUE || ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret);
ok(fail_size > 1, "Got %d\n", fail_size);
}
else
ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH,
"(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret);
fail_size = ARRAY_SIZE(driveA) - 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);
if(drive_type == DRIVE_REMOTE)
todo_wine
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);
if(drive_type == DRIVE_REMOTE)
todo_wine
ok(ret == WN_BAD_VALUE || ret == WN_MORE_DATA, "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);
if(drive_type == DRIVE_REMOTE)
todo_wine
ok(ret == WN_BAD_POINTER || ret == WN_BAD_VALUE, "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 = ARRAY_SIZE(driveA) - 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) break;
}
if (ret == ERROR_ALREADY_ASSIGNED) goto end; /* no drives available */
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);
end:
HeapFree(GetProcessHeap(), 0, netRes);
}
START_TEST(mpr)
{
test_WNetGetUniversalName();
test_WNetGetRemoteName();
test_WNetCachePassword();
test_WNetUseConnection();
}