|
|
//
// 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
}
|