Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.5 KiB

  1. //
  2. // REGEVAL.C
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995
  5. //
  6. // Implementation of RegEnumValue and supporting functions.
  7. //
  8. #include "pch.h"
  9. //
  10. // RgLookupValueByIndex
  11. // (BIGKEY aware)
  12. //
  13. // Searches for the value with the specified index and returns a pointer to its
  14. // VALUE_RECORD.
  15. //
  16. // This locks the datablock associated with the KEY_RECORD and VALUE_RECORD.
  17. // This is always hKey->BigKeyLockedBlockIndex
  18. // It is the callers responsibility to unlock the datablock.
  19. //
  20. int
  21. INTERNAL
  22. RgLookupValueByIndex(
  23. HKEY hKey,
  24. UINT Index,
  25. LPVALUE_RECORD FAR* lplpValueRecord
  26. )
  27. {
  28. int ErrorCode;
  29. HKEY hKeyExtent;
  30. UINT IndexKey;
  31. LPSTR KeyName;
  32. DWORD cbKeyName;
  33. UINT ValueCount;
  34. ErrorCode = RgLookupValueByIndexStd(hKey, Index, lplpValueRecord, &ValueCount);
  35. hKey-> BigKeyLockedBlockIndex = hKey-> BlockIndex;
  36. if (ErrorCode == ERROR_NO_MORE_ITEMS && (hKey->Flags & KEYF_BIGKEYROOT)) {
  37. if (IsNullPtr(KeyName = RgSmAllocMemory(MAXIMUM_SUB_KEY_LENGTH)))
  38. return ERROR_OUTOFMEMORY;
  39. IndexKey = 0;
  40. while (ErrorCode == ERROR_NO_MORE_ITEMS && Index >= ValueCount)
  41. {
  42. Index -= ValueCount;
  43. cbKeyName = MAXIMUM_SUB_KEY_LENGTH;
  44. if (RgLookupKeyByIndex(hKey, IndexKey++, KeyName, &cbKeyName, LK_BIGKEYEXT) != ERROR_SUCCESS) {
  45. ErrorCode = ERROR_NO_MORE_ITEMS;
  46. goto lFreeKeyName;
  47. }
  48. if (RgLookupKey(hKey, KeyName, &hKeyExtent, LK_OPEN | LK_BIGKEYEXT) != ERROR_SUCCESS) {
  49. ErrorCode = ERROR_NO_MORE_ITEMS;
  50. goto lFreeKeyName;
  51. }
  52. hKey-> BigKeyLockedBlockIndex = hKeyExtent-> BlockIndex;
  53. ErrorCode = RgLookupValueByIndexStd(hKeyExtent, Index,
  54. lplpValueRecord, &ValueCount);
  55. RgDestroyKeyHandle(hKeyExtent);
  56. }
  57. lFreeKeyName:
  58. RgSmFreeMemory(KeyName);
  59. }
  60. return ErrorCode;
  61. }
  62. //
  63. // RgLookupValueByIndexStd
  64. //
  65. // Searches for the value with the specified index and returns a pointer to its
  66. // VALUE_RECORD.
  67. //
  68. // This locks the datablock associated with the VALUE_RECORD.
  69. // This is always hKey->BlockIndex
  70. // It is the callers responsibility to unlock the datablock.
  71. //
  72. int
  73. INTERNAL
  74. RgLookupValueByIndexStd(
  75. HKEY hKey,
  76. UINT Index,
  77. LPVALUE_RECORD FAR* lplpValueRecord,
  78. UINT FAR* lpValueCount
  79. )
  80. {
  81. int ErrorCode;
  82. LPKEY_RECORD lpKeyRecord;
  83. LPVALUE_RECORD lpValueRecord;
  84. *lpValueCount = 0;
  85. // Handle Win95 registries that don't have a key record for the root key.
  86. if (IsNullBlockIndex(hKey-> BlockIndex))
  87. return ERROR_NO_MORE_ITEMS;
  88. if ((ErrorCode = RgLockKeyRecord(hKey-> lpFileInfo, hKey-> BlockIndex,
  89. hKey-> KeyRecordIndex, &lpKeyRecord)) == ERROR_SUCCESS) {
  90. *lpValueCount = lpKeyRecord-> ValueCount;
  91. if (Index >= lpKeyRecord-> ValueCount) {
  92. RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BlockIndex, FALSE);
  93. ErrorCode = ERROR_NO_MORE_ITEMS;
  94. }
  95. else {
  96. lpValueRecord = (LPVALUE_RECORD) ((LPBYTE) &lpKeyRecord-> Name +
  97. lpKeyRecord-> NameLength + lpKeyRecord-> ClassLength);
  98. // Should probably do more sanity checking on lpValueRecord
  99. while (Index--) {
  100. lpValueRecord = (LPVALUE_RECORD) ((LPBYTE) &lpValueRecord->
  101. Name + lpValueRecord-> NameLength + lpValueRecord->
  102. DataLength);
  103. }
  104. *lplpValueRecord = lpValueRecord;
  105. ErrorCode = ERROR_SUCCESS;
  106. }
  107. }
  108. return ErrorCode;
  109. }
  110. //
  111. // VMMRegEnumValue
  112. //
  113. // See Win32 documentation for a description of the behavior.
  114. //
  115. LONG
  116. REGAPI
  117. VMMRegEnumValue(
  118. HKEY hKey,
  119. DWORD Index,
  120. LPSTR lpValueName,
  121. LPDWORD lpcbValueName,
  122. LPDWORD lpReserved,
  123. LPDWORD lpType,
  124. LPBYTE lpData,
  125. LPDWORD lpcbData
  126. )
  127. {
  128. int ErrorCode;
  129. LPVALUE_RECORD lpValueRecord;
  130. if (IsBadHugeWritePtr(lpcbValueName, sizeof(DWORD)) ||
  131. IsBadHugeWritePtr(lpValueName, *lpcbValueName) ||
  132. (IsBadHugeOptionalWritePtr(lpType, sizeof(DWORD))))
  133. return ERROR_INVALID_PARAMETER;
  134. if (IsBadHugeOptionalWritePtr(lpType, sizeof(DWORD)))
  135. return ERROR_INVALID_PARAMETER;
  136. if (IsNullPtr(lpcbData)) {
  137. if (!IsNullPtr(lpData))
  138. return ERROR_INVALID_PARAMETER;
  139. }
  140. else {
  141. // Win95 compatibility: don't validate lpData is of size *lpcbData.
  142. // Instead of validating the entire buffer, we'll validate just the
  143. // required buffer length in RgCopyFromValueRecord.
  144. if (IsBadHugeWritePtr(lpcbData, sizeof(DWORD)))
  145. return ERROR_INVALID_PARAMETER;
  146. }
  147. if (IsEnumIndexTooBig(Index))
  148. return ERROR_NO_MORE_ITEMS;
  149. if (!RgLockRegistry())
  150. return ERROR_LOCK_FAILED;
  151. if ((ErrorCode = RgValidateAndConvertKeyHandle(&hKey)) == ERROR_SUCCESS) {
  152. if ((ErrorCode = RgLookupValueByIndex(hKey, (UINT) Index,
  153. &lpValueRecord)) == ERROR_SUCCESS) {
  154. ErrorCode = RgCopyFromValueRecord(hKey, lpValueRecord, lpValueName,
  155. lpcbValueName, lpType, lpData, lpcbData);
  156. RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BigKeyLockedBlockIndex, FALSE);
  157. }
  158. }
  159. RgUnlockRegistry();
  160. return ErrorCode;
  161. UNREFERENCED_PARAMETER(lpReserved);
  162. }