static void test_saxstr(unsigned line, const WCHAR *szStr, int nStr, const char *szTest) { WCHAR buf[1024]; int len; if(!szTest) { ok_(__FILE__,line) (szStr == NULL, "szStr != NULL\n"); ok_(__FILE__,line) (nStr == 0, "nStr = %d, expected 0\n", nStr); return; } len = strlen(szTest); ok_(__FILE__,line) (len == nStr, "nStr = %d, expected %d (%s)\n", nStr, len, szTest); if(len != nStr) return; MultiByteToWideChar(CP_ACP, 0, szTest, -1, buf, sizeof(buf)/sizeof(WCHAR)); ok_(__FILE__,line) (!memcmp(szStr, buf, len*sizeof(WCHAR)), "unexpected szStr %s, expected %s\n", wine_dbgstr_wn(szStr, nStr), szTest); }
static void test_GetStateText(void) { WCHAR buf[1024], buf2[1024]; char bufa[1024]; void *ptr; UINT ret, ret2; int i; ret2 = GetStateTextW(0, NULL, 1024); ok(ret2, "GetStateText failed\n"); ptr = NULL; ret = GetStateTextW(0, (WCHAR*)&ptr, 0); ok(ret == ret2, "got %d, expected %d\n", ret, ret2); ok(ptr != NULL, "ptr was not changed\n"); ret = GetStateTextW(0, buf, 1024); ok(ret == ret2, "got %d, expected %d\n", ret, ret2); ok(!memcmp(buf, ptr, ret*sizeof(WCHAR)), "got %s, expected %s\n", wine_dbgstr_wn(buf, ret), wine_dbgstr_wn(ptr, ret)); ret = GetStateTextW(0, buf, 1); ok(!ret, "got %d, expected 0\n", ret); ok(!buf[0], "buf[0] = '%c'\n", buf[0]); for(i=0; i<31; i++) { ret = GetStateTextW(1<<i, buf, 1024); ok(ret, "%d) GetStateText failed\n", i); } ret = GetStateTextW(1u<<31, buf, 1024); ok(!ret, "31) GetStateText succeeded: %d\n", ret); ret = GetStateTextW(2, buf, 1024); ok(ret, "GetStateText failed\n"); ret2 = GetStateTextW(3, buf2, 1024); ok(ret2, "GetStateText failed\n"); ok(ret == ret2, "got %d, expected %d\n", ret2, ret); ok(!memcmp(buf, buf2, ret*sizeof(WCHAR)), "GetStateText(2,...) returned different data than GetStateText(3,...)\n"); ret2 = GetStateTextA(0, NULL, 1024); ok(ret2, "GetStateText failed\n"); ptr = NULL; ret = GetStateTextA(0, (CHAR*)&ptr, 0); ok(!ret, "got %d\n", ret); ok(ptr == NULL, "ptr was changed\n"); ret = GetStateTextA(0, NULL, 0); ok(ret == ret2, "got %d, expected %d\n", ret, ret2); ret = GetStateTextA(0, bufa, 1024); ok(ret == ret2, "got %d, expected %d\n", ret, ret2); ret = GetStateTextA(0, bufa, 1); ok(!ret, "got %d, expected 0\n", ret); ok(!bufa[0], "bufa[0] = '%c'\n", bufa[0]); for(i=0; i<31; i++) { ret = GetStateTextA(1<<i, bufa, 1024); ok(ret, "%d) GetStateText failed\n", i); } ret = GetStateTextA(1u<<31, bufa, 1024); ok(!ret, "31) GetStateText succeeded: %d\n", ret); }
static void test_SQLGetPrivateProfileStringW(void) { static WCHAR testing[] = {'t','e','s','t','i','n','g',0}; static WCHAR wineodbc[] = {'w','i','n','e','o','d','b','c',0}; static WCHAR defaultval[] = {'d','e','f','a','u','l','t',0}; static WCHAR odbcini[] = {'O','D','B','C','.','I','N','I',0}; static WCHAR abcdini[] = {'a','b','c','d','.','I','N','I',0}; static WCHAR wine[] = {'w','i','n','e',0}; static WCHAR value[] = {'v','a','l','u','e',0}; static WCHAR empty[] = {0}; static WCHAR defaultX[] = {'d','e','f','a','u','l','t',0}; static WCHAR def[] = {'d','e','f',0}; static WCHAR value0[] = {'v','a','l','u','e','0','1','2','3','4','5','6','7','8','9',0}; static WCHAR testingvalue[] = {'t','e','s','t','i','n','g',0,'v','a','l','u','e',0}; int ret; WCHAR buffer[256] = {0}; LONG reg_ret; lstrcpyW(buffer, wine); ret = SQLGetPrivateProfileStringW(NULL, testing , defaultval, buffer, 256, odbcini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, wine), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); lstrcpyW(buffer, wine); ret = SQLGetPrivateProfileStringW(wineodbc, NULL , defaultval, buffer, 256, odbcini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, empty), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); lstrcpyW(buffer, value); ret = SQLGetPrivateProfileStringW(wineodbc, testing , NULL, buffer, 256, odbcini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, empty), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, buffer, 256, odbcini); ok(ret == lstrlenW(defaultX), "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, defaultX), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, buffer, 4, odbcini); ok(ret == lstrlenW(def), "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, def), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, buffer, 8, odbcini); ok(ret == lstrlenW(defaultX), "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, defaultX), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, NULL, 256, odbcini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); lstrcpyW(buffer, value); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, buffer, 0, odbcini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, value), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLWritePrivateProfileString("wineodbc", "testing" , "value0123456789", "abcd.ini"); ok(ret, "SQLWritePrivateProfileString failed\n"); if(ret) { HKEY hkey; ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, buffer, 256, abcdini); ok(ret == lstrlenW(value0), "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, value0), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, NULL, 0, abcdini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); ret = SQLGetPrivateProfileStringW(wineodbc, testing , defaultX, buffer, 7, abcdini); ok(ret == 6, "SQLGetPrivateProfileStringW returned %d\n", ret); lstrcpyW(buffer, wine); ret = SQLGetPrivateProfileStringW(wineodbc, NULL , empty, buffer, 10, abcdini); ok(ret == lstrlenW(testing)+1, "SQLGetPrivateProfileStringW returned %d\n", ret); ok(!lstrcmpW(buffer, testing), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); ret = SQLWritePrivateProfileString("wineodbc", "value" , "0", "abcd.ini"); ok(ret, "SQLWritePrivateProfileString failed\n"); lstrcpyW(buffer, wine); ret = SQLGetPrivateProfileStringW(wineodbc, NULL , empty, buffer, 256, abcdini); ok(ret == (lstrlenW(testing) + lstrlenW(value)+2), "SQLGetPrivateProfileStringW returned %d\n", ret); if(ret == (lstrlenW(testing) + lstrlenW(value)+2)) { ok(!memcmp(buffer, testingvalue, sizeof(testingvalue)), "incorrect string '%s'\n", wine_dbgstr_wn(buffer, ret)); } lstrcpyW(buffer, value); ret = SQLGetPrivateProfileStringW(wineodbc, NULL , empty, buffer, 10, abcdini); ok(ret == lstrlenW(testing)+1, "SQLGetPrivateProfileStringW returned %d\n", ret); if(ret >= lstrlenW(testing)+1) { ok(!lstrcmpW(buffer, testing), "incorrect string '%s'\n", wine_dbgstr_w(buffer)); } lstrcpyW(buffer, value); ret = SQLGetPrivateProfileStringW(wineodbc, NULL , empty, buffer, 2, abcdini); ok(ret == 0, "SQLGetPrivateProfileStringW returned %d\n", ret); reg_ret = RegOpenKeyExW(HKEY_CURRENT_USER, abcd_key, 0, KEY_READ, &hkey); ok(reg_ret == ERROR_SUCCESS, "RegOpenKeyExW failed\n"); if(reg_ret == ERROR_SUCCESS) { reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, abcd_key); ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed\n"); RegCloseKey(hkey); } /* Cleanup key */ reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, abcdini_key); ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed\n"); } }
static void test_utf7_decoding(void) { char input[32]; WCHAR output[32], expected[32]; int i, len, expected_len; static const signed char base64_decoding_table[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */ }; struct { /* inputs */ char src[32]; int srclen; WCHAR *dst; int dstlen; /* expected outputs */ WCHAR expected_dst[32]; int chars_written; int len; } tests[] = { /* tests string conversion with srclen=-1 */ { "+T2BZfQ-", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60,0x597D,0}, 3, 3 }, /* tests string conversion with srclen=-2 */ { "+T2BZfQ-", -2, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60,0x597D,0}, 3, 3 }, /* tests string conversion with dstlen=strlen(expected_dst) */ { "+T2BZfQ-", -1, output, 2, {0x4F60,0x597D}, 2, 0 }, /* tests string conversion with dstlen=strlen(expected_dst)+1 */ { "+T2BZfQ-", -1, output, 3, {0x4F60,0x597D,0}, 3, 3 }, /* tests string conversion with dstlen=strlen(expected_dst)+2 */ { "+T2BZfQ-", -1, output, 4, {0x4F60,0x597D,0}, 3, 3 }, /* tests dry run with dst=NULL and dstlen=0 */ { "+T2BZfQ-", -1, NULL, 0, {}, 0, 3 }, /* tests dry run with dst!=NULL and dstlen=0 */ { "+T2BZfQ-", -1, output, 0, {}, 0, 3 }, /* tests ill-formed UTF-7: 6 bits, not enough for a byte pair */ { "+T-+T-+T-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {'h','e','l','l','o',0}, 6, 6 }, /* tests ill-formed UTF-7: 12 bits, not enough for a byte pair */ { "+T2-+T2-+T2-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {'h','e','l','l','o',0}, 6, 6 }, /* tests ill-formed UTF-7: 18 bits, not a multiple of 16 and the last bit is a 1 */ { "+T2B-+T2B-+T2B-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9 }, /* tests ill-formed UTF-7: 24 bits, a multiple of 8 but not a multiple of 16 */ { "+T2BZ-+T2BZ-+T2BZ-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9 }, /* tests UTF-7 followed by characters that should be encoded but aren't */ { "+T2BZ-\x82\xFE", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60,0x0082,0x00FE,0}, 4, 4 }, /* tests srclen > strlen(src) */ { "a\0b", 4, output, sizeof(output) / sizeof(WCHAR) - 1, {'a',0,'b',0}, 4, 4 }, /* tests srclen < strlen(src) outside of a UTF-7 sequence */ { "hello", 2, output, sizeof(output) / sizeof(WCHAR) - 1, {'h','e'}, 2, 2 }, /* tests srclen < strlen(src) inside of a UTF-7 sequence */ { "+T2BZfQ-", 4, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60}, 1, 1 }, /* tests srclen < strlen(src) right at the beginning of a UTF-7 sequence */ { "hi+T2A-", 3, output, sizeof(output) / sizeof(WCHAR) - 1, {'h','i'}, 2, 2 }, /* tests srclen < strlen(src) right at the end of a UTF-7 sequence */ { "+T2A-hi", 5, output, sizeof(output) / sizeof(WCHAR) - 1, {0x4F60}, 1, 1 }, /* tests srclen < strlen(src) at the beginning of an escaped + sign */ { "hi+-", 3, output, sizeof(output) / sizeof(WCHAR) - 1, {'h','i'}, 2, 2 }, /* tests srclen < strlen(src) at the end of an escaped + sign */ { "+-hi", 2, output, sizeof(output) / sizeof(WCHAR) - 1, {'+'}, 1, 1 }, /* tests len=0 but no error */ { "+", 1, output, sizeof(output) / sizeof(WCHAR) - 1, {}, 0, 0 }, /* tests a single null char */ { "", -1, output, sizeof(output) / sizeof(WCHAR) - 1, {0}, 1, 1 }, /* tests a buffer that runs out while not decoding a UTF-7 sequence */ { "hello", -1, output, 2, {'h','e'}, 2, 0 }, /* tests a buffer that runs out in the middle of decoding a UTF-7 sequence */ { "+T2BZfQ-", -1, output, 1, {0x4F60}, 1, 0 } }; /* test which one-byte characters remove stray + signs */ for (i = 0; i < 256; i++) { sprintf(input, "+%c+AAA", i); memset(output, 0x23, sizeof(output) - sizeof(WCHAR)); output[sizeof(output) / sizeof(WCHAR) - 1] = 0; len = MultiByteToWideChar(CP_UTF7, 0, input, 7, output, sizeof(output) / sizeof(WCHAR) - 1); if (i == '-') { /* removes the - sign */ expected_len = 3; expected[0] = 0x002B; expected[1] = 0; expected[2] = 0; } else if (i <= 0x7F && base64_decoding_table[i] != -1) { /* absorbs the character into the base64 sequence */ expected_len = 2; expected[0] = (base64_decoding_table[i] << 10) | 0x03E0; expected[1] = 0; } else { /* removes the + sign */ expected_len = 3; expected[0] = i; expected[1] = 0; expected[2] = 0; } expected[expected_len] = 0x2323; ok(len == expected_len, "i=0x%02x: expected len=%i, got len=%i\n", i, expected_len, len); ok(memcmp(output, expected, (expected_len + 1) * sizeof(WCHAR)) == 0, "i=0x%02x: expected output=%s, got output=%s\n", i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1)); } /* test which one-byte characters terminate a sequence * also test whether the unfinished byte pair is discarded or not */ for (i = 0; i < 256; i++) { sprintf(input, "+B%c+AAA", i); memset(output, 0x23, sizeof(output) - sizeof(WCHAR)); output[sizeof(output) / sizeof(WCHAR) - 1] = 0; len = MultiByteToWideChar(CP_UTF7, 0, input, 8, output, sizeof(output) / sizeof(WCHAR) - 1); if (i == '-') { /* explicitly terminates */ expected_len = 2; expected[0] = 0; expected[1] = 0; } else if (i <= 0x7F) { if (base64_decoding_table[i] != -1) { /* absorbs the character into the base64 sequence */ expected_len = 3; expected[0] = 0x0400 | (base64_decoding_table[i] << 4) | 0x000F; expected[1] = 0x8000; expected[2] = 0; } else { /* implicitly terminates and discards the unfinished byte pair */ expected_len = 3; expected[0] = i; expected[1] = 0; expected[2] = 0; } } else { /* implicitly terminates but does not the discard unfinished byte pair */ expected_len = 3; expected[0] = i; expected[1] = 0x0400; expected[2] = 0; } expected[expected_len] = 0x2323; ok(len == expected_len, "i=0x%02x: expected len=%i, got len=%i\n", i, expected_len, len); ok(memcmp(output, expected, (expected_len + 1) * sizeof(WCHAR)) == 0, "i=0x%02x: expected output=%s, got output=%s\n", i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1)); } for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { memset(output, 0x23, sizeof(output) - sizeof(WCHAR)); output[sizeof(output) / sizeof(WCHAR) - 1] = 0; SetLastError(0xdeadbeef); len = MultiByteToWideChar(CP_UTF7, 0, tests[i].src, tests[i].srclen, tests[i].dst, tests[i].dstlen); tests[i].expected_dst[tests[i].chars_written] = 0x2323; if (!tests[i].len && tests[i].chars_written) { ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "tests[%i]: expected error=0x%x, got error=0x%x\n", i, ERROR_INSUFFICIENT_BUFFER, GetLastError()); } ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len); if (tests[i].dst) { ok(memcmp(tests[i].dst, tests[i].expected_dst, (tests[i].chars_written + 1) * sizeof(WCHAR)) == 0, "tests[%i]: expected dst=%s, got dst=%s\n", i, wine_dbgstr_wn(tests[i].expected_dst, tests[i].chars_written + 1), wine_dbgstr_wn(tests[i].dst, tests[i].chars_written + 1)); } } }
static void test_NtQueryDirectoryFile_case(void) { static const char testfile[] = "TesT"; static const WCHAR testfile_w[] = {'T','e','s','T'}; static int testfile_len = sizeof(testfile) - 1; static WCHAR testmask[] = {'t','e','s','t'}; OBJECT_ATTRIBUTES attr; UNICODE_STRING ntdirname; char testdir[MAX_PATH]; WCHAR testdir_w[MAX_PATH]; HANDLE dirh; UNICODE_STRING mask; IO_STATUS_BLOCK io; UINT data_size, data_len; BYTE data[8192]; FILE_BOTH_DIRECTORY_INFORMATION *dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)data; DWORD status; WCHAR *name; ULONG name_len; /* Clean up from prior aborted run, if any, then set up test files */ ok(GetTempPathA(MAX_PATH, testdir), "couldn't get temp dir\n"); strcat(testdir, "case.tmp"); tear_down_case_test(testdir); set_up_case_test(testdir); pRtlMultiByteToUnicodeN(testdir_w, sizeof(testdir_w), NULL, testdir, strlen(testdir) + 1); if (!pRtlDosPathNameToNtPathName_U(testdir_w, &ntdirname, NULL, NULL)) { ok(0, "RtlDosPathNametoNtPathName_U failed\n"); goto done; } InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL); data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]); status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdir, status, GetLastError()); if (status != STATUS_SUCCESS) { skip("can't test if we can't open the directory\n"); return; } mask.Buffer = testmask; mask.Length = mask.MaximumLength = sizeof(testmask); pNtQueryDirectoryFile(dirh, NULL, NULL, NULL, &io, data, data_size, FileBothDirectoryInformation, TRUE, &mask, FALSE); ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); data_len = io.Information; ok(data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n"); name = dir_info->FileName; name_len = dir_info->FileNameLength / sizeof(WCHAR); ok(name_len == testfile_len, "unexpected filename length %u\n", name_len); ok(!memcmp(name, testfile_w, testfile_len * sizeof(WCHAR)), "unexpected filename %s\n", wine_dbgstr_wn(name, name_len)); pNtClose(dirh); done: tear_down_case_test(testdir); pRtlFreeUnicodeString(&ntdirname); }
static void test_NtQueryDirectoryFile(void) { OBJECT_ATTRIBUTES attr; UNICODE_STRING ntdirname, mask; char testdirA[MAX_PATH]; WCHAR testdirW[MAX_PATH]; int i; IO_STATUS_BLOCK io; WCHAR short_name[12]; UINT data_size; BYTE data[8192]; FILE_BOTH_DIRECTORY_INFORMATION *fbdi = (FILE_BOTH_DIRECTORY_INFORMATION*)data; DWORD status; HANDLE dirh; /* Clean up from prior aborted run, if any, then set up test files */ ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n"); strcat(testdirA, "NtQueryDirectoryFile.tmp"); tear_down_attribute_test(testdirA); set_up_attribute_test(testdirA); pRtlMultiByteToUnicodeN(testdirW, sizeof(testdirW), NULL, testdirA, strlen(testdirA)+1); if (!pRtlDosPathNameToNtPathName_U(testdirW, &ntdirname, NULL, NULL)) { ok(0, "RtlDosPathNametoNtPathName_U failed\n"); goto done; } InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL); test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, TRUE); test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, FALSE); test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, TRUE); test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, FALSE); for (i = 0; testfiles[i].name; i++) { if (testfiles[i].nameW[0] == '.') continue; /* . and .. as masks are broken on Windows */ mask.Buffer = testfiles[i].nameW; mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR); test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE); test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, FALSE); test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, TRUE); test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE); } /* short path passed as mask */ status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE); ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA); if (status != STATUS_SUCCESS) { skip("can't test if we can't open the directory\n"); return; } mask.Buffer = testfiles[0].nameW; mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].nameW) * sizeof(WCHAR); data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]); pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, FileBothDirectoryInformation, TRUE, &mask, FALSE); ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); ok(fbdi->ShortName[0], "ShortName is empty\n"); mask.Length = mask.MaximumLength = fbdi->ShortNameLength; memcpy(short_name, fbdi->ShortName, mask.Length); mask.Buffer = short_name; pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size, FileBothDirectoryInformation, TRUE, &mask, TRUE); ok(U(io).Status == STATUS_SUCCESS, "failed to query directory status %x\n", U(io).Status); ok(fbdi->FileNameLength == strlen(testfiles[0].name)*sizeof(WCHAR) && !memcmp(fbdi->FileName, testfiles[0].nameW, fbdi->FileNameLength), "incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR))); pNtClose(dirh); done: tear_down_attribute_test(testdirA); pRtlFreeUnicodeString(&ntdirname); }
static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA, UNICODE_STRING *mask, BOOLEAN single_entry, BOOLEAN restart_flag) { HANDLE dirh; IO_STATUS_BLOCK io; UINT data_pos, data_size; UINT data_len; /* length of dir data */ BYTE data[8192]; /* directory data */ FILE_BOTH_DIRECTORY_INFORMATION *dir_info; DWORD status; int numfiles; int i; reset_found_files(); data_size = mask ? offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ) : sizeof(data); /* Read the directory and note which files are found */ status = pNtOpenFile( &dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DIRECTORY_FILE); ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdirA, status, GetLastError()); if (status != STATUS_SUCCESS) { skip("can't test if we can't open the directory\n"); return; } pNtQueryDirectoryFile( dirh, NULL, NULL, NULL, &io, data, data_size, FileBothDirectoryInformation, single_entry, mask, restart_flag ); ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); data_len = io.Information; ok (data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n"); data_pos = 0; numfiles = 0; while ((data_pos < data_len) && (numfiles < max_test_dir_size)) { dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos); tally_test_file(dir_info); if (dir_info->NextEntryOffset == 0) { pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size, FileBothDirectoryInformation, single_entry, mask, FALSE ); if (U(io).Status == STATUS_NO_MORE_FILES) break; ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status); data_len = io.Information; if (data_len < sizeof(FILE_BOTH_DIRECTORY_INFORMATION)) break; data_pos = 0; } else { data_pos += dir_info->NextEntryOffset; } numfiles++; } ok(numfiles < max_test_dir_size, "too many loops\n"); if (mask) for (i=0; testfiles[i].name; i++) ok(testfiles[i].nfound == (testfiles[i].nameW == mask->Buffer), "Wrong number %d of %s files found (single_entry=%d,mask=%s)\n", testfiles[i].nfound, testfiles[i].description, single_entry, wine_dbgstr_wn(mask->Buffer, mask->Length/sizeof(WCHAR) )); else for (i=0; testfiles[i].name; i++) ok(testfiles[i].nfound == 1, "Wrong number %d of %s files found (single_entry=%d,restart=%d)\n", testfiles[i].nfound, testfiles[i].description, single_entry, restart_flag); pNtClose(dirh); }