[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->magic = REGISTRY_PIDL_MAGIC;
entry->entryType = otype;
entry->contentType = type;
if (cchName > 0)
{
@ -415,3 +416,50 @@ HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount
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

@ -102,3 +102,5 @@ struct RegPidlEntry
HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, 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,21 +362,24 @@ public:
return (entry->entryType == REG_ENTRY_KEY);
}
HRESULT FormatContentsForDisplay(RegPidlEntry * info, PCWSTR * strContents)
HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
{
PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (info->contentsLength > 0)
switch (contentType)
{
if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
{
switch (info->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(info->contentsLength + sizeof(WCHAR));
StringCbCopyNW(strValue, info->contentsLength + sizeof(WCHAR), (LPCWSTR) td, info->contentsLength);
PWSTR strValue = (PWSTR) CoTaskMemAlloc(contentsLength + sizeof(WCHAR));
StringCbCopyNW(strValue, contentsLength + sizeof(WCHAR), (LPCWSTR) td, contentsLength);
*strContents = strValue;
return S_OK;
}
@ -409,19 +412,38 @@ public:
}
}
}
else
HRESULT FormatContentsForDisplay(RegPidlEntry * info, PCWSTR * strContents)
{
PCWSTR strTodo = L"<TODO: Query non-embedded value>";
DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
StringCbCopyW(strValue, bufferLength, strTodo);
*strContents = strValue;
return S_OK;
PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
{
if (info->contentsLength > 0)
{
return FormatValueData(info->contentType, td, info->contentsLength, strContents);
}
}
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)
{
hr = FormatValueData(info->contentType, valueData, valueLength, strContents);
CoTaskMemFree(valueData);
return hr;
}
}
else
{
PCWSTR strEmpty = L"(Empty)";
PCWSTR strEmpty = L"";
DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
StringCbCopyW(strValue, bufferLength, strEmpty);
@ -429,6 +451,12 @@ public:
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;
}
};
@ -1002,12 +1030,27 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
if (IsEqualGUID(pscid->fmtid, storage))
{
if (pscid->pid == PID_STG_NAME)
{
if (info->entryNameLength > 0)
{
return MakeVariantString(pv, info->entryName);
}
return MakeVariantString(pv, L"(Default)");
}
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)
{
@ -1066,6 +1109,18 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
case REGISTRY_COLUMN_TYPE:
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));
case REGISTRY_COLUMN_VALUE: