[ros-diffs] [janderwald] 30431: - implement _ILIsMyDocuments - halfplement MyDocuments shell folder based on desktop code - insert MyDocuments folder before MyComputer pidl - setup still needs to create the MyDocuments folder

janderwald at svn.reactos.org janderwald at svn.reactos.org
Wed Nov 14 01:45:08 CET 2007


Author: janderwald
Date: Wed Nov 14 03:45:08 2007
New Revision: 30431

URL: http://svn.reactos.org/svn/reactos?rev=30431&view=rev
Log:
- implement _ILIsMyDocuments
- halfplement MyDocuments shell folder based on desktop code
- insert MyDocuments folder before MyComputer pidl
- setup still needs to create the MyDocuments folder

Added:
    trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c   (with props)
Modified:
    trunk/reactos/dll/win32/shell32/pidl.c
    trunk/reactos/dll/win32/shell32/pidl.h
    trunk/reactos/dll/win32/shell32/regsvr.c
    trunk/reactos/dll/win32/shell32/shell32.rbuild
    trunk/reactos/dll/win32/shell32/shell32_main.h
    trunk/reactos/dll/win32/shell32/shellole.c
    trunk/reactos/dll/win32/shell32/shfldr_desktop.c

Modified: trunk/reactos/dll/win32/shell32/pidl.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/pidl.c?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/pidl.c (original)
+++ trunk/reactos/dll/win32/shell32/pidl.c Wed Nov 14 03:45:08 2007
@@ -1623,6 +1623,17 @@
     return pidl && pidl->mkid.cb  ? 0 : 1;
 }
 
+BOOL _ILIsMyDocuments(LPCITEMIDLIST pidl)
+{
+    REFIID iid = _ILGetGUIDPointer(pidl);
+
+    TRACE("(%p)\n",pidl);
+
+    if (iid)
+        return IsEqualIID(iid, &CLSID_MyDocuments);
+    return FALSE;
+}
+
 BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
 {
     REFIID iid = _ILGetGUIDPointer(pidl);
@@ -1633,6 +1644,7 @@
         return IsEqualIID(iid, &CLSID_MyComputer);
     return FALSE;
 }
+
 BOOL _ILIsBitBucket(LPCITEMIDLIST pidl)
 {
     REFIID iid = _ILGetGUIDPointer(pidl);

Modified: trunk/reactos/dll/win32/shell32/pidl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/pidl.h?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/pidl.h (original)
+++ trunk/reactos/dll/win32/shell32/pidl.h Wed Nov 14 03:45:08 2007
@@ -204,6 +204,7 @@
 BOOL	_ILIsUnicode		(LPCITEMIDLIST pidl);
 BOOL	_ILIsDesktop		(LPCITEMIDLIST pidl);
 BOOL	_ILIsMyComputer		(LPCITEMIDLIST pidl);
+BOOL _ILIsMyDocuments       (LPCITEMIDLIST pidl);
 BOOL    _ILIsBitBucket      (LPCITEMIDLIST pidl);
 BOOL	_ILIsDrive		(LPCITEMIDLIST pidl);
 BOOL	_ILIsFolder		(LPCITEMIDLIST pidl);

Modified: trunk/reactos/dll/win32/shell32/regsvr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/regsvr.c?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/regsvr.c (original)
+++ trunk/reactos/dll/win32/shell32/regsvr.c Wed Nov 14 03:45:08 2007
@@ -714,12 +714,12 @@
         wszDesktop,
         wszSlash
     },
+#endif
     {
         &CLSID_MyDocuments,
         wszDesktop,
         wszMyDocuments
     },
-#endif
     {
         &CLSID_RecycleBin,
         wszDesktop,

Modified: trunk/reactos/dll/win32/shell32/shell32.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32.rbuild?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shell32.rbuild (original)
+++ trunk/reactos/dll/win32/shell32/shell32.rbuild Wed Nov 14 03:45:08 2007
@@ -52,6 +52,7 @@
 	<file>shfldr_desktop.c</file>
 	<file>shfldr_fs.c</file>
 	<file>shfldr_mycomp.c</file>
+	<file> shlfldr_mydocuments.c</file>
 	<file>shfldr_printers.c</file>
 	<file>shlexec.c</file>
 	<file>shlfileop.c</file>

Modified: trunk/reactos/dll/win32/shell32/shell32_main.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32_main.h?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shell32_main.h (original)
+++ trunk/reactos/dll/win32/shell32/shell32_main.h Wed Nov 14 03:45:08 2007
@@ -93,6 +93,7 @@
 HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI ISF_Printers_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+HRESULT WINAPI ISF_MyDocuments_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
 HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);

Modified: trunk/reactos/dll/win32/shell32/shellole.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shellole.c?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shellole.c (original)
+++ trunk/reactos/dll/win32/shell32/shellole.c Wed Nov 14 03:45:08 2007
@@ -73,8 +73,8 @@
 	{&CLSID_UnixFolder,     &UnixFolder_Constructor},
 	{&CLSID_UnixDosFolder,  &UnixDosFolder_Constructor},
 	{&CLSID_FolderShortcut, &FolderShortcut_Constructor},
-	{&CLSID_MyDocuments,    &MyDocuments_Constructor},
 #endif
+	{&CLSID_MyDocuments,    &ISF_MyDocuments_Constructor},
 	{&CLSID_Printers,       &ISF_Printers_Constructor},
 	{&CLSID_RecycleBin,     &RecycleBin_Constructor},
 	{&CLSID_OpenWith,       &SHEOW_Constructor},

Modified: trunk/reactos/dll/win32/shell32/shfldr_desktop.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr_desktop.c?rev=30431&r1=30430&r2=30431&view=diff
==============================================================================
--- trunk/reactos/dll/win32/shell32/shfldr_desktop.c (original)
+++ trunk/reactos/dll/win32/shell32/shfldr_desktop.c Wed Nov 14 03:45:08 2007
@@ -262,6 +262,7 @@
         UINT i;
 
         /* create the pidl for This item */
+        ret = AddToEnumList(list, _ILCreateMyDocuments());
         ret = AddToEnumList(list, _ILCreateMyComputer());
 
         for (i=0; i<2; i++) {
@@ -269,6 +270,7 @@
                                       Desktop_NameSpaceW, 0, KEY_READ, &hkey))
             {
                 WCHAR iid[50];
+                LPITEMIDLIST pidl;
                 int i=0;
 
                 while (ret)
@@ -280,7 +282,15 @@
                     r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
                     if (ERROR_SUCCESS == r)
                     {
-                        ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
+                        pidl = _ILCreateGuidFromStrW(iid);
+                        if (_ILIsMyDocuments(pidl))
+                        {
+                            SHFree(pidl);
+                        }
+                        else
+                        {
+                            ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
+                        }
                         i++;
                     }
                     else if (ERROR_NO_MORE_ITEMS == r)

Added: trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c?rev=30431&view=auto
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c (added)
+++ trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c Wed Nov 14 03:45:08 2007
@@ -1,0 +1,930 @@
+
+/*
+ *    Virtual MyDocuments Folder
+ *
+ *    Copyright 2007    Johannes Anderwald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+#include "ole2.h"
+#include "shlguid.h"
+
+#include "enumidlist.h"
+#include "pidl.h"
+#include "undocshell.h"
+#include "shell32_main.h"
+#include "shresdef.h"
+#include "shlwapi.h"
+#include "shellfolder.h"
+#include "wine/debug.h"
+#include "debughlp.h"
+#include "shfldr.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
+
+/***********************************************************************
+*     MyDocumentsfolder implementation
+*/
+
+typedef struct {
+    const IShellFolder2Vtbl *lpVtbl;
+    const IPersistFolder2Vtbl *lpPF2;
+    LONG ref;
+
+    /* both paths are parsible from the MyDocuments */
+    LPWSTR sPathTarget;     /* complete path to target used for enumeration and ChangeNotify */
+    LPITEMIDLIST pidlRoot;  /* absolute pidl */
+
+    UINT cfShellIDList;        /* clipboardformat for IDropTarget */
+    BOOL fAcceptFmt;        /* flag for pending Drop */
+} IGenericSFImpl;
+
+#define _IUnknown_(This)    (IShellFolder*)&(This->lpVtbl)
+#define _IShellFolder_(This)    (IShellFolder*)&(This->lpVtbl)
+
+static const shvheader MyDocumentsSFHeader[] = {
+    {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
+    {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+    {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+    {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
+    {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
+};
+
+#define MYDOCUMENTSSHELLVIEWCOLUMNS 5
+
+/**************************************************************************
+ *    ISF_MyDocuments_fnQueryInterface
+ *
+ * NOTES supports not IPersist/IPersistFolder
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnQueryInterface(
+                IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
+
+    *ppvObj = NULL;
+
+    if (IsEqualIID (riid, &IID_IUnknown) ||
+        IsEqualIID (riid, &IID_IShellFolder) ||
+        IsEqualIID (riid, &IID_IShellFolder2))
+    {
+        *ppvObj = This;
+    }
+    else if (IsEqualIID (riid, &IID_IPersistFolder) ||
+             IsEqualIID (riid, &IID_IPersistFolder2))
+    {
+        *ppvObj = &This->lpPF2;
+    }
+    if (*ppvObj)
+    {
+        IUnknown_AddRef ((IUnknown *) (*ppvObj));
+        TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
+        return S_OK;
+    }
+    TRACE ("-- Interface: E_NOINTERFACE\n");
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ISF_MyDocuments_fnAddRef (IShellFolder2 * iface)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->ref);
+
+    TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI ISF_MyDocuments_fnRelease (IShellFolder2 * iface)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    ULONG refCount = InterlockedDecrement(&This->ref);
+
+    TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
+
+    if (!refCount)
+    {
+        TRACE ("-- destroying IShellFolder(%p)\n", This);
+        SHFree (This->pidlRoot);
+        HeapFree(GetProcessHeap(), 0, This->sPathTarget);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return refCount;
+}
+
+static
+HRESULT
+WINAPI ISF_MyDocuments_fnParseDisplayName (IShellFolder2 * iface,
+                HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
+                DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    WCHAR szElement[MAX_PATH];
+    LPCWSTR szNext = NULL;
+    LPITEMIDLIST pidlTemp = NULL;
+    HRESULT hr = S_OK;
+    CLSID clsid;
+
+    TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
+           This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
+           pchEaten, ppidl, pdwAttributes);
+
+    if (!lpszDisplayName || !ppidl)
+        return E_INVALIDARG;
+
+    *ppidl = 0;
+
+    if (pchEaten)
+        *pchEaten = 0;        /* strange but like the original */
+
+    if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
+    {
+        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+        TRACE ("-- element: %s\n", debugstr_w (szElement));
+        SHCLSIDFromStringW (szElement + 2, &clsid);
+        pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
+    }
+    else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
+    {
+        *ppidl = pidlTemp;
+        return S_OK;
+    }
+    else
+    {
+        /* it's a filesystem path on the desktop. Let a FSFolder parse it */
+
+        if (*lpszDisplayName)
+        {
+            WCHAR szPath[MAX_PATH];
+            LPWSTR pathPtr;
+
+            /* build a complete path to create a simple pidl */
+            lstrcpynW(szPath, This->sPathTarget, MAX_PATH);
+            pathPtr = PathAddBackslashW(szPath);
+            if (pathPtr)
+            {
+                lstrcpynW(pathPtr, lpszDisplayName, MAX_PATH - (pathPtr - szPath));
+                hr = _ILCreateFromPathW(szPath, &pidlTemp);
+            }
+            else
+            {
+                /* should never reach here, but for completeness */
+                hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+            }
+        }
+        else
+            pidlTemp = _ILCreateMyComputer();
+
+        szNext = NULL;
+    }
+
+    if (SUCCEEDED(hr) && pidlTemp)
+    {
+        if (szNext && *szNext)
+        {
+            hr = SHELL32_ParseNextElement(iface, hwndOwner, pbc,
+                    &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
+        }
+        else
+        {
+            if (pdwAttributes && *pdwAttributes)
+                hr = SHELL32_GetItemAttributes(_IShellFolder_ (This),
+                                               pidlTemp, pdwAttributes);
+        }
+    }
+
+    *ppidl = pidlTemp;
+
+    TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr);
+
+    return hr;
+}
+
+/**************************************************************************
+ *  CreateDesktopEnumList()
+ */
+static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
+{
+    BOOL ret = TRUE;
+    WCHAR szPath[MAX_PATH];
+
+    TRACE("(%p)->(flags=0x%08x)\n", list, dwFlags);
+
+   /* enumerate the elements in %windir%\desktop */
+    SHGetSpecialFolderPathW(0, szPath, CSIDL_MYDOCUMENTS, FALSE);
+    ret = ret && CreateFolderEnumList(list, szPath, dwFlags);
+
+    return ret;
+}
+
+/**************************************************************************
+ *        ISF_MyDocuments_fnEnumObjects
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnEnumObjects (IShellFolder2 * iface,
+                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n",
+           This, hwndOwner, dwFlags, ppEnumIDList);
+
+    *ppEnumIDList = IEnumIDList_Constructor();
+    if (*ppEnumIDList)
+        CreateDesktopEnumList(*ppEnumIDList, dwFlags);
+
+    TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
+
+    return *ppEnumIDList ? S_OK : E_OUTOFMEMORY;
+}
+
+/**************************************************************************
+ *        ISF_MyDocuments_fnBindToObject
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnBindToObject (IShellFolder2 * iface,
+                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
+           This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    return SHELL32_BindToChild( This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut );
+}
+
+/**************************************************************************
+ *    ISF_MyDocuments_fnBindToStorage
+ */
+static
+HRESULT
+WINAPI
+ISF_MyDocuments_fnBindToStorage (IShellFolder2 * iface,
+                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
+           This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    *ppvOut = NULL;
+    return E_NOTIMPL;
+}
+
+/**************************************************************************
+ *     ISF_MyDocuments_fnCompareIDs
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnCompareIDs (IShellFolder2 * iface,
+                        LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    int nReturn;
+
+    TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
+    nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
+    TRACE ("-- %i\n", nReturn);
+    return nReturn;
+}
+
+/**************************************************************************
+ *    ISF_MyDocuments_fnCreateViewObject
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnCreateViewObject (IShellFolder2 * iface,
+                              HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    LPSHELLVIEW pShellView;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
+           This, hwndOwner, shdebugstr_guid (riid), ppvOut);
+
+    if (!ppvOut)
+        return hr;
+
+    *ppvOut = NULL;
+
+    if (IsEqualIID (riid, &IID_IDropTarget))
+    {
+        WARN ("IDropTarget not implemented\n");
+        hr = E_NOTIMPL;
+    }
+    else if (IsEqualIID (riid, &IID_IContextMenu))
+    {
+        WARN ("IContextMenu not implemented\n");
+        hr = E_NOTIMPL;
+    }
+    else if (IsEqualIID (riid, &IID_IShellView))
+    {
+        pShellView = IShellView_Constructor ((IShellFolder *) iface);
+        if (pShellView)
+        {
+            hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
+            IShellView_Release (pShellView);
+        }
+    }
+    TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
+    return hr;
+}
+
+/**************************************************************************
+ *  ISF_MyDocuments_fnGetAttributesOf
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnGetAttributesOf (IShellFolder2 * iface,
+                UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    HRESULT hr = S_OK;
+    static const DWORD dwDesktopAttributes =
+        SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
+        SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER;
+    static const DWORD dwMyComputerAttributes =
+        SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET |
+        SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
+
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
+           This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
+
+    if (!rgfInOut)
+        return E_INVALIDARG;
+    if (cidl && !apidl)
+        return E_INVALIDARG;
+
+    if (*rgfInOut == 0)
+        *rgfInOut = ~0;
+
+    if(cidl == 0) {
+        *rgfInOut &= dwDesktopAttributes;
+    } else {
+        while (cidl > 0 && *apidl) {
+            pdump (*apidl);
+            if (_ILIsDesktop(*apidl)) {
+                *rgfInOut &= dwDesktopAttributes;
+            } else if (_ILIsMyComputer(*apidl)) {
+                *rgfInOut &= dwMyComputerAttributes;
+            } else {
+                SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
+            }
+            apidl++;
+            cidl--;
+        }
+    }
+    /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
+    *rgfInOut &= ~SFGAO_VALIDATE;
+
+    TRACE ("-- result=0x%08x\n", *rgfInOut);
+
+    return hr;
+}
+
+/**************************************************************************
+ *    ISF_MyDocuments_fnGetUIObjectOf
+ *
+ * PARAMETERS
+ *  HWND           hwndOwner, //[in ] Parent window for any output
+ *  UINT           cidl,      //[in ] array size
+ *  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
+ *  REFIID         riid,      //[in ] Requested Interface
+ *  UINT*          prgfInOut, //[   ] reserved
+ *  LPVOID*        ppvObject) //[out] Resulting Interface
+ *
+ */
+static HRESULT WINAPI ISF_MyDocuments_fnGetUIObjectOf (IShellFolder2 * iface,
+                HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl,
+                REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    LPITEMIDLIST pidl;
+    IUnknown *pObj = NULL;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
+       This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+
+    if (!ppvOut)
+        return hr;
+
+    *ppvOut = NULL;
+
+    if (IsEqualIID (riid, &IID_IContextMenu))
+    {
+        if (cidl > 0)
+            pObj = (LPUNKNOWN) ISvItemCm_Constructor( (IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+        else
+            pObj = (LPUNKNOWN) ISvBgCm_Constructor( (IShellFolder *) iface, TRUE);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
+    {
+        pObj = (LPUNKNOWN) IDataObject_Constructor( hwndOwner,
+                                                  This->pidlRoot, apidl, cidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+        SHFree (pidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
+        SHFree (pidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
+    {
+        hr = IShellFolder_QueryInterface (iface,
+                                          &IID_IDropTarget, (LPVOID *) & pObj);
+    }
+    else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
+              IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
+        SHFree (pidl);
+    }
+    else
+        hr = E_NOINTERFACE;
+
+    if (SUCCEEDED(hr) && !pObj)
+        hr = E_OUTOFMEMORY;
+
+    *ppvOut = pObj;
+    TRACE ("(%p)->hr=0x%08x\n", This, hr);
+    return hr;
+}
+
+static
+HRESULT
+WINAPI ISF_MyDocuments_fnGetDisplayNameOf (IShellFolder2 * iface,
+                LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    HRESULT hr = S_OK;
+    LPWSTR pszPath;
+
+    TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet);
+    pdump (pidl);
+
+    if (!strRet)
+        return E_INVALIDARG;
+
+    pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
+    if (!pszPath)
+        return E_OUTOFMEMORY;
+
+    if (_ILIsMyDocuments (pidl))
+    {
+        if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
+            (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
+            strcpyW(pszPath, This->sPathTarget);
+        else
+            HCR_GetClassNameW(&CLSID_ShellDesktop, pszPath, MAX_PATH);
+    }
+    else if (_ILIsPidlSimple (pidl))
+    {
+        GUID const *clsid;
+
+        if ((clsid = _ILGetGUIDPointer (pidl)))
+        {
+            if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
+            {
+                int bWantsForParsing;
+
+                /*
+                 * We can only get a filesystem path from a shellfolder if the
+                 *  value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
+                 *
+                 * Exception: The MyComputer folder doesn't have this key,
+                 *   but any other filesystem backed folder it needs it.
+                 */
+                if (IsEqualIID (clsid, &CLSID_MyComputer))
+                {
+                    bWantsForParsing = TRUE;
+                }
+                else
+                {
+                    /* get the "WantsFORPARSING" flag from the registry */
+                    static const WCHAR clsidW[] =
+                     { 'C','L','S','I','D','\\',0 };
+                    static const WCHAR shellfolderW[] =
+                     { '\\','s','h','e','l','l','f','o','l','d','e','r',0 };
+                    static const WCHAR wantsForParsingW[] =
+                     { 'W','a','n','t','s','F','o','r','P','a','r','s','i','n',
+                     'g',0 };
+                    WCHAR szRegPath[100];
+                    LONG r;
+
+                    lstrcpyW (szRegPath, clsidW);
+                    SHELL32_GUIDToStringW (clsid, &szRegPath[6]);
+                    lstrcatW (szRegPath, shellfolderW);
+                    r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
+                                    wantsForParsingW, NULL, NULL, NULL);
+                    if (r == ERROR_SUCCESS)
+                        bWantsForParsing = TRUE;
+                    else
+                        bWantsForParsing = FALSE;
+                }
+
+                if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
+                     bWantsForParsing)
+                {
+                    /*
+                     * we need the filesystem path to the destination folder.
+                     * Only the folder itself can know it
+                     */
+                    hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags,
+                                                        pszPath,
+                                                        MAX_PATH);
+                }
+                else
+                {
+                    /* parsing name like ::{...} */
+                    pszPath[0] = ':';
+                    pszPath[1] = ':';
+                    SHELL32_GUIDToStringW (clsid, &pszPath[2]);
+                }
+            }
+            else
+            {
+                /* user friendly name */
+                HCR_GetClassNameW (clsid, pszPath, MAX_PATH);
+            }
+        }
+        else
+        {
+            int cLen = 0;
+
+            /* file system folder or file rooted at the desktop */
+            if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
+                (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
+            {
+                lstrcpynW(pszPath, This->sPathTarget, MAX_PATH - 1);
+                PathAddBackslashW(pszPath);
+                cLen = lstrlenW(pszPath);
+            }
+
+            _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
+
+            if (!_ILIsFolder(pidl))
+                SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
+        }
+    }
+    else
+    {
+        /* a complex pidl, let the subfolder do the work */
+        hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags,
+                                            pszPath, MAX_PATH);
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        /* Win9x always returns ANSI strings, NT always returns Unicode strings */
+        if (GetVersion() & 0x80000000)
+        {
+            strRet->uType = STRRET_CSTR;
+            if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH,
+                                     NULL, NULL))
+                strRet->u.cStr[0] = '\0';
+            CoTaskMemFree(pszPath);
+        }
+        else
+        {
+            strRet->uType = STRRET_WSTR;
+            strRet->u.pOleStr = pszPath;
+        }
+    }
+    else
+        CoTaskMemFree(pszPath);
+
+    TRACE ("-- (%p)->(%s,0x%08x)\n", This,
+     strRet->uType == STRRET_CSTR ? strRet->u.cStr :
+     debugstr_w(strRet->u.pOleStr), hr);
+    return hr;
+}
+
+static HRESULT WINAPI ISF_MyDocuments_fnSetNameOf (IShellFolder2 * iface,
+                HWND hwndOwner, LPCITEMIDLIST pidl,    /* simple pidl */
+                LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", This, hwndOwner, pidl,
+           debugstr_w (lpName), dwFlags, pPidlOut);
+
+    return E_FAIL;
+}
+
+static HRESULT WINAPI ISF_MyDocuments_fnGetDefaultSearchGUID(IShellFolder2 *iface,
+                GUID * pguid)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ISF_MyDocuments_fnEnumSearches (IShellFolder2 *iface,
+                IEnumExtraSearch ** ppenum)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+
+static
+HRESULT
+WINAPI
+ISF_MyDocuments_fnGetDefaultColumn (IShellFolder2 * iface,
+                DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    TRACE ("(%p)\n", This);
+
+    if (pSort)
+        *pSort = 0;
+    if (pDisplay)
+        *pDisplay = 0;
+
+    return S_OK;
+}
+static
+HRESULT
+WINAPI
+ISF_MyDocuments_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    TRACE ("(%p)\n", This);
+
+    if (!pcsFlags || iColumn >= MYDOCUMENTSSHELLVIEWCOLUMNS)
+    return E_INVALIDARG;
+
+    *pcsFlags = MyDocumentsSFHeader[iColumn].pcsFlags;
+
+    return S_OK;
+}
+
+static
+HRESULT
+WINAPI
+ISF_MyDocuments_fnGetDetailsEx (IShellFolder2 * iface, LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    FIXME ("(%p)\n", This);
+
+    return E_NOTIMPL;
+}
+
+static 
+HRESULT
+WINAPI
+ISF_MyDocuments_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+
+    HRESULT hr = S_OK;
+
+    TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
+
+    if (!psd || iColumn >= MYDOCUMENTSSHELLVIEWCOLUMNS)
+        return E_INVALIDARG;
+
+    if (!pidl)
+    {
+        psd->fmt = MyDocumentsSFHeader[iColumn].fmt;
+        psd->cxChar = MyDocumentsSFHeader[iColumn].cxChar;
+        psd->str.uType = STRRET_CSTR;
+        LoadStringA (shell32_hInstance, MyDocumentsSFHeader[iColumn].colnameid,
+                     psd->str.u.cStr, MAX_PATH);
+        return S_OK;
+    }
+
+    /* the data from the pidl */
+    psd->str.uType = STRRET_CSTR;
+    switch (iColumn)
+    {
+    case 0:        /* name */
+        hr = IShellFolder_GetDisplayNameOf(iface, pidl,
+                   SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+        break;
+    case 1:        /* size */
+        _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    case 2:        /* type */
+        _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    case 3:        /* date */
+        _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    case 4:        /* attributes */
+        _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    }
+
+    return hr;
+}
+
+static 
+HRESULT
+WINAPI
+ISF_MyDocuments_fnMapColumnToSCID (IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
+{
+    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+
+static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
+{
+    ISF_MyDocuments_fnQueryInterface,
+    ISF_MyDocuments_fnAddRef,
+    ISF_MyDocuments_fnRelease,
+    ISF_MyDocuments_fnParseDisplayName,
+    ISF_MyDocuments_fnEnumObjects,
+    ISF_MyDocuments_fnBindToObject,
+    ISF_MyDocuments_fnBindToStorage,
+    ISF_MyDocuments_fnCompareIDs,
+    ISF_MyDocuments_fnCreateViewObject,
+    ISF_MyDocuments_fnGetAttributesOf,
+    ISF_MyDocuments_fnGetUIObjectOf,
+    ISF_MyDocuments_fnGetDisplayNameOf,
+    ISF_MyDocuments_fnSetNameOf,
+    /* ShellFolder2 */
+    ISF_MyDocuments_fnGetDefaultSearchGUID,
+    ISF_MyDocuments_fnEnumSearches,
+    ISF_MyDocuments_fnGetDefaultColumn,
+    ISF_MyDocuments_fnGetDefaultColumnState,
+    ISF_MyDocuments_fnGetDetailsEx,
+    ISF_MyDocuments_fnGetDetailsOf,
+    ISF_MyDocuments_fnMapColumnToSCID
+};
+
+static inline IGenericSFImpl *impl_from_IPersistFolder2( IPersistFolder2 *iface )
+{
+    return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpPF2));
+}
+
+static HRESULT WINAPI
+ISF_MyDocuments_PersistFolder2_fnQueryInterface (IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
+{
+    IGenericSFImpl *This = impl_from_IPersistFolder2(iface);
+
+    TRACE ("(%p)\n", This);
+
+    return ISF_MyDocuments_fnQueryInterface ((IShellFolder2*)This, iid, ppvObj);
+}
+
+static ULONG WINAPI
+ISF_MyDocuments_PersistFolder2_fnAddRef (IPersistFolder2 * iface)
+{
+    IGenericSFImpl *This = impl_from_IPersistFolder2(iface);
+
+    TRACE ("(%p)->(count=%u)\n", This, This->ref);
+
+    return ISF_MyDocuments_fnAddRef((IShellFolder2*)This);
+}
+
+static ULONG WINAPI
+ISF_MyDocuments_PersistFolder2_fnRelease (IPersistFolder2 * iface)
+{
+    IGenericSFImpl *This = impl_from_IPersistFolder2(iface);
+
+    TRACE ("(%p)->(count=%u)\n", This, This->ref);
+
+    return ISF_MyDocuments_fnRelease ((IShellFolder2*)This);
+}
+
+static HRESULT WINAPI
+ISF_MyDocuments_PersistFolder2_fnGetClassID (IPersistFolder2 * iface, CLSID * lpClassId)
+{
+    IGenericSFImpl *This = impl_from_IPersistFolder2(iface);
+
+    static GUID const CLSID_MyDocuments = 
+    { 0x450d8fba, 0xad25, 0x11d0, {0x98,0xa8,0x08,0x00,0x36,0x1b,0x11,0x03} };
+
+    TRACE ("(%p)\n", This);
+
+    if (!lpClassId)
+        return E_POINTER;
+
+    memcpy(lpClassId, &CLSID_MyDocuments, sizeof(GUID));
+
+    return S_OK;
+}
+static HRESULT WINAPI
+ISF_MyDocuments_PersistFolder2_fnInitialize (IPersistFolder2 * iface, LPCITEMIDLIST pidl)
+{
+    IGenericSFImpl *This = impl_from_IPersistFolder2(iface);
+
+    TRACE ("(%p)->(%p)\n", This, pidl);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+ISF_MyDocuments_PersistFolder2_fnGetCurFolder (IPersistFolder2 * iface,
+                                       LPITEMIDLIST * pidl)
+{
+    IGenericSFImpl *This = impl_from_IPersistFolder2(iface);
+
+    TRACE ("(%p)->(%p)\n", This, pidl);
+
+    if (!pidl) return E_POINTER;
+    *pidl = ILClone (This->pidlRoot);
+    return S_OK;
+}
+
+static const IPersistFolder2Vtbl vt_FSFldr_PersistFolder2 =
+{
+    ISF_MyDocuments_PersistFolder2_fnQueryInterface,
+    ISF_MyDocuments_PersistFolder2_fnAddRef,
+    ISF_MyDocuments_PersistFolder2_fnRelease,
+    ISF_MyDocuments_PersistFolder2_fnGetClassID,
+    ISF_MyDocuments_PersistFolder2_fnInitialize,
+    ISF_MyDocuments_PersistFolder2_fnGetCurFolder,
+};
+
+
+/**************************************************************************
+ *    ISF_MyDocuments_Constructor
+ */
+HRESULT WINAPI ISF_MyDocuments_Constructor (
+                IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
+{
+    static IGenericSFImpl *cached_sf;
+    WCHAR szMyPath[MAX_PATH];
+
+    TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
+
+    if (!ppv)
+        return E_POINTER;
+    if (pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    if (!cached_sf)
+    {
+        IGenericSFImpl *sf;
+
+        if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
+            return E_UNEXPECTED;
+
+        sf = LocalAlloc( LMEM_ZEROINIT, sizeof (IGenericSFImpl) );
+        if (!sf)
+            return E_OUTOFMEMORY;
+
+        sf->ref = 1;
+        sf->lpVtbl = &vt_MCFldr_ShellFolder2;
+        sf->lpPF2 = &vt_FSFldr_PersistFolder2;
+        sf->pidlRoot = _ILCreateMyDocuments();    /* my qualified pidl */
+        sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
+        lstrcpyW( sf->sPathTarget, szMyPath );
+
+        if (InterlockedCompareExchangePointer((void *)&cached_sf, sf, NULL) != NULL)
+        {
+            /* some other thread already been here */
+            SHFree( sf->pidlRoot );
+            SHFree( sf->sPathTarget );
+            LocalFree( sf );
+        }
+    }
+
+    return IUnknown_QueryInterface( _IUnknown_(cached_sf), riid, ppv );
+}

Propchange: trunk/reactos/dll/win32/shell32/shlfldr_mydocuments.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list