mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 07:41:51 +00:00
[NTOBJSHEX] Formatting only
This commit is contained in:
parent
4c25af5bd4
commit
ba03ffd645
9 changed files with 404 additions and 390 deletions
|
@ -1,9 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/ntobjfolder.cpp
|
* PURPOSE: Folder view class placeholder file
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/ntobjfolder.h
|
* PURPOSE: Folder view class header and implementation
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
extern const GUID CLSID_NtObjectFolder;
|
extern const GUID CLSID_NtObjectFolder;
|
||||||
|
@ -24,16 +24,18 @@ public:
|
||||||
{
|
{
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case SFVM_DEFVIEWMODE:
|
case SFVM_DEFVIEWMODE:
|
||||||
{
|
{
|
||||||
FOLDERVIEWMODE* pViewMode = (FOLDERVIEWMODE*)lParam;
|
FOLDERVIEWMODE* pViewMode = (FOLDERVIEWMODE*)lParam;
|
||||||
*pViewMode = FVM_DETAILS;
|
*pViewMode = FVM_DETAILS;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
case SFVM_COLUMNCLICK:
|
|
||||||
return S_FALSE;
|
case SFVM_COLUMNCLICK:
|
||||||
case SFVM_BACKGROUNDENUM:
|
return S_FALSE;
|
||||||
return S_OK;
|
|
||||||
|
case SFVM_BACKGROUNDENUM:
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("MessageSFVCB unimplemented %d %08x %08x\n", uMsg, wParam, lParam);
|
DbgPrint("MessageSFVCB unimplemented %d %08x %08x\n", uMsg, wParam, lParam);
|
||||||
|
@ -697,12 +699,13 @@ public:
|
||||||
{
|
{
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case DFM_MERGECONTEXTMENU:
|
case DFM_MERGECONTEXTMENU:
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case DFM_INVOKECOMMAND:
|
|
||||||
case DFM_INVOKECOMMANDEX:
|
case DFM_INVOKECOMMAND:
|
||||||
case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
|
case DFM_INVOKECOMMANDEX:
|
||||||
return S_FALSE;
|
case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
|
||||||
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
@ -718,4 +721,4 @@ public:
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
|
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
|
||||||
END_COM_MAP()
|
END_COM_MAP()
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2004, 2005 Martin Fuchs
|
* PROJECT: NT Object Namespace shell extension
|
||||||
*
|
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||||
* This library is free software; you can redistribute it and/or
|
* PURPOSE: NT Object Namespace enumeration functions
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* COPYRIGHT: Copyright 2004-2005 Martin Fuchs <martin-fuchs@gmx.net>
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
@ -73,19 +62,19 @@ static DWORD NtOpenObject(OBJECT_TYPE type, PHANDLE phandle, DWORD access, LPCWS
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case DIRECTORY_OBJECT: return NtOpenDirectoryObject(phandle, access, &open_struct);
|
case DIRECTORY_OBJECT: return NtOpenDirectoryObject(phandle, access, &open_struct);
|
||||||
case SYMBOLICLINK_OBJECT: return NtOpenSymbolicLinkObject(phandle, access, &open_struct);
|
case SYMBOLICLINK_OBJECT: return NtOpenSymbolicLinkObject(phandle, access, &open_struct);
|
||||||
case MUTANT_OBJECT: return NtOpenMutant(phandle, access, &open_struct);
|
case MUTANT_OBJECT: return NtOpenMutant(phandle, access, &open_struct);
|
||||||
case SECTION_OBJECT: return NtOpenSection(phandle, access, &open_struct);
|
case SECTION_OBJECT: return NtOpenSection(phandle, access, &open_struct);
|
||||||
case EVENT_OBJECT: return NtOpenEvent(phandle, access, &open_struct);
|
case EVENT_OBJECT: return NtOpenEvent(phandle, access, &open_struct);
|
||||||
case SEMAPHORE_OBJECT: return NtOpenSemaphore(phandle, access, &open_struct);
|
case SEMAPHORE_OBJECT: return NtOpenSemaphore(phandle, access, &open_struct);
|
||||||
case TIMER_OBJECT: return NtOpenTimer(phandle, access, &open_struct);
|
case TIMER_OBJECT: return NtOpenTimer(phandle, access, &open_struct);
|
||||||
case KEY_OBJECT: return NtOpenKey(phandle, access, &open_struct);
|
case KEY_OBJECT: return NtOpenKey(phandle, access, &open_struct);
|
||||||
case EVENTPAIR_OBJECT: return NtOpenEventPair(phandle, access, &open_struct);
|
case EVENTPAIR_OBJECT: return NtOpenEventPair(phandle, access, &open_struct);
|
||||||
case IOCOMPLETION_OBJECT: return NtOpenIoCompletion(phandle, access, &open_struct);
|
case IOCOMPLETION_OBJECT: return NtOpenIoCompletion(phandle, access, &open_struct);
|
||||||
case FILE_OBJECT: return NtOpenFile(phandle, access, &open_struct, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0);
|
case FILE_OBJECT: return NtOpenFile(phandle, access, &open_struct, &ioStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0);
|
||||||
default:
|
default:
|
||||||
return ERROR_INVALID_FUNCTION;
|
return ERROR_INVALID_FUNCTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,4 +737,4 @@ HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil)
|
||||||
HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil)
|
HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil)
|
||||||
{
|
{
|
||||||
return ShellObjectCreatorInit<CEnumNTDirectory>(path, IID_PPV_ARG(IEnumIDList, ppil));
|
return ShellObjectCreatorInit<CEnumNTDirectory>(path, IID_PPV_ARG(IEnumIDList, ppil));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2004 Martin Fuchs
|
* PROJECT: NT Object Namespace shell extension
|
||||||
*
|
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||||
* This library is free software; you can redistribute it and/or
|
* PURPOSE: NT Object Namespace enumeration header
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* COPYRIGHT: Copyright 2004 Martin Fuchs <martin-fuchs@gmx.net>
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,4 +90,4 @@ HRESULT GetEnumRegistryRoot(IEnumIDList ** ppil);
|
||||||
HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil);
|
HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil);
|
||||||
HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil);
|
HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil);
|
||||||
|
|
||||||
HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_STRING LinkTarget);
|
HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_STRING LinkTarget);
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/ntobjfolder.cpp
|
* PURPOSE: NT Object Namespace folder class implementation
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
@ -62,32 +61,36 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolderExtractIcon::GetIconLocation(
|
||||||
|
|
||||||
switch (entry->objectType)
|
switch (entry->objectType)
|
||||||
{
|
{
|
||||||
case DIRECTORY_OBJECT:
|
case DIRECTORY_OBJECT:
|
||||||
case SYMBOLICLINK_OBJECT:
|
case SYMBOLICLINK_OBJECT:
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
*piIndex = -((uFlags & GIL_OPENICON) ? IDI_NTOBJECTDIROPEN : IDI_NTOBJECTDIR);
|
*piIndex = -((uFlags & GIL_OPENICON) ? IDI_NTOBJECTDIROPEN : IDI_NTOBJECTDIR);
|
||||||
*pwFlags = flags;
|
*pwFlags = flags;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case DEVICE_OBJECT:
|
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
case DEVICE_OBJECT:
|
||||||
*piIndex = -IDI_NTOBJECTDEVICE;
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
*pwFlags = flags;
|
*piIndex = -IDI_NTOBJECTDEVICE;
|
||||||
return S_OK;
|
*pwFlags = flags;
|
||||||
case PORT_OBJECT:
|
return S_OK;
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
|
||||||
*piIndex = -IDI_NTOBJECTPORT;
|
case PORT_OBJECT:
|
||||||
*pwFlags = flags;
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
return S_OK;
|
*piIndex = -IDI_NTOBJECTPORT;
|
||||||
case KEY_OBJECT:
|
*pwFlags = flags;
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
return S_OK;
|
||||||
*piIndex = -IDI_REGISTRYKEY;
|
|
||||||
*pwFlags = flags;
|
case KEY_OBJECT:
|
||||||
return S_OK;
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
default:
|
*piIndex = -IDI_REGISTRYKEY;
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
*pwFlags = flags;
|
||||||
*piIndex = -IDI_NTOBJECTITEM;
|
return S_OK;
|
||||||
*pwFlags = flags;
|
|
||||||
return S_OK;
|
default:
|
||||||
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
|
*piIndex = -IDI_NTOBJECTITEM;
|
||||||
|
*pwFlags = flags;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,15 +226,17 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDefaultColumnState(
|
||||||
{
|
{
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case NTOBJECT_COLUMN_NAME:
|
case NTOBJECT_COLUMN_NAME:
|
||||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case NTOBJECT_COLUMN_TYPE:
|
|
||||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
case NTOBJECT_COLUMN_TYPE:
|
||||||
return S_OK;
|
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
||||||
case NTOBJECT_COLUMN_LINKTARGET:
|
return S_OK;
|
||||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_SLOW;
|
|
||||||
return S_OK;
|
case NTOBJECT_COLUMN_LINKTARGET:
|
||||||
|
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_SLOW;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
@ -321,75 +326,83 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
|
||||||
|
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case NTOBJECT_COLUMN_NAME:
|
case NTOBJECT_COLUMN_NAME:
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
|
|
||||||
MakeStrRetFromString(info->entryName, info->entryNameLength, &(psd->str));
|
|
||||||
return S_OK;
|
|
||||||
case NTOBJECT_COLUMN_TYPE:
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
|
|
||||||
if (info->objectType < 0)
|
|
||||||
{
|
{
|
||||||
NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
if (td->typeNameLength > 0)
|
MakeStrRetFromString(info->entryName, info->entryNameLength, &(psd->str));
|
||||||
MakeStrRetFromString(td->typeName, td->typeNameLength, &(psd->str));
|
return S_OK;
|
||||||
else
|
|
||||||
MakeStrRetFromString(L"Unknown", &(psd->str));
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
MakeStrRetFromString(ObjectTypeNames[info->objectType], &(psd->str));
|
|
||||||
return S_OK;
|
|
||||||
case NTOBJECT_COLUMN_LINKTARGET:
|
|
||||||
{
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
|
|
||||||
if (info->objectType == SYMBOLICLINK_OBJECT)
|
case NTOBJECT_COLUMN_TYPE:
|
||||||
{
|
{
|
||||||
WCHAR wbLink[MAX_PATH] = { 0 };
|
psd->fmt = LVCFMT_LEFT;
|
||||||
UNICODE_STRING link;
|
|
||||||
RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
|
|
||||||
|
|
||||||
HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName, &link);
|
if (info->objectType < 0)
|
||||||
|
|
||||||
if (!FAILED_UNEXPECTEDLY(hr) && link.Length > 0)
|
|
||||||
{
|
{
|
||||||
MakeStrRetFromString(link.Buffer, link.Length, &(psd->str));
|
NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) + FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
|
||||||
return S_OK;
|
|
||||||
|
if (td->typeNameLength > 0)
|
||||||
|
MakeStrRetFromString(td->typeName, td->typeNameLength, &(psd->str));
|
||||||
|
else
|
||||||
|
MakeStrRetFromString(L"Unknown", &(psd->str));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
MakeStrRetFromString(ObjectTypeNames[info->objectType], &(psd->str));
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStrRetFromString(L"", &(psd->str));
|
case NTOBJECT_COLUMN_LINKTARGET:
|
||||||
return S_OK;
|
{
|
||||||
}
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
|
if (info->objectType == SYMBOLICLINK_OBJECT)
|
||||||
|
{
|
||||||
|
WCHAR wbLink[MAX_PATH] = { 0 };
|
||||||
|
UNICODE_STRING link;
|
||||||
|
RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
|
||||||
|
|
||||||
|
HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName, &link);
|
||||||
|
|
||||||
|
if (!FAILED_UNEXPECTEDLY(hr) && link.Length > 0)
|
||||||
|
{
|
||||||
|
MakeStrRetFromString(link.Buffer, link.Length, &(psd->str));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MakeStrRetFromString(L"", &(psd->str));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case NTOBJECT_COLUMN_NAME:
|
case NTOBJECT_COLUMN_NAME:
|
||||||
psd->fmt = LVCFMT_LEFT;
|
psd->fmt = LVCFMT_LEFT;
|
||||||
psd->cxChar = 30;
|
psd->cxChar = 30;
|
||||||
|
|
||||||
// TODO: Make localizable
|
// TODO: Make localizable
|
||||||
MakeStrRetFromString(L"Object Name", &(psd->str));
|
MakeStrRetFromString(L"Object Name", &(psd->str));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case NTOBJECT_COLUMN_TYPE:
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
psd->cxChar = 20;
|
|
||||||
|
|
||||||
// TODO: Make localizable
|
case NTOBJECT_COLUMN_TYPE:
|
||||||
MakeStrRetFromString(L"Object Type", &(psd->str));
|
psd->fmt = LVCFMT_LEFT;
|
||||||
return S_OK;
|
psd->cxChar = 20;
|
||||||
case NTOBJECT_COLUMN_LINKTARGET:
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
psd->cxChar = 30;
|
|
||||||
|
|
||||||
// TODO: Make localizable
|
// TODO: Make localizable
|
||||||
MakeStrRetFromString(L"Symlink Target", &(psd->str));
|
MakeStrRetFromString(L"Object Type", &(psd->str));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
case NTOBJECT_COLUMN_LINKTARGET:
|
||||||
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
psd->cxChar = 30;
|
||||||
|
|
||||||
|
// TODO: Make localizable
|
||||||
|
MakeStrRetFromString(L"Symlink Target", &(psd->str));
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,18 +416,20 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::MapColumnToSCID(
|
||||||
static const GUID storage = PSGUID_STORAGE;
|
static const GUID storage = PSGUID_STORAGE;
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case NTOBJECT_COLUMN_NAME:
|
case NTOBJECT_COLUMN_NAME:
|
||||||
pscid->fmtid = storage;
|
pscid->fmtid = storage;
|
||||||
pscid->pid = PID_STG_NAME;
|
pscid->pid = PID_STG_NAME;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case NTOBJECT_COLUMN_TYPE:
|
|
||||||
pscid->fmtid = storage;
|
case NTOBJECT_COLUMN_TYPE:
|
||||||
pscid->pid = PID_STG_STORAGETYPE;
|
pscid->fmtid = storage;
|
||||||
return S_OK;
|
pscid->pid = PID_STG_STORAGETYPE;
|
||||||
case NTOBJECT_COLUMN_LINKTARGET:
|
return S_OK;
|
||||||
pscid->fmtid = GUID_NtObjectColumns;
|
|
||||||
pscid->pid = NTOBJECT_COLUMN_LINKTARGET;
|
case NTOBJECT_COLUMN_LINKTARGET:
|
||||||
return S_OK;
|
pscid->fmtid = GUID_NtObjectColumns;
|
||||||
|
pscid->pid = NTOBJECT_COLUMN_LINKTARGET;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
@ -441,15 +456,15 @@ HRESULT CNtObjectFolder::CompareIDs(LPARAM lParam, const NtPidlEntry * first, co
|
||||||
|
|
||||||
switch (column)
|
switch (column)
|
||||||
{
|
{
|
||||||
case NTOBJECT_COLUMN_NAME:
|
case NTOBJECT_COLUMN_NAME:
|
||||||
return CompareName(lParam, first, second);
|
return CompareName(lParam, first, second);
|
||||||
|
|
||||||
case NTOBJECT_COLUMN_TYPE:
|
case NTOBJECT_COLUMN_TYPE:
|
||||||
return MAKE_COMPARE_HRESULT(second->objectType - first->objectType);
|
return MAKE_COMPARE_HRESULT(second->objectType - first->objectType);
|
||||||
|
|
||||||
case NTOBJECT_COLUMN_LINKTARGET:
|
case NTOBJECT_COLUMN_LINKTARGET:
|
||||||
// Can't sort by link target yet
|
// Can't sort by link target yet
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("Unsupported sorting mode.\n");
|
DbgPrint("Unsupported sorting mode.\n");
|
||||||
|
@ -498,4 +513,4 @@ HRESULT CNtObjectFolder::GetInfoFromPidl(LPCITEMIDLIST pcidl, const NtPidlEntry
|
||||||
|
|
||||||
*pentry = entry;
|
*pentry = entry;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/ntobjfolder.h
|
* PURPOSE: NT Object Namespace folder class header
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
extern const GUID CLSID_NtObjectFolder;
|
extern const GUID CLSID_NtObjectFolder;
|
||||||
|
@ -113,4 +113,4 @@ protected:
|
||||||
HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents);
|
HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents);
|
||||||
|
|
||||||
HRESULT FormatContentsForDisplay(const NtPidlEntry * info, HKEY rootKey, LPCWSTR ntPath, PCWSTR * strContents);
|
HRESULT FormatContentsForDisplay(const NtPidlEntry * info, HKEY rootKey, LPCWSTR ntPath, PCWSTR * strContents);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/ntobjshex.cpp
|
* PURPOSE: Shell extension entry point and exports
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/regfolder.cpp
|
* PURPOSE: System Registry folder class implementation
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
@ -64,22 +63,24 @@ HRESULT STDMETHODCALLTYPE CRegistryFolderExtractIcon::GetIconLocation(
|
||||||
|
|
||||||
switch (entry->entryType)
|
switch (entry->entryType)
|
||||||
{
|
{
|
||||||
case REG_ENTRY_KEY:
|
case REG_ENTRY_KEY:
|
||||||
case REG_ENTRY_ROOT:
|
case REG_ENTRY_ROOT:
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
*piIndex = -IDI_REGISTRYKEY;
|
*piIndex = -IDI_REGISTRYKEY;
|
||||||
*pwFlags = flags;
|
*pwFlags = flags;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case REG_ENTRY_VALUE:
|
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
case REG_ENTRY_VALUE:
|
||||||
*piIndex = -IDI_REGISTRYVALUE;
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
*pwFlags = flags;
|
*piIndex = -IDI_REGISTRYVALUE;
|
||||||
return S_OK;
|
*pwFlags = flags;
|
||||||
default:
|
return S_OK;
|
||||||
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
|
||||||
*piIndex = -IDI_NTOBJECTITEM;
|
default:
|
||||||
*pwFlags = flags;
|
GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
|
||||||
return S_OK;
|
*piIndex = -IDI_NTOBJECTITEM;
|
||||||
|
*pwFlags = flags;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,15 +161,17 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDefaultColumnState(
|
||||||
{
|
{
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case REGISTRY_COLUMN_NAME:
|
case REGISTRY_COLUMN_NAME:
|
||||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case REGISTRY_COLUMN_TYPE:
|
|
||||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
case REGISTRY_COLUMN_TYPE:
|
||||||
return S_OK;
|
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
||||||
case REGISTRY_COLUMN_VALUE:
|
return S_OK;
|
||||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_SLOW;
|
|
||||||
return S_OK;
|
case REGISTRY_COLUMN_VALUE:
|
||||||
|
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_SLOW;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
@ -264,83 +267,91 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
|
||||||
|
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case REGISTRY_COLUMN_NAME:
|
case REGISTRY_COLUMN_NAME:
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
|
|
||||||
if (info->entryNameLength > 0)
|
|
||||||
{
|
{
|
||||||
return MakeStrRetFromString(info->entryName, info->entryNameLength, &(psd->str));
|
psd->fmt = LVCFMT_LEFT;
|
||||||
}
|
|
||||||
return MakeStrRetFromString(L"(Default)", &(psd->str));
|
|
||||||
|
|
||||||
case REGISTRY_COLUMN_TYPE:
|
if (info->entryNameLength > 0)
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
|
|
||||||
if (info->entryType == REG_ENTRY_ROOT)
|
|
||||||
{
|
|
||||||
return MakeStrRetFromString(L"Key", &(psd->str));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->entryType == REG_ENTRY_KEY)
|
|
||||||
{
|
|
||||||
if (info->contentsLength > 0)
|
|
||||||
{
|
{
|
||||||
PWSTR td = (PWSTR)(((PBYTE)info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
|
return MakeStrRetFromString(info->entryName, info->entryNameLength, &(psd->str));
|
||||||
|
}
|
||||||
|
return MakeStrRetFromString(L"(Default)", &(psd->str));
|
||||||
|
}
|
||||||
|
|
||||||
return MakeStrRetFromString(td, info->contentsLength, &(psd->str));
|
case REGISTRY_COLUMN_TYPE:
|
||||||
|
{
|
||||||
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
|
if (info->entryType == REG_ENTRY_ROOT)
|
||||||
|
{
|
||||||
|
return MakeStrRetFromString(L"Key", &(psd->str));
|
||||||
}
|
}
|
||||||
|
|
||||||
return MakeStrRetFromString(L"Key", &(psd->str));
|
if (info->entryType == REG_ENTRY_KEY)
|
||||||
|
{
|
||||||
|
if (info->contentsLength > 0)
|
||||||
|
{
|
||||||
|
PWSTR td = (PWSTR)(((PBYTE)info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
|
||||||
|
|
||||||
|
return MakeStrRetFromString(td, info->contentsLength, &(psd->str));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakeStrRetFromString(L"Key", &(psd->str));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakeStrRetFromString(RegistryTypeNames[info->entryType], &(psd->str));
|
||||||
}
|
}
|
||||||
|
|
||||||
return MakeStrRetFromString(RegistryTypeNames[info->entryType], &(psd->str));
|
case REGISTRY_COLUMN_VALUE:
|
||||||
|
|
||||||
case REGISTRY_COLUMN_VALUE:
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
|
|
||||||
PCWSTR strValueContents;
|
|
||||||
|
|
||||||
hr = FormatContentsForDisplay(info, m_hRoot, m_NtPath, &strValueContents);
|
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
{
|
{
|
||||||
return MakeStrRetFromString(L"(Empty)", &(psd->str));
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
|
PCWSTR strValueContents;
|
||||||
|
|
||||||
|
hr = FormatContentsForDisplay(info, m_hRoot, m_NtPath, &strValueContents);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (hr == S_FALSE)
|
||||||
|
{
|
||||||
|
return MakeStrRetFromString(L"(Empty)", &(psd->str));
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = MakeStrRetFromString(strValueContents, &(psd->str));
|
||||||
|
|
||||||
|
CoTaskMemFree((PVOID)strValueContents);
|
||||||
|
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = MakeStrRetFromString(strValueContents, &(psd->str));
|
|
||||||
|
|
||||||
CoTaskMemFree((PVOID)strValueContents);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case REGISTRY_COLUMN_NAME:
|
case REGISTRY_COLUMN_NAME:
|
||||||
psd->fmt = LVCFMT_LEFT;
|
psd->fmt = LVCFMT_LEFT;
|
||||||
psd->cxChar = 30;
|
psd->cxChar = 30;
|
||||||
|
|
||||||
// TODO: Make localizable
|
// TODO: Make localizable
|
||||||
MakeStrRetFromString(L"Object Name", &(psd->str));
|
MakeStrRetFromString(L"Object Name", &(psd->str));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case REGISTRY_COLUMN_TYPE:
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
psd->cxChar = 20;
|
|
||||||
|
|
||||||
// TODO: Make localizable
|
case REGISTRY_COLUMN_TYPE:
|
||||||
MakeStrRetFromString(L"Content Type", &(psd->str));
|
psd->fmt = LVCFMT_LEFT;
|
||||||
return S_OK;
|
psd->cxChar = 20;
|
||||||
case REGISTRY_COLUMN_VALUE:
|
|
||||||
psd->fmt = LVCFMT_LEFT;
|
|
||||||
psd->cxChar = 20;
|
|
||||||
|
|
||||||
// TODO: Make localizable
|
// TODO: Make localizable
|
||||||
MakeStrRetFromString(L"Value", &(psd->str));
|
MakeStrRetFromString(L"Content Type", &(psd->str));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
case REGISTRY_COLUMN_VALUE:
|
||||||
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
psd->cxChar = 20;
|
||||||
|
|
||||||
|
// TODO: Make localizable
|
||||||
|
MakeStrRetFromString(L"Value", &(psd->str));
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,18 +365,20 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::MapColumnToSCID(
|
||||||
static const GUID storage = PSGUID_STORAGE;
|
static const GUID storage = PSGUID_STORAGE;
|
||||||
switch (iColumn)
|
switch (iColumn)
|
||||||
{
|
{
|
||||||
case REGISTRY_COLUMN_NAME:
|
case REGISTRY_COLUMN_NAME:
|
||||||
pscid->fmtid = storage;
|
pscid->fmtid = storage;
|
||||||
pscid->pid = PID_STG_NAME;
|
pscid->pid = PID_STG_NAME;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
case REGISTRY_COLUMN_TYPE:
|
|
||||||
pscid->fmtid = storage;
|
case REGISTRY_COLUMN_TYPE:
|
||||||
pscid->pid = PID_STG_STORAGETYPE;
|
pscid->fmtid = storage;
|
||||||
return S_OK;
|
pscid->pid = PID_STG_STORAGETYPE;
|
||||||
case REGISTRY_COLUMN_VALUE:
|
return S_OK;
|
||||||
pscid->fmtid = storage;
|
|
||||||
pscid->pid = PID_STG_CONTENTS;
|
case REGISTRY_COLUMN_VALUE:
|
||||||
return S_OK;
|
pscid->fmtid = storage;
|
||||||
|
pscid->pid = PID_STG_CONTENTS;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
@ -392,15 +405,15 @@ HRESULT CRegistryFolder::CompareIDs(LPARAM lParam, const RegPidlEntry * first, c
|
||||||
|
|
||||||
switch (column)
|
switch (column)
|
||||||
{
|
{
|
||||||
case REGISTRY_COLUMN_NAME:
|
case REGISTRY_COLUMN_NAME:
|
||||||
return CompareName(lParam, first, second);
|
return CompareName(lParam, first, second);
|
||||||
|
|
||||||
case REGISTRY_COLUMN_TYPE:
|
case REGISTRY_COLUMN_TYPE:
|
||||||
return MAKE_COMPARE_HRESULT(second->contentType - first->contentType);
|
return MAKE_COMPARE_HRESULT(second->contentType - first->contentType);
|
||||||
|
|
||||||
case REGISTRY_COLUMN_VALUE:
|
case REGISTRY_COLUMN_VALUE:
|
||||||
// Can't sort by link target yet
|
// Can't sort by link target yet
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("Unsupported sorting mode.\n");
|
DbgPrint("Unsupported sorting mode.\n");
|
||||||
|
@ -448,99 +461,105 @@ HRESULT CRegistryFolder::FormatValueData(DWORD contentType, PVOID td, DWORD cont
|
||||||
{
|
{
|
||||||
switch (contentType)
|
switch (contentType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
|
||||||
PCWSTR strTodo = L"";
|
|
||||||
DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
|
||||||
StringCbCopyW(strValue, bufferLength, strTodo);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case REG_SZ:
|
|
||||||
case REG_EXPAND_SZ:
|
|
||||||
{
|
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(contentsLength + sizeof(WCHAR));
|
|
||||||
StringCbCopyNW(strValue, contentsLength + sizeof(WCHAR), (LPCWSTR)td, contentsLength);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case REG_MULTI_SZ:
|
|
||||||
{
|
|
||||||
PCWSTR separator = L" "; // To match regedit
|
|
||||||
size_t sepChars = wcslen(separator);
|
|
||||||
int strings = 0;
|
|
||||||
int stringChars = 0;
|
|
||||||
|
|
||||||
PCWSTR strData = (PCWSTR)td;
|
|
||||||
while (*strData)
|
|
||||||
{
|
{
|
||||||
size_t len = wcslen(strData);
|
PCWSTR strTodo = L"";
|
||||||
stringChars += len;
|
DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
|
||||||
strData += len + 1; // Skips null-terminator
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
||||||
strings++;
|
StringCbCopyW(strValue, bufferLength, strTodo);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cch = stringChars + (strings - 1) * sepChars + 1;
|
case REG_SZ:
|
||||||
|
case REG_EXPAND_SZ:
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(cch * sizeof(WCHAR));
|
|
||||||
|
|
||||||
strValue[0] = 0;
|
|
||||||
|
|
||||||
strData = (PCWSTR)td;
|
|
||||||
while (*strData)
|
|
||||||
{
|
{
|
||||||
StrCatW(strValue, strData);
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(contentsLength + sizeof(WCHAR));
|
||||||
strData += wcslen(strData) + 1;
|
StringCbCopyNW(strValue, contentsLength + sizeof(WCHAR), (LPCWSTR)td, contentsLength);
|
||||||
if (*strData)
|
*strContents = strValue;
|
||||||
StrCatW(strValue, separator);
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
*strContents = strValue;
|
case REG_MULTI_SZ:
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case REG_DWORD:
|
|
||||||
{
|
|
||||||
DWORD bufferLength = 64 * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
|
||||||
StringCbPrintfW(strValue, bufferLength, L"0x%08x (%d)",
|
|
||||||
*(DWORD*)td, *(DWORD*)td);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case REG_QWORD:
|
|
||||||
{
|
|
||||||
DWORD bufferLength = 64 * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
|
||||||
StringCbPrintfW(strValue, bufferLength, L"0x%016llx (%lld)",
|
|
||||||
*(LARGE_INTEGER*)td, ((LARGE_INTEGER*)td)->QuadPart);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
case REG_BINARY:
|
|
||||||
{
|
|
||||||
DWORD bufferLength = (contentsLength * 3 + 1) * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
|
||||||
PWSTR strTemp = strValue;
|
|
||||||
PBYTE data = (PBYTE)td;
|
|
||||||
for (DWORD i = 0; i < contentsLength; i++)
|
|
||||||
{
|
{
|
||||||
StringCbPrintfW(strTemp, bufferLength, L"%02x ", data[i]);
|
PCWSTR separator = L" "; // To match regedit
|
||||||
strTemp += 3;
|
size_t sepChars = wcslen(separator);
|
||||||
bufferLength -= 3;
|
int strings = 0;
|
||||||
|
int stringChars = 0;
|
||||||
|
|
||||||
|
PCWSTR strData = (PCWSTR)td;
|
||||||
|
while (*strData)
|
||||||
|
{
|
||||||
|
size_t len = wcslen(strData);
|
||||||
|
stringChars += len;
|
||||||
|
strData += len + 1; // Skips null-terminator
|
||||||
|
strings++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cch = stringChars + (strings - 1) * sepChars + 1;
|
||||||
|
|
||||||
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(cch * sizeof(WCHAR));
|
||||||
|
|
||||||
|
strValue[0] = 0;
|
||||||
|
|
||||||
|
strData = (PCWSTR)td;
|
||||||
|
while (*strData)
|
||||||
|
{
|
||||||
|
StrCatW(strValue, strData);
|
||||||
|
strData += wcslen(strData) + 1;
|
||||||
|
if (*strData)
|
||||||
|
StrCatW(strValue, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case REG_DWORD:
|
||||||
|
{
|
||||||
|
DWORD bufferLength = 64 * sizeof(WCHAR);
|
||||||
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
||||||
|
StringCbPrintfW(strValue, bufferLength, L"0x%08x (%d)",
|
||||||
|
*(DWORD*)td, *(DWORD*)td);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case REG_QWORD:
|
||||||
|
{
|
||||||
|
DWORD bufferLength = 64 * sizeof(WCHAR);
|
||||||
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
||||||
|
StringCbPrintfW(strValue, bufferLength, L"0x%016llx (%lld)",
|
||||||
|
*(LARGE_INTEGER*)td, ((LARGE_INTEGER*)td)->QuadPart);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case REG_BINARY:
|
||||||
|
{
|
||||||
|
DWORD bufferLength = (contentsLength * 3 + 1) * sizeof(WCHAR);
|
||||||
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
||||||
|
PWSTR strTemp = strValue;
|
||||||
|
PBYTE data = (PBYTE)td;
|
||||||
|
for (DWORD i = 0; i < contentsLength; i++)
|
||||||
|
{
|
||||||
|
StringCbPrintfW(strTemp, bufferLength, L"%02x ", data[i]);
|
||||||
|
strTemp += 3;
|
||||||
|
bufferLength -= 3;
|
||||||
|
}
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
PCWSTR strFormat = L"<Unimplemented value type %d>";
|
||||||
|
DWORD bufferLength = (wcslen(strFormat) + 15) * sizeof(WCHAR);
|
||||||
|
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
||||||
|
StringCbPrintfW(strValue, bufferLength, strFormat, contentType);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
PCWSTR strFormat = L"<Unimplemented value type %d>";
|
|
||||||
DWORD bufferLength = (wcslen(strFormat) + 15) * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
|
|
||||||
StringCbPrintfW(strValue, bufferLength, strFormat, contentType);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* PROJECT: ReactOS shell extensions
|
* PROJECT: NT Object Namespace shell extension
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
* FILE: dll/shellext/ntobjshex/regfolder.h
|
* PURPOSE: System Registry folder class header
|
||||||
* PURPOSE: NT Object Namespace shell extension
|
* COPYRIGHT: Copyright 2015-2017 David Quintana <gigaherz@gmail.com>
|
||||||
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
extern const GUID CLSID_RegistryFolder;
|
extern const GUID CLSID_RegistryFolder;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue