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.

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