From: Vijay Kiran Kamuju Subject: [PATCH 6/6] setupapi: Implement SetupAddInstallSectionToDiskSpaceList. Message-Id: <20191019084451.1648-6-infyquest@gmail.com> Date: Sat, 19 Oct 2019 10:44:51 +0200 In-Reply-To: <20191019084451.1648-1-infyquest@gmail.com> References: <20191019084451.1648-1-infyquest@gmail.com> From: Michael Müller From: Michael Müller Signed-off-by: Vijay Kiran Kamuju --- 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 3153a18856a9..39673cd63b50 100644 --- a/dlls/setupapi/diskspace.c +++ b/dlls/setupapi/diskspace.c @@ -294,14 +294,93 @@ 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.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index ad8652ac93b3..1d09b0e7e577 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 f40506c4b36f..c2c714eecd9f 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 = §ion_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 = §ion_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 818cc12599a4..e54c6c227f67 100644 --- a/include/setupapi.h +++ b/include/setupapi.h @@ -1416,6 +1416,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.21.0