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.

324 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. ConfOpen.c
  5. Abstract:
  6. This module contains:
  7. NetpOpenConfigData
  8. NetpOpenConfigDataEx
  9. Author:
  10. John Rogers (JohnRo) 02-Dec-1991
  11. Environment:
  12. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  13. Requires ANSI C extensions: slash-slash comments, long external names.
  14. Revision History:
  15. 02-Dec-1991 JohnRo
  16. Created this routine, to prepare for revised config handlers.
  17. (Actually, I swiped some of this code from RitaW.)
  18. 06-Jan-1992 JohnRo
  19. Added support for FAKE_PER_PROCESS_RW_CONFIG handling.
  20. 09-Jan-1992 JohnRo
  21. Try workaround for lib/linker problem with NetpIsRemote().
  22. 22-Mar-1992 JohnRo
  23. Added support for using the real Win32 registry.
  24. Added debug code to print the fake array.
  25. Fixed a UNICODE bug which PC-LINT caught.
  26. Fixed double _close of RTL config file.
  27. Fixed memory _access error in setting fake end of array.
  28. Use DBGSTATIC where applicable.
  29. 05-May-1992 JohnRo
  30. Reflect movement of keys to under System\CurrentControlSet\Services.
  31. 08-May-1992 JohnRo
  32. Use <prefix.h> equates.
  33. 21-May-1992 JohnRo
  34. RAID 9826: Match revised winreg error codes.
  35. 08-Jul-1992 JohnRo
  36. RAID 10503: srv mgr: repl dialog doesn't come up.
  37. Added more debug output to track down bad error code during logoff.
  38. 23-Jul-1992 JohnRo
  39. RAID 2274: repl svc should impersonate caller.
  40. 22-Sep-1992 JohnRo
  41. Avoid GP fault printing first part of winreg handle.
  42. 28-Oct-1992 JohnRo
  43. RAID 10136: NetConfig APIs don't work to remote NT server.
  44. 12-Apr-1993 JohnRo
  45. RAID 5483: server manager: wrong path given in repl dialog.
  46. --*/
  47. // These must be included first:
  48. #include <nt.h> // NT definitions
  49. #include <ntrtl.h> // NT Rtl structures
  50. #include <nturtl.h> // NT config Rtl routines
  51. #include <windows.h> // Needed by <configp.h> and <winreg.h>
  52. #include <lmcons.h> // LAN Manager common definitions
  53. #include <netdebug.h> // (Needed by config.h)
  54. // These may be included in any order:
  55. #include <config.h> // My prototype, LPNET_CONFIG_HANDLE.
  56. #include <configp.h> // NET_CONFIG_HANDLE, etc.
  57. #include <debuglib.h> // IF_DEBUG().
  58. #include <icanon.h> // NetpIsRemote(), etc.
  59. #include <lmerr.h> // LAN Manager network error definitions
  60. #include <netlib.h> // NetpMemoryAllocate(), etc.
  61. #include <netlibnt.h> // NetpNtStatusToApiStatus
  62. #include <prefix.h> // PREFIX_ equates.
  63. #include <tstring.h> // NetpAlloc{type}From{type}, STRICMP(), etc.
  64. #define DEFAULT_AREA TEXT("Parameters")
  65. #define DEFAULT_ROOT_KEY HKEY_LOCAL_MACHINE
  66. DBGSTATIC NET_API_STATUS
  67. NetpSetupConfigSection (
  68. IN NET_CONFIG_HANDLE * ConfigHandle,
  69. IN LPTSTR SectionName
  70. );
  71. NET_API_STATUS
  72. NetpOpenConfigData(
  73. OUT LPNET_CONFIG_HANDLE *ConfigHandle,
  74. IN LPTSTR UncServerName OPTIONAL,
  75. IN LPTSTR SectionName,
  76. IN BOOL ReadOnly
  77. )
  78. /*++
  79. Routine Description:
  80. This function opens the system configuration file.
  81. Arguments:
  82. ConfigHandle - Points to a pointer which will be set to point to a
  83. net config handle for this section name. ConfigHandle will be set to
  84. NULL if any error occurs.
  85. SectionName - Points to the new (NT) section name to be opened.
  86. ReadOnly - Indicates whether all access through this net config handle is
  87. to be read only.
  88. Return Value:
  89. NET_API_STATUS - NO_ERROR or reason for failure.
  90. --*/
  91. {
  92. return ( NetpOpenConfigDataEx(
  93. ConfigHandle,
  94. UncServerName,
  95. SectionName, // Must be a SECT_NT_ name.
  96. DEFAULT_AREA,
  97. ReadOnly) );
  98. } // NetpOpenConfigData
  99. // NetpOpenConfigDataEx opens any area of a given service.
  100. NET_API_STATUS
  101. NetpOpenConfigDataEx(
  102. OUT LPNET_CONFIG_HANDLE *ConfigHandle,
  103. IN LPTSTR UncServerName OPTIONAL,
  104. IN LPTSTR SectionName, // Must be a SECT_NT_ name.
  105. IN LPTSTR AreaUnderSection OPTIONAL,
  106. IN BOOL ReadOnly
  107. )
  108. {
  109. NET_API_STATUS ApiStatus;
  110. DWORD LocalOrRemote; // Will be set to ISLOCAL or ISREMOTE.
  111. NET_CONFIG_HANDLE * MyHandle = NULL;
  112. LONG Error;
  113. HKEY RootKey = DEFAULT_ROOT_KEY;
  114. NetpAssert( ConfigHandle != NULL );
  115. *ConfigHandle = NULL; // Assume error until proven innocent.
  116. if ( (SectionName == NULL) || (*SectionName == TCHAR_EOS) ) {
  117. return (ERROR_INVALID_PARAMETER);
  118. }
  119. NetpAssert( (ReadOnly==TRUE) || (ReadOnly==FALSE) );
  120. if ( (UncServerName != NULL ) && ((*UncServerName) != TCHAR_EOS) ) {
  121. if( STRLEN(UncServerName) > MAX_PATH ) {
  122. return (ERROR_INVALID_PARAMETER);
  123. }
  124. //
  125. // Name was given. Canonicalize it and check if it's remote.
  126. //
  127. ApiStatus = NetpIsRemote(
  128. UncServerName, // input: uncanon name
  129. & LocalOrRemote, // output: local or remote flag
  130. NULL, // dont need output (canon name)
  131. 0); // flags: normal
  132. IF_DEBUG(CONFIG) {
  133. NetpKdPrint(( PREFIX_NETLIB "NetpOpenConfigDataEx: canon status is "
  134. FORMAT_API_STATUS ", Lcl/rmt=" FORMAT_HEX_DWORD ".\n",
  135. ApiStatus, LocalOrRemote));
  136. }
  137. if (ApiStatus != NO_ERROR) {
  138. return (ApiStatus);
  139. }
  140. if (LocalOrRemote == ISREMOTE) {
  141. //
  142. // Explicit remote name given.
  143. //
  144. Error = RegConnectRegistry(
  145. UncServerName,
  146. DEFAULT_ROOT_KEY,
  147. & RootKey ); // result key
  148. if (Error != ERROR_SUCCESS) {
  149. NetpKdPrint(( PREFIX_NETLIB
  150. "NetpOpenConfigDataEx: RegConnectRegistry(machine '"
  151. FORMAT_LPTSTR "') ret error " FORMAT_LONG ".\n",
  152. UncServerName, Error ));
  153. return ((NET_API_STATUS) Error);
  154. }
  155. NetpAssert( RootKey != DEFAULT_ROOT_KEY );
  156. }
  157. }
  158. else {
  159. LocalOrRemote = ISLOCAL;
  160. }
  161. MyHandle = NetpMemoryAllocate( sizeof(NET_CONFIG_HANDLE) );
  162. if (MyHandle == NULL) {
  163. if (RootKey != DEFAULT_ROOT_KEY) {
  164. (VOID) RegCloseKey( RootKey );
  165. }
  166. return (ERROR_NOT_ENOUGH_MEMORY);
  167. }
  168. {
  169. LPTSTR AreaToUse = DEFAULT_AREA;
  170. DWORD DesiredAccess;
  171. DWORD SubKeySize;
  172. LPTSTR SubKeyString;
  173. HKEY SectionKey;
  174. #define LM_SUBKEY_UNDER_LOCAL_MACHINE \
  175. TEXT("System\\CurrentControlSet\\Services\\")
  176. if (AreaUnderSection != NULL) {
  177. if ((*AreaUnderSection) != TCHAR_EOS) {
  178. AreaToUse = AreaUnderSection;
  179. }
  180. }
  181. SubKeySize = ( STRLEN(LM_SUBKEY_UNDER_LOCAL_MACHINE)
  182. + STRLEN(SectionName)
  183. + 1 // backslash
  184. + STRLEN(AreaToUse)
  185. + 1 ) // trailing null
  186. * sizeof(TCHAR);
  187. SubKeyString = NetpMemoryAllocate( SubKeySize );
  188. if (SubKeyString == NULL) {
  189. if (MyHandle != NULL) {
  190. NetpMemoryFree( MyHandle );
  191. MyHandle = NULL;
  192. }
  193. return (ERROR_NOT_ENOUGH_MEMORY);
  194. }
  195. (void) STRCPY( SubKeyString, LM_SUBKEY_UNDER_LOCAL_MACHINE );
  196. (void) STRCAT( SubKeyString, SectionName );
  197. (void) STRCAT( SubKeyString, TEXT("\\") );
  198. (void) STRCAT( SubKeyString, AreaToUse );
  199. if ( ReadOnly ) {
  200. DesiredAccess = KEY_READ;
  201. } else {
  202. DesiredAccess = KEY_READ | KEY_WRITE;
  203. // DesiredAccess = KEY_ALL_ACCESS; // Everything but SYNCHRONIZE.
  204. }
  205. Error = RegOpenKeyEx (
  206. RootKey,
  207. SubKeyString,
  208. REG_OPTION_NON_VOLATILE,
  209. DesiredAccess,
  210. & SectionKey );
  211. IF_DEBUG(CONFIG) {
  212. NetpKdPrint(( PREFIX_NETLIB
  213. "NetpOpenConfigDataEx: RegOpenKeyEx(subkey '"
  214. FORMAT_LPTSTR "') ret " FORMAT_LONG ", win reg handle at "
  215. FORMAT_LPVOID " is " FORMAT_LPVOID ".\n",
  216. SubKeyString, Error, (LPVOID) &(MyHandle->WinRegKey),
  217. SectionKey ));
  218. }
  219. if (Error == ERROR_FILE_NOT_FOUND) {
  220. ApiStatus = NERR_CfgCompNotFound;
  221. // Code below will free MyHandle, etc., based on ApiStatus.
  222. } else if (Error != ERROR_SUCCESS) {
  223. ApiStatus = (NET_API_STATUS) Error;
  224. // Code below will free MyHandle, etc., based on ApiStatus.
  225. } else {
  226. ApiStatus = NO_ERROR;
  227. }
  228. NetpMemoryFree( SubKeyString );
  229. if (RootKey != DEFAULT_ROOT_KEY) {
  230. (VOID) RegCloseKey( RootKey );
  231. }
  232. MyHandle->WinRegKey = SectionKey;
  233. }
  234. if (ApiStatus != NO_ERROR) {
  235. NetpMemoryFree( MyHandle );
  236. MyHandle = NULL;
  237. }
  238. if (MyHandle != NULL) {
  239. if (LocalOrRemote == ISREMOTE) {
  240. (VOID) STRCPY(
  241. MyHandle->UncServerName, // dest
  242. UncServerName ); // src
  243. } else {
  244. MyHandle->UncServerName[0] = TCHAR_EOS;
  245. }
  246. }
  247. *ConfigHandle = MyHandle; // Points to private handle, or is NULL on err.
  248. return (ApiStatus);
  249. } // NetpOpenConfigDataEx