mirror of
https://github.com/reactos/reactos.git
synced 2024-06-22 22:11:39 +00:00
[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:
commit
3bb734fcf3
|
@ -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)
|
||||
|
|
336
reactos/dll/win32/shell32/GlueCode.cpp
Normal file
336
reactos/dll/win32/shell32/GlueCode.cpp
Normal 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;
|
||||
}
|
11
reactos/dll/win32/shell32/GlueCode.h
Normal file
11
reactos/dll/win32/shell32/GlueCode.h
Normal 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
|
||||
|
2
reactos/dll/win32/shell32/authors.cpp
Normal file
2
reactos/dll/win32/shell32/authors.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
const char * const SHELL_Authors[] = { "Copyright 1993-2011 WINE team", "Copyright 1998-2011 ReactOS Team", 0 };
|
515
reactos/dll/win32/shell32/autocomplete.cpp
Normal file
515
reactos/dll/win32/shell32/autocomplete.cpp
Normal 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;
|
||||
}
|
65
reactos/dll/win32/shell32/autocomplete.h
Normal file
65
reactos/dll/win32/shell32/autocomplete.h
Normal 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_
|
0
reactos/dll/win32/shell32/basebar.cpp
Normal file
0
reactos/dll/win32/shell32/basebar.cpp
Normal file
0
reactos/dll/win32/shell32/basebar.h
Normal file
0
reactos/dll/win32/shell32/basebar.h
Normal file
816
reactos/dll/win32/shell32/brsfolder.cpp
Normal file
816
reactos/dll/win32/shell32/brsfolder.cpp
Normal 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;
|
||||
}
|
476
reactos/dll/win32/shell32/changenotify.cpp
Normal file
476
reactos/dll/win32/shell32/changenotify.cpp
Normal 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 );
|
||||
}
|
506
reactos/dll/win32/shell32/classes.cpp
Normal file
506
reactos/dll/win32/shell32/classes.cpp
Normal 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;
|
||||
}
|
240
reactos/dll/win32/shell32/clipboard.cpp
Normal file
240
reactos/dll/win32/shell32/clipboard.cpp
Normal 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;
|
||||
}
|
524
reactos/dll/win32/shell32/control.cpp
Normal file
524
reactos/dll/win32/shell32/control.cpp
Normal 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;
|
||||
}
|
391
reactos/dll/win32/shell32/dataobject.cpp
Normal file
391
reactos/dll/win32/shell32/dataobject.cpp
Normal 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;
|
||||
}
|
170
reactos/dll/win32/shell32/dde.cpp
Normal file
170
reactos/dll/win32/shell32/dde.cpp
Normal 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);
|
||||
}
|
||||
}
|
434
reactos/dll/win32/shell32/debughlp.cpp
Normal file
434
reactos/dll/win32/shell32/debughlp.cpp
Normal 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" );
|
||||
}
|
561
reactos/dll/win32/shell32/desktop.cpp
Normal file
561
reactos/dll/win32/shell32/desktop.cpp
Normal 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();
|
||||
}
|
738
reactos/dll/win32/shell32/dialogs.cpp
Normal file
738
reactos/dll/win32/shell32/dialogs.cpp
Normal 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);
|
||||
}
|
||||
}
|
67
reactos/dll/win32/shell32/dragdrophelper.cpp
Normal file
67
reactos/dll/win32/shell32/dragdrophelper.cpp
Normal 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;
|
||||
}
|
53
reactos/dll/win32/shell32/dragdrophelper.h
Normal file
53
reactos/dll/win32/shell32/dragdrophelper.h
Normal 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_
|
1288
reactos/dll/win32/shell32/drive.cpp
Normal file
1288
reactos/dll/win32/shell32/drive.cpp
Normal file
File diff suppressed because it is too large
Load diff
301
reactos/dll/win32/shell32/enumidlist.cpp
Normal file
301
reactos/dll/win32/shell32/enumidlist.cpp
Normal 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;
|
||||
}
|
|
@ -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__ */
|
||||
|
|
358
reactos/dll/win32/shell32/extracticon.cpp
Normal file
358
reactos/dll/win32/shell32/extracticon.cpp
Normal 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;
|
||||
}
|
827
reactos/dll/win32/shell32/folder_options.cpp
Normal file
827
reactos/dll/win32/shell32/folder_options.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
380
reactos/dll/win32/shell32/folders.cpp
Normal file
380
reactos/dll/win32/shell32/folders.cpp
Normal 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;
|
||||
}
|
943
reactos/dll/win32/shell32/fprop.cpp
Normal file
943
reactos/dll/win32/shell32/fprop.cpp
Normal 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 */
|
|
@ -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"
|
||||
|
|
936
reactos/dll/win32/shell32/iconcache.cpp
Normal file
936
reactos/dll/win32/shell32/iconcache.cpp
Normal 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;
|
||||
}
|
|
@ -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"
|
||||
|
|
0
reactos/dll/win32/shell32/menuband.cpp
Normal file
0
reactos/dll/win32/shell32/menuband.cpp
Normal file
0
reactos/dll/win32/shell32/menuband.h
Normal file
0
reactos/dll/win32/shell32/menuband.h
Normal file
0
reactos/dll/win32/shell32/menubandsite.cpp
Normal file
0
reactos/dll/win32/shell32/menubandsite.cpp
Normal file
0
reactos/dll/win32/shell32/menubandsite.h
Normal file
0
reactos/dll/win32/shell32/menubandsite.h
Normal file
0
reactos/dll/win32/shell32/menudeskbar.cpp
Normal file
0
reactos/dll/win32/shell32/menudeskbar.cpp
Normal file
0
reactos/dll/win32/shell32/menudeskbar.h
Normal file
0
reactos/dll/win32/shell32/menudeskbar.h
Normal file
2411
reactos/dll/win32/shell32/pidl.cpp
Normal file
2411
reactos/dll/win32/shell32/pidl.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
798
reactos/dll/win32/shell32/regsvr.cpp
Normal file
798
reactos/dll/win32/shell32/regsvr.cpp
Normal 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;
|
||||
}
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/Copy of rgs/autocomplete.rgs
Normal file
13
reactos/dll/win32/shell32/res/Copy of rgs/autocomplete.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
reactos/dll/win32/shell32/res/Copy of rgs/controlpanel.rgs
Normal file
52
reactos/dll/win32/shell32/res/Copy of rgs/controlpanel.rgs
Normal 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}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/Copy of rgs/dragdrophelper.rgs
Normal file
13
reactos/dll/win32/shell32/res/Copy of rgs/dragdrophelper.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
reactos/dll/win32/shell32/res/Copy of rgs/folderoptions.rgs
Normal file
56
reactos/dll/win32/shell32/res/Copy of rgs/folderoptions.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
reactos/dll/win32/shell32/res/Copy of rgs/foldershortcut.rgs
Normal file
23
reactos/dll/win32/shell32/res/Copy of rgs/foldershortcut.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/Copy of rgs/menubandsite.rgs
Normal file
13
reactos/dll/win32/shell32/res/Copy of rgs/menubandsite.rgs
Normal file
|
@ -0,0 +1,13 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {E13EF4E4-D2F2-11d0-9816-00C04FD91972} = s 'Menu Site'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
63
reactos/dll/win32/shell32/res/Copy of rgs/mycomputer.rgs
Normal file
63
reactos/dll/win32/shell32/res/Copy of rgs/mycomputer.rgs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
67
reactos/dll/win32/shell32/res/Copy of rgs/mydocuments.rgs
Normal file
67
reactos/dll/win32/shell32/res/Copy of rgs/mydocuments.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
reactos/dll/win32/shell32/res/Copy of rgs/networkplaces.rgs
Normal file
58
reactos/dll/win32/shell32/res/Copy of rgs/networkplaces.rgs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
reactos/dll/win32/shell32/res/Copy of rgs/newmenu.rgs
Normal file
14
reactos/dll/win32/shell32/res/Copy of rgs/newmenu.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
53
reactos/dll/win32/shell32/res/Copy of rgs/printers.rgs
Normal file
53
reactos/dll/win32/shell32/res/Copy of rgs/printers.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
reactos/dll/win32/shell32/res/Copy of rgs/recyclebin.rgs
Normal file
59
reactos/dll/win32/shell32/res/Copy of rgs/recyclebin.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
reactos/dll/win32/shell32/res/Copy of rgs/shelldesktop.rgs
Normal file
45
reactos/dll/win32/shell32/res/Copy of rgs/shelldesktop.rgs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/Copy of rgs/shellfsfolder.rgs
Normal file
13
reactos/dll/win32/shell32/res/Copy of rgs/shellfsfolder.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
reactos/dll/win32/shell32/res/Copy of rgs/shelllink.rgs
Normal file
23
reactos/dll/win32/shell32/res/Copy of rgs/shelllink.rgs
Normal 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 ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/Copy of rgs/startmenu.rgs
Normal file
13
reactos/dll/win32/shell32/res/Copy of rgs/startmenu.rgs
Normal file
|
@ -0,0 +1,13 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {4622AD11-FF23-11d0-8D34-00A0C90F2719} = s 'Start Menu'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
reactos/dll/win32/shell32/res/rgs/adminfoldershortcut.rgs
Normal file
56
reactos/dll/win32/shell32/res/rgs/adminfoldershortcut.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/rgs/autocomplete.rgs
Normal file
13
reactos/dll/win32/shell32/res/rgs/autocomplete.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
reactos/dll/win32/shell32/res/rgs/controlpanel.rgs
Normal file
52
reactos/dll/win32/shell32/res/rgs/controlpanel.rgs
Normal 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}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/rgs/dragdrophelper.rgs
Normal file
13
reactos/dll/win32/shell32/res/rgs/dragdrophelper.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
reactos/dll/win32/shell32/res/rgs/folderoptions.rgs
Normal file
56
reactos/dll/win32/shell32/res/rgs/folderoptions.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
reactos/dll/win32/shell32/res/rgs/foldershortcut.rgs
Normal file
23
reactos/dll/win32/shell32/res/rgs/foldershortcut.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
reactos/dll/win32/shell32/res/rgs/fontsfoldershortcut.rgs
Normal file
56
reactos/dll/win32/shell32/res/rgs/fontsfoldershortcut.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/rgs/menubandsite.rgs
Normal file
13
reactos/dll/win32/shell32/res/rgs/menubandsite.rgs
Normal file
|
@ -0,0 +1,13 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {E13EF4E4-D2F2-11d0-9816-00C04FD91972} = s 'Menu Site'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
63
reactos/dll/win32/shell32/res/rgs/mycomputer.rgs
Normal file
63
reactos/dll/win32/shell32/res/rgs/mycomputer.rgs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
67
reactos/dll/win32/shell32/res/rgs/mydocuments.rgs
Normal file
67
reactos/dll/win32/shell32/res/rgs/mydocuments.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
reactos/dll/win32/shell32/res/rgs/networkplaces.rgs
Normal file
58
reactos/dll/win32/shell32/res/rgs/networkplaces.rgs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
reactos/dll/win32/shell32/res/rgs/newmenu.rgs
Normal file
14
reactos/dll/win32/shell32/res/rgs/newmenu.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
53
reactos/dll/win32/shell32/res/rgs/printers.rgs
Normal file
53
reactos/dll/win32/shell32/res/rgs/printers.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
reactos/dll/win32/shell32/res/rgs/recyclebin.rgs
Normal file
59
reactos/dll/win32/shell32/res/rgs/recyclebin.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
reactos/dll/win32/shell32/res/rgs/shelldesktop.rgs
Normal file
45
reactos/dll/win32/shell32/res/rgs/shelldesktop.rgs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/rgs/shellfsfolder.rgs
Normal file
13
reactos/dll/win32/shell32/res/rgs/shellfsfolder.rgs
Normal 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
reactos/dll/win32/shell32/res/rgs/shelllink.rgs
Normal file
23
reactos/dll/win32/shell32/res/rgs/shelllink.rgs
Normal 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 ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
reactos/dll/win32/shell32/res/rgs/startmenu.rgs
Normal file
13
reactos/dll/win32/shell32/res/rgs/startmenu.rgs
Normal file
|
@ -0,0 +1,13 @@
|
|||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {4622AD11-FF23-11d0-8D34-00A0C90F2719} = s 'Start Menu'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Apartment'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
reactos/dll/win32/shell32/rgs_res.rc
Normal file
22
reactos/dll/win32/shell32/rgs_res.rc
Normal 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"
|
73
reactos/dll/win32/shell32/ros-systray.cpp
Normal file
73
reactos/dll/win32/shell32/ros-systray.cpp
Normal 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);
|
||||
}
|
1136
reactos/dll/win32/shell32/she_ocmenu.cpp
Normal file
1136
reactos/dll/win32/shell32/she_ocmenu.cpp
Normal file
File diff suppressed because it is too large
Load diff
65
reactos/dll/win32/shell32/she_ocmenu.h
Normal file
65
reactos/dll/win32/shell32/she_ocmenu.h
Normal 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_
|
21
reactos/dll/win32/shell32/shell.cpp
Normal file
21
reactos/dll/win32/shell32/shell.cpp
Normal 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
|
||||
*/
|
|
@ -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">
|
||||
|
|
90
reactos/dll/win32/shell32/shell32.rbuild.bak
Normal file
90
reactos/dll/win32/shell32/shell32.rbuild.bak
Normal 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>
|
|
@ -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
|
||||
|
|
1477
reactos/dll/win32/shell32/shell32_main.cpp
Normal file
1477
reactos/dll/win32/shell32/shell32_main.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
|
248
reactos/dll/win32/shell32/shellitem.cpp
Normal file
248
reactos/dll/win32/shell32/shellitem.cpp
Normal 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;
|
||||
}
|
62
reactos/dll/win32/shell32/shellitem.h
Normal file
62
reactos/dll/win32/shell32/shellitem.h
Normal 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_
|
2215
reactos/dll/win32/shell32/shelllink.cpp
Normal file
2215
reactos/dll/win32/shell32/shelllink.cpp
Normal file
File diff suppressed because it is too large
Load diff
182
reactos/dll/win32/shell32/shelllink.h
Normal file
182
reactos/dll/win32/shell32/shelllink.h
Normal 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_
|
582
reactos/dll/win32/shell32/shellole.cpp
Normal file
582
reactos/dll/win32/shell32/shellole.cpp
Normal 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;
|
||||
}
|
2288
reactos/dll/win32/shell32/shellord.cpp
Normal file
2288
reactos/dll/win32/shell32/shellord.cpp
Normal file
File diff suppressed because it is too large
Load diff
2030
reactos/dll/win32/shell32/shellpath.cpp
Normal file
2030
reactos/dll/win32/shell32/shellpath.cpp
Normal file
File diff suppressed because it is too large
Load diff
144
reactos/dll/win32/shell32/shellreg.cpp
Normal file
144
reactos/dll/win32/shell32/shellreg.cpp
Normal 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 );
|
||||
}
|
264
reactos/dll/win32/shell32/shellstring.cpp
Normal file
264
reactos/dll/win32/shell32/shellstring.cpp
Normal 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;
|
||||
}
|
|
@ -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_
|
||||
|
|
584
reactos/dll/win32/shell32/shfldr_admintools.cpp
Normal file
584
reactos/dll/win32/shell32/shfldr_admintools.cpp
Normal 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;
|
||||
}
|
87
reactos/dll/win32/shell32/shfldr_admintools.h
Normal file
87
reactos/dll/win32/shell32/shfldr_admintools.h
Normal 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_
|
1082
reactos/dll/win32/shell32/shfldr_cpanel.cpp
Normal file
1082
reactos/dll/win32/shell32/shfldr_cpanel.cpp
Normal file
File diff suppressed because it is too large
Load diff
107
reactos/dll/win32/shell32/shfldr_cpanel.h
Normal file
107
reactos/dll/win32/shell32/shfldr_cpanel.h
Normal 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
Loading…
Reference in a new issue