mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[NTOBJSHEX]
* Fix content type column to represent the correct type, or "Key". This column would contain the custom class name if it was ever assigned (I have not seen such a case). * Implement reading registry values when enumerating details. Now the registry browsing is semi-useful, albeit read-only. svn path=/trunk/; revision=66676
This commit is contained in:
parent
9606bcd3f2
commit
a5f9430988
3 changed files with 156 additions and 51 deletions
|
@ -372,6 +372,7 @@ HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount
|
||||||
entry->cb = FIELD_OFFSET(RegPidlEntry, entryName);
|
entry->cb = FIELD_OFFSET(RegPidlEntry, entryName);
|
||||||
entry->magic = REGISTRY_PIDL_MAGIC;
|
entry->magic = REGISTRY_PIDL_MAGIC;
|
||||||
entry->entryType = otype;
|
entry->entryType = otype;
|
||||||
|
entry->contentType = type;
|
||||||
|
|
||||||
if (cchName > 0)
|
if (cchName > 0)
|
||||||
{
|
{
|
||||||
|
@ -415,3 +416,50 @@ HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData, PDWORD valueLength)
|
||||||
|
{
|
||||||
|
HKEY hkey;
|
||||||
|
|
||||||
|
DWORD res;
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, &hkey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = NtOpenObject(KEY_OBJECT, (PHANDLE) &hkey, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, path);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(res))
|
||||||
|
{
|
||||||
|
ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
|
||||||
|
return HRESULT_FROM_NT(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = RegQueryValueExW(hkey, valueName, NULL, NULL, NULL, valueLength);
|
||||||
|
|
||||||
|
if (*valueLength > 0)
|
||||||
|
{
|
||||||
|
*valueData = (PBYTE) CoTaskMemAlloc(*valueLength);
|
||||||
|
|
||||||
|
res = RegQueryValueExW(hkey, valueName, NULL, NULL, (PBYTE) *valueData, valueLength);
|
||||||
|
if (!NT_SUCCESS(res))
|
||||||
|
{
|
||||||
|
CoTaskMemFree(*valueData);
|
||||||
|
*valueData = NULL;
|
||||||
|
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
|
ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
|
||||||
|
return HRESULT_FROM_NT(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*valueData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
|
@ -101,4 +101,6 @@ struct RegPidlEntry
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
|
|
||||||
HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
|
HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
|
||||||
HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount);
|
HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount);
|
||||||
|
|
||||||
|
HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData, PDWORD valueLength);
|
|
@ -362,66 +362,88 @@ public:
|
||||||
return (entry->entryType == REG_ENTRY_KEY);
|
return (entry->entryType == REG_ENTRY_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
|
||||||
|
{
|
||||||
|
switch (contentType)
|
||||||
|
{
|
||||||
|
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_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 (%d)",
|
||||||
|
*(LARGE_INTEGER*) td, ((LARGE_INTEGER*) td)->QuadPart);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
PCWSTR strTodo = L"<TODO: Convert value for display>";
|
||||||
|
DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
|
||||||
|
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
|
||||||
|
StringCbCopyW(strValue, bufferLength, strTodo);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT FormatContentsForDisplay(RegPidlEntry * info, PCWSTR * strContents)
|
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)
|
if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
|
||||||
{
|
{
|
||||||
if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
|
if (info->contentsLength > 0)
|
||||||
{
|
{
|
||||||
switch (info->contentType)
|
return FormatValueData(info->contentType, td, info->contentsLength, strContents);
|
||||||
{
|
|
||||||
case REG_SZ:
|
|
||||||
case REG_EXPAND_SZ:
|
|
||||||
{
|
|
||||||
PWSTR strValue = (PWSTR) CoTaskMemAlloc(info->contentsLength + sizeof(WCHAR));
|
|
||||||
StringCbCopyNW(strValue, info->contentsLength + sizeof(WCHAR), (LPCWSTR) td, info->contentsLength);
|
|
||||||
*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 (%d)",
|
|
||||||
*(LARGE_INTEGER*) td, ((LARGE_INTEGER*) td)->QuadPart);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
PCWSTR strTodo = L"<TODO: Convert value for display>";
|
|
||||||
DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
|
|
||||||
StringCbCopyW(strValue, bufferLength, strTodo);
|
|
||||||
*strContents = strValue;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else if (info->entryType == REG_ENTRY_VALUE)
|
||||||
|
{
|
||||||
|
PVOID valueData;
|
||||||
|
DWORD valueLength;
|
||||||
|
HRESULT hr = ReadRegistryValue(NULL, m_ntPath, info->entryName, &valueData, &valueLength);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (valueLength > 0)
|
||||||
{
|
{
|
||||||
PCWSTR strTodo = L"<TODO: Query non-embedded value>";
|
hr = FormatValueData(info->contentType, valueData, valueLength, strContents);
|
||||||
DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
|
|
||||||
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
|
CoTaskMemFree(valueData);
|
||||||
StringCbCopyW(strValue, bufferLength, strTodo);
|
|
||||||
*strContents = strValue;
|
return hr;
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCWSTR strEmpty = L"(Empty)";
|
PCWSTR strEmpty = L"";
|
||||||
DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
|
DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
|
||||||
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
|
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
|
||||||
StringCbCopyW(strValue, bufferLength, strEmpty);
|
StringCbCopyW(strValue, bufferLength, strEmpty);
|
||||||
|
@ -429,6 +451,12 @@ public:
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCWSTR strEmpty = L"(Empty)";
|
||||||
|
DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
|
||||||
|
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
|
||||||
|
StringCbCopyW(strValue, bufferLength, strEmpty);
|
||||||
|
*strContents = strValue;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1003,11 +1031,26 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
|
||||||
{
|
{
|
||||||
if (pscid->pid == PID_STG_NAME)
|
if (pscid->pid == PID_STG_NAME)
|
||||||
{
|
{
|
||||||
return MakeVariantString(pv, info->entryName);
|
if (info->entryNameLength > 0)
|
||||||
|
{
|
||||||
|
return MakeVariantString(pv, info->entryName);
|
||||||
|
}
|
||||||
|
return MakeVariantString(pv, L"(Default)");
|
||||||
}
|
}
|
||||||
else if (pscid->pid == PID_STG_STORAGETYPE)
|
else if (pscid->pid == PID_STG_STORAGETYPE)
|
||||||
{
|
{
|
||||||
return MakeVariantString(pv, RegistryTypeNames[info->entryType]);
|
if (info->entryType == REG_ENTRY_KEY)
|
||||||
|
{
|
||||||
|
if (info->contentsLength > 0)
|
||||||
|
{
|
||||||
|
PWSTR td = (PWSTR)(((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
|
||||||
|
|
||||||
|
return MakeVariantString(pv, td);
|
||||||
|
}
|
||||||
|
return MakeVariantString(pv, L"Key");
|
||||||
|
}
|
||||||
|
|
||||||
|
return MakeVariantString(pv, RegistryTypeNames[info->contentType]);
|
||||||
}
|
}
|
||||||
else if (pscid->pid == PID_STG_CONTENTS)
|
else if (pscid->pid == PID_STG_CONTENTS)
|
||||||
{
|
{
|
||||||
|
@ -1066,6 +1109,18 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
|
||||||
case REGISTRY_COLUMN_TYPE:
|
case REGISTRY_COLUMN_TYPE:
|
||||||
psd->fmt = LVCFMT_LEFT;
|
psd->fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
Loading…
Reference in a new issue