From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 177 ++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 84 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index f5e79d5327c9..94b68d2e82ba 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -2,6 +2,7 @@ * SetupAPI DiskSpace functions * * Copyright 2004 CodeWeavers (Aric Stewart) + * Copyright 2016 Michael Müller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,68 +29,50 @@ #include "winreg.h" #include "setupapi.h" #include "wine/debug.h" +#include "wine/heap.h" +#include "wine/list.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 = heap_alloc(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 = heap_alloc(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 = heap_alloc(sizeof(*file_copy)); + if (!file_copy) goto error; + + file_copy->path = strdupW(file->path); + if (!file_copy->path) + { + heap_free(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,46 @@ 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) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
- driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR)); - if (!driveW) + + if (towlower(drivespec[0]) < 'a' || towlower(drivespec[0]) > 'z' || + drivespec[1] != ':' || drivespec[2] != 0) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + FIXME("UNC paths not yet supported (%s)\n", debugstr_w(drivespec)); + SetLastError(ERROR_INVALID_DRIVE); return FALSE; }
- lstrcpyW(driveW,DriveSpec); - lstrcatW(driveW,bkslsh); - - TRACE("Looking for drive %s\n",debugstr_w(driveW)); - - for (i = 0; i < list->dwDriveCount; i++) + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) { - TRACE("checking drive %s\n",debugstr_w(list->Drives[i].lpzName)); - if (wcscmp(driveW,list->Drives[i].lpzName)==0) - { - rc = TRUE; - *SpaceRequired = list->Drives[i].dwWantedSpace; - break; - } + if (towlower(file->path[0]) == towlower(drivespec[0]) && + file->path[1] == ':' && file->path[2] == '\') + sum += file->size; }
- HeapFree(GetProcessHeap(), 0, driveW); - - if (!rc) SetLastError(ERROR_INVALID_DRIVE); - return rc; + *required = sum; + return TRUE; }
/*********************************************************************** @@ -233,7 +233,7 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace,
len = MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, NULL, 0);
- DriveSpecW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + DriveSpecW = heap_alloc(len * sizeof(WCHAR)); if (!DriveSpecW) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -245,7 +245,7 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, ret = SetupQuerySpaceRequiredOnDriveW(DiskSpace, DriveSpecW, SpaceRequired, Reserved1, Reserved2);
- HeapFree(GetProcessHeap(), 0, DriveSpecW); + heap_free(DriveSpecW);
return ret; } @@ -253,10 +253,19 @@ 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; + + LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry) + { + heap_free(file->path); + list_remove(&file->entry); + heap_free(file); + } + + heap_free(list); return TRUE; }
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 123 +++++++++++++++++++++++--- dlls/setupapi/tests/diskspace.c | 150 +++++++++++++++++++++++++++++++- 2 files changed, 261 insertions(+), 12 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 94b68d2e82ba..d500c4c02a33 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.@) @@ -270,25 +284,114 @@ 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 = heap_alloc(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 (!lstrcmpiW(file->path, fullpathW)) + break; + } + + if (&file->entry == &list->files) + { + file = heap_alloc(sizeof(*file)); + if (!file) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + + file->path = strdupW(fullpathW); + if (!file->path) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + heap_free(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: + heap_free(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; + BOOL ret; + + targetfileW = strdupAtoW(targetfile); + ret = SetupAddToDiskSpaceListW(diskspace, targetfileW, filesize, + operation, reserved1, reserved2); + heap_free(targetfileW); + return ret; } diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 4e87ea905e07..0da1b7fddaf2 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -300,11 +300,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 +389,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); @@ -378,9 +398,100 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) 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", + "Expected GetLastError() to return ERROR_INVALID_DRIVE, 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", wine_dbgstr_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", wine_dbgstr_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", wine_dbgstr_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", wine_dbgstr_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", wine_dbgstr_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", wine_dbgstr_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", wine_dbgstr_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", wine_dbgstr_longlong(space)); + ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); } @@ -472,6 +583,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 +627,5 @@ START_TEST(diskspace) test_SetupDuplicateDiskSpaceListW(); test_SetupQuerySpaceRequiredOnDriveA(); test_SetupQuerySpaceRequiredOnDriveW(); + test_SetupAddToDiskSpaceListA(); }
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 71 +++++++++++++++++++++++++++++++++ dlls/setupapi/stubs.c | 18 --------- dlls/setupapi/tests/diskspace.c | 71 +++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 18 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index d500c4c02a33..49db166e094f 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -395,3 +395,74 @@ BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, heap_free(targetfileW); return ret; } + + +/*********************************************************************** + * SetupQueryDrivesInDiskSpaceListW (SETUPAPI.@) + */ +BOOL WINAPI SetupQueryDrivesInDiskSpaceListW(HDSKSPC diskspace, PWSTR buffer, DWORD buffersize, PDWORD requiredsize) +{ + struct space_list *list = diskspace; + struct file_entry *file; + DWORD cur_size = 1; + BOOL used[26]; + + TRACE("(%p, %p, %d, %p)\n", diskspace, buffer, buffersize, requiredsize); + + if (!diskspace) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + memset(&used, 0, sizeof(used)); + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + int device; + + /* UNC paths are not yet supported by this function */ + if (towlower(file->path[0]) < 'a' || towlower(file->path[0]) > 'z' || file->path[1] != ':') + continue; + + device = towlower(file->path[0]) - 'a'; + if (used[device]) continue; + + cur_size += 3; + + if (buffer) + { + if (cur_size > buffersize) + { + if (requiredsize) *requiredsize = cur_size; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + *buffer++ = towlower(file->path[0]); + *buffer++ = ':'; + *buffer++ = 0; + } + + used[device] = TRUE; + } + + if (buffer && buffersize) *buffer = 0; + if (requiredsize) *requiredsize = cur_size; + return TRUE; +} + +/*********************************************************************** + * SetupQueryDrivesInDiskSpaceListA (SETUPAPI.@) + */ +BOOL WINAPI SetupQueryDrivesInDiskSpaceListA(HDSKSPC diskspace, PSTR buffer, DWORD buffersize, PDWORD requiredsize) +{ + WCHAR *bufferW = NULL; + BOOL ret; + int i; + + bufferW = strdupAtoW(buffer); + + ret = SetupQueryDrivesInDiskSpaceListW(diskspace, bufferW, buffersize, requiredsize); + + heap_free(bufferW); + return ret; +} diff --git a/dlls/setupapi/stubs.c b/dlls/setupapi/stubs.c index 47dca6c15052..80c3a7cfd9f7 100644 --- a/dlls/setupapi/stubs.c +++ b/dlls/setupapi/stubs.c @@ -230,24 +230,6 @@ INT WINAPI SetupPromptReboot( HSPFILEQ file_queue, HWND owner, BOOL scan_only ) return 0; }
-/*********************************************************************** - * SetupQueryDrivesInDiskSpaceListA (SETUPAPI.@) - */ -BOOL WINAPI SetupQueryDrivesInDiskSpaceListA(HDSKSPC disk_space, PSTR return_buffer, DWORD return_buffer_size, PDWORD required_size) -{ - FIXME("%p, %p, %d, %p: stub\n", disk_space, return_buffer, return_buffer_size, required_size); - return FALSE; -} - -/*********************************************************************** - * SetupQueryDrivesInDiskSpaceListW (SETUPAPI.@) - */ -BOOL WINAPI SetupQueryDrivesInDiskSpaceListW(HDSKSPC disk_space, PWSTR return_buffer, DWORD return_buffer_size, PDWORD required_size) -{ - FIXME("%p, %p, %d, %p: stub\n", disk_space, return_buffer, return_buffer_size, required_size); - return FALSE; -} - /*********************************************************************** * SetupAddToSourceListA (SETUPAPI.@) */ diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 0da1b7fddaf2..e5c9a4522f8b 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -617,6 +617,76 @@ static void test_SetupAddToDiskSpaceListA(void) "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static void test_SetupQueryDrivesInDiskSpaceListA(void) +{ + char buffer[MAX_PATH]; + HDSKSPC handle; + DWORD size; + BOOL ret; + + handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(handle != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n"); + + ret = SetupQueryDrivesInDiskSpaceListA(handle, NULL, 0, NULL); + ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n"); + + size = 0; + ret = SetupQueryDrivesInDiskSpaceListA(handle, NULL, 0, &size); + ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n"); + ok(size == 1, "Expected size 1, got %u\n", size); + + ret = SetupAddToDiskSpaceListA(handle, "F:\random-file.dat", 0, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "G:\random-file.dat", 0, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "G:\random-file2.dat", 0, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "X:\random-file.dat", 0, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + size = 0; + ret = SetupQueryDrivesInDiskSpaceListA(handle, NULL, 0, &size); + ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n"); + ok(size == 10, "Expected size 10, got %u\n", size); + + size = 0; + ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, 0, &size); + ok(!ret, "Expected SetupQueryDrivesInDiskSpaceListA to fail\n"); + ok(size == 4, "Expected size 4, got %u\n", size); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); + + size = 0; + ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, 4, &size); + ok(!ret, "Expected SetupQueryDrivesInDiskSpaceListA to fail\n"); + ok(size == 7, "Expected size 7, got %u\n", size); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); + + size = 0; + ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, 7, &size); + ok(!ret, "Expected SetupQueryDrivesInDiskSpaceListA to fail\n"); + ok(size == 10, "Expected size 10, got %u\n", size); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); + + size = 0; + memset(buffer, 0xff, sizeof(buffer)); + ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, sizeof(buffer), &size); + ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n"); + ok(size == 10, "Expected size 10, got %u\n", size); + ok(!memcmp("f:\0g:\0x:\0\0", buffer, 10), "Device list does not match\n"); + + memset(buffer, 0xff, sizeof(buffer)); + ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, sizeof(buffer), NULL); + ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n"); + ok(!memcmp("f:\0g:\0x:\0\0", buffer, 10), "Device list does not match\n"); +} + + START_TEST(diskspace) { is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) && @@ -628,4 +698,5 @@ START_TEST(diskspace) test_SetupQuerySpaceRequiredOnDriveA(); test_SetupQuerySpaceRequiredOnDriveW(); test_SetupAddToDiskSpaceListA(); + test_SetupQueryDrivesInDiskSpaceListA(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58195
Your paranoid android.
=== debian10 (32 bit report) ===
setupapi: diskspace.c:681: Test failed: Device list does not match diskspace.c:686: Test failed: Device list does not match
=== debian10 (32 bit French report) ===
setupapi: diskspace.c:681: Test failed: Device list does not match diskspace.c:686: Test failed: Device list does not match
=== debian10 (32 bit Japanese:Japan report) ===
setupapi: diskspace.c:681: Test failed: Device list does not match diskspace.c:686: Test failed: Device list does not match
=== debian10 (32 bit Chinese:China report) ===
setupapi: diskspace.c:681: Test failed: Device list does not match diskspace.c:686: Test failed: Device list does not match
=== debian10 (32 bit WoW report) ===
setupapi: diskspace.c:681: Test failed: Device list does not match diskspace.c:686: Test failed: Device list does not match
=== debian10 (64 bit WoW report) ===
setupapi: diskspace.c:681: Test failed: Device list does not match diskspace.c:686: Test failed: Device list does not match
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 6 ++++ dlls/setupapi/tests/diskspace.c | 60 ++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 49db166e094f..8cfc958df590 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -362,6 +362,12 @@ BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
list_add_tail(&list->files, &file->entry); } + else if (operation == FILEOP_DELETE) + { + /* delete operations for added files are ignored */ + ret = TRUE; + goto done; + }
file->operation = operation; if (operation == FILEOP_COPY) diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index e5c9a4522f8b..130e7582bd28 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -429,7 +429,15 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
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", wine_dbgstr_longlong(space)); + ok(space == 0x200000, "Expected 0x200000 as required space, got %s\n", wine_dbgstr_longlong(space)); + + snprintf(tmp, MAX_PATH, "F:\wine-test-should-not-exist.txt"); + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_DELETE, 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 0x200000 as required space, got %s\n", wine_dbgstr_longlong(space));
ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); @@ -467,6 +475,45 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n");
+ /* test FILEOP_DELETE, then FILEOP_COPY */ + 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"); + 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", wine_dbgstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + /* test FILEOP_COPY, then FILEOP_DELETE */ + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\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 || broken(space == -0x5000) || broken(space == -0x7000), + "Expected 0x0 as required space, got %s\n", wine_dbgstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + /* test FILEOP_DELETE without SPDSL_IGNORE_DISK */ handle = SetupCreateDiskSpaceListA(NULL, 0, 0); ok(handle != NULL, "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); @@ -481,6 +528,7 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n");
+ /* test FILEOP_COPY and FILEOP_DELETE with SPDSL_IGNORE_DISK */ handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); ok(handle != NULL, "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); @@ -492,6 +540,16 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); ok(space == 0, "Expected size = 0, got %s\n", wine_dbgstr_longlong(space));
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\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 size >= %s\n", wine_dbgstr_longlong(space)); + ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58196
Your paranoid android.
=== debian10 (32 bit report) ===
setupapi: diskspace.c:739: Test failed: Device list does not match diskspace.c:744: Test failed: Device list does not match
=== debian10 (32 bit French report) ===
setupapi: diskspace.c:739: Test failed: Device list does not match diskspace.c:744: Test failed: Device list does not match
=== debian10 (32 bit Japanese:Japan report) ===
setupapi: diskspace.c:739: Test failed: Device list does not match diskspace.c:744: Test failed: Device list does not match
=== debian10 (32 bit Chinese:China report) ===
setupapi: diskspace.c:739: Test failed: Device list does not match diskspace.c:744: Test failed: Device list does not match
=== debian10 (32 bit WoW report) ===
setupapi: diskspace.c:739: Test failed: Device list does not match diskspace.c:744: Test failed: Device list does not match
=== debian10 (64 bit WoW report) ===
setupapi: diskspace.c:739: Test failed: Device list does not match diskspace.c:744: Test failed: Device list does not match
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 114 ++++++++++++++++++ dlls/setupapi/queue.c | 2 +- dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/setupapi_private.h | 2 + dlls/setupapi/tests/diskspace.c | 192 +++++++++++++++++++++++++++++++ 5 files changed, 311 insertions(+), 3 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 8cfc958df590..2e2714df5c3f 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -65,6 +65,22 @@ static LONGLONG get_file_size(WCHAR *path) return size.QuadPart; }
+static BOOL get_size_from_inf(HINF layoutinf, WCHAR *filename, LONGLONG *size) +{ + static const WCHAR SourceDisksFiles[] = L"SourceDisksFiles"; + INFCONTEXT context; + WCHAR buffer[20]; + + if (!SetupFindFirstLineW(layoutinf, SourceDisksFiles, filename, &context)) + return FALSE; + + if (!SetupGetStringFieldW(&context, 3, buffer, sizeof(buffer), NULL)) + return FALSE; + + *size = _wcstoi64(buffer, NULL, 10); + return TRUE; +} + /*********************************************************************** * SetupCreateDiskSpaceListW (SETUPAPI.@) */ @@ -175,6 +191,104 @@ BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, return TRUE; }
+/*********************************************************************** + * SetupAddSectionToDiskSpaceListW (SETUPAPI.@) + */ +BOOL WINAPI SetupAddSectionToDiskSpaceListW(HDSKSPC diskspace, HINF hinf, HINF hlist, + PCWSTR section, UINT operation, PVOID reserved1, + UINT reserved2) +{ + static const WCHAR sepW[] = {'\',0}; + WCHAR dest[MAX_PATH], src[MAX_PATH], *dest_dir, *full_path; + INFCONTEXT context; + BOOL ret = FALSE; + + TRACE("(%p, %p, %p, %s, %u, %p, %u)\n", diskspace, hinf, hlist, debugstr_w(section), + operation, reserved1, reserved2); + + if (!diskspace) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (!section) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (!hlist) hlist = hinf; + + if (!SetupFindFirstLineW(hlist, section, NULL, &context)) + { + SetLastError(ERROR_SECTION_NOT_FOUND); + return FALSE; + } + + dest_dir = get_destination_dir(hinf, section); + if (!dest_dir) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + do + { + LONGLONG filesize; + int path_size, dest_len, src_len; + BOOL tmp_ret; + + if (!SetupGetStringFieldW(&context, 1, dest, ARRAY_SIZE( dest ), &dest_len)) + goto end; + if (!SetupGetStringFieldW(&context, 2, src, ARRAY_SIZE( src ), &src_len)) + *src = 0; + if (!get_size_from_inf(hinf, src_len ? src : dest, &filesize)) + goto end; + + path_size = lstrlenW(dest_dir) + dest_len + 2; + full_path = heap_alloc(path_size * sizeof(WCHAR)); + if (!full_path) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto end; + } + + lstrcpyW(full_path, dest_dir); + lstrcatW(full_path, sepW); + lstrcatW(full_path, dest); + + tmp_ret = SetupAddToDiskSpaceListW(diskspace, full_path, filesize, operation, 0, 0); + heap_free(full_path); + if (!tmp_ret) goto end; + } + while (SetupFindNextLine(&context, &context)); + + ret = TRUE; + +end: + heap_free(dest_dir); + return ret; +} + +/*********************************************************************** + * SetupAddSectionToDiskSpaceListA (SETUPAPI.@) + */ +BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC diskspace, HINF hinf, HINF hlist, + PCSTR section, UINT operation, PVOID reserved1, + UINT reserved2) +{ + LPWSTR sectionW = NULL; + BOOL ret; + + sectionW = strdupAtoW(section); + ret = SetupAddSectionToDiskSpaceListW(diskspace, hinf, hlist, sectionW, operation, + reserved1, reserved2); + heap_free(sectionW); + return ret; +} + + /*********************************************************************** * SetupQuerySpaceRequiredOnDriveW (SETUPAPI.@) */ diff --git a/dlls/setupapi/queue.c b/dlls/setupapi/queue.c index f7da3a7128e6..3d11d1ea8a02 100644 --- a/dlls/setupapi/queue.c +++ b/dlls/setupapi/queue.c @@ -338,7 +338,7 @@ static void get_source_info( HINF hinf, const WCHAR *src_file, SP_FILE_COPY_PARA * * Retrieve the destination dir for a given section. */ -static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section ) +WCHAR *get_destination_dir( HINF hinf, const WCHAR *section ) { static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0}; static const WCHAR Def[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0}; diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 81256a3417ce..ad8652ac93b3 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -244,8 +244,8 @@ @ stub SetArrayToMultiSzValue @ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long) @ stub SetupAddInstallSectionToDiskSpaceListW -@ stub SetupAddSectionToDiskSpaceListA -@ stub SetupAddSectionToDiskSpaceListW +@ stdcall SetupAddSectionToDiskSpaceListA(long long long str long ptr long) +@ stdcall SetupAddSectionToDiskSpaceListW(long long long wstr long ptr long) @ stdcall SetupAddToDiskSpaceListA(long str int64 long ptr long) @ stdcall SetupAddToDiskSpaceListW(long wstr int64 long ptr long) @ stdcall SetupAddToSourceListA(long str) diff --git a/dlls/setupapi/setupapi_private.h b/dlls/setupapi/setupapi_private.h index f4685ab2b4ce..4df062349cc5 100644 --- a/dlls/setupapi/setupapi_private.h +++ b/dlls/setupapi/setupapi_private.h @@ -92,6 +92,8 @@ extern const WCHAR *DIRID_get_string( int dirid ) DECLSPEC_HIDDEN; extern const WCHAR *PARSER_get_inf_filename( HINF hinf ) DECLSPEC_HIDDEN; extern WCHAR *PARSER_get_dest_dir( INFCONTEXT *context ) DECLSPEC_HIDDEN;
+extern WCHAR *get_destination_dir( HINF hinf, const WCHAR *section ); + /* support for Ascii queue callback functions */
struct callback_WtoA_context diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 130e7582bd28..ff7d6236092e 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -31,6 +31,20 @@
static BOOL is_win9x;
+#define STD_HEADER "[Version]\r\nSignature="$CHICAGO$"\r\n" + +/* create a new file with specified contents and open it */ +static HINF inf_open_file_content(const char * tmpfilename, const char *data, UINT *err_line) +{ + DWORD res; + HANDLE handle = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0); + if (handle == INVALID_HANDLE_VALUE) return 0; + if (!WriteFile( handle, data, strlen(data), &res, NULL )) trace( "write error\n" ); + CloseHandle( handle ); + return SetupOpenInfFileA( tmpfilename, 0, INF_STYLE_WIN4, err_line ); +} + static void test_SetupCreateDiskSpaceListA(void) { HDSKSPC ret; @@ -742,8 +756,185 @@ static void test_SetupQueryDrivesInDiskSpaceListA(void) ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, sizeof(buffer), NULL); ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n"); ok(!memcmp("f:\0g:\0x:\0\0", buffer, 10), "Device list does not match\n"); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); +} + +struct device_usage +{ + const char *dev; + LONGLONG usage; +}; + +struct section +{ + const char *name; + UINT fileop; + BOOL result; + DWORD error_code; +}; + +static const struct +{ + const char *data; + struct section sections[2]; + const char *devices; + int device_length; + struct device_usage usage[2]; } +section_test[] = +{ + /* 0 */ + {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {NULL, 0, TRUE, 0}}, + "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 1 */ + {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", FILEOP_DELETE, TRUE, 0}, {NULL, 0, TRUE, 0}}, + "c:\00", sizeof("c:\00"), {{"c:", 0}, {NULL, 0}}}, + /* 2 */ + {STD_HEADER "[a]\ntest,,,\n\r\n", + {{"a", FILEOP_COPY, FALSE, ERROR_LINE_NOT_FOUND}, {NULL, 0, TRUE, 0}}, + "", sizeof(""), {{NULL, 0}, {NULL, 0}}}, + /* 3 */ + {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\n[DestinationDirs]\nDefaultDestDir=-1,F:\test\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {NULL, 0, TRUE, 0}}, + "f:\00", sizeof("f:\00"), {{"f:", 4096}, {NULL, 0}}}, + /* 4 */ + {STD_HEADER "[a]\ntest,test2,,\n[SourceDisksFiles]\ntest2=1,,4096\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {NULL, 0, TRUE, 0}}, + "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 5 */ + {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"b", FILEOP_COPY, FALSE, ERROR_SECTION_NOT_FOUND}, {NULL, 0, TRUE, 0}}, + "", sizeof(""), {{NULL, 0}, {NULL, 0}}}, + /* 6 */ + {STD_HEADER "[a]\ntest,,,\n[b]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}}, + "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 7 */ + {STD_HEADER "[a]\ntest,,,\n[b]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\n[DestinationDirs]\nb=-1,F:\test\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}}, + "c:\00f:\00", sizeof("c:\00f:\00"), {{"c:", 4096}, {"f:", 4096}}}, + /* 8 */ + {STD_HEADER "[a]\ntest,test1,,\n[b]\ntest,test2,,\n[SourceDisksFiles]\ntest1=1,,4096\ntest2=1,,8192\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}}, + "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}}, + /* 9 */ + {STD_HEADER "[a]\ntest1,test,,\n[b]\ntest2,test,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}}, + "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}}, +}; + +static void test_SetupAddSectionToDiskSpaceListA(void) +{ + char tmp[MAX_PATH]; + char tmpfilename[MAX_PATH]; + char buffer[MAX_PATH]; + HDSKSPC diskspace; + UINT err_line; + LONGLONG space; + BOOL ret; + int i, j; + HINF inf;
+ if (!GetTempPathA(MAX_PATH, tmp)) + { + win_skip("GetTempPath failed with error %d\n", GetLastError()); + return; + } + + if (!GetTempFileNameA(tmp, "inftest", 0, tmpfilename)) + { + win_skip("GetTempFileNameA failed with error %d\n", GetLastError()); + return; + } + + inf = inf_open_file_content(tmpfilename, STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", &err_line); + ok(!!inf, "Failed to open inf file (%d, line %d)\n", GetLastError(), err_line); + + diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(diskspace != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n"); + + ret = SetupAddSectionToDiskSpaceListA(diskspace, NULL, NULL, "a", FILEOP_COPY, 0, 0); + ok(!ret, "Expected SetupAddSectionToDiskSpaceListA to fail\n"); + ok(GetLastError() == ERROR_SECTION_NOT_FOUND, "Expected ERROR_SECTION_NOT_FOUND as error, got %u\n", + GetLastError()); + + ret = SetupAddSectionToDiskSpaceListA(NULL, inf, NULL, "a", FILEOP_COPY, 0, 0); + ok(!ret, "Expected SetupAddSectionToDiskSpaceListA to fail\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE as error, got %u\n", + GetLastError()); + + ret = SetupAddSectionToDiskSpaceListA(NULL, inf, NULL, "b", FILEOP_COPY, 0, 0); + ok(!ret, "Expected SetupAddSectionToDiskSpaceListA to fail\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE as error, got %u\n", + GetLastError()); + + ret = SetupAddSectionToDiskSpaceListA(diskspace, inf, NULL, "a", 0, 0, 0); + ok(ret, "Expected SetupAddSectionToDiskSpaceListA to succeed (%u)\n", GetLastError()); + + ok(SetupDestroyDiskSpaceList(diskspace), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + for (i = 0; i < ARRAY_SIZE(section_test); i++) + { + err_line = 0; + + inf = inf_open_file_content(tmpfilename, section_test[i].data, &err_line); + ok(!!inf, "test %d: Failed to open inf file (%d, line %d)\n", i, GetLastError(), err_line); + if (!inf) continue; + + diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(diskspace != NULL, "Expected SetupCreateDiskSpaceListA to return a valid handle\n"); + + for (j = 0; j < 2; j++) + { + const struct section *section = §ion_test[i].sections[j]; + if (!section->name) + continue; + + SetLastError(0xdeadbeef); + ret = SetupAddSectionToDiskSpaceListA(diskspace, inf, NULL, section->name, section->fileop, 0, 0); + if (section->result) + ok(ret, "test %d: Expected adding section %d to succeed (%u)\n", i, j, GetLastError()); + else + { + ok(!ret, "test %d: Expected adding section %d to fail\n", i, j); + ok(GetLastError() == section->error_code, "test %d: Expected %u as error, got %u\n", + i, section->error_code, GetLastError()); + } + } + + memset(buffer, 0x0, sizeof(buffer)); + ret = SetupQueryDrivesInDiskSpaceListA(diskspace, buffer, sizeof(buffer), NULL); + ok(ret, "test %d: Expected SetupQueryDrivesInDiskSpaceListA to succeed (%u)\n", i, GetLastError()); + ok(!memcmp(section_test[i].devices, buffer, section_test[i].device_length), + "test %d: Device list (%s) does not match\n", i, buffer); + + for (j = 0; j < 2; j++) + { + const struct device_usage *usage = §ion_test[i].usage[j]; + if (!usage->dev) + continue; + + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(diskspace, usage->dev, &space, NULL, 0); + ok(ret, "test %d: Expected SetupQuerySpaceRequiredOnDriveA to succeed for device %s (%u)\n", + i, usage->dev, GetLastError()); + ok(space == usage->usage, "test %d: Expected size %u for device %s, got %u\n", + i, (DWORD)usage->usage, usage->dev, (DWORD)space); + } + + ok(SetupDestroyDiskSpaceList(diskspace), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + SetupCloseInfFile(inf); + } + + DeleteFileA(tmpfilename); +}
START_TEST(diskspace) { @@ -757,4 +948,5 @@ START_TEST(diskspace) test_SetupQuerySpaceRequiredOnDriveW(); test_SetupAddToDiskSpaceListA(); test_SetupQueryDrivesInDiskSpaceListA(); + test_SetupAddSectionToDiskSpaceListA(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58197
Your paranoid android.
=== debian10 (32 bit report) ===
setupapi: diskspace.c:753: Test failed: Device list does not match diskspace.c:758: Test failed: Device list does not match diskspace.c:876: Test failed: Expected SetupAddSectionToDiskSpaceListA to succeed (3758096642) diskspace.c:901: Test failed: test 0: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 0: Device list () does not match diskspace.c:926: Test failed: test 0: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 1: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 1: Device list () does not match diskspace.c:901: Test failed: test 3: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 3: Device list () does not match diskspace.c:926: Test failed: test 3: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 4: Device list () does not match diskspace.c:901: Test failed: test 6: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 6: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 6: Device list () does not match diskspace.c:926: Test failed: test 6: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 7: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 7: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 7: Device list () does not match diskspace.c:926: Test failed: test 7: Expected size 4096 for device c:, got 0 diskspace.c:926: Test failed: test 7: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 8: Device list () does not match diskspace.c:913: Test failed: test 9: Device list () does not match
=== debian10 (32 bit French report) ===
setupapi: diskspace.c:753: Test failed: Device list does not match diskspace.c:758: Test failed: Device list does not match diskspace.c:876: Test failed: Expected SetupAddSectionToDiskSpaceListA to succeed (3758096642) diskspace.c:901: Test failed: test 0: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 0: Device list () does not match diskspace.c:926: Test failed: test 0: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 1: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 1: Device list () does not match diskspace.c:901: Test failed: test 3: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 3: Device list () does not match diskspace.c:926: Test failed: test 3: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 4: Device list () does not match diskspace.c:901: Test failed: test 6: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 6: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 6: Device list () does not match diskspace.c:926: Test failed: test 6: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 7: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 7: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 7: Device list () does not match diskspace.c:926: Test failed: test 7: Expected size 4096 for device c:, got 0 diskspace.c:926: Test failed: test 7: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 8: Device list () does not match diskspace.c:913: Test failed: test 9: Device list () does not match
=== debian10 (32 bit Japanese:Japan report) ===
setupapi: diskspace.c:753: Test failed: Device list does not match diskspace.c:758: Test failed: Device list does not match diskspace.c:876: Test failed: Expected SetupAddSectionToDiskSpaceListA to succeed (3758096642) diskspace.c:901: Test failed: test 0: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 0: Device list () does not match diskspace.c:926: Test failed: test 0: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 1: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 1: Device list () does not match diskspace.c:901: Test failed: test 3: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 3: Device list () does not match diskspace.c:926: Test failed: test 3: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 4: Device list () does not match diskspace.c:901: Test failed: test 6: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 6: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 6: Device list () does not match diskspace.c:926: Test failed: test 6: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 7: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 7: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 7: Device list () does not match diskspace.c:926: Test failed: test 7: Expected size 4096 for device c:, got 0 diskspace.c:926: Test failed: test 7: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 8: Device list () does not match diskspace.c:913: Test failed: test 9: Device list () does not match
=== debian10 (32 bit Chinese:China report) ===
setupapi: diskspace.c:753: Test failed: Device list does not match diskspace.c:758: Test failed: Device list does not match diskspace.c:876: Test failed: Expected SetupAddSectionToDiskSpaceListA to succeed (3758096642) diskspace.c:901: Test failed: test 0: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 0: Device list () does not match diskspace.c:926: Test failed: test 0: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 1: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 1: Device list () does not match diskspace.c:901: Test failed: test 3: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 3: Device list () does not match diskspace.c:926: Test failed: test 3: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 4: Device list () does not match diskspace.c:901: Test failed: test 6: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 6: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 6: Device list () does not match diskspace.c:926: Test failed: test 6: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 7: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 7: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 7: Device list () does not match diskspace.c:926: Test failed: test 7: Expected size 4096 for device c:, got 0 diskspace.c:926: Test failed: test 7: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 8: Device list () does not match diskspace.c:913: Test failed: test 9: Device list () does not match
=== debian10 (32 bit WoW report) ===
setupapi: diskspace.c:753: Test failed: Device list does not match diskspace.c:758: Test failed: Device list does not match diskspace.c:876: Test failed: Expected SetupAddSectionToDiskSpaceListA to succeed (3758096642) diskspace.c:901: Test failed: test 0: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 0: Device list () does not match diskspace.c:926: Test failed: test 0: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 1: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 1: Device list () does not match diskspace.c:901: Test failed: test 3: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 3: Device list () does not match diskspace.c:926: Test failed: test 3: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 4: Device list () does not match diskspace.c:901: Test failed: test 6: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 6: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 6: Device list () does not match diskspace.c:926: Test failed: test 6: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 7: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 7: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 7: Device list () does not match diskspace.c:926: Test failed: test 7: Expected size 4096 for device c:, got 0 diskspace.c:926: Test failed: test 7: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 8: Device list () does not match diskspace.c:913: Test failed: test 9: Device list () does not match
=== debian10 (64 bit WoW report) ===
setupapi: diskspace.c:753: Test failed: Device list does not match diskspace.c:758: Test failed: Device list does not match diskspace.c:876: Test failed: Expected SetupAddSectionToDiskSpaceListA to succeed (3758096642) diskspace.c:901: Test failed: test 0: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 0: Device list () does not match diskspace.c:926: Test failed: test 0: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 1: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 1: Device list () does not match diskspace.c:901: Test failed: test 3: Expected adding section 0 to succeed (3758096642) diskspace.c:913: Test failed: test 3: Device list () does not match diskspace.c:926: Test failed: test 3: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 4: Device list () does not match diskspace.c:901: Test failed: test 6: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 6: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 6: Device list () does not match diskspace.c:926: Test failed: test 6: Expected size 4096 for device c:, got 0 diskspace.c:901: Test failed: test 7: Expected adding section 0 to succeed (3758096642) diskspace.c:901: Test failed: test 7: Expected adding section 1 to succeed (3758096642) diskspace.c:913: Test failed: test 7: Device list () does not match diskspace.c:926: Test failed: test 7: Expected size 4096 for device c:, got 0 diskspace.c:926: Test failed: test 7: Expected size 4096 for device f:, got 0 diskspace.c:913: Test failed: test 8: Device list () does not match diskspace.c:913: Test failed: test 9: Device list () does not match
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 75 +++++++++++++- dlls/setupapi/setupapi.spec | 2 +- dlls/setupapi/tests/diskspace.c | 170 ++++++++++++++++++++++++++++++++ include/setupapi.h | 3 + 4 files changed, 244 insertions(+), 6 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 2e2714df5c3f..03bdf357c489 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -181,16 +181,81 @@ HDSKSPC WINAPI SetupDuplicateDiskSpaceListA(HDSKSPC DiskSpace, PVOID Reserved1, }
/*********************************************************************** - * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@) + * SetupAddInstallSectionToDiskSpaceListW (SETUPAPI.@) */ -BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, - HINF InfHandle, HINF LayoutInfHandle, - LPCSTR SectionName, PVOID Reserved1, UINT Reserved2) +BOOL WINAPI SetupAddInstallSectionToDiskSpaceListW(HDSKSPC diskSpace, + HINF inf, HINF layoutinf, LPCWSTR section, + PVOID reserved1, UINT reserved2) { - FIXME ("Stub\n"); + static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0}; + static const WCHAR DelFiles[] = {'D','e','l','F','i','l','e','s',0}; + WCHAR section_name[MAX_PATH]; + INFCONTEXT context; + BOOL ret; + int i; + + TRACE("(%p, %p, %p, %s, %p, %u)\n", diskspace, inf, layoutinf, debugstr_w(section), + reserved1, reserved2); + + if (!diskspace) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (!section) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (!inf) return TRUE; + if (!layoutinf) layoutinf = inf; + + ret = SetupFindFirstLineW(inf, section, CopyFiles, &context); + while (ret) + { + for (i = 1;; i++) + { + if (!SetupGetStringFieldW(&context, i, section_name, ARRAY_SIZE( section_name ), NULL)) + break; + SetupAddSectionToDiskSpaceListW(diskspace, layoutinf, inf, section_name, FILEOP_COPY, 0, 0); + } + ret = SetupFindNextLine(&context, &context); + } + + ret = SetupFindFirstLineW(inf, section, DelFiles, &context); + while (ret) + { + for (i = 1;; i++) + { + if (!SetupGetStringFieldW(&context, i, section_name, ARRAY_SIZE( section_name ), NULL)) + break; + SetupAddSectionToDiskSpaceListW(diskspace, layoutinf, inf, section_name, FILEOP_DELETE, 0, 0); + } + ret = SetupFindNextLine(&context, &context); + } + return TRUE; }
+/*********************************************************************** + * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@) + */ +BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC diskSpace, + HINF inf, HINF layoutinf, LPCSTR section, + PVOID reserved1, UINT reserved2) +{ + LPWSTR sectionW = NULL; + BOOL ret; + + sectionW = strdupAtoW(section); + ret = SetupAddInstallSectionToDiskSpaceListW(diskspace, inf, layoutinf, + sectionW, reserved1, reserved2); + heap_free(sectionW); + return ret; +} + /*********************************************************************** * SetupAddSectionToDiskSpaceListW (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index ad8652ac93b3..1d09b0e7e577 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -243,7 +243,7 @@ @ stub SearchForInfFile @ stub SetArrayToMultiSzValue @ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long) -@ stub SetupAddInstallSectionToDiskSpaceListW +@ stdcall SetupAddInstallSectionToDiskSpaceListW(long long long wstr ptr long) @ stdcall SetupAddSectionToDiskSpaceListA(long long long str long ptr long) @ stdcall SetupAddSectionToDiskSpaceListW(long long long wstr long ptr long) @ stdcall SetupAddToDiskSpaceListA(long str int64 long ptr long) diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index ff7d6236092e..1b56b1bae709 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -936,6 +936,175 @@ static void test_SetupAddSectionToDiskSpaceListA(void) DeleteFileA(tmpfilename); }
+struct section_i +{ + const char *name; + BOOL result; + DWORD error_code; +}; + +static const struct +{ + const char *data; + struct section_i sections[2]; + const char *devices; + int device_length; + struct device_usage usage[2]; +} +section_test_i[] = +{ + /* 0 */ + {STD_HEADER "[a.Install]\nCopyFiles=a.CopyFiles\n" + "[a.CopyFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a.Install", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 1 */ + {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\n" + "[a.CopyFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 2 */ + {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\nCopyFiles=a.CopyFiles2\n" + "[a.CopyFiles]\ntest,,,\n[a.CopyFiles2]\ntest2,,,\n" + "[SourceDisksFiles]\ntest=1,,4096\ntest2=1,,4096\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}}, + /* 3 */ + {STD_HEADER "[a]\nCopyFiles=a.CopyFiles,a.CopyFiles2\n" + "[a.CopyFiles]\ntest,,,\n[a.CopyFiles2]\ntest2,,,\n" + "[SourceDisksFiles]\ntest=1,,4096\ntest2=1,,4096\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}}, + /* 4 */ + {STD_HEADER "[a]\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}}, + /* 5 */ + {STD_HEADER "[a]\nDelFiles=a.DelFiles\n" + "[a.nDelFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}}, + /* 6 */ + {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\nDelFiles=a.DelFiles\n" + "[a.CopyFiles]\ntest,,,\n[a.DelFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 7 */ + {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\n[b]\nDelFiles=b.DelFiles\n" + "[a.CopyFiles]\ntest,,,\n[b.DelFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", + {{"a", TRUE, 0}, {"b", TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}}, + /* 7 */ + {STD_HEADER "[a]\nCopyFiles=\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}}, + /* 8 */ + {STD_HEADER "[a]\nCopyFiles=something\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}}, + /* 9 */ + {STD_HEADER "[a]\nCopyFiles=a.CopyFiles,b.CopyFiles\n[a.CopyFiles]\ntest,,,\n[b.CopyFiles]\ntest,,,\n" + "[SourceDisksFiles]\ntest=1,,4096\n[DestinationDirs]\nb.CopyFiles=-1,F:\test\r\n", + {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00f:\00", sizeof("c:\00f:\00"), {{"c:", 4096}, {"f:", 4096}}}, +}; + +static void test_SetupAddInstallSectionToDiskSpaceListA(void) +{ + char tmp[MAX_PATH]; + char tmpfilename[MAX_PATH]; + char buffer[MAX_PATH]; + HDSKSPC diskspace; + LONGLONG space; + UINT err_line; + BOOL ret; + int i, j; + HINF inf; + + if (!GetTempPathA(MAX_PATH, tmp)) + { + win_skip("GetTempPath failed with error %d\n", GetLastError()); + return; + } + + if (!GetTempFileNameA(tmp, "inftest", 0, tmpfilename)) + { + win_skip("GetTempFileNameA failed with error %d\n", GetLastError()); + return; + } + + inf = inf_open_file_content(tmpfilename, STD_HEADER "[a]\nCopyFiles=b\n[b]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", &err_line); + ok(!!inf, "Failed to open inf file (%d, line %d)\n", GetLastError(), err_line); + + diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(diskspace != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n"); + + ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, NULL, NULL, "a", 0, 0); + ok(ret, "Expected SetupAddInstallSectionToDiskSpaceListA to succeed\n"); + + ret = SetupAddInstallSectionToDiskSpaceListA(NULL, inf, NULL, "a", 0, 0); + ok(!ret, "Expected SetupAddInstallSectionToDiskSpaceListA to fail\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE as error, got %u\n", + GetLastError()); + + ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, inf, NULL, NULL, 0, 0); + ok(!ret || broken(ret), "Expected SetupAddSectionToDiskSpaceListA to fail\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(ret), + "Expected ERROR_INVALID_PARAMETER as error, got %u\n", GetLastError()); + + ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, inf, NULL, "", 0, 0); + ok(ret, "Expected SetupAddInstallSectionToDiskSpaceListA to succeed (%u)\n", GetLastError()); + + ok(SetupDestroyDiskSpaceList(diskspace), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + for (i = 0; i < ARRAY_SIZE(section_test_i); i++) + { + err_line = 0; + + inf = inf_open_file_content(tmpfilename, section_test_i[i].data, &err_line); + ok(!!inf, "test %d: Failed to open inf file (%d, line %d)\n", i, GetLastError(), err_line); + if (!inf) continue; + + diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(diskspace != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n"); + + for (j = 0; j < 2; j++) + { + const struct section_i *section = §ion_test_i[i].sections[j]; + if (!section->name) + continue; + + SetLastError(0xdeadbeef); + ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, inf, NULL, section->name, 0, 0); + if (section->result) + ok(ret, "test %d: Expected adding section %d to succeed (%u)\n", i, j, GetLastError()); + else + { + ok(!ret, "test %d: Expected adding section %d to fail\n", i, j); + ok(GetLastError() == section->error_code, "test %d: Expected %u as error, got %u\n", + i, section->error_code, GetLastError()); + } + } + + memset(buffer, 0x0, sizeof(buffer)); + ret = SetupQueryDrivesInDiskSpaceListA(diskspace, buffer, sizeof(buffer), NULL); + ok(ret, "test %d: Expected SetupQueryDrivesInDiskSpaceListA to succeed (%u)\n", i, GetLastError()); + ok(!memcmp(section_test_i[i].devices, buffer, section_test_i[i].device_length), + "test %d: Device list (%s) does not match\n", i, buffer); + + for (j = 0; j < 2; j++) + { + const struct device_usage *usage = §ion_test_i[i].usage[j]; + if (!usage->dev) + continue; + + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(diskspace, usage->dev, &space, NULL, 0); + ok(ret, "test %d: Expected SetupQuerySpaceRequiredOnDriveA to succeed for device %s (%u)\n", + i, usage->dev, GetLastError()); + ok(space == usage->usage, "test %d: Expected size %u for device %s, got %u\n", + i, (DWORD)usage->usage, usage->dev, (DWORD)space); + } + + ok(SetupDestroyDiskSpaceList(diskspace), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + SetupCloseInfFile(inf); + } + + DeleteFileA(tmpfilename); +} + START_TEST(diskspace) { is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) && @@ -949,4 +1118,5 @@ START_TEST(diskspace) test_SetupAddToDiskSpaceListA(); test_SetupQueryDrivesInDiskSpaceListA(); test_SetupAddSectionToDiskSpaceListA(); + test_SetupAddInstallSectionToDiskSpaceListA(); } diff --git a/include/setupapi.h b/include/setupapi.h index 818cc12599a4..e54c6c227f67 100644 --- a/include/setupapi.h +++ b/include/setupapi.h @@ -1416,6 +1416,9 @@ DWORD WINAPI OpenAndMapForRead(PCWSTR, PDWORD, PHANDLE, PHANDLE, PVOID *); LONG WINAPI QueryRegistryValue(HKEY, PCWSTR, PBYTE *, PDWORD, PDWORD); /* RetreiveFileSecurity is not a typo, as per Microsoft's dlls */ DWORD WINAPI RetreiveFileSecurity(PCWSTR, PSECURITY_DESCRIPTOR *); +BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, PVOID, UINT); +BOOL WINAPI SetupAddInstallSectionToDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, PVOID, UINT); +#define SetupAddInstallSectionToDiskSpaceList WINELIB_NAME_AW(SetupAddInstallSectionToDiskSpaceList) BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, UINT, PVOID, UINT); BOOL WINAPI SetupAddSectionToDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, UINT, PVOID, UINT); #define SetupAddSectionToDiskSpaceList WINELIB_NAME_AW(SetupAddSectionToDiskSpaceList)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58198
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/setupapi/diskspace.c:197:41: error: ‘diskspace’ undeclared (first use in this function); did you mean ‘diskSpace’? ../../../wine/dlls/setupapi/diskspace.c:253:50: error: ‘diskspace’ undeclared (first use in this function); did you mean ‘diskSpace’? Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/setupapi/diskspace.c:197:41: error: ‘diskspace’ undeclared (first use in this function); did you mean ‘diskSpace’? ../../../wine/dlls/setupapi/diskspace.c:253:50: error: ‘diskspace’ undeclared (first use in this function); did you mean ‘diskSpace’? Task: The wow64 build failed