[NTOBJSHEX]

* Make the shell view default to details mode.
* Some cleanups.

svn path=/trunk/; revision=66603
This commit is contained in:
David Quintana 2015-03-08 02:05:24 +00:00
parent b0c6956a17
commit 9c9b3171f8
5 changed files with 89 additions and 129 deletions

View file

@ -50,13 +50,13 @@ class CMergedFolder :
public IShellFolder2,
public IPersistFolder2,
public IAugmentedShellFolder3 // -- undocumented
//public IShellService, // -- undocumented
//public IShellService, // DEPRECATED IE4 interface: https://msdn.microsoft.com/en-us/library/windows/desktop/bb774870%28v=vs.85%29.aspx
//public ITranslateShellChangeNotify,// -- undocumented
//public IStorage,
//public IPersistPropertyBag,
//public IShellIconOverlay, // -- undocumented
//public ICompositeFolder, // -- undocumented
//public IItemNameLimits, // -- undocumented
//public IItemNameLimits, // https://msdn.microsoft.com/en-us/library/windows/desktop/bb761776%28v=vs.85%29.aspx
{
private:
CComPtr<IShellFolder> m_UserLocal;

View file

@ -41,6 +41,12 @@ class CNtObjectFolderContextMenu :
PCITEMID_CHILD m_pcidlChild;
UINT m_idFirst;
enum ItemOffsets
{
ITEM_Open = 0,
ITEM_OpenNewWindow
};
public:
CNtObjectFolderContextMenu() :
m_pcidlFolder(NULL),
@ -70,24 +76,24 @@ public:
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
MENUITEMINFOW mii;
m_idFirst = idCmdFirst;
const NtPidlEntry * entry = (NtPidlEntry *) m_pcidlChild;
static WCHAR open [] = L"Open";
static WCHAR opennewwindow [] = L"Open in new window";
if ((entry->objectType == DIRECTORY_OBJECT) ||
(entry->objectType == SYMBOLICLINK_OBJECT) ||
(entry->objectType == KEY_OBJECT))
{
MENUITEMINFOW mii;
WCHAR open [] = L"Open";
WCHAR opennewwindow [] = L"Open in new window";
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
mii.fType = MFT_STRING;
mii.wID = idCmdFirst++;
mii.wID = (idCmdFirst = m_idFirst + ITEM_Open);
mii.dwTypeData = open;
mii.cch = _countof(open);
mii.fState = MFS_ENABLED | MFS_DEFAULT;
@ -100,7 +106,7 @@ public:
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
mii.fType = MFT_STRING;
mii.wID = idCmdFirst++;
mii.wID = (idCmdFirst = m_idFirst + ITEM_OpenNewWindow);
mii.dwTypeData = opennewwindow;
mii.cch = _countof(opennewwindow);
mii.fState = MFS_ENABLED;
@ -114,10 +120,10 @@ public:
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
if (LOWORD(lpici->lpVerb) == m_idFirst || !lpici->lpVerb)
{
LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
if (LOWORD(lpici->lpVerb) == (m_idFirst + ITEM_Open) || !lpici->lpVerb)
{
SHELLEXECUTEINFO sei = { 0 };
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
@ -132,10 +138,8 @@ public:
return bRes ? S_OK : HRESULT_FROM_WIN32(GetLastError());
}
else if (LOWORD(lpici->lpVerb) == (m_idFirst + 1))
else if (LOWORD(lpici->lpVerb) == (m_idFirst + ITEM_OpenNewWindow))
{
LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
SHELLEXECUTEINFO sei = { 0 };
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
@ -467,7 +471,7 @@ public:
if (ord < 0)
return MAKE_HRESULT(0, 0, (USHORT) -1);
ord = StrCmpNW(second->entryName, first->entryName, first->entryNameLength/sizeof(WCHAR));
ord = StrCmpNW(second->entryName, first->entryName, first->entryNameLength / sizeof(WCHAR));
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
@ -722,7 +726,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
if (info->objectType == SYMBOLICLINK_OBJECT)
{
NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (symlink->targetNameLength > 0)
{
@ -806,7 +810,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::CreateViewObject(
sfv.cbSize = sizeof(sfv);
sfv.pshf = this;
sfv.psvOuter = NULL;
sfv.psfvcb = NULL;
sfv.psfvcb = this;
return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut);
}
@ -954,26 +958,6 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::Initialize(LPCITEMIDLIST pidl)
PCWSTR ntPath = L"\\";
#if 0
WCHAR debugTemp[MAX_PATH];
GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
DbgPrint("INITIALIZE CRegistryFolder PIDL PATH: %S (ntPath: %S)\n", debugTemp, ntPath);
if (ntPath[wcslen(ntPath)-1] == L'\\' && debugTemp[wcslen(debugTemp) - 1] != L'\\')
wcscat(debugTemp, L"\\");
PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
PCWSTR nextTemp = findTemp + wcslen(guidTemp);
if (wcscmp(nextTemp, ntPath))
{
DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
return E_FAIL;
}
#endif
if (!m_PidlManager)
{
m_PidlManager = new CNtObjectPidlManager();
@ -989,27 +973,6 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::Initialize(LPCITEMIDLIST pidl, PCWSTR
{
TRACE("INITIALIZE %p CNtObjectFolder with ntPath %S\n", this, ntPath);
#if 0
m_shellPidl = ILClone(pidl);
WCHAR debugTemp[MAX_PATH];
GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
DbgPrint("INITIALIZE CNtObjectFolder PIDL PATH: %S (ntPath: %S)\n", debugTemp, ntPath);
if (ntPath[wcslen(ntPath) - 1] == L'\\' && debugTemp[wcslen(debugTemp) - 1] != L'\\')
wcscat(debugTemp, L"\\");
PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
PCWSTR nextTemp = findTemp + wcslen(guidTemp);
if (wcscmp(nextTemp, ntPath))
{
DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
return E_FAIL;
}
#endif
if (!m_PidlManager)
m_PidlManager = new CNtObjectPidlManager();
@ -1104,7 +1067,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsEx(
{
if (info->objectType < 0)
{
NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (td->typeNameLength > 0)
{
@ -1138,7 +1101,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsEx(
{
if (info->objectType == SYMBOLICLINK_OBJECT)
{
NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (symlink->targetNameLength > 0)
{
@ -1183,7 +1146,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
if (info->objectType < 0)
{
NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (td->typeNameLength > 0)
MakeStrRetFromString(td->typeName, td->typeNameLength, &(psd->str));
@ -1219,7 +1182,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
if (info->objectType == SYMBOLICLINK_OBJECT)
{
NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (symlink->targetNameLength > 0)
{
@ -1296,3 +1259,17 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::MapColumnToSCID(
}
return E_INVALIDARG;
}
HRESULT STDMETHODCALLTYPE CNtObjectFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case SFVM_DEFVIEWMODE:
{
FOLDERVIEWMODE* pViewMode = (FOLDERVIEWMODE*) lParam;
*pViewMode = FVM_DETAILS;
return S_OK;
}
}
return E_NOTIMPL;
}

View file

@ -15,7 +15,8 @@ class CNtObjectFolder :
public CComCoClass<CNtObjectFolder, &CLSID_NtObjectFolder>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder2
public IPersistFolder2,
public IShellFolderViewCB
{
CNtObjectPidlManager * m_PidlManager;
@ -130,6 +131,9 @@ public:
// IPersistFolder2
virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl);
// IShellFolderViewCB
virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
// Internal
HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl, PCWSTR ntPath);
@ -143,6 +147,7 @@ public:
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
END_COM_MAP()
};

View file

@ -40,6 +40,12 @@ class CRegistryFolderContextMenu :
PCITEMID_CHILD m_pcidlChild;
UINT m_idFirst;
enum ItemOffsets
{
ITEM_Open = 0,
ITEM_OpenNewWindow
};
public:
CRegistryFolderContextMenu() :
m_pcidlFolder(NULL),
@ -69,22 +75,22 @@ public:
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
MENUITEMINFOW mii;
m_idFirst = idCmdFirst;
const RegPidlEntry * entry = (RegPidlEntry *) m_pcidlChild;
static WCHAR open [] = L"Open";
static WCHAR opennewwindow [] = L"Open in new window";
if (entry->entryType == REG_ENTRY_KEY)
{
MENUITEMINFOW mii;
WCHAR open [] = L"Open";
WCHAR opennewwindow [] = L"Open in new window";
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
mii.fType = MFT_STRING;
mii.wID = idCmdFirst++;
mii.wID = (idCmdFirst = m_idFirst + ITEM_Open);
mii.dwTypeData = open;
mii.cch = _countof(open);
mii.fState = MFS_ENABLED | MFS_DEFAULT;
@ -97,7 +103,7 @@ public:
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
mii.fType = MFT_STRING;
mii.wID = idCmdFirst++;
mii.wID = (idCmdFirst = m_idFirst + ITEM_OpenNewWindow);
mii.dwTypeData = opennewwindow;
mii.cch = _countof(opennewwindow);
mii.fState = MFS_ENABLED;
@ -111,10 +117,10 @@ public:
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
if (LOWORD(lpici->lpVerb) == m_idFirst || !lpici->lpVerb)
{
LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
if (LOWORD(lpici->lpVerb) == (m_idFirst + ITEM_Open) || !lpici->lpVerb)
{
SHELLEXECUTEINFO sei = { 0 };
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
@ -129,10 +135,8 @@ public:
return bRes ? S_OK : HRESULT_FROM_WIN32(GetLastError());
}
else if (LOWORD(lpici->lpVerb) == (m_idFirst + 1))
else if (LOWORD(lpici->lpVerb) == (m_idFirst + ITEM_OpenNewWindow))
{
LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
SHELLEXECUTEINFO sei = { 0 };
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
@ -223,7 +227,7 @@ public:
return E_INVALIDARG;
UINT flags = 0;
switch (entry->entryType)
{
case REG_ENTRY_KEY:
@ -453,7 +457,7 @@ public:
if (ord < 0)
return MAKE_HRESULT(0, 0, (USHORT) -1);
ord = StrCmpNW(second->entryName, first->entryName, first->entryNameLength/sizeof(WCHAR));
ord = StrCmpNW(second->entryName, first->entryName, first->entryNameLength / sizeof(WCHAR));
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
@ -495,7 +499,7 @@ public:
HRESULT FormatContentsForDisplay(RegPidlEntry * info, PCWSTR * strContents)
{
PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (info->contentsLength > 0)
{
@ -553,7 +557,7 @@ public:
else
{
PCWSTR strEmpty = L"(Empty)";
DWORD bufferLength = (wcslen(strEmpty)+1) * sizeof(WCHAR);
DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
StringCbCopyW(strValue, bufferLength, strEmpty);
*strContents = strValue;
@ -755,11 +759,6 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
if (FAILED_UNEXPECTEDLY(hr))
return hr;
#if 0
if (!(info->objectInformation.GrantedAccess & (STANDARD_RIGHTS_READ | FILE_LIST_DIRECTORY)))
return E_ACCESSDENIED;
#endif
WCHAR path[MAX_PATH];
StringCbCopyW(path, _countof(path), m_NtPath);
@ -819,7 +818,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::CreateViewObject(
sfv.cbSize = sizeof(sfv);
sfv.pshf = this;
sfv.psvOuter = NULL;
sfv.psfvcb = NULL;
sfv.psfvcb = this;
return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut);
}
@ -967,26 +966,6 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl)
PCWSTR ntPath = L"\\REGISTRY";
#if 0
WCHAR debugTemp[MAX_PATH];
GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
DbgPrint("INITIALIZE CRegistryFolder PIDL PATH: %S (ntPath: %S)\n", debugTemp, ntPath);
if (ntPath[wcslen(ntPath) - 1] == L'\\' && debugTemp[wcslen(debugTemp) - 1] != L'\\')
wcscat(debugTemp, L"\\");
PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
PCWSTR nextTemp = findTemp + wcslen(guidTemp);
if (wcscmp(nextTemp, ntPath))
{
DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
return E_FAIL;
}
#endif
if (!m_PidlManager)
{
m_PidlManager = new CRegistryPidlManager();
@ -1002,26 +981,6 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl, PCWSTR
{
m_shellPidl = ILClone(pidl);
#if 0
WCHAR debugTemp[MAX_PATH];
GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
DbgPrint("INITIALIZE CRegistryFolder PIDL PATH: %S (ntPath: %S)\n", debugTemp, ntPath);
if (ntPath[wcslen(ntPath) - 1] == L'\\' && debugTemp[wcslen(debugTemp) - 1] != L'\\')
wcscat(debugTemp, L"\\");
PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
PCWSTR nextTemp = findTemp + wcslen(guidTemp);
if (wcscmp(nextTemp, ntPath))
{
DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
return E_FAIL;
}
#endif
if (!m_PidlManager)
m_PidlManager = new CRegistryPidlManager();
@ -1129,7 +1088,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
hr = MakeVariantString(pv, strValueContents);
CoTaskMemFree((PVOID)strValueContents);
CoTaskMemFree((PVOID) strValueContents);
return hr;
@ -1246,3 +1205,17 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::MapColumnToSCID(
}
return E_INVALIDARG;
}
HRESULT STDMETHODCALLTYPE CRegistryFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case SFVM_DEFVIEWMODE:
{
FOLDERVIEWMODE* pViewMode = (FOLDERVIEWMODE*) lParam;
*pViewMode = FVM_DETAILS;
return S_OK;
}
}
return E_NOTIMPL;
}

View file

@ -16,7 +16,8 @@ class CRegistryFolder :
public CComCoClass<CRegistryFolder, &CLSID_RegistryFolder>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder2
public IPersistFolder2,
public IShellFolderViewCB
{
CRegistryPidlManager * m_PidlManager;
@ -131,6 +132,9 @@ public:
// IPersistFolder2
virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl);
// IShellFolderViewCB
virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
// Internal
HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl, PCWSTR ntPath);
@ -144,6 +148,7 @@ public:
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
END_COM_MAP()
};