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.

256 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. ConfEnum.c
  5. Abstract:
  6. This module contains helper routines to _read fields out of the NT
  7. configuration files. This is for temporary use until the Configuration
  8. Registry is available.
  9. Author:
  10. John Rogers (JohnRo) 27-Nov-1991
  11. Revision History:
  12. 27-Nov-1991 JohnRo
  13. Prepare for revised config handlers. (Actually swiped the NtRtl
  14. version of this code from RitaW.)
  15. 12-Mar-1992 JohnRo
  16. Added support for using the real Win32 registry.
  17. Added support for FAKE_PER_PROCESS_RW_CONFIG handling.
  18. 01-Apr-1992 JohnRo
  19. Use NetApiBufferAllocate() instead of private version.
  20. 06-May-1992 JohnRo
  21. REG_SZ now implies a UNICODE string, so we can't use REG_USZ anymore.
  22. 13-Jun-1992 JohnRo
  23. Title index parm is defunct (now lpReserved).
  24. Use PREFIX_ equates.
  25. 13-Apr-1993 JohnRo
  26. RAID 5483: server manager: wrong path given in repl dialog.
  27. Made changes suggested by PC-LINT 5.0
  28. --*/
  29. // These must be included first:
  30. #include <nt.h> // NT definitions
  31. #include <ntrtl.h> // NT Rtl structures
  32. #include <nturtl.h> // NT Rtl structures
  33. #include <windows.h> // Needed by <configp.h> and <winreg.h>
  34. #include <lmcons.h> // LAN Manager common definitions
  35. #include <netdebug.h> // (Needed by config.h)
  36. // These may be included in any order:
  37. #include <config.h> // My prototype, LPNET_CONFIG_HANDLE, etc.
  38. #include <configp.h> // NET_CONFIG_HANDLE.
  39. #include <debuglib.h> // IF_DEBUG()
  40. #include <lmapibuf.h> // NetApiBufferAllocate(), NetApiBufferFree().
  41. #include <lmerr.h> // LAN Manager network error definitions
  42. #include <prefix.h> // PREFIX_ equates.
  43. NET_API_STATUS
  44. NetpEnumConfigSectionValues(
  45. IN LPNET_CONFIG_HANDLE ConfigHandle,
  46. OUT LPTSTR * KeywordBuffer, // Must be freed by NetApiBufferFree().
  47. OUT LPTSTR * ValueBuffer, // Must be freed by NetApiBufferFree().
  48. IN BOOL FirstTime
  49. )
  50. /*++
  51. Routine Description:
  52. This function gets the keyword value string from the configuration file.
  53. Arguments:
  54. ConfigHandle - Supplies a handle from NetpOpenConfigData for the
  55. appropriate section of the config data.
  56. KeywordBuffer - Returns the string of the keyword value which is
  57. copied into this buffer. This string will be allocated by this routine
  58. and must be freed by NetApiBufferFree().
  59. ValueBuffer - Returns the string of the keyword value which is
  60. copied into this buffer. This string will be allocated by this routine
  61. and must be freed by NetApiBufferFree().
  62. FirstTime - TRUE if caller wants to start at first keyword for this section.
  63. FALSE if caller wants to continue a previous enum on this handle.
  64. Return Value:
  65. NET_API_STATUS - NERR_Success or reason for failure.
  66. (NERR_CfgParamNotFound if no other values exist for this section.)
  67. --*/
  68. {
  69. NET_CONFIG_HANDLE * lpnetHandle = ConfigHandle; // conv from opaque type
  70. NET_API_STATUS ApiStatus;
  71. NetpAssert( KeywordBuffer != NULL );
  72. NetpAssert( ValueBuffer != NULL );
  73. NetpAssert( (FirstTime==TRUE) || (FirstTime==FALSE) );
  74. //
  75. // Assume error until proven otherwise.
  76. //
  77. *KeywordBuffer = NULL;
  78. *ValueBuffer = NULL;
  79. {
  80. DWORD dwType;
  81. LONG Error;
  82. DWORD MaxKeywordSize, MaxValueSize;
  83. DWORD NumberOfKeywords;
  84. LPTSTR ValueT;
  85. //
  86. // Find number of keys in this section.
  87. //
  88. ApiStatus = NetpNumberOfConfigKeywords (
  89. lpnetHandle,
  90. & NumberOfKeywords );
  91. NetpAssert( ApiStatus == NO_ERROR );
  92. if (NumberOfKeywords == 0) {
  93. return (NERR_CfgParamNotFound);
  94. }
  95. //
  96. // Set our index to something reasonable. Note that some other
  97. // process might have deleted a keyword since we last did an enum,
  98. // so don't worry if the index gets larger than the number of keys.
  99. //
  100. if (FirstTime) {
  101. lpnetHandle->LastEnumIndex = 0;
  102. } else {
  103. DWORD MaxKeyIndex = NumberOfKeywords - 1; // Indices start at 0.
  104. if (MaxKeyIndex < (lpnetHandle->LastEnumIndex)) {
  105. // Bug or someone deleted. No way to tell, so assume latter.
  106. return (NERR_CfgParamNotFound);
  107. } else if (MaxKeyIndex == (lpnetHandle->LastEnumIndex)) {
  108. // This is how we normally exit at end of list.
  109. return (NERR_CfgParamNotFound);
  110. } else {
  111. // Normal bump to next entry.
  112. ++(lpnetHandle->LastEnumIndex);
  113. }
  114. }
  115. //
  116. // Compute sizes and allocate (maximum) buffers.
  117. //
  118. ApiStatus = NetpGetConfigMaxSizes (
  119. lpnetHandle,
  120. & MaxKeywordSize,
  121. & MaxValueSize );
  122. NetpAssert( ApiStatus == NO_ERROR );
  123. NetpAssert( MaxKeywordSize > 0 );
  124. NetpAssert( MaxValueSize > 0 );
  125. ApiStatus = NetApiBufferAllocate(
  126. MaxValueSize,
  127. (LPVOID *) & ValueT);
  128. if (ApiStatus != NO_ERROR) {
  129. return (ApiStatus);
  130. }
  131. NetpAssert( ValueT != NULL);
  132. ApiStatus = NetApiBufferAllocate(
  133. MaxKeywordSize,
  134. (LPVOID *) KeywordBuffer);
  135. if (ApiStatus != NO_ERROR) {
  136. (void) NetApiBufferFree( ValueT );
  137. return (ApiStatus);
  138. }
  139. NetpAssert( (*KeywordBuffer) != NULL);
  140. //
  141. // Get the keyword name and the value.
  142. // (Win32 reg APIs convert from TCHARs to UNICODE for us.)
  143. //
  144. IF_DEBUG(CONFIG) {
  145. NetpKdPrint(( PREFIX_NETLIB
  146. "NetpEnumConfigSectionValues: getting entry "
  147. FORMAT_DWORD "...\n", lpnetHandle->LastEnumIndex ));
  148. }
  149. Error = RegEnumValue (
  150. lpnetHandle->WinRegKey, // handle to key (section)
  151. lpnetHandle->LastEnumIndex, // index of value name
  152. * KeywordBuffer, // value name (keyword)
  153. & MaxKeywordSize, // value name len (updated)
  154. NULL, // reserved
  155. & dwType,
  156. (LPVOID) ValueT, // TCHAR value
  157. & MaxValueSize ); // value size (updated)
  158. IF_DEBUG(CONFIG) {
  159. NetpKdPrint(( PREFIX_NETLIB
  160. "NetpEnumConfigSectionValues: RegEnumValue() ret "
  161. FORMAT_LONG ".\n", Error ));
  162. }
  163. if ( Error != ERROR_SUCCESS )
  164. {
  165. NetpAssert( Error == ERROR_SUCCESS );
  166. NetApiBufferFree( ValueT );
  167. return (Error);
  168. }
  169. if (dwType == REG_SZ) {
  170. *ValueBuffer = ValueT;
  171. ApiStatus = NO_ERROR;
  172. } else if (dwType == REG_EXPAND_SZ) {
  173. LPTSTR UnexpandedString = ValueT;
  174. LPTSTR ExpandedString = NULL;
  175. // Expand string, using remote environment if necessary.
  176. ApiStatus = NetpExpandConfigString(
  177. lpnetHandle->UncServerName, // server name (or null char)
  178. UnexpandedString,
  179. &ExpandedString ); // expanded: alloc and set ptr
  180. if (ApiStatus != NO_ERROR) {
  181. NetpKdPrint(( PREFIX_NETLIB
  182. "NetpEnumConfigSectionValues: NetpExpandConfigString "
  183. " returned API status " FORMAT_API_STATUS ".\n",
  184. ApiStatus ));
  185. ExpandedString = NULL;
  186. }
  187. (VOID) NetApiBufferFree( UnexpandedString );
  188. *ValueBuffer = ExpandedString;
  189. } else {
  190. // Unexpected data type.
  191. NetpAssert( dwType == REG_SZ );
  192. *ValueBuffer = NULL;
  193. (VOID) NetApiBufferFree( ValueT );
  194. ApiStatus = ERROR_INVALID_DATA;
  195. }
  196. }
  197. return (ApiStatus);
  198. }