[SHELL32]

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
This commit is contained in:
Pierre Schweitzer 2016-02-01 22:07:55 +00:00
parent ef3e0ddadc
commit 886fc1b808
3 changed files with 151 additions and 17 deletions

View 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)

View 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);
}
/**************************************************************************

View 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>