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.

973 lines
30 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation
  3. All rights reserved.
  4. Module Name: waitfor.cpp
  5. Abstract
  6. This module is used to send and receive signals.
  7. Author:
  8. Microsoft
  9. Revision History:
  10. Created by Microsoft
  11. Modified on 29-6-2000 by Wipro Technologies
  12. --*/
  13. #include "pch.h"
  14. #include "resource.h"
  15. #include "waitfor.h"
  16. #include <strsafe.h>
  17. struct Params
  18. {
  19. const WCHAR *szSignalName; // To hold the name of the signal
  20. BOOL fSignal; // To hold the Boolean
  21. UINT uiTimeOut; // To hold the Time to wait for.
  22. };
  23. class CWaitFor
  24. {
  25. private:
  26. WCHAR m_szSignal[MAX_STRING_LENGTH] ;
  27. WCHAR m_szServer[MAX_STRING_LENGTH];
  28. LPWSTR m_szUserName;
  29. WCHAR m_szPassword[MAX_STRING_LENGTH] ;
  30. WCHAR m_szDefault[MAX_STRING_LENGTH] ;
  31. BOOL m_bNeedPwd ;
  32. BOOL m_bConnFlag ;
  33. LONG m_dwTimeOut ;
  34. BOOL m_bLocalSystem;
  35. TCMDPARSER2 cmdOptions[MAX_OPTIONS] ;
  36. Params m_Parameters ;
  37. public:
  38. VOID ShowUsage();
  39. DWORD ProcessCmdLine();
  40. CWaitFor();
  41. ~CWaitFor();
  42. DWORD ProcessOptions( DWORD argc ,LPCWSTR argv[] ) ;
  43. DWORD PerformOperations();
  44. DWORD CheckForValidCharacters();
  45. DWORD ConnectRemoteServer();
  46. public:
  47. BOOL bShowUsage ;
  48. };
  49. CWaitFor ::CWaitFor()
  50. /*++
  51. Routine description : Constructor
  52. Arguments : none
  53. Return Value : None
  54. --*/
  55. {
  56. //Initialise the variables.
  57. StringCopy(m_szSignal,NULL_U_STRING, SIZE_OF_ARRAY(m_szSignal));
  58. StringCopy(m_szServer,NULL_U_STRING, SIZE_OF_ARRAY(m_szPassword));
  59. StringCopy(m_szPassword,NULL_U_STRING, SIZE_OF_ARRAY(m_szPassword));
  60. StringCopy(m_szDefault,NULL_U_STRING, SIZE_OF_ARRAY(m_szDefault));
  61. m_szUserName = NULL;
  62. m_bNeedPwd = FALSE;
  63. m_bLocalSystem = FALSE;
  64. m_dwTimeOut = 0 ;
  65. m_bConnFlag = TRUE ;
  66. bShowUsage = FALSE;
  67. }
  68. CWaitFor :: ~CWaitFor()
  69. /*++
  70. Routine description : Destructor. All the memory frreing is being done here
  71. The connection established to the remote system is also
  72. being closed here if required.
  73. Arguments : None.
  74. Return Value : None
  75. --*/
  76. {
  77. //
  78. // Closing the connection to the remote system
  79. // if there is no previous connection established
  80. //
  81. if(m_bConnFlag == TRUE && !m_bLocalSystem)
  82. {
  83. CloseConnection(m_szServer);
  84. }
  85. //release all the Global memory allocations.
  86. FreeMemory( (LPVOID *) &m_szUserName );
  87. ReleaseGlobals();
  88. }
  89. DWORD CWaitFor::ProcessCmdLine()
  90. /*++
  91. Routine description : Function used to process the command line arguments
  92. specified by the user.
  93. Arguments:
  94. none
  95. Return Value : DWORD
  96. EXIT_SUCCESS : If the utility successfully performs the specified operation.
  97. EXIT_FAILURE : If the utility is unsuccessful in performing the specified operation.
  98. --*/
  99. {
  100. m_Parameters.uiTimeOut = MAILSLOT_WAIT_FOREVER;
  101. m_Parameters.szSignalName = NULL;
  102. m_Parameters.fSignal = FALSE;
  103. if( (cmdOptions[OI_TIMEOUT].dwActuals != 0 ) && (cmdOptions[OI_SIGNAL].dwActuals != 0 ) )
  104. {
  105. ShowMessage(stderr,GetResString(IDS_ERROR_MUTUAL_EX));
  106. return EXIT_FAILURE ;
  107. }
  108. //
  109. // Display an error message if the user enters Timeout option
  110. // and does not enter any signal name.
  111. if( ( StringLengthW(m_szDefault, 0) == 0 ) && (m_dwTimeOut != 0) )
  112. {
  113. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_SYNTAX));
  114. return EXIT_FAILURE ;
  115. }
  116. if(m_dwTimeOut != 0)
  117. {
  118. m_Parameters.uiTimeOut = m_dwTimeOut*TIMEOUT_CONST ;
  119. }
  120. //set the Signal parameter to true
  121. // if the User enters a signal name to send.
  122. if(StringLengthW(m_szSignal, 0) )
  123. {
  124. m_Parameters.fSignal = TRUE;
  125. m_Parameters.szSignalName = m_szSignal ;
  126. }
  127. //
  128. //set the Signal parameter to true
  129. //if the User enters a signal name to wait for.
  130. if(StringLengthW(m_szDefault, 0) != 0 )
  131. {
  132. m_Parameters.fSignal = TRUE;
  133. m_Parameters.szSignalName = m_szDefault ;
  134. }
  135. return EXIT_SUCCESS ;
  136. }
  137. VOID
  138. CWaitFor :: ShowUsage()
  139. /*++
  140. Routine description : member function to show help.
  141. Arguments : none.
  142. Return Value : none
  143. --*/
  144. {
  145. DWORD dwIndex = IDS_WAITFOR_HELP_BEGIN ;
  146. for( ; dwIndex <= IDS_WAITFOR_HELP_END ; dwIndex++ )
  147. {
  148. ShowMessage( stdout,GetResString( dwIndex ) );
  149. }
  150. return ;
  151. }
  152. DWORD CWaitFor::PerformOperations()
  153. /*++
  154. Routine description : This routine is used to either send a signal or wait for
  155. a particular signal for a specified time interval.
  156. Arguments:
  157. none .
  158. Return Value : DWORD
  159. EXIT_FAILURE : If the utility successfully performs the operation.
  160. EXIT_SUCCESS : If the utility is unsuccessful in performing the specified
  161. operation.
  162. --*/
  163. {
  164. HANDLE hMailslot ;
  165. WCHAR szComputerName[MAX_STRING_LENGTH] = NULL_U_STRING ;
  166. DWORD dwNumWritten = 0 ;
  167. WCHAR szSignalName[MAX_RES_STRING] = NULL_U_STRING ;
  168. WCHAR szMailSlot[MAX_RES_STRING] = MAILSLOT ;
  169. WCHAR szHostName[MAX_STRING_LENGTH] = NULL_U_STRING;
  170. WCHAR szMailSlot2[MAX_RES_STRING] = MAILSLOT2 ;
  171. DWORD dwBytesRead = 0;
  172. BOOL fRead = FALSE ;
  173. BOOL fWrite = FALSE ;
  174. BOOL bRetVal = FALSE ;
  175. DWORD dwError = 0 ;
  176. DWORD dwComputerNameLen = SIZE_OF_ARRAY(szComputerName);
  177. bRetVal = GetComputerName(szComputerName, &dwComputerNameLen);
  178. if ( bRetVal == 0)
  179. {
  180. ShowMessage(stderr,GetResString(IDS_ERROR_SYSTEM_NAME));
  181. return EXIT_FAILURE ;
  182. }
  183. //display an error message if the signal length exceeds 225 characters
  184. if( StringLengthW(m_Parameters.szSignalName, 0) > 225 )
  185. {
  186. ShowMessage(stderr,GetResString(IDS_ERROR_SIG_LENGTH));
  187. return EXIT_FAILURE ;
  188. }
  189. if ( EXIT_FAILURE == CheckForValidCharacters() )
  190. {
  191. ShowLastErrorEx(stderr,SLE_TYPE_ERROR | SLE_INTERNAL );
  192. return EXIT_FAILURE ;
  193. }
  194. if( (StringLengthW(m_szServer, 0) > 0 ) )
  195. {
  196. //remove of //s infront of server name
  197. if( IsUNCFormat(m_szServer) )
  198. {
  199. StringCopy( szHostName, m_szServer+2, SIZE_OF_ARRAY(szHostName) );
  200. StringCopy( m_szServer, szHostName, SIZE_OF_ARRAY(m_szServer) );
  201. }
  202. //check if it is ip address or not
  203. if( IsValidIPAddress(m_szServer) )
  204. {
  205. //if it is Ip address but local system like 127.0.0.1 or local ip address
  206. if( IsLocalSystem( m_szServer ) )
  207. {
  208. StringCopy( szHostName, szComputerName, SIZE_OF_ARRAY(szHostName));
  209. }
  210. else
  211. {
  212. dwComputerNameLen = MAX_STRING_LENGTH+1;
  213. //not local, get the remote system name
  214. if (FALSE == GetHostByIPAddr( m_szServer, szHostName, &dwComputerNameLen, FALSE))
  215. {
  216. ShowMessage(stderr,GetResString(IDS_ERROR_HOSTNAME));
  217. return EXIT_FAILURE;
  218. }
  219. }
  220. }
  221. else
  222. {
  223. //this is not a ip address, so copy server name as host name
  224. StringCopy(szHostName,m_szServer, SIZE_OF_ARRAY(szHostName) );
  225. }
  226. }
  227. else
  228. {
  229. //this not a remote system, so copy local host name as host name
  230. StringCopy(szHostName,szComputerName, SIZE_OF_ARRAY(szHostName));
  231. }
  232. if ( ( m_Parameters.fSignal && ( (m_dwTimeOut ==0) && ( cmdOptions[OI_TIMEOUT].dwActuals != 0 ) ) ) || StringLengthW(m_szSignal, 0) != 0)
  233. {
  234. //if the target system is a local system.
  235. if(StringLengthW(m_szServer, 0)==0)
  236. {
  237. StringCchPrintf(szSignalName, SIZE_OF_ARRAY(szSignalName), szMailSlot2,m_Parameters.szSignalName);
  238. }
  239. else
  240. {
  241. //If the target system is a remote system.
  242. //form the appropriate path
  243. //
  244. StringCopy(szSignalName,BACKSLASH4, SIZE_OF_ARRAY(szSignalName));
  245. if( IsUNCFormat( szHostName ) )
  246. StringConcat(szSignalName,szHostName+2, SIZE_OF_ARRAY(szSignalName));
  247. else
  248. StringConcat(szSignalName,szHostName, SIZE_OF_ARRAY(szSignalName));
  249. StringConcat(szSignalName,BACKSLASH2, SIZE_OF_ARRAY(szSignalName));
  250. StringConcat(szSignalName,MAILSLOT1, SIZE_OF_ARRAY(szSignalName));
  251. StringConcat(szSignalName,BACKSLASH2, SIZE_OF_ARRAY(szSignalName));
  252. StringConcat(szSignalName,m_Parameters.szSignalName, SIZE_OF_ARRAY(szSignalName));
  253. }
  254. hMailslot = CreateFile(
  255. szSignalName,
  256. GENERIC_WRITE,
  257. FILE_SHARE_READ,
  258. NULL,
  259. OPEN_EXISTING,
  260. FILE_ATTRIBUTE_NORMAL,
  261. NULL
  262. );
  263. //display a error message and exit if unable to create a mailslot.
  264. if ( INVALID_HANDLE_VALUE == hMailslot )
  265. {
  266. ShowMessage(stderr,GetResString(IDS_ERROR_SEND_MESSAGE));
  267. return EXIT_FAILURE;
  268. }
  269. if(StringLengthW(m_szServer, 0) > 0)
  270. {
  271. fWrite = WriteFile(hMailslot, szHostName,
  272. StringLengthW(szHostName, 0)+1, &dwNumWritten, NULL);
  273. }
  274. else
  275. {
  276. fWrite = WriteFile(hMailslot, szComputerName,
  277. StringLengthW(szComputerName, 0)+1, &dwNumWritten, NULL);
  278. }
  279. if( !fWrite )
  280. {
  281. switch( GetLastError() )
  282. {
  283. case ERROR_NETWORK_UNREACHABLE :
  284. ShowMessage( stderr, GetResString(IDS_ERROR_SEND_MESSAGE2) );
  285. CloseHandle(hMailslot);
  286. return EXIT_FAILURE;
  287. default :
  288. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_SEND_SIGNAL),m_Parameters.szSignalName);
  289. return EXIT_FAILURE;
  290. }
  291. }
  292. //close the mail slot handle.
  293. CloseHandle(hMailslot);
  294. if (bRetVal == 0)
  295. {
  296. ShowMessage(stderr,GetResString(IDS_ERROR_HANDLE));
  297. return EXIT_FAILURE ;
  298. }
  299. if (fWrite)
  300. {
  301. ShowMessage( stdout, NEWLINE );
  302. ShowMessage(stdout,GetResString(IDS_SIGNAL_SENT));
  303. return EXIT_SUCCESS;
  304. }
  305. }
  306. else
  307. {
  308. if(StringLengthW(m_szServer, 0)==0)
  309. {
  310. StringCchPrintf(szSignalName, MAX_RES_STRING, szMailSlot,m_Parameters.szSignalName);
  311. }
  312. else
  313. {
  314. StringCchPrintf( szSignalName, MAX_RES_STRING, L"%s%s%s%s%s%s", BACKSLASH4, szHostName, BACKSLASH2,MAILSLOT1,BACKSLASH2,m_Parameters.szSignalName );
  315. }
  316. //swprintf(szSignalName, szMailSlot, m_Parameters.szSignalName);
  317. // Create a mail slot
  318. hMailslot = CreateMailslot(szSignalName,256,m_Parameters.uiTimeOut, NULL);
  319. //Display a error message and exit if unable to create a mail slot.
  320. if (hMailslot == INVALID_HANDLE_VALUE)
  321. {
  322. ShowMessage(stderr,GetResString(IDS_ERROR_CREATE_MAILSLOT));
  323. return EXIT_FAILURE;
  324. }
  325. //Read the data from the mail slot.
  326. fRead = ReadFile(hMailslot, szComputerName,MAX_STRING_LENGTH, &dwBytesRead, NULL);
  327. //Close the Handle to the mail slot.
  328. CloseHandle(hMailslot);
  329. if (!fRead)
  330. {
  331. dwError = GetLastError();
  332. if (GetLastError() == ERROR_SEM_TIMEOUT)
  333. {
  334. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_TIMEOUT),m_Parameters.szSignalName);
  335. }
  336. else
  337. {
  338. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_UNEXPECTED_ERROR),dwError);
  339. }
  340. return EXIT_FAILURE;
  341. }
  342. else
  343. {
  344. ShowMessage( stdout, NEWLINE );
  345. ShowMessage(stdout,GetResString(IDS_SIGNAL_RECD));
  346. }
  347. }
  348. return EXIT_SUCCESS;
  349. }
  350. DWORD CWaitFor:: ProcessOptions(
  351. IN DWORD argc ,
  352. IN LPCWSTR argv[]
  353. )
  354. /*++
  355. Routine description : This function parses the options specified at the command prompt
  356. Arguments:
  357. [ in ] argc : count of elements in argv
  358. [ in ] argv : command-line parameterd specified by the user
  359. Return Value : DWORD
  360. EXIT_FAILURE : If the utility successfully performs the operation.
  361. EXIT_SUCCESS : If the utility is unsuccessful in performing the specified
  362. operation.
  363. --*/
  364. {
  365. PTCMDPARSER2 pcmdOption;
  366. StringCopy(m_szPassword, L"*", MAX_STRING_LENGTH);
  367. //Fill each structure with the appropriate value.
  368. // help option
  369. pcmdOption = &cmdOptions[OI_USAGE] ;
  370. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  371. pcmdOption->dwCount = 1 ;
  372. pcmdOption->dwActuals = 0;
  373. pcmdOption->dwFlags = CP_USAGE ;
  374. pcmdOption->pValue = &bShowUsage;
  375. pcmdOption->pFunction = NULL ;
  376. pcmdOption->pFunctionData = NULL ;
  377. pcmdOption->dwLength = 0;
  378. pcmdOption->pwszFriendlyName=NULL;
  379. pcmdOption->dwReserved = 0;
  380. pcmdOption->pReserved1 = NULL;
  381. pcmdOption->pReserved2 = NULL;
  382. pcmdOption->pReserved3 = NULL;
  383. pcmdOption->pwszValues=NULL;
  384. pcmdOption->pwszOptions=OPTION_HELP;
  385. StringCopyA(cmdOptions[OI_USAGE].szSignature, "PARSER2", 8 );
  386. //server
  387. pcmdOption = &cmdOptions[OI_SERVER] ;
  388. pcmdOption->dwType = CP_TYPE_TEXT;
  389. pcmdOption->dwCount = 1 ;
  390. pcmdOption->dwActuals = 0;
  391. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;
  392. pcmdOption->pValue = m_szServer ;
  393. pcmdOption->pFunction = NULL ;
  394. pcmdOption->pFunctionData = NULL ;
  395. pcmdOption->dwLength = MAX_STRING_LENGTH;
  396. pcmdOption->pwszFriendlyName=NULL;
  397. pcmdOption->dwReserved = 0;
  398. pcmdOption->pReserved1 = NULL;
  399. pcmdOption->pReserved2 = NULL;
  400. pcmdOption->pReserved3 = NULL;
  401. pcmdOption->pwszValues=NULL;
  402. pcmdOption->pwszOptions=OPTION_SERVER;
  403. StringCopyA(cmdOptions[OI_SERVER].szSignature, "PARSER2", 8 );
  404. //User
  405. pcmdOption = &cmdOptions[OI_USER] ;
  406. pcmdOption->dwType = CP_TYPE_TEXT;
  407. pcmdOption->dwCount = 1 ;
  408. pcmdOption->dwActuals = 0;
  409. pcmdOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL ;
  410. pcmdOption->pValue = NULL ;
  411. pcmdOption->pFunction = NULL ;
  412. pcmdOption->pFunctionData = NULL ;
  413. pcmdOption->dwLength = 0;
  414. pcmdOption->pwszFriendlyName=NULL;
  415. pcmdOption->dwReserved = 0;
  416. pcmdOption->pReserved1 = NULL;
  417. pcmdOption->pReserved2 = NULL;
  418. pcmdOption->pReserved3 = NULL;
  419. pcmdOption->pwszValues=NULL;
  420. pcmdOption->pwszOptions=OPTION_USER;
  421. StringCopyA(cmdOptions[OI_USER].szSignature, "PARSER2", 8 );
  422. //password
  423. pcmdOption = &cmdOptions[OI_PASSWORD] ;
  424. pcmdOption->dwType = CP_TYPE_TEXT;
  425. pcmdOption->dwCount = 1 ;
  426. pcmdOption->dwActuals = 0;
  427. pcmdOption->dwFlags = CP2_VALUE_OPTIONAL ;
  428. pcmdOption->pValue = m_szPassword ;
  429. pcmdOption->pFunction = NULL ;
  430. pcmdOption->pFunctionData = NULL ;
  431. pcmdOption->dwLength = MAX_STRING_LENGTH;
  432. pcmdOption->pwszFriendlyName=NULL;
  433. pcmdOption->dwReserved = 0;
  434. pcmdOption->pReserved1 = NULL;
  435. pcmdOption->pReserved2 = NULL;
  436. pcmdOption->pReserved3 = NULL;
  437. pcmdOption->pwszValues=NULL;
  438. pcmdOption->pwszOptions=OPTION_PASSWORD;
  439. StringCopyA(cmdOptions[OI_PASSWORD].szSignature, "PARSER2", 8 );
  440. pcmdOption = &cmdOptions[OI_SIGNAL] ;
  441. pcmdOption->dwType = CP_TYPE_TEXT;
  442. pcmdOption->dwCount = 1 ;
  443. pcmdOption->dwActuals = 0;
  444. pcmdOption->dwFlags = CP_VALUE_MANDATORY; //CP2_VALUE_OPTIONAL ;
  445. pcmdOption->pValue = m_szSignal ;
  446. pcmdOption->pFunction = NULL ;
  447. pcmdOption->pFunctionData = NULL ;
  448. pcmdOption->dwLength = MAX_STRING_LENGTH;
  449. pcmdOption->pwszFriendlyName=NULL;
  450. pcmdOption->dwReserved = 0;
  451. pcmdOption->pReserved1 = NULL;
  452. pcmdOption->pReserved2 = NULL;
  453. pcmdOption->pReserved3 = NULL;
  454. pcmdOption->pwszValues=NULL;
  455. pcmdOption->pwszOptions=OPTION_SIGNAL;
  456. StringCopyA(cmdOptions[OI_SIGNAL].szSignature, "PARSER2", 8 );
  457. pcmdOption = &cmdOptions[OI_TIMEOUT] ;
  458. pcmdOption->dwType = CP_TYPE_NUMERIC;
  459. pcmdOption->dwCount = 1 ;
  460. pcmdOption->dwActuals = 0;
  461. pcmdOption->dwFlags = CP_VALUE_MANDATORY ;
  462. pcmdOption->pValue = &m_dwTimeOut ;
  463. pcmdOption->pFunction = NULL ;
  464. pcmdOption->pFunctionData = NULL ;
  465. pcmdOption->dwLength = MAX_STRING_LENGTH;
  466. pcmdOption->pwszFriendlyName=NULL;
  467. pcmdOption->dwReserved = 0;
  468. pcmdOption->pReserved1 = NULL;
  469. pcmdOption->pReserved2 = NULL;
  470. pcmdOption->pReserved3 = NULL;
  471. pcmdOption->pwszValues=NULL;
  472. pcmdOption->pwszOptions=OPTION_TIMEOUT;
  473. StringCopyA(cmdOptions[OI_TIMEOUT].szSignature, "PARSER2", 8 );
  474. //default
  475. pcmdOption = &cmdOptions[OI_DEFAULT] ;
  476. pcmdOption->dwType = CP_TYPE_TEXT;
  477. pcmdOption->dwCount = 1 ;
  478. pcmdOption->dwActuals = 0;
  479. pcmdOption->dwFlags = CP2_DEFAULT ;
  480. pcmdOption->pValue = m_szDefault ;
  481. pcmdOption->pFunction = NULL ;
  482. pcmdOption->pFunctionData = NULL ;
  483. pcmdOption->dwLength = MAX_STRING_LENGTH;
  484. pcmdOption->pwszFriendlyName=NULL;
  485. pcmdOption->dwReserved = 0;
  486. pcmdOption->pReserved1 = NULL;
  487. pcmdOption->pReserved2 = NULL;
  488. pcmdOption->pReserved3 = NULL;
  489. pcmdOption->pwszValues=NULL;
  490. pcmdOption->pwszOptions=OPTION_DEFAULT;
  491. StringCopyA(cmdOptions[OI_DEFAULT].szSignature, "PARSER2", 8 );
  492. //parse the command line arguments
  493. if ( ! DoParseParam2( argc, argv, -1, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  494. {
  495. DISPLAY_MESSAGE(stderr,GetResString(IDS_TAG_ERROR));
  496. DISPLAY_MESSAGE(stderr,SPACE_CHAR);
  497. DISPLAY_MESSAGE(stderr,GetReason());
  498. return (EXIT_FAILURE);
  499. }
  500. m_szUserName = (LPWSTR)cmdOptions[OI_USER].pValue;
  501. TrimString(m_szSignal, TRIM_ALL);
  502. TrimString(m_szDefault, TRIM_ALL);
  503. TrimString(m_szServer, TRIM_ALL);
  504. TrimString(m_szUserName, TRIM_ALL);
  505. //this is to check if both signal to wait and /si are mentioned
  506. if( StringLengthW( m_szDefault, 0) != 0 && cmdOptions[OI_SIGNAL].dwActuals != 0 )
  507. {
  508. ShowMessage( stderr, GetResString(IDS_ERROR_SYNTAX) );
  509. return( EXIT_FAILURE );
  510. }
  511. //
  512. // Display an error message if user gives -u with out -s
  513. //
  514. if( (cmdOptions[ OI_USER ].dwActuals != 0 ) && ( cmdOptions[ OI_SERVER ].dwActuals == 0 ) )
  515. {
  516. ShowMessage( stderr, GetResString(IDS_USER_BUT_NOMACHINE) );
  517. return( EXIT_FAILURE );
  518. }
  519. //
  520. // Display an error message if user gives -p with out -u
  521. //
  522. if( ( cmdOptions[ OI_USER ].dwActuals == 0 ) && ( 0 != cmdOptions[ OI_PASSWORD ].dwActuals ) )
  523. {
  524. ShowMessage( stderr, GetResString(IDS_PASSWD_BUT_NOUSER) );
  525. return( EXIT_FAILURE );
  526. }
  527. //check for remote system without specifying /si option and
  528. if((StringLengthW(m_szServer,0) !=0) && cmdOptions[OI_SIGNAL].dwActuals == 0)
  529. {
  530. ShowMessage( stderr, GetResString(IDS_ERROR_SYNTAX) );
  531. return( EXIT_FAILURE );
  532. }
  533. //check for remote system can't wait for a signal
  534. if((StringLengthW(m_szServer, 0) !=0) && (cmdOptions[OI_DEFAULT].dwActuals != 0 ) )
  535. {
  536. ShowMessage( stderr, GetResString(IDS_ERROR_SYNTAX) );
  537. return( EXIT_FAILURE );
  538. }
  539. //check for null default value
  540. if( ( 0 != cmdOptions[OI_DEFAULT].dwActuals ) && ( 0 == StringLengthW(m_szDefault, 0) ) )
  541. {
  542. ShowMessage(stderr,GetResString(IDS_ERROR_SYNTAX));
  543. return( EXIT_FAILURE );
  544. }
  545. //check for null /si value
  546. if( ( 0 != cmdOptions[OI_SIGNAL].dwActuals ) && ( 0 == StringLengthW(m_szSignal, 0) ) )
  547. {
  548. ShowMessage(stderr,GetResString(IDS_ERROR_SYNTAX));
  549. return( EXIT_FAILURE );
  550. }
  551. if ( ( (m_dwTimeOut <= 0 ) || (m_dwTimeOut >99999 ) )&&( 0 != cmdOptions[OI_TIMEOUT].dwActuals ) )
  552. {
  553. DISPLAY_MESSAGE ( stderr, GetResString ( IDS_INVALID_TIMEOUT_VAL) );
  554. return EXIT_FAILURE;
  555. }
  556. if( IsUNCFormat(m_szServer) )
  557. {
  558. StringCopy(m_szServer, m_szServer+2, SIZE_OF_ARRAY(m_szServer) );
  559. }
  560. //check if password is needed or not
  561. if(IsLocalSystem( m_szServer ) == FALSE )
  562. {
  563. // set the bNeedPassword to True or False .
  564. if ( cmdOptions[ OI_PASSWORD ].dwActuals != 0 &&
  565. m_szPassword != NULL && StringCompare( m_szPassword, _T( "*" ), TRUE, 0 ) == 0 )
  566. {
  567. // user wants the utility to prompt for the password before trying to connect
  568. m_bNeedPwd = TRUE;
  569. }
  570. else if ( cmdOptions[ OI_PASSWORD ].dwActuals == 0 &&
  571. ( cmdOptions[ OI_SERVER ].dwActuals != 0 || cmdOptions[ OI_USER ].dwActuals != 0 ) )
  572. {
  573. // -s, -u is specified without password ...
  574. // utility needs to try to connect first and if it fails then prompt for the password
  575. m_bNeedPwd = TRUE;
  576. if ( m_szPassword != NULL )
  577. {
  578. StringCopy( m_szPassword, _T( "" ), MAX_STRING_LENGTH );
  579. }
  580. }
  581. //allocate memory if /u is not specified
  582. if( NULL == m_szUserName )
  583. {
  584. m_szUserName = (LPWSTR) AllocateMemory( MAX_STRING_LENGTH*sizeof(WCHAR) );
  585. }
  586. }
  587. return EXIT_SUCCESS ;
  588. }
  589. DWORD
  590. CWaitFor::ConnectRemoteServer()
  591. /*++
  592. Routine description : This function connects to the Remote server.
  593. Arguments: None
  594. Return Value : DWORD
  595. EXIT_FAILURE : If the utility successfully performs the operation.
  596. EXIT_SUCCESS : If the utility is unsuccessful in performing the specified
  597. operation.
  598. --*/
  599. {
  600. BOOL bResult = FALSE ;
  601. //
  602. //checking for the local system
  603. //
  604. m_bLocalSystem = IsLocalSystem(m_szServer);
  605. if( m_bLocalSystem && StringLengthW(m_szUserName, 0) != 0)
  606. {
  607. ShowMessage( stderr, NEWLINE );
  608. ShowMessage( stderr, GetResString( IDS_IGNORE_LOCALCREDENTIALS ) );
  609. return (EXIT_SUCCESS);
  610. }
  611. if ( ( StringLengthW(m_szServer, 0) != 0 ) && !m_bLocalSystem )
  612. {
  613. //establish a connection to the Remote system specified by the user.
  614. bResult = EstablishConnection(m_szServer,
  615. m_szUserName,
  616. (StringLengthW(m_szUserName,0)!=0?SIZE_OF_ARRAY_IN_CHARS(m_szUserName):MAX_STRING_LENGTH),
  617. m_szPassword,
  618. SIZE_OF_ARRAY(m_szPassword),
  619. m_bNeedPwd);
  620. if (bResult == FALSE)
  621. {
  622. ShowMessage( stderr,GetResString(IDS_TAG_ERROR ));
  623. ShowMessage( stderr,SPACE_CHAR );
  624. ShowMessage( stderr, GetReason());
  625. SecureZeroMemory( m_szPassword, SIZE_OF_ARRAY(m_szPassword) );
  626. return EXIT_FAILURE ;
  627. }
  628. else
  629. {
  630. switch( GetLastError() )
  631. {
  632. case I_NO_CLOSE_CONNECTION:
  633. m_bConnFlag = FALSE ;
  634. break;
  635. case E_LOCAL_CREDENTIALS:
  636. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  637. {
  638. m_bConnFlag = FALSE ;
  639. ShowMessage( stderr, GetResString(IDS_TAG_WARNING) );
  640. ShowMessage( stderr, EMPTY_SPACE );
  641. ShowMessage( stderr, GetReason() );
  642. break;
  643. }
  644. }
  645. }
  646. SecureZeroMemory( m_szPassword, SIZE_OF_ARRAY(m_szPassword) );
  647. }
  648. if( StringLength(m_szServer, 0) != 0 && TRUE == IsLocalSystem(IsUNCFormat(m_szServer)?m_szServer+2:m_szServer) )
  649. {
  650. if( StringLength( m_szUserName, 0 ) > 0 )
  651. {
  652. ShowMessage( stdout, NEWLINE );
  653. ShowMessage( stdout, GetResString(IDS_IGNORE_LOCALCREDENTIALS) );
  654. }
  655. }
  656. return EXIT_SUCCESS;
  657. }
  658. DWORD CWaitFor::CheckForValidCharacters()
  659. {
  660. // local variables
  661. char ch;
  662. unsigned char uch;
  663. LPSTR pszSignal = NULL;
  664. DWORD dw = 0, dwLength = 0;
  665. // validate the input parameters
  666. if ( NULL == m_Parameters.szSignalName )
  667. {
  668. SetLastError( ERROR_INVALID_NAME );
  669. SaveLastError();
  670. return EXIT_FAILURE;
  671. }
  672. //
  673. // find the required no. of byte to translate the UNICODE name into ANSI
  674. //
  675. dwLength = WideCharToMultiByte( GetConsoleOutputCP(), 0, m_Parameters.szSignalName, -1, NULL, 0, NULL, NULL );
  676. if ( 0 == dwLength )
  677. {
  678. SetLastError( ERROR_INVALID_NAME );
  679. SaveLastError();
  680. return EXIT_FAILURE;
  681. }
  682. //
  683. // check the signal name for validity
  684. // here to optimize the checking, we will get the normal length of the string in UNCIDE format and
  685. // will compare to the length we got for translating it into Multi-byte
  686. // if we find that the two lengths are different, then, the signal name might have contained the double-byte
  687. // characters -- which is invalid and not allowed
  688. // so ...
  689. //
  690. if ( StringLength( m_Parameters.szSignalName, 0 ) != dwLength - 1 )
  691. {
  692. // yes -- the signal name has double-byte characters
  693. SetLastError( ERROR_INVALID_NAME );
  694. SaveLastError();
  695. return EXIT_FAILURE;
  696. }
  697. //
  698. // now, we are sure the signal name doesn't contain double-byte characters
  699. // the second step to validate the signal is -- making sure that signal name contains
  700. // only characters a-z, A-Z, 0-9 and upper ASCII characters i.e; ASCII characters in the range of 128-255
  701. // so, convert the UNICODE string into ANSI format ( multi-byte (or) single-byte )
  702. // for that
  703. // #1. Allocate the needed memory
  704. // #2. Do the conversion
  705. // #3. do the validation
  706. //
  707. // #1
  708. pszSignal = (LPSTR) AllocateMemory( dwLength*sizeof( CHAR ) );
  709. if ( NULL == pszSignal )
  710. {
  711. SetLastError((DWORD) E_OUTOFMEMORY );
  712. SaveLastError();
  713. return EXIT_FAILURE;
  714. }
  715. // #2 -- assuming no need to for error checking
  716. WideCharToMultiByte( GetConsoleOutputCP(), 0, m_Parameters.szSignalName, -1, pszSignal, dwLength, NULL, NULL );
  717. // #3
  718. // in this step, traverse thru all the characters in the string one-by-one and validate it
  719. for( dw = 0; dw < dwLength - 1; dw++ )
  720. {
  721. // get the current character in the string into local buffer
  722. ch = pszSignal[ dw ]; // signed version
  723. uch = static_cast< unsigned char >( pszSignal[ dw ] );
  724. // signed comparision --> a-z, A-Z and 0-9
  725. if ( ( ch >= 48 && ch <= 57 ) || ( ch >= 65 && ch <= 90 ) || ( ch >= 97 && ch <= 122 ) )
  726. {
  727. // this particular character is acceptable in the signal name
  728. continue;
  729. }
  730. // unsigned comparision --> ASCII 128 - 255
  731. if ( uch < 128 || uch > 255 )
  732. {
  733. // this character is not acceptable for the signal name
  734. FreeMemory((LPVOID*) &pszSignal );
  735. pszSignal = NULL;
  736. SetReason( GetResString(IDS_ERROR_SIG_CHAR) );
  737. return EXIT_FAILURE;
  738. }
  739. }
  740. if( pszSignal != NULL )
  741. {
  742. FreeMemory((LPVOID*) &pszSignal );
  743. }
  744. return EXIT_SUCCESS;
  745. }
  746. DWORD __cdecl wmain(
  747. IN DWORD argc,
  748. IN LPCWSTR argv[]
  749. )
  750. /*++
  751. Routine description : Main function which calls all the other main functions
  752. depending on the option specified by the user.
  753. Arguments:
  754. [in] argc : argument count specified at the command prompt.
  755. [in] argv : arguments specified at the command prompt.
  756. Return Value : DWORD
  757. 0 : If the utility successfully performs the operation.
  758. 1 : If the utility is unsuccessful in performing the specified
  759. operation.
  760. --*/
  761. {
  762. CWaitFor WaitFor ;
  763. //display a syntax error if no arguments are given.
  764. if(argc==1)
  765. {
  766. ShowMessage(stderr,GetResString(IDS_ERROR_SYNTAX));
  767. return (EXIT_FAILURE);
  768. }
  769. //
  770. //Process the command line arguments.
  771. //
  772. if(WaitFor.ProcessOptions( argc,argv) == EXIT_FAILURE)
  773. {
  774. return EXIT_FAILURE ;
  775. }
  776. if((WaitFor.bShowUsage ==TRUE) && ( argc > 2 ) )
  777. {
  778. ShowMessage(stderr,GetResString(IDS_ERROR_SYNTAX));
  779. return EXIT_FAILURE ;
  780. }
  781. //
  782. //display the help if the user selects help.
  783. //
  784. if (WaitFor.bShowUsage == TRUE )
  785. {
  786. WaitFor.ShowUsage();
  787. return EXIT_SUCCESS ;
  788. }
  789. //
  790. // Perform the validations and
  791. // display error messages if required.
  792. //
  793. if(WaitFor.ProcessCmdLine() == EXIT_FAILURE )
  794. {
  795. return EXIT_FAILURE ;
  796. }
  797. if( WaitFor.ConnectRemoteServer() == EXIT_FAILURE )
  798. {
  799. return EXIT_FAILURE;
  800. }
  801. //
  802. //Sends the signal or waits for the signal depending upon the
  803. // user specification
  804. if(WaitFor.PerformOperations() == EXIT_FAILURE)
  805. {
  806. return EXIT_FAILURE ;
  807. }
  808. return EXIT_SUCCESS;
  809. }