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:
Rob Shearman 2007-02-15 23:22:18 +00:00 committed by Alexandre Julliard
parent c9b9847dce
commit fc5b795f7c
2 changed files with 166 additions and 65 deletions

View File

@ -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;

View File

@ -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();
}