[PATCH v3 2/6] setupapi: Implement SetupAddToDiskSpaceList.
Vijay Kiran Kamuju
infyquest at gmail.com
Sun Oct 20 16:00:00 CDT 2019
From: Michael Müller <michael at fds-team.de>
Signed-off-by: Vijay Kiran Kamuju <infyquest at gmail.com>
---
dlls/setupapi/diskspace.c | 123 +++++++++++++++++++++++---
dlls/setupapi/tests/diskspace.c | 150 +++++++++++++++++++++++++++++++-
2 files changed, 261 insertions(+), 12 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c
index 94b68d2e82ba..d500c4c02a33 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -49,7 +49,21 @@ struct space_list
UINT flags;
};
+static LONGLONG get_file_size(WCHAR *path)
+{
+ HANDLE file;
+ LARGE_INTEGER size;
+
+ file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE) return 0;
+ if (!GetFileSizeEx(file, &size))
+ size.QuadPart = 0;
+
+ CloseHandle(file);
+ return size.QuadPart;
+}
/***********************************************************************
* SetupCreateDiskSpaceListW (SETUPAPI.@)
@@ -270,25 +284,114 @@ BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace)
}
/***********************************************************************
-* SetupAddToDiskSpaceListA (SETUPAPI.@)
+* SetupAddToDiskSpaceListW (SETUPAPI.@)
*/
-BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile,
+BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
LONGLONG filesize, UINT operation,
PVOID reserved1, UINT reserved2)
{
- FIXME(": stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ struct space_list *list = diskspace;
+ struct file_entry *file;
+ WCHAR *fullpathW;
+ BOOL ret = FALSE;
+ DWORD size;
+
+ TRACE("(%p, %s, %s, %u, %p, %u)\n", diskspace, debugstr_w(targetfile),
+ wine_dbgstr_longlong(filesize), operation, reserved1, reserved2);
+
+ if (!targetfile)
+ return TRUE;
+
+ if (!diskspace)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (operation != FILEOP_COPY && operation != FILEOP_DELETE)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ size = GetFullPathNameW(targetfile, 0, NULL, NULL);
+ if (!size)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ size = (size+1) * sizeof(WCHAR);
+ fullpathW = heap_alloc(size);
+
+ if (!GetFullPathNameW(targetfile, size, fullpathW, NULL))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto done;
+ }
+
+ if (fullpathW[1] != ':' && fullpathW[2] != '\\')
+ {
+ FIXME("UNC paths not yet supported\n");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ goto done;
+ }
+
+ LIST_FOR_EACH_ENTRY(file, &list->files, struct file_entry, entry)
+ {
+ if (!lstrcmpiW(file->path, fullpathW))
+ break;
+ }
+
+ if (&file->entry == &list->files)
+ {
+ file = heap_alloc(sizeof(*file));
+ if (!file)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto done;
+ }
+
+ file->path = strdupW(fullpathW);
+ if (!file->path)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ heap_free(file);
+ goto done;
+ }
+
+ list_add_tail(&list->files, &file->entry);
+ }
+
+ file->operation = operation;
+ if (operation == FILEOP_COPY)
+ file->size = filesize;
+ else
+ file->size = 0;
+
+ if (!(list->flags & SPDSL_IGNORE_DISK))
+ file->size -= get_file_size(fullpathW);
+
+ ret = TRUE;
+
+done:
+ heap_free(fullpathW);
+ return ret;
}
/***********************************************************************
-* SetupAddToDiskSpaceListW (SETUPAPI.@)
+* SetupAddToDiskSpaceListA (SETUPAPI.@)
*/
-BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
+BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile,
LONGLONG filesize, UINT operation,
PVOID reserved1, UINT reserved2)
{
- FIXME(": stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ LPWSTR targetfileW = NULL;
+ BOOL ret;
+
+ targetfileW = strdupAtoW(targetfile);
+ ret = SetupAddToDiskSpaceListW(diskspace, targetfileW, filesize,
+ operation, reserved1, reserved2);
+ heap_free(targetfileW);
+ return ret;
}
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c
index 4e87ea905e07..0da1b7fddaf2 100644
--- a/dlls/setupapi/tests/diskspace.c
+++ b/dlls/setupapi/tests/diskspace.c
@@ -300,11 +300,31 @@ static void test_SetupDuplicateDiskSpaceListW(void)
ok(SetupDestroyDiskSpaceList(handle), "Expected SetupDestroyDiskSpaceList to succeed\n");
}
+static LONGLONG get_file_size(char *path)
+{
+ HANDLE file;
+ LARGE_INTEGER size;
+
+ file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE) return 0;
+
+ if (!GetFileSizeEx(file, &size))
+ size.QuadPart = 0;
+
+ CloseHandle(file);
+ return size.QuadPart;
+}
+
static void test_SetupQuerySpaceRequiredOnDriveA(void)
{
BOOL ret;
HDSKSPC handle;
LONGLONG space;
+ char windir[MAX_PATH];
+ char drive[3];
+ char tmp[MAX_PATH];
+ LONGLONG size;
if (is_win9x)
win_skip("SetupQuerySpaceRequiredOnDriveA crashes with NULL disk space handle on Win9x\n");
@@ -369,7 +389,7 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
ret = SetupQuerySpaceRequiredOnDriveA(handle, "", NULL, NULL, 0);
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(GetLastError() == ERROR_INVALID_DRIVE,
- "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
+ "Expected GetLastError() to return ERROR_INVALID_DRIVE, got %u\n",
GetLastError());
SetLastError(0xdeadbeef);
@@ -378,9 +398,100 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
ok(!ret, "Expected SetupQuerySpaceRequiredOnDriveA to return FALSE, got %d\n", ret);
ok(space == 0xdeadbeef, "Expected output space parameter to be untouched\n");
ok(GetLastError() == ERROR_INVALID_DRIVE,
- "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n",
+ "Expected GetLastError() to return ERROR_INVALID_DRIVE, got %u\n",
GetLastError());
+ GetWindowsDirectoryA(windir, MAX_PATH);
+ drive[0] = windir[0]; drive[1] = windir[1]; drive[2] = 0;
+
+ snprintf(tmp, MAX_PATH, "%c:\\wine-test-should-not-exist.txt", drive[0]);
+ ret = SetupAddToDiskSpaceListA(handle, tmp, 0x100000, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == 0x100000, "Expected 0x100000 as required space, got %s\n", wine_dbgstr_longlong(space));
+
+ /* adding the same file again doesn't sum up the size */
+ ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == 0x200000, "Expected 0x200000 as required space, got %s\n", wine_dbgstr_longlong(space));
+
+ /* the device doesn't need to exist */
+ snprintf(tmp, MAX_PATH, "F:\\wine-test-should-not-exist.txt");
+ ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, "F:", &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == 0x200000, "Expected 0x100000 as required space, got %s\n", wine_dbgstr_longlong(space));
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
+ ok(handle != NULL,
+ "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
+
+ /* the real size is subtracted unless SPDSL_IGNORE_DISK is specified */
+ snprintf(tmp, MAX_PATH, "%s\\regedit.exe", windir);
+
+ size = get_file_size(tmp);
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == 0 || broken(space == -0x5000) || broken(space == -0x7000),
+ "Expected 0x0 as required space, got %s\n", wine_dbgstr_longlong(space));
+
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size + 0x100000, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == 0x100000 || broken(space == 0xf9000) || broken(space == 0xfb000),
+ "Expected 0x100000 as required space, got %s\n", wine_dbgstr_longlong(space));
+
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size - 0x1000, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == -0x1000 || broken(space == -0x6000) || broken(space == -0x8000),
+ "Expected -0x1000 as required space, got %s\n", wine_dbgstr_longlong(space));
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
+ ok(handle != NULL,
+ "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
+
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space <= -size, "Expected space <= -size, got %s\n", wine_dbgstr_longlong(space));
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
+ ok(handle != NULL,
+ "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
+
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_DELETE, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(handle, drive, &space, NULL, 0);
+ ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
+ ok(space == 0, "Expected size = 0, got %s\n", wine_dbgstr_longlong(space));
+
ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
}
@@ -472,6 +583,40 @@ static void test_SetupQuerySpaceRequiredOnDriveW(void)
"Expected SetupDestroyDiskSpaceList to succeed\n");
}
+static void test_SetupAddToDiskSpaceListA(void)
+{
+ HDSKSPC handle;
+ BOOL ret;
+
+ ret = SetupAddToDiskSpaceListA(NULL, "C:\\some-file.dat", 0, FILEOP_COPY, 0, 0);
+ ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE, got %d\n", ret);
+ ok(GetLastError() == ERROR_INVALID_HANDLE,
+ "Expected GetLastError() to return ERROR_INVALID_HANDLE, got %u\n", GetLastError());
+
+ handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
+ ok(handle != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n");
+
+ ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_COPY, 0, 0);
+ ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ ret = SetupAddToDiskSpaceListA(handle, "C:\\some-file.dat", -20, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ ret = SetupAddToDiskSpaceListA(handle, "C:\\some-file.dat", 0, FILEOP_RENAME, 0, 0);
+ ok(!ret, "Expected SetupAddToDiskSpaceListA to return FALSE\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+
+ ret = SetupAddToDiskSpaceListA(handle, NULL, 0, FILEOP_RENAME, 0, 0);
+ ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ ret = SetupAddToDiskSpaceListA(NULL, NULL, 0, FILEOP_RENAME, 0, 0);
+ ok(ret || broken(!ret) /* >= Vista */, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+}
+
START_TEST(diskspace)
{
is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) &&
@@ -482,4 +627,5 @@ START_TEST(diskspace)
test_SetupDuplicateDiskSpaceListW();
test_SetupQuerySpaceRequiredOnDriveA();
test_SetupQuerySpaceRequiredOnDriveW();
+ test_SetupAddToDiskSpaceListA();
}
--
2.21.0
More information about the wine-devel
mailing list