mirror of
https://github.com/reactos/reactos.git
synced 2025-04-29 18:48:53 +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
|
||||
appbar.c
|
||||
autocomplete.c
|
||||
brsfolder.c
|
||||
ebrowser.c
|
||||
generated.c
|
||||
progman_dde.c
|
||||
recyclebin.c
|
||||
shelldispatch.c
|
||||
shelllink.c
|
||||
shellole.c
|
||||
shellpath.c
|
||||
shfldr_special.c
|
||||
shlexec.c
|
||||
shlfileop.c
|
||||
shlfolder.c
|
||||
|
@ -19,11 +25,10 @@ list(APPEND SOURCE
|
|||
string.c
|
||||
systray.c
|
||||
testlist.c
|
||||
shfldr_special.c
|
||||
rsrc.rc)
|
||||
|
||||
add_executable(shell32_winetest ${SOURCE})
|
||||
target_link_libraries(shell32_winetest wine uuid)
|
||||
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)
|
||||
|
|
|
@ -33,11 +33,115 @@ static HWND hMainWnd, hEdit;
|
|||
static HINSTANCE hinst;
|
||||
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)
|
||||
{
|
||||
HRESULT r;
|
||||
IAutoComplete* ac;
|
||||
IAutoComplete *ac;
|
||||
IUnknown *acSource;
|
||||
LONG_PTR user_data;
|
||||
|
||||
/* AutoComplete instance */
|
||||
r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
|
||||
|
@ -55,18 +159,20 @@ static IAutoComplete *test_init(void)
|
|||
if (r == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
win_skip("CLSID_ACLMulti is not registered\n");
|
||||
IAutoComplete_Release(ac);
|
||||
return NULL;
|
||||
}
|
||||
ok(r == S_OK, "no IID_IACList (0x%08x)\n", r);
|
||||
|
||||
if (0)
|
||||
{
|
||||
/* crashes on native */
|
||||
r = IAutoComplete_Init(ac, hEdit, NULL, NULL, NULL);
|
||||
}
|
||||
user_data = GetWindowLongPtrA(hEdit, GWLP_USERDATA);
|
||||
ok(user_data == 0, "Expected the edit control user data to be zero\n");
|
||||
|
||||
/* bind to edit control */
|
||||
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);
|
||||
|
||||
|
@ -134,6 +240,7 @@ START_TEST(autocomplete)
|
|||
ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
|
||||
if (!hMainWnd) return;
|
||||
|
||||
test_invalid_init();
|
||||
ac = test_init();
|
||||
if (!ac)
|
||||
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_expanded[MAX_PATH];
|
||||
WCHAR localized[MAX_PATH];
|
||||
HRESULT hr;
|
||||
int id;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, startup, -1, startupW, sizeof(startupW)/sizeof(WCHAR));
|
||||
pSHGetLocalizedName(startupW, module, MAX_PATH, &id);
|
||||
ExpandEnvironmentStringsW(module, module_expanded, MAX_PATH);
|
||||
LoadStringW(GetModuleHandleW(module_expanded), id, localized, MAX_PATH);
|
||||
hr = pSHGetLocalizedName(startupW, module, MAX_PATH, &id);
|
||||
todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
/* 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
|
||||
{
|
||||
|
|
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>
|
||||
<file>appbar.c</file>
|
||||
<file>autocomplete.c</file>
|
||||
<file>brsfolder.c</file>
|
||||
<file>ebrowser.c</file>
|
||||
<file>generated.c</file>
|
||||
<file>progman_dde.c</file>
|
||||
<file>recyclebin.c</file>
|
||||
<file>shelldispatch.c</file>
|
||||
<file>shelllink.c</file>
|
||||
<file>shellole.c</file>
|
||||
<file>shellpath.c</file>
|
||||
<file>shfldr_special.c</file>
|
||||
<file>shlexec.c</file>
|
||||
<file>shlfileop.c</file>
|
||||
<file>shlfolder.c</file>
|
||||
|
@ -28,7 +34,6 @@
|
|||
<file>string.c</file>
|
||||
<file>systray.c</file>
|
||||
<file>testlist.c</file>
|
||||
<file>shfldr_special.c</file>
|
||||
<file>rsrc.rc</file>
|
||||
</module>
|
||||
</group>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* 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
|
||||
* 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,
|
||||
&IID_IShellLinkW, (LPVOID*)&slW);
|
||||
if (!slW)
|
||||
skip("SetPath with NULL parameter crashes on Win9x\n");
|
||||
if (!slW /* Win9x */ || !pGetLongPathNameA /* NT4 */)
|
||||
skip("SetPath with NULL parameter crashes on Win9x and some NT4\n");
|
||||
else
|
||||
{
|
||||
IShellLinkW_Release(slW);
|
||||
r = IShellLinkA_SetPath(sl, NULL);
|
||||
ok(r==E_INVALIDARG ||
|
||||
broken(r==S_OK), /* Some Win95 and NT4 */
|
||||
"SetPath failed (0x%08x)\n", r);
|
||||
"SetPath returned wrong error (0x%08x)\n", r);
|
||||
}
|
||||
|
||||
r = IShellLinkA_SetPath(sl, "");
|
||||
|
@ -204,16 +204,14 @@ static void test_get_set(void)
|
|||
/* Test the interaction of SetPath and SetIDList */
|
||||
tmp_pidl=NULL;
|
||||
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)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
strcpy(buffer,"garbage");
|
||||
ret = SHGetPathFromIDListA(tmp_pidl, buffer);
|
||||
todo_wine {
|
||||
ok(ret, "SHGetPathFromIDListA failed\n");
|
||||
}
|
||||
if (ret)
|
||||
ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
|
||||
pILFree(tmp_pidl);
|
||||
|
@ -326,9 +324,7 @@ static void test_get_set(void)
|
|||
i=0xdeadbeef;
|
||||
strcpy(buffer,"garbage");
|
||||
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
|
||||
todo_wine {
|
||||
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);
|
||||
|
||||
|
@ -435,7 +431,7 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
|
|||
if (0)
|
||||
{
|
||||
/* crashes on XP */
|
||||
r = IPersistFile_GetCurFile(pf, NULL);
|
||||
IPersistFile_GetCurFile(pf, NULL);
|
||||
}
|
||||
|
||||
/* test GetCurFile before ::Save */
|
||||
|
@ -685,6 +681,24 @@ static void test_load_save(void)
|
|||
create_lnk(lnkfile, &desc, 0);
|
||||
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 */
|
||||
desc.description="command on path";
|
||||
desc.workdir=mypath;
|
||||
|
@ -701,6 +715,22 @@ static void test_load_save(void)
|
|||
desc.path=realpath;
|
||||
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 */
|
||||
r=GetTempPath(sizeof(mypath), mypath);
|
||||
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);
|
||||
|
||||
r=pGetShortPathNameA(mydir, mypath, sizeof(mypath));
|
||||
ok(r<sizeof(mypath), "GetShortPathName failed (%d), err %d\n", r, GetLastError());
|
||||
|
||||
strcpy(realpath, mypath);
|
||||
strcat(realpath, "\\test.txt");
|
||||
strcat(mypath, "\\\\test.txt");
|
||||
|
@ -751,6 +783,36 @@ static void test_load_save(void)
|
|||
r = DeleteFileA(mypath);
|
||||
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
|
||||
* represented as a path.
|
||||
*/
|
||||
|
@ -812,16 +874,21 @@ static void test_datalink(void)
|
|||
ok( r == E_FAIL, "CopyDataBlock failed\n");
|
||||
ok( dar == NULL, "should be null\n");
|
||||
|
||||
r = IShellLinkW_SetPath(sl, NULL);
|
||||
ok(r == E_INVALIDARG, "set path failed\n");
|
||||
if (!pGetLongPathNameA /* NT4 */)
|
||||
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);
|
||||
ok(r == S_OK, "set path failed\n");
|
||||
ok(r == S_OK, "SetPath failed\n");
|
||||
|
||||
if (0)
|
||||
{
|
||||
/* the following crashes */
|
||||
r = IShellLinkDataList_GetFlags( dl, NULL );
|
||||
IShellLinkDataList_GetFlags( dl, NULL );
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
|
@ -872,6 +939,66 @@ static void test_shdefextracticon(void)
|
|||
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)
|
||||
{
|
||||
HRESULT r;
|
||||
|
@ -895,6 +1022,7 @@ START_TEST(shelllink)
|
|||
test_load_save();
|
||||
test_datalink();
|
||||
test_shdefextracticon();
|
||||
test_GetIconLocation();
|
||||
|
||||
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)
|
||||
{
|
||||
/* crashes on XP */
|
||||
hr = IShellFolder2_GetDetailsOf(folder, NULL, 0, NULL);
|
||||
hr = IShellFolder2_GetDefaultColumnState(folder, 0, NULL);
|
||||
hr = IPersistFolder2_GetCurFolder(pf, NULL);
|
||||
IShellFolder2_GetDetailsOf(folder, NULL, 0, NULL);
|
||||
IShellFolder2_GetDefaultColumnState(folder, 0, NULL);
|
||||
IPersistFolder2_GetCurFolder(pf, NULL);
|
||||
}
|
||||
|
||||
/* 5 columns defined */
|
||||
|
@ -162,8 +162,11 @@ if (0)
|
|||
hr = IShellFolder2_GetDefaultColumnState(folder, 6, &state);
|
||||
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);
|
||||
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 */
|
||||
if (hr == S_OK)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,7 @@ static char tmpdir[MAX_PATH];
|
|||
static char child_file[MAX_PATH];
|
||||
static DLLVERSIONINFO dllver;
|
||||
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)
|
||||
{
|
||||
char* filename;
|
||||
char *filename, longpath[MAX_PATH] = "";
|
||||
HANDLE hFile, map;
|
||||
int i;
|
||||
int rc;
|
||||
|
@ -552,6 +553,8 @@ static void doChild(int argc, char** argv)
|
|||
trace("argvA%d=%s\n", i, 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");
|
||||
if (map != NULL)
|
||||
|
@ -572,13 +575,14 @@ static void doChild(int argc, char** argv)
|
|||
|
||||
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);
|
||||
CloseHandle(dde_ready);
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
DispatchMessage(&msg);
|
||||
|
||||
Sleep(500);
|
||||
KillTimer(NULL, timer);
|
||||
assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER));
|
||||
assert(DdeFreeStringHandle(ddeInst, hszTopic));
|
||||
|
@ -587,7 +591,7 @@ static void doChild(int argc, char** argv)
|
|||
}
|
||||
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);
|
||||
CloseHandle(dde_ready);
|
||||
}
|
||||
|
@ -676,6 +680,11 @@ static void _okChildString(const char* file, int line, const char* key, const ch
|
|||
{
|
||||
char* result;
|
||||
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,
|
||||
"%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;
|
||||
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,
|
||||
"%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;
|
||||
}
|
||||
|
||||
/***
|
||||
*
|
||||
* 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
|
||||
|
@ -1613,14 +1647,7 @@ static dde_tests_t dde_tests[] =
|
|||
|
||||
static DWORD WINAPI hooked_WaitForInputIdle(HANDLE process, DWORD timeout)
|
||||
{
|
||||
HANDLE dde_ready;
|
||||
DWORD wait_result;
|
||||
|
||||
dde_ready = CreateEventA(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready");
|
||||
wait_result = WaitForSingleObject(dde_ready, timeout);
|
||||
CloseHandle(dde_ready);
|
||||
|
||||
return wait_result;
|
||||
return WaitForSingleObject(dde_ready_event, timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1714,7 +1741,7 @@ static void test_dde(void)
|
|||
{
|
||||
if (!create_test_association(".sde"))
|
||||
{
|
||||
skip("Unable to create association for '.sfe'\n");
|
||||
skip("Unable to create association for '.sde'\n");
|
||||
return;
|
||||
}
|
||||
create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec,
|
||||
|
@ -1732,7 +1759,9 @@ static void test_dde(void)
|
|||
}
|
||||
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);
|
||||
CloseHandle(dde_ready_event);
|
||||
if ((test->todo & 0x1)==0)
|
||||
{
|
||||
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 chkfmt4[] = {'%','s','=','%','s','\"',' ','%','s','\"',0};
|
||||
WCHAR cmdline[255];
|
||||
LPWSTR *args = (LPWSTR*)0xdeadcafe;
|
||||
LPWSTR *args = (LPWSTR*)0xdeadcafe, pbuf;
|
||||
INT numargs = -1;
|
||||
size_t buflen;
|
||||
|
||||
wsprintfW(cmdline,fmt1,one,two,three,four);
|
||||
args=CommandLineToArgvW(cmdline,&numargs);
|
||||
|
@ -2170,6 +2200,46 @@ static void test_commandline(void)
|
|||
wsprintfW(cmdline,fmt6);
|
||||
args=CommandLineToArgvW(cmdline,&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)
|
||||
|
@ -2194,6 +2264,7 @@ START_TEST(shlexec)
|
|||
test_dde();
|
||||
test_dde_default_app();
|
||||
test_commandline();
|
||||
test_directory();
|
||||
|
||||
cleanup_test();
|
||||
}
|
||||
|
|
|
@ -820,6 +820,7 @@ static void test_copy(void)
|
|||
DWORD retval;
|
||||
LPSTR ptr;
|
||||
BOOL on_nt4 = FALSE;
|
||||
BOOL ret;
|
||||
|
||||
if (old_shell32)
|
||||
{
|
||||
|
@ -973,16 +974,16 @@ static void test_copy(void)
|
|||
shfo.pTo = "test2.txt\0";
|
||||
/* suppress the error-dialog in win9x here */
|
||||
shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
|
||||
ok(SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY),
|
||||
"Failure to set file attributes (error %x)\n", GetLastError());
|
||||
ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY);
|
||||
ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
|
||||
retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
|
||||
ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
|
||||
retval = SHFileOperationA(&shfo);
|
||||
/* Does not work on Win95, Win95B, NT4WS and NT4SRV */
|
||||
ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %x)\n", retval);
|
||||
/* Set back normal attributes to make the file deletion succeed */
|
||||
ok(SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL),
|
||||
"Failure to set file attributes (error %x)\n", GetLastError());
|
||||
ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL);
|
||||
ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
|
||||
shfo.fFlags = tmp_flags;
|
||||
|
||||
/* 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("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(!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("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);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -2065,6 +2067,7 @@ static void test_sh_path_prepare(void)
|
|||
HRESULT res;
|
||||
CHAR path[MAX_PATH];
|
||||
CHAR UNICODE_PATH_A[MAX_PATH];
|
||||
BOOL UsedDefaultChar;
|
||||
|
||||
if(!pSHPathPrepareForWriteA)
|
||||
{
|
||||
|
@ -2156,7 +2159,19 @@ static void test_sh_path_prepare(void)
|
|||
win_skip("Skipping SHPathPrepareForWriteW tests\n");
|
||||
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 */
|
||||
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 = 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,
|
||||
(LONG_PTR)listview_subclass_proc);
|
||||
|
@ -86,28 +96,71 @@ static HWND subclass_listview(HWND hwnd)
|
|||
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 */
|
||||
typedef struct {
|
||||
const IDataObjectVtbl *lpVtbl;
|
||||
IDataObject IDataObject_iface;
|
||||
LONG ref;
|
||||
} IDataObjectImpl;
|
||||
|
||||
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)
|
||||
{
|
||||
IDataObjectImpl *obj;
|
||||
|
||||
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
|
||||
obj->lpVtbl = &IDataObjectImpl_Vtbl;
|
||||
obj->IDataObject_iface.lpVtbl = &IDataObjectImpl_Vtbl;
|
||||
obj->ref = 1;
|
||||
|
||||
return (IDataObject*)obj;
|
||||
return &obj->IDataObject_iface;
|
||||
}
|
||||
|
||||
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) ||
|
||||
IsEqualIID(riid, &IID_IDataObject))
|
||||
|
@ -126,13 +179,13 @@ static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID
|
|||
|
||||
static ULONG WINAPI IDataObjectImpl_AddRef(IDataObject * iface)
|
||||
{
|
||||
IDataObjectImpl *This = (IDataObjectImpl *)iface;
|
||||
IDataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDataObjectImpl_Release(IDataObject * iface)
|
||||
{
|
||||
IDataObjectImpl *This = (IDataObjectImpl *)iface;
|
||||
IDataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (!ref)
|
||||
|
@ -210,28 +263,33 @@ static const IDataObjectVtbl IDataObjectImpl_Vtbl =
|
|||
|
||||
/* dummy IShellBrowser implementation */
|
||||
typedef struct {
|
||||
const IShellBrowserVtbl *lpVtbl;
|
||||
IShellBrowser IShellBrowser_iface;
|
||||
LONG ref;
|
||||
} IShellBrowserImpl;
|
||||
|
||||
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)
|
||||
{
|
||||
IShellBrowserImpl *browser;
|
||||
|
||||
browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
|
||||
browser->lpVtbl = &IShellBrowserImpl_Vtbl;
|
||||
browser->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl;
|
||||
browser->ref = 1;
|
||||
|
||||
return (IShellBrowser*)browser;
|
||||
return &browser->IShellBrowser_iface;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
|
||||
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
|
||||
|
||||
*ppvObj = NULL;
|
||||
|
||||
|
@ -253,13 +311,13 @@ static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
|
|||
|
||||
static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
|
||||
{
|
||||
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
|
||||
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
|
||||
{
|
||||
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
|
||||
IShellBrowserImpl *This = impl_from_IShellBrowser(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (!ref)
|
||||
|
@ -423,7 +481,7 @@ static const struct message folderview_getselectionmarked_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 }
|
||||
};
|
||||
|
||||
|
@ -451,7 +509,7 @@ static void test_IShellView_CreateViewWindow(void)
|
|||
if (0)
|
||||
{
|
||||
/* crashes on native */
|
||||
hr = IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
|
||||
IShellView_CreateViewWindow(view, NULL, &settings, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
settings.ViewMode = FVM_ICON;
|
||||
|
@ -487,7 +545,7 @@ static void test_IFolderView(void)
|
|||
HWND hwnd_view, hwnd_list;
|
||||
PITEMID_CHILD pidl;
|
||||
HRESULT hr;
|
||||
INT ret;
|
||||
INT ret, count;
|
||||
POINT pt;
|
||||
LONG ref1, ref2;
|
||||
RECT r;
|
||||
|
@ -519,14 +577,14 @@ static void test_IFolderView(void)
|
|||
if (0)
|
||||
{
|
||||
/* crashes on Vista and Win2k8 - List not created yet case */
|
||||
hr = IFolderView_GetSpacing(fv, &pt);
|
||||
IFolderView_GetSpacing(fv, &pt);
|
||||
|
||||
/* crashes on XP */
|
||||
hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
|
||||
hr = IFolderView_GetFocusedItem(fv, NULL);
|
||||
IFolderView_GetSelectionMarkedItem(fv, NULL);
|
||||
IFolderView_GetFocusedItem(fv, NULL);
|
||||
|
||||
/* crashes on Vista+ */
|
||||
hr = IFolderView_Item(fv, 0, NULL);
|
||||
IFolderView_Item(fv, 0, NULL);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
if (0)
|
||||
{
|
||||
/* crashes on XP */
|
||||
hr = IFolderView_GetSelectionMarkedItem(fv, NULL);
|
||||
IFolderView_GetSelectionMarkedItem(fv, NULL);
|
||||
}
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
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,
|
||||
"IFolderView::GetSelectionMarkedItem", FALSE);
|
||||
"IFolderView::GetSelectionMarkedItem", FALSE);
|
||||
|
||||
/* IFolderView::GetFocusedItem */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
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,
|
||||
"IFolderView::GetFocusedItem", FALSE);
|
||||
"IFolderView::GetFocusedItem", FALSE);
|
||||
|
||||
/* IFolderView::GetFolder, just return pointer */
|
||||
if (0)
|
||||
{
|
||||
/* crashes on XP */
|
||||
hr = IFolderView_GetFolder(fv, NULL, (void**)&folder);
|
||||
hr = IFolderView_GetFolder(fv, NULL, NULL);
|
||||
IFolderView_GetFolder(fv, NULL, (void**)&folder);
|
||||
IFolderView_GetFolder(fv, NULL, NULL);
|
||||
}
|
||||
|
||||
hr = IFolderView_GetFolder(fv, &IID_IShellFolder, NULL);
|
||||
|
@ -607,22 +681,10 @@ if (0)
|
|||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||
ref2 = IShellFolder_AddRef(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");
|
||||
|
||||
/* 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);
|
||||
IFolderView_Release(fv);
|
||||
IShellView_Release(view);
|
||||
|
@ -711,9 +773,9 @@ static void test_IShellFolderView(void)
|
|||
/* ::RemoveObject */
|
||||
i = 0xdeadbeef;
|
||||
hr = IShellFolderView_RemoveObject(folderview, NULL, &i);
|
||||
ok(hr == S_OK, "got (0x%08x)\n", hr);
|
||||
ok(i == 0 || i == -1 /* Win7 */ || broken(i == 0xdeadbeef) /* Vista, 2k8 */,
|
||||
"got %d\n", i);
|
||||
ok(hr == S_OK || hr == E_FAIL, "got (0x%08x)\n", hr);
|
||||
if (hr == S_OK) ok(i == 0 || broken(i == 0xdeadbeef) /* Vista, 2k8 */,
|
||||
"got %d\n", i);
|
||||
|
||||
IShellFolderView_Release(folderview);
|
||||
|
||||
|
@ -743,6 +805,352 @@ static void test_IOleWindow(void)
|
|||
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)
|
||||
{
|
||||
OleInitialize(NULL);
|
||||
|
@ -754,6 +1162,8 @@ START_TEST(shlview)
|
|||
test_GetItemObject();
|
||||
test_IShellFolderView();
|
||||
test_IOleWindow();
|
||||
test_GetSetCurrentViewMode();
|
||||
test_IOleCommandTarget();
|
||||
|
||||
OleUninitialize();
|
||||
}
|
||||
|
|
|
@ -45,19 +45,15 @@ static void test_cbsize(void)
|
|||
nidW.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
nidW.uCallbackMessage = WM_USER+17;
|
||||
ret = pShell_NotifyIconW(NIM_ADD, &nidW);
|
||||
if (ret)
|
||||
{
|
||||
/* using an invalid cbSize does work */
|
||||
nidW.cbSize = 3;
|
||||
nidW.hWnd = hMainWnd;
|
||||
nidW.uID = 1;
|
||||
ret = pShell_NotifyIconW(NIM_DELETE, &nidW);
|
||||
ok( ret || broken(!ret), /* nt4 */ "NIM_DELETE failed!\n");
|
||||
/* as icon doesn't exist anymore - now there will be an error */
|
||||
nidW.cbSize = sizeof(nidW);
|
||||
ok(!pShell_NotifyIconW(NIM_DELETE, &nidW) != !ret, "The icon was not deleted\n");
|
||||
}
|
||||
else win_skip( "Shell_NotifyIconW not working\n" ); /* win9x */
|
||||
/* using an invalid cbSize does work */
|
||||
nidW.cbSize = 3;
|
||||
nidW.hWnd = hMainWnd;
|
||||
nidW.uID = 1;
|
||||
ret = pShell_NotifyIconW(NIM_DELETE, &nidW);
|
||||
ok( ret || broken(!ret), /* nt4 */ "NIM_DELETE failed!\n");
|
||||
/* as icon doesn't exist anymore - now there will be an error */
|
||||
nidW.cbSize = sizeof(nidW);
|
||||
ok(!pShell_NotifyIconW(NIM_DELETE, &nidW) != !ret, "The icon was not deleted\n");
|
||||
}
|
||||
|
||||
/* same for Shell_NotifyIconA */
|
||||
|
@ -75,7 +71,7 @@ static void test_cbsize(void)
|
|||
nidA.hWnd = hMainWnd;
|
||||
nidA.uID = 1;
|
||||
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 */
|
||||
nidA.cbSize = sizeof(nidA);
|
||||
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_autocomplete(void);
|
||||
extern void func_brsfolder(void);
|
||||
extern void func_ebrowser(void);
|
||||
extern void func_generated(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_shellole(void);
|
||||
extern void func_shellpath(void);
|
||||
extern void func_shfldr_special(void);
|
||||
extern void func_shlexec(void);
|
||||
|
@ -23,16 +28,21 @@ extern void func_systray(void);
|
|||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "appbar", func_appbar },
|
||||
{ "autocomplete", func_autocomplete },
|
||||
{ "generated", func_generated },
|
||||
{ "progman_dde", func_progman_dde },
|
||||
{ "autocomplete", func_autocomplete },
|
||||
{ "brsfolder", func_brsfolder },
|
||||
{ "ebrowser", func_ebrowser },
|
||||
{ "generated", func_generated },
|
||||
{ "progman_dde", func_progman_dde },
|
||||
{ "recyclebin", func_recyclebin },
|
||||
{ "shelldispatch", func_shelldispatch },
|
||||
{ "shelllink", func_shelllink },
|
||||
{ "shellole", func_shellole },
|
||||
{ "shellpath", func_shellpath },
|
||||
{ "shfldr_special", func_shfldr_special },
|
||||
{ "shfldr_special", func_shfldr_special },
|
||||
{ "shlexec", func_shlexec },
|
||||
{ "shlfileop", func_shlfileop },
|
||||
{ "shlfolder", func_shlfolder },
|
||||
{ "shlview", func_shlview },
|
||||
{ "shlview", func_shlview },
|
||||
{ "string", func_string },
|
||||
{ "systray", func_systray },
|
||||
{ 0, 0 }
|
||||
|
|
Loading…
Reference in a new issue