Added patches to implement multiple setupapi DiskSpaceList functions.

This commit is contained in:
Sebastian Lackner 2016-03-03 06:56:21 +01:00
parent 35f38e546c
commit 91247236a6
5 changed files with 932 additions and 0 deletions

View File

@ -283,6 +283,7 @@ patch_enable_all ()
enable_server_Stored_ACLs="$1"
enable_server_Timestamp_Compat="$1"
enable_setupapi_DelReg="$1"
enable_setupapi_DiskSpaceList="$1"
enable_setupapi_Display_Device="$1"
enable_setupapi_Fix_Parser="$1"
enable_setupapi_HSPFILEQ_Check_Type="$1"
@ -1007,6 +1008,9 @@ patch_enable ()
setupapi-DelReg)
enable_setupapi_DelReg="$2"
;;
setupapi-DiskSpaceList)
enable_setupapi_DiskSpaceList="$2"
;;
setupapi-Display_Device)
enable_setupapi_Display_Device="$2"
;;
@ -5900,6 +5904,22 @@ if test "$enable_setupapi_DelReg" -eq 1; then
) >> "$patchlist"
fi
# Patchset setupapi-DiskSpaceList
# |
# | Modified files:
# | * dlls/setupapi/diskspace.c, dlls/setupapi/stubs.c, dlls/setupapi/tests/diskspace.c
# |
if test "$enable_setupapi_DiskSpaceList" -eq 1; then
patch_apply setupapi-DiskSpaceList/0001-setupapi-Rewrite-DiskSpaceList-logic-using-lists.patch
patch_apply setupapi-DiskSpaceList/0002-setupapi-Implement-SetupAddToDiskSpaceList.patch
patch_apply setupapi-DiskSpaceList/0003-setupapi-Implement-SetupQueryDrivesInDiskSpaceList.patch
(
echo '+ { "Michael Müller", "setupapi: Rewrite DiskSpaceList logic using lists.", 1 },';
echo '+ { "Michael Müller", "setupapi: Implement SetupAddToDiskSpaceList.", 1 },';
echo '+ { "Michael Müller", "setupapi: Implement SetupQueryDrivesInDiskSpaceList.", 1 },';
) >> "$patchlist"
fi
# Patchset setupapi-Display_Device
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,295 @@
From b83937f062380afb686fe503fe72c0d96a9843f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 3 Mar 2016 04:52:35 +0100
Subject: setupapi: Rewrite DiskSpaceList logic using lists.
---
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 1ca45f9..7c33542 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,&sectors,&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.7.1

View File

@ -0,0 +1,393 @@
From 675e85075039dca812bdfeb5e353d45d9da6cac3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 3 Mar 2016 05:02:21 +0100
Subject: setupapi: Implement SetupAddToDiskSpaceList.
---
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 7c33542..0e589fa 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -49,7 +49,21 @@ struct space_list
UINT flags;
};
+static LONGLONG get_file_size(WCHAR *path)
+{
+ HANDLE file;
+ LARGE_INTEGER size;
+
+ file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE) return 0;
+ if (!GetFileSizeEx(file, &size))
+ size.QuadPart = 0;
+
+ CloseHandle(file);
+ return size.QuadPart;
+}
/***********************************************************************
* SetupCreateDiskSpaceListW (SETUPAPI.@)
@@ -281,25 +295,128 @@ BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace)
}
/***********************************************************************
-* SetupAddToDiskSpaceListA (SETUPAPI.@)
+* SetupAddToDiskSpaceListW (SETUPAPI.@)
*/
-BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile,
+BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
LONGLONG filesize, UINT operation,
PVOID reserved1, UINT reserved2)
{
- FIXME(": stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ struct space_list *list = diskspace;
+ struct file_entry *file;
+ WCHAR *fullpathW;
+ BOOL ret = FALSE;
+ DWORD size;
+
+ TRACE("(%p, %s, %llu, %u, %p, %u)\n", diskspace, debugstr_w(targetfile), filesize,
+ operation, reserved1, reserved2);
+
+ if (!targetfile)
+ return TRUE;
+
+ if (!diskspace)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (operation != FILEOP_COPY && operation != FILEOP_DELETE)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ size = GetFullPathNameW(targetfile, 0, NULL, NULL);
+ if (!size)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ size = (size+1) * sizeof(WCHAR);
+ fullpathW = HeapAlloc(GetProcessHeap(), 0, size);
+
+ if (!GetFullPathNameW(targetfile, size, fullpathW, NULL))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto done;
+ }
+
+ if (fullpathW[1] != ':' && fullpathW[2] != '\\')
+ {
+ FIXME("UNC paths not yet supported\n");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ goto done;
+ }
+
+ LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
+ {
+ if (!strcmpiW(file->path, fullpathW))
+ break;
+ }
+
+ if (&file->entry == &list->files)
+ {
+ file = HeapAlloc(GetProcessHeap(), 0, sizeof(*file));
+ if (!file)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto done;
+ }
+
+ file->path = strdupW(fullpathW);
+ if (!file->path)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ HeapFree(GetProcessHeap(), 0, file);
+ goto done;
+ }
+
+ list_add_tail(&list->files, &file->entry);
+ }
+
+ file->operation = operation;
+ if (operation == FILEOP_COPY)
+ file->size = filesize;
+ else
+ file->size = 0;
+
+ if (!(list->flags & SPDSL_IGNORE_DISK))
+ file->size -= get_file_size(fullpathW);
+
+ ret = TRUE;
+
+done:
+ HeapFree(GetProcessHeap(), 0, fullpathW);
+ return ret;
}
/***********************************************************************
-* SetupAddToDiskSpaceListW (SETUPAPI.@)
+* SetupAddToDiskSpaceListA (SETUPAPI.@)
*/
-BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
+BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile,
LONGLONG filesize, UINT operation,
PVOID reserved1, UINT reserved2)
{
- FIXME(": stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LPWSTR targetfileW = NULL;
+ DWORD len;
+ BOOL ret;
+
+ if (targetfile)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, targetfile, -1, NULL, 0);
+
+ targetfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!targetfileW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, targetfile, -1, targetfileW, len);
+ }
+
+ ret = SetupAddToDiskSpaceListW(diskspace, targetfileW, filesize,
+ operation, reserved1, reserved2);
+ if (targetfileW) HeapFree(GetProcessHeap(), 0, targetfileW);
+ return ret;
}
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c
index 4e87ea9..bb8c7b7 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();
}
--
2.7.1

View File

@ -0,0 +1,222 @@
From 16118fd1abc95a103ff097409062abf5c3ebb592 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 3 Mar 2016 05:03:11 +0100
Subject: setupapi: Implement SetupQueryDrivesInDiskSpaceList.
---
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 0e589fa..378aa59d 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -420,3 +420,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 (tolowerW(file->path[0]) < 'a' || tolowerW(file->path[0]) > 'z' || file->path[1] != ':')
+ continue;
+
+ device = tolowerW(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++ = tolowerW(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 ffc766b..94e98af1 100644
--- a/dlls/setupapi/stubs.c
+++ b/dlls/setupapi/stubs.c
@@ -198,24 +198,6 @@ INT WINAPI SetupPromptReboot( HSPFILEQ file_queue, HWND owner, BOOL scan_only )
}
/***********************************************************************
- * 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.@)
*/
BOOL WINAPI SetupAddToSourceListA(DWORD flags, PCSTR source)
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c
index bb8c7b7..60087d1 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();
}
--
2.7.1

View File

@ -0,0 +1,2 @@
Fixes: Add implementation for setupapi.SetupAddToDiskSpaceListA/W
Fixes: Add implementation for setupapi.SetupQueryDrivesInDiskSpaceListA/W