|
|
//
// REGEVAL.C
//
// Copyright (C) Microsoft Corporation, 1995
//
// Implementation of RegEnumValue and supporting functions.
//
#include "pch.h"
//
// RgLookupValueByIndex
// (BIGKEY aware)
//
// Searches for the value with the specified index and returns a pointer to its
// VALUE_RECORD.
//
// This locks the datablock associated with the KEY_RECORD and VALUE_RECORD.
// This is always hKey->BigKeyLockedBlockIndex
// It is the callers responsibility to unlock the datablock.
//
int INTERNAL RgLookupValueByIndex( HKEY hKey, UINT Index, LPVALUE_RECORD FAR* lplpValueRecord ) { int ErrorCode; HKEY hKeyExtent; UINT IndexKey; LPSTR KeyName; DWORD cbKeyName; UINT ValueCount;
ErrorCode = RgLookupValueByIndexStd(hKey, Index, lplpValueRecord, &ValueCount); hKey-> BigKeyLockedBlockIndex = hKey-> BlockIndex; if (ErrorCode == ERROR_NO_MORE_ITEMS && (hKey->Flags & KEYF_BIGKEYROOT)) {
if (IsNullPtr(KeyName = RgSmAllocMemory(MAXIMUM_SUB_KEY_LENGTH))) return ERROR_OUTOFMEMORY; IndexKey = 0; while (ErrorCode == ERROR_NO_MORE_ITEMS && Index >= ValueCount) { Index -= ValueCount;
cbKeyName = MAXIMUM_SUB_KEY_LENGTH; if (RgLookupKeyByIndex(hKey, IndexKey++, KeyName, &cbKeyName, LK_BIGKEYEXT) != ERROR_SUCCESS) { ErrorCode = ERROR_NO_MORE_ITEMS; goto lFreeKeyName; }
if (RgLookupKey(hKey, KeyName, &hKeyExtent, LK_OPEN | LK_BIGKEYEXT) != ERROR_SUCCESS) { ErrorCode = ERROR_NO_MORE_ITEMS; goto lFreeKeyName; }
hKey-> BigKeyLockedBlockIndex = hKeyExtent-> BlockIndex; ErrorCode = RgLookupValueByIndexStd(hKeyExtent, Index, lplpValueRecord, &ValueCount);
RgDestroyKeyHandle(hKeyExtent); }
lFreeKeyName: RgSmFreeMemory(KeyName); }
return ErrorCode; }
//
// RgLookupValueByIndexStd
//
// Searches for the value with the specified index and returns a pointer to its
// VALUE_RECORD.
//
// This locks the datablock associated with the VALUE_RECORD.
// This is always hKey->BlockIndex
// It is the callers responsibility to unlock the datablock.
//
int INTERNAL RgLookupValueByIndexStd( HKEY hKey, UINT Index, LPVALUE_RECORD FAR* lplpValueRecord, UINT FAR* lpValueCount ) {
int ErrorCode; LPKEY_RECORD lpKeyRecord; LPVALUE_RECORD lpValueRecord;
*lpValueCount = 0; // Handle Win95 registries that don't have a key record for the root key.
if (IsNullBlockIndex(hKey-> BlockIndex)) return ERROR_NO_MORE_ITEMS;
if ((ErrorCode = RgLockKeyRecord(hKey-> lpFileInfo, hKey-> BlockIndex, hKey-> KeyRecordIndex, &lpKeyRecord)) == ERROR_SUCCESS) {
*lpValueCount = lpKeyRecord-> ValueCount;
if (Index >= lpKeyRecord-> ValueCount) { RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BlockIndex, FALSE); ErrorCode = ERROR_NO_MORE_ITEMS; }
else {
lpValueRecord = (LPVALUE_RECORD) ((LPBYTE) &lpKeyRecord-> Name + lpKeyRecord-> NameLength + lpKeyRecord-> ClassLength);
// Should probably do more sanity checking on lpValueRecord
while (Index--) { lpValueRecord = (LPVALUE_RECORD) ((LPBYTE) &lpValueRecord-> Name + lpValueRecord-> NameLength + lpValueRecord-> DataLength); }
*lplpValueRecord = lpValueRecord; ErrorCode = ERROR_SUCCESS;
}
}
return ErrorCode;
}
//
// VMMRegEnumValue
//
// See Win32 documentation for a description of the behavior.
//
LONG REGAPI VMMRegEnumValue( HKEY hKey, DWORD Index, LPSTR lpValueName, LPDWORD lpcbValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ) {
int ErrorCode; LPVALUE_RECORD lpValueRecord;
if (IsBadHugeWritePtr(lpcbValueName, sizeof(DWORD)) || IsBadHugeWritePtr(lpValueName, *lpcbValueName) || (IsBadHugeOptionalWritePtr(lpType, sizeof(DWORD)))) return ERROR_INVALID_PARAMETER;
if (IsBadHugeOptionalWritePtr(lpType, sizeof(DWORD))) return ERROR_INVALID_PARAMETER;
if (IsNullPtr(lpcbData)) { if (!IsNullPtr(lpData)) return ERROR_INVALID_PARAMETER; }
else { // Win95 compatibility: don't validate lpData is of size *lpcbData.
// Instead of validating the entire buffer, we'll validate just the
// required buffer length in RgCopyFromValueRecord.
if (IsBadHugeWritePtr(lpcbData, sizeof(DWORD))) return ERROR_INVALID_PARAMETER; }
if (IsEnumIndexTooBig(Index)) return ERROR_NO_MORE_ITEMS;
if (!RgLockRegistry()) return ERROR_LOCK_FAILED;
if ((ErrorCode = RgValidateAndConvertKeyHandle(&hKey)) == ERROR_SUCCESS) {
if ((ErrorCode = RgLookupValueByIndex(hKey, (UINT) Index, &lpValueRecord)) == ERROR_SUCCESS) { ErrorCode = RgCopyFromValueRecord(hKey, lpValueRecord, lpValueName, lpcbValueName, lpType, lpData, lpcbData); RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BigKeyLockedBlockIndex, FALSE); }
}
RgUnlockRegistry();
return ErrorCode;
UNREFERENCED_PARAMETER(lpReserved);
}
|