176 lines
4.4 KiB
C
176 lines
4.4 KiB
C
|
//
|
||
|
// REGQKEY.C
|
||
|
//
|
||
|
// Copyright (C) Microsoft Corporation, 1995
|
||
|
//
|
||
|
// Implementation of RegQueryInfoKey.
|
||
|
//
|
||
|
|
||
|
#include "pch.h"
|
||
|
|
||
|
//
|
||
|
// VMMRegQueryInfoKey
|
||
|
//
|
||
|
// See Win32 documentation of RegQueryInfoKey. When VXD is defined, this
|
||
|
// function does not take all of the parameters that we end up ignoring anyway
|
||
|
// (class, security, timestamp parameters).
|
||
|
//
|
||
|
|
||
|
#ifdef VXD
|
||
|
LONG
|
||
|
REGAPI
|
||
|
VMMRegQueryInfoKey(
|
||
|
HKEY hKey,
|
||
|
LPDWORD lpcSubKeys,
|
||
|
LPDWORD lpcbMaxSubKeyLen,
|
||
|
LPDWORD lpcValues,
|
||
|
LPDWORD lpcbMaxValueName,
|
||
|
LPDWORD lpcbMaxValueData
|
||
|
)
|
||
|
#else
|
||
|
LONG
|
||
|
REGAPI
|
||
|
VMMRegQueryInfoKey(
|
||
|
HKEY hKey,
|
||
|
LPSTR lpClass,
|
||
|
LPDWORD lpcbClass,
|
||
|
LPDWORD lpReserved,
|
||
|
LPDWORD lpcSubKeys,
|
||
|
LPDWORD lpcbMaxSubKeyLen,
|
||
|
LPDWORD lpcbMaxClassLen,
|
||
|
LPDWORD lpcValues,
|
||
|
LPDWORD lpcbMaxValueName,
|
||
|
LPDWORD lpcbMaxValueData,
|
||
|
LPVOID lpcbSecurityDescriptor,
|
||
|
LPVOID lpftLastWriteTime
|
||
|
)
|
||
|
#endif
|
||
|
{
|
||
|
|
||
|
int ErrorCode;
|
||
|
LPVALUE_RECORD lpValueRecord;
|
||
|
UINT cItems;
|
||
|
DWORD cbValueData;
|
||
|
DWORD cbMaxValueData;
|
||
|
DWORD cbStringLen;
|
||
|
DWORD cbMaxStringLen;
|
||
|
|
||
|
if (IsBadHugeOptionalWritePtr(lpcSubKeys, sizeof(DWORD)) ||
|
||
|
IsBadHugeOptionalWritePtr(lpcbMaxSubKeyLen, sizeof(DWORD)) ||
|
||
|
IsBadHugeOptionalWritePtr(lpcValues, sizeof(DWORD)) ||
|
||
|
IsBadHugeOptionalWritePtr(lpcbMaxValueName, sizeof(DWORD)) ||
|
||
|
IsBadHugeOptionalWritePtr(lpcbMaxValueData, sizeof(DWORD)))
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
|
||
|
if (!RgLockRegistry())
|
||
|
return ERROR_LOCK_FAILED;
|
||
|
|
||
|
if ((ErrorCode = RgValidateAndConvertKeyHandle(&hKey)) != ERROR_SUCCESS)
|
||
|
goto ReturnErrorCode;
|
||
|
|
||
|
//
|
||
|
// Compute cValues, cbMaxValueName, and cbMaxValueData.
|
||
|
//
|
||
|
|
||
|
if (!IsNullPtr(lpcValues) || !IsNullPtr(lpcbMaxValueName) ||
|
||
|
!IsNullPtr(lpcbMaxValueData)) {
|
||
|
|
||
|
cItems = 0;
|
||
|
cbMaxStringLen = 0;
|
||
|
cbMaxValueData = 0;
|
||
|
|
||
|
while ((ErrorCode = RgLookupValueByIndex(hKey, cItems,
|
||
|
&lpValueRecord)) == ERROR_SUCCESS) {
|
||
|
|
||
|
cItems++;
|
||
|
|
||
|
if (lpValueRecord-> NameLength > cbMaxStringLen)
|
||
|
cbMaxStringLen = lpValueRecord-> NameLength;
|
||
|
|
||
|
// RgCopyFromValueRecord will handle static and dynamic keys...
|
||
|
ErrorCode = RgCopyFromValueRecord(hKey, lpValueRecord, NULL, NULL,
|
||
|
NULL, NULL, &cbValueData);
|
||
|
|
||
|
RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BigKeyLockedBlockIndex, FALSE);
|
||
|
|
||
|
if (ErrorCode != ERROR_SUCCESS)
|
||
|
goto ReturnErrorCode;
|
||
|
|
||
|
if (cbValueData > cbMaxValueData)
|
||
|
cbMaxValueData = cbValueData;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (ErrorCode == ERROR_NO_MORE_ITEMS) {
|
||
|
|
||
|
if (!IsNullPtr(lpcValues))
|
||
|
*lpcValues = cItems;
|
||
|
|
||
|
if (!IsNullPtr(lpcbMaxValueName))
|
||
|
*lpcbMaxValueName = cbMaxStringLen;
|
||
|
|
||
|
if (!IsNullPtr(lpcbMaxValueData))
|
||
|
*lpcbMaxValueData = cbMaxValueData;
|
||
|
|
||
|
ErrorCode = ERROR_SUCCESS;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Compute cSubKeys and cbMaxSubKeyLen. Somewhat painful because we must
|
||
|
// touch each child keynode and datablock.
|
||
|
//
|
||
|
|
||
|
if (!IsNullPtr(lpcSubKeys) || !IsNullPtr(lpcbMaxSubKeyLen)) {
|
||
|
|
||
|
cItems = 0;
|
||
|
cbMaxStringLen = 0;
|
||
|
cbStringLen = 0;
|
||
|
|
||
|
while (TRUE) {
|
||
|
ErrorCode = RgLookupKeyByIndex(hKey, cItems, NULL,
|
||
|
&cbStringLen, 0);
|
||
|
|
||
|
if ((ErrorCode != ERROR_SUCCESS) && (ErrorCode != ERROR_MORE_DATA))
|
||
|
break;
|
||
|
cItems++;
|
||
|
|
||
|
// Win95 compatibility: the old code included the null terminator, even
|
||
|
// though the documentation for RegQueryInfoKey states that it doesn't.
|
||
|
if (cbStringLen && (cbStringLen + 1 > cbMaxStringLen))
|
||
|
cbMaxStringLen = cbStringLen + 1;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (ErrorCode == ERROR_NO_MORE_ITEMS) {
|
||
|
|
||
|
if (!IsNullPtr(lpcSubKeys))
|
||
|
*lpcSubKeys = cItems;
|
||
|
|
||
|
if (!IsNullPtr(lpcbMaxSubKeyLen))
|
||
|
*lpcbMaxSubKeyLen = cbMaxStringLen;
|
||
|
|
||
|
ErrorCode = ERROR_SUCCESS;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
ReturnErrorCode:
|
||
|
RgUnlockRegistry();
|
||
|
|
||
|
return ErrorCode;
|
||
|
|
||
|
#ifndef VXD
|
||
|
UNREFERENCED_PARAMETER(lpClass);
|
||
|
UNREFERENCED_PARAMETER(lpcbClass);
|
||
|
UNREFERENCED_PARAMETER(lpReserved);
|
||
|
UNREFERENCED_PARAMETER(lpcbMaxClassLen);
|
||
|
UNREFERENCED_PARAMETER(lpcbSecurityDescriptor);
|
||
|
UNREFERENCED_PARAMETER(lpftLastWriteTime);
|
||
|
#endif
|
||
|
|
||
|
}
|