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.

206 lines
5.2 KiB

  1. //
  2. // REGEKEY.C
  3. //
  4. // Copyright (C) Microsoft Corporation, 1995
  5. //
  6. // Implementation of RegEnumKey and supporting functions.
  7. //
  8. #include "pch.h"
  9. //
  10. // RgLookupKeyByIndex
  11. //
  12. // lpKeyName, points to a buffer that receives the name of the subkey,
  13. // including the null terminator. May be NULL.
  14. // lpcbKeyName, on entry, specifies the size in characters of the buffer
  15. // pointed to be lpKeyName, and on return, specifies the size of the
  16. // indexed subkey. May not be NULL.
  17. //
  18. int
  19. INTERNAL
  20. RgLookupKeyByIndex(
  21. HKEY hKey,
  22. UINT Index,
  23. LPSTR lpKeyName,
  24. LPDWORD lpcbKeyName
  25. )
  26. {
  27. int ErrorCode;
  28. LPFILE_INFO lpFileInfo;
  29. UINT KeysToSkip;
  30. DWORD KeynodeIndex;
  31. DWORD TempOffset;
  32. LPKEYNODE lpKeynode;
  33. LPKEY_RECORD lpKeyRecord;
  34. #ifdef WANT_HIVE_SUPPORT
  35. LPHIVE_INFO lpHiveInfo;
  36. #endif
  37. lpFileInfo = hKey-> lpFileInfo;
  38. KeysToSkip = Index;
  39. //
  40. // Check if we've cached the keynode index of the last key index
  41. // (confusing?) from a previous call to this function. If so, then we can
  42. // skip ahead a bit and avoid touching a bunch of keynode pages.
  43. //
  44. if ((hKey-> Flags & KEYF_ENUMKEYCACHED) && (Index >=
  45. hKey-> LastEnumKeyIndex)) {
  46. KeysToSkip -= hKey-> LastEnumKeyIndex;
  47. KeynodeIndex = hKey-> LastEnumKeyKeynodeIndex;
  48. }
  49. else
  50. KeynodeIndex = hKey-> ChildKeynodeIndex;
  51. //
  52. // Loop over the child keys of this key until we find our index or run out
  53. // of children.
  54. //
  55. while (!IsNullKeynodeIndex(KeynodeIndex)) {
  56. if ((ErrorCode = RgLockInUseKeynode(lpFileInfo, KeynodeIndex,
  57. &lpKeynode)) != ERROR_SUCCESS)
  58. return ErrorCode;
  59. ASSERT(hKey-> KeynodeIndex == lpKeynode-> ParentIndex);
  60. if (KeysToSkip == 0) {
  61. if ((ErrorCode = RgLockKeyRecord(lpFileInfo, lpKeynode-> BlockIndex,
  62. (BYTE) lpKeynode-> KeyRecordIndex, &lpKeyRecord)) ==
  63. ERROR_SUCCESS) {
  64. if (!IsNullPtr(lpKeyName)) {
  65. if (*lpcbKeyName <= lpKeyRecord-> NameLength)
  66. ErrorCode = ERROR_MORE_DATA;
  67. else {
  68. MoveMemory(lpKeyName, lpKeyRecord-> Name, lpKeyRecord->
  69. NameLength);
  70. lpKeyName[lpKeyRecord-> NameLength] = '\0';
  71. }
  72. }
  73. // Does not include terminating null.
  74. *lpcbKeyName = lpKeyRecord-> NameLength;
  75. RgUnlockDatablock(lpFileInfo, lpKeynode-> BlockIndex, FALSE);
  76. }
  77. RgUnlockKeynode(lpFileInfo, KeynodeIndex, FALSE);
  78. // Cache our current position because the caller is likely to turn
  79. // around and ask for the next index.
  80. hKey-> LastEnumKeyIndex = Index;
  81. hKey-> LastEnumKeyKeynodeIndex = KeynodeIndex;
  82. hKey-> Flags |= KEYF_ENUMKEYCACHED;
  83. return ErrorCode;
  84. }
  85. TempOffset = lpKeynode-> NextIndex;
  86. RgUnlockKeynode(lpFileInfo, KeynodeIndex, FALSE);
  87. KeynodeIndex = TempOffset;
  88. KeysToSkip--;
  89. }
  90. #ifdef WANT_HIVE_SUPPORT
  91. //
  92. // Loop over the hives of this key until we find our index or run out of
  93. // hives.
  94. //
  95. if (hKey-> Flags & KEYF_HIVESALLOWED) {
  96. lpHiveInfo = hKey-> lpFileInfo-> lpHiveInfoList;
  97. while (!IsNullPtr(lpHiveInfo)) {
  98. if (KeysToSkip == 0) {
  99. ErrorCode = ERROR_SUCCESS;
  100. if (!IsNullPtr(lpKeyName)) {
  101. if (*lpcbKeyName <= lpHiveInfo-> NameLength)
  102. ErrorCode = ERROR_MORE_DATA;
  103. else {
  104. MoveMemory(lpKeyName, lpHiveInfo-> Name, lpHiveInfo->
  105. NameLength);
  106. lpKeyName[lpHiveInfo-> NameLength] = '\0';
  107. }
  108. }
  109. // Does not include terminating null.
  110. *lpcbKeyName = lpHiveInfo-> NameLength;
  111. // We don't worry about the enum key cache if we find a
  112. // hit in this code. This is a rare case and already the cache
  113. // that we do have is much better then Win95.
  114. return ErrorCode;
  115. }
  116. lpHiveInfo = lpHiveInfo-> lpNextHiveInfo;
  117. KeysToSkip--;
  118. }
  119. }
  120. #endif
  121. return ERROR_NO_MORE_ITEMS;
  122. }
  123. //
  124. // VMMRegEnumKey
  125. //
  126. // See Win32 documentation for a description of the behavior.
  127. //
  128. LONG
  129. REGAPI
  130. VMMRegEnumKey(
  131. HKEY hKey,
  132. DWORD Index,
  133. LPSTR lpKeyName,
  134. DWORD cbKeyName
  135. )
  136. {
  137. int ErrorCode;
  138. if (IsBadHugeWritePtr(lpKeyName, cbKeyName))
  139. return ERROR_INVALID_PARAMETER;
  140. if (IsEnumIndexTooBig(Index))
  141. return ERROR_NO_MORE_ITEMS;
  142. if (!RgLockRegistry())
  143. return ERROR_LOCK_FAILED;
  144. if ((ErrorCode = RgValidateAndConvertKeyHandle(&hKey)) == ERROR_SUCCESS)
  145. ErrorCode = RgLookupKeyByIndex(hKey, (UINT) Index, lpKeyName,
  146. &cbKeyName);
  147. RgUnlockRegistry();
  148. return ErrorCode;
  149. }