Ge van Geldorp <gvg@reactos.com>
authorGé van Geldorp <ge@gse.nl>
Sat, 28 May 2005 21:30:32 +0000 (21:30 +0000)
committerGé van Geldorp <ge@gse.nl>
Sat, 28 May 2005 21:30:32 +0000 (21:30 +0000)
- Overlay icons for .lnk files with a small arrow in the lower left
  corner.
Alexandre Julliard <julliard@winehq.org>
- Added rules for building import libraries in the individual dll
  makefiles, and added support for building a .def.a static import
  library too.
- Removed unnecessary code in the 16-bit DllEntryPoint function of some
  dlls, and also fixed its ordinal in a few places.
- Comment out stub WEP entry points so that we can call WEP for builtin
  dlls too.
Juan Lang <juan_lang@yahoo.com>
- Fixes to IShellFolder::GetAttributesOf implementations, spotted by
  silverblade_:
  - a count of zero is allowed to GetAttributesOf if apidl is NULL
  - SFGAO_VALIDATE must be cleared upon return
- only log unsupported flags in ShellExecute
- environment variables are expanded, so SEE_MASK_DOENVSUBST is
  supported
Michael Jung <mjung@iss.tu-darmstadt.de>
- Add a new CLSID for UnixDosFolder, which is identical to UnixFolder,
  but does unix <-> dos path conversion for GetDisplayNameOf and
  ParseDisplayName.
- Make the root of the shell extension map to the root of the unix
  filesystem.
- More robustly query the SHGDN_FORPARSING flag in the shell32's folders
  GetDisplayNameOf methods.
- Fixed GetDisplayNameOf method to not depend on incorrect behaviour
  regarding the SHGDN_INFOLDER flag.
- Fixed MyComputer's GetDisplayNameOf method.
- Return a cloned PIDL by SHBrowseForFolder to avoid heap corruption.
- Fixed incorrect IShellFolder::EnumOjects API usage.
- Support for regular files (as opposed to directories).
- Display a drive icon for the unix root directory.
- Consider only the GIL_FORSHORTCUT flag in SIC_CompareEntries.
Stefan Doesinger <stefandoesinger@gmx.at>
- Handle cidl==0 in shfldr_desktop, shfldr_fs and shfldr_mycomp.
- Remove the dwAttributes member from the IGenericSFImpl class, it's
  not needed and can't be initialised in Initialize and InitializeEx.
Mike McCormack <mike@codeweavers.com>
- Split SHGetFileInfoW into two functions.
- Remove static variables in SHBrowseForFolder implementation.
- Split up the window procedure.
- Remove some unused include files.
- MSI advertised shortcuts don't require a product ID.
Peter Berg Larsen <pebl@math.ku.dk>
- Rewritten DoEnvironmentSubst16.
Kouji Sasaki <taro-x@justsystem.co.jp>
- Added the processing for determination of SFGAO_HASSUBFOLDER flag in
  SHELL32_GetItemAttribute function.
Francois Gouget <fgouget@free.fr>
- Assorted spelling fixes.
Huw Davies <huw@codeweavers.com>
- It makes no sense to have a left pointing arrow as the desktop icon.
  Replace it with something more appropiate.
Mike Hearn <mh@codeweavers.com>
- Fix SHELL_GetPathFromIDList[AW] to return the desktop path given an
  empty PIDL.

svn path=/trunk/; revision=15617

22 files changed:
reactos/lib/shell32/Makefile.in
reactos/lib/shell32/brsfolder.c
reactos/lib/shell32/cpanelfolder.c
reactos/lib/shell32/folders.c
reactos/lib/shell32/iconcache.c
reactos/lib/shell32/pidl.c
reactos/lib/shell32/regsvr.c
reactos/lib/shell32/shell.c
reactos/lib/shell32/shell.spec
reactos/lib/shell32/shell32_De.rc
reactos/lib/shell32/shell32_En.rc
reactos/lib/shell32/shell32_main.c
reactos/lib/shell32/shell32_main.h
reactos/lib/shell32/shelllink.c
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/shres.rc
reactos/lib/shell32/shresdef.h

index b28dfc4..3915b15 100644 (file)
@@ -4,6 +4,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = shell32.dll
+IMPORTLIB = libshell32.$(IMPLIBEXT)
 IMPORTS   = shlwapi comctl32 user32 gdi32 advapi32 kernel32
 DELAYIMPORTS = ole32
 EXTRALIBS = -luuid $(LIBUNICODE)
@@ -63,7 +64,8 @@ RC_BINARIES = \
        netdrive.ico \
        netdrive2.ico \
        printer.ico \
-       ramdisk.ico
+       ramdisk.ico \
+       shortcut.ico
 
 C_SRCS16  = shell.c
 RC_SRCS16 = version16.rc
index 63be4a3..52c5d5f 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
-static HWND            hwndTreeView;
-static LPBROWSEINFOW   lpBrowseInfo;
-static LPITEMIDLIST    pidlRet;
+typedef struct tagbrowse_info
+{
+    HWND          hWnd;
+    HWND          hwndTreeView;
+    LPBROWSEINFOW lpBrowseInfo;
+    LPITEMIDLIST  pidlRet;
+} browse_info;
 
-static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST  lpifq, HTREEITEM hParent, IEnumIDList* lpe);
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent);
+typedef struct tagTV_ITEMDATA
+{
+   LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
+   LPITEMIDLIST  lpi;        /* PIDL relativ to parent */
+   LPITEMIDLIST  lpifq;      /* Fully qualified PIDL */
+   IEnumIDList*  pEnumIL;    /* Children iterator */ 
+} TV_ITEMDATA, *LPTV_ITEMDATA;
 
 #define SUPPORTEDFLAGS (BIF_STATUSTEXT | \
                         BIF_BROWSEFORCOMPUTER | \
@@ -50,11 +59,30 @@ static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, LPC
                         BIF_RETURNONLYFSDIRS | \
                         BIF_BROWSEINCLUDEFILES)
 
+static void FillTreeView(browse_info*, LPSHELLFOLDER,
+               LPITEMIDLIST, HTREEITEM, IEnumIDList*);
+static HTREEITEM InsertTreeViewItem( browse_info*, IShellFolder *,
+               LPCITEMIDLIST, LPCITEMIDLIST, IEnumIDList*, HTREEITEM);
+
+const WCHAR szBrowseFolderInfo[] = {
+    '_','_','W','I','N','E','_',
+    'B','R','S','F','O','L','D','E','R','D','L','G','_',
+    'I','N','F','O',0
+};
+
 static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
 {
     return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS : 0);
 }
 
+static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND hWnd,
+                                   UINT msg, LPARAM param )
+{
+    if (!lpBrowseInfo->lpfn)
+        return;
+    lpBrowseInfo->lpfn( hWnd, BFFM_INITIALIZED, param, lpBrowseInfo->lParam );
+}
+
 /******************************************************************************
  * InitializeTreeView [Internal]
  *
@@ -64,25 +92,23 @@ static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
  *  hwndParent [I] The BrowseForFolder dialog
  *  root       [I] ITEMIDLIST of the root shell folder
  */
-static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
+static void InitializeTreeView( browse_info *info )
 {
     LPITEMIDLIST pidlParent, pidlChild;
     HIMAGELIST hImageList;
     HRESULT hr;
     IShellFolder *lpsfParent, *lpsfRoot;
     IEnumIDList * pEnumChildren = NULL;
+    HTREEITEM item;
+    DWORD flags;
+    LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot;
 
-    TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
+    TRACE("%p\n", info );
     
-    hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
-    if (!hwndTreeView) {
-        FIXME("Could not get handle to treeview control! Error: %08lx\n", GetLastError());
-        return;
-    }
     Shell_GetImageList(NULL, &hImageList);
 
     if (hImageList)
-        TreeView_SetImageList(hwndTreeView, hImageList, 0);
+        TreeView_SetImageList( info->hwndTreeView, hImageList, 0 );
 
     /* We want to call InsertTreeViewItem down the code, in order to insert
      * the root item of the treeview. Due to InsertTreeViewItem's signature, 
@@ -131,7 +157,8 @@ static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
         return;
     }
 
-    hr = IShellFolder_EnumObjects(lpsfRoot, hwndParent, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumChildren);
+    flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags );
+    hr = IShellFolder_EnumObjects( lpsfRoot, info->hWnd, flags, &pEnumChildren );
     if (!SUCCEEDED(hr)) {
         WARN("Could not get child iterator! hr = %08lx\n", hr);
         IShellFolder_Release(lpsfParent);
@@ -139,8 +166,10 @@ static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
         return;
     }
 
-    TreeView_DeleteAllItems(hwndTreeView);
-    TreeView_Expand(hwndTreeView, InsertTreeViewItem(lpsfParent, pidlChild, pidlParent, pEnumChildren,  TVI_ROOT), TVE_EXPAND);
+    TreeView_DeleteAllItems( info->hwndTreeView );
+    item = InsertTreeViewItem( info, lpsfParent, pidlChild,
+                               pidlParent, pEnumChildren, TVI_ROOT );
+    TreeView_Expand( info->hwndTreeView, item, TVE_EXPAND );
 
     IShellFolder_Release(lpsfRoot);
     IShellFolder_Release(lpsfParent);
@@ -148,40 +177,34 @@ static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
 
 static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
 {
-       SHFILEINFOW    sfi;
-       SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
-       return sfi.iIcon;
+    SHFILEINFOW sfi;
+    SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
+    return sfi.iIcon;
 }
 
 static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
 {
-       LPITEMIDLIST pidlDesktop = NULL;
+    LPITEMIDLIST pidlDesktop = NULL;
+    DWORD flags;
 
-       TRACE("%p %p\n",lpifq, lpTV_ITEM);
+    TRACE("%p %p\n",lpifq, lpTV_ITEM);
 
-       if (!lpifq)
-       {
-           pidlDesktop = _ILCreateDesktop();
-           lpifq = pidlDesktop;
-       }
+    if (!lpifq)
+    {
+        pidlDesktop = _ILCreateDesktop();
+        lpifq = pidlDesktop;
+    }
 
-       lpTV_ITEM->iImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
-       lpTV_ITEM->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);
+    flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
+    lpTV_ITEM->iImage = GetIcon( lpifq, flags );
 
-       if (pidlDesktop)
-           ILFree(pidlDesktop);
+    flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON;
+    lpTV_ITEM->iSelectedImage = GetIcon( lpifq, flags );
 
-       return;
+    if (pidlDesktop)
+        ILFree( pidlDesktop );
 }
 
-typedef struct tagID
-{
-   LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
-   LPITEMIDLIST  lpi;        /* PIDL relativ to parent */
-   LPITEMIDLIST  lpifq;      /* Fully qualified PIDL */
-   IEnumIDList*  pEnumIL;    /* Children iterator */ 
-} TV_ITEMDATA, *LPTV_ITEMDATA;
-
 /******************************************************************************
  * GetName [Internal]
  *
@@ -221,6 +244,7 @@ static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR
  * InsertTreeViewItem [Internal]
  *
  * PARAMS
+ *  info       [I] data for the dialog
  *  lpsf       [I] IShellFolder interface of the item's parent shell folder 
  *  pidl       [I] ITEMIDLIST of the child to insert, relativ to parent 
  *  pidlParent [I] ITEMIDLIST of the parent shell folder
@@ -231,8 +255,9 @@ static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR
  *  Success: Handle to the created and inserted treeview-item
  *  Failure: NULL
  */
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, 
-    LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
+static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder * lpsf,
+    LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL,
+    HTREEITEM hParent)
 {
        TVITEMW         tvi;
        TVINSERTSTRUCTW tvins;
@@ -244,7 +269,8 @@ static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl,
        tvi.cChildren= pEnumIL ? 1 : 0;
        tvi.mask |= TVIF_CHILDREN;
 
-       if (!(lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA))))
+       lptvid = SHAlloc( sizeof(TV_ITEMDATA) );
+       if (!lptvid)
            return NULL;
 
        if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
@@ -265,7 +291,7 @@ static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl,
        tvins.hInsertAfter = NULL;
        tvins.hParent      = hParent;
 
-       return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
+       return (HTREEITEM)TreeView_InsertItemW( info->hwndTreeView, &tvins );
 }
 
 /******************************************************************************
@@ -275,26 +301,28 @@ static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl,
  * lpsf and whose PIDL is pidl, insert a treeview-item right under hParent
  *
  * PARAMS
+ *  info    [I] data for the dialog
  *  lpsf    [I] IShellFolder interface of the parent shell folder
  *  pidl    [I] ITEMIDLIST of the parent shell folder
  *  hParent [I] The treeview item that represents the parent shell folder
  *  lpe     [I] An iterator for the children of the parent shell folder
  */
-static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST  pidl, HTREEITEM hParent, IEnumIDList* lpe)
+static void FillTreeView( browse_info *info, IShellFolder * lpsf,
+                 LPITEMIDLIST  pidl, HTREEITEM hParent, IEnumIDList* lpe)
 {
        HTREEITEM       hPrev = 0;
        LPITEMIDLIST    pidlTemp = 0;
        ULONG           ulFetched;
        HRESULT         hr;
-       HWND            hwnd=GetParent(hwndTreeView);
+       HWND            hwnd = GetParent( info->hwndTreeView );
 
        TRACE("%p %p %x %p\n",lpsf, pidl, (INT)hParent, lpe);
 
        /* No IEnumIDList -> No children */
        if (!lpe) return;
        
-       SetCapture(GetParent(hwndTreeView));
-       SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
+       SetCapture( hwnd );
+       SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) );
 
        while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
        {
@@ -307,10 +335,12 @@ static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST  pidl, HTREEITEM hPar
                hr = IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)&pSFChild);
                if (SUCCEEDED(hr))
                 {
-                   hr = IShellFolder_EnumObjects(pSFChild, hwnd, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumIL);
-                    if (SUCCEEDED(hr))
+                   DWORD flags = BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
+                   hr = IShellFolder_EnumObjects(pSFChild, hwnd, flags, &pEnumIL);
+                    if (hr == S_OK)
                     {
-                        if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) || FAILED(IEnumIDList_Reset(pEnumIL)))
+                        if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) ||
+                             FAILED(IEnumIDList_Reset(pEnumIL)))
                         {
                             IEnumIDList_Release(pEnumIL);
                             pEnumIL = NULL;
@@ -320,13 +350,13 @@ static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST  pidl, HTREEITEM hPar
                 }
            }
 
-           if (!(hPrev = InsertTreeViewItem(lpsf, pidlTemp, pidl, pEnumIL, hParent)))
-               goto Done;
+           if (!(hPrev = InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent)))
+               goto done;
            SHFree(pidlTemp);  /* Finally, free the pidl that the shell gave us... */
            pidlTemp=NULL;
        }
 
-Done:
+done:
        ReleaseCapture();
        SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
 
@@ -342,182 +372,238 @@ static inline BOOL PIDLIsType(LPCITEMIDLIST pidl, PIDLTYPE type)
     return (data->type == type);
 }
 
-static void BrsFolder_CheckValidSelection(HWND hWndTree, LPTV_ITEMDATA lptvid)
+static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptvid )
 {
+    LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
     LPCITEMIDLIST pidl = lptvid->lpi;
     BOOL bEnabled = TRUE;
     DWORD dwAttributes;
+    HRESULT r;
+
     if ((lpBrowseInfo->ulFlags & BIF_BROWSEFORCOMPUTER) &&
         !PIDLIsType(pidl, PT_COMP))
         bEnabled = FALSE;
     if (lpBrowseInfo->ulFlags & BIF_RETURNFSANCESTORS)
     {
         dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
-        if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) ||
-            !dwAttributes)
+        r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
+                                (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
+        if (FAILED(r) || !dwAttributes)
             bEnabled = FALSE;
     }
     if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
     {
         dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
-        if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1, (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) ||
-            (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
+        r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
+                                (LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
+        if (FAILED(r) || (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
             bEnabled = FALSE;
     }
-    SendMessageW(hWndTree, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
+    SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
 }
 
-static LRESULT MsgNotify(HWND hWnd,  UINT CtlID, LPNMHDR lpnmh)
+static LRESULT BrsFolder_Treeview_Delete( browse_info *info, NMTREEVIEWW *pnmtv )
 {
-       NMTREEVIEWW     *pnmtv   = (NMTREEVIEWW *)lpnmh;
-       LPTV_ITEMDATA   lptvid;  /* Long pointer to TreeView item data */
-       IShellFolder *  lpsf2=0;
+    LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA)pnmtv->itemOld.lParam;
 
+    TRACE("TVN_DELETEITEMA/W %p\n", lptvid);
 
-       TRACE("%p %x %p msg=%x\n", hWnd,  CtlID, lpnmh, pnmtv->hdr.code);
+    IShellFolder_Release(lptvid->lpsfParent);
+    if (lptvid->pEnumIL)
+        IEnumIDList_Release(lptvid->pEnumIL);
+    SHFree(lptvid->lpi);
+    SHFree(lptvid->lpifq);
+    SHFree(lptvid);
+    return 0;
+}
 
-       switch (pnmtv->hdr.idFrom)
-       { case IDD_TREEVIEW:
-           switch (pnmtv->hdr.code)
-           {
-             case TVN_DELETEITEMA:
-             case TVN_DELETEITEMW:
-                TRACE("TVN_DELETEITEMA/W\n");
-               lptvid=(LPTV_ITEMDATA)pnmtv->itemOld.lParam;
-               IShellFolder_Release(lptvid->lpsfParent);
-               if (lptvid->pEnumIL)
-                 IEnumIDList_Release(lptvid->pEnumIL);
-               SHFree(lptvid->lpi);
-               SHFree(lptvid->lpifq);
-               SHFree(lptvid);
-               break;
-
-             case TVN_ITEMEXPANDINGA:
-             case TVN_ITEMEXPANDINGW:
-               {
-                  TRACE("TVN_ITEMEXPANDINGA/W\n");
-                 if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
-                   break;
-
-                 lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
-                 if (SUCCEEDED(IShellFolder_BindToObject(lptvid->lpsfParent, lptvid->lpi,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
-                 { FillTreeView( lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
-                 }
-                 /* My Computer is already sorted and trying to do a simple text
-                  * sort will only mess things up */
-                 if (!_ILIsMyComputer(lptvid->lpi))
-                   TreeView_SortChildren(hwndTreeView, pnmtv->itemNew.hItem, FALSE);
-               }
-               break;
-             case TVN_SELCHANGEDA:
-             case TVN_SELCHANGEDW:
-               lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
-               pidlRet = lptvid->lpifq;
-               if (lpBrowseInfo->lpfn)
-                  (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED, (LPARAM)pidlRet, lpBrowseInfo->lParam);
-               BrsFolder_CheckValidSelection(hWnd, lptvid);
-               break;
-
-             default:
-               WARN("unhandled (%d)\n", pnmtv->hdr.code);
-               break;
-           }
-           break;
+static LRESULT BrsFolder_Treeview_Expand( browse_info *info, NMTREEVIEWW *pnmtv )
+{
+    IShellFolder *lpsf2 = NULL;
+    LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
+    HRESULT r;
 
-         default:
-           break;
-       }
+    TRACE("TVN_ITEMEXPANDINGA/W\n");
+
+    if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
+        return 0;
+
+    r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
+                                  (REFIID)&IID_IShellFolder, (LPVOID *)&lpsf2 );
+    if (SUCCEEDED(r))
+        FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem, lptvid->pEnumIL);
+
+    /* My Computer is already sorted and trying to do a simple text
+     * sort will only mess things up */
+    if (!_ILIsMyComputer(lptvid->lpi))
+        TreeView_SortChildren(info->hwndTreeView, pnmtv->itemNew.hItem, FALSE);
+
+    return 0;
+}
+
+static HRESULT BrsFolder_Treeview_Changed( browse_info *info, NMTREEVIEWW *pnmtv )
+{
+    LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
+
+    lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
+    info->pidlRet = lptvid->lpifq;
+    browsefolder_callback( info->lpBrowseInfo, info->hWnd, BFFM_SELCHANGED,
+                           (LPARAM)info->pidlRet );
+    BrsFolder_CheckValidSelection( info, lptvid );
+    return 0;
+}
+
+static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID, LPNMHDR lpnmh )
+{
+    NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
+
+    TRACE("%p %x %p msg=%x\n", info, CtlID, lpnmh, pnmtv->hdr.code);
+
+    if (pnmtv->hdr.idFrom != IDD_TREEVIEW)
+        return 0;
+
+    switch (pnmtv->hdr.code)
+    {
+    case TVN_DELETEITEMA:
+    case TVN_DELETEITEMW:
+        return BrsFolder_Treeview_Delete( info, pnmtv );
 
-       return 0;
+    case TVN_ITEMEXPANDINGA:
+    case TVN_ITEMEXPANDINGW:
+        return BrsFolder_Treeview_Expand( info, pnmtv );
+
+    case TVN_SELCHANGEDA:
+    case TVN_SELCHANGEDW:
+        return BrsFolder_Treeview_Changed( info, pnmtv );
+
+    default:
+        WARN("unhandled (%d)\n", pnmtv->hdr.code);
+        break;
+    }
+
+    return 0;
 }
 
 
+static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
+{
+    LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
+    info->hWnd = hWnd;
+    SetPropW( hWnd, szBrowseFolderInfo, info );
+
+    if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
+       FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
+
+    if (lpBrowseInfo->lpszTitle)
+       SetWindowTextW( GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle );
+    else
+       ShowWindow( GetDlgItem(hWnd, IDD_TITLE), SW_HIDE );
+
+    if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
+       ShowWindow( GetDlgItem(hWnd, IDD_STATUS), SW_HIDE );
+
+    info->hwndTreeView = GetDlgItem( hWnd, IDD_TREEVIEW );
+    if (info->hwndTreeView)
+        InitializeTreeView( info );
+    else
+        ERR("treeview control missing!\n");
+
+    browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED, 0 );
+
+    return TRUE;
+}
+
+static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
+{
+    LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
+    switch (id)
+    {
+    case IDOK:
+        info->pidlRet = ILClone(info->pidlRet); /* The original pidl will be free'd. */
+        pdump( info->pidlRet );
+        if (lpBrowseInfo->pszDisplayName)
+            SHGetPathFromIDListW( info->pidlRet, lpBrowseInfo->pszDisplayName );
+        EndDialog( info->hWnd, 1 );
+        return TRUE;
+
+    case IDCANCEL:
+        EndDialog( info->hWnd, 0 );
+        return TRUE;
+    }
+    return FALSE;
+}
+
 /*************************************************************************
  *             BrsFolderDlgProc32  (not an exported API function)
  */
-static INT_PTR CALLBACK BrsFolderDlgProc(HWND hWnd, UINT msg, WPARAM wParam,
-                                    LPARAM lParam )
+static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
+                                         LPARAM lParam )
 {
-       TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd,  msg, wParam, lParam );
-
-       switch(msg)
-       { case WM_INITDIALOG:
-           pidlRet = NULL;
-           lpBrowseInfo = (LPBROWSEINFOW) lParam;
-           if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
-             FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS);
-           if (lpBrowseInfo->lpszTitle) {
-              SetWindowTextW(GetDlgItem(hWnd, IDD_TITLE), lpBrowseInfo->lpszTitle);
-           } else {
-              ShowWindow(GetDlgItem(hWnd, IDD_TITLE), SW_HIDE);
-           }
-           if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
-              ShowWindow(GetDlgItem(hWnd, IDD_STATUS), SW_HIDE);
-
-           InitializeTreeView(hWnd, lpBrowseInfo->pidlRoot);
-
-           if (lpBrowseInfo->lpfn)
-              (lpBrowseInfo->lpfn)(hWnd, BFFM_INITIALIZED, 0, lpBrowseInfo->lParam);
+    browse_info *info;
 
-           return TRUE;
+    TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd,  msg, wParam, lParam );
 
-         case WM_NOTIFY:
-           MsgNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
-           break;
+    if (msg == WM_INITDIALOG)
+        return BrsFolder_OnCreate( hWnd, (browse_info*) lParam );
 
-         case WM_COMMAND:
-           switch (wParam)
-           { case IDOK:
-               pdump ( pidlRet );
-               if (lpBrowseInfo->pszDisplayName)
-                   SHGetPathFromIDListW(pidlRet, lpBrowseInfo->pszDisplayName);
-               EndDialog(hWnd, (DWORD) ILClone(pidlRet));
-               return TRUE;
+    info = (browse_info*) GetPropW( hWnd, szBrowseFolderInfo );
 
-             case IDCANCEL:
-               EndDialog(hWnd, 0);
-               return TRUE;
-           }
-           break;
-       case BFFM_SETSTATUSTEXTA:
-          TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
-          SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
-          break;
-       case BFFM_SETSTATUSTEXTW:
-          TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
-          SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
-          break;
-       case BFFM_ENABLEOK:
-          TRACE("Enable %ld\n", lParam);
-          EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
-          break;
-       case BFFM_SETOKTEXT: /* unicode only */
-          TRACE("Set OK text %s\n", debugstr_w((LPWSTR)wParam));
-          SetWindowTextW(GetDlgItem(hWnd, 1), (LPWSTR)wParam);
-          break;
-       case BFFM_SETSELECTIONA:
-          if (wParam)
-             FIXME("Set selection %s\n", debugstr_a((LPSTR)lParam));
-          else
-             FIXME("Set selection %p\n", (void*)lParam);
-          break;
-       case BFFM_SETSELECTIONW:
-          if (wParam)
-             FIXME("Set selection %s\n", debugstr_w((LPWSTR)lParam));
-          else
-             FIXME("Set selection %p\n", (void*)lParam);
-          break;
-       case BFFM_SETEXPANDED: /* unicode only */
-          if (wParam)
-             FIXME("Set expanded %s\n", debugstr_w((LPWSTR)lParam));
-          else
-             FIXME("Set expanded %p\n", (void*)lParam);
-          break;
-       }
-       return FALSE;
+    switch (msg)
+    {
+    case WM_NOTIFY:
+        return BrsFolder_OnNotify( info, (UINT)wParam, (LPNMHDR)lParam);
+
+    case WM_COMMAND:
+        return BrsFolder_OnCommand( info, wParam );
+
+    case BFFM_SETSTATUSTEXTA:
+        TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
+        SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
+        break;
+
+    case BFFM_SETSTATUSTEXTW:
+        TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
+        SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
+        break;
+
+    case BFFM_ENABLEOK:
+        TRACE("Enable %ld\n", lParam);
+        EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
+        break;
+
+    case BFFM_SETOKTEXT: /* unicode only */
+        TRACE("Set OK text %s\n", debugstr_w((LPWSTR)wParam));
+        SetWindowTextW(GetDlgItem(hWnd, 1), (LPWSTR)wParam);
+        break;
+
+    case BFFM_SETSELECTIONA:
+        if (wParam)
+            FIXME("Set selection %s\n", debugstr_a((LPSTR)lParam));
+        else
+            FIXME("Set selection %p\n", (void*)lParam);
+        break;
+
+    case BFFM_SETSELECTIONW:
+        if (wParam)
+            FIXME("Set selection %s\n", debugstr_w((LPWSTR)lParam));
+        else
+            FIXME("Set selection %p\n", (void*)lParam);
+        break;
+
+    case BFFM_SETEXPANDED: /* unicode only */
+        if (wParam)
+            FIXME("Set expanded %s\n", debugstr_w((LPWSTR)lParam));
+        else
+            FIXME("Set expanded %p\n", (void*)lParam);
+        break;
+    }
+    return FALSE;
 }
 
-static const WCHAR swBrowseTempName[] = {'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
+static const WCHAR swBrowseTemplateName[] = {
+    'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G','B','O','X',0};
 
 /*************************************************************************
  * SHBrowseForFolderA [SHELL32.@]
@@ -525,66 +611,69 @@ static const WCHAR swBrowseTempName[] = {'S','H','B','R','S','F','O','R','F','O'
  */
 LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
 {
-       BROWSEINFOW bi;
-       LPITEMIDLIST lpid;
-       INT len;
-       
-       TRACE("(%p{lpszTitle=%s,owner=%p})\n", lpbi,
-           lpbi ? debugstr_a(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : NULL);
-
-       if (!lpbi)
-         return NULL;
+    BROWSEINFOW bi;
+    LPITEMIDLIST lpid;
+    INT len;
+    
+    TRACE("%p\n", lpbi);
 
-       bi.hwndOwner = lpbi->hwndOwner;
-       bi.pidlRoot = lpbi->pidlRoot;
-       if (lpbi->pszDisplayName)
-       {
-         /*lpbi->pszDisplayName is assumed to be MAX_PATH (MSDN) */
-         bi.pszDisplayName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
-         MultiByteToWideChar(CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, MAX_PATH);
-       }
-       else
-         bi.pszDisplayName = NULL;
+    bi.hwndOwner = lpbi->hwndOwner;
+    bi.pidlRoot = lpbi->pidlRoot;
+    if (lpbi->pszDisplayName)
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, NULL, 0 );
+        bi.pszDisplayName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1, bi.pszDisplayName, len );
+    }
+    else
+        bi.pszDisplayName = NULL;
 
-       if (lpbi->lpszTitle)
-       {
-         len = MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0);
-         bi.lpszTitle = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-         MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1, (LPWSTR)bi.lpszTitle, len);
-       }
-       else
-         bi.lpszTitle = NULL;
-
-       bi.ulFlags = lpbi->ulFlags;
-       bi.lpfn = lpbi->lpfn;
-       bi.lParam = lpbi->lParam;
-       bi.iImage = lpbi->iImage;
-       lpid = (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
-                                             swBrowseTempName, lpbi->hwndOwner,
-                                             BrsFolderDlgProc, (INT)&bi);
-       if (bi.pszDisplayName)
-       {
-         WideCharToMultiByte(CP_ACP, 0, bi.pszDisplayName, -1, lpbi->pszDisplayName, MAX_PATH, 0, NULL);
-         HeapFree(GetProcessHeap(), 0, bi.pszDisplayName);
-       }
-        HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
-       lpbi->iImage = bi.iImage;
-       return lpid;
+    if (lpbi->lpszTitle)
+    {
+        len = MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, NULL, 0 );
+        bi.lpszTitle = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1, (LPWSTR)bi.lpszTitle, len );
+    }
+    else
+        bi.lpszTitle = NULL;
+
+    bi.ulFlags = lpbi->ulFlags;
+    bi.lpfn = lpbi->lpfn;
+    bi.lParam = lpbi->lParam;
+    bi.iImage = lpbi->iImage;
+    lpid = SHBrowseForFolderW( &bi );
+    if (bi.pszDisplayName)
+    {
+        WideCharToMultiByte( CP_ACP, 0, bi.pszDisplayName, -1,
+                             lpbi->pszDisplayName, MAX_PATH, 0, NULL);
+        HeapFree( GetProcessHeap(), 0, bi.pszDisplayName );
+    }
+    HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
+    lpbi->iImage = bi.iImage;
+    return lpid;
 }
 
 
 /*************************************************************************
  * SHBrowseForFolderW [SHELL32.@]
+ *
+ * NOTES:
+ *  crashes when passed a null pointer
  */
 LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
 {
-       TRACE("((%p->{lpszTitle=%s,owner=%p})\n", lpbi,
-           lpbi ? debugstr_w(lpbi->lpszTitle) : NULL, lpbi ? lpbi->hwndOwner : 0);
+    browse_info info;
+    DWORD r;
+
+    info.hWnd = 0;
+    info.pidlRet = NULL;
+    info.lpBrowseInfo = lpbi;
+    info.hwndTreeView = NULL;
 
-       if (!lpbi)
-         return NULL;
+    r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner,
+                        BrsFolderDlgProc, (LPARAM)&info );
+    if (!r)
+        return NULL;
 
-       return (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
-                                             swBrowseTempName, lpbi->hwndOwner,
-                                             BrsFolderDlgProc, (INT)lpbi);
+    return info.pidlRet;
 }
index 0b41c07..9058568 100644 (file)
@@ -552,10 +552,13 @@ ISF_ControlPanel_fnGetAttributesOf(IShellFolder2 * iface, UINT cidl, LPCITEMIDLI
 
     HRESULT hr = S_OK;
 
-    TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl, *rgfInOut);
+    TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
+          This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
 
-    if ((!cidl) ||(!apidl) ||(!rgfInOut))
-       return E_INVALIDARG;
+    if (!rgfInOut)
+        return E_INVALIDARG;
+    if (cidl && !apidl)
+        return E_INVALIDARG;
 
     if (*rgfInOut == 0)
        *rgfInOut = ~0;
@@ -566,6 +569,8 @@ ISF_ControlPanel_fnGetAttributesOf(IShellFolder2 * iface, UINT cidl, LPCITEMIDLI
        apidl++;
        cidl--;
     }
+    /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
+    *rgfInOut &= ~SFGAO_VALIDATE;
 
     TRACE("-- result=0x%08lx\n", *rgfInOut);
     return hr;
index 6a53efb..15e66ac 100644 (file)
@@ -383,7 +383,7 @@ static HRESULT WINAPI IExtractIconW_fnExtract(IExtractIconW * iface, LPCWSTR psz
        FIXME("(%p) (file=%p index=%d %p %p size=%08x) semi-stub\n", This, debugstr_w(pszFile), (signed)nIconIndex,
               phiconLarge, phiconSmall, nIconSize);
 
-        index = SIC_GetIconIndex(pszFile, nIconIndex);
+        index = SIC_GetIconIndex(pszFile, nIconIndex, 0);
 
        if (phiconLarge)
          *phiconLarge = ImageList_GetIcon(ShellBigIconList, index, ILD_TRANSPARENT);
index 264cb3e..8ccdc3e 100644 (file)
@@ -43,6 +43,7 @@
 #include "pidl.h"
 #include "shell32_main.h"
 #include "undocshell.h"
+#include "shresdef.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -77,23 +78,165 @@ static CRITICAL_SECTION SHELL32_SicCS = { &critsect_debug, -1, 0, 0, 0, 0 };
  *  Callback for DPA_Search
  */
 static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam)
-{      TRACE("%p %p %8lx\n", p1, p2, lparam);
-
-       if (((LPSIC_ENTRY)p1)->dwSourceIndex != ((LPSIC_ENTRY)p2)->dwSourceIndex) /* first the faster one*/
+{      LPSIC_ENTRY e1 = (LPSIC_ENTRY)p1, e2 = (LPSIC_ENTRY)p2;
+       
+       TRACE("%p %p %8lx\n", p1, p2, lparam);
+
+       /* Icons in the cache are keyed by the name of the file they are
+        * loaded from, their resource index and the fact if they have a shortcut
+        * icon overlay or not. 
+        */
+       if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the faster one */
+           (e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags & GIL_FORSHORTCUT)) 
          return 1;
 
-       if (strcmpiW(((LPSIC_ENTRY)p1)->sSourceFile,((LPSIC_ENTRY)p2)->sSourceFile))
+       if (strcmpiW(e1->sSourceFile,e2->sSourceFile))
          return 1;
 
        return 0;
 }
+
+/*****************************************************************************
+ * SIC_OverlayShortcutImage                    [internal]
+ *
+ * NOTES
+ *  Creates a new icon as a copy of the passed-in icon, overlayed with a
+ *  shortcut image. 
+ */
+static HICON SIC_OverlayShortcutImage(HICON SourceIcon)
+{      ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
+       HICON ShortcutIcon, TargetIcon;
+       BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
+       HDC SourceDC = NULL,
+         ShortcutDC = NULL,
+         TargetDC = NULL,
+         ScreenDC = NULL;
+       HBITMAP OldSourceBitmap = NULL,
+         OldShortcutBitmap = NULL,
+         OldTargetBitmap = NULL;
+
+       /* Get information about the source icon and shortcut overlay */
+       if (! GetIconInfo(SourceIcon, &SourceIconInfo)
+           || 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
+       {
+         return NULL;
+       }
+       ShortcutIcon = LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_SHORTCUT),
+                                 IMAGE_ICON, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmWidth,
+                                 LR_SHARED);
+       if (NULL == ShortcutIcon
+           || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
+           || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
+       {
+         return NULL;
+       }
+
+       TargetIconInfo = SourceIconInfo;
+       TargetIconInfo.hbmMask = NULL;
+       TargetIconInfo.hbmColor = NULL;
+
+       /* Setup the source, shortcut and target masks */
+       SourceDC = CreateCompatibleDC(NULL);
+       if (NULL == SourceDC) goto fail;
+       OldSourceBitmap = SelectObject(SourceDC, SourceIconInfo.hbmMask);
+       if (NULL == OldSourceBitmap) goto fail;
+
+       ShortcutDC = CreateCompatibleDC(NULL);
+       if (NULL == ShortcutDC) goto fail;
+       OldShortcutBitmap = SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
+       if (NULL == OldShortcutBitmap) goto fail;
+
+       TargetDC = CreateCompatibleDC(NULL);
+       if (NULL == TargetDC) goto fail;
+       TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC, SourceBitmapInfo.bmWidth,
+                                                       SourceBitmapInfo.bmHeight);
+       if (NULL == TargetIconInfo.hbmMask) goto fail;
+       ScreenDC = GetDC(NULL);
+       if (NULL == ScreenDC) goto fail;
+       TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC, SourceBitmapInfo.bmWidth,
+                                                        SourceBitmapInfo.bmHeight);
+       ReleaseDC(NULL, ScreenDC);
+       if (NULL == TargetIconInfo.hbmColor) goto fail;
+       OldTargetBitmap = SelectObject(TargetDC, TargetIconInfo.hbmMask);
+       if (NULL == OldTargetBitmap) goto fail;
+
+       /* Create the target mask by ANDing the source and shortcut masks */
+       if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
+                    SourceDC, 0, 0, SRCCOPY) ||
+           ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
+                    ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
+                    ShortcutDC, 0, 0, SRCAND))
+       {
+         goto fail;
+       }
+
+       /* Setup the source and target xor bitmap */
+       if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) ||
+           NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
+       {
+         goto fail;
+       }
+
+       /* Copy the source xor bitmap to the target and clear out part of it by using
+          the shortcut mask */
+       if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
+                    SourceDC, 0, 0, SRCCOPY) ||
+           ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
+                    ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
+                    ShortcutDC, 0, 0, SRCAND))
+       {
+         goto fail;
+       }
+
+       if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
+
+       /* Now put in the shortcut xor mask */
+       if (! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
+                    ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
+                    ShortcutDC, 0, 0, SRCINVERT))
+       {
+         goto fail;
+       }
+
+       /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
+          handles to NULL */
+       SelectObject(TargetDC, OldTargetBitmap);
+       DeleteObject(TargetDC);
+       SelectObject(ShortcutDC, OldShortcutBitmap);
+       DeleteObject(ShortcutDC);
+       SelectObject(SourceDC, OldSourceBitmap);
+       DeleteObject(SourceDC);
+
+       /* Create the icon using the bitmaps prepared earlier */
+       TargetIcon = CreateIconIndirect(&TargetIconInfo);
+
+       /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
+       DeleteObject(TargetIconInfo.hbmColor);
+       DeleteObject(TargetIconInfo.hbmMask);
+
+       return TargetIcon;
+
+fail:
+       /* Clean up scratch resources we created */
+       if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap);
+       if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
+       if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
+       if (NULL != TargetDC) DeleteObject(TargetDC);
+       if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
+       if (NULL != ShortcutDC) DeleteObject(ShortcutDC);
+       if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap);
+       if (NULL != SourceDC) DeleteObject(SourceDC);
+
+       return NULL;
+}
+
 /*****************************************************************************
  * SIC_IconAppend                      [internal]
  *
  * NOTES
  *  appends an icon pair to the end of the cache
  */
-static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon)
+static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
 {      LPSIC_ENTRY lpsice;
        INT ret, index, index1;
        WCHAR path[MAX_PATH];
@@ -101,11 +244,12 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
 
        lpsice = (LPSIC_ENTRY) SHAlloc (sizeof (SIC_ENTRY));
 
-       GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
+       GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
        lpsice->sSourceFile = HeapAlloc( GetProcessHeap(), 0, (strlenW(path)+1)*sizeof(WCHAR) );
        strcpyW( lpsice->sSourceFile, path );
 
        lpsice->dwSourceIndex = dwSourceIndex;
+       lpsice->dwFlags = dwFlags;
 
        EnterCriticalSection(&SHELL32_SicCS);
 
@@ -138,9 +282,11 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
  * NOTES
  *  gets small/big icon by number from a file
  */
-static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex)
+static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
 {      HICON   hiconLarge=0;
        HICON   hiconSmall=0;
+       HICON   hiconLargeShortcut;
+       HICON   hiconSmallShortcut;
 
 #if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
        static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
@@ -164,7 +310,26 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex)
          WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
          return -1;
        }
-       return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge);
+
+       if (0 != (dwFlags & GIL_FORSHORTCUT))
+       {
+         hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge);
+         hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall);
+         if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
+         {
+           hiconLarge = hiconLargeShortcut;
+           hiconSmall = hiconSmallShortcut;
+         }
+         else
+         {
+           WARN("Failed to create shortcut overlayed icons\n");
+           if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
+           if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
+           dwFlags &= ~ GIL_FORSHORTCUT;
+         }
+       }
+
+       return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
 }
 /*****************************************************************************
  * SIC_GetIconIndex                    [internal]
@@ -177,7 +342,7 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex)
  *  look in the cache for a proper icon. if not available the icon is taken
  *  from the file and cached
  */
-INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex )
+INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
 {
        SIC_ENTRY sice;
        INT ret, index = INVALID_INDEX;
@@ -188,6 +353,7 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex )
        GetFullPathNameW(sSourceFile, MAX_PATH, path, NULL);
        sice.sSourceFile = path;
        sice.dwSourceIndex = dwSourceIndex;
+       sice.dwFlags = dwFlags;
 
        EnterCriticalSection(&SHELL32_SicCS);
 
@@ -199,7 +365,7 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex )
 
        if ( INVALID_INDEX == index )
        {
-         ret = SIC_LoadIcon (sSourceFile, dwSourceIndex);
+         ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
        }
        else
        {
@@ -257,8 +423,8 @@ BOOL SIC_Initialize(void)
            hSm = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(1), IMAGE_ICON, cx_small, cy_small, LR_SHARED);
            hLg = LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(1), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
          }
-         SIC_IconAppend (swShell32Name, index - 1, hSm, hLg);
-         SIC_IconAppend (swShell32Name, -index, hSm, hLg);
+         SIC_IconAppend (swShell32Name, index - 1, hSm, hLg, 0);
+         SIC_IconAppend (swShell32Name, -index, hSm, hLg, 0);
        }
 
        TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
@@ -332,24 +498,52 @@ BOOL PidlToSicIndex (
 {
        IExtractIconW   *ei;
        WCHAR           szIconFile[MAX_PATH];   /* file containing the icon */
+       char            szTemp[MAX_PATH];
        INT             iSourceIndex;           /* index or resID(negated) in this file */
        BOOL            ret = FALSE;
        UINT            dwFlags = 0;
+       HKEY            keyCls;
+       int             iShortcutDefaultIndex = INVALID_INDEX;
 
        TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
 
        if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei)))
        {
+         if (_ILGetExtension(pidl, szTemp, MAX_PATH) &&
+             HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE))
+         {
+           if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls))
+           {
+             if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL))
+             {
+               uFlags |= GIL_FORSHORTCUT;
+             }
+             RegCloseKey(keyCls);
+           }
+         }
          if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags)))
          {
-           *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex);
+           *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags);
            ret = TRUE;
          }
          IExtractIconW_Release(ei);
        }
 
        if (INVALID_INDEX == *pIndex)   /* default icon when failed */
-         *pIndex = 0;
+       {
+         if (0 == (uFlags & GIL_FORSHORTCUT))
+         {
+           *pIndex = 0;
+         }
+         else
+         {
+           if (INVALID_INDEX == iShortcutDefaultIndex)
+           {
+             iShortcutDefaultIndex = SIC_LoadIcon(swShell32Name, 0, GIL_FORSHORTCUT);
+           }
+           *pIndex = (INVALID_INDEX != iShortcutDefaultIndex ? iShortcutDefaultIndex : 0);
+         }
+       }
 
        return ret;
 
@@ -399,7 +593,7 @@ INT WINAPI Shell_GetCachedImageIndexA(LPCSTR szPath, INT nIndex, BOOL bSimulateD
        szTemp = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
        MultiByteToWideChar( CP_ACP, 0, szPath, -1, szTemp, len );
 
-       ret = SIC_GetIconIndex( szTemp, nIndex );
+       ret = SIC_GetIconIndex( szTemp, nIndex, 0 );
 
        HeapFree( GetProcessHeap(), 0, szTemp );
 
@@ -410,7 +604,7 @@ INT WINAPI Shell_GetCachedImageIndexW(LPCWSTR szPath, INT nIndex, BOOL bSimulate
 {
        WARN("(%s,%08x,%08x) semi-stub.\n",debugstr_w(szPath), nIndex, bSimulateDoc);
 
-       return SIC_GetIconIndex(szPath, nIndex);
+       return SIC_GetIconIndex(szPath, nIndex, 0);
 }
 
 INT WINAPI Shell_GetCachedImageIndexAW(LPCVOID szPath, INT nIndex, BOOL bSimulateDoc)
index 265c364..1d582ba 100644 (file)
@@ -1219,7 +1219,7 @@ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSiz
     pszPath[0]=0;
 
     /* One case is a PIDL rooted at desktop level */
-    if (_ILIsValue(pidl) || _ILIsFolder(pidl))
+    if (_ILIsDesktop(pidl) || _ILIsValue(pidl) || _ILIsFolder(pidl))
     {
         hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE);
 
@@ -1331,7 +1331,7 @@ HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSi
     pszPath[0]=0;
 
     /* One case is a PIDL rooted at desktop level */
-    if (_ILIsValue(pidl) || _ILIsFolder(pidl))
+    if (_ILIsDesktop(pidl) ||_ILIsValue(pidl) || _ILIsFolder(pidl))
     {
         hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE);
 
index 87a5833..5486253 100644 (file)
@@ -70,6 +70,7 @@ struct regsvr_coclass
 
 /* flags for regsvr_coclass.flags */
 #define SHELLEX_MAYCHANGEDEFAULTMENU 0x00000001
+#define SHELLFOLDER_WANTSFORPARSING  0x00000002
 
 static HRESULT register_coclasses(struct regsvr_coclass const *list);
 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
@@ -102,10 +103,13 @@ static WCHAR const progid_keyname[7] = {
     'P', 'r', 'o', 'g', 'I', 'D', 0 };
 static WCHAR const shellex_keyname[8] = {
     's', 'h', 'e', 'l', 'l', 'e', 'x', 0 };
+static WCHAR const shellfolder_keyname[12] = {
+    'S', 'h', 'e', 'l', 'l', 'F', 'o', 'l', 'd', 'e', 'r', 0 };
 static WCHAR const mcdm_keyname[21] = {
     'M', 'a', 'y', 'C', 'h', 'a', 'n', 'g', 'e', 'D', 'e', 'f',
     'a', 'u', 'l', 't', 'M', 'e', 'n', 'u', 0 };
 static char const tmodel_valuename[] = "ThreadingModel";
+static char const wfparsing_valuename[] = "WantsFORPARSING";
 
 /***********************************************************************
  *             static helper functions
@@ -281,6 +285,19 @@ static HRESULT register_coclasses(struct regsvr_coclass const *list)
            RegCloseKey(mcdm_key);
        }
 
+       if (list->flags & SHELLFOLDER_WANTSFORPARSING) {
+           HKEY shellfolder_key;
+
+           res = RegCreateKeyExW(clsid_key, shellfolder_keyname, 0, NULL, 0,
+                                 KEY_READ | KEY_WRITE, NULL,
+                                 &shellfolder_key, NULL);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+           res = RegSetValueExA(shellfolder_key, wfparsing_valuename, 0, REG_SZ, 
+                                                    "", 1);
+           RegCloseKey(shellfolder_key);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
        if (list->clsid_str) {
            res = register_key_defvalueA(clsid_key, clsid_keyname,
                                         list->clsid_str);
index dfa1937..16f12e0 100644 (file)
@@ -70,9 +70,6 @@ static HHOOK  SHELL_hHook = 0;
 static UINT    uMsgWndCreated = 0;
 static UINT    uMsgWndDestroyed = 0;
 static UINT    uMsgShellActivate = 0;
-HINSTANCE16    SHELL_hInstance = 0;
-HINSTANCE SHELL_hInstance32;
-static int SHELL_Attach = 0;
 
 /***********************************************************************
  * DllEntryPoint [SHELL.101]
@@ -87,33 +84,6 @@ static int SHELL_Attach = 0;
 BOOL WINAPI SHELL_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst,
                                WORD ds, WORD HeapSize, DWORD res1, WORD res2)
 {
-    TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n",
-          Reason, hInst, ds, HeapSize, res1, res2);
-
-    switch(Reason)
-    {
-    case DLL_PROCESS_ATTACH:
-       if (SHELL_Attach++) break;
-       SHELL_hInstance = hInst;
-       if(!SHELL_hInstance32)
-       {
-           if(!(SHELL_hInstance32 = LoadLibraryA("shell32.dll")))
-           {
-               ERR("Could not load sibling shell32.dll\n");
-               return FALSE;
-           }
-       }
-       break;
-
-    case DLL_PROCESS_DETACH:
-       if(!--SHELL_Attach)
-       {
-           SHELL_hInstance = 0;
-           if(SHELL_hInstance32)
-               FreeLibrary(SHELL_hInstance32);
-       }
-       break;
-    }
     return TRUE;
 }
 
@@ -363,74 +333,82 @@ SEGPTR WINAPI FindEnvironmentString16(LPSTR str)
  *                             DoEnvironmentSubst      [SHELL.37]
  *
  * Replace %KEYWORD% in the str with the value of variable KEYWORD
- * from "DOS" environment.
+ * 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%.
+ *             [O] '\0' terminated string with %keyword% substituted.
+ * length      [I] size of str.
+ *
+ * Return
+ *     str length in the LOWORD and 1 in HIWORD if subst was successful.
  */
 DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length)
 {
   LPSTR   lpEnv = MapSL(GetDOSEnvironment16());
-  LPSTR   lpBuffer = HeapAlloc( GetProcessHeap(), 0, length);
   LPSTR   lpstr = str;
-  LPSTR   lpbstr = lpBuffer;
+  LPSTR   lpend;
+  LPSTR   lpBuffer = HeapAlloc( GetProcessHeap(), 0, length);
+  WORD    bufCnt = 0;
+  WORD    envKeyLen;
+  LPSTR   lpKey;
+  WORD    retStatus = 0;
+  WORD    retLength = length;
 
   CharToOemA(str,str);
 
   TRACE("accept %s\n", str);
 
-  while( *lpstr && lpbstr - lpBuffer < length )
-   {
-     LPSTR lpend = lpstr;
-
-     if( *lpstr == '%' )
-       {
-         do { lpend++; } while( *lpend && *lpend != '%' );
-         if( *lpend == '%' && lpend - lpstr > 1 )      /* found key */
-           {
-              LPSTR lpKey;
-             *lpend = '\0';
-              lpKey = SHELL_FindString(lpEnv, lpstr+1);
-              if( lpKey )                              /* found key value */
-                {
-                  int l = strlen(lpKey);
-
-                  if( l > length - (lpbstr - lpBuffer) - 1 )
-                    {
-           WARN("-- Env subst aborted - string too short\n");
-                     *lpend = '%';
-                      break;
-                    }
-                  strcpy(lpbstr, lpKey);
-                  lpbstr += l;
-                }
-              else break;
-             *lpend = '%';
-              lpstr = lpend + 1;
-           }
-         else break;                                   /* back off and whine */
-
-         continue;
-       }
-
-     *lpbstr++ = *lpstr++;
-   }
-
- *lpbstr = '\0';
-  if( lpstr - str == strlen(str) )
-    {
-      strncpy(str, lpBuffer, length);
-      length = 1;
-    }
-  else
-      length = 0;
-
+  while( *lpstr && bufCnt <= length - 1 ) {
+     if ( *lpstr != '%' ) {
+        lpBuffer[bufCnt++] = *lpstr++;
+        continue;
+     }
+
+     for( lpend = lpstr + 1; *lpend && *lpend != '%'; lpend++) /**/;
+
+     envKeyLen = lpend - lpstr - 1;
+     if( *lpend != '%' || envKeyLen == 0)
+        goto err; /* "%\0" or "%%" found; back off and whine */
+
+     *lpend = '\0';
+     lpKey = SHELL_FindString(lpEnv, lpstr+1);
+     *lpend = '%';
+     if( lpKey ) {
+         int l = strlen(lpKey);
+
+         if( bufCnt + l > length - 1 )
+                goto err;
+
+        memcpy(lpBuffer + bufCnt, lpKey, l);
+        bufCnt += l;
+     } else { /* Keyword not found; Leave the %KEYWORD% intact */
+        if( bufCnt + envKeyLen + 2 > length - 1 )
+            goto err;
+
+         memcpy(lpBuffer + bufCnt, lpstr, envKeyLen + 2);
+        bufCnt += envKeyLen + 2;
+     }
+
+     lpstr = lpend + 1;
+  }
+
+  if (!*lpstr && bufCnt <= length - 1) {
+      memcpy(str,lpBuffer, bufCnt);
+      str[bufCnt] = '\0';
+      retLength = bufCnt + 1;
+      retStatus = 1;
+  }
+
+  err:
+  if (!retStatus)
+      WARN("-- Env subst aborted - string too short or invalid input\n");
   TRACE("-- return %s\n", str);
 
   OemToCharA(str,str);
   HeapFree( GetProcessHeap(), 0, lpBuffer);
 
-  /*  Return str length in the LOWORD
-   *  and 1 in HIWORD if subst was successful.
-   */
- return (DWORD)MAKELONG(strlen(str), length);
+  return (DWORD)MAKELONG(retLength, retStatus);
 }
 
 /*************************************************************************
index 64c5574..ac36ec7 100644 (file)
@@ -5,6 +5,7 @@
   5 pascal   RegSetValue(long str long str long) RegSetValue16
   6 pascal   RegQueryValue(long str ptr ptr) RegQueryValue16
   7 pascal   RegEnumKey(long long ptr long) RegEnumKey16
+# 8 stub     WEP
   9 pascal -ret16 DragAcceptFiles(word word) DragAcceptFiles16
  11 pascal -ret16 DragQueryFile(word s_word ptr s_word) DragQueryFile16
  12 pascal -ret16 DragFinish(word) DragFinish16
@@ -41,5 +42,4 @@
 401 stub SHCHECKDRIVE
 #  402 _RUNDLLCHECKDRIVE
 
-# 8 WEP
 #32 WCI
index 15288eb..a76f08a 100644 (file)
@@ -132,30 +132,33 @@ FONT 8, "MS Shell Dlg"
  PUSHBUTTON "&Durchsuchen...", 12288, 170, 63, 50, 14, WS_TABSTOP
 }
 
-/*
-       special folders
-*/
 STRINGTABLE DISCARDABLE
 {
+        /* columns in the shellview */
+       IDS_SHV_COLUMN1         "Datei"
+       IDS_SHV_COLUMN2         "Größe"
+       IDS_SHV_COLUMN3         "Typ"
+       IDS_SHV_COLUMN4         "Geändert"
+       IDS_SHV_COLUMN5         "Attribute"
+       IDS_SHV_COLUMN6         "Gesamtgröße"
+       IDS_SHV_COLUMN7         "Freier Speicher"
+       IDS_SHV_COLUMN8         "Name"
+       IDS_SHV_COLUMN9         "Kommentar"
+       IDS_SHV_COLUMN10        "Besitzer"
+       IDS_SHV_COLUMN11        "Gruppe"
+
+        /* special folders */
        IDS_DESKTOP             "Desktop"
        IDS_MYCOMPUTER          "Arbeitsplatz"
-}
 
-/*
-       context menus
-*/
-STRINGTABLE DISCARDABLE
-{
+        /* context menus */
        IDS_VIEW_LARGE          "&Große Symbole"
        IDS_VIEW_SMALL          "&Kleine Symbole"
        IDS_VIEW_LIST           "&Liste"
        IDS_VIEW_DETAILS        "&Details"
        IDS_SELECT              "Auswählen"
        IDS_OPEN                "Öffnen"
-}
 
-STRINGTABLE DISCARDABLE
-{
        IDS_CREATEFOLDER_DENIED "Es konnte kein neues Verzeichnis erstellt werden: Zugriff verweigert."
        IDS_CREATEFOLDER_CAPTION "Es trat ein Fehler beim Erstellen eines neuen Verzeichnisses auf"
        IDS_DELETEITEM_CAPTION "Bestätigung: Datei löschen"
@@ -164,34 +167,14 @@ STRINGTABLE DISCARDABLE
        IDS_DELETEMULTIPLE_TEXT "Sind Sie sich sicher, dass Sie diese %1 Dateien löschen möchten ?"
        IDS_OVERWRITEFILE_TEXT "Möchten Sie, dass die Datei '%1' überschrieben wird ?"
        IDS_OVERWRITEFILE_CAPTION "Bestätigung: Datei überschreiben"
-}
 
-/*     columns in the shellview        */
-STRINGTABLE
-BEGIN
-       IDS_SHV_COLUMN1         "Datei"
-       IDS_SHV_COLUMN2         "Größe"
-       IDS_SHV_COLUMN3         "Typ"
-       IDS_SHV_COLUMN4         "Geändert"
-       IDS_SHV_COLUMN5         "Attribute"
-       IDS_SHV_COLUMN6         "Gesamtgröße"
-       IDS_SHV_COLUMN7         "Freier Speicher"
-       IDS_SHV_COLUMN8         "Name"
-       IDS_SHV_COLUMN9         "Kommentar"
-END
+        /* message box strings */
+        IDS_RESTART_TITLE       "Neustarten"
+        IDS_RESTART_PROMPT      "Möchten Sie, dass ein simulierter Windows Neustart durchgeführt wird ?"
+        IDS_SHUTDOWN_TITLE      "Anhalten"
+        IDS_SHUTDOWN_PROMPT     "Möchten Sie die aktuelle ReactOS Sitzung beenden ?"
 
-/* message box strings */
-STRINGTABLE DISCARDABLE
-{
-       IDS_RESTART_TITLE       "Neustarten"
-       IDS_RESTART_PROMPT      "Möchten Sie, dass ein simulierter Windows Neustart durchgeführt wird ?"
-       IDS_SHUTDOWN_TITLE      "Anhalten"
-       IDS_SHUTDOWN_PROMPT     "Möchten Sie die aktuelle ReactOS Sitzung beenden ?"
-}
-
-/* shell folder path default values */
-STRINGTABLE DISCARDABLE
-{
+        /* shell folder path default values */
        IDS_PROGRAMS            "Startmenü\\Programme"
        IDS_PERSONAL            "Eigene Dateien"
        IDS_FAVORITES           "Favoriten"
index 8a21d12..9a53a19 100644 (file)
@@ -131,66 +131,49 @@ FONT 8, "MS Shell Dlg"
  PUSHBUTTON "&Browse...", 12288, 170, 63, 50, 14, WS_TABSTOP
 }
 
-/*
-       special folders
-*/
 STRINGTABLE DISCARDABLE
 {
+        /* columns in the shellview */
+       IDS_SHV_COLUMN1         "File"
+       IDS_SHV_COLUMN2         "Size"
+       IDS_SHV_COLUMN3         "Type"
+       IDS_SHV_COLUMN4         "Modified"
+       IDS_SHV_COLUMN5         "Attributes"
+       IDS_SHV_COLUMN6         "Size"
+       IDS_SHV_COLUMN7         "Size available"
+       IDS_SHV_COLUMN8         "Name"
+       IDS_SHV_COLUMN9         "Comments"
+       IDS_SHV_COLUMN10        "Owner"
+       IDS_SHV_COLUMN11        "Group"
+
+        /* special folders */
        IDS_DESKTOP             "Desktop"
        IDS_MYCOMPUTER          "My Computer"
-}
 
-/*
-       context menus
-*/
-STRINGTABLE DISCARDABLE
-{
+        /* context menus */
        IDS_VIEW_LARGE          "Lar&ge Icons"
        IDS_VIEW_SMALL          "S&mall Icons"
        IDS_VIEW_LIST           "&List"
        IDS_VIEW_DETAILS        "&Details"
        IDS_SELECT              "Select"
        IDS_OPEN                "Open"
-}
 
-STRINGTABLE DISCARDABLE
-{
-       IDS_CREATEFOLDER_DENIED "Can not create new Folder: Permission denied."
+       IDS_CREATEFOLDER_DENIED "Unable to create new Folder: Permission denied."
        IDS_CREATEFOLDER_CAPTION "Error during creation of a new folder"
-       IDS_DELETEITEM_CAPTION "Confirm file delete"
-       IDS_DELETEFOLDER_CAPTION "Confirm folder delete"
+       IDS_DELETEITEM_CAPTION "Confirm file deletion"
+       IDS_DELETEFOLDER_CAPTION "Confirm folder deletion"
        IDS_DELETEITEM_TEXT "Are you sure you want to delete '%1'?"
        IDS_DELETEMULTIPLE_TEXT "Are you sure you want to delete these %1 items?"
        IDS_OVERWRITEFILE_TEXT "OverWrite File %1?"
        IDS_OVERWRITEFILE_CAPTION "Confirm File OverWrite"
-}
 
-/*     columns in the shellview        */
-STRINGTABLE
-BEGIN
-       IDS_SHV_COLUMN1         "File"
-       IDS_SHV_COLUMN2         "Size"
-       IDS_SHV_COLUMN3         "Type"
-       IDS_SHV_COLUMN4         "Modified"
-       IDS_SHV_COLUMN5         "Attributes"
-       IDS_SHV_COLUMN6         "Size"
-       IDS_SHV_COLUMN7         "Size available"
-       IDS_SHV_COLUMN8         "Name"
-       IDS_SHV_COLUMN9         "Comments"
-END
-
-/* message box strings */
-STRINGTABLE DISCARDABLE
-{
+        /* message box strings */
        IDS_RESTART_TITLE       "Restart"
        IDS_RESTART_PROMPT      "Do you want to restart the system?"
        IDS_SHUTDOWN_TITLE      "Shutdown"
        IDS_SHUTDOWN_PROMPT     "Do you want to shutdown?"
-}
 
-/* shell folder path default values */
-STRINGTABLE DISCARDABLE
-{
+        /* shell folder path default values */
        IDS_PROGRAMS                "Start Menu\\Programs"
        IDS_PERSONAL                "My Documents"
        IDS_FAVORITES               "Favorites"
index ed592fe..64cdf6e 100644 (file)
@@ -236,6 +236,67 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
     return argv;
 }
 
+static DWORD shgfi_get_exe_type(LPCWSTR szFullPath)
+{
+    BOOL status = FALSE;
+    HANDLE hfile;
+    DWORD BinaryType;
+    IMAGE_DOS_HEADER mz_header;
+    IMAGE_NT_HEADERS nt;
+    DWORD len;
+    char magic[4];
+
+    status = GetBinaryTypeW (szFullPath, &BinaryType);
+    if (!status)
+        return 0;
+    if (BinaryType == SCS_DOS_BINARY || BinaryType == SCS_PIF_BINARY)
+        return 0x4d5a;
+
+    hfile = CreateFileW( szFullPath, GENERIC_READ, FILE_SHARE_READ,
+                         NULL, OPEN_EXISTING, 0, 0 );
+    if ( hfile == INVALID_HANDLE_VALUE )
+        return 0;
+
+    /*
+     * The next section is adapted from MODULE_GetBinaryType, as we need
+     * to examine the image header to get OS and version information. We
+     * know from calling GetBinaryTypeA that the image is valid and either
+     * an NE or PE, so much error handling can be omitted.
+     * Seek to the start of the file and read the header information.
+     */
+
+    SetFilePointer( hfile, 0, NULL, SEEK_SET );
+    ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL );
+
+    SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
+    ReadFile( hfile, magic, sizeof(magic), &len, NULL );
+    if ( *(DWORD*)magic == IMAGE_NT_SIGNATURE )
+    {
+        SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
+        ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
+        CloseHandle( hfile );
+        if (nt.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
+        {
+             return IMAGE_NT_SIGNATURE | 
+                   (nt.OptionalHeader.MajorSubsystemVersion << 24) |
+                   (nt.OptionalHeader.MinorSubsystemVersion << 16);
+        }
+        return IMAGE_NT_SIGNATURE;
+    }
+    else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
+    {
+        IMAGE_OS2_HEADER ne;
+        SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
+        ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
+        CloseHandle( hfile );
+        if (ne.ne_exetyp == 2)
+            return IMAGE_OS2_SIGNATURE | (ne.ne_expver << 16);
+        return 0;
+    }
+    CloseHandle( hfile );
+    return 0;
+}
+
 #define SHGFI_KNOWN_FLAGS \
     (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
      SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
@@ -277,7 +338,7 @@ DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
 
     if (!(flags & SHGFI_PIDL))
     {
-        /* SHGitFileInfo should work with absolute and relative paths */
+        /* SHGetFileInfo should work with absolute and relative paths */
         if (PathIsRelativeW(path))
         {
             GetCurrentDirectoryW(MAX_PATH, szLocation);
@@ -291,66 +352,9 @@ DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
 
     if (flags & SHGFI_EXETYPE)
     {
-        BOOL status = FALSE;
-        HANDLE hfile;
-        DWORD BinaryType;
-        IMAGE_DOS_HEADER mz_header;
-        IMAGE_NT_HEADERS nt;
-        DWORD len;
-        char magic[4];
-
         if (flags != SHGFI_EXETYPE)
             return 0;
-
-        status = GetBinaryTypeW (szFullPath, &BinaryType);
-        if (!status)
-            return 0;
-        if ((BinaryType == SCS_DOS_BINARY) || (BinaryType == SCS_PIF_BINARY))
-            return 0x4d5a;
-
-        hfile = CreateFileW( szFullPath, GENERIC_READ, FILE_SHARE_READ,
-                             NULL, OPEN_EXISTING, 0, 0 );
-        if ( hfile == INVALID_HANDLE_VALUE )
-            return 0;
-
-        /*
-         * The next section is adapted from MODULE_GetBinaryType, as we need
-         * to examine the image header to get OS and version information. We
-         * know from calling GetBinaryTypeA that the image is valid and either
-         * an NE or PE, so much error handling can be omitted.
-         * Seek to the start of the file and read the header information.
-         */
-
-        SetFilePointer( hfile, 0, NULL, SEEK_SET );
-        ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL );
-
-        SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
-        ReadFile( hfile, magic, sizeof(magic), &len, NULL );
-        if ( *(DWORD*)magic      == IMAGE_NT_SIGNATURE )
-        {
-            SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
-            ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
-            CloseHandle( hfile );
-            if (nt.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
-            {
-                 return IMAGE_NT_SIGNATURE | 
-                       (nt.OptionalHeader.MajorSubsystemVersion << 24) |
-                       (nt.OptionalHeader.MinorSubsystemVersion << 16);
-            }
-            return IMAGE_NT_SIGNATURE;
-        }
-        else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
-        {
-            IMAGE_OS2_HEADER ne;
-            SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
-            ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
-            CloseHandle( hfile );
-            if (ne.ne_exetyp == 2)
-                return IMAGE_OS2_SIGNATURE | (ne.ne_expver << 16);
-            return 0;
-        }
-        CloseHandle( hfile );
-        return 0;
+        return shgfi_get_exe_type(szFullPath);
     }
 
     /*
@@ -502,7 +506,7 @@ DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
             lstrcpynW(sTemp, szFullPath, MAX_PATH);
 
             if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER);
+                psfi->iIcon = SIC_GetIconIndex(swShell32Name, -IDI_SHELL_FOLDER, 0);
             else
             {
                 static const WCHAR p1W[] = {'%','1',0};
@@ -518,7 +522,7 @@ DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
 
                     if (flags & SHGFI_SYSICONINDEX) 
                     {
-                        psfi->iIcon = SIC_GetIconIndex(sTemp,dwNr);
+                        psfi->iIcon = SIC_GetIconIndex(sTemp,dwNr,0);
                         if (psfi->iIcon == -1)
                             psfi->iIcon = 0;
                     }
index 805cc55..bb2db9b 100644 (file)
@@ -53,7 +53,7 @@ BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList)
 BOOL SIC_Initialize(void);
 void SIC_Destroy(void);
 BOOL PidlToSicIndex (IShellFolder * sh, LPCITEMIDLIST pidl, BOOL bBigIcon, UINT uFlags, int * pIndex);
-INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex );
+INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags );
 
 /* Classes Root */
 BOOL HCR_MapTypeToValueW(LPCWSTR szExtension, LPWSTR szFileType, DWORD len, BOOL bPrependDot);
@@ -93,6 +93,7 @@ HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid,
 HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
 HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI UnixFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+HRESULT WINAPI UnixDosFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID *ppv);
 extern HRESULT CPanel_GetIconLocationW(LPITEMIDLIST, LPWSTR, UINT, int*);
 HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
 HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
@@ -221,6 +222,7 @@ UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation,
 extern WCHAR swShell32Name[MAX_PATH];
 
 extern const GUID CLSID_UnixFolder;
+extern const GUID CLSID_UnixDosFolder;
 
 /* Default shell folder value registration */
 HRESULT SHELL_RegisterShellFolders(void);
index 3b6b89c..ef04100 100644 (file)
  *   in that string is parsed an stored.
  */
 
-#include "config.h"
-#include "wine/port.h"
-
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <errno.h>
-#include <limits.h>
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
 #define COBJMACROS
 
 #include "wine/debug.h"
@@ -1996,6 +1980,9 @@ static LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str)
     LPCWSTR p;
     DWORD len;
 
+    if( !str )
+        return NULL;
+
     p = strchrW( str, ':' );
     if( !p )
         return NULL;
@@ -2057,8 +2044,8 @@ static HRESULT ShellLink_SetAdvertiseInfo(IShellLinkImpl *This, LPCWSTR str)
             return E_FAIL;
     }
 
-    /* we have to have at least one of these two for an advertised shortcut */
-    if( !szComponent && !szProduct )
+    /* we have to have a component for an advertised shortcut */
+    if( !szComponent )
         return E_FAIL;
 
     This->sComponent = ShellLink_GetAdvertisedArg( szComponent );
index c2c200b..82a3836 100644 (file)
@@ -430,10 +430,12 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface,
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",
-           This, cidl, apidl, *rgfInOut);
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
+           This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
 
-    if (!cidl || !apidl || !rgfInOut)
+    if (!rgfInOut)
+        return E_INVALIDARG;
+    if (cidl && !apidl)
         return E_INVALIDARG;
 
     if (*rgfInOut == 0)
@@ -446,6 +448,8 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface,
         apidl++;
         cidl--;
     }
+    /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
+    *rgfInOut &= ~SFGAO_VALIDATE;
 
     TRACE ("-- result=0x%08lx\n", *rgfInOut);
 
@@ -555,7 +559,7 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
     if (_ILIsDesktop (pidl))
     {
         if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
-            (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING))
+            (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
         {
             BOOL defCharUsed;
 
@@ -585,7 +589,7 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
 
         if ((clsid = _ILGetGUIDPointer (pidl)))
         {
-            if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
+            if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
             {
                 int bWantsForParsing;
 
index 4d0a9b4..5060c47 100644 (file)
@@ -576,10 +576,12 @@ IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl,
 
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl,
-     *rgfInOut);
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n", This, cidl, apidl,
+     rgfInOut, rgfInOut ? *rgfInOut : 0);
 
-    if ((!cidl) || (!apidl) || (!rgfInOut))
+    if (!rgfInOut)
+        return E_INVALIDARG;
+    if (cidl && !apidl)
         return E_INVALIDARG;
 
     if (*rgfInOut == 0)
@@ -591,6 +593,8 @@ IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl,
         apidl++;
         cidl--;
     }
+    /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
+    *rgfInOut &= ~SFGAO_VALIDATE;
 
     TRACE ("-- result=0x%08lx\n", *rgfInOut);
 
@@ -749,56 +753,43 @@ IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl,
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-    CHAR szPath[MAX_PATH];
+    HRESULT hr = S_OK;
     int len = 0;
-    BOOL bSimplePidl;
-
-    *szPath = '\0';
 
     TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
     pdump (pidl);
 
     if (!pidl || !strRet)
         return E_INVALIDARG;
-
-    bSimplePidl = _ILIsPidlSimple (pidl);
-
-    /* take names of special folders only if its only this folder */
-    if (_ILIsSpecialFolder (pidl)) {
-        if (bSimplePidl) {
-            _ILSimpleGetText (pidl, szPath, MAX_PATH); /* append my own path */
+    
+    strRet->uType = STRRET_CSTR;
+    if (_ILIsDesktop(pidl)) { /* empty pidl */
+        if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
+            (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER)) 
+        {
+            if (This->sPathTarget)
+                lstrcpynA(strRet->u.cStr, This->sPathTarget, MAX_PATH);
         } else {
-            FIXME ("special pidl\n");
+            /* pidl has to contain exactly one non null SHITEMID */
+            hr = E_INVALIDARG;
         }
-    } else {
-        if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) &&
-         This->sPathTarget) {
-            /* get path to root */
-            lstrcpyA (szPath, This->sPathTarget);
-            PathAddBackslashA (szPath);
-            len = lstrlenA (szPath);
+    } else if (_ILIsPidlSimple(pidl)) {
+        if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
+            (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) && 
+            This->sPathTarget) 
+        {
+            lstrcpynA(strRet->u.cStr, This->sPathTarget, MAX_PATH);
+            PathAddBackslashA(strRet->u.cStr);
+            len = lstrlenA(strRet->u.cStr);
         }
-        /* append my own path */
-        _ILSimpleGetText (pidl, szPath + len, MAX_PATH - len);
-
-        if (!_ILIsFolder(pidl))
-            SHELL_FS_ProcessDisplayFilename(szPath, dwFlags);
-    }
-
-    /* go deeper if needed */
-    if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) {
-        PathAddBackslashA (szPath);
-        len = lstrlenA (szPath);
-
-        if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild (iface, pidl,
-         dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len)))
-            return E_OUTOFMEMORY;
+        _ILSimpleGetText(pidl, strRet->u.cStr + len, MAX_PATH - len);
+        if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(strRet->u.cStr, dwFlags);
+    } else {
+        hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, strRet->u.cStr, MAX_PATH);
     }
-    strRet->uType = STRRET_CSTR;
-    lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
 
-    TRACE ("-- (%p)->(%s)\n", This, szPath);
-    return S_OK;
+    TRACE ("-- (%p)->(%s)\n", This, strRet->u.cStr);
+    return hr;
 }
 
 /**************************************************************************
index 4c76ebc..98b5d62 100644 (file)
@@ -428,9 +428,12 @@ static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl, *rgfInOut);
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
+           This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
 
-    if (!cidl || !apidl || !rgfInOut)
+    if (!rgfInOut)
+        return E_INVALIDARG;
+    if (cidl && !apidl)
         return E_INVALIDARG;
 
     if (*rgfInOut == 0)
@@ -443,6 +446,8 @@ static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
         apidl++;
         cidl--;
     }
+    /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
+    *rgfInOut &= ~SFGAO_VALIDATE;
 
     TRACE ("-- result=0x%08lx\n", *rgfInOut);
     return hr;
@@ -535,9 +540,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    char szPath[MAX_PATH], szDrive[18];
-    int len = 0;
-    BOOL bSimplePidl;
+    char szPath[MAX_PATH];
     HRESULT hr = S_OK;
 
     TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
@@ -547,9 +550,6 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
         return E_INVALIDARG;
 
     szPath[0] = 0x00;
-    szDrive[0] = 0x00;
-
-    bSimplePidl = _ILIsPidlSimple (pidl);
 
     if (!pidl->mkid.cb)
     {
@@ -557,17 +557,17 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
         lstrcpyA (szPath, "::");
         SHELL32_GUIDToStringA(&CLSID_MyComputer, &szPath[2]);
     }
-    else if (_ILIsSpecialFolder (pidl))
+    else if (_ILIsPidlSimple(pidl))    
     {
         /* take names of special folders only if its only this folder */
-        if (bSimplePidl)
+        if (_ILIsSpecialFolder(pidl))
         {
             GUID const *clsid;
 
             clsid = _ILGetGUIDPointer (pidl);
             if (clsid)
             {
-                if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
+                if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
                 {
                     static const WCHAR clsidW[] =
                      { 'C','L','S','I','D','\\',0 };
@@ -634,42 +634,37 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
                 _ILSimpleGetText (pidl, szPath, MAX_PATH);
             }
         }
-        else
-            FIXME ("special folder\n");
-    }
-    else
-    {
-        if (!_ILIsDrive (pidl))
-        {
-            ERR ("Wrong pidl type\n");
-            return E_INVALIDARG;
-        }
-
-        _ILSimpleGetText (pidl, szPath, MAX_PATH);    /* append my own path */
+        else if (_ILIsDrive(pidl))
+        {        
+            _ILSimpleGetText (pidl, szPath, MAX_PATH);    /* append my own path */
 
-        /* long view "lw_name (C:)" */
-        if (bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
+            /* long view "lw_name (C:)" */
+            if (!(dwFlags & SHGDN_FORPARSING))
+            {
+                DWORD dwVolumeSerialNumber, dwMaximumComponetLength, dwFileSystemFlags;
+                char szDrive[18] = "";
+
+                GetVolumeInformationA (szPath, szDrive, sizeof (szDrive) - 6,
+                           &dwVolumeSerialNumber,
+                           &dwMaximumComponetLength, &dwFileSystemFlags, NULL, 0);
+                strcat (szDrive, " (");
+                strncat (szDrive, szPath, 2);
+                strcat (szDrive, ")");
+                strcpy (szPath, szDrive);
+            }
+        }
+        else 
         {
-            DWORD dwVolumeSerialNumber, dwMaximumComponetLength, dwFileSystemFlags;
-
-            GetVolumeInformationA (szPath, szDrive, sizeof (szDrive) - 6,
-                       &dwVolumeSerialNumber,
-                       &dwMaximumComponetLength, &dwFileSystemFlags, NULL, 0);
-            strcat (szDrive, " (");
-            strncat (szDrive, szPath, 2);
-            strcat (szDrive, ")");
-            strcpy (szPath, szDrive);
+            /* Neither a shell namespace extension nor a drive letter. */
+            ERR("Wrong pidl type\n");
+            return E_INVALIDARG;
         }
     }
-
-    if (!bSimplePidl)
+    else
     {
-        /* go deeper if needed */
-        PathAddBackslashA (szPath);
-        len = strlen (szPath);
-
-        hr = SHELL32_GetDisplayNameOfChild (iface, pidl,
-                  dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len);
+        /* Complex pidl. Let the child folder do the work */
+        strRet->uType = STRRET_CSTR;
+        hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH);
     }
 
     if (SUCCEEDED (hr))
index cf3b4db..936d9be 100644 (file)
@@ -971,6 +971,11 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
     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 |
+        SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI |
+        SEE_MASK_UNICODE       | SEE_MASK_NO_CONSOLE   | SEE_MASK_ASYNCOK |
+        SEE_MASK_HMONITOR;
 
     WCHAR wszApplicationName[MAX_PATH+2], wszParameters[1024], wszDir[MAX_PATH];
     SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */
@@ -1016,12 +1021,9 @@ BOOL WINAPI ShellExecuteExW32 (LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfun
     sei_tmp.lpParameters = wszParameters;
     sei_tmp.lpDirectory = wszDir;
 
-    if (sei_tmp.fMask & (SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
-        SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
-        SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE |
-        SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
+    if (sei_tmp.fMask & unsupportedFlags)
     {
-        FIXME("flags ignored: 0x%08lx\n", sei_tmp.fMask);
+        FIXME("flags ignored: 0x%08lx\n", sei_tmp.fMask & unsupportedFlags);
     }
 
     /* process the IDList */
index 5e12e81..0f9d9b2 100644 (file)
@@ -817,7 +817,7 @@ int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
          if (ForFree)
          {
            retCode = SHFileOperationW(&nFileOp);
-           HeapFree(GetProcessHeap(), 0, ForFree); /* we can not use wString, it was changed */
+           HeapFree(GetProcessHeap(), 0, ForFree); /* we cannot use wString, it was changed */
            break;
          }
          else
index da5acfb..17d98f2 100644 (file)
@@ -415,6 +415,22 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO
            if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk"))
                *pdwAttributes &= ~SFGAO_LINK;
        }
+
+       if (SFGAO_HASSUBFOLDER & *pdwAttributes)
+       {
+           IShellFolder *psf2;
+           if (SUCCEEDED(IShellFolder_BindToObject(psf, pidl, 0, (REFIID)&IID_IShellFolder, (LPVOID *)&psf2)))
+           {
+               IEnumIDList     *pEnumIL = NULL;
+               if (SUCCEEDED(IShellFolder_EnumObjects(psf2, 0, SHCONTF_FOLDERS, &pEnumIL)))
+               {
+                   if (IEnumIDList_Skip(pEnumIL, 1) != S_OK)
+                       *pdwAttributes &= ~SFGAO_HASSUBFOLDER;
+                   IEnumIDList_Release(pEnumIL);
+               }
+               IShellFolder_Release(psf2);
+           }
+       }
     } else {
        *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
     }
index df55c74..286e367 100644 (file)
@@ -22570,6 +22570,171 @@ IDI_SHELL_PRINTER ICON printer.ico
  '00 00 FF FF 00 00'
 } */
 
+/* BINRES shortcut.ico */
+IDI_SHELL_SHORTCUT ICON shortcut.ico
+/* {
+ '00 00 01 00 02 00 20 20 00 00 00 00 00 00 A8 08'
+ '00 00 26 00 00 00 10 10 10 00 00 00 00 00 28 01'
+ '00 00 CE 08 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 04 04 04 00 08 08 08 00 0C 0C'
+ '0C 00 11 11 11 00 16 16 16 00 1C 1C 1C 00 22 22'
+ '22 00 29 29 29 00 55 55 55 00 4D 4D 4D 00 42 42'
+ '42 00 39 39 39 00 80 7C FF 00 50 50 FF 00 93 00'
+ 'D6 00 FF EC CC 00 C6 D6 EF 00 D6 E7 E7 00 90 A9'
+ 'AD 00 00 00 33 00 00 00 66 00 00 00 99 00 00 00'
+ 'CC 00 00 33 00 00 00 33 33 00 00 33 66 00 00 33'
+ '99 00 00 33 CC 00 00 33 FF 00 00 66 00 00 00 66'
+ '33 00 00 66 66 00 00 66 99 00 00 66 CC 00 00 66'
+ 'FF 00 00 99 00 00 00 99 33 00 00 99 66 00 00 99'
+ '99 00 00 99 CC 00 00 99 FF 00 00 CC 00 00 00 CC'
+ '33 00 00 CC 66 00 00 CC 99 00 00 CC CC 00 00 CC'
+ 'FF 00 00 FF 66 00 00 FF 99 00 00 FF CC 00 33 00'
+ '00 00 33 00 33 00 33 00 66 00 33 00 99 00 33 00'
+ 'CC 00 33 00 FF 00 33 33 00 00 33 33 33 00 33 33'
+ '66 00 33 33 99 00 33 33 CC 00 33 33 FF 00 33 66'
+ '00 00 33 66 33 00 33 66 66 00 33 66 99 00 33 66'
+ 'CC 00 33 66 FF 00 33 99 00 00 33 99 33 00 33 99'
+ '66 00 33 99 99 00 33 99 CC 00 33 99 FF 00 33 CC'
+ '00 00 33 CC 33 00 33 CC 66 00 33 CC 99 00 33 CC'
+ 'CC 00 33 CC FF 00 33 FF 33 00 33 FF 66 00 33 FF'
+ '99 00 33 FF CC 00 33 FF FF 00 66 00 00 00 66 00'
+ '33 00 66 00 66 00 66 00 99 00 66 00 CC 00 66 00'
+ 'FF 00 66 33 00 00 66 33 33 00 66 33 66 00 66 33'
+ '99 00 66 33 CC 00 66 33 FF 00 66 66 00 00 66 66'
+ '33 00 66 66 66 00 66 66 99 00 66 66 CC 00 66 99'
+ '00 00 66 99 33 00 66 99 66 00 66 99 99 00 66 99'
+ 'CC 00 66 99 FF 00 66 CC 00 00 66 CC 33 00 66 CC'
+ '99 00 66 CC CC 00 66 CC FF 00 66 FF 00 00 66 FF'
+ '33 00 66 FF 99 00 66 FF CC 00 CC 00 FF 00 FF 00'
+ 'CC 00 99 99 00 00 99 33 99 00 99 00 99 00 99 00'
+ 'CC 00 99 00 00 00 99 33 33 00 99 00 66 00 99 33'
+ 'CC 00 99 00 FF 00 99 66 00 00 99 66 33 00 99 33'
+ '66 00 99 66 99 00 99 66 CC 00 99 33 FF 00 99 99'
+ '33 00 99 99 66 00 99 99 99 00 99 99 CC 00 99 99'
+ 'FF 00 99 CC 00 00 99 CC 33 00 66 CC 66 00 99 CC'
+ '99 00 99 CC CC 00 99 CC FF 00 99 FF 00 00 99 FF'
+ '33 00 99 CC 66 00 99 FF 99 00 99 FF CC 00 99 FF'
+ 'FF 00 CC 00 00 00 99 00 33 00 CC 00 66 00 CC 00'
+ '99 00 CC 00 CC 00 99 33 00 00 CC 33 33 00 CC 33'
+ '66 00 CC 33 99 00 CC 33 CC 00 CC 33 FF 00 CC 66'
+ '00 00 CC 66 33 00 99 66 66 00 CC 66 99 00 CC 66'
+ 'CC 00 99 66 FF 00 CC 99 00 00 CC 99 33 00 CC 99'
+ '66 00 CC 99 99 00 CC 99 CC 00 CC 99 FF 00 CC CC'
+ '00 00 CC CC 33 00 CC CC 66 00 CC CC 99 00 CC CC'
+ 'CC 00 CC CC FF 00 CC FF 00 00 CC FF 33 00 99 FF'
+ '66 00 CC FF 99 00 CC FF CC 00 CC FF FF 00 CC 00'
+ '33 00 FF 00 66 00 FF 00 99 00 CC 33 00 00 FF 33'
+ '33 00 FF 33 66 00 FF 33 99 00 FF 33 CC 00 FF 33'
+ 'FF 00 FF 66 00 00 FF 66 33 00 CC 66 66 00 FF 66'
+ '99 00 FF 66 CC 00 CC 66 FF 00 FF 99 00 00 FF 99'
+ '33 00 FF 99 66 00 FF 99 99 00 FF 99 CC 00 FF 99'
+ 'FF 00 FF CC 00 00 FF CC 33 00 FF CC 66 00 FF CC'
+ '99 00 FF CC CC 00 FF CC FF 00 FF FF 33 00 CC FF'
+ '66 00 FF FF 99 00 FF FF CC 00 66 66 FF 00 66 FF'
+ '66 00 66 FF FF 00 FF 66 66 00 FF 66 FF 00 FF FF'
+ '66 00 21 00 A5 00 5F 5F 5F 00 77 77 77 00 86 86'
+ '86 00 96 96 96 00 CB CB CB 00 B2 B2 B2 00 D7 D7'
+ 'D7 00 DD DD DD 00 E3 E3 E3 00 EA EA EA 00 F1 F1'
+ 'F1 00 F8 F8 F8 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF FF FF FF FF FF FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ '0A FF FF FF FF FF FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ '0A 0A FF FF FF FF FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF 0A 0A FF FF FF FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF 0A 0A 0A FF 0A FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF FF 0A 0A 0A 0A FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF FF FF 0A 0A 0A FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF FF 0A 0A 0A 0A FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 FF'
+ 'FF FF FF FF FF FF FF FF 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 07 07'
+ '07 07 07 07 07 07 07 07 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A'
+ '0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 00 1F'
+ 'FF FF 00 1F FF FF 00 1F FF FF 00 1F FF FF 00 1F'
+ 'FF FF 00 1F FF FF 00 1F FF FF 00 1F FF FF 00 1F'
+ 'FF FF 00 1F FF FF 00 1F FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
+ '00 00 C0 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 7F FF'
+ 'FF 00 00 00 00 00 70 FF FF 00 00 00 00 00 7F 00'
+ 'FF 00 00 00 00 00 7F 00 FF 00 00 00 00 00 7F FF'
+ 'FF 00 00 00 00 00 77 77 77 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 01 FF 00 00 01 FF 00 00 01 FF'
+ '00 00 01 FF 00 00 01 FF 00 00 01 FF 00 00 01 FF'
+ '00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 FF FF'
+ '00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 FF FF'
+ '00 00 FF FF 00 00'
+} */
+
 /* BINRES desktop.ico */
 IDI_SHELL_DESKTOP ICON desktop.ico
 /* {
@@ -24152,8 +24317,6 @@ IDI_SHELL_DESKTOP ICON desktop.ico
 } */
 
 
-
-
 /*--------------------- END FIXME ------------------------*/
 
 /*
index 061ce69..ebc844d 100644 (file)
@@ -31,6 +31,8 @@
 #define IDS_SHV_COLUMN7                13
 #define IDS_SHV_COLUMN8                14
 #define IDS_SHV_COLUMN9                15
+#define IDS_SHV_COLUMN10       16
+#define IDS_SHV_COLUMN11       17
 
 #define IDS_DESKTOP            20
 #define IDS_MYCOMPUTER         21
 #define IDI_SHELL_COMPUTERS_NEAR_ME 19
 #define IDI_SHELL_SEARCH            23
 #define IDI_SHELL_HELP              24
+#define IDI_SHELL_SHORTCUT          30
 #define IDI_SHELL_EMPTY_RECYCLE_BIN 32
 #define IDI_SHELL_FULL_RECYCLE_BIN  33
 #define IDI_SHELL_DESKTOP           35