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.

365 lines
7.9 KiB

  1. /*++
  2. Copyright (C) 1999 Microsoft Coporation
  3. Module Name:
  4. writereg.c
  5. Abstract:
  6. This module write the configuration to the registry from the
  7. MM data structures for NT4 and W2K.
  8. --*/
  9. #include <precomp.h>
  10. DWORD
  11. SaveOrRestoreConfigToFile(
  12. IN HKEY hKey,
  13. IN LPWSTR ConfigFileName,
  14. IN BOOL fRestore
  15. )
  16. /*++
  17. Routine Description:
  18. This routine backs up or restores the dhcp configuration between
  19. the registry and the file.
  20. Arguments:
  21. hKey -- key to backup or restore onto
  22. ConfigFileName -- file name to use to backup onto or restore from.
  23. This must be full path name.
  24. fRestore -- TRUE ==> do a restore from file; FALSE => do backup to
  25. file.
  26. Return Values:
  27. Win32 errors...
  28. --*/
  29. {
  30. DWORD Error;
  31. BOOL fError;
  32. BOOLEAN WasEnable;
  33. NTSTATUS NtStatus;
  34. HANDLE ImpersonationToken;
  35. if( FALSE == fRestore ) {
  36. //
  37. // If backing up, delete the old file.
  38. //
  39. fError = DeleteFile( ConfigFileName );
  40. if(FALSE == fError ) {
  41. Error = GetLastError();
  42. if( ERROR_FILE_NOT_FOUND != Error &&
  43. ERROR_PATH_NOT_FOUND != Error ) {
  44. ASSERT(FALSE);
  45. return Error;
  46. }
  47. }
  48. }
  49. //
  50. // Impersonate to self.
  51. //
  52. NtStatus = RtlImpersonateSelf( SecurityImpersonation );
  53. if( !NT_SUCCESS(NtStatus) ) {
  54. DbgPrint("Impersonation failed: 0x%lx\n", NtStatus);
  55. Error = RtlNtStatusToDosError( NtStatus );
  56. return Error;
  57. }
  58. NtStatus = RtlAdjustPrivilege(
  59. SE_BACKUP_PRIVILEGE,
  60. TRUE, // enable privilege
  61. TRUE, // adjust client token
  62. &WasEnable
  63. );
  64. if( !NT_SUCCESS (NtStatus ) ) {
  65. DbgPrint("RtlAdjustPrivilege: 0x%lx\n", NtStatus );
  66. Error = RtlNtStatusToDosError( NtStatus );
  67. goto Cleanup;
  68. }
  69. NtStatus = RtlAdjustPrivilege(
  70. SE_RESTORE_PRIVILEGE,
  71. TRUE, // enable privilege
  72. TRUE, // adjust client token
  73. &WasEnable
  74. );
  75. if( !NT_SUCCESS (NtStatus ) ) {
  76. DbgPrint( "RtlAdjustPrivilege: 0x%lx\n", NtStatus );
  77. Error = RtlNtStatusToDosError( NtStatus );
  78. goto Cleanup;
  79. }
  80. //
  81. // Backup or restore appropriately.
  82. //
  83. if( FALSE == fRestore ) {
  84. Error = RegSaveKey( hKey, ConfigFileName, NULL );
  85. } else {
  86. Error = RegRestoreKey( hKey, ConfigFileName, 0 );
  87. }
  88. if( ERROR_SUCCESS != Error ) {
  89. DbgPrint("Backup/Restore: 0x%lx\n", Error);
  90. }
  91. //
  92. // revert impersonation.
  93. //
  94. Cleanup:
  95. ImpersonationToken = NULL;
  96. NtStatus = NtSetInformationThread(
  97. NtCurrentThread(),
  98. ThreadImpersonationToken,
  99. (PVOID)&ImpersonationToken,
  100. sizeof(ImpersonationToken)
  101. );
  102. if( !NT_SUCCESS(NtStatus ) ) {
  103. DbgPrint("NtSetInfo: 0x%lx\n", NtStatus);
  104. if( ERROR_SUCCESS == Error ) {
  105. Error = RtlNtStatusToDosError(NtStatus);
  106. }
  107. }
  108. return Error;
  109. }
  110. DWORD
  111. DhcpRegDeleteKey(
  112. HKEY ParentKeyHandle,
  113. LPWSTR KeyName
  114. )
  115. /*++
  116. Routine Description:
  117. This function deletes the specified key and all its subkeys.
  118. Arguments:
  119. ParentKeyHandle : handle of the parent key.
  120. KeyName : name of the key to be deleted.
  121. Return Value:
  122. Registry Errors.
  123. --*/
  124. {
  125. DWORD Error, NumSubKeys;
  126. HKEY KeyHandle = NULL;
  127. //
  128. // open key.
  129. //
  130. Error = RegOpenKeyEx(
  131. ParentKeyHandle,
  132. KeyName,
  133. 0,
  134. KEY_ALL_ACCESS,
  135. &KeyHandle );
  136. if ( Error != ERROR_SUCCESS ) {
  137. goto Cleanup;
  138. }
  139. //
  140. // query key info.
  141. //
  142. Error = RegQueryInfoKey(
  143. KeyHandle, NULL, NULL, NULL, &NumSubKeys, NULL, NULL,
  144. NULL, NULL, NULL, NULL, NULL );
  145. if( Error != ERROR_SUCCESS ) {
  146. goto Cleanup;
  147. }
  148. //
  149. // delete all its subkeys if they exist.
  150. //
  151. if( NumSubKeys != 0 ) {
  152. DWORD Index;
  153. DWORD KeyLength;
  154. WCHAR KeyBuffer[100];
  155. FILETIME KeyLastWrite;
  156. for(Index = 0; Index < NumSubKeys ; Index++ ) {
  157. //
  158. // read next subkey name.
  159. //
  160. // Note : specify '0' as index each time, since deleting
  161. // first element causes the next element as first
  162. // element after delete.
  163. //
  164. KeyLength = sizeof(KeyBuffer)/sizeof(WCHAR);
  165. Error = RegEnumKeyEx(
  166. KeyHandle,
  167. 0, // index.
  168. KeyBuffer,
  169. &KeyLength,
  170. 0, // reserved.
  171. NULL, // class string not required.
  172. 0, // class string buffer size.
  173. &KeyLastWrite );
  174. if( Error != ERROR_SUCCESS ) {
  175. goto Cleanup;
  176. }
  177. //
  178. // delete this key recursively.
  179. //
  180. Error = DhcpRegDeleteKey(
  181. KeyHandle,
  182. KeyBuffer );
  183. if( Error != ERROR_SUCCESS ) {
  184. goto Cleanup;
  185. }
  186. }
  187. }
  188. //
  189. // close the key before delete.
  190. //
  191. RegCloseKey( KeyHandle );
  192. KeyHandle = NULL;
  193. //
  194. // at last delete this key.
  195. //
  196. Error = RegDeleteKey( ParentKeyHandle, KeyName );
  197. Cleanup:
  198. if( KeyHandle == NULL ) {
  199. RegCloseKey( KeyHandle );
  200. }
  201. return( Error );
  202. }
  203. DWORD
  204. DhcpRegDeleteKeyByName(
  205. IN LPWSTR Parent,
  206. IN LPWSTR SubKey
  207. )
  208. {
  209. HKEY hKey;
  210. ULONG Error;
  211. Error = RegOpenKeyEx(
  212. HKEY_LOCAL_MACHINE,
  213. Parent,
  214. 0,
  215. KEY_ALL_ACCESS,
  216. &hKey
  217. );
  218. if( ERROR_SUCCESS != Error ) return Error;
  219. Error = DhcpRegDeleteKey(hKey, SubKey);
  220. RegCloseKey(hKey);
  221. return Error;
  222. }
  223. DWORD
  224. DhcpeximWriteRegistryConfiguration(
  225. IN PM_SERVER Server
  226. )
  227. {
  228. REG_HANDLE Hdl;
  229. DWORD Error, Disp;
  230. LPTSTR Loc, TempLoc;
  231. HKEY hKey;
  232. //
  233. // The location in the registry where things are read from is
  234. // different between whether it is NT4 or W2K.
  235. //
  236. if( IsNT4() ) Loc = DHCPEXIM_REG_CFG_LOC4;
  237. else Loc = DHCPEXIM_REG_CFG_LOC5;
  238. TempLoc = TEXT("Software\\Microsoft\\DhcpExim");
  239. //
  240. // Now open the regkey
  241. //
  242. Error = RegCreateKeyEx(
  243. HKEY_LOCAL_MACHINE, TempLoc, 0, TEXT("DHCPCLASS"),
  244. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &Hdl.Key, &Disp );
  245. if( NO_ERROR != Error ) return Error;
  246. Error = RegOpenKeyEx(
  247. HKEY_LOCAL_MACHINE, Loc, 0, KEY_ALL_ACCESS, &hKey );
  248. if( NO_ERROR != Error ) {
  249. RegCloseKey( Hdl.Key );
  250. return Error;
  251. }
  252. //
  253. // Set this as the current server
  254. //
  255. DhcpRegSetCurrentServer(&Hdl);
  256. //
  257. // Save the configuration temporarily
  258. //
  259. Error = DhcpRegServerSave(Server);
  260. //
  261. // Now attempt to save the temporary key to disk and restore
  262. // it back where it should really be and delete temp key
  263. //
  264. if( NO_ERROR == Error ) {
  265. Error = SaveOrRestoreConfigToFile(
  266. Hdl.Key, L"Dhcpexim.reg", FALSE );
  267. if( NO_ERROR == Error ) {
  268. Error = SaveOrRestoreConfigToFile(
  269. hKey, L"Dhcpexim.reg", TRUE );
  270. if( NO_ERROR == Error ) {
  271. RegCloseKey(Hdl.Key);
  272. Hdl.Key = NULL;
  273. DhcpRegDeleteKeyByName(
  274. L"Software\\Microsoft", L"DhcpExim" );
  275. }
  276. }
  277. }
  278. if( NULL != Hdl.Key ) RegCloseKey(Hdl.Key);
  279. RegCloseKey(hKey);
  280. DhcpRegSetCurrentServer(NULL);
  281. return Error;
  282. }