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.

468 lines
13 KiB

  1. //-----------------------------------------------------------------------//
  2. //
  3. // File: export.cpp
  4. // Created: April 1997
  5. // By: Zeyong Xu
  6. // Purpose: Support EXPORT and IMPORT .reg file
  7. //
  8. //------------------------------------------------------------------------//
  9. #include "stdafx.h"
  10. #include "reg.h"
  11. #include "regporte.h"
  12. //
  13. // global variables
  14. //
  15. extern UINT g_FileErrorStringID;
  16. extern DWORD g_dwTotalKeysSaved;
  17. //
  18. // function prototypes
  19. //
  20. BOOL ParseExportCmdLine( DWORD argc, LPCWSTR argv[],
  21. PTREG_PARAMS pParams, BOOL* pbUsage );
  22. BOOL ParseImportCmdLine( DWORD argc, LPCWSTR argv[],
  23. PTREG_PARAMS pParams, BOOL* pbUsage );
  24. //
  25. // implementation
  26. //
  27. //-----------------------------------------------------------------------
  28. //
  29. // ExportRegFile()
  30. //
  31. //-----------------------------------------------------------------------
  32. LONG
  33. ExportRegistry( DWORD argc, LPCWSTR argv[] )
  34. {
  35. // local variables
  36. HKEY hKey = NULL;
  37. BOOL bResult = 0;
  38. LONG lResult = 0;
  39. TREG_PARAMS params;
  40. BOOL bUsage = FALSE;
  41. HANDLE hFile = NULL;
  42. LPCWSTR pwszFormat = NULL;
  43. LPCWSTR pwszList = NULL;
  44. if ( argc == 0 || argv == NULL )
  45. {
  46. SetLastError( ERROR_INVALID_PARAMETER );
  47. ShowLastError( stderr );
  48. return 1;
  49. }
  50. // initialize the global data structure
  51. InitGlobalData( REG_EXPORT, &params );
  52. //
  53. // Parse the cmd-line
  54. //
  55. bResult = ParseExportCmdLine( argc, argv, &params, &bUsage );
  56. if( bResult == FALSE )
  57. {
  58. ShowLastErrorEx( stderr, SLE_INTERNAL );
  59. FreeGlobalData( &params );
  60. return 1;
  61. }
  62. // check whether we need to display the usage
  63. if ( bUsage == TRUE )
  64. {
  65. Usage( REG_EXPORT );
  66. FreeGlobalData( &params );
  67. return 0;
  68. }
  69. //
  70. // check if the key existed
  71. //
  72. bResult = TRUE;
  73. lResult = RegOpenKeyEx( params.hRootKey, params.pwszSubKey, 0, KEY_READ, &hKey );
  74. if( lResult == ERROR_SUCCESS )
  75. {
  76. // close the reg key
  77. SafeCloseKey( &hKey );
  78. //
  79. // now it is time to check the existence of the file
  80. hFile = CreateFile( params.pwszValueName,
  81. GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, 0, 0 );
  82. if ( hFile != INVALID_HANDLE_VALUE )
  83. {
  84. //
  85. // file is existing
  86. //
  87. // close the handle first -- we dont need it
  88. CloseHandle( hFile );
  89. // load the format strings
  90. pwszList = GetResString2( IDS_CONFIRM_CHOICE_LIST, 1 );
  91. pwszFormat = GetResString2( IDS_SAVE_OVERWRITE_CONFIRM, 0 );
  92. // ...
  93. do
  94. {
  95. lResult = Prompt( pwszFormat,
  96. params.pwszValueName, pwszList, params.bForce );
  97. } while ( lResult > 2 );
  98. // check the user's choice
  99. lResult = (lResult == 1) ? ERROR_SUCCESS : ERROR_CANCELLED;
  100. }
  101. else
  102. {
  103. //
  104. // failed to open the file
  105. // find out why it is failed
  106. //
  107. lResult = GetLastError();
  108. if ( lResult == ERROR_FILE_NOT_FOUND )
  109. {
  110. lResult = ERROR_SUCCESS;
  111. }
  112. else
  113. {
  114. bResult = FALSE;
  115. lResult = IDS_EXPFILEERRFILEWRITE;
  116. }
  117. }
  118. // ...
  119. if ( lResult == ERROR_SUCCESS )
  120. {
  121. // since there are chances of getting access problems --
  122. // instead of directly manipulating with the original file name, we will try to
  123. // save the data using temporary file name and then transfer
  124. // the contents to the orignal filename
  125. params.pwszValue = params.pwszValueName;
  126. params.pwszValueName = GetTemporaryFileName( params.pwszValueName );
  127. if ( params.pwszValueName == NULL )
  128. {
  129. bResult = FALSE;
  130. lResult = IDS_EXPFILEERRFILEWRITE;
  131. }
  132. else
  133. {
  134. // ...
  135. ExportWinNT50RegFile( params.pwszValueName, params.pwszFullKey );
  136. //
  137. // in order make REG in sync with REGEDIt, we are absolutely
  138. // ignoring all the errors that are generated during the export
  139. // process -- so, result 99% EXPORT will always results in
  140. // successful return except when the root hive is not accessible
  141. // and if there are any syntax errors
  142. // in future if one wants to do minimal error checking, just
  143. // uncomment the below code and you are set
  144. //
  145. // if ( g_dwTotalKeysSaved > 0 ||
  146. // g_FileErrorStringID == IDS_EXPFILEERRSUCCESS )
  147. {
  148. if ( CopyFile( params.pwszValueName, params.pwszValue, FALSE ) == FALSE )
  149. {
  150. bResult = FALSE;
  151. lResult = IDS_EXPFILEERRFILEWRITE;
  152. }
  153. }
  154. // else if ( g_FileErrorStringID == IDS_EXPFILEERRBADREGPATH ||
  155. // g_FileErrorStringID == IDS_EXPFILEERRREGENUM ||
  156. // g_FileErrorStringID == IDS_EXPFILEERRREGOPEN ||
  157. // g_FileErrorStringID == IDS_EXPFILEERRFILEOPEN )
  158. // {
  159. // lResult = ERROR_ACCESS_DENIED;
  160. // }
  161. // else
  162. // {
  163. // bResult = FALSE;
  164. // lResult = g_FileErrorStringID;
  165. // }
  166. // delete the temporary file
  167. DeleteFile( params.pwszValueName );
  168. }
  169. }
  170. }
  171. else
  172. {
  173. if ( lResult == ERROR_INVALID_HANDLE )
  174. {
  175. bResult = FALSE;
  176. lResult = IDS_EXPFILEERRINVALID;
  177. }
  178. }
  179. if ( lResult == ERROR_SUCCESS || lResult == ERROR_CANCELLED )
  180. {
  181. SaveErrorMessage( lResult );
  182. ShowLastErrorEx( stdout, SLE_INTERNAL );
  183. lResult = 0;
  184. }
  185. else
  186. {
  187. if ( bResult == FALSE )
  188. {
  189. SetReason( GetResString2( lResult, 0 ) );
  190. }
  191. else
  192. {
  193. SaveErrorMessage( lResult );
  194. }
  195. // ...
  196. lResult = 1;
  197. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  198. }
  199. // ...
  200. FreeGlobalData( &params );
  201. return lResult;
  202. }
  203. //------------------------------------------------------------------------
  204. //
  205. // ParseCmdLine()
  206. //
  207. //------------------------------------------------------------------------
  208. BOOL
  209. ParseExportCmdLine( DWORD argc, LPCWSTR argv[],
  210. PTREG_PARAMS pParams, BOOL* pbUsage )
  211. {
  212. // local variables
  213. DWORD dwLength = 0;
  214. BOOL bResult = FALSE;
  215. // check the input
  216. if ( argc == 0 || argv == NULL || pParams == NULL || pbUsage == NULL )
  217. {
  218. SaveErrorMessage( ERROR_INVALID_PARAMETER );
  219. return FALSE;
  220. }
  221. // check whether this function is being called for
  222. // valid operation or not
  223. if ( pParams->lOperation < 0 || pParams->lOperation >= REG_OPTIONS_COUNT )
  224. {
  225. SaveErrorMessage( ERROR_INVALID_PARAMETER );
  226. return FALSE;
  227. }
  228. //
  229. // Do we have a *valid* number of cmd-line params
  230. //
  231. if ( InString( argv[ 2 ], L"-?|/?|-h|/h", TRUE ) == TRUE )
  232. {
  233. if ( argc == 3 )
  234. {
  235. *pbUsage = TRUE;
  236. return TRUE;
  237. }
  238. else
  239. {
  240. SetLastError( (DWORD) MK_E_SYNTAX );
  241. SetReason2( 1, ERROR_INVALID_SYNTAX_WITHOPT, g_wszOptions[ REG_EXPORT ] );
  242. return FALSE;
  243. }
  244. }
  245. else if ( argc < 4 || argc > 5 )
  246. {
  247. SetLastError( (DWORD) MK_E_SYNTAX );
  248. SetReason2( 1, ERROR_INVALID_SYNTAX_WITHOPT, g_wszOptions[ REG_EXPORT ] );
  249. return FALSE;
  250. }
  251. // Machine Name and Registry key
  252. //
  253. bResult = BreakDownKeyString( argv[ 2 ], pParams );
  254. if( bResult == FALSE )
  255. {
  256. return FALSE;
  257. }
  258. // current, not remotable
  259. if ( pParams->bUseRemoteMachine == TRUE )
  260. {
  261. SetLastError( (DWORD) MK_E_SYNTAX );
  262. SetReason( ERROR_NONREMOTABLEROOT_EXPORT );
  263. return FALSE;
  264. }
  265. //
  266. // Get the FileName - using the szValueName string field to hold it
  267. //
  268. dwLength = StringLength( argv[ 3 ], 0 ) + 5;
  269. pParams->pwszValueName = (LPWSTR) AllocateMemory( dwLength * sizeof(WCHAR) );
  270. if ( pParams->pwszValueName == NULL )
  271. {
  272. SaveLastError();
  273. return FALSE;
  274. }
  275. // ...
  276. StringCopy( pParams->pwszValueName, argv[ 3 ], dwLength );
  277. // validate the file name -- it should not be empty
  278. TrimString( pParams->pwszValueName, TRIM_ALL );
  279. if ( StringLength( pParams->pwszValueName, 0 ) == 0 )
  280. {
  281. SetLastError( (DWORD) MK_E_SYNTAX );
  282. SetReason2( 1, ERROR_INVALID_SYNTAX_WITHOPT, g_wszOptions[ REG_EXPORT ] );
  283. return FALSE;
  284. }
  285. // check if user specified overwrite flag or not
  286. pParams->bForce = FALSE;
  287. if ( argc == 5 )
  288. {
  289. if ( StringCompareEx( argv[ 4 ], L"/y", TRUE, 0 ) == 0 )
  290. {
  291. pParams->bForce = TRUE;
  292. }
  293. else
  294. {
  295. SetLastError( (DWORD) MK_E_SYNTAX );
  296. SetReason2( 1, ERROR_INVALID_SYNTAX_WITHOPT, g_wszOptions[ REG_EXPORT ] );
  297. return FALSE;
  298. }
  299. }
  300. // return
  301. return TRUE;
  302. }
  303. //-----------------------------------------------------------------------
  304. //
  305. // ImportRegFile()
  306. //
  307. //-----------------------------------------------------------------------
  308. LONG
  309. ImportRegistry( DWORD argc, LPCWSTR argv[] )
  310. {
  311. // local variables
  312. BOOL bResult = 0;
  313. LONG lResult = 0;
  314. TREG_PARAMS params;
  315. BOOL bUsage = FALSE;
  316. if ( argc == 0 || argv == NULL )
  317. {
  318. SetLastError( ERROR_INVALID_PARAMETER );
  319. ShowLastError( stderr );
  320. return 1;
  321. }
  322. // initialize the global data structure
  323. InitGlobalData( REG_IMPORT, &params );
  324. //
  325. // Parse the cmd-line
  326. //
  327. bResult = ParseImportCmdLine( argc, argv, &params, &bUsage );
  328. if( bResult == FALSE )
  329. {
  330. ShowLastErrorEx( stderr, SLE_INTERNAL );
  331. FreeGlobalData( &params );
  332. return 1;
  333. }
  334. // check whether we need to display the usage
  335. if ( bUsage == TRUE )
  336. {
  337. Usage( REG_IMPORT );
  338. FreeGlobalData( &params );
  339. return 0;
  340. }
  341. //
  342. // do the import
  343. //
  344. ImportRegFileWorker( params.pwszValueName );
  345. if ( g_FileErrorStringID == IDS_IMPFILEERRSUCCESS )
  346. {
  347. SaveErrorMessage( ERROR_SUCCESS );
  348. ShowLastErrorEx( stderr, SLE_INTERNAL );
  349. lResult = 0;
  350. }
  351. else
  352. {
  353. switch( g_FileErrorStringID )
  354. {
  355. default:
  356. {
  357. SetReason( GetResString( g_FileErrorStringID ) );
  358. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  359. lResult = 1;
  360. }
  361. }
  362. }
  363. FreeGlobalData( &params );
  364. return lResult;
  365. }
  366. //------------------------------------------------------------------------
  367. //
  368. // ParseCmdLine()
  369. //
  370. //------------------------------------------------------------------------
  371. BOOL
  372. ParseImportCmdLine( DWORD argc, LPCWSTR argv[],
  373. PTREG_PARAMS pParams, BOOL* pbUsage )
  374. {
  375. // local variables
  376. DWORD dwLength = 0;
  377. // check the input
  378. if ( argc == 0 || argv == NULL || pParams == NULL || pbUsage == NULL )
  379. {
  380. SaveErrorMessage( ERROR_INVALID_PARAMETER );
  381. return FALSE;
  382. }
  383. // check whether this function is being called for
  384. // valid operation or not
  385. if ( pParams->lOperation < 0 || pParams->lOperation >= REG_OPTIONS_COUNT )
  386. {
  387. SaveErrorMessage( ERROR_INVALID_PARAMETER );
  388. return FALSE;
  389. }
  390. //
  391. // Do we have a *valid* number of cmd-line params
  392. //
  393. if ( argc != 3 )
  394. {
  395. SetLastError( (DWORD) MK_E_SYNTAX );
  396. SetReason2( 1, ERROR_INVALID_SYNTAX_WITHOPT, g_wszOptions[ REG_IMPORT ] );
  397. return FALSE;
  398. }
  399. else if ( InString( argv[ 2 ], L"-?|/?|-h|/h", TRUE ) == TRUE )
  400. {
  401. *pbUsage = TRUE;
  402. return TRUE;
  403. }
  404. //
  405. // Get the FileName - using the szValueName string field to hold it
  406. //
  407. dwLength = StringLength( argv[ 2 ], 0 ) + 1;
  408. pParams->pwszValueName = (LPWSTR) AllocateMemory( dwLength * sizeof(WCHAR) );
  409. if ( pParams->pwszValueName == NULL )
  410. {
  411. SaveLastError();
  412. return FALSE;
  413. }
  414. // ...
  415. StringCopy( pParams->pwszValueName, argv[ 2 ], dwLength );
  416. // return
  417. return TRUE;
  418. }