Source code of Windows XP (NT5)
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.

132 lines
3.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. //
  12. // Searches for the value with the specified index and returns a pointer to its
  13. // VALUE_RECORD.
  14. //
  15. int
  16. INTERNAL
  17. RgLookupValueByIndex(
  18. HKEY hKey,
  19. UINT Index,
  20. LPVALUE_RECORD FAR* lplpValueRecord
  21. )
  22. {
  23. int ErrorCode;
  24. LPKEY_RECORD lpKeyRecord;
  25. LPVALUE_RECORD lpValueRecord;
  26. // Handle Win95 registries that don't have a key record for the root key.
  27. if (IsNullBlockIndex(hKey-> BlockIndex))
  28. return ERROR_NO_MORE_ITEMS;
  29. if ((ErrorCode = RgLockKeyRecord(hKey-> lpFileInfo, hKey-> BlockIndex,
  30. hKey-> KeyRecordIndex, &lpKeyRecord)) == ERROR_SUCCESS) {
  31. if (Index >= lpKeyRecord-> ValueCount) {
  32. RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BlockIndex, FALSE);
  33. ErrorCode = ERROR_NO_MORE_ITEMS;
  34. }
  35. else {
  36. lpValueRecord = (LPVALUE_RECORD) ((LPBYTE) &lpKeyRecord-> Name +
  37. lpKeyRecord-> NameLength + lpKeyRecord-> ClassLength);
  38. while (Index--) {
  39. lpValueRecord = (LPVALUE_RECORD) ((LPBYTE) &lpValueRecord->
  40. Name + lpValueRecord-> NameLength + lpValueRecord->
  41. DataLength);
  42. }
  43. *lplpValueRecord = lpValueRecord;
  44. ErrorCode = ERROR_SUCCESS;
  45. }
  46. }
  47. return ErrorCode;
  48. }
  49. //
  50. // VMMRegEnumValue
  51. //
  52. // See Win32 documentation for a description of the behavior.
  53. //
  54. LONG
  55. REGAPI
  56. VMMRegEnumValue(
  57. HKEY hKey,
  58. DWORD Index,
  59. LPSTR lpValueName,
  60. LPDWORD lpcbValueName,
  61. LPDWORD lpReserved,
  62. LPDWORD lpType,
  63. LPBYTE lpData,
  64. LPDWORD lpcbData
  65. )
  66. {
  67. int ErrorCode;
  68. LPVALUE_RECORD lpValueRecord;
  69. if (IsBadHugeWritePtr(lpcbValueName, sizeof(DWORD)) ||
  70. IsBadHugeWritePtr(lpValueName, *lpcbValueName) ||
  71. (IsBadHugeOptionalWritePtr(lpType, sizeof(DWORD))))
  72. return ERROR_INVALID_PARAMETER;
  73. if (IsBadHugeOptionalWritePtr(lpType, sizeof(DWORD)))
  74. return ERROR_INVALID_PARAMETER;
  75. if (IsNullPtr(lpcbData)) {
  76. if (!IsNullPtr(lpData))
  77. return ERROR_INVALID_PARAMETER;
  78. }
  79. else {
  80. // Win95 compatibility: don't validate lpData is of size *lpcbData.
  81. // Instead of validating the entire buffer, we'll validate just the
  82. // required buffer length in RgCopyFromValueRecord.
  83. if (IsBadHugeWritePtr(lpcbData, sizeof(DWORD)))
  84. return ERROR_INVALID_PARAMETER;
  85. }
  86. if (IsEnumIndexTooBig(Index))
  87. return ERROR_NO_MORE_ITEMS;
  88. if (!RgLockRegistry())
  89. return ERROR_LOCK_FAILED;
  90. if ((ErrorCode = RgValidateAndConvertKeyHandle(&hKey)) == ERROR_SUCCESS) {
  91. if ((ErrorCode = RgLookupValueByIndex(hKey, (UINT) Index,
  92. &lpValueRecord)) == ERROR_SUCCESS) {
  93. ErrorCode = RgCopyFromValueRecord(hKey, lpValueRecord, lpValueName,
  94. lpcbValueName, lpType, lpData, lpcbData);
  95. RgUnlockDatablock(hKey-> lpFileInfo, hKey-> BlockIndex, FALSE);
  96. }
  97. }
  98. RgUnlockRegistry();
  99. return ErrorCode;
  100. UNREFERENCED_PARAMETER(lpReserved);
  101. }