[SETUPAPI_WINETEST] Sync with Wine Staging 1.9.11. CORE-11368
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 3 Jul 2016 11:54:30 +0000 (11:54 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 3 Jul 2016 11:54:30 +0000 (11:54 +0000)
svn path=/trunk/; revision=71787

rostests/winetests/setupapi/CMakeLists.txt
rostests/winetests/setupapi/diskspace.c
rostests/winetests/setupapi/install.c
rostests/winetests/setupapi/parser.c
rostests/winetests/setupapi/setupapi.manifest [new file with mode: 0644]
rostests/winetests/setupapi/setupapi.rc [new file with mode: 0644]
rostests/winetests/setupapi/setupcab.c

index c314cff..638322b 100644 (file)
@@ -11,7 +11,7 @@ list(APPEND SOURCE
     stringtable.c
     testlist.c)
 
-add_executable(setupapi_winetest ${SOURCE})
+add_executable(setupapi_winetest ${SOURCE} setupapi.rc)
 set_module_type(setupapi_winetest win32cui)
-add_importlibs(setupapi_winetest advapi32 setupapi user32 msvcrt kernel32)
+add_importlibs(setupapi_winetest advapi32 setupapi user32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET setupapi_winetest DESTINATION reactos/bin FOR all)
index 4e87ea9..c2c714e 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <stdarg.h>
+#include <stdio.h>
 
 #include "windef.h"
 #include "winbase.h"
 
 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];
+    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;
+}
+
+/* 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;
@@ -300,11 +325,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 +414,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 +426,155 @@ 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 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");
+
+    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");
+
+    /* 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");
+
+    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");
+
+    /* 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");
+
+    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));
+
+    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");
 }
@@ -472,6 +666,456 @@ 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");
+}
+
+static void test_SetupQueryDrivesInDiskSpaceListA(void)
+{
+    char buffer[MAX_PATH];
+    HDSKSPC handle;
+    DWORD size;
+    BOOL ret;
+
+    handle = SetupCreateDiskSpaceListA(NULL, 0, SPDSL_IGNORE_DISK);
+    ok(handle != NULL,"Expected SetupCreateDiskSpaceListA to return a valid handle\n");
+
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, NULL, 0, NULL);
+    ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n");
+
+    size = 0;
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, NULL, 0, &size);
+    ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n");
+    ok(size == 1, "Expected size 1, got %u\n", size);
+
+    ret = SetupAddToDiskSpaceListA(handle, "F:\\random-file.dat", 0, FILEOP_COPY, 0, 0);
+    ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+    ret = SetupAddToDiskSpaceListA(handle, "G:\\random-file.dat", 0, FILEOP_COPY, 0, 0);
+    ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+    ret = SetupAddToDiskSpaceListA(handle, "G:\\random-file2.dat", 0, FILEOP_COPY, 0, 0);
+    ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+    ret = SetupAddToDiskSpaceListA(handle, "X:\\random-file.dat", 0, FILEOP_COPY, 0, 0);
+    ok(ret, "Expected SetupAddToDiskSpaceListA to succeed\n");
+
+    size = 0;
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, NULL, 0, &size);
+    ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n");
+    ok(size == 10, "Expected size 10, got %u\n", size);
+
+    size = 0;
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, 0, &size);
+    ok(!ret, "Expected SetupQueryDrivesInDiskSpaceListA to fail\n");
+    ok(size == 4, "Expected size 4, got %u\n", size);
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+
+    size = 0;
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, 4, &size);
+    ok(!ret, "Expected SetupQueryDrivesInDiskSpaceListA to fail\n");
+    ok(size == 7, "Expected size 7, got %u\n", size);
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+
+    size = 0;
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, 7, &size);
+    ok(!ret, "Expected SetupQueryDrivesInDiskSpaceListA to fail\n");
+    ok(size == 10, "Expected size 10, got %u\n", size);
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+       "Expected GetLastError() to return ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
+
+    size = 0;
+    memset(buffer, 0xff, sizeof(buffer));
+    ret = SetupQueryDrivesInDiskSpaceListA(handle, buffer, sizeof(buffer), &size);
+    ok(ret, "Expected SetupQueryDrivesInDiskSpaceListA to succeed\n");
+    ok(size == 10, "Expected size 10, got %u\n", size);
+    ok(!memcmp("f:\0g:\0x:\0\0", buffer, 10), "Device list does not match\n");
+
+    memset(buffer, 0xff, sizeof(buffer));
+    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);
+}
+
+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) &&
@@ -482,4 +1126,8 @@ START_TEST(diskspace)
     test_SetupDuplicateDiskSpaceListW();
     test_SetupQuerySpaceRequiredOnDriveA();
     test_SetupQuerySpaceRequiredOnDriveW();
+    test_SetupAddToDiskSpaceListA();
+    test_SetupQueryDrivesInDiskSpaceListA();
+    test_SetupAddSectionToDiskSpaceListA();
+    test_SetupAddInstallSectionToDiskSpaceListA();
 }
index d12d683..e09ac8e 100644 (file)
@@ -174,7 +174,6 @@ static void test_registry(void)
 
     /* Check if the registry key is recursively deleted */
     res = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest", &key);
-    todo_wine
     ok(res == ERROR_FILE_NOT_FOUND, "Didn't expect the registry key to exist\n");
     /* Just in case */
     if (res == ERROR_SUCCESS)
index c2d554a..67c9887 100644 (file)
@@ -133,6 +133,18 @@ static const struct
     { STD_HEADER " [Test\x00Section]\n",                     ERROR_BAD_SECTION_NAME_LINE, 3,    FALSE },
     { STD_HEADER " [TestSection\x00]\n",                     ERROR_BAD_SECTION_NAME_LINE, 3,    FALSE },
     { STD_HEADER " [Test\x00Section]\n",                     ERROR_BAD_SECTION_NAME_LINE, 3,    FALSE },
+    { "garbage1\ngarbage2\n[abc]\n" STD_HEADER,              ERROR_EXPECTED_SECTION_NAME, 1,    FALSE },
+    { "garbage1\ngarbage2\n[Strings]\n" STD_HEADER,          0,                           0,    FALSE },
+    { ";comment\ngarbage1\ngarbage2\n[abc]\n" STD_HEADER,    ERROR_EXPECTED_SECTION_NAME, 2,    FALSE },
+    { ";comment\ngarbage1\ngarbage2\n[Strings]\n" STD_HEADER, 0,                          0,    FALSE },
+    { " \t\ngarbage1\ngarbage2\n[abc]\n" STD_HEADER,         ERROR_EXPECTED_SECTION_NAME, 2,    FALSE },
+    { " \t\ngarbage1\ngarbage2\n[Strings]\n" STD_HEADER,     0,                           0,    FALSE },
+    { "garbage1\ngarbage2\n" STD_HEADER "[abc]\n",           ERROR_EXPECTED_SECTION_NAME, 1,    FALSE },
+    { "garbage1\ngarbage2\n" STD_HEADER "[Strings]\n",       0,                           0,    FALSE },
+    { ";comment\ngarbage1\ngarbage2\n" STD_HEADER "[abc]\n", ERROR_EXPECTED_SECTION_NAME, 2,    FALSE },
+    { ";comment\ngarbage1\ngarbage2\n" STD_HEADER "[Strings]\n", 0,                       0,    FALSE },
+    { " \t\ngarbage1\ngarbage2\n" STD_HEADER "[abc]\n",      ERROR_EXPECTED_SECTION_NAME, 2,    FALSE },
+    { " \t\ngarbage1\ngarbage2\n" STD_HEADER "[Strings]\n",  0,                           0,    FALSE },
 };
 
 static void test_invalid_files(void)
@@ -152,14 +164,7 @@ static void test_invalid_files(void)
         if (invalid_files[i].error)  /* should fail */
         {
             ok( hinf == INVALID_HANDLE_VALUE, "file %u: Open succeeded\n", i );
-            if (invalid_files[i].todo) todo_wine
-            {
-                ok( err == invalid_files[i].error, "file %u: Bad error %u/%u\n",
-                    i, err, invalid_files[i].error );
-                ok( err_line == invalid_files[i].err_line, "file %u: Bad error line %d/%d\n",
-                    i, err_line, invalid_files[i].err_line );
-            }
-            else
+            todo_wine_if (invalid_files[i].todo)
             {
                 ok( err == invalid_files[i].error, "file %u: Bad error %u/%u\n",
                     i, err, invalid_files[i].error );
diff --git a/rostests/winetests/setupapi/setupapi.manifest b/rostests/winetests/setupapi/setupapi.manifest
new file mode 100644 (file)
index 0000000..d0e3692
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+    <assemblyIdentity type="win32" name="Wine.SetupapiTest" version="0.0.0.0"/>
+    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+        <security>
+            <requestedPrivileges>
+                <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+            </requestedPrivileges>
+        </security>
+    </trustInfo>
+</assembly>
diff --git a/rostests/winetests/setupapi/setupapi.rc b/rostests/winetests/setupapi/setupapi.rc
new file mode 100644 (file)
index 0000000..3af9a20
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * setupapi test resources
+ *
+ * Copyright 2015 Vincent Povirk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#include <winuser.rh>
+
+/* @makedep: setupapi.manifest */
+1 RT_MANIFEST setupapi.manifest
index 6c76321..33daae9 100644 (file)
@@ -115,19 +115,10 @@ static void test_invalid_parametersA(void)
         ret = SetupIterateCabinetA(invalid_parameters[i].CabinetFile, 0,
                                    invalid_parameters[i].MsgHandler, NULL);
         ok(!ret, "[%d] Expected SetupIterateCabinetA to return 0, got %d\n", i, ret);
-        if (invalid_parameters[i].todo_lasterror)
-        {
-            todo_wine
-            ok(GetLastError() == invalid_parameters[i].expected_lasterror,
-               "[%d] Expected GetLastError() to return %u, got %u\n",
-               i, invalid_parameters[i].expected_lasterror, GetLastError());
-        }
-        else
-        {
+        todo_wine_if (invalid_parameters[i].todo_lasterror)
             ok(GetLastError() == invalid_parameters[i].expected_lasterror,
                "[%d] Expected GetLastError() to return %u, got %u\n",
                i, invalid_parameters[i].expected_lasterror, GetLastError());
-        }
     }
 
     SetLastError(0xdeadbeef);
@@ -190,19 +181,10 @@ static void test_invalid_parametersW(void)
         ret = SetupIterateCabinetW(invalid_parameters[i].CabinetFile, 0,
                                    invalid_parameters[i].MsgHandler, NULL);
         ok(!ret, "[%d] Expected SetupIterateCabinetW to return 0, got %d\n", i, ret);
-        if (invalid_parameters[i].todo_lasterror)
-        {
-            todo_wine
-            ok(GetLastError() == invalid_parameters[i].expected_lasterror,
-               "[%d] Expected GetLastError() to return %u, got %u\n",
-               i, invalid_parameters[i].expected_lasterror, GetLastError());
-        }
-        else
-        {
+        todo_wine_if (invalid_parameters[i].todo_lasterror)
             ok(GetLastError() == invalid_parameters[i].expected_lasterror,
                "[%d] Expected GetLastError() to return %u, got %u\n",
                i, invalid_parameters[i].expected_lasterror, GetLastError());
-        }
     }
 
     SetLastError(0xdeadbeef);