[SHELL32]

* Reintegrate the c++ shell32 branch. Exemplary team-work.. kudos !
* Better code quality, more tests run with less failures... and more.
* Dedicated to everyone who helped ;)

svn path=/trunk/; revision=53653
This commit is contained in:
Amine Khaldi 2011-09-09 10:55:09 +00:00
commit 3bb734fcf3
145 changed files with 51026 additions and 293 deletions

View file

@ -1,3 +1,4 @@
set_cpp()
remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x600)
@ -10,71 +11,78 @@ add_definitions(
include_directories(
${REACTOS_SOURCE_DIR}/include/reactos/wine
${REACTOS_SOURCE_DIR}/lib/recyclebin
${REACTOS_SOURCE_DIR}/lib/atl
${REACTOS_SOURCE_DIR})
spec2def(shell32.dll shell32.spec)
list(APPEND SOURCE
authors.c
autocomplete.c
brsfolder.c
changenotify.c
classes.c
clipboard.c
control.c
dataobject.c
dde.c
debughlp.c
desktop.c
dialogs.c
dragdrophelper.c
enumidlist.c
extracticon.c
folders.c
iconcache.c
pidl.c
regsvr.c
shell32_main.c
shellitem.c
shelllink.c
shellole.c
shellord.c
shellpath.c
shellreg.c
shellstring.c
shfldr_desktop.c
shfldr_fs.c
shfldr_mycomp.c
shfldr_mydocuments.c
shfldr_printers.c
shfldr_admintools.c
shfldr_netplaces.c
shfldr_fonts.c
shfldr_cpanel.c
shfldr_recyclebin.c
shlexec.c
shlfileop.c
shlfolder.c
shlfsbind.c
shlmenu.c
shlview.c
shpolicy.c
shv_def_cmenu.c
startmenu.c
stubs.c
ros-systray.c
fprop.c
drive.c
she_ocmenu.c
shv_item_new.c
folder_options.c
authors.cpp
autocomplete.cpp
brsfolder.cpp
changenotify.cpp
classes.cpp
clipboard.cpp
control.cpp
dataobject.cpp
dde.cpp
debughlp.cpp
desktop.cpp
dialogs.cpp
dragdrophelper.cpp
enumidlist.cpp
extracticon.cpp
folders.cpp
iconcache.cpp
pidl.cpp
shell32_main.cpp
shellitem.cpp
shelllink.cpp
shellole.cpp
shellord.cpp
shellpath.cpp
shellreg.cpp
shellstring.cpp
shfldr_desktop.cpp
shfldr_fs.cpp
shfldr_mycomp.cpp
shfldr_mydocuments.cpp
shfldr_printers.cpp
shfldr_admintools.cpp
shfldr_netplaces.cpp
shfldr_fonts.cpp
shfldr_cpanel.cpp
shfldr_recyclebin.cpp
shlexec.cpp
shlfileop.cpp
shlfolder.cpp
shlfsbind.cpp
shlmenu.cpp
shlview.cpp
shpolicy.cpp
shv_def_cmenu.cpp
startmenu.cpp
stubs.cpp
ros-systray.cpp
fprop.cpp
drive.cpp
she_ocmenu.cpp
shv_item_new.cpp
folder_options.cpp
shell32.rc
${CMAKE_CURRENT_BINARY_DIR}/shell32_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/shell32.def)
add_library(shell32 SHARED ${SOURCE})
set_module_type(shell32 win32dll)
target_link_libraries(shell32 wine uuid recyclebin)
set_module_type(shell32 win32dll UNICODE)
target_link_libraries(shell32
atlnew
wine
uuid
recyclebin)
add_delay_importlibs(shell32 ole32 version)
add_importlibs(shell32
@ -92,5 +100,6 @@ add_importlibs(shell32
ntdll)
add_pch(shell32 precomp.h)
add_cd_file(TARGET shell32 DESTINATION reactos/system32 FOR all)
add_importlib_target(shell32.spec)

View file

@ -0,0 +1,336 @@
LONG WINAPI RegCopyTreeX(HKEY, LPCWSTR, HKEY)
{
DebugBreak();
return 0;
}
static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
{
HGLOBAL hMemory;
HRSRC hResource;
WCHAR *pString;
int idxString;
/* Negative values have to be inverted. */
if (HIWORD(resId) == 0xffff)
resId = (UINT)(-((INT)resId));
/* Load the resource into memory and get a pointer to it. */
hResource = FindResourceW(hModule, MAKEINTRESOURCEW(LOWORD(resId >> 4) + 1), (LPWSTR)RT_STRING);
if (!hResource) return 0;
hMemory = LoadResource(hModule, hResource);
if (!hMemory) return 0;
pString = (WCHAR *)LockResource(hMemory);
/* Strings are length-prefixed. Lowest nibble of resId is an index. */
idxString = resId & 0xf;
while (idxString--) pString += *pString + 1;
/* If no buffer is given, return length of the string. */
if (!pwszBuffer) return *pString;
/* Else copy over the string, respecting the buffer size. */
cMaxChars = (*pString < cMaxChars) ? *pString : (cMaxChars - 1);
if (cMaxChars >= 0)
{
memcpy(pwszBuffer, pString+1, cMaxChars * sizeof(WCHAR));
pwszBuffer[cMaxChars] = L'\0';
}
return cMaxChars;
}
LONG WINAPI
RegLoadMUIStringWX(IN HKEY hKey,
IN LPCWSTR pszValue OPTIONAL,
OUT LPWSTR pszOutBuf,
IN DWORD cbOutBuf,
OUT LPDWORD pcbData OPTIONAL,
IN DWORD Flags,
IN LPCWSTR pszDirectory OPTIONAL)
{
DWORD dwValueType, cbData;
LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL;
LONG result;
/* Parameter sanity checks. */
if (!hKey || !pszOutBuf)
return ERROR_INVALID_PARAMETER;
if (pszDirectory && *pszDirectory)
{
return ERROR_INVALID_PARAMETER;
}
/* Check for value existence and correctness of it's type, allocate a buffer and load it. */
result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, NULL, &cbData);
if (result != ERROR_SUCCESS) goto cleanup;
if (!(dwValueType == REG_SZ || dwValueType == REG_EXPAND_SZ) || !cbData)
{
result = ERROR_FILE_NOT_FOUND;
goto cleanup;
}
pwszTempBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cbData);
if (!pwszTempBuffer)
{
result = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, (LPBYTE)pwszTempBuffer, &cbData);
if (result != ERROR_SUCCESS) goto cleanup;
/* Expand environment variables, if appropriate, or copy the original string over. */
if (dwValueType == REG_EXPAND_SZ)
{
cbData = ExpandEnvironmentStringsW(pwszTempBuffer, NULL, 0) * sizeof(WCHAR);
if (!cbData) goto cleanup;
pwszExpandedBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cbData);
if (!pwszExpandedBuffer)
{
result = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData);
}
else
{
pwszExpandedBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cbData);
memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData);
}
/* If the value references a resource based string, parse the value and load the string.
* Else just copy over the original value. */
result = ERROR_SUCCESS;
if (*pwszExpandedBuffer != L'@') /* '@' is the prefix for resource based string entries. */
{
lstrcpynW(pszOutBuf, pwszExpandedBuffer, cbOutBuf / sizeof(WCHAR));
}
else
{
WCHAR *pComma = wcsrchr(pwszExpandedBuffer, L',');
UINT uiStringId;
HMODULE hModule;
/* Format of the expanded value is 'path_to_dll,-resId' */
if (!pComma || pComma[1] != L'-')
{
result = ERROR_BADKEY;
goto cleanup;
}
uiStringId = _wtoi(pComma+2);
*pComma = L'\0';
hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (!hModule || !load_string(hModule, uiStringId, pszOutBuf, cbOutBuf / sizeof(WCHAR)))
result = ERROR_BADKEY;
FreeLibrary(hModule);
}
cleanup:
HeapFree(GetProcessHeap(), 0, pwszTempBuffer);
HeapFree(GetProcessHeap(), 0, pwszExpandedBuffer);
return result;
}
#if 0
VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString);
#else
typedef VOID (WINAPI *PRtlFreeUnicodeString)(PUNICODE_STRING UnicodeString);
static VOID WINAPI
RtlFreeUnicodeStringx(PUNICODE_STRING UnicodeString)
{
static PRtlFreeUnicodeString Func = NULL;
if (Func == NULL)
{
HMODULE hShlwapi;
hShlwapi = LoadLibrary(TEXT("ntdll.DLL"));
if (hShlwapi != NULL)
{
Func = (PRtlFreeUnicodeString)GetProcAddress(hShlwapi, "RtlFreeUnicodeString");
}
}
if (Func != NULL)
{
Func(UnicodeString);
return;
}
MessageBox(NULL, TEXT("RtlFreeUnicodeString not available"), NULL, 0);
}
#endif
LONG WINAPI
RegLoadMUIStringAX(IN HKEY hKey,
IN LPCSTR pszValue OPTIONAL,
OUT LPSTR pszOutBuf,
IN DWORD cbOutBuf,
OUT LPDWORD pcbData OPTIONAL,
IN DWORD Flags,
IN LPCSTR pszDirectory OPTIONAL)
{
UNICODE_STRING valueW, baseDirW;
WCHAR *pwszBuffer;
DWORD cbData = cbOutBuf * sizeof(WCHAR);
LONG result;
valueW.Buffer = baseDirW.Buffer = pwszBuffer = NULL;
if (!RtlCreateUnicodeStringFromAsciiz(&valueW, pszValue) ||
!RtlCreateUnicodeStringFromAsciiz(&baseDirW, pszDirectory) ||
!(pwszBuffer = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, cbData)))
{
result = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
result = RegLoadMUIStringWX(hKey, valueW.Buffer, pwszBuffer, cbData, NULL, Flags,
baseDirW.Buffer);
if (result == ERROR_SUCCESS)
{
cbData = WideCharToMultiByte(CP_ACP, 0, pwszBuffer, -1, pszOutBuf, cbOutBuf, NULL, NULL);
if (pcbData)
*pcbData = cbData;
}
cleanup:
HeapFree(GetProcessHeap(), 0, pwszBuffer);
RtlFreeUnicodeStringx(&baseDirW);
RtlFreeUnicodeStringx(&valueW);
return result;
}
static VOID
RegpApplyRestrictions(DWORD dwFlags,
DWORD dwType,
DWORD cbData,
PLONG ret)
{
/* Check if the type is restricted by the passed flags */
if (*ret == ERROR_SUCCESS || *ret == ERROR_MORE_DATA)
{
DWORD dwMask = 0;
switch (dwType)
{
case REG_NONE: dwMask = RRF_RT_REG_NONE; break;
case REG_SZ: dwMask = RRF_RT_REG_SZ; break;
case REG_EXPAND_SZ: dwMask = RRF_RT_REG_EXPAND_SZ; break;
case REG_MULTI_SZ: dwMask = RRF_RT_REG_MULTI_SZ; break;
case REG_BINARY: dwMask = RRF_RT_REG_BINARY; break;
case REG_DWORD: dwMask = RRF_RT_REG_DWORD; break;
case REG_QWORD: dwMask = RRF_RT_REG_QWORD; break;
}
if (dwFlags & dwMask)
{
/* Type is not restricted, check for size mismatch */
if (dwType == REG_BINARY)
{
DWORD cbExpect = 0;
if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
cbExpect = 4;
else if ((dwFlags & RRF_RT_QWORD) == RRF_RT_QWORD)
cbExpect = 8;
if (cbExpect && cbData != cbExpect)
*ret = ERROR_DATATYPE_MISMATCH;
}
}
else *ret = ERROR_UNSUPPORTED_TYPE;
}
}
LONG WINAPI RegGetValueX(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
{
DWORD dwType, cbData = pcbData ? *pcbData : 0;
PVOID pvBuf = NULL;
LONG ret;
if (pvData && !pcbData)
return ERROR_INVALID_PARAMETER;
if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND) &&
((dwFlags & RRF_RT_ANY) != RRF_RT_ANY))
return ERROR_INVALID_PARAMETER;
if (pszSubKey && pszSubKey[0])
{
ret = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
if (ret != ERROR_SUCCESS) return ret;
}
ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, (LPBYTE)pvData, &cbData);
/* If we are going to expand we need to read in the whole the value even
* if the passed buffer was too small as the expanded string might be
* smaller than the unexpanded one and could fit into cbData bytes. */
if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) &&
dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND))
{
do
{
HeapFree(GetProcessHeap(), 0, pvBuf);
pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
if (!pvBuf)
{
ret = ERROR_NOT_ENOUGH_MEMORY;
break;
}
if (ret == ERROR_MORE_DATA || !pvData)
ret = RegQueryValueExW(hKey, pszValue, NULL,
&dwType, (LPBYTE)pvBuf, &cbData);
else
{
/* Even if cbData was large enough we have to copy the
* string since ExpandEnvironmentStrings can't handle
* overlapping buffers. */
CopyMemory(pvBuf, pvData, cbData);
}
/* Both the type or the value itself could have been modified in
* between so we have to keep retrying until the buffer is large
* enough or we no longer have to expand the value. */
}
while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
if (ret == ERROR_SUCCESS)
{
/* Recheck dwType in case it changed since the first call */
if (dwType == REG_EXPAND_SZ)
{
cbData = ExpandEnvironmentStringsW((LPCWSTR)pvBuf, (LPWSTR)pvData,
pcbData ? *pcbData : 0) * sizeof(WCHAR);
dwType = REG_SZ;
if (pvData && pcbData && cbData > *pcbData)
ret = ERROR_MORE_DATA;
}
else if (pvData)
CopyMemory(pvData, pvBuf, *pcbData);
}
HeapFree(GetProcessHeap(), 0, pvBuf);
}
if (pszSubKey && pszSubKey[0])
RegCloseKey(hKey);
RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
if (pvData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE))
ZeroMemory(pvData, *pcbData);
if (pdwType)
*pdwType = dwType;
if (pcbData)
*pcbData = cbData;
return ret;
}

View file

@ -0,0 +1,11 @@
#ifndef _GLUE_CODE_H_
#define _GLUE_CODE_H_
LONG WINAPI RegCopyTreeX(HKEY, LPCWSTR, HKEY);
LONG WINAPI RegGetValueX(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
LONG WINAPI RegLoadMUIStringWX(IN HKEY hKey, IN LPCWSTR pszValue OPTIONAL, OUT LPWSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCWSTR pszDirectory OPTIONAL);
LONG WINAPI RegLoadMUIStringAX(IN HKEY hKey, IN LPCSTR pszValue OPTIONAL, OUT LPSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCSTR pszDirectory OPTIONAL);
#endif

View file

@ -0,0 +1,2 @@
const char * const SHELL_Authors[] = { "Copyright 1993-2011 WINE team", "Copyright 1998-2011 ReactOS Team", 0 };

View file

@ -0,0 +1,515 @@
/*
* AutoComplete interfaces implementation.
*
* Copyright 2004 Maxime Bellengé <maxime.bellenge@laposte.net>
* Copyright 2009 Andrew Hill
*
* 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
*/
/*
Implemented:
- ACO_AUTOAPPEND style
- ACO_AUTOSUGGEST style
- ACO_UPDOWNKEYDROPSLIST style
- Handle pwzsRegKeyPath and pwszQuickComplete in Init
TODO:
- implement ACO_SEARCH style
- implement ACO_FILTERPREFIXES style
- implement ACO_USETAB style
- implement ACO_RTLREADING style
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/**************************************************************************
* IAutoComplete_Constructor
*/
CAutoComplete::CAutoComplete()
{
enabled = TRUE;
options = ACO_AUTOAPPEND;
wpOrigEditProc = NULL;
hwndListBox = NULL;
txtbackup = NULL;
quickComplete = NULL;
hwndEdit = NULL;
wpOrigLBoxProc = NULL;
}
/**************************************************************************
* IAutoComplete_Destructor
*/
CAutoComplete::~CAutoComplete()
{
TRACE(" destroying IAutoComplete(%p)\n", this);
HeapFree(GetProcessHeap(), 0, quickComplete);
HeapFree(GetProcessHeap(), 0, txtbackup);
if (hwndListBox)
DestroyWindow(hwndListBox);
}
/******************************************************************************
* IAutoComplete_fnEnable
*/
HRESULT WINAPI CAutoComplete::Enable(BOOL fEnable)
{
HRESULT hr = S_OK;
TRACE("(%p)->(%s)\n", this, (fEnable) ? "true" : "false");
enabled = fEnable;
return hr;
}
/******************************************************************************
* IAutoComplete_fnInit
*/
HRESULT WINAPI CAutoComplete::Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwzsRegKeyPath, LPCOLESTR pwszQuickComplete)
{
static const WCHAR lbName[] = {'L','i','s','t','B','o','x',0};
TRACE("(%p)->(0x%08lx, %p, %s, %s)\n",
this, hwndEdit, punkACL, debugstr_w(pwzsRegKeyPath), debugstr_w(pwszQuickComplete));
if (options & ACO_AUTOSUGGEST)
TRACE(" ACO_AUTOSUGGEST\n");
if (options & ACO_AUTOAPPEND)
TRACE(" ACO_AUTOAPPEND\n");
if (options & ACO_SEARCH)
FIXME(" ACO_SEARCH not supported\n");
if (options & ACO_FILTERPREFIXES)
FIXME(" ACO_FILTERPREFIXES not supported\n");
if (options & ACO_USETAB)
FIXME(" ACO_USETAB not supported\n");
if (options & ACO_UPDOWNKEYDROPSLIST)
TRACE(" ACO_UPDOWNKEYDROPSLIST\n");
if (options & ACO_RTLREADING)
FIXME(" ACO_RTLREADING not supported\n");
hwndEdit = hwndEdit;
if (!SUCCEEDED (punkACL->QueryInterface(IID_IEnumString, (LPVOID *)&enumstr)))
{
TRACE("No IEnumString interface\n");
return E_NOINTERFACE;
}
wpOrigEditProc = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
SetWindowLongPtrW(hwndEdit, GWLP_USERDATA, (LONG_PTR)this);
if (options & ACO_AUTOSUGGEST)
{
HWND hwndParent;
hwndParent = GetParent(hwndEdit);
/* FIXME : The listbox should be resizable with the mouse. WS_THICKFRAME looks ugly */
hwndListBox = CreateWindowExW(0, lbName, NULL,
WS_BORDER | WS_CHILD | WS_VSCROLL | LBS_HASSTRINGS | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hwndParent, NULL,
(HINSTANCE)GetWindowLongPtrW(hwndParent, GWLP_HINSTANCE), NULL);
if (hwndListBox)
{
wpOrigLBoxProc = (WNDPROC)SetWindowLongPtrW(hwndListBox, GWLP_WNDPROC, (LONG_PTR)ACLBoxSubclassProc);
SetWindowLongPtrW(hwndListBox, GWLP_USERDATA, (LONG_PTR)this);
}
}
if (pwzsRegKeyPath)
{
WCHAR *key;
WCHAR result[MAX_PATH];
WCHAR *value;
HKEY hKey = 0;
LONG res;
LONG len;
/* pwszRegKeyPath contains the key as well as the value, so we split */
key = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pwzsRegKeyPath) + 1) * sizeof(WCHAR));
if (key)
{
wcscpy(key, pwzsRegKeyPath);
value = const_cast<WCHAR *>(strrchrW(key, '\\'));
if (value)
{
*value = 0;
value++;
/* Now value contains the value and buffer the key */
res = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
if (res != ERROR_SUCCESS)
{
/* if the key is not found, MSDN states we must seek in HKEY_LOCAL_MACHINE */
res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey);
}
if (res == ERROR_SUCCESS)
{
res = RegQueryValueW(hKey, value, result, &len);
if (res == ERROR_SUCCESS)
{
quickComplete = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
wcscpy(quickComplete, result);
}
RegCloseKey(hKey);
}
}
HeapFree(GetProcessHeap(), 0, key);
}
else
{
TRACE("HeapAlloc Failed when trying to alloca %d bytes\n", (wcslen(pwzsRegKeyPath) + 1) * sizeof(WCHAR));
return S_FALSE;
}
}
if ((pwszQuickComplete) && (!quickComplete))
{
quickComplete = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pwszQuickComplete) + 1) * sizeof(WCHAR));
if (quickComplete)
{
wcscpy(quickComplete, pwszQuickComplete);
}
else
{
TRACE("HeapAlloc Failed when trying to alloca %d bytes\n", (wcslen(pwszQuickComplete) + 1) * sizeof(WCHAR));
return S_FALSE;
}
}
return S_OK;
}
/**************************************************************************
* IAutoComplete_fnGetOptions
*/
HRESULT WINAPI CAutoComplete::GetOptions(DWORD *pdwFlag)
{
HRESULT hr = S_OK;
TRACE("(%p) -> (%p)\n", this, pdwFlag);
*pdwFlag = options;
return hr;
}
/**************************************************************************
* IAutoComplete_fnSetOptions
*/
HRESULT WINAPI CAutoComplete::SetOptions(DWORD dwFlag)
{
HRESULT hr = S_OK;
TRACE("(%p) -> (0x%x)\n", this, dwFlag);
options = (AUTOCOMPLETEOPTIONS)dwFlag;
return hr;
}
/*
Window procedure for autocompletion
*/
LRESULT APIENTRY CAutoComplete::ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CAutoComplete *pThis = (CAutoComplete *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
LPOLESTR strs;
HRESULT hr;
WCHAR hwndText[255];
WCHAR *hwndQCText;
RECT r;
BOOL control, filled, displayall = FALSE;
int cpt, height, sel;
if (!pThis->enabled)
{
return CallWindowProcW(pThis->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}
switch (uMsg)
{
case CB_SHOWDROPDOWN:
{
ShowWindow(pThis->hwndListBox, SW_HIDE);
}; break;
case WM_KILLFOCUS:
{
if ((pThis->options & ACO_AUTOSUGGEST) && ((HWND)wParam != pThis->hwndListBox))
{
ShowWindow(pThis->hwndListBox, SW_HIDE);
}
return CallWindowProcW(pThis->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}; break;
case WM_KEYUP:
{
GetWindowTextW(hwnd, (LPWSTR)hwndText, 255);
switch(wParam)
{
case VK_RETURN:
{
/* If quickComplete is set and control is pressed, replace the string */
control = GetKeyState(VK_CONTROL) & 0x8000;
if (control && pThis->quickComplete)
{
hwndQCText = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
(wcslen(pThis->quickComplete)+wcslen(hwndText))*sizeof(WCHAR));
sel = swprintf(hwndQCText, pThis->quickComplete, hwndText);
SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)hwndQCText);
SendMessageW(hwnd, EM_SETSEL, 0, sel);
HeapFree(GetProcessHeap(), 0, hwndQCText);
}
ShowWindow(pThis->hwndListBox, SW_HIDE);
return 0;
}; break;
case VK_LEFT:
case VK_RIGHT:
{
return 0;
}; break;
case VK_UP:
case VK_DOWN:
{
/* Two cases here :
- if the listbox is not visible, displays it
with all the entries if the style ACO_UPDOWNKEYDROPSLIST
is present but does not select anything.
- if the listbox is visible, change the selection
*/
if ( (pThis->options & (ACO_AUTOSUGGEST | ACO_UPDOWNKEYDROPSLIST))
&& (!IsWindowVisible(pThis->hwndListBox) && (! *hwndText)) )
{
/* We must display all the entries */
displayall = TRUE;
}
else
{
if (IsWindowVisible(pThis->hwndListBox))
{
int count;
count = SendMessageW(pThis->hwndListBox, LB_GETCOUNT, 0, 0);
/* Change the selection */
sel = SendMessageW(pThis->hwndListBox, LB_GETCURSEL, 0, 0);
if (wParam == VK_UP)
sel = ((sel-1)<0)?count-1:sel-1;
else
sel = ((sel+1)>= count)?-1:sel+1;
SendMessageW(pThis->hwndListBox, LB_SETCURSEL, sel, 0);
if (sel != -1)
{
WCHAR *msg;
int len;
len = SendMessageW(pThis->hwndListBox, LB_GETTEXTLEN, sel, (LPARAM)NULL);
msg = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR));
if (msg)
{
SendMessageW(pThis->hwndListBox, LB_GETTEXT, sel, (LPARAM)msg);
SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)msg);
SendMessageW(hwnd, EM_SETSEL, wcslen(msg), wcslen(msg));
HeapFree(GetProcessHeap(), 0, msg);
}
else
{
TRACE("HeapAlloc failed to allocate %d bytes\n", (len + 1) * sizeof(WCHAR));
}
}
else
{
SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)pThis->txtbackup);
SendMessageW(hwnd, EM_SETSEL, wcslen(pThis->txtbackup), wcslen(pThis->txtbackup));
}
}
return 0;
}
}; break;
case VK_BACK:
case VK_DELETE:
{
if ((! *hwndText) && (pThis->options & ACO_AUTOSUGGEST))
{
ShowWindow(pThis->hwndListBox, SW_HIDE);
return CallWindowProcW(pThis->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}
if (pThis->options & ACO_AUTOAPPEND)
{
DWORD b;
SendMessageW(hwnd, EM_GETSEL, (WPARAM)&b, (LPARAM)NULL);
if (b>1)
{
hwndText[b-1] = '\0';
}
else
{
hwndText[0] = '\0';
SetWindowTextW(hwnd, hwndText);
}
}
}; break;
default:
;
}
SendMessageW(pThis->hwndListBox, LB_RESETCONTENT, 0, 0);
HeapFree(GetProcessHeap(), 0, pThis->txtbackup);
pThis->txtbackup = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(hwndText)+1)*sizeof(WCHAR));
if (pThis->txtbackup)
{
wcscpy(pThis->txtbackup, hwndText);
}
else
{
TRACE("HeapAlloc failed to allocate %d bytes\n", (wcslen(hwndText)+1)*sizeof(WCHAR));
}
/* Returns if there is no text to search and we doesn't want to display all the entries */
if ((!displayall) && (! *hwndText) )
break;
pThis->enumstr->Reset();
filled = FALSE;
for(cpt = 0;;)
{
hr = pThis->enumstr->Next(1, &strs, NULL);
if (hr != S_OK)
break;
if ((LPWSTR)strstrW(strs, hwndText) == strs)
{
if (pThis->options & ACO_AUTOAPPEND)
{
SetWindowTextW(hwnd, strs);
SendMessageW(hwnd, EM_SETSEL, wcslen(hwndText), wcslen(strs));
break;
}
if (pThis->options & ACO_AUTOSUGGEST)
{
SendMessageW(pThis->hwndListBox, LB_ADDSTRING, 0, (LPARAM)strs);
filled = TRUE;
cpt++;
}
}
}
if (pThis->options & ACO_AUTOSUGGEST)
{
if (filled)
{
height = SendMessageW(pThis->hwndListBox, LB_GETITEMHEIGHT, 0, 0);
SendMessageW(pThis->hwndListBox, LB_CARETOFF, 0, 0);
GetWindowRect(hwnd, &r);
SetParent(pThis->hwndListBox, HWND_DESKTOP);
/* It seems that Windows XP displays 7 lines at most
and otherwise displays a vertical scroll bar */
SetWindowPos(pThis->hwndListBox, HWND_TOP,
r.left, r.bottom + 1, r.right - r.left, min(height * 7, height * (cpt + 1)),
SWP_SHOWWINDOW );
}
else
{
ShowWindow(pThis->hwndListBox, SW_HIDE);
}
}
}; break;
default:
{
return CallWindowProcW(pThis->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}
}
return 0;
}
LRESULT APIENTRY CAutoComplete::ACLBoxSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CAutoComplete *pThis = (CAutoComplete *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
WCHAR *msg;
int sel, len;
switch (uMsg)
{
case WM_MOUSEMOVE:
{
sel = SendMessageW(hwnd, LB_ITEMFROMPOINT, 0, lParam);
SendMessageW(hwnd, LB_SETCURSEL, (WPARAM)sel, (LPARAM)0);
}; break;
case WM_LBUTTONDOWN:
{
sel = SendMessageW(hwnd, LB_GETCURSEL, 0, 0);
if (sel < 0)
break;
len = SendMessageW(pThis->hwndListBox, LB_GETTEXTLEN, sel, 0);
msg = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len + 1) * sizeof(WCHAR));
if (msg)
{
SendMessageW(hwnd, LB_GETTEXT, sel, (LPARAM)msg);
SendMessageW(pThis->hwndEdit, WM_SETTEXT, 0, (LPARAM)msg);
SendMessageW(pThis->hwndEdit, EM_SETSEL, 0, wcslen(msg));
ShowWindow(hwnd, SW_HIDE);
HeapFree(GetProcessHeap(), 0, msg);
}
else
{
TRACE("HeapAlloc failed to allocate %d bytes\n", (len + 1) * sizeof(WCHAR));
}
}; break;
default:
return CallWindowProcW(pThis->wpOrigLBoxProc, hwnd, uMsg, wParam, lParam);
}
return 0;
}

View file

@ -0,0 +1,65 @@
/*
* AutoComplete interfaces implementation.
*
* Copyright 2004 Maxime Bellengé <maxime.bellenge@laposte.net>
* Copyright 2009 Andrew Hill
*
* 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
*/
#ifndef _AUTOCOMPLETE_H_
#define _AUTOCOMPLETE_H_
class CAutoComplete :
public CComCoClass<CAutoComplete, &CLSID_AutoComplete>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IAutoComplete2
{
private:
BOOL enabled;
HWND hwndEdit;
HWND hwndListBox;
WNDPROC wpOrigEditProc;
WNDPROC wpOrigLBoxProc;
WCHAR *txtbackup;
WCHAR *quickComplete;
CComPtr<IEnumString> enumstr;
AUTOCOMPLETEOPTIONS options;
public:
CAutoComplete();
~CAutoComplete();
static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY ACLBoxSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// IAutoComplete2
virtual HRESULT WINAPI Enable(BOOL fEnable);
virtual HRESULT WINAPI Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwzsRegKeyPath, LPCOLESTR pwszQuickComplete);
virtual HRESULT WINAPI GetOptions(DWORD *pdwFlag);
virtual HRESULT WINAPI SetOptions(DWORD dwFlag);
DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE)
DECLARE_NOT_AGGREGATABLE(CAutoComplete)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CAutoComplete)
COM_INTERFACE_ENTRY_IID(IID_IAutoComplete, IAutoComplete)
COM_INTERFACE_ENTRY_IID(IID_IAutoComplete2, IAutoComplete2)
END_COM_MAP()
};
#endif // _AUTOCOMPLETE_H_

View file

View file

View file

@ -0,0 +1,816 @@
/*
* Copyright 1999 Juergen Schmied
*
* 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
*
* FIXME:
* - many memory leaks
* - many flags unimplemented
* - implement new dialog style "make new folder" button
* - implement editbox
* - implement new dialog style resizing
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
typedef struct tagbrowse_info
{
HWND hWnd;
HWND hwndTreeView;
LPBROWSEINFOW lpBrowseInfo;
LPITEMIDLIST pidlRet;
} browse_info;
typedef struct tagTV_ITEMDATA
{
LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
LPITEMIDLIST lpi; /* PIDL relative to parent */
LPITEMIDLIST lpifq; /* Fully qualified PIDL */
IEnumIDList* pEnumIL; /* Children iterator */
} TV_ITEMDATA, *LPTV_ITEMDATA;
#define SUPPORTEDFLAGS (BIF_STATUSTEXT | \
BIF_BROWSEFORCOMPUTER | \
BIF_RETURNFSANCESTORS | \
BIF_RETURNONLYFSDIRS | \
BIF_NONEWFOLDERBUTTON | \
BIF_NEWDIALOGSTYLE | \
BIF_BROWSEINCLUDEFILES)
static void FillTreeView(browse_info*, LPSHELLFOLDER,
LPITEMIDLIST, HTREEITEM, IEnumIDList*);
static HTREEITEM InsertTreeViewItem( browse_info*, IShellFolder *,
LPCITEMIDLIST, LPCITEMIDLIST, IEnumIDList*, HTREEITEM);
static const WCHAR szBrowseFolderInfo[] = {
'_','_','W','I','N','E','_',
'B','R','S','F','O','L','D','E','R','D','L','G','_',
'I','N','F','O',0
};
static DWORD __inline BrowseFlagsToSHCONTF(UINT ulFlags)
{
return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS : 0);
}
static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND hWnd,
UINT msg, LPARAM param )
{
if (!lpBrowseInfo->lpfn)
return;
lpBrowseInfo->lpfn( hWnd, msg, param, lpBrowseInfo->lParam );
}
/******************************************************************************
* InitializeTreeView [Internal]
*
* Called from WM_INITDIALOG handler.
*
* PARAMS
* hwndParent [I] The BrowseForFolder dialog
* root [I] ITEMIDLIST of the root shell folder
*/
static void InitializeTreeView( browse_info *info )
{
LPITEMIDLIST pidlParent, pidlChild;
HIMAGELIST hImageList;
HRESULT hr;
IShellFolder *lpsfParent, *lpsfRoot;
IEnumIDList * pEnumChildren = NULL;
HTREEITEM item;
DWORD flags;
LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot;
TRACE("%p\n", info );
Shell_GetImageLists(NULL, &hImageList);
if (hImageList)
SendMessageW( info->hwndTreeView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList );
/* We want to call InsertTreeViewItem down the code, in order to insert
* the root item of the treeview. Due to InsertTreeViewItem's signature,
* we need the following to do this:
*
* + An ITEMIDLIST corresponding to _the parent_ of root.
* + An ITEMIDLIST, which is a relative path from root's parent to root
* (containing a single SHITEMID).
* + An IShellFolder interface pointer of root's parent folder.
*
* If root is 'Desktop', then root's parent is also 'Desktop'.
*/
pidlParent = ILClone(root);
ILRemoveLastID(pidlParent);
pidlChild = ILClone(ILFindLastID(root));
if (_ILIsDesktop(pidlParent)) {
hr = SHGetDesktopFolder(&lpsfParent);
} else {
IShellFolder *lpsfDesktop;
hr = SHGetDesktopFolder(&lpsfDesktop);
if (!SUCCEEDED(hr)) {
WARN("SHGetDesktopFolder failed! hr = %08x\n", hr);
return;
}
hr = lpsfDesktop->BindToObject(pidlParent, 0, IID_IShellFolder, (LPVOID *)&lpsfParent);
lpsfDesktop->Release();
}
if (!SUCCEEDED(hr)) {
WARN("Could not bind to parent shell folder! hr = %08x\n", hr);
return;
}
if (pidlChild && pidlChild->mkid.cb) {
hr = lpsfParent->BindToObject(pidlChild, 0, IID_IShellFolder, (LPVOID *)&lpsfRoot);
} else {
lpsfRoot = lpsfParent;
hr = lpsfParent->AddRef();
}
if (!SUCCEEDED(hr)) {
WARN("Could not bind to root shell folder! hr = %08x\n", hr);
lpsfParent->Release();
return;
}
flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags );
hr = lpsfRoot->EnumObjects(info->hWnd, flags, &pEnumChildren );
if (!SUCCEEDED(hr)) {
WARN("Could not get child iterator! hr = %08x\n", hr);
lpsfParent->Release();
lpsfRoot->Release();
return;
}
SendMessageW( info->hwndTreeView, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT );
item = InsertTreeViewItem( info, lpsfParent, pidlChild,
pidlParent, pEnumChildren, TVI_ROOT );
SendMessageW( info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item );
lpsfRoot->Release();
lpsfParent->Release();
}
static int GetIcon(LPCITEMIDLIST lpi, UINT uFlags)
{
SHFILEINFOW sfi;
SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
return sfi.iIcon;
}
static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
{
LPITEMIDLIST pidlDesktop = NULL;
DWORD flags;
TRACE("%p %p\n",lpifq, lpTV_ITEM);
if (!lpifq)
{
pidlDesktop = _ILCreateDesktop();
lpifq = pidlDesktop;
}
flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
lpTV_ITEM->iImage = GetIcon( lpifq, flags );
flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON;
lpTV_ITEM->iSelectedImage = GetIcon( lpifq, flags );
if (pidlDesktop)
ILFree( pidlDesktop );
}
/******************************************************************************
* GetName [Internal]
*
* Query a shell folder for the display name of one of it's children
*
* PARAMS
* lpsf [I] IShellFolder interface of the folder to be queried.
* lpi [I] ITEMIDLIST of the child, relative to parent
* dwFlags [I] as in IShellFolder::GetDisplayNameOf
* lpFriendlyName [O] The desired display name in unicode
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR lpFriendlyName)
{
BOOL bSuccess=TRUE;
STRRET str;
TRACE("%p %p %x %p\n", lpsf, lpi, dwFlags, lpFriendlyName);
if (SUCCEEDED(lpsf->GetDisplayNameOf(lpi, dwFlags, &str)))
bSuccess = StrRetToStrNW(lpFriendlyName, MAX_PATH, &str, lpi);
else
bSuccess = FALSE;
TRACE("-- %s\n", debugstr_w(lpFriendlyName));
return bSuccess;
}
/******************************************************************************
* InsertTreeViewItem [Internal]
*
* PARAMS
* info [I] data for the dialog
* lpsf [I] IShellFolder interface of the item's parent shell folder
* pidl [I] ITEMIDLIST of the child to insert, relative to parent
* pidlParent [I] ITEMIDLIST of the parent shell folder
* pEnumIL [I] Iterator for the children of the item to be inserted
* hParent [I] The treeview-item that represents the parent shell folder
*
* RETURNS
* Success: Handle to the created and inserted treeview-item
* Failure: NULL
*/
static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf,
LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL,
HTREEITEM hParent)
{
TVITEMW tvi;
TVINSERTSTRUCTW tvins;
WCHAR szBuff[MAX_PATH];
LPTV_ITEMDATA lptvid=0;
tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
tvi.cChildren= pEnumIL ? 1 : 0;
tvi.mask |= TVIF_CHILDREN;
lptvid = (TV_ITEMDATA *)SHAlloc( sizeof(TV_ITEMDATA) );
if (!lptvid)
return NULL;
if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
return NULL;
tvi.pszText = szBuff;
tvi.cchTextMax = MAX_PATH;
tvi.lParam = (LPARAM)lptvid;
lpsf->AddRef();
lptvid->lpsfParent = lpsf;
lptvid->lpi = ILClone(pidl);
lptvid->lpifq = pidlParent ? ILCombine(pidlParent, pidl) : ILClone(pidl);
lptvid->pEnumIL = pEnumIL;
GetNormalAndSelectedIcons(lptvid->lpifq, &tvi);
tvins.item = tvi;
tvins.hInsertAfter = NULL;
tvins.hParent = hParent;
return (HTREEITEM)SendMessageW(info->hwndTreeView, TVM_INSERTITEM, 0, (LPARAM)&tvins );
}
/******************************************************************************
* FillTreeView [Internal]
*
* For each child (given by lpe) of the parent shell folder, which is given by
* lpsf and whose PIDL is pidl, insert a treeview-item right under hParent
*
* PARAMS
* info [I] data for the dialog
* lpsf [I] IShellFolder interface of the parent shell folder
* pidl [I] ITEMIDLIST of the parent shell folder
* hParent [I] The treeview item that represents the parent shell folder
* lpe [I] An iterator for the children of the parent shell folder
*/
static void FillTreeView( browse_info *info, IShellFolder * lpsf,
LPITEMIDLIST pidl, HTREEITEM hParent, IEnumIDList* lpe)
{
HTREEITEM hPrev = 0;
LPITEMIDLIST pidlTemp = 0;
ULONG ulFetched;
HRESULT hr;
HWND hwnd = GetParent( info->hwndTreeView );
TRACE("%p %p %p %p\n",lpsf, pidl, hParent, lpe);
/* No IEnumIDList -> No children */
if (!lpe) return;
SetCapture( hwnd );
SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) );
while (NOERROR == lpe->Next(1,&pidlTemp,&ulFetched))
{
ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
IEnumIDList* pEnumIL = NULL;
IShellFolder* pSFChild = NULL;
lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)&pidlTemp, &ulAttrs);
if (ulAttrs & SFGAO_FOLDER)
{
hr = lpsf->BindToObject(pidlTemp, NULL, IID_IShellFolder, (LPVOID *)&pSFChild);
if (SUCCEEDED(hr))
{
DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
hr = pSFChild->EnumObjects(hwnd, flags, &pEnumIL);
if (hr == S_OK)
{
if ((pEnumIL->Skip(1) != S_OK) ||
FAILED(pEnumIL->Reset()))
{
pEnumIL->Release();
pEnumIL = NULL;
}
}
pSFChild->Release();
}
}
if (!(hPrev = InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent)))
goto done;
SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */
pidlTemp=NULL;
}
done:
ReleaseCapture();
SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
SHFree(pidlTemp);
}
static BOOL __inline PIDLIsType(LPCITEMIDLIST pidl, PIDLTYPE type)
{
LPPIDLDATA data = _ILGetDataPointer(pidl);
if (!data)
return FALSE;
return (data->type == type);
}
static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptvid )
{
LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
LPCITEMIDLIST pidl = lptvid->lpi;
BOOL bEnabled = TRUE;
DWORD dwAttributes;
HRESULT r;
if ((lpBrowseInfo->ulFlags & BIF_BROWSEFORCOMPUTER) &&
!PIDLIsType(pidl, PT_COMP))
bEnabled = FALSE;
if (lpBrowseInfo->ulFlags & BIF_RETURNFSANCESTORS)
{
dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
r = lptvid->lpsfParent->GetAttributesOf(1,
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
if (FAILED(r) || !(dwAttributes & (SFGAO_FILESYSANCESTOR|SFGAO_FILESYSTEM)))
bEnabled = FALSE;
}
if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
{
dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
r = lptvid->lpsfParent->GetAttributesOf(1,
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
if (FAILED(r) ||
((dwAttributes & (SFGAO_FOLDER|SFGAO_FILESYSTEM)) != (SFGAO_FOLDER|SFGAO_FILESYSTEM)))
{
bEnabled = FALSE;
}
}
SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
}
static LRESULT BrsFolder_Treeview_Delete( browse_info *info, NMTREEVIEWW *pnmtv )
{
LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA)pnmtv->itemOld.lParam;
TRACE("TVN_DELETEITEMA/W %p\n", lptvid);
lptvid->lpsfParent->Release();
if (lptvid->pEnumIL)
lptvid->pEnumIL->Release();
SHFree(lptvid->lpi);
SHFree(lptvid->lpifq);
SHFree(lptvid);
return 0;
}
static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv )
{
IShellFolder *lpsf2 = NULL;
LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
HRESULT r;
TRACE("TVN_ITEMEXPANDINGA/W\n");
if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
return 0;
if (lptvid->lpi && lptvid->lpi->mkid.cb) {
r = lptvid->lpsfParent->BindToObject(lptvid->lpi, 0,
IID_IShellFolder, (LPVOID *)&lpsf2 );
} else {
lpsf2 = lptvid->lpsfParent;
r = lpsf2->AddRef();
}
if (SUCCEEDED(r))
FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
/* My Computer is already sorted and trying to do a simple text
* sort will only mess things up */
if (!_ILIsMyComputer(lptvid->lpi))
SendMessageW( info->hwndTreeView, TVM_SORTCHILDREN,
FALSE, (LPARAM)pnmtv->itemNew.hItem );
return 0;
}
static HRESULT BrsFolder_Treeview_Changed( browse_info *info, NMTREEVIEWW *pnmtv )
{
LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
info->pidlRet = lptvid->lpifq;
browsefolder_callback( info->lpBrowseInfo, info->hWnd, BFFM_SELCHANGED,
(LPARAM)info->pidlRet );
BrsFolder_CheckValidSelection( info, lptvid );
return 0;
}
static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh )
{
NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
TRACE("%p %x %p msg=%x\n", info, CtlID, lpnmh, pnmtv->hdr.code);
if (pnmtv->hdr.idFrom != IDD_TREEVIEW)
return 0;
switch (pnmtv->hdr.code)
{
case TVN_DELETEITEMA:
case TVN_DELETEITEMW:
return BrsFolder_Treeview_Delete( info, pnmtv );
case TVN_ITEMEXPANDINGA:
case TVN_ITEMEXPANDINGW:
return BrsFolder_Treeview_Expand( info, pnmtv );
case TVN_SELCHANGEDA:
case TVN_SELCHANGEDW:
return BrsFolder_Treeview_Changed( info, pnmtv );
default:
WARN("unhandled (%d)\n", pnmtv->hdr.code);
break;
}
return 0;
}
static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
{
LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
info->hWnd = hWnd;
SetPropW( hWnd, szBrowseFolderInfo, info );
if (lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE)
FIXME("flags BIF_NEWDIALOGSTYLE partially implemented\n");
if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
if (lpBrowseInfo->lpszTitle)
SetWindowTextW( GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle );
else
ShowWindow( GetDlgItem(hWnd, IDD_TITLE), SW_HIDE );
if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT)
|| (lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE))
ShowWindow( GetDlgItem(hWnd, IDD_STATUS), SW_HIDE );
/* Hide "Make New Folder" Button? */
if ((lpBrowseInfo->ulFlags & BIF_NONEWFOLDERBUTTON)
|| !(lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE))
ShowWindow( GetDlgItem(hWnd, IDD_MAKENEWFOLDER), SW_HIDE );
/* Hide the editbox? */
if (!(lpBrowseInfo->ulFlags & BIF_EDITBOX))
{
ShowWindow( GetDlgItem(hWnd, IDD_FOLDER), SW_HIDE );
ShowWindow( GetDlgItem(hWnd, IDD_FOLDERTEXT), SW_HIDE );
}
info->hwndTreeView = GetDlgItem( hWnd, IDD_TREEVIEW );
if (info->hwndTreeView)
{
InitializeTreeView( info );
/* Resize the treeview if there's not editbox */
if ((lpBrowseInfo->ulFlags & BIF_NEWDIALOGSTYLE)
&& !(lpBrowseInfo->ulFlags & BIF_EDITBOX))
{
RECT rc;
GetClientRect(info->hwndTreeView, &rc);
SetWindowPos(info->hwndTreeView, HWND_TOP, 0, 0,
rc.right, rc.bottom + 40, SWP_NOMOVE);
}
}
else
ERR("treeview control missing!\n");
browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED, 0 );
return TRUE;
}
static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
{
LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
switch (id)
{
case IDOK:
/* The original pidl is owned by the treeview and will be free'd. */
info->pidlRet = ILClone(info->pidlRet);
if (info->pidlRet == NULL) /* A null pidl would mean a cancel */
info->pidlRet = _ILCreateDesktop();
pdump( info->pidlRet );
if (lpBrowseInfo->pszDisplayName)
SHGetPathFromIDListW( info->pidlRet, lpBrowseInfo->pszDisplayName );
EndDialog( info->hWnd, 1 );
return TRUE;
case IDCANCEL:
EndDialog( info->hWnd, 0 );
return TRUE;
case IDD_MAKENEWFOLDER:
FIXME("make new folder not implemented\n");
return TRUE;
}
return FALSE;
}
static BOOL BrsFolder_OnSetExpanded(browse_info *info, LPVOID selection,
BOOL is_str, HTREEITEM *pItem)
{
LPITEMIDLIST pidlSelection = (LPITEMIDLIST)selection;
LPCITEMIDLIST pidlCurrent, pidlRoot;
TVITEMEXW item;
BOOL bResult = FALSE;
/* If 'selection' is a string, convert to a Shell ID List. */
if (is_str) {
IShellFolder *psfDesktop;
HRESULT hr;
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED(hr))
goto done;
hr = psfDesktop->ParseDisplayName(NULL, NULL,
(LPOLESTR)selection, NULL, &pidlSelection, NULL);
psfDesktop->Release();
if (FAILED(hr))
goto done;
}
/* Move pidlCurrent behind the SHITEMIDs in pidlSelection, which are the root of
* the sub-tree currently displayed. */
pidlRoot = info->lpBrowseInfo->pidlRoot;
pidlCurrent = pidlSelection;
while (!_ILIsEmpty(pidlRoot) && _ILIsEqualSimple(pidlRoot, pidlCurrent)) {
pidlRoot = ILGetNext(pidlRoot);
pidlCurrent = ILGetNext(pidlCurrent);
}
/* The given ID List is not part of the SHBrowseForFolder's current sub-tree. */
if (!_ILIsEmpty(pidlRoot))
goto done;
/* Initialize item to point to the first child of the root folder. */
memset(&item, 0, sizeof(item));
item.mask = TVIF_PARAM;
item.hItem = TreeView_GetRoot(info->hwndTreeView);
if (item.hItem)
item.hItem = TreeView_GetChild(info->hwndTreeView, item.hItem);
/* Walk the tree along the nodes corresponding to the remaining ITEMIDLIST */
while (item.hItem && !_ILIsEmpty(pidlCurrent)) {
LPTV_ITEMDATA pItemData;
SendMessageW(info->hwndTreeView, TVM_GETITEMW, 0, (LPARAM)&item);
pItemData = (LPTV_ITEMDATA)item.lParam;
if (_ILIsEqualSimple(pItemData->lpi, pidlCurrent)) {
pidlCurrent = ILGetNext(pidlCurrent);
if (!_ILIsEmpty(pidlCurrent)) {
/* Only expand current node and move on to it's first child,
* if we didn't already reach the last SHITEMID */
SendMessageW(info->hwndTreeView, TVM_EXPAND, TVE_EXPAND, (LPARAM)item.hItem);
item.hItem = TreeView_GetChild(info->hwndTreeView, item.hItem);
}
} else {
item.hItem = TreeView_GetNextSibling(info->hwndTreeView, item.hItem);
}
}
if (_ILIsEmpty(pidlCurrent) && item.hItem)
bResult = TRUE;
done:
if (pidlSelection && pidlSelection != (LPITEMIDLIST)selection)
ILFree(pidlSelection);
if (pItem)
*pItem = item.hItem;
return bResult;
}
static BOOL BrsFolder_OnSetSelectionW(browse_info *info, LPVOID selection, BOOL is_str) {
HTREEITEM hItem;
BOOL bResult;
bResult = BrsFolder_OnSetExpanded(info, selection, is_str, &hItem);
if (bResult)
SendMessageW(info->hwndTreeView, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem );
return bResult;
}
static BOOL BrsFolder_OnSetSelectionA(browse_info *info, LPVOID selection, BOOL is_str) {
LPWSTR selectionW = NULL;
BOOL result = FALSE;
int length;
if (!is_str)
return BrsFolder_OnSetSelectionW(info, selection, is_str);
if ((length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)selection, -1, NULL, 0)) &&
(selectionW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR))) &&
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)selection, -1, selectionW, length))
{
result = BrsFolder_OnSetSelectionW(info, selectionW, is_str);
}
HeapFree(GetProcessHeap(), 0, selectionW);
return result;
}
/*************************************************************************
* BrsFolderDlgProc32 (not an exported API function)
*/
static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
browse_info *info;
TRACE("hwnd=%p msg=%04x 0x%08lx 0x%08lx\n", hWnd, msg, wParam, lParam );
if (msg == WM_INITDIALOG)
return BrsFolder_OnCreate( hWnd, (browse_info*) lParam );
info = (browse_info*) GetPropW( hWnd, szBrowseFolderInfo );
switch (msg)
{
case WM_NOTIFY:
return BrsFolder_OnNotify( info, (UINT)wParam, (LPNMHDR)lParam);
case WM_COMMAND:
return BrsFolder_OnCommand( info, wParam );
case BFFM_SETSTATUSTEXTA:
TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
break;
case BFFM_SETSTATUSTEXTW:
TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
break;
case BFFM_ENABLEOK:
TRACE("Enable %ld\n", lParam);
EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
break;
case BFFM_SETOKTEXT: /* unicode only */
TRACE("Set OK text %s\n", debugstr_w((LPWSTR)wParam));
SetWindowTextW(GetDlgItem(hWnd, 1), (LPWSTR)wParam);
break;
case BFFM_SETSELECTIONA:
return BrsFolder_OnSetSelectionA(info, (LPVOID)lParam, (BOOL)wParam);
case BFFM_SETSELECTIONW:
return BrsFolder_OnSetSelectionW(info, (LPVOID)lParam, (BOOL)wParam);
case BFFM_SETEXPANDED: /* unicode only */
return BrsFolder_OnSetExpanded(info, (LPVOID)lParam, (BOOL)wParam, NULL);
}
return FALSE;
}
static const WCHAR swBrowseTemplateName[] = {
'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
static const WCHAR swNewBrowseTemplateName[] = {
'S','H','N','E','W','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
/*************************************************************************
* SHBrowseForFolderA [SHELL32.@]
* SHBrowseForFolder [SHELL32.@]
*/
LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
{
BROWSEINFOW bi;
LPITEMIDLIST lpid;
INT len;
LPWSTR title;
TRACE("%p\n", lpbi);
bi.hwndOwner = lpbi->hwndOwner;
bi.pidlRoot = lpbi->pidlRoot;
if (lpbi->pszDisplayName)
{
bi.pszDisplayName = (WCHAR *)HeapAlloc( GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, MAX_PATH );
}
else
bi.pszDisplayName = NULL;
if (lpbi->lpszTitle)
{
len = MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0 );
title = (WCHAR *)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, title, len );
}
else
title = NULL;
bi.lpszTitle = title;
bi.ulFlags = lpbi->ulFlags;
bi.lpfn = lpbi->lpfn;
bi.lParam = lpbi->lParam;
bi.iImage = lpbi->iImage;
lpid = SHBrowseForFolderW( &bi );
if (bi.pszDisplayName)
{
WideCharToMultiByte( CP_ACP, 0, bi.pszDisplayName, -1,
lpbi->pszDisplayName, MAX_PATH, 0, NULL);
HeapFree( GetProcessHeap(), 0, bi.pszDisplayName );
}
HeapFree(GetProcessHeap(), 0, title);
lpbi->iImage = bi.iImage;
return lpid;
}
/*************************************************************************
* SHBrowseForFolderW [SHELL32.@]
*
* NOTES
* crashes when passed a null pointer
*/
LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
{
browse_info info;
DWORD r;
HRESULT hr;
const WCHAR * templateName;
info.hWnd = 0;
info.pidlRet = NULL;
info.lpBrowseInfo = lpbi;
info.hwndTreeView = NULL;
hr = OleInitialize(NULL);
if (lpbi->ulFlags & BIF_NEWDIALOGSTYLE)
templateName = swNewBrowseTemplateName;
else
templateName = swBrowseTemplateName;
r = DialogBoxParamW( shell32_hInstance, templateName, lpbi->hwndOwner,
BrsFolderDlgProc, (LPARAM)&info );
if (SUCCEEDED(hr))
OleUninitialize();
if (!r)
return NULL;
return info.pidlRet;
}

View file

@ -0,0 +1,476 @@
/*
* shell change notification
*
* Copyright 2000 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
namespace
{
extern CRITICAL_SECTION SHELL32_ChangenotifyCS;
CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &SHELL32_ChangenotifyCS,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": SHELL32_ChangenotifyCS") }
};
CRITICAL_SECTION SHELL32_ChangenotifyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
}
typedef SHChangeNotifyEntry *LPNOTIFYREGISTER;
/* internal list of notification clients (internal) */
typedef struct _NOTIFICATIONLIST
{
struct _NOTIFICATIONLIST *next;
struct _NOTIFICATIONLIST *prev;
HWND hwnd; /* window to notify */
DWORD uMsg; /* message to send */
LPNOTIFYREGISTER apidl; /* array of entries to watch*/
UINT cidl; /* number of pidls in array */
LONG wEventMask; /* subscribed events */
LONG wSignalledEvent; /* event that occurred */
DWORD dwFlags; /* client flags */
LPCITEMIDLIST pidlSignaled; /*pidl of the path that caused the signal*/
} NOTIFICATIONLIST, *LPNOTIFICATIONLIST;
static NOTIFICATIONLIST *head, *tail;
#define SHCNE_NOITEMEVENTS ( \
SHCNE_ASSOCCHANGED )
#define SHCNE_ONEITEMEVENTS ( \
SHCNE_ATTRIBUTES | SHCNE_CREATE | SHCNE_DELETE | SHCNE_DRIVEADD | \
SHCNE_DRIVEADDGUI | SHCNE_DRIVEREMOVED | SHCNE_FREESPACE | \
SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED | SHCNE_MKDIR | \
SHCNE_NETSHARE | SHCNE_NETUNSHARE | SHCNE_RMDIR | \
SHCNE_SERVERDISCONNECT | SHCNE_UPDATEDIR | SHCNE_UPDATEIMAGE )
#define SHCNE_TWOITEMEVENTS ( \
SHCNE_RENAMEFOLDER | SHCNE_RENAMEITEM | SHCNE_UPDATEITEM )
/* for dumping events */
static const char * DumpEvent( LONG event )
{
if( event == SHCNE_ALLEVENTS )
return "SHCNE_ALLEVENTS";
#define DUMPEV(x) ,( event & SHCNE_##x )? #x " " : ""
return wine_dbg_sprintf( "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
DUMPEV(RENAMEITEM)
DUMPEV(CREATE)
DUMPEV(DELETE)
DUMPEV(MKDIR)
DUMPEV(RMDIR)
DUMPEV(MEDIAINSERTED)
DUMPEV(MEDIAREMOVED)
DUMPEV(DRIVEREMOVED)
DUMPEV(DRIVEADD)
DUMPEV(NETSHARE)
DUMPEV(NETUNSHARE)
DUMPEV(ATTRIBUTES)
DUMPEV(UPDATEDIR)
DUMPEV(UPDATEITEM)
DUMPEV(SERVERDISCONNECT)
DUMPEV(UPDATEIMAGE)
DUMPEV(DRIVEADDGUI)
DUMPEV(RENAMEFOLDER)
DUMPEV(FREESPACE)
DUMPEV(EXTENDED_EVENT)
DUMPEV(ASSOCCHANGED)
DUMPEV(INTERRUPT)
);
#undef DUMPEV
}
static const char * NodeName(const NOTIFICATIONLIST *item)
{
const char *str;
WCHAR path[MAX_PATH];
if(SHGetPathFromIDListW(item->apidl[0].pidl, path ))
str = wine_dbg_sprintf("%s", debugstr_w(path));
else
str = wine_dbg_sprintf("<not a disk file>" );
return str;
}
static void AddNode(LPNOTIFICATIONLIST item)
{
TRACE("item %p\n", item );
/* link items */
item->prev = tail;
item->next = NULL;
if( tail )
tail->next = item;
else
head = item;
tail = item;
}
static LPNOTIFICATIONLIST FindNode( HANDLE hitem )
{
LPNOTIFICATIONLIST ptr;
for( ptr = head; ptr; ptr = ptr->next )
if( ptr == (LPNOTIFICATIONLIST) hitem )
return ptr;
return NULL;
}
static void DeleteNode(LPNOTIFICATIONLIST item)
{
UINT i;
TRACE("item=%p prev=%p next=%p\n", item, item->prev, item->next);
/* remove item from list */
if( item->prev )
item->prev->next = item->next;
else
head = item->next;
if( item->next )
item->next->prev = item->prev;
else
tail = item->prev;
/* free the item */
for (i=0; i<item->cidl; i++)
SHFree((LPITEMIDLIST)item->apidl[i].pidl);
SHFree(item->apidl);
SHFree(item);
}
void InitChangeNotifications(void)
{
}
void FreeChangeNotifications(void)
{
TRACE("\n");
EnterCriticalSection(&SHELL32_ChangenotifyCS);
while( head )
DeleteNode( head );
LeaveCriticalSection(&SHELL32_ChangenotifyCS);
// DeleteCriticalSection(&SHELL32_ChangenotifyCS); // static
}
/*************************************************************************
* SHChangeNotifyRegister [SHELL32.2]
*
*/
ULONG WINAPI
SHChangeNotifyRegister(
HWND hwnd,
int fSources,
LONG wEventMask,
UINT uMsg,
int cItems,
SHChangeNotifyEntry *lpItems)
{
LPNOTIFICATIONLIST item;
int i;
item = (NOTIFICATIONLIST *)SHAlloc(sizeof(NOTIFICATIONLIST));
TRACE("(%p,0x%08x,0x%08x,0x%08x,%d,%p) item=%p\n",
hwnd, fSources, wEventMask, uMsg, cItems, lpItems, item);
item->next = NULL;
item->prev = NULL;
item->cidl = cItems;
item->apidl = (SHChangeNotifyEntry *)SHAlloc(sizeof(SHChangeNotifyEntry) * cItems);
for(i=0;i<cItems;i++)
{
item->apidl[i].pidl = ILClone(lpItems[i].pidl);
item->apidl[i].fRecursive = lpItems[i].fRecursive;
}
item->hwnd = hwnd;
item->uMsg = uMsg;
item->wEventMask = wEventMask;
item->wSignalledEvent = 0;
item->dwFlags = fSources;
TRACE("new node: %s\n", NodeName( item ));
EnterCriticalSection(&SHELL32_ChangenotifyCS);
AddNode(item);
LeaveCriticalSection(&SHELL32_ChangenotifyCS);
return (ULONG)item;
}
/*************************************************************************
* SHChangeNotifyDeregister [SHELL32.4]
*/
BOOL WINAPI SHChangeNotifyDeregister(ULONG hNotify)
{
LPNOTIFICATIONLIST node;
TRACE("(0x%08x)\n", hNotify);
EnterCriticalSection(&SHELL32_ChangenotifyCS);
node = FindNode((HANDLE)hNotify);
if( node )
DeleteNode(node);
LeaveCriticalSection(&SHELL32_ChangenotifyCS);
return node?TRUE:FALSE;
}
/*************************************************************************
* SHChangeNotifyUpdateEntryList [SHELL32.5]
*/
EXTERN_C BOOL WINAPI SHChangeNotifyUpdateEntryList(DWORD unknown1, DWORD unknown2,
DWORD unknown3, DWORD unknown4)
{
FIXME("(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
unknown1, unknown2, unknown3, unknown4);
return -1;
}
static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL sub )
{
TRACE("%p %p %d\n", changed, watched, sub );
if ( !watched )
return FALSE;
if (ILIsEqual( watched, changed ) )
return TRUE;
if( sub && ILIsParent( watched, changed, TRUE ) )
return TRUE;
return FALSE;
}
/*************************************************************************
* SHChangeNotify [SHELL32.@]
*/
void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
{
LPCITEMIDLIST Pidls[2];
LPNOTIFICATIONLIST ptr;
UINT typeFlag = uFlags & SHCNF_TYPE;
Pidls[0] = NULL;
Pidls[1] = NULL;
TRACE("(0x%08x,0x%08x,%p,%p):stub.\n", wEventId, uFlags, dwItem1, dwItem2);
if( ( wEventId & SHCNE_NOITEMEVENTS ) && ( dwItem1 || dwItem2 ) )
{
TRACE("dwItem1 and dwItem2 are not zero, but should be\n");
dwItem1 = 0;
dwItem2 = 0;
return;
}
else if( ( wEventId & SHCNE_ONEITEMEVENTS ) && dwItem2 )
{
TRACE("dwItem2 is not zero, but should be\n");
dwItem2 = 0;
return;
}
if( ( ( wEventId & SHCNE_NOITEMEVENTS ) &&
( wEventId & ~SHCNE_NOITEMEVENTS ) ) ||
( ( wEventId & SHCNE_ONEITEMEVENTS ) &&
( wEventId & ~SHCNE_ONEITEMEVENTS ) ) ||
( ( wEventId & SHCNE_TWOITEMEVENTS ) &&
( wEventId & ~SHCNE_TWOITEMEVENTS ) ) )
{
WARN("mutually incompatible events listed\n");
return;
}
/* convert paths in IDLists*/
switch (typeFlag)
{
case SHCNF_PATHA:
if (dwItem1) Pidls[0] = SHSimpleIDListFromPathA((LPCSTR)dwItem1); //FIXME
if (dwItem2) Pidls[1] = SHSimpleIDListFromPathA((LPCSTR)dwItem2); //FIXME
break;
case SHCNF_PATHW:
if (dwItem1) Pidls[0] = SHSimpleIDListFromPathW((LPCWSTR)dwItem1);
if (dwItem2) Pidls[1] = SHSimpleIDListFromPathW((LPCWSTR)dwItem2);
break;
case SHCNF_IDLIST:
Pidls[0] = (LPCITEMIDLIST)dwItem1;
Pidls[1] = (LPCITEMIDLIST)dwItem2;
break;
case SHCNF_PRINTERA:
case SHCNF_PRINTERW:
FIXME("SHChangeNotify with (uFlags & SHCNF_PRINTER)\n");
return;
case SHCNF_DWORD:
default:
FIXME("unknown type %08x\n",typeFlag);
return;
}
{
WCHAR path[MAX_PATH];
if( Pidls[0] && SHGetPathFromIDListW(Pidls[0], path ))
TRACE("notify %08x on item1 = %s\n", wEventId, debugstr_w(path));
if( Pidls[1] && SHGetPathFromIDListW(Pidls[1], path ))
TRACE("notify %08x on item2 = %s\n", wEventId, debugstr_w(path));
}
EnterCriticalSection(&SHELL32_ChangenotifyCS);
/* loop through the list */
for( ptr = head; ptr; ptr = ptr->next )
{
BOOL notify;
DWORD i;
notify = FALSE;
TRACE("trying %p\n", ptr);
for( i=0; (i<ptr->cidl) && !notify ; i++ )
{
LPCITEMIDLIST pidl = ptr->apidl[i].pidl;
BOOL subtree = ptr->apidl[i].fRecursive;
if (wEventId & ptr->wEventMask)
{
if( !pidl ) /* all ? */
notify = TRUE;
else if( wEventId & SHCNE_NOITEMEVENTS )
notify = TRUE;
else if( wEventId & ( SHCNE_ONEITEMEVENTS | SHCNE_TWOITEMEVENTS ) )
notify = should_notify( Pidls[0], pidl, subtree );
else if( wEventId & SHCNE_TWOITEMEVENTS )
notify = should_notify( Pidls[1], pidl, subtree );
}
}
if( !notify )
continue;
ptr->pidlSignaled = ILClone(Pidls[0]);
TRACE("notifying %s, event %s(%x) before\n", NodeName( ptr ), DumpEvent(
wEventId ),wEventId );
ptr->wSignalledEvent |= wEventId;
if (ptr->dwFlags & SHCNRF_NewDelivery)
SendMessageW(ptr->hwnd, ptr->uMsg, (WPARAM) ptr, (LPARAM) GetCurrentProcessId());
else
SendMessageW(ptr->hwnd, ptr->uMsg, (WPARAM)Pidls, wEventId);
TRACE("notifying %s, event %s(%x) after\n", NodeName( ptr ), DumpEvent(
wEventId ),wEventId );
}
TRACE("notify Done\n");
LeaveCriticalSection(&SHELL32_ChangenotifyCS);
/* if we allocated it, free it. The ANSI flag is also set in its Unicode sibling. */
if ((typeFlag & SHCNF_PATHA) || (typeFlag & SHCNF_PRINTERA))
{
SHFree((LPITEMIDLIST)Pidls[0]);
SHFree((LPITEMIDLIST)Pidls[1]);
}
}
/*************************************************************************
* NTSHChangeNotifyRegister [SHELL32.640]
* NOTES
* Idlist is an array of structures and Count specifies how many items in the array.
* count should always be one when calling SHChangeNotifyRegister, or
* SHChangeNotifyDeregister will not work properly.
*/
EXTERN_C ULONG WINAPI NTSHChangeNotifyRegister(
HWND hwnd,
int fSources,
LONG fEvents,
UINT msg,
int count,
SHChangeNotifyEntry *idlist)
{
return SHChangeNotifyRegister(hwnd, fSources | SHCNRF_NewDelivery,
fEvents, msg, count, idlist);
}
/*************************************************************************
* SHChangeNotification_Lock [SHELL32.644]
*/
HANDLE WINAPI SHChangeNotification_Lock(
HANDLE hChange,
DWORD dwProcessId,
LPITEMIDLIST **lppidls,
LPLONG lpwEventId)
{
DWORD i;
LPNOTIFICATIONLIST node;
LPCITEMIDLIST *idlist;
TRACE("%p %08x %p %p\n", hChange, dwProcessId, lppidls, lpwEventId);
/* EnterCriticalSection(&SHELL32_ChangenotifyCS); */
node = FindNode( hChange );
if( node )
{
idlist = (LPCITEMIDLIST *)SHAlloc( sizeof(LPCITEMIDLIST *) * node->cidl );
for(i=0; i<node->cidl; i++)
idlist[i] = (LPCITEMIDLIST)node->pidlSignaled;
*lpwEventId = node->wSignalledEvent;
*lppidls = (LPITEMIDLIST*)idlist;
node->wSignalledEvent = 0;
}
else
ERR("Couldn't find %p\n", hChange );
/* LeaveCriticalSection(&SHELL32_ChangenotifyCS); */
return (HANDLE) node;
}
/*************************************************************************
* SHChangeNotification_Unlock [SHELL32.645]
*/
BOOL WINAPI SHChangeNotification_Unlock ( HANDLE hLock)
{
TRACE("\n");
return 1;
}
/*************************************************************************
* NTSHChangeNotifyDeregister [SHELL32.641]
*/
EXTERN_C DWORD WINAPI NTSHChangeNotifyDeregister(ULONG x1)
{
FIXME("(0x%08x):semi stub.\n",x1);
return SHChangeNotifyDeregister( x1 );
}

View file

@ -0,0 +1,506 @@
/*
* file type mapping
* (HKEY_CLASSES_ROOT - Stuff)
*
* Copyright 1998, 1999, 2000 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
#define MAX_EXTENSION_LENGTH 20
BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, LONG len, BOOL bPrependDot)
{
HKEY hkey;
WCHAR szTemp[MAX_EXTENSION_LENGTH + 2];
TRACE("%s %p\n", debugstr_w(szExtension), debugstr_w(szFileType));
/* added because we do not want to have double dots */
if (szExtension[0] == '.')
bPrependDot = 0;
if (bPrependDot)
szTemp[0] = '.';
lstrcpynW(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szTemp, 0, KEY_READ, &hkey))
{
return FALSE;
}
if (RegQueryValueW(hkey, NULL, szFileType, &len))
{
RegCloseKey(hkey);
return FALSE;
}
RegCloseKey(hkey);
TRACE("--UE;\n} %s\n", debugstr_w(szFileType));
return TRUE;
}
BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, LONG len, BOOL bPrependDot)
{
HKEY hkey;
char szTemp[MAX_EXTENSION_LENGTH + 2];
TRACE("%s %p\n", szExtension, szFileType);
/* added because we do not want to have double dots */
if (szExtension[0] == '.')
bPrependDot = 0;
if (bPrependDot)
szTemp[0] = '.';
lstrcpynA(szTemp + (bPrependDot?1:0), szExtension, MAX_EXTENSION_LENGTH);
if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_READ, &hkey))
{
return FALSE;
}
if (RegLoadMUIStringA(hkey, "FriendlyTypeName", szFileType, len, NULL, 0, NULL) == ERROR_SUCCESS)
{
RegCloseKey(hkey);
return TRUE;
}
if (RegQueryValueA(hkey, NULL, szFileType, &len))
{
RegCloseKey(hkey);
return FALSE;
}
RegCloseKey(hkey);
TRACE("--UE;\n} %s\n", szFileType);
return TRUE;
}
static const WCHAR swShell[] = {'s','h','e','l','l','\\',0};
static const WCHAR swOpen[] = {'o','p','e','n',0};
static const WCHAR swCommand[] = {'\\','c','o','m','m','a','n','d',0};
BOOL HCR_GetDefaultVerbW( HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len )
{
WCHAR sTemp[MAX_PATH];
LONG size;
HKEY hkey;
TRACE("%p %s %p\n", hkeyClass, debugstr_w(szVerb), szDest);
if (szVerb)
{
lstrcpynW(szDest, szVerb, len);
return TRUE;
}
size=len;
*szDest='\0';
if (!RegQueryValueW(hkeyClass, L"shell", szDest, &size) && *szDest)
{
/* The MSDN says to first try the default verb */
wcscpy(sTemp, swShell);
wcscat(sTemp, szDest);
wcscat(sTemp, swCommand);
if (!RegOpenKeyExW(hkeyClass, sTemp, 0, KEY_READ, &hkey))
{
RegCloseKey(hkey);
TRACE("default verb=%s\n", debugstr_w(szDest));
return TRUE;
}
}
/* then fallback to 'open' */
wcscpy(sTemp, swShell);
wcscat(sTemp, swOpen);
wcscat(sTemp, swCommand);
if (!RegOpenKeyExW(hkeyClass, sTemp, 0, KEY_READ, &hkey))
{
RegCloseKey(hkey);
lstrcpynW(szDest, swOpen, len);
TRACE("default verb=open\n");
return TRUE;
}
/* and then just use the first verb on Windows >= 2000 */
if (!RegOpenKeyExW(hkeyClass, L"shell", 0, KEY_READ, &hkey))
{
if (!RegEnumKeyW(hkey, 0, szDest, len) && *szDest)
{
TRACE("default verb=first verb=%s\n", debugstr_w(szDest));
RegCloseKey(hkey);
return TRUE;
}
RegCloseKey(hkey);
}
TRACE("no default verb!\n");
return FALSE;
}
BOOL HCR_GetExecuteCommandW( HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len )
{
WCHAR sTempVerb[MAX_PATH];
BOOL ret;
TRACE("%p %s %s %p\n", hkeyClass, debugstr_w(szClass), debugstr_w(szVerb), szDest);
if (szClass)
RegOpenKeyExW(HKEY_CLASSES_ROOT, szClass, 0, KEY_READ, &hkeyClass);
if (!hkeyClass)
return FALSE;
ret = FALSE;
if (HCR_GetDefaultVerbW(hkeyClass, szVerb, sTempVerb, sizeof(sTempVerb)))
{
WCHAR sTemp[MAX_PATH];
wcscpy(sTemp, swShell);
wcscat(sTemp, sTempVerb);
wcscat(sTemp, swCommand);
ret = (ERROR_SUCCESS == SHGetValueW(hkeyClass, sTemp, NULL, NULL, szDest, &len));
}
if (szClass)
RegCloseKey(hkeyClass);
TRACE("-- %s\n", debugstr_w(szDest) );
return ret;
}
/***************************************************************************************
* HCR_GetDefaultIcon [internal]
*
* Gets the icon for a filetype
*/
static BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey)
{
WCHAR xriid[50];
swprintf( xriid, L"CLSID\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
riid.Data1, riid.Data2, riid.Data3,
riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3],
riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7] );
TRACE("%S\n",xriid );
return !RegOpenKeyExW(HKEY_CLASSES_ROOT, xriid, 0, KEY_READ, hkey);
}
static BOOL HCR_RegGetDefaultIconW(HKEY hkey, LPWSTR szDest, DWORD len, int* picon_idx)
{
DWORD dwType;
WCHAR sTemp[MAX_PATH];
WCHAR sNum[7];
if (!RegQueryValueExW(hkey, NULL, 0, &dwType, (LPBYTE)szDest, &len))
{
if (dwType == REG_EXPAND_SZ)
{
ExpandEnvironmentStringsW(szDest, sTemp, MAX_PATH);
lstrcpynW(szDest, sTemp, len);
}
if (ParseFieldW (szDest, 2, sNum, _countof(sNum)))
*picon_idx = atoiW(sNum);
else
*picon_idx=0; /* sometimes the icon number is missing */
ParseFieldW (szDest, 1, szDest, len);
PathUnquoteSpacesW(szDest);
return TRUE;
}
return FALSE;
}
static BOOL HCR_RegGetDefaultIconA(HKEY hkey, LPSTR szDest, DWORD len, int* picon_idx)
{
DWORD dwType;
char sTemp[MAX_PATH];
char sNum[5];
if (!RegQueryValueExA(hkey, NULL, 0, &dwType, (LPBYTE)szDest, &len))
{
if (dwType == REG_EXPAND_SZ)
{
ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
lstrcpynA(szDest, sTemp, len);
}
if (ParseFieldA (szDest, 2, sNum, 5))
*picon_idx=atoi(sNum);
else
*picon_idx=0; /* sometimes the icon number is missing */
ParseFieldA (szDest, 1, szDest, len);
PathUnquoteSpacesA(szDest);
return TRUE;
}
return FALSE;
}
BOOL HCR_GetDefaultIconW(LPCWSTR szClass, LPWSTR szDest, DWORD len, int* picon_idx)
{
static const WCHAR swDefaultIcon[] = {'\\','D','e','f','a','u','l','t','I','c','o','n',0};
HKEY hkey;
WCHAR sTemp[MAX_PATH];
BOOL ret = FALSE;
TRACE("%s\n",debugstr_w(szClass) );
lstrcpynW(sTemp, szClass, MAX_PATH);
wcscat(sTemp, swDefaultIcon);
if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, sTemp, 0, KEY_READ, &hkey))
{
ret = HCR_RegGetDefaultIconW(hkey, szDest, len, picon_idx);
RegCloseKey(hkey);
}
if(ret)
TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx);
else
TRACE("-- not found\n");
return ret;
}
BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, int* picon_idx)
{
HKEY hkey;
char sTemp[MAX_PATH];
BOOL ret = FALSE;
TRACE("%s\n",szClass );
sprintf(sTemp, "%s\\DefaultIcon",szClass);
if (!RegOpenKeyExA(HKEY_CLASSES_ROOT, sTemp, 0, KEY_READ, &hkey))
{
ret = HCR_RegGetDefaultIconA(hkey, szDest, len, picon_idx);
RegCloseKey(hkey);
}
TRACE("-- %s %i\n", szDest, *picon_idx);
return ret;
}
BOOL HCR_GetDefaultIconFromGUIDW(REFIID riid, LPWSTR szDest, DWORD len, int* picon_idx)
{
HKEY hkey;
BOOL ret = FALSE;
if (HCR_RegOpenClassIDKey(riid, &hkey))
{
ret = HCR_RegGetDefaultIconW(hkey, szDest, len, picon_idx);
RegCloseKey(hkey);
}
TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx);
return ret;
}
/***************************************************************************************
* HCR_GetClassName [internal]
*
* Gets the name of a registered class
*/
static const WCHAR swEmpty[] = {0};
BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len)
{
HKEY hkey;
BOOL ret = FALSE;
DWORD buflen = len;
WCHAR szName[100];
LPOLESTR pStr;
szDest[0] = 0;
if (StringFromCLSID(riid, &pStr) == S_OK)
{
DWORD dwLen = buflen * sizeof(WCHAR);
swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr);
if (RegGetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, NULL, (PVOID)szDest, &dwLen) == ERROR_SUCCESS)
{
ret = TRUE;
}
CoTaskMemFree(pStr);
}
if (!ret && HCR_RegOpenClassIDKey(riid, &hkey))
{
static const WCHAR wszLocalizedString[] =
{ 'L','o','c','a','l','i','z','e','d','S','t','r','i','n','g', 0 };
if (!RegLoadMUIStringW(hkey, wszLocalizedString, szDest, len, NULL, 0, NULL) ||
!RegQueryValueExW(hkey, swEmpty, 0, NULL, (LPBYTE)szDest, &len))
{
ret = TRUE;
}
RegCloseKey(hkey);
}
if (!ret || !szDest[0])
{
if(IsEqualIID(riid, CLSID_ShellDesktop))
{
if (LoadStringW(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
ret = TRUE;
}
else if (IsEqualIID(riid, CLSID_MyComputer))
{
if(LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
ret = TRUE;
}
else if (IsEqualIID(riid, CLSID_MyDocuments))
{
if(LoadStringW(shell32_hInstance, IDS_PERSONAL, szDest, buflen))
ret = TRUE;
}
else if (IsEqualIID(riid, CLSID_RecycleBin))
{
if(LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_FOLDER_NAME, szDest, buflen))
ret = TRUE;
}
else if (IsEqualIID(riid, CLSID_ControlPanel))
{
if(LoadStringW(shell32_hInstance, IDS_CONTROLPANEL, szDest, buflen))
ret = TRUE;
}
else if (IsEqualIID(riid, CLSID_AdminFolderShortcut))
{
if(LoadStringW(shell32_hInstance, IDS_ADMINISTRATIVETOOLS, szDest, buflen))
ret = TRUE;
}
}
TRACE("-- %s\n", debugstr_w(szDest));
return ret;
}
BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len)
{ HKEY hkey;
BOOL ret = FALSE;
DWORD buflen = len;
szDest[0] = 0;
if (HCR_RegOpenClassIDKey(riid, &hkey))
{
if (!RegLoadMUIStringA(hkey,"LocalizedString",szDest,len,NULL,0,NULL) ||
!RegQueryValueExA(hkey,"",0,NULL,(LPBYTE)szDest,&len))
{
ret = TRUE;
}
RegCloseKey(hkey);
}
if (!ret || !szDest[0])
{
if(IsEqualIID(riid, CLSID_ShellDesktop))
{
if (LoadStringA(shell32_hInstance, IDS_DESKTOP, szDest, buflen))
ret = TRUE;
}
else if (IsEqualIID(riid, CLSID_MyComputer))
{
if(LoadStringA(shell32_hInstance, IDS_MYCOMPUTER, szDest, buflen))
ret = TRUE;
}
}
TRACE("-- %s\n", szDest);
return ret;
}
/******************************************************************************
* HCR_GetFolderAttributes [Internal]
*
* Query the registry for a shell folders' attributes
*
* PARAMS
* pidlFolder [I] A simple pidl of type PT_GUID.
* pdwAttributes [IO] In: Attributes to be queried, OUT: Resulting attributes.
*
* RETURNS
* TRUE: Found information for the attributes in the registry
* FALSE: No attribute information found
*
* NOTES
* If queried for an attribute, which is set in the CallForAttributes registry
* value, the function binds to the shellfolder objects and queries it.
*/
BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD pdwAttributes)
{
HKEY hSFKey;
LPOLESTR pwszCLSID;
LONG lResult;
DWORD dwTemp, dwLen;
static const WCHAR wszAttributes[] = { 'A','t','t','r','i','b','u','t','e','s',0 };
static const WCHAR wszCallForAttributes[] = {
'C','a','l','l','F','o','r','A','t','t','r','i','b','u','t','e','s',0 };
WCHAR wszShellFolderKey[] = { 'C','L','S','I','D','\\','{','0','0','0','2','1','4','0','0','-',
'0','0','0','0','-','0','0','0','0','-','C','0','0','0','-','0','0','0','0','0','0','0',
'0','0','0','4','6','}','\\','S','h','e','l','l','F','o','l','d','e','r',0 };
TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder, pdwAttributes);
if (!_ILIsPidlSimple(pidlFolder)) {
ERR("should be called for simple PIDL's only!\n");
return FALSE;
}
if (!_ILIsDesktop(pidlFolder)) {
if (FAILED(StringFromCLSID(*_ILGetGUIDPointer(pidlFolder), &pwszCLSID))) return FALSE;
memcpy(&wszShellFolderKey[6], pwszCLSID, 38 * sizeof(WCHAR));
CoTaskMemFree(pwszCLSID);
}
lResult = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszShellFolderKey, 0, KEY_READ, &hSFKey);
if (lResult != ERROR_SUCCESS) return FALSE;
dwLen = sizeof(DWORD);
lResult = RegQueryValueExW(hSFKey, wszCallForAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen);
if ((lResult == ERROR_SUCCESS) && (dwTemp & *pdwAttributes)) {
CComPtr<IShellFolder> psfDesktop;
CComPtr<IShellFolder> psfFolder;
HRESULT hr;
RegCloseKey(hSFKey);
hr = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hr)) {
hr = psfDesktop->BindToObject(pidlFolder, NULL, IID_IShellFolder,
(LPVOID*)&psfFolder);
if (SUCCEEDED(hr)) {
hr = psfFolder->GetAttributesOf(0, NULL, pdwAttributes);
}
}
if (FAILED(hr)) return FALSE;
} else {
lResult = RegQueryValueExW(hSFKey, wszAttributes, 0, NULL, (LPBYTE)&dwTemp, &dwLen);
RegCloseKey(hSFKey);
if (lResult == ERROR_SUCCESS) {
*pdwAttributes &= dwTemp;
} else {
return FALSE;
}
}
TRACE("-- *pdwAttributes == 0x%08x\n", *pdwAttributes);
return TRUE;
}

View file

@ -0,0 +1,240 @@
/*
* clipboard helper functions
*
* Copyright 2000 Juergen Schmied <juergen.schmied@debitel.de>
*
* 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
*
* NOTES:
*
* For copy & paste functions within contextmenus does the shell use
* the OLE clipboard functions in combination with dataobjects.
* The OLE32.DLL gets loaded with LoadLibrary
*
* - a right mousebutton-copy sets the following formats:
* classic:
* Shell IDList Array
* Preferred Drop Effect
* Shell Object Offsets
* HDROP
* FileName
* ole:
* OlePrivateData (ClipboardDataObjectInterface)
*
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/**************************************************************************
* RenderHDROP
*
* creates a CF_HDROP structure
*/
HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
UINT i;
int size = 0;
WCHAR wszFileName[MAX_PATH];
HGLOBAL hGlobal = NULL;
DROPFILES *pDropFiles;
int offset;
LPITEMIDLIST *pidls;
TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
pidls = (LPITEMIDLIST *)HeapAlloc(GetProcessHeap(), 0, cidl * sizeof(*pidls));
if (!pidls)
goto cleanup;
/* get the size needed */
size = sizeof(DROPFILES);
for (i=0; i<cidl;i++)
{
pidls[i] = ILCombine(pidlRoot, apidl[i]);
SHGetPathFromIDListW(pidls[i], wszFileName);
size += (wcslen(wszFileName) + 1) * sizeof(WCHAR);
}
size += sizeof(WCHAR);
/* Fill the structure */
hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
if(!hGlobal)
goto cleanup;
pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR);
pDropFiles->pFiles = offset * sizeof(WCHAR);
pDropFiles->fWide = TRUE;
for (i=0; i<cidl;i++)
{
SHGetPathFromIDListW(pidls[i], wszFileName);
wcscpy(((WCHAR*)pDropFiles)+offset, wszFileName);
offset += wcslen(wszFileName) + 1;
ILFree(pidls[i]);
}
((WCHAR*)pDropFiles)[offset] = 0;
GlobalUnlock(hGlobal);
cleanup:
if(pidls)
HeapFree(GetProcessHeap(), 0, pidls);
return hGlobal;
}
HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
UINT i;
int offset = 0, sizePidl, size;
HGLOBAL hGlobal;
LPIDA pcida;
TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
/* get the size needed */
size = sizeof(CIDA) + sizeof (UINT)*(cidl); /* header */
size += ILGetSize (pidlRoot); /* root pidl */
for(i=0; i<cidl; i++)
{
size += ILGetSize(apidl[i]); /* child pidls */
}
/* fill the structure */
hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
if(!hGlobal) return hGlobal;
pcida = (LPIDA)GlobalLock (hGlobal);
pcida->cidl = cidl;
/* root pidl */
offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
pcida->aoffset[0] = offset; /* first element */
sizePidl = ILGetSize (pidlRoot);
memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
offset += sizePidl;
for(i=0; i<cidl; i++) /* child pidls */
{
pcida->aoffset[i+1] = offset;
sizePidl = ILGetSize(apidl[i]);
memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
offset += sizePidl;
}
GlobalUnlock(hGlobal);
return hGlobal;
}
HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
FIXME("\n");
return 0;
}
HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
FIXME("\n");
return 0;
}
HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
FIXME("\n");
return 0;
}
HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
int size = 0;
char szTemp[MAX_PATH], *szFileName;
LPITEMIDLIST pidl;
HGLOBAL hGlobal;
BOOL bSuccess;
TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
/* get path of combined pidl */
pidl = ILCombine(pidlRoot, apidl[0]);
if (!pidl)
return 0;
bSuccess = SHGetPathFromIDListA(pidl, szTemp);
SHFree(pidl);
if (!bSuccess)
return 0;
size = strlen(szTemp) + 1;
/* fill the structure */
hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
if(!hGlobal) return hGlobal;
szFileName = (char *)GlobalLock(hGlobal);
memcpy(szFileName, szTemp, size);
GlobalUnlock(hGlobal);
return hGlobal;
}
HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
{
int size = 0;
WCHAR szTemp[MAX_PATH], *szFileName;
LPITEMIDLIST pidl;
HGLOBAL hGlobal;
BOOL bSuccess;
TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
/* get path of combined pidl */
pidl = ILCombine(pidlRoot, apidl[0]);
if (!pidl)
return 0;
bSuccess = SHGetPathFromIDListW(pidl, szTemp);
SHFree(pidl);
if (!bSuccess)
return 0;
size = (wcslen(szTemp)+1) * sizeof(WCHAR);
/* fill the structure */
hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
if(!hGlobal) return hGlobal;
szFileName = (WCHAR *)GlobalLock(hGlobal);
memcpy(szFileName, szTemp, size);
GlobalUnlock(hGlobal);
return hGlobal;
}
HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
{
DWORD * pdwFlag;
HGLOBAL hGlobal;
TRACE("(0x%08x)\n", dwFlags);
hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
if(!hGlobal) return hGlobal;
pdwFlag = (DWORD*)GlobalLock(hGlobal);
*pdwFlag = dwFlags;
GlobalUnlock(hGlobal);
return hGlobal;
}

View file

@ -0,0 +1,524 @@
/* Control Panel management
*
* Copyright 2001 Eric Pouech
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shlctrl);
CPlApplet* Control_UnloadApplet(CPlApplet* applet)
{
unsigned i;
CPlApplet* next;
for (i = 0; i < applet->count; i++) {
if (!applet->info[i].dwSize) continue;
applet->proc(applet->hWnd, CPL_STOP, i, applet->info[i].lData);
}
if (applet->proc) applet->proc(applet->hWnd, CPL_EXIT, 0L, 0L);
FreeLibrary(applet->hModule);
next = applet->next;
HeapFree(GetProcessHeap(), 0, applet);
return next;
}
CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
{
CPlApplet* applet;
unsigned i;
CPLINFO info;
NEWCPLINFOW newinfo;
if (!(applet = (CPlApplet *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*applet))))
return applet;
applet->hWnd = hWnd;
if (!(applet->hModule = LoadLibraryW(cmd))) {
WARN("Cannot load control panel applet %s\n", debugstr_w(cmd));
goto theError;
}
if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) {
WARN("Not a valid control panel applet %s\n", debugstr_w(cmd));
goto theError;
}
if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) {
WARN("Init of applet has failed\n");
goto theError;
}
if ((applet->count = applet->proc(hWnd, CPL_GETCOUNT, 0L, 0L)) == 0) {
WARN("No subprogram in applet\n");
goto theError;
}
applet = (CPlApplet *)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet,
sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOW));
for (i = 0; i < applet->count; i++) {
ZeroMemory(&newinfo, sizeof(newinfo));
newinfo.dwSize = sizeof(NEWCPLINFOW);
applet->info[i].dwSize = sizeof(NEWCPLINFOW);
/* proc is supposed to return a null value upon success for
* CPL_INQUIRE and CPL_NEWINQUIRE
* However, real drivers don't seem to behave like this
* So, use introspection rather than return value
*/
applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&newinfo);
if (newinfo.hIcon == 0) {
applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info);
if (info.idIcon == 0 || info.idName == 0) {
WARN("Couldn't get info from sp %u\n", i);
applet->info[i].dwSize = 0;
} else {
/* convert the old data into the new structure */
applet->info[i].dwFlags = 0;
applet->info[i].dwHelpContext = 0;
applet->info[i].lData = info.lData;
applet->info[i].hIcon = LoadIconW(applet->hModule,
MAKEINTRESOURCEW(info.idIcon));
LoadStringW(applet->hModule, info.idName,
applet->info[i].szName, sizeof(applet->info[i].szName) / sizeof(WCHAR));
LoadStringW(applet->hModule, info.idInfo,
applet->info[i].szInfo, sizeof(applet->info[i].szInfo) / sizeof(WCHAR));
applet->info[i].szHelpFile[0] = '\0';
}
}
else
{
CopyMemory(&applet->info[i], &newinfo, newinfo.dwSize);
if (newinfo.dwSize != sizeof(NEWCPLINFOW))
{
applet->info[i].dwSize = sizeof(NEWCPLINFOW);
lstrcpyW(applet->info[i].szName, newinfo.szName);
lstrcpyW(applet->info[i].szInfo, newinfo.szInfo);
lstrcpyW(applet->info[i].szHelpFile, newinfo.szHelpFile);
}
}
}
applet->next = panel->first;
panel->first = applet;
return applet;
theError:
Control_UnloadApplet(applet);
return NULL;
}
static void Control_WndProc_Create(HWND hWnd, const CREATESTRUCTW* cs)
{
CPanel* panel = (CPanel*)cs->lpCreateParams;
SetWindowLongPtrW(hWnd, 0, (LONG_PTR)panel);
panel->status = 0;
panel->hWnd = hWnd;
}
#define XICON 32
#define XSTEP 128
#define YICON 32
#define YSTEP 64
static BOOL Control_Localize(const CPanel* panel, int cx, int cy,
CPlApplet** papplet, unsigned* psp)
{
unsigned int i;
int x = (XSTEP-XICON)/2, y = 0;
CPlApplet* applet;
RECT rc;
GetClientRect(panel->hWnd, &rc);
for (applet = panel->first; applet; applet = applet->next) {
for (i = 0; i < applet->count; i++) {
if (!applet->info[i].dwSize) continue;
if (x + XSTEP >= rc.right - rc.left) {
x = (XSTEP-XICON)/2;
y += YSTEP;
}
if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP) {
*papplet = applet;
*psp = i;
return TRUE;
}
x += XSTEP;
}
}
return FALSE;
}
static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rc, txtRect;
unsigned int i;
int x = 0, y = 0;
CPlApplet* applet;
HGDIOBJ hOldFont;
hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps);
hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
GetClientRect(panel->hWnd, &rc);
for (applet = panel->first; applet; applet = applet->next) {
for (i = 0; i < applet->count; i++) {
if (x + XSTEP >= rc.right - rc.left) {
x = 0;
y += YSTEP;
}
if (!applet->info[i].dwSize) continue;
DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon);
txtRect.left = x;
txtRect.right = x + XSTEP;
txtRect.top = y + YICON;
txtRect.bottom = y + YSTEP;
DrawTextW(hdc, applet->info[i].szName, -1, &txtRect,
DT_CENTER | DT_VCENTER);
x += XSTEP;
}
}
SelectObject(hdc, hOldFont);
if (!wParam) EndPaint(panel->hWnd, &ps);
return 0;
}
static LRESULT Control_WndProc_LButton(CPanel* panel, LPARAM lParam, BOOL up)
{
unsigned i;
CPlApplet* applet;
if (Control_Localize(panel, (short)LOWORD(lParam), (short)HIWORD(lParam), &applet, &i)) {
if (up) {
if (panel->clkApplet == applet && panel->clkSP == i) {
applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData);
}
} else {
panel->clkApplet = applet;
panel->clkSP = i;
}
}
return 0;
}
static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg,
WPARAM lParam1, LPARAM lParam2)
{
CPanel* panel = (CPanel*)GetWindowLongPtrW(hWnd, 0);
if (panel || wMsg == WM_CREATE) {
switch (wMsg) {
case WM_CREATE:
Control_WndProc_Create(hWnd, (CREATESTRUCTW*)lParam2);
return 0;
case WM_DESTROY:
{
CPlApplet* applet = panel->first;
while (applet)
applet = Control_UnloadApplet(applet);
}
PostQuitMessage(0);
break;
case WM_PAINT:
return Control_WndProc_Paint(panel, lParam1);
case WM_LBUTTONUP:
return Control_WndProc_LButton(panel, lParam2, TRUE);
case WM_LBUTTONDOWN:
return Control_WndProc_LButton(panel, lParam2, FALSE);
/* EPP case WM_COMMAND: */
/* EPP return Control_WndProc_Command(mwi, lParam1, lParam2); */
}
}
return DefWindowProcW(hWnd, wMsg, lParam1, lParam2);
}
static void Control_DoInterface(CPanel* panel, HWND hWnd, HINSTANCE hInst)
{
WNDCLASSW wc;
MSG msg;
const WCHAR* appName = L"ReactOS Control Panel";
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = Control_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(CPlApplet*);
wc.hInstance = hInst;
wc.hIcon = 0;
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"Shell_Control_WndClass";
if (!RegisterClassW(&wc)) return;
CreateWindowExW(0, wc.lpszClassName, appName,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, NULL, hInst, panel);
if (!panel->hWnd) return;
if (!panel->first) {
/* FIXME appName & message should be localized */
MessageBoxW(panel->hWnd, L"Cannot load any applets", appName, MB_OK);
return;
}
while (GetMessageW(&msg, panel->hWnd, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
static void Control_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst)
{
HANDLE h;
WIN32_FIND_DATAW fd;
WCHAR buffer[MAX_PATH];
static const WCHAR wszAllCpl[] = {'*','.','c','p','l',0};
WCHAR *p;
GetSystemDirectoryW( buffer, MAX_PATH );
p = buffer + wcslen(buffer);
*p++ = '\\';
wcscpy(p, wszAllCpl);
if ((h = FindFirstFileW(buffer, &fd)) != INVALID_HANDLE_VALUE) {
do {
wcscpy(p, fd.cFileName);
Control_LoadApplet(hWnd, buffer, panel);
} while (FindNextFileW(h, &fd));
FindClose(h);
}
Control_DoInterface(panel, hWnd, hInst);
}
static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
/* forms to parse:
* foo.cpl,@sp,str
* foo.cpl,@sp
* foo.cpl,,str
* foo.cpl @sp
* foo.cpl str
* "a path\foo.cpl"
*/
{
LPWSTR buffer;
LPWSTR beg = NULL;
LPWSTR end;
WCHAR ch;
LPCWSTR ptr, ptr2;
WCHAR szName[MAX_PATH];
unsigned sp = 0;
LPWSTR extraPmts = NULL;
int quoted = 0;
BOOL spSet = FALSE;
HANDLE hMutex;
UINT Length;
ptr = wcsrchr(wszCmd, L'\\');
ptr2 = wcsrchr(wszCmd, L',');
if (!ptr2)
{
ptr2 = wszCmd + wcslen(wszCmd) + 1;
}
if (ptr)
ptr++;
else
ptr = wszCmd;
Length = (ptr2 - ptr);
if (Length >= MAX_PATH)
return;
memcpy(szName, (LPVOID)ptr, Length * sizeof(WCHAR));
szName[Length] = L'\0';
hMutex = CreateMutexW(NULL, TRUE, szName);
if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS))
return;
buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(wszCmd) + 1) * sizeof(*wszCmd));
if (!buffer)
{
CloseHandle(hMutex);
return;
}
end = wcscpy(buffer, wszCmd);
for (;;) {
ch = *end;
if (ch == '"') quoted = !quoted;
if (!quoted && (ch == ' ' || ch == ',' || ch == '\0')) {
*end = '\0';
if (beg) {
if (*beg == '@') {
sp = atoiW(beg + 1);
spSet = TRUE;
} else if (*beg == '\0') {
sp = 0;
spSet = TRUE;
} else {
extraPmts = beg;
}
}
if (ch == '\0') break;
beg = end + 1;
if (ch == ' ') while (end[1] == ' ') end++;
}
end++;
}
while ((ptr = StrChrW(buffer, '"')))
memmove((LPVOID)ptr, ptr+1, wcslen(ptr)*sizeof(WCHAR));
while ((ptr = StrChrW(extraPmts, '"')))
memmove((LPVOID)ptr, ptr+1, wcslen(ptr)*sizeof(WCHAR));
TRACE("cmd %s, extra %s, sp %d\n", debugstr_w(buffer), debugstr_w(extraPmts), sp);
Control_LoadApplet(hWnd, buffer, panel);
if (panel->first) {
CPlApplet* applet = panel->first;
assert(applet && applet->next == NULL);
if (sp >= applet->count) {
WARN("Out of bounds (%u >= %u), setting to 0\n", sp, applet->count);
sp = 0;
}
if ((extraPmts) && extraPmts[0] &&(!spSet))
{
while ((lstrcmpiW(extraPmts, applet->info[sp].szName)) && (sp < applet->count))
sp++;
if (sp >= applet->count)
{
ReleaseMutex(hMutex);
CloseHandle(hMutex);
Control_UnloadApplet(applet);
HeapFree(GetProcessHeap(), 0, buffer);
return;
}
}
if (applet->info[sp].dwSize) {
if (!applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].lData))
applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp, (LPARAM)extraPmts);
}
Control_UnloadApplet(applet);
}
ReleaseMutex(hMutex);
CloseHandle(hMutex);
HeapFree(GetProcessHeap(), 0, buffer);
}
/*************************************************************************
* Control_RunDLLW [SHELL32.@]
*
*/
EXTERN_C void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
{
CPanel panel;
TRACE("(%p, %p, %s, 0x%08x)\n",
hWnd, hInst, debugstr_w(cmd), nCmdShow);
memset(&panel, 0, sizeof(panel));
if (!cmd || !*cmd) {
Control_DoWindow(&panel, hWnd, hInst);
} else {
Control_DoLaunch(&panel, hWnd, cmd);
}
}
/*************************************************************************
* Control_RunDLLA [SHELL32.@]
*
*/
EXTERN_C void WINAPI Control_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
DWORD len = MultiByteToWideChar(CP_ACP, 0, cmd, -1, NULL, 0 );
LPWSTR wszCmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wszCmd && MultiByteToWideChar(CP_ACP, 0, cmd, -1, wszCmd, len ))
{
Control_RunDLLW(hWnd, hInst, wszCmd, nCmdShow);
}
HeapFree(GetProcessHeap(), 0, wszCmd);
}
/*************************************************************************
* Control_FillCache_RunDLLW [SHELL32.@]
*
*/
EXTERN_C HRESULT WINAPI Control_FillCache_RunDLLW(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
{
FIXME("%p %p 0x%08x 0x%08x stub\n", hWnd, hModule, w, x);
return 0;
}
/*************************************************************************
* Control_FillCache_RunDLLA [SHELL32.@]
*
*/
EXTERN_C HRESULT WINAPI Control_FillCache_RunDLLA(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
{
return Control_FillCache_RunDLLW(hWnd, hModule, w, x);
}
/*************************************************************************
* RunDLL_CallEntry16 [SHELL32.122]
* the name is probably wrong
*/
EXTERN_C void WINAPI RunDLL_CallEntry16( DWORD proc, HWND hwnd, HINSTANCE inst,
LPCSTR cmdline, INT cmdshow )
{
#if !defined(__CYGWIN__) && !defined (__MINGW32__) && !defined(_MSC_VER)
WORD args[5];
SEGPTR cmdline_seg;
TRACE( "proc %x hwnd %p inst %p cmdline %s cmdshow %d\n",
proc, hwnd, inst, debugstr_a(cmdline), cmdshow );
cmdline_seg = MapLS( cmdline );
args[4] = HWND_16(hwnd);
args[3] = MapHModuleLS(inst);
args[2] = SELECTOROF(cmdline_seg);
args[1] = OFFSETOF(cmdline_seg);
args[0] = cmdshow;
WOWCallback16Ex( proc, WCB16_PASCAL, sizeof(args), args, NULL );
UnMapLS( cmdline_seg );
#else
FIXME( "proc %lx hwnd %p inst %p cmdline %s cmdshow %d\n",
proc, hwnd, inst, debugstr_a(cmdline), cmdshow );
#endif
}
/*************************************************************************
* CallCPLEntry16 [SHELL32.166]
*
* called by desk.cpl on "Advanced" with:
* hMod("DeskCp16.Dll"), pFunc("CplApplet"), 0, 1, 0xc, 0
*
*/
LRESULT WINAPI CallCPLEntry16(HINSTANCE hMod, FARPROC pFunc, HWND dw3, UINT dw4, LPARAM dw5, LPARAM dw6)
{
FIXME("(%p, %p, %08x, %08x, %08x, %08x): stub.\n", hMod, pFunc, dw3, dw4, dw5, dw6);
return 0x0deadbee;
}

View file

@ -0,0 +1,391 @@
/*
* IEnumFORMATETC, IDataObject
*
* selecting and droping objects within the shell and/or common dialogs
*
* Copyright 1998, 1999 <juergen.schmied@metronet.de>
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/***********************************************************************
* IEnumFORMATETC implementation
*/
class IEnumFORMATETCImpl :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IEnumFORMATETC
{
private:
UINT posFmt;
UINT countFmt;
LPFORMATETC pFmt;
public:
IEnumFORMATETCImpl();
~IEnumFORMATETCImpl();
HRESULT WINAPI Initialize(UINT cfmt, const FORMATETC afmt[]);
// *****************
virtual HRESULT WINAPI Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed);
virtual HRESULT WINAPI Skip(ULONG celt);
virtual HRESULT WINAPI Reset();
virtual HRESULT WINAPI Clone(LPENUMFORMATETC* ppenum);
BEGIN_COM_MAP(IEnumFORMATETCImpl)
COM_INTERFACE_ENTRY_IID(IID_IEnumFORMATETC, IEnumFORMATETC)
END_COM_MAP()
};
IEnumFORMATETCImpl::IEnumFORMATETCImpl()
{
posFmt = 0;
countFmt = 0;
pFmt = NULL;
}
IEnumFORMATETCImpl::~IEnumFORMATETCImpl()
{
}
HRESULT WINAPI IEnumFORMATETCImpl::Initialize(UINT cfmt, const FORMATETC afmt[])
{
DWORD size;
size = cfmt * sizeof(FORMATETC);
countFmt = cfmt;
pFmt = (LPFORMATETC)SHAlloc(size);
if (pFmt == NULL)
return E_OUTOFMEMORY;
memcpy(pFmt, afmt, size);
return S_OK;
}
HRESULT WINAPI IEnumFORMATETCImpl::Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
{
UINT i;
TRACE("(%p)->(%u,%p)\n", this, celt, rgelt);
if(!pFmt)return S_FALSE;
if(!rgelt) return E_INVALIDARG;
if (pceltFethed) *pceltFethed = 0;
for(i = 0; posFmt < countFmt && celt > i; i++)
{
*rgelt++ = pFmt[posFmt++];
}
if (pceltFethed) *pceltFethed = i;
return ((i == celt) ? S_OK : S_FALSE);
}
HRESULT WINAPI IEnumFORMATETCImpl::Skip(ULONG celt)
{
TRACE("(%p)->(num=%u)\n", this, celt);
if (posFmt + celt >= countFmt) return S_FALSE;
posFmt += celt;
return S_OK;
}
HRESULT WINAPI IEnumFORMATETCImpl::Reset()
{
TRACE("(%p)->()\n", this);
posFmt = 0;
return S_OK;
}
HRESULT WINAPI IEnumFORMATETCImpl::Clone(LPENUMFORMATETC* ppenum)
{
HRESULT hResult;
TRACE("(%p)->(ppenum=%p)\n", this, ppenum);
if (!ppenum) return E_INVALIDARG;
hResult = IEnumFORMATETC_Constructor(countFmt, pFmt, ppenum);
if (FAILED (hResult))
return hResult;
return (*ppenum)->Skip(posFmt);
}
HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **enumerator)
{
CComObject<IEnumFORMATETCImpl> *theEnumerator;
CComPtr<IEnumFORMATETC> result;
HRESULT hResult;
if (enumerator == NULL)
return E_POINTER;
*enumerator = NULL;
ATLTRY (theEnumerator = new CComObject<IEnumFORMATETCImpl>);
if (theEnumerator == NULL)
return E_OUTOFMEMORY;
hResult = theEnumerator->QueryInterface (IID_IEnumFORMATETC, (void **)&result);
if (FAILED (hResult))
{
delete theEnumerator;
return hResult;
}
hResult = theEnumerator->Initialize (cfmt, afmt);
if (FAILED (hResult))
return hResult;
*enumerator = result.Detach ();
TRACE("(%p)->(%u,%p)\n", *enumerator, cfmt, afmt);
return S_OK;
}
/***********************************************************************
* IDataObject implementation
*/
/* number of supported formats */
#define MAX_FORMATS 4
class IDataObjectImpl :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDataObject
{
private:
LPITEMIDLIST pidl;
LPITEMIDLIST * apidl;
UINT cidl;
FORMATETC pFormatEtc[MAX_FORMATS];
UINT cfShellIDList;
UINT cfFileNameA;
UINT cfFileNameW;
public:
IDataObjectImpl();
~IDataObjectImpl();
HRESULT WINAPI Initialize(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidlx, UINT cidlx);
///////////
virtual HRESULT WINAPI GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium);
virtual HRESULT WINAPI GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium);
virtual HRESULT WINAPI QueryGetData(LPFORMATETC pformatetc);
virtual HRESULT WINAPI GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut);
virtual HRESULT WINAPI SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
virtual HRESULT WINAPI EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
virtual HRESULT WINAPI DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
virtual HRESULT WINAPI DUnadvise(DWORD dwConnection);
virtual HRESULT WINAPI EnumDAdvise(IEnumSTATDATA **ppenumAdvise);
BEGIN_COM_MAP(IDataObjectImpl)
COM_INTERFACE_ENTRY_IID(IID_IDataObject, IDataObject)
END_COM_MAP()
};
IDataObjectImpl::IDataObjectImpl()
{
pidl = NULL;
apidl = NULL;
cidl = 0;
cfShellIDList = 0;
cfFileNameA = 0;
cfFileNameW = 0;
}
IDataObjectImpl::~IDataObjectImpl()
{
TRACE(" destroying IDataObject(%p)\n",this);
_ILFreeaPidl(apidl, cidl);
ILFree(pidl);
}
HRESULT WINAPI IDataObjectImpl::Initialize(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidlx, UINT cidlx)
{
pidl = ILClone(pMyPidl);
apidl = _ILCopyaPidl(apidlx, cidlx);
if (pidl == NULL || apidl == NULL)
return E_OUTOFMEMORY;
cidl = cidlx;
cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA);
cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW);
InitFormatEtc(pFormatEtc[0], cfShellIDList, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[2], cfFileNameA, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[3], cfFileNameW, TYMED_HGLOBAL);
return S_OK;
}
/**************************************************************************
* IDataObject_fnGetData
*/
HRESULT WINAPI IDataObjectImpl::GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
{
char szTemp[256];
szTemp[0] = 0;
GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256);
TRACE("(%p)->(%p %p format=%s)\n", this, pformatetcIn, pmedium, szTemp);
if (pformatetcIn->cfFormat == cfShellIDList)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderSHELLIDLIST(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == CF_HDROP)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderHDROP(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == cfFileNameA)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderFILENAMEA(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == cfFileNameW)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderFILENAMEW(pidl, apidl, cidl);
}
else
{
FIXME("-- expected clipformat not implemented\n");
return (E_INVALIDARG);
}
if (pmedium->hGlobal)
{
pmedium->tymed = TYMED_HGLOBAL;
pmedium->pUnkForRelease = NULL;
return S_OK;
}
return E_OUTOFMEMORY;
}
HRESULT WINAPI IDataObjectImpl::GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI IDataObjectImpl::QueryGetData(LPFORMATETC pformatetc)
{
UINT i;
TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", this, pformatetc->cfFormat, pformatetc->tymed);
if(!(DVASPECT_CONTENT & pformatetc->dwAspect))
return DV_E_DVASPECT;
/* check our formats table what we have */
for (i=0; i<MAX_FORMATS; i++)
{
if ((pFormatEtc[i].cfFormat == pformatetc->cfFormat)
&& (pFormatEtc[i].tymed == pformatetc->tymed))
{
return S_OK;
}
}
return DV_E_TYMED;
}
HRESULT WINAPI IDataObjectImpl::GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI IDataObjectImpl::SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI IDataObjectImpl::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{
TRACE("(%p)->()\n", this);
*ppenumFormatEtc = NULL;
/* only get data */
if (DATADIR_GET == dwDirection)
{
return IEnumFORMATETC_Constructor(MAX_FORMATS, pFormatEtc, ppenumFormatEtc);
}
return E_NOTIMPL;
}
HRESULT WINAPI IDataObjectImpl::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI IDataObjectImpl::DUnadvise(DWORD dwConnection)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI IDataObjectImpl::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
/**************************************************************************
* IDataObject_Constructor
*/
HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidl, UINT cidl, IDataObject **dataObject)
{
CComObject<IDataObjectImpl> *theDataObject;
CComPtr<IDataObject> result;
HRESULT hResult;
if (dataObject == NULL)
return E_POINTER;
*dataObject = NULL;
ATLTRY (theDataObject = new CComObject<IDataObjectImpl>);
if (theDataObject == NULL)
return E_OUTOFMEMORY;
hResult = theDataObject->QueryInterface (IID_IDataObject, (void **)&result);
if (FAILED (hResult))
{
delete theDataObject;
return hResult;
}
hResult = theDataObject->Initialize (hwndOwner, pMyPidl, apidl, cidl);
if (FAILED (hResult))
return hResult;
*dataObject = result.Detach ();
TRACE("(%p)->(apidl=%p cidl=%u)\n", *dataObject, apidl, cidl);
return S_OK;
}
/*************************************************************************
* SHCreateDataObject [SHELL32.@]
*
*/
HRESULT WINAPI SHCreateDataObject(LPCITEMIDLIST pidlFolder, UINT cidl, LPCITEMIDLIST* apidl, IDataObject *pdtInner, REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IDataObject))
{
return CIDLData_CreateFromIDArray(pidlFolder, cidl, apidl, (IDataObject **)ppv);
}
return E_FAIL;
}

View file

@ -0,0 +1,170 @@
/*
* Shell DDE Handling
*
* Copyright 2004 Robert Shearman
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/* String handles */
static HSZ hszProgmanTopic;
static HSZ hszProgmanService;
static HSZ hszAsterisk;
static HSZ hszShell;
static HSZ hszAppProperties;
static HSZ hszFolders;
/* DDE Instance ID */
static DWORD dwDDEInst;
static BOOL __inline Dde_OnConnect(HSZ hszTopic, HSZ hszService)
{
if ((hszTopic == hszProgmanTopic) && (hszService == hszProgmanService))
return TRUE;
if ((hszTopic == hszProgmanTopic) && (hszService == hszAppProperties))
return TRUE;
if ((hszTopic == hszShell) && (hszService == hszFolders))
return TRUE;
if ((hszTopic == hszShell) && (hszService == hszAppProperties))
return TRUE;
return FALSE;
}
static void __inline Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
{
FIXME("stub\n");
}
static BOOL __inline Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
{
FIXME("stub\n");
return FALSE;
}
static HDDEDATA __inline Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
HSZ hszItem)
{
FIXME("stub\n");
return NULL;
}
static DWORD __inline Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
{
BYTE * pszCommand;
pszCommand = DdeAccessData(hdata, NULL);
if (!pszCommand)
return DDE_FNOTPROCESSED;
FIXME("stub: %s\n", pszCommand);
DdeUnaccessData(hdata);
return DDE_FNOTPROCESSED;
}
static void __inline Dde_OnDisconnect(HCONV hconv)
{
FIXME("stub\n");
}
static HDDEDATA CALLBACK DdeCallback(
UINT uType,
UINT uFmt,
HCONV hconv,
HSZ hsz1,
HSZ hsz2,
HDDEDATA hdata,
ULONG_PTR dwData1,
ULONG_PTR dwData2)
{
switch (uType)
{
case XTYP_CONNECT:
return (HDDEDATA)(DWORD_PTR)Dde_OnConnect(hsz1, hsz2);
case XTYP_CONNECT_CONFIRM:
Dde_OnConnectConfirm(hconv, hsz1, hsz2);
return NULL;
case XTYP_WILDCONNECT:
return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hsz1, hsz2);
case XTYP_REQUEST:
return Dde_OnRequest(uFmt, hconv, hsz1, hsz2);
case XTYP_EXECUTE:
return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hconv, hsz1, hdata);
case XTYP_DISCONNECT:
Dde_OnDisconnect(hconv);
return NULL;
default:
return NULL;
}
}
/*************************************************************************
* ShellDDEInit (SHELL32.@)
*
* Registers the Shell DDE services with the system so that applications
* can use them.
*
* PARAMS
* bInit [I] TRUE to initialize the services, FALSE to uninitalize.
*
* RETURNS
* Nothing.
*/
EXTERN_C void WINAPI ShellDDEInit(BOOL bInit)
{
TRACE("bInit = %s\n", bInit ? "TRUE" : "FALSE");
if (bInit)
{
static const WCHAR wszProgman[] = {'P','r','o','g','m','a','n',0};
static const WCHAR wszAsterisk[] = {'*',0};
static const WCHAR wszShell[] = {'S','h','e','l','l',0};
static const WCHAR wszAppProperties[] =
{'A','p','p','P','r','o','p','e','r','t','i','e','s',0};
static const WCHAR wszFolders[] = {'F','o','l','d','e','r','s',0};
DdeInitializeW(&dwDDEInst, DdeCallback, CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
hszProgmanService = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
hszAsterisk = DdeCreateStringHandleW(dwDDEInst, wszAsterisk, CP_WINUNICODE);
hszShell = DdeCreateStringHandleW(dwDDEInst, wszShell, CP_WINUNICODE);
hszAppProperties = DdeCreateStringHandleW(dwDDEInst, wszAppProperties, CP_WINUNICODE);
hszFolders = DdeCreateStringHandleW(dwDDEInst, wszFolders, CP_WINUNICODE);
DdeNameService(dwDDEInst, hszFolders, 0, DNS_REGISTER);
DdeNameService(dwDDEInst, hszProgmanService, 0, DNS_REGISTER);
DdeNameService(dwDDEInst, hszShell, 0, DNS_REGISTER);
}
else
{
/* unregister all services */
DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
DdeFreeStringHandle(dwDDEInst, hszFolders);
DdeFreeStringHandle(dwDDEInst, hszAppProperties);
DdeFreeStringHandle(dwDDEInst, hszShell);
DdeFreeStringHandle(dwDDEInst, hszAsterisk);
DdeFreeStringHandle(dwDDEInst, hszProgmanService);
DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
DdeUninitialize(dwDDEInst);
}
}

View file

@ -0,0 +1,434 @@
/*
* Helper functions for debugging
*
* Copyright 1998, 2002 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(pidl);
static
LPITEMIDLIST _dbg_ILGetNext(LPCITEMIDLIST pidl)
{
WORD len;
if(pidl)
{
len = pidl->mkid.cb;
if (len)
{
return (LPITEMIDLIST) (((LPBYTE)pidl)+len);
}
}
return NULL;
}
static
BOOL _dbg_ILIsDesktop(LPCITEMIDLIST pidl)
{
return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
}
static
LPPIDLDATA _dbg_ILGetDataPointer(LPCITEMIDLIST pidl)
{
if(pidl && pidl->mkid.cb != 0x00)
return (LPPIDLDATA) &(pidl->mkid.abID);
return NULL;
}
static
LPSTR _dbg_ILGetTextPointer(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
if (pdata)
{
switch (pdata->type)
{
case PT_GUID:
case PT_SHELLEXT:
case PT_YAGUID:
return NULL;
case PT_DRIVE:
case PT_DRIVE1:
case PT_DRIVE2:
case PT_DRIVE3:
return (LPSTR)&(pdata->u.drive.szDriveName);
case PT_FOLDER:
case PT_FOLDER1:
case PT_VALUE:
case PT_IESPECIAL1:
case PT_IESPECIAL2:
return (LPSTR)&(pdata->u.file.szNames);
case PT_WORKGRP:
case PT_COMP:
case PT_NETWORK:
case PT_NETPROVIDER:
case PT_SHARE:
return (LPSTR)&(pdata->u.network.szNames);
}
}
return NULL;
}
static
LPWSTR _dbg_ILGetTextPointerW(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
if (pdata)
{
switch (pdata->type)
{
case PT_GUID:
case PT_SHELLEXT:
case PT_YAGUID:
return NULL;
case PT_DRIVE:
case PT_DRIVE1:
case PT_DRIVE2:
case PT_DRIVE3:
/* return (LPSTR)&(pdata->u.drive.szDriveName);*/
return NULL;
case PT_FOLDER:
case PT_FOLDER1:
case PT_VALUE:
case PT_IESPECIAL1:
case PT_IESPECIAL2:
/* return (LPSTR)&(pdata->u.file.szNames); */
return NULL;
case PT_WORKGRP:
case PT_COMP:
case PT_NETWORK:
case PT_NETPROVIDER:
case PT_SHARE:
/* return (LPSTR)&(pdata->u.network.szNames); */
return NULL;
case PT_VALUEW:
return (LPWSTR)&(pdata->u.file.szNames);
}
}
return NULL;
}
static
LPSTR _dbg_ILGetSTextPointer(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
if (pdata)
{
switch (pdata->type)
{
case PT_FOLDER:
case PT_VALUE:
case PT_IESPECIAL1:
case PT_IESPECIAL2:
return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);
case PT_WORKGRP:
return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
}
}
return NULL;
}
static
LPWSTR _dbg_ILGetSTextPointerW(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
if (pdata)
{
switch (pdata->type)
{
case PT_FOLDER:
case PT_VALUE:
case PT_IESPECIAL1:
case PT_IESPECIAL2:
/*return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1); */
return NULL;
case PT_WORKGRP:
/* return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1); */
return NULL;
case PT_VALUEW:
return (LPWSTR)(pdata->u.file.szNames + wcslen ((LPWSTR)pdata->u.file.szNames) + 1);
}
}
return NULL;
}
static
IID* _dbg_ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata =_ILGetDataPointer(pidl);
if (pdata)
{
switch (pdata->type)
{
case PT_SHELLEXT:
case PT_GUID:
case PT_YAGUID:
return &(pdata->u.guid.guid);
}
}
return NULL;
}
static
void _dbg_ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
{
LPSTR szSrc;
LPWSTR szSrcW;
GUID const * riid;
if (!pidl) return;
if (szOut)
*szOut = 0;
if (_dbg_ILIsDesktop(pidl))
{
/* desktop */
if (szOut) lstrcpynA(szOut, "Desktop", uOutSize);
}
else if (( szSrc = _dbg_ILGetTextPointer(pidl) ))
{
/* filesystem */
if (szOut) lstrcpynA(szOut, szSrc, uOutSize);
}
else if (( szSrcW = _dbg_ILGetTextPointerW(pidl) ))
{
CHAR tmp[MAX_PATH];
/* unicode filesystem */
WideCharToMultiByte(CP_ACP,0,szSrcW, -1, tmp, MAX_PATH, NULL, NULL);
if (szOut) lstrcpynA(szOut, tmp, uOutSize);
}
else if (( riid = _dbg_ILGetGUIDPointer(pidl) ))
{
if (szOut)
sprintf( szOut, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
riid->Data1, riid->Data2, riid->Data3,
riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
}
}
void pdump (LPCITEMIDLIST pidl)
{
LPCITEMIDLIST pidltemp = pidl;
if (!TRACE_ON(pidl)) return;
if (! pidltemp)
{
MESSAGE ("-------- pidl=NULL (Desktop)\n");
}
else
{
MESSAGE ("-------- pidl=%p\n", pidl);
if (pidltemp->mkid.cb)
{
do
{
if (_ILIsUnicode(pidltemp))
{
DWORD dwAttrib = 0;
LPPIDLDATA pData = _dbg_ILGetDataPointer(pidltemp);
DWORD type = pData ? pData->type : 0;
LPWSTR szLongName = _dbg_ILGetTextPointerW(pidltemp);
LPWSTR szShortName = _dbg_ILGetSTextPointerW(pidltemp);
char szName[MAX_PATH];
_dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
if ( pData && (PT_FOLDER == type || PT_VALUE == type) )
dwAttrib = pData->u.file.uFileAttribs;
MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n",
pidltemp, pidltemp->mkid.cb, type, dwAttrib,
debugstr_a(szName), debugstr_w(szLongName), debugstr_w(szShortName));
}
else
{
DWORD dwAttrib = 0;
LPPIDLDATA pData = _dbg_ILGetDataPointer(pidltemp);
DWORD type = pData ? pData->type : 0;
LPSTR szLongName = _dbg_ILGetTextPointer(pidltemp);
LPSTR szShortName = _dbg_ILGetSTextPointer(pidltemp);
char szName[MAX_PATH];
_dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
if ( pData && (PT_FOLDER == type || PT_VALUE == type) )
dwAttrib = pData->u.file.uFileAttribs;
MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n",
pidltemp, pidltemp->mkid.cb, type, dwAttrib,
debugstr_a(szName), debugstr_a(szLongName), debugstr_a(szShortName));
}
pidltemp = _dbg_ILGetNext(pidltemp);
} while (pidltemp && pidltemp->mkid.cb);
}
else
{
MESSAGE ("empty pidl (Desktop)\n");
}
pcheck(pidl);
}
}
static void dump_pidl_hex( LPCITEMIDLIST pidl )
{
const unsigned char *p = (const unsigned char *)pidl;
const int max_bytes = 0x80;
#define max_line 0x10
char szHex[max_line*3+1], szAscii[max_line+1];
int i, n;
n = pidl->mkid.cb;
if( n>max_bytes )
n = max_bytes;
for( i=0; i<n; i++ )
{
sprintf( &szHex[ (i%max_line)*3 ], "%02X ", p[i] );
szAscii[ (i%max_line) ] = isprint( p[i] ) ? p[i] : '.';
/* print out at the end of each line and when we're finished */
if( i!=(n-1) && (i%max_line) != (max_line-1) )
continue;
szAscii[ (i%max_line)+1 ] = 0;
ERR("%-*s %s\n", max_line*3, szHex, szAscii );
}
}
BOOL pcheck( LPCITEMIDLIST pidl )
{
DWORD type;
LPCITEMIDLIST pidltemp = pidl;
while( pidltemp && pidltemp->mkid.cb )
{
LPPIDLDATA pidlData = _dbg_ILGetDataPointer(pidltemp);
if (pidlData)
{
type = pidlData->type;
switch( type )
{
case PT_CPLAPPLET:
case PT_GUID:
case PT_SHELLEXT:
case PT_DRIVE:
case PT_DRIVE1:
case PT_DRIVE2:
case PT_DRIVE3:
case PT_FOLDER:
case PT_VALUE:
case PT_VALUEW:
case PT_FOLDER1:
case PT_WORKGRP:
case PT_COMP:
case PT_NETPROVIDER:
case PT_NETWORK:
case PT_IESPECIAL1:
case PT_YAGUID:
case PT_IESPECIAL2:
case PT_SHARE:
break;
default:
ERR("unknown IDLIST %p [%p] size=%u type=%x\n",
pidl, pidltemp, pidltemp->mkid.cb,type );
dump_pidl_hex( pidltemp );
return FALSE;
}
pidltemp = _dbg_ILGetNext(pidltemp);
}
else
{
return FALSE;
}
}
return TRUE;
}
static const struct {
REFIID riid;
const char *name;
} InterfaceDesc[] = {
{IID_IUnknown, "IID_IUnknown"},
{IID_IClassFactory, "IID_IClassFactory"},
{IID_IShellView, "IID_IShellView"},
{IID_IOleCommandTarget, "IID_IOleCommandTarget"},
{IID_IDropTarget, "IID_IDropTarget"},
{IID_IDropSource, "IID_IDropSource"},
{IID_IViewObject, "IID_IViewObject"},
{IID_IContextMenu, "IID_IContextMenu"},
{IID_IShellExtInit, "IID_IShellExtInit"},
{IID_IShellFolder, "IID_IShellFolder"},
{IID_IShellFolder2, "IID_IShellFolder2"},
{IID_IPersist, "IID_IPersist"},
{IID_IPersistFolder, "IID_IPersistFolder"},
{IID_IPersistFolder2, "IID_IPersistFolder2"},
{IID_IPersistFolder3, "IID_IPersistFolder3"},
{IID_IExtractIconA, "IID_IExtractIconA"},
{IID_IExtractIconW, "IID_IExtractIconW"},
{IID_IDataObject, "IID_IDataObject"},
{IID_IAutoComplete, "IID_IAutoComplete"},
{IID_IAutoComplete2, "IID_IAutoComplete2"},
{IID_IShellLinkA, "IID_IShellLinkA"},
{IID_IShellLinkW, "IID_IShellLinkW"},
};
const char * shdebugstr_guid( const struct _GUID *id )
{
unsigned int i;
const char* name = NULL;
char clsidbuf[100];
if (!id) return "(null)";
for (i=0; i < sizeof(InterfaceDesc) / sizeof(InterfaceDesc[0]); i++) {
if (IsEqualIID(InterfaceDesc[i].riid, *id)) name = InterfaceDesc[i].name;
}
if (!name) {
if (HCR_GetClassNameA(*id, clsidbuf, 100))
name = clsidbuf;
}
return wine_dbg_sprintf( "\n\t{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} (%s)",
id->Data1, id->Data2, id->Data3,
id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], name ? name : "unknown" );
}

View file

@ -0,0 +1,561 @@
/*
* Shell Desktop
*
* Copyright 2008 Thomas Bluemel
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
BOOL WINAPI SetShellWindowEx(HWND, HWND);
#define SHDESK_TAG 0x4b534544
static const WCHAR szProgmanClassName[] = {'P','r','o','g','m','a','n'};
static const WCHAR szProgmanWindowName[] = {
'P','r','o','g','r','a','m',' ','M','a','n','a','g','e','r'
};
class CDesktopBrowser :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellBrowser,
public ICommDlgBrowser,
public IServiceProvider
{
public:
DWORD Tag;
private:
HWND hWnd;
HWND hWndShellView;
HWND hWndDesktopListView;
CComPtr<IShellDesktopTray> ShellDesk;
CComPtr<IShellView> DesktopView;
IShellBrowser *DefaultShellBrowser;
LPITEMIDLIST pidlDesktopDirectory;
LPITEMIDLIST pidlDesktop;
public:
CDesktopBrowser();
~CDesktopBrowser();
HRESULT Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx);
HWND FindDesktopListView ();
BOOL CreateDeskWnd();
HWND DesktopGetWindowControl(IN UINT id);
static LRESULT CALLBACK ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam);
static BOOL MessageLoop();
// *** IOleWindow methods ***
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
// *** IShellBrowser methods ***
virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject);
virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared);
virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCOLESTR pszStatusText);
virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable);
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID);
virtual HRESULT STDMETHODCALLTYPE BrowseObject(LPCITEMIDLIST pidl, UINT wFlags);
virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode, IStream **ppStrm);
virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND *lphwnd);
virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret);
virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(struct IShellView **ppshv);
virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv);
virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags);
// *** ICommDlgBrowser methods ***
virtual HRESULT STDMETHODCALLTYPE OnDefaultCommand (struct IShellView *ppshv);
virtual HRESULT STDMETHODCALLTYPE OnStateChange (struct IShellView *ppshv, ULONG uChange);
virtual HRESULT STDMETHODCALLTYPE IncludeObject (struct IShellView *ppshv, LPCITEMIDLIST pidl);
// *** IServiceProvider methods ***
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
BEGIN_COM_MAP(CDesktopBrowser)
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
COM_INTERFACE_ENTRY_IID(IID_ICommDlgBrowser, ICommDlgBrowser)
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
END_COM_MAP()
};
CDesktopBrowser::CDesktopBrowser()
{
Tag = SHDESK_TAG;
hWnd = NULL;
hWndShellView = NULL;
hWndDesktopListView = NULL;
DefaultShellBrowser = NULL;
pidlDesktopDirectory = NULL;
pidlDesktop = NULL;
}
CDesktopBrowser::~CDesktopBrowser()
{
if (DesktopView.p != NULL)
{
if (hWndShellView != NULL)
DesktopView->DestroyViewWindow();
hWndShellView = NULL;
hWndDesktopListView = NULL;
}
if (pidlDesktopDirectory != NULL)
{
ILFree(pidlDesktopDirectory);
pidlDesktopDirectory = NULL;
}
if (pidlDesktop != NULL)
{
ILFree(pidlDesktop);
pidlDesktop = NULL;
}
}
HRESULT CDesktopBrowser::Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx)
{
CComPtr<IShellFolder> psfDesktopFolder;
CSFV csfv;
HRESULT hRet;
hWnd = hWndx;
ShellDesk = ShellDeskx;
ShellDesk->AddRef();
pidlDesktopDirectory = SHCloneSpecialIDList(hWnd, CSIDL_DESKTOPDIRECTORY, FALSE);
hRet = SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlDesktop);
if (FAILED(hRet))
return hRet;
hRet = SHGetDesktopFolder(&psfDesktopFolder);
if (FAILED(hRet))
return hRet;
ZeroMemory(&csfv, sizeof(csfv));
csfv.cbSize = sizeof(csfv);
csfv.pshf = psfDesktopFolder;
csfv.psvOuter = NULL;
hRet = SHCreateShellFolderViewEx(&csfv, &DesktopView);
return hRet;
}
static CDesktopBrowser *SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
IShellDesktopTray *ShellDesk;
CComObject<CDesktopBrowser> *pThis;
HRESULT hRet;
ShellDesk = (IShellDesktopTray *)lpCreateStruct->lpCreateParams;
if (ShellDesk == NULL)
{
WARN("No IShellDesk interface provided!");
return NULL;
}
pThis = new CComObject<CDesktopBrowser>;
if (pThis == NULL)
return NULL;
pThis->AddRef();
hRet = pThis->Initialize(hWnd, ShellDesk);
if (FAILED(hRet))
{
pThis->Release();
return NULL;
}
return pThis;
}
HWND CDesktopBrowser::FindDesktopListView ()
{
return FindWindowExW(hWndShellView, NULL, WC_LISTVIEW, NULL);
}
BOOL CDesktopBrowser::CreateDeskWnd()
{
FOLDERSETTINGS fs;
RECT rcClient;
HRESULT hRet;
if (!GetClientRect(hWnd, &rcClient))
{
return FALSE;
}
fs.ViewMode = FVM_ICON;
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
hRet = DesktopView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcClient, &hWndShellView);
if (!SUCCEEDED(hRet))
return FALSE;
SetShellWindowEx(hWnd, FindDesktopListView());
return TRUE;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *phwnd)
{
if (hWnd != NULL)
{
*phwnd = hWnd;
return S_OK;
}
*phwnd = NULL;
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::RemoveMenusSB(HMENU hmenuShared)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetStatusTextSB(LPCOLESTR lpszStatusText)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID)
{
return S_FALSE;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
{
return E_NOTIMPL;
}
HWND CDesktopBrowser::DesktopGetWindowControl(IN UINT id)
{
switch (id)
{
case FCW_TOOLBAR:
case FCW_STATUS:
case FCW_TREE:
case FCW_PROGRESS:
return NULL;
default:
return NULL;
}
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd)
{
HWND hWnd;
hWnd = DesktopGetWindowControl(id);
if (hWnd != NULL)
{
*lphwnd = hWnd;
return S_OK;
}
*lphwnd = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
{
HWND hWnd;
if (pret == NULL)
return E_POINTER;
hWnd = DesktopGetWindowControl(id);
if (hWnd != NULL)
{
*pret = SendMessageW(hWnd,
uMsg,
wParam,
lParam);
return S_OK;
}
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv)
{
*ppshv = DesktopView;
if (DesktopView != NULL)
DesktopView->AddRef();
return S_OK;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnViewWindowActive(IShellView *ppshv)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnDefaultCommand(IShellView *ppshv)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnStateChange(IShellView *ppshv, ULONG uChange)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::IncludeObject(IShellView *ppshv, LPCITEMIDLIST pidl)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv)
{
/* FIXME - handle guidService */
return QueryInterface(riid, ppv);
}
BOOL CDesktopBrowser::MessageLoop()
{
MSG Msg;
BOOL bRet;
while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
{
if (bRet != -1)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
}
return TRUE;
}
LRESULT CALLBACK CDesktopBrowser::ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
{
CDesktopBrowser *pThis = NULL;
LRESULT Ret = FALSE;
if (uMsg != WM_NCCREATE)
{
pThis = (CDesktopBrowser*)GetWindowLongPtrW(hwnd,
0);
if (pThis == NULL)
goto DefMsgHandler;
}
if (pThis != NULL || uMsg == WM_NCCREATE)
{
switch (uMsg)
{
case WM_ERASEBKGND:
return (LRESULT)PaintDesktop((HDC)wParam);
case WM_GETISHELLBROWSER:
Ret = (LRESULT)((IShellBrowser *)pThis);
break;
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
/* Hey, we're the desktop!!! */
ShowWindow(hwnd,
SW_RESTORE);
}
else
{
RECT rcDesktop;
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
/* FIXME: Update work area */
}
break;
case WM_SYSCOLORCHANGE:
{
InvalidateRect(pThis->hWnd,
NULL,
TRUE);
if (pThis->hWndShellView != NULL)
{
/* Forward the message */
SendMessageW(pThis->hWndShellView,
WM_SYSCOLORCHANGE,
wParam,
lParam);
}
break;
}
case WM_CREATE:
{
pThis->ShellDesk->RegisterDesktopWindow(pThis->hWnd);
if (!pThis->CreateDeskWnd())
WARN("Could not create the desktop view control!\n");
break;
}
case WM_NCCREATE:
{
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
pThis = SHDESK_Create(hwnd, CreateStruct);
if (pThis == NULL)
{
WARN("Failed to create desktop structure\n");
break;
}
SetWindowLongPtrW(hwnd,
0,
(LONG_PTR)pThis);
Ret = TRUE;
break;
}
case WM_NCDESTROY:
{
pThis->Release();
break;
}
default:
DefMsgHandler:
Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
break;
}
}
return Ret;
}
static BOOL
RegisterProgmanWindowClass(VOID)
{
WNDCLASSW wcProgman;
wcProgman.style = CS_DBLCLKS;
wcProgman.lpfnWndProc = CDesktopBrowser::ProgmanWindowProc;
wcProgman.cbClsExtra = 0;
wcProgman.cbWndExtra = sizeof(CDesktopBrowser *);
wcProgman.hInstance = shell32_hInstance;
wcProgman.hIcon = NULL;
wcProgman.hCursor = LoadCursorW(NULL, IDC_ARROW);
wcProgman.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wcProgman.lpszMenuName = NULL;
wcProgman.lpszClassName = szProgmanClassName;
return RegisterClassW(&wcProgman) != 0;
}
/*************************************************************************
* SHCreateDesktop [SHELL32.200]
*
*/
HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
{
HWND hWndDesk;
RECT rcDesk;
if (ShellDesk == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
if (RegisterProgmanWindowClass() == 0)
{
WARN("Failed to register the Progman window class!\n");
return NULL;
}
rcDesk.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesk.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesk.right = rcDesk.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesk.bottom = rcDesk.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (IsRectEmpty(&rcDesk))
{
rcDesk.left = rcDesk.top = 0;
rcDesk.right = GetSystemMetrics(SM_CXSCREEN);
rcDesk.bottom = GetSystemMetrics(SM_CYSCREEN);
}
hWndDesk = CreateWindowExW(0, szProgmanClassName, szProgmanWindowName,
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
rcDesk.left, rcDesk.top, rcDesk.right, rcDesk.bottom,
NULL, NULL, shell32_hInstance, (LPVOID)ShellDesk);
if (hWndDesk != NULL)
return (HANDLE)GetWindowLongPtrW(hWndDesk, 0);
return NULL;
}
/*************************************************************************
* SHCreateDesktop [SHELL32.201]
*
*/
BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
{
CDesktopBrowser *Desk = (CDesktopBrowser *)hDesktop;
if (Desk == NULL || Desk->Tag != SHDESK_TAG)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return Desk->MessageLoop();
}

View file

@ -0,0 +1,738 @@
/*
* common shell dialogs
*
* Copyright 2000 Juergen Schmied
*
* 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 <precomp.h>
typedef struct
{
HWND hwndOwner ;
HICON hIcon ;
LPCWSTR lpstrDirectory ;
LPCWSTR lpstrTitle ;
LPCWSTR lpstrDescription ;
UINT uFlags ;
} RUNFILEDLGPARAMS ;
typedef BOOL (WINAPI * LPFNOFN) (OPENFILENAMEW *) ;
WINE_DEFAULT_DEBUG_CHANNEL(shell);
static INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ;
static void FillList (HWND, char *, BOOL) ;
/*************************************************************************
* PickIconDlg [SHELL32.62]
*
*/
typedef struct
{
HMODULE hLibrary;
HWND hDlgCtrl;
WCHAR szName[MAX_PATH];
INT Index;
}PICK_ICON_CONTEXT, *PPICK_ICON_CONTEXT;
BOOL CALLBACK EnumPickIconResourceProc(HMODULE hModule,
LPCWSTR lpszType,
LPWSTR lpszName,
LONG_PTR lParam
)
{
WCHAR szName[100];
int index;
HICON hIcon;
PPICK_ICON_CONTEXT pIconContext = (PPICK_ICON_CONTEXT)lParam;
if (IS_INTRESOURCE(lpszName))
swprintf(szName, L"%u", lpszName);
else
wcscpy(szName, (WCHAR*)lpszName);
hIcon = LoadIconW(pIconContext->hLibrary, (LPCWSTR)lpszName);
if (hIcon == NULL)
return TRUE;
index = SendMessageW(pIconContext->hDlgCtrl, LB_ADDSTRING, 0, (LPARAM)szName);
if (index != LB_ERR)
SendMessageW(pIconContext->hDlgCtrl, LB_SETITEMDATA, index, (LPARAM)hIcon);
return TRUE;
}
void
DestroyIconList(HWND hDlgCtrl)
{
int count;
int index;
count = SendMessage(hDlgCtrl, LB_GETCOUNT, 0, 0);
if (count == LB_ERR)
return;
for(index = 0; index < count; index++)
{
HICON hIcon = (HICON)SendMessageW(hDlgCtrl, LB_GETITEMDATA, index, 0);
DestroyIcon(hIcon);
}
}
INT_PTR CALLBACK PickIconProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
LPMEASUREITEMSTRUCT lpmis;
LPDRAWITEMSTRUCT lpdis;
HICON hIcon;
INT index, count;
WCHAR szText[MAX_PATH], szTitle[100], szFilter[100];
OPENFILENAMEW ofn = {0};
PPICK_ICON_CONTEXT pIconContext = (PPICK_ICON_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
switch(uMsg)
{
case WM_INITDIALOG:
pIconContext = (PPICK_ICON_CONTEXT)lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)pIconContext);
pIconContext->hDlgCtrl = GetDlgItem(hwndDlg, IDC_PICKICON_LIST);
EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext);
if (PathUnExpandEnvStringsW(pIconContext->szName, szText, MAX_PATH))
SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)szText);
else
SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)pIconContext->szName);
count = SendMessage(pIconContext->hDlgCtrl, LB_GETCOUNT, 0, 0);
if (count != LB_ERR)
{
if (count > pIconContext->Index)
SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, pIconContext->Index, 0);
else
SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0);
}
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0);
pIconContext->Index = index;
SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_GETTEXT, MAX_PATH, (LPARAM)pIconContext->szName);
DestroyIconList(pIconContext->hDlgCtrl);
EndDialog(hwndDlg, 1);
break;
case IDCANCEL:
DestroyIconList(pIconContext->hDlgCtrl);
EndDialog(hwndDlg, 0);
break;
case IDC_PICKICON_LIST:
if (HIWORD(wParam) == LBN_SELCHANGE)
InvalidateRect((HWND)lParam, NULL, TRUE); // FIXME USE UPDATE RECT
break;
case IDC_BUTTON_PATH:
szText[0] = 0;
szTitle[0] = 0;
szFilter[0] = 0;
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwndDlg;
ofn.lpstrFile = szText;
ofn.nMaxFile = MAX_PATH;
LoadStringW(shell32_hInstance, IDS_PICK_ICON_TITLE, szTitle, sizeof(szTitle) / sizeof(WCHAR));
ofn.lpstrTitle = szTitle;
LoadStringW(shell32_hInstance, IDS_PICK_ICON_FILTER, szFilter, sizeof(szFilter) / sizeof(WCHAR));
ofn.lpstrFilter = szFilter;
if (GetOpenFileNameW(&ofn))
{
HMODULE hLibrary;
if (!wcsicmp(pIconContext->szName, szText))
break;
DestroyIconList(pIconContext->hDlgCtrl);
hLibrary = LoadLibraryExW(szText, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
if (hLibrary == NULL)
break;
FreeLibrary(pIconContext->hLibrary);
pIconContext->hLibrary = hLibrary;
wcscpy(pIconContext->szName, szText);
EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext);
if (PathUnExpandEnvStringsW(pIconContext->szName, szText, MAX_PATH))
SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)szText);
else
SendDlgItemMessageW(hwndDlg, IDC_EDIT_PATH, WM_SETTEXT, 0, (LPARAM)pIconContext->szName);
SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0);
}
break;
}
break;
case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT) lParam;
lpmis->itemHeight = 32;
lpmis->itemWidth = 64;
return TRUE;
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam;
if (lpdis->itemID == (UINT)-1)
{
break;
}
switch (lpdis->itemAction)
{
case ODA_SELECT:
case ODA_DRAWENTIRE:
index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0);
hIcon =(HICON)SendMessage(lpdis->hwndItem, LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);
if (lpdis->itemID == (UINT)index)
{
HBRUSH hBrush;
hBrush = CreateSolidBrush(RGB(0, 0, 255));
FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
DeleteObject(hBrush);
}
else
{
HBRUSH hBrush;
hBrush = CreateSolidBrush(RGB(255, 255, 255));
FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
DeleteObject(hBrush);
}
DrawIconEx(lpdis->hDC, lpdis->rcItem.left,lpdis->rcItem.top, hIcon,
0,
0,
0,
NULL,
DI_NORMAL);
break;
}
break;
}
return FALSE;
}
BOOL WINAPI PickIconDlg(
HWND hwndOwner,
LPWSTR lpstrFile,
UINT nMaxFile,
INT* lpdwIconIndex)
{
HMODULE hLibrary;
int res;
PICK_ICON_CONTEXT IconContext;
hLibrary = LoadLibraryExW(lpstrFile, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
IconContext.hLibrary = hLibrary;
IconContext.Index = *lpdwIconIndex;
wcscpy(IconContext.szName, lpstrFile);
res = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_PICK_ICON_DIALOG), hwndOwner, PickIconProc, (LPARAM)&IconContext);
if (res)
{
wcscpy(lpstrFile, IconContext.szName);
*lpdwIconIndex = IconContext.Index;
}
FreeLibrary(hLibrary);
return res;
}
/*************************************************************************
* RunFileDlg [internal]
*
* The Unicode function that is available as ordinal 61 on Windows NT/2000/XP/...
*/
void WINAPI RunFileDlg(
HWND hwndOwner,
HICON hIcon,
LPCWSTR lpstrDirectory,
LPCWSTR lpstrTitle,
LPCWSTR lpstrDescription,
UINT uFlags)
{
static const WCHAR resnameW[] = {'S','H','E','L','L','_','R','U','N','_','D','L','G',0};
RUNFILEDLGPARAMS rfdp;
HRSRC hRes;
LPVOID tmplate;
TRACE("\n");
rfdp.hwndOwner = hwndOwner;
rfdp.hIcon = hIcon;
rfdp.lpstrDirectory = lpstrDirectory;
rfdp.lpstrTitle = lpstrTitle;
rfdp.lpstrDescription = lpstrDescription;
rfdp.uFlags = uFlags;
if (!(hRes = FindResourceW(shell32_hInstance, resnameW, (LPWSTR)RT_DIALOG)) ||
!(tmplate = LoadResource(shell32_hInstance, hRes)))
{
ERR("Couldn't load SHELL_RUN_DLG resource\n");
ShellMessageBoxW(shell32_hInstance, hwndOwner, MAKEINTRESOURCEW(IDS_RUNDLG_ERROR), NULL, MB_OK | MB_ICONERROR);
return;
}
DialogBoxIndirectParamW(shell32_hInstance,
(LPCDLGTEMPLATEW)tmplate, hwndOwner, RunDlgProc, (LPARAM)&rfdp);
}
/* find the directory that contains the file being run */
static LPWSTR RunDlg_GetParentDir(LPCWSTR cmdline)
{
const WCHAR *src;
WCHAR *dest, *result, *result_end=NULL;
static const WCHAR dotexeW[] = {'.','e','x','e',0};
result = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(strlenW(cmdline)+5));
if (NULL == result)
{
TRACE("HeapAlloc couldn't allocate %d bytes\n", sizeof(WCHAR)*(strlenW(cmdline)+5));
return NULL;
}
src = cmdline;
dest = result;
if (*src == '"')
{
src++;
while (*src && *src != '"')
{
if (*src == '\\')
result_end = dest;
*dest++ = *src++;
}
}
else {
while (*src)
{
if (isspaceW(*src))
{
*dest = 0;
if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result))
break;
strcatW(dest, dotexeW);
if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result))
break;
}
else if (*src == '\\')
result_end = dest;
*dest++ = *src++;
}
}
if (result_end)
{
*result_end = 0;
return result;
}
else
{
HeapFree(GetProcessHeap(), 0, result);
return NULL;
}
}
/* Dialog procedure for RunFileDlg */
static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RUNFILEDLGPARAMS *prfdp = (RUNFILEDLGPARAMS *)GetWindowLongPtrW(hwnd, DWLP_USER);
switch (message)
{
case WM_INITDIALOG :
prfdp = (RUNFILEDLGPARAMS *)lParam ;
SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)prfdp);
if (prfdp->lpstrTitle)
SetWindowTextW(hwnd, prfdp->lpstrTitle);
if (prfdp->lpstrDescription)
SetWindowTextW(GetDlgItem(hwnd, IDC_RUNDLG_DESCRIPTION), prfdp->lpstrDescription);
if (prfdp->uFlags & RFF_NOBROWSE)
{
HWND browse = GetDlgItem(hwnd, IDC_RUNDLG_BROWSE);
ShowWindow(browse, SW_HIDE);
EnableWindow(browse, FALSE);
}
if (prfdp->uFlags & RFF_NOLABEL)
ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_LABEL), SW_HIDE);
if (prfdp->uFlags & RFF_CALCDIRECTORY)
FIXME("RFF_CALCDIRECTORY not supported\n");
if (prfdp->hIcon == NULL)
prfdp->hIcon = LoadIconW(NULL, (LPCWSTR)IDI_WINLOGO);
SendMessageW(hwnd, WM_SETICON, ICON_BIG, (LPARAM)prfdp->hIcon);
SendMessageW(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)prfdp->hIcon);
SendMessageW(GetDlgItem(hwnd, IDC_RUNDLG_ICON), STM_SETICON, (WPARAM)prfdp->hIcon, 0);
FillList (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), NULL, (prfdp->uFlags & RFF_NODEFAULT) == 0) ;
SetFocus (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH)) ;
return TRUE ;
case WM_COMMAND :
switch (LOWORD (wParam))
{
case IDOK :
{
int ic ;
HWND htxt = GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH);
if ((ic = GetWindowTextLengthW (htxt)))
{
WCHAR *psz, *parent=NULL ;
SHELLEXECUTEINFOW sei ;
ZeroMemory (&sei, sizeof(sei)) ;
sei.cbSize = sizeof(sei) ;
psz = (WCHAR *)HeapAlloc( GetProcessHeap(), 0, (ic + 1)*sizeof(WCHAR) );
if (psz)
{
GetWindowTextW (htxt, psz, ic + 1) ;
/* according to http://www.codeproject.com/KB/shell/runfiledlg.aspx we should send a
* WM_NOTIFY before execution */
sei.hwnd = hwnd;
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = psz;
if (prfdp->lpstrDirectory)
sei.lpDirectory = prfdp->lpstrDirectory;
else
sei.lpDirectory = parent = RunDlg_GetParentDir(sei.lpFile);
if (!ShellExecuteExW( &sei ))
{
HeapFree(GetProcessHeap(), 0, psz);
HeapFree(GetProcessHeap(), 0, parent);
SendMessageA (htxt, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
return TRUE ;
}
/* FillList is still ANSI */
GetWindowTextA (htxt, (LPSTR)psz, ic + 1) ;
FillList (htxt, (LPSTR)psz, FALSE) ;
HeapFree(GetProcessHeap(), 0, psz);
HeapFree(GetProcessHeap(), 0, parent);
EndDialog (hwnd, 0);
}
}
}
case IDCANCEL :
EndDialog (hwnd, 0) ;
return TRUE ;
case IDC_RUNDLG_BROWSE :
{
HMODULE hComdlg = NULL ;
LPFNOFN ofnProc = NULL ;
static const WCHAR comdlg32W[] = {'c','o','m','d','l','g','3','2',0};
WCHAR szFName[1024] = {0};
WCHAR filter[MAX_PATH], szCaption[MAX_PATH];
OPENFILENAMEW ofn;
LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_FILTER, filter, MAX_PATH);
LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_CAPTION, szCaption, MAX_PATH);
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = filter;
ofn.lpstrFile = szFName;
ofn.nMaxFile = 1023;
ofn.lpstrTitle = szCaption;
ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
ofn.lpstrInitialDir = prfdp->lpstrDirectory;
if (NULL == (hComdlg = LoadLibraryExW (comdlg32W, NULL, 0)) ||
NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameW")))
{
ERR("Couldn't get GetOpenFileName function entry (lib=%p, proc=%p)\n", hComdlg, ofnProc);
ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_RUNDLG_BROWSE_ERROR), NULL, MB_OK | MB_ICONERROR);
return TRUE ;
}
if (ofnProc(&ofn))
{
SetFocus (GetDlgItem (hwnd, IDOK)) ;
SetWindowTextW (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), szFName) ;
SendMessageW (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
SetFocus (GetDlgItem (hwnd, IDOK)) ;
}
FreeLibrary (hComdlg) ;
return TRUE ;
}
}
return TRUE ;
}
return FALSE ;
}
/* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */
/* fShowDefault ignored if pszLatest != NULL */
static void FillList (HWND hCb, char *pszLatest, BOOL fShowDefault)
{
HKEY hkey ;
/* char szDbgMsg[256] = "" ; */
char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ;
DWORD icList = 0, icCmd = 0 ;
UINT Nix ;
SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ;
if (ERROR_SUCCESS != RegCreateKeyExA (
HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL))
MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ;
RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList) ;
if (icList > 0)
{
pszList = (char *)HeapAlloc( GetProcessHeap(), 0, icList) ;
if (pszList)
{
if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, (LPBYTE)pszList, &icList))
MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK);
}
else
{
TRACE("HeapAlloc failed to allocate %d bytes\n", icList);
}
}
else
{
icList = 1 ;
pszList = (char *)HeapAlloc( GetProcessHeap(), 0, icList) ;
pszList[0] = 0 ;
}
for (Nix = 0 ; Nix < icList - 1 ; Nix++)
{
if (pszList[Nix] > cMax)
cMax = pszList[Nix] ;
szIndex[0] = pszList[Nix] ;
if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd))
MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ;
if( pszCmd )
pszCmd = (char *)HeapReAlloc(GetProcessHeap(), 0, pszCmd, icCmd) ;
else
pszCmd = (char *)HeapAlloc(GetProcessHeap(), 0, icCmd) ;
if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, (LPBYTE)pszCmd, &icCmd))
MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ;
if (NULL != pszLatest)
{
if (!lstrcmpiA(pszCmd, pszLatest))
{
/*
sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ;
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
*/
SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ;
SetWindowTextA (hCb, pszCmd) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
cMatch = pszList[Nix] ;
memmove (&pszList[1], pszList, Nix) ;
pszList[0] = cMatch ;
continue ;
}
}
if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest)
{
/*
sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ;
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
*/
SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ;
if (!Nix && fShowDefault)
{
SetWindowTextA (hCb, pszCmd) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
}
}
else
{
/*
sprintf (szDbgMsg, "Doing loop thing.\n") ;
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
*/
SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
SetWindowTextA (hCb, pszLatest) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
cMatch = pszList[Nix] ;
memmove (&pszList[1], pszList, Nix) ;
pszList[0] = cMatch ;
szIndex[0] = cMatch ;
RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ;
}
}
if (!cMatch && NULL != pszLatest)
{
/*
sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ;
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
*/
SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
SetWindowTextA (hCb, pszLatest) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
cMatch = ++cMax ;
if (pszList)
pszList = (char *)HeapReAlloc(GetProcessHeap(), 0, pszList, ++icList) ;
else
pszList = (char *)HeapAlloc(GetProcessHeap(), 0, ++icList) ;
if (pszList)
{
memmove (&pszList[1], pszList, icList - 1) ;
pszList[0] = cMatch ;
szIndex[0] = cMatch ;
RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ;
}
else
{
TRACE("HeapAlloc or HeapReAlloc failed to allocate enough bytes\n");
}
}
RegSetValueExA (hkey, "MRUList", 0, REG_SZ, (LPBYTE)pszList, strlen (pszList) + 1) ;
HeapFree( GetProcessHeap(), 0, pszCmd) ;
HeapFree( GetProcessHeap(), 0, pszList) ;
}
/*************************************************************************
* ConfirmDialog [internal]
*
* Put up a confirm box, return TRUE if the user confirmed
*/
static BOOL ConfirmDialog(HWND hWndOwner, UINT PromptId, UINT TitleId)
{
WCHAR Prompt[256];
WCHAR Title[256];
LoadStringW(shell32_hInstance, PromptId, Prompt, sizeof(Prompt) / sizeof(WCHAR));
LoadStringW(shell32_hInstance, TitleId, Title, sizeof(Title) / sizeof(WCHAR));
return MessageBoxW(hWndOwner, Prompt, Title, MB_YESNO|MB_ICONQUESTION) == IDYES;
}
/*************************************************************************
* RestartDialogEx [SHELL32.730]
*/
int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, DWORD uReason)
{
TRACE("(%p)\n", hWndOwner);
/* FIXME: use lpwstrReason */
if (ConfirmDialog(hWndOwner, IDS_RESTART_PROMPT, IDS_RESTART_TITLE))
{
HANDLE hToken;
TOKEN_PRIVILEGES npr;
/* enable the shutdown privilege for the current process */
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
npr.PrivilegeCount = 1;
npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
CloseHandle(hToken);
}
ExitWindowsEx(EWX_REBOOT, uReason);
}
return 0;
}
/*************************************************************************
* LogoffWindowsDialog [SHELL32.54]
*/
EXTERN_C int WINAPI LogoffWindowsDialog(HWND hWndOwner)
{
if (ConfirmDialog(hWndOwner, IDS_LOGOFF_PROMPT, IDS_LOGOFF_TITLE))
{
ExitWindowsEx(EWX_LOGOFF, 0);
}
return 0;}
/*************************************************************************
* RestartDialog [SHELL32.59]
*/
int WINAPI RestartDialog(HWND hWndOwner, LPCWSTR lpstrReason, DWORD uFlags)
{
return RestartDialogEx(hWndOwner, lpstrReason, uFlags, 0);
}
/*************************************************************************
* ExitWindowsDialog [SHELL32.60]
*
* NOTES
* exported by ordinal
*/
void WINAPI ExitWindowsDialog (HWND hWndOwner)
{
TRACE("(%p)\n", hWndOwner);
if (ConfirmDialog(hWndOwner, IDS_SHUTDOWN_PROMPT, IDS_SHUTDOWN_TITLE))
{
HANDLE hToken;
TOKEN_PRIVILEGES npr;
/* enable shutdown privilege for current process */
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
LookupPrivilegeValueA(0, "SeShutdownPrivilege", &npr.Privileges[0].Luid);
npr.PrivilegeCount = 1;
npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
CloseHandle(hToken);
}
ExitWindowsEx(EWX_SHUTDOWN, 0);
}
}

View file

@ -0,0 +1,67 @@
/*
* file system folder
*
* Copyright 1997 Marcus Meissner
* Copyright 1998, 1999, 2002 Juergen Schmied
* Copyright 2009 Andrew Hill
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL (shell);
/***********************************************************************
* IDropTargetHelper implementation
*/
IDropTargetHelperImpl::IDropTargetHelperImpl()
{
}
IDropTargetHelperImpl::~IDropTargetHelperImpl()
{
}
HRESULT WINAPI IDropTargetHelperImpl::DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect)
{
FIXME ("(%p)->(%p %p %p 0x%08x)\n", this, hwndTarget, pDataObject, ppt, dwEffect);
return E_NOTIMPL;
}
HRESULT WINAPI IDropTargetHelperImpl::DragLeave()
{
FIXME ("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI IDropTargetHelperImpl::DragOver(POINT *ppt, DWORD dwEffect)
{
FIXME ("(%p)->(%p 0x%08x)\n", this, ppt, dwEffect);
return E_NOTIMPL;
}
HRESULT WINAPI IDropTargetHelperImpl::Drop(IDataObject* pDataObject, POINT* ppt, DWORD dwEffect)
{
FIXME ("(%p)->(%p %p 0x%08x)\n", this, pDataObject, ppt, dwEffect);
return E_NOTIMPL;
}
HRESULT WINAPI IDropTargetHelperImpl::Show(BOOL fShow)
{
FIXME ("(%p)->(%u)\n", this, fShow);
return E_NOTIMPL;
}

View file

@ -0,0 +1,53 @@
/*
* file system folder
*
* Copyright 1997 Marcus Meissner
* Copyright 1998, 1999, 2002 Juergen Schmied
* Copyright 2009 Andrew Hill
*
* 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
*/
#ifndef _DRAGDROPHELPER_H_
#define _DRAGDROPHELPER_H_
class IDropTargetHelperImpl :
public CComCoClass<IDropTargetHelperImpl, &CLSID_DragDropHelper>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDropTargetHelper
{
private:
public:
IDropTargetHelperImpl();
~IDropTargetHelperImpl();
////////
virtual HRESULT WINAPI DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI DragOver(POINT *ppt, DWORD dwEffect);
virtual HRESULT WINAPI Drop(IDataObject* pDataObject, POINT* ppt, DWORD dwEffect);
virtual HRESULT WINAPI Show(BOOL fShow);
DECLARE_REGISTRY_RESOURCEID(IDR_DRAGDROPHELPER)
DECLARE_NOT_AGGREGATABLE(IDropTargetHelperImpl)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(IDropTargetHelperImpl)
COM_INTERFACE_ENTRY_IID(IID_IDropTargetHelper, IDropTargetHelper)
END_COM_MAP()
};
#endif // _DRAGDROPHELPER_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,301 @@
/*
* IEnumIDList
*
* Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
IEnumIDListImpl::IEnumIDListImpl()
{
mpFirst = NULL;
mpLast = NULL;
mpCurrent = NULL;
}
IEnumIDListImpl::~IEnumIDListImpl()
{
}
/**************************************************************************
* AddToEnumList()
*/
BOOL IEnumIDListImpl::AddToEnumList(LPITEMIDLIST pidl)
{
ENUMLIST *pNew;
TRACE("(%p)->(pidl=%p)\n", this, pidl);
if (!pidl)
return FALSE;
pNew = (ENUMLIST *)SHAlloc(sizeof(ENUMLIST));
if (pNew)
{
/*set the next pointer */
pNew->pNext = NULL;
pNew->pidl = pidl;
/*is This the first item in the list? */
if (!mpFirst)
{
mpFirst = pNew;
mpCurrent = pNew;
}
if (mpLast)
{
/*add the new item to the end of the list */
mpLast->pNext = pNew;
}
/*update the last item pointer */
mpLast = pNew;
TRACE("-- (%p)->(first=%p, last=%p)\n", this, mpFirst, mpLast);
return TRUE;
}
return FALSE;
}
/**************************************************************************
* DeleteList()
*/
BOOL IEnumIDListImpl::DeleteList()
{
ENUMLIST *pDelete;
TRACE("(%p)->()\n", this);
while (mpFirst)
{
pDelete = mpFirst;
mpFirst = pDelete->pNext;
SHFree(pDelete->pidl);
SHFree(pDelete);
}
mpFirst = NULL;
mpLast = NULL;
mpCurrent = NULL;
return TRUE;
}
/**************************************************************************
* HasItemWithCLSID()
*/
BOOL IEnumIDListImpl::HasItemWithCLSID(LPITEMIDLIST pidl)
{
ENUMLIST *pCur;
IID *ptr = _ILGetGUIDPointer(pidl);
if (ptr)
{
REFIID refid = *ptr;
pCur = mpFirst;
while(pCur)
{
LPGUID curid = _ILGetGUIDPointer(pCur->pidl);
if (curid && IsEqualGUID(*curid, refid))
{
return TRUE;
}
pCur = pCur->pNext;
}
}
return FALSE;
}
/**************************************************************************
* CreateFolderEnumList()
*/
BOOL IEnumIDListImpl::CreateFolderEnumList(
LPCWSTR lpszPath,
DWORD dwFlags)
{
LPITEMIDLIST pidl=NULL;
WIN32_FIND_DATAW stffile;
HANDLE hFile;
WCHAR szPath[MAX_PATH];
BOOL succeeded = TRUE;
static const WCHAR stars[] = { '*','.','*',0 };
static const WCHAR dot[] = { '.',0 };
static const WCHAR dotdot[] = { '.','.',0 };
TRACE("(%p)->(path=%s flags=0x%08x)\n", this, debugstr_w(lpszPath), dwFlags);
if(!lpszPath || !lpszPath[0]) return FALSE;
wcscpy(szPath, lpszPath);
PathAddBackslashW(szPath);
wcscat(szPath,stars);
hFile = FindFirstFileW(szPath,&stffile);
if ( hFile != INVALID_HANDLE_VALUE )
{
BOOL findFinished = FALSE;
do
{
if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
|| (dwFlags & SHCONTF_INCLUDEHIDDEN) )
{
if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
dwFlags & SHCONTF_FOLDERS &&
strcmpW(stffile.cFileName, dot) && strcmpW(stffile.cFileName, dotdot))
{
pidl = _ILCreateFromFindDataW(&stffile);
succeeded = succeeded && AddToEnumList(pidl);
}
else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& dwFlags & SHCONTF_NONFOLDERS)
{
pidl = _ILCreateFromFindDataW(&stffile);
succeeded = succeeded && AddToEnumList(pidl);
}
}
if (succeeded)
{
if (!FindNextFileW(hFile, &stffile))
{
if (GetLastError() == ERROR_NO_MORE_FILES)
findFinished = TRUE;
else
succeeded = FALSE;
}
}
} while (succeeded && !findFinished);
FindClose(hFile);
}
return succeeded;
}
/**************************************************************************
* IEnumIDList_fnNext
*/
HRESULT WINAPI IEnumIDListImpl::Next(
ULONG celt,
LPITEMIDLIST * rgelt,
ULONG *pceltFetched)
{
ULONG i;
HRESULT hr = S_OK;
LPITEMIDLIST temp;
TRACE("(%p)->(%d,%p, %p)\n", this, celt, rgelt, pceltFetched);
/* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
* subsystems actually use it (and so may a third party browser)
*/
if(pceltFetched)
*pceltFetched = 0;
*rgelt=0;
if(celt > 1 && !pceltFetched)
{ return E_INVALIDARG;
}
if(celt > 0 && !mpCurrent)
{ return S_FALSE;
}
for(i = 0; i < celt; i++)
{ if(!mpCurrent)
break;
temp = ILClone(mpCurrent->pidl);
rgelt[i] = temp;
mpCurrent = mpCurrent->pNext;
}
if(pceltFetched)
{ *pceltFetched = i;
}
return hr;
}
/**************************************************************************
* IEnumIDList_fnSkip
*/
HRESULT WINAPI IEnumIDListImpl::Skip(
ULONG celt)
{
DWORD dwIndex;
HRESULT hr = S_OK;
TRACE("(%p)->(%u)\n", this, celt);
for(dwIndex = 0; dwIndex < celt; dwIndex++)
{ if(!mpCurrent)
{ hr = S_FALSE;
break;
}
mpCurrent = mpCurrent->pNext;
}
return hr;
}
/**************************************************************************
* IEnumIDList_fnReset
*/
HRESULT WINAPI IEnumIDListImpl::Reset()
{
TRACE("(%p)\n", this);
mpCurrent = mpFirst;
return S_OK;
}
/**************************************************************************
* IEnumIDList_fnClone
*/
HRESULT WINAPI IEnumIDListImpl::Clone(LPENUMIDLIST *ppenum)
{
TRACE("(%p)->() to (%p)->() E_NOTIMPL\n", this, ppenum);
return E_NOTIMPL;
}
/**************************************************************************
* IEnumIDList_Folder_Constructor
*
*/
HRESULT IEnumIDList_Constructor(IEnumIDList **enumerator)
{
CComObject<IEnumIDListImpl> *theEnumerator;
CComPtr<IEnumIDList> result;
HRESULT hResult;
if (enumerator == NULL)
return E_POINTER;
*enumerator = NULL;
ATLTRY (theEnumerator = new CComObject<IEnumIDListImpl>);
if (theEnumerator == NULL)
return E_OUTOFMEMORY;
hResult = theEnumerator->QueryInterface (IID_IEnumIDList, (void **)&result);
if (FAILED (hResult))
{
delete theEnumerator;
return hResult;
}
*enumerator = result.Detach ();
return S_OK;
}

View file

@ -18,14 +18,37 @@
#include "shlobj.h"
/* Creates an IEnumIDList; add LPITEMIDLISTs to it with AddToEnumList. */
LPENUMIDLIST IEnumIDList_Constructor(void);
BOOL AddToEnumList(IEnumIDList *list, LPITEMIDLIST pidl);
BOOL HasItemWithCLSID(IEnumIDList *list, LPITEMIDLIST pidl);
struct ENUMLIST
{
ENUMLIST *pNext;
LPITEMIDLIST pidl;
};
/* Enumerates the folders and/or files (depending on dwFlags) in lpszPath and
* adds them to the already-created list.
*/
BOOL CreateFolderEnumList(IEnumIDList *list, LPCWSTR lpszPath, DWORD dwFlags);
class IEnumIDListImpl :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IEnumIDList
{
private:
ENUMLIST *mpFirst;
ENUMLIST *mpLast;
ENUMLIST *mpCurrent;
public:
IEnumIDListImpl();
~IEnumIDListImpl();
BOOL AddToEnumList(LPITEMIDLIST pidl);
BOOL DeleteList();
BOOL HasItemWithCLSID(LPITEMIDLIST pidl);
BOOL CreateFolderEnumList(LPCWSTR lpszPath, DWORD dwFlags);
// *** IEnumIDList methods ***
virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched);
virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt);
virtual HRESULT STDMETHODCALLTYPE Reset();
virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum);
BEGIN_COM_MAP(IEnumIDListImpl)
COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
END_COM_MAP()
};
#endif /* ndef __ENUMIDLIST_H__ */

View file

@ -0,0 +1,358 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Registry namespace extension
* FILE: dll/win32/shell32/extracticon.c
* PURPOSE: Icon extraction
*
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
struct IconLocation
{
LPWSTR file;
UINT index;
};
class IconExtraction :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDefaultExtractIconInit,
public IExtractIconW,
public IExtractIconA,
public IPersistFile
{
private:
UINT flags;
struct IconLocation defaultIcon;
struct IconLocation normalIcon;
struct IconLocation openIcon;
struct IconLocation shortcutIcon;
public:
IconExtraction();
~IconExtraction();
// IDefaultExtractIconInit
virtual HRESULT STDMETHODCALLTYPE SetDefaultIcon(LPCWSTR pszFile, int iIcon);
virtual HRESULT STDMETHODCALLTYPE SetFlags(UINT uFlags);
virtual HRESULT STDMETHODCALLTYPE SetKey(HKEY hkey);
virtual HRESULT STDMETHODCALLTYPE SetNormalIcon(LPCWSTR pszFile, int iIcon);
virtual HRESULT STDMETHODCALLTYPE SetOpenIcon(LPCWSTR pszFile, int iIcon);
virtual HRESULT STDMETHODCALLTYPE SetShortcutIcon(LPCWSTR pszFile, int iIcon);
// IExtractIconW
virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
virtual HRESULT STDMETHODCALLTYPE Extract(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
// IExtractIconA
virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, LPSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
virtual HRESULT STDMETHODCALLTYPE Extract(LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
// IPersist
virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
virtual HRESULT STDMETHODCALLTYPE IsDirty();
// IPersistFile
virtual HRESULT STDMETHODCALLTYPE Load(LPCOLESTR pszFileName, DWORD dwMode);
virtual HRESULT STDMETHODCALLTYPE Save(LPCOLESTR pszFileName, BOOL fRemember);
virtual HRESULT STDMETHODCALLTYPE SaveCompleted(LPCOLESTR pszFileName);
virtual HRESULT STDMETHODCALLTYPE GetCurFile(LPOLESTR *ppszFileName);
BEGIN_COM_MAP(IconExtraction)
COM_INTERFACE_ENTRY_IID(IID_IDefaultExtractIconInit, IDefaultExtractIconInit)
COM_INTERFACE_ENTRY_IID(IID_IExtractIconW, IExtractIconW)
COM_INTERFACE_ENTRY_IID(IID_IExtractIconA, IExtractIconA)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
END_COM_MAP()
};
VOID DuplicateString(
LPCWSTR Source,
LPWSTR *Destination)
{
SIZE_T cb;
if (*Destination)
CoTaskMemFree(*Destination);
cb = (wcslen(Source) + 1) * sizeof(WCHAR);
*Destination = (LPWSTR)CoTaskMemAlloc(cb);
if (!*Destination)
return;
CopyMemory(*Destination, Source, cb);
}
IconExtraction::IconExtraction()
{
flags = 0;
memset(&defaultIcon, 0, sizeof(defaultIcon));
memset(&normalIcon, 0, sizeof(normalIcon));
memset(&openIcon, 0, sizeof(openIcon));
memset(&shortcutIcon, 0, sizeof(shortcutIcon));
}
IconExtraction::~IconExtraction()
{
if (defaultIcon.file) CoTaskMemFree(defaultIcon.file);
if (normalIcon.file) CoTaskMemFree(normalIcon.file);
if (openIcon.file) CoTaskMemFree(openIcon.file);
if (shortcutIcon.file) CoTaskMemFree(shortcutIcon.file);
}
HRESULT STDMETHODCALLTYPE IconExtraction::SetDefaultIcon(
LPCWSTR pszFile,
int iIcon)
{
TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
DuplicateString(pszFile, &defaultIcon.file);
if (!defaultIcon.file)
return E_OUTOFMEMORY;
defaultIcon.index = iIcon;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::SetFlags(
UINT uFlags)
{
TRACE("(%p, 0x%x)\n", this, uFlags);
flags = uFlags;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::SetKey(
HKEY hkey)
{
FIXME("(%p, %p)\n", this, hkey);
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE IconExtraction::SetNormalIcon(
LPCWSTR pszFile,
int iIcon)
{
TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
DuplicateString(pszFile, &normalIcon.file);
if (!normalIcon.file)
return E_OUTOFMEMORY;
normalIcon.index = iIcon;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::SetOpenIcon(
LPCWSTR pszFile,
int iIcon)
{
TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
DuplicateString(pszFile, &openIcon.file);
if (!openIcon.file)
return E_OUTOFMEMORY;
openIcon.index = iIcon;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::SetShortcutIcon(
LPCWSTR pszFile,
int iIcon)
{
TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
DuplicateString(pszFile, &shortcutIcon.file);
if (!shortcutIcon.file)
return E_OUTOFMEMORY;
shortcutIcon.index = iIcon;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::GetIconLocation(
UINT uFlags,
LPWSTR szIconFile,
UINT cchMax,
int *piIndex,
UINT *pwFlags)
{
const struct IconLocation *icon = NULL;
SIZE_T cb;
TRACE("(%p, 0x%x, %s, 0x%x, %p, %p)\n", this, uFlags, debugstr_w(szIconFile), cchMax, piIndex, pwFlags);
if (!piIndex || !pwFlags)
return E_POINTER;
if (uFlags & GIL_DEFAULTICON)
icon = defaultIcon.file ? &defaultIcon : &normalIcon;
else if (uFlags & GIL_FORSHORTCUT)
icon = shortcutIcon.file ? &shortcutIcon : &normalIcon;
else if (uFlags & GIL_OPENICON)
icon = openIcon.file ? &openIcon : &normalIcon;
else
icon = &normalIcon;
if (!icon->file)
return E_FAIL;
cb = wcslen(icon->file) + 1;
if (cchMax < (UINT)cb)
return E_FAIL;
CopyMemory(szIconFile, icon->file, cb * sizeof(WCHAR));
*piIndex = icon->index;
*pwFlags = flags;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::Extract(
LPCWSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize)
{
TRACE("(%p, %s, %u, %p, %p, %u)\n", this, debugstr_w(pszFile), nIconIndex, phiconLarge, phiconSmall, nIconSize);
/* Nothing to do, ExtractIconW::GetIconLocation should be enough */
return S_FALSE;
}
HRESULT STDMETHODCALLTYPE IconExtraction::GetIconLocation(
UINT uFlags,
LPSTR szIconFile,
UINT cchMax,
int *piIndex,
UINT *pwFlags)
{
LPWSTR szIconFileW = NULL;
HRESULT hr;
if (cchMax > 0)
{
szIconFileW = (LPWSTR)CoTaskMemAlloc(cchMax * sizeof(WCHAR));
if (!szIconFileW)
return E_OUTOFMEMORY;
}
hr = GetIconLocation(
uFlags, szIconFileW, cchMax, piIndex, pwFlags);
if (SUCCEEDED(hr) && cchMax > 0)
if (0 == WideCharToMultiByte(CP_ACP, 0, szIconFileW, cchMax, szIconFile, cchMax, NULL, NULL))
hr = E_FAIL;
if (szIconFileW)
CoTaskMemFree(szIconFileW);
return hr;
}
HRESULT STDMETHODCALLTYPE IconExtraction::Extract(
LPCSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize)
{
LPWSTR pszFileW = NULL;
int nLength;
HRESULT hr;
if (pszFile)
{
nLength = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0);
if (nLength == 0)
return E_FAIL;
pszFileW = (LPWSTR)CoTaskMemAlloc(nLength * sizeof(WCHAR));
if (!pszFileW)
return E_OUTOFMEMORY;
if (!MultiByteToWideChar(CP_ACP, 0, pszFile, nLength, pszFileW, nLength))
{
CoTaskMemFree(pszFileW);
return E_FAIL;
}
}
hr = Extract(
pszFileW, nIconIndex, phiconLarge, phiconSmall, nIconSize);
if (pszFileW)
CoTaskMemFree(pszFileW);
return hr;
}
HRESULT STDMETHODCALLTYPE IconExtraction::GetClassID(
CLSID *pClassID)
{
TRACE("(%p, %p)\n", this, pClassID);
if (!pClassID)
return E_POINTER;
*pClassID = GUID_NULL;
return S_OK;
}
HRESULT STDMETHODCALLTYPE IconExtraction::IsDirty()
{
FIXME("(%p)\n", this);
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE IconExtraction::Load(
LPCOLESTR pszFileName,
DWORD dwMode)
{
FIXME("(%p, %s, %u)\n", this, debugstr_w(pszFileName), dwMode);
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE IconExtraction::Save(
LPCOLESTR pszFileName,
BOOL fRemember)
{
FIXME("(%p, %s, %d)\n", this, debugstr_w(pszFileName), fRemember);
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE IconExtraction::SaveCompleted(
LPCOLESTR pszFileName)
{
FIXME("(%p, %s)\n", this, debugstr_w(pszFileName));
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE IconExtraction::GetCurFile(
LPOLESTR *ppszFileName)
{
FIXME("(%p, %p)\n", this, ppszFileName);
UNIMPLEMENTED;
return E_NOTIMPL;
}
HRESULT WINAPI SHCreateDefaultExtractIcon(REFIID riid, void **ppv)
{
CComObject<IconExtraction> *theExtractor;
CComPtr<IUnknown> result;
HRESULT hResult;
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY (theExtractor = new CComObject<IconExtraction>);
if (theExtractor == NULL)
return E_OUTOFMEMORY;
hResult = theExtractor->QueryInterface (riid, (void **)&result);
if (FAILED (hResult))
{
delete theExtractor;
return hResult;
}
*ppv = result.Detach ();
return S_OK;
}

View file

@ -0,0 +1,827 @@
/*
* Open With Context Menu extension
*
* Copyright 2007 Johannes Anderwald <janderwald@reactos.org>
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL (fprop);
#define MAX_PROPERTY_SHEET_PAGE (32)
/// Folder Options:
/// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
/// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
/// Verbs: Open / RunAs
/// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
/// ShellFolder Attributes: 0x0
typedef struct
{
DWORD cFiles;
DWORD cFolder;
LARGE_INTEGER bSize;
HWND hwndDlg;
WCHAR szFolderPath[MAX_PATH];
}FOLDER_PROPERTIES_CONTEXT, *PFOLDER_PROPERTIES_CONTEXT;
typedef struct
{
WCHAR FileExtension[30];
WCHAR FileDescription[100];
WCHAR ClassKey[MAX_PATH];
}FOLDER_FILE_TYPE_ENTRY, *PFOLDER_FILE_TYPE_ENTRY;
typedef struct
{
LPCWSTR szKeyName;
UINT ResourceID;
}FOLDER_VIEW_ENTRY, PFOLDER_VIEW_ENTRY;
/*
static FOLDER_VIEW_ENTRY s_Options[] =
{
{ L"AlwaysShowMenus", IDS_ALWAYSSHOWMENUS },
{ L"AutoCheckSelect", -1 },
{ L"ClassicViewState", -1 },
{ L"DontPrettyPath", -1 },
{ L"Filter", -1 },
{ L"FolderContentsInfoTip", IDS_FOLDERCONTENTSTIP },
{ L"FriendlyTree", -1 },
{ L"Hidden", -1, },
{ L"HideFileExt", IDS_HIDEFILEEXT },
{ L"HideIcons", -1},
{ L"IconsOnly", -1},
{ L"ListviewAlphaSelect", -1},
{ L"ListviewShadow", -1},
{ L"ListviewWatermark", -1},
{ L"MapNetDrvBtn", -1},
{ L"PersistBrowsers", -1},
{ L"SeperateProcess", IDS_SEPERATEPROCESS},
{ L"ServerAdminUI", -1},
{ L"SharingWizardOn", IDS_USESHAREWIZARD},
{ L"ShowCompColor", IDS_COMPCOLOR},
{ L"ShowInfoTip", IDS_SHOWINFOTIP},
{ L"ShowPreviewHandlers", -1},
{ L"ShowSuperHidden", IDS_HIDEOSFILES},
{ L"ShowTypeOverlay", -1},
{ L"Start_ShowMyGames", -1},
{ L"StartMenuInit", -1},
{ L"SuperHidden", -1},
{ L"TypeAhead", -1},
{ L"Webview", -1},
{ NULL, -1}
};
*/
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
INT_PTR
CALLBACK
FolderOptionsGeneralDlg(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
return FALSE;
}
static
VOID
InitializeFolderOptionsListCtrl(HWND hwndDlg)
{
RECT clientRect;
LVCOLUMNW col;
WCHAR szName[50];
HWND hDlgCtrl;
hDlgCtrl = GetDlgItem(hwndDlg, 14003);
if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
szName[0] = 0;
szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
GetClientRect(hDlgCtrl, &clientRect);
ZeroMemory(&col, sizeof(LV_COLUMN));
col.mask = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
col.iSubItem = 0;
col.pszText = szName;
col.fmt = LVCFMT_LEFT;
col.cx = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
(void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMN, 0, (LPARAM)&col);
}
INT_PTR
CALLBACK
FolderOptionsViewDlg(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_INITDIALOG:
InitializeFolderOptionsListCtrl(hwndDlg);
return TRUE;
}
return FALSE;
}
VOID
InitializeFileTypesListCtrlColumns(HWND hDlgCtrl)
{
RECT clientRect;
LVCOLUMNW col;
WCHAR szName[50];
DWORD dwStyle;
int columnSize = 140;
if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
{
/* default to english */
wcscpy(szName, L"Extensions");
}
/* make sure its null terminated */
szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
GetClientRect(hDlgCtrl, &clientRect);
ZeroMemory(&col, sizeof(LV_COLUMN));
columnSize = 140; //FIXME
col.iSubItem = 0;
col.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
col.fmt = LVCFMT_FIXED_WIDTH;
col.cx = columnSize | LVCFMT_LEFT;
col.cchTextMax = wcslen(szName);
col.pszText = szName;
(void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&col);
if (!LoadStringW(shell32_hInstance, IDS_FILE_TYPES, szName, sizeof(szName) / sizeof(WCHAR)))
{
/* default to english */
wcscpy(szName, L"FileTypes");
}
col.iSubItem = 1;
col.cx = clientRect.right - clientRect.left - columnSize;
col.cchTextMax = wcslen(szName);
col.pszText = szName;
(void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM)&col);
/* set full select style */
dwStyle = (DWORD) SendMessage(hDlgCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
SendMessage(hDlgCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
}
INT
FindItem(HWND hDlgCtrl, WCHAR * ItemName)
{
LVFINDINFOW findInfo;
ZeroMemory(&findInfo, sizeof(LVFINDINFOW));
findInfo.flags = LVFI_STRING;
findInfo.psz = ItemName;
return ListView_FindItem(hDlgCtrl, 0, &findInfo);
}
VOID
InsertFileType(HWND hDlgCtrl, WCHAR * szName, PINT iItem, WCHAR * szFile)
{
PFOLDER_FILE_TYPE_ENTRY Entry;
HKEY hKey;
LVITEMW lvItem;
DWORD dwSize;
if (szName[0] != L'.')
{
/* FIXME handle URL protocol handlers */
return;
}
/* allocate file type entry */
Entry = (PFOLDER_FILE_TYPE_ENTRY)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY));
if (!Entry)
return;
/* open key */
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szName, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
return;
/* FIXME check for duplicates */
/* query for the default key */
dwSize = sizeof(Entry->ClassKey);
if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)Entry->ClassKey, &dwSize) != ERROR_SUCCESS)
{
/* no link available */
Entry->ClassKey[0] = 0;
}
if (Entry->ClassKey[0])
{
HKEY hTemp;
/* try open linked key */
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, Entry->ClassKey, 0, KEY_READ, &hTemp) == ERROR_SUCCESS)
{
/* use linked key */
RegCloseKey(hKey);
hKey = hTemp;
}
}
/* read friendly type name */
if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", Entry->FileDescription, sizeof(Entry->FileDescription), NULL, 0, NULL) != ERROR_SUCCESS)
{
/* read file description */
dwSize = sizeof(Entry->FileDescription);
Entry->FileDescription[0] = 0;
/* read default key */
RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)Entry->FileDescription, &dwSize);
}
/* close key */
RegCloseKey(hKey);
/* convert extension to upper case */
wcscpy(Entry->FileExtension, szName);
_wcsupr(Entry->FileExtension);
if (!Entry->FileDescription[0])
{
/* construct default 'FileExtensionFile' */
wcscpy(Entry->FileDescription, &Entry->FileExtension[1]);
wcscat(Entry->FileDescription, L" ");
wcscat(Entry->FileDescription, szFile);
}
ZeroMemory(&lvItem, sizeof(LVITEMW));
lvItem.mask = LVIF_TEXT | LVIF_PARAM;
lvItem.iSubItem = 0;
lvItem.pszText = &Entry->FileExtension[1];
lvItem.iItem = *iItem;
lvItem.lParam = (LPARAM)Entry;
(void)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
ZeroMemory(&lvItem, sizeof(LVITEMW));
lvItem.mask = LVIF_TEXT;
lvItem.pszText = Entry->FileDescription;
lvItem.iItem = *iItem;
lvItem.iSubItem = 1;
(void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&lvItem);
(*iItem)++;
}
int
CALLBACK
ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
PFOLDER_FILE_TYPE_ENTRY Entry1, Entry2;
Entry1 = (PFOLDER_FILE_TYPE_ENTRY)lParam1;
Entry2 = (PFOLDER_FILE_TYPE_ENTRY)lParam2;
return wcsicmp(Entry1->FileExtension, Entry2->FileExtension);
}
BOOL
InitializeFileTypesListCtrl(HWND hwndDlg)
{
HWND hDlgCtrl;
DWORD dwIndex = 0;
WCHAR szName[50];
WCHAR szFile[100];
DWORD dwName;
LVITEMW lvItem;
INT iItem = 0;
hDlgCtrl = GetDlgItem(hwndDlg, 14000);
InitializeFileTypesListCtrlColumns(hDlgCtrl);
szFile[0] = 0;
if (!LoadStringW(shell32_hInstance, IDS_SHV_COLUMN1, szFile, sizeof(szFile) / sizeof(WCHAR)))
{
/* default to english */
wcscpy(szFile, L"File");
}
szFile[(sizeof(szFile)/sizeof(WCHAR))-1] = 0;
dwName = sizeof(szName) / sizeof(WCHAR);
while(RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
InsertFileType(hDlgCtrl, szName, &iItem, szFile);
dwName = sizeof(szName) / sizeof(WCHAR);
}
/* sort list */
ListView_SortItems(hDlgCtrl, ListViewCompareProc, NULL);
/* select first item */
ZeroMemory(&lvItem, sizeof(LVITEMW));
lvItem.mask = LVIF_STATE;
lvItem.stateMask = (UINT)-1;
lvItem.state = LVIS_FOCUSED|LVIS_SELECTED;
lvItem.iItem = 0;
(void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&lvItem);
return TRUE;
}
PFOLDER_FILE_TYPE_ENTRY
FindSelectedItem(
HWND hDlgCtrl)
{
UINT Count, Index;
LVITEMW lvItem;
Count = ListView_GetItemCount(hDlgCtrl);
for (Index = 0; Index < Count; Index++)
{
ZeroMemory(&lvItem, sizeof(LVITEM));
lvItem.mask = LVIF_PARAM | LVIF_STATE;
lvItem.iItem = Index;
lvItem.stateMask = (UINT)-1;
if (ListView_GetItem(hDlgCtrl, &lvItem))
{
if (lvItem.state & LVIS_SELECTED)
return (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
}
}
return NULL;
}
INT_PTR
CALLBACK
FolderOptionsFileTypesDlg(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
LPNMLISTVIEW lppl;
LVITEMW lvItem;
WCHAR Buffer[255], FormatBuffer[255];
PFOLDER_FILE_TYPE_ENTRY pItem;
OPENASINFO Info;
switch(uMsg)
{
case WM_INITDIALOG:
InitializeFileTypesListCtrl(hwndDlg);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case 14006:
pItem = FindSelectedItem(GetDlgItem(hwndDlg, 14000));
if (pItem)
{
Info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT;
Info.pcszClass = pItem->FileExtension;
SHOpenWithDialog(hwndDlg, &Info);
}
break;
}
break;
case WM_NOTIFY:
lppl = (LPNMLISTVIEW) lParam;
if (lppl->hdr.code == LVN_ITEMCHANGING)
{
ZeroMemory(&lvItem, sizeof(LVITEM));
lvItem.mask = LVIF_PARAM;
lvItem.iItem = lppl->iItem;
if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&lvItem))
return TRUE;
pItem = (PFOLDER_FILE_TYPE_ENTRY)lvItem.lParam;
if (!pItem)
return TRUE;
if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
{
/* new focused item */
if (!LoadStringW(shell32_hInstance, IDS_FILE_DETAILS, FormatBuffer, sizeof(FormatBuffer) / sizeof(WCHAR)))
{
/* use default english format string */
wcscpy(FormatBuffer, L"Details for '%s' extension");
}
/* format buffer */
swprintf(Buffer, FormatBuffer, &pItem->FileExtension[1]);
/* update dialog */
SendDlgItemMessageW(hwndDlg, 14003, WM_SETTEXT, 0, (LPARAM)Buffer);
if (!LoadStringW(shell32_hInstance, IDS_FILE_DETAILSADV, FormatBuffer, sizeof(FormatBuffer) / sizeof(WCHAR)))
{
/* use default english format string */
wcscpy(FormatBuffer, L"Files with extension '%s' are of type '%s'. To change settings that affect all '%s' files, click Advanced.");
}
/* format buffer */
swprintf(Buffer, FormatBuffer, &pItem->FileExtension[1], &pItem->FileDescription[0], &pItem->FileDescription[0]);
/* update dialog */
SendDlgItemMessageW(hwndDlg, 14007, WM_SETTEXT, 0, (LPARAM)Buffer);
}
}
break;
}
return FALSE;
}
VOID
ShowFolderOptionsDialog(HWND hWnd, HINSTANCE hInst)
{
PROPSHEETHEADERW pinfo;
HPROPSHEETPAGE hppages[3];
HPROPSHEETPAGE hpage;
UINT num_pages = 0;
WCHAR szOptions[100];
hpage = SH_CreatePropertySheetPage("FOLDER_OPTIONS_GENERAL_DLG", FolderOptionsGeneralDlg, 0, NULL);
if (hpage)
hppages[num_pages++] = hpage;
hpage = SH_CreatePropertySheetPage("FOLDER_OPTIONS_VIEW_DLG", FolderOptionsViewDlg, 0, NULL);
if (hpage)
hppages[num_pages++] = hpage;
hpage = SH_CreatePropertySheetPage("FOLDER_OPTIONS_FILETYPES_DLG", FolderOptionsFileTypesDlg, 0, NULL);
if (hpage)
hppages[num_pages++] = hpage;
szOptions[0] = L'\0';
LoadStringW(shell32_hInstance, IDS_FOLDER_OPTIONS, szOptions, sizeof(szOptions) / sizeof(WCHAR));
szOptions[(sizeof(szOptions)/sizeof(WCHAR))-1] = L'\0';
memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
pinfo.dwSize = sizeof(PROPSHEETHEADERW);
pinfo.dwFlags = PSH_NOCONTEXTHELP;
pinfo.nPages = num_pages;
pinfo.phpage = hppages;
pinfo.pszCaption = szOptions;
PropertySheetW(&pinfo);
}
VOID
Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow)
{
switch(fOptions)
{
case 0:
ShowFolderOptionsDialog(hWnd, hInst);
break;
case 1:
// show taskbar options dialog
FIXME("notify explorer to show taskbar options dialog");
//PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
break;
default:
FIXME("unrecognized options id %d\n", fOptions);
}
}
/*************************************************************************
* Options_RunDLL (SHELL32.@)
*/
EXTERN_C VOID WINAPI Options_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow);
}
/*************************************************************************
* Options_RunDLLA (SHELL32.@)
*/
EXTERN_C VOID WINAPI Options_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow);
}
/*************************************************************************
* Options_RunDLLW (SHELL32.@)
*/
EXTERN_C VOID WINAPI Options_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
{
Options_RunDLLCommon(hWnd, hInst, StrToIntW(cmd), nCmdShow);
}
static
DWORD WINAPI
CountFolderAndFiles(LPVOID lParam)
{
WIN32_FIND_DATAW FindData;
HANDLE hFile;
UINT Length;
LPWSTR pOffset;
BOOL ret;
PFOLDER_PROPERTIES_CONTEXT pContext = (PFOLDER_PROPERTIES_CONTEXT) lParam;
pOffset = PathAddBackslashW(pContext->szFolderPath);
if (!pOffset)
return 0;
Length = pOffset - pContext->szFolderPath;
wcscpy(pOffset, L"*.*");
hFile = FindFirstFileW(pContext->szFolderPath, &FindData);
if (hFile == INVALID_HANDLE_VALUE)
return 0;
do
{
ret = FindNextFileW(hFile, &FindData);
if (ret)
{
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (FindData.cFileName[0] == L'.' && FindData.cFileName[1] == L'.' &&
FindData.cFileName[2] == L'\0')
continue;
pContext->cFolder++;
wcscpy(pOffset, FindData.cFileName);
CountFolderAndFiles((LPVOID)pContext);
pOffset[0] = L'\0';
}
else
{
pContext->cFiles++;
pContext->bSize.u.LowPart += FindData.nFileSizeLow;
pContext->bSize.u.HighPart += FindData.nFileSizeHigh;
}
}
else if (GetLastError() == ERROR_NO_MORE_FILES)
{
break;
}
}while(1);
FindClose(hFile);
return 1;
}
static
VOID
InitializeFolderGeneralDlg(PFOLDER_PROPERTIES_CONTEXT pContext)
{
LPWSTR pFolderName;
WIN32_FILE_ATTRIBUTE_DATA FolderAttribute;
FILETIME ft;
SYSTEMTIME dt;
WCHAR szBuffer[MAX_PATH+5];
WCHAR szFormat[30] = {0};
static const WCHAR wFormat[] = {'%','0','2','d','/','%','0','2','d','/','%','0','4','d',' ',' ','%','0','2','d',':','%','0','2','u',0};
pFolderName = wcsrchr(pContext->szFolderPath, L'\\');
if (!pFolderName)
return;
/* set folder name */
SendDlgItemMessageW(pContext->hwndDlg, 14001, WM_SETTEXT, 0, (LPARAM) (pFolderName + 1));
/* set folder location */
pFolderName[0] = L'\0';
if (wcslen(pContext->szFolderPath) == 2)
{
/* folder is located at root */
WCHAR szDrive[4] = {L'C',L':',L'\\',L'\0'};
szDrive[0] = pContext->szFolderPath[0];
SendDlgItemMessageW(pContext->hwndDlg, 14007, WM_SETTEXT, 0, (LPARAM) szDrive);
}
else
{
SendDlgItemMessageW(pContext->hwndDlg, 14007, WM_SETTEXT, 0, (LPARAM) pContext->szFolderPath);
}
pFolderName[0] = L'\\';
/* get folder properties */
if (GetFileAttributesExW(pContext->szFolderPath, GetFileExInfoStandard, (LPVOID)&FolderAttribute))
{
if (FolderAttribute.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
{
/* check readonly button */
SendDlgItemMessage(pContext->hwndDlg, 14021, BM_SETCHECK, BST_CHECKED, 0);
}
if (FolderAttribute.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
{
/* check hidden button */
SendDlgItemMessage(pContext->hwndDlg, 14022, BM_SETCHECK, BST_CHECKED, 0);
}
if (FileTimeToLocalFileTime(&FolderAttribute.ftCreationTime, &ft))
{
FileTimeToSystemTime(&ft, &dt);
swprintf (szBuffer, wFormat, dt.wDay, dt.wMonth, dt.wYear, dt.wHour, dt.wMinute);
SendDlgItemMessageW(pContext->hwndDlg, 14015, WM_SETTEXT, 0, (LPARAM) szBuffer);
}
}
/* now enumerate enumerate contents */
wcscpy(szBuffer, pContext->szFolderPath);
CountFolderAndFiles((LPVOID)pContext);
wcscpy(pContext->szFolderPath, szBuffer);
/* set folder details */
LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, szFormat, sizeof(szFormat)/sizeof(WCHAR));
szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
swprintf(szBuffer, szFormat, pContext->cFiles, pContext->cFolder);
SendDlgItemMessageW(pContext->hwndDlg, 14011, WM_SETTEXT, 0, (LPARAM) szBuffer);
if (StrFormatByteSizeW(pContext->bSize.QuadPart, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
{
/* store folder size */
SendDlgItemMessageW(pContext->hwndDlg, 14009, WM_SETTEXT, 0, (LPARAM) szBuffer);
}
}
INT_PTR
CALLBACK
FolderPropertiesGeneralDlg(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
LPPROPSHEETPAGEW ppsp;
PFOLDER_PROPERTIES_CONTEXT pContext;
HICON hIcon;
WIN32_FILE_ATTRIBUTE_DATA FolderAttribute;
LONG res;
LPPSHNOTIFY lppsn;
DWORD Attribute;
switch(uMsg)
{
case WM_INITDIALOG:
ppsp = (LPPROPSHEETPAGEW)lParam;
if (ppsp == NULL)
break;
hIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPEN));
if (hIcon)
SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIcon, 0);
pContext = (FOLDER_PROPERTIES_CONTEXT *)SHAlloc(sizeof(FOLDER_PROPERTIES_CONTEXT));
if (pContext)
{
ZeroMemory(pContext, sizeof(FOLDER_PROPERTIES_CONTEXT));
pContext->hwndDlg = hwndDlg;
wcscpy(pContext->szFolderPath, (LPWSTR)ppsp->lParam);
SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)pContext);
InitializeFolderGeneralDlg(pContext);
}
return TRUE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
{
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
break;
case WM_DESTROY:
pContext = (PFOLDER_PROPERTIES_CONTEXT)GetWindowLongPtr(hwndDlg, DWL_USER);
SHFree((LPVOID)pContext);
break;
case WM_NOTIFY:
pContext = (PFOLDER_PROPERTIES_CONTEXT)GetWindowLongPtr(hwndDlg, DWL_USER);
lppsn = (LPPSHNOTIFY) lParam;
if (lppsn->hdr.code == PSN_APPLY)
{
if (GetFileAttributesExW(pContext->szFolderPath, GetFileExInfoStandard, (LPVOID)&FolderAttribute))
{
res = SendDlgItemMessageW(hwndDlg, 14021, BM_GETCHECK, 0, 0);
if (res == BST_CHECKED)
FolderAttribute.dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
else
FolderAttribute.dwFileAttributes &= (~FILE_ATTRIBUTE_READONLY);
res = SendDlgItemMessageW(hwndDlg, 14022, BM_GETCHECK, 0, 0);
if (res == BST_CHECKED)
FolderAttribute.dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
else
FolderAttribute.dwFileAttributes &= (~FILE_ATTRIBUTE_HIDDEN);
Attribute = FolderAttribute.dwFileAttributes &
(FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY);
SetFileAttributesW(pContext->szFolderPath, Attribute);
}
SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
return TRUE;
}
break;
}
return FALSE;
}
static
BOOL
CALLBACK
FolderAddPropSheetPageProc(HPROPSHEETPAGE hpage, LPARAM lParam)
{
PROPSHEETHEADERW *ppsh = (PROPSHEETHEADERW *)lParam;
if (ppsh != NULL && ppsh->nPages < MAX_PROPERTY_SHEET_PAGE)
{
ppsh->phpage[ppsh->nPages++] = hpage;
return TRUE;
}
return FALSE;
}
BOOL
SH_ShowFolderProperties(LPWSTR pwszFolder, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * apidl)
{
HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
HPROPSHEETPAGE hpage;
PROPSHEETHEADERW psh;
BOOL ret;
WCHAR szName[MAX_PATH] = {0};
HPSXA hpsx = NULL;
LPWSTR pFolderName;
CComPtr<IDataObject> pDataObj;
if (!PathIsDirectoryW(pwszFolder))
return FALSE;
pFolderName = wcsrchr(pwszFolder, L'\\');
if (!pFolderName)
return FALSE;
wcscpy(szName, pFolderName + 1);
hpage = SH_CreatePropertySheetPage("SHELL_FOLDER_GENERAL_DLG", FolderPropertiesGeneralDlg, (LPARAM)pwszFolder, NULL);
if (!hpage)
return FALSE;
ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
hppages[psh.nPages] = hpage;
psh.nPages++;
psh.dwSize = sizeof(PROPSHEETHEADERW);
psh.dwFlags = PSH_PROPTITLE;
psh.hwndParent = NULL;
psh.phpage = hppages;
psh.pszCaption = szName;
if (SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (void**)&pDataObj) == S_OK)
{
hpsx = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Directory", MAX_PROPERTY_SHEET_PAGE-1, pDataObj);
if (hpsx)
{
SHAddFromPropSheetExtArray(hpsx,
(LPFNADDPROPSHEETPAGE)FolderAddPropSheetPageProc,
(LPARAM)&psh);
}
}
ret = PropertySheetW(&psh);
if (hpsx)
SHDestroyPropSheetExtArray(hpsx);
if (ret < 0)
return FALSE;
else
return TRUE;
}

View file

@ -0,0 +1,380 @@
/*
* Copyright 1997 Marcus Meissner
* Copyright 1998 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
WCHAR swShell32Name[MAX_PATH];
DWORD NumIconOverlayHandlers = 0;
IShellIconOverlayIdentifier ** Handlers = NULL;
static HRESULT getIconLocationForFolder(LPCITEMIDLIST pidl, UINT uFlags,
LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
{
int icon_idx;
WCHAR wszPath[MAX_PATH];
WCHAR wszCLSIDValue[CHARS_IN_GUID];
static const WCHAR shellClassInfo[] = { '.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0 };
static const WCHAR iconFile[] = { 'I','c','o','n','F','i','l','e',0 };
static const WCHAR clsid[] = { 'C','L','S','I','D',0 };
static const WCHAR clsid2[] = { 'C','L','S','I','D','2',0 };
static const WCHAR iconIndex[] = { 'I','c','o','n','I','n','d','e','x',0 };
if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconFile,
wszPath, MAX_PATH))
{
WCHAR wszIconIndex[10];
SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, iconIndex,
wszIconIndex, 10);
*piIndex = _wtoi(wszIconIndex);
}
else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid,
wszCLSIDValue, CHARS_IN_GUID) &&
HCR_GetDefaultIconW(wszCLSIDValue, szIconFile, cchMax, &icon_idx))
{
*piIndex = icon_idx;
}
else if (SHELL32_GetCustomFolderAttribute(pidl, shellClassInfo, clsid2,
wszCLSIDValue, CHARS_IN_GUID) &&
HCR_GetDefaultIconW(wszCLSIDValue, szIconFile, cchMax, &icon_idx))
{
*piIndex = icon_idx;
}
else
{
static const WCHAR folder[] = { 'F','o','l','d','e','r',0 };
if (!HCR_GetDefaultIconW(folder, szIconFile, cchMax, &icon_idx))
{
lstrcpynW(szIconFile, swShell32Name, cchMax);
icon_idx = -IDI_SHELL_FOLDER;
}
if (uFlags & GIL_OPENICON)
*piIndex = icon_idx<0? icon_idx-1: icon_idx+1;
else
*piIndex = icon_idx;
}
return S_OK;
}
void InitIconOverlays(void)
{
HKEY hKey;
DWORD dwIndex, dwResult, dwSize;
WCHAR szName[MAX_PATH];
WCHAR szValue[100];
CLSID clsid;
IShellIconOverlayIdentifier * Overlay;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers",0, KEY_READ, &hKey) != ERROR_SUCCESS)
return;
if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwResult, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return;
}
Handlers = (IShellIconOverlayIdentifier **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwResult * sizeof(IShellIconOverlayIdentifier*));
if (!Handlers)
{
RegCloseKey(hKey);
return;
}
dwIndex = 0;
CoInitialize(0);
do
{
dwSize = sizeof(szName) / sizeof(WCHAR);
dwResult = RegEnumKeyExW(hKey, dwIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
if (dwResult == ERROR_NO_MORE_ITEMS)
break;
if (dwResult == ERROR_SUCCESS)
{
dwSize = sizeof(szValue) / sizeof(WCHAR);
if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szValue, &dwSize) == ERROR_SUCCESS)
{
CLSIDFromString(szValue, &clsid);
dwResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (LPVOID*)&Overlay);
if (dwResult == S_OK)
{
Handlers[NumIconOverlayHandlers] = Overlay;
NumIconOverlayHandlers++;
}
}
}
dwIndex++;
}while(1);
RegCloseKey(hKey);
}
BOOL
GetIconOverlay(LPCITEMIDLIST pidl, WCHAR * wTemp, int* pIndex)
{
DWORD Index;
HRESULT hResult;
int Priority;
int HighestPriority;
ULONG IconIndex;
ULONG Flags;
WCHAR szPath[MAX_PATH];
if(!SHGetPathFromIDListW(pidl, szPath))
return FALSE;
HighestPriority = 101;
IconIndex = NumIconOverlayHandlers;
for(Index = 0; Index < NumIconOverlayHandlers; Index++)
{
hResult = Handlers[Index]->IsMemberOf(szPath, SFGAO_FILESYSTEM);
if (hResult == S_OK)
{
hResult = Handlers[Index]->GetPriority(&Priority);
if (hResult == S_OK)
{
if (Priority < HighestPriority)
{
HighestPriority = Priority;
IconIndex = Index;
}
}
}
}
if (IconIndex == NumIconOverlayHandlers)
return FALSE;
hResult = Handlers[IconIndex]->GetOverlayInfo(wTemp, MAX_PATH, pIndex, &Flags);
if (hResult == S_OK)
return TRUE;
else
return FALSE;
}
/**************************************************************************
* IExtractIconW_Constructor
*/
IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl)
{
CComPtr<IDefaultExtractIconInit> initIcon;
IExtractIconW *extractIcon;
GUID const * riid;
int icon_idx;
UINT flags;
CHAR sTemp[MAX_PATH];
WCHAR wTemp[MAX_PATH];
LPITEMIDLIST pSimplePidl = ILFindLastID(pidl);
HRESULT hr;
hr = SHCreateDefaultExtractIcon(IID_IDefaultExtractIconInit, (void **)&initIcon);
if (FAILED(hr))
return NULL;
hr = initIcon->QueryInterface(IID_IExtractIconW, (void **)&extractIcon);
if (FAILED(hr))
return NULL;
if (_ILIsDesktop(pSimplePidl))
{
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP);
}
else if ((riid = _ILGetGUIDPointer(pSimplePidl)))
{
/* my computer and other shell extensions */
static const WCHAR fmt[] = { 'C','L','S','I','D','\\',
'{','%','0','8','l','x','-','%','0','4','x','-','%','0','4','x','-',
'%','0','2','x','%','0','2','x','-','%','0','2','x', '%','0','2','x',
'%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0 };
WCHAR xriid[50];
swprintf(xriid, fmt,
riid->Data1, riid->Data2, riid->Data3,
riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
if (HCR_GetDefaultIconW(xriid, wTemp, MAX_PATH, &icon_idx))
{
initIcon->SetNormalIcon(wTemp, icon_idx);
}
else
{
if (IsEqualGUID(*riid, CLSID_MyComputer))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER);
else if (IsEqualGUID(*riid, CLSID_MyDocuments))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS);
else if (IsEqualGUID(*riid, CLSID_NetworkPlaces))
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES);
else
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER);
}
}
else if (_ILIsDrive (pSimplePidl))
{
static const WCHAR drive[] = { 'D','r','i','v','e',0 };
int icon_idx = -1;
if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH))
{
switch(GetDriveTypeA(sTemp))
{
case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_FLOPPY; break;
case DRIVE_CDROM: icon_idx = IDI_SHELL_CDROM; break;
case DRIVE_REMOTE: icon_idx = IDI_SHELL_NETDRIVE; break;
case DRIVE_RAMDISK: icon_idx = IDI_SHELL_RAMDISK; break;
case DRIVE_NO_ROOT_DIR: icon_idx = IDI_SHELL_CDROM; break;
}
}
if (icon_idx != -1)
{
initIcon->SetNormalIcon(swShell32Name, -icon_idx);
}
else
{
if (HCR_GetDefaultIconW(drive, wTemp, MAX_PATH, &icon_idx))
initIcon->SetNormalIcon(wTemp, icon_idx);
else
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE);
}
}
else if (_ILIsFolder (pSimplePidl))
{
if (SUCCEEDED(getIconLocationForFolder(
pidl, 0, wTemp, MAX_PATH,
&icon_idx,
&flags)))
{
initIcon->SetNormalIcon(wTemp, icon_idx);
}
if (SUCCEEDED(getIconLocationForFolder(
pidl, GIL_DEFAULTICON, wTemp, MAX_PATH,
&icon_idx,
&flags)))
{
initIcon->SetDefaultIcon(wTemp, icon_idx);
}
if (SUCCEEDED(getIconLocationForFolder(
pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH,
&icon_idx,
&flags)))
{
initIcon->SetShortcutIcon(wTemp, icon_idx);
}
if (SUCCEEDED(getIconLocationForFolder(
pidl, GIL_OPENICON, wTemp, MAX_PATH,
&icon_idx,
&flags)))
{
initIcon->SetOpenIcon(wTemp, icon_idx);
}
}
else
{
BOOL found = FALSE;
if (_ILIsCPanelStruct(pSimplePidl))
{
if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, wTemp, MAX_PATH, &icon_idx)))
found = TRUE;
}
else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH))
{
if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
&& HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &icon_idx))
{
if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
{
SHGetPathFromIDListW(pidl, wTemp);
icon_idx = 0;
}
else
{
MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH);
}
found = TRUE;
}
else if (!lstrcmpiA(sTemp, "lnkfile"))
{
/* extract icon from shell shortcut */
CComPtr<IShellFolder> dsf;
CComPtr<IShellLinkW> psl;
if (SUCCEEDED(SHGetDesktopFolder(&dsf)))
{
HRESULT hr = dsf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidl, IID_IShellLinkW, NULL, (LPVOID *)&psl);
if (SUCCEEDED(hr))
{
hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx);
if (SUCCEEDED(hr) && *sTemp)
found = TRUE;
}
}
}
}
if (!found)
/* default icon */
initIcon->SetNormalIcon(swShell32Name, 0);
else
initIcon->SetNormalIcon(wTemp, icon_idx);
}
return extractIcon;
}
/**************************************************************************
* IExtractIconA_Constructor
*/
IExtractIconA* IExtractIconA_Constructor(LPCITEMIDLIST pidl)
{
IExtractIconW *extractIconW;
IExtractIconA *extractIconA;
HRESULT hr;
extractIconW = IExtractIconW_Constructor(pidl);
if (!extractIconW)
return NULL;
hr = extractIconW->QueryInterface(IID_IExtractIconA, (void **)&extractIconA);
extractIconW->Release();
if (FAILED(hr))
return NULL;
return extractIconA;
}

View file

@ -0,0 +1,943 @@
/*
* Shell Library Functions
*
* Copyright 2005 Johannes Anderwald
*
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
#define MAX_PROPERTY_SHEET_PAGE 32
typedef struct _LANGANDCODEPAGE_
{
WORD lang;
WORD code;
} LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
static LONG SH_GetAssociatedApplication(WCHAR *fileext, WCHAR *wAssocApp)
{
WCHAR wDataType[MAX_PATH] = {0};
HKEY hkey;
LONG result;
DWORD dwLen = MAX_PATH * sizeof(WCHAR);
wAssocApp[0] = '\0';
RegCreateKeyExW(HKEY_CLASSES_ROOT, fileext, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL);
result = RegQueryValueExW(hkey, L"", NULL, NULL, (LPBYTE)wDataType, &dwLen);
RegCloseKey(hkey);
if (result == ERROR_SUCCESS)
{
wcscat(wDataType, L"\\shell\\open\\command");
dwLen = MAX_PATH * sizeof(WCHAR);
RegCreateKeyExW(HKEY_CLASSES_ROOT, wDataType, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL);
result = (RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)wAssocApp, &dwLen));
RegCloseKey(hkey);
if (result != ERROR_SUCCESS)
{
/* FIXME: Make it return full path instead of
notepad.exe "%1"
%systemroot%\notepad.exe "%1"
etc
Maybe there is code to do that somewhere?
dll\win32\shell32\shlexec.c for example?
*/
wAssocApp[0] = '\0';
}
}
return result;
}
static LONG SH_FileGeneralOpensWith(HWND hwndDlg, WCHAR *fileext)
{
HWND hDlgCtrl;
LONG result;
WCHAR wAppName[MAX_PATH] = {0};
WCHAR wAssocApp[MAX_PATH] = {0};
hDlgCtrl = GetDlgItem(hwndDlg, 14007);
result = SH_GetAssociatedApplication(fileext, wAssocApp);
if (result == ERROR_SUCCESS)
{
_wsplitpath(wAssocApp, NULL, NULL, wAppName, NULL);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wAppName);
}
return result;
}
/*************************************************************************
*
* SH_CreatePropertySheetPage [Internal]
*
* creates a property sheet page from an resource name
*
*/
HPROPSHEETPAGE
SH_CreatePropertySheetPage(LPCSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle)
{
HRSRC hRes;
LPVOID lpsztemplate;
PROPSHEETPAGEW ppage;
if (resname == NULL)
return (HPROPSHEETPAGE)0;
hRes = FindResourceA(shell32_hInstance, resname, (LPSTR)RT_DIALOG);
if (hRes == NULL)
{
ERR("failed to find resource name\n");
return (HPROPSHEETPAGE)0;
}
lpsztemplate = LoadResource(shell32_hInstance, hRes);
if (lpsztemplate == NULL)
return (HPROPSHEETPAGE)0;
memset(&ppage, 0x0, sizeof(PROPSHEETPAGEW));
ppage.dwSize = sizeof(PROPSHEETPAGEW);
ppage.dwFlags = PSP_DLGINDIRECT;
ppage.pResource = (DLGTEMPLATE *)lpsztemplate;
ppage.pfnDlgProc = dlgproc;
ppage.lParam = lParam;
ppage.pszTitle = szTitle;
if (szTitle)
{
ppage.dwFlags |= PSP_USETITLE;
}
return CreatePropertySheetPageW(&ppage);
}
/*************************************************************************
*
* SH_FileGeneralFileType [Internal]
*
* retrieves file extension description from registry and sets it in dialog
*
* TODO: retrieve file extension default icon and load it
* find executable name from registry, retrieve description from executable
*/
BOOL
SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR *filext)
{
WCHAR name[MAX_PATH];
WCHAR value[MAX_PATH];
DWORD lname = MAX_PATH;
DWORD lvalue = MAX_PATH;
HKEY hKey;
LONG result;
HWND hDlgCtrl;
TRACE("fileext %s\n", debugstr_w(filext));
if (filext == NULL)
return FALSE;
hDlgCtrl = GetDlgItem(hwndDlg, 14005);
if (hDlgCtrl == NULL)
return FALSE;
if (RegOpenKeyW(HKEY_CLASSES_ROOT, filext, &hKey) != ERROR_SUCCESS)
{
/* the file extension is unknown, so default to string "FileExtension File" */
SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)value);
swprintf(name, L"%s %s", &filext[1], value);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)name);
return TRUE;
}
result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
RegCloseKey(hKey);
if (result != ERROR_SUCCESS)
return FALSE;
if (RegOpenKeyW(HKEY_CLASSES_ROOT, value, &hKey) == ERROR_SUCCESS)
{
if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", value, MAX_PATH, NULL, 0, NULL) != ERROR_SUCCESS)
{
lvalue = lname = MAX_PATH;
result = RegEnumValueW(hKey, 0, name, &lname, NULL, NULL, (LPBYTE)value, &lvalue);
}
lname = MAX_PATH;
if (RegGetValueW(hKey, L"DefaultIcon", NULL, RRF_RT_REG_SZ, NULL, name, &lname) == ERROR_SUCCESS)
{
UINT IconIndex;
WCHAR szBuffer[MAX_PATH];
WCHAR *Offset;
HICON hIcon = 0;
HRSRC hResource;
LPVOID pResource = NULL;
HGLOBAL hGlobal;
HINSTANCE hLibrary;
Offset = wcsrchr(name, L',');
if (Offset)
{
IconIndex = _wtoi(Offset + 2);
*Offset = L'\0';
name[MAX_PATH - 1] = L'\0';
if (ExpandEnvironmentStringsW(name, szBuffer, MAX_PATH))
{
szBuffer[MAX_PATH - 1] = L'\0';
hLibrary = LoadLibraryExW(szBuffer, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (hLibrary)
{
hResource = FindResourceW(hLibrary, MAKEINTRESOURCEW(IconIndex), (LPCWSTR)RT_ICON);
if (hResource)
{
hGlobal = LoadResource(shell32_hInstance, hResource);
if (hGlobal)
{
pResource = LockResource(hGlobal);
if (pResource != NULL)
{
hIcon = CreateIconFromResource((LPBYTE)pResource, SizeofResource(shell32_hInstance, hResource), TRUE, 0x00030000);
TRACE("hIcon %p,- szBuffer %s IconIndex %u error %u icon %p hResource %p pResource %p\n",
hIcon,
debugstr_w(szBuffer),
IconIndex,
MAKEINTRESOURCEW(IconIndex),
hResource,
pResource);
SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIcon, 0);
}
}
}
FreeLibrary(hLibrary);
}
}
}
}
RegCloseKey(hKey);
}
/* file extension type */
value[MAX_PATH - 1] = L'\0';
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)value);
return TRUE;
}
/*************************************************************************
*
* SHFileGeneralGetFileTimeString [Internal]
*
* formats a given LPFILETIME struct into readable user format
*/
BOOL
SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR *lpResult)
{
FILETIME ft;
SYSTEMTIME dt;
WORD wYear;
static const WCHAR wFormat[] = {
'%', '0', '2', 'd', '/', '%', '0', '2', 'd', '/', '%', '0', '4', 'd',
' ', ' ', '%', '0', '2', 'd', ':', '%', '0', '2', 'u', 0 };
if (lpFileTime == NULL || lpResult == NULL)
return FALSE;
if (!FileTimeToLocalFileTime(lpFileTime, &ft))
return FALSE;
FileTimeToSystemTime(&ft, &dt);
wYear = dt.wYear;
/* ddmmyy */
swprintf(lpResult, wFormat, dt.wDay, dt.wMonth, wYear, dt.wHour, dt.wMinute);
TRACE("result %s\n", debugstr_w(lpResult));
return TRUE;
}
/*************************************************************************
*
* SH_FileGeneralSetText [Internal]
*
* sets file path string and filename string
*
*/
BOOL
SH_FileGeneralSetText(HWND hwndDlg, WCHAR *lpstr)
{
int flength;
int plength;
WCHAR *lpdir;
WCHAR buff[MAX_PATH];
HWND hDlgCtrl;
if (lpstr == NULL)
return FALSE;
lpdir = wcsrchr(lpstr, '\\'); /* find the last occurence of '\\' */
plength = wcslen(lpstr);
flength = wcslen(lpdir);
if (lpdir)
{
/* location text field */
wcsncpy(buff, lpstr, plength - flength);
buff[plength - flength] = UNICODE_NULL;
if (wcslen(buff) == 2)
{
wcscat(buff, L"\\");
}
hDlgCtrl = GetDlgItem(hwndDlg, 14009);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
}
if (flength > 1)
{
/* text filename field */
wcsncpy(buff, &lpdir[1], flength);
hDlgCtrl = GetDlgItem(hwndDlg, 14001);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
}
return TRUE;
}
/*************************************************************************
*
* SH_FileGeneralSetFileSizeTime [Internal]
*
* retrieves file information from file and sets in dialog
*
*/
BOOL
SH_FileGeneralSetFileSizeTime(HWND hwndDlg, WCHAR *lpfilename, PULARGE_INTEGER lpfilesize)
{
BOOL result;
HANDLE hFile;
FILETIME create_time;
FILETIME accessed_time;
FILETIME write_time;
WCHAR resultstr[MAX_PATH];
HWND hDlgCtrl;
LARGE_INTEGER file_size;
if (lpfilename == NULL)
return FALSE;
hFile = CreateFileW(lpfilename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
WARN("failed to open file %s\n", debugstr_w(lpfilename));
return FALSE;
}
result = GetFileTime(hFile, &create_time, &accessed_time, &write_time);
if (!result)
{
WARN("GetFileTime failed\n");
return FALSE;
}
if (SHFileGeneralGetFileTimeString(&create_time, resultstr))
{
hDlgCtrl = GetDlgItem(hwndDlg, 14015);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
}
if (SHFileGeneralGetFileTimeString(&accessed_time, resultstr))
{
hDlgCtrl = GetDlgItem(hwndDlg, 14019);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
}
if (SHFileGeneralGetFileTimeString(&write_time, resultstr))
{
hDlgCtrl = GetDlgItem(hwndDlg, 14017);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
}
if (!GetFileSizeEx(hFile, &file_size))
{
WARN("GetFileSize failed\n");
CloseHandle(hFile);
return FALSE;
}
CloseHandle(hFile);
if (!StrFormatByteSizeW(file_size.QuadPart,
resultstr,
sizeof(resultstr) / sizeof(WCHAR)))
return FALSE;
hDlgCtrl = GetDlgItem(hwndDlg, 14011);
TRACE("result size %u resultstr %s\n", file_size.QuadPart, debugstr_w(resultstr));
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)resultstr);
if (lpfilesize)
lpfilesize->QuadPart = (ULONGLONG)file_size.QuadPart;
return TRUE;
}
/*************************************************************************
*
* SH_SetFileVersionText [Internal]
*
*
*/
BOOL
SH_FileVersionQuerySetText(HWND hwndDlg, DWORD dlgId, LPVOID pInfo, WCHAR *text, WCHAR **resptr)
{
UINT reslen;
HWND hDlgCtrl;
if (hwndDlg == NULL || resptr == NULL || text == NULL)
return FALSE;
if (VerQueryValueW(pInfo, text, (LPVOID *)resptr, &reslen))
{
/* file description property */
hDlgCtrl = GetDlgItem(hwndDlg, dlgId);
TRACE("%s :: %s\n", debugstr_w(text), debugstr_w(*resptr));
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)0, (LPARAM)*resptr);
return TRUE;
}
return FALSE;
}
/*************************************************************************
*
* SH_FileVersionQuerySetListText [Internal]
*
* retrieves a version string and adds it to listbox
*
*/
BOOL
SH_FileVersionQuerySetListText(HWND hwndDlg, LPVOID pInfo, const WCHAR *text, WCHAR **resptr, WORD lang, WORD code)
{
UINT reslen;
HWND hDlgCtrl;
UINT index;
static const WCHAR wFormat[] = {
'\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
'\\', '%', '0', '4', 'x', '%', '0', '4', 'x', '\\', '%', 's', 0 };
WCHAR buff[256];
TRACE("text %s, resptr %p hwndDlg %p\n", debugstr_w(text), resptr, hwndDlg);
if (hwndDlg == NULL || resptr == NULL || text == NULL)
return FALSE;
swprintf(buff, wFormat, lang, code, text);
if (VerQueryValueW(pInfo, buff, (LPVOID *)resptr, &reslen))
{
/* listbox name property */
hDlgCtrl = GetDlgItem(hwndDlg, 14009);
TRACE("%s :: %s\n", debugstr_w(text), debugstr_w(*resptr));
index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)text);
SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)index, (LPARAM)(WCHAR *)*resptr);
return TRUE;
}
return FALSE;
}
/*************************************************************************
*
* SH_FileVersionInitialize [Internal]
*
* sets all file version properties in dialog
*/
BOOL
SH_FileVersionInitialize(HWND hwndDlg, WCHAR *lpfilename)
{
LPVOID pBuf;
DWORD versize;
DWORD handle;
LPVOID info = NULL;
UINT infolen;
WCHAR buff[256];
HWND hDlgCtrl;
WORD lang = 0;
WORD code = 0;
LPLANGANDCODEPAGE lplangcode;
WCHAR *str;
static const WCHAR wVersionFormat[] = {
'%', 'd', '.', '%', 'd', '.', '%', 'd', '.', '%', 'd', 0 };
static const WCHAR wFileDescriptionFormat[] = {
'\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
'\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
'\\', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 0 };
static const WCHAR wLegalCopyrightFormat[] = {
'\\', 'S', 't', 'r', 'i', 'n', 'g', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
'\\', '%', '0', '4', 'x', '%', '0', '4', 'x',
'\\', 'L', 'e', 'g', 'a', 'l', 'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', 0 };
static const WCHAR wTranslation[] = {
'V', 'a', 'r', 'F', 'i', 'l', 'e', 'I', 'n', 'f', 'o',
'\\', 'T', 'r', 'a', 'n', 's', 'l', 'a', 't', 'i', 'o', 'n', 0 };
static const WCHAR wCompanyName[] = {
'C', 'o', 'm', 'p', 'a', 'n', 'y', 'N', 'a', 'm', 'e', 0 };
static const WCHAR wFileVersion[] = {
'F', 'i', 'l', 'e', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
static const WCHAR wInternalName[] = {
'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'N', 'a', 'm', 'e', 0 };
static const WCHAR wOriginalFilename[] = {
'O', 'r', 'i', 'g', 'i', 'n', 'a', 'l', 'F', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 };
static const WCHAR wProductName[] = {
'P', 'r', 'o', 'd', 'u', 'c', 't', 'N', 'a', 'm', 'e', 0 };
static const WCHAR wProductVersion[] = {
'P', 'r', 'o', 'd', 'u', 'c', 't', 'V', 'e', 'r', 's', 'i', 'o', 'n', 0 };
static const WCHAR wSlash[] = { '\\', 0 };
if (lpfilename == 0)
return FALSE;
if (!(versize = GetFileVersionInfoSizeW(lpfilename, &handle)))
{
WARN("GetFileVersionInfoSize failed\n");
return FALSE;
}
if (!(pBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, versize)))
{
WARN("HeapAlloc failed bytes %x\n", versize);
return FALSE;
}
if (!GetFileVersionInfoW(lpfilename, handle, versize, pBuf))
{
HeapFree(GetProcessHeap(), 0, pBuf);
return FALSE;
}
if (VerQueryValueW(pBuf, const_cast<LPWSTR>(wSlash), &info, &infolen))
{
VS_FIXEDFILEINFO *inf = (VS_FIXEDFILEINFO *)info;
swprintf(buff, wVersionFormat, HIWORD(inf->dwFileVersionMS),
LOWORD(inf->dwFileVersionMS),
HIWORD(inf->dwFileVersionLS),
LOWORD(inf->dwFileVersionLS));
hDlgCtrl = GetDlgItem(hwndDlg, 14001);
TRACE("MS %x LS %x res %s \n", inf->dwFileVersionMS, inf->dwFileVersionLS, debugstr_w(buff));
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)buff);
}
if (VerQueryValueW(pBuf, const_cast<LPWSTR>(wTranslation), (LPVOID *)&lplangcode, &infolen))
{
/* FIXME find language from current locale / if not available,
* default to english
* for now default to first available language
*/
lang = lplangcode->lang;
code = lplangcode->code;
}
swprintf(buff, wFileDescriptionFormat, lang, code);
SH_FileVersionQuerySetText(hwndDlg, 14003, pBuf, buff, &str);
swprintf(buff, wLegalCopyrightFormat, lang, code);
SH_FileVersionQuerySetText(hwndDlg, 14005, pBuf, buff, &str);
/* listbox properties */
SH_FileVersionQuerySetListText(hwndDlg, pBuf, wCompanyName, &str, lang, code);
SH_FileVersionQuerySetListText(hwndDlg, pBuf, wFileVersion, &str, lang, code);
SH_FileVersionQuerySetListText(hwndDlg, pBuf, wInternalName, &str, lang, code);
/* FIXME insert language identifier */
SH_FileVersionQuerySetListText(hwndDlg, pBuf, wOriginalFilename, &str, lang, code);
SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductName, &str, lang, code);
SH_FileVersionQuerySetListText(hwndDlg, pBuf, wProductVersion, &str, lang, code);
SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)pBuf);
/* select first item */
hDlgCtrl = GetDlgItem(hwndDlg, 14009);
SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
str = (WCHAR *) SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0, (LPARAM)NULL);
hDlgCtrl = GetDlgItem(hwndDlg, 14010);
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
return TRUE;
}
/*************************************************************************
*
* SH_FileVersionDlgProc
*
* wnd proc of 'Version' property sheet page
*/
INT_PTR
CALLBACK
SH_FileVersionDlgProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LPPROPSHEETPAGE ppsp;
WCHAR *lpstr;
LPVOID buf;
switch (uMsg)
{
case WM_INITDIALOG:
ppsp = (LPPROPSHEETPAGE)lParam;
if (ppsp == NULL)
break;
TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg, lParam, ppsp->lParam);
lpstr = (WCHAR *)ppsp->lParam;
if (lpstr == NULL)
break;
return SH_FileVersionInitialize(hwndDlg, lpstr);
case WM_COMMAND:
if (LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_DBLCLK)
{
HWND hDlgCtrl;
LRESULT lresult;
WCHAR *str;
hDlgCtrl = GetDlgItem(hwndDlg, 14009);
lresult = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL, (LPARAM)NULL);
if (lresult == LB_ERR)
break;
str = (WCHAR *) SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)lresult, (LPARAM)NULL);
if (str == NULL)
break;
hDlgCtrl = GetDlgItem(hwndDlg, 14010);
TRACE("hDlgCtrl %x string %s \n", hDlgCtrl, debugstr_w(str));
SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)str);
return TRUE;
}
break;
case WM_DESTROY:
buf = (LPVOID) GetWindowLongPtr(hwndDlg, DWL_USER);
HeapFree(GetProcessHeap(), 0, buf);
break;
default:
break;
}
return FALSE;
}
/*************************************************************************
*
* SH_FileGeneralDlgProc
*
* wnd proc of 'General' property sheet page
*
*/
INT_PTR
CALLBACK
SH_FileGeneralDlgProc(HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
LPPROPSHEETPAGEW ppsp;
WCHAR *lpstr;
switch (uMsg)
{
case WM_INITDIALOG:
ppsp = (LPPROPSHEETPAGEW)lParam;
if (ppsp == NULL)
break;
TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg, lParam, ppsp->lParam);
lpstr = (WCHAR *)ppsp->lParam;
if (lpstr == NULL)
{
ERR("no filename\n");
break;
}
/* set general text properties filename filelocation and icon */
SH_FileGeneralSetText(hwndDlg, lpstr);
/* enumerate file extension from registry and application which opens it */
SH_FileGeneralSetFileType(hwndDlg, wcsrchr(lpstr, '.'));
/* set opens with */
SH_FileGeneralOpensWith(hwndDlg, wcsrchr(lpstr, '.'));
/* set file time create/modfied/accessed */
SH_FileGeneralSetFileSizeTime(hwndDlg, lpstr, NULL);
return TRUE;
default:
break;
}
return FALSE;
}
BOOL
CALLBACK
AddShellPropSheetExCallback(HPROPSHEETPAGE hPage,
LPARAM lParam)
{
PROPSHEETHEADERW *pinfo = (PROPSHEETHEADERW *)lParam;
if (pinfo->nPages < MAX_PROPERTY_SHEET_PAGE)
{
pinfo->phpage[pinfo->nPages++] = hPage;
return TRUE;
}
return FALSE;
}
int
EnumPropSheetExt(LPWSTR wFileName, PROPSHEETHEADERW *pinfo, int NumPages, HPSXA *hpsxa, IDataObject *pDataObj)
{
WCHAR szName[MAX_PATH] = { 0 };
WCHAR *pOffset;
UINT Length;
DWORD dwName;
int Pages;
CLSID clsid;
pOffset = wcsrchr(wFileName, L'.');
if (!pOffset)
{
Length = wcslen(szName);
if (Length + 6 > sizeof(szName) / sizeof(szName[0]))
return 0;
if (CLSIDFromString(wFileName, &clsid) == NOERROR)
{
wcscpy(szName, L"CLSID\\");
wcscpy(&szName[6], wFileName);
}
else
{
wcscpy(szName, wFileName);
}
}
else
{
Length = wcslen(pOffset);
if (Length >= sizeof(szName) / sizeof(szName[0]))
return 0;
wcscpy(szName, pOffset);
}
TRACE("EnumPropSheetExt szName %s\n", debugstr_w(szName));
hpsxa[0] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, szName, NumPages, pDataObj);
Pages = SHAddFromPropSheetExtArray(hpsxa[0], AddShellPropSheetExCallback, (LPARAM)pinfo);
hpsxa[1] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"*", NumPages-Pages, pDataObj);
Pages += SHAddFromPropSheetExtArray(hpsxa[1], AddShellPropSheetExCallback, (LPARAM)pinfo);
hpsxa[2] = NULL;
if (pOffset)
{
/* try to load property sheet handlers from prog id key */
dwName = sizeof(szName);
if (RegGetValueW(HKEY_CLASSES_ROOT, pOffset, NULL, RRF_RT_REG_SZ, NULL, szName, &dwName) == ERROR_SUCCESS)
{
TRACE("EnumPropSheetExt szName %s, pOffset %s\n", debugstr_w(szName), debugstr_w(pOffset));
szName[(sizeof(szName) / sizeof(WCHAR)) - 1] = L'\0';
hpsxa[2] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, szName, NumPages - Pages, pDataObj);
Pages += SHAddFromPropSheetExtArray(hpsxa[2], AddShellPropSheetExCallback, (LPARAM)pinfo);
}
}
return Pages;
}
/*************************************************************************
*
* SH_ShowPropertiesDialog
*
* called from ShellExecuteExW32
*
* lpf contains (quoted) path of folder/file
*
* TODO: provide button change application type if file has registered type
* make filename field editable and apply changes to filename on close
*/
BOOL
SH_ShowPropertiesDialog(WCHAR *lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl)
{
PROPSHEETHEADERW pinfo;
HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
WCHAR wFileName[MAX_PATH];
DWORD dwHandle = 0;
WCHAR *pFileName;
HPSXA hpsxa[3];
INT_PTR res;
CComPtr<IDataObject> pDataObj;
HRESULT hResult;
TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(lpf));
if (lpf == NULL)
return FALSE;
if (!wcslen(lpf))
return FALSE;
memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
if (lpf[0] == '"')
{
/* remove quotes from lpf */
LPCWSTR src = lpf + 1;
LPWSTR dst = wFileName;
while (*src && *src != '"')
*dst++ = *src++;
*dst = '\0';
}
else
{
wcscpy(wFileName, lpf);
}
if (PathIsDirectoryW(wFileName))
{
return SH_ShowFolderProperties(wFileName, pidlFolder, apidl);
}
if (wcslen(wFileName) == 3)
{
return SH_ShowDriveProperties(wFileName, pidlFolder, apidl);
}
pFileName = wcsrchr(wFileName, '\\');
if (!pFileName)
pFileName = wFileName;
else
pFileName++;
memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
pinfo.dwSize = sizeof(PROPSHEETHEADERW);
pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
pinfo.phpage = hppages;
pinfo.pszCaption = pFileName;
hppages[pinfo.nPages] =
SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",
SH_FileGeneralDlgProc,
(LPARAM)wFileName,
NULL);
if (hppages[pinfo.nPages])
pinfo.nPages++;
hResult = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj);
if (hResult == S_OK)
{
if (!EnumPropSheetExt(wFileName, &pinfo, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj))
{
hpsxa[0] = NULL;
hpsxa[1] = NULL;
hpsxa[2] = NULL;
}
}
if (GetFileVersionInfoSizeW(lpf, &dwHandle))
{
hppages[pinfo.nPages] =
SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",
SH_FileVersionDlgProc,
(LPARAM)wFileName,
NULL);
if (hppages[pinfo.nPages])
pinfo.nPages++;
}
res = PropertySheetW(&pinfo);
if (hResult == S_OK)
{
SHDestroyPropSheetExtArray(hpsxa[0]);
SHDestroyPropSheetExtArray(hpsxa[1]);
SHDestroyPropSheetExtArray(hpsxa[2]);
}
return (res != -1);
}
/*EOF */

View file

@ -45,7 +45,9 @@ IDI_SHELL_FIND_IN_FILE ICON "res/icons/134.ico"
IDI_SHELL_OPEN_WITH ICON "res/icons/135.ico"
IDI_SHELL_CONTROL_PANEL3 ICON "res/icons/137.ico"
IDI_SHELL_PRINTER2 ICON "res/icons/138.ico"
/* TODO: 139.ico, 140.ico, 141.ico, 142.ico, 143.ico, 144,ico, 145.ico, 146.ico, 147.ico, 148.ico */
/* TODO: 139.ico, 140.ico, 141.ico */
IDI_SHELL_TRASH_FILE ICON "res/icons/33.ico" //142
/* TODO 143.ico, 144,ico, 145.ico, 146.ico, 147.ico, 148.ico */
IDI_SHELL_INF_FILE ICON "res/icons/151.ico"
IDI_SHELL_TEXT_FILE ICON "res/icons/152.ico"
IDI_SHELL_BAT_FILE ICON "res/icons/153.ico"

View file

@ -0,0 +1,936 @@
/*
* shell icon cache (SIC)
*
* Copyright 1998, 1999 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/********************** THE ICON CACHE ********************************/
#define INVALID_INDEX -1
typedef struct
{
LPWSTR sSourceFile; /* file (not path!) containing the icon */
DWORD dwSourceIndex; /* index within the file, if it is a resoure ID it will be negated */
DWORD dwListIndex; /* index within the iconlist */
DWORD dwFlags; /* GIL_* flags */
DWORD dwAccessTime;
} SIC_ENTRY, * LPSIC_ENTRY;
static HDPA sic_hdpa = 0;
namespace
{
extern CRITICAL_SECTION SHELL32_SicCS;
CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &SHELL32_SicCS,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": SHELL32_SicCS") }
};
CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
}
/*****************************************************************************
* SIC_CompareEntries
*
* NOTES
* Callback for DPA_Search
*/
static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
{ LPSIC_ENTRY e1 = (LPSIC_ENTRY)p1, e2 = (LPSIC_ENTRY)p2;
TRACE("%p %p %8lx\n", p1, p2, lparam);
/* Icons in the cache are keyed by the name of the file they are
* loaded from, their resource index and the fact if they have a shortcut
* icon overlay or not.
*/
if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the faster one */
(e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT))
return 1;
if (wcsicmp(e1->sSourceFile,e2->sSourceFile))
return 1;
return 0;
}
/* declare SIC_LoadOverlayIcon() */
static int SIC_LoadOverlayIcon(int icon_idx);
/*****************************************************************************
* SIC_OverlayShortcutImage [internal]
*
* NOTES
* Creates a new icon as a copy of the passed-in icon, overlayed with a
* shortcut image.
*/
static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
HICON ShortcutIcon, TargetIcon;
BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
HDC SourceDC = NULL,
ShortcutDC = NULL,
TargetDC = NULL,
ScreenDC = NULL;
HBITMAP OldSourceBitmap = NULL,
OldShortcutBitmap = NULL,
OldTargetBitmap = NULL;
static int s_imgListIdx = -1;
/* Get information about the source icon and shortcut overlay */
if (! GetIconInfo(SourceIcon, &SourceIconInfo)
|| 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
{
return NULL;
}
/* search for the shortcut icon only once */
if (s_imgListIdx == -1)
s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT);
/* FIXME should use icon index 29 instead of the
resource id, but not all icons are present yet
so we can't use icon indices */
if (s_imgListIdx != -1)
{
if (large)
ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT);
else
ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT);
} else
ShortcutIcon = NULL;
if (NULL == ShortcutIcon
|| ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
|| 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
{
return NULL;
}
TargetIconInfo = SourceIconInfo;
TargetIconInfo.hbmMask = NULL;
TargetIconInfo.hbmColor = NULL;
/* Setup the source, shortcut and target masks */
SourceDC = CreateCompatibleDC(NULL);
if (NULL == SourceDC) goto fail;
OldSourceBitmap = (HBITMAP)SelectObject(SourceDC, SourceIconInfo.hbmMask);
if (NULL == OldSourceBitmap) goto fail;
ShortcutDC = CreateCompatibleDC(NULL);
if (NULL == ShortcutDC) goto fail;
OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
if (NULL == OldShortcutBitmap) goto fail;
TargetDC = CreateCompatibleDC(NULL);
if (NULL == TargetDC) goto fail;
TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC, SourceBitmapInfo.bmWidth,
SourceBitmapInfo.bmHeight);
if (NULL == TargetIconInfo.hbmMask) goto fail;
ScreenDC = GetDC(NULL);
if (NULL == ScreenDC) goto fail;
TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC, SourceBitmapInfo.bmWidth,
SourceBitmapInfo.bmHeight);
ReleaseDC(NULL, ScreenDC);
if (NULL == TargetIconInfo.hbmColor) goto fail;
OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask);
if (NULL == OldTargetBitmap) goto fail;
/* Create the target mask by ANDing the source and shortcut masks */
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
SourceDC, 0, 0, SRCCOPY) ||
! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
ShortcutDC, 0, 0, SRCAND))
{
goto fail;
}
/* Setup the source and target xor bitmap */
if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) ||
NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
{
goto fail;
}
/* Copy the source color bitmap to the target */
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
SourceDC, 0, 0, SRCCOPY)) goto fail;
/* Copy the source xor bitmap to the target and clear out part of it by using
the shortcut mask */
if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
MAKEROP4(0xAA0000, SRCCOPY)))
{
goto fail;
}
/* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
handles to NULL */
SelectObject(TargetDC, OldTargetBitmap);
DeleteObject(TargetDC);
SelectObject(ShortcutDC, OldShortcutBitmap);
DeleteObject(ShortcutDC);
SelectObject(SourceDC, OldSourceBitmap);
DeleteObject(SourceDC);
/* Create the icon using the bitmaps prepared earlier */
TargetIcon = CreateIconIndirect(&TargetIconInfo);
/* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
DeleteObject(TargetIconInfo.hbmColor);
DeleteObject(TargetIconInfo.hbmMask);
return TargetIcon;
fail:
/* Clean up scratch resources we created */
if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap);
if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
if (NULL != TargetDC) DeleteObject(TargetDC);
if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
if (NULL != ShortcutDC) DeleteObject(ShortcutDC);
if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap);
if (NULL != SourceDC) DeleteObject(SourceDC);
return NULL;
}
/*****************************************************************************
* SIC_IconAppend [internal]
*
* NOTES
* appends an icon pair to the end of the cache
*/
static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
{ LPSIC_ENTRY lpsice;
INT ret, index, index1;
WCHAR path[MAX_PATH];
TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon);
lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
lpsice->sSourceFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, (wcslen(path)+1)*sizeof(WCHAR) );
wcscpy( lpsice->sSourceFile, path );
lpsice->dwSourceIndex = dwSourceIndex;
lpsice->dwFlags = dwFlags;
EnterCriticalSection(&SHELL32_SicCS);
index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice);
if ( INVALID_INDEX == index )
{
HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile);
SHFree(lpsice);
ret = INVALID_INDEX;
}
else
{
index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
if (index!=index1)
{
FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
}
lpsice->dwListIndex = index;
ret = lpsice->dwListIndex;
}
LeaveCriticalSection(&SHELL32_SicCS);
return ret;
}
/****************************************************************************
* SIC_LoadIcon [internal]
*
* NOTES
* gets small/big icon by number from a file
*/
static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
{ HICON hiconLarge=0;
HICON hiconSmall=0;
HICON hiconLargeShortcut;
HICON hiconSmallShortcut;
#if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
if (!PrivateExtractIconExW) {
HMODULE hUser32 = GetModuleHandleA("user32");
PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
}
if (PrivateExtractIconExW)
PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1);
else
#endif
{
PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0);
PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0);
}
if ( !hiconLarge || !hiconSmall)
{
WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
return -1;
}
if (0 != (dwFlags & GIL_FORSHORTCUT))
{
hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
{
hiconLarge = hiconLargeShortcut;
hiconSmall = hiconSmallShortcut;
}
else
{
WARN("Failed to create shortcut overlayed icons\n");
if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
dwFlags &= ~ GIL_FORSHORTCUT;
}
}
return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
}
/*****************************************************************************
* SIC_GetIconIndex [internal]
*
* Parameters
* sSourceFile [IN] filename of file containing the icon
* index [IN] index/resID (negated) in this file
*
* NOTES
* look in the cache for a proper icon. if not available the icon is taken
* from the file and cached
*/
INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
{
SIC_ENTRY sice;
INT ret, index = INVALID_INDEX;
WCHAR path[MAX_PATH];
TRACE("%s %i\n", debugstr_w(sSourceFile), dwSourceIndex);
GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
sice.sSourceFile = path;
sice.dwSourceIndex = dwSourceIndex;
sice.dwFlags = dwFlags;
EnterCriticalSection(&SHELL32_SicCS);
if (NULL != DPA_GetPtr (sic_hdpa, 0))
{
/* search linear from position 0*/
index = DPA_Search (sic_hdpa, &sice, 0, SIC_CompareEntries, 0, 0);
}
if ( INVALID_INDEX == index )
{
ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
}
else
{
TRACE("-- found\n");
ret = ((LPSIC_ENTRY)DPA_GetPtr(sic_hdpa, index))->dwListIndex;
}
LeaveCriticalSection(&SHELL32_SicCS);
return ret;
}
/*****************************************************************************
* SIC_Initialize [internal]
*/
BOOL SIC_Initialize(void)
{
HICON hSm = NULL, hLg = NULL;
INT cx_small, cy_small;
INT cx_large, cy_large;
HDC hDC;
INT bpp;
DWORD ilMask;
TRACE("Entered SIC_Initialize\n");
if (sic_hdpa)
{
TRACE("Icon cache already initialized\n");
return TRUE;
}
sic_hdpa = DPA_Create(16);
if (!sic_hdpa)
{
return FALSE;
}
hDC = CreateICW(L"DISPLAY", NULL, NULL, NULL);
if (!hDC)
{
ERR("Failed to create information context (error %d)\n", GetLastError());
return FALSE;
}
bpp = GetDeviceCaps(hDC, BITSPIXEL);
ReleaseDC(NULL, hDC);
if (bpp <= 4)
ilMask = ILC_COLOR4;
else if (bpp <= 8)
ilMask = ILC_COLOR8;
else if (bpp <= 16)
ilMask = ILC_COLOR16;
else if (bpp <= 24)
ilMask = ILC_COLOR24;
else if (bpp <= 32)
ilMask = ILC_COLOR32;
else
ilMask = ILC_COLOR;
ilMask |= ILC_MASK;
cx_small = GetSystemMetrics(SM_CXSMICON);
cy_small = GetSystemMetrics(SM_CYSMICON);
cx_large = GetSystemMetrics(SM_CXICON);
cy_large = GetSystemMetrics(SM_CYICON);
ShellSmallIconList = ImageList_Create(cx_small,
cy_small,
ilMask,
100,
100);
ShellBigIconList = ImageList_Create(cx_large,
cy_large,
ilMask,
100,
100);
if (ShellSmallIconList)
{
/* Load the document icon, which is used as the default if an icon isn't found. */
hSm = (HICON)LoadImageW(shell32_hInstance,
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
IMAGE_ICON,
cx_small,
cy_small,
LR_SHARED | LR_DEFAULTCOLOR);
if (!hSm)
{
ERR("Failed to load IDI_SHELL_DOCUMENT icon1!\n");
return FALSE;
}
}
else
{
ERR("Failed to load ShellSmallIconList\n");
return FALSE;
}
if (ShellBigIconList)
{
hLg = (HICON)LoadImageW(shell32_hInstance,
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
IMAGE_ICON,
cx_large,
cy_large,
LR_SHARED | LR_DEFAULTCOLOR);
if (!hLg)
{
ERR("Failed to load IDI_SHELL_DOCUMENT icon2!\n");
DestroyIcon(hSm);
return FALSE;
}
}
else
{
ERR("Failed to load ShellBigIconList\n");
return FALSE;
}
SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0);
SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0);
TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
return TRUE;
}
/*************************************************************************
* SIC_Destroy
*
* frees the cache
*/
static INT CALLBACK sic_free( LPVOID ptr, LPVOID lparam )
{
HeapFree(GetProcessHeap(), 0, ((LPSIC_ENTRY)ptr)->sSourceFile);
SHFree(ptr);
return TRUE;
}
void SIC_Destroy(void)
{
TRACE("\n");
EnterCriticalSection(&SHELL32_SicCS);
if (sic_hdpa) DPA_DestroyCallback(sic_hdpa, sic_free, NULL );
sic_hdpa = NULL;
ImageList_Destroy(ShellSmallIconList);
ShellSmallIconList = 0;
ImageList_Destroy(ShellBigIconList);
ShellBigIconList = 0;
LeaveCriticalSection(&SHELL32_SicCS);
//DeleteCriticalSection(&SHELL32_SicCS); //static
}
/*****************************************************************************
* SIC_LoadOverlayIcon [internal]
*
* Load a shell overlay icon and return its icon cache index.
*/
static int SIC_LoadOverlayIcon(int icon_idx)
{
WCHAR buffer[1024], wszIdx[8];
HKEY hKeyShellIcons;
LPCWSTR iconPath;
int iconIdx;
static const WCHAR wszShellIcons[] = {
'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','I','c','o','n','s',0
};
static const WCHAR wszNumFmt[] = {'%','d',0};
iconPath = swShell32Name; /* default: load icon from shell32.dll */
iconIdx = icon_idx;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS)
{
DWORD count = sizeof(buffer);
swprintf(wszIdx, wszNumFmt, icon_idx);
/* read icon path and index */
if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS)
{
LPWSTR p = wcschr(buffer, ',');
if (p)
*p++ = 0;
iconPath = buffer;
iconIdx = _wtoi(p);
}
RegCloseKey(hKeyShellIcons);
}
return SIC_LoadIcon(iconPath, iconIdx, 0);
}
/*************************************************************************
* Shell_GetImageLists [SHELL32.71]
*
* PARAMETERS
* imglist[1|2] [OUT] pointer which receives imagelist handles
*
*/
BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
{ TRACE("(%p,%p)\n",lpBigList,lpSmallList);
if (lpBigList)
{ *lpBigList = ShellBigIconList;
}
if (lpSmallList)
{ *lpSmallList = ShellSmallIconList;
}
return TRUE;
}
/*************************************************************************
* PidlToSicIndex [INTERNAL]
*
* PARAMETERS
* sh [IN] IShellFolder
* pidl [IN]
* bBigIcon [IN]
* uFlags [IN] GIL_*
* pIndex [OUT] index within the SIC
*
*/
BOOL PidlToSicIndex (
IShellFolder * sh,
LPCITEMIDLIST pidl,
BOOL bBigIcon,
UINT uFlags,
int * pIndex)
{
CComPtr<IExtractIconW> ei;
WCHAR szIconFile[MAX_PATH]; /* file containing the icon */
INT iSourceIndex; /* index or resID(negated) in this file */
BOOL ret = FALSE;
UINT dwFlags = 0;
int iShortcutDefaultIndex = INVALID_INDEX;
TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
if (SUCCEEDED (sh->GetUIObjectOf(0, 1, &pidl, IID_IExtractIconW, 0, (void **)&ei)))
{
if (SUCCEEDED(ei->GetIconLocation(uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
{
*pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
ret = TRUE;
}
}
if (INVALID_INDEX == *pIndex) /* default icon when failed */
{
if (0 == (uFlags & GIL_FORSHORTCUT))
{
*pIndex = 0;
}
else
{
if (INVALID_INDEX == iShortcutDefaultIndex)
{
iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT);
}
*pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0);
}
}
return ret;
}
/*************************************************************************
* SHMapPIDLToSystemImageListIndex [SHELL32.77]
*
* PARAMETERS
* sh [IN] pointer to an instance of IShellFolder
* pidl [IN]
* pIndex [OUT][OPTIONAL] SIC index for big icon
*
*/
int WINAPI SHMapPIDLToSystemImageListIndex(
IShellFolder *sh,
LPCITEMIDLIST pidl,
int *pIndex)
{
int Index;
UINT uGilFlags = 0;
TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex);
pdump(pidl);
if (SHELL_IsShortcut(pidl))
uGilFlags |= GIL_FORSHORTCUT;
if (pIndex)
if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex))
*pIndex = -1;
if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index))
return -1;
return Index;
}
/*************************************************************************
* SHMapIDListToImageListIndexAsync [SHELL32.148]
*/
EXTERN_C HRESULT WINAPI SHMapIDListToImageListIndexAsync(IShellTaskScheduler *pts, IShellFolder *psf,
LPCITEMIDLIST pidl, UINT flags,
PFNASYNCICONTASKBALLBACK pfn, void *pvData, void *pvHint,
int *piIndex, int *piIndexSel)
{
FIXME("(%p, %p, %p, 0x%08x, %p, %p, %p, %p, %p)\n",
pts, psf, pidl, flags, pfn, pvData, pvHint, piIndex, piIndexSel);
return E_FAIL;
}
/*************************************************************************
* Shell_GetCachedImageIndex [SHELL32.72]
*
*/
INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, UINT bSimulateDoc)
{
INT ret, len;
LPWSTR szTemp;
WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_a(szPath), nIndex, bSimulateDoc);
len = MultiByteToWideChar( CP_ACP, 0, szPath, -1, NULL, 0 );
szTemp = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, szPath, -1, szTemp, len );
ret = SIC_GetIconIndex( szTemp, nIndex, 0 );
HeapFree( GetProcessHeap(), 0, szTemp );
return ret;
}
INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, UINT bSimulateDoc)
{
WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc);
return SIC_GetIconIndex(szPath, nIndex, 0);
}
EXTERN_C INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc)
{ if( SHELL_OsIsUnicode())
return Shell_GetCachedImageIndexW((LPCWSTR)szPath, nIndex, bSimulateDoc);
return Shell_GetCachedImageIndexA((LPCSTR)szPath, nIndex, bSimulateDoc);
}
/*************************************************************************
* ExtractIconExW [SHELL32.@]
* RETURNS
* 0 no icon found
* -1 file is not valid
* or number of icons extracted
*/
UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
{
/* get entry point of undocumented function PrivateExtractIconExW() in user32 */
#if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
if (!PrivateExtractIconExW) {
HMODULE hUser32 = GetModuleHandleA("user32");
PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
if (!PrivateExtractIconExW)
return 0;
}
#endif
TRACE("%s %i %p %p %i\n", debugstr_w(lpszFile), nIconIndex, phiconLarge, phiconSmall, nIcons);
return PrivateExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
}
/*************************************************************************
* ExtractIconExA [SHELL32.@]
*/
UINT WINAPI ExtractIconExA(LPCSTR lpszFile, INT nIconIndex, HICON * phiconLarge, HICON * phiconSmall, UINT nIcons)
{
UINT ret = 0;
INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
TRACE("%s %i %p %p %i\n", lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
if (lpwstrFile)
{
MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
ret = ExtractIconExW(lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
HeapFree(GetProcessHeap(), 0, lpwstrFile);
}
return ret;
}
/*************************************************************************
* ExtractAssociatedIconA (SHELL32.@)
*
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIcon)
{
HICON hIcon = NULL;
INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0);
/* Note that we need to allocate MAX_PATH, since we are supposed to fill
* the correct executable if there is no icon in lpIconPath directly.
* lpIconPath itself is supposed to be large enough, so make sure lpIconPathW
* is large enough too. Yes, I am puking too.
*/
LPWSTR lpIconPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon);
if (lpIconPathW)
{
MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, lpIconPathW, len);
hIcon = ExtractAssociatedIconW(hInst, lpIconPathW, lpiIcon);
WideCharToMultiByte(CP_ACP, 0, lpIconPathW, -1, lpIconPath, MAX_PATH , NULL, NULL);
HeapFree(GetProcessHeap(), 0, lpIconPathW);
}
return hIcon;
}
/*************************************************************************
* ExtractAssociatedIconW (SHELL32.@)
*
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
HICON WINAPI ExtractAssociatedIconW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIcon)
{
HICON hIcon = NULL;
WORD wDummyIcon = 0;
TRACE("%p %s %p\n", hInst, debugstr_w(lpIconPath), lpiIcon);
if(lpiIcon == NULL)
lpiIcon = &wDummyIcon;
hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
if( hIcon < (HICON)2 )
{ if( hIcon == (HICON)1 ) /* no icons found in given file */
{ WCHAR tempPath[MAX_PATH];
HINSTANCE uRet = FindExecutableW(lpIconPath,NULL,tempPath);
if( uRet > (HINSTANCE)32 && tempPath[0] )
{ wcscpy(lpIconPath,tempPath);
hIcon = ExtractIconW(hInst, lpIconPath, *lpiIcon);
if( hIcon > (HICON)2 )
return hIcon;
}
}
if( hIcon == (HICON)1 )
*lpiIcon = 2; /* MSDOS icon - we found .exe but no icons in it */
else
*lpiIcon = 6; /* generic icon - found nothing */
if (GetModuleFileNameW(hInst, lpIconPath, MAX_PATH))
hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(*lpiIcon));
}
return hIcon;
}
/*************************************************************************
* ExtractAssociatedIconExW (SHELL32.@)
*
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
EXTERN_C HICON WINAPI ExtractAssociatedIconExW(HINSTANCE hInst, LPWSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
{
FIXME("%p %s %p %p): stub\n", hInst, debugstr_w(lpIconPath), lpiIconIdx, lpiIconId);
return 0;
}
/*************************************************************************
* ExtractAssociatedIconExA (SHELL32.@)
*
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
EXTERN_C HICON WINAPI ExtractAssociatedIconExA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lpiIconIdx, LPWORD lpiIconId)
{
HICON ret;
INT len = MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, NULL, 0 );
LPWSTR lpwstrFile = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
TRACE("%p %s %p %p)\n", hInst, lpIconPath, lpiIconIdx, lpiIconId);
MultiByteToWideChar( CP_ACP, 0, lpIconPath, -1, lpwstrFile, len );
ret = ExtractAssociatedIconExW(hInst, lpwstrFile, lpiIconIdx, lpiIconId);
HeapFree(GetProcessHeap(), 0, lpwstrFile);
return ret;
}
/****************************************************************************
* SHDefExtractIconW [SHELL32.@]
*/
HRESULT WINAPI SHDefExtractIconW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
{
UINT ret;
HICON hIcons[2];
WARN("%s %d 0x%08x %p %p %d, semi-stub\n", debugstr_w(pszIconFile), iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
ret = PrivateExtractIconsW(pszIconFile, iIndex, nIconSize, nIconSize, hIcons, NULL, 2, LR_DEFAULTCOLOR);
/* FIXME: deal with uFlags parameter which contains GIL_ flags */
if (ret == 0xFFFFFFFF)
return E_FAIL;
if (ret > 0) {
if (phiconLarge)
*phiconLarge = hIcons[0];
else
DestroyIcon(hIcons[0]);
if (phiconSmall)
*phiconSmall = hIcons[1];
else
DestroyIcon(hIcons[1]);
return S_OK;
}
return S_FALSE;
}
/****************************************************************************
* SHDefExtractIconA [SHELL32.@]
*/
HRESULT WINAPI SHDefExtractIconA(LPCSTR pszIconFile, int iIndex, UINT uFlags,
HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize)
{
HRESULT ret;
INT len = MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, NULL, 0);
LPWSTR lpwstrFile = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
TRACE("%s %d 0x%08x %p %p %d\n", pszIconFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
MultiByteToWideChar(CP_ACP, 0, pszIconFile, -1, lpwstrFile, len);
ret = SHDefExtractIconW(lpwstrFile, iIndex, uFlags, phiconLarge, phiconSmall, nIconSize);
HeapFree(GetProcessHeap(), 0, lpwstrFile);
return ret;
}
/****************************************************************************
* SHGetIconOverlayIndexA [SHELL32.@]
*
* Returns the index of the overlay icon in the system image list.
*/
EXTERN_C INT WINAPI SHGetIconOverlayIndexA(LPCSTR pszIconPath, INT iIconIndex)
{
FIXME("%s, %d\n", debugstr_a(pszIconPath), iIconIndex);
return -1;
}
/****************************************************************************
* SHGetIconOverlayIndexW [SHELL32.@]
*
* Returns the index of the overlay icon in the system image list.
*/
EXTERN_C INT WINAPI SHGetIconOverlayIndexW(LPCWSTR pszIconPath, INT iIconIndex)
{
FIXME("%s, %d\n", debugstr_w(pszIconPath), iIconIndex);
return -1;
}

View file

@ -55,7 +55,7 @@ BEGIN
MENUITEM "Aktualisieren", FCIDM_SHVIEW_REFRESH
MENUITEM SEPARATOR
MENUITEM "Einfügen", FCIDM_SHVIEW_INSERT
MENUITEM "Verknüpfung einfügen", FCIDM_SHVIEW_INSERTLINK
MENUITEM "Einfügen als Verweis", FCIDM_SHVIEW_INSERTLINK
MENUITEM SEPARATOR
MENUITEM "&Eigenschaften", FCIDM_SHVIEW_PROPERTIES
END
@ -719,7 +719,7 @@ BEGIN
IDS_SHELL_ABOUT_BACK "< &Zurück"
FCIDM_SHVIEW_NEW "Neu"
FCIDM_SHVIEW_NEWFOLDER "Neues Ver&zeichnis"
FCIDM_SHVIEW_NEWLINK "Neue &Verknüpfung"
FCIDM_SHVIEW_NEWLINK "Neuer Ver&weis"
IDS_FOLDER_OPTIONS "Ordneroptionen"
IDS_RECYCLEBIN_LOCATION "Papierkorbpfad"
IDS_RECYCLEBIN_DISKSPACE "freier Speicher"

View file

View file

View file

View file

File diff suppressed because it is too large Load diff

View file

@ -163,7 +163,7 @@ typedef struct tagFileStruct
WORD uFileDate; /*06*/
WORD uFileTime; /*08*/
WORD uFileAttribs; /*10*/
CHAR szNames[1]; /*12*/
CHAR szNames[0]; /*12*/
/* Here are coming two strings. The first is the long name.
The second the dos name when needed or just 0x00 */
} FileStruct;
@ -179,7 +179,7 @@ typedef struct tagFileStructW {
WORD uLastAccessDate;
WORD uLastAccessTime;
BYTE dummy2[4];
WCHAR wszName[1];
WCHAR wszName[0];
} FileStructW;
typedef struct tagValueW

View file

@ -12,12 +12,8 @@
#include <malloc.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define WIN32_NO_STATUS
#define NTOS_MODE_USER
#define UNICODE
#define _UNICODE
#include <windows.h>
@ -44,11 +40,16 @@
#include <ntquery.h>
#include <recyclebin.h>
#include <shtypes.h>
#include <ndk/umtypes.h>
#include <ndk/rtlfuncs.h>
#include <fmifs/fmifs.h>
#include <largeint.h>
#include <sddl.h>
#include <tchar.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include "base/shell/explorer-new/todo.h"
#include "dlgs.h"
#include "pidl.h"
@ -64,6 +65,24 @@
#include "xdg.h"
#include "shellapi.h"
#include "shfldr_fs.h"
#include "shfldr_mycomp.h"
#include "shfldr_desktop.h"
#include "shellitem.h"
#include "shelllink.h"
#include "dragdrophelper.h"
#include "shfldr_cpanel.h"
#include "autocomplete.h"
#include "shfldr_mydocuments.h"
#include "shfldr_netplaces.h"
#include "shfldr_fonts.h"
#include "shfldr_printers.h"
#include "shfldr_admintools.h"
#include "shfldr_recyclebin.h"
#include "she_ocmenu.h"
#include "shv_item_new.h"
#include "startmenu.h"
#include "wine/debug.h"
#include "wine/unicode.h"

View file

@ -0,0 +1,798 @@
/*
* self-registerable dll functions for shell32.dll
*
* Copyright (C) 2003 John K. Hohm
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/*
* Near the bottom of this file are the exported DllRegisterServer and
* DllUnregisterServer, which make all this worthwhile.
*/
/***********************************************************************
* interface for self-registering
*/
struct regsvr_interface
{
IID const *iid; /* NULL for end of list */
LPCSTR name; /* can be NULL to omit */
IID const *base_iid; /* can be NULL to omit */
int num_methods; /* can be <0 to omit */
CLSID const *ps_clsid; /* can be NULL to omit */
CLSID const *ps_clsid32; /* can be NULL to omit */
};
static HRESULT register_interfaces(struct regsvr_interface const *list);
static HRESULT unregister_interfaces(struct regsvr_interface const *list);
struct regsvr_coclass
{
CLSID const *clsid; /* NULL for end of list */
LPCSTR name; /* can be NULL to omit */
UINT idName; /* can be 0 to omit */
LPCSTR ips; /* can be NULL to omit */
LPCSTR ips32; /* can be NULL to omit */
LPCSTR ips32_tmodel; /* can be NULL to omit */
DWORD flags;
DWORD dwAttributes;
DWORD dwCallForAttributes;
LPCSTR clsid_str; /* can be NULL to omit */
LPCSTR progid; /* can be NULL to omit */
UINT idDefaultIcon; /* can be 0 to omit */
// CLSID const *clsid_menu; /* can be NULL to omit */
};
/* flags for regsvr_coclass.flags */
#define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001
#define SHELLFOLDER_WANTSFORPARSING 0x00000002
#define SHELLFOLDER_ATTRIBUTES 0x00000004
#define SHELLFOLDER_CALLFORATTRIBUTES 0x00000008
#define SHELLFOLDER_WANTSFORDISPLAY 0x00000010
#define SHELLFOLDER_HIDEASDELETEPERUSER 0x00000020
static HRESULT register_coclasses(struct regsvr_coclass const *list);
static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
struct regsvr_namespace
{
CLSID const *clsid; /* CLSID of the namespace extension. NULL for end of list */
LPCWSTR parent; /* Mount point (MyComputer, Desktop, ..). */
LPCWSTR value; /* Display name of the extension. */
};
static HRESULT register_namespace_extensions(struct regsvr_namespace const *list);
static HRESULT unregister_namespace_extensions(struct regsvr_namespace const *list);
/***********************************************************************
* static helper functions
*/
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
WCHAR const *value);
static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
char const *value);
/***********************************************************************
* register_interfaces
*/
static HRESULT register_interfaces(struct regsvr_interface const *list)
{
LONG res = ERROR_SUCCESS;
HKEY interface_key;
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, L"Interface", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->iid; ++list) {
WCHAR buf[39];
HKEY iid_key;
StringFromGUID2(*list->iid, buf, 39);
res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_interface_key;
if (list->name) {
res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
(CONST BYTE*)(list->name),
strlen(list->name) + 1);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
if (list->base_iid) {
res = register_key_guid(iid_key, L"BaseInterface", list->base_iid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
if (0 <= list->num_methods) {
static WCHAR const fmt[3] = { '%', 'd', 0 };
HKEY key;
res = RegCreateKeyExW(iid_key, L"NumMethods", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &key, NULL);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
swprintf(buf, fmt, list->num_methods);
res = RegSetValueExW(key, NULL, 0, REG_SZ,
(CONST BYTE*)buf,
(wcslen(buf) + 1) * sizeof(WCHAR));
RegCloseKey(key);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
if (list->ps_clsid) {
res = register_key_guid(iid_key, L"ProxyStubClsid", list->ps_clsid);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
if (list->ps_clsid32) {
res = register_key_guid(iid_key, L"ProxyStubClsid32", list->ps_clsid32);
if (res != ERROR_SUCCESS) goto error_close_iid_key;
}
error_close_iid_key:
RegCloseKey(iid_key);
}
error_close_interface_key:
RegCloseKey(interface_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* unregister_interfaces
*/
static HRESULT unregister_interfaces(struct regsvr_interface const *list)
{
LONG res = ERROR_SUCCESS;
HKEY interface_key;
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface", 0,
KEY_READ | KEY_WRITE, &interface_key);
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->iid; ++list) {
WCHAR buf[39];
StringFromGUID2(*list->iid, buf, 39);
res = RegDeleteTreeW(interface_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
}
RegCloseKey(interface_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* register_coclasses
*/
static HRESULT register_coclasses(struct regsvr_coclass const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
WCHAR buf[39];
HKEY clsid_key;
StringFromGUID2(*list->clsid, buf, 39);
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
if (list->name) {
res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
(CONST BYTE*)(list->name),
strlen(list->name) + 1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->idName) {
char buffer[64];
sprintf(buffer, "@shell32.dll,-%u", list->idName);
res = RegSetValueExA(clsid_key, "LocalizedString", 0, REG_SZ,
(CONST BYTE*)(buffer), strlen(buffer)+1);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->idDefaultIcon) {
HKEY icon_key;
char buffer[64];
res = RegCreateKeyExW(clsid_key, L"DefaultIcon", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &icon_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
sprintf(buffer, "shell32.dll,-%u", list->idDefaultIcon);
res = RegSetValueExA(icon_key, NULL, 0, REG_SZ,
(CONST BYTE*)(buffer), strlen(buffer)+1);
RegCloseKey(icon_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->ips) {
res = register_key_defvalueA(clsid_key, L"InProcServer", list->ips);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->ips32) {
HKEY ips32_key;
res = RegCreateKeyExW(clsid_key, L"InProcServer32", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&ips32_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
(CONST BYTE*)list->ips32,
lstrlenA(list->ips32) + 1);
if (res == ERROR_SUCCESS && list->ips32_tmodel)
res = RegSetValueExA(ips32_key, "ThreadingModel", 0, REG_SZ,
(CONST BYTE*)list->ips32_tmodel,
strlen(list->ips32_tmodel) + 1);
RegCloseKey(ips32_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->flags & SHELLEX_MAYCHANGEDEFAULTMENU) {
HKEY shellex_key, mcdm_key;
res = RegCreateKeyExW(clsid_key, L"shellex", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&shellex_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = RegCreateKeyExW(shellex_key, L"MayChangeDefaultMenu", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&mcdm_key, NULL);
RegCloseKey(shellex_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
RegCloseKey(mcdm_key);
}
if (list->flags &
(SHELLFOLDER_WANTSFORPARSING|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES|SHELLFOLDER_WANTSFORDISPLAY|SHELLFOLDER_HIDEASDELETEPERUSER))
{
HKEY shellfolder_key;
res = RegCreateKeyExW(clsid_key, L"ShellFolder", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&shellfolder_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
if (list->flags & SHELLFOLDER_WANTSFORPARSING)
res = RegSetValueExA(shellfolder_key, "WantsFORPARSING", 0, REG_SZ, (const BYTE *)"", 1);
if (list->flags & SHELLFOLDER_ATTRIBUTES)
res = RegSetValueExA(shellfolder_key, "Attributes", 0, REG_DWORD,
(const BYTE *)&list->dwAttributes, sizeof(DWORD));
if (list->flags & SHELLFOLDER_CALLFORATTRIBUTES)
res = RegSetValueExA(shellfolder_key, "CallForAttributes", 0, REG_DWORD,
(const BYTE *)&list->dwCallForAttributes, sizeof(DWORD));
if (list->flags & SHELLFOLDER_WANTSFORDISPLAY)
res = RegSetValueExA(shellfolder_key, "WantsFORDISPLAY", 0, REG_SZ, (const BYTE *)"", 1);
if (list->flags & SHELLFOLDER_HIDEASDELETEPERUSER)
res = RegSetValueExA(shellfolder_key, "HideAsDeletePerUser", 0, REG_SZ, (const BYTE *)"", 1);
RegCloseKey(shellfolder_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->clsid_str) {
res = register_key_defvalueA(clsid_key, L"CLSID",
list->clsid_str);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (list->progid) {
HKEY progid_key;
res = register_key_defvalueA(clsid_key, L"ProgID",
list->progid);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0,
NULL, 0, KEY_READ | KEY_WRITE, NULL,
&progid_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = register_key_defvalueW(progid_key, L"CLSID", buf);
RegCloseKey(progid_key);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
}
if (IsEqualIID(list->clsid, CLSID_RecycleBin)) {//if (list->clsid_menu) {
HKEY shellex_key, cmenu_key, menuhandler_key;
res = RegCreateKeyExW(clsid_key, L"shellex", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&shellex_key, NULL);
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
res = RegCreateKeyExW(shellex_key, L"ContextMenuHandlers", 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&cmenu_key, NULL);
if (res != ERROR_SUCCESS) {
RegCloseKey(shellex_key);
goto error_close_clsid_key;
}
StringFromGUID2(*list->clsid, buf, 39); //clsid_menu
res = RegCreateKeyExW(cmenu_key, buf, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL,
&menuhandler_key, NULL);
RegCloseKey(menuhandler_key);
RegCloseKey(cmenu_key);
RegCloseKey(shellex_key);
}
error_close_clsid_key:
RegCloseKey(clsid_key);
}
error_close_coclass_key:
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/***********************************************************************
* unregister_coclasses
*/
static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
{
LONG res = ERROR_SUCCESS;
HKEY coclass_key;
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0,
KEY_READ | KEY_WRITE, &coclass_key);
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
if (res != ERROR_SUCCESS) goto error_return;
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
WCHAR buf[39];
StringFromGUID2(*list->clsid, buf, 39);
res = RegDeleteTreeW(coclass_key, buf);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
if (list->progid) {
res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
}
}
error_close_coclass_key:
RegCloseKey(coclass_key);
error_return:
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
}
/**********************************************************************
* register_namespace_extensions
*/
static WCHAR *get_namespace_key(struct regsvr_namespace const *list) {
static const WCHAR wszExplorerKey[] = {
'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
'E','x','p','l','o','r','e','r','\\',0 };
static const WCHAR wszNamespace[] = { '\\','N','a','m','e','s','p','a','c','e','\\',0 };
WCHAR *pwszKey, *pwszCLSID;
pwszKey = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, sizeof(wszExplorerKey)+sizeof(wszNamespace)+
sizeof(WCHAR)*(wcslen(list->parent)+CHARS_IN_GUID));
if (!pwszKey)
return NULL;
wcscpy(pwszKey, wszExplorerKey);
wcscat(pwszKey, list->parent);
wcscat(pwszKey, wszNamespace);
if (FAILED(StringFromCLSID(*list->clsid, &pwszCLSID))) {
HeapFree(GetProcessHeap(), 0, pwszKey);
return NULL;
}
wcscat(pwszKey, pwszCLSID);
CoTaskMemFree(pwszCLSID);
return pwszKey;
}
static HRESULT register_namespace_extensions(struct regsvr_namespace const *list) {
WCHAR *pwszKey;
HKEY hKey;
for (; list->clsid; list++) {
pwszKey = get_namespace_key(list);
/* Create the key and set the value. */
if (pwszKey && ERROR_SUCCESS ==
RegCreateKeyExW(HKEY_LOCAL_MACHINE, pwszKey, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL))
{
RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE *)list->value, sizeof(WCHAR)*(wcslen(list->value)+1));
RegCloseKey(hKey);
}
HeapFree(GetProcessHeap(), 0, pwszKey);
}
return S_OK;
}
static HRESULT unregister_namespace_extensions(struct regsvr_namespace const *list) {
WCHAR *pwszKey;
for (; list->clsid; list++) {
pwszKey = get_namespace_key(list);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, pwszKey);
HeapFree(GetProcessHeap(), 0, pwszKey);
}
return S_OK;
}
/***********************************************************************
* regsvr_key_guid
*/
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
{
WCHAR buf[39];
StringFromGUID2(*guid, buf, 39);
return register_key_defvalueW(base, name, buf);
}
/***********************************************************************
* regsvr_key_defvalueW
*/
static LONG register_key_defvalueW(
HKEY base,
WCHAR const *name,
WCHAR const *value)
{
LONG res;
HKEY key;
res = RegCreateKeyExW(base, name, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &key, NULL);
if (res != ERROR_SUCCESS) return res;
res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
(wcslen(value) + 1) * sizeof(WCHAR));
RegCloseKey(key);
return res;
}
/***********************************************************************
* regsvr_key_defvalueA
*/
static LONG register_key_defvalueA(
HKEY base,
WCHAR const *name,
char const *value)
{
LONG res;
HKEY key;
res = RegCreateKeyExW(base, name, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &key, NULL);
if (res != ERROR_SUCCESS) return res;
res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
lstrlenA(value) + 1);
RegCloseKey(key);
return res;
}
/***********************************************************************
* coclass list
*/
static GUID const CLSID_Desktop = {
0x00021400, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static GUID const CLSID_Shortcut = {
0x00021401, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
static struct regsvr_coclass const coclass_list[] = {
{
&CLSID_Desktop,
"Desktop",
IDS_DESKTOP,
NULL,
"shell32.dll",
"Apartment"
},
{
&CLSID_ControlPanel,
"Shell Control Panel Folder",
IDS_CONTROLPANEL,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_WANTSFORDISPLAY|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_HIDEASDELETEPERUSER,
SFGAO_FOLDER|SFGAO_HASSUBFOLDER,
0,
NULL,
NULL,
IDI_SHELL_CONTROL_PANEL1
},
{
&CLSID_DragDropHelper,
"Shell Drag and Drop Helper",
0,
NULL,
"shell32.dll",
"Apartment"
},
{
&CLSID_Printers,
"Printers & Fax",
IDS_PRINTERS,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES,
SFGAO_FOLDER,
0,
NULL,
NULL,
IDI_SHELL_PRINTERS_FOLDER
},
{
&CLSID_MyComputer,
"My Computer",
IDS_MYCOMPUTER,
NULL,
"shell32.dll",
"Apartment"
},
{
&CLSID_NetworkPlaces,
"My Network Places",
IDS_NETWORKPLACE,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES,
SFGAO_FOLDER|SFGAO_HASPROPSHEET,
0,
NULL,
NULL,
IDI_SHELL_MY_NETWORK_PLACES
},
{
&CLSID_FontsFolderShortcut,
"Fonts",
IDS_FONTS,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES,
SFGAO_FOLDER,
0,
NULL,
NULL,
IDI_SHELL_FONTS_FOLDER
},
{
&CLSID_AdminFolderShortcut,
"Administrative Tools",
IDS_ADMINISTRATIVETOOLS,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES,
SFGAO_FOLDER,
0,
NULL,
NULL,
IDI_SHELL_ADMINTOOLS //FIXME
},
{
&CLSID_Shortcut,
"Shortcut",
0,
NULL,
"shell32.dll",
"Apartment",
SHELLEX_MAYCHANGEDEFAULTMENU
},
{
&CLSID_AutoComplete,
"AutoComplete",
0,
NULL,
"shell32.dll",
"Apartment",
},
{
&CLSID_FolderShortcut,
"Foldershortcut",
0,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES,
SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_LINK,
SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR
},
{
&CLSID_MyDocuments,
"My Documents",
IDS_PERSONAL,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_WANTSFORPARSING|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES,
SFGAO_FILESYSANCESTOR|SFGAO_FOLDER|SFGAO_HASSUBFOLDER,
SFGAO_FILESYSTEM
},
{
&CLSID_RecycleBin,
"Trash",
IDS_RECYCLEBIN_FOLDER_NAME,
NULL,
"shell32.dll",
"Apartment",
SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES,
SFGAO_FOLDER|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET,
0,
NULL,
NULL,
IDI_SHELL_FULL_RECYCLE_BIN
// &CLSID_RecycleBin
},
{
&CLSID_ShellFSFolder,
"Shell File System Folder",
0,
NULL,
"shell32.dll",
"Apartment"
},
{
&CLSID_ShellFolderViewOC,
"Microsoft Shell Folder View Router",
0,
NULL,
"shell32.dll",
"Apartment"
},
{
&CLSID_StartMenu,
"Start Menu",
0,
NULL,
"shell32.dll",
"Apartment"
},
{
&CLSID_MenuBandSite,
"Menu Site",
0,
NULL,
"shell32.dll",
"Apartment"
},
{ NULL } /* list terminator */
};
/***********************************************************************
* interface list
*/
static struct regsvr_interface const interface_list[] = {
{ NULL } /* list terminator */
};
/***********************************************************************
* namespace extensions list
*/
static const WCHAR wszDesktop[] = { 'D','e','s','k','t','o','p',0 };
static const WCHAR wszSlash[] = { '/', 0 };
static const WCHAR wszMyDocuments[] = { 'M','y',' ','D','o','c','u','m','e','n','t','s', 0 };
static const WCHAR wszRecycleBin[] = { 'T','r','a','s','h', 0 };
static const WCHAR wszMyComputer[] = { 'M','y','C','o','m','p','u','t','e','r',0 };
static const WCHAR wszControlPanel[] = { 'C','o','n','t','r','o','l','P','a','n','e','l',0 };
static const WCHAR wszFolderOptions[] = { 'F','o','l','d','e','r',' ','O','p','t','i','o','n','s',0 };
static const WCHAR wszNethoodFolder[] = { 'N','e','t','h','o','o','d',' ','f','o','l','d','e','r',0};
static const WCHAR wszPrinters[] = { 'P','r','i','n','t','e','r','s',0 };
static const WCHAR wszFonts[] = { 'F','o','n','t','s',0 };
static const WCHAR wszAdminTools[] = { 'A','d','m','i','n','T','o','o','l','s',0 };
static struct regsvr_namespace const namespace_extensions_list[] = {
{
&CLSID_MyDocuments,
L"Desktop",
L"My Documents"
},
{
&CLSID_NetworkPlaces,
L"Desktop",
L"Nethood folder"
},
{
&CLSID_RecycleBin,
L"Desktop",
L"Trash"
},
{
&CLSID_ControlPanel,
L"MyComputer",
L"ControlPanel"
},
{
&CLSID_FolderOptions,
L"ControlPanel"
L"Folder Options"
},
{
&CLSID_FontsFolderShortcut,
L"ControlPanel"
L"Fonts"
},
{
&CLSID_Printers,
L"ControlPanel"
L"Printers"
},
{
&CLSID_AdminFolderShortcut,
L"ControlPanel"
L"AdminTools"
},
{ NULL }
};
/***********************************************************************
* DllRegisterServer (SHELL32.@)
*/
EXTERN_C HRESULT WINAPI DllRegisterServer(void)
{
HRESULT hr;
TRACE("\n");
hr = register_coclasses(coclass_list);
if (SUCCEEDED(hr))
hr = register_interfaces(interface_list);
if (SUCCEEDED(hr))
hr = SHELL_RegisterShellFolders();
if (SUCCEEDED(hr))
hr = register_namespace_extensions(namespace_extensions_list);
return hr;
}
/***********************************************************************
* DllUnregisterServer (SHELL32.@)
*/
EXTERN_C HRESULT WINAPI DllUnregisterServer(void)
{
HRESULT hr;
TRACE("\n");
hr = unregister_coclasses(coclass_list);
if (SUCCEEDED(hr))
hr = unregister_interfaces(interface_list);
if (SUCCEEDED(hr))
hr = unregister_namespace_extensions(namespace_extensions_list);
return hr;
}

View file

@ -0,0 +1,56 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {D20EA4E1-3957-11d2-A40B-0C5020524153} = s 'Administrative Tools'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '5'
val InfoTip = s '@%SystemRoot%\system32\SHELL32.dll,-22921'
val LocalizedString = s '@%SystemRoot%\system32\SHELL32.dll,-22982'
DefaultIcon = s '%SystemRoot%\system32\main.cpl,10'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
Instance
{
val CLSID = s '{0AFACED1-E828-11D1-9187-B532F1E9575D}'
InitPropertyBag
{
val Attributes = s '0x00000011'
val TargetSpecialFolder = s '0x002f'
}
}
'ShellFolder'
{
val Attributes = d '&H60000100'
val WantsFORPARSING = s ''
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
ControlPanel
{
NameSpace
{
'{D20EA4E1-3957-11d2-A40B-0C5020524153}' = s 'Administrative Tools'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {00BB2763-6A77-11D0-A535-00C04FD7D062} = s 'Shell ReactOS AutoComplete'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,52 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {21EC2020-3AEA-1069-A2DD-08002B30309D}
{
val InfoTip = s '@%SystemRoot%\system32\SHELL32.dll,-31361'
DefaultIcon = s '%SystemRoot%\System32\shell32.dll,-137'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
ShellFolder
{
val Attributes = d '0'
val HideAsDeletePerUser = s ''
val WantsFORDISPLAY = s ''
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
ControlPanel
{
NameSpace
{
}
}
MyComputer
{
NameSpace
{
Controls = s '{21EC2020-3AEA-1069-A2DD-08002B30309D}'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {4657278A-411B-11d2-839A-00C04FD918D0} = s 'Shell Drag and Drop helper'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,56 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {6DFD7C5C-2451-11d3-A299-00C04F8EF6AF} = s 'Folder Options'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '1'
val InfoTip = s '@%SystemRoot%\system32\SHELL32.dll,-22924'
val LocalizedString = s '@%SystemRoot%\system32\SHELL32.dll,-22985'
DefaultIcon = s '%SystemRoot%\system32\SHELL32.dll,-210'
Shell
{
Open
{
Command = s 'rundll32.exe shell32.dll,Options_RunDLL 0'
}
RunAs
{
Command = s 'rundll32.exe shell32.dll,Options_RunDLL 0'
{
val Extended = s ''
}
}
}
ShellFolder
{
val Attributes = d '0'
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
Desktop
{
NameSpace
{
'{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}' = s 'Folder Options'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,23 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {0AFACED1-E828-11D1-9187-B532F1E9575D} = s 'Folder Shortcut'
{
val Details = s 'prop:Name;LinkTarget'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'shellex'
{
IconHandler = s '{0AFACED1-E828-11D1-9187-B532F1E9575D}'
}
'ShellFolder'
{
val Attributes = d '&H60410137'
val CallForAttributes = d '&Hf0000000'
}
}
}
}

View file

@ -0,0 +1,56 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {D20EA4E1-3957-11d2-A40B-0C5020524152} = s 'Fonts'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '&Hffffffff'
val InfoTip = s '@%SystemRoot%\system32\SHELL32.dll,-22920'
val LocalizedString = s '@%SystemRoot%\system32\SHELL32.dll,-22981'
DefaultIcon = s '%SystemRoot%\system32\main.cpl,9'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
Instance
{
val CLSID = s '{0AFACED1-E828-11D1-9187-B532F1E9575D}'
InitPropertyBag
{
val Attributes = s '0x00000015'
val TargetSpecialFolder = s '0x0014'
}
}
'ShellFolder'
{
val Attributes = d '&H60000100'
val WantsFORPARSING = s ''
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
ControlPanel
{
NameSpace
{
'{D20EA4E1-3957-11d2-A40B-0C5020524152}' = s 'Fonts'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {E13EF4E4-D2F2-11d0-9816-00C04FD91972} = s 'Menu Site'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,63 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {20D04FE0-3AEA-1069-A2D8-08002B30309D} = s 'My Computer'
{
val 'InfoTip' = s '@%SystemRoot%\system32\SHELL32.dll,-22913'
val 'IntroText' = s '@%SystemRoot%\system32\SHELL32.dll,-31751'
val 'LocalizedString' = s '@%SystemRoot%\system32\SHELL32.dll,-9216'
DefaultIcon = s '%SystemRoot%\Explorer.exe,0'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'HideOnDesktopPerUser' = s ''
}
'shell'
{
'find' = s '@%SystemRoot%\system32\SHELL32.dll,-8503'
{
val 'SuppressionPolicy' = d '&H00000080'
'command' = s '%SystemRoot%\Explorer.exe'
'ddeexec' = s '[FindFolder("%l", %I)]'
{
'application' = s 'Folders'
'topic' = s 'AppProperties'
}
}
'Manage'
{
'command' = s '%windir%\system32\mmc.exe /s %windir%\system32\compmgmt.msc'
val 'SuppressionPolicy' = d '&H4000003c'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
MyComputer
{
NameSpace
{
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,67 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {450D8FBA-AD25-11D0-98A8-0800361B1103}
{
val 'InfoTip' = s '@%SystemRoot%\system32\SHELL32.dll,-22914'
val 'SortOrderIndex' = d '&H00000048'
val 'LocalizedString' = s '@%SystemRoot%\system32\SHELL32.dll,-9227'
DefaultIcon = s '%SystemRoot%\system32\SHELL32.dll,-235'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
val LoadWithoutCOM = s ''
}
'ShellFolder'
{
val 'Attributes' = d '&Hf080013d'
val 'CallForAttributes' = d '&H00020040'
val 'HideOnDesktopPerUser' = s ''
val 'QueryForOverlay' = s ''
val 'WantsFORPARSING' = s ''
}
'shell'
{
'find' = s '@%SystemRoot%\system32\SHELL32.dll,-29188'
{
val 'SuppressionPolicy' = d '&H00000080'
'command' = s '%SystemRoot%\Explorer.exe'
'ddeexec' = s '[FindFolder("%l", %I)]'
{
'application' = s 'Folders'
'topic' = s 'AppProperties'
}
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
Desktop
{
NameSpace
{
'{450D8FBA-AD25-11D0-98A8-0800361B1103}'
{
val 'Removal Message' = s '@mydocs.dll,-900'
}
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,58 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {208D2C60-3AEA-1069-A2D7-08002B30309D} = s 'My Network Places'
{
val 'InfoTip' = s '@%SystemRoot%\system32\SHELL32.dll,-22912'
val 'IntroText' = s '@%SystemRoot%\system32\SHELL32.dll,-31749'
val 'LocalizedString' = s '@%SystemRoot%\system32\SHELL32.dll,-9217'
DefaultIcon = s '%SystemRoot%\system32\SHELL32.dll,17'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'HideOnDesktopPerUser' = s ''
}
'shell'
{
'find' = s '@%SystemRoot%\system32\SHELL32.dll,-29188'
{
val 'SuppressionPolicy' = d '&H00000080'
'command' = s '%SystemRoot%\Explorer.exe'
'ddeexec' = s '[FindFolder("%l", %I)]'
{
'application' = s 'Folders'
'topic' = s 'AppProperties'
}
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NetworkNeighborhood
{
NameSpace
{
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,14 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {D969A300-E7FF-11d0-A93B-00A0C90F2719} = s 'ReactOS New Object Service'
{
val flags = d '0'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,53 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {2227A280-3AEA-1069-A2DE-08002B30309D} = s 'Printers and Faxes'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '2'
val 'InfoTip' = s '@%SystemRoot%\system32\SHELL32.dll,-12696'
val 'IntroText' = s '@%SystemRoot%\system32\SHELL32.dll,-31757'
val 'LocalizedString' = s '@%SystemRoot%\system32\SHELL32.dll,-9319'
DefaultIcon = s '%SystemRoot%\System32\shell32.dll,-138'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'Attributes' = d '&H20000004'
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
Desktop
{
NameSpace
{
Printers = s '{2227A280-3AEA-1069-A2DE-08002B30309D}'
{
val 'IconIndex' = d '&H0000012C'
val 'Info' = s 'Adds, removes and changes settings for printers.'
val 'Module' = s '%SystemRoot%\system32\main.cpl'
val 'Name' = s 'Printers and Faxes'
}
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,59 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {645FF040-5081-101B-9F08-00AA002F954E}
{
val 'InfoTip' = s '@%SystemRoot%\system32\SHELL32.dll,-22915'
val 'IntroText' = d '@%SystemRoot%\system32\SHELL32.dll,-31748'
val 'LocalizedString' = s '@%SystemRoot%\system32\SHELL32.dll,-8964'
DefaultIcon = s '%SystemRoot%\System32\shell32.dll,31'
{
val Empty = s '%SystemRoot%\System32\shell32.dll,31'
val Full = s '%SystemRoot%\System32\shell32.dll,32'
}
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'Attributes' = b '&H40 &H01 &H00 &H20'
val 'CallForAttributes' = d '&H00000040'
}
'shellex'
{
'find' = s '@%SystemRoot%\system32\SHELL32.dll,-29188'
{
'ContextMenuHandlers'
'PropertySheetHandlers'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
Desktop
{
NameSpace
{
'{645FF040-5081-101B-9F08-00AA002F954E}' = s 'Recycle Bin'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,45 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {00021400-0000-0000-C000-000000000046} = s 'Desktop'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
shellex
{
ExtShellFolderViews
{
{5984FFE0-28D4-11CF-AE66-08002B2E1262}
val PersistMoniker = s 'file://%userappdata%\Microsoft\Internet Explorer\Desktop.htt'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
Desktop
{
NameSpace
{
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {F3364BA0-65B9-11CE-A9BA-00AA004AE837} = s 'Shell File System Folder'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,23 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {00021401-0000-0000-C000-000000000046} = s 'Shortcut'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
PersistentAddinsRegistered
{
{89BCB740-6119-101A-BCB7-00DD010655AF} = s '{00021401-0000-0000-C000-000000000046}'
}
PersistentHandler = s '{00021401-0000-0000-C000-000000000046}'
ProgID = s 'lnkfile'
shellex
{
MayChangeDefaultMenu = s ''
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {4622AD11-FF23-11d0-8D34-00A0C90F2719} = s 'Start Menu'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,56 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {D20EA4E1-3957-11d2-A40B-0C5020524153} = s 'Administrative Tools'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '5'
val InfoTip = e '@%%SystemRoot%%\system32\SHELL32.dll,-22921'
val LocalizedString = e '@%%SystemRoot%%\system32\SHELL32.dll,-22982'
DefaultIcon = e '%%SystemRoot%%\system32\main.cpl,10'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
Instance
{
val CLSID = s '{0AFACED1-E828-11D1-9187-B532F1E9575D}'
InitPropertyBag
{
val Attributes = s '0x00000011'
val TargetSpecialFolder = s '0x002f'
}
}
'ShellFolder'
{
val Attributes = d '&H60000100'
val WantsFORPARSING = s ''
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove ControlPanel
{
NoRemove NameSpace
{
'{D20EA4E1-3957-11d2-A40B-0C5020524153}' = s 'Administrative Tools'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {00BB2763-6A77-11D0-A535-00C04FD7D062} = s 'Shell ReactOS AutoComplete'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,52 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {21EC2020-3AEA-1069-A2DD-08002B30309D}
{
val InfoTip = e '@%%SystemRoot%%\system32\SHELL32.dll,-31361'
DefaultIcon = e '%%SystemRoot%%\System32\shell32.dll,-137'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
ShellFolder
{
val Attributes = d '0'
val HideAsDeletePerUser = s ''
val WantsFORDISPLAY = s ''
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
ControlPanel
{
NameSpace
{
}
}
NoRemove MyComputer
{
NoRemove NameSpace
{
Controls = s '{21EC2020-3AEA-1069-A2DD-08002B30309D}'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {4657278A-411B-11d2-839A-00C04FD918D0} = s 'Shell Drag and Drop helper'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,56 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {6DFD7C5C-2451-11d3-A299-00C04F8EF6AF} = s 'Folder Options'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '1'
val InfoTip = e '@%%SystemRoot%%\system32\SHELL32.dll,-22924'
val LocalizedString = e '@%%SystemRoot%%\system32\SHELL32.dll,-22985'
DefaultIcon = e '%%SystemRoot%%\system32\SHELL32.dll,-210'
Shell
{
Open
{
Command = s 'rundll32.exe shell32.dll,Options_RunDLL 0'
}
RunAs
{
Command = s 'rundll32.exe shell32.dll,Options_RunDLL 0'
{
val Extended = s ''
}
}
}
ShellFolder
{
val Attributes = d '0'
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove ControlPanel
{
NoRemove NameSpace
{
'{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}' = s 'Folder Options'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,23 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {0AFACED1-E828-11D1-9187-B532F1E9575D} = s 'Folder Shortcut'
{
val Details = s 'prop:Name;LinkTarget'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'shellex'
{
IconHandler = s '{0AFACED1-E828-11D1-9187-B532F1E9575D}'
}
'ShellFolder'
{
val Attributes = d '&H60410137'
val CallForAttributes = d '&Hf0000000'
}
}
}
}

View file

@ -0,0 +1,56 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {D20EA4E1-3957-11d2-A40B-0C5020524152} = s 'Fonts'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '&Hffffffff'
val InfoTip = e '@%%SystemRoot%%\system32\SHELL32.dll,-22920'
val LocalizedString = e '@%%SystemRoot%%\system32\SHELL32.dll,-22981'
DefaultIcon = e '%%SystemRoot%%\system32\main.cpl,9'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
Instance
{
val CLSID = s '{0AFACED1-E828-11D1-9187-B532F1E9575D}'
InitPropertyBag
{
val Attributes = s '0x00000015'
val TargetSpecialFolder = s '0x0014'
}
}
'ShellFolder'
{
val Attributes = d '&H60000100'
val WantsFORPARSING = s ''
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove ControlPanel
{
NoRemove NameSpace
{
'{D20EA4E1-3957-11d2-A40B-0C5020524152}' = s 'Fonts'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {E13EF4E4-D2F2-11d0-9816-00C04FD91972} = s 'Menu Site'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,63 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {20D04FE0-3AEA-1069-A2D8-08002B30309D} = s 'My Computer'
{
val 'InfoTip' = e '@%%SystemRoot%%\system32\SHELL32.dll,-22913'
val 'IntroText' = e '@%%SystemRoot%%\system32\SHELL32.dll,-31751'
val 'LocalizedString' = e '@%%SystemRoot%%\system32\SHELL32.dll,-9216'
DefaultIcon = e '%%SystemRoot%%\Explorer.exe,0'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'HideOnDesktopPerUser' = s ''
}
'shell'
{
'find' = e '@%%SystemRoot%%\system32\SHELL32.dll,-8503'
{
val 'SuppressionPolicy' = d '&H00000080'
'command' = e '%%SystemRoot%%\Explorer.exe'
'ddeexec' = s '[FindFolder("%%l", %%I)]'
{
'application' = s 'Folders'
'topic' = s 'AppProperties'
}
}
'Manage'
{
'command' = e '%%windir%%\system32\mmc.exe /s %%windir%%\system32\compmgmt.msc'
val 'SuppressionPolicy' = d '&H4000003c'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
MyComputer
{
NameSpace
{
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,67 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {450D8FBA-AD25-11D0-98A8-0800361B1103}
{
val 'InfoTip' = e '@%%SystemRoot%%\system32\SHELL32.dll,-22914'
val 'SortOrderIndex' = d '&H00000048'
val 'LocalizedString' = e '@%%SystemRoot%%\system32\SHELL32.dll,-9227'
DefaultIcon = e '%%SystemRoot%%\system32\SHELL32.dll,-235'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
val LoadWithoutCOM = s ''
}
'ShellFolder'
{
val 'Attributes' = d '&Hf080013d'
val 'CallForAttributes' = d '&H00020040'
val 'HideOnDesktopPerUser' = s ''
val 'QueryForOverlay' = s ''
val 'WantsFORPARSING' = s ''
}
'shell'
{
'find' = e '@%%SystemRoot%%\system32\SHELL32.dll,-29188'
{
val 'SuppressionPolicy' = d '&H00000080'
'command' = e '%%SystemRoot%%\Explorer.exe'
'ddeexec' = s '[FindFolder("%%l", %%I)]'
{
'application' = s 'Folders'
'topic' = s 'AppProperties'
}
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove Desktop
{
NoRemove NameSpace
{
'{450D8FBA-AD25-11D0-98A8-0800361B1103}'
{
val 'Removal Message' = s '@mydocs.dll,-900'
}
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,58 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {208D2C60-3AEA-1069-A2D7-08002B30309D} = s 'My Network Places'
{
val 'InfoTip' = e '@%%SystemRoot%%\system32\SHELL32.dll,-22912'
val 'IntroText' = e '@%%SystemRoot%%\system32\SHELL32.dll,-31749'
val 'LocalizedString' = e '@%%SystemRoot%%\system32\SHELL32.dll,-9217'
DefaultIcon = e '%%SystemRoot%%\system32\SHELL32.dll,17'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'HideOnDesktopPerUser' = s ''
}
'shell'
{
'find' = e '@%%SystemRoot%%\system32\SHELL32.dll,-29188'
{
val 'SuppressionPolicy' = d '&H00000080'
'command' = e '%%SystemRoot%%\Explorer.exe'
'ddeexec' = s '[FindFolder("%%l", %%I)]'
{
'application' = s 'Folders'
'topic' = s 'AppProperties'
}
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NetworkNeighborhood
{
NameSpace
{
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,14 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {D969A300-E7FF-11d0-A93B-00A0C90F2719} = s 'ReactOS New Object Service'
{
val flags = d '0'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,53 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {2227A280-3AEA-1069-A2DE-08002B30309D} = s 'Printers and Faxes'
{
val '{305CA226-D286-468e-B848-2B2E8E697B74} 2' = d '2'
val 'InfoTip' = e '@%%SystemRoot%%\system32\SHELL32.dll,-12696'
val 'IntroText' = e '@%%SystemRoot%%\system32\SHELL32.dll,-31757'
val 'LocalizedString' = e '@%%SystemRoot%%\system32\SHELL32.dll,-9319'
DefaultIcon = e '%%SystemRoot%%\System32\shell32.dll,-138'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'Attributes' = d '&H20000004'
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove Desktop
{
NoRemove NameSpace
{
Printers = s '{2227A280-3AEA-1069-A2DE-08002B30309D}'
{
val 'IconIndex' = d '&H0000012C'
val 'Info' = s 'Adds, removes and changes settings for printers.'
val 'Module' = e '%%SystemRoot%%\system32\main.cpl'
val 'Name' = s 'Printers and Faxes'
}
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,59 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {645FF040-5081-101B-9F08-00AA002F954E}
{
val 'InfoTip' = e '@%%SystemRoot%%\system32\SHELL32.dll,-22915'
val 'IntroText' = e '@%%SystemRoot%%\system32\SHELL32.dll,-31748'
val 'LocalizedString' = e '@%%SystemRoot%%\system32\SHELL32.dll,-8964'
DefaultIcon = e '%%SystemRoot%%\System32\shell32.dll,31'
{
val Empty = e '%%SystemRoot%%\System32\shell32.dll,31'
val Full = e '%%SystemRoot%%\System32\shell32.dll,32'
}
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'ShellFolder'
{
val 'Attributes' = b '40010020'
val 'CallForAttributes' = d '&H00000040'
}
'shellex'
{
'find' = e '@%%SystemRoot%%\system32\SHELL32.dll,-29188'
{
'ContextMenuHandlers'
'PropertySheetHandlers'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
NoRemove Desktop
{
NoRemove NameSpace
{
'{645FF040-5081-101B-9F08-00AA002F954E}' = s 'Recycle Bin'
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,45 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {00021400-0000-0000-C000-000000000046} = s 'Desktop'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
shellex
{
ExtShellFolderViews
{
{5984FFE0-28D4-11CF-AE66-08002B2E1262}
val PersistMoniker = s 'file://%%userappdata%%\Microsoft\Internet Explorer\Desktop.htt'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Explorer
{
Desktop
{
NameSpace
{
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {F3364BA0-65B9-11CE-A9BA-00AA004AE837} = s 'Shell File System Folder'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,23 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {00021401-0000-0000-C000-000000000046} = s 'Shortcut'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
PersistentAddinsRegistered
{
{89BCB740-6119-101A-BCB7-00DD010655AF} = s '{00021401-0000-0000-C000-000000000046}'
}
PersistentHandler = s '{00021401-0000-0000-C000-000000000046}'
ProgID = s 'lnkfile'
shellex
{
MayChangeDefaultMenu = s ''
}
}
}
}

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {4622AD11-FF23-11d0-8D34-00A0C90F2719} = s 'Start Menu'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,22 @@
/////////////////////////////////////////////////////////////////////////////
//
// REGISTRY
//
IDR_ADMINFOLDERSHORTCUT REGISTRY "res\\rgs\\adminfoldershortcut.rgs"
IDR_AUTOCOMPLETE REGISTRY "res\\rgs\\autocomplete.rgs"
IDR_CONTROLPANEL REGISTRY "res\\rgs\\controlpanel.rgs"
IDR_DRAGDROPHELPER REGISTRY "res\\rgs\\dragdrophelper.rgs"
IDR_FOLDEROPTIONS REGISTRY "res\\rgs\\folderoptions.rgs"
IDR_FOLDERSHORTCUT REGISTRY "res\\rgs\\foldershortcut.rgs"
IDR_FONTSFOLDERSHORTCUT REGISTRY "res\\rgs\\fontsfoldershortcut.rgs"
IDR_MENUBANDSITE REGISTRY "res\\rgs\\menubandsite.rgs"
IDR_MYCOMPUTER REGISTRY "res\\rgs\\mycomputer.rgs"
IDR_MYDOCUMENTS REGISTRY "res\\rgs\\mydocuments.rgs"
IDR_NETWORKPLACES REGISTRY "res\\rgs\\networkplaces.rgs"
IDR_NEWMENU REGISTRY "res\\rgs\\newmenu.rgs"
IDR_PRINTERS REGISTRY "res\\rgs\\printers.rgs"
IDR_RECYCLEBIN REGISTRY "res\\rgs\\recyclebin.rgs"
IDR_SHELLDESKTOP REGISTRY "res\\rgs\\shelldesktop.rgs"
IDR_SHELLFSFOLDER REGISTRY "res\\rgs\\shellfsfolder.rgs"
IDR_SHELLLINK REGISTRY "res\\rgs\\shelllink.rgs"
IDR_STARTMENU REGISTRY "res\\rgs\\startmenu.rgs"

View file

@ -0,0 +1,73 @@
/*
* Copyright 2004 Martin Fuchs
*
* Pass on icon notification messages to the systray implementation
* in the currently running shell.
*
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <precomp.h>
/* copy data structure for tray notifications */
typedef struct TrayNotifyCDS_Dummy {
DWORD cookie;
DWORD notify_code;
DWORD nicon_data[1]; // placeholder for NOTIFYICONDATA structure
} TrayNotifyCDS_Dummy;
/* The only difference between Shell_NotifyIconA and Shell_NotifyIconW is the call to SendMessageA/W. */
static BOOL SHELL_NotifyIcon(DWORD dwMessage, void* pnid, HWND nid_hwnd, int nid_size, BOOL unicode)
{
HWND hwnd;
COPYDATASTRUCT data;
BOOL ret = FALSE;
int len = sizeof(TrayNotifyCDS_Dummy)-sizeof(DWORD)+nid_size;
TrayNotifyCDS_Dummy* pnotify_data = (TrayNotifyCDS_Dummy*) alloca(len);
pnotify_data->cookie = 1;
pnotify_data->notify_code = dwMessage;
memcpy(&pnotify_data->nicon_data, pnid, nid_size);
data.dwData = 1;
data.cbData = len;
data.lpData = pnotify_data;
for(hwnd=0; (hwnd=FindWindowExW(0, hwnd, L"Shell_TrayWnd", NULL)); )
if ((unicode?SendMessageW:SendMessageA)(hwnd, WM_COPYDATA, (WPARAM)nid_hwnd, (LPARAM)&data))
ret = TRUE;
return ret;
}
/*************************************************************************
* Shell_NotifyIcon [SHELL32.296]
* Shell_NotifyIconA [SHELL32.297]
*/
BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
{
return SHELL_NotifyIcon(dwMessage, pnid, pnid->hWnd, pnid->cbSize, FALSE);
}
/*************************************************************************
* Shell_NotifyIconW [SHELL32.298]
*/
BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid)
{
return SHELL_NotifyIcon(dwMessage, pnid, pnid->hWnd, pnid->cbSize, TRUE);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
/*
* Open With Context Menu extension
*
* Copyright 2007 Johannes Anderwald <janderwald@reactos.org>
* Copyright 2009 Andrew Hill
*
* 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
*/
#ifndef _SHE_OCMENU_H_
#define _SHE_OCMENU_H_
class COpenWithMenu :
public CComCoClass<COpenWithMenu, &CLSID_OpenWithMenu>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IContextMenu2,
public IShellExtInit
{
private:
LONG wId;
BOOL NoOpen;
UINT count;
WCHAR szPath[MAX_PATH];
HMENU hSubMenu;
public:
COpenWithMenu();
~COpenWithMenu();
HRESULT SHEOW_LoadOpenWithItems(IDataObject *pdtobj);
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand,UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
// IContextMenu2
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
// IShellExtInit
virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
DECLARE_NO_REGISTRY()
DECLARE_NOT_AGGREGATABLE(COpenWithMenu)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(COpenWithMenu)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
END_COM_MAP()
};
#endif // _SHE_OCMENU_H_

View file

@ -0,0 +1,21 @@
/*
* Shell Library Functions
*
* Copyright 1998 Marcus Meissner
* Copyright 2000 Juergen Schmied
* Copyright 2002 Eric Pouech
*
* 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
*/

View file

@ -1,13 +1,15 @@
<group>
<module name="shell32" type="win32dll" baseaddress="${BASEADDRESS_SHELL32}" installbase="system32" installname="shell32.dll" crt="msvcrt">
<module name="shell32" type="win32dll" baseaddress="${BASEADDRESS_SHELL32}" installbase="system32" installname="shell32.dll" allowwarnings="true" crt="msvcrt">
<autoregister infsection="OleControlDlls" type="Both" />
<importlibrary definition="shell32.spec" />
<include base="shell32">.</include>
<include base="recyclebin">.</include>
<include base="ReactOS">include/reactos/wine</include>
<define name="_SHELL32_" />
<include base="atlnew">.</include>
<define name="_SHELL32_" />
<define name="COM_NO_WINDOWS_H" />
<define name="_WINE" />
<define name="UNICODE" />
<define name="_UNICODE" />
<redefine name="_WIN32_WINNT">0x600</redefine>
<library>wine</library>
<library>uuid</library>
@ -24,60 +26,61 @@
<library>devmgr</library>
<library>winspool</library>
<library>winmm</library>
<library>msvcrt</library>
<library>atlnew</library>
<pch>precomp.h</pch>
<file>authors.c</file>
<file>autocomplete.c</file>
<file>brsfolder.c</file>
<file>changenotify.c</file>
<file>classes.c</file>
<file>clipboard.c</file>
<file>control.c</file>
<file>dataobject.c</file>
<file>dde.c</file>
<file>debughlp.c</file>
<file>desktop.c</file>
<file>dialogs.c</file>
<file>dragdrophelper.c</file>
<file>enumidlist.c</file>
<file>extracticon.c</file>
<file>folders.c</file>
<file>iconcache.c</file>
<file>pidl.c</file>
<file>regsvr.c</file>
<file>shell32_main.c</file>
<file>shellitem.c</file>
<file>shelllink.c</file>
<file>shellole.c</file>
<file>shellord.c</file>
<file>shellpath.c</file>
<file>shellreg.c</file>
<file>shellstring.c</file>
<file>shfldr_desktop.c</file>
<file>shfldr_fs.c</file>
<file>shfldr_mycomp.c</file>
<file>shfldr_mydocuments.c</file>
<file>shfldr_printers.c</file>
<file>shfldr_admintools.c</file>
<file>shfldr_netplaces.c</file>
<file>shfldr_fonts.c</file>
<file>shfldr_cpanel.c</file>
<file>shfldr_recyclebin.c</file>
<file>shlexec.c</file>
<file>shlfileop.c</file>
<file>shlfolder.c</file>
<file>shlfsbind.c</file>
<file>shlmenu.c</file>
<file>shlview.c</file>
<file>shpolicy.c</file>
<file>shv_def_cmenu.c</file>
<file>startmenu.c</file>
<file>stubs.c</file>
<file>ros-systray.c</file>
<file>fprop.c</file>
<file>drive.c</file>
<file>she_ocmenu.c</file>
<file>shv_item_new.c</file>
<file>folder_options.c</file>
<file>authors.cpp</file>
<file>autocomplete.cpp</file>
<file>brsfolder.cpp</file>
<file>changenotify.cpp</file>
<file>classes.cpp</file>
<file>clipboard.cpp</file>
<file>control.cpp</file>
<file>dataobject.cpp</file>
<file>dde.cpp</file>
<file>debughlp.cpp</file>
<file>desktop.cpp</file>
<file>dialogs.cpp</file>
<file>dragdrophelper.cpp</file>
<file>enumidlist.cpp</file>
<file>extracticon.cpp</file>
<file>folders.cpp</file>
<file>iconcache.cpp</file>
<file>pidl.cpp</file>
<file>shell32_main.cpp</file>
<file>shellitem.cpp</file>
<file>shelllink.cpp</file>
<file>shellole.cpp</file>
<file>shellord.cpp</file>
<file>shellpath.cpp</file>
<file>shellreg.cpp</file>
<file>shellstring.cpp</file>
<file>shfldr_desktop.cpp</file>
<file>shfldr_fs.cpp</file>
<file>shfldr_mycomp.cpp</file>
<file>shfldr_mydocuments.cpp</file>
<file>shfldr_printers.cpp</file>
<file>shfldr_admintools.cpp</file>
<file>shfldr_netplaces.cpp</file>
<file>shfldr_fonts.cpp</file>
<file>shfldr_cpanel.cpp</file>
<file>shfldr_recyclebin.cpp</file>
<file>shlexec.cpp</file>
<file>shlfileop.cpp</file>
<file>shlfolder.cpp</file>
<file>shlfsbind.cpp</file>
<file>shlmenu.cpp</file>
<file>shlview.cpp</file>
<file>shpolicy.cpp</file>
<file>shv_def_cmenu.cpp</file>
<file>startmenu.cpp</file>
<file>stubs.cpp</file>
<file>ros-systray.cpp</file>
<file>fprop.cpp</file>
<file>drive.cpp</file>
<file>she_ocmenu.cpp</file>
<file>shv_item_new.cpp</file>
<file>folder_options.cpp</file>
<file>shell32.rc</file>
</module>
<module name="shobjidl_local_interface" type="idlinterface">

View file

@ -0,0 +1,90 @@
<group>
<module name="shell32" type="win32dll" baseaddress="${BASEADDRESS_SHELL32}" installbase="system32" installname="shell32.dll" crt="msvcrt">
<autoregister infsection="OleControlDlls" type="Both" />
<importlibrary definition="shell32.spec" />
<include base="shell32">.</include>
<include base="recyclebin">.</include>
<include base="ReactOS">include/reactos/wine</include>
<include base="atlnew">.</include>
<define name="_SHELL32_" />
<define name="COM_NO_WINDOWS_H" />
<define name="_WINE" />
<define name="UNICODE" />
<define name="_UNICODE" />
<redefine name="_WIN32_WINNT">0x600</redefine>
<library>wine</library>
<library>uuid</library>
<library>recyclebin</library>
<library>ntdll</library>
<library>advapi32</library>
<library>gdi32</library>
<library>user32</library>
<library>comctl32</library>
<library>comdlg32</library>
<library>shlwapi</library>
<library>ole32</library>
<library>version</library>
<library>devmgr</library>
<library>winspool</library>
<library>winmm</library>
<library>msvcrt</library>
<library>atlnew</library>
<pch>precomp.h</pch>
<file>authors.cpp</file>
<file>autocomplete.cpp</file>
<file>brsfolder.cpp</file>
<file>changenotify.cpp</file>
<file>classes.cpp</file>
<file>clipboard.cpp</file>
<file>control.cpp</file>
<file>dataobject.cpp</file>
<file>dde.cpp</file>
<file>debughlp.cpp</file>
<file>desktop.cpp</file>
<file>dialogs.cpp</file>
<file>dragdrophelper.cpp</file>
<file>enumidlist.cpp</file>
<file>extracticon.cpp</file>
<file>folders.cpp</file>
<file>iconcache.cpp</file>
<file>pidl.cpp</file>
<file>shell32_main.cpp</file>
<file>shellitem.cpp</file>
<file>shelllink.cpp</file>
<file>shellole.cpp</file>
<file>shellord.cpp</file>
<file>shellpath.cpp</file>
<file>shellreg.cpp</file>
<file>shellstring.cpp</file>
<file>shfldr_desktop.cpp</file>
<file>shfldr_fs.cpp</file>
<file>shfldr_mycomp.cpp</file>
<file>shfldr_mydocuments.cpp</file>
<file>shfldr_printers.cpp</file>
<file>shfldr_admintools.cpp</file>
<file>shfldr_netplaces.cpp</file>
<file>shfldr_fonts.cpp</file>
<file>shfldr_cpanel.cpp</file>
<file>shfldr_recyclebin.cpp</file>
<file>shlexec.cpp</file>
<file>shlfileop.cpp</file>
<file>shlfolder.cpp</file>
<file>shlfsbind.cpp</file>
<file>shlmenu.cpp</file>
<file>shlview.cpp</file>
<file>shpolicy.cpp</file>
<file>shv_def_cmenu.cpp</file>
<file>startmenu.cpp</file>
<file>stubs.cpp</file>
<file>ros-systray.cpp</file>
<file>fprop.cpp</file>
<file>drive.cpp</file>
<file>she_ocmenu.cpp</file>
<file>shv_item_new.cpp</file>
<file>folder_options.cpp</file>
<file>shell32.rc</file>
</module>
<module name="shobjidl_local_interface" type="idlinterface">
<file>shobjidl_local.idl</file>
</module>
</group>

View file

@ -39,6 +39,7 @@ END
#include "icon_res.rc"
#include "bitmap_res.rc"
#include "avi_res.rc"
#include "rgs_res.rc"
/*
* Everything specific to any language goes

File diff suppressed because it is too large Load diff

View file

@ -50,7 +50,7 @@ extern HINSTANCE shell32_hInstance;
extern HIMAGELIST ShellSmallIconList;
extern HIMAGELIST ShellBigIconList;
BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList);
extern "C" BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList);
/* Iconcache */
#define INVALID_INDEX -1
@ -81,45 +81,22 @@ DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len);
/****************************************************************************
* Class constructors
*/
LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST myPidl, LPCITEMIDLIST * apidl, UINT cidl);
LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT, const FORMATETC []);
HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidl, UINT cidl, IDataObject **dataObject);
HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **enumerator);
LPCLASSFACTORY IClassFactory_Constructor(REFCLSID);
IContextMenu2 * ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, const LPCITEMIDLIST *aPidls, UINT uItemCount);
HRESULT WINAPI INewItem_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID *ppv);
IContextMenu2 * ISvStaticItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *apidl, UINT cidl, HKEY hKey);
IContextMenu2 * ISvBgCm_Constructor(LPSHELLFOLDER pSFParent, BOOL bDesktop);
LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER);
HRESULT WINAPI IShellView_Constructor(IShellFolder *pFolder, IShellView **newView);
HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IShellItem_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IShellLink_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IShellLink_ConstructFromFile(IUnknown * pUnkOuter, REFIID riid, LPCITEMIDLIST pidl, LPVOID * ppv);
HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI ISF_Printers_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI ISF_MyDocuments_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI ISF_NetworkPlaces_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI ISF_Fonts_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI ISF_AdminTools_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI UnixFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI UnixDosFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI FolderShortcut_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI MyDocuments_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI RecycleBin_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID *ppv);
HRESULT WINAPI SHEOW_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID *ppv);
HRESULT WINAPI ShellFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI StartMenu_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
HRESULT WINAPI MenuBandSite_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
extern HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST, LPWSTR, UINT, int*);
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
HRESULT WINAPI IAutoComplete_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
LPEXTRACTICONA IExtractIconA_Constructor(LPCITEMIDLIST);
LPEXTRACTICONW IExtractIconW_Constructor(LPCITEMIDLIST);
@ -183,29 +160,29 @@ static BOOL __inline SHELL_OsIsUnicode(void)
SHFree(*ptr); \
*ptr = NULL; \
};
static void __inline __SHCloneStrA(char ** target,const char * source)
static void __inline __SHCloneStrA(char **target, const char *source)
{
*target = SHAlloc(strlen(source)+1);
*target = (char *)SHAlloc(strlen(source) + 1);
strcpy(*target, source);
}
static void __inline __SHCloneStrWtoA(char ** target, const WCHAR * source)
static void __inline __SHCloneStrWtoA(char **target, const WCHAR *source)
{
int len = WideCharToMultiByte(CP_ACP, 0, source, -1, NULL, 0, NULL, NULL);
*target = SHAlloc(len);
*target = (char *)SHAlloc(len);
WideCharToMultiByte(CP_ACP, 0, source, -1, *target, len, NULL, NULL);
}
static void __inline __SHCloneStrW(WCHAR ** target, const WCHAR * source)
static void __inline __SHCloneStrW(WCHAR **target, const WCHAR *source)
{
*target = SHAlloc( (lstrlenW(source)+1) * sizeof(WCHAR) );
*target = (WCHAR *)SHAlloc((lstrlenW(source) + 1) * sizeof(WCHAR) );
lstrcpyW(*target, source);
}
static LPWSTR __inline __SHCloneStrAtoW(WCHAR ** target, const char * source)
static LPWSTR __inline __SHCloneStrAtoW(WCHAR **target, const char *source)
{
int len = MultiByteToWideChar(CP_ACP, 0, source, -1, NULL, 0);
*target = SHAlloc(len*sizeof(WCHAR));
*target = (WCHAR *)SHAlloc(len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, source, -1, *target, len);
return *target;
}
@ -235,7 +212,7 @@ BOOL SHELL_IsShortcut(LPCITEMIDLIST);
INT_PTR CALLBACK SH_FileGeneralDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK SH_FileVersionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
HPROPSHEETPAGE SH_CreatePropertySheetPage(LPSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle);
HPROPSHEETPAGE SH_CreatePropertySheetPage(LPCSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle);
BOOL SH_ShowDriveProperties(WCHAR * drive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * apidl);
BOOL SH_ShowRecycleBinProperties(WCHAR sDrive);
BOOL SH_ShowPropertiesDialog(LPWSTR lpf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST * apidl);

View file

@ -0,0 +1,248 @@
/*
* IShellItem implementation
*
* Copyright 2008 Vincent Povirk for CodeWeavers
* Copyright 2009 Andrew Hill
*
* 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 "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
EXTERN_C HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi);
ShellItem::ShellItem()
{
pidl = NULL;
}
ShellItem::~ShellItem()
{
ILFree(pidl);
}
HRESULT ShellItem::get_parent_pidl(LPITEMIDLIST *parent_pidl)
{
*parent_pidl = ILClone(pidl);
if (*parent_pidl)
{
if (ILRemoveLastID(*parent_pidl))
return S_OK;
else
{
ILFree(*parent_pidl);
*parent_pidl = NULL;
return E_INVALIDARG;
}
}
else
{
*parent_pidl = NULL;
return E_OUTOFMEMORY;
}
}
HRESULT ShellItem::get_parent_shellfolder(IShellFolder **ppsf)
{
LPITEMIDLIST parent_pidl;
CComPtr<IShellFolder> desktop;
HRESULT ret;
ret = get_parent_pidl(&parent_pidl);
if (SUCCEEDED(ret))
{
ret = SHGetDesktopFolder(&desktop);
if (SUCCEEDED(ret))
ret = desktop->BindToObject(parent_pidl, NULL, IID_IShellFolder, (void**)ppsf);
ILFree(parent_pidl);
}
return ret;
}
HRESULT WINAPI ShellItem::BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut)
{
FIXME("(%p,%p,%s,%p,%p)\n", this, pbc, shdebugstr_guid(&rbhid), riid, ppvOut);
*ppvOut = NULL;
return E_NOTIMPL;
}
HRESULT WINAPI ShellItem::GetParent(IShellItem **ppsi)
{
LPITEMIDLIST parent_pidl;
HRESULT ret;
TRACE("(%p,%p)\n", this, ppsi);
ret = get_parent_pidl(&parent_pidl);
if (SUCCEEDED(ret))
{
ret = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi);
ILFree(parent_pidl);
}
return ret;
}
HRESULT WINAPI ShellItem::GetDisplayName(SIGDN sigdnName, LPWSTR *ppszName)
{
FIXME("(%p,%x,%p)\n", this, sigdnName, ppszName);
*ppszName = NULL;
return E_NOTIMPL;
}
HRESULT WINAPI ShellItem::GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs)
{
CComPtr<IShellFolder> parent_folder;
LPITEMIDLIST child_pidl;
HRESULT ret;
TRACE("(%p,%x,%p)\n", this, sfgaoMask, psfgaoAttribs);
ret = get_parent_shellfolder(&parent_folder);
if (SUCCEEDED(ret))
{
child_pidl = ILFindLastID(pidl);
*psfgaoAttribs = sfgaoMask;
ret = parent_folder->GetAttributesOf(1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs);
}
return ret;
}
HRESULT WINAPI ShellItem::Compare(IShellItem *oth, SICHINTF hint, int *piOrder)
{
FIXME("(%p,%p,%x,%p)\n", this, oth, hint, piOrder);
return E_NOTIMPL;
}
HRESULT WINAPI ShellItem::GetClassID(CLSID *pClassID)
{
TRACE("(%p,%p)\n", this, pClassID);
*pClassID = CLSID_ShellItem;
return S_OK;
}
HRESULT WINAPI ShellItem::SetIDList(LPCITEMIDLIST pidlx)
{
LPITEMIDLIST new_pidl;
TRACE("(%p,%p)\n", this, pidlx);
new_pidl = ILClone(pidlx);
if (new_pidl)
{
ILFree(pidl);
pidl = new_pidl;
return S_OK;
}
else
return E_OUTOFMEMORY;
}
HRESULT WINAPI ShellItem::GetIDList(LPITEMIDLIST *ppidl)
{
TRACE("(%p,%p)\n", this, ppidl);
*ppidl = ILClone(pidl);
if (*ppidl)
return S_OK;
else
return E_OUTOFMEMORY;
}
HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent,
IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi)
{
IShellItem *newShellItem;
LPITEMIDLIST new_pidl;
CComPtr<IPersistIDList> newPersistIDList;
HRESULT ret;
TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi);
if (!pidl)
{
return E_INVALIDARG;
}
else if (pidlParent || psfParent)
{
LPITEMIDLIST temp_parent=NULL;
if (!pidlParent)
{
CComPtr<IPersistFolder2> ppf2Parent;
if (FAILED(psfParent->QueryInterface(IID_IPersistFolder2, (void**)&ppf2Parent)))
{
FIXME("couldn't get IPersistFolder2 interface of parent\n");
return E_NOINTERFACE;
}
if (FAILED(ppf2Parent->GetCurFolder(&temp_parent)))
{
FIXME("couldn't get parent PIDL\n");
return E_NOINTERFACE;
}
pidlParent = temp_parent;
}
new_pidl = ILCombine(pidlParent, pidl);
ILFree(temp_parent);
if (!new_pidl)
return E_OUTOFMEMORY;
}
else
{
new_pidl = ILClone(pidl);
if (!new_pidl)
return E_OUTOFMEMORY;
}
ret = ShellItem::_CreatorClass::CreateInstance(NULL, IID_IShellItem, (void**)&newShellItem);
if (FAILED(ret))
{
*ppsi = NULL;
ILFree(new_pidl);
return ret;
}
ret = newShellItem->QueryInterface(IID_IPersistIDList, (void **)&newPersistIDList);
if (FAILED(ret))
{
ILFree(new_pidl);
return ret;
}
ret = newPersistIDList->SetIDList(new_pidl);
if (FAILED(ret))
{
ILFree(new_pidl);
return ret;
}
ILFree(new_pidl);
*ppsi = newShellItem;
return ret;
}

View file

@ -0,0 +1,62 @@
/*
* IShellItem implementation
*
* Copyright 2008 Vincent Povirk for CodeWeavers
* Copyright 2009 Andrew Hill
*
* 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
*/
#ifndef _SHELLITEM_H_
#define _SHELLITEM_H_
class ShellItem :
public CComCoClass<ShellItem, &CLSID_ShellItem>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellItem,
public IPersistIDList
{
private:
LPITEMIDLIST pidl;
public:
ShellItem();
~ShellItem();
HRESULT get_parent_pidl(LPITEMIDLIST *parent_pidl);
HRESULT get_parent_shellfolder(IShellFolder **ppsf);
// IShellItem
virtual HRESULT WINAPI BindToHandler(IBindCtx *pbc, REFGUID rbhid, REFIID riid, void **ppvOut);
virtual HRESULT WINAPI GetParent(IShellItem **ppsi);
virtual HRESULT WINAPI GetDisplayName(SIGDN sigdnName, LPWSTR *ppszName);
virtual HRESULT WINAPI GetAttributes(SFGAOF sfgaoMask, SFGAOF *psfgaoAttribs);
virtual HRESULT WINAPI Compare(IShellItem *oth, SICHINTF hint, int *piOrder);
// IPersistIDList
virtual HRESULT WINAPI GetClassID(CLSID *pClassID);
virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl);
DECLARE_NO_REGISTRY()
DECLARE_NOT_AGGREGATABLE(ShellItem)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ShellItem)
COM_INTERFACE_ENTRY_IID(IID_IShellItem, IShellItem)
COM_INTERFACE_ENTRY_IID(IID_IPersistIDList, IPersistIDList)
END_COM_MAP()
};
#endif // _SHELLITEM_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,182 @@
/*
*
* Copyright 1997 Marcus Meissner
* Copyright 1998 Juergen Schmied
* Copyright 2005 Mike McCormack
* Copyright 2009 Andrew Hill
*
* 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
*
*/
#ifndef _SHELLLINK_H_
#define _SHELLLINK_H_
class ShellLink :
public CComCoClass<ShellLink, &CLSID_ShellLink>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellLinkA,
public IShellLinkW,
public IPersistFile,
public IPersistStream,
public IShellLinkDataList,
public IShellExtInit,
public IContextMenu,
public IObjectWithSite,
public IShellPropSheetExt
{
public:
/* link file formats */
#include "pshpack1.h"
struct volume_info
{
DWORD type;
DWORD serial;
WCHAR label[12]; /* assume 8.3 */
};
#include "poppack.h"
private:
/* data structures according to the information in the link */
LPITEMIDLIST pPidl;
WORD wHotKey;
SYSTEMTIME time1;
SYSTEMTIME time2;
SYSTEMTIME time3;
DWORD iShowCmd;
LPWSTR sIcoPath;
INT iIcoNdx;
LPWSTR sPath;
LPWSTR sArgs;
LPWSTR sWorkDir;
LPWSTR sDescription;
LPWSTR sPathRel;
LPWSTR sProduct;
LPWSTR sComponent;
volume_info volume;
LPWSTR sLinkPath;
BOOL bRunAs;
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */
CComPtr<IUnknown> site;
public:
ShellLink();
~ShellLink();
LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str);
HRESULT ShellLink_SetAdvertiseInfo(LPCWSTR str);
static INT_PTR CALLBACK SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
// IPersistFile
virtual HRESULT WINAPI GetClassID(CLSID *pclsid);
virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
// IPersistStream
// virtual WINAPI HRESULT GetClassID(CLSID *pclsid);
// virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(IStream *stm);
virtual HRESULT WINAPI Save(IStream *stm, BOOL fClearDirty);
virtual HRESULT WINAPI GetSizeMax(ULARGE_INTEGER *pcbSize);
// IShellLinkA
virtual HRESULT WINAPI GetPath(LPSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags);
virtual HRESULT WINAPI GetIDList(LPITEMIDLIST * ppidl);
virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetDescription(LPSTR pszName,INT cchMaxName);
virtual HRESULT WINAPI SetDescription(LPCSTR pszName);
virtual HRESULT WINAPI GetWorkingDirectory(LPSTR pszDir,INT cchMaxPath);
virtual HRESULT WINAPI SetWorkingDirectory(LPCSTR pszDir);
virtual HRESULT WINAPI GetArguments(LPSTR pszArgs,INT cchMaxPath);
virtual HRESULT WINAPI SetArguments(LPCSTR pszArgs);
virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
virtual HRESULT WINAPI GetIconLocation(LPSTR pszIconPath,INT cchIconPath,INT *piIcon);
virtual HRESULT WINAPI SetIconLocation(LPCSTR pszIconPath,INT iIcon);
virtual HRESULT WINAPI SetRelativePath(LPCSTR pszPathRel, DWORD dwReserved);
virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
virtual HRESULT WINAPI SetPath(LPCSTR pszFile);
// IShellLinkW
virtual HRESULT WINAPI GetPath(LPWSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags);
// virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl);
// virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetDescription(LPWSTR pszName, INT cchMaxName);
virtual HRESULT WINAPI SetDescription(LPCWSTR pszName);
virtual HRESULT WINAPI GetWorkingDirectory(LPWSTR pszDir, INT cchMaxPath);
virtual HRESULT WINAPI SetWorkingDirectory(LPCWSTR pszDir);
virtual HRESULT WINAPI GetArguments(LPWSTR pszArgs,INT cchMaxPath);
virtual HRESULT WINAPI SetArguments(LPCWSTR pszArgs);
// virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
// virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
// virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
// virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
virtual HRESULT WINAPI GetIconLocation(LPWSTR pszIconPath,INT cchIconPath,INT *piIcon);
virtual HRESULT WINAPI SetIconLocation(LPCWSTR pszIconPath,INT iIcon);
virtual HRESULT WINAPI SetRelativePath(LPCWSTR pszPathRel, DWORD dwReserved);
// virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
virtual HRESULT WINAPI SetPath(LPCWSTR pszFile);
// IShellLinkDataList
virtual HRESULT WINAPI AddDataBlock(void *pDataBlock);
virtual HRESULT WINAPI CopyDataBlock(DWORD dwSig, void **ppDataBlock);
virtual HRESULT WINAPI RemoveDataBlock(DWORD dwSig);
virtual HRESULT WINAPI GetFlags(DWORD *pdwFlags);
virtual HRESULT WINAPI SetFlags(DWORD dwFlags);
// IShellExtInit
virtual HRESULT WINAPI Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
// IShellPropSheetExt
virtual HRESULT WINAPI AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
virtual HRESULT WINAPI ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam);
// IObjectWithSite
virtual HRESULT WINAPI SetSite(IUnknown *punk);
virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLLINK)
DECLARE_NOT_AGGREGATABLE(ShellLink)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ShellLink)
COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
END_COM_MAP()
};
#endif // _SHELLLINK_H_

View file

@ -0,0 +1,582 @@
/*
* handling of SHELL32.DLL OLE-Objects
*
* Copyright 1997 Marcus Meissner
* Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
extern HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
static const WCHAR sShell32[12] = {'S','H','E','L','L','3','2','.','D','L','L','\0'};
/**************************************************************************
* Default ClassFactory types
*/
typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
HRESULT IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, const IID *riidInst, IClassFactory **theFactory);
/* FIXME: this should be SHLWAPI.24 since we can't yet import by ordinal */
DWORD WINAPI __SHGUIDToStringW (REFGUID guid, LPWSTR str)
{
WCHAR sFormat[52] = {'{','%','0','8','l','x','-','%','0','4',
'x','-','%','0','4','x','-','%','0','2',
'x','%','0','2','x','-','%','0','2','x',
'%','0','2','x','%','0','2','x','%','0',
'2','x','%','0','2','x','%','0','2','x',
'}','\0'};
return swprintf ( str, sFormat,
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7] );
}
/*************************************************************************
* SHCoCreateInstance [SHELL32.102]
*
* Equivalent to CoCreateInstance. Under Windows 9x this function could sometimes
* use the shell32 built-in "mini-COM" without the need to load ole32.dll - see
* SHLoadOLE for details.
*
* Under wine if a "LoadWithoutCOM" value is present or the object resides in
* shell32.dll the function will load the object manually without the help of ole32
*
* NOTES
* exported by ordinal
*
* SEE ALSO
* CoCreateInstace, SHLoadOLE
*/
HRESULT WINAPI SHCoCreateInstance(
LPCWSTR aclsid,
const CLSID *clsid,
LPUNKNOWN pUnkOuter,
REFIID refiid,
LPVOID *ppv)
{
DWORD hres;
CLSID iid;
const CLSID * myclsid = clsid;
WCHAR sKeyName[MAX_PATH];
const WCHAR sCLSID[7] = {'C','L','S','I','D','\\','\0'};
WCHAR sClassID[60];
const WCHAR sInProcServer32[16] ={'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'};
const WCHAR sLoadWithoutCOM[15] ={'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'};
WCHAR sDllPath[MAX_PATH];
HKEY hKey;
DWORD dwSize;
BOOLEAN bLoadFromShell32 = FALSE;
BOOLEAN bLoadWithoutCOM = FALSE;
CComPtr<IClassFactory> pcf;
if(!ppv) return E_POINTER;
*ppv=NULL;
/* if the clsid is a string, convert it */
if (!clsid)
{
if (!aclsid) return REGDB_E_CLASSNOTREG;
CLSIDFromString((LPOLESTR)aclsid, &iid);
myclsid = &iid;
}
TRACE("(%p,%s,unk:%p,%s,%p)\n",
aclsid, shdebugstr_guid(myclsid), pUnkOuter, shdebugstr_guid(&refiid), ppv);
/* we look up the dll path in the registry */
__SHGUIDToStringW(*myclsid, sClassID);
wcscpy(sKeyName, sCLSID);
wcscat(sKeyName, sClassID);
wcscat(sKeyName, sInProcServer32);
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey)) {
dwSize = sizeof(sDllPath);
SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize );
/* if a special registry key is set, we load a shell extension without help of OLE32 */
bLoadWithoutCOM = (ERROR_SUCCESS == SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0));
/* if the com object is inside shell32, omit use of ole32 */
bLoadFromShell32 = (0==lstrcmpiW( PathFindFileNameW(sDllPath), sShell32));
RegCloseKey (hKey);
} else {
/* since we can't find it in the registry we try internally */
bLoadFromShell32 = TRUE;
}
TRACE("WithoutCom=%u FromShell=%u\n", bLoadWithoutCOM, bLoadFromShell32);
/* now we create an instance */
if (bLoadFromShell32) {
if (! SUCCEEDED(DllGetClassObject(*myclsid, IID_IClassFactory, (LPVOID*)&pcf))) {
ERR("LoadFromShell failed for CLSID=%s\n", shdebugstr_guid(myclsid));
}
} else if (bLoadWithoutCOM) {
/* load an external dll without ole32 */
HINSTANCE hLibrary;
typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
DllGetClassObjectFunc DllGetClassObject;
if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath));
hres = E_ACCESSDENIED;
goto end;
} else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(sDllPath));
FreeLibrary( hLibrary );
hres = E_ACCESSDENIED;
goto end;
} else if (! SUCCEEDED(hres = DllGetClassObject(*myclsid, IID_IClassFactory, (LPVOID*)&pcf))) {
TRACE("GetClassObject failed 0x%08x\n", hres);
goto end;
}
} else {
/* load an external dll in the usual way */
hres = CoCreateInstance(*myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
goto end;
}
/* here we should have a ClassFactory */
if (!pcf) return E_ACCESSDENIED;
hres = pcf->CreateInstance(pUnkOuter, refiid, ppv);
end:
if(hres!=S_OK)
{
ERR("failed (0x%08x) to create CLSID:%s IID:%s\n",
hres, shdebugstr_guid(myclsid), shdebugstr_guid(&refiid));
ERR("class not found in registry\n");
}
TRACE("-- instance: %p\n",*ppv);
return hres;
}
/*************************************************************************
* SHCLSIDFromString [SHELL32.147]
*
* Under Windows 9x this was an ANSI version of CLSIDFromString. It also allowed
* to avoid dependency on ole32.dll (see SHLoadOLE for details).
*
* Under Windows NT/2000/XP this is equivalent to CLSIDFromString
*
* NOTES
* exported by ordinal
*
* SEE ALSO
* CLSIDFromString, SHLoadOLE
*/
DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id)
{
WCHAR buffer[40];
TRACE("(%p(%s) %p)\n", clsid, clsid, id);
if (!MultiByteToWideChar( CP_ACP, 0, clsid, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
return CO_E_CLASSSTRING;
return CLSIDFromString( buffer, id );
}
DWORD WINAPI SHCLSIDFromStringW (LPCWSTR clsid, CLSID *id)
{
TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
return CLSIDFromString((LPWSTR)clsid, id);
}
EXTERN_C DWORD WINAPI SHCLSIDFromStringAW (LPCVOID clsid, CLSID *id)
{
if (SHELL_OsIsUnicode())
return SHCLSIDFromStringW ((LPCWSTR)clsid, id);
return SHCLSIDFromStringA ((LPCSTR)clsid, id);
}
/*************************************************************************
* SHGetMalloc [SHELL32.@]
*
* Equivalent to CoGetMalloc(MEMCTX_TASK, ...). Under Windows 9x this function
* could use the shell32 built-in "mini-COM" without the need to load ole32.dll -
* see SHLoadOLE for details.
*
* PARAMS
* lpmal [O] Destination for IMalloc interface.
*
* RETURNS
* Success: S_OK. lpmal contains the shells IMalloc interface.
* Failure. An HRESULT error code.
*
* SEE ALSO
* CoGetMalloc, SHLoadOLE
*/
HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal)
{
TRACE("(%p)\n", lpmal);
return CoGetMalloc(MEMCTX_TASK, lpmal);
}
/*************************************************************************
* SHAlloc [SHELL32.196]
*
* Equivalent to CoTaskMemAlloc. Under Windows 9x this function could use
* the shell32 built-in "mini-COM" without the need to load ole32.dll -
* see SHLoadOLE for details.
*
* NOTES
* exported by ordinal
*
* SEE ALSO
* CoTaskMemAlloc, SHLoadOLE
*/
LPVOID WINAPI SHAlloc(DWORD len)
{
LPVOID ret;
ret = CoTaskMemAlloc(len);
TRACE("%u bytes at %p\n",len, ret);
return ret;
}
/*************************************************************************
* SHFree [SHELL32.195]
*
* Equivalent to CoTaskMemFree. Under Windows 9x this function could use
* the shell32 built-in "mini-COM" without the need to load ole32.dll -
* see SHLoadOLE for details.
*
* NOTES
* exported by ordinal
*
* SEE ALSO
* CoTaskMemFree, SHLoadOLE
*/
void WINAPI SHFree(LPVOID pv)
{
TRACE("%p\n",pv);
CoTaskMemFree(pv);
}
/*************************************************************************
* SHGetDesktopFolder [SHELL32.@]
*/
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
{
HRESULT hres = S_OK;
TRACE("\n");
if(!psf) return E_INVALIDARG;
*psf = NULL;
hres = CDesktopFolder::_CreatorClass::CreateInstance(NULL, IID_IShellFolder, (void**)psf);
TRACE("-- %p->(%p)\n",psf, *psf);
return hres;
}
/**************************************************************************
* Default ClassFactory Implementation
*
* SHCreateDefClassObject
*
* NOTES
* Helper function for dlls without their own classfactory.
* A generic classfactory is returned.
* When the CreateInstance of the cf is called the callback is executed.
*/
class IDefClFImpl :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IClassFactory
{
private:
CLSID *rclsid;
LPFNCREATEINSTANCE lpfnCI;
const IID *riidInst;
LONG *pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */
public:
IDefClFImpl();
HRESULT Initialize(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, const IID *riidInstx);
// IClassFactory
virtual HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject);
virtual HRESULT WINAPI LockServer(BOOL fLock);
BEGIN_COM_MAP(IDefClFImpl)
COM_INTERFACE_ENTRY_IID(IID_IClassFactory, IClassFactory)
END_COM_MAP()
};
IDefClFImpl::IDefClFImpl()
{
lpfnCI = NULL;
riidInst = NULL;
pcRefDll = NULL;
rclsid = NULL;
}
HRESULT IDefClFImpl::Initialize(LPFNCREATEINSTANCE lpfnCIx, PLONG pcRefDllx, const IID *riidInstx)
{
lpfnCI = lpfnCIx;
riidInst = riidInstx;
pcRefDll = pcRefDllx;
if (pcRefDll)
InterlockedIncrement(pcRefDll);
TRACE("(%p)%s\n", this, shdebugstr_guid(riidInst));
return S_OK;
}
/******************************************************************************
* IDefClF_fnCreateInstance
*/
HRESULT WINAPI IDefClFImpl::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
{
TRACE("%p->(%p,%s,%p)\n", this, pUnkOuter, shdebugstr_guid(&riid), ppvObject);
*ppvObject = NULL;
if (riidInst == NULL || IsEqualCLSID(riid, *riidInst) || IsEqualCLSID(riid, IID_IUnknown))
{
return lpfnCI(pUnkOuter, riid, ppvObject);
}
ERR("unknown IID requested %s\n", shdebugstr_guid(&riid));
return E_NOINTERFACE;
}
/******************************************************************************
* IDefClF_fnLockServer
*/
HRESULT WINAPI IDefClFImpl::LockServer(BOOL fLock)
{
TRACE("%p->(0x%x), not implemented\n", this, fLock);
return E_NOTIMPL;
}
/**************************************************************************
* IDefClF_fnConstructor
*/
HRESULT IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, const IID *riidInst, IClassFactory **theFactory)
{
CComObject<IDefClFImpl> *theClassObject;
CComPtr<IClassFactory> result;
HRESULT hResult;
if (theFactory == NULL)
return E_POINTER;
*theFactory = NULL;
ATLTRY (theClassObject = new CComObject<IDefClFImpl>);
if (theClassObject == NULL)
return E_OUTOFMEMORY;
hResult = theClassObject->QueryInterface (IID_IClassFactory, (void **)&result);
if (FAILED (hResult))
{
delete theClassObject;
return hResult;
}
hResult = theClassObject->Initialize (lpfnCI, pcRefDll, riidInst);
if (FAILED (hResult))
return hResult;
*theFactory = result.Detach ();
return S_OK;
}
/******************************************************************************
* SHCreateDefClassObject [SHELL32.70]
*/
HRESULT WINAPI SHCreateDefClassObject(
REFIID riid,
LPVOID* ppv,
LPFNCREATEINSTANCE lpfnCI, /* [in] create instance callback entry */
LPDWORD pcRefDll, /* [in/out] ref count of the dll */
REFIID riidInst) /* [in] optional interface to the instance */
{
IClassFactory *pcf;
HRESULT hResult;
TRACE("%s %p %p %p %s\n", shdebugstr_guid(&riid), ppv, lpfnCI, pcRefDll, shdebugstr_guid(&riidInst));
if (!IsEqualCLSID(riid, IID_IClassFactory))
return E_NOINTERFACE;
hResult = IDefClF_fnConstructor(lpfnCI, (PLONG)pcRefDll, &riidInst, &pcf);
if (FAILED(hResult))
return hResult;
*ppv = pcf;
return NOERROR;
}
/*************************************************************************
* DragAcceptFiles [SHELL32.@]
*/
void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
{
LONG exstyle;
if( !IsWindow(hWnd) ) return;
exstyle = GetWindowLongPtrA(hWnd,GWL_EXSTYLE);
if (b)
exstyle |= WS_EX_ACCEPTFILES;
else
exstyle &= ~WS_EX_ACCEPTFILES;
SetWindowLongPtrA(hWnd,GWL_EXSTYLE,exstyle);
}
/*************************************************************************
* DragFinish [SHELL32.@]
*/
void WINAPI DragFinish(HDROP h)
{
TRACE("\n");
GlobalFree((HGLOBAL)h);
}
/*************************************************************************
* DragQueryPoint [SHELL32.@]
*/
BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
{
DROPFILES *lpDropFileStruct;
BOOL bRet;
TRACE("\n");
lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
*p = lpDropFileStruct->pt;
bRet = lpDropFileStruct->fNC;
GlobalUnlock(hDrop);
return bRet;
}
/*************************************************************************
* DragQueryFileA [SHELL32.@]
* DragQueryFile [SHELL32.@]
*/
UINT WINAPI DragQueryFileA(
HDROP hDrop,
UINT lFile,
LPSTR lpszFile,
UINT lLength)
{
LPSTR lpDrop;
UINT i = 0;
DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength);
if(!lpDropFileStruct) goto end;
lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles;
if(lpDropFileStruct->fWide) {
LPWSTR lpszFileW = NULL;
if(lpszFile) {
lpszFileW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, lLength*sizeof(WCHAR));
if(lpszFileW == NULL) {
goto end;
}
}
i = DragQueryFileW(hDrop, lFile, lpszFileW, lLength);
if(lpszFileW) {
WideCharToMultiByte(CP_ACP, 0, lpszFileW, -1, lpszFile, lLength, 0, NULL);
HeapFree(GetProcessHeap(), 0, lpszFileW);
}
goto end;
}
while (i++ < lFile)
{
while (*lpDrop++); /* skip filename */
if (!*lpDrop)
{
i = (lFile == 0xFFFFFFFF) ? i : 0;
goto end;
}
}
i = strlen(lpDrop);
if (!lpszFile ) goto end; /* needed buffer size */
lstrcpynA (lpszFile, lpDrop, lLength);
end:
GlobalUnlock(hDrop);
return i;
}
/*************************************************************************
* DragQueryFileW [SHELL32.@]
*/
UINT WINAPI DragQueryFileW(
HDROP hDrop,
UINT lFile,
LPWSTR lpszwFile,
UINT lLength)
{
LPWSTR lpwDrop;
UINT i = 0;
DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop);
TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength);
if(!lpDropFileStruct) goto end;
lpwDrop = (LPWSTR) ((LPSTR)lpDropFileStruct + lpDropFileStruct->pFiles);
if(lpDropFileStruct->fWide == FALSE) {
LPSTR lpszFileA = NULL;
if(lpszwFile) {
lpszFileA = (LPSTR)HeapAlloc(GetProcessHeap(), 0, lLength);
if(lpszFileA == NULL) {
goto end;
}
}
i = DragQueryFileA(hDrop, lFile, lpszFileA, lLength);
if(lpszFileA) {
MultiByteToWideChar(CP_ACP, 0, lpszFileA, -1, lpszwFile, lLength);
HeapFree(GetProcessHeap(), 0, lpszFileA);
}
goto end;
}
i = 0;
while (i++ < lFile)
{
while (*lpwDrop++); /* skip filename */
if (!*lpwDrop)
{
i = (lFile == 0xFFFFFFFF) ? i : 0;
goto end;
}
}
i = wcslen(lpwDrop);
if ( !lpszwFile) goto end; /* needed buffer size */
lstrcpynW (lpszwFile, lpwDrop, lLength);
end:
GlobalUnlock(hDrop);
return i;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,144 @@
/*
* Shell Registry Access
*
* Copyright 2000 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/*************************************************************************
* SHRegOpenKeyA [SHELL32.506]
*
*/
EXTERN_C HRESULT WINAPI SHRegOpenKeyA(
HKEY hKey,
LPSTR lpSubKey,
PHKEY phkResult)
{
TRACE("(%p, %s, %p)\n", hKey, debugstr_a(lpSubKey), phkResult);
return RegOpenKeyA(hKey, lpSubKey, phkResult);
}
/*************************************************************************
* SHRegOpenKeyW [SHELL32.507] NT 4.0
*
*/
EXTERN_C HRESULT WINAPI SHRegOpenKeyW (
HKEY hkey,
LPCWSTR lpszSubKey,
PHKEY retkey)
{
WARN("%p %s %p\n",hkey,debugstr_w(lpszSubKey),retkey);
return RegOpenKeyW( hkey, lpszSubKey, retkey );
}
/*************************************************************************
* SHRegQueryValueA [SHELL32.508]
*
*/
EXTERN_C HRESULT WINAPI SHRegQueryValueA(HKEY hkey, LPSTR lpSubKey, LPSTR lpValue, LPDWORD lpcbValue)
{
TRACE("(%p %s %p %p)\n", hkey, debugstr_a(lpSubKey), lpValue, lpcbValue);
return RegQueryValueA(hkey, lpSubKey, lpValue, (LONG*)lpcbValue);
}
/*************************************************************************
* SHRegQueryValueExA [SHELL32.509]
*
*/
EXTERN_C HRESULT WINAPI SHRegQueryValueExA(
HKEY hkey,
LPSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData)
{
TRACE("%p %s %p %p %p %p\n", hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
return RegQueryValueExA (hkey, lpValueName, lpReserved, lpType, lpData, lpcbData);
}
/*************************************************************************
* SHRegQueryValueW [SHELL32.510] NT4.0
*
*/
EXTERN_C HRESULT WINAPI SHRegQueryValueW(
HKEY hkey,
LPWSTR lpszSubKey,
LPWSTR lpszData,
LPDWORD lpcbData )
{
WARN("%p %s %p %p semi-stub\n",
hkey, debugstr_w(lpszSubKey), lpszData, lpcbData);
return RegQueryValueW( hkey, lpszSubKey, lpszData, (LONG*)lpcbData );
}
/*************************************************************************
* SHRegQueryValueExW [SHELL32.511] NT4.0
*
* FIXME
* if the datatype REG_EXPAND_SZ then expand the string and change
* *pdwType to REG_SZ.
*/
EXTERN_C HRESULT WINAPI SHRegQueryValueExW (
HKEY hkey,
LPWSTR pszValue,
LPDWORD pdwReserved,
LPDWORD pdwType,
LPVOID pvData,
LPDWORD pcbData)
{
DWORD ret;
WARN("%p %s %p %p %p %p semi-stub\n",
hkey, debugstr_w(pszValue), pdwReserved, pdwType, pvData, pcbData);
ret = RegQueryValueExW ( hkey, pszValue, pdwReserved, pdwType, (LPBYTE)pvData, pcbData);
return ret;
}
/*************************************************************************
* SHRegDeleteKeyA [SHELL32.?]
*/
HRESULT WINAPI SHRegDeleteKeyA(
HKEY hkey,
LPCSTR pszSubKey)
{
FIXME("hkey=%p, %s\n", hkey, debugstr_a(pszSubKey));
return 0;
}
/*************************************************************************
* SHRegDeleteKeyW [SHELL32.512]
*/
EXTERN_C HRESULT WINAPI SHRegDeleteKeyW(
HKEY hkey,
LPCWSTR pszSubKey)
{
FIXME("hkey=%p, %s\n", hkey, debugstr_w(pszSubKey));
return 0;
}
/*************************************************************************
* SHRegCloseKey [SHELL32.505] NT 4.0
*
*/
EXTERN_C HRESULT WINAPI SHRegCloseKey (HKEY hkey)
{
TRACE("%p\n",hkey);
return RegCloseKey( hkey );
}

View file

@ -0,0 +1,264 @@
/*
* Copyright 2000 Juergen Schmied
*
* 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 <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/************************* STRRET functions ****************************/
BOOL WINAPI StrRetToStrNA(LPSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
{
TRACE("dest=%p len=0x%x strret=%p(%s) pidl=%p\n",
dest,len,src,
(src->uType == STRRET_WSTR) ? "STRRET_WSTR" :
(src->uType == STRRET_CSTR) ? "STRRET_CSTR" :
(src->uType == STRRET_OFFSET) ? "STRRET_OFFSET" : "STRRET_???",
pidl);
if (!dest)
return FALSE;
switch (src->uType)
{
case STRRET_WSTR:
WideCharToMultiByte(CP_ACP, 0, src->pOleStr, -1, dest, len, NULL, NULL);
CoTaskMemFree(src->pOleStr);
break;
case STRRET_CSTR:
lstrcpynA(dest, src->cStr, len);
break;
case STRRET_OFFSET:
lstrcpynA(dest, ((LPCSTR)&pidl->mkid)+src->uOffset, len);
break;
default:
FIXME("unknown type!\n");
if (len) *dest = '\0';
return FALSE;
}
TRACE("-- %s\n", debugstr_a(dest) );
return TRUE;
}
/************************************************************************/
BOOL WINAPI StrRetToStrNW(LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
{
TRACE("dest=%p len=0x%x strret=%p(%s) pidl=%p\n",
dest,len,src,
(src->uType == STRRET_WSTR) ? "STRRET_WSTR" :
(src->uType == STRRET_CSTR) ? "STRRET_CSTR" :
(src->uType == STRRET_OFFSET) ? "STRRET_OFFSET" : "STRRET_???",
pidl);
if (!dest)
return FALSE;
switch (src->uType)
{
case STRRET_WSTR:
lstrcpynW(dest, src->pOleStr, len);
CoTaskMemFree(src->pOleStr);
break;
case STRRET_CSTR:
if (!MultiByteToWideChar( CP_ACP, 0, src->cStr, -1, dest, len ) && len)
dest[len-1] = 0;
break;
case STRRET_OFFSET:
if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->uOffset, -1, dest, len ) && len)
dest[len-1] = 0;
break;
default:
FIXME("unknown type!\n");
if (len) *dest = '\0';
return FALSE;
}
return TRUE;
}
/*************************************************************************
* StrRetToStrN [SHELL32.96]
*
* converts a STRRET to a normal string
*
* NOTES
* the pidl is for STRRET OFFSET
*/
EXTERN_C BOOL WINAPI StrRetToStrNAW(LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
{
if(SHELL_OsIsUnicode())
return StrRetToStrNW((LPWSTR)dest, len, src, pidl);
else
return StrRetToStrNA((LPSTR)dest, len, src, pidl);
}
/************************* OLESTR functions ****************************/
/************************************************************************
* StrToOleStr [SHELL32.163]
*
*/
int WINAPI StrToOleStrA (LPWSTR lpWideCharStr, LPCSTR lpMultiByteString)
{
TRACE("(%p, %p %s)\n",
lpWideCharStr, lpMultiByteString, debugstr_a(lpMultiByteString));
return MultiByteToWideChar(0, 0, lpMultiByteString, -1, lpWideCharStr, MAX_PATH);
}
int WINAPI StrToOleStrW (LPWSTR lpWideCharStr, LPCWSTR lpWString)
{
TRACE("(%p, %p %s)\n",
lpWideCharStr, lpWString, debugstr_w(lpWString));
wcscpy (lpWideCharStr, lpWString );
return wcslen(lpWideCharStr);
}
EXTERN_C BOOL WINAPI StrToOleStrAW (LPWSTR lpWideCharStr, LPCVOID lpString)
{
if (SHELL_OsIsUnicode())
return StrToOleStrW (lpWideCharStr, (LPCWSTR)lpString);
return StrToOleStrA (lpWideCharStr, (LPCSTR)lpString);
}
/*************************************************************************
* StrToOleStrN [SHELL32.79]
* lpMulti, nMulti, nWide [IN]
* lpWide [OUT]
*/
BOOL WINAPI StrToOleStrNA (LPWSTR lpWide, INT nWide, LPCSTR lpStrA, INT nStr)
{
TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_an(lpStrA,nStr), nStr);
return MultiByteToWideChar (0, 0, lpStrA, nStr, lpWide, nWide);
}
BOOL WINAPI StrToOleStrNW (LPWSTR lpWide, INT nWide, LPCWSTR lpStrW, INT nStr)
{
TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_wn(lpStrW, nStr), nStr);
if (lstrcpynW (lpWide, lpStrW, nWide))
{ return wcslen (lpWide);
}
return 0;
}
EXTERN_C BOOL WINAPI StrToOleStrNAW (LPWSTR lpWide, INT nWide, LPCVOID lpStr, INT nStr)
{
if (SHELL_OsIsUnicode())
return StrToOleStrNW (lpWide, nWide, (LPCWSTR)lpStr, nStr);
return StrToOleStrNA (lpWide, nWide, (LPCSTR)lpStr, nStr);
}
/*************************************************************************
* OleStrToStrN [SHELL32.78]
*/
BOOL WINAPI OleStrToStrNA (LPSTR lpStr, INT nStr, LPCWSTR lpOle, INT nOle)
{
TRACE("(%p, %x, %s, %x)\n", lpStr, nStr, debugstr_wn(lpOle,nOle), nOle);
return WideCharToMultiByte (0, 0, lpOle, nOle, lpStr, nStr, NULL, NULL);
}
BOOL WINAPI OleStrToStrNW (LPWSTR lpwStr, INT nwStr, LPCWSTR lpOle, INT nOle)
{
TRACE("(%p, %x, %s, %x)\n", lpwStr, nwStr, debugstr_wn(lpOle,nOle), nOle);
if (lstrcpynW ( lpwStr, lpOle, nwStr))
{ return wcslen (lpwStr);
}
return 0;
}
EXTERN_C BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn, INT nIn)
{
if (SHELL_OsIsUnicode())
return OleStrToStrNW ((LPWSTR)lpOut, nOut, (LPCWSTR)lpIn, nIn);
return OleStrToStrNA ((LPSTR)lpOut, nOut, (LPCWSTR)lpIn, nIn);
}
/*************************************************************************
* CheckEscapesA [SHELL32.@]
*
* Checks a string for special characters which are not allowed in a path
* and encloses it in quotes if that is the case.
*
* PARAMS
* string [I/O] string to check and on return eventually quoted
* len [I] length of string
*
* RETURNS
* length of actual string
*
* NOTES
* Not really sure if this function returns actually a value at all.
*/
DWORD WINAPI CheckEscapesA(
LPSTR string, /* [I/O] string to check ??*/
DWORD len) /* [I] is 0 */
{
LPWSTR wString;
DWORD ret = 0;
TRACE("(%s %d)\n", debugstr_a(string), len);
wString = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR));
if (wString)
{
MultiByteToWideChar(CP_ACP, 0, string, len, wString, len);
ret = CheckEscapesW(wString, len);
WideCharToMultiByte(CP_ACP, 0, wString, len, string, len, NULL, NULL);
LocalFree(wString);
}
return ret;
}
static const WCHAR strEscapedChars[] = {' ','"',',',';','^',0};
/*************************************************************************
* CheckEscapesW [SHELL32.@]
*
* See CheckEscapesA.
*/
DWORD WINAPI CheckEscapesW(
LPWSTR string,
DWORD len)
{
DWORD size = wcslen(string);
LPWSTR s, d;
TRACE("(%s %d) stub\n", debugstr_w(string), len);
if (StrPBrkW(string, strEscapedChars) && size + 2 <= len)
{
s = &string[size - 1];
d = &string[size + 2];
*d-- = 0;
*d-- = '"';
for (;d > string;)
*d-- = *s--;
*d = '"';
return size + 2;
}
return size;
}

View file

@ -21,6 +21,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _SHFLDR_H_
#define _SHFLDR_H_
#define CHARS_IN_GUID 39
typedef struct {
@ -51,9 +54,9 @@ LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
static int __inline SHELL32_GUIDToStringA (REFGUID guid, LPSTR str)
{
return sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
}
static int __inline SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
@ -64,10 +67,12 @@ static int __inline SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
'%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
'%','0','2','x','%','0','2','x','}',0 };
return swprintf(str, fmtW,
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
}
void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags);
BOOL SHELL_FS_HideExtension(LPWSTR pwszPath);
#endif // _SHFLDR_H_

View file

@ -0,0 +1,584 @@
/*
* Virtual Admin Tools Folder
*
* Copyright 2008 Johannes Anderwald
* Copyright 2009 Andrew Hill
*
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL (shell);
/*
This folder should not exist. It is just a file system folder...
*/
/* List shortcuts of
* CSIDL_COMMON_ADMINTOOLS
* Note: CSIDL_ADMINTOOLS is ignored, tested with Window XP SP3+
*/
/***********************************************************************
* AdminTools folder implementation
*/
class CDesktopFolderEnumY :
public IEnumIDListImpl
{
private:
public:
CDesktopFolderEnumY();
~CDesktopFolderEnumY();
HRESULT WINAPI Initialize(LPWSTR szTarget, DWORD dwFlags);
BEGIN_COM_MAP(CDesktopFolderEnumY)
COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
END_COM_MAP()
};
static const shvheader AdminToolsSFHeader[] = {
{IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12}
};
#define COLUMN_NAME 0
#define COLUMN_SIZE 1
#define COLUMN_TYPE 2
#define COLUMN_DATE 3
#define AdminToolsHELLVIEWCOLUMNS (4)
CDesktopFolderEnumY::CDesktopFolderEnumY()
{
}
CDesktopFolderEnumY::~CDesktopFolderEnumY()
{
}
HRESULT WINAPI CDesktopFolderEnumY::Initialize(LPWSTR szTarget, DWORD dwFlags)
{
TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
/* enumerate the elements in %windir%\desktop */
return CreateFolderEnumList(szTarget, dwFlags);
}
CAdminToolsFolder::CAdminToolsFolder()
{
pclsid = NULL;
pidlRoot = NULL; /* absolute pidl */
szTarget = NULL;
dwAttributes = 0; /* attributes returned by GetAttributesOf FIXME: use it */
}
CAdminToolsFolder::~CAdminToolsFolder()
{
TRACE ("-- destroying IShellFolder(%p)\n", this);
if (pidlRoot)
SHFree(pidlRoot);
HeapFree(GetProcessHeap(), 0, szTarget);
}
HRESULT WINAPI CAdminToolsFolder::FinalConstruct()
{
szTarget = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
if (szTarget == NULL)
return E_OUTOFMEMORY;
if (!SHGetSpecialFolderPathW(NULL, szTarget, CSIDL_COMMON_ADMINTOOLS, FALSE))
return E_FAIL;
pidlRoot = _ILCreateAdminTools(); /* my qualified pidl */
if (pidlRoot == NULL)
return E_OUTOFMEMORY;
return S_OK;
}
/**************************************************************************
* ISF_AdminTools_fnParseDisplayName
*
*/
HRESULT WINAPI CAdminToolsFolder::ParseDisplayName (HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
{
TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
pchEaten, ppidl, pdwAttributes);
*ppidl = 0;
if (pchEaten)
*pchEaten = 0;
MessageBoxW(NULL, lpszDisplayName, L"ParseDisplayName", MB_OK);
return E_NOTIMPL;
}
/**************************************************************************
* ISF_AdminTools_fnEnumObjects
*/
HRESULT WINAPI CAdminToolsFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
CComObject<CDesktopFolderEnumY> *theEnumerator;
CComPtr<IEnumIDList> result;
HRESULT hResult;
TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList);
if (ppEnumIDList == NULL)
return E_POINTER;
*ppEnumIDList = NULL;
ATLTRY (theEnumerator = new CComObject<CDesktopFolderEnumY>);
if (theEnumerator == NULL)
return E_OUTOFMEMORY;
hResult = theEnumerator->QueryInterface (IID_IEnumIDList, (void **)&result);
if (FAILED (hResult))
{
delete theEnumerator;
return hResult;
}
hResult = theEnumerator->Initialize (szTarget, dwFlags);
if (FAILED (hResult))
return hResult;
*ppEnumIDList = result.Detach ();
TRACE ("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
return S_OK;
}
/**************************************************************************
* ISF_AdminTools_fnBindToObject
*/
HRESULT WINAPI CAdminToolsFolder::BindToObject(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", this,
pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
return SHELL32_BindToChild (pidlRoot, NULL, pidl, riid, ppvOut);
}
/**************************************************************************
* ISF_AdminTools_fnBindToStorage
*/
HRESULT WINAPI CAdminToolsFolder::BindToStorage(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
*ppvOut = NULL;
return E_NOTIMPL;
}
/**************************************************************************
* ISF_AdminTools_fnCompareIDs
*/
HRESULT WINAPI CAdminToolsFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
int nReturn;
TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
TRACE ("-- %i\n", nReturn);
return nReturn;
}
/**************************************************************************
* ISF_AdminTools_fnCreateViewObject
*/
HRESULT WINAPI CAdminToolsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
{
CComPtr<IShellView> pShellView;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(hwnd=%p,%s,%p)\n", this,
hwndOwner, shdebugstr_guid (&riid), ppvOut);
if (!ppvOut)
return hr;
*ppvOut = NULL;
if (IsEqualIID (riid, IID_IDropTarget))
{
WARN ("IDropTarget not implemented\n");
hr = E_NOTIMPL;
}
else if (IsEqualIID (riid, IID_IShellView))
{
hr = IShellView_Constructor ((IShellFolder *)this, &pShellView);
if (pShellView)
hr = pShellView->QueryInterface(riid, ppvOut);
}
TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
return hr;
}
/**************************************************************************
* ISF_AdminTools_fnGetAttributesOf
*/
HRESULT WINAPI CAdminToolsFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST *apidl, DWORD *rgfInOut)
{
HRESULT hr = S_OK;
static const DWORD dwAdminToolsAttributes =
SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM;
TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
if (!rgfInOut)
return E_INVALIDARG;
if (cidl && !apidl)
return E_INVALIDARG;
if (*rgfInOut == 0)
*rgfInOut = ~0;
if(cidl == 0) {
*rgfInOut &= dwAdminToolsAttributes;
} else {
while (cidl > 0 && *apidl) {
pdump (*apidl);
if (_ILIsAdminTools(*apidl)) {
*rgfInOut &= dwAdminToolsAttributes;
} else {
SHELL32_GetItemAttributes (this, *apidl, rgfInOut);
}
apidl++;
cidl--;
}
}
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
*rgfInOut &= ~SFGAO_VALIDATE;
TRACE ("-- result=0x%08x\n", *rgfInOut);
return hr;
}
/**************************************************************************
* ISF_AdminTools_fnGetUIObjectOf
*
* PARAMETERS
* HWND hwndOwner, //[in ] Parent window for any output
* UINT cidl, //[in ] array size
* LPCITEMIDLIST* apidl, //[in ] simple pidl array
* REFIID riid, //[in ] Requested Interface
* UINT* prgfInOut, //[ ] reserved
* LPVOID* ppvObject) //[out] Resulting Interface
*
*/
HRESULT WINAPI CAdminToolsFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST *apidl,
REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
{
LPITEMIDLIST pidl;
CComPtr<IUnknown> pObj;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
if (!ppvOut)
return hr;
*ppvOut = NULL;
if (IsEqualIID (riid, IID_IContextMenu))
{
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder *)this, NULL, 0, NULL, (IContextMenu **)&pObj);
}
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
{
hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
}
else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
{
pidl = ILCombine (pidlRoot, apidl[0]);
pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
SHFree (pidl);
hr = S_OK;
}
else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
{
pidl = ILCombine (pidlRoot, apidl[0]);
pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
SHFree (pidl);
hr = S_OK;
}
else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
{
hr = this->QueryInterface(IID_IDropTarget, (LPVOID *)&pObj);
}
else if ((IsEqualIID(riid, IID_IShellLinkW) ||
IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
{
pidl = ILCombine (pidlRoot, apidl[0]);
hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
SHFree (pidl);
}
else
hr = E_NOINTERFACE;
if (SUCCEEDED(hr) && !pObj)
hr = E_OUTOFMEMORY;
*ppvOut = pObj.Detach();
TRACE ("(%p)->hr=0x%08x\n", this, hr);
return hr;
}
/**************************************************************************
* ISF_AdminTools_fnGetDisplayNameOf
*
*/
HRESULT WINAPI CAdminToolsFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
{
HRESULT hr = S_OK;
LPWSTR pszPath, pOffset;
TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
pdump (pidl);
if (!strRet)
return E_INVALIDARG;
pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
if (!pszPath)
return E_OUTOFMEMORY;
ZeroMemory(pszPath, (MAX_PATH +1) * sizeof(WCHAR));
if (_ILIsAdminTools (pidl))
{
if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
(GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
wcscpy(pszPath, szTarget);
else if (!HCR_GetClassNameW(CLSID_AdminFolderShortcut, pszPath, MAX_PATH))
hr = E_FAIL;
}
else if (_ILIsPidlSimple(pidl))
{
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
(GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
szTarget)
{
wcscpy(pszPath, szTarget);
pOffset = PathAddBackslashW(pszPath);
if (pOffset)
{
if (!_ILSimpleGetTextW(pidl, pOffset, MAX_PATH + 1 - (pOffset - pszPath)))
hr = E_FAIL;
}
else
hr = E_FAIL;
}
else
{
if (_ILSimpleGetTextW(pidl, pszPath, MAX_PATH + 1))
{
if (SHELL_FS_HideExtension(pszPath))
PathRemoveExtensionW(pszPath);
}
else
hr = E_FAIL;
}
}
else if (_ILIsSpecialFolder(pidl))
{
BOOL bSimplePidl = _ILIsPidlSimple(pidl);
if (bSimplePidl)
{
if (!_ILSimpleGetTextW(pidl, pszPath, MAX_PATH))
hr = E_FAIL;
}
else if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl)
{
int len = 0;
wcscpy(pszPath, szTarget);
PathAddBackslashW(pszPath);
len = wcslen(pszPath);
if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags | SHGDN_INFOLDER, pszPath + len, MAX_PATH + 1 - len)))
{
CoTaskMemFree(pszPath);
return E_OUTOFMEMORY;
}
}
}
if (SUCCEEDED(hr))
{
strRet->uType = STRRET_WSTR;
strRet->pOleStr = pszPath;
TRACE ("-- (%p)->(%s,0x%08x)\n", this, debugstr_w(strRet->pOleStr), hr);
}
else
CoTaskMemFree(pszPath);
return hr;
}
/**************************************************************************
* ISF_AdminTools_fnSetNameOf
* Changes the name of a file object or subfolder, possibly changing its item
* identifier in the process.
*
* PARAMETERS
* HWND hwndOwner, //[in ] Owner window for output
* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
* LPCOLESTR lpszName, //[in ] the items new display name
* DWORD dwFlags, //[in ] SHGNO formatting flags
* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
*/
HRESULT WINAPI CAdminToolsFolder::SetNameOf (HWND hwndOwner, LPCITEMIDLIST pidl, /* simple pidl */
LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
{
FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", this, hwndOwner, pidl,
debugstr_w (lpName), dwFlags, pPidlOut);
return E_FAIL;
}
HRESULT WINAPI CAdminToolsFolder::GetDefaultSearchGUID(GUID *pguid)
{
FIXME ("(%p)\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CAdminToolsFolder::EnumSearches(IEnumExtraSearch ** ppenum)
{
FIXME ("(%p)\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CAdminToolsFolder::GetDefaultColumn (DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
{
if (pSort)
*pSort = 0;
if (pDisplay)
*pDisplay = 0;
return S_OK;
}
HRESULT WINAPI CAdminToolsFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
{
if (!pcsFlags || iColumn >= AdminToolsHELLVIEWCOLUMNS)
return E_INVALIDARG;
*pcsFlags = AdminToolsSFHeader[iColumn].pcsFlags;
return S_OK;
}
HRESULT WINAPI CAdminToolsFolder::GetDetailsEx (LPCITEMIDLIST pidl, const SHCOLUMNID *pscid, VARIANT *pv)
{
FIXME ("(%p): stub\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CAdminToolsFolder::GetDetailsOf (LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
{
WCHAR buffer[MAX_PATH] = {0};
HRESULT hr = E_FAIL;
TRACE("(%p)->(%p %i %p): stub\n", this, pidl, iColumn, psd);
if (iColumn >= AdminToolsHELLVIEWCOLUMNS)
return E_FAIL;
psd->fmt = AdminToolsSFHeader[iColumn].fmt;
psd->cxChar = AdminToolsSFHeader[iColumn].cxChar;
if (pidl == NULL)
{
psd->str.uType = STRRET_WSTR;
if (LoadStringW(shell32_hInstance, AdminToolsSFHeader[iColumn].colnameid, buffer, MAX_PATH))
hr = SHStrDupW(buffer, &psd->str.pOleStr);
return hr;
}
psd->str.uType = STRRET_CSTR;
switch (iColumn)
{
case COLUMN_NAME:
psd->str.uType = STRRET_WSTR;
hr = GetDisplayNameOf(pidl,
SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
break;
case COLUMN_SIZE:
_ILGetFileSize (pidl, psd->str.cStr, MAX_PATH);
break;
case COLUMN_TYPE:
_ILGetFileType (pidl, psd->str.cStr, MAX_PATH);
break;
case COLUMN_DATE:
_ILGetFileDate (pidl, psd->str.cStr, MAX_PATH);
break;
}
return hr;
}
HRESULT WINAPI CAdminToolsFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
{
FIXME ("(%p): stub\n", this);
return E_NOTIMPL;
}
/************************************************************************
* IPF_AdminTools_GetClassID
*/
HRESULT WINAPI CAdminToolsFolder::GetClassID(CLSID *lpClassId)
{
TRACE ("(%p)\n", this);
memcpy(lpClassId, &CLSID_AdminFolderShortcut, sizeof(CLSID));
return S_OK;
}
/************************************************************************
* IPF_AdminTools_Initialize
*
*/
HRESULT WINAPI CAdminToolsFolder::Initialize(LPCITEMIDLIST pidl)
{
if (pidlRoot)
SHFree((LPVOID)pidlRoot);
pidlRoot = ILClone(pidl);
return S_OK;
}
/**************************************************************************
* IPF_AdminTools_fnGetCurFolder
*/
HRESULT WINAPI CAdminToolsFolder::GetCurFolder(LPITEMIDLIST *pidl)
{
TRACE ("(%p)->(%p)\n", this, pidl);
*pidl = ILClone (pidlRoot);
return S_OK;
}

View file

@ -0,0 +1,87 @@
/*
* Virtual Admin Tools Folder
*
* Copyright 2008 Johannes Anderwald
* Copyright 2009 Andrew Hill
*
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SHFLDR_ADMINTOOLS_H_
#define _SHFLDR_ADMINTOOLS_H_
class CAdminToolsFolder :
public CComCoClass<CAdminToolsFolder, &CLSID_AdminFolderShortcut>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder2
{
private:
CLSID *pclsid;
LPITEMIDLIST pidlRoot; /* absolute pidl */
LPWSTR szTarget;
int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */
public:
CAdminToolsFolder();
~CAdminToolsFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName (HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, LPITEMIDLIST *ppidl, DWORD *pdwAttributes);
virtual HRESULT WINAPI EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList);
virtual HRESULT WINAPI BindToObject(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI BindToStorage(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
virtual HRESULT WINAPI CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI GetAttributesOf (UINT cidl, LPCITEMIDLIST *apidl, DWORD *rgfInOut);
virtual HRESULT WINAPI GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut);
virtual HRESULT WINAPI GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet);
virtual HRESULT WINAPI SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl, LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST *pPidlOut);
/* ShellFolder2 */
virtual HRESULT WINAPI GetDefaultSearchGUID(GUID *pguid);
virtual HRESULT WINAPI EnumSearches(IEnumExtraSearch **ppenum);
virtual HRESULT WINAPI GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay);
virtual HRESULT WINAPI GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags);
virtual HRESULT WINAPI GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID *pscid, VARIANT *pv);
virtual HRESULT WINAPI GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd);
virtual HRESULT WINAPI MapColumnToSCID(UINT column, SHCOLUMNID *pscid);
// IPersist
virtual HRESULT WINAPI GetClassID(CLSID *lpClassId);
// IPersistFolder
virtual HRESULT WINAPI Initialize(LPCITEMIDLIST pidl);
// IPersistFolder2
virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
DECLARE_REGISTRY_RESOURCEID(IDR_ADMINFOLDERSHORTCUT)
DECLARE_NOT_AGGREGATABLE(CAdminToolsFolder)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CAdminToolsFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
END_COM_MAP()
};
#endif // _SHFLDR_ADMINTOOLS_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,107 @@
/*
* Control panel folder
*
* Copyright 2003 Martin Fuchs
* Copyright 2009 Andrew Hill
*
* 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
*/
#ifndef _SHFLDR_CPANEL_H_
#define _SHFLDR_CPANEL_H_
class CControlPanelFolder :
public CComCoClass<CControlPanelFolder, &CLSID_ControlPanel>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder2,
public IShellExecuteHookA,
public IShellExecuteHookW,
public IContextMenu2
{
private:
/* both paths are parsible from the desktop */
LPITEMIDLIST pidlRoot; /* absolute pidl */
int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */
LPCITEMIDLIST *apidl;
UINT cidl;
public:
CControlPanelFolder();
~CControlPanelFolder();
HRESULT WINAPI FinalConstruct();
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName (HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, LPITEMIDLIST *ppidl, DWORD *pdwAttributes);
virtual HRESULT WINAPI EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList);
virtual HRESULT WINAPI BindToObject(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI BindToStorage(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
virtual HRESULT WINAPI CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI GetAttributesOf (UINT cidl, LPCITEMIDLIST *apidl, DWORD *rgfInOut);
virtual HRESULT WINAPI GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut);
virtual HRESULT WINAPI GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet);
virtual HRESULT WINAPI SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl, LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST *pPidlOut);
/* ShellFolder2 */
virtual HRESULT WINAPI GetDefaultSearchGUID(GUID *pguid);
virtual HRESULT WINAPI EnumSearches(IEnumExtraSearch **ppenum);
virtual HRESULT WINAPI GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay);
virtual HRESULT WINAPI GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags);
virtual HRESULT WINAPI GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID *pscid, VARIANT *pv);
virtual HRESULT WINAPI GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd);
virtual HRESULT WINAPI MapColumnToSCID(UINT column, SHCOLUMNID *pscid);
// IPersist
virtual HRESULT WINAPI GetClassID(CLSID *lpClassId);
// IPersistFolder
virtual HRESULT WINAPI Initialize(LPCITEMIDLIST pidl);
// IPersistFolder2
virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
// IShellExecuteHookW
virtual HRESULT WINAPI Execute(LPSHELLEXECUTEINFOW psei);
// IShellExecuteHookA
virtual HRESULT WINAPI Execute(LPSHELLEXECUTEINFOA psei);
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand,UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
// IContextMenu2
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
DECLARE_REGISTRY_RESOURCEID(IDR_CONTROLPANEL)
DECLARE_NOT_AGGREGATABLE(CControlPanelFolder)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CControlPanelFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IShellExecuteHookA, IShellExecuteHookA)
COM_INTERFACE_ENTRY_IID(IID_IShellExecuteHookW, IShellExecuteHookW)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
END_COM_MAP()
};
#endif // _SHFLDR_CPANEL_H_

Some files were not shown because too many files have changed in this diff Show more