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(); }