From: Vijay Kiran Kamuju Subject: [PATCH] setupapi: Rewrite DiskSpaceList logic using lists. Message-Id: <20190328134935.23940-1-infyquest@gmail.com> Date: Thu, 28 Mar 2019 14:49:35 +0100 From: Michael Müller From: Michael Müller Signed-off-by: Vijay Kiran Kamuju --- dlls/setupapi/diskspace.c | 184 +++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 82 deletions(-) diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c index 1ca45f9691..7c33542e5a 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -1,6 +1,7 @@ /* * SetupAPI DiskSpace functions * + * Copyright 2016 Michael Müller * Copyright 2004 CodeWeavers (Aric Stewart) * * This library is free software; you can redistribute it and/or @@ -27,69 +28,51 @@ #include "winnls.h" #include "winreg.h" #include "setupapi.h" +#include "wine/unicode.h" +#include "wine/list.h" #include "wine/debug.h" +#include "setupapi_private.h" WINE_DEFAULT_DEBUG_CHANNEL(setupapi); -typedef struct { - WCHAR lpzName[20]; - LONGLONG dwFreeSpace; - LONGLONG dwWantedSpace; -} DRIVE_ENTRY, *LPDRIVE_ENTRY; +struct file_entry +{ + struct list entry; + WCHAR *path; + UINT operation; + LONGLONG size; +}; + +struct space_list +{ + struct list files; + UINT flags; +}; -typedef struct { - DWORD dwDriveCount; - DRIVE_ENTRY Drives[26]; -} DISKSPACELIST, *LPDISKSPACELIST; /*********************************************************************** * SetupCreateDiskSpaceListW (SETUPAPI.@) */ -HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID reserved1, DWORD reserved2, UINT flags) { - WCHAR drives[255]; - DWORD rc; - WCHAR *ptr; - LPDISKSPACELIST list=NULL; + struct space_list *list; - TRACE("(%p, %u, 0x%08x)\n", Reserved1, Reserved2, Flags); + TRACE("(%p, %u, 0x%08x)\n", reserved1, reserved2, flags); - if (Reserved1 || Reserved2 || Flags & ~SPDSL_IGNORE_DISK) + if (reserved1 || reserved2 || flags & ~SPDSL_IGNORE_DISK) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } - rc = GetLogicalDriveStringsW(255,drives); - - if (rc == 0) - return NULL; - - list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST)); - - list->dwDriveCount = 0; - - ptr = drives; - - while (*ptr) + list = HeapAlloc(GetProcessHeap(), 0, sizeof(*list)); + if (list) { - DWORD type = GetDriveTypeW(ptr); - if (type == DRIVE_FIXED) - { - DWORD clusters; - DWORD sectors; - DWORD bytes; - DWORD total; - lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr); - GetDiskFreeSpaceW(ptr,§ors,&bytes,&clusters,&total); - list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors * - bytes; - list->Drives[list->dwDriveCount].dwWantedSpace = 0; - list->dwDriveCount++; - } - ptr += lstrlenW(ptr) + 1; + list->flags = flags; + list_init(&list->files); } + return list; } @@ -105,32 +88,58 @@ HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT /*********************************************************************** * SetupDuplicateDiskSpaceListW (SETUPAPI.@) */ -HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags) +HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC diskspace, PVOID reserved1, DWORD reserved2, UINT flags) { - DISKSPACELIST *list_copy, *list_original = DiskSpace; + struct space_list *list_copy, *list = diskspace; + struct file_entry *file, *file_copy; + + TRACE("(%p, %p, %u, %u)\n", diskspace, reserved1, reserved2, flags); - if (Reserved1 || Reserved2 || Flags) + if (reserved1 || reserved2 || flags) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } - if (!DiskSpace) + if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return NULL; } - list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST)); + list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*list_copy)); if (!list_copy) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } - *list_copy = *list_original; + list_copy->flags = list->flags; + list_init(&list_copy->files); + + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + file_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(*file_copy)); + if (!file_copy) goto error; + + file_copy->path = strdupW(file->path); + if (!file_copy->path) + { + HeapFree(GetProcessHeap(), 0, file_copy); + goto error; + } + + file_copy->operation = file->operation; + file_copy->size = file->size; + list_add_head(&list_copy->files, &file->entry); + } return list_copy; + +error: + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetupDestroyDiskSpaceList(list_copy); + return NULL; } /*********************************************************************** @@ -155,55 +164,51 @@ BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, /*********************************************************************** * SetupQuerySpaceRequiredOnDriveW (SETUPAPI.@) */ -BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace, - LPCWSTR DriveSpec, LONGLONG *SpaceRequired, - PVOID Reserved1, UINT Reserved2) +BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC diskspace, + LPCWSTR drivespec, LONGLONG *required, + PVOID reserved1, UINT reserved2) { - WCHAR *driveW; - unsigned int i; - LPDISKSPACELIST list = DiskSpace; - BOOL rc = FALSE; - static const WCHAR bkslsh[]= {'\\',0}; + struct space_list *list = diskspace; + struct file_entry *file; + LONGLONG sum = 0; - if (!DiskSpace) + TRACE("(%p, %s, %p, %p, %u)\n", diskspace, debugstr_w(drivespec), required, reserved1, reserved2); + + if (!diskspace) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } - if (!DriveSpec) + if (!drivespec || !drivespec[0]) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError(drivespec ? ERROR_INVALID_DRIVE : ERROR_INVALID_DRIVE); return FALSE; } - driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR)); - if (!driveW) + if (!required) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - lstrcpyW(driveW,DriveSpec); - lstrcatW(driveW,bkslsh); - - TRACE("Looking for drive %s\n",debugstr_w(driveW)); - - for (i = 0; i < list->dwDriveCount; i++) + if (tolowerW(drivespec[0]) < 'a' || tolowerW(drivespec[0]) > 'z' || + drivespec[1] != ':' || drivespec[2] != 0) { - TRACE("checking drive %s\n",debugstr_w(list->Drives[i].lpzName)); - if (lstrcmpW(driveW,list->Drives[i].lpzName)==0) - { - rc = TRUE; - *SpaceRequired = list->Drives[i].dwWantedSpace; - break; - } + FIXME("UNC paths not yet supported (%s)\n", debugstr_w(drivespec)); + SetLastError((GetVersion() & 0x80000000) ? ERROR_INVALID_DRIVE : ERROR_INVALID_PARAMETER); + return FALSE; } - HeapFree(GetProcessHeap(), 0, driveW); + LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry) + { + if (tolowerW(file->path[0]) == tolowerW(drivespec[0]) && + file->path[1] == ':' && file->path[2] == '\\') + sum += file->size; + } - if (!rc) SetLastError(ERROR_INVALID_DRIVE); - return rc; + *required = sum; + return TRUE; } /*********************************************************************** @@ -253,10 +258,25 @@ BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, /*********************************************************************** * SetupDestroyDiskSpaceList (SETUPAPI.@) */ -BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace) +BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace) { - LPDISKSPACELIST list = DiskSpace; - HeapFree(GetProcessHeap(),0,list); + struct space_list *list = diskspace; + struct file_entry *file, *file2; + + if (!diskspace) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + LIST_FOR_EACH_ENTRY_SAFE(file, file2, &list->files, struct file_entry, entry) + { + HeapFree(GetProcessHeap(), 0, file->path); + list_remove(&file->entry); + HeapFree(GetProcessHeap(), 0, file); + } + + HeapFree(GetProcessHeap(), 0, list); return TRUE; } -- 2.21.0