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.

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