From a291f2d15a675b8dc0791b23a69b99978575803d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 5 Aug 2005 07:48:18 +0000 Subject: [PATCH] Sync to Wine-20050628: Dmitry Timoshkov - Make remaining OLE interface vtables const. Mike McCormack - SHCreateStreamOnFileW is implemented in shlwapi, so we don't need another implementation in shell32. - Add a cast to get rid of a warning. - Warning fixes for -Wmissing-declarations and -Wwrite-strings. - Make functions static. - -Wpointer-sign fixes. - forward AddRef, Release, QueryInterface and GetClassID to internal implementations - implement GetClassID properly - Switch IShellLink to use shlwapi.SHCreateStreamOnFileW. - Remove some uses of wine/unicode.h functions. - Add the IContextMenu interface to the ShellLink object. - Implement ShellLink's IShellExtInit::Initialize() method. - add the IShellExtInit interface to the ShellLink object - use inline functions rather than macros to resolve the implementation pointer from an interface pointer - Add the IShellLinkDataList interface to the ShellLink object. Michael Jung - Use the CallForAttributes registry value, instead of promoting the root folder's SFGAO_FILESYSTEM flag to the registry. - Return the correct attributes for the desktop folder. - Corresponding tests. - Support for shellfolder's CallForAttributes registry value. - Let BindToObject fail, if called with empty relative pidl. - Tests to show that it should do so. - Fix SHBrowseForFolder to not pass an empty pidl to BindToObject. - Fix a lurking infinite loop in SHGetPathFromIDList. - Support for shellfolder's CallForAttributes registry value. - Use SHGetPathFromIDList instead of SHELL32_GetPathFromIDList. - Implement SHGetPathFromIDList based on GetDisplayNameOf. Stefan Doesinger - Handle cidl==0 in shfldr_desktop, shfldr_fs and shfldr_mycomp. - Remove the dwAttributes member from the IGenericSFImpl class, it's not needed and can't be initialised in Initialize and InitializeEx. Vitaly Lipatov - Realize DoEnvironmentSubstA via ExpandEnvironmentStringsA. - Fix types and return values. - Add prototype into shellapi.h. Aric Stewart - Fix the BrowseForFolder dialog so that when it does the callbacks it uses the correct message instead of always sending BEFM_INITIALIZED. Juan Lang - Const-ify a mask. - Set default for "My Documents" to $HOME, and "Desktop" to ~/Desktop. Alexandre Julliard - Sort entry points in the same order as Windows. Francois Gouget - Fix winapi_check documentation warnings. Marcus Meissner - ExtractAssociatedIconA needs to allocate enough space to have EAIW fill in lpIconPathW. Huw Davies - Unquote the icon file path if it's quoted. svn path=/trunk/; revision=17060 --- reactos/lib/shell32/Makefile.in | 1 - reactos/lib/shell32/autocomplete.c | 12 +- reactos/lib/shell32/brsfolder.c | 12 +- reactos/lib/shell32/classes.c | 118 +++-- reactos/lib/shell32/clipboard.c | 12 +- reactos/lib/shell32/cpanelfolder.c | 24 +- reactos/lib/shell32/dataobject.c | 8 +- reactos/lib/shell32/debughlp.c | 6 +- reactos/lib/shell32/dragdrophelper.c | 6 +- reactos/lib/shell32/enumidlist.c | 6 +- reactos/lib/shell32/folders.c | 18 +- reactos/lib/shell32/iconcache.c | 14 +- reactos/lib/shell32/memorystream.c | 309 ------------- reactos/lib/shell32/pidl.c | 196 +------- reactos/lib/shell32/pidl.h | 3 - reactos/lib/shell32/regsvr.c | 24 +- reactos/lib/shell32/shell32.spec | 126 ++--- reactos/lib/shell32/shell32.xml | 1 - reactos/lib/shell32/shell32_main.h | 6 +- reactos/lib/shell32/shelllink.c | 662 +++++++++++++++++++-------- reactos/lib/shell32/shellole.c | 12 +- reactos/lib/shell32/shellord.c | 45 +- reactos/lib/shell32/shellpath.c | 52 ++- reactos/lib/shell32/shfldr_desktop.c | 30 +- reactos/lib/shell32/shfldr_fs.c | 54 ++- reactos/lib/shell32/shfldr_mycomp.c | 35 +- reactos/lib/shell32/shlexec.c | 2 +- reactos/lib/shell32/shlfolder.c | 101 ++-- reactos/lib/shell32/shlfsbind.c | 4 +- reactos/lib/shell32/shlmenu.c | 19 +- reactos/lib/shell32/shlview.c | 34 +- reactos/lib/shell32/shv_bg_cmenu.c | 6 +- reactos/lib/shell32/shv_item_cmenu.c | 10 +- reactos/lib/shell32/systray.c | 10 +- 34 files changed, 969 insertions(+), 1009 deletions(-) delete mode 100644 reactos/lib/shell32/memorystream.c diff --git a/reactos/lib/shell32/Makefile.in b/reactos/lib/shell32/Makefile.in index 3915b158978..7094a043679 100644 --- a/reactos/lib/shell32/Makefile.in +++ b/reactos/lib/shell32/Makefile.in @@ -25,7 +25,6 @@ C_SRCS = \ enumidlist.c \ folders.c \ iconcache.c \ - memorystream.c \ pidl.c \ regsvr.c \ shell32_main.c \ diff --git a/reactos/lib/shell32/autocomplete.c b/reactos/lib/shell32/autocomplete.c index 9d75ccf08d6..4926e3ad01f 100644 --- a/reactos/lib/shell32/autocomplete.c +++ b/reactos/lib/shell32/autocomplete.c @@ -62,8 +62,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); typedef struct { - IAutoCompleteVtbl *lpVtbl; - IAutoComplete2Vtbl *lpvtblAutoComplete2; + const IAutoCompleteVtbl *lpVtbl; + const IAutoComplete2Vtbl *lpvtblAutoComplete2; DWORD ref; BOOL enabled; HWND hwndEdit; @@ -76,8 +76,8 @@ typedef struct AUTOCOMPLETEOPTIONS options; } IAutoCompleteImpl; -static struct IAutoCompleteVtbl acvt; -static struct IAutoComplete2Vtbl ac2vt; +static const IAutoCompleteVtbl acvt; +static const IAutoComplete2Vtbl ac2vt; #define _IAutoComplete2_Offset ((int)(&(((IAutoCompleteImpl*)0)->lpvtblAutoComplete2))) #define _ICOM_THIS_From_IAutoComplete2(class, name) class* This = (class*)(((char*)name)-_IAutoComplete2_Offset); @@ -312,7 +312,7 @@ static HRESULT WINAPI IAutoComplete_fnInit( /************************************************************************** * IAutoComplete_fnVTable */ -static IAutoCompleteVtbl acvt = +static const IAutoCompleteVtbl acvt = { IAutoComplete_fnQueryInterface, IAutoComplete_fnAddRef, @@ -432,7 +432,7 @@ static HRESULT WINAPI IAutoComplete2_fnSetOptions( /************************************************************************** * IAutoComplete2_fnVTable */ -static IAutoComplete2Vtbl ac2vt = +static const IAutoComplete2Vtbl ac2vt = { IAutoComplete2_fnQueryInterface, IAutoComplete2_fnAddRef, diff --git a/reactos/lib/shell32/brsfolder.c b/reactos/lib/shell32/brsfolder.c index 52c5d5f5b21..9d5b955972f 100644 --- a/reactos/lib/shell32/brsfolder.c +++ b/reactos/lib/shell32/brsfolder.c @@ -80,7 +80,7 @@ static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND hWnd, { if (!lpBrowseInfo->lpfn) return; - lpBrowseInfo->lpfn( hWnd, BFFM_INITIALIZED, param, lpBrowseInfo->lParam ); + lpBrowseInfo->lpfn( hWnd, msg, param, lpBrowseInfo->lParam ); } /****************************************************************************** @@ -428,8 +428,14 @@ static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE)) return 0; - r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0, - (REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 ); + if (lptvid->lpi && lptvid->lpi->mkid.cb) { + r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0, + (REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 ); + } else { + lpsf2 = lptvid->lpsfParent; + r = IShellFolder_AddRef(lpsf2); + } + if (SUCCEEDED(r)) FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL); diff --git a/reactos/lib/shell32/classes.c b/reactos/lib/shell32/classes.c index 96635f9765b..334b2acb6f1 100644 --- a/reactos/lib/shell32/classes.c +++ b/reactos/lib/shell32/classes.c @@ -26,6 +26,9 @@ #include #include #include + +#define COBJMACROS + #include "wine/debug.h" #include "winerror.h" #include "windef.h" @@ -39,6 +42,7 @@ #include "shlguid.h" #include "shresdef.h" #include "shlwapi.h" +#include "pidl.h" #include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(shell); @@ -178,6 +182,7 @@ static BOOL HCR_RegGetDefaultIconW(HKEY hkey, LPWSTR szDest, DWORD len, LPDWORD else *dwNr=0; /* sometimes the icon number is missing */ ParseFieldW (szDest, 1, szDest, len); + PathUnquoteSpacesW(szDest); return TRUE; } return FALSE; @@ -201,6 +206,7 @@ static BOOL HCR_RegGetDefaultIconA(HKEY hkey, LPSTR szDest, DWORD len, LPDWORD d else *dwNr=0; /* sometimes the icon number is missing */ ParseFieldA (szDest, 1, szDest, len); + PathUnquoteSpacesA(szDest); return TRUE; } return FALSE; @@ -339,47 +345,81 @@ BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len) return ret; } -/*************************************************************************************** -* HCR_GetFolderAttributes [internal] -* -* gets the folder attributes of a class -* -* FIXME -* verify the defaultvalue for *szDest -*/ -BOOL HCR_GetFolderAttributes (REFIID riid, LPDWORD szDest) -{ HKEY hkey; - char xriid[60]; - DWORD attributes; - DWORD len = 4; +/****************************************************************************** + * 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 }; - sprintf( xriid, "CLSID\\{%08lx-%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 ); + TRACE("(pidlFolder=%p, pdwAttributes=%p)\n", pidlFolder, pdwAttributes); + + if (!_ILIsPidlSimple(pidlFolder)) { + ERR("HCR_GetFolderAttributes 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)) { + LPSHELLFOLDER psfDesktop, psfFolder; + HRESULT hr; - if (!szDest) return FALSE; - *szDest = SFGAO_FOLDER|SFGAO_FILESYSTEM; + RegCloseKey(hSFKey); + hr = SHGetDesktopFolder(&psfDesktop); + if (SUCCEEDED(hr)) { + hr = IShellFolder_BindToObject(psfDesktop, pidlFolder, NULL, &IID_IShellFolder, + (LPVOID*)&psfFolder); + if (SUCCEEDED(hr)) { + hr = IShellFolder_GetAttributesOf(psfFolder, 0, NULL, pdwAttributes); + } + } + IShellFolder_Release(psfFolder); + IShellFolder_Release(psfDesktop); + 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; + } + } - strcat (xriid, "\\ShellFolder"); + TRACE("-- *pdwAttributes == 0x%08lx\n", *pdwAttributes); - if (RegOpenKeyExA(HKEY_CLASSES_ROOT,xriid,0,KEY_READ,&hkey)) - { - return FALSE; - } - - if (RegQueryValueExA(hkey,"Attributes",0,NULL,(LPBYTE)&attributes,&len)) - { - RegCloseKey(hkey); - return FALSE; - } - - RegCloseKey(hkey); - - TRACE("-- 0x%08lx\n", attributes); - - *szDest = attributes; - - return TRUE; + return TRUE; } diff --git a/reactos/lib/shell32/clipboard.c b/reactos/lib/shell32/clipboard.c index 9f06d9703d3..58fe3422bfb 100644 --- a/reactos/lib/shell32/clipboard.c +++ b/reactos/lib/shell32/clipboard.c @@ -176,7 +176,7 @@ HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) char szTemp[MAX_PATH], *szFileName; LPITEMIDLIST pidl; HGLOBAL hGlobal; - HRESULT hr; + BOOL bSuccess; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); @@ -185,9 +185,9 @@ HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) if (!pidl) return 0; - hr = SHELL_GetPathFromIDListA(pidl, szTemp, MAX_PATH); + bSuccess = SHGetPathFromIDListA(pidl, szTemp); SHFree(pidl); - if (FAILED(hr)) + if (!bSuccess) return 0; size = strlen(szTemp) + 1; @@ -208,7 +208,7 @@ HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) WCHAR szTemp[MAX_PATH], *szFileName; LPITEMIDLIST pidl; HGLOBAL hGlobal; - HRESULT hr; + BOOL bSuccess; TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); @@ -217,9 +217,9 @@ HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) if (!pidl) return 0; - hr = SHELL_GetPathFromIDListW(pidl, szTemp, MAX_PATH); + bSuccess = SHGetPathFromIDListW(pidl, szTemp); SHFree(pidl); - if (FAILED(hr)) + if (!bSuccess) return 0; size = (strlenW(szTemp)+1) * sizeof(WCHAR); diff --git a/reactos/lib/shell32/cpanelfolder.c b/reactos/lib/shell32/cpanelfolder.c index 90585686823..6f55c4c5788 100644 --- a/reactos/lib/shell32/cpanelfolder.c +++ b/reactos/lib/shell32/cpanelfolder.c @@ -58,11 +58,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); */ typedef struct { - IShellFolder2Vtbl *lpVtbl; + const IShellFolder2Vtbl *lpVtbl; DWORD ref; - IPersistFolder2Vtbl *lpVtblPersistFolder2; - IShellExecuteHookWVtbl *lpVtblShellExecuteHookW; - IShellExecuteHookAVtbl *lpVtblShellExecuteHookA; + const IPersistFolder2Vtbl *lpVtblPersistFolder2; + const IShellExecuteHookWVtbl *lpVtblShellExecuteHookW; + const IShellExecuteHookAVtbl *lpVtblShellExecuteHookA; IUnknown *pUnkOuter; /* used for aggregation */ @@ -71,10 +71,10 @@ typedef struct { int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */ } ICPanelImpl; -static IShellFolder2Vtbl vt_ShellFolder2; -static IPersistFolder2Vtbl vt_PersistFolder2; -static IShellExecuteHookWVtbl vt_ShellExecuteHookW; -static IShellExecuteHookAVtbl vt_ShellExecuteHookA; +static const IShellFolder2Vtbl vt_ShellFolder2; +static const IPersistFolder2Vtbl vt_PersistFolder2; +static const IShellExecuteHookWVtbl vt_ShellExecuteHookW; +static const IShellExecuteHookAVtbl vt_ShellExecuteHookA; #define _IPersistFolder2_Offset ((int)(&(((ICPanelImpl*)0)->lpVtblPersistFolder2))) #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset); @@ -792,7 +792,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnMapColumnToSCID(IShellFolder2 * iface, return E_NOTIMPL; } -static IShellFolder2Vtbl vt_ShellFolder2 = +static const IShellFolder2Vtbl vt_ShellFolder2 = { ISF_ControlPanel_fnQueryInterface, @@ -898,7 +898,7 @@ static HRESULT WINAPI ICPanel_PersistFolder2_GetCurFolder(IPersistFolder2 * ifac return S_OK; } -static IPersistFolder2Vtbl vt_PersistFolder2 = +static const IPersistFolder2Vtbl vt_PersistFolder2 = { ICPanel_PersistFolder2_QueryInterface, @@ -1000,7 +1000,7 @@ static HRESULT WINAPI IShellExecuteHookW_fnExecute(IShellExecuteHookW* iface, LP return S_FALSE; } -static IShellExecuteHookWVtbl vt_ShellExecuteHookW = +static const IShellExecuteHookWVtbl vt_ShellExecuteHookW = { IShellExecuteHookW_fnQueryInterface, @@ -1079,7 +1079,7 @@ static HRESULT WINAPI IShellExecuteHookA_fnExecute(IShellExecuteHookA* iface, LP return S_FALSE; } -static IShellExecuteHookAVtbl vt_ShellExecuteHookA = +static const IShellExecuteHookAVtbl vt_ShellExecuteHookA = { IShellExecuteHookA_fnQueryInterface, IShellExecuteHookA_fnAddRef, diff --git a/reactos/lib/shell32/dataobject.c b/reactos/lib/shell32/dataobject.c index d4d5b217917..c8d4c11eea2 100644 --- a/reactos/lib/shell32/dataobject.c +++ b/reactos/lib/shell32/dataobject.c @@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); typedef struct { /* IUnknown fields */ - IEnumFORMATETCVtbl *lpVtbl; + const IEnumFORMATETCVtbl *lpVtbl; DWORD ref; /* IEnumFORMATETC fields */ UINT posFmt; @@ -159,7 +159,7 @@ static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMAT return S_OK; } -static struct IEnumFORMATETCVtbl efvt = +static const IEnumFORMATETCVtbl efvt = { IEnumFORMATETC_fnQueryInterface, IEnumFORMATETC_fnAddRef, @@ -204,7 +204,7 @@ LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[]) typedef struct { /* IUnknown fields */ - IDataObjectVtbl *lpVtbl; + const IDataObjectVtbl *lpVtbl; DWORD ref; /* IDataObject fields */ @@ -408,7 +408,7 @@ static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDAT return E_NOTIMPL; } -static struct IDataObjectVtbl dtovt = +static const IDataObjectVtbl dtovt = { IDataObject_fnQueryInterface, IDataObject_fnAddRef, diff --git a/reactos/lib/shell32/debughlp.c b/reactos/lib/shell32/debughlp.c index 2282f6c9418..28e6a2df673 100644 --- a/reactos/lib/shell32/debughlp.c +++ b/reactos/lib/shell32/debughlp.c @@ -295,8 +295,8 @@ static char shdebugstr_buf2[100]; static char * shdebugstr_buf = shdebugstr_buf1; static struct { - REFIID riid; - char *name; + REFIID riid; + const char *name; } InterfaceDesc[] = { {&IID_IUnknown, "IID_IUnknown"}, {&IID_IClassFactory, "IID_IClassFactory"}, @@ -325,7 +325,7 @@ static struct { const char * shdebugstr_guid( const struct _GUID *id ) { int i; - char* name = NULL; + const char* name = NULL; char clsidbuf[100]; shdebugstr_buf = (shdebugstr_buf == shdebugstr_buf1) ? shdebugstr_buf2 : shdebugstr_buf1; diff --git a/reactos/lib/shell32/dragdrophelper.c b/reactos/lib/shell32/dragdrophelper.c index f46823049b9..356bff29d46 100644 --- a/reactos/lib/shell32/dragdrophelper.c +++ b/reactos/lib/shell32/dragdrophelper.c @@ -48,11 +48,11 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); */ typedef struct { - IDropTargetHelperVtbl *lpVtbl; + const IDropTargetHelperVtbl *lpVtbl; DWORD ref; } IDropTargetHelperImpl; -static struct IDropTargetHelperVtbl vt_IDropTargetHelper; +static const IDropTargetHelperVtbl vt_IDropTargetHelper; #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl) #define _IDropTargetHelper_(This) (IDropTargetHelper*)&(This->lpVtbl) @@ -175,7 +175,7 @@ static HRESULT WINAPI IDropTargetHelper_fnShow (IDropTargetHelper * iface, BOOL return E_NOTIMPL; } -static IDropTargetHelperVtbl vt_IDropTargetHelper = +static const IDropTargetHelperVtbl vt_IDropTargetHelper = { IDropTargetHelper_fnQueryInterface, IDropTargetHelper_fnAddRef, diff --git a/reactos/lib/shell32/enumidlist.c b/reactos/lib/shell32/enumidlist.c index 7e1cb064a3e..17cda2c7057 100644 --- a/reactos/lib/shell32/enumidlist.c +++ b/reactos/lib/shell32/enumidlist.c @@ -45,7 +45,7 @@ typedef struct tagENUMLIST typedef struct { - IEnumIDListVtbl *lpVtbl; + const IEnumIDListVtbl *lpVtbl; DWORD ref; LPENUMLIST mpFirst; LPENUMLIST mpLast; @@ -53,7 +53,7 @@ typedef struct } IEnumIDListImpl; -static struct IEnumIDListVtbl eidlvt; +static const IEnumIDListVtbl eidlvt; /************************************************************************** * AddToEnumList() @@ -367,7 +367,7 @@ static HRESULT WINAPI IEnumIDList_fnClone( /************************************************************************** * IEnumIDList_fnVTable */ -static IEnumIDListVtbl eidlvt = +static const IEnumIDListVtbl eidlvt = { IEnumIDList_fnQueryInterface, IEnumIDList_fnAddRef, diff --git a/reactos/lib/shell32/folders.c b/reactos/lib/shell32/folders.c index 15e66ac17cf..e38beb6ce93 100644 --- a/reactos/lib/shell32/folders.c +++ b/reactos/lib/shell32/folders.c @@ -49,16 +49,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); */ typedef struct { - IExtractIconWVtbl *lpVtbl; + const IExtractIconWVtbl *lpVtbl; DWORD ref; - IPersistFileVtbl *lpvtblPersistFile; - IExtractIconAVtbl *lpvtblExtractIconA; + const IPersistFileVtbl *lpvtblPersistFile; + const IExtractIconAVtbl *lpvtblExtractIconA; LPITEMIDLIST pidl; } IExtractIconWImpl; -static struct IExtractIconAVtbl eiavt; -static struct IExtractIconWVtbl eivt; -static struct IPersistFileVtbl pfvt; +static const IExtractIconAVtbl eiavt; +static const IExtractIconWVtbl eivt; +static const IPersistFileVtbl pfvt; #define _IPersistFile_Offset ((int)(&(((IExtractIconWImpl*)0)->lpvtblPersistFile))) #define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset); @@ -394,7 +394,7 @@ static HRESULT WINAPI IExtractIconW_fnExtract(IExtractIconW * iface, LPCWSTR psz return S_OK; } -static struct IExtractIconWVtbl eivt = +static const IExtractIconWVtbl eivt = { IExtractIconW_fnQueryInterface, IExtractIconW_fnAddRef, @@ -486,7 +486,7 @@ static HRESULT WINAPI IExtractIconA_fnExtract(IExtractIconA * iface, LPCSTR pszF return ret; } -static struct IExtractIconAVtbl eiavt = +static const IExtractIconAVtbl eiavt = { IExtractIconA_fnQueryInterface, IExtractIconA_fnAddRef, @@ -558,7 +558,7 @@ static HRESULT WINAPI IEIPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFi } -static struct IPersistFileVtbl pfvt = +static const IPersistFileVtbl pfvt = { IEIPersistFile_fnQueryInterface, IEIPersistFile_fnAddRef, diff --git a/reactos/lib/shell32/iconcache.c b/reactos/lib/shell32/iconcache.c index 8ccdc3e2462..9af214ff5d5 100644 --- a/reactos/lib/shell32/iconcache.c +++ b/reactos/lib/shell32/iconcache.c @@ -670,7 +670,12 @@ HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lp { HICON hIcon = NULL; INT len = MultiByteToWideChar(CP_ACP, 0, lpIconPath, -1, NULL, 0); - LPWSTR lpIconPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + /* 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 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); TRACE("%p %s %p\n", hInst, debugstr_a(lpIconPath), lpiIcon); @@ -678,11 +683,18 @@ HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lp { 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; diff --git a/reactos/lib/shell32/memorystream.c b/reactos/lib/shell32/memorystream.c deleted file mode 100644 index f4c17f4c50c..00000000000 --- a/reactos/lib/shell32/memorystream.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * This class implements a pure IStream object - * and can be used for many purposes. - * - * The main reason for implementing this was - * a cleaner implementation of IShellLink which - * needs to be able to load lnks from an IStream - * interface so it was obvious to capsule the file - * access in an IStream to. - * - * Copyright 1999 Juergen Schmied - * Copyright 2003 Mike McCormack for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "winuser.h" -#include "wingdi.h" -#include "shlobj.h" -#include "wine/debug.h" -#include "shell32_main.h" - -WINE_DEFAULT_DEBUG_CHANNEL(shell); - -#define STGM_ACCESS_MODE(stgm) ((stgm)&0x0000f) -#define STGM_SHARE_MODE(stgm) ((stgm)&0x000f0) -#define STGM_CREATE_MODE(stgm) ((stgm)&0x0f000) - -typedef struct -{ - const IStreamVtbl *lpvtst; - DWORD ref; - HANDLE handle; -} ISHFileStream; - -/************************************************************************** -* IStream_fnQueryInterface -*/ -static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IStream)) - *ppvObj = This; - - if(*ppvObj) - { - IStream_AddRef((IStream*)*ppvObj); - TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/************************************************************************** -* IStream_fnAddRef -*/ -static ULONG WINAPI IStream_fnAddRef(IStream *iface) -{ - ISHFileStream *This = (ISHFileStream *)iface; - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(count=%lu)\n", This, refCount - 1); - - return refCount; -} - -/************************************************************************** -* IStream_fnRelease -*/ -static ULONG WINAPI IStream_fnRelease(IStream *iface) -{ - ISHFileStream *This = (ISHFileStream *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(count=%lu)\n", This, refCount + 1); - - if (!refCount) - { - TRACE(" destroying SHFileStream (%p)\n",This); - CloseHandle(This->handle); - HeapFree(GetProcessHeap(),0,This); - } - return refCount; -} - -static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead); - - if ( !pv ) - return STG_E_INVALIDPOINTER; - - if ( ! ReadFile( This->handle, pv, cb, pcbRead, NULL ) ) - return S_FALSE; - - return S_OK; -} - -static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten) -{ - DWORD dummy_count; - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - if( !pv ) - return STG_E_INVALIDPOINTER; - - /* WriteFile() doesn't allow to specify NULL as write count pointer */ - if (!pcbWritten) - pcbWritten = &dummy_count; - - if( ! WriteFile( This->handle, pv, cb, pcbWritten, NULL ) ) - return E_FAIL; - - return S_OK; -} - -static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) -{ - DWORD pos, newposlo, newposhi; - - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - pos = dlibMove.QuadPart; /* FIXME: truncates */ - newposhi = 0; - newposlo = SetFilePointer( This->handle, pos, &newposhi, dwOrigin ); - if( newposlo == INVALID_SET_FILE_POINTER ) - return E_FAIL; - - plibNewPosition->QuadPart = newposlo | ( (LONGLONG)newposhi<<32); - - return S_OK; -} - -static HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - if( ! SetFilePointer( This->handle, libNewSize.QuadPart, NULL, FILE_BEGIN ) ) - return E_FAIL; - - if( ! SetEndOfFile( This->handle ) ) - return E_FAIL; - - return S_OK; -} -static HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnRevert (IStream * iface) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnLockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} -static HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm) -{ - ISHFileStream *This = (ISHFileStream *)iface; - - TRACE("(%p)\n",This); - - return E_NOTIMPL; -} - -static const IStreamVtbl stvt = -{ - IStream_fnQueryInterface, - IStream_fnAddRef, - IStream_fnRelease, - IStream_fnRead, - IStream_fnWrite, - IStream_fnSeek, - IStream_fnSetSize, - IStream_fnCopyTo, - IStream_fnCommit, - IStream_fnRevert, - IStream_fnLockRegion, - IStream_fnUnlockRegion, - IStream_fnStat, - IStream_fnClone -}; - -/************************************************************************** - * CreateStreamOnFile() - * - * similar to CreateStreamOnHGlobal - */ -HRESULT CreateStreamOnFile (LPCWSTR pszFilename, DWORD grfMode, IStream ** ppstm) -{ - ISHFileStream* fstr; - HANDLE handle; - DWORD access = GENERIC_READ, creat; - - if( grfMode & STGM_TRANSACTED ) - return E_INVALIDARG; - - switch( STGM_ACCESS_MODE( grfMode ) ) - { - case STGM_READ: - access = GENERIC_READ; - break; - case STGM_WRITE: - case STGM_READWRITE: - access = GENERIC_WRITE | GENERIC_READ; - break; - default: - return STG_E_INVALIDFLAG; - } - - switch( STGM_CREATE_MODE( grfMode ) ) - { - case STGM_CREATE: - creat = CREATE_ALWAYS; - break; - case STGM_FAILIFTHERE: - creat = OPEN_EXISTING; - break; - default: - return STG_E_INVALIDFLAG; - } - - handle = CreateFileW( pszFilename, access, - FILE_SHARE_READ, NULL, creat, 0, NULL ); - if( handle == INVALID_HANDLE_VALUE ) - return HRESULT_FROM_WIN32(GetLastError()); - - fstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ISHFileStream)); - if( !fstr ) - return E_OUTOFMEMORY; - fstr->lpvtst = &stvt; - fstr->ref = 1; - fstr->handle = handle; - - (*ppstm) = (IStream*)fstr; - - return S_OK; -} diff --git a/reactos/lib/shell32/pidl.c b/reactos/lib/shell32/pidl.c index 1d582ba3220..97632bcc189 100644 --- a/reactos/lib/shell32/pidl.c +++ b/reactos/lib/shell32/pidl.c @@ -1209,87 +1209,6 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, return E_INVALIDARG; } -/************************************************************************* - * SHELL_GetPathFromIDListA - */ -HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize) -{ - HRESULT hr = S_OK; - - pszPath[0]=0; - - /* One case is a PIDL rooted at desktop level */ - if (_ILIsDesktop(pidl) || _ILIsValue(pidl) || _ILIsFolder(pidl)) - { - hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE); - - if (SUCCEEDED(hr)) - PathAddBackslashA(pszPath); - } - /* The only other valid case is an item ID list beginning at "My Computer" */ - else if (_ILIsMyComputer(pidl)) - pidl = ILGetNext(pidl); - - if (SUCCEEDED(hr)) - { - LPSTR txt; - - while(pidl && pidl->mkid.cb) - { - if (_ILIsSpecialFolder(pidl)) - { - hr = E_INVALIDARG; - break; - } - - txt = _ILGetTextPointer(pidl); - if (!txt) - { - hr = E_INVALIDARG; - break; - } - - if (lstrlenA(txt) > pidl->mkid.cb) - ERR("pidl %p is borked\n",pidl); - - /* make sure there's enough space for the next segment */ - if ((lstrlenA(txt) + lstrlenA(pszPath)) > uOutSize) - { - hr = E_INVALIDARG; - break; - } - lstrcatA( pszPath, txt ); - - pidl = ILGetNext(pidl); - if (!pidl) - { - hr = E_INVALIDARG; - break; - } - - /* Are we at the end and successfully converted the complete PIDL? */ - if (!pidl->mkid.cb) - break; - - if ((lstrlenA(pszPath) + 1) > uOutSize) - { - hr = E_INVALIDARG; - break; - } - if (!PathAddBackslashA(pszPath)) - { - hr = E_INVALIDARG; - break; - } - } - } - else - hr = E_INVALIDARG; - - TRACE_(shell)("-- %s, 0x%08lx\n", pszPath, hr); - return hr; -} - /************************************************************************* * SHGetPathFromIDListA [SHELL32.@][NT 4.0: SHELL32.220] * @@ -1307,100 +1226,14 @@ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSiz */ BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath) { - HRESULT hr; + WCHAR wszPath[MAX_PATH]; + BOOL bSuccess; - TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath); - pdump(pidl); + bSuccess = SHGetPathFromIDListW(pidl, wszPath); + if (bSuccess) + WideCharToMultiByte(CP_ACP, 0, wszPath, -1, pszPath, MAX_PATH, NULL, NULL); - if (!pidl) - return FALSE; - - hr = SHELL_GetPathFromIDListA(pidl, pszPath, MAX_PATH); - - return SUCCEEDED(hr); -} - -/************************************************************************* - * SHELL_GetPathFromIDListW - */ -HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize) -{ - HRESULT hr = S_OK; - UINT len; - - pszPath[0]=0; - - /* One case is a PIDL rooted at desktop level */ - if (_ILIsDesktop(pidl) ||_ILIsValue(pidl) || _ILIsFolder(pidl)) - { - hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE); - - if (SUCCEEDED(hr)) - PathAddBackslashW(pszPath); - } - /* The only other valid case is an item ID list beginning at "My Computer" */ - else if (_ILIsMyComputer(pidl)) - pidl = ILGetNext(pidl); - - if (SUCCEEDED(hr)) - { - LPSTR txt; - - while(pidl && pidl->mkid.cb) - { - if (_ILIsSpecialFolder(pidl)) - { - hr = E_INVALIDARG; - break; - } - - txt = _ILGetTextPointer(pidl); - if (!txt) - { - hr = E_INVALIDARG; - break; - } - - if (lstrlenA(txt) > pidl->mkid.cb) - ERR("pidl %p is borked\n",pidl); - len = MultiByteToWideChar(CP_ACP, 0, txt, -1, NULL, 0); - if ( (lstrlenW(pszPath) + len) > uOutSize ) - { - hr = E_INVALIDARG; - break; - } - - MultiByteToWideChar(CP_ACP, 0, txt, -1, - &pszPath[lstrlenW(pszPath)], len); - - pidl = ILGetNext(pidl); - if (!pidl) - { - hr = E_INVALIDARG; - break; - } - - /* Are we at the end and successfully converted the complete PIDL? */ - if (!pidl->mkid.cb) - break; - - if ((lstrlenW(pszPath) + 1) > uOutSize ) - { - hr = E_INVALIDARG; - break; - } - if (!PathAddBackslashW(pszPath)) - { - hr = E_INVALIDARG; - break; - } - } - } - else - hr = E_INVALIDARG; - - TRACE_(shell)("-- %s, 0x%08lx\n", debugstr_w(pszPath), hr); - return hr; + return bSuccess; } /************************************************************************* @@ -1409,6 +1242,10 @@ HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSi BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath) { HRESULT hr; + LPCITEMIDLIST pidlLast; + LPSHELLFOLDER psfFolder; + DWORD dwAttributes; + STRRET strret; TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath)); pdump(pidl); @@ -1416,7 +1253,18 @@ BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath) if (!pidl) return FALSE; - hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH); + hr = SHBindToParent(pidl, &IID_IShellFolder, (VOID**)&psfFolder, &pidlLast); + if (FAILED(hr)) return FALSE; + + dwAttributes = SFGAO_FILESYSTEM; + hr = IShellFolder_GetAttributesOf(psfFolder, 1, &pidlLast, &dwAttributes); + if (FAILED(hr) || !(dwAttributes & SFGAO_FILESYSTEM)) return FALSE; + + hr = IShellFolder_GetDisplayNameOf(psfFolder, pidlLast, SHGDN_FORPARSING, &strret); + if (FAILED(hr)) return FALSE; + + hr = StrRetToBufW(&strret, pidlLast, pszPath, MAX_PATH); + IShellFolder_Release(psfFolder); TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr); return SUCCEEDED(hr); diff --git a/reactos/lib/shell32/pidl.h b/reactos/lib/shell32/pidl.h index 9f5ef5a1d31..d7da55a2085 100644 --- a/reactos/lib/shell32/pidl.h +++ b/reactos/lib/shell32/pidl.h @@ -257,7 +257,4 @@ LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida); BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type); BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type); -HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize); -HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize); - #endif diff --git a/reactos/lib/shell32/regsvr.c b/reactos/lib/shell32/regsvr.c index 548625320cc..006cfddccb2 100644 --- a/reactos/lib/shell32/regsvr.c +++ b/reactos/lib/shell32/regsvr.c @@ -64,13 +64,17 @@ struct regsvr_coclass 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 */ }; /* flags for regsvr_coclass.flags */ -#define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001 -#define SHELLFOLDER_WANTSFORPARSING 0x00000002 +#define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001 +#define SHELLFOLDER_WANTSFORPARSING 0x00000002 +#define SHELLFOLDER_ATTRIBUTES 0x00000004 +#define SHELLFOLDER_CALLFORATTRIBUTES 0x00000008 static HRESULT register_coclasses(struct regsvr_coclass const *list); static HRESULT unregister_coclasses(struct regsvr_coclass const *list); @@ -110,6 +114,8 @@ static WCHAR const mcdm_keyname[21] = { 'a', 'u', 'l', 't', 'M', 'e', 'n', 'u', 0 }; static char const tmodel_valuename[] = "ThreadingModel"; static char const wfparsing_valuename[] = "WantsFORPARSING"; +static char const attributes_valuename[] = "Attributes"; +static char const cfattributes_valuename[] = "CallForAttributes"; /*********************************************************************** * static helper functions @@ -285,15 +291,23 @@ static HRESULT register_coclasses(struct regsvr_coclass const *list) RegCloseKey(mcdm_key); } - if (list->flags & SHELLFOLDER_WANTSFORPARSING) { + if (list->flags & + (SHELLFOLDER_WANTSFORPARSING|SHELLFOLDER_ATTRIBUTES|SHELLFOLDER_CALLFORATTRIBUTES)) + { HKEY shellfolder_key; res = RegCreateKeyExW(clsid_key, shellfolder_keyname, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &shellfolder_key, NULL); if (res != ERROR_SUCCESS) goto error_close_clsid_key; - res = RegSetValueExA(shellfolder_key, wfparsing_valuename, 0, REG_SZ, - "", 1); + if (list->flags & SHELLFOLDER_WANTSFORPARSING) + res = RegSetValueExA(shellfolder_key, wfparsing_valuename, 0, REG_SZ, "", 1); + if (list->flags & SHELLFOLDER_ATTRIBUTES) + res = RegSetValueExA(shellfolder_key, attributes_valuename, 0, REG_DWORD, + (LPBYTE)&list->dwAttributes, sizeof(DWORD)); + if (list->flags & SHELLFOLDER_CALLFORATTRIBUTES) + res = RegSetValueExA(shellfolder_key, cfattributes_valuename, 0, REG_DWORD, + (LPBYTE)&list->dwCallForAttributes, sizeof(DWORD)); RegCloseKey(shellfolder_key); if (res != ERROR_SUCCESS) goto error_close_clsid_key; } diff --git a/reactos/lib/shell32/shell32.spec b/reactos/lib/shell32/shell32.spec index b038862cd3f..55a32d14b5f 100644 --- a/reactos/lib/shell32/shell32.spec +++ b/reactos/lib/shell32/shell32.spec @@ -237,26 +237,19 @@ 650 stdcall -noname PathIsSameRoot(ptr ptr) PathIsSameRootAW -# nt40/win98 651 stdcall -noname ReadCabinetState(long long) # OldReadCabinetState 652 stdcall -noname WriteCabinetState(long) 653 stdcall -noname PathProcessCommand(long long long long) PathProcessCommandAW - -# win98 654 stdcall @(long long) shell32_654 # ReadCabinetState@8 + 660 stdcall -noname FileIconInit(long) 680 stdcall -noname IsUserAdmin() -# >= NT5 714 stdcall @(ptr) SHELL32_714 # PathIsTemporaryW 730 stdcall -noname RestartDialogEx(long wstr long long) 1217 stub FOOBAR1217 # no joke! This is the real name!! -# -# version 4.0 (win95) -# _WIN32_IE >= 0x0200 -# @ stdcall CheckEscapesA(str long) @ stdcall CheckEscapesW(wstr long) @ stdcall CommandLineToArgvW(wstr ptr) @@ -269,6 +262,7 @@ @ stdcall Control_RunDLLW(ptr ptr wstr long) @ stdcall -private DllCanUnloadNow() SHELL32_DllCanUnloadNow @ stdcall -private DllGetClassObject(long long ptr) SHELL32_DllGetClassObject +@ stdcall DllGetVersion(ptr)SHELL32_DllGetVersion @ stdcall DllInstall(long wstr)SHELL32_DllInstall @ stdcall -private DllRegisterServer() SHELL32_DllRegisterServer @ stdcall -private DllUnregisterServer() SHELL32_DllUnregisterServer @@ -290,9 +284,9 @@ @ stdcall ExtractIconEx(ptr long ptr ptr long) ExtractIconExA @ stdcall ExtractIconExA(str long ptr ptr long) @ stdcall ExtractIconExW(wstr long ptr ptr long) -@ stdcall ExtractIconW(long wstr long) @ stub ExtractIconResInfoA @ stub ExtractIconResInfoW +@ stdcall ExtractIconW(long wstr long) @ stub ExtractVersionResource16W @ stub FindExeDlgProc @ stdcall FindExecutableA(ptr ptr ptr) @@ -315,6 +309,7 @@ @ stub RegenerateUserEnvironment @ stdcall SHAddToRecentDocs (long ptr) @ stdcall SHAppBarMessage(long ptr) +@ stdcall SHBindToParent(ptr ptr ptr ptr) @ stdcall SHBrowseForFolder(ptr) SHBrowseForFolderA @ stdcall SHBrowseForFolderA(ptr) @ stdcall SHBrowseForFolderW(ptr) @@ -323,36 +318,10 @@ @ stdcall SHCreateDirectoryExA(long str ptr) @ stdcall SHCreateDirectoryExW(long wstr ptr) @ stub SHCreateProcessAsUserW -@ stdcall SheChangeDirA(str) -@ stub SheChangeDirExA -@ stub SheChangeDirExW -@ stdcall SheChangeDirW(wstr) -@ stub SheConvertPathW -@ stub SheFullPathA -@ stub SheFullPathW -@ stub SheGetCurDrive -@ stdcall SheGetDirA(long long) -@ stub SheGetDirExW -@ stdcall SheGetDirW (long long) -@ stub SheGetPathOffsetW -@ stdcall ShellAboutA(long str str long) -@ stdcall ShellAboutW(long wstr wstr long) -@ stdcall ShellExecuteA(long str str str str long) -@ stdcall ShellExecuteEx (long) ShellExecuteExA -@ stdcall ShellExecuteExA (long) -@ stdcall ShellExecuteExW (long) -@ stdcall ShellExecuteW (long wstr wstr wstr wstr long) -@ stub ShellHookProc -@ stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIconA -@ stdcall Shell_NotifyIconA(long ptr) -@ stdcall Shell_NotifyIconW(long ptr) +@ stdcall SHDefExtractIconA(str long long ptr ptr long) +@ stdcall SHDefExtractIconW(wstr long long ptr ptr long) @ stdcall SHEmptyRecycleBinA(long str long) @ stdcall SHEmptyRecycleBinW(long wstr long) -@ stub SheRemoveQuotesA -@ stub SheRemoveQuotesW -@ stub SheSetCurDrive -@ stub SheShortenPathA -@ stub SheShortenPathW @ stub SHExtractIconsW @ stdcall SHFileOperation(ptr) SHFileOperationA @ stdcall SHFileOperationA(ptr) @@ -362,9 +331,18 @@ @ stdcall SHGetDataFromIDListA(ptr ptr long ptr long) @ stdcall SHGetDataFromIDListW(ptr ptr long ptr long) @ stdcall SHGetDesktopFolder(ptr) +@ stdcall SHGetDiskFreeSpaceA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA +@ stdcall SHGetDiskFreeSpaceExA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA +@ stdcall SHGetDiskFreeSpaceExW(wstr ptr ptr ptr) kernel32.GetDiskFreeSpaceExW @ stdcall SHGetFileInfo(ptr long ptr long long) SHGetFileInfoA @ stdcall SHGetFileInfoA(ptr long ptr long long) @ stdcall SHGetFileInfoW(ptr long ptr long long) +@ stdcall SHGetFolderLocation(long long long long ptr) +@ stdcall SHGetFolderPathA(long long long long ptr) +@ stdcall SHGetFolderPathW(long long long long ptr) +@ stub SHGetFreeDiskSpace +@ stub SHGetIconOverlayIndexA +@ stub SHGetIconOverlayIndexW @ stdcall SHGetInstanceExplorer(long) @ stdcall SHGetMalloc(ptr) @ stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA @@ -373,6 +351,8 @@ @ stdcall SHGetPathFromIDListW(ptr ptr) @ stdcall SHGetSettings(ptr long) @ stdcall SHGetSpecialFolderLocation(long long ptr) +@ stdcall SHGetSpecialFolderPathA(long ptr long long) +@ stdcall SHGetSpecialFolderPathW(long ptr long long) @ stdcall SHHelpShortcuts_RunDLL(long long long long) SHHelpShortcuts_RunDLLA @ stdcall SHHelpShortcuts_RunDLLA(long long long long) @ stdcall SHHelpShortcuts_RunDLLW(long long long long) @@ -386,6 +366,37 @@ @ stdcall SHQueryRecycleBinA(str ptr) @ stdcall SHQueryRecycleBinW(wstr ptr) @ stub SHUpdateRecycleBinIcon +@ stdcall SheChangeDirA(str) +@ stub SheChangeDirExA +@ stub SheChangeDirExW +@ stdcall SheChangeDirW(wstr) +@ stub SheConvertPathW +@ stub SheFullPathA +@ stub SheFullPathW +@ stub SheGetCurDrive +@ stdcall SheGetDirA(long long) +@ stub SheGetDirExW +@ stdcall SheGetDirW (long long) +@ stub SheGetPathOffsetW +@ stub SheRemoveQuotesA +@ stub SheRemoveQuotesW +@ stub SheSetCurDrive +@ stub SheShortenPathA +@ stub SheShortenPathW +@ stdcall ShellAboutA(long str str long) +@ stdcall ShellAboutW(long wstr wstr long) +@ stub ShellExec_RunDLL +@ stub ShellExec_RunDLLA +@ stub ShellExec_RunDLLW +@ stdcall ShellExecuteA(long str str str str long) +@ stdcall ShellExecuteEx (long) ShellExecuteExA +@ stdcall ShellExecuteExA (long) +@ stdcall ShellExecuteExW (long) +@ stdcall ShellExecuteW (long wstr wstr wstr wstr long) +@ stub ShellHookProc +@ stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIconA +@ stdcall Shell_NotifyIconA(long ptr) +@ stdcall Shell_NotifyIconW(long ptr) @ stdcall StrChrA(str long) shlwapi.StrChrA @ stdcall StrChrIA(str long) shlwapi.StrChrIA @ stdcall StrChrIW(wstr long) shlwapi.StrChrIW @@ -415,44 +426,3 @@ @ stdcall StrStrIW(wstr wstr) shlwapi.StrStrIW @ stdcall StrStrW(wstr wstr) shlwapi.StrStrW @ stub WOWShellExecute - -# -# version 4.70 (IE3.0) -# _WIN32_IE >= 0x0300 -# - -# -# version 4.71 (IE4.0) -# _WIN32_IE >= 0x0400 -# -@ stdcall DllGetVersion(ptr)SHELL32_DllGetVersion -@ stub SHGetFreeDiskSpace -@ stdcall SHGetSpecialFolderPathA(long ptr long long) -@ stdcall SHGetSpecialFolderPathW(long ptr long long) -# -# version 4.72 (IE4.01) -# _WIN32_IE >= 0x0401 -# no new exports -# - -# -# version 5.00 (Win2K) -# _WIN32_IE >= 0x0500 -# -@ stub ShellExec_RunDLL -@ stub ShellExec_RunDLLA -@ stub ShellExec_RunDLLW -@ stdcall SHBindToParent(ptr ptr ptr ptr) -@ stdcall SHGetDiskFreeSpaceA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA -@ stdcall SHGetDiskFreeSpaceExA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA -@ stdcall SHGetDiskFreeSpaceExW(wstr ptr ptr ptr) kernel32.GetDiskFreeSpaceExW -@ stdcall SHGetFolderPathA(long long long long ptr) -@ stdcall SHGetFolderPathW(long long long long ptr) -@ stdcall SHGetFolderLocation(long long long long ptr) -@ stub SHGetIconOverlayIndexA -@ stub SHGetIconOverlayIndexW - -# version 6.0 (WinXP) -# _WIN32_IE >= 0x600 -@ stdcall SHDefExtractIconA(str long long ptr ptr long) -@ stdcall SHDefExtractIconW(wstr long long ptr ptr long) diff --git a/reactos/lib/shell32/shell32.xml b/reactos/lib/shell32/shell32.xml index 681a8e73a9e..201f2a167af 100644 --- a/reactos/lib/shell32/shell32.xml +++ b/reactos/lib/shell32/shell32.xml @@ -34,7 +34,6 @@ enumidlist.c folders.c iconcache.c - memorystream.c pidl.c regsvr.c shell32_main.c diff --git a/reactos/lib/shell32/shell32_main.h b/reactos/lib/shell32/shell32_main.h index bb2db9b9dd7..a425ca9d83b 100644 --- a/reactos/lib/shell32/shell32_main.h +++ b/reactos/lib/shell32/shell32_main.h @@ -67,7 +67,7 @@ BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, DWORD len, BOOL b BOOL HCR_GetDefaultIconA(LPCSTR szClass, LPSTR szDest, DWORD len, LPDWORD dwNr); BOOL HCR_GetClassNameA(REFIID riid, LPSTR szDest, DWORD len); -BOOL HCR_GetFolderAttributes(REFIID riid, LPDWORD szDest); +BOOL HCR_GetFolderAttributes(LPCITEMIDLIST pidlFolder, LPDWORD dwAttributes); INT_PTR CALLBACK AboutDlgProc(HWND,UINT,WPARAM,LPARAM); DWORD WINAPI ParseFieldA(LPCSTR src, DWORD nField, LPSTR dst, DWORD len); @@ -102,7 +102,6 @@ HRESULT WINAPI IAutoComplete_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVO LPEXTRACTICONA IExtractIconA_Constructor(LPCITEMIDLIST); LPEXTRACTICONW IExtractIconW_Constructor(LPCITEMIDLIST); -HRESULT CreateStreamOnFile (LPCWSTR pszFilename, DWORD grfMode, IStream ** ppstm); /* FIXME: rename the functions when the shell32.dll has it's own exports namespace */ HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv); @@ -167,6 +166,9 @@ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16,LPCSTR,UINT16,WORD); BOOL16 WINAPI ShellAbout16(HWND16,LPCSTR,LPCSTR,HICON16); BOOL16 WINAPI AboutDlgProc16(HWND16,UINT16,WPARAM16,LPARAM); +void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition, + UINT wID, UINT fType, LPCSTR dwTypeData, UINT fState); + inline static BOOL SHELL_OsIsUnicode(void) { /* if high-bit of version is 0, we are emulating NT */ diff --git a/reactos/lib/shell32/shelllink.c b/reactos/lib/shell32/shelllink.c index ef04100855b..61d0fcc3e4a 100644 --- a/reactos/lib/shell32/shelllink.c +++ b/reactos/lib/shell32/shelllink.c @@ -33,6 +33,7 @@ */ #define COBJMACROS +#define NONAMELESSUNION #include "wine/debug.h" #include "winerror.h" @@ -112,21 +113,27 @@ typedef struct volume_info_t #include "poppack.h" -static IShellLinkAVtbl slvt; -static IShellLinkWVtbl slvtw; -static IPersistFileVtbl pfvt; -static IPersistStreamVtbl psvt; +static const IShellLinkAVtbl slvt; +static const IShellLinkWVtbl slvtw; +static const IPersistFileVtbl pfvt; +static const IPersistStreamVtbl psvt; +static const IShellLinkDataListVtbl dlvt; +static const IShellExtInitVtbl eivt; +static const IContextMenuVtbl cmvt; /* IShellLink Implementation */ typedef struct { - IShellLinkAVtbl *lpVtbl; - DWORD ref; + const IShellLinkAVtbl *lpVtbl; + const IShellLinkWVtbl *lpvtblw; + const IPersistFileVtbl *lpvtblPersistFile; + const IPersistStreamVtbl *lpvtblPersistStream; + const IShellLinkDataListVtbl *lpvtblShellLinkDataList; + const IShellExtInitVtbl *lpvtblShellExtInit; + const IContextMenuVtbl *lpvtblContextMenu; - IShellLinkWVtbl *lpvtblw; - IPersistFileVtbl *lpvtblPersistFile; - IPersistStreamVtbl *lpvtblPersistStream; + DWORD ref; /* data structures according to the informations in the link */ LPITEMIDLIST pPidl; @@ -150,14 +157,47 @@ typedef struct BOOL bDirty; } IShellLinkImpl; -#define _IShellLinkW_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblw))) -#define _ICOM_THIS_From_IShellLinkW(class, name) class* This = (class*)(((char*)name)-_IShellLinkW_Offset) +static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblw)); +} +#define _ICOM_THIS_From_IShellLinkW(class, iface) \ + class* This = impl_from_IShellLinkW( iface ) -#define _IPersistFile_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistFile))) -#define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset) +static inline IShellLinkImpl *impl_from_IPersistFile( IPersistFile *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblPersistFile)); +} +#define _ICOM_THIS_From_IPersistFile(class, iface) \ + class* This = impl_from_IPersistFile( iface ) -#define _IPersistStream_Offset ((int)(&(((IShellLinkImpl*)0)->lpvtblPersistStream))) -#define _ICOM_THIS_From_IPersistStream(class, name) class* This = (class*)(((char*)name)-_IPersistStream_Offset) +static inline IShellLinkImpl *impl_from_IPersistStream( IPersistStream *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblPersistStream)); +} +#define _ICOM_THIS_From_IPersistStream(class, iface) \ + class* This = impl_from_IPersistStream( iface ) + +static inline IShellLinkImpl *impl_from_IShellLinkDataList( IShellLinkDataList *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblShellLinkDataList)); +} +#define _ICOM_THIS_From_IShellLinkDataList(class, iface) \ + class* This = impl_from_IShellLinkDataList( iface ) + +static inline IShellLinkImpl *impl_from_IShellExtInit( IShellExtInit *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblShellExtInit)); +} +#define _ICOM_THIS_From_IShellExtInit(class, iface) \ + class* This = impl_from_IShellExtInit( iface ) + +static inline IShellLinkImpl *impl_from_IContextMenu( IContextMenu *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblContextMenu)); +} +#define _ICOM_THIS_From_IContextMenu(class, iface) \ + class* This = impl_from_IContextMenu( iface ) static HRESULT ShellLink_UpdatePath(LPWSTR sPathRel, LPCWSTR path, LPCWSTR sWorkDir, LPWSTR* psPath); @@ -172,6 +212,102 @@ inline static LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str) return p; } +/************************************************************************** + * ShellLink::QueryInterface implementation + */ +static HRESULT ShellLink_QueryInterface( IShellLinkImpl *This, REFIID riid, LPVOID *ppvObj) +{ + TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid)); + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellLinkA)) + { + *ppvObj = This; + } + else if(IsEqualIID(riid, &IID_IShellLinkW)) + { + *ppvObj = &(This->lpvtblw); + } + else if(IsEqualIID(riid, &IID_IPersistFile)) + { + *ppvObj = &(This->lpvtblPersistFile); + } + else if(IsEqualIID(riid, &IID_IPersistStream)) + { + *ppvObj = &(This->lpvtblPersistStream); + } + else if(IsEqualIID(riid, &IID_IShellLinkDataList)) + { + *ppvObj = &(This->lpvtblShellLinkDataList); + } + else if(IsEqualIID(riid, &IID_IShellExtInit)) + { + *ppvObj = &(This->lpvtblShellExtInit); + } + else if(IsEqualIID(riid, &IID_IContextMenu)) + { + *ppvObj = &(This->lpvtblContextMenu); + } + + if(*ppvObj) + { + IUnknown_AddRef((IUnknown*)(*ppvObj)); + TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); + return S_OK; + } + ERR("-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/************************************************************************** + * ShellLink::AddRef implementation + */ +static ULONG ShellLink_AddRef( IShellLinkImpl *This ) +{ + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(count=%lu)\n", This, refCount - 1); + + return refCount; +} + +/************************************************************************** + * ShellLink::Release implementation + */ +static ULONG ShellLink_Release( IShellLinkImpl *This ) +{ + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(count=%lu)\n", This, refCount + 1); + + if (refCount) + return refCount; + + TRACE("-- destroying IShellLink(%p)\n",This); + + HeapFree(GetProcessHeap(), 0, This->sIcoPath); + HeapFree(GetProcessHeap(), 0, This->sArgs); + HeapFree(GetProcessHeap(), 0, This->sWorkDir); + HeapFree(GetProcessHeap(), 0, This->sDescription); + HeapFree(GetProcessHeap(),0,This->sPath); + + if (This->pPidl) + ILFree(This->pPidl); + + LocalFree((HANDLE)This); + + return 0; +} + +static HRESULT ShellLink_GetClassID( IShellLinkImpl *This, CLSID *pclsid ) +{ + TRACE("%p %p\n", This, pclsid); + + memcpy( pclsid, &CLSID_ShellLink, sizeof (CLSID) ); + return S_OK; +} + /************************************************************************** * IPersistFile_QueryInterface */ @@ -180,11 +316,8 @@ static HRESULT WINAPI IPersistFile_fnQueryInterface( REFIID riid, LPVOID *ppvObj) { - _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); - - TRACE("(%p)\n",This); - - return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj); + _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); + return ShellLink_QueryInterface( This, riid, ppvObj ); } /****************************************************************************** @@ -192,30 +325,25 @@ static HRESULT WINAPI IPersistFile_fnQueryInterface( */ static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile* iface) { - _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); - - TRACE("(%p)->(count=%lu)\n",This,This->ref); - - return IShellLinkA_AddRef((IShellLinkA*)This); + _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); + return ShellLink_AddRef( This ); } + /****************************************************************************** * IPersistFile_Release */ static ULONG WINAPI IPersistFile_fnRelease(IPersistFile* iface) { - _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); - - TRACE("(%p)->(count=%lu)\n",This,This->ref); - - return IShellLinkA_Release((IShellLinkA*)This); + _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); + return IShellLinkA_Release((IShellLinkA*)This); } static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile* iface, CLSID *pClassID) { - _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); - FIXME("(%p)\n",This); - return NOERROR; + _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); + return ShellLink_GetClassID( This, pClassID ); } + static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile* iface) { _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); @@ -227,6 +355,7 @@ static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile* iface) return S_FALSE; } + static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode) { _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); @@ -236,7 +365,9 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFile TRACE("(%p, %s, %lx)\n",This, debugstr_w(pszFileName), dwMode); - r = CreateStreamOnFile(pszFileName, dwMode, &stm); + if( dwMode == 0 ) + dwMode = STGM_READ | STGM_SHARE_DENY_WRITE; + r = SHCreateStreamOnFileW(pszFileName, dwMode, &stm); if( SUCCEEDED( r ) ) { r = IPersistStream_Load(StreamThis, stm); @@ -293,7 +424,7 @@ static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFile if (!pszFileName) return E_FAIL; - r = CreateStreamOnFile(pszFileName, STGM_READWRITE | STGM_CREATE, &stm); + r = SHCreateStreamOnFileW( pszFileName, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, &stm ); if( SUCCEEDED( r ) ) { r = IPersistStream_Save(StreamThis, stm, FALSE); @@ -321,6 +452,7 @@ static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile* iface, LPCOLEST FIXME("(%p)->(%s)\n",This,debugstr_w(pszFileName)); return NOERROR; } + static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *ppszFileName) { _ICOM_THIS_From_IPersistFile(IShellLinkImpl, iface); @@ -328,7 +460,7 @@ static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *p return NOERROR; } -static IPersistFileVtbl pfvt = +static const IPersistFileVtbl pfvt = { IPersistFile_fnQueryInterface, IPersistFile_fnAddRef, @@ -347,13 +479,10 @@ static IPersistFileVtbl pfvt = static HRESULT WINAPI IPersistStream_fnQueryInterface( IPersistStream* iface, REFIID riid, - VOID** ppvoid) + VOID** ppvObj) { - _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); - - TRACE("(%p)\n",This); - - return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvoid); + _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); + return ShellLink_QueryInterface( This, riid, ppvObj ); } /************************************************************************ @@ -362,11 +491,8 @@ static HRESULT WINAPI IPersistStream_fnQueryInterface( static ULONG WINAPI IPersistStream_fnRelease( IPersistStream* iface) { - _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); - - TRACE("(%p)\n",This); - - return IShellLinkA_Release((IShellLinkA*)This); + _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); + return IShellLinkA_Release((IShellLinkA*)This); } /************************************************************************ @@ -375,11 +501,8 @@ static ULONG WINAPI IPersistStream_fnRelease( static ULONG WINAPI IPersistStream_fnAddRef( IPersistStream* iface) { - _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); - - TRACE("(%p)\n",This); - - return IShellLinkA_AddRef((IShellLinkA*)This); + _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); + return ShellLink_AddRef( This ); } /************************************************************************ @@ -390,16 +513,8 @@ static HRESULT WINAPI IPersistStream_fnGetClassID( IPersistStream* iface, CLSID* pClassID) { - _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); - - TRACE("(%p)\n", This); - - if (pClassID==0) - return E_POINTER; - -/* memcpy(pClassID, &CLSID_???, sizeof(CLSID_???)); */ - - return S_OK; + _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface); + return ShellLink_GetClassID( This, pClassID ); } /************************************************************************ @@ -634,8 +749,8 @@ static HRESULT Stream_LoadAdvertiseInfo( IStream* stm, LPWSTR *str ) } *str = HeapAlloc( GetProcessHeap(), 0, - (strlenW(buffer.szwDarwinID)+1) * sizeof(WCHAR) ); - strcpyW( *str, buffer.szwDarwinID ); + (lstrlenW(buffer.szwDarwinID)+1) * sizeof(WCHAR) ); + lstrcpyW( *str, buffer.szwDarwinID ); return S_OK; } @@ -932,7 +1047,7 @@ static HRESULT WINAPI IPersistStream_fnSave( * so if the executable does not exist the just trust the path they * gave us */ - if (!*exePath) strcpyW(exePath,This->sPath); + if (!*exePath) lstrcpyW(exePath,This->sPath); } memset(&header, 0, sizeof(header)); @@ -1030,7 +1145,7 @@ static HRESULT WINAPI IPersistStream_fnGetSizeMax( return E_NOTIMPL; } -static IPersistStreamVtbl psvt = +static const IPersistStreamVtbl psvt = { IPersistStream_fnQueryInterface, IPersistStream_fnAddRef, @@ -1065,6 +1180,9 @@ HRESULT WINAPI IShellLink_Constructor( IUnknown *pUnkOuter, sl->lpvtblw = &slvtw; sl->lpvtblPersistFile = &pfvt; sl->lpvtblPersistStream = &psvt; + sl->lpvtblShellLinkDataList = &dlvt; + sl->lpvtblShellExtInit = &eivt; + sl->lpvtblContextMenu = &cmvt; sl->iShowCmd = SW_SHOWNORMAL; sl->bDirty = FALSE; @@ -1186,78 +1304,26 @@ HRESULT WINAPI IShellLink_ConstructFromFile( IUnknown* pUnkOuter, REFIID riid, */ static HRESULT WINAPI IShellLinkA_fnQueryInterface( IShellLinkA * iface, REFIID riid, LPVOID *ppvObj) { - IShellLinkImpl *This = (IShellLinkImpl *)iface; - - TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid)); - - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IShellLinkA)) - { - *ppvObj = This; - } - else if(IsEqualIID(riid, &IID_IShellLinkW)) - { - *ppvObj = (IShellLinkW *)&(This->lpvtblw); - } - else if(IsEqualIID(riid, &IID_IPersistFile)) - { - *ppvObj = (IPersistFile *)&(This->lpvtblPersistFile); - } - else if(IsEqualIID(riid, &IID_IPersistStream)) - { - *ppvObj = (IPersistStream *)&(This->lpvtblPersistStream); - } - - if(*ppvObj) - { - IUnknown_AddRef((IUnknown*)(*ppvObj)); - TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; + IShellLinkImpl *This = (IShellLinkImpl *)iface; + return ShellLink_QueryInterface( This, riid, ppvObj ); } + /****************************************************************************** * IShellLinkA_AddRef */ static ULONG WINAPI IShellLinkA_fnAddRef(IShellLinkA * iface) { - IShellLinkImpl *This = (IShellLinkImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(count=%lu)\n", This, refCount - 1); - - return refCount; + IShellLinkImpl *This = (IShellLinkImpl *)iface; + return ShellLink_AddRef( This ); } + /****************************************************************************** * IShellLinkA_Release */ static ULONG WINAPI IShellLinkA_fnRelease(IShellLinkA * iface) { IShellLinkImpl *This = (IShellLinkImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(count=%lu)\n", This, refCount + 1); - - if (refCount) - return refCount; - - TRACE("-- destroying IShellLink(%p)\n",This); - - HeapFree(GetProcessHeap(), 0, This->sIcoPath); - HeapFree(GetProcessHeap(), 0, This->sArgs); - HeapFree(GetProcessHeap(), 0, This->sWorkDir); - HeapFree(GetProcessHeap(), 0, This->sDescription); - HeapFree(GetProcessHeap(),0,This->sPath); - - if (This->pPidl) - ILFree(This->pPidl); - - LocalFree((HANDLE)This); - - return 0; + return ShellLink_Release( This ); } static HRESULT WINAPI IShellLinkA_fnGetPath(IShellLinkA * iface, LPSTR pszFile, @@ -1319,6 +1385,7 @@ static HRESULT WINAPI IShellLinkA_fnGetDescription(IShellLinkA * iface, LPSTR ps return S_OK; } + static HRESULT WINAPI IShellLinkA_fnSetDescription(IShellLinkA * iface, LPCSTR pszName) { IShellLinkImpl *This = (IShellLinkImpl *)iface; @@ -1399,25 +1466,25 @@ static HRESULT WINAPI IShellLinkA_fnSetArguments(IShellLinkA * iface, LPCSTR psz static HRESULT WINAPI IShellLinkA_fnGetHotkey(IShellLinkA * iface, WORD *pwHotkey) { - IShellLinkImpl *This = (IShellLinkImpl *)iface; + IShellLinkImpl *This = (IShellLinkImpl *)iface; - TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey); + TRACE("(%p)->(%p)(0x%08x)\n",This, pwHotkey, This->wHotKey); - *pwHotkey = This->wHotKey; + *pwHotkey = This->wHotKey; - return S_OK; + return S_OK; } static HRESULT WINAPI IShellLinkA_fnSetHotkey(IShellLinkA * iface, WORD wHotkey) { - IShellLinkImpl *This = (IShellLinkImpl *)iface; + IShellLinkImpl *This = (IShellLinkImpl *)iface; - TRACE("(%p)->(hotkey=%x)\n",This, wHotkey); + TRACE("(%p)->(hotkey=%x)\n",This, wHotkey); - This->wHotKey = wHotkey; - This->bDirty = TRUE; + This->wHotKey = wHotkey; + This->bDirty = TRUE; - return S_OK; + return S_OK; } static HRESULT WINAPI IShellLinkA_fnGetShowCmd(IShellLinkA * iface, INT *piShowCmd) @@ -1576,29 +1643,29 @@ static HRESULT WINAPI IShellLinkA_fnSetPath(IShellLinkA * iface, LPCSTR pszFile) * IShellLink Implementation */ -static IShellLinkAVtbl slvt = +static const IShellLinkAVtbl slvt = { - IShellLinkA_fnQueryInterface, - IShellLinkA_fnAddRef, - IShellLinkA_fnRelease, - IShellLinkA_fnGetPath, - IShellLinkA_fnGetIDList, - IShellLinkA_fnSetIDList, - IShellLinkA_fnGetDescription, - IShellLinkA_fnSetDescription, - IShellLinkA_fnGetWorkingDirectory, - IShellLinkA_fnSetWorkingDirectory, - IShellLinkA_fnGetArguments, - IShellLinkA_fnSetArguments, - IShellLinkA_fnGetHotkey, - IShellLinkA_fnSetHotkey, - IShellLinkA_fnGetShowCmd, - IShellLinkA_fnSetShowCmd, - IShellLinkA_fnGetIconLocation, - IShellLinkA_fnSetIconLocation, - IShellLinkA_fnSetRelativePath, - IShellLinkA_fnResolve, - IShellLinkA_fnSetPath + IShellLinkA_fnQueryInterface, + IShellLinkA_fnAddRef, + IShellLinkA_fnRelease, + IShellLinkA_fnGetPath, + IShellLinkA_fnGetIDList, + IShellLinkA_fnSetIDList, + IShellLinkA_fnGetDescription, + IShellLinkA_fnSetDescription, + IShellLinkA_fnGetWorkingDirectory, + IShellLinkA_fnSetWorkingDirectory, + IShellLinkA_fnGetArguments, + IShellLinkA_fnSetArguments, + IShellLinkA_fnGetHotkey, + IShellLinkA_fnSetHotkey, + IShellLinkA_fnGetShowCmd, + IShellLinkA_fnSetShowCmd, + IShellLinkA_fnGetIconLocation, + IShellLinkA_fnSetIconLocation, + IShellLinkA_fnSetRelativePath, + IShellLinkA_fnResolve, + IShellLinkA_fnSetPath }; @@ -1608,9 +1675,8 @@ static IShellLinkAVtbl slvt = static HRESULT WINAPI IShellLinkW_fnQueryInterface( IShellLinkW * iface, REFIID riid, LPVOID *ppvObj) { - _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); - - return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObj); + _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); + return ShellLink_QueryInterface( This, riid, ppvObj ); } /****************************************************************************** @@ -1618,23 +1684,17 @@ static HRESULT WINAPI IShellLinkW_fnQueryInterface( */ static ULONG WINAPI IShellLinkW_fnAddRef(IShellLinkW * iface) { - _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); - - TRACE("(%p)->(count=%lu)\n",This,This->ref); - - return IShellLinkA_AddRef((IShellLinkA*)This); + _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); + return ShellLink_AddRef( This ); } + /****************************************************************************** * IShellLinkW_fnRelease */ - static ULONG WINAPI IShellLinkW_fnRelease(IShellLinkW * iface) { - _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); - - TRACE("(%p)->(count=%lu)\n",This,This->ref); - - return IShellLinkA_Release((IShellLinkA*)This); + _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); + return ShellLink_Release( This ); } static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,INT cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags) @@ -1936,6 +1996,7 @@ static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags) { HRESULT hr = S_OK; + BOOL bSuccess; _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface); @@ -1946,9 +2007,9 @@ static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWOR if (!This->sPath && This->pPidl) { WCHAR buffer[MAX_PATH]; - hr = SHELL_GetPathFromIDListW(This->pPidl, buffer, MAX_PATH); + bSuccess = SHGetPathFromIDListW(This->pPidl, buffer); - if (SUCCEEDED(hr) && *buffer) { + if (bSuccess && *buffer) { This->sPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(buffer)+1)*sizeof(WCHAR)); if (!This->sPath) return E_OUTOFMEMORY; @@ -2118,27 +2179,240 @@ static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile * IShellLinkW Implementation */ -static IShellLinkWVtbl slvtw = +static const IShellLinkWVtbl slvtw = { - IShellLinkW_fnQueryInterface, - IShellLinkW_fnAddRef, - IShellLinkW_fnRelease, - IShellLinkW_fnGetPath, - IShellLinkW_fnGetIDList, - IShellLinkW_fnSetIDList, - IShellLinkW_fnGetDescription, - IShellLinkW_fnSetDescription, - IShellLinkW_fnGetWorkingDirectory, - IShellLinkW_fnSetWorkingDirectory, - IShellLinkW_fnGetArguments, - IShellLinkW_fnSetArguments, - IShellLinkW_fnGetHotkey, - IShellLinkW_fnSetHotkey, - IShellLinkW_fnGetShowCmd, - IShellLinkW_fnSetShowCmd, - IShellLinkW_fnGetIconLocation, - IShellLinkW_fnSetIconLocation, - IShellLinkW_fnSetRelativePath, - IShellLinkW_fnResolve, - IShellLinkW_fnSetPath + IShellLinkW_fnQueryInterface, + IShellLinkW_fnAddRef, + IShellLinkW_fnRelease, + IShellLinkW_fnGetPath, + IShellLinkW_fnGetIDList, + IShellLinkW_fnSetIDList, + IShellLinkW_fnGetDescription, + IShellLinkW_fnSetDescription, + IShellLinkW_fnGetWorkingDirectory, + IShellLinkW_fnSetWorkingDirectory, + IShellLinkW_fnGetArguments, + IShellLinkW_fnSetArguments, + IShellLinkW_fnGetHotkey, + IShellLinkW_fnSetHotkey, + IShellLinkW_fnGetShowCmd, + IShellLinkW_fnSetShowCmd, + IShellLinkW_fnGetIconLocation, + IShellLinkW_fnSetIconLocation, + IShellLinkW_fnSetRelativePath, + IShellLinkW_fnResolve, + IShellLinkW_fnSetPath +}; + +static HRESULT WINAPI +ShellLink_DataList_QueryInterface( IShellLinkDataList* iface, REFIID riid, void** ppvObject) +{ + _ICOM_THIS_From_IShellLinkDataList(IShellLinkImpl, iface); + return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObject); +} + +static ULONG WINAPI +ShellLink_DataList_AddRef( IShellLinkDataList* iface ) +{ + _ICOM_THIS_From_IShellLinkDataList(IShellLinkImpl, iface); + return IShellLinkA_AddRef((IShellLinkA*)This); +} + +static ULONG WINAPI +ShellLink_DataList_Release( IShellLinkDataList* iface ) +{ + _ICOM_THIS_From_IShellLinkDataList(IShellLinkImpl, iface); + return ShellLink_Release( This ); +} + +static HRESULT WINAPI +ShellLink_AddDataBlock( IShellLinkDataList* iface, void* pDataBlock ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI +ShellLink_CopyDataBlock( IShellLinkDataList* iface, DWORD dwSig, void** ppDataBlock ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI +ShellLink_RemoveDataBlock( IShellLinkDataList* iface, DWORD dwSig ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI +ShellLink_GetFlags( IShellLinkDataList* iface, DWORD* pdwFlags ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI +ShellLink_SetFlags( IShellLinkDataList* iface, DWORD dwFlags ) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const IShellLinkDataListVtbl dlvt = +{ + ShellLink_DataList_QueryInterface, + ShellLink_DataList_AddRef, + ShellLink_DataList_Release, + ShellLink_AddDataBlock, + ShellLink_CopyDataBlock, + ShellLink_RemoveDataBlock, + ShellLink_GetFlags, + ShellLink_SetFlags +}; + +static HRESULT WINAPI +ShellLink_ExtInit_QueryInterface( IShellExtInit* iface, REFIID riid, void** ppvObject ) +{ + _ICOM_THIS_From_IShellExtInit(IShellLinkImpl, iface); + return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObject); +} + +static ULONG WINAPI +ShellLink_ExtInit_AddRef( IShellExtInit* iface ) +{ + _ICOM_THIS_From_IShellExtInit(IShellLinkImpl, iface); + return IShellLinkA_AddRef((IShellLinkA*)This); +} + +static ULONG WINAPI +ShellLink_ExtInit_Release( IShellExtInit* iface ) +{ + _ICOM_THIS_From_IShellExtInit(IShellLinkImpl, iface); + return ShellLink_Release( This ); +} + +/************************************************************************** + * ShellLink implementation of IShellExtInit::Initialize() + * + * Loads the shelllink from the dataobject the shell is pointing to. + */ +static HRESULT WINAPI +ShellLink_ExtInit_Initialize( IShellExtInit* iface, LPCITEMIDLIST pidlFolder, + IDataObject *pdtobj, HKEY hkeyProgID ) +{ + _ICOM_THIS_From_IShellExtInit(IShellLinkImpl, iface); + FORMATETC format; + STGMEDIUM stgm; + UINT count; + HRESULT r = E_FAIL; + + TRACE("%p %p %p %p\n", This, pidlFolder, pdtobj, hkeyProgID ); + + if( !pdtobj ) + return r; + + format.cfFormat = CF_HDROP; + format.ptd = NULL; + format.dwAspect = DVASPECT_CONTENT; + format.lindex = -1; + format.tymed = TYMED_HGLOBAL; + + if( FAILED( IDataObject_GetData( pdtobj, &format, &stgm ) ) ) + return r; + + count = DragQueryFileW( stgm.u.hGlobal, -1, NULL, 0 ); + if( count == 1 ) + { + LPWSTR path; + + count = DragQueryFileW( stgm.u.hGlobal, 0, NULL, 0 ); + count++; + path = HeapAlloc( GetProcessHeap(), 0, count*sizeof(WCHAR) ); + if( path ) + { + IPersistFile *pf = (IPersistFile*) &This->lpvtblPersistFile; + + count = DragQueryFileW( stgm.u.hGlobal, 0, path, count ); + r = IPersistFile_Load( pf, path, 0 ); + HeapFree( GetProcessHeap(), 0, path ); + } + } + ReleaseStgMedium( &stgm ); + + return r; +} + +static const IShellExtInitVtbl eivt = +{ + ShellLink_ExtInit_QueryInterface, + ShellLink_ExtInit_AddRef, + ShellLink_ExtInit_Release, + ShellLink_ExtInit_Initialize +}; + +static HRESULT WINAPI +ShellLink_ContextMenu_QueryInterface( IContextMenu* iface, REFIID riid, void** ppvObject ) +{ + _ICOM_THIS_From_IContextMenu(IShellLinkImpl, iface); + return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObject); +} + +static ULONG WINAPI +ShellLink_ContextMenu_AddRef( IContextMenu* iface ) +{ + _ICOM_THIS_From_IContextMenu(IShellLinkImpl, iface); + return IShellLinkA_AddRef((IShellLinkA*)This); +} + +static ULONG WINAPI +ShellLink_ContextMenu_Release( IContextMenu* iface ) +{ + _ICOM_THIS_From_IContextMenu(IShellLinkImpl, iface); + return ShellLink_Release( This ); +} + +static HRESULT WINAPI +ShellLink_QueryContextMenu( IContextMenu* iface, HMENU hmenu, UINT indexMenu, + UINT idCmdFirst, UINT idCmdLast, UINT uFlags ) +{ + _ICOM_THIS_From_IContextMenu(IShellLinkImpl, iface); + + FIXME("%p %p %u %u %u %u\n", This, + hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags ); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +ShellLink_InvokeCommand( IContextMenu* iface, LPCMINVOKECOMMANDINFO lpici ) +{ + _ICOM_THIS_From_IContextMenu(IShellLinkImpl, iface); + + FIXME("%p %p\n", This, lpici ); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +ShellLink_GetCommandString( IContextMenu* iface, UINT idCmd, UINT uType, + UINT* pwReserved, LPSTR pszName, UINT cchMax ) +{ + _ICOM_THIS_From_IContextMenu(IShellLinkImpl, iface); + + FIXME("%p %u %u %p %p %u\n", This, + idCmd, uType, pwReserved, pszName, cchMax ); + + return E_NOTIMPL; +} + +static const IContextMenuVtbl cmvt = +{ + ShellLink_ContextMenu_QueryInterface, + ShellLink_ContextMenu_AddRef, + ShellLink_ContextMenu_Release, + ShellLink_QueryContextMenu, + ShellLink_InvokeCommand, + ShellLink_GetCommandString }; diff --git a/reactos/lib/shell32/shellole.c b/reactos/lib/shell32/shellole.c index e2971039571..e3c3d1bcdfc 100644 --- a/reactos/lib/shell32/shellole.c +++ b/reactos/lib/shell32/shellole.c @@ -276,11 +276,11 @@ DWORD WINAPI SHCLSIDFromStringAW (LPVOID clsid, CLSID *id) */ /* set the vtable later */ -static IMallocVtbl VT_Shell_IMalloc32; +static const IMallocVtbl VT_Shell_IMalloc32; /* this is the static object instance */ typedef struct { - IMallocVtbl *lpVtbl; + const IMallocVtbl *lpVtbl; DWORD dummy; } _ShellMalloc; @@ -384,7 +384,7 @@ static VOID WINAPI IShellMalloc_fnHeapMinimize(LPMALLOC iface) TRACE("()\n"); } -static IMallocVtbl VT_Shell_IMalloc32 = +static const IMallocVtbl VT_Shell_IMalloc32 = { IShellMalloc_fnQueryInterface, IShellMalloc_fnAddRefRelease, @@ -499,7 +499,7 @@ HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf) typedef struct { - IClassFactoryVtbl *lpVtbl; + const IClassFactoryVtbl *lpVtbl; DWORD ref; CLSID *rclsid; LPFNCREATEINSTANCE lpfnCI; @@ -507,7 +507,7 @@ typedef struct ULONG * pcRefDll; /* pointer to refcounter in external dll (ugrrr...) */ } IDefClFImpl; -static IClassFactoryVtbl dclfvt; +static const IClassFactoryVtbl dclfvt; /************************************************************************** * IDefClF_fnConstructor @@ -614,7 +614,7 @@ static HRESULT WINAPI IDefClF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock) return E_NOTIMPL; } -static IClassFactoryVtbl dclfvt = +static const IClassFactoryVtbl dclfvt = { IDefClF_fnQueryInterface, IDefClF_fnAddRef, diff --git a/reactos/lib/shell32/shellord.c b/reactos/lib/shell32/shellord.c index 36dd3e0c56a..a271e5e3592 100644 --- a/reactos/lib/shell32/shellord.c +++ b/reactos/lib/shell32/shellord.c @@ -1354,32 +1354,57 @@ HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z) /************************************************************************ * DoEnvironmentSubstA [SHELL32.@] * + * Replace %KEYWORD% in the str with the value of variable KEYWORD + * from environment. If it is not found the %KEYWORD% is left + * intact. If the buffer is too small, str is not modified. + * + * pszString [I] '\0' terminated string with %keyword%. + * [O] '\0' terminated string with %keyword% substituted. + * cchString [I] size of str. + * + * Return + * cchString length in the HIWORD; + * TRUE in LOWORD if subst was successful and FALSE in other case */ -HRESULT WINAPI DoEnvironmentSubstA(LPSTR x, LPSTR y) +DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString) { - FIXME("(%s, %s) stub\n", debugstr_a(x), debugstr_a(y)); - return 0; + LPSTR dst; + BOOL res = FALSE; + FIXME("(%s, %d) stub\n", debugstr_a(pszString), cchString); + if (pszString == NULL) /* Really return 0? */ + return 0; + if ((dst = HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(CHAR)))) + { + DWORD num = ExpandEnvironmentStringsA(pszString, dst, cchString); + if (num && num < cchString) /* dest buffer is too small */ + { + res = TRUE; + memcpy(pszString, dst, num); + } + HeapFree(GetProcessHeap(), 0, dst); + } + return MAKELONG(res,cchString); /* Always cchString? */ } /************************************************************************ * DoEnvironmentSubstW [SHELL32.@] * */ -HRESULT WINAPI DoEnvironmentSubstW(LPWSTR x, LPWSTR y) +DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString) { - FIXME("(%s, %s): stub\n", debugstr_w(x), debugstr_w(y)); - return 0; + FIXME("(%s, %d): stub\n", debugstr_w(pszString), cchString); + return MAKELONG(FALSE,cchString); } /************************************************************************ * DoEnvironmentSubst [SHELL32.53] * */ -HRESULT WINAPI DoEnvironmentSubstAW(LPVOID x, LPVOID y) +DWORD WINAPI DoEnvironmentSubstAW(LPVOID x, UINT y) { - if (SHELL_OsIsUnicode()) - return DoEnvironmentSubstW(x, y); - return DoEnvironmentSubstA(x, y); + if (SHELL_OsIsUnicode()) + return DoEnvironmentSubstW(x, y); + return DoEnvironmentSubstA(x, y); } /************************************************************************* diff --git a/reactos/lib/shell32/shellpath.c b/reactos/lib/shell32/shellpath.c index 825f7f43f25..534e98ddcb4 100644 --- a/reactos/lib/shell32/shellpath.c +++ b/reactos/lib/shell32/shellpath.c @@ -1240,13 +1240,6 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, * CSIDL_Type_AllUsers: %ALLUSERSPROFILE% * CSIDL_Type_CurrVer: %SystemDrive% * (Others might make sense too, but as yet are unneeded.) - * FIXME: there are two special cases for the default value: - * - the "My Documents" (CSIDL_PERSONAL) entry should be $HOME - * - the CSIDL_DESKTOP and CSIDL_DESKTOPDIRECTORY (which have the same path) - * should be $HOME/Desktop if it exists - * But, $HOME doesn't seem to be inherited into the Wine environment. I could - * use getenv, but this returns me a UNIX path, which may or may not be - * reachable from any currently mounted DOS drives. */ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) { @@ -1261,6 +1254,51 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) if (!pszPath) return E_INVALIDARG; + /* Try special cases first */ + hr = E_FAIL; + switch (folder) + { + case CSIDL_PERSONAL: + { + const char *home = getenv("HOME"); + + /* special case for "My Documents", map to $HOME */ + if (home) + { + WCHAR homeW[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, home, -1, homeW, MAX_PATH); + if (GetFullPathNameW(homeW, MAX_PATH, pszPath, NULL) != 0 && + PathIsDirectoryW(pszPath)) + hr = S_OK; + } + break; + } + case CSIDL_DESKTOP: + case CSIDL_DESKTOPDIRECTORY: + { + const char *home = getenv("HOME"); + + /* special case for Desktop, map to $HOME/Desktop if it exists */ + if (home) + { + WCHAR desktopW[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, home, -1, desktopW, MAX_PATH); + PathAppendW(desktopW, DesktopW); + if (GetFullPathNameW(desktopW, MAX_PATH, pszPath, NULL) != 0 && + PathIsDirectoryW(pszPath)) + hr = S_OK; + } + break; + } + } + if (SUCCEEDED(hr)) + return hr; + + /* Either the folder was unhandled, or a suitable default wasn't found, + * so use one of the resource-based defaults + */ if (CSIDL_Data[folder].szDefaultPath && IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath)) { diff --git a/reactos/lib/shell32/shfldr_desktop.c b/reactos/lib/shell32/shfldr_desktop.c index 82a3836498a..9b564f8ed4f 100644 --- a/reactos/lib/shell32/shfldr_desktop.c +++ b/reactos/lib/shell32/shfldr_desktop.c @@ -60,7 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); */ typedef struct { - IShellFolder2Vtbl *lpVtbl; + const IShellFolder2Vtbl *lpVtbl; DWORD ref; CLSID *pclsid; @@ -69,8 +69,6 @@ typedef struct { LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */ LPITEMIDLIST pidlRoot; /* absolute pidl */ - int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */ - UINT cfShellIDList; /* clipboardformat for IDropTarget */ BOOL fAcceptFmt; /* flag for pending Drop */ } IGenericSFImpl; @@ -429,6 +427,9 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface, { IGenericSFImpl *This = (IGenericSFImpl *)iface; HRESULT hr = S_OK; + const static DWORD dwDesktopAttributes = + SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGE_ANCESTOR | + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER; TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n", This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); @@ -440,13 +441,20 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface, if (*rgfInOut == 0) *rgfInOut = ~0; - - while (cidl > 0 && *apidl) - { - pdump (*apidl); - SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut); - apidl++; - cidl--; + + if(cidl == 0) { + *rgfInOut &= dwDesktopAttributes; + } else { + while (cidl > 0 && *apidl) { + pdump (*apidl); + if (_ILIsDesktop(*apidl)) { + *rgfInOut &= dwDesktopAttributes; + } else { + SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut); + } + apidl++; + cidl--; + } } /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; @@ -808,7 +816,7 @@ static HRESULT WINAPI ISF_Desktop_fnMapColumnToSCID ( return E_NOTIMPL; } -static IShellFolder2Vtbl vt_MCFldr_ShellFolder2 = +static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 = { ISF_Desktop_fnQueryInterface, ISF_Desktop_fnAddRef, diff --git a/reactos/lib/shell32/shfldr_fs.c b/reactos/lib/shell32/shfldr_fs.c index 5060c4705ad..c99a34304ff 100644 --- a/reactos/lib/shell32/shfldr_fs.c +++ b/reactos/lib/shell32/shfldr_fs.c @@ -60,12 +60,12 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); */ typedef struct { - IUnknownVtbl *lpVtbl; + const IUnknownVtbl *lpVtbl; DWORD ref; - IShellFolder2Vtbl *lpvtblShellFolder; - IPersistFolder3Vtbl *lpvtblPersistFolder3; - IDropTargetVtbl *lpvtblDropTarget; - ISFHelperVtbl *lpvtblSFHelper; + const IShellFolder2Vtbl *lpvtblShellFolder; + const IPersistFolder3Vtbl *lpvtblPersistFolder3; + const IDropTargetVtbl *lpvtblDropTarget; + const ISFHelperVtbl *lpvtblSFHelper; IUnknown *pUnkOuter; /* used for aggregation */ @@ -76,17 +76,15 @@ typedef struct { LPITEMIDLIST pidlRoot; /* absolute pidl */ - int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */ - UINT cfShellIDList; /* clipboardformat for IDropTarget */ BOOL fAcceptFmt; /* flag for pending Drop */ } IGenericSFImpl; -static struct IUnknownVtbl unkvt; -static struct IShellFolder2Vtbl sfvt; -static struct IPersistFolder3Vtbl vt_FSFldr_PersistFolder3; /* IPersistFolder3 for a FS_Folder */ -static struct IDropTargetVtbl dtvt; -static struct ISFHelperVtbl shvt; +static const IUnknownVtbl unkvt; +static const IShellFolder2Vtbl sfvt; +static const IPersistFolder3Vtbl vt_FSFldr_PersistFolder3; /* IPersistFolder3 for a FS_Folder */ +static const IDropTargetVtbl dtvt; +static const ISFHelperVtbl shvt; #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder))) #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset); @@ -199,7 +197,7 @@ static ULONG WINAPI IUnknown_fnRelease (IUnknown * iface) return refCount; } -static IUnknownVtbl unkvt = +static const IUnknownVtbl unkvt = { IUnknown_fnQueryInterface, IUnknown_fnAddRef, @@ -587,11 +585,21 @@ IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, if (*rgfInOut == 0) *rgfInOut = ~0; - while (cidl > 0 && *apidl) { - pdump (*apidl); - SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut); - apidl++; - cidl--; + if(cidl == 0){ + IShellFolder *psfParent = NULL; + LPCITEMIDLIST rpidl = NULL; + + hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&rpidl); + if(SUCCEEDED(hr)) + SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut); + } + else { + while (cidl > 0 && *apidl) { + pdump (*apidl); + SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut); + apidl++; + cidl--; + } } /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; @@ -972,7 +980,7 @@ IShellFolder_fnMapColumnToSCID (IShellFolder2 * iface, UINT column, return E_NOTIMPL; } -static IShellFolder2Vtbl sfvt = +static const IShellFolder2Vtbl sfvt = { IShellFolder_fnQueryInterface, IShellFolder_fnAddRef, @@ -1042,7 +1050,7 @@ ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName, UINT uLen) IEnumIDList *penum; HRESULT hr; char szText[MAX_PATH]; - char *szNewFolder = "New Folder"; + const char *szNewFolder = "New Folder"; TRACE ("(%p)(%s %u)\n", This, lpName, uLen); @@ -1224,7 +1232,7 @@ ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, return S_OK; } -static ISFHelperVtbl shvt = +static const ISFHelperVtbl shvt = { ISFHelper_fnQueryInterface, ISFHelper_fnAddRef, @@ -1412,7 +1420,7 @@ IFSFldr_PersistFolder3_GetFolderTargetInfo (IPersistFolder3 * iface, return E_NOTIMPL; } -static IPersistFolder3Vtbl vt_FSFldr_PersistFolder3 = +static const IPersistFolder3Vtbl vt_FSFldr_PersistFolder3 = { IFSFldr_PersistFolder3_QueryInterface, IFSFldr_PersistFolder3_AddRef, @@ -1534,7 +1542,7 @@ ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject, return E_NOTIMPL; } -static struct IDropTargetVtbl dtvt = { +static const IDropTargetVtbl dtvt = { ISFDropTarget_QueryInterface, ISFDropTarget_AddRef, ISFDropTarget_Release, diff --git a/reactos/lib/shell32/shfldr_mycomp.c b/reactos/lib/shell32/shfldr_mycomp.c index 98b5d62fbf8..1181030b31f 100644 --- a/reactos/lib/shell32/shfldr_mycomp.c +++ b/reactos/lib/shell32/shfldr_mycomp.c @@ -55,17 +55,16 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell); */ typedef struct { - IShellFolder2Vtbl *lpVtbl; + const IShellFolder2Vtbl *lpVtbl; DWORD ref; - IPersistFolder2Vtbl *lpVtblPersistFolder2; + const IPersistFolder2Vtbl *lpVtblPersistFolder2; /* both paths are parsible from the desktop */ LPITEMIDLIST pidlRoot; /* absolute pidl */ - int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */ } IGenericSFImpl; -static struct IShellFolder2Vtbl vt_ShellFolder2; -static struct IPersistFolder2Vtbl vt_PersistFolder2; +static const IShellFolder2Vtbl vt_ShellFolder2; +static const IPersistFolder2Vtbl vt_PersistFolder2; #define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2))) #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset); @@ -85,7 +84,7 @@ static struct IPersistFolder2Vtbl vt_PersistFolder2; * IShellFolder [MyComputer] implementation */ -static shvheader MyComputerSFHeader[] = { +static const shvheader MyComputerSFHeader[] = { {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15}, {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, {IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, @@ -438,13 +437,21 @@ static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface, if (*rgfInOut == 0) *rgfInOut = ~0; + + if(cidl == 0){ + IShellFolder *psfParent = NULL; + LPCITEMIDLIST rpidl = NULL; - while (cidl > 0 && *apidl) - { - pdump (*apidl); - SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut); - apidl++; - cidl--; + hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&rpidl); + if(SUCCEEDED(hr)) + SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut); + } else { + while (cidl > 0 && *apidl) { + pdump (*apidl); + SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut); + apidl++; + cidl--; + } } /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ *rgfInOut &= ~SFGAO_VALIDATE; @@ -815,7 +822,7 @@ static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID ( return E_NOTIMPL; } -static IShellFolder2Vtbl vt_ShellFolder2 = +static const IShellFolder2Vtbl vt_ShellFolder2 = { ISF_MyComputer_fnQueryInterface, ISF_MyComputer_fnAddRef, @@ -923,7 +930,7 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder ( return S_OK; } -static IPersistFolder2Vtbl vt_PersistFolder2 = +static const IPersistFolder2Vtbl vt_PersistFolder2 = { IMCFldr_PersistFolder2_QueryInterface, IMCFldr_PersistFolder2_AddRef, diff --git a/reactos/lib/shell32/shlexec.c b/reactos/lib/shell32/shlexec.c index 936d9beeb4f..c6ff531d62c 100644 --- a/reactos/lib/shell32/shlexec.c +++ b/reactos/lib/shell32/shlexec.c @@ -296,7 +296,7 @@ static HRESULT SHELL_ResolveShortCutW(LPWSTR wcmd, LPWSTR wargs, LPWSTR wdir, HW if (SUCCEEDED(hr) && *ppidl) { /* We got a PIDL instead of a file system path - try to translate it. */ - if (SUCCEEDED(SHELL_GetPathFromIDListW(*ppidl, wcmd, MAX_PATH))) { + if (SHGetPathFromIDListW(*ppidl, wcmd)) { SHFree(*ppidl); *ppidl = NULL; } diff --git a/reactos/lib/shell32/shlfolder.c b/reactos/lib/shell32/shlfolder.c index 17d98f2f818..6992d7e2cac 100644 --- a/reactos/lib/shell32/shlfolder.c +++ b/reactos/lib/shell32/shlfolder.c @@ -70,14 +70,26 @@ static const WCHAR wszDotShellClassInfo[] = { * TRUE if returned non-NULL value. * FALSE otherwise. */ -BOOL SHELL32_GetCustomFolderAttribute( - LPCITEMIDLIST pidl, LPCWSTR pwszHeading, LPCWSTR pwszAttribute, +static inline BOOL SHELL32_GetCustomFolderAttributeFromPath( + LPWSTR pwszFolderPath, LPCWSTR pwszHeading, LPCWSTR pwszAttribute, LPWSTR pwszValue, DWORD cchValue) { static const WCHAR wszDesktopIni[] = {'d','e','s','k','t','o','p','.','i','n','i',0}; static const WCHAR wszDefault[] = {0}; + + PathAddBackslashW(pwszFolderPath); + PathAppendW(pwszFolderPath, wszDesktopIni); + return GetPrivateProfileStringW(pwszHeading, pwszAttribute, wszDefault, + pwszValue, cchValue, pwszFolderPath); +} + +BOOL SHELL32_GetCustomFolderAttribute( + LPCITEMIDLIST pidl, LPCWSTR pwszHeading, LPCWSTR pwszAttribute, + LPWSTR pwszValue, DWORD cchValue) +{ DWORD dwAttrib = FILE_ATTRIBUTE_SYSTEM; + WCHAR wszFolderPath[MAX_PATH]; /* Hack around not having system attribute on non-Windows file systems */ if (0) @@ -85,20 +97,15 @@ BOOL SHELL32_GetCustomFolderAttribute( if (dwAttrib & FILE_ATTRIBUTE_SYSTEM) { - DWORD ret; - WCHAR wszDesktopIniPath[MAX_PATH]; - - if (!SHGetPathFromIDListW(pidl, wszDesktopIniPath)) + if (!SHGetPathFromIDListW(pidl, wszFolderPath)) return FALSE; - PathAppendW(wszDesktopIniPath, wszDesktopIni); - ret = GetPrivateProfileStringW(pwszHeading, pwszAttribute, - wszDefault, pwszValue, cchValue, wszDesktopIniPath); - return ret; + + return SHELL32_GetCustomFolderAttributeFromPath(wszFolderPath, pwszHeading, + pwszAttribute, pwszValue, cchValue); } return FALSE; } - /*************************************************************************** * GetNextElement (internal function) * @@ -239,54 +246,70 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot, } /*********************************************************************** - * SHELL32_BindToChild + * SHELL32_BindToChild [Internal] * * Common code for IShellFolder_BindToObject. - * Creates a shell folder by binding to a root pidl. + * + * PARAMS + * pidlRoot [I] The parent shell folder's absolute pidl. + * pathRoot [I] Absolute dos path of the parent shell folder. + * pidlComplete [I] PIDL of the child. Relative to pidlRoot. + * riid [I] GUID of the interface, which ppvOut shall be bound to. + * ppvOut [O] A reference to the child's interface (riid). + * + * NOTES + * pidlComplete has to contain at least one non empty SHITEMID. + * This function makes special assumptions on the shell namespace, which + * means you probably can't use it for your IShellFolder implementation. */ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, - LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) + LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut) { GUID const *clsid; IShellFolder *pSF; HRESULT hr; LPITEMIDLIST pidlChild; - if (!pidlRoot || !ppvOut) - return E_INVALIDARG; + if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb) + return E_INVALIDARG; *ppvOut = NULL; pidlChild = ILCloneFirst (pidlComplete); if ((clsid = _ILGetGUIDPointer (pidlChild))) { - /* virtual folder */ - hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsid, &IID_IShellFolder, (LPVOID *) & pSF); + /* virtual folder */ + hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, clsid, &IID_IShellFolder, (LPVOID *) & pSF); } else { /* file system folder */ CLSID clsidFolder = CLSID_ShellFSFolder; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; - WCHAR wszCLSIDValue[CHARS_IN_GUID]; - LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild); + WCHAR wszCLSIDValue[CHARS_IN_GUID], wszFolderPath[MAX_PATH], *pwszPathTail = wszFolderPath; + /* see if folder CLSID should be overridden by desktop.ini file */ - if (SHELL32_GetCustomFolderAttribute (pidlAbsolute, + if (pathRoot) { + MultiByteToWideChar(CP_ACP, 0, pathRoot, -1, wszFolderPath, MAX_PATH); + pwszPathTail = PathAddBackslashW(wszFolderPath); + } + MultiByteToWideChar(CP_ACP, 0, _ILGetTextPointer(pidlChild), -1, pwszPathTail, MAX_PATH); + if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath, wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID)) CLSIDFromString (wszCLSIDValue, &clsidFolder); - ILFree (pidlAbsolute); - hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, + + hr = SHELL32_CoCreateInitSF (pidlRoot, pathRoot, pidlChild, &clsidFolder, &IID_IShellFolder, (LPVOID *)&pSF); } ILFree (pidlChild); if (SUCCEEDED (hr)) { - if (_ILIsPidlSimple (pidlComplete)) { - /* no sub folders */ - hr = IShellFolder_QueryInterface (pSF, riid, ppvOut); - } else { - /* go deeper */ - hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut); - } - IShellFolder_Release (pSF); + if (_ILIsPidlSimple (pidlComplete)) { + /* no sub folders */ + hr = IShellFolder_QueryInterface (pSF, riid, ppvOut); + } else { + /* go deeper */ + hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut); + } + IShellFolder_Release (pSF); } TRACE ("-- returning (%p) %08lx\n", *ppvOut, hr); @@ -361,9 +384,9 @@ HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, */ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { - GUID const *clsid; DWORD dwAttributes; - DWORD dwSupportedAttr=SFGAO_CANCOPY | /*0x00000001 */ + static const DWORD dwSupportedAttr= + SFGAO_CANCOPY | /*0x00000001 */ SFGAO_CANMOVE | /*0x00000002 */ SFGAO_CANLINK | /*0x00000004 */ SFGAO_CANRENAME | /*0x00000010 */ @@ -387,12 +410,12 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO } if (_ILIsDrive (pidl)) { - *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; - } else if ((clsid = _ILGetGUIDPointer (pidl))) { - if (HCR_GetFolderAttributes (clsid, &dwAttributes)) { - *pdwAttributes &= dwAttributes; - } else { - *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK; + *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| + SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; + } else if (_ILGetGUIDPointer (pidl)) { + if (!HCR_GetFolderAttributes (pidl, pdwAttributes)) { + *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| + SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK; } } else if (_ILGetDataPointer (pidl)) { dwAttributes = _ILGetFileAttributes (pidl, NULL, 0); diff --git a/reactos/lib/shell32/shlfsbind.c b/reactos/lib/shell32/shlfsbind.c index 17ff2301948..1660a587413 100644 --- a/reactos/lib/shell32/shlfsbind.c +++ b/reactos/lib/shell32/shlfsbind.c @@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(pidl); */ typedef struct { - IFileSystemBindDataVtbl *lpVtbl; + const IFileSystemBindDataVtbl *lpVtbl; DWORD ref; WIN32_FIND_DATAW findFile; } IFileSystemBindDataImpl; @@ -53,7 +53,7 @@ static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *); static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *, WIN32_FIND_DATAW *); static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *, const WIN32_FIND_DATAW *); -static struct IFileSystemBindDataVtbl sbvt = +static const IFileSystemBindDataVtbl sbvt = { IFileSystemBindData_fnQueryInterface, IFileSystemBindData_fnAddRef, diff --git a/reactos/lib/shell32/shlmenu.c b/reactos/lib/shell32/shlmenu.c index ea245f2a864..527d8a21349 100644 --- a/reactos/lib/shell32/shlmenu.c +++ b/reactos/lib/shell32/shlmenu.c @@ -75,8 +75,9 @@ static BOOL bAbortInit; WINE_DEFAULT_DEBUG_CHANNEL(shell); -LPFMINFO FM_GetMenuInfo(HMENU hmenu) -{ MENUINFO MenuInfo; +static LPFMINFO FM_GetMenuInfo(HMENU hmenu) +{ + MENUINFO MenuInfo; LPFMINFO menudata; MenuInfo.cbSize = sizeof(MENUINFO); @@ -410,6 +411,7 @@ BOOL WINAPI FileMenu_AppendItemAW( return ret; } + /************************************************************************* * FileMenu_InsertUsingPidl [SHELL32.110] * @@ -828,16 +830,16 @@ void WINAPI FileMenu_AbortInitMenu (void) * or NULL at failure. */ LPVOID WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x) -{ FIXME("hmenu=%p hwnd=%p 0x%08lx 0x%08lx stub\n", +{ + FIXME("hmenu=%p hwnd=%p 0x%08lx 0x%08lx stub\n", hMenu,hWndParent,w,x); return NULL; /* this is supposed to be a pointer */ } /************************************************************************* - * Shell_MergeMenus [SHELL32.67] - * + * _SHIsMenuSeparator (internal) */ -BOOL _SHIsMenuSeparator(HMENU hm, int i) +static BOOL _SHIsMenuSeparator(HMENU hm, int i) { MENUITEMINFOW mii; @@ -857,8 +859,9 @@ BOOL _SHIsMenuSeparator(HMENU hm, int i) return(FALSE); } -/**********************************************************************/ - +/************************************************************************* + * Shell_MergeMenus [SHELL32.67] + */ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags) { int nItem; HMENU hmSubMenu; diff --git a/reactos/lib/shell32/shlview.c b/reactos/lib/shell32/shlview.c index 0634a4ffc8f..3514bb72ee7 100644 --- a/reactos/lib/shell32/shlview.c +++ b/reactos/lib/shell32/shlview.c @@ -76,12 +76,12 @@ typedef struct typedef struct { - IShellViewVtbl* lpVtbl; + const IShellViewVtbl* lpVtbl; DWORD ref; - IOleCommandTargetVtbl* lpvtblOleCommandTarget; - IDropTargetVtbl* lpvtblDropTarget; - IDropSourceVtbl* lpvtblDropSource; - IViewObjectVtbl* lpvtblViewObject; + const IOleCommandTargetVtbl* lpvtblOleCommandTarget; + const IDropTargetVtbl* lpvtblDropTarget; + const IDropSourceVtbl* lpvtblDropSource; + const IViewObjectVtbl* lpvtblViewObject; IShellFolder* pSFParent; IShellFolder2* pSF2Parent; IShellBrowser* pShellBrowser; @@ -102,21 +102,20 @@ typedef struct IAdviseSink *pAdvSink; } IShellViewImpl; -static struct IShellViewVtbl svvt; - -static struct IOleCommandTargetVtbl ctvt; +static const IShellViewVtbl svvt; +static const IOleCommandTargetVtbl ctvt; #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget))) #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset); -static struct IDropTargetVtbl dtvt; +static const IDropTargetVtbl dtvt; #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget))) #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset); -static struct IDropSourceVtbl dsvt; +static const IDropSourceVtbl dsvt; #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource))) #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset); -static struct IViewObjectVtbl vovt; +static const IViewObjectVtbl vovt; #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject))) #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset); @@ -141,9 +140,6 @@ static struct IViewObjectVtbl vovt; #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) -extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition, - UINT wID, UINT fType, LPSTR dwTypeData, UINT fState); - /* Items merged into the toolbar and and the filemenu */ @@ -1992,7 +1988,7 @@ static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, return S_OK; } -static struct IShellViewVtbl svvt = +static const IShellViewVtbl svvt = { IShellView_fnQueryInterface, IShellView_fnAddRef, @@ -2104,7 +2100,7 @@ static HRESULT WINAPI ISVOleCmdTarget_Exec( return OLECMDERR_E_UNKNOWNGROUP; } -static IOleCommandTargetVtbl ctvt = +static const IOleCommandTargetVtbl ctvt = { ISVOleCmdTarget_QueryInterface, ISVOleCmdTarget_AddRef, @@ -2199,7 +2195,7 @@ static HRESULT WINAPI ISVDropTarget_Drop( return E_NOTIMPL; } -static struct IDropTargetVtbl dtvt = +static const IDropTargetVtbl dtvt = { ISVDropTarget_QueryInterface, ISVDropTarget_AddRef, @@ -2269,7 +2265,7 @@ static HRESULT WINAPI ISVDropSource_GiveFeedback( return DRAGDROP_S_USEDEFAULTCURSORS; } -static struct IDropSourceVtbl dsvt = +static const IDropSourceVtbl dsvt = { ISVDropSource_QueryInterface, ISVDropSource_AddRef, @@ -2418,7 +2414,7 @@ static HRESULT WINAPI ISVViewObject_GetAdvise( } -static struct IViewObjectVtbl vovt = +static const IViewObjectVtbl vovt = { ISVViewObject_QueryInterface, ISVViewObject_AddRef, diff --git a/reactos/lib/shell32/shv_bg_cmenu.c b/reactos/lib/shell32/shv_bg_cmenu.c index 2244626ab83..54dd9e8532e 100644 --- a/reactos/lib/shell32/shv_bg_cmenu.c +++ b/reactos/lib/shell32/shv_bg_cmenu.c @@ -43,14 +43,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); */ typedef struct { - IContextMenu2Vtbl *lpVtbl; + const IContextMenu2Vtbl *lpVtbl; IShellFolder* pSFParent; DWORD ref; BOOL bDesktop; } BgCmImpl; -static struct IContextMenu2Vtbl cmvt; +static const IContextMenu2Vtbl cmvt; /************************************************************************** * ISVBgCm_Constructor() @@ -445,7 +445,7 @@ static HRESULT WINAPI ISVBgCm_fnHandleMenuMsg( * IContextMenu2 VTable * */ -static struct IContextMenu2Vtbl cmvt = +static const IContextMenu2Vtbl cmvt = { ISVBgCm_fnQueryInterface, ISVBgCm_fnAddRef, diff --git a/reactos/lib/shell32/shv_item_cmenu.c b/reactos/lib/shell32/shv_item_cmenu.c index 689cfbdbd9c..5516c1d32bb 100644 --- a/reactos/lib/shell32/shv_item_cmenu.c +++ b/reactos/lib/shell32/shv_item_cmenu.c @@ -43,7 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); * IContextMenu Implementation */ typedef struct -{ IContextMenu2Vtbl *lpVtbl; +{ const IContextMenu2Vtbl *lpVtbl; DWORD ref; IShellFolder* pSFParent; LPITEMIDLIST pidl; /* root pidl */ @@ -53,7 +53,7 @@ typedef struct } ItemCmImpl; -static struct IContextMenu2Vtbl cmvt; +static const IContextMenu2Vtbl cmvt; /************************************************************************** * ISvItemCm_CanRenameItems() @@ -186,7 +186,7 @@ void WINAPI _InsertMenuItem ( BOOL fByPosition, UINT wID, UINT fType, - LPSTR dwTypeData, + LPCSTR dwTypeData, UINT fState) { MENUITEMINFOA mii; @@ -200,7 +200,7 @@ void WINAPI _InsertMenuItem ( else { mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; - mii.dwTypeData = dwTypeData; + mii.dwTypeData = (LPSTR) dwTypeData; mii.fState = fState; } mii.wID = wID; @@ -535,7 +535,7 @@ static HRESULT WINAPI ISvItemCm_fnHandleMenuMsg( return E_NOTIMPL; } -static struct IContextMenu2Vtbl cmvt = +static const IContextMenu2Vtbl cmvt = { ISvItemCm_fnQueryInterface, ISvItemCm_fnAddRef, diff --git a/reactos/lib/shell32/systray.c b/reactos/lib/shell32/systray.c index 714ef7727b1..2dbe589cabd 100644 --- a/reactos/lib/shell32/systray.c +++ b/reactos/lib/shell32/systray.c @@ -157,7 +157,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam, } -BOOL SYSTRAY_RegisterClass(void) +static BOOL SYSTRAY_RegisterClass(void) { WNDCLASSA wc; @@ -180,7 +180,7 @@ BOOL SYSTRAY_RegisterClass(void) } -BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem) +static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem) { RECT rect; @@ -237,13 +237,13 @@ static void SYSTRAY_ItemTerm(SystrayItem *ptrayItem) } -void SYSTRAY_ItemSetMessage(SystrayItem *ptrayItem, UINT uCallbackMessage) +static void SYSTRAY_ItemSetMessage(SystrayItem *ptrayItem, UINT uCallbackMessage) { ptrayItem->notifyIcon.uCallbackMessage = uCallbackMessage; } -void SYSTRAY_ItemSetIcon(SystrayItem *ptrayItem, HICON hIcon) +static void SYSTRAY_ItemSetIcon(SystrayItem *ptrayItem, HICON hIcon) { if(ptrayItem->notifyIcon.hIcon) DestroyIcon(ptrayItem->notifyIcon.hIcon); @@ -252,7 +252,7 @@ void SYSTRAY_ItemSetIcon(SystrayItem *ptrayItem, HICON hIcon) } -void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify) +static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify) { TTTOOLINFOA ti;