mirror of
https://github.com/reactos/reactos.git
synced 2025-04-30 02:58:48 +00:00
[SHELL32_WINETEST]
* Sync to Wine 1.3.29. svn path=/trunk/; revision=53821
This commit is contained in:
parent
3ed568c40d
commit
b1df00f897
19 changed files with 8076 additions and 151 deletions
|
@ -8,10 +8,16 @@ add_definitions(
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
appbar.c
|
appbar.c
|
||||||
autocomplete.c
|
autocomplete.c
|
||||||
|
brsfolder.c
|
||||||
|
ebrowser.c
|
||||||
generated.c
|
generated.c
|
||||||
progman_dde.c
|
progman_dde.c
|
||||||
|
recyclebin.c
|
||||||
|
shelldispatch.c
|
||||||
shelllink.c
|
shelllink.c
|
||||||
|
shellole.c
|
||||||
shellpath.c
|
shellpath.c
|
||||||
|
shfldr_special.c
|
||||||
shlexec.c
|
shlexec.c
|
||||||
shlfileop.c
|
shlfileop.c
|
||||||
shlfolder.c
|
shlfolder.c
|
||||||
|
@ -19,11 +25,10 @@ list(APPEND SOURCE
|
||||||
string.c
|
string.c
|
||||||
systray.c
|
systray.c
|
||||||
testlist.c
|
testlist.c
|
||||||
shfldr_special.c
|
|
||||||
rsrc.rc)
|
rsrc.rc)
|
||||||
|
|
||||||
add_executable(shell32_winetest ${SOURCE})
|
add_executable(shell32_winetest ${SOURCE})
|
||||||
target_link_libraries(shell32_winetest wine uuid)
|
target_link_libraries(shell32_winetest wine uuid)
|
||||||
set_module_type(shell32_winetest win32cui)
|
set_module_type(shell32_winetest win32cui)
|
||||||
add_importlibs(shell32_winetest shlwapi gdi32 shell32 ole32 oleaut32 user32 advapi32 msvcrt kernel32 ntdll)
|
add_importlibs(shell32_winetest shell32 ole32 oleaut32 user32 advapi32 msvcrt kernel32 ntdll)
|
||||||
add_cd_file(TARGET shell32_winetest DESTINATION reactos/bin FOR all)
|
add_cd_file(TARGET shell32_winetest DESTINATION reactos/bin FOR all)
|
||||||
|
|
|
@ -33,11 +33,115 @@ static HWND hMainWnd, hEdit;
|
||||||
static HINSTANCE hinst;
|
static HINSTANCE hinst;
|
||||||
static int killfocus_count;
|
static int killfocus_count;
|
||||||
|
|
||||||
|
static void test_invalid_init(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
IAutoComplete *ac;
|
||||||
|
IUnknown *acSource;
|
||||||
|
HWND edit_control;
|
||||||
|
|
||||||
|
/* AutoComplete instance */
|
||||||
|
hr = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IAutoComplete, (void **)&ac);
|
||||||
|
if (hr == REGDB_E_CLASSNOTREG)
|
||||||
|
{
|
||||||
|
win_skip("CLSID_AutoComplete is not registered\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok(hr == S_OK, "no IID_IAutoComplete (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
/* AutoComplete source */
|
||||||
|
hr = CoCreateInstance(&CLSID_ACLMulti, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IACList, (void **)&acSource);
|
||||||
|
if (hr == REGDB_E_CLASSNOTREG)
|
||||||
|
{
|
||||||
|
win_skip("CLSID_ACLMulti is not registered\n");
|
||||||
|
IAutoComplete_Release(ac);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok(hr == S_OK, "no IID_IACList (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
edit_control = CreateWindowExA(0, "EDIT", "Some text", 0, 10, 10, 300, 300,
|
||||||
|
hMainWnd, NULL, hinst, NULL);
|
||||||
|
ok(edit_control != NULL, "Can't create edit control\n");
|
||||||
|
|
||||||
|
/* The refcount of acSource would be incremented on older Windows. */
|
||||||
|
hr = IAutoComplete_Init(ac, NULL, acSource, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG ||
|
||||||
|
broken(hr == S_OK), /* Win2k/XP/Win2k3 */
|
||||||
|
"Init returned 0x%08x\n", hr);
|
||||||
|
if (hr == E_INVALIDARG)
|
||||||
|
{
|
||||||
|
LONG ref;
|
||||||
|
|
||||||
|
IUnknown_AddRef(acSource);
|
||||||
|
ref = IUnknown_Release(acSource);
|
||||||
|
ok(ref == 1, "Expected AutoComplete source refcount to be 1, got %d\n", ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
/* Older Windows versions never check the window handle, while newer
|
||||||
|
* versions only check for NULL. Subsequent attempts to initialize the
|
||||||
|
* object after this call succeeds would fail, because initialization
|
||||||
|
* state is determined by whether a non-NULL window handle is stored. */
|
||||||
|
hr = IAutoComplete_Init(ac, (HWND)0xdeadbeef, acSource, NULL, NULL);
|
||||||
|
ok(hr == S_OK, "Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* Tests crash on older Windows. */
|
||||||
|
hr = IAutoComplete_Init(ac, NULL, NULL, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG, "Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IAutoComplete_Init(ac, edit_control, NULL, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG, "Init returned 0x%08x\n", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bind to edit control */
|
||||||
|
hr = IAutoComplete_Init(ac, edit_control, acSource, NULL, NULL);
|
||||||
|
ok(hr == S_OK, "Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* try invalid parameters after successful initialization .*/
|
||||||
|
hr = IAutoComplete_Init(ac, NULL, NULL, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG ||
|
||||||
|
hr == E_FAIL, /* Win2k/XP/Win2k3 */
|
||||||
|
"Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IAutoComplete_Init(ac, NULL, acSource, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG ||
|
||||||
|
hr == E_FAIL, /* Win2k/XP/Win2k3 */
|
||||||
|
"Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IAutoComplete_Init(ac, edit_control, NULL, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG ||
|
||||||
|
hr == E_FAIL, /* Win2k/XP/Win2k3 */
|
||||||
|
"Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* try initializing twice on the same control */
|
||||||
|
hr = IAutoComplete_Init(ac, edit_control, acSource, NULL, NULL);
|
||||||
|
ok(hr == E_FAIL, "Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* try initializing with a different control */
|
||||||
|
hr = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL);
|
||||||
|
ok(hr == E_FAIL, "Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
DestroyWindow(edit_control);
|
||||||
|
|
||||||
|
/* try initializing with a different control after
|
||||||
|
* destroying the original initialization control */
|
||||||
|
hr = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL);
|
||||||
|
ok(hr == E_UNEXPECTED ||
|
||||||
|
hr == E_FAIL, /* Win2k/XP/Win2k3 */
|
||||||
|
"Init returned 0x%08x\n", hr);
|
||||||
|
|
||||||
|
IUnknown_Release(acSource);
|
||||||
|
IAutoComplete_Release(ac);
|
||||||
|
}
|
||||||
static IAutoComplete *test_init(void)
|
static IAutoComplete *test_init(void)
|
||||||
{
|
{
|
||||||
HRESULT r;
|
HRESULT r;
|
||||||
IAutoComplete* ac;
|
IAutoComplete *ac;
|
||||||
IUnknown *acSource;
|
IUnknown *acSource;
|
||||||
|
LONG_PTR user_data;
|
||||||
|
|
||||||
/* AutoComplete instance */
|
/* AutoComplete instance */
|
||||||
r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
|
r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
@ -55,18 +159,20 @@ static IAutoComplete *test_init(void)
|
||||||
if (r == REGDB_E_CLASSNOTREG)
|
if (r == REGDB_E_CLASSNOTREG)
|
||||||
{
|
{
|
||||||
win_skip("CLSID_ACLMulti is not registered\n");
|
win_skip("CLSID_ACLMulti is not registered\n");
|
||||||
|
IAutoComplete_Release(ac);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ok(r == S_OK, "no IID_IACList (0x%08x)\n", r);
|
ok(r == S_OK, "no IID_IACList (0x%08x)\n", r);
|
||||||
|
|
||||||
if (0)
|
user_data = GetWindowLongPtrA(hEdit, GWLP_USERDATA);
|
||||||
{
|
ok(user_data == 0, "Expected the edit control user data to be zero\n");
|
||||||
/* crashes on native */
|
|
||||||
r = IAutoComplete_Init(ac, hEdit, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
/* bind to edit control */
|
/* bind to edit control */
|
||||||
r = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL);
|
r = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL);
|
||||||
ok(r == S_OK, "Init failed (0x%08x)\n", r);
|
ok(r == S_OK, "Init returned 0x%08x\n", r);
|
||||||
|
|
||||||
|
user_data = GetWindowLongPtrA(hEdit, GWLP_USERDATA);
|
||||||
|
ok(user_data == 0, "Expected the edit control user data to be zero\n");
|
||||||
|
|
||||||
IUnknown_Release(acSource);
|
IUnknown_Release(acSource);
|
||||||
|
|
||||||
|
@ -134,6 +240,7 @@ START_TEST(autocomplete)
|
||||||
ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
|
ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
|
||||||
if (!hMainWnd) return;
|
if (!hMainWnd) return;
|
||||||
|
|
||||||
|
test_invalid_init();
|
||||||
ac = test_init();
|
ac = test_init();
|
||||||
if (!ac)
|
if (!ac)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
365
rostests/winetests/shell32/brsfolder.c
Normal file
365
rostests/winetests/shell32/brsfolder.c
Normal file
|
@ -0,0 +1,365 @@
|
||||||
|
/*
|
||||||
|
* Unit test of the SHBrowseForFolder function.
|
||||||
|
*
|
||||||
|
* Copyright 2009-2010 Michael Mc Donnell
|
||||||
|
* Copyright 2011 André Hentschel
|
||||||
|
*
|
||||||
|
* 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 <windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <shobjidl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "wine/test.h"
|
||||||
|
#define IDD_MAKENEWFOLDER 0x3746 /* From "../shresdef.h" */
|
||||||
|
#define TIMER_WAIT_MS 50 /* Should be long enough for slow systems */
|
||||||
|
|
||||||
|
static const char new_folder_name[] = "foo";
|
||||||
|
static LPITEMIDLIST selected_folder_pidl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the number of folders in a folder.
|
||||||
|
*/
|
||||||
|
static int get_number_of_folders(LPCSTR path)
|
||||||
|
{
|
||||||
|
int number_of_folders = 0;
|
||||||
|
char path_search_string[MAX_PATH];
|
||||||
|
WIN32_FIND_DATA find_data;
|
||||||
|
HANDLE find_handle;
|
||||||
|
|
||||||
|
strncpy(path_search_string, path, MAX_PATH);
|
||||||
|
strncat(path_search_string, "*", 1);
|
||||||
|
|
||||||
|
find_handle = FindFirstFile(path_search_string, &find_data);
|
||||||
|
if (find_handle == INVALID_HANDLE_VALUE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||||
|
strcmp(find_data.cFileName, ".") != 0 &&
|
||||||
|
strcmp(find_data.cFileName, "..") != 0)
|
||||||
|
{
|
||||||
|
number_of_folders++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (FindNextFile(find_handle, &find_data) != 0);
|
||||||
|
|
||||||
|
FindClose(find_handle);
|
||||||
|
return number_of_folders;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL does_folder_or_file_exist(LPCSTR folder_path)
|
||||||
|
{
|
||||||
|
DWORD file_attributes = GetFileAttributesA(folder_path);
|
||||||
|
return !(file_attributes == INVALID_FILE_ATTRIBUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timer callback used by test_click_make_new_folder_button. It simulates a user
|
||||||
|
* making a new folder and calling it "foo".
|
||||||
|
*/
|
||||||
|
static void CALLBACK make_new_folder_timer_callback(HWND hwnd, UINT uMsg,
|
||||||
|
UINT_PTR idEvent, DWORD dwTime)
|
||||||
|
{
|
||||||
|
static int step = 0;
|
||||||
|
|
||||||
|
switch (step++)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
/* Click "Make New Folder" button */
|
||||||
|
PostMessage(hwnd, WM_COMMAND, IDD_MAKENEWFOLDER, 0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* Set the new folder name to foo by replacing text in edit control */
|
||||||
|
SendMessage(GetFocus(), EM_REPLACESEL, 0, (LPARAM) new_folder_name);
|
||||||
|
SetFocus(hwnd);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/*
|
||||||
|
* The test does not trigger the correct state on Windows. This results
|
||||||
|
* in the new folder pidl not being returned. The result is as
|
||||||
|
* expected if the same steps are done manually.
|
||||||
|
* Sending the down key selects the new folder again which sets the
|
||||||
|
* correct state. This ensures that the correct pidl is returned.
|
||||||
|
*/
|
||||||
|
keybd_event(VK_DOWN, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
KillTimer(hwnd, idEvent);
|
||||||
|
/* Close dialog box */
|
||||||
|
SendMessage(hwnd, WM_COMMAND, IDOK, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback used by test_click_make_new_folder_button. It sets up a timer to
|
||||||
|
* simulate user input.
|
||||||
|
*/
|
||||||
|
static int CALLBACK create_new_folder_callback(HWND hwnd, UINT uMsg,
|
||||||
|
LPARAM lParam, LPARAM lpData)
|
||||||
|
{
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case BFFM_INITIALIZED:
|
||||||
|
/* User input is simulated in timer callback */
|
||||||
|
SetTimer(hwnd, 0, TIMER_WAIT_MS, make_new_folder_timer_callback);
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests if clicking the "Make New Folder" button in a SHBrowseForFolder
|
||||||
|
* dialog box creates a new folder. (Bug 17986).
|
||||||
|
*
|
||||||
|
* Here follows a description of what happens on W2K,Vista, W2K8, W7:
|
||||||
|
* When the "Make New Folder" button is clicked a new folder is created and
|
||||||
|
* inserted into the tree. The folder is given a default name that depends on
|
||||||
|
* the locale (e.g. "New Folder"). The folder name is selected and the dialog
|
||||||
|
* waits for the user to type in a new name. The folder is renamed when the user
|
||||||
|
* types in a name and presses enter.
|
||||||
|
*
|
||||||
|
* Note that XP and W2K3 do not select the folder name or wait for the user
|
||||||
|
* to type in a new folder name. This behavior is considered broken as most
|
||||||
|
* users would like to give the folder a name after creating it. The fact that
|
||||||
|
* it originally waited for the user to type in a new folder name(W2K), and then
|
||||||
|
* again was changed back wait for the new folder name(Vista, W2K8, W7),
|
||||||
|
* indicates that MS also believes that it was broken in XP and W2K3.
|
||||||
|
*/
|
||||||
|
static void test_click_make_new_folder_button(void)
|
||||||
|
{
|
||||||
|
HRESULT resCoInit, hr;
|
||||||
|
BROWSEINFO bi;
|
||||||
|
LPITEMIDLIST pidl = NULL;
|
||||||
|
LPITEMIDLIST test_folder_pidl;
|
||||||
|
IShellFolder *test_folder_object;
|
||||||
|
char test_folder_path[MAX_PATH];
|
||||||
|
WCHAR test_folder_pathW[MAX_PATH];
|
||||||
|
CHAR new_folder_path[MAX_PATH];
|
||||||
|
CHAR new_folder_pidl_path[MAX_PATH];
|
||||||
|
char selected_folder[MAX_PATH];
|
||||||
|
const CHAR title[] = "test_click_make_new_folder_button";
|
||||||
|
int number_of_folders = -1;
|
||||||
|
SHFILEOPSTRUCT shfileop;
|
||||||
|
|
||||||
|
if (does_folder_or_file_exist(title))
|
||||||
|
{
|
||||||
|
skip("The test folder already exists.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must initialize COM if using the NEWDIAlOGSTYLE according to MSDN. */
|
||||||
|
resCoInit = CoInitialize(NULL);
|
||||||
|
if(!(resCoInit == S_OK || resCoInit == S_FALSE))
|
||||||
|
{
|
||||||
|
skip("COM could not be initialized %u\n", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave room for concatenating title, two backslashes, and an extra NULL. */
|
||||||
|
if (!GetCurrentDirectoryA(MAX_PATH-strlen(title)-3, test_folder_path))
|
||||||
|
{
|
||||||
|
skip("GetCurrentDirectoryA failed %u\n", GetLastError());
|
||||||
|
}
|
||||||
|
strncat(test_folder_path, "\\", 1);
|
||||||
|
strncat(test_folder_path, title, MAX_PATH-1);
|
||||||
|
strncat(test_folder_path, "\\", 1);
|
||||||
|
|
||||||
|
/* Avoid conflicts by creating a test folder. */
|
||||||
|
if (!CreateDirectoryA(title, NULL))
|
||||||
|
{
|
||||||
|
skip("CreateDirectoryA failed %u\n", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize browse info struct for SHBrowseForFolder */
|
||||||
|
bi.hwndOwner = NULL;
|
||||||
|
bi.pszDisplayName = (LPTSTR) &selected_folder;
|
||||||
|
bi.lpszTitle = (LPTSTR) title;
|
||||||
|
bi.ulFlags = BIF_NEWDIALOGSTYLE;
|
||||||
|
bi.lpfn = create_new_folder_callback;
|
||||||
|
/* Use test folder as the root folder for dialog box */
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, test_folder_path, MAX_PATH,
|
||||||
|
test_folder_pathW, MAX_PATH);
|
||||||
|
hr = SHGetDesktopFolder(&test_folder_object);
|
||||||
|
ok (SUCCEEDED(hr), "SHGetDesktopFolder failed with hr 0x%08x\n", hr);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
skip("SHGetDesktopFolder failed - skipping\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
test_folder_object->lpVtbl->ParseDisplayName(test_folder_object, NULL, NULL,
|
||||||
|
test_folder_pathW, 0UL, &test_folder_pidl, 0UL);
|
||||||
|
bi.pidlRoot = test_folder_pidl;
|
||||||
|
|
||||||
|
/* Display dialog box and let callback click the buttons */
|
||||||
|
pidl = SHBrowseForFolder(&bi);
|
||||||
|
|
||||||
|
number_of_folders = get_number_of_folders(test_folder_path);
|
||||||
|
ok(number_of_folders == 1 || broken(number_of_folders == 0) /* W95, W98 */,
|
||||||
|
"Clicking \"Make New Folder\" button did not result in a new folder.\n");
|
||||||
|
|
||||||
|
/* There should be a new folder foo inside the test folder */
|
||||||
|
strcpy(new_folder_path, test_folder_path);
|
||||||
|
strcat(new_folder_path, new_folder_name);
|
||||||
|
ok(does_folder_or_file_exist(new_folder_path)
|
||||||
|
|| broken(!does_folder_or_file_exist(new_folder_path)) /* W95, W98, XP, W2K3 */,
|
||||||
|
"The new folder did not get the name %s\n", new_folder_name);
|
||||||
|
|
||||||
|
/* Dialog should return a pidl pointing to the new folder */
|
||||||
|
ok(SHGetPathFromIDListA(pidl, new_folder_pidl_path),
|
||||||
|
"SHGetPathFromIDList failed for new folder.\n");
|
||||||
|
ok(strcmp(new_folder_path, new_folder_pidl_path) == 0
|
||||||
|
|| broken(strcmp(new_folder_path, new_folder_pidl_path) != 0) /* earlier than Vista */,
|
||||||
|
"SHBrowseForFolder did not return the pidl for the new folder. "
|
||||||
|
"Expected '%s' got '%s'\n", new_folder_path, new_folder_pidl_path);
|
||||||
|
|
||||||
|
/* Remove test folder and any subfolders created in this test */
|
||||||
|
shfileop.hwnd = NULL;
|
||||||
|
shfileop.wFunc = FO_DELETE;
|
||||||
|
/* Path must be double NULL terminated */
|
||||||
|
test_folder_path[strlen(test_folder_path)+1] = '\0';
|
||||||
|
shfileop.pFrom = test_folder_path;
|
||||||
|
shfileop.pTo = NULL;
|
||||||
|
shfileop.fFlags = FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_SILENT;
|
||||||
|
SHFileOperation(&shfileop);
|
||||||
|
|
||||||
|
if (pidl)
|
||||||
|
CoTaskMemFree(pidl);
|
||||||
|
if (test_folder_pidl)
|
||||||
|
CoTaskMemFree(test_folder_pidl);
|
||||||
|
test_folder_object->lpVtbl->Release(test_folder_object);
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback used by test_selection.
|
||||||
|
*/
|
||||||
|
static int CALLBACK selection_callback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
|
||||||
|
{
|
||||||
|
DWORD ret;
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case BFFM_INITIALIZED:
|
||||||
|
/* test with zero values */
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONA, 0, 0);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONW, 0, 0);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONA, 1, 0);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
|
||||||
|
if(0)
|
||||||
|
{
|
||||||
|
/* Crashes on NT4 */
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONW, 1, 0);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONA, 0, (LPARAM)selected_folder_pidl);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONW, 0, (LPARAM)selected_folder_pidl);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONA, 1, (LPARAM)selected_folder_pidl);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)selected_folder_pidl);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONA, 1, (LPARAM)new_folder_name);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
ret = SendMessage(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)new_folder_name);
|
||||||
|
ok(!ret, "SendMessage returned: %u\n", ret);
|
||||||
|
|
||||||
|
SendMessage(hwnd, WM_COMMAND, IDOK, 0);
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_selection(void)
|
||||||
|
{
|
||||||
|
HRESULT resCoInit, hr;
|
||||||
|
BROWSEINFO bi;
|
||||||
|
LPITEMIDLIST pidl = NULL;
|
||||||
|
IShellFolder *desktop_object;
|
||||||
|
WCHAR selected_folderW[MAX_PATH];
|
||||||
|
const CHAR title[] = "test_selection";
|
||||||
|
|
||||||
|
resCoInit = CoInitialize(NULL);
|
||||||
|
if(!(resCoInit == S_OK || resCoInit == S_FALSE))
|
||||||
|
{
|
||||||
|
skip("COM could not be initialized %u\n", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetCurrentDirectoryW(MAX_PATH, selected_folderW))
|
||||||
|
{
|
||||||
|
skip("GetCurrentDirectoryW failed %u\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize browse info struct for SHBrowseForFolder */
|
||||||
|
bi.hwndOwner = NULL;
|
||||||
|
bi.pszDisplayName = NULL;
|
||||||
|
bi.lpszTitle = (LPTSTR) title;
|
||||||
|
bi.lpfn = selection_callback;
|
||||||
|
|
||||||
|
hr = SHGetDesktopFolder(&desktop_object);
|
||||||
|
ok (SUCCEEDED(hr), "SHGetDesktopFolder failed with hr 0x%08x\n", hr);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
skip("SHGetDesktopFolder failed - skipping\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
desktop_object->lpVtbl->ParseDisplayName(desktop_object, NULL, NULL,
|
||||||
|
selected_folderW, 0UL, &selected_folder_pidl, 0UL);
|
||||||
|
bi.pidlRoot = selected_folder_pidl;
|
||||||
|
|
||||||
|
/* test without flags */
|
||||||
|
bi.ulFlags = 0;
|
||||||
|
pidl = SHBrowseForFolder(&bi);
|
||||||
|
|
||||||
|
if (pidl)
|
||||||
|
CoTaskMemFree(pidl);
|
||||||
|
|
||||||
|
/* test with flag */
|
||||||
|
bi.ulFlags = BIF_NEWDIALOGSTYLE;
|
||||||
|
pidl = SHBrowseForFolder(&bi);
|
||||||
|
|
||||||
|
if (pidl)
|
||||||
|
CoTaskMemFree(pidl);
|
||||||
|
|
||||||
|
desktop_object->lpVtbl->Release(desktop_object);
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(brsfolder)
|
||||||
|
{
|
||||||
|
test_click_make_new_folder_button();
|
||||||
|
test_selection();
|
||||||
|
}
|
1799
rostests/winetests/shell32/ebrowser.c
Normal file
1799
rostests/winetests/shell32/ebrowser.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -200,14 +200,22 @@ static void init_strings(void)
|
||||||
WCHAR module[MAX_PATH];
|
WCHAR module[MAX_PATH];
|
||||||
WCHAR module_expanded[MAX_PATH];
|
WCHAR module_expanded[MAX_PATH];
|
||||||
WCHAR localized[MAX_PATH];
|
WCHAR localized[MAX_PATH];
|
||||||
|
HRESULT hr;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, startup, -1, startupW, sizeof(startupW)/sizeof(WCHAR));
|
MultiByteToWideChar(CP_ACP, 0, startup, -1, startupW, sizeof(startupW)/sizeof(WCHAR));
|
||||||
pSHGetLocalizedName(startupW, module, MAX_PATH, &id);
|
hr = pSHGetLocalizedName(startupW, module, MAX_PATH, &id);
|
||||||
ExpandEnvironmentStringsW(module, module_expanded, MAX_PATH);
|
todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
LoadStringW(GetModuleHandleW(module_expanded), id, localized, MAX_PATH);
|
/* check to be removed when SHGetLocalizedName is implemented */
|
||||||
|
if (hr == S_OK)
|
||||||
|
{
|
||||||
|
ExpandEnvironmentStringsW(module, module_expanded, MAX_PATH);
|
||||||
|
LoadStringW(GetModuleHandleW(module_expanded), id, localized, MAX_PATH);
|
||||||
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, localized, -1, StartupTitle, sizeof(StartupTitle), NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, localized, -1, StartupTitle, sizeof(StartupTitle), NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lstrcpyA(StartupTitle, (strrchr(startup, '\\') + 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
107
rostests/winetests/shell32/recyclebin.c
Normal file
107
rostests/winetests/shell32/recyclebin.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Tests for recycle bin functions
|
||||||
|
*
|
||||||
|
* Copyright 2011 Jay Yang
|
||||||
|
*
|
||||||
|
* 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 WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include "shellapi.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static int (WINAPI *pSHQueryRecycleBinA)(LPCSTR,LPSHQUERYRBINFO);
|
||||||
|
static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA);
|
||||||
|
|
||||||
|
static char int64_buffer[65];
|
||||||
|
/* Note: This function uses a single buffer for the return value.*/
|
||||||
|
static const char* str_from_int64(__int64 ll)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
|
||||||
|
sprintf(int64_buffer,"%lx%08lx",(unsigned long)(ll >> 32),(unsigned long)ll);
|
||||||
|
else
|
||||||
|
sprintf(int64_buffer,"%lx",(unsigned long)ll);
|
||||||
|
return int64_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_pointers(void)
|
||||||
|
{
|
||||||
|
HMODULE hshell32 = GetModuleHandleA("shell32.dll");
|
||||||
|
pSHQueryRecycleBinA = (void*)GetProcAddress(hshell32, "SHQueryRecycleBinA");
|
||||||
|
pSHFileOperationA = (void*)GetProcAddress(hshell32, "SHFileOperationA");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_query_recyclebin(void)
|
||||||
|
{
|
||||||
|
SHQUERYRBINFO info1={sizeof(info1),0xdeadbeef,0xdeadbeef};
|
||||||
|
SHQUERYRBINFO info2={sizeof(info2),0xdeadbeef,0xdeadbeef};
|
||||||
|
UINT written;
|
||||||
|
HRESULT hr;
|
||||||
|
HANDLE file;
|
||||||
|
SHFILEOPSTRUCTA shfo;
|
||||||
|
const CHAR *name="test.txt";
|
||||||
|
CHAR buf[MAX_PATH+strlen(name)+2];
|
||||||
|
if(!pSHQueryRecycleBinA)
|
||||||
|
{
|
||||||
|
skip("SHQueryRecycleBinA does not exist\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!pSHFileOperationA)
|
||||||
|
{
|
||||||
|
skip("SHFileOperationA does not exist\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GetCurrentDirectoryA(MAX_PATH, buf);
|
||||||
|
strcat(buf,"\\");
|
||||||
|
strcat(buf,name);
|
||||||
|
buf[strlen(buf) + 1] = '\0';
|
||||||
|
hr = pSHQueryRecycleBinA(buf,&info1);
|
||||||
|
ok(hr == S_OK, "SHQueryRecycleBinA failed with error 0x%x\n", hr);
|
||||||
|
ok(info1.i64Size!=0xdeadbeef,"i64Size not set\n");
|
||||||
|
ok(info1.i64NumItems!=0xdeadbeef,"i64NumItems not set\n");
|
||||||
|
/*create and send a file to the recycle bin*/
|
||||||
|
file = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
|
||||||
|
ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n",name);
|
||||||
|
WriteFile(file,name,strlen(name),&written,NULL);
|
||||||
|
CloseHandle(file);
|
||||||
|
shfo.hwnd = NULL;
|
||||||
|
shfo.wFunc = FO_DELETE;
|
||||||
|
shfo.pFrom = buf;
|
||||||
|
shfo.pTo = NULL;
|
||||||
|
shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT | FOF_ALLOWUNDO;
|
||||||
|
shfo.hNameMappings = NULL;
|
||||||
|
shfo.lpszProgressTitle = NULL;
|
||||||
|
ok(!pSHFileOperationA(&shfo), "Deletion was not successful\n");
|
||||||
|
hr = pSHQueryRecycleBinA(buf,&info2);
|
||||||
|
ok(hr == S_OK, "SHQueryRecycleBinW failed with error 0x%x\n", hr);
|
||||||
|
if(info2.i64Size!=info1.i64Size || info2.i64NumItems!=info1.i64NumItems) {
|
||||||
|
ok(info2.i64Size==info1.i64Size+written,"Expected recycle bin to have 0x%s bytes\n",str_from_int64(info1.i64Size+written));
|
||||||
|
ok(info2.i64NumItems==info1.i64NumItems+1,"Expected recycle bin to have 0x%s items\n",str_from_int64(info1.i64NumItems+1));
|
||||||
|
} else todo_wine {
|
||||||
|
ok(info2.i64Size==info1.i64Size+written,"Expected recycle bin to have 0x%s bytes\n",str_from_int64(info1.i64Size+written));
|
||||||
|
ok(info2.i64NumItems==info1.i64NumItems+1,"Expected recycle bin to have 0x%s items\n",str_from_int64(info1.i64NumItems+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST(recyclebin)
|
||||||
|
{
|
||||||
|
setup_pointers();
|
||||||
|
test_query_recyclebin();
|
||||||
|
}
|
|
@ -17,10 +17,16 @@
|
||||||
<library>ntdll</library>
|
<library>ntdll</library>
|
||||||
<file>appbar.c</file>
|
<file>appbar.c</file>
|
||||||
<file>autocomplete.c</file>
|
<file>autocomplete.c</file>
|
||||||
|
<file>brsfolder.c</file>
|
||||||
|
<file>ebrowser.c</file>
|
||||||
<file>generated.c</file>
|
<file>generated.c</file>
|
||||||
<file>progman_dde.c</file>
|
<file>progman_dde.c</file>
|
||||||
|
<file>recyclebin.c</file>
|
||||||
|
<file>shelldispatch.c</file>
|
||||||
<file>shelllink.c</file>
|
<file>shelllink.c</file>
|
||||||
|
<file>shellole.c</file>
|
||||||
<file>shellpath.c</file>
|
<file>shellpath.c</file>
|
||||||
|
<file>shfldr_special.c</file>
|
||||||
<file>shlexec.c</file>
|
<file>shlexec.c</file>
|
||||||
<file>shlfileop.c</file>
|
<file>shlfileop.c</file>
|
||||||
<file>shlfolder.c</file>
|
<file>shlfolder.c</file>
|
||||||
|
@ -28,7 +34,6 @@
|
||||||
<file>string.c</file>
|
<file>string.c</file>
|
||||||
<file>systray.c</file>
|
<file>systray.c</file>
|
||||||
<file>testlist.c</file>
|
<file>testlist.c</file>
|
||||||
<file>shfldr_special.c</file>
|
|
||||||
<file>rsrc.rc</file>
|
<file>rsrc.rc</file>
|
||||||
</module>
|
</module>
|
||||||
</group>
|
</group>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Unit test suite for shell32 functions
|
* Unit test suite for shell32 functions
|
||||||
*
|
*
|
||||||
* Copyright 2005 Francois Gougett for CodeWeavers
|
* Copyright 2005 Francois Gouget for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
319
rostests/winetests/shell32/shelldispatch.c
Normal file
319
rostests/winetests/shell32/shelldispatch.c
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
/*
|
||||||
|
* Unit tests for IShellDispatch
|
||||||
|
*
|
||||||
|
* Copyright 2010 Alexander Morozov for Etersoft
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
#define NONAMELESSUNION
|
||||||
|
#define NONAMELESSSTRUCT
|
||||||
|
|
||||||
|
#include "shldisp.h"
|
||||||
|
#include "shlobj.h"
|
||||||
|
#include "shlwapi.h"
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static HRESULT (WINAPI *pSHGetFolderPathW)(HWND, int, HANDLE, DWORD, LPWSTR);
|
||||||
|
static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*);
|
||||||
|
static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
|
||||||
|
static DWORD (WINAPI *pGetLongPathNameW)(LPCWSTR, LPWSTR, DWORD);
|
||||||
|
|
||||||
|
static void init_function_pointers(void)
|
||||||
|
{
|
||||||
|
HMODULE hshell32, hkernel32;
|
||||||
|
|
||||||
|
hshell32 = GetModuleHandleA("shell32.dll");
|
||||||
|
hkernel32 = GetModuleHandleA("kernel32.dll");
|
||||||
|
pSHGetFolderPathW = (void*)GetProcAddress(hshell32, "SHGetFolderPathW");
|
||||||
|
pSHGetNameFromIDList = (void*)GetProcAddress(hshell32, "SHGetNameFromIDList");
|
||||||
|
pSHGetSpecialFolderLocation = (void*)GetProcAddress(hshell32,
|
||||||
|
"SHGetSpecialFolderLocation");
|
||||||
|
pGetLongPathNameW = (void*)GetProcAddress(hkernel32, "GetLongPathNameW");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_namespace(void)
|
||||||
|
{
|
||||||
|
static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
|
||||||
|
static const WCHAR backslashW[] = {'\\',0};
|
||||||
|
static const WCHAR clsidW[] = {
|
||||||
|
':',':','{','6','4','5','F','F','0','4','0','-','5','0','8','1','-',
|
||||||
|
'1','0','1','B','-','9','F','0','8','-',
|
||||||
|
'0','0','A','A','0','0','2','F','9','5','4','E','}',0};
|
||||||
|
|
||||||
|
static WCHAR tempW[MAX_PATH], curW[MAX_PATH];
|
||||||
|
WCHAR *long_pathW = NULL;
|
||||||
|
HRESULT r;
|
||||||
|
IShellDispatch *sd;
|
||||||
|
Folder *folder;
|
||||||
|
Folder2 *folder2;
|
||||||
|
FolderItem *item;
|
||||||
|
VARIANT var;
|
||||||
|
BSTR title, item_path;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IShellDispatch, (LPVOID*)&sd);
|
||||||
|
if (r == REGDB_E_CLASSNOTREG) /* NT4 */
|
||||||
|
{
|
||||||
|
win_skip("skipping IShellDispatch tests\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r);
|
||||||
|
if (FAILED(r))
|
||||||
|
return;
|
||||||
|
|
||||||
|
VariantInit(&var);
|
||||||
|
folder = (void*)0xdeadbeef;
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
|
||||||
|
ok(folder == NULL, "expected NULL, got %p\n", folder);
|
||||||
|
|
||||||
|
V_VT(&var) = VT_I4;
|
||||||
|
V_I4(&var) = -1;
|
||||||
|
folder = (void*)0xdeadbeef;
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
todo_wine {
|
||||||
|
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
|
||||||
|
ok(folder == NULL, "got %p\n", folder);
|
||||||
|
}
|
||||||
|
V_VT(&var) = VT_I4;
|
||||||
|
V_I4(&var) = ssfPROGRAMFILES;
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
ok(r == S_OK ||
|
||||||
|
broken(r == S_FALSE), /* NT4 */
|
||||||
|
"IShellDispatch::NameSpace failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
static WCHAR path[MAX_PATH];
|
||||||
|
|
||||||
|
if (pSHGetFolderPathW)
|
||||||
|
{
|
||||||
|
r = pSHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL,
|
||||||
|
SHGFP_TYPE_CURRENT, path);
|
||||||
|
ok(r == S_OK, "SHGetFolderPath failed: %08x\n", r);
|
||||||
|
}
|
||||||
|
r = Folder_get_Title(folder, &title);
|
||||||
|
todo_wine
|
||||||
|
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
/* On Win2000-2003 title is equal to program files directory name in
|
||||||
|
HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir.
|
||||||
|
On newer Windows it seems constant and is not changed
|
||||||
|
if the program files directory name is changed */
|
||||||
|
if (pSHGetSpecialFolderLocation && pSHGetNameFromIDList)
|
||||||
|
{
|
||||||
|
LPITEMIDLIST pidl;
|
||||||
|
PWSTR name;
|
||||||
|
|
||||||
|
r = pSHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES, &pidl);
|
||||||
|
ok(r == S_OK, "SHGetSpecialFolderLocation failed: %08x\n", r);
|
||||||
|
r = pSHGetNameFromIDList(pidl, SIGDN_NORMALDISPLAY, &name);
|
||||||
|
ok(r == S_OK, "SHGetNameFromIDList failed: %08x\n", r);
|
||||||
|
todo_wine
|
||||||
|
ok(!lstrcmpW(title, name), "expected %s, got %s\n",
|
||||||
|
wine_dbgstr_w(name), wine_dbgstr_w(title));
|
||||||
|
CoTaskMemFree(name);
|
||||||
|
CoTaskMemFree(pidl);
|
||||||
|
}
|
||||||
|
else if (pSHGetFolderPathW)
|
||||||
|
{
|
||||||
|
WCHAR *p;
|
||||||
|
|
||||||
|
p = path + lstrlenW(path);
|
||||||
|
while (path < p && *(p - 1) != '\\')
|
||||||
|
p--;
|
||||||
|
ok(!lstrcmpW(title, p), "expected %s, got %s\n",
|
||||||
|
wine_dbgstr_w(p), wine_dbgstr_w(title));
|
||||||
|
}
|
||||||
|
else skip("skipping Folder::get_Title test\n");
|
||||||
|
SysFreeString(title);
|
||||||
|
}
|
||||||
|
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
|
||||||
|
ok(r == S_OK, "Folder::QueryInterface failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder2_get_Self(folder2, &item);
|
||||||
|
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = FolderItem_get_Path(item, &item_path);
|
||||||
|
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
|
||||||
|
if (pSHGetFolderPathW)
|
||||||
|
ok(!lstrcmpW(item_path, path), "expected %s, got %s\n",
|
||||||
|
wine_dbgstr_w(path), wine_dbgstr_w(item_path));
|
||||||
|
SysFreeString(item_path);
|
||||||
|
FolderItem_Release(item);
|
||||||
|
}
|
||||||
|
Folder2_Release(folder2);
|
||||||
|
}
|
||||||
|
Folder_Release(folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
V_VT(&var) = VT_I4;
|
||||||
|
V_I4(&var) = ssfBITBUCKET;
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
ok(r == S_OK ||
|
||||||
|
broken(r == S_FALSE), /* NT4 */
|
||||||
|
"IShellDispatch::NameSpace failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
|
||||||
|
ok(r == S_OK ||
|
||||||
|
broken(r == E_NOINTERFACE), /* NT4 */
|
||||||
|
"Folder::QueryInterface failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder2_get_Self(folder2, &item);
|
||||||
|
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = FolderItem_get_Path(item, &item_path);
|
||||||
|
todo_wine
|
||||||
|
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
|
||||||
|
todo_wine
|
||||||
|
ok(!lstrcmpW(item_path, clsidW), "expected %s, got %s\n",
|
||||||
|
wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
|
||||||
|
SysFreeString(item_path);
|
||||||
|
FolderItem_Release(item);
|
||||||
|
}
|
||||||
|
Folder2_Release(folder2);
|
||||||
|
}
|
||||||
|
Folder_Release(folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTempPathW(MAX_PATH, tempW);
|
||||||
|
GetCurrentDirectoryW(MAX_PATH, curW);
|
||||||
|
SetCurrentDirectoryW(tempW);
|
||||||
|
CreateDirectoryW(winetestW, NULL);
|
||||||
|
V_VT(&var) = VT_BSTR;
|
||||||
|
V_BSTR(&var) = SysAllocString(winetestW);
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
|
||||||
|
SysFreeString(V_BSTR(&var));
|
||||||
|
|
||||||
|
GetFullPathNameW(winetestW, MAX_PATH, tempW, NULL);
|
||||||
|
if (pGetLongPathNameW)
|
||||||
|
{
|
||||||
|
len = pGetLongPathNameW(tempW, NULL, 0);
|
||||||
|
long_pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
|
if (long_pathW)
|
||||||
|
pGetLongPathNameW(tempW, long_pathW, len);
|
||||||
|
}
|
||||||
|
V_VT(&var) = VT_BSTR;
|
||||||
|
V_BSTR(&var) = SysAllocString(tempW);
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder_get_Title(folder, &title);
|
||||||
|
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
ok(!lstrcmpW(title, winetestW), "bad title: %s\n",
|
||||||
|
wine_dbgstr_w(title));
|
||||||
|
SysFreeString(title);
|
||||||
|
}
|
||||||
|
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
|
||||||
|
ok(r == S_OK ||
|
||||||
|
broken(r == E_NOINTERFACE), /* NT4 */
|
||||||
|
"Folder::QueryInterface failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder2_get_Self(folder2, &item);
|
||||||
|
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = FolderItem_get_Path(item, &item_path);
|
||||||
|
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
|
||||||
|
if (long_pathW)
|
||||||
|
ok(!lstrcmpW(item_path, long_pathW),
|
||||||
|
"expected %s, got %s\n", wine_dbgstr_w(long_pathW),
|
||||||
|
wine_dbgstr_w(item_path));
|
||||||
|
SysFreeString(item_path);
|
||||||
|
FolderItem_Release(item);
|
||||||
|
}
|
||||||
|
Folder2_Release(folder2);
|
||||||
|
}
|
||||||
|
Folder_Release(folder);
|
||||||
|
}
|
||||||
|
SysFreeString(V_BSTR(&var));
|
||||||
|
|
||||||
|
len = lstrlenW(tempW);
|
||||||
|
if (len < MAX_PATH - 1)
|
||||||
|
{
|
||||||
|
lstrcatW(tempW, backslashW);
|
||||||
|
V_VT(&var) = VT_BSTR;
|
||||||
|
V_BSTR(&var) = SysAllocString(tempW);
|
||||||
|
r = IShellDispatch_NameSpace(sd, var, &folder);
|
||||||
|
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder_get_Title(folder, &title);
|
||||||
|
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
ok(!lstrcmpW(title, winetestW), "bad title: %s\n",
|
||||||
|
wine_dbgstr_w(title));
|
||||||
|
SysFreeString(title);
|
||||||
|
}
|
||||||
|
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
|
||||||
|
ok(r == S_OK ||
|
||||||
|
broken(r == E_NOINTERFACE), /* NT4 */
|
||||||
|
"Folder::QueryInterface failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = Folder2_get_Self(folder2, &item);
|
||||||
|
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
|
||||||
|
if (r == S_OK)
|
||||||
|
{
|
||||||
|
r = FolderItem_get_Path(item, &item_path);
|
||||||
|
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
|
||||||
|
if (long_pathW)
|
||||||
|
ok(!lstrcmpW(item_path, long_pathW),
|
||||||
|
"expected %s, got %s\n", wine_dbgstr_w(long_pathW),
|
||||||
|
wine_dbgstr_w(item_path));
|
||||||
|
SysFreeString(item_path);
|
||||||
|
FolderItem_Release(item);
|
||||||
|
}
|
||||||
|
Folder2_Release(folder2);
|
||||||
|
}
|
||||||
|
Folder_Release(folder);
|
||||||
|
}
|
||||||
|
SysFreeString(V_BSTR(&var));
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, long_pathW);
|
||||||
|
RemoveDirectoryW(winetestW);
|
||||||
|
SetCurrentDirectoryW(curW);
|
||||||
|
IShellDispatch_Release(sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(shelldispatch)
|
||||||
|
{
|
||||||
|
HRESULT r;
|
||||||
|
|
||||||
|
r = CoInitialize(NULL);
|
||||||
|
ok(SUCCEEDED(r), "CoInitialize failed: %08x\n", r);
|
||||||
|
if (FAILED(r))
|
||||||
|
return;
|
||||||
|
|
||||||
|
init_function_pointers();
|
||||||
|
test_namespace();
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
|
@ -168,15 +168,15 @@ static void test_get_set(void)
|
||||||
|
|
||||||
CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||||
&IID_IShellLinkW, (LPVOID*)&slW);
|
&IID_IShellLinkW, (LPVOID*)&slW);
|
||||||
if (!slW)
|
if (!slW /* Win9x */ || !pGetLongPathNameA /* NT4 */)
|
||||||
skip("SetPath with NULL parameter crashes on Win9x\n");
|
skip("SetPath with NULL parameter crashes on Win9x and some NT4\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IShellLinkW_Release(slW);
|
IShellLinkW_Release(slW);
|
||||||
r = IShellLinkA_SetPath(sl, NULL);
|
r = IShellLinkA_SetPath(sl, NULL);
|
||||||
ok(r==E_INVALIDARG ||
|
ok(r==E_INVALIDARG ||
|
||||||
broken(r==S_OK), /* Some Win95 and NT4 */
|
broken(r==S_OK), /* Some Win95 and NT4 */
|
||||||
"SetPath failed (0x%08x)\n", r);
|
"SetPath returned wrong error (0x%08x)\n", r);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = IShellLinkA_SetPath(sl, "");
|
r = IShellLinkA_SetPath(sl, "");
|
||||||
|
@ -204,16 +204,14 @@ static void test_get_set(void)
|
||||||
/* Test the interaction of SetPath and SetIDList */
|
/* Test the interaction of SetPath and SetIDList */
|
||||||
tmp_pidl=NULL;
|
tmp_pidl=NULL;
|
||||||
r = IShellLinkA_GetIDList(sl, &tmp_pidl);
|
r = IShellLinkA_GetIDList(sl, &tmp_pidl);
|
||||||
todo_wine ok(r == S_OK, "GetIDList failed (0x%08x)\n", r);
|
ok(r == S_OK, "GetIDList failed (0x%08x)\n", r);
|
||||||
if (r == S_OK)
|
if (r == S_OK)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
strcpy(buffer,"garbage");
|
strcpy(buffer,"garbage");
|
||||||
ret = SHGetPathFromIDListA(tmp_pidl, buffer);
|
ret = SHGetPathFromIDListA(tmp_pidl, buffer);
|
||||||
todo_wine {
|
|
||||||
ok(ret, "SHGetPathFromIDListA failed\n");
|
ok(ret, "SHGetPathFromIDListA failed\n");
|
||||||
}
|
|
||||||
if (ret)
|
if (ret)
|
||||||
ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
|
ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
|
||||||
pILFree(tmp_pidl);
|
pILFree(tmp_pidl);
|
||||||
|
@ -326,9 +324,7 @@ static void test_get_set(void)
|
||||||
i=0xdeadbeef;
|
i=0xdeadbeef;
|
||||||
strcpy(buffer,"garbage");
|
strcpy(buffer,"garbage");
|
||||||
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
||||||
todo_wine {
|
|
||||||
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
|
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
|
||||||
}
|
|
||||||
ok(*buffer=='\0', "GetIconLocation returned '%s'\n", buffer);
|
ok(*buffer=='\0', "GetIconLocation returned '%s'\n", buffer);
|
||||||
ok(i==0, "GetIconLocation returned %d\n", i);
|
ok(i==0, "GetIconLocation returned %d\n", i);
|
||||||
|
|
||||||
|
@ -435,7 +431,7 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* crashes on XP */
|
/* crashes on XP */
|
||||||
r = IPersistFile_GetCurFile(pf, NULL);
|
IPersistFile_GetCurFile(pf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test GetCurFile before ::Save */
|
/* test GetCurFile before ::Save */
|
||||||
|
@ -685,6 +681,24 @@ static void test_load_save(void)
|
||||||
create_lnk(lnkfile, &desc, 0);
|
create_lnk(lnkfile, &desc, 0);
|
||||||
check_lnk(lnkfile, &desc, 0x0);
|
check_lnk(lnkfile, &desc, 0x0);
|
||||||
|
|
||||||
|
/* Test omitting .exe from an absolute path */
|
||||||
|
p=strrchr(realpath, '.');
|
||||||
|
if (p)
|
||||||
|
*p='\0';
|
||||||
|
|
||||||
|
desc.description="absolute path without .exe";
|
||||||
|
desc.workdir=mydir;
|
||||||
|
desc.path=realpath;
|
||||||
|
desc.pidl=NULL;
|
||||||
|
desc.arguments="/option1 /option2 \"Some string\"";
|
||||||
|
desc.showcmd=SW_SHOWNORMAL;
|
||||||
|
desc.icon=mypath;
|
||||||
|
desc.icon_id=0;
|
||||||
|
desc.hotkey=0x1234;
|
||||||
|
create_lnk(lnkfile, &desc, 0);
|
||||||
|
strcat(realpath, ".exe");
|
||||||
|
check_lnk(lnkfile, &desc, 0x4);
|
||||||
|
|
||||||
/* Overwrite the existing lnk file and test link to a command on the path */
|
/* Overwrite the existing lnk file and test link to a command on the path */
|
||||||
desc.description="command on path";
|
desc.description="command on path";
|
||||||
desc.workdir=mypath;
|
desc.workdir=mypath;
|
||||||
|
@ -701,6 +715,22 @@ static void test_load_save(void)
|
||||||
desc.path=realpath;
|
desc.path=realpath;
|
||||||
check_lnk(lnkfile, &desc, 0x0);
|
check_lnk(lnkfile, &desc, 0x0);
|
||||||
|
|
||||||
|
/* Test omitting .exe from a command on the path */
|
||||||
|
desc.description="command on path without .exe";
|
||||||
|
desc.workdir=mypath;
|
||||||
|
desc.path="rundll32";
|
||||||
|
desc.pidl=NULL;
|
||||||
|
desc.arguments="/option1 /option2 \"Some string\"";
|
||||||
|
desc.showcmd=SW_SHOWNORMAL;
|
||||||
|
desc.icon=mypath;
|
||||||
|
desc.icon_id=0;
|
||||||
|
desc.hotkey=0x1234;
|
||||||
|
create_lnk(lnkfile, &desc, 0);
|
||||||
|
/* Check that link is created to proper location */
|
||||||
|
SearchPathA( NULL, "rundll32", NULL, MAX_PATH, realpath, NULL);
|
||||||
|
desc.path=realpath;
|
||||||
|
check_lnk(lnkfile, &desc, 0x4);
|
||||||
|
|
||||||
/* Create a temporary non-executable file */
|
/* Create a temporary non-executable file */
|
||||||
r=GetTempPath(sizeof(mypath), mypath);
|
r=GetTempPath(sizeof(mypath), mypath);
|
||||||
ok(r<sizeof(mypath), "GetTempPath failed (%d), err %d\n", r, GetLastError());
|
ok(r<sizeof(mypath), "GetTempPath failed (%d), err %d\n", r, GetLastError());
|
||||||
|
@ -730,6 +760,8 @@ static void test_load_save(void)
|
||||||
check_lnk(lnkfile, &desc, 0x0);
|
check_lnk(lnkfile, &desc, 0x0);
|
||||||
|
|
||||||
r=pGetShortPathNameA(mydir, mypath, sizeof(mypath));
|
r=pGetShortPathNameA(mydir, mypath, sizeof(mypath));
|
||||||
|
ok(r<sizeof(mypath), "GetShortPathName failed (%d), err %d\n", r, GetLastError());
|
||||||
|
|
||||||
strcpy(realpath, mypath);
|
strcpy(realpath, mypath);
|
||||||
strcat(realpath, "\\test.txt");
|
strcat(realpath, "\\test.txt");
|
||||||
strcat(mypath, "\\\\test.txt");
|
strcat(mypath, "\\\\test.txt");
|
||||||
|
@ -751,6 +783,36 @@ static void test_load_save(void)
|
||||||
r = DeleteFileA(mypath);
|
r = DeleteFileA(mypath);
|
||||||
ok(r, "failed to delete file %s (%d)\n", mypath, GetLastError());
|
ok(r, "failed to delete file %s (%d)\n", mypath, GetLastError());
|
||||||
|
|
||||||
|
/* Create a temporary .bat file */
|
||||||
|
strcpy(mypath, mydir);
|
||||||
|
strcat(mypath, "\\test.bat");
|
||||||
|
hf = CreateFile(mypath, GENERIC_WRITE, 0, NULL,
|
||||||
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
CloseHandle(hf);
|
||||||
|
|
||||||
|
strcpy(realpath, mypath);
|
||||||
|
|
||||||
|
p=strrchr(mypath, '.');
|
||||||
|
if (p)
|
||||||
|
*p='\0';
|
||||||
|
|
||||||
|
/* Try linking to the .bat file without the extension */
|
||||||
|
desc.description="batch file";
|
||||||
|
desc.workdir=mydir;
|
||||||
|
desc.path=mypath;
|
||||||
|
desc.pidl=NULL;
|
||||||
|
desc.arguments="";
|
||||||
|
desc.showcmd=SW_SHOWNORMAL;
|
||||||
|
desc.icon=mypath;
|
||||||
|
desc.icon_id=0;
|
||||||
|
desc.hotkey=0x1234;
|
||||||
|
create_lnk(lnkfile, &desc, 0);
|
||||||
|
desc.path = realpath;
|
||||||
|
check_lnk(lnkfile, &desc, 0x4);
|
||||||
|
|
||||||
|
r = DeleteFileA(realpath);
|
||||||
|
ok(r, "failed to delete file %s (%d)\n", realpath, GetLastError());
|
||||||
|
|
||||||
/* FIXME: Also test saving a .lnk pointing to a pidl that cannot be
|
/* FIXME: Also test saving a .lnk pointing to a pidl that cannot be
|
||||||
* represented as a path.
|
* represented as a path.
|
||||||
*/
|
*/
|
||||||
|
@ -812,16 +874,21 @@ static void test_datalink(void)
|
||||||
ok( r == E_FAIL, "CopyDataBlock failed\n");
|
ok( r == E_FAIL, "CopyDataBlock failed\n");
|
||||||
ok( dar == NULL, "should be null\n");
|
ok( dar == NULL, "should be null\n");
|
||||||
|
|
||||||
r = IShellLinkW_SetPath(sl, NULL);
|
if (!pGetLongPathNameA /* NT4 */)
|
||||||
ok(r == E_INVALIDARG, "set path failed\n");
|
skip("SetPath with NULL parameter crashes on NT4\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = IShellLinkW_SetPath(sl, NULL);
|
||||||
|
ok(r == E_INVALIDARG, "SetPath returned wrong error (0x%08x)\n", r);
|
||||||
|
}
|
||||||
|
|
||||||
r = IShellLinkW_SetPath(sl, lnk);
|
r = IShellLinkW_SetPath(sl, lnk);
|
||||||
ok(r == S_OK, "set path failed\n");
|
ok(r == S_OK, "SetPath failed\n");
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* the following crashes */
|
/* the following crashes */
|
||||||
r = IShellLinkDataList_GetFlags( dl, NULL );
|
IShellLinkDataList_GetFlags( dl, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
@ -872,6 +939,66 @@ static void test_shdefextracticon(void)
|
||||||
ok(SUCCEEDED(res), "SHDefExtractIconA failed, res=%x\n", res);
|
ok(SUCCEEDED(res), "SHDefExtractIconA failed, res=%x\n", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_GetIconLocation(void)
|
||||||
|
{
|
||||||
|
IShellLinkA *sl;
|
||||||
|
const char *str;
|
||||||
|
char buffer[INFOTIPSIZE], mypath[MAX_PATH];
|
||||||
|
int i;
|
||||||
|
HRESULT r;
|
||||||
|
LPITEMIDLIST pidl;
|
||||||
|
|
||||||
|
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IShellLinkA, (LPVOID*)&sl);
|
||||||
|
ok(r == S_OK, "no IID_IShellLinkA (0x%08x)\n", r);
|
||||||
|
if(r != S_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
i = 0xdeadbeef;
|
||||||
|
strcpy(buffer, "garbage");
|
||||||
|
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
||||||
|
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
|
||||||
|
ok(*buffer == '\0', "GetIconLocation returned '%s'\n", buffer);
|
||||||
|
ok(i == 0, "GetIconLocation returned %d\n", i);
|
||||||
|
|
||||||
|
str = "c:\\some\\path";
|
||||||
|
r = IShellLinkA_SetPath(sl, str);
|
||||||
|
ok(r == S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||||
|
|
||||||
|
i = 0xdeadbeef;
|
||||||
|
strcpy(buffer, "garbage");
|
||||||
|
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
||||||
|
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
|
||||||
|
ok(*buffer == '\0', "GetIconLocation returned '%s'\n", buffer);
|
||||||
|
ok(i == 0, "GetIconLocation returned %d\n", i);
|
||||||
|
|
||||||
|
GetWindowsDirectoryA(mypath, sizeof(mypath) - 12);
|
||||||
|
strcat(mypath, "\\regedit.exe");
|
||||||
|
pidl = path_to_pidl(mypath);
|
||||||
|
r = IShellLinkA_SetIDList(sl, pidl);
|
||||||
|
ok(r == S_OK, "SetPath failed (0x%08x)\n", r);
|
||||||
|
pILFree(pidl);
|
||||||
|
|
||||||
|
i = 0xdeadbeef;
|
||||||
|
strcpy(buffer, "garbage");
|
||||||
|
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
||||||
|
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
|
||||||
|
ok(*buffer == '\0', "GetIconLocation returned '%s'\n", buffer);
|
||||||
|
ok(i == 0, "GetIconLocation returned %d\n", i);
|
||||||
|
|
||||||
|
str = "c:\\nonexistent\\file";
|
||||||
|
r = IShellLinkA_SetIconLocation(sl, str, 0xbabecafe);
|
||||||
|
ok(r == S_OK, "SetIconLocation failed (0x%08x)\n", r);
|
||||||
|
|
||||||
|
i = 0xdeadbeef;
|
||||||
|
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
||||||
|
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
|
||||||
|
ok(lstrcmpi(buffer,str) == 0, "GetIconLocation returned '%s'\n", buffer);
|
||||||
|
ok(i == 0xbabecafe, "GetIconLocation returned %d'\n", i);
|
||||||
|
|
||||||
|
IShellLinkA_Release(sl);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(shelllink)
|
START_TEST(shelllink)
|
||||||
{
|
{
|
||||||
HRESULT r;
|
HRESULT r;
|
||||||
|
@ -895,6 +1022,7 @@ START_TEST(shelllink)
|
||||||
test_load_save();
|
test_load_save();
|
||||||
test_datalink();
|
test_datalink();
|
||||||
test_shdefextracticon();
|
test_shdefextracticon();
|
||||||
|
test_GetIconLocation();
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
437
rostests/winetests/shell32/shellole.c
Normal file
437
rostests/winetests/shell32/shellole.c
Normal file
|
@ -0,0 +1,437 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 Piotr Caban 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
#define CONST_VTABLE
|
||||||
|
#define NONAMELESSUNION
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wine/test.h>
|
||||||
|
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "shlobj.h"
|
||||||
|
#include "initguid.h"
|
||||||
|
|
||||||
|
DEFINE_GUID(FMTID_Test,0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12);
|
||||||
|
DEFINE_GUID(FMTID_NotExisting, 0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13);
|
||||||
|
|
||||||
|
#define DEFINE_EXPECT(func) \
|
||||||
|
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
|
||||||
|
|
||||||
|
#define SET_EXPECT(func) \
|
||||||
|
expect_ ## func = TRUE
|
||||||
|
|
||||||
|
#define CHECK_EXPECT2(func) \
|
||||||
|
do { \
|
||||||
|
ok(expect_ ##func, "unexpected call " #func "\n"); \
|
||||||
|
called_ ## func = TRUE; \
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
#define CHECK_EXPECT(func) \
|
||||||
|
do { \
|
||||||
|
CHECK_EXPECT2(func); \
|
||||||
|
expect_ ## func = FALSE; \
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
#define CHECK_CALLED(func) \
|
||||||
|
do { \
|
||||||
|
ok(called_ ## func, "expected " #func "\n"); \
|
||||||
|
expect_ ## func = called_ ## func = FALSE; \
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
DEFINE_EXPECT(Create);
|
||||||
|
DEFINE_EXPECT(Delete);
|
||||||
|
DEFINE_EXPECT(Open);
|
||||||
|
DEFINE_EXPECT(ReadMultiple);
|
||||||
|
DEFINE_EXPECT(ReadMultipleCodePage);
|
||||||
|
DEFINE_EXPECT(Release);
|
||||||
|
DEFINE_EXPECT(Stat);
|
||||||
|
DEFINE_EXPECT(WriteMultiple);
|
||||||
|
|
||||||
|
static HRESULT (WINAPI *pSHPropStgCreate)(IPropertySetStorage*, REFFMTID, const CLSID*,
|
||||||
|
DWORD, DWORD, DWORD, IPropertyStorage**, UINT*);
|
||||||
|
static HRESULT (WINAPI *pSHPropStgReadMultiple)(IPropertyStorage*, UINT,
|
||||||
|
ULONG, const PROPSPEC*, PROPVARIANT*);
|
||||||
|
static HRESULT (WINAPI *pSHPropStgWriteMultiple)(IPropertyStorage*, UINT*,
|
||||||
|
ULONG, const PROPSPEC*, PROPVARIANT*, PROPID);
|
||||||
|
|
||||||
|
static void init(void)
|
||||||
|
{
|
||||||
|
HMODULE hmod = GetModuleHandleA("shell32.dll");
|
||||||
|
|
||||||
|
pSHPropStgCreate = (void*)GetProcAddress(hmod, "SHPropStgCreate");
|
||||||
|
pSHPropStgReadMultiple = (void*)GetProcAddress(hmod, "SHPropStgReadMultiple");
|
||||||
|
pSHPropStgWriteMultiple = (void*)GetProcAddress(hmod, "SHPropStgWriteMultiple");
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_QueryInterface(IPropertyStorage *This,
|
||||||
|
REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI PropertyStorage_AddRef(IPropertyStorage *This)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI PropertyStorage_Release(IPropertyStorage *This)
|
||||||
|
{
|
||||||
|
CHECK_EXPECT(Release);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_ReadMultiple(IPropertyStorage *This, ULONG cpspec,
|
||||||
|
const PROPSPEC *rgpspec, PROPVARIANT *rgpropvar)
|
||||||
|
{
|
||||||
|
if(cpspec == 1) {
|
||||||
|
CHECK_EXPECT(ReadMultipleCodePage);
|
||||||
|
|
||||||
|
ok(rgpspec != NULL, "rgpspec = NULL\n");
|
||||||
|
ok(rgpropvar != NULL, "rgpropvar = NULL\n");
|
||||||
|
|
||||||
|
ok(rgpspec[0].ulKind == PRSPEC_PROPID, "rgpspec[0].ulKind = %d\n", rgpspec[0].ulKind);
|
||||||
|
ok(rgpspec[0].u.propid == PID_CODEPAGE, "rgpspec[0].propid = %d\n", rgpspec[0].u.propid);
|
||||||
|
|
||||||
|
rgpropvar[0].vt = VT_I2;
|
||||||
|
rgpropvar[0].u.iVal = 1234;
|
||||||
|
} else {
|
||||||
|
CHECK_EXPECT(ReadMultiple);
|
||||||
|
|
||||||
|
ok(cpspec == 10, "cpspec = %u\n", cpspec);
|
||||||
|
ok(rgpspec == (void*)0xdeadbeef, "rgpspec = %p\n", rgpspec);
|
||||||
|
ok(rgpropvar != NULL, "rgpropvar = NULL\n");
|
||||||
|
|
||||||
|
ok(rgpropvar[0].vt==0 || broken(rgpropvar[0].vt==VT_BSTR), "rgpropvar[0].vt = %d\n", rgpropvar[0].vt);
|
||||||
|
|
||||||
|
rgpropvar[0].vt = VT_BSTR;
|
||||||
|
rgpropvar[0].u.bstrVal = (void*)0xdeadbeef;
|
||||||
|
rgpropvar[1].vt = VT_LPSTR;
|
||||||
|
rgpropvar[1].u.pszVal = (void*)0xdeadbeef;
|
||||||
|
rgpropvar[2].vt = VT_BYREF|VT_I1;
|
||||||
|
rgpropvar[2].u.pcVal = (void*)0xdeadbeef;
|
||||||
|
rgpropvar[3].vt = VT_BYREF|VT_VARIANT;
|
||||||
|
rgpropvar[3].u.pvarVal = (void*)0xdeadbeef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_WriteMultiple(IPropertyStorage *This, ULONG cpspec,
|
||||||
|
const PROPSPEC *rgpspec, const PROPVARIANT *rgpropvar,
|
||||||
|
PROPID propidNameFirst)
|
||||||
|
{
|
||||||
|
CHECK_EXPECT(WriteMultiple);
|
||||||
|
|
||||||
|
ok(cpspec == 20, "cpspec = %d\n", cpspec);
|
||||||
|
ok(rgpspec == (void*)0xdeadbeef, "rgpspec = %p\n", rgpspec);
|
||||||
|
ok(rgpropvar == (void*)0xdeadbeef, "rgpropvar = %p\n", rgpspec);
|
||||||
|
ok(propidNameFirst == PID_FIRST_USABLE, "propidNameFirst = %d\n", propidNameFirst);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_DeleteMultiple(IPropertyStorage *This, ULONG cpspec,
|
||||||
|
const PROPSPEC *rgpspec)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_ReadPropertyNames(IPropertyStorage *This, ULONG cpropid,
|
||||||
|
const PROPID *rgpropid, LPOLESTR *rglpwstrName)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_WritePropertyNames(IPropertyStorage *This, ULONG cpropid,
|
||||||
|
const PROPID *rgpropid, const LPOLESTR *rglpwstrName)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_DeletePropertyNames(IPropertyStorage *This, ULONG cpropid,
|
||||||
|
const PROPID *rgpropid)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_Commit(IPropertyStorage *This, DWORD grfCommitFlags)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_Revert(IPropertyStorage *This)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_Enum(IPropertyStorage *This, IEnumSTATPROPSTG **ppenum)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_SetTimes(IPropertyStorage *This, const FILETIME *pctime,
|
||||||
|
const FILETIME *patime, const FILETIME *pmtime)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_SetClass(IPropertyStorage *This, REFCLSID clsid)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertyStorage_Stat(IPropertyStorage *This, STATPROPSETSTG *statpsstg)
|
||||||
|
{
|
||||||
|
CHECK_EXPECT(Stat);
|
||||||
|
|
||||||
|
memset(statpsstg, 0, sizeof(STATPROPSETSTG));
|
||||||
|
memcpy(&statpsstg->fmtid, &FMTID_Test, sizeof(FMTID));
|
||||||
|
statpsstg->grfFlags = PROPSETFLAG_ANSI;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IPropertyStorageVtbl PropertyStorageVtbl = {
|
||||||
|
PropertyStorage_QueryInterface,
|
||||||
|
PropertyStorage_AddRef,
|
||||||
|
PropertyStorage_Release,
|
||||||
|
PropertyStorage_ReadMultiple,
|
||||||
|
PropertyStorage_WriteMultiple,
|
||||||
|
PropertyStorage_DeleteMultiple,
|
||||||
|
PropertyStorage_ReadPropertyNames,
|
||||||
|
PropertyStorage_WritePropertyNames,
|
||||||
|
PropertyStorage_DeletePropertyNames,
|
||||||
|
PropertyStorage_Commit,
|
||||||
|
PropertyStorage_Revert,
|
||||||
|
PropertyStorage_Enum,
|
||||||
|
PropertyStorage_SetTimes,
|
||||||
|
PropertyStorage_SetClass,
|
||||||
|
PropertyStorage_Stat
|
||||||
|
};
|
||||||
|
|
||||||
|
static IPropertyStorage PropertyStorage = { &PropertyStorageVtbl };
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertySetStorage_QueryInterface(IPropertySetStorage *This,
|
||||||
|
REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI PropertySetStorage_AddRef(IPropertySetStorage *This)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI PropertySetStorage_Release(IPropertySetStorage *This)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertySetStorage_Create(IPropertySetStorage *This,
|
||||||
|
REFFMTID rfmtid, const CLSID *pclsid, DWORD grfFlags,
|
||||||
|
DWORD grfMode, IPropertyStorage **ppprstg)
|
||||||
|
{
|
||||||
|
CHECK_EXPECT(Create);
|
||||||
|
ok(IsEqualGUID(rfmtid, &FMTID_Test) || IsEqualGUID(rfmtid, &FMTID_NotExisting),
|
||||||
|
"Incorrect rfmtid value\n");
|
||||||
|
ok(pclsid == NULL, "pclsid != NULL\n");
|
||||||
|
ok(grfFlags == PROPSETFLAG_ANSI, "grfFlags = %x\n", grfFlags);
|
||||||
|
ok(grfMode == STGM_READ, "grfMode = %x\n", grfMode);
|
||||||
|
|
||||||
|
*ppprstg = &PropertyStorage;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertySetStorage_Open(IPropertySetStorage *This,
|
||||||
|
REFFMTID rfmtid, DWORD grfMode, IPropertyStorage **ppprstg)
|
||||||
|
{
|
||||||
|
CHECK_EXPECT(Open);
|
||||||
|
|
||||||
|
if(IsEqualGUID(rfmtid, &FMTID_Test)) {
|
||||||
|
ok(grfMode == STGM_READ, "grfMode = %x\n", grfMode);
|
||||||
|
|
||||||
|
*ppprstg = &PropertyStorage;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STG_E_FILENOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertySetStorage_Delete(IPropertySetStorage *This,
|
||||||
|
REFFMTID rfmtid)
|
||||||
|
{
|
||||||
|
CHECK_EXPECT(Delete);
|
||||||
|
ok(IsEqualGUID(rfmtid, &FMTID_Test), "wrong rfmtid value\n");
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI PropertySetStorage_Enum(IPropertySetStorage *This,
|
||||||
|
IEnumSTATPROPSETSTG **ppenum)
|
||||||
|
{
|
||||||
|
ok(0, "unexpected call\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IPropertySetStorageVtbl PropertySetStorageVtbl = {
|
||||||
|
PropertySetStorage_QueryInterface,
|
||||||
|
PropertySetStorage_AddRef,
|
||||||
|
PropertySetStorage_Release,
|
||||||
|
PropertySetStorage_Create,
|
||||||
|
PropertySetStorage_Open,
|
||||||
|
PropertySetStorage_Delete,
|
||||||
|
PropertySetStorage_Enum
|
||||||
|
};
|
||||||
|
|
||||||
|
static IPropertySetStorage PropertySetStorage = { &PropertySetStorageVtbl };
|
||||||
|
|
||||||
|
static void test_SHPropStg_functions(void)
|
||||||
|
{
|
||||||
|
IPropertyStorage *property_storage;
|
||||||
|
UINT codepage;
|
||||||
|
PROPVARIANT read[10];
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
if(!pSHPropStgCreate || !pSHPropStgReadMultiple || !pSHPropStgWriteMultiple) {
|
||||||
|
win_skip("SHPropStg* functions are missing\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0) {
|
||||||
|
/* Crashes on Windows */
|
||||||
|
pSHPropStgCreate(NULL, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT,
|
||||||
|
STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
|
||||||
|
pSHPropStgCreate(&PropertySetStorage, NULL, NULL, PROPSETFLAG_DEFAULT,
|
||||||
|
STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
|
||||||
|
pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT,
|
||||||
|
STGM_READ, OPEN_EXISTING, NULL, &codepage);
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_EXPECT(Open);
|
||||||
|
SET_EXPECT(ReadMultipleCodePage);
|
||||||
|
hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_DEFAULT,
|
||||||
|
STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
|
||||||
|
ok(codepage == 1234, "codepage = %d\n", codepage);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(Open);
|
||||||
|
CHECK_CALLED(ReadMultipleCodePage);
|
||||||
|
|
||||||
|
SET_EXPECT(Open);
|
||||||
|
hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_NotExisting, NULL,
|
||||||
|
PROPSETFLAG_DEFAULT, STGM_READ, OPEN_EXISTING, &property_storage, &codepage);
|
||||||
|
ok(hres == STG_E_FILENOTFOUND, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(Open);
|
||||||
|
|
||||||
|
SET_EXPECT(Open);
|
||||||
|
SET_EXPECT(Release);
|
||||||
|
SET_EXPECT(Delete);
|
||||||
|
SET_EXPECT(Create);
|
||||||
|
SET_EXPECT(ReadMultipleCodePage);
|
||||||
|
hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, NULL, PROPSETFLAG_ANSI,
|
||||||
|
STGM_READ, CREATE_ALWAYS, &property_storage, &codepage);
|
||||||
|
ok(codepage == 1234, "codepage = %d\n", codepage);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(Open);
|
||||||
|
CHECK_CALLED(Release);
|
||||||
|
CHECK_CALLED(Delete);
|
||||||
|
CHECK_CALLED(Create);
|
||||||
|
CHECK_CALLED(ReadMultipleCodePage);
|
||||||
|
|
||||||
|
SET_EXPECT(Open);
|
||||||
|
SET_EXPECT(Create);
|
||||||
|
SET_EXPECT(ReadMultipleCodePage);
|
||||||
|
hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_NotExisting, NULL, PROPSETFLAG_ANSI,
|
||||||
|
STGM_READ, CREATE_ALWAYS, &property_storage, &codepage);
|
||||||
|
ok(codepage == 1234, "codepage = %d\n", codepage);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(Open);
|
||||||
|
CHECK_CALLED(Create);
|
||||||
|
CHECK_CALLED(ReadMultipleCodePage);
|
||||||
|
|
||||||
|
SET_EXPECT(Open);
|
||||||
|
hres = pSHPropStgCreate(&PropertySetStorage, &FMTID_Test, &FMTID_NotExisting,
|
||||||
|
PROPSETFLAG_DEFAULT, STGM_READ, OPEN_EXISTING, &property_storage, NULL);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(Open);
|
||||||
|
|
||||||
|
SET_EXPECT(Stat);
|
||||||
|
SET_EXPECT(ReadMultipleCodePage);
|
||||||
|
SET_EXPECT(WriteMultiple);
|
||||||
|
codepage = 0;
|
||||||
|
hres = pSHPropStgWriteMultiple(property_storage, &codepage, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
ok(codepage == 1234, "codepage = %d\n", codepage);
|
||||||
|
CHECK_CALLED(Stat);
|
||||||
|
CHECK_CALLED(ReadMultipleCodePage);
|
||||||
|
CHECK_CALLED(WriteMultiple);
|
||||||
|
|
||||||
|
SET_EXPECT(Stat);
|
||||||
|
SET_EXPECT(ReadMultipleCodePage);
|
||||||
|
SET_EXPECT(WriteMultiple);
|
||||||
|
hres = pSHPropStgWriteMultiple(property_storage, NULL, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(Stat);
|
||||||
|
CHECK_CALLED(ReadMultipleCodePage);
|
||||||
|
CHECK_CALLED(WriteMultiple);
|
||||||
|
|
||||||
|
SET_EXPECT(Stat);
|
||||||
|
SET_EXPECT(WriteMultiple);
|
||||||
|
codepage = 1000;
|
||||||
|
hres = pSHPropStgWriteMultiple(property_storage, &codepage, 20, (void*)0xdeadbeef, (void*)0xdeadbeef, PID_FIRST_USABLE);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
ok(codepage == 1000, "codepage = %d\n", codepage);
|
||||||
|
CHECK_CALLED(Stat);
|
||||||
|
CHECK_CALLED(WriteMultiple);
|
||||||
|
|
||||||
|
read[0].vt = VT_BSTR;
|
||||||
|
read[0].u.bstrVal = (void*)0xdeadbeef;
|
||||||
|
SET_EXPECT(ReadMultiple);
|
||||||
|
SET_EXPECT(ReadMultipleCodePage);
|
||||||
|
SET_EXPECT(Stat);
|
||||||
|
hres = pSHPropStgReadMultiple(property_storage, 0, 10, (void*)0xdeadbeef, read);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(ReadMultiple);
|
||||||
|
CHECK_CALLED(ReadMultipleCodePage);
|
||||||
|
CHECK_CALLED(Stat);
|
||||||
|
|
||||||
|
SET_EXPECT(ReadMultiple);
|
||||||
|
SET_EXPECT(Stat);
|
||||||
|
hres = pSHPropStgReadMultiple(property_storage, 1251, 10, (void*)0xdeadbeef, read);
|
||||||
|
ok(hres == S_OK, "hres = %x\n", hres);
|
||||||
|
CHECK_CALLED(ReadMultiple);
|
||||||
|
CHECK_CALLED(Stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(shellole)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
test_SHPropStg_functions();
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -150,9 +150,9 @@ static void test_printers_folder(void)
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* crashes on XP */
|
/* crashes on XP */
|
||||||
hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, NULL);
|
IShellFolder2_GetDetailsOf(folder, NULL, 0, NULL);
|
||||||
hr = IShellFolder2_GetDefaultColumnState(folder, 0, NULL);
|
IShellFolder2_GetDefaultColumnState(folder, 0, NULL);
|
||||||
hr = IPersistFolder2_GetCurFolder(pf, NULL);
|
IPersistFolder2_GetCurFolder(pf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 5 columns defined */
|
/* 5 columns defined */
|
||||||
|
@ -162,8 +162,11 @@ if (0)
|
||||||
hr = IShellFolder2_GetDefaultColumnState(folder, 6, &state);
|
hr = IShellFolder2_GetDefaultColumnState(folder, 6, &state);
|
||||||
ok(broken(hr == E_NOTIMPL) || hr == E_INVALIDARG /* Win7 */, "got 0x%08x\n", hr);
|
ok(broken(hr == E_NOTIMPL) || hr == E_INVALIDARG /* Win7 */, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
details.str.u.pOleStr = NULL;
|
||||||
hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, &details);
|
hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, &details);
|
||||||
ok(hr == S_OK || broken(E_NOTIMPL) /* W2K */, "got 0x%08x\n", hr);
|
ok(hr == S_OK || broken(E_NOTIMPL) /* W2K */, "got 0x%08x\n", hr);
|
||||||
|
if (SHELL_OsIsUnicode()) SHFree(details.str.u.pOleStr);
|
||||||
|
|
||||||
/* test every column if method is implemented */
|
/* test every column if method is implemented */
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,7 @@ static char tmpdir[MAX_PATH];
|
||||||
static char child_file[MAX_PATH];
|
static char child_file[MAX_PATH];
|
||||||
static DLLVERSIONINFO dllver;
|
static DLLVERSIONINFO dllver;
|
||||||
static BOOL skip_noassoc_tests = FALSE;
|
static BOOL skip_noassoc_tests = FALSE;
|
||||||
|
static HANDLE dde_ready_event;
|
||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -526,7 +527,7 @@ static void CALLBACK childTimeout(HWND wnd, UINT msg, UINT_PTR timer, DWORD time
|
||||||
|
|
||||||
static void doChild(int argc, char** argv)
|
static void doChild(int argc, char** argv)
|
||||||
{
|
{
|
||||||
char* filename;
|
char *filename, longpath[MAX_PATH] = "";
|
||||||
HANDLE hFile, map;
|
HANDLE hFile, map;
|
||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -552,6 +553,8 @@ static void doChild(int argc, char** argv)
|
||||||
trace("argvA%d=%s\n", i, argv[i]);
|
trace("argvA%d=%s\n", i, argv[i]);
|
||||||
childPrintf(hFile, "argvA%d=%s\r\n", i, encodeA(argv[i]));
|
childPrintf(hFile, "argvA%d=%s\r\n", i, encodeA(argv[i]));
|
||||||
}
|
}
|
||||||
|
GetModuleFileNameA(GetModuleHandleA(NULL), longpath, MAX_PATH);
|
||||||
|
childPrintf(hFile, "longPath=%s\r\n", encodeA(longpath));
|
||||||
|
|
||||||
map = OpenFileMappingA(FILE_MAP_READ, FALSE, "winetest_shlexec_dde_map");
|
map = OpenFileMappingA(FILE_MAP_READ, FALSE, "winetest_shlexec_dde_map");
|
||||||
if (map != NULL)
|
if (map != NULL)
|
||||||
|
@ -572,13 +575,14 @@ static void doChild(int argc, char** argv)
|
||||||
|
|
||||||
timer = SetTimer(NULL, 0, 2500, childTimeout);
|
timer = SetTimer(NULL, 0, 2500, childTimeout);
|
||||||
|
|
||||||
dde_ready = CreateEvent(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready");
|
dde_ready = OpenEvent(EVENT_MODIFY_STATE, FALSE, "winetest_shlexec_dde_ready");
|
||||||
SetEvent(dde_ready);
|
SetEvent(dde_ready);
|
||||||
CloseHandle(dde_ready);
|
CloseHandle(dde_ready);
|
||||||
|
|
||||||
while (GetMessage(&msg, NULL, 0, 0))
|
while (GetMessage(&msg, NULL, 0, 0))
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
|
|
||||||
|
Sleep(500);
|
||||||
KillTimer(NULL, timer);
|
KillTimer(NULL, timer);
|
||||||
assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER));
|
assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER));
|
||||||
assert(DdeFreeStringHandle(ddeInst, hszTopic));
|
assert(DdeFreeStringHandle(ddeInst, hszTopic));
|
||||||
|
@ -587,7 +591,7 @@ static void doChild(int argc, char** argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dde_ready = CreateEvent(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready");
|
dde_ready = OpenEvent(EVENT_MODIFY_STATE, FALSE, "winetest_shlexec_dde_ready");
|
||||||
SetEvent(dde_ready);
|
SetEvent(dde_ready);
|
||||||
CloseHandle(dde_ready);
|
CloseHandle(dde_ready);
|
||||||
}
|
}
|
||||||
|
@ -676,6 +680,11 @@ static void _okChildString(const char* file, int line, const char* key, const ch
|
||||||
{
|
{
|
||||||
char* result;
|
char* result;
|
||||||
result=getChildString("Arguments", key);
|
result=getChildString("Arguments", key);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
ok_(file, line)(FALSE, "%s expected '%s', but key not found or empty\n", key, expected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
ok_(file, line)(lstrcmpiA(result, expected) == 0,
|
ok_(file, line)(lstrcmpiA(result, expected) == 0,
|
||||||
"%s expected '%s', got '%s'\n", key, expected, result);
|
"%s expected '%s', got '%s'\n", key, expected, result);
|
||||||
}
|
}
|
||||||
|
@ -684,6 +693,11 @@ static void _okChildPath(const char* file, int line, const char* key, const char
|
||||||
{
|
{
|
||||||
char* result;
|
char* result;
|
||||||
result=getChildString("Arguments", key);
|
result=getChildString("Arguments", key);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
ok_(file, line)(FALSE, "%s expected '%s', but key not found or empty\n", key, expected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
ok_(file, line)(StrCmpPath(result, expected) == 0,
|
ok_(file, line)(StrCmpPath(result, expected) == 0,
|
||||||
"%s expected '%s', got '%s'\n", key, expected, result);
|
"%s expected '%s', got '%s'\n", key, expected, result);
|
||||||
}
|
}
|
||||||
|
@ -774,6 +788,26 @@ static DWORD get_long_path_name(const char* shortpath, char* longpath, DWORD lon
|
||||||
return tmplen;
|
return tmplen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* PathFindFileNameA equivalent that supports WinNT
|
||||||
|
*
|
||||||
|
***/
|
||||||
|
|
||||||
|
static LPSTR path_find_file_name(LPCSTR lpszPath)
|
||||||
|
{
|
||||||
|
LPCSTR lastSlash = lpszPath;
|
||||||
|
|
||||||
|
while (lpszPath && *lpszPath)
|
||||||
|
{
|
||||||
|
if ((*lpszPath == '\\' || *lpszPath == '/' || *lpszPath == ':') &&
|
||||||
|
lpszPath[1] && lpszPath[1] != '\\' && lpszPath[1] != '/')
|
||||||
|
lastSlash = lpszPath + 1;
|
||||||
|
lpszPath = CharNext(lpszPath);
|
||||||
|
}
|
||||||
|
return (LPSTR)lastSlash;
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*
|
*
|
||||||
* Tests
|
* Tests
|
||||||
|
@ -1613,14 +1647,7 @@ static dde_tests_t dde_tests[] =
|
||||||
|
|
||||||
static DWORD WINAPI hooked_WaitForInputIdle(HANDLE process, DWORD timeout)
|
static DWORD WINAPI hooked_WaitForInputIdle(HANDLE process, DWORD timeout)
|
||||||
{
|
{
|
||||||
HANDLE dde_ready;
|
return WaitForSingleObject(dde_ready_event, timeout);
|
||||||
DWORD wait_result;
|
|
||||||
|
|
||||||
dde_ready = CreateEventA(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready");
|
|
||||||
wait_result = WaitForSingleObject(dde_ready, timeout);
|
|
||||||
CloseHandle(dde_ready);
|
|
||||||
|
|
||||||
return wait_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1714,7 +1741,7 @@ static void test_dde(void)
|
||||||
{
|
{
|
||||||
if (!create_test_association(".sde"))
|
if (!create_test_association(".sde"))
|
||||||
{
|
{
|
||||||
skip("Unable to create association for '.sfe'\n");
|
skip("Unable to create association for '.sde'\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec,
|
create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec,
|
||||||
|
@ -1732,7 +1759,9 @@ static void test_dde(void)
|
||||||
}
|
}
|
||||||
ddeExec[0] = 0;
|
ddeExec[0] = 0;
|
||||||
|
|
||||||
|
dde_ready_event = CreateEventA(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready");
|
||||||
rc = shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, filename, NULL, NULL);
|
rc = shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, filename, NULL, NULL);
|
||||||
|
CloseHandle(dde_ready_event);
|
||||||
if ((test->todo & 0x1)==0)
|
if ((test->todo & 0x1)==0)
|
||||||
{
|
{
|
||||||
ok(32 < rc, "%s failed: rc=%d err=%d\n", shell_call,
|
ok(32 < rc, "%s failed: rc=%d err=%d\n", shell_call,
|
||||||
|
@ -2118,8 +2147,9 @@ static void test_commandline(void)
|
||||||
static const WCHAR chkfmt3[] = {'\\','\"','%','s','\"',0};
|
static const WCHAR chkfmt3[] = {'\\','\"','%','s','\"',0};
|
||||||
static const WCHAR chkfmt4[] = {'%','s','=','%','s','\"',' ','%','s','\"',0};
|
static const WCHAR chkfmt4[] = {'%','s','=','%','s','\"',' ','%','s','\"',0};
|
||||||
WCHAR cmdline[255];
|
WCHAR cmdline[255];
|
||||||
LPWSTR *args = (LPWSTR*)0xdeadcafe;
|
LPWSTR *args = (LPWSTR*)0xdeadcafe, pbuf;
|
||||||
INT numargs = -1;
|
INT numargs = -1;
|
||||||
|
size_t buflen;
|
||||||
|
|
||||||
wsprintfW(cmdline,fmt1,one,two,three,four);
|
wsprintfW(cmdline,fmt1,one,two,three,four);
|
||||||
args=CommandLineToArgvW(cmdline,&numargs);
|
args=CommandLineToArgvW(cmdline,&numargs);
|
||||||
|
@ -2170,6 +2200,46 @@ static void test_commandline(void)
|
||||||
wsprintfW(cmdline,fmt6);
|
wsprintfW(cmdline,fmt6);
|
||||||
args=CommandLineToArgvW(cmdline,&numargs);
|
args=CommandLineToArgvW(cmdline,&numargs);
|
||||||
ok(numargs == 1, "expected 1 args, got %i\n",numargs);
|
ok(numargs == 1, "expected 1 args, got %i\n",numargs);
|
||||||
|
if (numargs == 1) {
|
||||||
|
buflen = max(lstrlenW(args[0])+1,256);
|
||||||
|
pbuf = HeapAlloc(GetProcessHeap(), 0, buflen*sizeof(pbuf[0]));
|
||||||
|
GetModuleFileNameW(NULL, pbuf, buflen);
|
||||||
|
pbuf[buflen-1] = 0;
|
||||||
|
/* check args[0] is module file name */
|
||||||
|
ok(lstrcmpW(args[0],pbuf)==0, "wrong path to the current executable\n");
|
||||||
|
HeapFree(GetProcessHeap(), 0, pbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_directory(void)
|
||||||
|
{
|
||||||
|
char path[MAX_PATH], newdir[MAX_PATH];
|
||||||
|
char params[1024];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* copy this executable to a new folder and cd to it */
|
||||||
|
sprintf(newdir, "%s\\newfolder", tmpdir);
|
||||||
|
rc = CreateDirectoryA( newdir, NULL );
|
||||||
|
ok( rc, "failed to create %s err %u\n", newdir, GetLastError() );
|
||||||
|
sprintf(path, "%s\\%s", newdir, path_find_file_name(argv0));
|
||||||
|
CopyFileA(argv0, path, FALSE);
|
||||||
|
SetCurrentDirectory(tmpdir);
|
||||||
|
|
||||||
|
sprintf(params, "shlexec \"%s\" Exec", child_file);
|
||||||
|
|
||||||
|
rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI,
|
||||||
|
NULL, path_find_file_name(argv0), params, NULL);
|
||||||
|
todo_wine ok(rc == SE_ERR_FNF, "%s returned %d\n", shell_call, rc);
|
||||||
|
|
||||||
|
rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_FLAG_NO_UI,
|
||||||
|
NULL, path_find_file_name(argv0), params, newdir);
|
||||||
|
ok(rc > 32, "%s returned %d\n", shell_call, rc);
|
||||||
|
okChildInt("argcA", 4);
|
||||||
|
okChildString("argvA3", "Exec");
|
||||||
|
todo_wine okChildPath("longPath", path);
|
||||||
|
|
||||||
|
DeleteFile(path);
|
||||||
|
RemoveDirectoryA(newdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(shlexec)
|
START_TEST(shlexec)
|
||||||
|
@ -2194,6 +2264,7 @@ START_TEST(shlexec)
|
||||||
test_dde();
|
test_dde();
|
||||||
test_dde_default_app();
|
test_dde_default_app();
|
||||||
test_commandline();
|
test_commandline();
|
||||||
|
test_directory();
|
||||||
|
|
||||||
cleanup_test();
|
cleanup_test();
|
||||||
}
|
}
|
||||||
|
|
|
@ -820,6 +820,7 @@ static void test_copy(void)
|
||||||
DWORD retval;
|
DWORD retval;
|
||||||
LPSTR ptr;
|
LPSTR ptr;
|
||||||
BOOL on_nt4 = FALSE;
|
BOOL on_nt4 = FALSE;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
if (old_shell32)
|
if (old_shell32)
|
||||||
{
|
{
|
||||||
|
@ -973,16 +974,16 @@ static void test_copy(void)
|
||||||
shfo.pTo = "test2.txt\0";
|
shfo.pTo = "test2.txt\0";
|
||||||
/* suppress the error-dialog in win9x here */
|
/* suppress the error-dialog in win9x here */
|
||||||
shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
|
shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
|
||||||
ok(SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY),
|
ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY);
|
||||||
"Failure to set file attributes (error %x)\n", GetLastError());
|
ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
|
||||||
retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
|
retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
|
||||||
ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
|
ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
|
||||||
retval = SHFileOperationA(&shfo);
|
retval = SHFileOperationA(&shfo);
|
||||||
/* Does not work on Win95, Win95B, NT4WS and NT4SRV */
|
/* Does not work on Win95, Win95B, NT4WS and NT4SRV */
|
||||||
ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %x)\n", retval);
|
ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %x)\n", retval);
|
||||||
/* Set back normal attributes to make the file deletion succeed */
|
/* Set back normal attributes to make the file deletion succeed */
|
||||||
ok(SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL),
|
ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL);
|
||||||
"Failure to set file attributes (error %x)\n", GetLastError());
|
ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
|
||||||
shfo.fFlags = tmp_flags;
|
shfo.fFlags = tmp_flags;
|
||||||
|
|
||||||
/* try to copy files to a file */
|
/* try to copy files to a file */
|
||||||
|
@ -1715,11 +1716,11 @@ static void test_copy(void)
|
||||||
{
|
{
|
||||||
ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
|
ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
|
||||||
ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
|
ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
|
||||||
ok(!RemoveDirectoryA("fourdir"), "Expected dit to not exist\n");
|
ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
|
||||||
}
|
}
|
||||||
ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
|
ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
|
||||||
ok(!DeleteFileA("five"), "Expected file to not exist\n");
|
ok(!DeleteFileA("five"), "Expected file to not exist\n");
|
||||||
ok(!RemoveDirectoryA("five"), "Expected dit to not exist\n");
|
ok(!RemoveDirectoryA("five"), "Expected dir to not exist\n");
|
||||||
|
|
||||||
createTestFile("aa.txt");
|
createTestFile("aa.txt");
|
||||||
createTestFile("ab.txt");
|
createTestFile("ab.txt");
|
||||||
|
@ -2057,6 +2058,7 @@ static void test_sh_create_dir(void)
|
||||||
ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
|
ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
|
||||||
|
|
||||||
ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
|
ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
|
||||||
|
ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory, ret = %d\n", ret);
|
||||||
ok(file_exists("c:\\testdir3"), "The directory is not created\n");
|
ok(file_exists("c:\\testdir3"), "The directory is not created\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2065,6 +2067,7 @@ static void test_sh_path_prepare(void)
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
CHAR path[MAX_PATH];
|
CHAR path[MAX_PATH];
|
||||||
CHAR UNICODE_PATH_A[MAX_PATH];
|
CHAR UNICODE_PATH_A[MAX_PATH];
|
||||||
|
BOOL UsedDefaultChar;
|
||||||
|
|
||||||
if(!pSHPathPrepareForWriteA)
|
if(!pSHPathPrepareForWriteA)
|
||||||
{
|
{
|
||||||
|
@ -2156,7 +2159,19 @@ static void test_sh_path_prepare(void)
|
||||||
win_skip("Skipping SHPathPrepareForWriteW tests\n");
|
win_skip("Skipping SHPathPrepareForWriteW tests\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WideCharToMultiByte(CP_ACP, 0, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, NULL);
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
UsedDefaultChar = FALSE;
|
||||||
|
if (WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, &UsedDefaultChar) == 0)
|
||||||
|
{
|
||||||
|
win_skip("Could not convert Unicode path name to multibyte (%d)\n", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (UsedDefaultChar)
|
||||||
|
{
|
||||||
|
win_skip("Could not find unique multibyte representation for directory name using default codepage\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* unicode directory doesn't exist, SHPPFW_NONE */
|
/* unicode directory doesn't exist, SHPPFW_NONE */
|
||||||
RemoveDirectoryA(UNICODE_PATH_A);
|
RemoveDirectoryA(UNICODE_PATH_A);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -78,6 +78,16 @@ static HWND subclass_listview(HWND hwnd)
|
||||||
|
|
||||||
/* listview is a first child */
|
/* listview is a first child */
|
||||||
listview = FindWindowExA(hwnd, NULL, WC_LISTVIEWA, NULL);
|
listview = FindWindowExA(hwnd, NULL, WC_LISTVIEWA, NULL);
|
||||||
|
if(!listview)
|
||||||
|
{
|
||||||
|
/* .. except for some versions of Windows XP, where things
|
||||||
|
are slightly more complicated. */
|
||||||
|
HWND hwnd_tmp;
|
||||||
|
hwnd_tmp = FindWindowExA(hwnd, NULL, "DUIViewWndClassName", NULL);
|
||||||
|
hwnd_tmp = FindWindowExA(hwnd_tmp, NULL, "DirectUIHWND", NULL);
|
||||||
|
hwnd_tmp = FindWindowExA(hwnd_tmp, NULL, "CtrlNotifySink", NULL);
|
||||||
|
listview = FindWindowExA(hwnd_tmp, NULL, WC_LISTVIEWA, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
oldproc = (WNDPROC)SetWindowLongPtrA(listview, GWLP_WNDPROC,
|
oldproc = (WNDPROC)SetWindowLongPtrA(listview, GWLP_WNDPROC,
|
||||||
(LONG_PTR)listview_subclass_proc);
|
(LONG_PTR)listview_subclass_proc);
|
||||||
|
@ -86,28 +96,71 @@ static HWND subclass_listview(HWND hwnd)
|
||||||
return listview;
|
return listview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT get_msg_count(struct msg_sequence **seq, int sequence_index, UINT message)
|
||||||
|
{
|
||||||
|
struct msg_sequence *msg_seq = seq[sequence_index];
|
||||||
|
UINT i, count = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < msg_seq->count ; i++)
|
||||||
|
if(msg_seq->sequence[i].message == message)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks that every message in the sequence seq is also present in
|
||||||
|
* the UINT array msgs */
|
||||||
|
static void verify_msgs_in_(struct msg_sequence *seq, const UINT *msgs,
|
||||||
|
const char *file, int line)
|
||||||
|
{
|
||||||
|
UINT i, j, msg, failcount = 0;
|
||||||
|
for(i = 0; i < seq->count; i++)
|
||||||
|
{
|
||||||
|
BOOL found = FALSE;
|
||||||
|
msg = seq->sequence[i].message;
|
||||||
|
for(j = 0; msgs[j] != 0; j++)
|
||||||
|
if(msgs[j] == msg) found = TRUE;
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
{
|
||||||
|
failcount++;
|
||||||
|
trace("Unexpected message %d\n", msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok_(file, line) (!failcount, "%d failures.\n", failcount);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define verify_msgs_in(seq, msgs) \
|
||||||
|
verify_msgs_in_(seq, msgs, __FILE__, __LINE__)
|
||||||
|
|
||||||
/* dummy IDataObject implementation */
|
/* dummy IDataObject implementation */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const IDataObjectVtbl *lpVtbl;
|
IDataObject IDataObject_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
} IDataObjectImpl;
|
} IDataObjectImpl;
|
||||||
|
|
||||||
static const IDataObjectVtbl IDataObjectImpl_Vtbl;
|
static const IDataObjectVtbl IDataObjectImpl_Vtbl;
|
||||||
|
|
||||||
|
static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, IDataObjectImpl, IDataObject_iface);
|
||||||
|
}
|
||||||
|
|
||||||
static IDataObject* IDataObjectImpl_Construct(void)
|
static IDataObject* IDataObjectImpl_Construct(void)
|
||||||
{
|
{
|
||||||
IDataObjectImpl *obj;
|
IDataObjectImpl *obj;
|
||||||
|
|
||||||
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
|
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
|
||||||
obj->lpVtbl = &IDataObjectImpl_Vtbl;
|
obj->IDataObject_iface.lpVtbl = &IDataObjectImpl_Vtbl;
|
||||||
obj->ref = 1;
|
obj->ref = 1;
|
||||||
|
|
||||||
return (IDataObject*)obj;
|
return &obj->IDataObject_iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, void **ppvObj)
|
static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, void **ppvObj)
|
||||||
{
|
{
|
||||||
IDataObjectImpl *This = (IDataObjectImpl *)iface;
|
IDataObjectImpl *This = impl_from_IDataObject(iface);
|
||||||
|
|
||||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||||
IsEqualIID(riid, &IID_IDataObject))
|
IsEqualIID(riid, &IID_IDataObject))
|
||||||
|
@ -126,13 +179,13 @@ static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID
|
||||||
|
|
||||||
static ULONG WINAPI IDataObjectImpl_AddRef(IDataObject * iface)
|
static ULONG WINAPI IDataObjectImpl_AddRef(IDataObject * iface)
|
||||||
{
|
{
|
||||||
IDataObjectImpl *This = (IDataObjectImpl *)iface;
|
IDataObjectImpl *This = impl_from_IDataObject(iface);
|
||||||
return InterlockedIncrement(&This->ref);
|
return InterlockedIncrement(&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IDataObjectImpl_Release(IDataObject * iface)
|
static ULONG WINAPI IDataObjectImpl_Release(IDataObject * iface)
|
||||||
{
|
{
|
||||||
IDataObjectImpl *This = (IDataObjectImpl *)iface;
|
IDataObjectImpl *This = impl_from_IDataObject(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
|
@ -210,28 +263,33 @@ static const IDataObjectVtbl IDataObjectImpl_Vtbl =
|
||||||
|
|
||||||
/* dummy IShellBrowser implementation */
|
/* dummy IShellBrowser implementation */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const IShellBrowserVtbl *lpVtbl;
|
IShellBrowser IShellBrowser_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
} IShellBrowserImpl;
|
} IShellBrowserImpl;
|
||||||
|
|
||||||
static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
|
static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
|
||||||
|
|
||||||
|
static inline IShellBrowserImpl *impl_from_IShellBrowser(IShellBrowser *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, IShellBrowserImpl, IShellBrowser_iface);
|
||||||
|
}
|
||||||
|
|
||||||
static IShellBrowser* IShellBrowserImpl_Construct(void)
|
static IShellBrowser* IShellBrowserImpl_Construct(void)
|
||||||
{
|
{
|
||||||
IShellBrowserImpl *browser;
|
IShellBrowserImpl *browser;
|
||||||
|
|
||||||
browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
|
browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
|
||||||
browser->lpVtbl = &IShellBrowserImpl_Vtbl;
|
browser->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl;
|
||||||
browser->ref = 1;
|
browser->ref = 1;
|
||||||
|
|
||||||
return (IShellBrowser*)browser;
|
return &browser->IShellBrowser_iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
|
static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
LPVOID *ppvObj)
|
LPVOID *ppvObj)
|
||||||
{
|
{
|
||||||
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
|
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
|
||||||
|
|
||||||
*ppvObj = NULL;
|
*ppvObj = NULL;
|
||||||
|
|
||||||
|
@ -253,13 +311,13 @@ static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
|
||||||
|
|
||||||
static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
|
static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
|
||||||
{
|
{
|
||||||
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
|
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
|
||||||
return InterlockedIncrement(&This->ref);
|
return InterlockedIncrement(&This->ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
|
static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
|
||||||
{
|
{
|
||||||
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
|
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
|
||||||
ULONG ref = InterlockedDecrement(&This->ref);
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
|
@ -423,7 +481,7 @@ static const struct message folderview_getselectionmarked_seq[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct message folderview_getfocused_seq[] = {
|
static const struct message folderview_getfocused_seq[] = {
|
||||||
{ LVM_GETNEXTITEM, sent|wparam|lparam, -1, LVNI_FOCUSED },
|
{ LVM_GETNEXTITEM, sent|wparam|lparam|optional, -1, LVNI_FOCUSED },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -451,7 +509,7 @@ static void test_IShellView_CreateViewWindow(void)
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* crashes on native */
|
/* crashes on native */
|
||||||
hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
|
IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.ViewMode = FVM_ICON;
|
settings.ViewMode = FVM_ICON;
|
||||||
|
@ -487,7 +545,7 @@ static void test_IFolderView(void)
|
||||||
HWND hwnd_view, hwnd_list;
|
HWND hwnd_view, hwnd_list;
|
||||||
PITEMID_CHILD pidl;
|
PITEMID_CHILD pidl;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
INT ret;
|
INT ret, count;
|
||||||
POINT pt;
|
POINT pt;
|
||||||
LONG ref1, ref2;
|
LONG ref1, ref2;
|
||||||
RECT r;
|
RECT r;
|
||||||
|
@ -519,14 +577,14 @@ static void test_IFolderView(void)
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* crashes on Vista and Win2k8 - List not created yet case */
|
/* crashes on Vista and Win2k8 - List not created yet case */
|
||||||
hr = IFolderView_GetSpacing(fv, &pt);
|
IFolderView_GetSpacing(fv, &pt);
|
||||||
|
|
||||||
/* crashes on XP */
|
/* crashes on XP */
|
||||||
hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
|
IFolderView_GetSelectionMarkedItem(fv, NULL);
|
||||||
hr = IFolderView_GetFocusedItem(fv, NULL);
|
IFolderView_GetFocusedItem(fv, NULL);
|
||||||
|
|
||||||
/* crashes on Vista+ */
|
/* crashes on Vista+ */
|
||||||
hr = IFolderView_Item(fv, 0, NULL);
|
IFolderView_Item(fv, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
browser = IShellBrowserImpl_Construct();
|
browser = IShellBrowserImpl_Construct();
|
||||||
|
@ -570,32 +628,48 @@ if (0)
|
||||||
ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret));
|
ok(pt.x == LOWORD(ret) && pt.y == HIWORD(ret), "got (%d, %d)\n", LOWORD(ret), HIWORD(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* IFolderView::ItemCount */
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
/* crashes on XP */
|
||||||
|
IFolderView_ItemCount(fv, SVGIO_ALLVIEW, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
IFolderView_ItemCount(fv, SVGIO_ALLVIEW, &count);
|
||||||
|
|
||||||
/* IFolderView::GetSelectionMarkedItem */
|
/* IFolderView::GetSelectionMarkedItem */
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* crashes on XP */
|
/* crashes on XP */
|
||||||
hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
|
IFolderView_GetSelectionMarkedItem(fv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
hr = IFolderView_GetSelectionMarkedItem(fv, &ret);
|
hr = IFolderView_GetSelectionMarkedItem(fv, &ret);
|
||||||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
if (count)
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
else
|
||||||
|
ok(hr == S_FALSE, "got (0x%08x)\n", hr);
|
||||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getselectionmarked_seq,
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getselectionmarked_seq,
|
||||||
"IFolderView::GetSelectionMarkedItem", FALSE);
|
"IFolderView::GetSelectionMarkedItem", FALSE);
|
||||||
|
|
||||||
/* IFolderView::GetFocusedItem */
|
/* IFolderView::GetFocusedItem */
|
||||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
hr = IFolderView_GetFocusedItem(fv, &ret);
|
hr = IFolderView_GetFocusedItem(fv, &ret);
|
||||||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
if (count)
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
else
|
||||||
|
ok(hr == S_FALSE, "got (0x%08x)\n", hr);
|
||||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getfocused_seq,
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_getfocused_seq,
|
||||||
"IFolderView::GetFocusedItem", FALSE);
|
"IFolderView::GetFocusedItem", FALSE);
|
||||||
|
|
||||||
/* IFolderView::GetFolder, just return pointer */
|
/* IFolderView::GetFolder, just return pointer */
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
/* crashes on XP */
|
/* crashes on XP */
|
||||||
hr = IFolderView_GetFolder(fv, NULL, (void**)&folder);
|
IFolderView_GetFolder(fv, NULL, (void**)&folder);
|
||||||
hr = IFolderView_GetFolder(fv, NULL, NULL);
|
IFolderView_GetFolder(fv, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL);
|
hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL);
|
||||||
|
@ -607,22 +681,10 @@ if (0)
|
||||||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
ref2 = IShellFolder_AddRef(desktop);
|
ref2 = IShellFolder_AddRef(desktop);
|
||||||
IShellFolder_Release(desktop);
|
IShellFolder_Release(desktop);
|
||||||
ok(ref1 == ref2, "expected same refcount, got %d\n", ref2);
|
ok(ref1 == ref2 || ref1 + 1 == ref2, /* >= vista */
|
||||||
|
"expected same refcount, got %d\n", ref2);
|
||||||
ok(desktop == folder, "\n");
|
ok(desktop == folder, "\n");
|
||||||
|
|
||||||
/* IFolderView::ItemCount */
|
|
||||||
if (0)
|
|
||||||
{
|
|
||||||
/* crashes on XP */
|
|
||||||
hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
|
||||||
hr = IFolderView_ItemCount(fv, SVGIO_ALLVIEW, &ret);
|
|
||||||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
|
||||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_itemcount_seq,
|
|
||||||
"IFolderView::ItemCount", FALSE);
|
|
||||||
|
|
||||||
IShellBrowser_Release(browser);
|
IShellBrowser_Release(browser);
|
||||||
IFolderView_Release(fv);
|
IFolderView_Release(fv);
|
||||||
IShellView_Release(view);
|
IShellView_Release(view);
|
||||||
|
@ -711,9 +773,9 @@ static void test_IShellFolderView(void)
|
||||||
/* ::RemoveObject */
|
/* ::RemoveObject */
|
||||||
i = 0xdeadbeef;
|
i = 0xdeadbeef;
|
||||||
hr = IShellFolderView_RemoveObject(folderview, NULL, &i);
|
hr = IShellFolderView_RemoveObject(folderview, NULL, &i);
|
||||||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
ok(hr == S_OK || hr == E_FAIL, "got (0x%08x)\n", hr);
|
||||||
ok(i == 0 || i == -1 /* Win7 */ || broken(i == 0xdeadbeef) /* Vista, 2k8 */,
|
if (hr == S_OK) ok(i == 0 || broken(i == 0xdeadbeef) /* Vista, 2k8 */,
|
||||||
"got %d\n", i);
|
"got %d\n", i);
|
||||||
|
|
||||||
IShellFolderView_Release(folderview);
|
IShellFolderView_Release(folderview);
|
||||||
|
|
||||||
|
@ -743,6 +805,352 @@ static void test_IOleWindow(void)
|
||||||
IShellFolder_Release(desktop);
|
IShellFolder_Release(desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct message folderview_setcurrentviewmode1_2_prevista[] = {
|
||||||
|
{ LVM_SETVIEW, sent|wparam, LV_VIEW_ICON},
|
||||||
|
{ LVM_SETIMAGELIST, sent|wparam, 0},
|
||||||
|
{ LVM_SETIMAGELIST, sent|wparam, 1},
|
||||||
|
{ 0x105a, sent},
|
||||||
|
{ LVM_SETBKIMAGEW, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETBKCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETTEXTBKCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETTEXTCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_SETEXTENDEDLISTVIEWSTYLE, sent|optional|wparam, 0xc8}, /* w2k3 */
|
||||||
|
{ LVM_ARRANGE, sent },
|
||||||
|
{ LVM_ARRANGE, sent|optional }, /* WinXP */
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message folderview_setcurrentviewmode3_prevista[] = {
|
||||||
|
{ LVM_SETVIEW, sent|wparam, LV_VIEW_LIST},
|
||||||
|
{ LVM_SETIMAGELIST, sent|wparam, 0},
|
||||||
|
{ LVM_SETIMAGELIST, sent|wparam, 1},
|
||||||
|
{ 0x105a, sent},
|
||||||
|
{ LVM_SETBKIMAGEW, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETBKCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETTEXTBKCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETTEXTCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_SETEXTENDEDLISTVIEWSTYLE, sent|optional|wparam, 0xc8}, /* w2k3 */
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct message folderview_setcurrentviewmode4_prevista[] = {
|
||||||
|
{ LVM_GETHEADER, sent},
|
||||||
|
{ LVM_GETITEMCOUNT, sent|optional },
|
||||||
|
{ LVM_SETSELECTEDCOLUMN, sent},
|
||||||
|
{ WM_NOTIFY, sent },
|
||||||
|
{ WM_NOTIFY, sent },
|
||||||
|
{ WM_NOTIFY, sent },
|
||||||
|
{ WM_NOTIFY, sent },
|
||||||
|
{ LVM_SETVIEW, sent|wparam, LV_VIEW_DETAILS},
|
||||||
|
{ LVM_SETIMAGELIST, sent|wparam, 0},
|
||||||
|
{ LVM_SETIMAGELIST, sent|wparam, 1},
|
||||||
|
{ 0x105a, sent},
|
||||||
|
{ LVM_SETBKIMAGEW, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETBKCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETTEXTBKCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_GETTEXTCOLOR, sent|optional}, /* w2k3 */
|
||||||
|
{ LVM_SETEXTENDEDLISTVIEWSTYLE, sent|optional|wparam, 0xc8}, /* w2k3 */
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* XP, SetCurrentViewMode(5)
|
||||||
|
108e - LVM_SETVIEW (LV_VIEW_ICON);
|
||||||
|
1036 - LVM_SETEXTEDEDLISTVIEWSTYLE (0x8000, 0)
|
||||||
|
100c/104c repeated X times
|
||||||
|
1003 - LVM_SETIMAGELIST
|
||||||
|
1035 - LVM_SETICONSPACING
|
||||||
|
1004 - LVM_GETITEMCOUNT
|
||||||
|
105a - ?
|
||||||
|
1016 - LVM_ARRANGE
|
||||||
|
1016 - LVM_ARRANGE
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XP, SetCurrentViewMode(6)
|
||||||
|
1036 - LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0)
|
||||||
|
1035 - LVM_SETICONSPACING
|
||||||
|
1003 - LVM_SETIMAGELIST
|
||||||
|
1003 - LVM_SETIMAGELIST
|
||||||
|
100c/104c repeated X times
|
||||||
|
10a2 - LVM_SETTILEVIEWINFO
|
||||||
|
108e - LVM_SETVIEW (LV_VIEW_TILE)
|
||||||
|
1003 - LVM_SETIMAGELIST
|
||||||
|
105a - ?
|
||||||
|
1016 - LVM_ARRANGE
|
||||||
|
1016 - LVM_ARRANGE
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XP, SetCurrentViewMode (7)
|
||||||
|
10a2 - LVM_SETTILEVIEWINFO
|
||||||
|
108e - LVM_SETVIEW (LV_VIEW_ICON)
|
||||||
|
1004/10a4 (LVM_GETITEMCOUNT/LVM_SETTILEINFO) X times
|
||||||
|
1016 - LVM_ARRANGE
|
||||||
|
1016 - LVM_ARRANGE
|
||||||
|
...
|
||||||
|
LVM_SETEXTENDEDLISTVIEWSTYLE (0x40000, 0x40000)
|
||||||
|
...
|
||||||
|
LVM_SETEXTENDEDLISTVIEWSTYLE (0x8000, 0x8000)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_GetSetCurrentViewMode(void)
|
||||||
|
{
|
||||||
|
IShellFolder *desktop;
|
||||||
|
IShellView *sview;
|
||||||
|
IFolderView *fview;
|
||||||
|
IShellBrowser *browser;
|
||||||
|
FOLDERSETTINGS fs;
|
||||||
|
UINT viewmode;
|
||||||
|
HWND hwnd;
|
||||||
|
RECT rc = {0, 0, 10, 10};
|
||||||
|
HRESULT hr;
|
||||||
|
UINT i;
|
||||||
|
static const int winxp_res[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
static const int win2k3_res[11] = {0, 1, 2, 3, 4, 5, 6, 5, 8, 0, 0};
|
||||||
|
static const int vista_res[11] = {0, 1, 5, 3, 4, 5, 6, 7, 7, 0, 0};
|
||||||
|
static const int win7_res[11] = {1, 1, 1, 3, 4, 1, 6, 1, 8, 8, 8};
|
||||||
|
|
||||||
|
hr = SHGetDesktopFolder(&desktop);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
hr = IShellFolder_CreateViewObject(desktop, NULL, &IID_IShellView, (void**)&sview);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
fs.ViewMode = 1;
|
||||||
|
fs.fFlags = 0;
|
||||||
|
browser = IShellBrowserImpl_Construct();
|
||||||
|
hr = IShellView_CreateViewWindow(sview, NULL, &fs, browser, &rc, &hwnd);
|
||||||
|
ok(hr == S_OK || broken(hr == S_FALSE /*Win2k*/ ), "got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
hr = IShellView_QueryInterface(sview, &IID_IFolderView, (void**)&fview);
|
||||||
|
ok(hr == S_OK || broken(hr == E_NOINTERFACE), "got (0x%08x)\n", hr);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
HWND hwnd_lv;
|
||||||
|
UINT count;
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
{
|
||||||
|
/* Crashes under Win7/WinXP */
|
||||||
|
IFolderView_GetCurrentViewMode(fview, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
ok(viewmode == 1, "ViewMode was %d\n", viewmode);
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, FVM_AUTO);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 0);
|
||||||
|
ok(hr == E_INVALIDARG || broken(hr == S_OK),
|
||||||
|
"got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
for(i = 1; i < 9; i++)
|
||||||
|
{
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, i);
|
||||||
|
ok(hr == S_OK || (i == 8 && hr == E_INVALIDARG /*Vista*/),
|
||||||
|
"(%d) got (0x%08x)\n", i, hr);
|
||||||
|
|
||||||
|
hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
|
||||||
|
ok(hr == S_OK, "(%d) got (0x%08x)\n", i, hr);
|
||||||
|
|
||||||
|
/* Wine currently behaves like winxp here. */
|
||||||
|
ok((viewmode == win7_res[i]) || (viewmode == vista_res[i]) ||
|
||||||
|
(viewmode == win2k3_res[i]) || (viewmode == winxp_res[i]),
|
||||||
|
"(%d) got %d\n",i , viewmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 9);
|
||||||
|
ok(hr == E_INVALIDARG || broken(hr == S_OK),
|
||||||
|
"got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
/* Test messages */
|
||||||
|
hwnd_lv = subclass_listview(hwnd);
|
||||||
|
ok(hwnd_lv != NULL, "Failed to subclass listview\n");
|
||||||
|
if(hwnd_lv)
|
||||||
|
{
|
||||||
|
/* Vista seems to set the viewmode by other means than
|
||||||
|
sending messages. At least no related messages are
|
||||||
|
captured by subclassing.
|
||||||
|
*/
|
||||||
|
BOOL vista_plus = FALSE;
|
||||||
|
static const UINT vista_plus_msgs[] = {
|
||||||
|
WM_SETREDRAW, WM_NOTIFY, WM_NOTIFYFORMAT, WM_QUERYUISTATE,
|
||||||
|
WM_MENUCHAR, WM_WINDOWPOSCHANGING, WM_NCCALCSIZE, WM_WINDOWPOSCHANGED,
|
||||||
|
WM_PARENTNOTIFY, LVM_GETHEADER, 0 };
|
||||||
|
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 1);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
/* WM_SETREDRAW is not sent in versions before Vista. */
|
||||||
|
vista_plus = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, WM_SETREDRAW);
|
||||||
|
if(vista_plus)
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
else
|
||||||
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode1_2_prevista,
|
||||||
|
"IFolderView::SetCurrentViewMode(1)", TRUE);
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 2);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
if(vista_plus)
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
else
|
||||||
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode1_2_prevista,
|
||||||
|
"IFolderView::SetCurrentViewMode(2)", TRUE);
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 3);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
if(vista_plus)
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
else
|
||||||
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode3_prevista,
|
||||||
|
"IFolderView::SetCurrentViewMode(3)", TRUE);
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 4);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
if(vista_plus)
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
else
|
||||||
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, folderview_setcurrentviewmode4_prevista,
|
||||||
|
"IFolderView::SetCurrentViewMode(4)", TRUE);
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 5);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
if(vista_plus)
|
||||||
|
{
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
|
||||||
|
ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
|
||||||
|
ok(count == 1 || count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 6);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
if(vista_plus)
|
||||||
|
{
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
|
||||||
|
ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
|
||||||
|
ok(count == 1 || count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 7);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
if(vista_plus)
|
||||||
|
{
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
|
||||||
|
ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
|
||||||
|
ok(count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IFolderView_SetCurrentViewMode(fview, 8);
|
||||||
|
ok(hr == S_OK || broken(hr == E_INVALIDARG /* Vista */), "got 0x%08x\n", hr);
|
||||||
|
todo_wine
|
||||||
|
{
|
||||||
|
if(vista_plus)
|
||||||
|
{
|
||||||
|
verify_msgs_in(sequences[LISTVIEW_SEQ_INDEX], vista_plus_msgs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETVIEW);
|
||||||
|
ok(count == 1, "LVM_SETVIEW sent %d times.\n", count);
|
||||||
|
count = get_msg_count(sequences, LISTVIEW_SEQ_INDEX, LVM_SETEXTENDEDLISTVIEWSTYLE);
|
||||||
|
ok(count == 2, "LVM_SETEXTENDEDLISTVIEWSTYLE sent %d times.\n", count);
|
||||||
|
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IFolderView_GetCurrentViewMode(fview, &viewmode);
|
||||||
|
ok(hr == S_OK, "Failed to get current viewmode.\n");
|
||||||
|
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, empty_seq,
|
||||||
|
"IFolderView::GetCurrentViewMode", FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFolderView_Release(fview);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skip("No IFolderView for the desktop folder.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
IShellBrowser_Release(browser);
|
||||||
|
IShellView_DestroyViewWindow(sview);
|
||||||
|
IShellView_Release(sview);
|
||||||
|
IShellFolder_Release(desktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_IOleCommandTarget(void)
|
||||||
|
{
|
||||||
|
IShellFolder *psf_desktop;
|
||||||
|
IShellView *psv;
|
||||||
|
IOleCommandTarget *poct;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = SHGetDesktopFolder(&psf_desktop);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
|
||||||
|
hr = IShellFolder_CreateViewObject(psf_desktop, NULL, &IID_IShellView, (void**)&psv);
|
||||||
|
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = IShellView_QueryInterface(psv, &IID_IOleCommandTarget, (void**)&poct);
|
||||||
|
ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win95/NT4 */, "Got 0x%08x\n", hr);
|
||||||
|
if(SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
OLECMD oc;
|
||||||
|
|
||||||
|
hr = IOleCommandTarget_QueryStatus(poct, NULL, 0, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
oc.cmdID = 1;
|
||||||
|
hr = IOleCommandTarget_QueryStatus(poct, NULL, 0, &oc, NULL);
|
||||||
|
ok(hr == OLECMDERR_E_UNKNOWNGROUP, "Got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
oc.cmdID = 1;
|
||||||
|
hr = IOleCommandTarget_QueryStatus(poct, NULL, 1, &oc, NULL);
|
||||||
|
ok(hr == OLECMDERR_E_UNKNOWNGROUP, "Got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
hr = IOleCommandTarget_Exec(poct, NULL, 0, 0, NULL, NULL);
|
||||||
|
ok(hr == OLECMDERR_E_UNKNOWNGROUP, "Got 0x%08x\n", hr);
|
||||||
|
|
||||||
|
IOleCommandTarget_Release(poct);
|
||||||
|
}
|
||||||
|
|
||||||
|
IShellView_Release(psv);
|
||||||
|
}
|
||||||
|
|
||||||
|
IShellFolder_Release(psf_desktop);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(shlview)
|
START_TEST(shlview)
|
||||||
{
|
{
|
||||||
OleInitialize(NULL);
|
OleInitialize(NULL);
|
||||||
|
@ -754,6 +1162,8 @@ START_TEST(shlview)
|
||||||
test_GetItemObject();
|
test_GetItemObject();
|
||||||
test_IShellFolderView();
|
test_IShellFolderView();
|
||||||
test_IOleWindow();
|
test_IOleWindow();
|
||||||
|
test_GetSetCurrentViewMode();
|
||||||
|
test_IOleCommandTarget();
|
||||||
|
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,19 +45,15 @@ static void test_cbsize(void)
|
||||||
nidW.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
nidW.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
nidW.uCallbackMessage = WM_USER+17;
|
nidW.uCallbackMessage = WM_USER+17;
|
||||||
ret = pShell_NotifyIconW(NIM_ADD, &nidW);
|
ret = pShell_NotifyIconW(NIM_ADD, &nidW);
|
||||||
if (ret)
|
/* using an invalid cbSize does work */
|
||||||
{
|
nidW.cbSize = 3;
|
||||||
/* using an invalid cbSize does work */
|
nidW.hWnd = hMainWnd;
|
||||||
nidW.cbSize = 3;
|
nidW.uID = 1;
|
||||||
nidW.hWnd = hMainWnd;
|
ret = pShell_NotifyIconW(NIM_DELETE, &nidW);
|
||||||
nidW.uID = 1;
|
ok( ret || broken(!ret), /* nt4 */ "NIM_DELETE failed!\n");
|
||||||
ret = pShell_NotifyIconW(NIM_DELETE, &nidW);
|
/* as icon doesn't exist anymore - now there will be an error */
|
||||||
ok( ret || broken(!ret), /* nt4 */ "NIM_DELETE failed!\n");
|
nidW.cbSize = sizeof(nidW);
|
||||||
/* as icon doesn't exist anymore - now there will be an error */
|
ok(!pShell_NotifyIconW(NIM_DELETE, &nidW) != !ret, "The icon was not deleted\n");
|
||||||
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 */
|
/* same for Shell_NotifyIconA */
|
||||||
|
@ -75,7 +71,7 @@ static void test_cbsize(void)
|
||||||
nidA.hWnd = hMainWnd;
|
nidA.hWnd = hMainWnd;
|
||||||
nidA.uID = 1;
|
nidA.uID = 1;
|
||||||
ret = Shell_NotifyIconA(NIM_DELETE, &nidA);
|
ret = Shell_NotifyIconA(NIM_DELETE, &nidA);
|
||||||
ok( ret || broken(!ret), /* win9x */ "NIM_DELETE failed!\n");
|
ok(ret, "NIM_DELETE failed!\n");
|
||||||
/* as icon doesn't exist anymore - now there will be an error */
|
/* as icon doesn't exist anymore - now there will be an error */
|
||||||
nidA.cbSize = sizeof(nidA);
|
nidA.cbSize = sizeof(nidA);
|
||||||
ok(!Shell_NotifyIconA(NIM_DELETE, &nidA) != !ret, "The icon was not deleted\n");
|
ok(!Shell_NotifyIconA(NIM_DELETE, &nidA) != !ret, "The icon was not deleted\n");
|
||||||
|
|
|
@ -8,9 +8,14 @@
|
||||||
|
|
||||||
extern void func_appbar(void);
|
extern void func_appbar(void);
|
||||||
extern void func_autocomplete(void);
|
extern void func_autocomplete(void);
|
||||||
|
extern void func_brsfolder(void);
|
||||||
|
extern void func_ebrowser(void);
|
||||||
extern void func_generated(void);
|
extern void func_generated(void);
|
||||||
extern void func_progman_dde(void);
|
extern void func_progman_dde(void);
|
||||||
|
extern void func_recyclebin(void);
|
||||||
|
extern void func_shelldispatch(void);
|
||||||
extern void func_shelllink(void);
|
extern void func_shelllink(void);
|
||||||
|
extern void func_shellole(void);
|
||||||
extern void func_shellpath(void);
|
extern void func_shellpath(void);
|
||||||
extern void func_shfldr_special(void);
|
extern void func_shfldr_special(void);
|
||||||
extern void func_shlexec(void);
|
extern void func_shlexec(void);
|
||||||
|
@ -23,16 +28,21 @@ extern void func_systray(void);
|
||||||
const struct test winetest_testlist[] =
|
const struct test winetest_testlist[] =
|
||||||
{
|
{
|
||||||
{ "appbar", func_appbar },
|
{ "appbar", func_appbar },
|
||||||
{ "autocomplete", func_autocomplete },
|
{ "autocomplete", func_autocomplete },
|
||||||
{ "generated", func_generated },
|
{ "brsfolder", func_brsfolder },
|
||||||
{ "progman_dde", func_progman_dde },
|
{ "ebrowser", func_ebrowser },
|
||||||
|
{ "generated", func_generated },
|
||||||
|
{ "progman_dde", func_progman_dde },
|
||||||
|
{ "recyclebin", func_recyclebin },
|
||||||
|
{ "shelldispatch", func_shelldispatch },
|
||||||
{ "shelllink", func_shelllink },
|
{ "shelllink", func_shelllink },
|
||||||
|
{ "shellole", func_shellole },
|
||||||
{ "shellpath", func_shellpath },
|
{ "shellpath", func_shellpath },
|
||||||
{ "shfldr_special", func_shfldr_special },
|
{ "shfldr_special", func_shfldr_special },
|
||||||
{ "shlexec", func_shlexec },
|
{ "shlexec", func_shlexec },
|
||||||
{ "shlfileop", func_shlfileop },
|
{ "shlfileop", func_shlfileop },
|
||||||
{ "shlfolder", func_shlfolder },
|
{ "shlfolder", func_shlfolder },
|
||||||
{ "shlview", func_shlview },
|
{ "shlview", func_shlview },
|
||||||
{ "string", func_string },
|
{ "string", func_string },
|
||||||
{ "systray", func_systray },
|
{ "systray", func_systray },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
|
|
Loading…
Reference in a new issue