Author: cwittich Date: Wed Nov 11 08:36:49 2009 New Revision: 44098
URL: http://svn.reactos.org/svn/reactos?rev=44098&view=rev Log: sync shell32 winetest to wine 1.1.32
Modified: trunk/rostests/winetests/shell32/appbar.c trunk/rostests/winetests/shell32/shelllink.c trunk/rostests/winetests/shell32/shellpath.c trunk/rostests/winetests/shell32/shlexec.c trunk/rostests/winetests/shell32/shlfileop.c
Modified: trunk/rostests/winetests/shell32/appbar.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/shell32/appbar.c... ============================================================================== --- trunk/rostests/winetests/shell32/appbar.c [iso-8859-1] (original) +++ trunk/rostests/winetests/shell32/appbar.c [iso-8859-1] Wed Nov 11 08:36:49 2009 @@ -205,6 +205,7 @@ RECT rc; int screen_width, screen_height; BOOL ret; + int org_bottom1;
screen_width = GetSystemMetrics(SM_CXSCREEN); screen_height = GetSystemMetrics(SM_CYSCREEN); @@ -336,6 +337,9 @@
/* removing windows[0] will cause windows[1] to move down into its space */ expected_bottom = max(windows[0].allocated_rect.bottom, windows[1].allocated_rect.bottom); + org_bottom1 = windows[1].allocated_rect.bottom; + ok(windows[0].allocated_rect.bottom > windows[1].allocated_rect.bottom, + "Expected windows[0] to be lower than windows[1]\n");
abd.hWnd = windows[0].hwnd; windows[0].to_be_deleted = TRUE; @@ -346,7 +350,12 @@
do_events_until(got_expected_bottom);
- ok(windows[1].allocated_rect.bottom == expected_bottom, "windows[1]'s bottom is %i, expected %i\n", windows[1].allocated_rect.bottom, expected_bottom); + if (windows[1].allocated_rect.bottom == org_bottom1) + win_skip("Some broken Vista boxes don't move the higher appbar down\n"); + else + ok(windows[1].allocated_rect.bottom == expected_bottom, + "windows[1]'s bottom is %i, expected %i\n", + windows[1].allocated_rect.bottom, expected_bottom);
test_window_rects(1, 2);
Modified: trunk/rostests/winetests/shell32/shelllink.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/shell32/shelllin... ============================================================================== --- trunk/rostests/winetests/shell32/shelllink.c [iso-8859-1] (original) +++ trunk/rostests/winetests/shell32/shelllink.c [iso-8859-1] Wed Nov 11 08:36:49 2009 @@ -107,6 +107,7 @@ { HRESULT r; IShellLinkA *sl; + IShellLinkW *slW = NULL; char mypath[MAX_PATH]; char buffer[INFOTIPSIZE]; LPITEMIDLIST pidl, tmp_pidl; @@ -155,6 +156,19 @@ r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH); ok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r); ok(*buffer=='\0', "GetPath returned '%s'\n", buffer); + + CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, (LPVOID*)&slW); + if (!slW) + skip("SetPath with NULL parameter crashes on Win9x\n"); + else + { + IShellLinkW_Release(slW); + r = IShellLinkA_SetPath(sl, NULL); + ok(r==E_INVALIDARG || + broken(r==S_OK), /* Some Win95 and NT4 */ + "SetPath failed (0x%08x)\n", r); + }
r = IShellLinkA_SetPath(sl, ""); ok(r==S_OK, "SetPath failed (0x%08x)\n", r); @@ -651,16 +665,12 @@ static void test_datalink(void) { static const WCHAR lnk[] = { - ':',':','{','9','d','b','1','1','8','6','f','-','4','0','d','f','-','1', + ':',':','{','9','d','b','1','1','8','6','e','-','4','0','d','f','-','1', '1','d','1','-','a','a','8','c','-','0','0','c','0','4','f','b','6','7', - '8','6','3','}',':','{','0','0','0','1','0','4','0','9','-','7','8','E', - '1','-','1','1','D','2','-','B','6','0','F','-','0','0','6','0','9','7', - 'C','9','9','8','E','7','}',':',':','{','9','d','b','1','1','8','6','e', - '-','4','0','d','f','-','1','1','d','1','-','a','a','8','c','-','0','0', - 'c','0','4','f','b','6','7','8','6','3','}',':','2','6',',','!','!','g', - 'x','s','f','(','N','g',']','q','F','`','H','{','L','s','A','C','C','E', - 'S','S','F','i','l','e','s','>','p','l','T',']','j','I','{','j','f','(', - '=','1','&','L','[','-','8','1','-',']',':',':',0 }; + '8','6','3','}',':','2','6',',','!','!','g','x','s','f','(','N','g',']', + 'q','F','`','H','{','L','s','A','C','C','E','S','S','F','i','l','e','s', + '>','p','l','T',']','j','I','{','j','f','(','=','1','&','L','[','-','8', + '1','-',']',':',':',0 }; static const WCHAR comp[] = { '2','6',',','!','!','g','x','s','f','(','N','g',']','q','F','`','H','{', 'L','s','A','C','C','E','S','S','F','i','l','e','s','>','p','l','T',']', @@ -704,6 +714,9 @@ ok( r == E_FAIL, "CopyDataBlock failed\n"); ok( dar == NULL, "should be null\n");
+ r = IShellLinkW_SetPath(sl, NULL); + ok(r == E_INVALIDARG, "set path failed\n"); + r = IShellLinkW_SetPath(sl, lnk); ok(r == S_OK, "set path failed\n");
@@ -715,7 +728,8 @@ flags = 0; r = IShellLinkDataList_GetFlags( dl, &flags ); ok( r == S_OK, "GetFlags failed\n"); - ok( flags == (SLDF_HAS_DARWINID|SLDF_HAS_LOGO3ID), + /* SLDF_HAS_LOGO3ID is no longer supported on Vista+, filter it out */ + ok( (flags & (~ SLDF_HAS_LOGO3ID)) == SLDF_HAS_DARWINID, "GetFlags returned wrong flags\n");
dar = NULL;
Modified: trunk/rostests/winetests/shell32/shellpath.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/shell32/shellpat... ============================================================================== --- trunk/rostests/winetests/shell32/shellpath.c [iso-8859-1] (original) +++ trunk/rostests/winetests/shell32/shellpath.c [iso-8859-1] Wed Nov 11 08:36:49 2009 @@ -43,6 +43,9 @@ #endif
/* from pidl.h, not included here: */ +#ifndef PT_CPL /* Guess, Win7 uses this for CSIDL_CONTROLS */ +#define PT_CPL 0x01 /* no path */ +#endif #ifndef PT_GUID #define PT_GUID 0x1f /* no path */ #endif @@ -93,7 +96,7 @@ static DLLVERSIONINFO shellVersion = { 0 }; static LPMALLOC pMalloc; static const BYTE guidType[] = { PT_GUID }; -static const BYTE controlPanelType[] = { PT_SHELLEXT, PT_GUID }; +static const BYTE controlPanelType[] = { PT_SHELLEXT, PT_GUID, PT_CPL }; static const BYTE folderType[] = { PT_FOLDER, PT_FOLDERW }; static const BYTE favoritesType[] = { PT_FOLDER, PT_FOLDERW, 0, PT_IESPECIAL2 /* Win98 */ }; static const BYTE folderOrSpecialType[] = { PT_FOLDER, PT_IESPECIAL2 };
Modified: trunk/rostests/winetests/shell32/shlexec.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/shell32/shlexec.... ============================================================================== --- trunk/rostests/winetests/shell32/shlexec.c [iso-8859-1] (original) +++ trunk/rostests/winetests/shell32/shlexec.c [iso-8859-1] Wed Nov 11 08:36:49 2009 @@ -56,6 +56,7 @@ static char tmpdir[MAX_PATH]; static char child_file[MAX_PATH]; static DLLVERSIONINFO dllver; +static BOOL skip_noassoc_tests = FALSE;
/*** @@ -117,7 +118,18 @@ { int wait_rc; wait_rc=WaitForSingleObject(hEvent, 5000); - ok(wait_rc==WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait_rc); + if (wait_rc == WAIT_TIMEOUT) + { + HWND wnd = FindWindowA("#32770", "Windows"); + if (wnd != NULL) + { + SendMessage(wnd, WM_CLOSE, 0, 0); + win_skip("Skipping shellexecute of file with unassociated extension\n"); + skip_noassoc_tests = TRUE; + rc = SE_ERR_NOASSOC; + } + } + ok(wait_rc==WAIT_OBJECT_0 || rc <= 32, "WaitForSingleObject returned %d\n", wait_rc); } /* The child process may have changed the result file, so let profile * functions know about it @@ -462,11 +474,67 @@ WriteFile(h, buffer, strlen(buffer), &w, NULL); }
+static DWORD ddeInst; +static HSZ hszTopic; +static char ddeExec[MAX_PATH], ddeApplication[MAX_PATH]; +static BOOL post_quit_on_execute; + +static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, + HSZ hsz1, HSZ hsz2, HDDEDATA hData, + ULONG_PTR dwData1, ULONG_PTR dwData2) +{ + DWORD size = 0; + + if (winetest_debug > 2) + trace("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", + uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); + + switch (uType) + { + case XTYP_CONNECT: + if (!DdeCmpStringHandles(hsz1, hszTopic)) + { + size = DdeQueryString(ddeInst, hsz2, ddeApplication, MAX_PATH, CP_WINANSI); + assert(size < MAX_PATH); + return (HDDEDATA)TRUE; + } + return (HDDEDATA)FALSE; + + case XTYP_EXECUTE: + size = DdeGetData(hData, (LPBYTE)ddeExec, MAX_PATH, 0L); + assert(size < MAX_PATH); + DdeFreeDataHandle(hData); + if (post_quit_on_execute) + PostQuitMessage(0); + return (HDDEDATA)DDE_FACK; + + default: + return NULL; + } +} + +/* + * This is just to make sure the child won't run forever stuck in a GetMessage() + * loop when DDE fails for some reason. + */ +static void CALLBACK childTimeout(HWND wnd, UINT msg, UINT_PTR timer, DWORD time) +{ + trace("childTimeout called\n"); + + PostQuitMessage(0); +} + static void doChild(int argc, char** argv) { char* filename; - HANDLE hFile; + HANDLE hFile, map; int i; + int rc; + HSZ hszApplication; + UINT_PTR timer; + HANDLE dde_ready; + MSG msg; + char *shared_block;
filename=argv[2]; hFile=CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); @@ -484,6 +552,51 @@ trace("argvA%d=%s\n", i, argv[i]); childPrintf(hFile, "argvA%d=%s\r\n", i, encodeA(argv[i])); } + + map = OpenFileMappingA(FILE_MAP_READ, FALSE, "winetest_shlexec_dde_map"); + if (map != NULL) + { + shared_block = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 4096); + CloseHandle(map); + if (shared_block[0] != '\0' || shared_block[1] != '\0') + { + post_quit_on_execute = TRUE; + ddeInst = 0; + rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | + CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0L); + assert(rc == DMLERR_NO_ERROR); + hszApplication = DdeCreateStringHandleA(ddeInst, shared_block, CP_WINANSI); + hszTopic = DdeCreateStringHandleA(ddeInst, shared_block + strlen(shared_block) + 1, CP_WINANSI); + assert(hszApplication && hszTopic); + assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_REGISTER | DNS_FILTEROFF)); + + timer = SetTimer(NULL, 0, 2500, childTimeout); + + dde_ready = CreateEvent(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); + SetEvent(dde_ready); + CloseHandle(dde_ready); + + while (GetMessage(&msg, NULL, 0, 0)) + DispatchMessage(&msg); + + KillTimer(NULL, timer); + assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER)); + assert(DdeFreeStringHandle(ddeInst, hszTopic)); + assert(DdeFreeStringHandle(ddeInst, hszApplication)); + assert(DdeUninitialize(ddeInst)); + } + else + { + dde_ready = CreateEvent(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); + SetEvent(dde_ready); + CloseHandle(dde_ready); + } + + UnmapViewOfFile(shared_block); + + childPrintf(hFile, "ddeExec=%s\r\n", encodeA(ddeExec)); + } + CloseHandle(hFile);
init_event(filename); @@ -750,6 +863,13 @@ while (test->basename) { BOOL quotedfile = FALSE; + + if (skip_noassoc_tests && test->rc == SE_ERR_NOASSOC) + { + win_skip("Skipping shellexecute of file with unassociated extension\n"); + test++; + continue; + }
sprintf(filename, test->basename, tmpdir); if (strchr(filename, '/')) @@ -1117,7 +1237,7 @@ { okChildInt("argcA", 5); } - else + else { okChildInt("argcA", 5); } @@ -1159,13 +1279,20 @@ okChildInt("argcA", 4); okChildString("argvA3", "Exec");
- sprintf(filename, "%s\test file.noassoc", tmpdir); - if (CopyFile(argv0, filename, FALSE)) - { - rc=shell_execute(NULL, filename, params, NULL); - todo_wine { - ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); - } + if (! skip_noassoc_tests) + { + sprintf(filename, "%s\test file.noassoc", tmpdir); + if (CopyFile(argv0, filename, FALSE)) + { + rc=shell_execute(NULL, filename, params, NULL); + todo_wine { + ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + } + } + } + else + { + win_skip("Skipping shellexecute of file with unassociated extension\n"); } }
@@ -1190,13 +1317,20 @@ okChildInt("argcA", 4); okChildString("argvA3", longparam);
- sprintf(filename, "%s\test file.noassoc", tmpdir); - if (CopyFile(argv0, filename, FALSE)) - { - rc=shell_execute(NULL, filename, params, NULL); - todo_wine { - ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); - } + if (! skip_noassoc_tests) + { + sprintf(filename, "%s\test file.noassoc", tmpdir); + if (CopyFile(argv0, filename, FALSE)) + { + rc=shell_execute(NULL, filename, params, NULL); + todo_wine { + ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + } + } + } + else + { + win_skip("Skipping shellexecute of file with unassociated extension\n"); } }
@@ -1210,115 +1344,123 @@ int expectedArgs; const char* expectedDdeExec; int todo; - int rc; } dde_tests_t;
static dde_tests_t dde_tests[] = { /* Test passing and not passing command-line * argument, no DDE */ - {"", NULL, NULL, NULL, NULL, FALSE, "", 0x0, 33}, - {""%1"", NULL, NULL, NULL, NULL, TRUE, "", 0x0, 33}, + {"", NULL, NULL, NULL, NULL, FALSE, "", 0x0}, + {""%1"", NULL, NULL, NULL, NULL, TRUE, "", 0x0},
/* Test passing and not passing command-line * argument, with DDE */ - {"", "[open("%1")]", "shlexec", "dde", NULL, FALSE, "[open("%s")]", 0x0, 33}, - {""%1"", "[open("%1")]", "shlexec", "dde", NULL, TRUE, "[open("%s")]", 0x0, 33}, + {"", "[open("%1")]", "shlexec", "dde", NULL, FALSE, "[open("%s")]", 0x0}, + {""%1"", "[open("%1")]", "shlexec", "dde", NULL, TRUE, "[open("%s")]", 0x0},
/* Test unquoted %1 in command and ddeexec * (test filename has space) */ - {"%1", "[open(%1)]", "shlexec", "dde", NULL, 2, "[open(%s)]", 0x0, 33}, + {"%1", "[open(%1)]", "shlexec", "dde", NULL, 2, "[open(%s)]", 0x0},
/* Test ifexec precedence over ddeexec */ - {"", "[open("%1")]", "shlexec", "dde", "[ifexec("%1")]", FALSE, "[ifexec("%s")]", 0x0, 33}, + {"", "[open("%1")]", "shlexec", "dde", "[ifexec("%1")]", FALSE, "[ifexec("%s")]", 0x0},
/* Test default DDE topic */ - {"", "[open("%1")]", "shlexec", NULL, NULL, FALSE, "[open("%s")]", 0x0, 33}, + {"", "[open("%1")]", "shlexec", NULL, NULL, FALSE, "[open("%s")]", 0x0},
/* Test default DDE application */ - {"", "[open("%1")]", NULL, "dde", NULL, FALSE, "[open("%s")]", 0x0, 33}, - - {NULL, NULL, NULL, NULL, NULL, 0, 0x0, 0} + {"", "[open("%1")]", NULL, "dde", NULL, FALSE, "[open("%s")]", 0x0}, + + {NULL, NULL, NULL, NULL, NULL, 0, 0x0} };
-static DWORD ddeInst; -static HSZ hszTopic; -static char ddeExec[MAX_PATH], ddeApplication[MAX_PATH]; -static BOOL denyNextConnection; - -static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, - HSZ hsz1, HSZ hsz2, HDDEDATA hData, - ULONG_PTR dwData1, ULONG_PTR dwData2) -{ - DWORD size = 0; - - if (winetest_debug > 2) - trace("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", - uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); - - switch (uType) - { - case XTYP_CONNECT: - if (!DdeCmpStringHandles(hsz1, hszTopic)) - { - if (denyNextConnection) - denyNextConnection = FALSE; - else +static DWORD WINAPI hooked_WaitForInputIdle(HANDLE process, DWORD timeout) +{ + HANDLE dde_ready; + DWORD wait_result; + + dde_ready = CreateEventA(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); + wait_result = WaitForSingleObject(dde_ready, timeout); + CloseHandle(dde_ready); + + return wait_result; +} + +/* + * WaitForInputIdle() will normally return immediately for console apps. That's + * a problem for us because ShellExecute will assume that an app is ready to + * receive DDE messages after it has called WaitForInputIdle() on that app. + * To work around that we install our own version of WaitForInputIdle() that + * will wait for the child to explicitly tell us that it is ready. We do that + * by changing the entry for WaitForInputIdle() in the shell32 import address + * table. + */ +static void hook_WaitForInputIdle(void *new_func) +{ + char *base; + PIMAGE_NT_HEADERS nt_headers; + DWORD import_directory_rva; + PIMAGE_IMPORT_DESCRIPTOR import_descriptor; + + base = (char *) GetModuleHandleA("shell32.dll"); + nt_headers = (PIMAGE_NT_HEADERS)(base + ((PIMAGE_DOS_HEADER) base)->e_lfanew); + import_directory_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + /* Search for the correct imported module by walking the import descriptors */ + import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)(base + import_directory_rva); + while (U(*import_descriptor).OriginalFirstThunk != 0) + { + char *import_module_name; + + import_module_name = base + import_descriptor->Name; + if (lstrcmpiA(import_module_name, "user32.dll") == 0 || + lstrcmpiA(import_module_name, "user32") == 0) + { + PIMAGE_THUNK_DATA int_entry; + PIMAGE_THUNK_DATA iat_entry; + + /* The import name table and import address table are two parallel + * arrays. We need the import name table to find the imported + * routine and the import address table to patch the address, so + * walk them side by side */ + int_entry = (PIMAGE_THUNK_DATA)(base + U(*import_descriptor).OriginalFirstThunk); + iat_entry = (PIMAGE_THUNK_DATA)(base + import_descriptor->FirstThunk); + while (int_entry->u1.Ordinal != 0) + { + if (! IMAGE_SNAP_BY_ORDINAL(int_entry->u1.Ordinal)) { - size = DdeQueryString(ddeInst, hsz2, ddeApplication, MAX_PATH, CP_WINANSI); - assert(size < MAX_PATH); - return (HDDEDATA)TRUE; + PIMAGE_IMPORT_BY_NAME import_by_name; + import_by_name = (PIMAGE_IMPORT_BY_NAME)(base + int_entry->u1.AddressOfData); + if (lstrcmpA((char *) import_by_name->Name, "WaitForInputIdle") == 0) + { + /* Found the correct routine in the correct imported module. Patch it. */ + DWORD old_prot; + VirtualProtect(&iat_entry->u1.Function, sizeof(ULONG_PTR), PAGE_READWRITE, &old_prot); + iat_entry->u1.Function = (ULONG_PTR) new_func; + VirtualProtect(&iat_entry->u1.Function, sizeof(ULONG_PTR), old_prot, &old_prot); + break; + } } - } - return (HDDEDATA)FALSE; - - case XTYP_EXECUTE: - size = DdeGetData(hData, (LPBYTE)ddeExec, MAX_PATH, 0L); - assert(size < MAX_PATH); - DdeFreeDataHandle(hData); - return (HDDEDATA)DDE_FACK; - - default: - return NULL; - } -} - -typedef struct -{ - char *filename; - DWORD threadIdParent; -} dde_thread_info_t; - -static DWORD CALLBACK ddeThread(LPVOID arg) -{ - dde_thread_info_t *info = arg; - assert(info && info->filename); - PostThreadMessage(info->threadIdParent, - WM_QUIT, - shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, info->filename, NULL, NULL), - 0L); - ExitThread(0); -} - -/* ShellExecute won't successfully send DDE commands to console applications after starting them, - * so we run a DDE server in this application, deny the first connection request to make - * ShellExecute start the application, and then process the next DDE connection in this application - * to see the execute command that is sent. */ + int_entry++; + iat_entry++; + } + break; + } + + import_descriptor++; + } +} + static void test_dde(void) { char filename[MAX_PATH], defApplication[MAX_PATH]; - HSZ hszApplication; - dde_thread_info_t info = { filename, GetCurrentThreadId() }; const dde_tests_t* test; char params[1024]; - DWORD threadId; - MSG msg; int rc; - - ddeInst = 0; - rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | - CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0L); - assert(rc == DMLERR_NO_ERROR); + HANDLE map; + char *shared_block; + + hook_WaitForInputIdle((void *) hooked_WaitForInputIdle);
sprintf(filename, "%s\test file.sde", tmpdir);
@@ -1326,6 +1468,10 @@ strcpy(defApplication, strrchr(argv0, '\')+1); *strchr(defApplication, '.') = 0;
+ map = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, + 4096, "winetest_shlexec_dde_map"); + shared_block = MapViewOfFile(map, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 4096); + test = dde_tests; while (test->command) { @@ -1336,29 +1482,31 @@ } create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec, test->application, test->topic, test->ifexec); - hszApplication = DdeCreateStringHandleA(ddeInst, test->application ? - test->application : defApplication, CP_WINANSI); - hszTopic = DdeCreateStringHandleA(ddeInst, test->topic ? test->topic : SZDDESYS_TOPIC, - CP_WINANSI); - assert(hszApplication && hszTopic); - assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_REGISTER)); - denyNextConnection = TRUE; + + if (test->application != NULL || test->topic != NULL) + { + strcpy(shared_block, test->application ? test->application : defApplication); + strcpy(shared_block + strlen(shared_block) + 1, test->topic ? test->topic : SZDDESYS_TOPIC); + } + else + { + shared_block[0] = '\0'; + shared_block[1] = '\0'; + } ddeExec[0] = 0;
- assert(CreateThread(NULL, 0, ddeThread, &info, 0, &threadId)); - while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); - rc = msg.wParam > 32 ? 33 : msg.wParam; + rc = shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, filename, NULL, NULL); if ((test->todo & 0x1)==0) { - ok(rc==test->rc, "%s failed: rc=%d err=%d\n", shell_call, + ok(32 < rc, "%s failed: rc=%d err=%d\n", shell_call, rc, GetLastError()); } else todo_wine { - ok(rc==test->rc, "%s failed: rc=%d err=%d\n", shell_call, + ok(32 < rc, "%s failed: rc=%d err=%d\n", shell_call, rc, GetLastError()); } - if (rc == 33) + if (32 < rc) { if ((test->todo & 0x2)==0) { @@ -1382,25 +1530,22 @@ if ((test->todo & 0x8) == 0) { sprintf(params, test->expectedDdeExec, filename); - ok(StrCmpPath(params, ddeExec) == 0, - "ddeexec expected '%s', got '%s'\n", params, ddeExec); + okChildPath("ddeExec", params); } else todo_wine { sprintf(params, test->expectedDdeExec, filename); - ok(StrCmpPath(params, ddeExec) == 0, - "ddeexec expected '%s', got '%s'\n", params, ddeExec); - } - } - - assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER)); - assert(DdeFreeStringHandle(ddeInst, hszTopic)); - assert(DdeFreeStringHandle(ddeInst, hszApplication)); + okChildPath("ddeExec", params); + } + } + delete_test_association(".sde"); test++; }
- assert(DdeUninitialize(ddeInst)); + UnmapViewOfFile(shared_block); + CloseHandle(map); + hook_WaitForInputIdle((void *) WaitForInputIdle); }
#define DDE_DEFAULT_APP_VARIANTS 2 @@ -1453,6 +1598,23 @@
{NULL, {NULL}, 0, {0}} }; + +typedef struct +{ + char *filename; + DWORD threadIdParent; +} dde_thread_info_t; + +static DWORD CALLBACK ddeThread(LPVOID arg) +{ + dde_thread_info_t *info = arg; + assert(info && info->filename); + PostThreadMessage(info->threadIdParent, + WM_QUIT, + shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, info->filename, NULL, NULL), + 0L); + ExitThread(0); +}
static void test_dde_default_app(void) { @@ -1465,6 +1627,7 @@ MSG msg; int rc, which = 0;
+ post_quit_on_execute = FALSE; ddeInst = 0; rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0L); @@ -1491,7 +1654,6 @@ sprintf(params, test->command, tmpdir); create_test_verb_dde(".sde", "Open", 1, params, "[test]", NULL, "shlexec", NULL); - denyNextConnection = FALSE; ddeApplication[0] = 0;
/* No application will be run as we will respond to the first DDE event,
Modified: trunk/rostests/winetests/shell32/shlfileop.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/shell32/shlfileo... ============================================================================== --- trunk/rostests/winetests/shell32/shlfileop.c [iso-8859-1] (original) +++ trunk/rostests/winetests/shell32/shlfileop.c [iso-8859-1] Wed Nov 11 08:36:49 2009 @@ -48,8 +48,8 @@ "Expected %d, got %d\n", ret, retval)
static CHAR CURR_DIR[MAX_PATH]; -static const WCHAR UNICODE_PATH[] = {'c',':','\',0x00c4,'\0','\0'}; - /* "c:\Ã", or "c:\A" with diaeresis */ +static const WCHAR UNICODE_PATH[] = {'c',':','\',0x00ae,'\0','\0'}; + /* "c:\®" can be used in all codepages */ /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
static HMODULE hshell32; @@ -207,11 +207,11 @@ memset(&shfiw, 0xcf, sizeof(shfiw)); memset(&unset_icon, 0xcf, sizeof(unset_icon)); rc=pSHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0); - todo_wine ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n"); + ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n"); ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n"); - todo_wine ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n"); - todo_wine ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n"); - todo_wine ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n"); + ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n"); + ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n"); + ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n"); ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n"); } else @@ -1042,10 +1042,13 @@ shfo.pTo = "testdir2\a.txt\0testdir2\b.txt\0testdir2\c.txt\0"; shfo.fAnyOperationsAborted = FALSE; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); ok(DeleteFile("testdir2\a.txt"), "Expected testdir2\a.txt to exist\n"); ok(DeleteFile("testdir2\b.txt"), "Expected testdir2\b.txt to exist\n"); - ok(RemoveDirectory("testdir2\c.txt"), "Expected testdir2\c.txt to exist\n"); + if (retval == ERROR_SUCCESS) + ok(RemoveDirectory("testdir2\c.txt"), "Expected testdir2\c.txt to exist\n");
/* try many dest files without FOF_MULTIDESTFILES flag */ shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0"; @@ -1073,7 +1076,9 @@ shfo.pTo = "testdir2\0"; shfo.fFlags &= ~FOF_MULTIDESTFILES; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); ok(file_exists("testdir2\test1.txt"), "Expected testdir2\test1.txt to exist\n");
/* try a glob with FOF_FILESONLY */ @@ -1190,18 +1195,28 @@ shfo.fFlags &= ~FOF_MULTIDESTFILES; shfo.fAnyOperationsAborted = FALSE; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); - ok(DeleteFile("testdir2\test1.txt"), "Expected testdir2\test1.txt to exist\n"); - ok(DeleteFile("testdir2\test4.txt\a.txt"), "Expected a.txt to exist\n"); - ok(RemoveDirectory("testdir2\test4.txt"), "Expected testdir2\test4.txt to exist\n"); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); + if (retval == ERROR_SUCCESS) + { + ok(DeleteFile("testdir2\test1.txt"), "Expected testdir2\test1.txt to exist\n"); + ok(DeleteFile("testdir2\test4.txt\a.txt"), "Expected a.txt to exist\n"); + ok(RemoveDirectory("testdir2\test4.txt"), "Expected testdir2\test4.txt to exist\n"); + }
/* copy one directory and a file in that dir to another dir */ shfo.pFrom = "test4.txt\0test4.txt\a.txt\0"; shfo.pTo = "testdir2\0"; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); - ok(DeleteFile("testdir2\test4.txt\a.txt"), "Expected a.txt to exist\n"); - ok(DeleteFile("testdir2\a.txt"), "Expected testdir2\a.txt to exist\n"); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); + if (retval == ERROR_SUCCESS) + { + ok(DeleteFile("testdir2\test4.txt\a.txt"), "Expected a.txt to exist\n"); + ok(DeleteFile("testdir2\a.txt"), "Expected testdir2\a.txt to exist\n"); + }
/* copy a file in a directory first, and then the directory to a nonexistent dir */ shfo.pFrom = "test4.txt\a.txt\0test4.txt\0"; @@ -1362,13 +1377,21 @@ createTestFile("test4.txt\test1.txt"); shfo.pFrom = "test4.txt\0"; shfo.pTo = "testdir2\0"; + /* WinMe needs FOF_NOERRORUI */ + shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI; + retval = SHFileOperation(&shfo); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); shfo.fFlags = FOF_NOCONFIRMATION; - ok(!SHFileOperation(&shfo), "First SHFileOperation failed\n"); - createTestFile("test4.txt\.\test1.txt"); /* modify the content of the file */ - /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */ - retval = SHFileOperation(&shfo); - ok(retval == 0, "Expected 0, got %d\n", retval); - ok(file_has_content("testdir2\test4.txt\test1.txt", "test4.txt\.\test1.txt\n"), "The file was not copied\n"); + if (ERROR_SUCCESS) + { + createTestFile("test4.txt\.\test1.txt"); /* modify the content of the file */ + /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */ + retval = SHFileOperation(&shfo); + ok(retval == 0, "Expected 0, got %d\n", retval); + ok(file_has_content("testdir2\test4.txt\test1.txt", "test4.txt\.\test1.txt\n"), "The file was not copied\n"); + }
createTestFile("one.txt");
@@ -1955,6 +1978,7 @@ { HRESULT res; CHAR path[MAX_PATH]; + CHAR UNICODE_PATH_A[MAX_PATH];
if(!pSHPathPrepareForWriteA) { @@ -1987,12 +2011,14 @@ set_curr_dir_path(path, "test1.txt\0"); res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE); ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) || + res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */ res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */ "Unexpected result : 0x%08x\n", res);
/* file exists, SHPPFW_DIRCREATE */ res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE); ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) || + res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */ res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */ "Unexpected result : 0x%08x\n", res);
@@ -2000,6 +2026,7 @@ set_curr_dir_path(path, "test1.txt\\0"); res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE); ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) || + res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */ res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */ "Unexpected result : 0x%08x\n", res);
@@ -2040,19 +2067,22 @@
if(!pSHPathPrepareForWriteW) { - skip("Skipping SHPathPrepareForWriteW tests\n"); + win_skip("Skipping SHPathPrepareForWriteW tests\n"); return; } + WideCharToMultiByte(CP_ACP, 0, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, NULL); + /* unicode directory doesn't exist, SHPPFW_NONE */ + RemoveDirectoryA(UNICODE_PATH_A); res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE); ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res); - ok(!file_existsW(UNICODE_PATH), "unicode path was created but shouldn't be\n"); - RemoveDirectoryW(UNICODE_PATH); + ok(!file_exists(UNICODE_PATH_A), "unicode path was created but shouldn't be\n"); + RemoveDirectoryA(UNICODE_PATH_A);
/* unicode directory doesn't exist, SHPPFW_DIRCREATE */ res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE); ok(res == S_OK, "res == %08x, expected S_OK\n", res); - ok(file_existsW(UNICODE_PATH), "unicode path should've been created\n"); + ok(file_exists(UNICODE_PATH_A), "unicode path should've been created\n");
/* unicode directory exists, SHPPFW_NONE */ res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE); @@ -2061,7 +2091,7 @@ /* unicode directory exists, SHPPFW_DIRCREATE */ res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE); ok(res == S_OK, "ret == %08x, expected S_OK\n", res); - RemoveDirectoryW(UNICODE_PATH); + RemoveDirectoryA(UNICODE_PATH_A); }
static void test_sh_new_link_info(void)