setupapi-DiskSpaceList: Add additional patches with implementation for setupapi.SetupAdd{Install}SectionToDiskSpaceListA/W.

This commit is contained in:
Sebastian Lackner 2016-03-04 18:09:37 +01:00
parent 67f656285c
commit 6f84288f36
5 changed files with 890 additions and 1 deletions

View File

@ -5888,16 +5888,23 @@ fi
# Patchset setupapi-DiskSpaceList
# |
# | Modified files:
# | * dlls/setupapi/diskspace.c, dlls/setupapi/stubs.c, dlls/setupapi/tests/diskspace.c
# | * dlls/setupapi/diskspace.c, dlls/setupapi/queue.c, dlls/setupapi/setupapi.spec, dlls/setupapi/setupapi_private.h,
# | dlls/setupapi/stubs.c, dlls/setupapi/tests/diskspace.c, include/setupapi.h
# |
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
patch_apply setupapi-DiskSpaceList/0004-setupapi-Ignore-deletion-of-added-files-in-SetupAddT.patch
patch_apply setupapi-DiskSpaceList/0005-setupapi-ImplementSetupAddSectionToDiskSpaceList.patch
patch_apply setupapi-DiskSpaceList/0006-setupapi-Implement-SetupAddInstallSectionToDiskSpace.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 },';
echo '+ { "Michael Müller", "setupapi: Ignore deletion of added files in SetupAddToDiskSpaceList.", 1 },';
echo '+ { "Michael Müller", "setupapi: ImplementSetupAddSectionToDiskSpaceList.", 1 },';
echo '+ { "Michael Müller", "setupapi: Implement SetupAddInstallSectionToDiskSpaceList.", 1 },';
) >> "$patchlist"
fi

View File

@ -0,0 +1,122 @@
From a9ca8eed486e1a1deb479643ce00a149a93b0f38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Mar 2016 04:21:18 +0100
Subject: setupapi: Ignore deletion of added files in SetupAddToDiskSpaceList.
---
dlls/setupapi/diskspace.c | 6 +++++
dlls/setupapi/tests/diskspace.c | 60 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c
index 378aa59d..0cadf72 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -373,6 +373,12 @@ BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
list_add_tail(&list->files, &file->entry);
}
+ else if (operation == FILEOP_DELETE)
+ {
+ /* delete operations for added files are ignored */
+ ret = TRUE;
+ goto done;
+ }
file->operation = operation;
if (operation == FILEOP_COPY)
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c
index 60087d1..793d3a1 100644
--- a/dlls/setupapi/tests/diskspace.c
+++ b/dlls/setupapi/tests/diskspace.c
@@ -440,7 +440,15 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
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(space == 0x200000, "Expected 0x200000 as required space, got %s\n", debugstr_longlong(space));
+
+ snprintf(tmp, MAX_PATH, "F:\\wine-test-should-not-exist.txt");
+ ret = SetupAddToDiskSpaceListA(handle, tmp, 0x200000, FILEOP_DELETE, 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 0x200000 as required space, got %s\n", debugstr_longlong(space));
ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
@@ -478,6 +486,45 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
+ /* test FILEOP_DELETE, then FILEOP_COPY */
+ 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");
+ 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));
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ /* test FILEOP_COPY, then FILEOP_DELETE */
+ handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
+ ok(handle != NULL,
+ "Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
+
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\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 || broken(space == -0x5000) || broken(space == -0x7000),
+ "Expected 0x0 as required space, got %s\n", debugstr_longlong(space));
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ /* test FILEOP_DELETE without SPDSL_IGNORE_DISK */
handle = SetupCreateDiskSpaceListA(NULL, 0, 0);
ok(handle != NULL,
"Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
@@ -492,6 +539,7 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
+ /* test FILEOP_COPY and FILEOP_DELETE with SPDSL_IGNORE_DISK */
handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
ok(handle != NULL,
"Expected SetupCreateDiskSpaceListA to return a valid handle, got NULL\n");
@@ -503,6 +551,16 @@ static void test_SetupQuerySpaceRequiredOnDriveA(void)
ok(ret, "Expected SetupQuerySpaceRequiredOnDriveA to succeed\n");
ok(space == 0, "Expected size = 0, got %s\n", debugstr_longlong(space));
+ ret = SetupAddToDiskSpaceListA(handle, tmp, size, FILEOP_COPY, 0, 0);
+ ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\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 size >= %s\n", debugstr_longlong(space));
+
ok(SetupDestroyDiskSpaceList(handle),
"Expected SetupDestroyDiskSpaceList to succeed\n");
}
--
2.7.1

View File

@ -0,0 +1,428 @@
From 8962a061f011918c5e2694c504a51e29ec667dad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Mar 2016 04:53:00 +0100
Subject: setupapi: ImplementSetupAddSectionToDiskSpaceList.
---
dlls/setupapi/diskspace.c | 130 +++++++++++++++++++++++++-
dlls/setupapi/queue.c | 2 +-
dlls/setupapi/setupapi.spec | 4 +-
dlls/setupapi/setupapi_private.h | 2 +
dlls/setupapi/tests/diskspace.c | 193 +++++++++++++++++++++++++++++++++++++++
5 files changed, 327 insertions(+), 4 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c
index 0cadf72..2159ab9 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -65,6 +65,23 @@ static LONGLONG get_file_size(WCHAR *path)
return size.QuadPart;
}
+static BOOL get_size_from_inf(HINF layoutinf, WCHAR *filename, LONGLONG *size)
+{
+ static const WCHAR SourceDisksFiles[] = {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
+ INFCONTEXT context;
+ WCHAR buffer[20];
+
+ if (!SetupFindFirstLineW(layoutinf, SourceDisksFiles, filename, &context))
+ return FALSE;
+
+ if (!SetupGetStringFieldW(&context, 3, buffer, sizeof(buffer), NULL))
+ return FALSE;
+
+ /* FIXME: is there a atollW ? */
+ *size = atolW(buffer);
+ return TRUE;
+}
+
/***********************************************************************
* SetupCreateDiskSpaceListW (SETUPAPI.@)
*/
@@ -165,7 +182,118 @@ HDSKSPC WINAPI SetupDuplicateDiskSpaceListA(HDSKSPC DiskSpace, PVOID Reserved1,
}
/***********************************************************************
- * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@)
+ * SetupAddSectionToDiskSpaceListW (SETUPAPI.@)
+ */
+BOOL WINAPI SetupAddSectionToDiskSpaceListW(HDSKSPC diskspace, HINF hinf, HINF hlist,
+ PCWSTR section, UINT operation, PVOID reserved1,
+ UINT reserved2)
+{
+ static const WCHAR sepW[] = {'\\',0};
+ WCHAR dest[MAX_PATH], src[MAX_PATH], *dest_dir, *full_path;
+ INFCONTEXT context;
+ BOOL ret = FALSE;
+
+ TRACE("(%p, %p, %p, %s, %u, %p, %u)\n", diskspace, hinf, hlist, debugstr_w(section),
+ operation, reserved1, reserved2);
+
+ if (!diskspace)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (!section)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!hlist) hlist = hinf;
+
+ if (!SetupFindFirstLineW(hlist, section, NULL, &context))
+ {
+ SetLastError(ERROR_SECTION_NOT_FOUND);
+ return FALSE;
+ }
+
+ dest_dir = get_destination_dir(hinf, section);
+ if (!dest_dir)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ do
+ {
+ LONGLONG filesize;
+ int path_size;
+ BOOL tmp_ret;
+
+ if (!SetupGetStringFieldW(&context, 1, dest, sizeof(dest) / sizeof(WCHAR), NULL))
+ goto end;
+ if (!SetupGetStringFieldW(&context, 2, src, sizeof(src) / sizeof(WCHAR), NULL))
+ *src = 0;
+ if (!get_size_from_inf(hinf, src[0] ? src : dest, &filesize))
+ goto end;
+
+ path_size = strlenW(dest_dir) + strlenW(dest) + 2;
+ full_path = HeapAlloc(GetProcessHeap(), 0, path_size * sizeof(WCHAR));
+ if (!full_path)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto end;
+ }
+
+ strcpyW(full_path, dest_dir);
+ strcatW(full_path, sepW);
+ strcatW(full_path, dest);
+
+ tmp_ret = SetupAddToDiskSpaceListW(diskspace, full_path, filesize, operation, 0, 0);
+ HeapFree(GetProcessHeap(), 0, full_path);
+ if (!tmp_ret) goto end;
+ }
+ while (SetupFindNextLine(&context, &context));
+
+ ret = TRUE;
+
+end:
+ HeapFree(GetProcessHeap(), 0, dest_dir);
+ return ret;
+}
+
+/***********************************************************************
+ * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@)
+ */
+BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC diskspace, HINF hinf, HINF hlist,
+ PCSTR section, UINT operation, PVOID reserved1,
+ UINT reserved2)
+{
+ LPWSTR sectionW = NULL;
+ DWORD len;
+ BOOL ret;
+
+ if (section)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, section, -1, NULL, 0);
+
+ sectionW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!sectionW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, section, -1, sectionW, len);
+ }
+
+ ret = SetupAddSectionToDiskSpaceListW(diskspace, hinf, hlist, sectionW, operation,
+ reserved1, reserved2);
+ if (sectionW) HeapFree(GetProcessHeap(), 0, sectionW);
+ return ret;
+}
+
+/***********************************************************************
+ * SetupAddInstallSectionToDiskSpaceListW (SETUPAPI.@)
*/
BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace,
HINF InfHandle, HINF LayoutInfHandle,
diff --git a/dlls/setupapi/queue.c b/dlls/setupapi/queue.c
index d2e2a1d..2c94ece 100644
--- a/dlls/setupapi/queue.c
+++ b/dlls/setupapi/queue.c
@@ -335,7 +335,7 @@ static void get_src_file_info( HINF hinf, struct file_op *op )
*
* Retrieve the destination dir for a given section.
*/
-static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )
+WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )
{
static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
static const WCHAR Def[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec
index 4486994..5554d16 100644
--- a/dlls/setupapi/setupapi.spec
+++ b/dlls/setupapi/setupapi.spec
@@ -244,8 +244,8 @@
@ stub SetArrayToMultiSzValue
@ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long)
@ stub SetupAddInstallSectionToDiskSpaceListW
-@ stub SetupAddSectionToDiskSpaceListA
-@ stub SetupAddSectionToDiskSpaceListW
+@ stdcall SetupAddSectionToDiskSpaceListA(long long long str long ptr long)
+@ stdcall SetupAddSectionToDiskSpaceListW(long long long wstr long ptr long)
@ stdcall SetupAddToDiskSpaceListA(long str int64 long ptr long)
@ stdcall SetupAddToDiskSpaceListW(long wstr int64 long ptr long)
@ stdcall SetupAddToSourceListA(long str)
diff --git a/dlls/setupapi/setupapi_private.h b/dlls/setupapi/setupapi_private.h
index 5cdedb6..502208b 100644
--- a/dlls/setupapi/setupapi_private.h
+++ b/dlls/setupapi/setupapi_private.h
@@ -88,6 +88,8 @@ extern const WCHAR *PARSER_get_inf_filename( HINF hinf ) DECLSPEC_HIDDEN;
extern WCHAR *PARSER_get_src_root( HINF hinf ) DECLSPEC_HIDDEN;
extern WCHAR *PARSER_get_dest_dir( INFCONTEXT *context ) DECLSPEC_HIDDEN;
+extern WCHAR *get_destination_dir( HINF hinf, const WCHAR *section );
+
/* support for Ascii queue callback functions */
struct callback_WtoA_context
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c
index 793d3a1..f40506c 100644
--- a/dlls/setupapi/tests/diskspace.c
+++ b/dlls/setupapi/tests/diskspace.c
@@ -32,6 +32,8 @@
static BOOL is_win9x;
+#define STD_HEADER "[Version]\r\nSignature=\"$CHICAGO$\"\r\n"
+
static inline const char* debugstr_longlong(ULONGLONG ll)
{
static char string[17];
@@ -42,6 +44,18 @@ static inline const char* debugstr_longlong(ULONGLONG ll)
return string;
}
+/* create a new file with specified contents and open it */
+static HINF inf_open_file_content(const char * tmpfilename, const char *data, UINT *err_line)
+{
+ DWORD res;
+ HANDLE handle = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
+ if (handle == INVALID_HANDLE_VALUE) return 0;
+ if (!WriteFile( handle, data, strlen(data), &res, NULL )) trace( "write error\n" );
+ CloseHandle( handle );
+ return SetupOpenInfFileA( tmpfilename, 0, INF_STYLE_WIN4, err_line );
+}
+
static void test_SetupCreateDiskSpaceListA(void)
{
HDSKSPC ret;
@@ -753,6 +767,184 @@ static void test_SetupQueryDrivesInDiskSpaceListA(void)
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");
+
+ ok(SetupDestroyDiskSpaceList(handle),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+}
+
+struct device_usage
+{
+ const char *dev;
+ LONGLONG usage;
+};
+
+struct section
+{
+ const char *name;
+ UINT fileop;
+ BOOL result;
+ DWORD error_code;
+};
+
+static const struct
+{
+ const char *data;
+ struct section sections[2];
+ const char *devices;
+ int device_length;
+ struct device_usage usage[2];
+}
+section_test[] =
+{
+ /* 0 */
+ {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {NULL, 0, TRUE, 0}},
+ "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 1 */
+ {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", FILEOP_DELETE, TRUE, 0}, {NULL, 0, TRUE, 0}},
+ "c:\00", sizeof("c:\00"), {{"c:", 0}, {NULL, 0}}},
+ /* 2 */
+ {STD_HEADER "[a]\ntest,,,\n\r\n",
+ {{"a", FILEOP_COPY, FALSE, ERROR_LINE_NOT_FOUND}, {NULL, 0, TRUE, 0}},
+ "", sizeof(""), {{NULL, 0}, {NULL, 0}}},
+ /* 3 */
+ {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\n[DestinationDirs]\nDefaultDestDir=-1,F:\\test\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {NULL, 0, TRUE, 0}},
+ "f:\00", sizeof("f:\00"), {{"f:", 4096}, {NULL, 0}}},
+ /* 4 */
+ {STD_HEADER "[a]\ntest,test2,,\n[SourceDisksFiles]\ntest2=1,,4096\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {NULL, 0, TRUE, 0}},
+ "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 5 */
+ {STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"b", FILEOP_COPY, FALSE, ERROR_SECTION_NOT_FOUND}, {NULL, 0, TRUE, 0}},
+ "", sizeof(""), {{NULL, 0}, {NULL, 0}}},
+ /* 6 */
+ {STD_HEADER "[a]\ntest,,,\n[b]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}},
+ "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 7 */
+ {STD_HEADER "[a]\ntest,,,\n[b]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\n[DestinationDirs]\nb=-1,F:\\test\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}},
+ "c:\00f:\00", sizeof("c:\00f:\00"), {{"c:", 4096}, {"f:", 4096}}},
+ /* 8 */
+ {STD_HEADER "[a]\ntest,test1,,\n[b]\ntest,test2,,\n[SourceDisksFiles]\ntest1=1,,4096\ntest2=1,,8192\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}},
+ "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}},
+ /* 9 */
+ {STD_HEADER "[a]\ntest1,test,,\n[b]\ntest2,test,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", FILEOP_COPY, TRUE, 0}, {"b", FILEOP_COPY, TRUE, 0}},
+ "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}},
+};
+
+static void test_SetupAddSectionToDiskSpaceListA(void)
+{
+ char tmp[MAX_PATH];
+ char tmpfilename[MAX_PATH];
+ char buffer[MAX_PATH];
+ HDSKSPC diskspace;
+ UINT err_line;
+ LONGLONG space;
+ BOOL ret;
+ int i, j;
+ HINF inf;
+
+ if (!GetTempPathA(MAX_PATH, tmp))
+ {
+ win_skip("GetTempPath failed with error %d\n", GetLastError());
+ return;
+ }
+
+ if (!GetTempFileNameA(tmp, "inftest", 0, tmpfilename))
+ {
+ win_skip("GetTempFileNameA failed with error %d\n", GetLastError());
+ return;
+ }
+
+ inf = inf_open_file_content(tmpfilename, STD_HEADER "[a]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", &err_line);
+ ok(!!inf, "Failed to open inf file (%d, line %d)\n", GetLastError(), err_line);
+
+ diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
+ ok(diskspace != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n");
+
+ ret = SetupAddSectionToDiskSpaceListA(diskspace, NULL, NULL, "a", FILEOP_COPY, 0, 0);
+ ok(!ret, "Expected SetupAddSectionToDiskSpaceListA to fail\n");
+ ok(GetLastError() == ERROR_SECTION_NOT_FOUND, "Expected ERROR_SECTION_NOT_FOUND as error, got %u\n",
+ GetLastError());
+
+ ret = SetupAddSectionToDiskSpaceListA(NULL, inf, NULL, "a", FILEOP_COPY, 0, 0);
+ ok(!ret, "Expected SetupAddSectionToDiskSpaceListA to fail\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE as error, got %u\n",
+ GetLastError());
+
+ ret = SetupAddSectionToDiskSpaceListA(NULL, inf, NULL, "b", FILEOP_COPY, 0, 0);
+ ok(!ret, "Expected SetupAddSectionToDiskSpaceListA to fail\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE as error, got %u\n",
+ GetLastError());
+
+ ret = SetupAddSectionToDiskSpaceListA(diskspace, inf, NULL, "a", 0, 0, 0);
+ ok(ret, "Expected SetupAddSectionToDiskSpaceListA to succeed (%u)\n", GetLastError());
+
+ ok(SetupDestroyDiskSpaceList(diskspace),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ for (i = 0; i < sizeof(section_test) / sizeof(section_test[0]); i++)
+ {
+ err_line = 0;
+
+ inf = inf_open_file_content(tmpfilename, section_test[i].data, &err_line);
+ ok(!!inf, "test %d: Failed to open inf file (%d, line %d)\n", i, GetLastError(), err_line);
+ if (!inf) continue;
+
+ diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
+ ok(diskspace != NULL, "Expected SetupCreateDiskSpaceListA to return a valid handle\n");
+
+ for (j = 0; j < 2; j++)
+ {
+ const struct section *section = &section_test[i].sections[j];
+ if (!section->name)
+ continue;
+
+ SetLastError(0xdeadbeef);
+ ret = SetupAddSectionToDiskSpaceListA(diskspace, inf, NULL, section->name, section->fileop, 0, 0);
+ if (section->result)
+ ok(ret, "test %d: Expected adding section %d to succeed (%u)\n", i, j, GetLastError());
+ else
+ {
+ ok(!ret, "test %d: Expected adding section %d to fail\n", i, j);
+ ok(GetLastError() == section->error_code, "test %d: Expected %u as error, got %u\n",
+ i, section->error_code, GetLastError());
+ }
+ }
+
+ memset(buffer, 0x0, sizeof(buffer));
+ ret = SetupQueryDrivesInDiskSpaceListA(diskspace, buffer, sizeof(buffer), NULL);
+ ok(ret, "test %d: Expected SetupQueryDrivesInDiskSpaceListA to succeed (%u)\n", i, GetLastError());
+ ok(!memcmp(section_test[i].devices, buffer, section_test[i].device_length),
+ "test %d: Device list (%s) does not match\n", i, buffer);
+
+ for (j = 0; j < 2; j++)
+ {
+ const struct device_usage *usage = &section_test[i].usage[j];
+ if (!usage->dev)
+ continue;
+
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(diskspace, usage->dev, &space, NULL, 0);
+ ok(ret, "test %d: Expected SetupQuerySpaceRequiredOnDriveA to succeed for device %s (%u)\n",
+ i, usage->dev, GetLastError());
+ ok(space == usage->usage, "test %d: Expected size %u for device %s, got %u\n",
+ i, (DWORD)usage->usage, usage->dev, (DWORD)space);
+ }
+
+ ok(SetupDestroyDiskSpaceList(diskspace),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ SetupCloseInfFile(inf);
+ }
+
+ DeleteFileA(tmpfilename);
}
START_TEST(diskspace)
@@ -767,4 +959,5 @@ START_TEST(diskspace)
test_SetupQuerySpaceRequiredOnDriveW();
test_SetupAddToDiskSpaceListA();
test_SetupQueryDrivesInDiskSpaceListA();
+ test_SetupAddSectionToDiskSpaceListA();
}
--
2.7.1

View File

@ -0,0 +1,331 @@
From f0a9b4d7def2704e971966ac9eccca613e636c6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Mar 2016 04:54:37 +0100
Subject: setupapi: Implement SetupAddInstallSectionToDiskSpaceList.
---
dlls/setupapi/diskspace.c | 87 +++++++++++++++++++-
dlls/setupapi/setupapi.spec | 2 +-
dlls/setupapi/tests/diskspace.c | 170 ++++++++++++++++++++++++++++++++++++++++
include/setupapi.h | 3 +
4 files changed, 257 insertions(+), 5 deletions(-)
diff --git a/dlls/setupapi/diskspace.c b/dlls/setupapi/diskspace.c
index 2159ab9..626758b 100644
--- a/dlls/setupapi/diskspace.c
+++ b/dlls/setupapi/diskspace.c
@@ -295,15 +295,94 @@ BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC diskspace, HINF hinf, HINF h
/***********************************************************************
* SetupAddInstallSectionToDiskSpaceListW (SETUPAPI.@)
*/
-BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace,
- HINF InfHandle, HINF LayoutInfHandle,
- LPCSTR SectionName, PVOID Reserved1, UINT Reserved2)
+BOOL WINAPI SetupAddInstallSectionToDiskSpaceListW(HDSKSPC diskspace,
+ HINF inf, HINF layoutinf, LPCWSTR section,
+ PVOID reserved1, UINT reserved2)
{
- FIXME ("Stub\n");
+ static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0};
+ static const WCHAR DelFiles[] = {'D','e','l','F','i','l','e','s',0};
+ WCHAR section_name[MAX_PATH];
+ INFCONTEXT context;
+ BOOL ret;
+ int i;
+
+ TRACE("(%p, %p, %p, %s, %p, %u)\n", diskspace, inf, layoutinf, debugstr_w(section),
+ reserved1, reserved2);
+
+ if (!diskspace)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (!section)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!inf) return TRUE;
+ if (!layoutinf) layoutinf = inf;
+
+ ret = SetupFindFirstLineW(inf, section, CopyFiles, &context);
+ while (ret)
+ {
+ for (i = 1;; i++)
+ {
+ if (!SetupGetStringFieldW(&context, i, section_name, sizeof(section_name) / sizeof(WCHAR), NULL))
+ break;
+ SetupAddSectionToDiskSpaceListW(diskspace, layoutinf, inf, section_name, FILEOP_COPY, 0, 0);
+ }
+ ret = SetupFindNextLine(&context, &context);
+ }
+
+ ret = SetupFindFirstLineW(inf, section, DelFiles, &context);
+ while (ret)
+ {
+ for (i = 1;; i++)
+ {
+ if (!SetupGetStringFieldW(&context, i, section_name, sizeof(section_name) / sizeof(WCHAR), NULL))
+ break;
+ SetupAddSectionToDiskSpaceListW(diskspace, layoutinf, inf, section_name, FILEOP_DELETE, 0, 0);
+ }
+ ret = SetupFindNextLine(&context, &context);
+ }
+
return TRUE;
}
/***********************************************************************
+ * SetupAddInstallSectionToDiskSpaceListA (SETUPAPI.@)
+ */
+BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC diskspace,
+ HINF inf, HINF layoutinf, LPCSTR section,
+ PVOID reserved1, UINT reserved2)
+{
+ LPWSTR sectionW = NULL;
+ DWORD len;
+ BOOL ret;
+
+ if (section)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, section, -1, NULL, 0);
+
+ sectionW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!sectionW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, section, -1, sectionW, len);
+ }
+
+ ret = SetupAddInstallSectionToDiskSpaceListW(diskspace, inf, layoutinf,
+ sectionW, reserved1, reserved2);
+ if (sectionW) HeapFree(GetProcessHeap(), 0, sectionW);
+ return ret;
+}
+
+/***********************************************************************
* SetupQuerySpaceRequiredOnDriveW (SETUPAPI.@)
*/
BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC diskspace,
diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec
index 5554d16..adebf28 100644
--- a/dlls/setupapi/setupapi.spec
+++ b/dlls/setupapi/setupapi.spec
@@ -243,7 +243,7 @@
@ stub SearchForInfFile
@ stub SetArrayToMultiSzValue
@ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long)
-@ stub SetupAddInstallSectionToDiskSpaceListW
+@ stdcall SetupAddInstallSectionToDiskSpaceListW(long long long wstr ptr long)
@ stdcall SetupAddSectionToDiskSpaceListA(long long long str long ptr long)
@ stdcall SetupAddSectionToDiskSpaceListW(long long long wstr long ptr long)
@ stdcall SetupAddToDiskSpaceListA(long str int64 long ptr long)
diff --git a/dlls/setupapi/tests/diskspace.c b/dlls/setupapi/tests/diskspace.c
index f40506c..c2c714e 100644
--- a/dlls/setupapi/tests/diskspace.c
+++ b/dlls/setupapi/tests/diskspace.c
@@ -947,6 +947,175 @@ static void test_SetupAddSectionToDiskSpaceListA(void)
DeleteFileA(tmpfilename);
}
+struct section_i
+{
+ const char *name;
+ BOOL result;
+ DWORD error_code;
+};
+
+static const struct
+{
+ const char *data;
+ struct section_i sections[2];
+ const char *devices;
+ int device_length;
+ struct device_usage usage[2];
+}
+section_test_i[] =
+{
+ /* 0 */
+ {STD_HEADER "[a.Install]\nCopyFiles=a.CopyFiles\n"
+ "[a.CopyFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a.Install", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 1 */
+ {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\n"
+ "[a.CopyFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 2 */
+ {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\nCopyFiles=a.CopyFiles2\n"
+ "[a.CopyFiles]\ntest,,,\n[a.CopyFiles2]\ntest2,,,\n"
+ "[SourceDisksFiles]\ntest=1,,4096\ntest2=1,,4096\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}},
+ /* 3 */
+ {STD_HEADER "[a]\nCopyFiles=a.CopyFiles,a.CopyFiles2\n"
+ "[a.CopyFiles]\ntest,,,\n[a.CopyFiles2]\ntest2,,,\n"
+ "[SourceDisksFiles]\ntest=1,,4096\ntest2=1,,4096\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 8192}, {NULL, 0}}},
+ /* 4 */
+ {STD_HEADER "[a]\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}},
+ /* 5 */
+ {STD_HEADER "[a]\nDelFiles=a.DelFiles\n"
+ "[a.nDelFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}},
+ /* 6 */
+ {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\nDelFiles=a.DelFiles\n"
+ "[a.CopyFiles]\ntest,,,\n[a.DelFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 7 */
+ {STD_HEADER "[a]\nCopyFiles=a.CopyFiles\n[b]\nDelFiles=b.DelFiles\n"
+ "[a.CopyFiles]\ntest,,,\n[b.DelFiles]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n",
+ {{"a", TRUE, 0}, {"b", TRUE, 0}}, "c:\00", sizeof("c:\00"), {{"c:", 4096}, {NULL, 0}}},
+ /* 7 */
+ {STD_HEADER "[a]\nCopyFiles=\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}},
+ /* 8 */
+ {STD_HEADER "[a]\nCopyFiles=something\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "", sizeof(""), {{NULL, 0}, {NULL, 0}}},
+ /* 9 */
+ {STD_HEADER "[a]\nCopyFiles=a.CopyFiles,b.CopyFiles\n[a.CopyFiles]\ntest,,,\n[b.CopyFiles]\ntest,,,\n"
+ "[SourceDisksFiles]\ntest=1,,4096\n[DestinationDirs]\nb.CopyFiles=-1,F:\\test\r\n",
+ {{"a", TRUE, 0}, {NULL, TRUE, 0}}, "c:\00f:\00", sizeof("c:\00f:\00"), {{"c:", 4096}, {"f:", 4096}}},
+};
+
+static void test_SetupAddInstallSectionToDiskSpaceListA(void)
+{
+ char tmp[MAX_PATH];
+ char tmpfilename[MAX_PATH];
+ char buffer[MAX_PATH];
+ HDSKSPC diskspace;
+ LONGLONG space;
+ UINT err_line;
+ BOOL ret;
+ int i, j;
+ HINF inf;
+
+ if (!GetTempPathA(MAX_PATH, tmp))
+ {
+ win_skip("GetTempPath failed with error %d\n", GetLastError());
+ return;
+ }
+
+ if (!GetTempFileNameA(tmp, "inftest", 0, tmpfilename))
+ {
+ win_skip("GetTempFileNameA failed with error %d\n", GetLastError());
+ return;
+ }
+
+ inf = inf_open_file_content(tmpfilename, STD_HEADER "[a]\nCopyFiles=b\n[b]\ntest,,,\n[SourceDisksFiles]\ntest=1,,4096\r\n", &err_line);
+ ok(!!inf, "Failed to open inf file (%d, line %d)\n", GetLastError(), err_line);
+
+ diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
+ ok(diskspace != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n");
+
+ ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, NULL, NULL, "a", 0, 0);
+ ok(ret, "Expected SetupAddInstallSectionToDiskSpaceListA to succeed\n");
+
+ ret = SetupAddInstallSectionToDiskSpaceListA(NULL, inf, NULL, "a", 0, 0);
+ ok(!ret, "Expected SetupAddInstallSectionToDiskSpaceListA to fail\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE as error, got %u\n",
+ GetLastError());
+
+ ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, inf, NULL, NULL, 0, 0);
+ ok(!ret || broken(ret), "Expected SetupAddSectionToDiskSpaceListA to fail\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(ret),
+ "Expected ERROR_INVALID_PARAMETER as error, got %u\n", GetLastError());
+
+ ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, inf, NULL, "", 0, 0);
+ ok(ret, "Expected SetupAddInstallSectionToDiskSpaceListA to succeed (%u)\n", GetLastError());
+
+ ok(SetupDestroyDiskSpaceList(diskspace),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ for (i = 0; i < sizeof(section_test_i) / sizeof(section_test_i[0]); i++)
+ {
+ err_line = 0;
+
+ inf = inf_open_file_content(tmpfilename, section_test_i[i].data, &err_line);
+ ok(!!inf, "test %d: Failed to open inf file (%d, line %d)\n", i, GetLastError(), err_line);
+ if (!inf) continue;
+
+ diskspace = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
+ ok(diskspace != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n");
+
+ for (j = 0; j < 2; j++)
+ {
+ const struct section_i *section = &section_test_i[i].sections[j];
+ if (!section->name)
+ continue;
+
+ SetLastError(0xdeadbeef);
+ ret = SetupAddInstallSectionToDiskSpaceListA(diskspace, inf, NULL, section->name, 0, 0);
+ if (section->result)
+ ok(ret, "test %d: Expected adding section %d to succeed (%u)\n", i, j, GetLastError());
+ else
+ {
+ ok(!ret, "test %d: Expected adding section %d to fail\n", i, j);
+ ok(GetLastError() == section->error_code, "test %d: Expected %u as error, got %u\n",
+ i, section->error_code, GetLastError());
+ }
+ }
+
+ memset(buffer, 0x0, sizeof(buffer));
+ ret = SetupQueryDrivesInDiskSpaceListA(diskspace, buffer, sizeof(buffer), NULL);
+ ok(ret, "test %d: Expected SetupQueryDrivesInDiskSpaceListA to succeed (%u)\n", i, GetLastError());
+ ok(!memcmp(section_test_i[i].devices, buffer, section_test_i[i].device_length),
+ "test %d: Device list (%s) does not match\n", i, buffer);
+
+ for (j = 0; j < 2; j++)
+ {
+ const struct device_usage *usage = &section_test_i[i].usage[j];
+ if (!usage->dev)
+ continue;
+
+ space = 0;
+ ret = SetupQuerySpaceRequiredOnDriveA(diskspace, usage->dev, &space, NULL, 0);
+ ok(ret, "test %d: Expected SetupQuerySpaceRequiredOnDriveA to succeed for device %s (%u)\n",
+ i, usage->dev, GetLastError());
+ ok(space == usage->usage, "test %d: Expected size %u for device %s, got %u\n",
+ i, (DWORD)usage->usage, usage->dev, (DWORD)space);
+ }
+
+ ok(SetupDestroyDiskSpaceList(diskspace),
+ "Expected SetupDestroyDiskSpaceList to succeed\n");
+
+ SetupCloseInfFile(inf);
+ }
+
+ DeleteFileA(tmpfilename);
+}
+
START_TEST(diskspace)
{
is_win9x = !SetupCreateDiskSpaceListW((void *)0xdeadbeef, 0xdeadbeef, 0) &&
@@ -960,4 +1129,5 @@ START_TEST(diskspace)
test_SetupAddToDiskSpaceListA();
test_SetupQueryDrivesInDiskSpaceListA();
test_SetupAddSectionToDiskSpaceListA();
+ test_SetupAddInstallSectionToDiskSpaceListA();
}
diff --git a/include/setupapi.h b/include/setupapi.h
index 0d6911d..229e37d 100644
--- a/include/setupapi.h
+++ b/include/setupapi.h
@@ -1415,6 +1415,9 @@ DWORD WINAPI OpenAndMapForRead(PCWSTR, PDWORD, PHANDLE, PHANDLE, PVOID *);
LONG WINAPI QueryRegistryValue(HKEY, PCWSTR, PBYTE *, PDWORD, PDWORD);
/* RetreiveFileSecurity is not a typo, as per Microsoft's dlls */
DWORD WINAPI RetreiveFileSecurity(PCWSTR, PSECURITY_DESCRIPTOR *);
+BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, PVOID, UINT);
+BOOL WINAPI SetupAddInstallSectionToDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, PVOID, UINT);
+#define SetupAddInstallSectionToDiskSpaceList WINELIB_NAME_AW(SetupAddInstallSectionToDiskSpaceList)
BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC, HINF, HINF, PCSTR, UINT, PVOID, UINT);
BOOL WINAPI SetupAddSectionToDiskSpaceListW(HDSKSPC, HINF, HINF, PCWSTR, UINT, PVOID, UINT);
#define SetupAddSectionToDiskSpaceList WINELIB_NAME_AW(SetupAddSectionToDiskSpaceList)
--
2.7.1

View File

@ -1,2 +1,3 @@
Fixes: Add implementation for setupapi.SetupAddToDiskSpaceListA/W
Fixes: Add implementation for setupapi.SetupQueryDrivesInDiskSpaceListA/W
Fixes: Add implementation for setupapi.SetupAdd{Install}SectionToDiskSpaceListA/W