mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[NETSHELL][SHELL32] Make NetShell PIDL format more Windows compatible (#7183)
- The PIDL format needs to be Windows compatible so that wlanwiz can get the connection GUID. - SHELL32::ILIsEqual cannot deem PIDL formats it does not understand as invalid. - DefView must ask the folder when comparing PIDLs.
This commit is contained in:
parent
5d96ba9217
commit
ea60890961
7 changed files with 144 additions and 26 deletions
|
@ -9,9 +9,13 @@
|
|||
|
||||
PNETCONIDSTRUCT ILGetConnData(PCITEMID_CHILD pidl)
|
||||
{
|
||||
if (!pidl || !pidl->mkid.cb || pidl->mkid.abID[0] != 0x99)
|
||||
return NULL;
|
||||
return (PNETCONIDSTRUCT)(&pidl->mkid.abID[0]);
|
||||
if (pidl && pidl->mkid.cb >= 2 + sizeof(NETCONIDSTRUCT))
|
||||
{
|
||||
PNETCONIDSTRUCT pData = (PNETCONIDSTRUCT)pidl->mkid.abID;
|
||||
if (pData->Signature == NETCONIDSTRUCT_SIG)
|
||||
return pData;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PWCHAR ILGetConnName(PCITEMID_CHILD pidl)
|
||||
|
@ -48,17 +52,21 @@ PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem)
|
|||
|
||||
/* Allocate enough memory for the trailing id which will indicate that this is a simple id */
|
||||
pidl = static_cast<LPITEMIDLIST>(SHAlloc(size + sizeof(SHITEMID)));
|
||||
if (!pidl)
|
||||
goto end;
|
||||
pidl->mkid.cb = (WORD)size;
|
||||
pidl->mkid.abID[0] = 0x99;
|
||||
((PNETCONIDSTRUCT)(pidl->mkid.abID))->Signature = NETCONIDSTRUCT_SIG;
|
||||
|
||||
/* Copy the connection properties */
|
||||
pnetid = ILGetConnData(pidl);
|
||||
memset(pnetid->Unknown, 0, sizeof(pnetid->Unknown));
|
||||
pnetid->clsidThisObject = pProperties->clsidThisObject;
|
||||
pnetid->guidId = pProperties->guidId;
|
||||
pnetid->Status = pProperties->Status;
|
||||
pnetid->MediaType = pProperties->MediaType;
|
||||
pnetid->dwCharacter = pProperties->dwCharacter;
|
||||
pnetid->uNameOffset = sizeof(NETCONIDSTRUCT);
|
||||
pnetid->uDeviceNameOffset = pnetid->uNameOffset + (wcslen(pProperties->pszwName) + 1) * sizeof(WCHAR);
|
||||
pnetid->uDeviceNameOffset = ULONG(pnetid->uNameOffset + (wcslen(pProperties->pszwName) + 1) * sizeof(WCHAR));
|
||||
|
||||
pwchName = ILGetConnName(pidl);
|
||||
wcscpy(pwchName, pProperties->pszwName);
|
||||
|
@ -68,7 +76,7 @@ PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem)
|
|||
|
||||
/* Set the trailing id to null */
|
||||
memset((void*)((ULONG_PTR)pidl + size), 0, sizeof(SHITEMID));
|
||||
|
||||
end:
|
||||
NcFreeNetconProperties(pProperties);
|
||||
|
||||
return pidl;
|
||||
|
|
|
@ -55,16 +55,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
|||
extern HINSTANCE netshell_hInstance;
|
||||
|
||||
/* enumlist.c */
|
||||
#include <pshpack1.h>
|
||||
#define NETCONIDSTRUCT_SIG 0x4EFF
|
||||
typedef struct tagNETCONIDSTRUCT
|
||||
{
|
||||
BYTE type;
|
||||
WORD Signature;
|
||||
BYTE Unknown[8];
|
||||
CLSID clsidThisObject;
|
||||
GUID guidId;
|
||||
NETCON_STATUS Status;
|
||||
NETCON_MEDIATYPE MediaType;
|
||||
DWORD dwCharacter;
|
||||
ULONG_PTR uNameOffset;
|
||||
ULONG_PTR uDeviceNameOffset;
|
||||
NETCON_MEDIATYPE MediaType;
|
||||
NETCON_STATUS Status;
|
||||
ULONG uNameOffset;
|
||||
ULONG uDeviceNameOffset;
|
||||
} NETCONIDSTRUCT, *PNETCONIDSTRUCT;
|
||||
#include <poppack.h>
|
||||
|
||||
C_ASSERT(2 + FIELD_OFFSET(NETCONIDSTRUCT, clsidThisObject) == 2 + (2 + 8));
|
||||
C_ASSERT(2 + FIELD_OFFSET(NETCONIDSTRUCT, guidId) == 2 + (2 + 8 + 16));
|
||||
C_ASSERT(2 + FIELD_OFFSET(NETCONIDSTRUCT, dwCharacter) == 2 + (2 + 8 + 32));
|
||||
C_ASSERT(2 + FIELD_OFFSET(NETCONIDSTRUCT, MediaType) == 2 + (2 + 8 + 36));
|
||||
|
||||
PNETCONIDSTRUCT ILGetConnData(PCITEMID_CHILD pidl);
|
||||
PWCHAR ILGetConnName(PCITEMID_CHILD pidl);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <shellfolderutils.h>
|
||||
|
||||
#define MAX_PROPERTY_SHEET_PAGE (10)
|
||||
|
||||
|
@ -99,11 +100,26 @@ HRESULT WINAPI CNetworkConnections::BindToStorage(
|
|||
/**************************************************************************
|
||||
* ISF_NetConnect_fnCompareIDs
|
||||
*/
|
||||
|
||||
HRESULT WINAPI CNetworkConnections::CompareIDs(
|
||||
LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
const UINT colcount = NETCONNECTSHELLVIEWCOLUMNS;
|
||||
|
||||
if (ILGetNext(pidl1) || ILGetNext(pidl2))
|
||||
return E_NOTIMPL; // FIXME: Can the connection folder have subfolders?
|
||||
|
||||
if (lParam & SHCIDS_CANONICALONLY)
|
||||
{
|
||||
PNETCONIDSTRUCT p1 = ILGetConnData(pidl1);
|
||||
PNETCONIDSTRUCT p2 = ILGetConnData(pidl2);
|
||||
if (p1 && p2)
|
||||
{
|
||||
int res = memcmp(&p1->guidId, &p2->guidId, sizeof(GUID));
|
||||
return MAKE_COMPARE_HRESULT(res);
|
||||
}
|
||||
}
|
||||
IShellFolder2 *psf = static_cast<IShellFolder2*>(this);
|
||||
return ShellFolderImpl_CompareItemIDs<colcount, -1>(psf, lParam, (PCUITEMID_CHILD)pidl1, (PCUITEMID_CHILD)pidl2);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -140,6 +156,7 @@ HRESULT WINAPI CNetworkConnections::GetAttributesOf(
|
|||
UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut)
|
||||
{
|
||||
//IGenericSFImpl *This = (IGenericSFImpl *)iface;
|
||||
// FIXME: Why are these reporting SFGAO_FILESYSTEM and SFGAO_FILESYSANCESTOR?
|
||||
HRESULT hr = S_OK;
|
||||
static const DWORD dwNetConnectAttributes = SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
|
||||
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
|
||||
|
@ -156,6 +173,9 @@ HRESULT WINAPI CNetworkConnections::GetAttributesOf(
|
|||
if (*rgfInOut == 0)
|
||||
*rgfInOut = ~0;
|
||||
|
||||
if (cidl > 1)
|
||||
*rgfInOut &= ~SFGAO_HASPROPSHEET;
|
||||
|
||||
if (cidl == 0)
|
||||
{
|
||||
*rgfInOut = dwNetConnectAttributes;
|
||||
|
@ -610,20 +630,23 @@ ShowNetConnectionProperties(
|
|||
*/
|
||||
HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
|
||||
{
|
||||
UINT CmdId;
|
||||
UINT CmdId = LOWORD(lpcmi->lpVerb) + IDS_NET_ACTIVATE;
|
||||
|
||||
/* We should get this when F2 is pressed in explorer */
|
||||
if (HIWORD(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "rename"))
|
||||
lpcmi->lpVerb = MAKEINTRESOURCEA(IDS_NET_RENAME);
|
||||
|
||||
if (HIWORD(lpcmi->lpVerb) || LOWORD(lpcmi->lpVerb) > 7)
|
||||
if (!IS_INTRESOURCE(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "rename"))
|
||||
{
|
||||
CmdId = IDS_NET_RENAME;
|
||||
}
|
||||
else if (!IS_INTRESOURCE(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "properties"))
|
||||
{
|
||||
CmdId = IDS_NET_PROPERTIES;
|
||||
}
|
||||
else if (!IS_INTRESOURCE(lpcmi->lpVerb) || LOWORD(lpcmi->lpVerb) > 7)
|
||||
{
|
||||
FIXME("Got invalid command\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
CmdId = LOWORD(lpcmi->lpVerb) + IDS_NET_ACTIVATE;
|
||||
|
||||
switch(CmdId)
|
||||
{
|
||||
case IDS_NET_RENAME:
|
||||
|
|
|
@ -1290,15 +1290,29 @@ PCUITEMID_CHILD CDefView::_PidlByItem(LVITEM& lvItem)
|
|||
|
||||
int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl)
|
||||
{
|
||||
ASSERT(m_ListView);
|
||||
ASSERT(m_ListView && m_pSFParent);
|
||||
|
||||
int cItems = m_ListView.GetItemCount();
|
||||
|
||||
for (int i = 0; i<cItems; i++)
|
||||
LPARAM lParam = m_pSF2Parent ? SHCIDS_CANONICALONLY : 0;
|
||||
for (int i = 0; i < cItems; i++)
|
||||
{
|
||||
PCUITEMID_CHILD currentpidl = _PidlByItem(i);
|
||||
if (ILIsEqual(pidl, currentpidl))
|
||||
return i;
|
||||
HRESULT hr = m_pSFParent->CompareIDs(lParam, pidl, currentpidl);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (hr == S_EQUAL)
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < cItems; i++)
|
||||
{
|
||||
currentpidl = _PidlByItem(i);
|
||||
if (ILIsEqual(pidl, currentpidl))
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -379,7 +379,6 @@ BOOL pcheck( LPCITEMIDLIST pidl )
|
|||
case PT_YAGUID:
|
||||
case PT_IESPECIAL2:
|
||||
case PT_SHARE:
|
||||
case 0x99: /* Network Connection pidl type */
|
||||
break;
|
||||
default:
|
||||
ERR("unknown IDLIST %p [%p] size=%u type=%x\n",
|
||||
|
|
|
@ -557,7 +557,13 @@ BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
|
|||
* so we can only check here
|
||||
*/
|
||||
if (!pcheck(pidl1) || !pcheck (pidl2))
|
||||
#ifdef __REACTOS__
|
||||
{
|
||||
/* We don't understand the PIDL content but that does not mean it's invalid */
|
||||
}
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
pdump (pidl1);
|
||||
pdump (pidl2);
|
||||
|
|
58
sdk/include/reactos/shellfolderutils.h
Normal file
58
sdk/include/reactos/shellfolderutils.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
|
||||
* PURPOSE: Utility functions for IShellFolder implementations
|
||||
* COPYRIGHT: Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shellutils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
template <BOOL LOGICALCMP = TRUE>
|
||||
static HRESULT ShellFolderImpl_CompareItemColumn(IShellFolder2 *psf, UINT column, PCUITEMID_CHILD pidl1, PCUITEMID_CHILD pidl2)
|
||||
{
|
||||
SHELLDETAILS details1, details2;
|
||||
LPWSTR str1, str2;
|
||||
HRESULT hr;
|
||||
if (SUCCEEDED(hr = psf->GetDetailsOf(pidl1, column, &details1)) &&
|
||||
SUCCEEDED(hr = StrRetToStrW(&details1.str, pidl1, &str1)))
|
||||
{
|
||||
if (SUCCEEDED(hr = psf->GetDetailsOf(pidl2, column, &details2)) &&
|
||||
SUCCEEDED(hr = StrRetToStrW(&details2.str, pidl2, &str2)))
|
||||
{
|
||||
int res = LOGICALCMP ? StrCmpLogicalW(str1, str2) : lstrcmpiW(str1, str2);
|
||||
hr = MAKE_COMPARE_HRESULT(res);
|
||||
SHFree(str2);
|
||||
}
|
||||
SHFree(str1);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
template <UINT COLCOUNT, int CANONICAL, BOOL LOGICALCMP = TRUE>
|
||||
static HRESULT ShellFolderImpl_CompareItemIDs(IShellFolder2 *psf, LPARAM lParam, PCUITEMID_CHILD pidl1, PCUITEMID_CHILD pidl2)
|
||||
{
|
||||
HRESULT hr;
|
||||
if (CANONICAL >= 0 && (lParam & SHCIDS_CANONICALONLY))
|
||||
{
|
||||
hr = ShellFolderImpl_CompareItemColumn<LOGICALCMP>(psf, CANONICAL, pidl1, pidl2);
|
||||
if (hr == S_EQUAL || !(lParam & SHCIDS_ALLFIELDS) || FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
if (lParam & SHCIDS_ALLFIELDS)
|
||||
{
|
||||
for (UINT i = 0; i < COLCOUNT; ++i)
|
||||
{
|
||||
hr = ShellFolderImpl_CompareItemColumn<LOGICALCMP>(psf, i, pidl1, pidl2);
|
||||
if (hr && SUCCEEDED(hr)) // Only stop if we successfully found a difference
|
||||
break;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
const UINT column = (UINT)(lParam & SHCIDS_COLUMNMASK);
|
||||
return ShellFolderImpl_CompareItemColumn<LOGICALCMP>(psf, column, pidl1, pidl2);
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
Loading…
Reference in a new issue