From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 184 +++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 82 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 1ca45f96913..7c33542e5a8 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -1,6 +1,7 @@ /* * SetupAPI DiskSpace functions * + * Copyright 2016 Michael Müller * Copyright 2004 CodeWeavers (Aric Stewart) * * This library is free software; you can redistribute it and/or @@ -27,69 +28,51 @@ #include "winnls.h" #include "winreg.h" #include "setupapi.h" +#include "wine/unicode.h" +#include "wine/list.h" #include "wine/debug.h" +#include "setupapi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-typedef struct { - WCHAR lpzName[20]; - LONGLONG dwFreeSpace; - LONGLONG dwWantedSpace; -} DRIVE_ENTRY, *LPDRIVE_ENTRY; +struct file_entry +{ + struct list entry; + WCHAR *path; + UINT operation; + LONGLONG size; +}; + +struct space_list +{ + struct list files; + UINT flags; +};
-typedef struct { - DWORD dwDriveCount; - DRIVE_ENTRY Drives[26]; -} DISKSPACELIST, *LPDISKSPACELIST;
/*********************************************************************** * SetupCreateDiskSpaceListW (SETUPAPI.@) */ -HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID reserved1, DWORD reserved2, UINT flags) { - WCHAR drives[255]; - DWORD rc; - WCHAR *ptr; - LPDISKSPACELIST list=NULL; + struct space_list *list;
- TRACE("(%p, %u, 0x%08x)\n", Reserved1, Reserved2, Flags); + TRACE("(%p, %u, 0x%08x)\n", reserved1, reserved2, flags);
- if (Reserved1 || Reserved2 || Flags & ~SPDSL_IGNORE_DISK) + if (reserved1 || reserved2 || flags & ~SPDSL_IGNORE_DISK) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; }
- rc = GetLogicalDriveStringsW(255,drives); - - if (rc == 0) - return NULL; - - list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST)); - - list->dwDriveCount = 0; - - ptr = drives; - - while (*ptr) + list = HeapAlloc(GetProcessHeap(), 0, sizeof(*list)); + if (list) { - DWORD type = GetDriveTypeW(ptr); - if (type == DRIVE_FIXED) - { - DWORD clusters; - DWORD sectors; - DWORD bytes; - DWORD total; - lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr); - GetDiskFreeSpaceW(ptr,§ors,&bytes,&clusters,&total); - list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors * - bytes; - list->Drives[list->dwDriveCount].dwWantedSpace = 0; - list->dwDriveCount++; - } - ptr += lstrlenW(ptr) + 1; + list->flags = flags; + list_init(&list->files); } + return list; }
@@ -105,32 +88,58 @@ HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT /*********************************************************************** * SetupDuplicateDiskSpaceListW (SETUPAPI.@) */ -HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC diskspace, PVOID reserved1, DWORD reserved2, UINT flags) { - DISKSPACELIST *list_copy, *list_original = DiskSpace; + struct space_list *list_copy, *list = diskspace; + struct file_entry *file, *file_copy; + + TRACE("(%p, %p, %u, %u)\n", diskspace, reserved1, reserved2, flags);
- if (Reserved1 || Reserved2 || Flags) + if (reserved1 || reserved2 || flags) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; }
- if (!DiskSpace) + if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return NULL; }
- list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST)); + list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*list_copy)); if (!list_copy) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
- *list_copy = *list_original; + list_copy->flags = list->flags; + list_init(&list_copy->files); + + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + file_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*file_copy)); + if (!file_copy) goto error; + + file_copy->path = strdupW(file->path); + if (!file_copy->path) + { + HeapFree(GetProcessHeap(), 0, file_copy); + goto error; + } + + file_copy->operation = file->operation; + file_copy->size = file->size; + list_add_head(&list_copy->files, &file->entry); + }
return list_copy; + +error: + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetupDestroyDiskSpaceList(list_copy); + return NULL; }
/*********************************************************************** @@ -155,55 +164,51 @@ BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, /*********************************************************************** * SetupQuerySpaceRequiredOnDriveW (SETUPAPI.@) */ -BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace, - LPCWSTR DriveSpec, LONGLONG *SpaceRequired, - PVOID Reserved1, UINT Reserved2) +BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC diskspace, + LPCWSTR drivespec, LONGLONG *required, + PVOID reserved1, UINT reserved2) { - WCHAR *driveW; - unsigned int i; - LPDISKSPACELIST list = DiskSpace; - BOOL rc = FALSE; - static const WCHAR bkslsh[]= {'\',0}; + struct space_list *list = diskspace; + struct file_entry *file; + LONGLONG sum = 0;
- if (!DiskSpace) + TRACE("(%p, %s, %p, %p, %u)\n", diskspace, debugstr_w(drivespec), required, reserved1, reserved2); + + if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; }
- if (!DriveSpec) + if (!drivespec || !drivespec[0]) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(drivespec ? ERROR_INVALID_DRIVE : ERROR_INVALID_DRIVE); return FALSE; }
- driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR)); - if (!driveW) + if (!required) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
- lstrcpyW(driveW,DriveSpec); - lstrcatW(driveW,bkslsh); - - TRACE("Looking for drive %s\n",debugstr_w(driveW)); - - for (i = 0; i < list->dwDriveCount; i++) + if (tolowerW(drivespec[0]) < 'a' || tolowerW(drivespec[0]) > 'z' || + drivespec[1] != ':' || drivespec[2] != 0) { - TRACE("checking drive %s\n",debugstr_w(list->Drives[i].lpzName)); - if (lstrcmpW(driveW,list->Drives[i].lpzName)==0) - { - rc = TRUE; - *SpaceRequired = list->Drives[i].dwWantedSpace; - break; - } + FIXME("UNC paths not yet supported (%s)\n", debugstr_w(drivespec)); + SetLastError((GetVersion() & 0x80000000) ? ERROR_INVALID_DRIVE : ERROR_INVALID_PARAMETER); + return FALSE; }
- HeapFree(GetProcessHeap(), 0, driveW); + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + if (tolowerW(file->path[0]) == tolowerW(drivespec[0]) && + file->path[1] == ':' && file->path[2] == '\') + sum += file->size; + }
- if (!rc) SetLastError(ERROR_INVALID_DRIVE); - return rc; + *required = sum; + return TRUE; }
/*********************************************************************** @@ -253,10 +258,25 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, /*********************************************************************** * SetupDestroyDiskSpaceList (SETUPAPI.@) */ -BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace) +BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) { - LPDISKSPACELIST list = DiskSpace; - HeapFree(GetProcessHeap(),0,list); + struct space_list *list = diskspace; + struct file_entry *file, *file2; + + if (!diskspace) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry) + { + HeapFree(GetProcessHeap(), 0, file->path); + list_remove(&file->entry); + HeapFree(GetProcessHeap(), 0, file); + } + + HeapFree(GetProcessHeap(), 0, list); return TRUE; }
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 137 +++++++++++++++++++++++++-- dlls/setupapi/tests/diskspace.c | 159 +++++++++++++++++++++++++++++++- 2 files changed, 285 insertions(+), 11 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 7c33542e5a8..f945b994bb7 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -49,7 +49,21 @@ struct space_list UINT flags; };
+static LONGLONG get_file_size(WCHAR *path) +{ + HANDLE file; + LARGE_INTEGER size; + + file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) return 0;
+ if (!GetFileSizeEx(file, &size)) + size.QuadPart = 0; + + CloseHandle(file); + return size.QuadPart; +}
/*********************************************************************** * SetupCreateDiskSpaceListW (SETUPAPI.@) @@ -281,25 +295,128 @@ BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) }
/*********************************************************************** -* SetupAddToDiskSpaceListA (SETUPAPI.@) +* SetupAddToDiskSpaceListW (SETUPAPI.@) */ -BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, +BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile, LONGLONG filesize, UINT operation, PVOID reserved1, UINT reserved2) { - FIXME(": stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + struct space_list *list = diskspace; + struct file_entry *file; + WCHAR *fullpathW; + BOOL ret = FALSE; + DWORD size; + + TRACE("(%p, %s, %s, %u, %p, %u)\n", diskspace, debugstr_w(targetfile), + wine_dbgstr_longlong(filesize), operation, reserved1, reserved2); + + if (!targetfile) + return TRUE; + + if (!diskspace) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (operation != FILEOP_COPY && operation != FILEOP_DELETE) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + size = GetFullPathNameW(targetfile, 0, NULL, NULL); + if (!size) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + size = (size+1) * sizeof(WCHAR); + fullpathW = HeapAlloc(GetProcessHeap(), 0, size); + + if (!GetFullPathNameW(targetfile, size, fullpathW, NULL)) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto done; + } + + if (fullpathW[1] != ':' && fullpathW[2] != '\') + { + FIXME("UNC paths not yet supported\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + goto done; + } + + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + if (!strcmpiW(file->path, fullpathW)) + break; + } + + if (&file->entry == &list->files) + { + file = HeapAlloc(GetProcessHeap(), 0, sizeof(*file)); + if (!file) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + + file->path = strdupW(fullpathW); + if (!file->path) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + HeapFree(GetProcessHeap(), 0, file); + goto done; + } + + list_add_tail(&list->files, &file->entry); + } + + file->operation = operation; + if (operation == FILEOP_COPY) + file->size = filesize; + else + file->size = 0; + + if (!(list->flags & SPDSL_IGNORE_DISK)) + file->size -= get_file_size(fullpathW); + + ret = TRUE; + +done: + HeapFree(GetProcessHeap(), 0, fullpathW); + return ret; }
/*********************************************************************** -* SetupAddToDiskSpaceListW (SETUPAPI.@) +* SetupAddToDiskSpaceListA (SETUPAPI.@) */ -BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile, +BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, LONGLONG filesize, UINT operation, PVOID reserved1, UINT reserved2) { - FIXME(": stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + LPWSTR targetfileW = NULL; + DWORD len; + BOOL ret; + + if (targetfile) + { + len = MultiByteToWideChar(CP_ACP, 0, targetfile, -1, NULL, 0); + + targetfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!targetfileW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + MultiByteToWideChar(CP_ACP, 0, targetfile, -1, targetfileW, len); + } + + ret = SetupAddToDiskSpaceListW(diskspace, targetfileW, filesize, + operation, reserved1, reserved2); + if (targetfileW) HeapFree(GetProcessHeap(), 0, targetfileW); + return ret; } diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 4e87ea905e0..bb8c7b78463 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -19,6 +19,7 @@ */
#include <stdarg.h> +#include <stdio.h>
#include "windef.h" #include "winbase.h" @@ -31,6 +32,16 @@
static BOOL is_win9x;
+static inline const char* debugstr_longlong(ULONGLONG ll) +{ + static char string[17]; + if (sizeof(ll) > sizeof(unsigned long) && ll >> 32) + sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll); + else + sprintf(string, "%lx", (unsigned long)ll); + return string; +} + static void test_SetupCreateDiskSpaceListA(void) { HDSKSPC ret; @@ -300,11 +311,31 @@ static void test_SetupDuplicateDiskSpaceListW(void) ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static LONGLONG get_file_size(char *path) +{ + HANDLE file; + LARGE_INTEGER size; + + file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) return 0; + + if (!GetFileSizeEx(file, &size)) + size.QuadPart = 0; + + CloseHandle(file); + return size.QuadPart; +} + static void test_SetupQuerySpaceRequiredOnDriveA(void) { BOOL ret; HDSKSPC handle; LONGLONG space; + char windir[MAX_PATH]; + char drive[3]; + char tmp[MAX_PATH]; + LONGLONG size;
if (is_win9x) win_skip("SetupQuerySpaceRequiredOnDriveA crashes with NULL disk space handle on Win9x\n"); @@ -369,7 +400,7 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) 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", + "Expected GetLastError() to return ERROR_INVALID_DRIVE, got %u\n", GetLastError());
SetLastError(0xdeadbeef); @@ -381,6 +412,97 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+ GetWindowsDirectoryA(windir, MAX_PATH); + drive[0] = windir[0]; drive[1] = windir[1]; drive[2] = 0; + + snprintf(tmp, MAX_PATH, "%c:\wine-test-should-not-exist.txt", drive[0]); + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x100000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x100000, "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space)); + + /* adding the same file again doesn't sum up the size */ + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x200000, "Expected 0x200000 as required space, got %s\n", debugstr_longlong(space)); + + /* the device doesn't need to exist */ + snprintf(tmp, MAX_PATH, "F:\wine-test-should-not-exist.txt"); + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupQuerySpaceRequiredOnDriveA(handle, "F:", &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x200000, "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + /* the real size is subtracted unless SPDSL_IGNORE_DISK is specified */ + snprintf(tmp, MAX_PATH, "%s\regedit.exe", windir); + + size = get_file_size(tmp); + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0 || broken(space == -0x5000) || broken(space == -0x7000), + "Expected 0x0 as required space, got %s\n", debugstr_longlong(space)); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size + 0x100000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x100000 || broken(space == 0xf9000) || broken(space == 0xfb000), + "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space)); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size - 0x1000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == -0x1000 || broken(space == -0x6000) || broken(space == -0x8000), + "Expected -0x1000 as required space, got %s\n", debugstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space <= -size, "Expected space <= -size, got %s\n", debugstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0, "Expected size = 0, got %s\n", debugstr_longlong(space)); + ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); } @@ -472,6 +594,40 @@ static void test_SetupQuerySpaceRequiredOnDriveW(void) "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static void test_SetupAddToDiskSpaceListA(void) +{ + HDSKSPC handle; + BOOL ret; + + ret = SetupAddToDiskSpaceListA(NULL, "C:\some-file.dat", 0, FILEOP_COPY, 0, 0); + ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE, got %d\n", ret); + 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\n"); + + ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_COPY, 0, 0); + ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "C:\some-file.dat", -20, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "C:\some-file.dat", 0, FILEOP_RENAME, 0, 0); + ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); + + ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_RENAME, 0, 0); + ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(NULL, NULL, 0, FILEOP_RENAME, 0, 0); + ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); +} + START_TEST(diskspace) { is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) && @@ -482,4 +638,5 @@ START_TEST(diskspace) test_SetupDuplicateDiskSpaceListW(); test_SetupQuerySpaceRequiredOnDriveA(); test_SetupQuerySpaceRequiredOnDriveW(); + test_SetupAddToDiskSpaceListA(); }