[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:
David Quintana 2015-03-14 04:04:27 +00:00
parent 9606bcd3f2
commit a5f9430988
3 changed files with 156 additions and 51 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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: