Vitaliy Margolen <wine-patch@kievinfo.com>
authorGé van Geldorp <ge@gse.nl>
Sun, 20 Nov 2005 08:41:46 +0000 (08:41 +0000)
committerGé van Geldorp <ge@gse.nl>
Sun, 20 Nov 2005 08:41:46 +0000 (08:41 +0000)
- 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.

svn path=/trunk/; revision=19356

26 files changed:
reactos/bootdata/hivecls.inf
reactos/include/wine/shobjidl.h
reactos/lib/shell32/Makefile.in
reactos/lib/shell32/brsfolder.c
reactos/lib/shell32/cpanelfolder.c
reactos/lib/shell32/enumidlist.c
reactos/lib/shell32/iconcache.c
reactos/lib/shell32/pidl.c
reactos/lib/shell32/shell.c
reactos/lib/shell32/shell32_main.h
reactos/lib/shell32/shelllink.c
reactos/lib/shell32/shellole.c
reactos/lib/shell32/shellord.c
reactos/lib/shell32/shellpath.c
reactos/lib/shell32/shellstring.c
reactos/lib/shell32/shfldr.h
reactos/lib/shell32/shfldr_desktop.c
reactos/lib/shell32/shfldr_fs.c
reactos/lib/shell32/shfldr_mycomp.c
reactos/lib/shell32/shlexec.c
reactos/lib/shell32/shlfileop.c
reactos/lib/shell32/shlfolder.c
reactos/lib/shell32/shlmenu.c
reactos/lib/shell32/systray.c
reactos/w32api/include/appmgmt.h [new file with mode: 0644]
reactos/w32api/include/shlobj.h

index 279c595..0cf767a 100644 (file)
@@ -21,6 +21,7 @@ HKCR,"lnkfile","NeverShowExt",0x00000000,""
 HKCR,"lnkfile","IsShortcut",0x00000000,"yes"
 HKCR,"lnkfile\CLSID","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
 HKCR,"lnkfile\shellex\IconHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
+HKCR,lnkfile\shellex\ContextMenuHandlers\{00021401-0000-0000-C000-000000000046},,,
 
 ; shell command files (e.g. "Show Desktop" in quicklaunch bar)
 HKCR,".scf","",0x00000000,"SHCmdFile"
index 11df4f4..9c85291 100644 (file)
@@ -43,4 +43,13 @@ DEFINE_GUID(IID_IPersistFolder3, 0xcef04fdf, 0xfe72, 0x11d2, 0x87,0xa5, 0x00,0xc
 /*** 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 */
index e7700d4..a1cb903 100644 (file)
@@ -6,7 +6,7 @@ VPATH     = @srcdir@
 MODULE    = shell32.dll
 IMPORTLIB = libshell32.$(IMPLIBEXT)
 IMPORTS   = shlwapi comctl32 user32 gdi32 advapi32 kernel32 ntdll
-DELAYIMPORTS = ole32
+DELAYIMPORTS = ole32 oleaut32
 EXTRALIBS = -luuid $(LIBUNICODE)
 
 C_SRCS = \
index daf8b5f..54a48b1 100644 (file)
@@ -388,7 +388,7 @@ static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptv
         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 @@ static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptv
         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 @@ LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
 /*************************************************************************
  * 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;
 
index 07d0fd1..cbac65a 100644 (file)
@@ -410,7 +410,7 @@ static BOOL CreateCPanelEnumList(
     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)
index 972bd20..98577f2 100644 (file)
@@ -116,7 +116,7 @@ BOOL CreateFolderEnumList(
     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;
 
index 4b87550..1d54196 100644 (file)
@@ -365,7 +365,7 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
 
        if ( INVALID_INDEX == index )
        {
-         ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
+          ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
        }
        else
        {
@@ -378,15 +378,10 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
 }
 /*****************************************************************************
  * 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 @@ BOOL SIC_Initialize(void)
          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;
index 7468a3f..b39fb24 100644 (file)
@@ -254,7 +254,7 @@ LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
     DWORD len;
     LPITEMIDLIST pidlNew = NULL;
 
-    TRACE("pidl=%p \n",pidl);
+    TRACE("pidl=%p\n", pidl);
     pdump(pidl);
 
     if (pidl)
@@ -885,6 +885,9 @@ LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd)
  * PARAMS
  *  pidl         [I]
  *
+ * RETURNS
+ *  Nothing
+ *
  * NOTES
  *  exported by ordinal
  */
@@ -903,6 +906,9 @@ void WINAPI ILFree(LPITEMIDLIST pidl)
  * PARAMS
  *  pidl         [I]
  *
+ * RETURNS
+ *  Nothing
+ *
  * NOTES
  *  exported by ordinal.
  */
@@ -941,6 +947,8 @@ LPITEMIDLIST WINAPI ILCreateFromPathA (LPCSTR path)
 
 /*************************************************************************
  * ILCreateFromPathW         [SHELL32.190]
+ *
+ * See ILCreateFromPathA.
  */
 LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path)
 {
@@ -1238,6 +1246,8 @@ BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
 
 /*************************************************************************
  * SHGetPathFromIDListW             [SHELL32.@]
+ *
+ * See SHGetPathFromIDListA.
  */
 BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
 {
index 5337566..18bbc7c 100644 (file)
@@ -335,12 +335,13 @@ SEGPTR WINAPI FindEnvironmentString16(LPSTR str)
  * 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 @@ HINSTANCE16 WINAPI ShellExecute16( HWND16 hWnd, LPCSTR lpOperation,
     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);
index 7eebd30..a95d67f 100644 (file)
@@ -213,7 +213,7 @@ inline static WCHAR * __SHCloneStrAtoW(WCHAR ** target, const char * source)
 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);
index 71bcb7b..40ab9d3 100644 (file)
@@ -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 IPersistStreamVtbl psvt;
 static const IShellLinkDataListVtbl dlvt;
 static const IShellExtInitVtbl eivt;
 static const IContextMenuVtbl cmvt;
+static const IObjectWithSiteVtbl owsvt;
 
 /* IShellLink Implementation */
 
@@ -132,6 +135,7 @@ typedef struct
        const IShellLinkDataListVtbl *lpvtblShellLinkDataList;
        const IShellExtInitVtbl *lpvtblShellExtInit;
        const IContextMenuVtbl *lpvtblContextMenu;
+       const IObjectWithSiteVtbl *lpvtblObjectWithSite;
 
        LONG            ref;
 
@@ -154,7 +158,9 @@ typedef struct
        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 @@ static inline IShellLinkImpl *impl_from_IContextMenu( IContextMenu *iface )
     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 @@ inline static LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
     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 @@ static HRESULT ShellLink_QueryInterface( IShellLinkImpl *This, REFIID riid,  LPV
     {
         *ppvObj = &(This->lpvtblContextMenu);
     }
+    else if(IsEqualIID(riid, &IID_IObjectWithSite))
+    {
+        *ppvObj = &(This->lpvtblObjectWithSite);
+    }
 
     if(*ppvObj)
     {
@@ -280,6 +305,9 @@ static ULONG ShellLink_Release( IShellLinkImpl *This )
     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 @@ static HRESULT Stream_WriteLocationInfo( IStream* stm, LPCWSTR path,
     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 @@ static HRESULT WINAPI IPersistStream_fnSave(
         return r;
     }
 
-    TRACE("Writing pidl \n");
+    TRACE("Writing pidl\n");
 
     /* write the PIDL to the shortcut */
     if( This->pPidl )
@@ -1172,8 +1209,11 @@ HRESULT WINAPI IShellLink_Constructor( IUnknown *pUnkOuter,
        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 @@ ShellLink_AddDataBlock( IShellLinkDataList* iface, void* pDataBlock )
 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 @@ ShellLink_RemoveDataBlock( IShellLinkDataList* iface, DWORD dwSig )
 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 @@ ShellLink_QueryContextMenu( IContextMenu* iface, HMENU hmenu, UINT indexMenu,
                             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 @@ static const IContextMenuVtbl cmvt =
     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,
+};
index 9f52ff7..467d50d 100644 (file)
@@ -689,8 +689,8 @@ BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
 }
 
 /*************************************************************************
- *  DragQueryFile              [SHELL32.@]
  *  DragQueryFileA             [SHELL32.@]
+ *  DragQueryFile              [SHELL32.@]
  */
 UINT WINAPI DragQueryFileA(
        HDROP hDrop,
index c4bd324..d0e0da7 100644 (file)
@@ -622,12 +622,17 @@ static INT SHADD_create_add_mru_data(HANDLE mruhandle, LPSTR doc_name, LPSTR new
 /*************************************************************************
  * 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 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
     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 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
         *    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 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
 
     /* 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 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
            }
 
            /* 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 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
 /*************************************************************************
  * 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 @@ BOOL WINAPI ReadCabinetState(CABINETSTATE *cs, int length)
        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 @@ BOOL WINAPI SHWaitForFileToOpen(
 /************************************************************************
  *     @                               [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 @@ HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
  * 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 @@ DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString)
 /************************************************************************
  *     DoEnvironmentSubstW                     [SHELL32.@]
  *
+ * See DoEnvironmentSubstA.  
  */
 DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
 {
@@ -1398,6 +1427,7 @@ DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
 /************************************************************************
  *     DoEnvironmentSubst                      [SHELL32.53]
  *
+ * See DoEnvironmentSubstA.  
  */
 DWORD WINAPI DoEnvironmentSubstAW(LPVOID x, UINT y)
 {
@@ -1563,6 +1593,9 @@ BOOL WINAPI SHFindFiles( LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidlSaveFile )
  *  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 @@ void WINAPI SHUpdateImageW(LPCWSTR pszHashItem, int iIndex, UINT uFlags, int iIm
     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);
index b9c48ef..2064601 100644 (file)
@@ -1562,8 +1562,14 @@ end:
 /*************************************************************************
  * 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 @@ end:
  * http://www.microsoft.com/windows2000/techinfo/reskit/en-us/default.asp?url=/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 @@ end:
 
 /*************************************************************************
  * SHGetFolderPathA                    [SHELL32.@]
+ *
+ * See SHGetFolderPathW.
  */
 HRESULT WINAPI SHGetFolderPathA(
        HWND hwndOwner,
@@ -1928,11 +1936,7 @@ BOOL WINAPI SHGetSpecialFolderPathAW (
 /*************************************************************************
  * 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 @@ BOOL WINAPI SHGetSpecialFolderPathAW (
  *   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,
index 3581768..a41b0b9 100644 (file)
@@ -260,7 +260,7 @@ static const WCHAR strEscapedChars[] = {' ','"',',',';','^',0};
 /*************************************************************************
  * CheckEscapesW             [SHELL32.@]
  *
- * see CheckEscapesA
+ * See CheckEscapesA.
  */
 DWORD WINAPI CheckEscapesW(
        LPWSTR  string,
index 0cbdf91..e626255 100644 (file)
@@ -43,7 +43,7 @@ HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl,
                                       DWORD dwOutLen);
 
 HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
-                            LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
+                            LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
 
 HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
 LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
index 7b41d06..af7b5b2 100644 (file)
@@ -265,7 +265,7 @@ static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
     BOOL ret = TRUE;
     WCHAR szPath[MAX_PATH];
 
-    TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
+    TRACE("(%p)->(flags=0x%08lx)\n", list, dwFlags);
 
     /* enumerate the root folders */
     if (dwFlags & SHCONTF_FOLDERS)
@@ -338,14 +338,11 @@ static HRESULT WINAPI ISF_Desktop_fnBindToObject (IShellFolder2 * iface,
                 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-    char szPath[MAX_PATH];
 
     TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
            This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
 
-    WideCharToMultiByte( CP_ACP, 0, This->sPathTarget, -1,
-                         szPath, MAX_PATH, NULL, NULL );
-    return SHELL32_BindToChild( This->pidlRoot, szPath, pidl, riid, ppvOut );
+    return SHELL32_BindToChild( This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut );
 }
 
 /**************************************************************************
index cb92d73..53d8231 100644 (file)
@@ -481,11 +481,13 @@ IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                              LPBC pbc, REFIID riid, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = impl_from_IShellFolder2(iface);
+    WCHAR szPath[MAX_PATH];
 
     TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc,
      shdebugstr_guid (riid), ppvOut);
 
-    return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid,
+    MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath, MAX_PATH);
+    return SHELL32_BindToChild (This->pidlRoot, szPath, pidl, riid,
      ppvOut);
 }
 
index abbafd5..ec137ce 100644 (file)
@@ -266,7 +266,7 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
 {
     BOOL ret = TRUE;
 
-    TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
+    TRACE("(%p)->(flags=0x%08lx)\n", list, dwFlags);
 
     /* enumerate the folders */
     if (dwFlags & SHCONTF_FOLDERS)
index 1122aee..0e4d30d 100644 (file)
@@ -266,70 +266,6 @@ HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, U
     return hr;
 }
 
-/*************************************************************************
- *     SHELL_ResolveShortCutW [Internal]
- *     read shortcut file at 'wcmd'
- */
-static HRESULT SHELL_ResolveShortCutW(LPWSTR wcmd, LPWSTR wargs, LPWSTR wdir, HWND hwnd, LPCWSTR lpVerb, int* pshowcmd, LPITEMIDLIST* ppidl)
-{
-    IShellFolder* psf;
-
-    HRESULT hr = SHGetDesktopFolder(&psf);
-
-    *ppidl = NULL;
-
-    if (SUCCEEDED(hr)) {
-       LPITEMIDLIST pidl;
-       ULONG l;
-
-       hr = IShellFolder_ParseDisplayName(psf, 0, 0, wcmd, &l, &pidl, 0);
-
-       if (SUCCEEDED(hr)) {
-           IShellLinkW* psl;
-
-           hr = IShellFolder_GetUIObjectOf(psf, NULL, 1, (LPCITEMIDLIST*)&pidl, &IID_IShellLinkW, NULL, (LPVOID*)&psl);
-
-           if (SUCCEEDED(hr)) {
-               hr = IShellLinkW_Resolve(psl, hwnd, 0);
-
-               if (SUCCEEDED(hr)) {
-                   hr = IShellLinkW_GetPath(psl, wcmd, MAX_PATH, NULL, SLGP_UNCPRIORITY);
-
-                   if (SUCCEEDED(hr)) {
-                       if (!*wcmd) {
-                           /* We could not translate the PIDL in the shell link into a valid file system path - so return the PIDL instead. */
-                           hr = IShellLinkW_GetIDList(psl, ppidl);
-
-                           if (SUCCEEDED(hr) && *ppidl) {
-                               /* We got a PIDL instead of a file system path - try to translate it. */
-                               if (SHGetPathFromIDListW(*ppidl, wcmd)) {
-                                   SHFree(*ppidl);
-                                   *ppidl = NULL;
-                               }
-                           }
-                       }
-
-                       if (SUCCEEDED(hr)) {
-                           /* get command line arguments, working directory and display mode if available */
-                           IShellLinkW_GetWorkingDirectory(psl, wdir, MAX_PATH);
-                           IShellLinkW_GetArguments(psl, wargs, MAX_PATH);
-                           IShellLinkW_GetShowCmd(psl, pshowcmd);
-                       }
-                   }
-               }
-
-               IShellLinkW_Release(psl);
-           }
-
-           SHFree(pidl);
-       }
-
-       IShellFolder_Release(psf);
-    }
-
-    return hr;
-}
-
 /*************************************************************************
  *     SHELL_ExecuteW [Internal]
  *
@@ -772,8 +708,7 @@ static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv,
 static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
                             const WCHAR* lpFile, WCHAR *env,
                            LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc,
-                            LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out,
-                            BOOL unicode)
+                            LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
 {
     static const WCHAR wApplication[] = {'\\','a','p','p','l','i','c','a','t','i','o','n',0};
     static const WCHAR wTopic[] = {'\\','t','o','p','i','c',0};
@@ -787,6 +722,7 @@ static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
     HCONV       hConv;
     HDDEDATA    hDdeData;
     unsigned    ret = 31;
+    BOOL unicode = !(GetVersion() & 0x80000000);
 
     strcpyW(endkey, wApplication);
     applen = sizeof(app);
@@ -883,8 +819,7 @@ static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
  */
 static UINT_PTR execute_from_key(LPWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR szCommandline,
                             SHELL_ExecuteW32 execfunc,
-                             LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out,
-                             BOOL unicode)
+                             LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
 {
     WCHAR cmd[1024];
     LONG cmdlen = sizeof(cmd);
@@ -912,7 +847,7 @@ static UINT_PTR execute_from_key(LPWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR
         if (RegQueryValueW(HKEY_CLASSES_ROOT, key, param, &paramlen) == ERROR_SUCCESS)
         {
             TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(param));
-            retval = dde_connect(key, cmd, param, lpFile, env, szCommandline, psei->lpIDList, execfunc, psei, psei_out, unicode);
+            retval = dde_connect(key, cmd, param, lpFile, env, szCommandline, psei->lpIDList, execfunc, psei, psei_out);
         }
         else
         {
@@ -983,17 +918,272 @@ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpR
     return (HINSTANCE)retval;
 }
 
+/* FIXME: is this already implemented somewhere else? */
+static HKEY ShellExecute_GetClassKey( LPSHELLEXECUTEINFOW sei )
+{
+    LPCWSTR ext = NULL, lpClass = NULL;
+    LPWSTR cls = NULL;
+    DWORD type = 0, sz = 0;
+    HKEY hkey = 0;
+    LONG r;
+
+    if (sei->fMask & SEE_MASK_CLASSALL)
+        return sei->hkeyClass;
+    if (sei->fMask & SEE_MASK_CLASSNAME)
+        lpClass = sei->lpClass;
+    else
+    {
+        ext = PathFindExtensionW( sei->lpFile );
+        TRACE("ext = %s\n", debugstr_w( ext ) );
+        if (!ext)
+            return hkey;
+
+        r = RegOpenKeyW( HKEY_CLASSES_ROOT, ext, &hkey );
+        if (r != ERROR_SUCCESS )
+            return hkey;
+
+        r = RegQueryValueExW( hkey, NULL, 0, &type, NULL, &sz );
+        if ( r == ERROR_SUCCESS && type == REG_SZ )
+        {
+            sz += sizeof (WCHAR);
+            cls = HeapAlloc( GetProcessHeap(), 0, sz );
+            cls[0] = 0;
+            RegQueryValueExW( hkey, NULL, 0, &type, (LPBYTE) cls, &sz );
+        }
+
+        RegCloseKey( hkey );
+        lpClass = cls;
+    }
+
+    TRACE("class = %s\n", debugstr_w(lpClass) );
+
+    hkey = 0;
+    if ( lpClass )
+        RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey );
+
+    HeapFree( GetProcessHeap(), 0, cls );
+
+    return hkey;
+}
+
+static IDataObject *shellex_get_dataobj( LPSHELLEXECUTEINFOW sei )
+{
+    LPCITEMIDLIST pidllast = NULL;
+    IDataObject *dataobj = NULL;
+    IShellFolder *shf = NULL;
+    LPITEMIDLIST pidl = NULL;
+    HRESULT r;
+
+    if (sei->fMask & SEE_MASK_CLASSALL)
+        pidl = sei->lpIDList;
+    else
+    {
+        WCHAR fullpath[MAX_PATH];
+
+        fullpath[0] = 0;
+        r = GetFullPathNameW( sei->lpFile, MAX_PATH, fullpath, NULL );
+        if (!r)
+            goto end;
+
+        pidl = ILCreateFromPathW( fullpath );
+    }
+
+    r = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&shf, &pidllast );
+    if ( FAILED( r ) )
+        goto end;
+
+    IShellFolder_GetUIObjectOf( shf, NULL, 1, &pidllast,
+                                &IID_IDataObject, NULL, (LPVOID*) &dataobj );
+
+end:
+    if ( pidl != sei->lpIDList )
+        ILFree( pidl );
+    if ( shf )
+        IShellFolder_Release( shf );
+    return dataobj;
+}
+
+static HRESULT shellex_run_context_menu_default( IShellExtInit *obj,
+                                                 LPSHELLEXECUTEINFOW sei )
+{
+    IContextMenu *cm = NULL;
+    CMINVOKECOMMANDINFOEX ici;
+    MENUITEMINFOW info;
+    WCHAR string[0x80];
+    INT i, n, def = -1;
+    HMENU hmenu = 0;
+    HRESULT r;
+
+    TRACE("%p %p\n", obj, sei );
+
+    r = IShellExtInit_QueryInterface( obj, &IID_IContextMenu, (LPVOID*) &cm );
+    if ( FAILED( r ) )
+        return r;
+
+    hmenu = CreateMenu();
+    if ( !hmenu )
+        goto end;
+
+    /* the number of the last menu added is returned in r */
+    r = IContextMenu_QueryContextMenu( cm, hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY );
+    if ( FAILED( r ) )
+        goto end;
+
+    n = GetMenuItemCount( hmenu );
+    for ( i = 0; i < n; i++ )
+    {
+        memset( &info, 0, sizeof info );
+        info.cbSize = sizeof info;
+        info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_DATA | MIIM_ID;
+        info.dwTypeData = string;
+        info.cch = sizeof string;
+        string[0] = 0;
+        GetMenuItemInfoW( hmenu, i, TRUE, &info );
+
+        TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
+            info.fState, info.dwItemData, info.fType, info.wID );
+        if ( ( !sei->lpVerb && (info.fState & MFS_DEFAULT) ) ||
+             ( sei->lpVerb && !lstrcmpiW( sei->lpVerb, string ) ) )
+        {
+            def = i;
+            break;
+        }
+    }
+
+    r = E_FAIL;
+    if ( def == -1 )
+        goto end;
+
+    memset( &ici, 0, sizeof ici );
+    ici.cbSize = sizeof ici;
+    ici.fMask = CMIC_MASK_UNICODE;
+    ici.nShow = sei->nShow;
+    ici.lpVerb = MAKEINTRESOURCEA( def );
+    ici.hwnd = sei->hwnd;
+    ici.lpParametersW = sei->lpParameters;
+    
+    r = IContextMenu_InvokeCommand( cm, (LPCMINVOKECOMMANDINFO) &ici );
+
+    TRACE("invoke command returned %08lx\n", r );
+
+end:
+    if ( hmenu )
+        DestroyMenu( hmenu );
+    if ( cm )
+        IContextMenu_Release( cm );
+    return r;
+}
+
+static HRESULT shellex_load_object_and_run( HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei )
+{
+    IDataObject *dataobj = NULL;
+    IObjectWithSite *ows = NULL;
+    IShellExtInit *obj = NULL;
+    HRESULT r;
+
+    TRACE("%p %s %p\n", hkey, debugstr_guid( guid ), sei );
+
+    r = CoInitialize( NULL );
+    if ( FAILED( r ) )
+        goto end;
+
+    r = CoCreateInstance( guid, NULL, CLSCTX_INPROC_SERVER,
+                           &IID_IShellExtInit, (LPVOID*)&obj );
+    if ( FAILED( r ) )
+    {
+        ERR("failed %08lx\n", r );
+        goto end;
+    }
+
+    dataobj = shellex_get_dataobj( sei );
+    if ( !dataobj )
+    {
+        ERR("failed to get data object\n");
+        goto end;
+    }
+
+    r = IShellExtInit_Initialize( obj, NULL, dataobj, hkey );
+    if ( FAILED( r ) )
+        goto end;
+
+    r = IShellExtInit_QueryInterface( obj, &IID_IObjectWithSite, (LPVOID*) &ows );
+    if ( FAILED( r ) )
+        goto end;
+
+    IObjectWithSite_SetSite( ows, NULL );
+
+    r = shellex_run_context_menu_default( obj, sei );
+
+end:
+    if ( ows )
+        IObjectWithSite_Release( ows );
+    if ( dataobj )
+        IDataObject_Release( dataobj );
+    if ( obj )
+        IShellExtInit_Release( obj );
+    CoUninitialize();
+    return r;
+}
+
+
+/*************************************************************************
+ *     ShellExecute_FromContextMenu [Internal]
+ */
+static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei )
+{
+    static const WCHAR szcm[] = { 's','h','e','l','l','e','x','\\',
+        'C','o','n','t','e','x','t','M','e','n','u','H','a','n','d','l','e','r','s',0 };
+    HKEY hkey, hkeycm = 0;
+    WCHAR szguid[39];
+    HRESULT hr;
+    GUID guid;
+    DWORD i;
+    LONG r;
+
+    TRACE("%s\n", debugstr_w(sei->lpFile) );
+
+    hkey = ShellExecute_GetClassKey( sei );
+    if ( !hkey )
+        return ERROR_FUNCTION_FAILED;
+
+    r = RegOpenKeyW( hkey, szcm, &hkeycm );
+    if ( r == ERROR_SUCCESS )
+    {
+        i = 0;
+        while ( 1 )
+        {
+            r = RegEnumKeyW( hkeycm, i++, szguid, 39 );
+            if ( r != ERROR_SUCCESS )
+                break;
+            r = ERROR_FUNCTION_FAILED;
+            hr = CLSIDFromString( szguid, &guid );
+            if ( FAILED( hr ) )
+                break;
+            r = ERROR_SUCCESS;
+            /* stop at the first one that succeeds in running */
+            hr = shellex_load_object_and_run( hkey, &guid, sei );
+            if ( SUCCEEDED( hr ) )
+                break;
+        }
+        RegCloseKey( hkeycm );
+    }
+
+    if ( hkey != sei->hkeyClass )
+        RegCloseKey( hkey );
+    return r;
+}
+
 /*************************************************************************
  *     SHELL_execute [Internal]
  */
-BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL unicode )
+BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
 {
     static const WCHAR wQuote[] = {'"',0};
     static const WCHAR wSpace[] = {' ',0};
     static const WCHAR wWww[] = {'w','w','w',0};
     static const WCHAR wFile[] = {'f','i','l','e',0};
     static const WCHAR wHttp[] = {'h','t','t','p',':','/','/',0};
-    static const WCHAR wExtLnk[] = {'.','l','n','k',0};
     static const WCHAR wExplorer[] = {'e','x','p','l','o','r','e','r','.','e','x','e',0};
     static const DWORD unsupportedFlags =
         SEE_MASK_INVOKEIDLIST  | SEE_MASK_ICON         | SEE_MASK_HOTKEY |
@@ -1010,7 +1200,6 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
     UINT_PTR retval = 31;
     WCHAR wcmd[1024];
     WCHAR buffer[MAX_PATH];
-    const WCHAR* ext;
     BOOL done;
 
     /* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
@@ -1077,12 +1266,16 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
                return TRUE;
        }
 
-        wszApplicationName[0] = '"';
-        SHGetPathFromIDListW(sei_tmp.lpIDList, wszApplicationName+1);
-        strcatW(wszApplicationName, wQuote);
+        SHGetPathFromIDListW(sei_tmp.lpIDList, wszApplicationName);
         TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
     }
 
+    if ( ERROR_SUCCESS == ShellExecute_FromContextMenu( &sei_tmp ) )
+    {
+        sei->hInstApp = (HINSTANCE) 33;
+        return TRUE;
+    }
+
     if (sei_tmp.fMask & SEE_MASK_CLASSALL)
     {
        /* launch a document by fileclass like 'WordPad.Document.1' */
@@ -1111,78 +1304,6 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
             return FALSE;
     }
 
-
-    /* resolve shell shortcuts */
-    ext = PathFindExtensionW(sei_tmp.lpFile);
-
-    if (ext && !strncmpiW(ext, wExtLnk, sizeof(wExtLnk) / sizeof(WCHAR) - 1) &&
-        (ext[sizeof(wExtLnk) / sizeof(WCHAR) - 1] == '\0' ||
-         (sei_tmp.lpFile[0] == '"' && ext[sizeof(wExtLnk) / sizeof(WCHAR) - 1] == '"')))       /* or check for: shell_attribs & SFGAO_LINK */
-    {
-       HRESULT hr;
-       BOOL Quoted;
-
-       if (wszApplicationName[0] == '"')
-       {
-           if (wszApplicationName[strlenW(wszApplicationName) - 1] == '"')
-           {
-               wszApplicationName[strlenW(wszApplicationName) - 1] = '\0';
-               Quoted = TRUE;
-           }
-           else
-           {
-               Quoted = FALSE;
-           }
-       }
-       else
-       {
-           Quoted = FALSE;
-       }
-       /* expand paths before reading shell link */
-       if (ExpandEnvironmentStringsW(Quoted ? sei_tmp.lpFile + 1 : sei_tmp.lpFile, buffer, MAX_PATH))
-           lstrcpyW(Quoted ? wszApplicationName + 1 : wszApplicationName/*sei_tmp.lpFile*/, buffer);
-
-       if (*sei_tmp.lpParameters)
-           if (ExpandEnvironmentStringsW(sei_tmp.lpParameters, buffer, MAX_PATH))
-               lstrcpyW(wszParameters/*sei_tmp.lpParameters*/, buffer);
-
-       hr = SHELL_ResolveShortCutW((LPWSTR)(Quoted ? sei_tmp.lpFile + 1 : sei_tmp.lpFile),
-                                   (LPWSTR)sei_tmp.lpParameters, (LPWSTR)sei_tmp.lpDirectory,
-                                   sei_tmp.hwnd, sei_tmp.lpVerb?sei_tmp.lpVerb:wszEmpty, &sei_tmp.nShow, (LPITEMIDLIST*)&sei_tmp.lpIDList);
-       if (Quoted)
-       {
-           wszApplicationName[strlenW(wszApplicationName) + 1] = '\0';
-           wszApplicationName[strlenW(wszApplicationName)] = '"';
-       }
-
-       if (sei->lpIDList)
-           sei->fMask |= SEE_MASK_IDLIST;
-
-       if (SUCCEEDED(hr))
-       {
-           /* repeat IDList processing if needed */
-           if (sei_tmp.fMask & SEE_MASK_IDLIST)
-           {
-               IShellExecuteHookW* pSEH;
-
-               HRESULT hr = SHBindToParent(sei_tmp.lpIDList, &IID_IShellExecuteHookW, (LPVOID*)&pSEH, NULL);
-
-               if (SUCCEEDED(hr))
-               {
-                   hr = IShellExecuteHookW_Execute(pSEH, &sei_tmp);
-
-                   IShellExecuteHookW_Release(pSEH);
-
-                   if (hr == S_OK)
-                       return TRUE;
-               }
-
-               TRACE("-- idlist=%p (%s)\n", debugstr_w(sei_tmp.lpIDList), debugstr_w(sei_tmp.lpFile));
-           }
-       }
-    }
-
-
     /* Has the IDList not yet been translated? */
     if (sei_tmp.fMask & SEE_MASK_IDLIST)
     {
@@ -1314,7 +1435,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
         }
         TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(sei_tmp.lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol));
         if (*lpstrProtocol)
-            retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei_tmp.lpParameters, execfunc, &sei_tmp, sei, unicode);
+            retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei_tmp.lpParameters, execfunc, &sei_tmp, sei);
         else
             retval = execfunc(wszQuotedCmd, env, FALSE, &sei_tmp, sei);
         HeapFree( GetProcessHeap(), 0, env );
@@ -1347,7 +1468,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
             lpFile += iSize;
             while (*lpFile == ':') lpFile++;
         }
-        retval = execute_from_key(lpstrProtocol, lpFile, NULL, sei_tmp.lpParameters, execfunc, &sei_tmp, sei, unicode);
+        retval = execute_from_key(lpstrProtocol, lpFile, NULL, sei_tmp.lpParameters, execfunc, &sei_tmp, sei);
     }
     /* Check if file specified is in the form www.??????.*** */
     else if (!strncmpiW(lpFile, wWww, 3))
@@ -1432,7 +1553,7 @@ BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
     else
         seiW.lpClass = NULL;
 
-    ret = SHELL_execute( &seiW, SHELL_ExecuteW, FALSE );
+    ret = SHELL_execute( &seiW, SHELL_ExecuteW );
 
     sei->hInstApp = seiW.hInstApp;
 
@@ -1454,7 +1575,7 @@ BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
  */
 BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
 {
-    return  SHELL_execute( sei, SHELL_ExecuteW, TRUE );
+    return SHELL_execute( sei, SHELL_ExecuteW );
 }
 
 /*************************************************************************
@@ -1483,6 +1604,6 @@ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile,
     sei.dwHotKey = 0;
     sei.hProcess = 0;
 
-    SHELL_execute( &sei, SHELL_ExecuteW, TRUE );
+    SHELL_execute( &sei, SHELL_ExecuteW );
     return sei.hInstApp;
 }
index 0f9d9b2..b6139b8 100644 (file)
@@ -236,7 +236,7 @@ BOOL SHELL_DeleteFileW(LPCWSTR pszFile, BOOL bShowUI)
  * RETURNS
  *  TRUE if successful, FALSE otherwise
  *
- * NOTES:
+ * NOTES
  *  Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
  *  This is Unicode on NT/2000
  */
@@ -290,7 +290,7 @@ BOOL WINAPI Win32CreateDirectoryAW(LPCVOID path, LPSECURITY_ATTRIBUTES sec)
  * RETURNS
  *  TRUE if successful, FALSE otherwise
  *
- * NOTES:
+ * NOTES
  *  Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
  *  This is Unicode on NT/2000
  */
@@ -354,7 +354,7 @@ BOOL WINAPI Win32RemoveDirectoryAW(LPCVOID path)
  * RETURNS
  *  TRUE if successful, FALSE otherwise
  *
- * NOTES:
+ * NOTES
  *  Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
  *  This is Unicode on NT/2000
  */
@@ -560,6 +560,8 @@ int WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES se
 
 /*************************************************************************
  * SHCreateDirectoryExW      [SHELL32.@]
+ *
+ * See SHCreateDirectoryExA.
  */
 int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
 {
@@ -792,6 +794,10 @@ DWORD SHNameTranslate(LPWSTR* wString, LPCWSTR* pWToFrom, BOOL more)
  * PARAMS
  *  lpFileOp   [I/O] pointer to a structure containing all the necessary information
  *
+ * RETURNS
+ *  Success: zero
+ *  Failure: nonzero
+ *
  * NOTES
  *  exported by name
  */
@@ -998,7 +1004,7 @@ static DWORD shfileops_get_parent_attr(LPWSTR pFile,LPWSTR pTemp)
 /*************************************************************************
  * SHFileOperationW          [SHELL32.@]
  *
- * See SHFileOperationA
+ * See SHFileOperationA.
  */
 int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
 {
@@ -1394,6 +1400,8 @@ shfileop_end:
  * PARAMS
  *  hNameMapping [I] handle to the name mappings used during renaming of files
  *
+ * RETURNS
+ *  Nothing
  */
 void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
 {
index 6063e01..d033b2a 100644 (file)
@@ -192,12 +192,12 @@ HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
  *   pathRoot can be NULL for Folders beeing a drive.
  *   In this case the absolute path is build from pidlChild (eg. C:)
  */
-HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot,        LPCSTR pathRoot,
+static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
     LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID riid, LPVOID * ppvOut)
 {
     HRESULT hr;
 
-    TRACE ("%p %s %p\n", pidlRoot, pathRoot, pidlChild);
+    TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild);
 
     if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, clsid, NULL, riid, ppvOut)))) {
        LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
@@ -208,32 +208,29 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot,   LPCSTR pathRoot,
             SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) 
         {
            PERSIST_FOLDER_TARGET_INFO ppfti;
-           char szDestPath[MAX_PATH];
 
            ZeroMemory (&ppfti, sizeof (ppfti));
 
+           /* fill the PERSIST_FOLDER_TARGET_INFO */
+           ppfti.dwAttributes = -1;
+           ppfti.csidl = -1;
+
            /* build path */
            if (pathRoot) {
-               lstrcpyA (szDestPath, pathRoot);
-               PathAddBackslashA(szDestPath);          /* FIXME: why have drives a backslash here ? */
-           } else {
-               szDestPath[0] = '\0';
+               lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
+               PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */
            }
 
            if (pidlChild) {
-               LPSTR pszChild = _ILGetTextPointer(pidlChild);
+               LPCSTR pszChild = _ILGetTextPointer(pidlChild);
+                int len = lstrlenW(ppfti.szTargetParsingName);
 
                if (pszChild)
-                   lstrcatA (szDestPath, pszChild);
+                   MultiByteToWideChar (CP_ACP, 0, pszChild, -1, ppfti.szTargetParsingName + len, MAX_PATH - len);
                else
                    hr = E_INVALIDARG;
            }
 
-           /* fill the PERSIST_FOLDER_TARGET_INFO */
-           ppfti.dwAttributes = -1;
-           ppfti.csidl = -1;
-           MultiByteToWideChar (CP_ACP, 0, szDestPath, -1, ppfti.szTargetParsingName, MAX_PATH);
-
            IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti);
            IPersistFolder3_Release (ppf);
        }
@@ -265,7 +262,7 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot,     LPCSTR pathRoot,
  *  means you probably can't use it for your IShellFolder implementation.
  */
 HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
-                             LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
+                             LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
 {
     GUID const *clsid;
     IShellFolder *pSF;
@@ -290,10 +287,10 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
        
         /* see if folder CLSID should be overridden by desktop.ini file */
         if (pathRoot) {
-            MultiByteToWideChar(CP_ACP, 0, pathRoot, -1, wszFolderPath, MAX_PATH);
+            lstrcpynW(wszFolderPath, pathRoot, MAX_PATH);
             pwszPathTail = PathAddBackslashW(wszFolderPath);
         }
-        MultiByteToWideChar(CP_ACP, 0, _ILGetTextPointer(pidlChild), -1, pwszPathTail, MAX_PATH);
+        MultiByteToWideChar(CP_ACP, 0, _ILGetTextPointer(pidlChild), -1, pwszPathTail, MAX_PATH - (int)(pwszPathTail - wszFolderPath));
         if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath,
             wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID))
             CLSIDFromString (wszCLSIDValue, &clsidFolder);
@@ -421,16 +418,23 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO
     } else if (_ILGetDataPointer (pidl)) {
        dwAttributes = _ILGetFileAttributes (pidl, NULL, 0);
 
-        if ((SFGAO_FILESYSANCESTOR & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
-            *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
+        /* Set common attributes */
+        *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | 
+                          SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY;
 
-       if ((SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
-           *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
+       if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
+           *pdwAttributes |=  (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
+       else
+           *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
 
-       if ((SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
+       if (dwAttributes & FILE_ATTRIBUTE_HIDDEN)
+           *pdwAttributes |=  SFGAO_HIDDEN;
+       else
            *pdwAttributes &= ~SFGAO_HIDDEN;
 
-       if ((SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
+       if (dwAttributes & FILE_ATTRIBUTE_READONLY)
+           *pdwAttributes |=  SFGAO_READONLY;
+       else
            *pdwAttributes &= ~SFGAO_READONLY;
 
        if (SFGAO_LINK & *pdwAttributes) {
index 99810dc..1a45100 100644 (file)
@@ -818,6 +818,8 @@ void WINAPI FileMenu_AbortInitMenu (void)
 /*************************************************************************
  * SHFind_InitMenuPopup                                [SHELL32.149]
  *
+ * Get the IContextMenu instance for the submenu of options displayed
+ * for the Search entry in the Classic style Start menu.
  *
  * PARAMETERS
  *  hMenu              [in] handle of menu previously created
index 2dbe589..8dd241f 100644 (file)
@@ -46,15 +46,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
 typedef struct SystrayItem {
   HWND                  hWnd;
   HWND                  hWndToolTip;
-  NOTIFYICONDATAA       notifyIcon;
+  NOTIFYICONDATAW       notifyIcon;
   struct SystrayItem    *nextTrayItem;
 } SystrayItem;
 
 static SystrayItem *systray=NULL;
 static int firstSystray=TRUE; /* defer creation of window class until first systray item is created */
 
-static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid);
-
 
 #define ICON_SIZE GetSystemMetrics(SM_CXSMICON)
 /* space around icon (forces icon to center of KDE systray area) */
@@ -62,13 +60,47 @@ static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid);
 
 
 
-static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAA pnid1, PNOTIFYICONDATAA pnid2)
+static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAW pnid1, PNOTIFYICONDATAW pnid2)
 {
   if (pnid1->hWnd != pnid2->hWnd) return FALSE;
   if (pnid1->uID  != pnid2->uID)  return FALSE;
   return TRUE;
 }
 
+
+static void SYSTRAY_ItemTerm(SystrayItem *ptrayItem)
+{
+  if(ptrayItem->notifyIcon.hIcon)
+     DestroyIcon(ptrayItem->notifyIcon.hIcon);
+  if(ptrayItem->hWndToolTip)
+      DestroyWindow(ptrayItem->hWndToolTip);
+  if(ptrayItem->hWnd)
+    DestroyWindow(ptrayItem->hWnd);
+  return;
+}
+
+
+static BOOL SYSTRAY_Delete(PNOTIFYICONDATAW pnid)
+{
+  SystrayItem **ptrayItem = &systray;
+
+  while (*ptrayItem) {
+    if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon)) {
+      SystrayItem *next = (*ptrayItem)->nextTrayItem;
+      TRACE("%p: %p %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd, debugstr_w((*ptrayItem)->notifyIcon.szTip));
+      SYSTRAY_ItemTerm(*ptrayItem);
+
+      HeapFree(GetProcessHeap(),0,*ptrayItem);
+      *ptrayItem = next;
+
+      return TRUE;
+    }
+    ptrayItem = &((*ptrayItem)->nextTrayItem);
+  }
+
+  return FALSE; /* not found */
+}
+
 static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
   HDC hdc;
@@ -120,7 +152,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
         msg.pt.x = LOWORD(GetMessagePos ());
         msg.pt.y = HIWORD(GetMessagePos ());
 
-        SendMessageA(ptrayItem->hWndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
+        SendMessageW(ptrayItem->hWndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
       }
       ptrayItem = ptrayItem->nextTrayItem;
     }
@@ -136,7 +168,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
     while (ptrayItem) {
       if (ptrayItem->hWnd == hWnd) {
        if (ptrayItem->notifyIcon.hWnd && ptrayItem->notifyIcon.uCallbackMessage) {
-          if (!PostMessageA(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
+          if (!PostMessageW(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
                             (WPARAM)ptrayItem->notifyIcon.uID, (LPARAM)message)) {
              ERR("PostMessage(SystrayWindow %p) failed -> removing SystrayItem %p\n", hWnd, ptrayItem);
              SYSTRAY_Delete(&ptrayItem->notifyIcon);
@@ -150,7 +182,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
   break;
 
   default:
-    return (DefWindowProcA(hWnd, message, wParam, lParam));
+    return (DefWindowProcW(hWnd, message, wParam, lParam));
   }
   return (0);
 
@@ -159,7 +191,8 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
 
 static BOOL SYSTRAY_RegisterClass(void)
 {
-  WNDCLASSA  wc;
+  WNDCLASSW  wc;
+  static const WCHAR WineSystrayW[] = { 'W','i','n','e','S','y','s','t','r','a','y',0 };
 
   wc.style         = CS_SAVEBITS|CS_DBLCLKS;
   wc.lpfnWndProc   = SYSTRAY_WndProc;
@@ -167,12 +200,12 @@ static BOOL SYSTRAY_RegisterClass(void)
   wc.cbWndExtra    = 0;
   wc.hInstance     = 0;
   wc.hIcon         = 0;
-  wc.hCursor       = LoadCursorA(0, (LPSTR)IDC_ARROW);
+  wc.hCursor       = LoadCursorW(0, (LPWSTR)IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
   wc.lpszMenuName  = NULL;
-  wc.lpszClassName = "WineSystray";
+  wc.lpszClassName = WineSystrayW;
 
-  if (!RegisterClassA(&wc)) {
+  if (!RegisterClassW(&wc)) {
     ERR("RegisterClass(WineSystray) failed\n");
     return FALSE;
   }
@@ -183,6 +216,8 @@ static BOOL SYSTRAY_RegisterClass(void)
 static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
 {
   RECT rect;
+  static const WCHAR WineSystrayW[] = { 'W','i','n','e','S','y','s','t','r','a','y',0 };
+  static const WCHAR Wine_SystrayW[] = { 'W','i','n','e','-','S','y','s','t','r','a','y',0 };
 
   /* Register the class if this is our first tray item. */
   if ( firstSystray ) {
@@ -201,8 +236,8 @@ static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
 
   ZeroMemory( ptrayItem, sizeof(SystrayItem) );
   /* Create tray window for icon. */
-  ptrayItem->hWnd = CreateWindowExA( WS_EX_TRAYWINDOW,
-                                "WineSystray", "Wine-Systray",
+  ptrayItem->hWnd = CreateWindowExW( WS_EX_TRAYWINDOW,
+                                WineSystrayW, Wine_SystrayW,
                                 WS_VISIBLE,
                                 CW_USEDEFAULT, CW_USEDEFAULT,
                                 rect.right-rect.left, rect.bottom-rect.top,
@@ -213,7 +248,7 @@ static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
   }
 
   /* Create tooltip for icon. */
-  ptrayItem->hWndToolTip = CreateWindowA( TOOLTIPS_CLASSA,NULL,TTS_ALWAYSTIP,
+  ptrayItem->hWndToolTip = CreateWindowW( TOOLTIPS_CLASSW,NULL,TTS_ALWAYSTIP,
                                      CW_USEDEFAULT, CW_USEDEFAULT,
                                      CW_USEDEFAULT, CW_USEDEFAULT,
                                      ptrayItem->hWnd, 0, 0, 0 );
@@ -225,18 +260,6 @@ static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
 }
 
 
-static void SYSTRAY_ItemTerm(SystrayItem *ptrayItem)
-{
-  if(ptrayItem->notifyIcon.hIcon)
-     DestroyIcon(ptrayItem->notifyIcon.hIcon);
-  if(ptrayItem->hWndToolTip)
-      DestroyWindow(ptrayItem->hWndToolTip);
-  if(ptrayItem->hWnd)
-    DestroyWindow(ptrayItem->hWnd);
-  return;
-}
-
-
 static void SYSTRAY_ItemSetMessage(SystrayItem *ptrayItem, UINT uCallbackMessage)
 {
   ptrayItem->notifyIcon.uCallbackMessage = uCallbackMessage;
@@ -252,13 +275,13 @@ static void SYSTRAY_ItemSetIcon(SystrayItem *ptrayItem, HICON hIcon)
 }
 
 
-static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
+static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, const WCHAR* szTip, int modify)
 {
-  TTTOOLINFOA ti;
+  TTTOOLINFOW ti;
 
-  lstrcpynA(ptrayItem->notifyIcon.szTip, szTip, sizeof(ptrayItem->notifyIcon.szTip));
+  lstrcpynW(ptrayItem->notifyIcon.szTip, szTip, sizeof(ptrayItem->notifyIcon.szTip)/sizeof(WCHAR));
 
-  ti.cbSize = sizeof(TTTOOLINFOA);
+  ti.cbSize = sizeof(TTTOOLINFOW);
   ti.uFlags = 0;
   ti.hwnd = ptrayItem->hWnd;
   ti.hinst = 0;
@@ -270,15 +293,16 @@ static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
   ti.rect.bottom = ICON_SIZE+2*ICON_BORDER;
 
   if(modify)
-    SendMessageA(ptrayItem->hWndToolTip, TTM_UPDATETIPTEXTA, 0, (LPARAM)&ti);
+    SendMessageW(ptrayItem->hWndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti);
   else
-    SendMessageA(ptrayItem->hWndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
+    SendMessageW(ptrayItem->hWndToolTip, TTM_ADDTOOLW, 0, (LPARAM)&ti);
 }
 
 
-static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
+static BOOL SYSTRAY_Add(PNOTIFYICONDATAW pnid)
 {
   SystrayItem **ptrayItem = &systray;
+  static const WCHAR emptyW[] = { 0 };
 
   /* Find last element. */
   while( *ptrayItem ) {
@@ -295,15 +319,15 @@ static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
   (*ptrayItem)->notifyIcon.hWnd = pnid->hWnd; /* only needed for callback message */
   SYSTRAY_ItemSetIcon   (*ptrayItem, (pnid->uFlags&NIF_ICON)   ?pnid->hIcon           :0);
   SYSTRAY_ItemSetMessage(*ptrayItem, (pnid->uFlags&NIF_MESSAGE)?pnid->uCallbackMessage:0);
-  SYSTRAY_ItemSetTip    (*ptrayItem, (pnid->uFlags&NIF_TIP)    ?pnid->szTip           :"", FALSE);
+  SYSTRAY_ItemSetTip    (*ptrayItem, (pnid->uFlags&NIF_TIP)    ?pnid->szTip           :emptyW, FALSE);
 
   TRACE("%p: %p %s\n",  (*ptrayItem), (*ptrayItem)->notifyIcon.hWnd,
-                                          (*ptrayItem)->notifyIcon.szTip);
+                                          debugstr_w((*ptrayItem)->notifyIcon.szTip));
   return TRUE;
 }
 
 
-static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
+static BOOL SYSTRAY_Modify(PNOTIFYICONDATAW pnid)
 {
   SystrayItem *ptrayItem = systray;
 
@@ -316,7 +340,7 @@ static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
       if (pnid->uFlags & NIF_TIP)
         SYSTRAY_ItemSetTip(ptrayItem, pnid->szTip, TRUE);
 
-      TRACE("%p: %p %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.szTip);
+      TRACE("%p: %p %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd, debugstr_w(ptrayItem->notifyIcon.szTip));
       return TRUE;
     }
     ptrayItem = ptrayItem->nextTrayItem;
@@ -325,27 +349,6 @@ static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
 }
 
 
-static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid)
-{
-  SystrayItem **ptrayItem = &systray;
-
-  while (*ptrayItem) {
-    if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon)) {
-      SystrayItem *next = (*ptrayItem)->nextTrayItem;
-      TRACE("%p: %p %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd, (*ptrayItem)->notifyIcon.szTip);
-      SYSTRAY_ItemTerm(*ptrayItem);
-
-      HeapFree(GetProcessHeap(),0,*ptrayItem);
-      *ptrayItem = next;
-
-      return TRUE;
-    }
-    ptrayItem = &((*ptrayItem)->nextTrayItem);
-  }
-
-  return FALSE; /* not found */
-}
-
 /*************************************************************************
  *
  */
@@ -355,10 +358,9 @@ BOOL SYSTRAY_Init(void)
 }
 
 /*************************************************************************
- * Shell_NotifyIcon                    [SHELL32.296]
- * Shell_NotifyIconA                   [SHELL32.297]
+ * Shell_NotifyIconW                   [SHELL32.298]
  */
-BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
+BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid )
 {
   BOOL flag=FALSE;
   TRACE("enter %p %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
@@ -378,18 +380,19 @@ BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
 }
 
 /*************************************************************************
- * Shell_NotifyIconW                   [SHELL32.298]
+ * Shell_NotifyIconA                   [SHELL32.297]
+ * Shell_NotifyIcon                    [SHELL32.296]
  */
-BOOL WINAPI Shell_NotifyIconW (DWORD dwMessage, PNOTIFYICONDATAW pnid )
+BOOL WINAPI Shell_NotifyIconA (DWORD dwMessage, PNOTIFYICONDATAA pnid )
 {
        BOOL ret;
 
-       PNOTIFYICONDATAA p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAA));
-       memcpy(p, pnid, sizeof(NOTIFYICONDATAA));
-        WideCharToMultiByte( CP_ACP, 0, pnid->szTip, -1, p->szTip, sizeof(p->szTip), NULL, NULL );
-        p->szTip[sizeof(p->szTip)-1] = 0;
+       PNOTIFYICONDATAW p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAW));
+       memcpy(p, pnid, sizeof(NOTIFYICONDATAW));
+        MultiByteToWideChar( CP_ACP, 0, pnid->szTip, -1, p->szTip, sizeof(p->szTip)/sizeof(WCHAR) );
+        p->szTip[sizeof(p->szTip)/sizeof(WCHAR)-1] = 0;
 
-       ret = Shell_NotifyIconA(dwMessage, p );
+       ret = Shell_NotifyIconW(dwMessage, p );
 
        HeapFree(GetProcessHeap(),0,p);
        return ret;
diff --git a/reactos/w32api/include/appmgmt.h b/reactos/w32api/include/appmgmt.h
new file mode 100644 (file)
index 0000000..c66b1ba
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005 Mike McCormack
+ *
+ * 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
+ */
+
+#ifndef _APPMGMT_H
+#define _APPMGMT_H
+
+typedef struct _MANAGEDAPPLICATION
+{
+    LPWSTR pszPackageName;
+    LPWSTR pszPublisher;
+    DWORD dwVersionHi;
+    DWORD dwVersionLo;
+    DWORD dwRevision;
+    GUID GpoId;
+    LPWSTR pszPolicyName;
+    GUID ProductId;
+    LANGID Language;
+    LPWSTR pszOwner;
+    LPWSTR pszCompany;
+    LPWSTR pszComments;
+    LPWSTR pszContact;
+    LPWSTR pszSupportUrl;
+    DWORD dwPathType;
+    BOOL bInstalled;
+} MANAGEDAPPLICATION, *PMANAGEDAPPLICATION;
+
+DWORD WINAPI CommandLineFromMsiDescriptor(WCHAR*,WCHAR*,DWORD*);
+DWORD WINAPI GetManagedApplications(GUID*,DWORD,DWORD,LPDWORD,PMANAGEDAPPLICATION*);
+
+#endif /* _APPMGMT_H */
index b0afb13..1f303f6 100644 (file)
@@ -51,7 +51,13 @@ extern "C" {
 #endif
 #define DVASPECT_SHORTNAME 2
 #define SHARD_PIDL     1
-#define SHARD_PATH     2
+#define SHARD_PATHA    2
+#define SHARD_PATHW    3
+#ifdef UNICODE
+#define SHARD_PATH     SHARD_PATHW
+#else
+#define SHARD_PATH     SHARD_PATHA
+#endif
 #define SHCNE_RENAMEITEM       1
 #define SHCNE_CREATE   2
 #define SHCNE_DELETE   4
@@ -282,6 +288,7 @@ extern "C" {
 #define CMIC_MASK_HOTKEY       SEE_MASK_HOTKEY
 #define CMIC_MASK_ICON SEE_MASK_ICON
 #define CMIC_MASK_FLAG_NO_UI   SEE_MASK_FLAG_NO_UI
+#define CMIC_MASK_UNICODE      SEE_MASK_UNICODE
 #define CMIC_MASK_MODAL        0x80000000
 #define CMIC_VALID_SEE_FLAGS   SEE_VALID_CMIC_FLAGS
 #define GIL_OPENICON   1
@@ -458,6 +465,23 @@ typedef struct _CMInvokeCommandInfo {
        DWORD dwHotKey;
        HANDLE hIcon;
 } CMINVOKECOMMANDINFO,*LPCMINVOKECOMMANDINFO;
+typedef struct _CMInvokeCommandInfoEx {
+       DWORD cbSize;
+       DWORD fMask;
+       HWND hwnd;
+       LPCSTR lpVerb;
+       LPCSTR lpParameters;
+       LPCSTR lpDirectory;
+       INT nShow;
+       DWORD dwHotKey;
+       HANDLE hIcon;
+       LPCSTR lpTitle;
+       LPCWSTR lpVerbW;
+       LPCWSTR lpParametersW;
+       LPCWSTR lpDirectoryW;
+       LPCWSTR lpTitleW;
+       POINT ptInvoke;
+} CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX;
 typedef struct _DROPFILES {
        DWORD pFiles;
        POINT pt;
@@ -1788,6 +1812,13 @@ LPITEMIDLIST WINAPI ILAppendID(LPITEMIDLIST, LPCSHITEMID, BOOL);
 LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST);
 LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST);
 LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST, LPCITEMIDLIST);
+LPITEMIDLIST WINAPI ILCreateFromPathA(LPCSTR);
+LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR);
+#ifdef UNICODE
+#define ILCreateFromPath ILCreateFromPathW
+#else
+#define ILCreateFromPath ILCreateFromPathA
+#endif
 LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST, LPCITEMIDLIST);
 LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST);
 LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST);