kernel32: Fix the GetComputerName* functions to not write to the buffer at all if there is not enough space.
Add tests for the GetComputerName* functions that show this issue. Fix an off-by-one error in setting the size when there is not enough space. Remove the exception handlers for GetComputerNameW, GetComputerNameExA/W, since testing on XP SP2 shows that access violations are not caught and these are not present on Win9x, which does have an exception handler.
This commit is contained in:
parent
c9b9847dce
commit
fc5b795f7c
|
@ -333,28 +333,18 @@ BOOL WINAPI GetComputerNameW(LPWSTR name,LPDWORD size)
|
|||
len = (len -offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data )) / sizeof (WCHAR) - 1;
|
||||
TRACE ("ComputerName is %s (length %u)\n", debugstr_w ( theName ), len);
|
||||
|
||||
__TRY
|
||||
if ( *size < len + 1 )
|
||||
{
|
||||
if ( *size < len )
|
||||
{
|
||||
memcpy ( name, theName, *size * sizeof (WCHAR) );
|
||||
name[*size] = 0;
|
||||
*size = len;
|
||||
st = STATUS_MORE_ENTRIES;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy ( name, theName, len * sizeof (WCHAR) );
|
||||
name[len] = 0;
|
||||
*size = len;
|
||||
st = STATUS_SUCCESS;
|
||||
}
|
||||
*size = len + 1;
|
||||
st = STATUS_MORE_ENTRIES;
|
||||
}
|
||||
__EXCEPT_PAGE_FAULT
|
||||
else
|
||||
{
|
||||
st = STATUS_INVALID_PARAMETER;
|
||||
memcpy ( name, theName, len * sizeof (WCHAR) );
|
||||
name[len] = 0;
|
||||
*size = len;
|
||||
st = STATUS_SUCCESS;
|
||||
}
|
||||
__ENDTRY
|
||||
|
||||
out:
|
||||
NtClose ( hsubkey );
|
||||
|
@ -382,20 +372,19 @@ BOOL WINAPI GetComputerNameA(LPSTR name, LPDWORD size)
|
|||
|
||||
if ( !GetComputerNameW (nameW, &sizeW) ) return FALSE;
|
||||
|
||||
len = WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, NULL, 0, NULL, 0 );
|
||||
len = WideCharToMultiByte ( CP_ACP, 0, nameW, -1, NULL, 0, NULL, 0 );
|
||||
/* for compatibility with Win9x */
|
||||
__TRY
|
||||
{
|
||||
if ( *size < len )
|
||||
if ( *size < len + 1 )
|
||||
{
|
||||
WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, name, *size, NULL, 0 );
|
||||
name[*size] = 0;
|
||||
*size = len;
|
||||
*size = len + 1;
|
||||
SetLastError( ERROR_MORE_DATA );
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WideCharToMultiByte ( CP_ACP, 0, nameW, sizeW, name, len, NULL, 0 );
|
||||
WideCharToMultiByte ( CP_ACP, 0, nameW, -1, name, len, NULL, 0 );
|
||||
name[len] = 0;
|
||||
*size = len;
|
||||
ret = TRUE;
|
||||
|
@ -444,30 +433,19 @@ BOOL WINAPI GetComputerNameExA(COMPUTER_NAME_FORMAT type, LPSTR name, LPDWORD si
|
|||
if ( ret )
|
||||
{
|
||||
TRACE ("-> %s (%d)\n", debugstr_a (buf), len);
|
||||
__TRY
|
||||
if ( *size < len + 1 )
|
||||
{
|
||||
if ( *size < len )
|
||||
{
|
||||
memcpy( name, buf, *size );
|
||||
name[*size] = 0;
|
||||
*size = len;
|
||||
SetLastError( ERROR_MORE_DATA );
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( name, buf, len );
|
||||
name[len] = 0;
|
||||
*size = len;
|
||||
ret = TRUE;
|
||||
}
|
||||
*size = len + 1;
|
||||
SetLastError( ERROR_MORE_DATA );
|
||||
ret = FALSE;
|
||||
}
|
||||
__EXCEPT_PAGE_FAULT
|
||||
else
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
memcpy( name, buf, len );
|
||||
name[len] = 0;
|
||||
*size = len;
|
||||
ret = TRUE;
|
||||
}
|
||||
__ENDTRY
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -507,32 +485,24 @@ BOOL WINAPI GetComputerNameExW( COMPUTER_NAME_FORMAT type, LPWSTR name, LPDWORD
|
|||
|
||||
if ( ret )
|
||||
{
|
||||
unsigned int lenW;
|
||||
|
||||
TRACE ("-> %s (%d)\n", debugstr_a (buf), len);
|
||||
__TRY
|
||||
|
||||
lenW = MultiByteToWideChar( CP_ACP, 0, buf, len, NULL, 0 );
|
||||
if ( *size < lenW + 1 )
|
||||
{
|
||||
unsigned int lenW = MultiByteToWideChar( CP_ACP, 0, buf, len, NULL, 0 );
|
||||
if ( *size < lenW )
|
||||
{
|
||||
MultiByteToWideChar( CP_ACP, 0, buf, len, name, *size );
|
||||
name[*size] = 0;
|
||||
*size = lenW;
|
||||
SetLastError( ERROR_MORE_DATA );
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MultiByteToWideChar( CP_ACP, 0, buf, len, name, lenW );
|
||||
name[lenW] = 0;
|
||||
*size = lenW;
|
||||
ret = TRUE;
|
||||
}
|
||||
*size = lenW + 1;
|
||||
SetLastError( ERROR_MORE_DATA );
|
||||
ret = FALSE;
|
||||
}
|
||||
__EXCEPT_PAGE_FAULT
|
||||
else
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
MultiByteToWideChar( CP_ACP, 0, buf, len, name, lenW );
|
||||
name[lenW] = 0;
|
||||
*size = lenW;
|
||||
ret = TRUE;
|
||||
}
|
||||
__ENDTRY
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -229,9 +229,140 @@ static void test_ExpandEnvironmentStringsA(void)
|
|||
ok(!strcmp(buf, buf1), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %d\n", buf, buf1, ret_size);
|
||||
}
|
||||
|
||||
static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
|
||||
static BOOL (WINAPI *pGetComputerNameExW)(COMPUTER_NAME_FORMAT,LPWSTR,LPDWORD);
|
||||
|
||||
static void test_GetComputerName(void)
|
||||
{
|
||||
DWORD size;
|
||||
BOOL ret;
|
||||
LPSTR name;
|
||||
LPWSTR nameW;
|
||||
DWORD error;
|
||||
|
||||
size = 0;
|
||||
ret = GetComputerNameA((LPSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameA should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
|
||||
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = GetComputerNameA(name, &size);
|
||||
ok(ret, "GetComputerNameA failed with error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
|
||||
size = 0;
|
||||
ret = GetComputerNameW((LPWSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameW should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
|
||||
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = GetComputerNameW(nameW, &size);
|
||||
ok(ret, "GetComputerNameW failed with error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, nameW);
|
||||
|
||||
pGetComputerNameExA = GetProcAddress(GetModuleHandle("kernel32.dll"), "GetComputerNameExA");
|
||||
if (!pGetComputerNameExA)
|
||||
{
|
||||
skip("GetComputerNameExA function not implemented, so not testing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExA(ComputerNameDnsDomain, (LPSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExA should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
|
||||
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExA(ComputerNameDnsDomain, name, &size);
|
||||
ok(ret, "GetComputerNameExA(ComputerNameDnsDomain) failed with error %d\n", GetLastError());
|
||||
trace("domain name is \"%s\"\n", name);
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, (LPSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExA should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
|
||||
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, name, &size);
|
||||
ok(ret, "GetComputerNameExA(ComputerNameDnsFullyQualified) failed with error %d\n", GetLastError());
|
||||
trace("fully qualified hostname is \"%s\"\n", name);
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExA(ComputerNameDnsHostname, (LPSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExA should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
|
||||
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExA(ComputerNameDnsHostname, name, &size);
|
||||
ok(ret, "GetComputerNameExA(ComputerNameDnsHostname) failed with error %d\n", GetLastError());
|
||||
trace("hostname is \"%s\"\n", name);
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExA(ComputerNameNetBIOS, (LPSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExA should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
|
||||
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExA(ComputerNameNetBIOS, name, &size);
|
||||
ok(ret, "GetComputerNameExA(ComputerNameNetBIOS) failed with error %d\n", GetLastError());
|
||||
trace("NetBIOS name is \"%s\"\n", name);
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
|
||||
pGetComputerNameExW = GetProcAddress(GetModuleHandle("kernel32.dll"), "GetComputerNameExW");
|
||||
if (!pGetComputerNameExW)
|
||||
{
|
||||
skip("GetComputerNameExW function not implemented, so not testing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExW(ComputerNameDnsDomain, (LPWSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
|
||||
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExW(ComputerNameDnsDomain, nameW, &size);
|
||||
ok(ret, "GetComputerNameExW(ComputerNameDnsDomain) failed with error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, nameW);
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExW(ComputerNameDnsFullyQualified, (LPWSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
|
||||
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExW(ComputerNameDnsFullyQualified, nameW, &size);
|
||||
ok(ret, "GetComputerNameExW(ComputerNameDnsFullyQualified) failed with error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, nameW);
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExW(ComputerNameDnsHostname, (LPWSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
|
||||
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExW(ComputerNameDnsHostname, nameW, &size);
|
||||
ok(ret, "GetComputerNameExW(ComputerNameDnsHostname) failed with error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, nameW);
|
||||
|
||||
size = 0;
|
||||
ret = pGetComputerNameExW(ComputerNameNetBIOS, (LPWSTR)0xdeadbeef, &size);
|
||||
error = GetLastError();
|
||||
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
|
||||
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
|
||||
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
|
||||
ret = pGetComputerNameExW(ComputerNameNetBIOS, nameW, &size);
|
||||
ok(ret, "GetComputerNameExW(ComputerNameNetBIOS) failed with error %d\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, nameW);
|
||||
}
|
||||
|
||||
START_TEST(environ)
|
||||
{
|
||||
test_GetSetEnvironmentVariableA();
|
||||
test_GetSetEnvironmentVariableW();
|
||||
test_ExpandEnvironmentStringsA();
|
||||
test_GetComputerName();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue