diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index c87d4b60db2..050a3891d38 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -127,6 +127,18 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace, BOOL rc = FALSE; static const WCHAR bkslsh[]= {'\\',0}; + if (!DiskSpace) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (!DriveSpec) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + driveW = HeapAlloc(GetProcessHeap(), 0, lstrlenW(DriveSpec) + 2); if (!driveW) { @@ -152,6 +164,7 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace, HeapFree(GetProcessHeap(), 0, driveW); + if (!rc) SetLastError(ERROR_INVALID_DRIVE); return rc; } @@ -162,23 +175,35 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, LPCSTR DriveSpec, LONGLONG *SpaceRequired, PVOID Reserved1, UINT Reserved2) { - LPWSTR DriveSpecW = NULL; + DWORD len; + LPWSTR DriveSpecW; BOOL ret; - if (DriveSpec) + /* The parameter validation checks are in a different order from the + * Unicode variant of SetupQuerySpaceRequiredOnDrive. */ + if (!DriveSpec) { - DWORD len = MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, NULL, 0); - - DriveSpecW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (!DriveSpecW) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, DriveSpecW, len); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } + if (!DiskSpace) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + len = MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, NULL, 0); + + DriveSpecW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!DriveSpecW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, DriveSpecW, len); + ret = SetupQuerySpaceRequiredOnDriveW(DiskSpace, DriveSpecW, SpaceRequired, Reserved1, Reserved2); diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 33ea608d502..4700c5d08e7 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -146,8 +146,184 @@ static void test_SetupCreateDiskSpaceListW(void) GetLastError()); } +static void test_SetupQuerySpaceRequiredOnDriveA(void) +{ + BOOL ret; + HDSKSPC handle; + LONGLONG space; + int is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) && + GetLastError() == ERROR_CALL_NOT_IMPLEMENTED; + + if (is_win9x) + win_skip("SetupQuerySpaceRequiredOnDriveA crashes with NULL disk space handle on Win9x\n"); + else + { + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveA(NULL, "", NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveA(NULL, "", &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", + GetLastError()); + } + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveA(handle, NULL, NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_INVALID_DRIVE, /* Win9x */ + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveA(handle, NULL, &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_INVALID_DRIVE, /* Win9x */ + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveA(handle, "", NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_DRIVE, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveA(handle, "", &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_DRIVE, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); +} + +static void test_SetupQuerySpaceRequiredOnDriveW(void) +{ + static const WCHAR emptyW[] = {0}; + + BOOL ret; + HDSKSPC handle; + LONGLONG space; + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveW(NULL, NULL, NULL, NULL, 0); + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("SetupQuerySpaceRequiredOnDriveW is not available\n"); + return; + } + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveW(NULL, NULL, &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveW(NULL, emptyW, NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveW(NULL, emptyW, &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", + GetLastError()); + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveW(handle, NULL, NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_INVALID_DRIVE, /* NT4/Win2k/XP/Win2k3 */ + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveW(handle, NULL, &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_INVALID_DRIVE, /* NT4/Win2k/XP/Win2k3 */ + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupQuerySpaceRequiredOnDriveW(handle, emptyW, NULL, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_DRIVE, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + space = 0xdeadbeef; + ret = SetupQuerySpaceRequiredOnDriveW(handle, emptyW, &space, NULL, 0); + ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveW to return FALSE, got %d\n", ret); + ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n"); + ok(GetLastError() == ERROR_INVALID_DRIVE, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); +} + START_TEST(diskspace) { test_SetupCreateDiskSpaceListA(); test_SetupCreateDiskSpaceListW(); + test_SetupQuerySpaceRequiredOnDriveA(); + test_SetupQuerySpaceRequiredOnDriveW(); }