[SHELL32]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 1 Feb 2016 22:07:55 +0000 (22:07 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 1 Feb 2016 22:07:55 +0000 (22:07 +0000)
Time to (re)act!
Step 2/2: continue Giannis' UNC hack in Shell32:
- Implement the ILCreateFromNetworkPlaceW() helper, which is just Giannis' code to allow creating a hacky PIDL for enumeration.
- Implement the CNetFolderEnum class, which allows enumerating network places. So far, it's pretty basic (no tree structure) but, it does its job. It would be to improve
- Implement the CNetFolder::EnumObjects() function.

This commit, in itself, more or less obsoletes hackssign application. Indeed, now, you just need to go to your network places, to be able to browse your network shares (like VMware or VBox shares) provided you installed the VMware/VBox additions in your VM.
However, hackssign will remains in rosapps for now: we don't have any other way to assign a drive letter to a network place so far, and VMware doesn't provide such feature.
Furthermore, this is a big hack. And until we have a correct implementation, we can keep another hack along ;-).

Feel free to decently enjoy your network shares in ReactOS :-).

CORE-10032
ROSAPPS-303

svn path=/trunk/; revision=70671

reactos/dll/win32/shell32/CMakeLists.txt
reactos/dll/win32/shell32/folders/CNetFolder.cpp
reactos/dll/win32/shell32/precomp.h

index f555871..caa7d9c 100644 (file)
@@ -84,6 +84,6 @@ add_library(shell32 SHARED
 set_module_type(shell32 win32dll UNICODE)
 target_link_libraries(shell32 shellmenu shelldesktop atlnew wine uuid recyclebin)
 add_delay_importlibs(shell32 uxtheme ole32 userenv version fmifs)
-add_importlibs(shell32 advapi32 browseui gdi32 user32 powrprof comctl32 comdlg32 shdocvw shlwapi devmgr winspool winmm msvcrt kernel32 ntdll)
+add_importlibs(shell32 advapi32 browseui gdi32 user32 powrprof comctl32 comdlg32 shdocvw shlwapi devmgr winspool winmm msvcrt kernel32 ntdll mpr)
 add_pch(shell32 precomp.h SOURCE)
 add_cd_file(TARGET shell32 DESTINATION reactos/system32 FOR all)
index 29e8797..d5e445c 100644 (file)
@@ -27,10 +27,41 @@ WINE_DEFAULT_DEBUG_CHANNEL (shell);
 
 #define HACKY_UNC_PATHS
 
+#ifdef HACKY_UNC_PATHS
+LPITEMIDLIST ILCreateFromNetworkPlaceW(LPCWSTR lpNetworkPlace)
+{
+    int cbData = sizeof(WORD) + sizeof(WCHAR) * (wcslen(lpNetworkPlace)+1);
+    LPITEMIDLIST pidl = (LPITEMIDLIST)SHAlloc(cbData + sizeof(WORD));
+    if (!pidl)
+        return NULL;
+
+    pidl->mkid.cb = cbData;
+    wcscpy((WCHAR*)&pidl->mkid.abID[0], lpNetworkPlace);
+    *(WORD*)((char*)pidl + cbData) = 0;
+
+    return pidl;
+}
+#endif
+
 /***********************************************************************
 *   IShellFolder implementation
 */
 
+class CNetFolderEnum :
+    public CEnumIDListBase
+{
+    public:
+        CNetFolderEnum();
+        ~CNetFolderEnum();
+        HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags);
+        BOOL CreateMyCompEnumList(DWORD dwFlags);
+        BOOL EnumerateRec(LPNETRESOURCE lpNet);
+
+        BEGIN_COM_MAP(CNetFolderEnum)
+        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+        END_COM_MAP()
+};
+
 static shvheader NetworkPlacesSFHeader[] = {
     {IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
     {IDS_SHV_COLUMN13, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
@@ -45,6 +76,119 @@ static shvheader NetworkPlacesSFHeader[] = {
 
 #define NETWORKPLACESSHELLVIEWCOLUMNS 4
 
+CNetFolderEnum::CNetFolderEnum()
+{
+}
+
+CNetFolderEnum::~CNetFolderEnum()
+{
+}
+
+HRESULT WINAPI CNetFolderEnum::Initialize(HWND hwndOwner, DWORD dwFlags)
+{
+    if (CreateMyCompEnumList(dwFlags) == FALSE)
+        return E_FAIL;
+
+    return S_OK;
+}
+
+/**************************************************************************
+ *  CDrivesFolderEnum::CreateMyCompEnumList()
+ */
+
+BOOL CNetFolderEnum::EnumerateRec(LPNETRESOURCE lpNet)
+{
+    BOOL bRet = TRUE;
+    DWORD dRet;
+    HANDLE hEnum;
+    LPNETRESOURCE lpRes;
+    DWORD dSize = 0x1000;
+    DWORD dCount = -1;
+    LPNETRESOURCE lpCur;
+
+    dRet = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, lpNet, &hEnum);
+    if (dRet != WN_SUCCESS)
+    {
+        ERR("WNetOpenEnum() failed: %x\n", dRet);
+        return FALSE;
+    }
+
+    lpRes = (LPNETRESOURCE)CoTaskMemAlloc(dSize);
+    if (!lpRes)
+    {
+        ERR("CoTaskMemAlloc() failed\n");
+        WNetCloseEnum(hEnum);
+        return FALSE;
+    }
+
+    do
+    {
+        dSize = 0x1000;
+        dCount = -1;
+
+        memset(lpRes, 0, dSize);
+        dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
+        if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
+        {
+            lpCur = lpRes;
+            for (; dCount; dCount--)
+            {
+                TRACE("lpRemoteName: %S\n", lpCur->lpRemoteName);
+
+                if ((lpCur->dwUsage & RESOURCEUSAGE_CONTAINER) == RESOURCEUSAGE_CONTAINER)
+                {
+                    TRACE("Found provider: %S\n", lpCur->lpProvider);
+                    /* Sounds like a WTF hack.... Is Wine doing correct? */
+                    if (!wcscmp(lpCur->lpRemoteName, lpCur->lpProvider))
+                    {
+                        lpCur->lpRemoteName = NULL;
+                    }
+                    EnumerateRec(lpCur);
+                }
+                else
+                {
+                    LPITEMIDLIST pidl;
+
+#ifdef HACKY_UNC_PATHS
+                    pidl = ILCreateFromNetworkPlaceW(lpCur->lpRemoteName);
+#endif
+                    if (pidl != NULL)
+                        bRet = AddToEnumList(pidl);
+                    else
+                    {
+                        ERR("ILCreateFromPathW() failed\n");
+                        bRet = FALSE;
+                        break;
+                    }
+                }
+
+                lpCur++;
+            }
+        }
+    } while (dRet != WN_NO_MORE_ENTRIES);
+
+    WNetCloseEnum(hEnum);
+
+    TRACE("Done: %u\n", bRet);
+
+    return bRet;
+}
+
+BOOL CNetFolderEnum::CreateMyCompEnumList(DWORD dwFlags)
+{
+    BOOL bRet = TRUE;
+
+    TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
+
+    /* enumerate the folders */
+    if (dwFlags & SHCONTF_FOLDERS)
+    {
+        bRet = EnumerateRec(NULL);
+    }
+
+    return bRet;
+}
+
 CNetFolder::CNetFolder()
 {
     pidlRoot = NULL;
@@ -78,17 +222,13 @@ HRESULT WINAPI CNetFolder::ParseDisplayName(HWND hwndOwner, LPBC pbcReserved, LP
     DWORD attrs = GetFileAttributes(lpszDisplayName);
     if ((attrs & FILE_ATTRIBUTE_DIRECTORY))
     {
+        if (pchEaten)
+            *pchEaten = 0;        /* strange but like the original */
+
         /* YES WE CAN */
 
         /* Create our hacky pidl */
-        int cbData = sizeof(WORD) + sizeof(WCHAR) * (wcslen(lpszDisplayName)+1);
-        LPITEMIDLIST pidl = (LPITEMIDLIST)SHAlloc(cbData + sizeof(WORD));
-        if (!pidl)
-            return NULL;
-
-        pidl->mkid.cb = cbData;
-        wcscpy((WCHAR*)&pidl->mkid.abID[0], lpszDisplayName);
-        *(WORD*)((char*)pidl + cbData) = 0;
+        LPITEMIDLIST pidl = ILCreateFromNetworkPlaceW(lpszDisplayName);
 
         *ppidl = pidl;
         if (pdwAttributes)
@@ -115,14 +255,7 @@ HRESULT WINAPI CNetFolder::ParseDisplayName(HWND hwndOwner, LPBC pbcReserved, LP
 */
 HRESULT WINAPI CNetFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    TRACE("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this,
-          hwndOwner, dwFlags, ppEnumIDList);
-
-    *ppEnumIDList = NULL; //IEnumIDList_Constructor();
-
-    TRACE("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
-    return S_FALSE;
-    // return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY;
+    return ShellObjectCreatorInit<CNetFolderEnum>(hwndOwner, dwFlags, IID_IEnumIDList, ppEnumIDList);
 }
 
 /**************************************************************************
index 4969721..d24f83a 100644 (file)
@@ -29,6 +29,7 @@
 #include <atlcom.h>
 #include <atlwin.h>
 #include <powrprof.h>
+#include <winnetwk.h>
 
 #include <comctl32_undoc.h>
 #include <shlguid_undoc.h>