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.

682 lines
16 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1998 - 2001
  4. Module Name:
  5. netdom5.cxx
  6. Abstract:
  7. Command line utility for taking care of all the desired net operations
  8. --*/
  9. #include "pch.h"
  10. #pragma hdrstop
  11. #include "netdom.h"
  12. #include "CompName.h"
  13. HINSTANCE g_hInstance = NULL;
  14. BOOL Verbose = FALSE;
  15. //+----------------------------------------------------------------------------
  16. //
  17. // Function: GetPrimaryArg
  18. //
  19. // Synopsis: The second argument of the command line should be the primary
  20. // command (the first is the program name).
  21. //
  22. // Arguments: [rgNetDomArgs] - The command line argument array.
  23. // [pTokens] - the token array.
  24. // [PriCmd] - the out parameter reference.
  25. //
  26. // Returns: Success or error.
  27. //
  28. //-----------------------------------------------------------------------------
  29. DWORD
  30. GetPrimaryArg(ARG_RECORD * rgNetDomArgs, CToken * pTokens,
  31. NETDOM_ARG_ENUM & PriCmd)
  32. {
  33. if (!rgNetDomArgs || !pTokens || !(pTokens + 1))
  34. {
  35. ASSERT(FALSE);
  36. return ERROR_INVALID_PARAMETER;
  37. }
  38. PWSTR str = (pTokens + 1)->GetToken();
  39. if (!str) return ERROR_INVALID_PARAMETER;
  40. if ((pTokens + 1)->IsSwitch())
  41. {
  42. str++;
  43. }
  44. for (int i = eArgBegin; i < ePriEnd; i += 1)
  45. {
  46. // NOTICE-2002/02/26-ericb - SecurityPush: the argument array strings
  47. // are all loaded from the resource fork.
  48. if (rgNetDomArgs[i].strArg1 && !_wcsicmp(str, rgNetDomArgs[i].strArg1) ||
  49. rgNetDomArgs[i].strArg2 && !_wcsicmp(str, rgNetDomArgs[i].strArg2))
  50. {
  51. PriCmd = (NETDOM_ARG_ENUM)i;
  52. return ERROR_SUCCESS;
  53. }
  54. }
  55. return ERROR_INVALID_PARAMETER;
  56. }
  57. //+----------------------------------------------------------------------------
  58. //
  59. // Function: GetHelpTarget
  60. //
  61. // Synopsis: If the second argument of the command line is help, the next
  62. // arg can be either SYNTAX or a primary command.
  63. //
  64. // Arguments: [rgNetDomArgs] - The command line argument array.
  65. // [pTokens] - the token array.
  66. // [argc] - the count of arguments.
  67. //
  68. //-----------------------------------------------------------------------------
  69. void
  70. GetHelpTarget(ARG_RECORD * rgNetDomArgs, CToken * pTokens, int argc, NETDOM_ARG_ENUM ePrimaryCmd)
  71. {
  72. if (!rgNetDomArgs || !pTokens || !(pTokens + 1) || !(pTokens + 2))
  73. {
  74. ASSERT(FALSE);
  75. DisplayHelp(ePriHelp);
  76. return;
  77. }
  78. if (argc < 3)
  79. {
  80. DisplayHelp(ePriHelp);
  81. return;
  82. }
  83. PWSTR str = (pTokens + 2)->GetToken();
  84. if (!str)
  85. {
  86. DisplayHelp(ePriHelp);
  87. return;
  88. }
  89. if ((pTokens + 2)->IsSwitch())
  90. {
  91. str++;
  92. }
  93. // NOTICE-2002/02/26-ericb - SecurityPush: the argument array strings
  94. // are all loaded from the resource fork.
  95. if (rgNetDomArgs[eHelpSyntax].strArg1 &&
  96. !_wcsicmp(str, rgNetDomArgs[eHelpSyntax].strArg1))
  97. {
  98. DisplayHelp(eHelpSyntax);
  99. }
  100. for (int i = eArgBegin; i < ePriEnd; i += 1)
  101. {
  102. if (rgNetDomPriArgs[i].strArg1 && !_wcsicmp(str, rgNetDomPriArgs[i].strArg1))
  103. {
  104. if ( ePrimaryCmd == ePriExpertHelp )
  105. {
  106. DisplayExpertHelp ( (NETDOM_ARG_ENUM) i );
  107. }
  108. else
  109. {
  110. DisplayHelp ( (NETDOM_ARG_ENUM) i );
  111. }
  112. return;
  113. }
  114. }
  115. DisplayHelp(ePriHelp);
  116. }
  117. VOID
  118. NetDompDisplayMessage(
  119. IN DWORD MessageId,
  120. ...
  121. )
  122. /*++
  123. Routine Description:
  124. Loads the resource out of the executable and displays it.
  125. Arguments:
  126. MessageId - Id of the message to load
  127. ... - Optional list of parameters
  128. Return Value:
  129. VOID
  130. --*/
  131. {
  132. PWSTR MessageDisplayString;
  133. va_list ArgList;
  134. ULONG Length;
  135. va_start( ArgList, MessageId );
  136. // NOTICE-2002/02/27-ericb - SecurityPush: the netdom output routines should
  137. // be modified to use the command parser output routine WriteStandardOut in varg.cxx.
  138. // (shasan-2002/04/18 - fixed, using DisplayOutput instead )
  139. Length = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  140. NULL,
  141. MessageId,
  142. 0,
  143. ( PWSTR )&MessageDisplayString,
  144. 0,
  145. &ArgList );
  146. if ( Length != 0 ) {
  147. DisplayOutput ( MessageDisplayString );
  148. LocalFree( MessageDisplayString );
  149. #if DBG
  150. } else {
  151. printf( "Failed to format buffer for %lu: %lu\n", MessageId, GetLastError() );
  152. #endif
  153. }
  154. va_end( ArgList );
  155. }
  156. VOID
  157. NetDompDisplayMessageAndError(
  158. IN DWORD MessageId,
  159. IN DWORD Error,
  160. IN PCWSTR String
  161. )
  162. /*++
  163. Routine Description:
  164. Loads the resource out of the executable and displays it.
  165. Arguments:
  166. MessageId - Id of the message to load
  167. Error - Error message to display
  168. Return Value:
  169. VOID
  170. --*/
  171. {
  172. #if DBG
  173. DWORD Win32Err = ERROR_SUCCESS;
  174. #endif
  175. PWSTR ErrorString, Lop;
  176. ULONG Length;
  177. // NOTICE-2002/02/27-ericb - SecurityPush: the netdom output routines should
  178. // be modified to use the command parser output routine WriteStandardOut in varg.cxx.
  179. // (shasan-2002/04/18 - No change necessary )
  180. Length = FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM |
  181. FORMAT_MESSAGE_ALLOCATE_BUFFER,
  182. NULL,
  183. Error,
  184. 0,
  185. ( PWSTR )&ErrorString,
  186. 0,
  187. NULL );
  188. if ( Length == 0 ) {
  189. #if DBG
  190. Win32Err = GetLastError();
  191. #endif
  192. } else {
  193. Lop = wcsrchr( ErrorString, L'\n' );
  194. if ( Lop ) {
  195. *Lop = UNICODE_NULL;
  196. if ( Lop != ErrorString ) {
  197. *(Lop - 1 ) = UNICODE_NULL;
  198. }
  199. }
  200. NetDompDisplayMessage( MessageId, String, ErrorString );
  201. LocalFree( ErrorString );
  202. }
  203. }
  204. VOID
  205. NetDompDisplayErrorMessage(
  206. IN DWORD Error
  207. )
  208. /*++
  209. Routine Description:
  210. This function display the error string for the given error status
  211. Arguments:
  212. Error - Status to display the message for
  213. Return Value:
  214. VOID
  215. --*/
  216. {
  217. HMODULE NetMsgHandle = NULL;
  218. ULONG Size = 0;
  219. PWSTR DisplayString = NULL;
  220. ULONG Options = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM;
  221. //
  222. // Load and display the net errors, if that is what we were given
  223. //
  224. if ( Error >= 2100 && Error <= 3000 ) {
  225. //
  226. // If it fails to load, it's not the end of the world. We just won't be able
  227. // to map the message
  228. //
  229. NetMsgHandle = LoadLibraryEx( L"netmsg.dll", NULL, LOAD_LIBRARY_AS_DATAFILE );
  230. if ( NetMsgHandle ) {
  231. Options |= FORMAT_MESSAGE_FROM_HMODULE;
  232. }
  233. }
  234. // NOTICE-2002/02/27-ericb - SecurityPush: the netdom output routines should
  235. // be modified to use the command parser output routine WriteStandardOut in varg.cxx.
  236. // (shasan-2002/04/18 - fixed, using DisplayOutput instead )
  237. Size = FormatMessage( Options,
  238. ( LPCVOID )NetMsgHandle,
  239. Error,
  240. MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
  241. ( LPTSTR )&DisplayString,
  242. 0,
  243. NULL );
  244. if ( Size != 0 ) {
  245. DisplayOutput( DisplayString );
  246. LocalFree( DisplayString );
  247. #if DBG
  248. } else {
  249. printf( "Failed to map %lu: %lu\n", Error, GetLastError() );
  250. #endif
  251. }
  252. if ( NetMsgHandle ) {
  253. FreeLibrary( NetMsgHandle );
  254. }
  255. }
  256. VOID
  257. NetDompDisplayUnexpectedParameter(
  258. IN PWSTR UnexpectedParameter
  259. )
  260. {
  261. NetDompDisplayMessage(MSG_NETDOM5_UNEXPECTED, UnexpectedParameter);
  262. }
  263. VOID
  264. DisplayExpertHelp(NETDOM_ARG_ENUM HelpOp)
  265. /*++
  266. Routine Description:
  267. This function displays the Expert Help associated with a given operation
  268. --*/
  269. {
  270. NetDompDisplayMessage( MSG_NETDOM5_SYNTAX );
  271. switch (HelpOp)
  272. {
  273. case ePriTrust:
  274. NetDompDisplayMessage( MSG_NETDOM5_EXPERT_HELP_TRUST );
  275. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  276. break;
  277. default:
  278. NetDompDisplayMessage( MSG_NETDOM5_COMMAND_USAGE );
  279. break;
  280. }
  281. }
  282. VOID
  283. DisplayHelp(NETDOM_ARG_ENUM HelpOp)
  284. /*++
  285. Routine Description:
  286. This function displays the help associated with a given operation
  287. --*/
  288. {
  289. NetDompDisplayMessage( MSG_NETDOM5_SYNTAX );
  290. switch (HelpOp)
  291. {
  292. case ePriHelp:
  293. NetDompDisplayMessage( MSG_NETDOM5_COMMAND_USAGE );
  294. break;
  295. case eHelpSyntax:
  296. NetDompDisplayMessage( MSG_NETDOM5_HELP_SYNTAX );
  297. break;
  298. case ePriAdd:
  299. NetDompDisplayMessage( MSG_NETDOM5_HELP_ADD );
  300. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  301. break;
  302. case ePriCompName:
  303. NetDompDisplayMessage( MSG_NETDOM5_HELP_COMPUERNAME );
  304. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  305. break;
  306. case ePriJoin:
  307. NetDompDisplayMessage( MSG_NETDOM5_HELP_JOIN );
  308. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  309. break;
  310. case ePriMove:
  311. NetDompDisplayMessage( MSG_NETDOM5_HELP_MOVE );
  312. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  313. break;
  314. case ePriQuery:
  315. NetDompDisplayMessage( MSG_NETDOM5_HELP_QUERY );
  316. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  317. break;
  318. case ePriRemove:
  319. NetDompDisplayMessage( MSG_NETDOM5_HELP_REMOVE );
  320. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  321. break;
  322. case ePriMoveNT4BDC:
  323. NetDompDisplayMessage( MSG_NETDOM5_HELP_MOVENT4BDC );
  324. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  325. break;
  326. case ePriRenameComputer:
  327. NetDompDisplayMessage( MSG_NETDOM5_HELP_RENAMECOMPUTER );
  328. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  329. break;
  330. case ePriReset:
  331. NetDompDisplayMessage( MSG_NETDOM5_HELP_RESET );
  332. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  333. break;
  334. case ePriResetPwd:
  335. NetDompDisplayMessage( MSG_NETDOM5_HELP_RESETPWD );
  336. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  337. break;
  338. case ePriTrust:
  339. NetDompDisplayMessage( MSG_NETDOM5_HELP_TRUST );
  340. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  341. break;
  342. case ePriVerify:
  343. NetDompDisplayMessage( MSG_NETDOM5_HELP_VERIFY );
  344. NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  345. break;
  346. // case ePriTime:
  347. // NetDompDisplayMessage( MSG_NETDOM5_HELP_TIME );
  348. // NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
  349. // break;
  350. default:
  351. NetDompDisplayMessage( MSG_NETDOM5_COMMAND_USAGE );
  352. break;
  353. }
  354. }
  355. int __cdecl _tmain(VOID)
  356. {
  357. DWORD Win32Err = ERROR_SUCCESS;
  358. g_hInstance = GetModuleHandle(NULL);
  359. setlocale(LC_CTYPE, "");
  360. //
  361. // Parse the command line
  362. //
  363. int argc = 0;
  364. CToken * pTokens = NULL;
  365. PARSE_ERROR Error = {0};
  366. Win32Err = GetCommandInput(&argc, &pTokens);
  367. if (ERROR_SUCCESS != Win32Err)
  368. {
  369. NetDompDisplayErrorMessage(Win32Err);
  370. goto Netdom5Exit;
  371. }
  372. //
  373. // Display the help.
  374. //
  375. if (argc < 2)
  376. {
  377. NetDompDisplayMessage(MSG_NETDOM5_SYNTAX);
  378. NetDompDisplayMessage(MSG_NETDOM5_USAGE);
  379. goto Netdom5Exit;
  380. }
  381. NETDOM_ARG_ENUM ePrimaryCmd = ePriHelp;
  382. if (!LoadCmd(rgNetDomArgs) || !LoadCmd(rgNetDomPriArgs))
  383. {
  384. Win32Err = ERROR_NOT_ENOUGH_MEMORY;
  385. goto Netdom5Exit;
  386. }
  387. Win32Err = GetPrimaryArg(rgNetDomPriArgs, pTokens, ePrimaryCmd);
  388. if (ERROR_SUCCESS != Win32Err)
  389. {
  390. PWSTR wzTok = (pTokens + 1)->GetToken();
  391. if (wzTok)
  392. {
  393. NetDompDisplayUnexpectedParameter(wzTok);
  394. }
  395. goto Netdom5Exit;
  396. }
  397. //
  398. // Handle the help case
  399. //
  400. if (ePriHelp == ePrimaryCmd || ePriHelp2 == ePrimaryCmd || ePriExpertHelp == ePrimaryCmd )
  401. {
  402. GetHelpTarget( rgNetDomArgs, pTokens, argc, ePrimaryCmd );
  403. goto Netdom5Exit;
  404. }
  405. if (argc < 3)
  406. {
  407. // All commands require at least one argument after the primary command.
  408. //
  409. DisplayHelp(ePrimaryCmd);
  410. goto Netdom5Exit;
  411. }
  412. bool fSkipObject = false;
  413. //
  414. // The QUERY and RESETPWD commands don't take an "object" parameter.
  415. //
  416. if (ePriQuery == ePrimaryCmd || ePriResetPwd == ePrimaryCmd)
  417. {
  418. fSkipObject = true;
  419. }
  420. if (!ParseCmd(rgNetDomArgs,
  421. argc - 2, // skip the program name and primary arg.
  422. pTokens + 2,
  423. fSkipObject,
  424. &Error))
  425. {
  426. if (Error.Error == PARSE_ERROR_HELP_SWITCH)
  427. {
  428. DisplayHelp(ePrimaryCmd);
  429. }
  430. else if ( Error.Error == PARSE_ERROR_EXPERT_HELP_SWITCH)
  431. {
  432. DisplayExpertHelp(ePrimaryCmd);
  433. }
  434. else
  435. {
  436. //
  437. // Display the usage text
  438. //
  439. NetDompDisplayMessage(MSG_NETDOM5_SYNTAX);
  440. NetDompDisplayMessage(MSG_NETDOM5_USAGE);
  441. Win32Err = ERROR_INVALID_PARAMETER;
  442. }
  443. goto Netdom5Exit;
  444. }
  445. if (CmdFlagOn(rgNetDomArgs, eCommHelp) || CmdFlagOn(rgNetDomArgs, eCommQHelp))
  446. {
  447. DisplayHelp(ePrimaryCmd);
  448. goto Netdom5Exit;
  449. }
  450. if (CmdFlagOn(rgNetDomArgs, eCommExpertHelp))
  451. {
  452. DisplayExpertHelp(ePrimaryCmd);
  453. goto Netdom5Exit;
  454. }
  455. //
  456. // Make sure the object name followed the primary command. The query and
  457. // ResetPwd primary operations don't use the object param.
  458. //
  459. if (!fSkipObject && !rgNetDomArgs[eObject].strValue)
  460. {
  461. if (argc > 2)
  462. {
  463. PWSTR wzTok = (pTokens + 2)->GetToken();
  464. if (wzTok)
  465. {
  466. NetDompDisplayUnexpectedParameter(wzTok);
  467. }
  468. }
  469. NetDompDisplayMessage(MSG_NETDOM5_SYNTAX);
  470. NetDompDisplayMessage(MSG_NETDOM5_USAGE);
  471. Win32Err = ERROR_INVALID_PARAMETER;
  472. goto Netdom5Exit;
  473. }
  474. Verbose = CmdFlagOn(rgNetDomArgs, eCommVerbose);
  475. switch (ePrimaryCmd)
  476. {
  477. case ePriAdd:
  478. Win32Err = NetDompHandleAdd(rgNetDomArgs);
  479. break;
  480. case ePriCompName:
  481. Win32Err = NetDomComputerNames(rgNetDomArgs);
  482. break;
  483. case ePriJoin:
  484. Win32Err = NetDompHandleJoin(rgNetDomArgs, FALSE);
  485. break;
  486. case ePriMove:
  487. Win32Err = NetDompHandleMove(rgNetDomArgs);
  488. break;
  489. case ePriQuery:
  490. Win32Err = NetDompHandleQuery(rgNetDomArgs);
  491. break;
  492. case ePriRemove:
  493. Win32Err = NetDompHandleRemove(rgNetDomArgs);
  494. break;
  495. // case ePriTime:
  496. // Win32Err = NetDompHandleTime(rgNetDomArgs);
  497. // break;
  498. case ePriMoveNT4BDC:
  499. Win32Err = NetDompHandleMoveNT4BDC(rgNetDomArgs);
  500. break;
  501. case ePriRenameComputer:
  502. Win32Err = NetDompHandleRenameComputer(rgNetDomArgs);
  503. break;
  504. case ePriReset:
  505. Win32Err = NetDompHandleReset(rgNetDomArgs);
  506. break;
  507. case ePriResetPwd:
  508. Win32Err = NetDompHandleResetPwd(rgNetDomArgs);
  509. break;
  510. case ePriTrust:
  511. Win32Err = NetDompHandleTrust(rgNetDomArgs);
  512. break;
  513. case ePriVerify:
  514. Win32Err = NetDompHandleVerify(rgNetDomArgs);
  515. break;
  516. default:
  517. Win32Err = ERROR_INVALID_PARAMETER;
  518. break;
  519. }
  520. Netdom5Exit:
  521. if (pTokens)
  522. {
  523. delete [] pTokens;
  524. }
  525. FreeCmd(rgNetDomArgs);
  526. FreeCmd(rgNetDomPriArgs);
  527. if (Win32Err == ERROR_SUCCESS)
  528. {
  529. NetDompDisplayMessage( MSG_NETDOM5_SUCCESS );
  530. }
  531. else
  532. {
  533. if (ERROR_INVALID_PARAMETER == Win32Err)
  534. {
  535. NetDompDisplayMessage(MSG_NETDOM5_HELPHINT);
  536. }
  537. else
  538. {
  539. NetDompDisplayMessage(MSG_NETDOM5_FAILURE);
  540. }
  541. }
  542. return(Win32Err);
  543. }