mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 17:10:22 +00:00
sync shell32_winetest with wine 1.1.20
svn path=/trunk/; revision=40733
This commit is contained in:
parent
835f656bfa
commit
f51cc69532
14 changed files with 3632 additions and 1190 deletions
420
rostests/winetests/shell32/appbar.c
Normal file
420
rostests/winetests/shell32/appbar.c
Normal file
|
@ -0,0 +1,420 @@
|
|||
/* Unit tests for appbars
|
||||
*
|
||||
* Copyright 2008 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define MSG_APPBAR WM_APP
|
||||
|
||||
static const CHAR testwindow_class[] = "testwindow";
|
||||
|
||||
static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD);
|
||||
|
||||
typedef BOOL (*boolean_function)(void);
|
||||
|
||||
struct testwindow_info
|
||||
{
|
||||
HWND hwnd;
|
||||
BOOL registered;
|
||||
RECT desired_rect;
|
||||
UINT edge;
|
||||
RECT allocated_rect;
|
||||
};
|
||||
|
||||
static struct testwindow_info windows[3];
|
||||
|
||||
static int expected_bottom;
|
||||
|
||||
static void testwindow_setpos(HWND hwnd)
|
||||
{
|
||||
struct testwindow_info* info = (struct testwindow_info*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
APPBARDATA abd;
|
||||
BOOL ret;
|
||||
|
||||
ok(info != NULL, "got unexpected ABN_POSCHANGED notification\n");
|
||||
|
||||
if (!info || !info->registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
abd.cbSize = sizeof(abd);
|
||||
abd.hWnd = hwnd;
|
||||
abd.uEdge = info->edge;
|
||||
abd.rc = info->desired_rect;
|
||||
ret = SHAppBarMessage(ABM_QUERYPOS, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
switch (info->edge)
|
||||
{
|
||||
case ABE_BOTTOM:
|
||||
ok(info->desired_rect.top == abd.rc.top, "ABM_QUERYPOS changed top of rect from %i to %i\n", info->desired_rect.top, abd.rc.top);
|
||||
abd.rc.top = abd.rc.bottom - (info->desired_rect.bottom - info->desired_rect.top);
|
||||
break;
|
||||
case ABE_LEFT:
|
||||
ok(info->desired_rect.right == abd.rc.right, "ABM_QUERYPOS changed right of rect from %i to %i\n", info->desired_rect.top, abd.rc.top);
|
||||
abd.rc.right = abd.rc.left + (info->desired_rect.right - info->desired_rect.left);
|
||||
break;
|
||||
case ABE_RIGHT:
|
||||
ok(info->desired_rect.left == abd.rc.left, "ABM_QUERYPOS changed left of rect from %i to %i\n", info->desired_rect.top, abd.rc.top);
|
||||
abd.rc.left = abd.rc.right - (info->desired_rect.right - info->desired_rect.left);
|
||||
break;
|
||||
case ABE_TOP:
|
||||
ok(info->desired_rect.bottom == abd.rc.bottom, "ABM_QUERYPOS changed bottom of rect from %i to %i\n", info->desired_rect.top, abd.rc.top);
|
||||
abd.rc.bottom = abd.rc.top + (info->desired_rect.bottom - info->desired_rect.top);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = SHAppBarMessage(ABM_SETPOS, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
|
||||
info->allocated_rect = abd.rc;
|
||||
MoveWindow(hwnd, abd.rc.left, abd.rc.top, abd.rc.right-abd.rc.left, abd.rc.bottom-abd.rc.top, TRUE);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case MSG_APPBAR:
|
||||
{
|
||||
switch(wparam)
|
||||
{
|
||||
case ABN_POSCHANGED:
|
||||
testwindow_setpos(hwnd);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
/* process pending messages until a condition is true or 3 seconds pass */
|
||||
static void do_events_until(boolean_function test)
|
||||
{
|
||||
MSG msg;
|
||||
UINT_PTR timerid;
|
||||
BOOL timedout=FALSE;
|
||||
|
||||
timerid = SetTimer(0, 0, 3000, NULL);
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.hwnd == 0 && msg.message == WM_TIMER && msg.wParam == timerid)
|
||||
timedout = TRUE;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
if (timedout || test())
|
||||
break;
|
||||
WaitMessage();
|
||||
}
|
||||
|
||||
KillTimer(0, timerid);
|
||||
}
|
||||
|
||||
/* process any pending messages */
|
||||
static void do_events(void)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL no_appbars_intersect(void)
|
||||
{
|
||||
int i, j;
|
||||
RECT rc;
|
||||
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
for (j=i+1; j<3; j++)
|
||||
{
|
||||
if (windows[i].registered && windows[j].registered &&
|
||||
IntersectRect(&rc, &windows[i].allocated_rect, &windows[j].allocated_rect))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL got_expected_bottom(void)
|
||||
{
|
||||
return (no_appbars_intersect() && windows[1].allocated_rect.bottom == expected_bottom);
|
||||
}
|
||||
|
||||
static void register_testwindow_class(void)
|
||||
{
|
||||
WNDCLASSEXA cls;
|
||||
|
||||
ZeroMemory(&cls, sizeof(cls));
|
||||
cls.cbSize = sizeof(cls);
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = testwindow_wndproc;
|
||||
cls.hInstance = NULL;
|
||||
cls.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
cls.hbrBackground = (HBRUSH) COLOR_WINDOW;
|
||||
cls.lpszClassName = testwindow_class;
|
||||
|
||||
RegisterClassExA(&cls);
|
||||
}
|
||||
|
||||
#define test_window_rects(a, b) \
|
||||
ok(!IntersectRect(&rc, &windows[a].allocated_rect, &windows[b].allocated_rect), \
|
||||
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", \
|
||||
windows[a].allocated_rect.left, windows[a].allocated_rect.top, windows[a].allocated_rect.right, windows[a].allocated_rect.bottom, \
|
||||
windows[b].allocated_rect.left, windows[b].allocated_rect.top, windows[b].allocated_rect.right, windows[b].allocated_rect.bottom)
|
||||
|
||||
static void test_setpos(void)
|
||||
{
|
||||
APPBARDATA abd;
|
||||
RECT rc;
|
||||
int screen_width, screen_height;
|
||||
BOOL ret;
|
||||
|
||||
screen_width = GetSystemMetrics(SM_CXSCREEN);
|
||||
screen_height = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
/* create and register windows[0] */
|
||||
windows[0].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
|
||||
testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL);
|
||||
ok(windows[0].hwnd != NULL, "couldn't create window\n");
|
||||
do_events();
|
||||
abd.cbSize = sizeof(abd);
|
||||
abd.hWnd = windows[0].hwnd;
|
||||
abd.uCallbackMessage = MSG_APPBAR;
|
||||
ret = SHAppBarMessage(ABM_NEW, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
|
||||
/* ABM_NEW should return FALSE if the window is already registered */
|
||||
ret = SHAppBarMessage(ABM_NEW, &abd);
|
||||
ok(ret == FALSE, "SHAppBarMessage returned %i\n", ret);
|
||||
do_events();
|
||||
|
||||
/* dock windows[0] to the bottom of the screen */
|
||||
windows[0].registered = TRUE;
|
||||
windows[0].edge = ABE_BOTTOM;
|
||||
windows[0].desired_rect.left = 0;
|
||||
windows[0].desired_rect.right = screen_width;
|
||||
windows[0].desired_rect.top = screen_height - 15;
|
||||
windows[0].desired_rect.bottom = screen_height;
|
||||
SetWindowLongPtr(windows[0].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[0]);
|
||||
testwindow_setpos(windows[0].hwnd);
|
||||
do_events();
|
||||
|
||||
/* create and register windows[1] */
|
||||
windows[1].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
|
||||
testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL);
|
||||
ok(windows[1].hwnd != NULL, "couldn't create window\n");
|
||||
abd.hWnd = windows[1].hwnd;
|
||||
ret = SHAppBarMessage(ABM_NEW, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
|
||||
/* dock windows[1] to the bottom of the screen */
|
||||
windows[1].registered = TRUE;
|
||||
windows[1].edge = ABE_BOTTOM;
|
||||
windows[1].desired_rect.left = 0;
|
||||
windows[1].desired_rect.right = screen_width;
|
||||
windows[1].desired_rect.top = screen_height - 10;
|
||||
windows[1].desired_rect.bottom = screen_height;
|
||||
SetWindowLongPtr(windows[1].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[1]);
|
||||
testwindow_setpos(windows[1].hwnd);
|
||||
|
||||
/* the windows are adjusted to they don't overlap */
|
||||
do_events_until(no_appbars_intersect);
|
||||
test_window_rects(0, 1);
|
||||
|
||||
/* make windows[0] larger, forcing windows[1] to move out of its way */
|
||||
windows[0].desired_rect.top = screen_height - 20;
|
||||
testwindow_setpos(windows[0].hwnd);
|
||||
do_events_until(no_appbars_intersect);
|
||||
test_window_rects(0, 1);
|
||||
|
||||
/* create and register windows[2] */
|
||||
windows[2].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
|
||||
testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL);
|
||||
ok(windows[2].hwnd != NULL, "couldn't create window\n");
|
||||
do_events();
|
||||
|
||||
abd.hWnd = windows[2].hwnd;
|
||||
ret = SHAppBarMessage(ABM_NEW, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
|
||||
/* dock windows[2] to the bottom of the screen */
|
||||
windows[2].registered = TRUE;
|
||||
windows[2].edge = ABE_BOTTOM;
|
||||
windows[2].desired_rect.left = 0;
|
||||
windows[2].desired_rect.right = screen_width;
|
||||
windows[2].desired_rect.top = screen_height - 10;
|
||||
windows[2].desired_rect.bottom = screen_height;
|
||||
SetWindowLongPtr(windows[2].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[2]);
|
||||
testwindow_setpos(windows[2].hwnd);
|
||||
|
||||
do_events_until(no_appbars_intersect);
|
||||
test_window_rects(0, 1);
|
||||
test_window_rects(0, 2);
|
||||
test_window_rects(1, 2);
|
||||
|
||||
/* move windows[2] to the right side of the screen */
|
||||
windows[2].edge = ABE_RIGHT;
|
||||
windows[2].desired_rect.left = screen_width - 15;
|
||||
windows[2].desired_rect.right = screen_width;
|
||||
windows[2].desired_rect.top = 0;
|
||||
windows[2].desired_rect.bottom = screen_height;
|
||||
testwindow_setpos(windows[2].hwnd);
|
||||
|
||||
do_events_until(no_appbars_intersect);
|
||||
test_window_rects(0, 1);
|
||||
test_window_rects(0, 2);
|
||||
test_window_rects(1, 2);
|
||||
|
||||
/* move windows[1] to the top of the screen */
|
||||
windows[1].edge = ABE_TOP;
|
||||
windows[1].desired_rect.left = 0;
|
||||
windows[1].desired_rect.right = screen_width;
|
||||
windows[1].desired_rect.top = 0;
|
||||
windows[1].desired_rect.bottom = 15;
|
||||
testwindow_setpos(windows[1].hwnd);
|
||||
|
||||
do_events_until(no_appbars_intersect);
|
||||
test_window_rects(0, 1);
|
||||
test_window_rects(0, 2);
|
||||
test_window_rects(1, 2);
|
||||
|
||||
/* move windows[1] back to the bottom of the screen */
|
||||
windows[1].edge = ABE_BOTTOM;
|
||||
windows[1].desired_rect.left = 0;
|
||||
windows[1].desired_rect.right = screen_width;
|
||||
windows[1].desired_rect.top = screen_height - 10;
|
||||
windows[1].desired_rect.bottom = screen_height;
|
||||
testwindow_setpos(windows[1].hwnd);
|
||||
|
||||
do_events_until(no_appbars_intersect);
|
||||
test_window_rects(0, 1);
|
||||
test_window_rects(0, 2);
|
||||
test_window_rects(1, 2);
|
||||
|
||||
/* 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);
|
||||
|
||||
abd.hWnd = windows[0].hwnd;
|
||||
ret = SHAppBarMessage(ABM_REMOVE, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
windows[0].registered = FALSE;
|
||||
DestroyWindow(windows[0].hwnd);
|
||||
|
||||
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);
|
||||
|
||||
test_window_rects(1, 2);
|
||||
|
||||
/* remove the other windows */
|
||||
abd.hWnd = windows[1].hwnd;
|
||||
ret = SHAppBarMessage(ABM_REMOVE, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
windows[1].registered = FALSE;
|
||||
DestroyWindow(windows[1].hwnd);
|
||||
|
||||
abd.hWnd = windows[2].hwnd;
|
||||
ret = SHAppBarMessage(ABM_REMOVE, &abd);
|
||||
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
|
||||
windows[2].registered = FALSE;
|
||||
DestroyWindow(windows[2].hwnd);
|
||||
}
|
||||
|
||||
static void test_appbarget(void)
|
||||
{
|
||||
APPBARDATA abd;
|
||||
HWND hwnd, foregnd, unset_hwnd;
|
||||
UINT_PTR ret;
|
||||
|
||||
memset(&abd, 0xcc, sizeof(abd));
|
||||
memset(&unset_hwnd, 0xcc, sizeof(unset_hwnd));
|
||||
abd.cbSize = sizeof(abd);
|
||||
abd.uEdge = ABE_BOTTOM;
|
||||
|
||||
hwnd = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
|
||||
ok(hwnd == NULL || IsWindow(hwnd), "ret %p which is not a window\n", hwnd);
|
||||
ok(abd.hWnd == unset_hwnd, "hWnd overwritten %p\n",abd.hWnd);
|
||||
|
||||
if (!pMonitorFromWindow)
|
||||
{
|
||||
win_skip("MonitorFromWindow is not available\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Presumably one can pass a hwnd with ABM_GETAUTOHIDEBAR to specify a monitor.
|
||||
Pass the foreground window and check */
|
||||
foregnd = GetForegroundWindow();
|
||||
if(foregnd)
|
||||
{
|
||||
abd.hWnd = foregnd;
|
||||
hwnd = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
|
||||
ok(hwnd == NULL || IsWindow(hwnd), "ret %p which is not a window\n", hwnd);
|
||||
ok(abd.hWnd == foregnd, "hWnd overwritten\n");
|
||||
if(hwnd)
|
||||
{
|
||||
HMONITOR appbar_mon, foregnd_mon;
|
||||
appbar_mon = pMonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
foregnd_mon = pMonitorFromWindow(foregnd, MONITOR_DEFAULTTONEAREST);
|
||||
ok(appbar_mon == foregnd_mon, "Windows on different monitors\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(&abd, 0xcc, sizeof(abd));
|
||||
abd.cbSize = sizeof(abd);
|
||||
ret = SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
|
||||
if(ret)
|
||||
{
|
||||
ok(abd.hWnd == (HWND)0xcccccccc, "hWnd overwritten\n");
|
||||
ok(abd.uEdge <= ABE_BOTTOM, "uEdge not returned\n");
|
||||
ok(abd.rc.left != 0xcccccccc, "rc not updated\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
START_TEST(appbar)
|
||||
{
|
||||
HMODULE huser32;
|
||||
|
||||
huser32 = GetModuleHandleA("user32.dll");
|
||||
pMonitorFromWindow = (void*)GetProcAddress(huser32, "MonitorFromWindow");
|
||||
|
||||
register_testwindow_class();
|
||||
|
||||
test_setpos();
|
||||
test_appbarget();
|
||||
}
|
136
rostests/winetests/shell32/autocomplete.c
Normal file
136
rostests/winetests/shell32/autocomplete.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Tests for autocomplete
|
||||
*
|
||||
* Copyright 2008 Jan de Mooij
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include <wine/test.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windows.h"
|
||||
#include "shobjidl.h"
|
||||
#include "shlguid.h"
|
||||
#include "initguid.h"
|
||||
#include "shldisp.h"
|
||||
|
||||
static HWND hMainWnd, hEdit;
|
||||
static HINSTANCE hinst;
|
||||
static int killfocus_count;
|
||||
|
||||
static BOOL test_init(void) {
|
||||
HRESULT r;
|
||||
IAutoComplete* ac;
|
||||
IUnknown *acSource;
|
||||
|
||||
/* AutoComplete instance */
|
||||
r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IAutoComplete, (LPVOID*)&ac);
|
||||
if (r == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
win_skip("CLSID_AutoComplete is not registered\n");
|
||||
return FALSE;
|
||||
}
|
||||
ok(SUCCEEDED(r), "no IID_IAutoComplete (0x%08x)\n", r);
|
||||
|
||||
/* AutoComplete source */
|
||||
r = CoCreateInstance(&CLSID_ACLMulti, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IACList, (LPVOID*)&acSource);
|
||||
if (r == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
win_skip("CLSID_ACLMulti is not registered\n");
|
||||
return FALSE;
|
||||
}
|
||||
ok(SUCCEEDED(r), "no IID_IACList (0x%08x)\n", r);
|
||||
|
||||
/* bind to edit control */
|
||||
r = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL);
|
||||
ok(SUCCEEDED(r), "Init failed (0x%08x)\n", r);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
static void test_killfocus(void) {
|
||||
/* Test if WM_KILLFOCUS messages are handled properly by checking if
|
||||
* the parent receives an EN_KILLFOCUS message. */
|
||||
SetFocus(hEdit);
|
||||
killfocus_count = 0;
|
||||
SetFocus(0);
|
||||
ok(killfocus_count == 1, "Expected one EN_KILLFOCUS message, got: %d\n", killfocus_count);
|
||||
}
|
||||
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
switch(msg) {
|
||||
case WM_CREATE:
|
||||
/* create edit control */
|
||||
hEdit = CreateWindowEx(0, "EDIT", "Some text", 0, 10, 10, 300, 300,
|
||||
hWnd, NULL, hinst, NULL);
|
||||
ok(hEdit != NULL, "Can't create edit control\n");
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
if(HIWORD(wParam) == EN_KILLFOCUS)
|
||||
killfocus_count++;
|
||||
break;
|
||||
}
|
||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
static void createMainWnd(void) {
|
||||
WNDCLASSA wc;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandleA(NULL);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "MyTestWnd";
|
||||
wc.lpfnWndProc = MyWndProc;
|
||||
RegisterClassA(&wc);
|
||||
|
||||
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
}
|
||||
START_TEST(autocomplete) {
|
||||
HRESULT r;
|
||||
MSG msg;
|
||||
|
||||
r = CoInitialize(NULL);
|
||||
ok(SUCCEEDED(r), "CoInitialize failed (0x%08x). Tests aborted.\n", r);
|
||||
if (FAILED(r))
|
||||
return;
|
||||
|
||||
createMainWnd();
|
||||
|
||||
if(!ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n"))
|
||||
return;
|
||||
|
||||
if (!test_init())
|
||||
goto cleanup;
|
||||
test_killfocus();
|
||||
|
||||
PostQuitMessage(0);
|
||||
while(GetMessageA(&msg,0,0,0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
DestroyWindow(hEdit);
|
||||
DestroyWindow(hMainWnd);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
File diff suppressed because it is too large
Load diff
28
rostests/winetests/shell32/rsrc.rc
Normal file
28
rostests/winetests/shell32/rsrc.rc
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* String resource for shlfolder test.
|
||||
*
|
||||
* Copyright 2008 Vincent Povirk for CodeWeavers
|
||||
*
|
||||
* 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 "windef.h"
|
||||
#include "winuser.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
1 "Folder Name Resource"
|
||||
}
|
|
@ -15,6 +15,8 @@
|
|||
<library>kernel32</library>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
<file>appbar.c</file>
|
||||
<file>autocomplete.c</file>
|
||||
<file>generated.c</file>
|
||||
<file>shelllink.c</file>
|
||||
<file>shellpath.c</file>
|
||||
|
@ -25,5 +27,7 @@
|
|||
<file>systray.c</file>
|
||||
<file>testlist.c</file>
|
||||
<file>shfldr_netplaces.c</file>
|
||||
<file>shfldr_special.c</file>
|
||||
<file>rsrc.rc</file>
|
||||
</module>
|
||||
</group>
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
#define COBJMACROS
|
||||
|
||||
#include <windows.h>
|
||||
#include "initguid.h"
|
||||
#include "windows.h"
|
||||
#include "shlguid.h"
|
||||
#include "shobjidl.h"
|
||||
#include "shlobj.h"
|
||||
|
@ -32,6 +33,9 @@
|
|||
|
||||
#include "shell32_test.h"
|
||||
|
||||
#ifndef SLDF_HAS_LOGO3ID
|
||||
# define SLDF_HAS_LOGO3ID 0x00000800 /* not available in the Vista SDK */
|
||||
#endif
|
||||
|
||||
typedef void (WINAPI *fnILFree)(LPITEMIDLIST);
|
||||
typedef BOOL (WINAPI *fnILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
|
||||
|
@ -48,7 +52,6 @@ static const GUID _IID_IShellLinkDataList = {
|
|||
{ 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1 }
|
||||
};
|
||||
|
||||
static const WCHAR lnkfile[]= { 'C',':','\\','t','e','s','t','.','l','n','k',0 };
|
||||
static const WCHAR notafile[]= { 'C',':','\\','n','o','n','e','x','i','s','t','e','n','t','\\','f','i','l','e',0 };
|
||||
|
||||
|
||||
|
@ -67,7 +70,7 @@ static LPITEMIDLIST path_to_pidl(const char* path)
|
|||
HMODULE hdll=GetModuleHandleA("shell32.dll");
|
||||
pSHSimpleIDListFromPathAW=(void*)GetProcAddress(hdll, (char*)162);
|
||||
if (!pSHSimpleIDListFromPathAW)
|
||||
trace("SHSimpleIDListFromPathAW not found in shell32.dll\n");
|
||||
win_skip("SHSimpleIDListFromPathAW not found in shell32.dll\n");
|
||||
}
|
||||
|
||||
pidl=NULL;
|
||||
|
@ -86,9 +89,7 @@ static LPITEMIDLIST path_to_pidl(const char* path)
|
|||
MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, len);
|
||||
|
||||
r=pSHILCreateFromPath(pathW, &pidl, NULL);
|
||||
todo_wine {
|
||||
ok(SUCCEEDED(r), "SHILCreateFromPath failed (0x%08x)\n", r);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pathW);
|
||||
}
|
||||
return pidl;
|
||||
|
@ -113,7 +114,7 @@ static void test_get_set(void)
|
|||
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLinkA, (LPVOID*)&sl);
|
||||
ok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08x)\n", r);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
return;
|
||||
|
||||
/* Test Getting / Setting the description */
|
||||
|
@ -170,9 +171,9 @@ static void test_get_set(void)
|
|||
ok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
|
||||
ok(lstrcmpi(buffer,str)==0, "GetPath returned '%s'\n", buffer);
|
||||
|
||||
/* Get some a real path to play with */
|
||||
r=GetModuleFileName(NULL, mypath, sizeof(mypath));
|
||||
ok(r>=0 && r<sizeof(mypath), "GetModuleFileName failed (%d)\n", r);
|
||||
/* Get some real path to play with */
|
||||
GetWindowsDirectoryA( mypath, sizeof(mypath)-12 );
|
||||
strcat(mypath, "\\regedit.exe");
|
||||
|
||||
/* Test the interaction of SetPath and SetIDList */
|
||||
tmp_pidl=NULL;
|
||||
|
@ -180,19 +181,19 @@ static void test_get_set(void)
|
|||
ok(SUCCEEDED(r), "GetIDList failed (0x%08x)\n", r);
|
||||
if (SUCCEEDED(r))
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
strcpy(buffer,"garbage");
|
||||
r=SHGetPathFromIDListA(tmp_pidl, buffer);
|
||||
ret = SHGetPathFromIDListA(tmp_pidl, buffer);
|
||||
todo_wine {
|
||||
ok(r, "SHGetPathFromIDListA failed\n");
|
||||
ok(ret, "SHGetPathFromIDListA failed\n");
|
||||
}
|
||||
if (r)
|
||||
if (ret)
|
||||
ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
|
||||
}
|
||||
|
||||
pidl=path_to_pidl(mypath);
|
||||
todo_wine {
|
||||
ok(pidl!=NULL, "path_to_pidl returned a NULL pidl\n");
|
||||
}
|
||||
|
||||
if (pidl)
|
||||
{
|
||||
|
@ -211,31 +212,35 @@ static void test_get_set(void)
|
|||
strcpy(buffer,"garbage");
|
||||
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
|
||||
ok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
|
||||
todo_wine
|
||||
ok(lstrcmpi(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
|
||||
|
||||
}
|
||||
|
||||
/* test path with quotes (Win98 IShellLinkA_SetPath returns S_FALSE, WinXP returns S_OK) */
|
||||
/* test path with quotes (IShellLinkA_SetPath returns S_FALSE on W2K and below and S_OK on XP and above */
|
||||
r = IShellLinkA_SetPath(sl, "\"c:\\nonexistent\\file\"");
|
||||
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||
|
||||
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
|
||||
ok(r==S_OK, "GetPath failed (0x%08x)\n", r);
|
||||
ok(!lstrcmp(buffer, "C:\\nonexistent\\file"), "case doesn't match\n");
|
||||
ok(!lstrcmp(buffer, "C:\\nonexistent\\file") ||
|
||||
broken(!lstrcmp(buffer, "C:\\\"c:\\nonexistent\\file\"")), /* NT4 */
|
||||
"case doesn't match\n");
|
||||
|
||||
r = IShellLinkA_SetPath(sl, "\"c:\\foo");
|
||||
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||
ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r);
|
||||
|
||||
r = IShellLinkA_SetPath(sl, "\"\"c:\\foo");
|
||||
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||
ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r);
|
||||
|
||||
r = IShellLinkA_SetPath(sl, "c:\\foo\"");
|
||||
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||
ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r);
|
||||
|
||||
r = IShellLinkA_SetPath(sl, "\"\"c:\\foo\"");
|
||||
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||
ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r);
|
||||
|
||||
r = IShellLinkA_SetPath(sl, "\"\"c:\\foo\"\"");
|
||||
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||
ok(r==S_FALSE || r == S_OK || r == E_INVALIDARG /* Vista */, "SetPath failed (0x%08x)\n", r);
|
||||
|
||||
/* Test Getting / Setting the arguments */
|
||||
strcpy(buffer,"garbage");
|
||||
|
@ -326,7 +331,7 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
|
|||
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLinkA, (LPVOID*)&sl);
|
||||
lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08x)\n", r);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
return;
|
||||
|
||||
if (desc->description)
|
||||
|
@ -401,12 +406,12 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
|
|||
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLinkA, (LPVOID*)&sl);
|
||||
lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08x)\n", r);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
return;
|
||||
|
||||
r = IShellLinkA_QueryInterface(sl, &IID_IPersistFile, (LPVOID*)&pf);
|
||||
lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08x)\n", r);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
{
|
||||
IShellLinkA_Release(sl);
|
||||
return;
|
||||
|
@ -415,7 +420,7 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
|
|||
r = IPersistFile_Load(pf, path, STGM_READ);
|
||||
lok(SUCCEEDED(r), "load failed (0x%08x)\n", r);
|
||||
IPersistFile_Release(pf);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
{
|
||||
IShellLinkA_Release(sl);
|
||||
return;
|
||||
|
@ -493,6 +498,10 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
|
|||
|
||||
static void test_load_save(void)
|
||||
{
|
||||
WCHAR lnkfile[MAX_PATH];
|
||||
char lnkfileA[MAX_PATH];
|
||||
static const char lnkfileA_name[] = "\\test.lnk";
|
||||
|
||||
lnk_desc_t desc;
|
||||
char mypath[MAX_PATH];
|
||||
char mydir[MAX_PATH];
|
||||
|
@ -501,6 +510,17 @@ static void test_load_save(void)
|
|||
HANDLE hf;
|
||||
DWORD r;
|
||||
|
||||
if (!pGetLongPathNameA)
|
||||
{
|
||||
win_skip("GetLongPathNameA is not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't used a fixed path for the test.lnk file */
|
||||
GetTempPathA(MAX_PATH, lnkfileA);
|
||||
lstrcatA(lnkfileA, lnkfileA_name);
|
||||
MultiByteToWideChar(CP_ACP, 0, lnkfileA, -1, lnkfile, MAX_PATH);
|
||||
|
||||
/* Save an empty .lnk file */
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
create_lnk(lnkfile, &desc, 0);
|
||||
|
@ -533,10 +553,13 @@ static void test_load_save(void)
|
|||
if (p)
|
||||
*p='\0';
|
||||
|
||||
/* IShellLink returns path in long form */
|
||||
if (!pGetLongPathNameA(mypath, realpath, MAX_PATH)) strcpy( realpath, mypath );
|
||||
|
||||
/* Overwrite the existing lnk file and point it to existing files */
|
||||
desc.description="test 2";
|
||||
desc.workdir=mydir;
|
||||
desc.path=mypath;
|
||||
desc.path=realpath;
|
||||
desc.pidl=NULL;
|
||||
desc.arguments="/option1 /option2 \"Some string\"";
|
||||
desc.showcmd=SW_SHOWNORMAL;
|
||||
|
@ -565,11 +588,6 @@ static void test_load_save(void)
|
|||
/* Create a temporary non-executable file */
|
||||
r=GetTempPath(sizeof(mypath), mypath);
|
||||
ok(r<sizeof(mypath), "GetTempPath failed (%d), err %d\n", r, GetLastError());
|
||||
if (!pGetLongPathNameA)
|
||||
{
|
||||
skip("GetLongPathNameA is not available\n");
|
||||
goto cleanup;
|
||||
}
|
||||
r=pGetLongPathNameA(mypath, mydir, sizeof(mydir));
|
||||
ok(r<sizeof(mydir), "GetLongPathName failed (%d), err %d\n", r, GetLastError());
|
||||
p=strrchr(mydir, '\\');
|
||||
|
@ -602,10 +620,9 @@ static void test_load_save(void)
|
|||
* represented as a path.
|
||||
*/
|
||||
|
||||
cleanup:
|
||||
/* DeleteFileW is not implemented on Win9x */
|
||||
r=DeleteFileA("c:\\test.lnk");
|
||||
ok(r, "failed to delete link (%d)\n", GetLastError());
|
||||
r=DeleteFileA(lnkfileA);
|
||||
ok(r, "failed to delete link '%s' (%d)\n", lnkfileA, GetLastError());
|
||||
}
|
||||
|
||||
static void test_datalink(void)
|
||||
|
@ -633,19 +650,24 @@ static void test_datalink(void)
|
|||
|
||||
r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellLinkW, (LPVOID*)&sl );
|
||||
ok( r == S_OK || r == E_NOINTERFACE, "CoCreateInstance failed (0x%08x)\n", r);
|
||||
ok( r == S_OK ||
|
||||
broken(r == E_NOINTERFACE), /* Win9x */
|
||||
"CoCreateInstance failed (0x%08x)\n", r);
|
||||
if (!sl)
|
||||
{
|
||||
skip("no shelllink\n");
|
||||
win_skip("no shelllink\n");
|
||||
return;
|
||||
}
|
||||
|
||||
r = IShellLinkW_QueryInterface( sl, &_IID_IShellLinkDataList, (LPVOID*) &dl );
|
||||
ok(r == S_OK, "IShellLinkW_QueryInterface failed (0x%08x)\n", r);
|
||||
ok( r == S_OK ||
|
||||
broken(r == E_NOINTERFACE), /* NT4 */
|
||||
"IShellLinkW_QueryInterface failed (0x%08x)\n", r);
|
||||
|
||||
if (!dl)
|
||||
{
|
||||
skip("no datalink interface\n");
|
||||
win_skip("no datalink interface\n");
|
||||
IShellLinkW_Release( sl );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -700,7 +722,7 @@ START_TEST(shelllink)
|
|||
|
||||
r = CoInitialize(NULL);
|
||||
ok(SUCCEEDED(r), "CoInitialize failed (0x%08x)\n", r);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
return;
|
||||
|
||||
test_get_set();
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
* This is a test program for the SHGet{Special}Folder{Path|Location} functions
|
||||
* of shell32, that get either a filesystem path or a LPITEMIDLIST (shell
|
||||
* namespace) path for a given folder (CSIDL value).
|
||||
*
|
||||
* FIXME:
|
||||
* - Need to verify on more systems.
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
|
@ -33,6 +30,7 @@
|
|||
#include "shlguid.h"
|
||||
#include "shlobj.h"
|
||||
#include "shlwapi.h"
|
||||
#include "initguid.h"
|
||||
#include "wine/test.h"
|
||||
|
||||
/* CSIDL_MYDOCUMENTS is now the same as CSIDL_PERSONAL, but what we want
|
||||
|
@ -60,6 +58,9 @@
|
|||
#ifndef PT_FOLDER
|
||||
#define PT_FOLDER 0x31 /* has path */
|
||||
#endif
|
||||
#ifndef PT_FOLDERW
|
||||
#define PT_FOLDERW 0x35 /* has path */
|
||||
#endif
|
||||
#ifndef PT_WORKGRP
|
||||
#define PT_WORKGRP 0x41 /* no path */
|
||||
#endif
|
||||
|
@ -74,8 +75,9 @@
|
|||
static GUID CLSID_CommonDocuments = { 0x0000000c, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x1a } };
|
||||
|
||||
struct shellExpectedValues {
|
||||
int folder;
|
||||
BYTE pidlType;
|
||||
int folder;
|
||||
int numTypes;
|
||||
const BYTE *types;
|
||||
};
|
||||
|
||||
static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO *);
|
||||
|
@ -89,71 +91,86 @@ static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA);
|
|||
static HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *);
|
||||
static DLLVERSIONINFO shellVersion = { 0 };
|
||||
static LPMALLOC pMalloc;
|
||||
static const BYTE guidType[] = { PT_GUID };
|
||||
static const BYTE controlPanelType[] = { PT_SHELLEXT, PT_GUID };
|
||||
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 };
|
||||
static const BYTE personalType[] = { PT_FOLDER, PT_GUID, PT_DRIVE, 0xff /* Win9x */,
|
||||
PT_IESPECIAL2 /* Win98 */, 0 /* Vista */ };
|
||||
/* FIXME: don't know the type of 0x71 returned by Vista/2008 for printers */
|
||||
static const BYTE printersType[] = { PT_YAGUID, PT_SHELLEXT, 0x71 };
|
||||
static const BYTE ieSpecialType[] = { PT_IESPECIAL2 };
|
||||
static const BYTE shellExtType[] = { PT_SHELLEXT };
|
||||
static const BYTE workgroupType[] = { PT_WORKGRP };
|
||||
#define DECLARE_TYPE(x, y) { x, sizeof(y) / sizeof(y[0]), y }
|
||||
static const struct shellExpectedValues requiredShellValues[] = {
|
||||
{ CSIDL_BITBUCKET, PT_GUID },
|
||||
{ CSIDL_CONTROLS, PT_SHELLEXT },
|
||||
{ CSIDL_COOKIES, PT_FOLDER },
|
||||
{ CSIDL_DESKTOPDIRECTORY, PT_FOLDER },
|
||||
{ CSIDL_DRIVES, PT_GUID },
|
||||
{ CSIDL_FAVORITES, PT_FOLDER },
|
||||
{ CSIDL_FONTS, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_BITBUCKET, guidType),
|
||||
DECLARE_TYPE(CSIDL_CONTROLS, controlPanelType),
|
||||
DECLARE_TYPE(CSIDL_COOKIES, folderType),
|
||||
DECLARE_TYPE(CSIDL_DESKTOPDIRECTORY, folderType),
|
||||
DECLARE_TYPE(CSIDL_DRIVES, guidType),
|
||||
DECLARE_TYPE(CSIDL_FAVORITES, favoritesType),
|
||||
DECLARE_TYPE(CSIDL_FONTS, folderOrSpecialType),
|
||||
/* FIXME: the following fails in Wine, returns type PT_FOLDER
|
||||
{ CSIDL_HISTORY, PT_IESPECIAL2 },
|
||||
DECLARE_TYPE(CSIDL_HISTORY, ieSpecialType),
|
||||
*/
|
||||
{ CSIDL_INTERNET, PT_GUID },
|
||||
{ CSIDL_NETHOOD, PT_FOLDER },
|
||||
{ CSIDL_NETWORK, PT_GUID },
|
||||
{ CSIDL_PRINTERS, PT_YAGUID },
|
||||
{ CSIDL_PRINTHOOD, PT_FOLDER },
|
||||
{ CSIDL_PROGRAMS, PT_FOLDER },
|
||||
{ CSIDL_RECENT, PT_FOLDER },
|
||||
{ CSIDL_SENDTO, PT_FOLDER },
|
||||
{ CSIDL_STARTMENU, PT_FOLDER },
|
||||
{ CSIDL_STARTUP, PT_FOLDER },
|
||||
{ CSIDL_TEMPLATES, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_INTERNET, guidType),
|
||||
DECLARE_TYPE(CSIDL_NETHOOD, folderType),
|
||||
DECLARE_TYPE(CSIDL_NETWORK, guidType),
|
||||
DECLARE_TYPE(CSIDL_PERSONAL, personalType),
|
||||
DECLARE_TYPE(CSIDL_PRINTERS, printersType),
|
||||
DECLARE_TYPE(CSIDL_PRINTHOOD, folderType),
|
||||
DECLARE_TYPE(CSIDL_PROGRAMS, folderType),
|
||||
DECLARE_TYPE(CSIDL_RECENT, folderOrSpecialType),
|
||||
DECLARE_TYPE(CSIDL_SENDTO, folderType),
|
||||
DECLARE_TYPE(CSIDL_STARTMENU, folderType),
|
||||
DECLARE_TYPE(CSIDL_STARTUP, folderType),
|
||||
DECLARE_TYPE(CSIDL_TEMPLATES, folderType),
|
||||
};
|
||||
static const struct shellExpectedValues optionalShellValues[] = {
|
||||
/* FIXME: the following only semi-succeed; they return NULL PIDLs on XP.. hmm.
|
||||
{ CSIDL_ALTSTARTUP, PT_FOLDER },
|
||||
{ CSIDL_COMMON_ALTSTARTUP, PT_FOLDER },
|
||||
{ CSIDL_COMMON_OEM_LINKS, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_ALTSTARTUP, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_ALTSTARTUP, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_OEM_LINKS, folderType),
|
||||
*/
|
||||
/* Windows NT-only: */
|
||||
{ CSIDL_COMMON_DESKTOPDIRECTORY, PT_FOLDER },
|
||||
{ CSIDL_COMMON_DOCUMENTS, PT_SHELLEXT },
|
||||
{ CSIDL_COMMON_FAVORITES, PT_FOLDER },
|
||||
{ CSIDL_COMMON_PROGRAMS, PT_FOLDER },
|
||||
{ CSIDL_COMMON_STARTMENU, PT_FOLDER },
|
||||
{ CSIDL_COMMON_STARTUP, PT_FOLDER },
|
||||
{ CSIDL_COMMON_TEMPLATES, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_COMMON_DESKTOPDIRECTORY, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_DOCUMENTS, shellExtType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_FAVORITES, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_PROGRAMS, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_STARTMENU, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_STARTUP, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_TEMPLATES, folderType),
|
||||
/* first appearing in shell32 version 4.71: */
|
||||
{ CSIDL_APPDATA, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_APPDATA, folderType),
|
||||
/* first appearing in shell32 version 4.72: */
|
||||
{ CSIDL_INTERNET_CACHE, PT_IESPECIAL2 },
|
||||
DECLARE_TYPE(CSIDL_INTERNET_CACHE, ieSpecialType),
|
||||
/* first appearing in shell32 version 5.0: */
|
||||
{ CSIDL_ADMINTOOLS, PT_FOLDER },
|
||||
{ CSIDL_COMMON_APPDATA, PT_FOLDER },
|
||||
{ CSIDL_LOCAL_APPDATA, PT_FOLDER },
|
||||
{ OLD_CSIDL_MYDOCUMENTS, PT_FOLDER },
|
||||
{ CSIDL_MYMUSIC, PT_FOLDER },
|
||||
{ CSIDL_MYPICTURES, PT_FOLDER },
|
||||
{ CSIDL_MYVIDEO, PT_FOLDER },
|
||||
{ CSIDL_PROFILE, PT_FOLDER },
|
||||
{ CSIDL_PROGRAM_FILES, PT_FOLDER },
|
||||
{ CSIDL_PROGRAM_FILESX86, PT_FOLDER },
|
||||
{ CSIDL_PROGRAM_FILES_COMMON, PT_FOLDER },
|
||||
{ CSIDL_PROGRAM_FILES_COMMONX86, PT_FOLDER },
|
||||
{ CSIDL_SYSTEM, PT_FOLDER },
|
||||
{ CSIDL_WINDOWS, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_ADMINTOOLS, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_APPDATA, folderType),
|
||||
DECLARE_TYPE(CSIDL_LOCAL_APPDATA, folderType),
|
||||
DECLARE_TYPE(OLD_CSIDL_MYDOCUMENTS, folderType),
|
||||
DECLARE_TYPE(CSIDL_MYMUSIC, folderType),
|
||||
DECLARE_TYPE(CSIDL_MYPICTURES, folderType),
|
||||
DECLARE_TYPE(CSIDL_MYVIDEO, folderType),
|
||||
DECLARE_TYPE(CSIDL_PROFILE, folderType),
|
||||
DECLARE_TYPE(CSIDL_PROGRAM_FILES, folderType),
|
||||
DECLARE_TYPE(CSIDL_PROGRAM_FILESX86, folderType),
|
||||
DECLARE_TYPE(CSIDL_PROGRAM_FILES_COMMON, folderType),
|
||||
DECLARE_TYPE(CSIDL_PROGRAM_FILES_COMMONX86, folderType),
|
||||
DECLARE_TYPE(CSIDL_SYSTEM, folderType),
|
||||
DECLARE_TYPE(CSIDL_WINDOWS, folderType),
|
||||
/* first appearing in shell32 6.0: */
|
||||
{ CSIDL_CDBURN_AREA, PT_FOLDER },
|
||||
{ CSIDL_COMMON_MUSIC, PT_FOLDER },
|
||||
{ CSIDL_COMMON_PICTURES, PT_FOLDER },
|
||||
{ CSIDL_COMMON_VIDEO, PT_FOLDER },
|
||||
{ CSIDL_COMPUTERSNEARME, PT_WORKGRP },
|
||||
{ CSIDL_RESOURCES, PT_FOLDER },
|
||||
{ CSIDL_RESOURCES_LOCALIZED, PT_FOLDER },
|
||||
DECLARE_TYPE(CSIDL_CDBURN_AREA, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_MUSIC, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_PICTURES, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMMON_VIDEO, folderType),
|
||||
DECLARE_TYPE(CSIDL_COMPUTERSNEARME, workgroupType),
|
||||
DECLARE_TYPE(CSIDL_RESOURCES, folderType),
|
||||
DECLARE_TYPE(CSIDL_RESOURCES_LOCALIZED, folderType),
|
||||
};
|
||||
#undef DECLARE_TYPE
|
||||
|
||||
static void loadShell32(void)
|
||||
{
|
||||
|
@ -188,9 +205,8 @@ static void loadShell32(void)
|
|||
{
|
||||
shellVersion.cbSize = sizeof(shellVersion);
|
||||
pDllGetVersion(&shellVersion);
|
||||
if (winetest_interactive)
|
||||
printf("shell32 version is %d.%d\n",
|
||||
shellVersion.dwMajorVersion, shellVersion.dwMinorVersion);
|
||||
trace("shell32 version is %d.%d\n",
|
||||
shellVersion.dwMajorVersion, shellVersion.dwMinorVersion);
|
||||
}
|
||||
#undef GET_PROC
|
||||
}
|
||||
|
@ -272,10 +288,8 @@ static const char *getFolderName(int folder)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *printGUID(const GUID *guid)
|
||||
static const char *printGUID(const GUID *guid, char * guidSTR)
|
||||
{
|
||||
static char guidSTR[39];
|
||||
|
||||
if (!guid) return NULL;
|
||||
|
||||
sprintf(guidSTR, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
|
@ -302,15 +316,8 @@ static void testSHGetFolderLocationInvalidArgs(void)
|
|||
/* check a bogus user token: */
|
||||
pidl = NULL;
|
||||
hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
|
||||
ok(hr == E_FAIL,
|
||||
"SHGetFolderLocation(NULL, CSIDL_FAVORITES, 2, 0, &pidl) returned 0x%08x, expected E_FAIL\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
IMalloc_Free(pMalloc, pidl);
|
||||
/* check reserved is not zero: */
|
||||
pidl = NULL;
|
||||
hr = pSHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, 1, &pidl);
|
||||
ok(hr == E_INVALIDARG,
|
||||
"SHGetFolderLocation(NULL, CSIDL_DESKTOP, NULL, 1, &pidl) returned 0x%08x, expected E_INVALIDARG\n", hr);
|
||||
ok(hr == E_FAIL || hr == E_HANDLE,
|
||||
"SHGetFolderLocation(NULL, CSIDL_FAVORITES, 2, 0, &pidl) returned 0x%08x, expected E_FAIL or E_HANDLE\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
IMalloc_Free(pMalloc, pidl);
|
||||
/* a NULL pidl pointer crashes, so don't test it */
|
||||
|
@ -340,7 +347,9 @@ static void testSHGetFolderPathInvalidArgs(void)
|
|||
/* expect 2's a bogus handle, especially since we didn't open it */
|
||||
hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2,
|
||||
SHGFP_TYPE_DEFAULT, path);
|
||||
ok(hr == E_FAIL,
|
||||
ok(hr == E_FAIL ||
|
||||
hr == E_HANDLE || /* Windows Vista and 2008 */
|
||||
broken(hr == S_OK), /* Windows 2000 and Me */
|
||||
"SHGetFolderPathA(NULL, CSIDL_DESKTOP, 2, SHGFP_TYPE_DEFAULT, path) returned 0x%08x, expected E_FAIL\n", hr);
|
||||
hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
|
||||
ok(hr == E_INVALIDARG,
|
||||
|
@ -379,7 +388,7 @@ static void testApiParameters(void)
|
|||
}
|
||||
|
||||
/* Returns the folder's PIDL type, or 0xff if one can't be found. */
|
||||
static BYTE testSHGetFolderLocation(BOOL optional, int folder)
|
||||
static BYTE testSHGetFolderLocation(int folder)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
HRESULT hr;
|
||||
|
@ -390,12 +399,8 @@ static BYTE testSHGetFolderLocation(BOOL optional, int folder)
|
|||
|
||||
pidl = NULL;
|
||||
hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
|
||||
ok(SUCCEEDED(hr) || optional,
|
||||
"SHGetFolderLocation(NULL, %s, NULL, 0, &pidl) failed: 0x%08x\n", getFolderName(folder), hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ok(pidl != NULL,
|
||||
"SHGetFolderLocation(NULL, %s, NULL, 0, &pidl) succeeded, but returned pidl is NULL\n", getFolderName(folder));
|
||||
if (pidl)
|
||||
{
|
||||
LPITEMIDLIST pidlLast = pILFindLastID(pidl);
|
||||
|
@ -411,7 +416,7 @@ static BYTE testSHGetFolderLocation(BOOL optional, int folder)
|
|||
}
|
||||
|
||||
/* Returns the folder's PIDL type, or 0xff if one can't be found. */
|
||||
static BYTE testSHGetSpecialFolderLocation(BOOL optional, int folder)
|
||||
static BYTE testSHGetSpecialFolderLocation(int folder)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
HRESULT hr;
|
||||
|
@ -422,12 +427,8 @@ static BYTE testSHGetSpecialFolderLocation(BOOL optional, int folder)
|
|||
|
||||
pidl = NULL;
|
||||
hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
|
||||
ok(SUCCEEDED(hr) || optional,
|
||||
"SHGetSpecialFolderLocation(NULL, %s, &pidl) failed: 0x%08x\n", getFolderName(folder), hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ok(pidl != NULL,
|
||||
"SHGetSpecialFolderLocation(NULL, %s, &pidl) succeeded, but returned pidl is NULL\n", getFolderName(folder));
|
||||
if (pidl)
|
||||
{
|
||||
LPITEMIDLIST pidlLast = pILFindLastID(pidl);
|
||||
|
@ -477,17 +478,27 @@ static void testShellValues(const struct shellExpectedValues testEntries[],
|
|||
for (i = 0; i < numEntries; i++)
|
||||
{
|
||||
BYTE type;
|
||||
int j;
|
||||
BOOL foundTypeMatch = FALSE;
|
||||
|
||||
type = testSHGetFolderLocation(optional, testEntries[i].folder);
|
||||
ok(type == testEntries[i].pidlType || optional,
|
||||
"%s has type %d (0x%02x), expected %d (0x%02x)\n",
|
||||
getFolderName(testEntries[i].folder), type, type,
|
||||
testEntries[i].pidlType, testEntries[i].pidlType);
|
||||
type = testSHGetSpecialFolderLocation(optional, testEntries[i].folder);
|
||||
ok(type == testEntries[i].pidlType || optional,
|
||||
"%s has type %d (0x%02x), expected %d (0x%02x)\n",
|
||||
getFolderName(testEntries[i].folder), type, type,
|
||||
testEntries[i].pidlType, testEntries[i].pidlType);
|
||||
if (pSHGetFolderLocation)
|
||||
{
|
||||
type = testSHGetFolderLocation(testEntries[i].folder);
|
||||
for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
|
||||
if (testEntries[i].types[j] == type)
|
||||
foundTypeMatch = TRUE;
|
||||
ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
|
||||
"%s has unexpected type %d (0x%02x)\n",
|
||||
getFolderName(testEntries[i].folder), type, type);
|
||||
}
|
||||
type = testSHGetSpecialFolderLocation(testEntries[i].folder);
|
||||
for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
|
||||
j < testEntries[i].numTypes; j++)
|
||||
if (testEntries[i].types[j] == type)
|
||||
foundTypeMatch = TRUE;
|
||||
ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
|
||||
"%s has unexpected type %d (0x%02x)\n",
|
||||
getFolderName(testEntries[i].folder), type, type);
|
||||
switch (type)
|
||||
{
|
||||
case PT_FOLDER:
|
||||
|
@ -530,7 +541,7 @@ static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
|
|||
* fail if it isn't--that check should already have been done.
|
||||
* Fails if the returned PIDL is a GUID whose value does not match guid.
|
||||
*/
|
||||
static void matchGUID(int folder, const GUID *guid)
|
||||
static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
HRESULT hr;
|
||||
|
@ -548,10 +559,18 @@ static void matchGUID(int folder, const GUID *guid)
|
|||
pidlLast->mkid.abID[0] == PT_GUID))
|
||||
{
|
||||
GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
|
||||
char shellGuidStr[39], guidStr[39], guid_altStr[39];
|
||||
|
||||
ok(IsEqualIID(shellGuid, guid),
|
||||
"%s: got GUID %s, expected %s\n", getFolderName(folder),
|
||||
printGUID(shellGuid), printGUID(guid));
|
||||
if (!guid_alt)
|
||||
ok(IsEqualIID(shellGuid, guid),
|
||||
"%s: got GUID %s, expected %s\n", getFolderName(folder),
|
||||
printGUID(shellGuid, shellGuidStr), printGUID(guid, guidStr));
|
||||
else
|
||||
ok(IsEqualIID(shellGuid, guid) ||
|
||||
IsEqualIID(shellGuid, guid_alt),
|
||||
"%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
|
||||
printGUID(shellGuid, shellGuidStr), printGUID(guid, guidStr),
|
||||
printGUID(guid_alt, guid_altStr));
|
||||
}
|
||||
IMalloc_Free(pMalloc, pidl);
|
||||
}
|
||||
|
@ -561,56 +580,31 @@ static void testDesktop(void)
|
|||
{
|
||||
testSHGetFolderPath(FALSE, CSIDL_DESKTOP);
|
||||
testSHGetSpecialFolderPath(FALSE, CSIDL_DESKTOP);
|
||||
/* Test the desktop; even though SHITEMID should always contain abID of at
|
||||
* least one type, when cb is 0 its value is undefined. So don't check
|
||||
* what the returned type is, just make sure it exists.
|
||||
*/
|
||||
testSHGetFolderLocation(FALSE, CSIDL_DESKTOP);
|
||||
testSHGetSpecialFolderLocation(FALSE, CSIDL_DESKTOP);
|
||||
}
|
||||
|
||||
static void testPersonal(void)
|
||||
{
|
||||
BYTE type;
|
||||
|
||||
/* The pidl may be a real folder, or a virtual directory, or a drive if the
|
||||
* home directory is set to the root directory of a drive.
|
||||
*/
|
||||
type = testSHGetFolderLocation(FALSE, CSIDL_PERSONAL);
|
||||
ok(type == PT_FOLDER || type == PT_GUID || type == PT_DRIVE,
|
||||
"CSIDL_PERSONAL returned invalid type 0x%02x, "
|
||||
"expected PT_FOLDER or PT_GUID\n", type);
|
||||
if (type == PT_FOLDER)
|
||||
testSHGetFolderPath(FALSE, CSIDL_PERSONAL);
|
||||
type = testSHGetSpecialFolderLocation(FALSE, CSIDL_PERSONAL);
|
||||
ok(type == PT_FOLDER || type == PT_GUID || type == PT_DRIVE,
|
||||
"CSIDL_PERSONAL returned invalid type 0x%02x, "
|
||||
"expected PT_FOLDER or PT_GUID\n", type);
|
||||
if (type == PT_FOLDER)
|
||||
testSHGetSpecialFolderPath(FALSE, CSIDL_PERSONAL);
|
||||
}
|
||||
|
||||
/* Checks the PIDL type of all the known values. */
|
||||
static void testPidlTypes(void)
|
||||
{
|
||||
testDesktop();
|
||||
testPersonal();
|
||||
testShellValues(requiredShellValues, ARRAY_SIZE(requiredShellValues),
|
||||
FALSE);
|
||||
testShellValues(optionalShellValues, ARRAY_SIZE(optionalShellValues),
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/* FIXME: Should be in shobjidl.idl */
|
||||
DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73, 0x67, 0xFC, 0x96, 0xEF, 0x3C);
|
||||
|
||||
/* Verifies various shell virtual folders have the correct well-known GUIDs. */
|
||||
static void testGUIDs(void)
|
||||
{
|
||||
matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin);
|
||||
matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel);
|
||||
matchGUID(CSIDL_DRIVES, &CLSID_MyComputer);
|
||||
matchGUID(CSIDL_INTERNET, &CLSID_Internet);
|
||||
matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces);
|
||||
matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments);
|
||||
matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments);
|
||||
matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
|
||||
matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
|
||||
matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
|
||||
matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
|
||||
matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder); /* Vista and higher */
|
||||
matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, NULL);
|
||||
matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments, NULL);
|
||||
}
|
||||
|
||||
/* Verifies various shell paths match the environment variables to which they
|
||||
|
@ -671,8 +665,8 @@ static void testWinDir(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Verifies the shell path for CSIDL_SYSTEM and CSIDL_SYSTEMX86 matches the
|
||||
* return from GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
|
||||
/* Verifies the shell path for CSIDL_SYSTEM matches the return from
|
||||
* GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
|
||||
* no foul--not every shell32 version supports CSIDL_SYSTEM.
|
||||
*/
|
||||
static void testSystemDir(void)
|
||||
|
@ -690,16 +684,10 @@ static void testSystemDir(void)
|
|||
"GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
|
||||
systemDir, systemShellPath);
|
||||
}
|
||||
/* check CSIDL_SYSTEMX86; note that this isn't always present, so don't
|
||||
* worry if it fails
|
||||
/* CSIDL_SYSTEMX86 isn't checked in the same way, since it's different
|
||||
* on Win64 (and non-x86 Windows systems, if there are any still in
|
||||
* existence) than on Win32.
|
||||
*/
|
||||
if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
|
||||
{
|
||||
myPathRemoveBackslashA(systemShellPath);
|
||||
ok(!lstrcmpiA(systemDir, systemShellPath),
|
||||
"GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
|
||||
systemDir, systemShellPath);
|
||||
}
|
||||
}
|
||||
|
||||
/* Globals used by subprocesses */
|
||||
|
@ -723,7 +711,7 @@ static void testNonExistentPath1(void)
|
|||
{
|
||||
HRESULT hr;
|
||||
LPITEMIDLIST pidl;
|
||||
char path[MAX_PATH];
|
||||
char *p, path[MAX_PATH];
|
||||
|
||||
/* test some failure cases first: */
|
||||
hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL,
|
||||
|
@ -733,16 +721,16 @@ static void testNonExistentPath1(void)
|
|||
pidl = NULL;
|
||||
hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0,
|
||||
&pidl);
|
||||
ok(hr == E_FAIL,
|
||||
"SHGetFolderLocation returned 0x%08x, expected E_FAIL\n", hr);
|
||||
ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
|
||||
"SHGetFolderLocation returned 0x%08x\n", hr);
|
||||
if (SUCCEEDED(hr) && pidl)
|
||||
IMalloc_Free(pMalloc, pidl);
|
||||
ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
|
||||
"SHGetSpecialFolderPath succeeded, expected failure\n");
|
||||
pidl = NULL;
|
||||
hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
|
||||
ok(hr == E_FAIL, "SHGetFolderLocation returned 0x%08x, expected E_FAIL\n",
|
||||
hr);
|
||||
ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
|
||||
"SHGetFolderLocation returned 0x%08x\n", hr);
|
||||
if (SUCCEEDED(hr) && pidl)
|
||||
IMalloc_Free(pMalloc, pidl);
|
||||
/* now test success: */
|
||||
|
@ -752,8 +740,7 @@ static void testNonExistentPath1(void)
|
|||
{
|
||||
BOOL ret;
|
||||
|
||||
if (winetest_interactive)
|
||||
printf("CSIDL_FAVORITES was changed to %s\n", path);
|
||||
trace("CSIDL_FAVORITES was changed to %s\n", path);
|
||||
ret = CreateDirectoryA(path, NULL);
|
||||
ok(!ret,
|
||||
"CreateDirectoryA succeeded but should have failed "
|
||||
|
@ -763,6 +750,13 @@ static void testNonExistentPath1(void)
|
|||
"CreateDirectoryA failed with %d, "
|
||||
"expected ERROR_ALREADY_EXISTS\n",
|
||||
GetLastError());
|
||||
p = path + strlen(path);
|
||||
strcpy(p, "\\desktop.ini");
|
||||
DeleteFileA(path);
|
||||
*p = 0;
|
||||
SetFileAttributesA( path, FILE_ATTRIBUTE_NORMAL );
|
||||
ret = RemoveDirectoryA(path);
|
||||
ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
|
||||
}
|
||||
ok(SUCCEEDED(hr),
|
||||
"SHGetFolderPath(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, "
|
||||
|
@ -831,15 +825,13 @@ static void testNonExistentPath(void)
|
|||
memcpy(modifiedPath, originalPath, len);
|
||||
modifiedPath[len++] = '2';
|
||||
modifiedPath[len++] = '\0';
|
||||
if (winetest_interactive)
|
||||
printf("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
|
||||
trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
|
||||
if (!RegSetValueExA(key, "Favorites", 0, type,
|
||||
(LPBYTE)modifiedPath, len))
|
||||
{
|
||||
char buffer[MAX_PATH+20];
|
||||
STARTUPINFOA startup;
|
||||
PROCESS_INFORMATION info;
|
||||
HRESULT hr;
|
||||
|
||||
sprintf(buffer, "%s tests/shellpath.c 1", selfname);
|
||||
memset(&startup, 0, sizeof(startup));
|
||||
|
@ -850,14 +842,8 @@ static void testNonExistentPath(void)
|
|||
&startup, &info);
|
||||
winetest_wait_child_process( info.hProcess );
|
||||
|
||||
/* Query the path to be able to delete it below */
|
||||
hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL,
|
||||
SHGFP_TYPE_CURRENT, modifiedPath);
|
||||
ok(SUCCEEDED(hr), "SHGetFolderPathA failed: 0x%08x\n", hr);
|
||||
|
||||
/* restore original values: */
|
||||
if (winetest_interactive)
|
||||
printf("Restoring CSIDL_FAVORITES to %s\n", originalPath);
|
||||
trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
|
||||
RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) originalPath,
|
||||
strlen(originalPath) + 1);
|
||||
RegFlushKey(key);
|
||||
|
@ -871,21 +857,13 @@ static void testNonExistentPath(void)
|
|||
&startup, &info);
|
||||
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
|
||||
"child process termination\n");
|
||||
|
||||
strcpy(buffer, modifiedPath);
|
||||
strcat(buffer, "\\desktop.ini");
|
||||
DeleteFileA(buffer);
|
||||
RemoveDirectoryA(modifiedPath);
|
||||
}
|
||||
}
|
||||
else if (winetest_interactive)
|
||||
printf("RegQueryValueExA(key, Favorites, ...) failed\n");
|
||||
else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
|
||||
if (key)
|
||||
RegCloseKey(key);
|
||||
}
|
||||
else if (winetest_interactive)
|
||||
printf("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n",
|
||||
userShellFolders);
|
||||
else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders);
|
||||
}
|
||||
|
||||
START_TEST(shellpath)
|
||||
|
@ -898,6 +876,10 @@ START_TEST(shellpath)
|
|||
doChild(myARGV[2]);
|
||||
else
|
||||
{
|
||||
/* Report missing functions once */
|
||||
if (!pSHGetFolderLocation)
|
||||
win_skip("SHGetFolderLocation is not available\n");
|
||||
|
||||
/* first test various combinations of parameters: */
|
||||
testApiParameters();
|
||||
|
||||
|
|
126
rostests/winetests/shell32/shfldr_special.c
Normal file
126
rostests/winetests/shell32/shfldr_special.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Tests for special shell folders
|
||||
*
|
||||
* Copyright 2008 Robert Shearman for CodeWeavers
|
||||
* Copyright 2008 Owen Rudge
|
||||
*
|
||||
* 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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define COBJMACROS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "shellapi.h"
|
||||
#include "shlobj.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
/* Tests for My Network Places */
|
||||
static void test_parse_for_entire_network(void)
|
||||
{
|
||||
static WCHAR my_network_places_path[] = {
|
||||
':',':','{','2','0','8','D','2','C','6','0','-','3','A','E','A','-',
|
||||
'1','0','6','9','-','A','2','D','7','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 };
|
||||
static WCHAR entire_network_path[] = {
|
||||
':',':','{','2','0','8','D','2','C','6','0','-','3','A','E','A','-',
|
||||
'1','0','6','9','-','A','2','D','7','-','0','8','0','0','2','B','3','0','3','0','9','D',
|
||||
'}','\\','E','n','t','i','r','e','N','e','t','w','o','r','k',0 };
|
||||
IShellFolder *psfDesktop;
|
||||
HRESULT hr;
|
||||
DWORD eaten = 0xdeadbeef;
|
||||
LPITEMIDLIST pidl;
|
||||
DWORD attr = ~0;
|
||||
DWORD expected_attr;
|
||||
DWORD alter_attr;
|
||||
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%x\n", hr);
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, my_network_places_path, &eaten, &pidl, &attr);
|
||||
ok(hr == S_OK, "IShellFolder_ParseDisplayName failed with error 0x%x\n", hr);
|
||||
todo_wine
|
||||
ok(eaten == 0xdeadbeef, "eaten should not have been set to %u\n", eaten);
|
||||
expected_attr = SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
|
||||
todo_wine
|
||||
ok((attr == expected_attr) || /* Win9x, NT4 */
|
||||
(attr == (expected_attr | SFGAO_STREAM)) || /* W2K */
|
||||
(attr == (expected_attr | SFGAO_CANDELETE)) || /* XP, W2K3 */
|
||||
(attr == (expected_attr | SFGAO_CANDELETE | SFGAO_NONENUMERATED)), /* Vista */
|
||||
"Unexpected attributes : %08x\n", attr);
|
||||
|
||||
ILFree(pidl);
|
||||
|
||||
/* Start clean again */
|
||||
eaten = 0xdeadbeef;
|
||||
attr = ~0;
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, entire_network_path, &eaten, &pidl, &attr);
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_BAD_NET_NAME) || hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER))
|
||||
{
|
||||
win_skip("'EntireNetwork' is not available on Win9x, NT4 and Vista\n");
|
||||
return;
|
||||
}
|
||||
ok(hr == S_OK, "IShellFolder_ParseDisplayName failed with error 0x%x\n", hr);
|
||||
todo_wine
|
||||
ok(eaten == 0xdeadbeef, "eaten should not have been set to %u\n", eaten);
|
||||
expected_attr = SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_STORAGEANCESTOR|SFGAO_HASPROPSHEET|SFGAO_CANLINK;
|
||||
alter_attr = (expected_attr & (~SFGAO_STORAGEANCESTOR)) | SFGAO_STREAM;
|
||||
todo_wine
|
||||
ok(attr == expected_attr ||
|
||||
attr == alter_attr, /* win2k */
|
||||
"attr should be 0x%x or 0x%x, not 0x%x\n", expected_attr, alter_attr, attr);
|
||||
|
||||
ILFree(pidl);
|
||||
}
|
||||
|
||||
/* Tests for Control Panel */
|
||||
static void test_parse_for_control_panel(void)
|
||||
{
|
||||
/* path of My Computer\Control Panel */
|
||||
static WCHAR control_panel_path[] = {
|
||||
':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}','\\',
|
||||
':',':','{','2','1','E','C','2','0','2','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','D','-','0','8','0','0','2','B','3','0','3','0','9','D','}', 0 };
|
||||
IShellFolder *psfDesktop;
|
||||
HRESULT hr;
|
||||
DWORD eaten = 0xdeadbeef;
|
||||
LPITEMIDLIST pidl;
|
||||
DWORD attr = ~0;
|
||||
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
ok(hr == S_OK, "SHGetDesktopFolder failed with error 0x%x\n", hr);
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, control_panel_path, &eaten, &pidl, &attr);
|
||||
ok(hr == S_OK, "IShellFolder_ParseDisplayName failed with error 0x%x\n", hr);
|
||||
todo_wine ok(eaten == 0xdeadbeef, "eaten should not have been set to %u\n", eaten);
|
||||
todo_wine
|
||||
ok((attr == (SFGAO_CANLINK | SFGAO_FOLDER)) || /* Win9x, NT4 */
|
||||
(attr == (SFGAO_CANLINK | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_STREAM)) || /* W2K */
|
||||
(attr == (SFGAO_CANLINK | SFGAO_FOLDER | SFGAO_HASSUBFOLDER)) || /* W2K, XP, W2K3 */
|
||||
(attr == (SFGAO_CANLINK | SFGAO_NONENUMERATED)) || /* Vista */
|
||||
(attr == SFGAO_CANLINK), /* Vista, W2K8 */
|
||||
"Unexpected attributes : %08x\n", attr);
|
||||
|
||||
ILFree(pidl);
|
||||
}
|
||||
|
||||
|
||||
START_TEST(shfldr_special)
|
||||
{
|
||||
test_parse_for_entire_network();
|
||||
test_parse_for_control_panel();
|
||||
}
|
|
@ -32,12 +32,13 @@
|
|||
* we could check
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Needed to get SEE_MASK_NOZONECHECKS with the PSDK */
|
||||
#define NTDDI_WINXPSP1 0x05010100
|
||||
#define NTDDI_VERSION NTDDI_WINXPSP1
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "wtypes.h"
|
||||
#include "winbase.h"
|
||||
|
@ -89,7 +90,7 @@ static void strcat_param(char* str, const char* param)
|
|||
static char shell_call[2048]="";
|
||||
static int shell_execute(LPCSTR operation, LPCSTR file, LPCSTR parameters, LPCSTR directory)
|
||||
{
|
||||
int rc;
|
||||
INT_PTR rc;
|
||||
|
||||
strcpy(shell_call, "ShellExecute(");
|
||||
strcat_param(shell_call, operation);
|
||||
|
@ -110,8 +111,7 @@ static int shell_execute(LPCSTR operation, LPCSTR file, LPCSTR parameters, LPCST
|
|||
* association it displays the 'Open With' dialog and I could not find
|
||||
* a flag to prevent this.
|
||||
*/
|
||||
rc=(int)ShellExecute(NULL, operation, file, parameters, directory,
|
||||
SW_SHOWNORMAL);
|
||||
rc=(INT_PTR)ShellExecute(NULL, operation, file, parameters, directory, SW_SHOWNORMAL);
|
||||
|
||||
if (rc > 32)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ static int shell_execute_ex(DWORD mask, LPCSTR operation, LPCSTR file,
|
|||
{
|
||||
SHELLEXECUTEINFO sei;
|
||||
BOOL success;
|
||||
int rc;
|
||||
INT_PTR rc;
|
||||
|
||||
strcpy(shell_call, "ShellExecuteEx(");
|
||||
strcat_param(shell_call, operation);
|
||||
|
@ -167,9 +167,9 @@ static int shell_execute_ex(DWORD mask, LPCSTR operation, LPCSTR file,
|
|||
DeleteFile(child_file);
|
||||
SetLastError(0xcafebabe);
|
||||
success=ShellExecuteEx(&sei);
|
||||
rc=(int)sei.hInstApp;
|
||||
rc=(INT_PTR)sei.hInstApp;
|
||||
ok((success && rc > 32) || (!success && rc <= 32),
|
||||
"%s rc=%d and hInstApp=%d is not allowed\n", shell_call, success, rc);
|
||||
"%s rc=%d and hInstApp=%ld is not allowed\n", shell_call, success, rc);
|
||||
|
||||
if (rc > 32)
|
||||
{
|
||||
|
@ -200,7 +200,7 @@ static int shell_execute_ex(DWORD mask, LPCSTR operation, LPCSTR file,
|
|||
*
|
||||
***/
|
||||
|
||||
static void create_test_association(const char* extension)
|
||||
static BOOL create_test_association(const char* extension)
|
||||
{
|
||||
HKEY hkey, hkey_shell;
|
||||
char class[MAX_PATH];
|
||||
|
@ -209,19 +209,25 @@ static void create_test_association(const char* extension)
|
|||
sprintf(class, "shlexec%s", extension);
|
||||
rc=RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, NULL, 0, KEY_SET_VALUE,
|
||||
NULL, &hkey, NULL);
|
||||
assert(rc==ERROR_SUCCESS);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
rc=RegSetValueEx(hkey, NULL, 0, REG_SZ, (LPBYTE) class, strlen(class)+1);
|
||||
assert(rc==ERROR_SUCCESS);
|
||||
ok(rc==ERROR_SUCCESS, "RegSetValueEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc);
|
||||
CloseHandle(hkey);
|
||||
|
||||
rc=RegCreateKeyEx(HKEY_CLASSES_ROOT, class, 0, NULL, 0,
|
||||
KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, NULL, &hkey, NULL);
|
||||
assert(rc==ERROR_SUCCESS);
|
||||
ok(rc==ERROR_SUCCESS, "RegCreateKeyEx '%s' failed, expected ERROR_SUCCESS, got %d\n", class, rc);
|
||||
|
||||
rc=RegCreateKeyEx(hkey, "shell", 0, NULL, 0,
|
||||
KEY_CREATE_SUB_KEY, NULL, &hkey_shell, NULL);
|
||||
assert(rc==ERROR_SUCCESS);
|
||||
ok(rc==ERROR_SUCCESS, "RegCreateKeyEx 'shell' failed, expected ERROR_SUCCESS, got %d\n", rc);
|
||||
|
||||
CloseHandle(hkey);
|
||||
CloseHandle(hkey_shell);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
|
||||
|
@ -620,8 +626,8 @@ typedef struct
|
|||
static filename_tests_t filename_tests[]=
|
||||
{
|
||||
/* Test bad / nonexistent filenames */
|
||||
{NULL, "%s\\nonexistent.shlexec", 0x11, SE_ERR_FNF},
|
||||
{NULL, "%s\\nonexistent.noassoc", 0x11, SE_ERR_FNF},
|
||||
{NULL, "%s\\nonexistent.shlexec", 0x0, SE_ERR_FNF},
|
||||
{NULL, "%s\\nonexistent.noassoc", 0x0, SE_ERR_FNF},
|
||||
|
||||
/* Standard tests */
|
||||
{NULL, "%s\\test file.shlexec", 0x0, 33},
|
||||
|
@ -637,7 +643,7 @@ static filename_tests_t filename_tests[]=
|
|||
{NULL, "%s\\test file.shlexec.noassoc", 0x0, SE_ERR_NOASSOC},
|
||||
|
||||
/* Test alternate verbs */
|
||||
{"LowerL", "%s\\nonexistent.shlexec", 0x11, SE_ERR_FNF},
|
||||
{"LowerL", "%s\\nonexistent.shlexec", 0x0, SE_ERR_FNF},
|
||||
{"LowerL", "%s\\test file.noassoc", 0x0, SE_ERR_NOASSOC},
|
||||
|
||||
{"QuotedLowerL", "%s\\test file.shlexec", 0x0, 33},
|
||||
|
@ -828,45 +834,56 @@ static void test_find_executable(void)
|
|||
char filename[MAX_PATH];
|
||||
char command[MAX_PATH];
|
||||
const filename_tests_t* test;
|
||||
int rc;
|
||||
INT_PTR rc;
|
||||
|
||||
create_test_association(".sfe");
|
||||
if (!create_test_association(".sfe"))
|
||||
{
|
||||
skip("Unable to create association for '.sfe'\n");
|
||||
return;
|
||||
}
|
||||
create_test_verb(".sfe", "Open", 1, "%1");
|
||||
|
||||
/* Don't test FindExecutable(..., NULL), it always crashes */
|
||||
|
||||
strcpy(command, "your word");
|
||||
rc=(int)FindExecutableA(NULL, NULL, command);
|
||||
ok(rc == SE_ERR_FNF || rc > 32 /* nt4 */, "FindExecutable(NULL) returned %d\n", rc);
|
||||
if (0) /* Can crash on Vista! */
|
||||
{
|
||||
rc=(INT_PTR)FindExecutableA(NULL, NULL, command);
|
||||
ok(rc == SE_ERR_FNF || rc > 32 /* nt4 */, "FindExecutable(NULL) returned %ld\n", rc);
|
||||
ok(strcmp(command, "your word") != 0, "FindExecutable(NULL) returned command=[%s]\n", command);
|
||||
}
|
||||
|
||||
strcpy(command, "your word");
|
||||
rc=(int)FindExecutableA(tmpdir, NULL, command);
|
||||
ok(rc == SE_ERR_NOASSOC /* >= win2000 */ || rc > 32 /* win98, nt4 */, "FindExecutable(NULL) returned %d\n", rc);
|
||||
rc=(INT_PTR)FindExecutableA(tmpdir, NULL, command);
|
||||
ok(rc == SE_ERR_NOASSOC /* >= win2000 */ || rc > 32 /* win98, nt4 */, "FindExecutable(NULL) returned %ld\n", rc);
|
||||
ok(strcmp(command, "your word") != 0, "FindExecutable(NULL) returned command=[%s]\n", command);
|
||||
|
||||
sprintf(filename, "%s\\test file.sfe", tmpdir);
|
||||
rc=(int)FindExecutableA(filename, NULL, command);
|
||||
ok(rc > 32, "FindExecutable(%s) returned %d\n", filename, rc);
|
||||
rc=(INT_PTR)FindExecutableA(filename, NULL, command);
|
||||
ok(rc > 32, "FindExecutable(%s) returned %ld\n", filename, rc);
|
||||
/* Depending on the platform, command could be '%1' or 'test file.sfe' */
|
||||
|
||||
rc=(int)FindExecutableA("test file.sfe", tmpdir, command);
|
||||
ok(rc > 32, "FindExecutable(%s) returned %d\n", filename, rc);
|
||||
rc=(INT_PTR)FindExecutableA("test file.sfe", tmpdir, command);
|
||||
ok(rc > 32, "FindExecutable(%s) returned %ld\n", filename, rc);
|
||||
|
||||
rc=(int)FindExecutableA("test file.sfe", NULL, command);
|
||||
todo_wine ok(rc == SE_ERR_FNF, "FindExecutable(%s) returned %d\n", filename, rc);
|
||||
rc=(INT_PTR)FindExecutableA("test file.sfe", NULL, command);
|
||||
ok(rc == SE_ERR_FNF, "FindExecutable(%s) returned %ld\n", filename, rc);
|
||||
|
||||
delete_test_association(".sfe");
|
||||
|
||||
create_test_association(".shl");
|
||||
if (!create_test_association(".shl"))
|
||||
{
|
||||
skip("Unable to create association for '.shl'\n");
|
||||
return;
|
||||
}
|
||||
create_test_verb(".shl", "Open", 0, "Open");
|
||||
|
||||
sprintf(filename, "%s\\test file.shl", tmpdir);
|
||||
rc=(int)FindExecutableA(filename, NULL, command);
|
||||
ok(rc == SE_ERR_FNF /* NT4 */ || rc > 32, "FindExecutable(%s) returned %d\n", filename, rc);
|
||||
rc=(INT_PTR)FindExecutableA(filename, NULL, command);
|
||||
ok(rc == SE_ERR_FNF /* NT4 */ || rc > 32, "FindExecutable(%s) returned %ld\n", filename, rc);
|
||||
|
||||
sprintf(filename, "%s\\test file.shlfoo", tmpdir);
|
||||
rc=(int)FindExecutableA(filename, NULL, command);
|
||||
rc=(INT_PTR)FindExecutableA(filename, NULL, command);
|
||||
|
||||
delete_test_association(".shl");
|
||||
|
||||
|
@ -901,16 +918,16 @@ static void test_find_executable(void)
|
|||
}
|
||||
/* Win98 does not '\0'-terminate command! */
|
||||
memset(command, '\0', sizeof(command));
|
||||
rc=(int)FindExecutableA(filename, NULL, command);
|
||||
rc=(INT_PTR)FindExecutableA(filename, NULL, command);
|
||||
if (rc > 32)
|
||||
rc=33;
|
||||
if ((test->todo & 0x10)==0)
|
||||
{
|
||||
ok(rc==test->rc, "FindExecutable(%s) failed: rc=%d\n", filename, rc);
|
||||
ok(rc==test->rc, "FindExecutable(%s) failed: rc=%ld\n", filename, rc);
|
||||
}
|
||||
else todo_wine
|
||||
{
|
||||
ok(rc==test->rc, "FindExecutable(%s) failed: rc=%d\n", filename, rc);
|
||||
ok(rc==test->rc, "FindExecutable(%s) failed: rc=%ld\n", filename, rc);
|
||||
}
|
||||
if (rc > 32)
|
||||
{
|
||||
|
@ -1195,7 +1212,7 @@ typedef struct
|
|||
|
||||
static DWORD CALLBACK ddeThread(LPVOID arg)
|
||||
{
|
||||
dde_thread_info_t *info = (dde_thread_info_t *)arg;
|
||||
dde_thread_info_t *info = arg;
|
||||
assert(info && info->filename);
|
||||
PostThreadMessage(info->threadIdParent,
|
||||
WM_QUIT,
|
||||
|
@ -1233,7 +1250,11 @@ static void test_dde(void)
|
|||
test = dde_tests;
|
||||
while (test->command)
|
||||
{
|
||||
create_test_association(".sde");
|
||||
if (!create_test_association(".sde"))
|
||||
{
|
||||
skip("Unable to create association for '.sfe'\n");
|
||||
return;
|
||||
}
|
||||
create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec,
|
||||
test->application, test->topic, test->ifexec);
|
||||
hszApplication = DdeCreateStringHandleA(ddeInst, test->application ?
|
||||
|
@ -1245,7 +1266,7 @@ static void test_dde(void)
|
|||
denyNextConnection = TRUE;
|
||||
ddeExec[0] = 0;
|
||||
|
||||
assert(CreateThread(NULL, 0, ddeThread, (LPVOID)&info, 0, &threadId));
|
||||
assert(CreateThread(NULL, 0, ddeThread, &info, 0, &threadId));
|
||||
while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);
|
||||
rc = msg.wParam > 32 ? 33 : msg.wParam;
|
||||
if ((test->todo & 0x1)==0)
|
||||
|
@ -1383,7 +1404,11 @@ static void test_dde_default_app(void)
|
|||
test = dde_default_app_tests;
|
||||
while (test->command)
|
||||
{
|
||||
create_test_association(".sde");
|
||||
if (!create_test_association(".sde"))
|
||||
{
|
||||
skip("Unable to create association for '.sde'\n");
|
||||
return;
|
||||
}
|
||||
sprintf(params, test->command, tmpdir);
|
||||
create_test_verb_dde(".sde", "Open", 1, params, "[test]", NULL,
|
||||
"shlexec", NULL);
|
||||
|
@ -1394,7 +1419,7 @@ static void test_dde_default_app(void)
|
|||
* so don't wait for it */
|
||||
SetEvent(hEvent);
|
||||
|
||||
assert(CreateThread(NULL, 0, ddeThread, (LPVOID)&info, 0, &threadId));
|
||||
assert(CreateThread(NULL, 0, ddeThread, &info, 0, &threadId));
|
||||
while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);
|
||||
rc = msg.wParam > 32 ? 33 : msg.wParam;
|
||||
|
||||
|
@ -1479,7 +1504,7 @@ static void init_test(void)
|
|||
|
||||
r = CoInitialize(NULL);
|
||||
ok(SUCCEEDED(r), "CoInitialize failed (0x%08x)\n", r);
|
||||
if (!SUCCEEDED(r))
|
||||
if (FAILED(r))
|
||||
exit(1);
|
||||
|
||||
rc=GetModuleFileName(NULL, argv0, sizeof(argv0));
|
||||
|
@ -1543,7 +1568,11 @@ static void init_test(void)
|
|||
create_lnk(lnkfile, &desc, 0);
|
||||
|
||||
/* Create a basic association suitable for most tests */
|
||||
create_test_association(".shlexec");
|
||||
if (!create_test_association(".shlexec"))
|
||||
{
|
||||
skip("Unable to create association for '.shlexec'\n");
|
||||
return;
|
||||
}
|
||||
create_test_verb(".shlexec", "Open", 0, "Open \"%1\"");
|
||||
create_test_verb(".shlexec", "NoQuotes", 0, "NoQuotes %1");
|
||||
create_test_verb(".shlexec", "LowerL", 0, "LowerL %l");
|
||||
|
@ -1575,6 +1604,79 @@ static void cleanup_test(void)
|
|||
CoUninitialize();
|
||||
}
|
||||
|
||||
static void test_commandline(void)
|
||||
{
|
||||
static const WCHAR one[] = {'o','n','e',0};
|
||||
static const WCHAR two[] = {'t','w','o',0};
|
||||
static const WCHAR three[] = {'t','h','r','e','e',0};
|
||||
static const WCHAR four[] = {'f','o','u','r',0};
|
||||
|
||||
static const WCHAR fmt1[] = {'%','s',' ','%','s',' ','%','s',' ','%','s',0};
|
||||
static const WCHAR fmt2[] = {' ','%','s',' ','%','s',' ','%','s',' ','%','s',0};
|
||||
static const WCHAR fmt3[] = {'%','s','=','%','s',' ','%','s','=','\"','%','s','\"',0};
|
||||
static const WCHAR fmt4[] = {'\"','%','s','\"',' ','\"','%','s',' ','%','s','\"',' ','%','s',0};
|
||||
static const WCHAR fmt5[] = {'\\','\"','%','s','\"',' ','%','s','=','\"','%','s','\\','\"',' ','\"','%','s','\\','\"',0};
|
||||
static const WCHAR fmt6[] = {0};
|
||||
|
||||
static const WCHAR chkfmt1[] = {'%','s','=','%','s',0};
|
||||
static const WCHAR chkfmt2[] = {'%','s',' ','%','s',0};
|
||||
static const WCHAR chkfmt3[] = {'\\','\"','%','s','\"',0};
|
||||
static const WCHAR chkfmt4[] = {'%','s','=','%','s','\"',' ','%','s','\"',0};
|
||||
WCHAR cmdline[255];
|
||||
LPWSTR *args = (LPWSTR*)0xdeadcafe;
|
||||
INT numargs = -1;
|
||||
|
||||
wsprintfW(cmdline,fmt1,one,two,three,four);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
if (args == NULL && numargs == -1)
|
||||
{
|
||||
win_skip("CommandLineToArgvW not implemented, skipping\n");
|
||||
return;
|
||||
}
|
||||
ok(numargs == 4, "expected 4 args, got %i\n",numargs);
|
||||
ok(lstrcmpW(args[0],one)==0,"arg0 is not as expected\n");
|
||||
ok(lstrcmpW(args[1],two)==0,"arg1 is not as expected\n");
|
||||
ok(lstrcmpW(args[2],three)==0,"arg2 is not as expected\n");
|
||||
ok(lstrcmpW(args[3],four)==0,"arg3 is not as expected\n");
|
||||
|
||||
wsprintfW(cmdline,fmt2,one,two,three,four);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
ok(numargs == 5, "expected 5 args, got %i\n",numargs);
|
||||
ok(args[0][0]==0,"arg0 is not as expected\n");
|
||||
ok(lstrcmpW(args[1],one)==0,"arg1 is not as expected\n");
|
||||
ok(lstrcmpW(args[2],two)==0,"arg2 is not as expected\n");
|
||||
ok(lstrcmpW(args[3],three)==0,"arg3 is not as expected\n");
|
||||
ok(lstrcmpW(args[4],four)==0,"arg4 is not as expected\n");
|
||||
|
||||
wsprintfW(cmdline,fmt3,one,two,three,four);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
ok(numargs == 2, "expected 2 args, got %i\n",numargs);
|
||||
wsprintfW(cmdline,chkfmt1,one,two);
|
||||
ok(lstrcmpW(args[0],cmdline)==0,"arg0 is not as expected\n");
|
||||
wsprintfW(cmdline,chkfmt1,three,four);
|
||||
ok(lstrcmpW(args[1],cmdline)==0,"arg1 is not as expected\n");
|
||||
|
||||
wsprintfW(cmdline,fmt4,one,two,three,four);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
ok(numargs == 3, "expected 3 args, got %i\n",numargs);
|
||||
ok(lstrcmpW(args[0],one)==0,"arg0 is not as expected\n");
|
||||
wsprintfW(cmdline,chkfmt2,two,three);
|
||||
ok(lstrcmpW(args[1],cmdline)==0,"arg1 is not as expected\n");
|
||||
ok(lstrcmpW(args[2],four)==0,"arg2 is not as expected\n");
|
||||
|
||||
wsprintfW(cmdline,fmt5,one,two,three,four);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
ok(numargs == 2, "expected 2 args, got %i\n",numargs);
|
||||
wsprintfW(cmdline,chkfmt3,one);
|
||||
todo_wine ok(lstrcmpW(args[0],cmdline)==0,"arg0 is not as expected\n");
|
||||
wsprintfW(cmdline,chkfmt4,two,three,four);
|
||||
todo_wine ok(lstrcmpW(args[1],cmdline)==0,"arg1 is not as expected\n");
|
||||
|
||||
wsprintfW(cmdline,fmt6);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
ok(numargs == 1, "expected 1 args, got %i\n",numargs);
|
||||
}
|
||||
|
||||
START_TEST(shlexec)
|
||||
{
|
||||
|
||||
|
@ -1594,6 +1696,7 @@ START_TEST(shlexec)
|
|||
test_exes_long();
|
||||
test_dde();
|
||||
test_dde_default_app();
|
||||
test_commandline();
|
||||
|
||||
cleanup_test();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,6 +46,7 @@ static HRESULT (WINAPI *pSHBindToParent)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEM
|
|||
static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
|
||||
static HRESULT (WINAPI *pSHGetFolderPathAndSubDirA)(HWND, int, HANDLE, DWORD, LPCSTR, LPSTR);
|
||||
static BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST,LPWSTR);
|
||||
static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
|
||||
static BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
|
||||
static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
|
||||
static LPITEMIDLIST (WINAPI *pILFindLastID)(LPCITEMIDLIST);
|
||||
|
@ -62,6 +63,7 @@ static void init_function_pointers(void)
|
|||
pSHGetFolderPathA = (void*)GetProcAddress(hmod, "SHGetFolderPathA");
|
||||
pSHGetFolderPathAndSubDirA = (void*)GetProcAddress(hmod, "SHGetFolderPathAndSubDirA");
|
||||
pSHGetPathFromIDListW = (void*)GetProcAddress(hmod, "SHGetPathFromIDListW");
|
||||
pSHGetSpecialFolderPathA = (void*)GetProcAddress(hmod, "SHGetSpecialFolderPathA");
|
||||
pSHGetSpecialFolderPathW = (void*)GetProcAddress(hmod, "SHGetSpecialFolderPathW");
|
||||
pILFindLastID = (void *)GetProcAddress(hmod, (LPCSTR)16);
|
||||
pILFree = (void*)GetProcAddress(hmod, (LPSTR)155);
|
||||
|
@ -80,6 +82,8 @@ static void test_ParseDisplayName(void)
|
|||
IShellFolder *IDesktopFolder;
|
||||
static const char *cNonExistDir1A = "c:\\nonexist_subdir";
|
||||
static const char *cNonExistDir2A = "c:\\\\nonexist_subdir";
|
||||
static const char *cInetTestA = "http:\\yyy";
|
||||
static const char *cInetTest2A = "xx:yyy";
|
||||
DWORD res;
|
||||
WCHAR cTestDirW [MAX_PATH] = {0};
|
||||
ITEMIDLIST *newPIDL;
|
||||
|
@ -88,6 +92,30 @@ static void test_ParseDisplayName(void)
|
|||
hr = SHGetDesktopFolder(&IDesktopFolder);
|
||||
if(hr != S_OK) return;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, cInetTestA, -1, cTestDirW, MAX_PATH);
|
||||
hr = IShellFolder_ParseDisplayName(IDesktopFolder,
|
||||
NULL, NULL, cTestDirW, NULL, &newPIDL, 0);
|
||||
todo_wine ok((SUCCEEDED(hr) || broken(hr == E_FAIL) /* NT4 */),
|
||||
"ParseDisplayName returned %08x, expected SUCCESS or E_FAIL\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ok(pILFindLastID(newPIDL)->mkid.abID[0] == 0x61, "Last pidl should be of type "
|
||||
"PT_IESPECIAL1, but is: %02x\n", pILFindLastID(newPIDL)->mkid.abID[0]);
|
||||
IMalloc_Free(ppM, newPIDL);
|
||||
}
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, cInetTest2A, -1, cTestDirW, MAX_PATH);
|
||||
hr = IShellFolder_ParseDisplayName(IDesktopFolder,
|
||||
NULL, NULL, cTestDirW, NULL, &newPIDL, 0);
|
||||
todo_wine ok((SUCCEEDED(hr) || broken(hr == E_FAIL) /* NT4 */),
|
||||
"ParseDisplayName returned %08x, expected SUCCESS or E_FAIL\n", hr);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ok(pILFindLastID(newPIDL)->mkid.abID[0] == 0x61, "Last pidl should be of type "
|
||||
"PT_IESPECIAL1, but is: %02x\n", pILFindLastID(newPIDL)->mkid.abID[0]);
|
||||
IMalloc_Free(ppM, newPIDL);
|
||||
}
|
||||
|
||||
res = GetFileAttributesA(cNonExistDir1A);
|
||||
if(res != INVALID_FILE_ATTRIBUTES) return;
|
||||
|
||||
|
@ -119,8 +147,10 @@ static void test_ParseDisplayName(void)
|
|||
ok(SUCCEEDED(hr), "DesktopFolder->ParseDisplayName failed. hr = %08x.\n", hr);
|
||||
if (FAILED(hr)) goto finished;
|
||||
|
||||
ok(pILFindLastID(newPIDL)->mkid.abID[0] == 0x31, "Last pidl should be of type "
|
||||
"PT_FOLDER, but is: %02x\n", pILFindLastID(newPIDL)->mkid.abID[0]);
|
||||
ok(pILFindLastID(newPIDL)->mkid.abID[0] == 0x31 ||
|
||||
pILFindLastID(newPIDL)->mkid.abID[0] == 0xb1, /* Win98 */
|
||||
"Last pidl should be of type PT_FOLDER or PT_IESPECIAL2, but is: %02x\n",
|
||||
pILFindLastID(newPIDL)->mkid.abID[0]);
|
||||
IMalloc_Free(ppM, newPIDL);
|
||||
|
||||
finished:
|
||||
|
@ -235,13 +265,17 @@ static void test_EnumObjects(IShellFolder *iFolder)
|
|||
hr = IShellFolder_GetAttributesOf(iFolder, 1, (LPCITEMIDLIST*)(idlArr + i), &flags);
|
||||
flags &= SFGAO_testfor;
|
||||
ok(hr == S_OK, "GetAttributesOf returns %08x\n", hr);
|
||||
ok(flags == (attrs[i]), "GetAttributesOf[%i] got %08x, expected %08x\n", i, flags, attrs[i]);
|
||||
ok(flags == (attrs[i]) ||
|
||||
flags == (attrs[i] & ~SFGAO_FILESYSANCESTOR), /* Win9x, NT4 */
|
||||
"GetAttributesOf[%i] got %08x, expected %08x\n", i, flags, attrs[i]);
|
||||
|
||||
flags = SFGAO_testfor;
|
||||
hr = IShellFolder_GetAttributesOf(iFolder, 1, (LPCITEMIDLIST*)(idlArr + i), &flags);
|
||||
flags &= SFGAO_testfor;
|
||||
ok(hr == S_OK, "GetAttributesOf returns %08x\n", hr);
|
||||
ok(flags == attrs[i], "GetAttributesOf[%i] got %08x, expected %08x\n", i, flags, attrs[i]);
|
||||
ok(flags == attrs[i] ||
|
||||
flags == (attrs[i] & ~SFGAO_FILESYSANCESTOR), /* Win9x, NT4 */
|
||||
"GetAttributesOf[%i] got %08x, expected %08x\n", i, flags, attrs[i]);
|
||||
}
|
||||
|
||||
for (i=0;i<5;i++)
|
||||
|
@ -356,7 +390,7 @@ static void test_GetDisplayName(void)
|
|||
BOOL result;
|
||||
HRESULT hr;
|
||||
HANDLE hTestFile;
|
||||
WCHAR wszTestFile[MAX_PATH], wszTestFile2[MAX_PATH], wszTestDir[MAX_PATH];
|
||||
WCHAR wszTestFile[MAX_PATH], wszTestFile2[MAX_PATH];
|
||||
char szTestFile[MAX_PATH], szTestDir[MAX_PATH];
|
||||
DWORD attr;
|
||||
STRRET strret;
|
||||
|
@ -365,6 +399,7 @@ static void test_GetDisplayName(void)
|
|||
SHITEMID emptyitem = { 0, { 0 } };
|
||||
LPITEMIDLIST pidlTestFile, pidlEmpty = (LPITEMIDLIST)&emptyitem;
|
||||
LPCITEMIDLIST pidlLast;
|
||||
static const CHAR szFileName[] = "winetest.foo";
|
||||
static const WCHAR wszFileName[] = { 'w','i','n','e','t','e','s','t','.','f','o','o',0 };
|
||||
static const WCHAR wszDirName[] = { 'w','i','n','e','t','e','s','t',0 };
|
||||
|
||||
|
@ -376,17 +411,18 @@ static void test_GetDisplayName(void)
|
|||
* no functional difference in this respect.
|
||||
*/
|
||||
|
||||
if(!pSHGetSpecialFolderPathW) return;
|
||||
if(!pSHGetSpecialFolderPathA) {
|
||||
win_skip("SHGetSpecialFolderPathA is not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* First creating a directory in MyDocuments and a file in this directory. */
|
||||
result = pSHGetSpecialFolderPathW(NULL, wszTestDir, CSIDL_PERSONAL, FALSE);
|
||||
ok(result, "SHGetSpecialFolderPathW failed! Last error: %u\n", GetLastError());
|
||||
result = pSHGetSpecialFolderPathA(NULL, szTestDir, CSIDL_PERSONAL, FALSE);
|
||||
ok(result, "SHGetSpecialFolderPathA failed! Last error: %u\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
||||
myPathAddBackslashW(wszTestDir);
|
||||
lstrcatW(wszTestDir, wszDirName);
|
||||
/* Use ANSI file functions so this works on Windows 9x */
|
||||
WideCharToMultiByte(CP_ACP, 0, wszTestDir, -1, szTestDir, MAX_PATH, 0, 0);
|
||||
lstrcatA(szTestDir, "\\winetest");
|
||||
CreateDirectoryA(szTestDir, NULL);
|
||||
attr=GetFileAttributesA(szTestDir);
|
||||
if (attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
|
@ -395,11 +431,9 @@ static void test_GetDisplayName(void)
|
|||
return;
|
||||
}
|
||||
|
||||
lstrcpyW(wszTestFile, wszTestDir);
|
||||
myPathAddBackslashW(wszTestFile);
|
||||
lstrcatW(wszTestFile, wszFileName);
|
||||
WideCharToMultiByte(CP_ACP, 0, wszTestFile, -1, szTestFile, MAX_PATH, 0, 0);
|
||||
|
||||
lstrcpyA(szTestFile, szTestDir);
|
||||
lstrcatA(szTestFile, "\\");
|
||||
lstrcatA(szTestFile, szFileName);
|
||||
hTestFile = CreateFileA(szTestFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
ok((hTestFile != INVALID_HANDLE_VALUE), "CreateFileA failed! Last error: %u\n", GetLastError());
|
||||
if (hTestFile == INVALID_HANDLE_VALUE) return;
|
||||
|
@ -410,6 +444,8 @@ static void test_GetDisplayName(void)
|
|||
ok(SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08x\n", hr);
|
||||
if (FAILED(hr)) return;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, szTestFile, -1, wszTestFile, MAX_PATH);
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszTestFile, NULL, &pidlTestFile, NULL);
|
||||
ok(SUCCEEDED(hr), "Desktop->ParseDisplayName failed! hr = %08x\n", hr);
|
||||
if (FAILED(hr)) {
|
||||
|
@ -417,50 +453,77 @@ static void test_GetDisplayName(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* WinXP stores the filenames as both ANSI and UNICODE in the pidls */
|
||||
pidlLast = pILFindLastID(pidlTestFile);
|
||||
ok(pidlLast->mkid.cb >=76, "Expected pidl length of at least 76, got %d.\n", pidlLast->mkid.cb);
|
||||
ok(pidlLast->mkid.cb >=76 ||
|
||||
broken(pidlLast->mkid.cb == 28) || /* W2K */
|
||||
broken(pidlLast->mkid.cb == 40), /* Win9x, WinME */
|
||||
"Expected pidl length of at least 76, got %d.\n", pidlLast->mkid.cb);
|
||||
if (pidlLast->mkid.cb >= 28) {
|
||||
ok(!lstrcmpA((CHAR*)&pidlLast->mkid.abID[12], szFileName),
|
||||
"Filename should be stored as ansi-string at this position!\n");
|
||||
}
|
||||
/* WinXP and up store the filenames as both ANSI and UNICODE in the pidls */
|
||||
if (pidlLast->mkid.cb >= 76) {
|
||||
ok(!lstrcmpW((WCHAR*)&pidlLast->mkid.abID[46], wszFileName),
|
||||
"WinXP stores the filename as a wchar-string at this position!\n");
|
||||
"Filename should be stored as wchar-string at this position!\n");
|
||||
}
|
||||
|
||||
/* It seems as if we cannot bind to regular files on windows, but only directories.
|
||||
*/
|
||||
hr = IShellFolder_BindToObject(psfDesktop, pidlTestFile, NULL, &IID_IUnknown, (VOID**)&psfFile);
|
||||
todo_wine { ok (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hr = %08x\n", hr); }
|
||||
todo_wine
|
||||
ok (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
|
||||
broken(SUCCEEDED(hr)), /* Win9x, W2K */
|
||||
"hr = %08x\n", hr);
|
||||
if (SUCCEEDED(hr)) {
|
||||
IShellFolder_Release(psfFile);
|
||||
}
|
||||
|
||||
if (!pSHBindToParent)
|
||||
{
|
||||
win_skip("SHBindToParent is missing\n");
|
||||
DeleteFileA(szTestFile);
|
||||
RemoveDirectoryA(szTestDir);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Some tests for IShellFolder::SetNameOf */
|
||||
hr = pSHBindToParent(pidlTestFile, &IID_IShellFolder, (VOID**)&psfPersonal, &pidlLast);
|
||||
ok(SUCCEEDED(hr), "SHBindToParent failed! hr = %08x\n", hr);
|
||||
if (SUCCEEDED(hr)) {
|
||||
/* It's ok to use this fixed path. Call will fail anyway. */
|
||||
WCHAR wszAbsoluteFilename[] = { 'C',':','\\','w','i','n','e','t','e','s','t', 0 };
|
||||
LPITEMIDLIST pidlNew;
|
||||
if (pSHGetFolderPathAndSubDirA)
|
||||
{
|
||||
hr = pSHBindToParent(pidlTestFile, &IID_IShellFolder, (VOID**)&psfPersonal, &pidlLast);
|
||||
ok(SUCCEEDED(hr), "SHBindToParent failed! hr = %08x\n", hr);
|
||||
if (SUCCEEDED(hr)) {
|
||||
/* It's ok to use this fixed path. Call will fail anyway. */
|
||||
WCHAR wszAbsoluteFilename[] = { 'C',':','\\','w','i','n','e','t','e','s','t', 0 };
|
||||
LPITEMIDLIST pidlNew;
|
||||
|
||||
/* The pidl returned through the last parameter of SetNameOf is a simple one. */
|
||||
hr = IShellFolder_SetNameOf(psfPersonal, NULL, pidlLast, wszDirName, SHGDN_NORMAL, &pidlNew);
|
||||
ok (SUCCEEDED(hr), "SetNameOf failed! hr = %08x\n", hr);
|
||||
ok (((LPITEMIDLIST)((LPBYTE)pidlNew+pidlNew->mkid.cb))->mkid.cb == 0,
|
||||
"pidl returned from SetNameOf should be simple!\n");
|
||||
/* The pidl returned through the last parameter of SetNameOf is a simple one. */
|
||||
hr = IShellFolder_SetNameOf(psfPersonal, NULL, pidlLast, wszDirName, SHGDN_NORMAL, &pidlNew);
|
||||
ok (SUCCEEDED(hr), "SetNameOf failed! hr = %08x\n", hr);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
ok (((LPITEMIDLIST)((LPBYTE)pidlNew+pidlNew->mkid.cb))->mkid.cb == 0,
|
||||
"pidl returned from SetNameOf should be simple!\n");
|
||||
|
||||
/* Passing an absolute path to SetNameOf fails. The HRESULT code indicates that SetNameOf
|
||||
* is implemented on top of SHFileOperation in WinXP. */
|
||||
hr = IShellFolder_SetNameOf(psfPersonal, NULL, pidlNew, wszAbsoluteFilename,
|
||||
SHGDN_FORPARSING, NULL);
|
||||
ok (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "SetNameOf succeeded! hr = %08x\n", hr);
|
||||
/* Passing an absolute path to SetNameOf fails. The HRESULT code indicates that SetNameOf
|
||||
* is implemented on top of SHFileOperation in WinXP. */
|
||||
hr = IShellFolder_SetNameOf(psfPersonal, NULL, pidlNew, wszAbsoluteFilename,
|
||||
SHGDN_FORPARSING, NULL);
|
||||
ok (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "SetNameOf succeeded! hr = %08x\n", hr);
|
||||
|
||||
/* Rename the file back to its original name. SetNameOf ignores the fact, that the
|
||||
* SHGDN flags specify an absolute path. */
|
||||
hr = IShellFolder_SetNameOf(psfPersonal, NULL, pidlNew, wszFileName, SHGDN_FORPARSING, NULL);
|
||||
ok (SUCCEEDED(hr), "SetNameOf failed! hr = %08x\n", hr);
|
||||
/* Rename the file back to its original name. SetNameOf ignores the fact, that the
|
||||
* SHGDN flags specify an absolute path. */
|
||||
hr = IShellFolder_SetNameOf(psfPersonal, NULL, pidlNew, wszFileName, SHGDN_FORPARSING, NULL);
|
||||
ok (SUCCEEDED(hr), "SetNameOf failed! hr = %08x\n", hr);
|
||||
|
||||
pILFree(pidlNew);
|
||||
IShellFolder_Release(psfPersonal);
|
||||
pILFree(pidlNew);
|
||||
}
|
||||
|
||||
IShellFolder_Release(psfPersonal);
|
||||
}
|
||||
}
|
||||
else
|
||||
win_skip("Avoid needs of interaction on Win2k\n");
|
||||
|
||||
/* Deleting the file and the directory */
|
||||
DeleteFileA(szTestFile);
|
||||
|
@ -474,8 +537,6 @@ static void test_GetDisplayName(void)
|
|||
ok (!lstrcmpiW(wszTestFile, wszTestFile2), "SHGetPathFromIDListW returns incorrect path!\n");
|
||||
}
|
||||
|
||||
if(!pSHBindToParent) return;
|
||||
|
||||
/* SHBindToParent fails, if called with a NULL PIDL. */
|
||||
hr = pSHBindToParent(NULL, &IID_IShellFolder, (VOID**)&psfPersonal, &pidlLast);
|
||||
ok (FAILED(hr), "SHBindToParent(NULL) should fail!\n");
|
||||
|
@ -554,7 +615,8 @@ static void test_CallForAttributes(void)
|
|||
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszMyDocuments, NULL,
|
||||
&pidlMyDocuments, NULL);
|
||||
ok (SUCCEEDED(hr),
|
||||
ok (SUCCEEDED(hr) ||
|
||||
broken(hr == E_INVALIDARG), /* Win95, NT4 */
|
||||
"Desktop's ParseDisplayName failed to parse MyDocuments's CLSID! hr = %08x\n", hr);
|
||||
if (FAILED(hr)) {
|
||||
IShellFolder_Release(psfDesktop);
|
||||
|
@ -645,22 +707,41 @@ static void test_GetAttributesOf(void)
|
|||
LPCITEMIDLIST pidlEmpty = (LPCITEMIDLIST)&emptyitem;
|
||||
LPITEMIDLIST pidlMyComputer;
|
||||
DWORD dwFlags;
|
||||
static const DWORD dwDesktopFlags = /* As observed on WinXP SP2 */
|
||||
SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
|
||||
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER;
|
||||
static const DWORD dwMyComputerFlags = /* As observed on WinXP SP2 */
|
||||
SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET |
|
||||
SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
|
||||
static const DWORD desktopFlags[] = {
|
||||
/* WinXP */
|
||||
SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | SFGAO_FILESYSANCESTOR |
|
||||
SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER,
|
||||
/* Win2k */
|
||||
SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_STREAM | SFGAO_FILESYSANCESTOR |
|
||||
SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER,
|
||||
/* WinMe, Win9x, WinNT*/
|
||||
SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSANCESTOR |
|
||||
SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER
|
||||
};
|
||||
static const DWORD myComputerFlags[] = {
|
||||
/* WinXP */
|
||||
SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
|
||||
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER,
|
||||
/* Win2k */
|
||||
SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_STREAM |
|
||||
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER,
|
||||
/* WinMe, Win9x, WinNT */
|
||||
SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR |
|
||||
SFGAO_FOLDER | SFGAO_HASSUBFOLDER,
|
||||
/* Win95, WinNT when queried directly */
|
||||
SFGAO_CANLINK | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR |
|
||||
SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER
|
||||
};
|
||||
WCHAR wszMyComputer[] = {
|
||||
':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
|
||||
'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
|
||||
char cCurrDirA [MAX_PATH] = {0};
|
||||
WCHAR cCurrDirW [MAX_PATH];
|
||||
static WCHAR cTestDirW[] = {'t','e','s','t','d','i','r',0};
|
||||
static const WCHAR cBackSlash[] = {'\\',0};
|
||||
IShellFolder *IDesktopFolder, *testIShellFolder;
|
||||
ITEMIDLIST *newPIDL;
|
||||
int len;
|
||||
int len, i;
|
||||
BOOL foundFlagsMatch;
|
||||
|
||||
hr = SHGetDesktopFolder(&psfDesktop);
|
||||
ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08x\n", hr);
|
||||
|
@ -670,15 +751,25 @@ static void test_GetAttributesOf(void)
|
|||
dwFlags = 0xffffffff;
|
||||
hr = IShellFolder_GetAttributesOf(psfDesktop, 1, &pidlEmpty, &dwFlags);
|
||||
ok (SUCCEEDED(hr), "Desktop->GetAttributesOf(empty pidl) failed! hr = %08x\n", hr);
|
||||
ok (dwFlags == dwDesktopFlags, "Wrong Desktop attributes: %08x, expected: %08x\n",
|
||||
dwFlags, dwDesktopFlags);
|
||||
for (i = 0, foundFlagsMatch = FALSE; !foundFlagsMatch &&
|
||||
i < sizeof(desktopFlags) / sizeof(desktopFlags[0]); i++)
|
||||
{
|
||||
if (desktopFlags[i] == dwFlags)
|
||||
foundFlagsMatch = TRUE;
|
||||
}
|
||||
ok (foundFlagsMatch, "Wrong Desktop attributes: %08x\n", dwFlags);
|
||||
|
||||
/* .. or with no itemidlist at all. */
|
||||
dwFlags = 0xffffffff;
|
||||
hr = IShellFolder_GetAttributesOf(psfDesktop, 0, NULL, &dwFlags);
|
||||
ok (SUCCEEDED(hr), "Desktop->GetAttributesOf(NULL) failed! hr = %08x\n", hr);
|
||||
ok (dwFlags == dwDesktopFlags, "Wrong Desktop attributes: %08x, expected: %08x\n",
|
||||
dwFlags, dwDesktopFlags);
|
||||
for (i = 0, foundFlagsMatch = FALSE; !foundFlagsMatch &&
|
||||
i < sizeof(desktopFlags) / sizeof(desktopFlags[0]); i++)
|
||||
{
|
||||
if (desktopFlags[i] == dwFlags)
|
||||
foundFlagsMatch = TRUE;
|
||||
}
|
||||
ok (foundFlagsMatch, "Wrong Desktop attributes: %08x\n", dwFlags);
|
||||
|
||||
/* Testing the attributes of the MyComputer shellfolder */
|
||||
hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszMyComputer, NULL, &pidlMyComputer, NULL);
|
||||
|
@ -688,18 +779,20 @@ static void test_GetAttributesOf(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* WinXP SP2 sets the SFGAO_CANLINK flag, when MyComputer is queried via the Desktop
|
||||
/* Windows sets the SFGAO_CANLINK flag, when MyComputer is queried via the Desktop
|
||||
* folder object. It doesn't do this, if MyComputer is queried directly (see below).
|
||||
* SFGAO_CANLINK is the same as DROPEFFECT_LINK, which MSDN says means: "Drag source
|
||||
* should create a link to the original data". You can't create links on MyComputer on
|
||||
* Windows, so this flag shouldn't be set. Seems like a bug in Windows. As long as nobody
|
||||
* depends on this bug, we probably shouldn't imitate it.
|
||||
*/
|
||||
dwFlags = 0xffffffff;
|
||||
hr = IShellFolder_GetAttributesOf(psfDesktop, 1, (LPCITEMIDLIST*)&pidlMyComputer, &dwFlags);
|
||||
ok (SUCCEEDED(hr), "Desktop->GetAttributesOf(MyComputer) failed! hr = %08x\n", hr);
|
||||
ok ((dwFlags & ~(DWORD)SFGAO_CANLINK) == dwMyComputerFlags,
|
||||
"Wrong MyComputer attributes: %08x, expected: %08x\n", dwFlags, dwMyComputerFlags);
|
||||
for (i = 0, foundFlagsMatch = FALSE; !foundFlagsMatch &&
|
||||
i < sizeof(myComputerFlags) / sizeof(myComputerFlags[0]); i++)
|
||||
{
|
||||
if ((myComputerFlags[i] | SFGAO_CANLINK) == dwFlags)
|
||||
foundFlagsMatch = TRUE;
|
||||
}
|
||||
todo_wine
|
||||
ok (foundFlagsMatch, "Wrong MyComputer attributes: %08x\n", dwFlags);
|
||||
|
||||
hr = IShellFolder_BindToObject(psfDesktop, pidlMyComputer, NULL, &IID_IShellFolder, (LPVOID*)&psfMyComputer);
|
||||
ok (SUCCEEDED(hr), "Desktop failed to bind to MyComputer object! hr = %08x\n", hr);
|
||||
|
@ -708,28 +801,37 @@ static void test_GetAttributesOf(void)
|
|||
if (FAILED(hr)) return;
|
||||
|
||||
hr = IShellFolder_GetAttributesOf(psfMyComputer, 1, &pidlEmpty, &dwFlags);
|
||||
todo_wine {ok (hr == E_INVALIDARG, "MyComputer->GetAttributesOf(emtpy pidl) should fail! hr = %08x\n", hr); }
|
||||
todo_wine
|
||||
ok (hr == E_INVALIDARG ||
|
||||
broken(SUCCEEDED(hr)), /* W2K and earlier */
|
||||
"MyComputer->GetAttributesOf(emtpy pidl) should fail! hr = %08x\n", hr);
|
||||
|
||||
dwFlags = 0xffffffff;
|
||||
hr = IShellFolder_GetAttributesOf(psfMyComputer, 0, NULL, &dwFlags);
|
||||
ok (SUCCEEDED(hr), "MyComputer->GetAttributesOf(NULL) failed! hr = %08x\n", hr);
|
||||
todo_wine { ok (dwFlags == dwMyComputerFlags,
|
||||
"Wrong MyComputer attributes: %08x, expected: %08x\n", dwFlags, dwMyComputerFlags); }
|
||||
for (i = 0, foundFlagsMatch = FALSE; !foundFlagsMatch &&
|
||||
i < sizeof(myComputerFlags) / sizeof(myComputerFlags[0]); i++)
|
||||
{
|
||||
if (myComputerFlags[i] == dwFlags)
|
||||
foundFlagsMatch = TRUE;
|
||||
}
|
||||
todo_wine
|
||||
ok (foundFlagsMatch, "Wrong MyComputer attributes: %08x\n", dwFlags);
|
||||
|
||||
IShellFolder_Release(psfMyComputer);
|
||||
|
||||
/* create test directory */
|
||||
CreateFilesFolders();
|
||||
|
||||
GetCurrentDirectoryA(MAX_PATH, cCurrDirA);
|
||||
len = lstrlenA(cCurrDirA);
|
||||
|
||||
if (len == 0) {
|
||||
trace("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n");
|
||||
return;
|
||||
win_skip("GetCurrentDirectoryA returned empty string. Skipping test_GetAttributesOf\n");
|
||||
return;
|
||||
}
|
||||
if(cCurrDirA[len-1] == '\\')
|
||||
cCurrDirA[len-1] = 0;
|
||||
if (len > 3 && cCurrDirA[len-1] == '\\')
|
||||
cCurrDirA[len-1] = 0;
|
||||
|
||||
/* create test directory */
|
||||
CreateFilesFolders();
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH);
|
||||
|
||||
|
@ -758,8 +860,10 @@ static void test_GetAttributesOf(void)
|
|||
IMalloc_Free(ppM, newPIDL);
|
||||
|
||||
/* append testdirectory name to path */
|
||||
lstrcatW(cCurrDirW, cBackSlash);
|
||||
lstrcatW(cCurrDirW, cTestDirW);
|
||||
if (cCurrDirA[len-1] == '\\')
|
||||
cCurrDirA[len-1] = 0;
|
||||
lstrcatA(cCurrDirA, "\\testdir");
|
||||
MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH);
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0);
|
||||
ok(hr == S_OK, "ParseDisplayName failed %08x\n", hr);
|
||||
|
@ -769,7 +873,7 @@ static void test_GetAttributesOf(void)
|
|||
hr = IShellFolder_GetAttributesOf(IDesktopFolder, 1, (LPCITEMIDLIST*)&newPIDL, &dwFlags);
|
||||
ok (SUCCEEDED(hr), "Desktop->GetAttributesOf() failed! hr = %08x\n", hr);
|
||||
ok ((dwFlags&SFGAO_FOLDER), "Wrong directory attribute for absolute PIDL: %08x\n", dwFlags);
|
||||
|
||||
|
||||
/* free memory */
|
||||
IMalloc_Free(ppM, newPIDL);
|
||||
|
||||
|
@ -778,7 +882,7 @@ static void test_GetAttributesOf(void)
|
|||
Cleanup();
|
||||
|
||||
IShellFolder_Release(IDesktopFolder);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_SHGetPathFromIDList(void)
|
||||
{
|
||||
|
@ -804,7 +908,7 @@ static void test_SHGetPathFromIDList(void)
|
|||
|
||||
if(!pSHGetPathFromIDListW || !pSHGetSpecialFolderPathW)
|
||||
{
|
||||
skip("SHGetPathFromIDListW() or SHGetSpecialFolderPathW() is missing\n");
|
||||
win_skip("SHGetPathFromIDListW() or SHGetSpecialFolderPathW() is missing\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -819,7 +923,16 @@ static void test_SHGetPathFromIDList(void)
|
|||
result = pSHGetSpecialFolderPathW(NULL, wszDesktop, CSIDL_DESKTOP, FALSE);
|
||||
ok(result, "SHGetSpecialFolderPathW(CSIDL_DESKTOP) failed! Last error: %u\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
||||
|
||||
/* Check if we are on Win9x */
|
||||
SetLastError(0xdeadbeef);
|
||||
lstrcmpiW(wszDesktop, wszDesktop);
|
||||
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
win_skip("Most W-calls are not implemented\n");
|
||||
return;
|
||||
}
|
||||
|
||||
result = pSHGetPathFromIDListW(pidlEmpty, wszPath);
|
||||
ok(result, "SHGetPathFromIDListW failed! Last error: %u\n", GetLastError());
|
||||
if (!result) return;
|
||||
|
@ -919,8 +1032,8 @@ static void test_EnumObjects_and_CompareIDs(void)
|
|||
ITEMIDLIST *newPIDL;
|
||||
IShellFolder *IDesktopFolder, *testIShellFolder;
|
||||
char cCurrDirA [MAX_PATH] = {0};
|
||||
WCHAR cCurrDirW [MAX_PATH];
|
||||
static const WCHAR cTestDirW[] = {'\\','t','e','s','t','d','i','r',0};
|
||||
static const CHAR cTestDirA[] = "\\testdir";
|
||||
WCHAR cTestDirW[MAX_PATH];
|
||||
int len;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -928,21 +1041,21 @@ static void test_EnumObjects_and_CompareIDs(void)
|
|||
len = lstrlenA(cCurrDirA);
|
||||
|
||||
if(len == 0) {
|
||||
trace("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n");
|
||||
win_skip("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n");
|
||||
return;
|
||||
}
|
||||
if(cCurrDirA[len-1] == '\\')
|
||||
cCurrDirA[len-1] = 0;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH);
|
||||
lstrcatW(cCurrDirW, cTestDirW);
|
||||
lstrcatA(cCurrDirA, cTestDirA);
|
||||
MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cTestDirW, MAX_PATH);
|
||||
|
||||
hr = SHGetDesktopFolder(&IDesktopFolder);
|
||||
ok(hr == S_OK, "SHGetDesktopfolder failed %08x\n", hr);
|
||||
|
||||
CreateFilesFolders();
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0);
|
||||
hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cTestDirW, NULL, &newPIDL, 0);
|
||||
ok(hr == S_OK, "ParseDisplayName failed %08x\n", hr);
|
||||
|
||||
hr = IShellFolder_BindToObject(IDesktopFolder, newPIDL, NULL, (REFIID)&IID_IShellFolder, (LPVOID *)&testIShellFolder);
|
||||
|
@ -1000,7 +1113,9 @@ static HRESULT WINAPI InitPropertyBag_IPropertyBag_Read(IPropertyBag *iface, LPC
|
|||
'R','e','s','o','l','v','e','L','i','n','k','F','l','a','g','s',0 };
|
||||
|
||||
if (!lstrcmpW(pszPropName, wszTargetSpecialFolder)) {
|
||||
ok(V_VT(pVar) == VT_I4, "Wrong variant type for 'TargetSpecialFolder' property!\n");
|
||||
ok(V_VT(pVar) == VT_I4 ||
|
||||
broken(V_VT(pVar) == VT_BSTR), /* Win2k */
|
||||
"Wrong variant type for 'TargetSpecialFolder' property!\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1129,9 @@ static HRESULT WINAPI InitPropertyBag_IPropertyBag_Read(IPropertyBag *iface, LPC
|
|||
WCHAR wszPath[MAX_PATH];
|
||||
BOOL result;
|
||||
|
||||
ok(V_VT(pVar) == VT_BSTR, "Wrong variant type for 'Target' property!\n");
|
||||
ok(V_VT(pVar) == VT_BSTR ||
|
||||
broken(V_VT(pVar) == VT_EMPTY), /* Win2k */
|
||||
"Wrong variant type for 'Target' property!\n");
|
||||
if (V_VT(pVar) != VT_BSTR) return E_INVALIDARG;
|
||||
|
||||
result = pSHGetSpecialFolderPathW(NULL, wszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
|
||||
|
@ -1082,14 +1199,27 @@ static void test_FolderShortcut(void) {
|
|||
static const GUID CLSID_UnixDosFolder =
|
||||
{0x9d20aae8, 0x0625, 0x44b0, {0x9c, 0xa7, 0x71, 0x88, 0x9c, 0x22, 0x54, 0xd9}};
|
||||
|
||||
if (!pSHGetSpecialFolderPathW || !pStrRetToBufW) return;
|
||||
|
||||
if (!pSHGetSpecialFolderPathW || !pStrRetToBufW) {
|
||||
win_skip("SHGetSpecialFolderPathW and/or StrRetToBufW are not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pSHGetFolderPathAndSubDirA)
|
||||
{
|
||||
win_skip("FolderShortcut test doesn't work on Win2k\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* These tests basically show, that CLSID_FolderShortcuts are initialized
|
||||
* via their IPersistPropertyBag interface. And that the target folder
|
||||
* is taken from the IPropertyBag's 'Target' property.
|
||||
*/
|
||||
hr = CoCreateInstance(&CLSID_FolderShortcut, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IPersistPropertyBag, (LPVOID*)&pPersistPropertyBag);
|
||||
if (hr == REGDB_E_CLASSNOTREG) {
|
||||
win_skip("CLSID_FolderShortcut is not implemented\n");
|
||||
return;
|
||||
}
|
||||
ok (SUCCEEDED(hr), "CoCreateInstance failed! hr = 0x%08x\n", hr);
|
||||
if (FAILED(hr)) return;
|
||||
|
||||
|
@ -1099,7 +1229,7 @@ static void test_FolderShortcut(void) {
|
|||
IPersistPropertyBag_Release(pPersistPropertyBag);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
hr = IPersistPropertyBag_QueryInterface(pPersistPropertyBag, &IID_IShellFolder,
|
||||
(LPVOID*)&pShellFolder);
|
||||
IPersistPropertyBag_Release(pPersistPropertyBag);
|
||||
|
@ -1253,17 +1383,22 @@ static void test_ITEMIDLIST_format(void) {
|
|||
HANDLE hFile;
|
||||
HRESULT hr;
|
||||
BOOL bResult;
|
||||
WCHAR wszFile[3][17] = { { 'e','v','e','n','_',0 }, { 'o','d','d','_',0 },
|
||||
WCHAR wszFile[3][17] = { { 'e','v','e','n','_',0 }, { 'o','d','d','_',0 },
|
||||
{ 'l','o','n','g','e','r','_','t','h','a','n','.','8','_','3',0 } };
|
||||
int i;
|
||||
|
||||
if(!pSHGetSpecialFolderPathW) return;
|
||||
|
||||
if (!pSHGetSpecialFolderPathW) return;
|
||||
|
||||
bResult = pSHGetSpecialFolderPathW(NULL, wszPersonal, CSIDL_PERSONAL, FALSE);
|
||||
ok(bResult, "SHGetSpecialFolderPathW failed! Last error: %u\n", GetLastError());
|
||||
if (!bResult) return;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
bResult = SetCurrentDirectoryW(wszPersonal);
|
||||
if (!bResult && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
|
||||
win_skip("Most W-calls are not implemented\n");
|
||||
return;
|
||||
}
|
||||
ok(bResult, "SetCurrentDirectory failed! Last error: %u\n", GetLastError());
|
||||
if (!bResult) return;
|
||||
|
||||
|
@ -1289,9 +1424,9 @@ static void test_ITEMIDLIST_format(void) {
|
|||
CHAR szFile[MAX_PATH];
|
||||
struct FileStructA *pFileStructA;
|
||||
WORD cbOffset;
|
||||
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, wszFile[i], -1, szFile, MAX_PATH, NULL, NULL);
|
||||
|
||||
|
||||
hFile = CreateFileW(wszFile[i], GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_FLAG_WRITE_THROUGH, NULL);
|
||||
ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed! (%u)\n", GetLastError());
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
|
@ -1311,56 +1446,63 @@ static void test_ITEMIDLIST_format(void) {
|
|||
pFileStructA = (struct FileStructA *)pidlFile->mkid.abID;
|
||||
ok(pFileStructA->type == 0x32, "PIDLTYPE should be 0x32!\n");
|
||||
ok(pFileStructA->dummy == 0x00, "Dummy Byte should be 0x00!\n");
|
||||
ok(pFileStructA->dwFileSize == 0, "Filesize should be zero!\n");
|
||||
ok(pFileStructA->dwFileSize == 0, "Filesize should be zero!\n");
|
||||
|
||||
if (i < 2) /* First two file names are already in valid 8.3 format */
|
||||
if (i < 2) /* First two file names are already in valid 8.3 format */
|
||||
ok(!strcmp(szFile, (CHAR*)&pidlFile->mkid.abID[12]), "Wrong file name!\n");
|
||||
else
|
||||
else
|
||||
/* WinXP stores a derived 8.3 dos name (LONGER~1.8_3) here. We probably
|
||||
* can't implement this correctly, since unix filesystems don't support
|
||||
* this nasty short/long filename stuff. So we'll probably stay with our
|
||||
* current habbit of storing the long filename here, which seems to work
|
||||
* just fine. */
|
||||
todo_wine { ok(pidlFile->mkid.abID[18] == '~', "Should be derived 8.3 name!\n"); }
|
||||
todo_wine
|
||||
ok(pidlFile->mkid.abID[18] == '~' ||
|
||||
broken(pidlFile->mkid.abID[34] == '~'), /* Win2k */
|
||||
"Should be derived 8.3 name!\n");
|
||||
|
||||
if (i == 0) /* First file name has an even number of chars. No need for alignment. */
|
||||
ok(pidlFile->mkid.abID[12 + strlen(szFile) + 1] != '\0',
|
||||
"Alignment byte, where there shouldn't be!\n");
|
||||
|
||||
ok(pidlFile->mkid.abID[12 + strlen(szFile) + 1] != '\0' ||
|
||||
broken(pidlFile->mkid.cb == 2 + 12 + strlen(szFile) + 1 + 1), /* Win2k */
|
||||
"Alignment byte, where there shouldn't be!\n");
|
||||
|
||||
if (i == 1) /* Second file name has an uneven number of chars => alignment byte */
|
||||
ok(pidlFile->mkid.abID[12 + strlen(szFile) + 1] == '\0',
|
||||
ok(pidlFile->mkid.abID[12 + strlen(szFile) + 1] == '\0',
|
||||
"There should be an alignment byte, but isn't!\n");
|
||||
|
||||
/* The offset of the FileStructW member is stored as a WORD at the end of the pidl. */
|
||||
cbOffset = *(WORD*)(((LPBYTE)pidlFile)+pidlFile->mkid.cb-sizeof(WORD));
|
||||
ok (cbOffset >= sizeof(struct FileStructA) &&
|
||||
cbOffset <= pidlFile->mkid.cb - sizeof(struct FileStructW),
|
||||
ok ((cbOffset >= sizeof(struct FileStructA) &&
|
||||
cbOffset <= pidlFile->mkid.cb - sizeof(struct FileStructW)) ||
|
||||
broken(pidlFile->mkid.cb == 2 + 12 + strlen(szFile) + 1 + 1) || /* Win2k on short names */
|
||||
broken(pidlFile->mkid.cb == 2 + 12 + strlen(szFile) + 1 + 12 + 1), /* Win2k on long names */
|
||||
"Wrong offset value (%d) stored at the end of the PIDL\n", cbOffset);
|
||||
|
||||
if (cbOffset >= sizeof(struct FileStructA) &&
|
||||
cbOffset <= pidlFile->mkid.cb - sizeof(struct FileStructW))
|
||||
cbOffset <= pidlFile->mkid.cb - sizeof(struct FileStructW))
|
||||
{
|
||||
struct FileStructW *pFileStructW = (struct FileStructW *)(((LPBYTE)pidlFile)+cbOffset);
|
||||
|
||||
ok(pidlFile->mkid.cb == cbOffset + pFileStructW->cbLen,
|
||||
ok(pidlFile->mkid.cb == cbOffset + pFileStructW->cbLen,
|
||||
"FileStructW's offset and length should add up to the PIDL's length!\n");
|
||||
|
||||
if (pidlFile->mkid.cb == cbOffset + pFileStructW->cbLen) {
|
||||
/* Since we just created the file, time of creation,
|
||||
* time of last access and time of last write access just be the same.
|
||||
* These tests seem to fail sometimes (on WinXP), if the test is run again shortly
|
||||
* time of last access and time of last write access just be the same.
|
||||
* These tests seem to fail sometimes (on WinXP), if the test is run again shortly
|
||||
* after the first run. I do remember something with NTFS keeping the creation time
|
||||
* if a file is deleted and then created again within a couple of seconds or so.
|
||||
* Might be the reason. */
|
||||
ok (pFileStructA->uFileDate == pFileStructW->uDate &&
|
||||
pFileStructA->uFileTime == pFileStructW->uTime,
|
||||
"Last write time should match creation time!\n");
|
||||
|
||||
|
||||
ok (pFileStructA->uFileDate == pFileStructW->uDate2 &&
|
||||
pFileStructA->uFileTime == pFileStructW->uTime2,
|
||||
"Last write time should match last access time!\n");
|
||||
|
||||
ok (!lstrcmpW(wszFile[i], pFileStructW->wszName),
|
||||
ok (!lstrcmpW(wszFile[i], pFileStructW->wszName) ||
|
||||
!lstrcmpW(wszFile[i], (WCHAR *)(pFileStructW->abFooBar2 + 22)), /* Vista */
|
||||
"The filename should be stored in unicode at this position!\n");
|
||||
}
|
||||
}
|
||||
|
@ -1385,7 +1527,7 @@ static void testSHGetFolderPathAndSubDirA(void)
|
|||
skip("SHGetFolderPathA not present!\n");
|
||||
return;
|
||||
}
|
||||
if(!SUCCEEDED(pSHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata)))
|
||||
if(FAILED(pSHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata)))
|
||||
{
|
||||
skip("SHGetFolderPathA failed for CSIDL_LOCAL_APPDATA!\n");
|
||||
return;
|
||||
|
@ -1475,6 +1617,129 @@ static void testSHGetFolderPathAndSubDirA(void)
|
|||
RemoveDirectoryA(testpath);
|
||||
}
|
||||
|
||||
static const char *wine_dbgstr_w(LPCWSTR str)
|
||||
{
|
||||
static char buf[512];
|
||||
if (!str)
|
||||
return "(null)";
|
||||
WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void test_LocalizedNames(void)
|
||||
{
|
||||
static char cCurrDirA[MAX_PATH];
|
||||
WCHAR cCurrDirW[MAX_PATH], tempbufW[25];
|
||||
IShellFolder *IDesktopFolder, *testIShellFolder;
|
||||
ITEMIDLIST *newPIDL;
|
||||
int len;
|
||||
HRESULT hr;
|
||||
static char resourcefile[MAX_PATH];
|
||||
DWORD res;
|
||||
HANDLE file;
|
||||
STRRET strret;
|
||||
|
||||
static const char desktopini_contents1[] =
|
||||
"[.ShellClassInfo]\r\n"
|
||||
"LocalizedResourceName=@";
|
||||
static const char desktopini_contents2[] =
|
||||
",-1\r\n";
|
||||
static WCHAR foldernameW[] = {'t','e','s','t','f','o','l','d','e','r',0};
|
||||
static const WCHAR folderdisplayW[] = {'F','o','l','d','e','r',' ','N','a','m','e',' ','R','e','s','o','u','r','c','e',0};
|
||||
|
||||
/* create folder with desktop.ini and localized name in GetModuleFileNameA(NULL) */
|
||||
CreateDirectoryA(".\\testfolder", NULL);
|
||||
|
||||
SetFileAttributesA(".\\testfolder", GetFileAttributesA(".\\testfolder")|FILE_ATTRIBUTE_SYSTEM);
|
||||
|
||||
GetModuleFileNameA(NULL, resourcefile, MAX_PATH);
|
||||
|
||||
file = CreateFileA(".\\testfolder\\desktop.ini", GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
ok(file != INVALID_HANDLE_VALUE, "CreateFileA failed %i\n", GetLastError());
|
||||
ok(WriteFile(file, desktopini_contents1, strlen(desktopini_contents1), &res, NULL) &&
|
||||
WriteFile(file, resourcefile, strlen(resourcefile), &res, NULL) &&
|
||||
WriteFile(file, desktopini_contents2, strlen(desktopini_contents2), &res, NULL),
|
||||
"WriteFile failed %i\n", GetLastError());
|
||||
CloseHandle(file);
|
||||
|
||||
/* get IShellFolder for parent */
|
||||
GetCurrentDirectoryA(MAX_PATH, cCurrDirA);
|
||||
len = lstrlenA(cCurrDirA);
|
||||
|
||||
if (len == 0) {
|
||||
trace("GetCurrentDirectoryA returned empty string. Skipping test_LocalizedNames\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if(cCurrDirA[len-1] == '\\')
|
||||
cCurrDirA[len-1] = 0;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH);
|
||||
|
||||
hr = SHGetDesktopFolder(&IDesktopFolder);
|
||||
ok(hr == S_OK, "SHGetDesktopfolder failed %08x\n", hr);
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0);
|
||||
ok(hr == S_OK, "ParseDisplayName failed %08x\n", hr);
|
||||
|
||||
hr = IShellFolder_BindToObject(IDesktopFolder, newPIDL, NULL, (REFIID)&IID_IShellFolder, (LPVOID *)&testIShellFolder);
|
||||
ok(hr == S_OK, "BindToObject failed %08x\n", hr);
|
||||
|
||||
IMalloc_Free(ppM, newPIDL);
|
||||
|
||||
/* windows reads the display name from the resource */
|
||||
hr = IShellFolder_ParseDisplayName(testIShellFolder, NULL, NULL, foldernameW, NULL, &newPIDL, 0);
|
||||
ok(hr == S_OK, "ParseDisplayName failed %08x\n", hr);
|
||||
|
||||
hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL, SHGDN_INFOLDER, &strret);
|
||||
ok(hr == S_OK, "GetDisplayNameOf failed %08x\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr) && pStrRetToBufW)
|
||||
{
|
||||
hr = pStrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR));
|
||||
ok (SUCCEEDED(hr), "StrRetToBufW failed! hr = %08x\n", hr);
|
||||
todo_wine
|
||||
ok (!lstrcmpiW(tempbufW, folderdisplayW) ||
|
||||
broken(!lstrcmpiW(tempbufW, foldernameW)), /* W2K */
|
||||
"GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW));
|
||||
}
|
||||
|
||||
/* editing name is also read from the resource */
|
||||
hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL, SHGDN_INFOLDER|SHGDN_FOREDITING, &strret);
|
||||
ok(hr == S_OK, "GetDisplayNameOf failed %08x\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr) && pStrRetToBufW)
|
||||
{
|
||||
hr = pStrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR));
|
||||
ok (SUCCEEDED(hr), "StrRetToBufW failed! hr = %08x\n", hr);
|
||||
todo_wine
|
||||
ok (!lstrcmpiW(tempbufW, folderdisplayW) ||
|
||||
broken(!lstrcmpiW(tempbufW, foldernameW)), /* W2K */
|
||||
"GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW));
|
||||
}
|
||||
|
||||
/* parsing name is unchanged */
|
||||
hr = IShellFolder_GetDisplayNameOf(testIShellFolder, newPIDL, SHGDN_INFOLDER|SHGDN_FORPARSING, &strret);
|
||||
ok(hr == S_OK, "GetDisplayNameOf failed %08x\n", hr);
|
||||
|
||||
if (SUCCEEDED(hr) && pStrRetToBufW)
|
||||
{
|
||||
hr = pStrRetToBufW(&strret, newPIDL, tempbufW, sizeof(tempbufW)/sizeof(WCHAR));
|
||||
ok (SUCCEEDED(hr), "StrRetToBufW failed! hr = %08x\n", hr);
|
||||
ok (!lstrcmpiW(tempbufW, foldernameW), "GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW));
|
||||
}
|
||||
|
||||
IShellFolder_Release(IDesktopFolder);
|
||||
IShellFolder_Release(testIShellFolder);
|
||||
|
||||
IMalloc_Free(ppM, newPIDL);
|
||||
|
||||
cleanup:
|
||||
DeleteFileA(".\\testfolder\\desktop.ini");
|
||||
SetFileAttributesA(".\\testfolder", GetFileAttributesA(".\\testfolder")&~FILE_ATTRIBUTE_SYSTEM);
|
||||
RemoveDirectoryA(".\\testfolder");
|
||||
}
|
||||
|
||||
|
||||
START_TEST(shlfolder)
|
||||
{
|
||||
|
@ -1496,6 +1761,7 @@ START_TEST(shlfolder)
|
|||
testSHGetFolderPathAndSubDirA();
|
||||
else
|
||||
skip("SHGetFolderPathAndSubDirA not present\n");
|
||||
test_LocalizedNames();
|
||||
|
||||
OleUninitialize();
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ static HRESULT (WINAPI *pStrRetToStrNAW)(LPVOID,DWORD,LPSTRRET,const ITEMIDLIST
|
|||
static WCHAR *CoDupStrW(const char* src)
|
||||
{
|
||||
INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
|
||||
WCHAR* szTemp = (WCHAR*)CoTaskMemAlloc(len * sizeof(WCHAR));
|
||||
WCHAR* szTemp = CoTaskMemAlloc(len * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
|
||||
return szTemp;
|
||||
}
|
||||
|
@ -110,4 +110,6 @@ START_TEST(string)
|
|||
else
|
||||
test_StrRetToStringNA();
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
|
||||
static HWND hMainWnd;
|
||||
static BOOL (WINAPI *pShell_NotifyIconW)(DWORD,PNOTIFYICONDATAW);
|
||||
static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD);
|
||||
|
||||
void test_cbsize(void)
|
||||
static void test_cbsize(void)
|
||||
{
|
||||
NOTIFYICONDATAA nidA;
|
||||
BOOL ret;
|
||||
|
||||
if (pShell_NotifyIconW)
|
||||
{
|
||||
|
@ -44,16 +44,20 @@ void test_cbsize(void)
|
|||
nidW.uFlags = NIF_ICON|NIF_MESSAGE;
|
||||
nidW.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
nidW.uCallbackMessage = WM_USER+17;
|
||||
ok(pShell_NotifyIconW(NIM_ADD, &nidW), "NIM_ADD failed!\n");
|
||||
|
||||
/* using an invalid cbSize does work */
|
||||
nidW.cbSize = 3;
|
||||
nidW.hWnd = hMainWnd;
|
||||
nidW.uID = 1;
|
||||
ok(pShell_NotifyIconW(NIM_DELETE, &nidW), "NIM_DELETE failed!\n");
|
||||
/* as icon doesn't exist anymore - now there will be an error */
|
||||
nidW.cbSize = sizeof(nidW);
|
||||
ok(!pShell_NotifyIconW(NIM_DELETE, &nidW), "The icon was not deleted\n");
|
||||
ret = pShell_NotifyIconW(NIM_ADD, &nidW);
|
||||
if (ret)
|
||||
{
|
||||
/* using an invalid cbSize does work */
|
||||
nidW.cbSize = 3;
|
||||
nidW.hWnd = hMainWnd;
|
||||
nidW.uID = 1;
|
||||
ret = pShell_NotifyIconW(NIM_DELETE, &nidW);
|
||||
ok( ret || broken(!ret), /* nt4 */ "NIM_DELETE failed!\n");
|
||||
/* as icon doesn't exist anymore - now there will be an error */
|
||||
nidW.cbSize = sizeof(nidW);
|
||||
ok(!pShell_NotifyIconW(NIM_DELETE, &nidW) != !ret, "The icon was not deleted\n");
|
||||
}
|
||||
else win_skip( "Shell_NotifyIconW not working\n" ); /* win9x */
|
||||
}
|
||||
|
||||
/* same for Shell_NotifyIconA */
|
||||
|
@ -70,65 +74,11 @@ void test_cbsize(void)
|
|||
nidA.cbSize = 3;
|
||||
nidA.hWnd = hMainWnd;
|
||||
nidA.uID = 1;
|
||||
ok(Shell_NotifyIconA(NIM_DELETE, &nidA), "NIM_DELETE failed!\n");
|
||||
ret = Shell_NotifyIconA(NIM_DELETE, &nidA);
|
||||
ok( ret || broken(!ret), /* win9x */ "NIM_DELETE failed!\n");
|
||||
/* as icon doesn't exist anymore - now there will be an error */
|
||||
nidA.cbSize = sizeof(nidA);
|
||||
ok(!Shell_NotifyIconA(NIM_DELETE, &nidA), "The icon was not deleted\n");
|
||||
}
|
||||
|
||||
static void test_SHAppBarMessage(void)
|
||||
{
|
||||
APPBARDATA abd;
|
||||
HWND hwnd, foregnd;
|
||||
UINT_PTR ret;
|
||||
|
||||
memset(&abd, 0xcc, sizeof(abd));
|
||||
abd.cbSize = sizeof(abd);
|
||||
abd.uEdge = ABE_BOTTOM;
|
||||
|
||||
hwnd = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
|
||||
ok(hwnd == NULL || IsWindow(hwnd), "ret %p which is not a window\n", hwnd);
|
||||
ok(abd.hWnd == (HWND)0xcccccccc, "hWnd overwritten\n");
|
||||
|
||||
if (!pMonitorFromWindow)
|
||||
{
|
||||
skip("MonitorFromWindow is not available\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Presumably one can pass a hwnd with ABM_GETAUTOHIDEBAR to specify a monitor.
|
||||
Pass the foreground window and check */
|
||||
foregnd = GetForegroundWindow();
|
||||
if(foregnd)
|
||||
{
|
||||
abd.hWnd = foregnd;
|
||||
hwnd = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
|
||||
ok(hwnd == NULL || IsWindow(hwnd), "ret %p which is not a window\n", hwnd);
|
||||
ok(abd.hWnd == foregnd, "hWnd overwritten\n");
|
||||
if(hwnd)
|
||||
{
|
||||
HMONITOR appbar_mon, foregnd_mon;
|
||||
appbar_mon = pMonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
foregnd_mon = pMonitorFromWindow(foregnd, MONITOR_DEFAULTTONEAREST);
|
||||
ok(appbar_mon == foregnd_mon, "Windows on different monitors\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(&abd, 0xcc, sizeof(abd));
|
||||
abd.cbSize = sizeof(abd);
|
||||
ret = SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
|
||||
if(ret)
|
||||
{
|
||||
ok(abd.hWnd == (HWND)0xcccccccc, "hWnd overwritten\n");
|
||||
todo_wine
|
||||
{
|
||||
ok(abd.uEdge >= ABE_LEFT && abd.uEdge <= ABE_BOTTOM, "uEdge not returned\n");
|
||||
ok(abd.rc.left != 0xcccccccc, "rc not updated\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
ok(!Shell_NotifyIconA(NIM_DELETE, &nidA) != !ret, "The icon was not deleted\n");
|
||||
}
|
||||
|
||||
START_TEST(systray)
|
||||
|
@ -136,14 +86,11 @@ START_TEST(systray)
|
|||
WNDCLASSA wc;
|
||||
MSG msg;
|
||||
RECT rc;
|
||||
HMODULE huser32, hshell32;
|
||||
HMODULE hshell32;
|
||||
|
||||
hshell32 = GetModuleHandleA("shell32.dll");
|
||||
pShell_NotifyIconW = (void*)GetProcAddress(hshell32, "Shell_NotifyIconW");
|
||||
|
||||
huser32 = GetModuleHandleA("user32.dll");
|
||||
pMonitorFromWindow = (void*)GetProcAddress(huser32, "MonitorFromWindow");
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
|
@ -169,6 +116,4 @@ START_TEST(systray)
|
|||
DispatchMessageA(&msg);
|
||||
}
|
||||
DestroyWindow(hMainWnd);
|
||||
|
||||
test_SHAppBarMessage();
|
||||
}
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
#define STANDALONE
|
||||
#include "wine/test.h"
|
||||
|
||||
extern void func_appbar(void);
|
||||
extern void func_autocomplete(void);
|
||||
extern void func_generated(void);
|
||||
extern void func_shelllink(void);
|
||||
extern void func_shellpath(void);
|
||||
extern void func_shfldr_netplaces(void);
|
||||
extern void func_shfldr_special(void);
|
||||
extern void func_shlexec(void);
|
||||
extern void func_shlfileop(void);
|
||||
extern void func_shlfolder(void);
|
||||
|
@ -18,10 +21,13 @@ extern void func_systray(void);
|
|||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "generated", func_generated },
|
||||
{ "appbar", func_appbar },
|
||||
{ "autocomplete", func_autocomplete },
|
||||
{ "generated", func_generated },
|
||||
{ "shelllink", func_shelllink },
|
||||
{ "shellpath", func_shellpath },
|
||||
{ "shfldr_netplaces", func_shfldr_netplaces },
|
||||
{ "shfldr_special", func_shfldr_special },
|
||||
{ "shlexec", func_shlexec },
|
||||
{ "shlfileop", func_shlfileop },
|
||||
{ "shlfolder", func_shlfolder },
|
||||
|
|
Loading…
Reference in a new issue