Vitaliy Margolen wine-patch@kievinfo.com - Michael Jung mjung@iss.tu-darmstadt.de Set all capability flags supported by the shellfolder, disregarding the flag mask given to GetAttributesOf. Unit tests to demonstrate this behaviour. Michael Jung mjung@iss.tu-darmstadt.de - Added some comments to document unixfs. - Fixed crash in unixfs shellfolder handling with winamp. - Implemented UnixFolder's IPersistPropertyBag::Load method. - Initialize COM prior to displaying the SHBrowseForFolder dialog. - More robust code for querying ShellFolder attributes (some ShellFolders ignore the flag mask in GetAttributesOf). - Remove iconcache pre-initialization hack, it's not necessary any more. - Move target folder initialization to a dedicated function. - Use this function in BindToObject (should be faster). - Special handling for FolderShortcut objects in Initialize method. - Removed a todo_wine from a no longer failing unit test. - Replaced tabs with spaces. Robert Shearman rob@codeweavers.com - Convert SHELL32_BindToChild to Unicode and fix up the callers. Vincent Bén vberon@mecano.gme.usherb.ca - Unicodify systray.c. - Move functions a bit to get rid of a static declaration. Dmitry Timoshkov dmitry@codeweavers.com - Correctly handle flags parameter in SHAddToRecentDocs. Martin Fuchs martin-fuchs@gmx.net - Correct WINAPI position for MSVC portability. Mike McCormack mike@codeweavers.com - Partially implement and test the shelllink object's IShellLinkDataList::CopyDataBlock and GetFlags methods. - Use advapi32.CommandLineFromMsiDescriptor to get msi component paths. - Pass the correct verb. Add a space between extra parameters. Wait for ShellExecute to complete. - Handle MSI advertised shortcuts in the shelllink object. - Implement IContextMenu::QueryContextMenu and IContextMenu::InvokeCommand. - Add the IObjectWithSite interface. - Invoke shortcuts through IContextMenu, rather than trying to access them directly. - Fix a problem spotted by Dmitry and another one stopping correctly formatted lnk files from being generated. Modified: trunk/reactos/bootdata/hivecls.inf Modified: trunk/reactos/include/wine/shobjidl.h Modified: trunk/reactos/lib/shell32/Makefile.in Modified: trunk/reactos/lib/shell32/brsfolder.c Modified: trunk/reactos/lib/shell32/cpanelfolder.c Modified: trunk/reactos/lib/shell32/enumidlist.c Modified: trunk/reactos/lib/shell32/iconcache.c Modified: trunk/reactos/lib/shell32/pidl.c Modified: trunk/reactos/lib/shell32/shell.c Modified: trunk/reactos/lib/shell32/shell32_main.h Modified: trunk/reactos/lib/shell32/shelllink.c Modified: trunk/reactos/lib/shell32/shellole.c Modified: trunk/reactos/lib/shell32/shellord.c Modified: trunk/reactos/lib/shell32/shellpath.c Modified: trunk/reactos/lib/shell32/shellstring.c Modified: trunk/reactos/lib/shell32/shfldr.h Modified: trunk/reactos/lib/shell32/shfldr_desktop.c Modified: trunk/reactos/lib/shell32/shfldr_fs.c Modified: trunk/reactos/lib/shell32/shfldr_mycomp.c Modified: trunk/reactos/lib/shell32/shlexec.c Modified: trunk/reactos/lib/shell32/shlfileop.c Modified: trunk/reactos/lib/shell32/shlfolder.c Modified: trunk/reactos/lib/shell32/shlmenu.c Modified: trunk/reactos/lib/shell32/systray.c Added: trunk/reactos/w32api/include/appmgmt.h Modified: trunk/reactos/w32api/include/shlobj.h _____
Modified: trunk/reactos/bootdata/hivecls.inf --- trunk/reactos/bootdata/hivecls.inf 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/bootdata/hivecls.inf 2005-11-20 08:41:46 UTC (rev 19356) @@ -21,6 +21,7 @@
HKCR,"lnkfile","IsShortcut",0x00000000,"yes"
HKCR,"lnkfile\CLSID","",0x00000000,"{00021401-0000-0000-C000-00000000004 6}"
HKCR,"lnkfile\shellex\IconHandler","",0x00000000,"{00021401-0000-0000-C0 00-000000000046}" +HKCR,lnkfile\shellex\ContextMenuHandlers{00021401-0000-0000-C000-00000 0000046},,,
; shell command files (e.g. "Show Desktop" in quicklaunch bar) HKCR,".scf","",0x00000000,"SHCmdFile" _____
Modified: trunk/reactos/include/wine/shobjidl.h --- trunk/reactos/include/wine/shobjidl.h 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/include/wine/shobjidl.h 2005-11-20 08:41:46 UTC (rev 19356) @@ -43,4 +43,13 @@
/*** IShellExecuteHookW methods ***/ #define IShellExecuteHookW_Execute(p,a) (p)->lpVtbl->Execute(p,a)
+#ifdef COBJMACROS +/*** IUnknown methods ***/ +#define IShellExtInit_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IShellExtInit_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IShellExtInit_Release(p) (p)->lpVtbl->Release(p) +/*** IShellExtInit methods ***/ +#define IShellExtInit_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c) +#endif + #endif /* __WINE_SHOBJIDL_H */ _____
Modified: trunk/reactos/lib/shell32/Makefile.in --- trunk/reactos/lib/shell32/Makefile.in 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/Makefile.in 2005-11-20 08:41:46 UTC (rev 19356) @@ -6,7 +6,7 @@
MODULE = shell32.dll IMPORTLIB = libshell32.$(IMPLIBEXT) IMPORTS = shlwapi comctl32 user32 gdi32 advapi32 kernel32 ntdll -DELAYIMPORTS = ole32 +DELAYIMPORTS = ole32 oleaut32 EXTRALIBS = -luuid $(LIBUNICODE)
C_SRCS = \ _____
Modified: trunk/reactos/lib/shell32/brsfolder.c --- trunk/reactos/lib/shell32/brsfolder.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/brsfolder.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -388,7 +388,7 @@
dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM; r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes); - if (FAILED(r) || !dwAttributes) + if (FAILED(r) || !(dwAttributes & (SFGAO_FILESYSANCESTOR|SFGAO_FILESYSTEM))) bEnabled = FALSE; } if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS) @@ -396,8 +396,11 @@ dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM; r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes); - if (FAILED(r) || (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM))) + if (FAILED(r) || + ((dwAttributes & (SFGAO_FOLDER|SFGAO_FILESYSTEM)) != (SFGAO_FOLDER|SFGAO_FILESYSTEM))) + { bEnabled = FALSE; + } } SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled); } @@ -662,21 +665,25 @@
/*********************************************************************** ** * SHBrowseForFolderW [SHELL32.@] * - * NOTES: + * NOTES * crashes when passed a null pointer */ LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi) { browse_info info; DWORD r; + HRESULT hr;
info.hWnd = 0; info.pidlRet = NULL; info.lpBrowseInfo = lpbi; info.hwndTreeView = NULL;
+ hr = CoInitialize(NULL); r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner, BrsFolderDlgProc, (LPARAM)&info ); + if (SUCCEEDED(hr)) + CoUninitialize(); if (!r) return NULL;
_____
Modified: trunk/reactos/lib/shell32/cpanelfolder.c --- trunk/reactos/lib/shell32/cpanelfolder.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/cpanelfolder.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -410,7 +410,7 @@
WIN32_FIND_DATAA wfd; HANDLE hFile;
- TRACE("(%p)->(flags=0x%08lx) \n",iface,dwFlags); + TRACE("(%p)->(flags=0x%08lx)\n", iface, dwFlags);
/* enumerate control panel folders folders */ if (dwFlags & SHCONTF_FOLDERS) _____
Modified: trunk/reactos/lib/shell32/enumidlist.c --- trunk/reactos/lib/shell32/enumidlist.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/enumidlist.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -116,7 +116,7 @@
static const WCHAR dot[] = { '.',0 }; static const WCHAR dotdot[] = { '.','.',0 };
- TRACE("(%p)->(path=%s flags=0x%08lx) \n",list,debugstr_w(lpszPath),dwFlags); + TRACE("(%p)->(path=%s flags=0x%08lx)\n", list, debugstr_w(lpszPath), dwFlags);
if(!lpszPath || !lpszPath[0]) return FALSE;
_____
Modified: trunk/reactos/lib/shell32/iconcache.c --- trunk/reactos/lib/shell32/iconcache.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/iconcache.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -365,7 +365,7 @@
if ( INVALID_INDEX == index ) { - ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags); + ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags); } else { @@ -378,15 +378,10 @@ }
/*********************************************************************** ****** * SIC_Initialize [internal] - * - * NOTES - * hack to load the resources from the shell32.dll under a different dll name - * will be removed when the resource-compiler is ready */ BOOL SIC_Initialize(void) { HICON hSm, hLg; - UINT index; int cx_small, cy_small; int cx_large, cy_large;
@@ -407,29 +402,27 @@ return(FALSE); }
- ShellSmallIconList = ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,0x20); - ShellBigIconList = ImageList_Create(32,32,ILC_COLOR32|ILC_MASK,0,0x20); + ShellSmallIconList = ImageList_Create(cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20); + ShellBigIconList = ImageList_Create(cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20);
- ImageList_SetBkColor(ShellSmallIconList, CLR_NONE); - ImageList_SetBkColor(ShellBigIconList, CLR_NONE); + ImageList_SetBkColor(ShellSmallIconList, CLR_NONE); + ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
- /* - * Wine will extract and cache all shell32 icons here. That's because - * they are unable to extract resources from their built-in DLLs. - * We don't need that, but we still want to make sure that the very - * first icon in the image lists is icon 1 from shell32.dll, since - * that's the default icon. - */ - index = 1; - hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_small, cy_small, LR_SHARED); - hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_large, cy_large, LR_SHARED); + /* Load the document icon, which is used as the default if an icon isn't found. */ + hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), + IMAGE_ICON, cx_small, cy_small, LR_SHARED); + hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT), + IMAGE_ICON, cx_large, cy_large, LR_SHARED);
- if(hSm) - { - SIC_IconAppend (swShell32Name, index - 1, hSm, hLg, 0); - SIC_IconAppend (swShell32Name, -index, hSm, hLg, 0); - } + if (!hSm || !hLg) + { + FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n"); + return FALSE; + }
+ SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); + SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); + TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
return TRUE; _____
Modified: trunk/reactos/lib/shell32/pidl.c --- trunk/reactos/lib/shell32/pidl.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/pidl.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -254,7 +254,7 @@
DWORD len; LPITEMIDLIST pidlNew = NULL;
- TRACE("pidl=%p \n",pidl); + TRACE("pidl=%p\n", pidl); pdump(pidl);
if (pidl) @@ -885,6 +885,9 @@ * PARAMS * pidl [I] * + * RETURNS + * Nothing + * * NOTES * exported by ordinal */ @@ -903,6 +906,9 @@ * PARAMS * pidl [I] * + * RETURNS + * Nothing + * * NOTES * exported by ordinal. */ @@ -941,6 +947,8 @@
/*********************************************************************** ** * ILCreateFromPathW [SHELL32.190] + * + * See ILCreateFromPathA. */ LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path) { @@ -1238,6 +1246,8 @@
/*********************************************************************** ** * SHGetPathFromIDListW [SHELL32.@] + * + * See SHGetPathFromIDListA. */ BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath) { _____
Modified: trunk/reactos/lib/shell32/shell.c --- trunk/reactos/lib/shell32/shell.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shell.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -335,12 +335,13 @@
* from "DOS" environment. If it is not found the %KEYWORD% is left * intact. If the buffer is too small, str is not modified. * - * str [I] '\0' terminated string with %keyword%. + * PARAMS + * str [I] '\0' terminated string with %keyword%. * [O] '\0' terminated string with %keyword% substituted. - * length [I] size of str. + * length [I] size of str. * - * Return - * str length in the LOWORD and 1 in HIWORD if subst was successful. + * RETURNS + * str length in the LOWORD and 1 in HIWORD if subst was successful. */ DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length) { @@ -625,7 +626,7 @@ seiW.dwHotKey = 0; seiW.hProcess = hProcess;
- SHELL_execute( &seiW, SHELL_Execute16, FALSE ); + SHELL_execute( &seiW, SHELL_Execute16 );
if (wVerb) SHFree(wVerb); if (wFile) SHFree(wFile); _____
Modified: trunk/reactos/lib/shell32/shell32_main.h --- trunk/reactos/lib/shell32/shell32_main.h 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shell32_main.h 2005-11-20 08:41:46 UTC (rev 19356) @@ -213,7 +213,7 @@
typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, LPSHELLEXECUTEINFOW sei, LPSHELLEXECUTEINFOW sei_out);
-BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL unicode); +BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc);
UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation, LPWSTR lpResult, int resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args); _____
Modified: trunk/reactos/lib/shell32/shelllink.c --- trunk/reactos/lib/shell32/shelllink.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shelllink.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -51,6 +51,8 @@
#include "shell32_main.h" #include "shlguid.h" #include "shlwapi.h" +#include "msi.h" +#include "appmgmt.h"
#include "initguid.h"
@@ -120,6 +122,7 @@ static const IShellLinkDataListVtbl dlvt; static const IShellExtInitVtbl eivt; static const IContextMenuVtbl cmvt; +static const IObjectWithSiteVtbl owsvt;
/* IShellLink Implementation */
@@ -132,6 +135,7 @@ const IShellLinkDataListVtbl *lpvtblShellLinkDataList; const IShellExtInitVtbl *lpvtblShellExtInit; const IContextMenuVtbl *lpvtblContextMenu; + const IObjectWithSiteVtbl *lpvtblObjectWithSite;
LONG ref;
@@ -154,7 +158,9 @@ LPWSTR sComponent; volume_info volume;
- BOOL bDirty; + BOOL bDirty; + INT iIdOpen; /* id of the "Open" entry in the context menu */ + IUnknown *site; } IShellLinkImpl;
static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface ) @@ -187,6 +193,11 @@ return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblContextMenu)); }
+static inline IShellLinkImpl *impl_from_IObjectWithSite( IObjectWithSite *iface ) +{ + return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblObjectWithSite)); +} + static HRESULT ShellLink_UpdatePath(LPWSTR sPathRel, LPCWSTR path, LPCWSTR sWorkDir, LPWSTR* psPath);
/* strdup on the process heap */ @@ -200,6 +211,16 @@ return p; }
+inline static LPWSTR strdupW( LPCWSTR src ) +{ + LPWSTR dest; + if (!src) return NULL; + dest = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(src)+1)*sizeof(WCHAR) ); + if (dest) + lstrcpyW(dest, src); + return dest; +} +
/*********************************************************************** *** * ShellLink::QueryInterface implementation */ @@ -237,6 +258,10 @@ { *ppvObj = &(This->lpvtblContextMenu); } + else if(IsEqualIID(riid, &IID_IObjectWithSite)) + { + *ppvObj = &(This->lpvtblObjectWithSite); + }
if(*ppvObj) { @@ -280,6 +305,9 @@ HeapFree(GetProcessHeap(), 0, This->sDescription); HeapFree(GetProcessHeap(),0,This->sPath);
+ if (This->site) + IUnknown_Release( This->site ); + if (This->pPidl) ILFree(This->pPidl);
@@ -986,20 +1014,29 @@ return IStream_Write( stm, loc, total_size, &count ); }
+static EXP_DARWIN_LINK* shelllink_build_darwinid( LPCWSTR string, DWORD magic ) +{ + EXP_DARWIN_LINK *buffer; + + buffer = LocalAlloc( LMEM_ZEROINIT, sizeof *buffer ); + buffer->dbh.cbSize = sizeof *buffer; + buffer->dbh.dwSignature = magic; + lstrcpynW( buffer->szwDarwinID, string, MAX_PATH ); + WideCharToMultiByte(CP_ACP, 0, string, -1, buffer->szDarwinID, MAX_PATH, NULL, NULL ); + + return buffer; +} + static HRESULT Stream_WriteAdvertiseInfo( IStream* stm, LPCWSTR string, DWORD magic ) { + EXP_DARWIN_LINK *buffer; ULONG count; - EXP_DARWIN_LINK buffer;
TRACE("%p\n",stm);
- memset( &buffer, 0, sizeof buffer ); - buffer.dbh.cbSize = sizeof buffer; - buffer.dbh.dwSignature = magic; - lstrcpynW( buffer.szwDarwinID, string, MAX_PATH ); - WideCharToMultiByte(CP_ACP, 0, string, -1, buffer.szDarwinID, MAX_PATH, NULL, NULL ); + buffer = shelllink_build_darwinid( string, magic );
- return IStream_Write( stm, &buffer, buffer.dbh.cbSize, &count ); + return IStream_Write( stm, buffer, buffer->dbh.cbSize, &count ); }
/*********************************************************************** * @@ -1075,7 +1112,7 @@ return r; }
- TRACE("Writing pidl \n"); + TRACE("Writing pidl\n");
/* write the PIDL to the shortcut */ if( This->pPidl ) @@ -1172,8 +1209,11 @@ sl->lpvtblShellLinkDataList = &dlvt; sl->lpvtblShellExtInit = &eivt; sl->lpvtblContextMenu = &cmvt; + sl->lpvtblObjectWithSite = &owsvt; sl->iShowCmd = SW_SHOWNORMAL; sl->bDirty = FALSE; + sl->iIdOpen = -1; + sl->site = NULL;
TRACE("(%p)->()\n",sl);
@@ -2215,8 +2255,32 @@ static HRESULT WINAPI ShellLink_CopyDataBlock( IShellLinkDataList* iface, DWORD dwSig, void** ppDataBlock ) { - FIXME("\n"); - return E_NOTIMPL; + IShellLinkImpl *This = impl_from_IShellLinkDataList(iface); + LPVOID block = NULL; + HRESULT r = E_FAIL; + + TRACE("%p %08lx %p\n", iface, dwSig, ppDataBlock ); + + switch (dwSig) + { + case EXP_DARWIN_ID_SIG: + if (!This->sComponent) + break; + block = shelllink_build_darwinid( This->sComponent, dwSig ); + r = S_OK; + break; + case EXP_SZ_LINK_SIG: + case NT_CONSOLE_PROPS_SIG: + case NT_FE_CONSOLE_PROPS_SIG: + case EXP_SPECIAL_FOLDER_SIG: + case EXP_SZ_ICON_SIG: + FIXME("valid but unhandled datablock %08lx\n", dwSig); + break; + default: + ERR("unknown datablock %08lx\n", dwSig); + } + *ppDataBlock = block; + return r; }
static HRESULT WINAPI @@ -2229,8 +2293,26 @@ static HRESULT WINAPI ShellLink_GetFlags( IShellLinkDataList* iface, DWORD* pdwFlags ) { - FIXME("\n"); - return E_NOTIMPL; + IShellLinkImpl *This = impl_from_IShellLinkDataList(iface); + DWORD flags = 0; + + FIXME("%p %p\n", This, pdwFlags ); + + /* FIXME: add more */ + if (This->sArgs) + flags |= SLDF_HAS_ARGS; + if (This->sComponent) + flags |= SLDF_HAS_DARWINID; + if (This->sIcoPath) + flags |= SLDF_HAS_ICONLOCATION; + if (This->sProduct) + flags |= SLDF_HAS_LOGO3ID; + if (This->pPidl) + flags |= SLDF_HAS_ID_LIST; + + *pdwFlags = flags; + + return S_OK; }
static HRESULT WINAPI @@ -2358,21 +2440,139 @@ UINT idCmdFirst, UINT idCmdLast, UINT uFlags ) { IShellLinkImpl *This = impl_from_IContextMenu(iface); + static const WCHAR szOpen[] = { 'O','p','e','n',0 }; + MENUITEMINFOW mii; + int id = 1;
- FIXME("%p %p %u %u %u %u\n", This, + TRACE("%p %p %u %u %u %u\n", This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags );
- return E_NOTIMPL; + if ( !hmenu ) + return E_INVALIDARG; + + memset( &mii, 0, sizeof mii ); + mii.cbSize = sizeof mii; + mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; + mii.dwTypeData = (LPWSTR)szOpen; + mii.cch = strlenW( mii.dwTypeData ); + mii.wID = idCmdFirst + id++; + mii.fState = MFS_DEFAULT | MFS_ENABLED; + mii.fType = MFT_STRING; + if (!InsertMenuItemW( hmenu, indexMenu, TRUE, &mii )) + return E_FAIL; + This->iIdOpen = 0; + + return MAKE_HRESULT( SEVERITY_SUCCESS, 0, id ); }
+static LPWSTR +shelllink_get_msi_component_path( LPWSTR component ) +{ + LPWSTR path = NULL; + DWORD r, sz = 0; + + r = CommandLineFromMsiDescriptor( component, NULL, &sz ); + if (r != ERROR_SUCCESS) + return path; + + sz++; + path = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) ); + r = CommandLineFromMsiDescriptor( component, path, &sz ); + if (r != ERROR_SUCCESS) + { + HeapFree( GetProcessHeap(), 0, path ); + path = NULL; + } + + TRACE("returning %s\n", debugstr_w( path ) ); + + return path; +} + static HRESULT WINAPI ShellLink_InvokeCommand( IContextMenu* iface, LPCMINVOKECOMMANDINFO lpici ) { IShellLinkImpl *This = impl_from_IContextMenu(iface); + static const WCHAR szOpen[] = { 'O','p','e','n',0 }; + SHELLEXECUTEINFOW sei; + HWND hwnd = NULL; /* FIXME: get using interface set from IObjectWithSite */ + LPWSTR args = NULL; + LPWSTR path = NULL; + HRESULT r;
- FIXME("%p %p\n", This, lpici ); + TRACE("%p %p\n", This, lpici );
- return E_NOTIMPL; + if ( lpici->cbSize < sizeof (CMINVOKECOMMANDINFO) ) + return E_INVALIDARG; + + if ( lpici->lpVerb != MAKEINTRESOURCEA(This->iIdOpen) ) + { + ERR("Unknown id %d != %d\n", (INT)lpici->lpVerb, This->iIdOpen ); + return E_INVALIDARG; + } + + r = IShellLinkW_Resolve( (IShellLinkW*)&(This->lpvtblw), hwnd, 0 ); + if ( FAILED( r ) ) + return r; + + if ( This->sComponent ) + { + path = shelllink_get_msi_component_path( This->sComponent ); + if (!path) + return E_FAIL; + } + else + path = strdupW( This->sPath ); + + if ( lpici->cbSize == sizeof (CMINVOKECOMMANDINFOEX) && + ( lpici->fMask & CMIC_MASK_UNICODE ) ) + { + LPCMINVOKECOMMANDINFOEX iciex = (LPCMINVOKECOMMANDINFOEX) lpici; + DWORD len = 2; + + if ( This->sArgs ) + len += lstrlenW( This->sArgs ); + if ( iciex->lpParametersW ) + len += lstrlenW( iciex->lpParametersW ); + + args = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); + args[0] = 0; + if ( This->sArgs ) + lstrcatW( args, This->sArgs ); + if ( iciex->lpParametersW ) + { + static const WCHAR space[] = { ' ', 0 }; + lstrcatW( args, space ); + lstrcatW( args, iciex->lpParametersW ); + } + } + + memset( &sei, 0, sizeof sei ); + sei.cbSize = sizeof sei; + sei.fMask = SEE_MASK_UNICODE | SEE_MASK_NOCLOSEPROCESS; + sei.lpFile = path; + sei.nShow = This->iShowCmd; + sei.lpIDList = This->pPidl; + sei.lpDirectory = This->sWorkDir; + sei.lpParameters = args; + sei.lpVerb = szOpen; + + if( ShellExecuteExW( &sei ) ) + { + if ( sei.hProcess ) + { + WaitForSingleObject( sei.hProcess, 10000 ); + CloseHandle( sei.hProcess ); + } + r = S_OK; + } + else + r = E_FAIL; + + HeapFree( GetProcessHeap(), 0, args ); + HeapFree( GetProcessHeap(), 0, path ); + + return r; }
static HRESULT WINAPI @@ -2396,3 +2596,59 @@ ShellLink_InvokeCommand, ShellLink_GetCommandString }; + +static HRESULT WINAPI +ShellLink_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject ) +{ + IShellLinkImpl *This = impl_from_IObjectWithSite(iface); + return ShellLink_QueryInterface( This, riid, ppvObject ); +} + +static ULONG WINAPI +ShellLink_ObjectWithSite_AddRef( IObjectWithSite* iface ) +{ + IShellLinkImpl *This = impl_from_IObjectWithSite(iface); + return ShellLink_AddRef( This ); +} + +static ULONG WINAPI +ShellLink_ObjectWithSite_Release( IObjectWithSite* iface ) +{ + IShellLinkImpl *This = impl_from_IObjectWithSite(iface); + return ShellLink_Release( This ); +} + +static HRESULT WINAPI +ShellLink_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite ) +{ + IShellLinkImpl *This = impl_from_IObjectWithSite(iface); + + TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite ); + + if ( !This->site ) + return E_FAIL; + return IUnknown_QueryInterface( This->site, iid, ppvSite ); +} + +static HRESULT WINAPI +ShellLink_SetSite( IObjectWithSite *iface, IUnknown *punk ) +{ + IShellLinkImpl *This = impl_from_IObjectWithSite(iface); + + TRACE("%p %p\n", iface, punk); + + if ( punk ) + IUnknown_AddRef( punk ); + This->site = punk; + + return S_OK; +} + +static const IObjectWithSiteVtbl owsvt = +{ + ShellLink_ObjectWithSite_QueryInterface, + ShellLink_ObjectWithSite_AddRef, + ShellLink_ObjectWithSite_Release, + ShellLink_SetSite, + ShellLink_GetSite, +}; _____
Modified: trunk/reactos/lib/shell32/shellole.c --- trunk/reactos/lib/shell32/shellole.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shellole.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -689,8 +689,8 @@
}
/*********************************************************************** ** + * DragQueryFileA [SHELL32.@] * DragQueryFile [SHELL32.@] - * DragQueryFileA [SHELL32.@] */ UINT WINAPI DragQueryFileA( HDROP hDrop, _____
Modified: trunk/reactos/lib/shell32/shellord.c --- trunk/reactos/lib/shell32/shellord.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shellord.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -622,12 +622,17 @@
/*********************************************************************** ** * SHAddToRecentDocs [SHELL32.@] * + * Modify (add/clear) Shell's list of recently used documents. + * * PARAMETERS - * uFlags [IN] SHARD_PATH or SHARD_PIDL + * uFlags [IN] SHARD_PATHA, SHARD_PATHW or SHARD_PIDL * pv [IN] string or pidl, NULL clears the list * * NOTES * exported by name + * + * FIXME + * convert to unicode */ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv) { @@ -652,6 +657,8 @@ INT ret; DWORD data[64], datalen, type;
+ TRACE("%04x %p\n", uFlags, pv); + /*FIXME: Document: * RecentDocs MRU data structure seems to be: * +0h document file name w/ terminating 0h @@ -732,7 +739,7 @@ * DeleteFileA(old_lnk_name); * } */ - FIXME("should delete all files in %s\ \n", link_dir); + FIXME("should delete all files in %s\\n", link_dir);
/* clear MRU list */ @@ -757,15 +764,28 @@
/* Get the pure document name from the input */ - if (uFlags & SHARD_PIDL) { + switch (uFlags) + { + case SHARD_PIDL: SHGetPathFromIDListA((LPCITEMIDLIST) pv, doc_name); + break; + + case SHARD_PATHA: + lstrcpynA(doc_name, (LPCSTR)pv, MAX_PATH); + break; + + case SHARD_PATHW: + WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pv, -1, doc_name, MAX_PATH, NULL, NULL); + break; + + default: + FIXME("Unsupported flags: %u\n", uFlags); + return; } - else { - lstrcpyA(doc_name, (LPCSTR) pv); - } - TRACE("full document name %s\n", doc_name); + + TRACE("full document name %s\n", debugstr_a(doc_name)); PathStripPathA(doc_name); - TRACE("stripped document name %s\n", doc_name); + TRACE("stripped document name %s\n", debugstr_a(doc_name));
/* *** JOB 1: Update registry for ...\Explorer\RecentDocs list *** */ @@ -902,7 +922,7 @@ }
/* Set the document path or pidl */ - if (uFlags & SHARD_PIDL) { + if (uFlags == SHARD_PIDL) { hres = IShellLinkA_SetIDList(psl, (LPCITEMIDLIST) pv); } else { hres = IShellLinkA_SetPath(psl, (LPCSTR) pv); @@ -955,6 +975,12 @@
/*********************************************************************** ** * SHCreateShellFolderViewEx [SHELL32.174] * + * Create a new instance of the default Shell folder view object. + * + * RETURNS + * Success: S_OK + * Failure: error value + * * NOTES * see IShellFolder::CreateViewObject */ @@ -1125,7 +1151,7 @@ HKEY hkey = 0; DWORD type, r;
- TRACE("%p %d \n",cs,length); + TRACE("%p %d\n", cs, length);
if( (cs == NULL) || (length < (int)sizeof(*cs)) ) return FALSE; @@ -1319,10 +1345,11 @@
/*********************************************************************** * * @ [SHELL32.654] * - * NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState) - * second one could be a size (0x0c). The size is the same as the structure saved to - * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState - * I'm (js) guessing: this one is just ReadCabinetState ;-) + * NOTES + * first parameter seems to be a pointer (same as passed to WriteCabinetState) + * second one could be a size (0x0c). The size is the same as the structure saved to + * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState + * I'm (js) guessing: this one is just ReadCabinetState ;-) */ HRESULT WINAPI shell32_654 (CABINETSTATE *cs, int length) { @@ -1357,11 +1384,12 @@ * 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%. + * PARAMS + * pszString [I] '\0' terminated string with %keyword%. * [O] '\0' terminated string with %keyword% substituted. - * cchString [I] size of str. + * cchString [I] size of str. * - * Return + * RETURNS * cchString length in the HIWORD; * TRUE in LOWORD if subst was successful and FALSE in other case */ @@ -1388,6 +1416,7 @@
/*********************************************************************** * * DoEnvironmentSubstW [SHELL32.@] * + * See DoEnvironmentSubstA. */ DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString) { @@ -1398,6 +1427,7 @@
/*********************************************************************** * * DoEnvironmentSubst [SHELL32.53] * + * See DoEnvironmentSubstA. */ DWORD WINAPI DoEnvironmentSubstAW(LPVOID x, UINT y) { @@ -1563,6 +1593,9 @@ * uFlags [I] Flags determining the icon attributes. See notes. * iImageIndex [I] Index of the icon in the system image list. * + * RETURNS + * Nothing + * * NOTES * uFlags can be one or more of the following flags: * GIL_NOTFILENAME - pszHashItem is not a file name. @@ -1573,6 +1606,11 @@ FIXME("%s, %d, 0x%x, %d - stub\n", debugstr_w(pszHashItem), iIndex, uFlags, iImageIndex); }
+/********************************************************************** *** + * SHUpdateImageA (SHELL32.191) + * + * See SHUpdateImageW. + */ VOID WINAPI SHUpdateImageA(LPCSTR pszHashItem, INT iIndex, UINT uFlags, INT iImageIndex) { FIXME("%s, %d, 0x%x, %d - stub\n", debugstr_a(pszHashItem), iIndex, uFlags, iImageIndex); _____
Modified: trunk/reactos/lib/shell32/shellpath.c --- trunk/reactos/lib/shell32/shellpath.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shellpath.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -1562,8 +1562,14 @@
/*********************************************************************** ** * SHGetFolderPathW [SHELL32.@] * + * Convert nFolder to path. + * + * RETURNS + * Success: S_OK + * Failure: standard HRESULT error codes. + * * NOTES - * Converts nFolder to path. Most values can be overridden in either + * Most values can be overridden in either * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders * or in the same location in HKLM. * The registry usage is explained by the following tech note: @@ -1577,13 +1583,13 @@ * http://www.microsoft.com/windows2000/techinfo/reskit/en-us/default.asp?u rl=/windows2000/techinfo/reskit/en-us/regentry/36276.asp * the HKCU paths take precedence over the HKLM paths. * - **********************************************************************/ + */ HRESULT WINAPI SHGetFolderPathW( - HWND hwndOwner, - int nFolder, - HANDLE hToken, - DWORD dwFlags, - LPWSTR pszPath) + HWND hwndOwner, /* [I] owner window */ + int nFolder, /* [I] CSIDL identifing the folder */ + HANDLE hToken, /* [I] access token */ + DWORD dwFlags, /* [I] which path to return */ + LPWSTR pszPath) /* [O] converted path */ { HRESULT hr; WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH]; @@ -1689,6 +1695,8 @@
/*********************************************************************** ** * SHGetFolderPathA [SHELL32.@] + * + * See SHGetFolderPathW. */ HRESULT WINAPI SHGetFolderPathA( HWND hwndOwner, @@ -1928,11 +1936,7 @@
/*********************************************************************** ** * SHGetFolderLocation [SHELL32.@] * - * NOTES * Gets the folder locations from the registry and creates a pidl. - * Creates missing reg keys and directories. - * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return - * virtual folders that are handled here. * * PARAMS * hwndOwner [I] @@ -1942,7 +1946,14 @@ * dwReserved [I] must be zero * ppidl [O] PIDL of a special folder * + * RETURNS + * Success: S_OK + * Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG + * * NOTES + * Creates missing reg keys and directories. + * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return + * virtual folders that are handled here. */ HRESULT WINAPI SHGetFolderLocation( HWND hwndOwner, _____
Modified: trunk/reactos/lib/shell32/shellstring.c --- trunk/reactos/lib/shell32/shellstring.c 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shellstring.c 2005-11-20 08:41:46 UTC (rev 19356) @@ -260,7 +260,7 @@
/*********************************************************************** ** * CheckEscapesW [SHELL32.@] * - * see CheckEscapesA + * See CheckEscapesA. */ DWORD WINAPI CheckEscapesW( LPWSTR string, _____
Modified: trunk/reactos/lib/shell32/shfldr.h --- trunk/reactos/lib/shell32/shfldr.h 2005-11-20 03:16:26 UTC (rev 19355) +++ trunk/reactos/lib/shell32/shfldr.h 2005-11-20 08:41:46 UTC (rev 19356) @@ -43,7 +43,7 @@
DWORD dwOutLen);
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot, - LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut); + LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
[truncated at 1000 lines; 1222 more skipped]