mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[WINESYNC] setupapi: Implement SetupAddToDiskSpaceList.
wine-staging patch by Michael Müller <michael@fds-team.de>
This commit is contained in:
parent
d154ec0984
commit
a405f58d89
3 changed files with 670 additions and 16 deletions
|
@ -36,7 +36,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.@)
|
||||
|
@ -267,18 +281,6 @@ BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC diskspace)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupAddToDiskSpaceListA (SETUPAPI.@)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupAddToDiskSpaceListW (SETUPAPI.@)
|
||||
*/
|
||||
|
@ -286,7 +288,122 @@ 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 = wcsdup(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;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupAddToDiskSpaceListA (SETUPAPI.@)
|
||||
*/
|
||||
BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile,
|
||||
LONGLONG filesize, UINT operation,
|
||||
PVOID reserved1, UINT reserved2)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -29,6 +30,16 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
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;
|
||||
|
@ -293,11 +304,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;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, NULL, NULL, 0);
|
||||
|
@ -357,7 +388,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 %lu\n",
|
||||
"Expected GetLastError() to return ERROR_INVALID_DRIVE, got %lu\n",
|
||||
GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -369,6 +400,97 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
|
|||
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\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");
|
||||
}
|
||||
|
@ -460,6 +582,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 %lu\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 %lu\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)
|
||||
{
|
||||
test_SetupCreateDiskSpaceListA();
|
||||
|
@ -468,4 +624,5 @@ START_TEST(diskspace)
|
|||
test_SetupDuplicateDiskSpaceListW();
|
||||
test_SetupQuerySpaceRequiredOnDriveA();
|
||||
test_SetupQuerySpaceRequiredOnDriveW();
|
||||
test_SetupAddToDiskSpaceListA();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,380 @@
|
|||
diff --git a/dll/win32/setupapi/diskspace.c b/dll/win32/setupapi/diskspace.c
|
||||
index b900f8a84ee..962764cf279 100644
|
||||
--- a/dll/win32/setupapi/diskspace.c
|
||||
+++ b/dll/win32/setupapi/diskspace.c
|
||||
@@ -36,7 +36,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.@)
|
||||
@@ -268,25 +282,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 = wcsdup(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/modules/rostests/winetests/setupapi/diskspace.c b/modules/rostests/winetests/setupapi/diskspace.c
|
||||
index 577b1f84a2a..3cd83c8471f 100644
|
||||
--- a/modules/rostests/winetests/setupapi/diskspace.c
|
||||
+++ b/modules/rostests/winetests/setupapi/diskspace.c
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
@@ -29,6 +30,16 @@
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
+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;
|
||||
@@ -293,11 +304,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;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetupQuerySpaceRequiredOnDriveA(NULL, NULL, NULL, NULL, 0);
|
||||
@@ -357,7 +388,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 %lu\n",
|
||||
+ "Expected GetLastError() to return ERROR_INVALID_DRIVE, got %lu\n",
|
||||
GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
@@ -369,6 +400,97 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
|
||||
"Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\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");
|
||||
}
|
||||
@@ -460,6 +582,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 %lu\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 %lu\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)
|
||||
{
|
||||
test_SetupCreateDiskSpaceListA();
|
||||
@@ -468,4 +624,5 @@ START_TEST(diskspace)
|
||||
test_SetupDuplicateDiskSpaceListW();
|
||||
test_SetupQuerySpaceRequiredOnDriveA();
|
||||
test_SetupQuerySpaceRequiredOnDriveW();
|
||||
+ test_SetupAddToDiskSpaceListA();
|
||||
}
|
Loading…
Reference in a new issue