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..60a31e17a434 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=58089
Your paranoid android.
=== build (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:702:1: error: expected ‘;’ before ‘}’ token Makefile:252: recipe for target 'diskspace.o' failed Makefile:7763: recipe for target 'dlls/setupapi/tests' failed Task: The exe32 Wine crossbuild failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:701:44: error: expected ‘;’ before ‘}’ token Task: The win32 build failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:701:44: error: expected ‘;’ before ‘}’ token Task: The wow64 build failed
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 60a31e17a434..9d9f65c80495 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=58090
Your paranoid android.
=== build (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:760:1: error: expected ‘;’ before ‘}’ token Makefile:252: recipe for target 'diskspace.o' failed Makefile:7763: recipe for target 'dlls/setupapi/tests' failed Task: The exe32 Wine crossbuild failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:759:44: error: expected ‘;’ before ‘}’ token Task: The win32 build failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:759:44: error: expected ‘;’ before ‘}’ token Task: The wow64 build failed
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[] = {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0}; + 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 9d9f65c80495..0f4e40a15f27 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=58091
Your paranoid android.
=== build (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:951:5: error: expected ‘;’ before ‘test_SetupAddSectionToDiskSpaceListA’ Makefile:252: recipe for target 'diskspace.o' failed Makefile:7763: recipe for target 'dlls/setupapi/tests' failed Task: The exe32 Wine crossbuild failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:950:44: error: expected ‘;’ before ‘test_SetupAddSectionToDiskSpaceListA’ Task: The win32 build failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:950:44: error: expected ‘;’ before ‘test_SetupAddSectionToDiskSpaceListA’ Task: The wow64 build failed
On 10/20/19 11:00 PM, Vijay Kiran Kamuju wrote:
+static BOOL get_size_from_inf(HINF layoutinf, WCHAR *filename, LONGLONG *size) +{
- static const WCHAR SourceDisksFiles[] = {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
Should you have to resend for an other reason then please use wide char string literals in setupapi.
bye michael
On Sun, Oct 20, 2019 at 11:38 PM Michael Stefaniuc mstefani@winehq.org wrote:
On 10/20/19 11:00 PM, Vijay Kiran Kamuju wrote:
+static BOOL get_size_from_inf(HINF layoutinf, WCHAR *filename, LONGLONG *size) +{
- static const WCHAR SourceDisksFiles[] = {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
Should you have to resend for an other reason then please use wide char string literals in setupapi.
The string is same as in queue.c lines 292-293. And in most of the places, its in similar fashion. Did anything change in between on how to represent wide char string literals.
bye michael
On 10/21/19 12:05 AM, Vijay Kiran Kamuju wrote:
On Sun, Oct 20, 2019 at 11:38 PM Michael Stefaniuc mstefani@winehq.org wrote:
On 10/20/19 11:00 PM, Vijay Kiran Kamuju wrote:
+static BOOL get_size_from_inf(HINF layoutinf, WCHAR *filename, LONGLONG *size) +{
- static const WCHAR SourceDisksFiles[] = {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
Should you have to resend for an other reason then please use wide char string literals in setupapi.
The string is same as in queue.c lines 292-293. And in most of the places, its in similar fashion. Did anything change in between on how to represent wide char string literals.
Yeah, the move to building the DLLs as PE makes it possible to use wide char string literals. Those are the modules with "EXTRADLLFLAGS = -mno-cygwin" in Makefile.in.
L"SourceDisksFiles", also without a variable to hold it, is so much nicer to use.
But like I said, don't worry about it if you don't have to resend.
bye michael
On Mon, Oct 21, 2019 at 9:51 PM Michael Stefaniuc mstefani@winehq.org wrote:
On 10/21/19 12:05 AM, Vijay Kiran Kamuju wrote:
On Sun, Oct 20, 2019 at 11:38 PM Michael Stefaniuc mstefani@winehq.org wrote:
On 10/20/19 11:00 PM, Vijay Kiran Kamuju wrote:
+static BOOL get_size_from_inf(HINF layoutinf, WCHAR *filename, LONGLONG *size) +{
- static const WCHAR SourceDisksFiles[] = {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
Should you have to resend for an other reason then please use wide char string literals in setupapi.
The string is same as in queue.c lines 292-293. And in most of the places, its in similar fashion. Did anything change in between on how to represent wide char string literals.
Yeah, the move to building the DLLs as PE makes it possible to use wide char string literals. Those are the modules with "EXTRADLLFLAGS = -mno-cygwin" in Makefile.in.
L"SourceDisksFiles", also without a variable to hold it, is so much nicer to use.
But like I said, don't worry about it if you don't have to resend.
I will have to resend, thanks for explaining the reason. If the earlier patches get in, I will send the fixed one later. Otherwise will resend the patch series tomorrow, I have already made the changes.
Thanks, Vijay
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..96c63277c4b0 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 0f4e40a15f27..8b400b4a59e2 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=58092
Your paranoid android.
=== build (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:1120:5: error: expected ‘;’ before ‘test_SetupAddSectionToDiskSpaceListA’ Makefile:252: recipe for target 'diskspace.o' failed Makefile:7763: recipe for target 'dlls/setupapi/tests' failed Task: The exe32 Wine crossbuild failed
=== debian10 (build log) ===
../../../../wine/dlls/setupapi/tests/diskspace.c:1119:44: error: expected ‘;’ before ‘test_SetupAddSectionToDiskSpaceListA’ ../../../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/tests/diskspace.c:1119:44: error: expected ‘;’ before ‘test_SetupAddSectionToDiskSpaceListA’ ../../../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