From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 183 +++++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index f5e79d5327c9..4f047dd2b544 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -1,6 +1,7 @@ /* * SetupAPI DiskSpace functions * + * Copyright 2016 Michael Müller * Copyright 2004 CodeWeavers (Aric Stewart) * * This library is free software; you can redistribute it and/or @@ -27,69 +28,50 @@ #include "winnls.h" #include "winreg.h" #include "setupapi.h" +#include "wine/list.h" #include "wine/debug.h" +#include "setupapi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-typedef struct { - WCHAR lpzName[20]; - LONGLONG dwFreeSpace; - LONGLONG dwWantedSpace; -} DRIVE_ENTRY, *LPDRIVE_ENTRY; +struct file_entry +{ + struct list entry; + WCHAR *path; + UINT operation; + LONGLONG size; +}; + +struct space_list +{ + struct list files; + UINT flags; +};
-typedef struct { - DWORD dwDriveCount; - DRIVE_ENTRY Drives[26]; -} DISKSPACELIST, *LPDISKSPACELIST;
/*********************************************************************** * SetupCreateDiskSpaceListW (SETUPAPI.@) */ -HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID reserved1, DWORD reserved2, UINT flags) { - WCHAR drives[255]; - DWORD rc; - WCHAR *ptr; - LPDISKSPACELIST list=NULL; + struct space_list *list;
- TRACE("(%p, %u, 0x%08x)\n", Reserved1, Reserved2, Flags); + TRACE("(%p, %u, 0x%08x)\n", reserved1, reserved2, flags);
- if (Reserved1 || Reserved2 || Flags & ~SPDSL_IGNORE_DISK) + if (reserved1 || reserved2 || flags & ~SPDSL_IGNORE_DISK) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; }
- rc = GetLogicalDriveStringsW(255,drives); - - if (rc == 0) - return NULL; - - list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST)); - - list->dwDriveCount = 0; - - ptr = drives; - - while (*ptr) + list = HeapAlloc(GetProcessHeap(), 0, sizeof(*list)); + if (list) { - DWORD type = GetDriveTypeW(ptr); - if (type == DRIVE_FIXED) - { - DWORD clusters; - DWORD sectors; - DWORD bytes; - DWORD total; - lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr); - GetDiskFreeSpaceW(ptr,§ors,&bytes,&clusters,&total); - list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors * - bytes; - list->Drives[list->dwDriveCount].dwWantedSpace = 0; - list->dwDriveCount++; - } - ptr += lstrlenW(ptr) + 1; + list->flags = flags; + list_init(&list->files); } + return list; }
@@ -105,32 +87,58 @@ HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT /*********************************************************************** * SetupDuplicateDiskSpaceListW (SETUPAPI.@) */ -HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC diskspace, PVOID reserved1, DWORD reserved2, UINT flags) { - DISKSPACELIST *list_copy, *list_original = DiskSpace; + struct space_list *list_copy, *list = diskspace; + struct file_entry *file, *file_copy; + + TRACE("(%p, %p, %u, %u)\n", diskspace, reserved1, reserved2, flags);
- if (Reserved1 || Reserved2 || Flags) + if (reserved1 || reserved2 || flags) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; }
- if (!DiskSpace) + if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return NULL; }
- list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST)); + list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*list_copy)); if (!list_copy) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
- *list_copy = *list_original; + list_copy->flags = list->flags; + list_init(&list_copy->files); + + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + file_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*file_copy)); + if (!file_copy) goto error; + + file_copy->path = strdupW(file->path); + if (!file_copy->path) + { + HeapFree(GetProcessHeap(), 0, file_copy); + goto error; + } + + file_copy->operation = file->operation; + file_copy->size = file->size; + list_add_head(&list_copy->files, &file->entry); + }
return list_copy; + +error: + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetupDestroyDiskSpaceList(list_copy); + return NULL; }
/*********************************************************************** @@ -155,55 +163,51 @@ BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, /*********************************************************************** * SetupQuerySpaceRequiredOnDriveW (SETUPAPI.@) */ -BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace, - LPCWSTR DriveSpec, LONGLONG *SpaceRequired, - PVOID Reserved1, UINT Reserved2) +BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC diskspace, + LPCWSTR drivespec, LONGLONG *required, + PVOID reserved1, UINT reserved2) { - WCHAR *driveW; - unsigned int i; - LPDISKSPACELIST list = DiskSpace; - BOOL rc = FALSE; - static const WCHAR bkslsh[]= {'\',0}; + struct space_list *list = diskspace; + struct file_entry *file; + LONGLONG sum = 0;
- if (!DiskSpace) + TRACE("(%p, %s, %p, %p, %u)\n", diskspace, debugstr_w(drivespec), required, reserved1, reserved2); + + if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; }
- if (!DriveSpec) + if (!drivespec || !drivespec[0]) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(drivespec ? ERROR_INVALID_DRIVE : ERROR_INVALID_DRIVE); return FALSE; }
- driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR)); - if (!driveW) + if (!required) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
- lstrcpyW(driveW,DriveSpec); - lstrcatW(driveW,bkslsh); - - TRACE("Looking for drive %s\n",debugstr_w(driveW)); - - for (i = 0; i < list->dwDriveCount; i++) + if (towlower(drivespec[0]) < 'a' || towlower(drivespec[0]) > 'z' || + drivespec[1] != ':' || drivespec[2] != 0) { - 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; - } + FIXME("UNC paths not yet supported (%s)\n", debugstr_w(drivespec)); + SetLastError((GetVersion() & 0x80000000) ? ERROR_INVALID_DRIVE : ERROR_INVALID_PARAMETER); + return FALSE; }
- HeapFree(GetProcessHeap(), 0, driveW); + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + if (towlower(file->path[0]) == towlower(drivespec[0]) && + file->path[1] == ':' && file->path[2] == '\') + sum += file->size; + }
- if (!rc) SetLastError(ERROR_INVALID_DRIVE); - return rc; + *required = sum; + return TRUE; }
/*********************************************************************** @@ -253,10 +257,25 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, /*********************************************************************** * SetupDestroyDiskSpaceList (SETUPAPI.@) */ -BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace) +BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) { - LPDISKSPACELIST list = DiskSpace; - HeapFree(GetProcessHeap(),0,list); + struct space_list *list = diskspace; + struct file_entry *file, *file2; + + if (!diskspace) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry) + { + HeapFree(GetProcessHeap(), 0, file->path); + list_remove(&file->entry); + HeapFree(GetProcessHeap(), 0, file); + } + + HeapFree(GetProcessHeap(), 0, list); return TRUE; }
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 137 +++++++++++++++++++++++++-- dlls/setupapi/tests/diskspace.c | 159 +++++++++++++++++++++++++++++++- 2 files changed, 285 insertions(+), 11 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 4f047dd2b544..dcee29443d71 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -48,7 +48,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.@) @@ -280,25 +294,128 @@ BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) }
/*********************************************************************** -* SetupAddToDiskSpaceListA (SETUPAPI.@) +* SetupAddToDiskSpaceListW (SETUPAPI.@) */ -BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, +BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile, LONGLONG filesize, UINT operation, PVOID reserved1, UINT reserved2) { - FIXME(": stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + struct space_list *list = diskspace; + struct file_entry *file; + WCHAR *fullpathW; + BOOL ret = FALSE; + DWORD size; + + TRACE("(%p, %s, %s, %u, %p, %u)\n", diskspace, debugstr_w(targetfile), + wine_dbgstr_longlong(filesize), operation, reserved1, reserved2); + + if (!targetfile) + return TRUE; + + if (!diskspace) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (operation != FILEOP_COPY && operation != FILEOP_DELETE) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + size = GetFullPathNameW(targetfile, 0, NULL, NULL); + if (!size) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + size = (size+1) * sizeof(WCHAR); + fullpathW = HeapAlloc(GetProcessHeap(), 0, size); + + if (!GetFullPathNameW(targetfile, size, fullpathW, NULL)) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto done; + } + + if (fullpathW[1] != ':' && fullpathW[2] != '\') + { + FIXME("UNC paths not yet supported\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + goto done; + } + + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + if (!lstrcmpiW(file->path, fullpathW)) + break; + } + + if (&file->entry == &list->files) + { + file = HeapAlloc(GetProcessHeap(), 0, sizeof(*file)); + if (!file) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + + file->path = strdupW(fullpathW); + if (!file->path) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + HeapFree(GetProcessHeap(), 0, file); + goto done; + } + + list_add_tail(&list->files, &file->entry); + } + + file->operation = operation; + if (operation == FILEOP_COPY) + file->size = filesize; + else + file->size = 0; + + if (!(list->flags & SPDSL_IGNORE_DISK)) + file->size -= get_file_size(fullpathW); + + ret = TRUE; + +done: + HeapFree(GetProcessHeap(), 0, fullpathW); + return ret; }
/*********************************************************************** -* SetupAddToDiskSpaceListW (SETUPAPI.@) +* SetupAddToDiskSpaceListA (SETUPAPI.@) */ -BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile, +BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, LONGLONG filesize, UINT operation, PVOID reserved1, UINT reserved2) { - FIXME(": stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + LPWSTR targetfileW = NULL; + DWORD len; + BOOL ret; + + if (targetfile) + { + len = MultiByteToWideChar(CP_ACP, 0, targetfile, -1, NULL, 0); + + targetfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!targetfileW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + MultiByteToWideChar(CP_ACP, 0, targetfile, -1, targetfileW, len); + } + + ret = SetupAddToDiskSpaceListW(diskspace, targetfileW, filesize, + operation, reserved1, reserved2); + if (targetfileW) HeapFree(GetProcessHeap(), 0, targetfileW); + return ret; } diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 4e87ea905e07..bb8c7b78463b 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -19,6 +19,7 @@ */
#include <stdarg.h> +#include <stdio.h>
#include "windef.h" #include "winbase.h" @@ -31,6 +32,16 @@
static BOOL is_win9x;
+static inline const char* debugstr_longlong(ULONGLONG ll) +{ + static char string[17]; + if (sizeof(ll) > sizeof(unsigned long) && ll >> 32) + sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll); + else + sprintf(string, "%lx", (unsigned long)ll); + return string; +} + static void test_SetupCreateDiskSpaceListA(void) { HDSKSPC ret; @@ -300,11 +311,31 @@ static void test_SetupDuplicateDiskSpaceListW(void) ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static LONGLONG get_file_size(char *path) +{ + HANDLE file; + LARGE_INTEGER size; + + file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) return 0; + + if (!GetFileSizeEx(file, &size)) + size.QuadPart = 0; + + CloseHandle(file); + return size.QuadPart; +} + static void test_SetupQuerySpaceRequiredOnDriveA(void) { BOOL ret; HDSKSPC handle; LONGLONG space; + char windir[MAX_PATH]; + char drive[3]; + char tmp[MAX_PATH]; + LONGLONG size;
if (is_win9x) win_skip("SetupQuerySpaceRequiredOnDriveA crashes with NULL disk space handle on Win9x\n"); @@ -369,7 +400,7 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) ret = SetupQuerySpaceRequiredOnDriveA(handle, "", NULL, NULL, 0); ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); ok(GetLastError() == ERROR_INVALID_DRIVE, - "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + "Expected GetLastError() to return ERROR_INVALID_DRIVE, got %u\n", GetLastError());
SetLastError(0xdeadbeef); @@ -381,6 +412,97 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+ GetWindowsDirectoryA(windir, MAX_PATH); + drive[0] = windir[0]; drive[1] = windir[1]; drive[2] = 0; + + snprintf(tmp, MAX_PATH, "%c:\wine-test-should-not-exist.txt", drive[0]); + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x100000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x100000, "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space)); + + /* adding the same file again doesn't sum up the size */ + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x200000, "Expected 0x200000 as required space, got %s\n", debugstr_longlong(space)); + + /* the device doesn't need to exist */ + snprintf(tmp, MAX_PATH, "F:\wine-test-should-not-exist.txt"); + ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupQuerySpaceRequiredOnDriveA(handle, "F:", &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x200000, "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + /* the real size is subtracted unless SPDSL_IGNORE_DISK is specified */ + snprintf(tmp, MAX_PATH, "%s\regedit.exe", windir); + + size = get_file_size(tmp); + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0 || broken(space == -0x5000) || broken(space == -0x7000), + "Expected 0x0 as required space, got %s\n", debugstr_longlong(space)); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size + 0x100000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0x100000 || broken(space == 0xf9000) || broken(space == 0xfb000), + "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space)); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size - 0x1000, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == -0x1000 || broken(space == -0x6000) || broken(space == -0x8000), + "Expected -0x1000 as required space, got %s\n", debugstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space <= -size, "Expected space <= -size, got %s\n", debugstr_longlong(space)); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); + + handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK); + ok(handle != NULL, + "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n"); + + ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + space = 0; + ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0); + ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); + ok(space == 0, "Expected size = 0, got %s\n", debugstr_longlong(space)); + ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); } @@ -472,6 +594,40 @@ static void test_SetupQuerySpaceRequiredOnDriveW(void) "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static void test_SetupAddToDiskSpaceListA(void) +{ + HDSKSPC handle; + BOOL ret; + + ret = SetupAddToDiskSpaceListA(NULL, "C:\some-file.dat", 0, FILEOP_COPY, 0, 0); + ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", GetLastError()); + + handle = SetupCreateDiskSpaceListA(NULL, 0, 0); + ok(handle != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n"); + + ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_COPY, 0, 0); + ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "C:\some-file.dat", -20, FILEOP_COPY, 0, 0); + ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(handle, "C:\some-file.dat", 0, FILEOP_RENAME, 0, 0); + ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); + + ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_RENAME, 0, 0); + ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ret = SetupAddToDiskSpaceListA(NULL, NULL, 0, FILEOP_RENAME, 0, 0); + ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n"); + + ok(SetupDestroyDiskSpaceList(handle), + "Expected SetupDestroyDiskSpaceList to succeed\n"); +} + START_TEST(diskspace) { is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) && @@ -482,4 +638,5 @@ START_TEST(diskspace) test_SetupDuplicateDiskSpaceListW(); test_SetupQuerySpaceRequiredOnDriveA(); test_SetupQuerySpaceRequiredOnDriveW(); + test_SetupAddToDiskSpaceListA(); }
On 10/19/19 9:55 PM, Vijay Kiran Kamuju wrote:
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com
dlls/setupapi/diskspace.c | 137 +++++++++++++++++++++++++-- dlls/setupapi/tests/diskspace.c | 159 +++++++++++++++++++++++++++++++- 2 files changed, 285 insertions(+), 11 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 4f047dd2b544..dcee29443d71 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -48,7 +48,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.@)
@@ -280,25 +294,128 @@ BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) }
/*********************************************************************** -* SetupAddToDiskSpaceListA (SETUPAPI.@) +* SetupAddToDiskSpaceListW (SETUPAPI.@) */ -BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, +BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile, LONGLONG filesize, UINT operation, PVOID reserved1, UINT reserved2) {
- FIXME(": stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- struct space_list *list = diskspace;
- struct file_entry *file;
- WCHAR *fullpathW;
- BOOL ret = FALSE;
- DWORD size;
- TRACE("(%p, %s, %s, %u, %p, %u)\n", diskspace, debugstr_w(targetfile),
wine_dbgstr_longlong(filesize), operation, reserved1, reserved2);
- if (!targetfile)
return TRUE;
- if (!diskspace)
- {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
- }
- if (operation != FILEOP_COPY && operation != FILEOP_DELETE)
- {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
- }
- size = GetFullPathNameW(targetfile, 0, NULL, NULL);
- if (!size)
- {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
- }
- size = (size+1) * sizeof(WCHAR);
- fullpathW = HeapAlloc(GetProcessHeap(), 0, size);
- if (!GetFullPathNameW(targetfile, size, fullpathW, NULL))
- {
SetLastError(ERROR_INVALID_PARAMETER);
goto done;
- }
- if (fullpathW[1] != ':' && fullpathW[2] != '\')
- {
FIXME("UNC paths not yet supported\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
goto done;
- }
- LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
- {
if (!lstrcmpiW(file->path, fullpathW))
break;
- }
- if (&file->entry == &list->files)
- {
I understand the purpose of this check, but it does not look intuitive. May
file = HeapAlloc(GetProcessHeap(), 0, sizeof(*file));
if (!file)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
file->path = strdupW(fullpathW);
if (!file->path)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
HeapFree(GetProcessHeap(), 0, file);
goto done;
}
list_add_tail(&list->files, &file->entry);
- }
- file->operation = operation;
- if (operation == FILEOP_COPY)
file->size = filesize;
- else
file->size = 0;
- if (!(list->flags & SPDSL_IGNORE_DISK))
file->size -= get_file_size(fullpathW);
- ret = TRUE;
+done:
HeapFree(GetProcessHeap(), 0, fullpathW);
return ret; }
/***********************************************************************
-* SetupAddToDiskSpaceListW (SETUPAPI.@) +* SetupAddToDiskSpaceListA (SETUPAPI.@) */ -BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile, +BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, LONGLONG filesize, UINT operation, PVOID reserved1, UINT reserved2) {
- FIXME(": stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- LPWSTR targetfileW = NULL;
- DWORD len;
- BOOL ret;
- if (targetfile)
- {
len = MultiByteToWideChar(CP_ACP, 0, targetfile, -1, NULL, 0);
targetfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!targetfileW)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
MultiByteToWideChar(CP_ACP, 0, targetfile, -1, targetfileW, len);
- }
We have strdupAtoW in the same module that you can use to collapse this part.
- ret = SetupAddToDiskSpaceListW(diskspace, targetfileW, filesize,
operation, reserved1, reserved2);
- if (targetfileW) HeapFree(GetProcessHeap(), 0, targetfileW);
Null check is unnecessary.
- return ret; }
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c index 4e87ea905e07..bb8c7b78463b 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -19,6 +19,7 @@ */
#include <stdarg.h> +#include <stdio.h>
#include "windef.h" #include "winbase.h" @@ -31,6 +32,16 @@
static BOOL is_win9x;
+static inline const char* debugstr_longlong(ULONGLONG ll) +{
- static char string[17];
- if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
- else
sprintf(string, "%lx", (unsigned long)ll);
- return string;
+}
This could be replaced with wine_dbgstr_longlong() I think.
- static void test_SetupCreateDiskSpaceListA(void) { HDSKSPC ret;
@@ -300,11 +311,31 @@ static void test_SetupDuplicateDiskSpaceListW(void) ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static LONGLONG get_file_size(char *path) +{
- HANDLE file;
- LARGE_INTEGER size;
- file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (file == INVALID_HANDLE_VALUE) return 0;
- if (!GetFileSizeEx(file, &size))
size.QuadPart = 0;
- CloseHandle(file);
- return size.QuadPart;
+}
static void test_SetupQuerySpaceRequiredOnDriveA(void) { BOOL ret; HDSKSPC handle; LONGLONG space;
char windir[MAX_PATH];
char drive[3];
char tmp[MAX_PATH];
LONGLONG size;
if (is_win9x) win_skip("SetupQuerySpaceRequiredOnDriveA crashes with NULL disk space handle on Win9x\n");
@@ -369,7 +400,7 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) ret = SetupQuerySpaceRequiredOnDriveA(handle, "", NULL, NULL, 0); ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret); ok(GetLastError() == ERROR_INVALID_DRIVE,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
"Expected GetLastError() to return ERROR_INVALID_DRIVE, got %u\n", GetLastError()); SetLastError(0xdeadbeef);
@@ -381,6 +412,97 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
- GetWindowsDirectoryA(windir, MAX_PATH);
- drive[0] = windir[0]; drive[1] = windir[1]; drive[2] = 0;
- snprintf(tmp, MAX_PATH, "%c:\wine-test-should-not-exist.txt", drive[0]);
- ret = SetupAddToDiskSpaceListA(handle, tmp, 0x100000, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- space = 0;
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == 0x100000, "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space));
- /* adding the same file again doesn't sum up the size */
- ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- space = 0;
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == 0x200000, "Expected 0x200000 as required space, got %s\n", debugstr_longlong(space));
- /* the device doesn't need to exist */
- snprintf(tmp, MAX_PATH, "F:\wine-test-should-not-exist.txt");
- ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ret = SetupQuerySpaceRequiredOnDriveA(handle, "F:", &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == 0x200000, "Expected 0x100000 as required space, got %s\n", debugstr_longlong(space));
- ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
- handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
- ok(handle != NULL,
"Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
- /* the real size is subtracted unless SPDSL_IGNORE_DISK is specified */
- snprintf(tmp, MAX_PATH, "%s\regedit.exe", windir);
- size = get_file_size(tmp);
- ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- space = 0;
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == 0 || broken(space == -0x5000) || broken(space == -0x7000),
"Expected 0x0 as required space, got %s\n", debugstr_longlong(space));
- ret = SetupAddToDiskSpaceListA(handle, tmp, size + 0x100000, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == 0x100000 || broken(space == 0xf9000) || broken(space == 0xfb000),
"Expected 0x100000 as required space, got %s\n", debugstr_longlong(space));
- ret = SetupAddToDiskSpaceListA(handle, tmp, size - 0x1000, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == -0x1000 || broken(space == -0x6000) || broken(space == -0x8000),
"Expected -0x1000 as required space, got %s\n", debugstr_longlong(space));
- ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
- handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
- ok(handle != NULL,
"Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
- ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- space = 0;
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space <= -size, "Expected space <= -size, got %s\n", debugstr_longlong(space));
- ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
- handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
- ok(handle != NULL,
"Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
- ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- space = 0;
- ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
- ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
- ok(space == 0, "Expected size = 0, got %s\n", debugstr_longlong(space));
}ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n");
@@ -472,6 +594,40 @@ static void test_SetupQuerySpaceRequiredOnDriveW(void) "Expected SetupDestroyDiskSpaceList to succeed\n"); }
+static void test_SetupAddToDiskSpaceListA(void) +{
- HDSKSPC handle;
- BOOL ret;
- ret = SetupAddToDiskSpaceListA(NULL, "C:\some-file.dat", 0, FILEOP_COPY, 0, 0);
- ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE, got %d\n", ret);
- ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", GetLastError());
- handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
- ok(handle != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n");
- ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_COPY, 0, 0);
- ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ret = SetupAddToDiskSpaceListA(handle, "C:\some-file.dat", -20, FILEOP_COPY, 0, 0);
- ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ret = SetupAddToDiskSpaceListA(handle, "C:\some-file.dat", 0, FILEOP_RENAME, 0, 0);
- ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE\n");
- ok(GetLastError() == ERROR_INVALID_PARAMETER,
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
- ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_RENAME, 0, 0);
- ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ret = SetupAddToDiskSpaceListA(NULL, NULL, 0, FILEOP_RENAME, 0, 0);
- ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n");
- ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
+}
There is a lot of broken() cases, especially concerning that allegedly vista+ behavior is considered broken, which is all currently relevant systems.
- START_TEST(diskspace) { is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) &&
@@ -482,4 +638,5 @@ START_TEST(diskspace) test_SetupDuplicateDiskSpaceListW(); test_SetupQuerySpaceRequiredOnDriveA(); test_SetupQuerySpaceRequiredOnDriveW();
- test_SetupAddToDiskSpaceListA(); }
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 85 +++++++++++++++++++++++++++++++++ dlls/setupapi/stubs.c | 18 ------- dlls/setupapi/tests/diskspace.c | 70 +++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 18 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index dcee29443d71..17873ddf9577 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -419,3 +419,88 @@ BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile, if (targetfileW) HeapFree(GetProcessHeap(), 0, targetfileW); return ret; } + +/*********************************************************************** + * SetupQueryDrivesInDiskSpaceListW (SETUPAPI.@) + */ +BOOL WINAPI SetupQueryDrivesInDiskSpaceListW(HDSKSPC diskspace, PWSTR buffer, DWORD size, PDWORD required_size) +{ + struct space_list *list = diskspace; + struct file_entry *file; + DWORD cur_size = 1; + BOOL used[26]; + + TRACE("(%p, %p, %d, %p)\n", diskspace, buffer, size, required_size); + + 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 > size) + { + if (required_size) *required_size = cur_size; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + *buffer++ = towlower(file->path[0]); + *buffer++ = ':'; + *buffer++ = 0; + } + + used[device] = TRUE; + } + + if (buffer && size) *buffer = 0; + if (required_size) *required_size = cur_size; + return TRUE; +} + +/*********************************************************************** + * SetupQueryDrivesInDiskSpaceListA (SETUPAPI.@) + */ +BOOL WINAPI SetupQueryDrivesInDiskSpaceListA(HDSKSPC diskspace, PSTR buffer, DWORD size, PDWORD required_size) +{ + WCHAR *bufferW = NULL; + BOOL ret; + int i; + + if (buffer && size) + { + bufferW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); + if (!bufferW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + } + + ret = SetupQueryDrivesInDiskSpaceListW(diskspace, bufferW ? bufferW : (WCHAR *)buffer, + size, required_size); + + if (bufferW) + { + for (i = 0; i < size; i++) + buffer[i] = bufferW[i]; + HeapFree(GetProcessHeap(), 0, 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 bb8c7b78463b..60087d11f689 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -628,6 +628,75 @@ 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) && @@ -639,4 +708,5 @@ START_TEST(diskspace) test_SetupQuerySpaceRequiredOnDriveA(); test_SetupQuerySpaceRequiredOnDriveW(); test_SetupAddToDiskSpaceListA(); + test_SetupQueryDrivesInDiskSpaceListA(); }
On 10/19/19 9:55 PM, Vijay Kiran Kamuju wrote:
- ret = SetupQueryDrivesInDiskSpaceListW(diskspace, bufferW ? bufferW : (WCHAR *)buffer,
size, required_size);
Why is there a need to ever pass A-function output buffer to W-function?
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 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 17873ddf9577..01b08c1408e7 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -372,6 +372,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 60087d11f689..793d3a1a6c58 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -440,7 +440,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", debugstr_longlong(space)); + ok(space == 0x200000, "Expected 0x200000 as required space, got %s\n", debugstr_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", debugstr_longlong(space));
ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); @@ -478,6 +486,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", debugstr_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", debugstr_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"); @@ -492,6 +539,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"); @@ -503,6 +551,16 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void) ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n"); ok(space == 0, "Expected size = 0, got %s\n", debugstr_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", debugstr_longlong(space)); + ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n"); }
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 130 ++++++++++++++++++++- dlls/setupapi/queue.c | 2 +- dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/setupapi_private.h | 2 + dlls/setupapi/tests/diskspace.c | 193 +++++++++++++++++++++++++++++++ 5 files changed, 327 insertions(+), 4 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 01b08c1408e7..cc8d353c6c04 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -64,6 +64,23 @@ 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; + + /* FIXME: is there a atollW ? */ + *size = wcstol(buffer, NULL, 10); + return TRUE; +} + /*********************************************************************** * SetupCreateDiskSpaceListW (SETUPAPI.@) */ @@ -164,7 +181,118 @@ HDSKSPC WINAPI SetupDuplicateDiskSpaceListA(HDSKSPC DiskSpace, PVOID Reserved1, }
/*********************************************************************** - * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@) + * 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; + BOOL tmp_ret; + + if (!SetupGetStringFieldW(&context, 1, dest, sizeof(dest) / sizeof(WCHAR), NULL)) + goto end; + if (!SetupGetStringFieldW(&context, 2, src, sizeof(src) / sizeof(WCHAR), NULL)) + *src = 0; + if (!get_size_from_inf(hinf, src[0] ? src : dest, &filesize)) + goto end; + + path_size = lstrlenW(dest_dir) + lstrlenW(dest) + 2; + full_path = HeapAlloc(GetProcessHeap(), 0, 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); + HeapFree(GetProcessHeap(), 0, full_path); + if (!tmp_ret) goto end; + } + while (SetupFindNextLine(&context, &context)); + + ret = TRUE; + +end: + HeapFree(GetProcessHeap(), 0, dest_dir); + return ret; +} + +/*********************************************************************** + * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@) + */ +BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC diskspace, HINF hinf, HINF hlist, + PCSTR section, UINT operation, PVOID reserved1, + UINT reserved2) +{ + LPWSTR sectionW = NULL; + DWORD len; + BOOL ret; + + if (section) + { + len = MultiByteToWideChar(CP_ACP, 0, section, -1, NULL, 0); + + sectionW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!sectionW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + MultiByteToWideChar(CP_ACP, 0, section, -1, sectionW, len); + } + + ret = SetupAddSectionToDiskSpaceListW(diskspace, hinf, hlist, sectionW, operation, + reserved1, reserved2); + if (sectionW) HeapFree(GetProcessHeap(), 0, sectionW); + return ret; +} + +/*********************************************************************** + * SetupAddInstallSectionToDiskSpaceListW (SETUPAPI.@) */ BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, HINF InfHandle, HINF LayoutInfHandle, 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 793d3a1a6c58..f40506c4b36f 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -32,6 +32,8 @@
static BOOL is_win9x;
+#define STD_HEADER "[Version]\r\nSignature="$CHICAGO$"\r\n" + static inline const char* debugstr_longlong(ULONGLONG ll) { static char string[17]; @@ -42,6 +44,18 @@ static inline const char* debugstr_longlong(ULONGLONG ll) return string; }
+/* 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; @@ -753,6 +767,184 @@ 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 < sizeof(section_test) / sizeof(section_test[0]); 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) @@ -767,4 +959,5 @@ START_TEST(diskspace) test_SetupQuerySpaceRequiredOnDriveW(); test_SetupAddToDiskSpaceListA(); test_SetupQueryDrivesInDiskSpaceListA(); + test_SetupAddSectionToDiskSpaceListA(); }
On 10/19/19 9:55 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};
- INFCONTEXT context;
- WCHAR buffer[20];
- if (!SetupFindFirstLineW(layoutinf, SourceDisksFiles, filename, &context))
return FALSE;
- if (!SetupGetStringFieldW(&context, 3, buffer, sizeof(buffer), NULL))
return FALSE;
- /* FIXME: is there a atollW ? */
- *size = wcstol(buffer, NULL, 10);
There is wcstoll in ucrtbase, and _wcstoi64() otherwise. Also you can inline string constants with L"".
- return TRUE;
+}
if (!SetupGetStringFieldW(&context, 1, dest, sizeof(dest) / sizeof(WCHAR), NULL))
goto end;
if (!SetupGetStringFieldW(&context, 2, src, sizeof(src) / sizeof(WCHAR), NULL))
*src = 0;
This should be cleaner if made dynamic, using returned required size.
- if (section)
- {
len = MultiByteToWideChar(CP_ACP, 0, section, -1, NULL, 0);
sectionW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!sectionW)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
MultiByteToWideChar(CP_ACP, 0, section, -1, sectionW, len);
- }
- ret = SetupAddSectionToDiskSpaceListW(diskspace, hinf, hlist, sectionW, operation,
reserved1, reserved2);
- if (sectionW) HeapFree(GetProcessHeap(), 0, sectionW);
- return ret;
+}
Same as for earlier patch, this could be using strdupAtoW().
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com --- dlls/setupapi/diskspace.c | 87 +++++++++++++++- dlls/setupapi/setupapi.spec | 2 +- dlls/setupapi/tests/diskspace.c | 170 ++++++++++++++++++++++++++++++++ include/setupapi.h | 3 + 4 files changed, 257 insertions(+), 5 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index cc8d353c6c04..3528698762ed 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -294,14 +294,93 @@ BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC diskspace, HINF hinf, HINF h /*********************************************************************** * 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, sizeof(section_name) / sizeof(WCHAR), 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, sizeof(section_name) / sizeof(WCHAR), 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; + DWORD len; + BOOL ret; + + if (section) + { + len = MultiByteToWideChar(CP_ACP, 0, section, -1, NULL, 0); + + sectionW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!sectionW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + MultiByteToWideChar(CP_ACP, 0, section, -1, sectionW, len); + } + + ret = SetupAddInstallSectionToDiskSpaceListW(diskspace, inf, layoutinf, + sectionW, reserved1, reserved2); + if (sectionW) HeapFree(GetProcessHeap(), 0, sectionW); + return ret; +} + /*********************************************************************** * SetupQuerySpaceRequiredOnDriveW (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 f40506c4b36f..c2c714eecd9f 100644 --- a/dlls/setupapi/tests/diskspace.c +++ b/dlls/setupapi/tests/diskspace.c @@ -947,6 +947,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 < sizeof(section_test_i) / sizeof(section_test_i[0]); 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) && @@ -960,4 +1129,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)
On 10/19/19 9:55 PM, Vijay Kiran Kamuju wrote:
From: Michael Müller michael@fds-team.de
From: Michael Müller michael@fds-team.de
Signed-off-by: Vijay Kiran Kamuju infyquest@gmail.com
dlls/setupapi/diskspace.c | 183 +++++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 82 deletions(-)
This is doing more than patch subject suggests. Any change to split it up more? If we don't have tests for error values, we can live that part out for now.
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index f5e79d5327c9..4f047dd2b544 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -1,6 +1,7 @@ /*
- SetupAPI DiskSpace functions
- Copyright 2016 Michael Müller
- Copyright 2004 CodeWeavers (Aric Stewart)
This is normally arranged in ascending order.
- This library is free software; you can redistribute it and/or
@@ -27,69 +28,50 @@ #include "winnls.h" #include "winreg.h" #include "setupapi.h" +#include "wine/list.h" #include "wine/debug.h" +#include "setupapi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-typedef struct {
- WCHAR lpzName[20];
- LONGLONG dwFreeSpace;
- LONGLONG dwWantedSpace;
-} DRIVE_ENTRY, *LPDRIVE_ENTRY; +struct file_entry +{
- struct list entry;
- WCHAR *path;
- UINT operation;
- LONGLONG size;
+};
+struct space_list +{
- struct list files;
- UINT flags;
+};
-typedef struct {
- DWORD dwDriveCount;
- DRIVE_ENTRY Drives[26];
-} DISKSPACELIST, *LPDISKSPACELIST;
/***********************************************************************
SetupCreateDiskSpaceListW (SETUPAPI.@)
*/ -HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID reserved1, DWORD reserved2, UINT flags) {
- WCHAR drives[255];
- DWORD rc;
- WCHAR *ptr;
- LPDISKSPACELIST list=NULL;
- struct space_list *list;
- TRACE("(%p, %u, 0x%08x)\n", Reserved1, Reserved2, Flags);
- TRACE("(%p, %u, 0x%08x)\n", reserved1, reserved2, flags);
- if (Reserved1 || Reserved2 || Flags & ~SPDSL_IGNORE_DISK)
- if (reserved1 || reserved2 || flags & ~SPDSL_IGNORE_DISK) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; }
- rc = GetLogicalDriveStringsW(255,drives);
- if (rc == 0)
return NULL;
- list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST));
- list->dwDriveCount = 0;
- ptr = drives;
- while (*ptr)
- list = HeapAlloc(GetProcessHeap(), 0, sizeof(*list));
- if (list) {
DWORD type = GetDriveTypeW(ptr);
if (type == DRIVE_FIXED)
{
DWORD clusters;
DWORD sectors;
DWORD bytes;
DWORD total;
lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr);
GetDiskFreeSpaceW(ptr,§ors,&bytes,&clusters,&total);
list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors *
bytes;
list->Drives[list->dwDriveCount].dwWantedSpace = 0;
list->dwDriveCount++;
}
ptr += lstrlenW(ptr) + 1;
list->flags = flags;
list_init(&list->files); }
}return list;
@@ -105,32 +87,58 @@ HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT /***********************************************************************
SetupDuplicateDiskSpaceListW (SETUPAPI.@)
*/ -HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC diskspace, PVOID reserved1, DWORD reserved2, UINT flags) {
- DISKSPACELIST *list_copy, *list_original = DiskSpace;
- struct space_list *list_copy, *list = diskspace;
- struct file_entry *file, *file_copy;
- TRACE("(%p, %p, %u, %u)\n", diskspace, reserved1, reserved2, flags);
- if (Reserved1 || Reserved2 || Flags)
- if (reserved1 || reserved2 || flags) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; }
- if (!DiskSpace)
- if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return NULL; }
- list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST));
- list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*list_copy)); if (!list_copy) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
- *list_copy = *list_original;
list_copy->flags = list->flags;
list_init(&list_copy->files);
LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
{
file_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*file_copy));
if (!file_copy) goto error;
file_copy->path = strdupW(file->path);
if (!file_copy->path)
{
HeapFree(GetProcessHeap(), 0, file_copy);
goto error;
}
file_copy->operation = file->operation;
file_copy->size = file->size;
list_add_head(&list_copy->files, &file->entry);
}
return list_copy;
+error:
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
SetupDestroyDiskSpaceList(list_copy);
return NULL; }
/***********************************************************************
@@ -155,55 +163,51 @@ BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, /***********************************************************************
SetupQuerySpaceRequiredOnDriveW (SETUPAPI.@)
*/ -BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace,
LPCWSTR DriveSpec, LONGLONG *SpaceRequired,
PVOID Reserved1, UINT Reserved2)
+BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC diskspace,
LPCWSTR drivespec, LONGLONG *required,
{PVOID reserved1, UINT reserved2)
- WCHAR *driveW;
- unsigned int i;
- LPDISKSPACELIST list = DiskSpace;
- BOOL rc = FALSE;
- static const WCHAR bkslsh[]= {'\',0};
- struct space_list *list = diskspace;
- struct file_entry *file;
- LONGLONG sum = 0;
- if (!DiskSpace)
- TRACE("(%p, %s, %p, %p, %u)\n", diskspace, debugstr_w(drivespec), required, reserved1, reserved2);
- if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; }
- if (!DriveSpec)
- if (!drivespec || !drivespec[0]) {
SetLastError(ERROR_INVALID_PARAMETER);
SetLastError(drivespec ? ERROR_INVALID_DRIVE : ERROR_INVALID_DRIVE); return FALSE; }
Empty string check is new, is it essential to switching to list? Changed last error looks broken.
- driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR));
- if (!driveW)
- if (!required) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
'required' wasn't tested like that before, right?
- lstrcpyW(driveW,DriveSpec);
- lstrcatW(driveW,bkslsh);
- TRACE("Looking for drive %s\n",debugstr_w(driveW));
- for (i = 0; i < list->dwDriveCount; i++)
- if (towlower(drivespec[0]) < 'a' || towlower(drivespec[0]) > 'z' ||
drivespec[1] != ':' || drivespec[2] != 0) {
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;
}
FIXME("UNC paths not yet supported (%s)\n", debugstr_w(drivespec));
SetLastError((GetVersion() & 0x80000000) ? ERROR_INVALID_DRIVE : ERROR_INVALID_PARAMETER);
return FALSE; }
It feels that using some path handling API to extract drive letter would look better. Also same considerations for error code, especially if it's version-dependent.
- HeapFree(GetProcessHeap(), 0, driveW);
- LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
- {
if (towlower(file->path[0]) == towlower(drivespec[0]) &&
file->path[1] == ':' && file->path[2] == '\\')
sum += file->size;
- }
- if (!rc) SetLastError(ERROR_INVALID_DRIVE);
- return rc;
*required = sum;
return TRUE; }
/***********************************************************************
@@ -253,10 +257,25 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, /***********************************************************************
SetupDestroyDiskSpaceList (SETUPAPI.@)
*/ -BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace) +BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) {
- LPDISKSPACELIST list = DiskSpace;
- HeapFree(GetProcessHeap(),0,list);
- struct space_list *list = diskspace;
- struct file_entry *file, *file2;
- if (!diskspace)
- {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
- }
- LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry)
- {
HeapFree(GetProcessHeap(), 0, file->path);
list_remove(&file->entry);
HeapFree(GetProcessHeap(), 0, file);
- }
- HeapFree(GetProcessHeap(), 0, list); return TRUE; }
Same as above, this changes behavior for return value and error code.