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.…
==============================================================================
--- 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/shellli…
==============================================================================
--- 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/shellpa…
==============================================================================
--- 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/shlfile…
==============================================================================
--- 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)