dplayx: Merge the IDirectPlay4_Close helper.
[wine] / dlls / shell32 / shfldr_mycomp.c
index 98b5d62..766e8d8 100644 (file)
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #include "config.h"
@@ -39,7 +39,6 @@
 #include "wingdi.h"
 #include "pidl.h"
 #include "shlguid.h"
-#include "enumidlist.h"
 #include "undocshell.h"
 #include "shell32_main.h"
 #include "shresdef.h"
@@ -55,51 +54,47 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);
 */
 
 typedef struct {
-    IShellFolder2Vtbl   *lpVtbl;
-    DWORD                ref;
-    IPersistFolder2Vtbl *lpVtblPersistFolder2;
+    IShellFolder2   IShellFolder2_iface;
+    IPersistFolder2 IPersistFolder2_iface;
+    LONG            ref;
 
     /* both paths are parsible from the desktop */
     LPITEMIDLIST pidlRoot;    /* absolute pidl */
-    int dwAttributes;        /* attributes returned by GetAttributesOf FIXME: use it */
-} IGenericSFImpl;
+} IMyComputerFolderImpl;
 
-static struct IShellFolder2Vtbl vt_ShellFolder2;
-static struct IPersistFolder2Vtbl vt_PersistFolder2;
+static const IShellFolder2Vtbl vt_ShellFolder2;
+static const IPersistFolder2Vtbl vt_PersistFolder2;
 
-#define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2)))
-#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);
+static inline IMyComputerFolderImpl *impl_from_IShellFolder2(IShellFolder2 *iface)
+{
+    return CONTAINING_RECORD(iface, IMyComputerFolderImpl, IShellFolder2_iface);
+}
 
-/*
-  converts This to an interface pointer
-*/
-#define _IUnknown_(This)    (IUnknown*)&(This->lpVtbl)
-#define _IShellFolder_(This)    (IShellFolder*)&(This->lpVtbl)
-#define _IShellFolder2_(This)    (IShellFolder2*)&(This->lpVtbl)
+static inline IMyComputerFolderImpl *impl_from_IPersistFolder2(IPersistFolder2 *iface)
+{
+    return CONTAINING_RECORD(iface, IMyComputerFolderImpl, IPersistFolder2_iface);
+}
 
-#define _IPersist_(This)    (IPersist*)&(This->lpVtblPersistFolder2)
-#define _IPersistFolder_(This)    (IPersistFolder*)&(This->lpVtblPersistFolder2)
-#define _IPersistFolder2_(This)    (IPersistFolder2*)&(This->lpVtblPersistFolder2)
 
 /***********************************************************************
 *   IShellFolder [MyComputer] implementation
 */
 
-static shvheader MyComputerSFHeader[] = {
+static const shvheader mycomputer_header[] = {
     {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
     {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
     {IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
     {IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
 };
 
-#define MYCOMPUTERSHELLVIEWCOLUMNS 4
+#define MYCOMPUTERSHELLVIEWCOLUMNS sizeof(mycomputer_header)/sizeof(shvheader)
 
 /**************************************************************************
 *    ISF_MyComputer_Constructor
 */
 HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
 {
-    IGenericSFImpl *sf;
+    IMyComputerFolderImpl *sf;
 
     TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
 
@@ -108,18 +103,18 @@ HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LP
     if (pUnkOuter)
         return CLASS_E_NOAGGREGATION;
 
-    sf = LocalAlloc (LMEM_ZEROINIT, sizeof (IGenericSFImpl));
+    sf = LocalAlloc (LMEM_ZEROINIT, sizeof (IMyComputerFolderImpl));
     if (!sf)
         return E_OUTOFMEMORY;
 
     sf->ref = 0;
-    sf->lpVtbl = &vt_ShellFolder2;
-    sf->lpVtblPersistFolder2 = &vt_PersistFolder2;
+    sf->IShellFolder2_iface.lpVtbl = &vt_ShellFolder2;
+    sf->IPersistFolder2_iface.lpVtbl = &vt_PersistFolder2;
     sf->pidlRoot = _ILCreateMyComputer ();    /* my qualified pidl */
 
-    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv)))
+    if (FAILED (IShellFolder2_QueryInterface (&sf->IShellFolder2_iface, riid, ppv)))
     {
-        IUnknown_Release (_IUnknown_ (sf));
+        IShellFolder2_Release (&sf->IShellFolder2_iface);
         return E_NOINTERFACE;
     }
 
@@ -135,7 +130,7 @@ HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LP
 static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 *iface,
                REFIID riid, LPVOID *ppvObj)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
     TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
 
@@ -151,7 +146,7 @@ static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 *iface,
              IsEqualIID (riid, &IID_IPersistFolder) ||
              IsEqualIID (riid, &IID_IPersistFolder2))
     {
-        *ppvObj = _IPersistFolder2_ (This);
+        *ppvObj = &This->IPersistFolder2_iface;
     }
 
     if (*ppvObj)
@@ -166,27 +161,26 @@ static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 *iface,
 
 static ULONG WINAPI ISF_MyComputer_fnAddRef (IShellFolder2 * iface)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     ULONG refCount = InterlockedIncrement(&This->ref);
 
-    TRACE ("(%p)->(count=%lu)\n", This, refCount - 1);
+    TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
 
     return refCount;
 }
 
 static ULONG WINAPI ISF_MyComputer_fnRelease (IShellFolder2 * iface)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     ULONG refCount = InterlockedDecrement(&This->ref);
 
-    TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
+    TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
 
     if (!refCount)
     {
         TRACE ("-- destroying IShellFolder(%p)\n", This);
-        if (This->pidlRoot)
-            SHFree (This->pidlRoot);
-        LocalFree ((HLOCAL) This);
+        SHFree (This->pidlRoot);
+        LocalFree (This);
     }
     return refCount;
 }
@@ -198,7 +192,7 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
                HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
                DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     HRESULT hr = E_INVALIDARG;
     LPCWSTR szNext = NULL;
     WCHAR szElement[MAX_PATH];
@@ -239,18 +233,56 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
     else
     {
         if (pdwAttributes && *pdwAttributes)
-            SHELL32_GetItemAttributes (_IShellFolder_ (This),
-                                       pidlTemp, pdwAttributes);
+            SHELL32_GetItemAttributes ((IShellFolder*)&This->IShellFolder2_iface, pidlTemp,
+                    pdwAttributes);
         hr = S_OK;
     }
 
     *ppidl = pidlTemp;
 
-    TRACE ("(%p)->(-- ret=0x%08lx)\n", This, hr);
+    TRACE ("(%p)->(-- ret=0x%08x)\n", This, hr);
 
     return hr;
 }
 
+/* retrieve a map of drives that should be displayed */
+static DWORD get_drive_map(void)
+{
+    static const WCHAR policiesW[] = {'S','o','f','t','w','a','r','e','\\',
+                                      'M','i','c','r','o','s','o','f','t','\\',
+                                      'W','i','n','d','o','w','s','\\',
+                                      'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                      'P','o','l','i','c','i','e','s','\\',
+                                      'E','x','p','l','o','r','e','r',0};
+    static const WCHAR nodrivesW[] = {'N','o','D','r','i','v','e','s',0};
+    static DWORD drive_mask, init_done;
+
+    if (!init_done)
+    {
+        DWORD type, size, data, mask = 0;
+        HKEY hkey;
+
+        if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, policiesW, &hkey ))
+        {
+            size = sizeof(data);
+            if (!RegQueryValueExW( hkey, nodrivesW, NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
+                mask |= data;
+            RegCloseKey( hkey );
+        }
+        if (!RegOpenKeyW( HKEY_CURRENT_USER, policiesW, &hkey ))
+        {
+            size = sizeof(data);
+            if (!RegQueryValueExW( hkey, nodrivesW, NULL, &type, (LPBYTE)&data, &size ) && type == REG_DWORD)
+                mask |= data;
+            RegCloseKey( hkey );
+        }
+        drive_mask = mask;
+        init_done = 1;
+    }
+
+    return GetLogicalDrives() & ~drive_mask;
+}
+
 /**************************************************************************
  *  CreateMyCompEnumList()
  */
@@ -260,18 +292,19 @@ static const WCHAR MyComputer_NameSpaceW[] = { 'S','O','F','T','W','A','R','E',
  'o','r','e','r','\\','M','y','C','o','m','p','u','t','e','r','\\','N','a','m',
  'e','s','p','a','c','e','\0' };
 
-static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
+static BOOL CreateMyCompEnumList(IEnumIDListImpl *list, DWORD dwFlags)
 {
     BOOL ret = TRUE;
 
-    TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
+    TRACE("(%p)->(flags=0x%08x)\n", list, dwFlags);
 
     /* enumerate the folders */
     if (dwFlags & SHCONTF_FOLDERS)
     {
         WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
-        DWORD dwDrivemap = GetLogicalDrives();
+        DWORD dwDrivemap = get_drive_map();
         HKEY hkey;
+        UINT i;
 
         while (ret && wszDriveName[0]<='Z')
         {
@@ -282,32 +315,34 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
         }
 
         TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list);
-        if (ret && !RegOpenKeyExW(HKEY_LOCAL_MACHINE, MyComputer_NameSpaceW,
-         0, KEY_READ, &hkey))
-        {
-            WCHAR iid[50];
-            int i=0;
-
-            while (ret)
+        for (i=0; i<2; i++) {
+            if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
+                                      MyComputer_NameSpaceW, 0, KEY_READ, &hkey))
             {
-                DWORD size;
-                LONG r;
+                WCHAR iid[50];
+                int i=0;
 
-                size = sizeof(iid) / sizeof(iid[0]);
-                r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
-                if (ERROR_SUCCESS == r)
+                while (ret)
                 {
-                    /* FIXME: shell extensions, shouldn't the type be
-                     * PT_SHELLEXT? */
-                    ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
-                    i++;
+                    DWORD size;
+                    LONG r;
+
+                    size = sizeof(iid) / sizeof(iid[0]);
+                    r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
+                    if (ERROR_SUCCESS == r)
+                    {
+                        /* FIXME: shell extensions, shouldn't the type be
+                         * PT_SHELLEXT? */
+                        ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
+                        i++;
+                    }
+                    else if (ERROR_NO_MORE_ITEMS == r)
+                        break;
+                    else
+                        ret = FALSE;
                 }
-                else if (ERROR_NO_MORE_ITEMS == r)
-                    break;
-                else
-                    ret = FALSE;
+                RegCloseKey(hkey);
             }
-            RegCloseKey(hkey);
         }
     }
     return ret;
@@ -319,18 +354,20 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects (IShellFolder2 *iface,
                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
+    IEnumIDListImpl *list;
 
-    TRACE("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This,
+    TRACE("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", This,
           hwndOwner, dwFlags, ppEnumIDList);
 
-    *ppEnumIDList = IEnumIDList_Constructor();
-    if (*ppEnumIDList)
-        CreateMyCompEnumList(*ppEnumIDList, dwFlags);
+    if (!(list = IEnumIDList_Constructor()))
+        return E_OUTOFMEMORY;
+    CreateMyCompEnumList(list, dwFlags);
+    *ppEnumIDList = &list->IEnumIDList_iface;
 
     TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
 
-    return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY;
+    return S_OK;
 }
 
 /**************************************************************************
@@ -339,7 +376,7 @@ static HRESULT WINAPI ISF_MyComputer_fnEnumObjects (IShellFolder2 *iface,
 static HRESULT WINAPI ISF_MyComputer_fnBindToObject (IShellFolder2 *iface,
                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
     TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", This,
           pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
@@ -353,7 +390,7 @@ static HRESULT WINAPI ISF_MyComputer_fnBindToObject (IShellFolder2 *iface,
 static HRESULT WINAPI ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
     FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
           pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
@@ -369,13 +406,13 @@ static HRESULT WINAPI ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
 static HRESULT WINAPI ISF_MyComputer_fnCompareIDs (IShellFolder2 *iface,
                LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
-    int nReturn;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
+    HRESULT hr;
 
     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;
+    hr = SHELL32_CompareIDs(&This->IShellFolder2_iface, lParam, pidl1, pidl2);
+    TRACE ("-- 0x%08x\n", hr);
+    return hr;
 }
 
 /**************************************************************************
@@ -384,7 +421,7 @@ static HRESULT WINAPI ISF_MyComputer_fnCompareIDs (IShellFolder2 *iface,
 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject (IShellFolder2 *iface,
                HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     LPSHELLVIEW pShellView;
     HRESULT hr = E_INVALIDARG;
 
@@ -425,10 +462,10 @@ static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject (IShellFolder2 *iface,
 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
                 UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
            This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
 
     if (!rgfInOut)
@@ -438,18 +475,28 @@ static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
 
     if (*rgfInOut == 0)
         *rgfInOut = ~0;
-
-    while (cidl > 0 && *apidl)
-    {
-        pdump (*apidl);
-        SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
-        apidl++;
-        cidl--;
+    
+    if(cidl == 0){
+        IShellFolder *psfParent = NULL;
+        LPCITEMIDLIST rpidl = NULL;
+
+        hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder, (LPVOID*)&psfParent, &rpidl);
+        if(SUCCEEDED(hr)) {
+            SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut);
+            IShellFolder_Release(psfParent);
+        }
+    } else {
+        while (cidl > 0 && *apidl) {
+            pdump (*apidl);
+            SHELL32_GetItemAttributes ((IShellFolder*)&This->IShellFolder2_iface, *apidl, rgfInOut);
+            apidl++;
+            cidl--;
+        }
     }
     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
     *rgfInOut &= ~SFGAO_VALIDATE;
 
-    TRACE ("-- result=0x%08lx\n", *rgfInOut);
+    TRACE ("-- result=0x%08x\n", *rgfInOut);
     return hr;
 }
 
@@ -469,7 +516,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
                 HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
                 UINT * prgfInOut, LPVOID * ppvOut)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
     LPITEMIDLIST pidl;
     IUnknown *pObj = NULL;
@@ -485,9 +532,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
 
     if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
     {
-        pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
-                                              This->pidlRoot, apidl, cidl);
-        hr = S_OK;
+        return ItemMenu_Constructor((IShellFolder*) iface, This->pidlRoot, apidl, cidl, riid, ppvOut);
     }
     else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
     {
@@ -511,7 +556,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
     }
     else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
     {
-        hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget,
+        hr = IShellFolder2_QueryInterface (iface, &IID_IDropTarget,
                                           (LPVOID *) &pObj);
     }
     else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
@@ -528,7 +573,7 @@ static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
         hr = E_OUTOFMEMORY;
 
     *ppvOut = pObj;
-    TRACE ("(%p)->hr=0x%08lx\n", This, hr);
+    TRACE ("(%p)->hr=0x%08x\n", This, hr);
     return hr;
 }
 
@@ -538,24 +583,29 @@ static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
                LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
-    char szPath[MAX_PATH];
+    LPWSTR pszPath;
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
+    TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet);
     pdump (pidl);
 
     if (!strRet)
         return E_INVALIDARG;
 
-    szPath[0] = 0x00;
+    pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
+    if (!pszPath)
+        return E_OUTOFMEMORY;
+
+    pszPath[0] = 0;
 
     if (!pidl->mkid.cb)
     {
         /* parsing name like ::{...} */
-        lstrcpyA (szPath, "::");
-        SHELL32_GUIDToStringA(&CLSID_MyComputer, &szPath[2]);
+        pszPath[0] = ':';
+        pszPath[1] = ':';
+        SHELL32_GUIDToStringW(&CLSID_MyComputer, &pszPath[2]);
     }
     else if (_ILIsPidlSimple(pidl))    
     {
@@ -607,73 +657,95 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
                          * Only the folder itself can know it
                          */
                         hr = SHELL32_GetDisplayNameOfChild (iface, pidl,
-                                                dwFlags, szPath, MAX_PATH);
+                                                dwFlags, pszPath, MAX_PATH);
                     }
                     else
                     {
-                        LPSTR p;
+                        LPWSTR p = pszPath;
 
                         /* parsing name like ::{...} */
-                        p = lstrcpyA(szPath, "::") + 2;
-                        p += SHELL32_GUIDToStringA(&CLSID_MyComputer, p);
-
-                        lstrcatA(p, "\\::");
+                        p[0] = ':';
+                        p[1] = ':';
+                        p += 2;
+                        p += SHELL32_GUIDToStringW(&CLSID_MyComputer, p);
+
+                        /* \:: */
+                        p[0] = '\\';
+                        p[1] = ':';
+                        p[2] = ':';
                         p += 3;
-                        SHELL32_GUIDToStringA(clsid, p);
+                        SHELL32_GUIDToStringW(clsid, p);
                     }
                 }
                 else
                 {
                     /* user friendly name */
-                    HCR_GetClassNameA (clsid, szPath, MAX_PATH);
+                    HCR_GetClassNameW (clsid, pszPath, MAX_PATH);
                 }
             }
             else
             {
                 /* append my own path */
-                _ILSimpleGetText (pidl, szPath, MAX_PATH);
+                _ILSimpleGetTextW (pidl, pszPath, MAX_PATH);
             }
         }
         else if (_ILIsDrive(pidl))
         {        
-            _ILSimpleGetText (pidl, szPath, MAX_PATH);    /* append my own path */
+            _ILSimpleGetTextW (pidl, pszPath, MAX_PATH);    /* append my own path */
 
             /* long view "lw_name (C:)" */
             if (!(dwFlags & SHGDN_FORPARSING))
             {
                 DWORD dwVolumeSerialNumber, dwMaximumComponetLength, dwFileSystemFlags;
-                char szDrive[18] = "";
+                WCHAR wszDrive[18] = {0};
+                static const WCHAR wszOpenBracket[] = {' ','(',0};
+                static const WCHAR wszCloseBracket[] = {')',0};
 
-                GetVolumeInformationA (szPath, szDrive, sizeof (szDrive) - 6,
+                GetVolumeInformationW (pszPath, wszDrive,
+                           sizeof(wszDrive)/sizeof(wszDrive[0]) - 6,
                            &dwVolumeSerialNumber,
                            &dwMaximumComponetLength, &dwFileSystemFlags, NULL, 0);
-                strcat (szDrive, " (");
-                strncat (szDrive, szPath, 2);
-                strcat (szDrive, ")");
-                strcpy (szPath, szDrive);
+                strcatW (wszDrive, wszOpenBracket);
+                lstrcpynW (wszDrive + strlenW(wszDrive), pszPath, 3);
+                strcatW (wszDrive, wszCloseBracket);
+                strcpyW (pszPath, wszDrive);
             }
         }
         else 
         {
             /* Neither a shell namespace extension nor a drive letter. */
             ERR("Wrong pidl type\n");
+            CoTaskMemFree(pszPath);
             return E_INVALIDARG;
         }
     }
     else
     {
         /* Complex pidl. Let the child folder do the work */
-        strRet->uType = STRRET_CSTR;
-        hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH);
+        hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, pszPath, MAX_PATH);
     }
 
     if (SUCCEEDED (hr))
     {
-        strRet->uType = STRRET_CSTR;
-        lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
+        /* 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)\n", This, szPath);
+    TRACE ("-- (%p)->(%s)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr));
     return hr;
 }
 
@@ -693,8 +765,8 @@ static HRESULT WINAPI ISF_MyComputer_fnSetNameOf (
                IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,
                LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
-    FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This,
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
+    FIXME ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", This,
            hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
     return E_FAIL;
 }
@@ -702,21 +774,21 @@ static HRESULT WINAPI ISF_MyComputer_fnSetNameOf (
 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID (
                IShellFolder2 * iface, GUID * pguid)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches (
                IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn (
                IShellFolder2 *iface, DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
     TRACE ("(%p)\n", This);
 
@@ -729,30 +801,34 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn (
 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState (
                IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
 
-    TRACE ("(%p)\n", This);
+    TRACE ("(%p)->(%d %p)\n", This, iColumn, pcsFlags);
 
     if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
         return E_INVALIDARG;
-    *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
+
+    *pcsFlags = mycomputer_header[iColumn].pcsFlags;
+
     return S_OK;
 }
 
 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx (IShellFolder2 * iface,
                LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
 
 /* FIXME: drive size >4GB is rolling over */
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface,
-               LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
+static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 *iface,
+               LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
-    HRESULT hr;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
+    char szPath[MAX_PATH];
+    ULARGE_INTEGER ulBytes;
+    HRESULT hr = S_OK;
 
     TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
 
@@ -760,25 +836,15 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface,
         return E_INVALIDARG;
 
     if (!pidl)
-    {
-        psd->fmt = MyComputerSFHeader[iColumn].fmt;
-        psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
-        psd->str.uType = STRRET_CSTR;
-        LoadStringA (shell32_hInstance, MyComputerSFHeader[iColumn].colnameid,
-                     psd->str.u.cStr, MAX_PATH);
-        return S_OK;
-    }
-    else
-    {
-        char szPath[MAX_PATH];
-        ULARGE_INTEGER ulBytes;
+        return SHELL32_GetColumnDetails(mycomputer_header, iColumn, psd);
 
-        psd->str.u.cStr[0] = 0x00;
-        psd->str.uType = STRRET_CSTR;
-        switch (iColumn)
-        {
+    psd->str.u.cStr[0] = 0;
+    psd->str.uType = STRRET_CSTR;
+
+    switch (iColumn)
+    {
         case 0:        /* name */
-            hr = IShellFolder_GetDisplayNameOf (iface, pidl,
+            hr = IShellFolder2_GetDisplayNameOf (iface, pidl,
                        SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
             break;
         case 1:        /* type */
@@ -800,8 +866,6 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface,
                 StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
             }
             break;
-        }
-        hr = S_OK;
     }
 
     return hr;
@@ -810,12 +874,12 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface,
 static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (
                IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
 {
-    IGenericSFImpl *This = (IGenericSFImpl *)iface;
+    IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
 
-static IShellFolder2Vtbl vt_ShellFolder2 =
+static const IShellFolder2Vtbl vt_ShellFolder2 =
 {
     ISF_MyComputer_fnQueryInterface,
     ISF_MyComputer_fnAddRef,
@@ -846,11 +910,9 @@ static IShellFolder2Vtbl vt_ShellFolder2 =
 static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (
                IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
 {
-    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
-
+    IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
     TRACE ("(%p)\n", This);
-
-    return IUnknown_QueryInterface (_IUnknown_ (This), iid, ppvObj);
+    return IShellFolder2_QueryInterface (&This->IShellFolder2_iface, iid, ppvObj);
 }
 
 /************************************************************************
@@ -858,11 +920,9 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (
  */
 static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
 {
-    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
-
-    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
-
-    return IUnknown_AddRef (_IUnknown_ (This));
+    IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
+    TRACE ("(%p)->(count=%u)\n", This, This->ref);
+    return IShellFolder2_AddRef (&This->IShellFolder2_iface);
 }
 
 /************************************************************************
@@ -870,11 +930,9 @@ static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
  */
 static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
 {
-    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
-
-    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
-
-    return IUnknown_Release (_IUnknown_ (This));
+    IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
+    TRACE ("(%p)->(count=%u)\n", This, This->ref);
+    return IShellFolder2_Release (&This->IShellFolder2_iface);
 }
 
 /************************************************************************
@@ -883,7 +941,7 @@ static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
 static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (
                IPersistFolder2 * iface, CLSID * lpClassId)
 {
-    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+    IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
 
     TRACE ("(%p)\n", This);
 
@@ -902,7 +960,7 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (
 static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (
                IPersistFolder2 * iface, LPCITEMIDLIST pidl)
 {
-    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+    IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
     TRACE ("(%p)->(%p)\n", This, pidl);
     return E_NOTIMPL;
 }
@@ -913,7 +971,7 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (
 static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (
                IPersistFolder2 * iface, LPITEMIDLIST * pidl)
 {
-    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+    IMyComputerFolderImpl *This = impl_from_IPersistFolder2(iface);
 
     TRACE ("(%p)->(%p)\n", This, pidl);
 
@@ -923,7 +981,7 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (
     return S_OK;
 }
 
-static IPersistFolder2Vtbl vt_PersistFolder2 =
+static const IPersistFolder2Vtbl vt_PersistFolder2 =
 {
     IMCFldr_PersistFolder2_QueryInterface,
     IMCFldr_PersistFolder2_AddRef,