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.

1205 lines
38 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. ExecCommand.c
  5. Abstract:
  6. Command having hexadecimal values are converted to their respective ASCII characters ,
  7. flags that are present in the command string are replaced by their values and
  8. the command formed after the replacement of hexadecimal values and flags is
  9. executed .
  10. Author:
  11. V Vijaya Bhaskar
  12. Revision History:
  13. 14-Jun-2001 : Created by V Vijaya Bhaskar ( Wipro Technologies ).
  14. --*/
  15. #include "Global.h"
  16. #include "ExecCommand.h"
  17. // Declared in ForFiles.cpp , holds starting node memory location .
  18. // No need to free this variable here, it will be freed in calling function
  19. extern LPWSTR g_lpszFileToSearch ;
  20. // Declared in ForFiles.cpp , holds path name specified at command prompt .
  21. extern LPWSTR g_lpszStartPath ;
  22. // Stores values of flags specified at command prompt.
  23. static WCHAR *szValue[ TOTAL_FLAGS ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } ;
  24. // Stores the command to execute.
  25. static LPWSTR g_f_lpszStoreCommand = NULL ;
  26. /******************************************************************************
  27. ** Function Prototypes Local To This File **
  28. ******************************************************************************/
  29. BOOL
  30. IsHex(
  31. IN WCHAR tIsNum
  32. ) ;
  33. DWORD
  34. CharToNum(
  35. OUT DWORD dwNumber
  36. ) ;
  37. BOOL
  38. ReplaceString(
  39. IN OUT LPWSTR lpszString ,
  40. IN DWORD dwIndex
  41. ) ;
  42. BOOL
  43. ReplacePercentChar(
  44. void
  45. ) ;
  46. void
  47. ReleaseFlagArray(
  48. IN DWORD dwTotalFlags
  49. ) ;
  50. BOOL
  51. FormatMessageString(
  52. IN DWORD dwIndex
  53. ) ;
  54. BOOL
  55. SeperateFileAndArgs(
  56. IN OUT LPWSTR* lpszArguments,
  57. OUT LPWSTR* lpszFileName
  58. ) ;
  59. /*************************************************************************
  60. /* Function Definition starts from here . **
  61. *************************************************************************/
  62. BOOL
  63. ReplaceHexToChar(
  64. OUT LPWSTR lpszCommand
  65. )
  66. /*++
  67. Routine Description:
  68. Replaces all hexadecimal values in a string to their ASCII characters .
  69. Arguments:
  70. [ OUT ] lpszCommand : Contains string in which hexadecimal values
  71. are to be converted to ASCII characters.
  72. Return value:
  73. FALSE : Memory is insufficient.
  74. TRUE
  75. --*/
  76. {
  77. WCHAR *szTemp = NULL ; // Memory pointer .
  78. unsigned char cHexChar[ 5 ]; // Contains ASCII character.
  79. WCHAR wszHexChar[ 5 ]; // Contains UNICODE character.
  80. SecureZeroMemory( wszHexChar, 5 * sizeof( WCHAR ) );
  81. SecureZeroMemory( cHexChar, 5 * sizeof( unsigned char ) );
  82. if( NULL == lpszCommand )
  83. {
  84. SetLastError( ERROR_INVALID_PARAMETER );
  85. SaveLastError() ;
  86. DISPLAY_GET_REASON();
  87. return FALSE ;
  88. }
  89. szTemp = lpszCommand ; // Initialized.
  90. // Continue while there are any hex character left .
  91. do
  92. {
  93. szTemp = FindSubString( szTemp , IS_HEX ) ;
  94. if( ( NULL != szTemp ) &&
  95. ( TRUE == IsHex( *( szTemp + 2 ) ) ) &&
  96. ( TRUE == IsHex( *( szTemp + 3 ) ) ) )
  97. {
  98. // An integer value of a hex "0x( HIGH_VALUE )( LOW_VALUE )" can
  99. // be obtained by ( HIGH_VALUE *16 + LOW_VALUE ) .
  100. cHexChar[ 0 ] = ( unsigned char )( ( CharToNum( *( szTemp + 2 ) ) * 16 ) +
  101. CharToNum( *( szTemp + 3 ) ) ) ;
  102. cHexChar[ 1 ] = '\0';
  103. // Code page is static.
  104. MultiByteToWideChar( US_ENG_CODE_PAGE, 0, (LPCSTR)cHexChar, -1, wszHexChar, 5 );
  105. *szTemp = ( WCHAR ) wszHexChar[0];
  106. // Copy STRING[0] = 0 , STRING[1] = x , STRING[2] = 1 , STRING[3] = a
  107. // To , STRING[0] = VALID_CHAR .
  108. StringCopy( ( szTemp + 1 ) , ( szTemp + 4 ), StringLength( ( szTemp + 1 ), 0 ) ) ;
  109. szTemp += 1 ;
  110. }
  111. else
  112. {
  113. /* Suppose the string contains 0xP then control should come here ,
  114. and this is the main purpose of this else block. */
  115. if( NULL != szTemp )
  116. {
  117. szTemp += 2 ;
  118. }
  119. // Now 'szTemp' is pointing to
  120. }
  121. } while( NULL != szTemp ) ;
  122. return TRUE;
  123. }
  124. BOOL
  125. IsHex(
  126. IN WCHAR wIsNum
  127. )
  128. /*++
  129. Routine Description:
  130. Checks whether the character falls in rangeof
  131. hex or not ( To fall in the range of hex a character
  132. must be either between 0 to 9 or a to f ).
  133. Arguments:
  134. [ IN ] tIsNum : Conatins a character which is to be checked for hex range .
  135. Return value:
  136. BOOL .
  137. --*/
  138. {
  139. if( ( ( _T( '0' ) <= wIsNum ) && ( _T( '9' ) >= wIsNum ) ) ||
  140. ( ( _T( 'A' ) <= wIsNum ) && ( _T( 'F' ) >= wIsNum ) ) ||
  141. ( ( _T( 'a' ) <= wIsNum ) && ( _T( 'f' ) >= wIsNum ) ) )
  142. {
  143. return TRUE ; // Character is in the range of hex . "
  144. }
  145. else
  146. {
  147. return FALSE ;
  148. }
  149. }
  150. DWORD
  151. CharToNum(
  152. OUT DWORD dwNumber
  153. )
  154. /*++
  155. Routine Description:
  156. Converts a character to number in HEX .
  157. It can be 0 - 9 or A - F .
  158. Arguments:
  159. [ OUT ] dwNumber : Conatins an ASCII value .
  160. Return value:
  161. DWORD .
  162. --*/
  163. {
  164. if( ( ASCII_0 <= dwNumber ) &&
  165. ( ASCII_9 >= dwNumber ) )
  166. { // Character is between 0 - 9 .
  167. dwNumber -= ASCII_0 ;
  168. }
  169. else
  170. {
  171. if( ( ASCII_a <= dwNumber ) &&
  172. ( ASCII_f >= dwNumber ) )
  173. { // Character is between a - f .In hex a = 10.
  174. dwNumber -= 87 ;
  175. }
  176. else
  177. {
  178. if( ( ASCII_A <= dwNumber ) &&
  179. ( ASCII_F >= dwNumber ) )
  180. { // Character is between A - F . In hex A = 10.
  181. dwNumber -= 55 ;
  182. }
  183. }
  184. }
  185. return dwNumber ; // Return the obtained HEX number .
  186. }
  187. BOOL
  188. ExecuteCommand(
  189. void
  190. )
  191. /*++
  192. Routine Description:
  193. Executes a command .
  194. Arguments:
  195. NONE
  196. Return value:
  197. BOOL .
  198. --*/
  199. {
  200. STARTUPINFO stInfo ;
  201. PROCESS_INFORMATION piProcess ;
  202. LPWSTR lpwszFileName = NULL;
  203. LPWSTR lpwszPathName = NULL;
  204. LPWSTR lpwFilePtr = NULL;
  205. DWORD dwFilePathLen = 0;
  206. DWORD dwTemp = 0;
  207. if( NULL == g_lpszFileToSearch )
  208. {
  209. SetLastError( ERROR_INVALID_PARAMETER );
  210. SaveLastError() ;
  211. DISPLAY_GET_REASON();
  212. return FALSE ;
  213. }
  214. // Initialize Process Info Structure With 0's
  215. SecureZeroMemory( &piProcess, sizeof( PROCESS_INFORMATION ) );
  216. // Initialize Startup Info Structure With 0's
  217. SecureZeroMemory( &stInfo, sizeof( STARTUPINFO ) );
  218. stInfo.cb = sizeof( stInfo ) ;
  219. if( FALSE == SeperateFileAndArgs( &g_lpszFileToSearch, &lpwszFileName ) )
  220. { // Error is displayed by called function.
  221. DISPLAY_MEMORY_ALLOC_FAIL();
  222. FREE_MEMORY( lpwszFileName );
  223. return FALSE;
  224. }
  225. dwFilePathLen = SearchPath( NULL, lpwszFileName, L".exe",
  226. dwTemp, lpwszPathName, &lpwFilePtr );
  227. if( 0 == dwFilePathLen )
  228. {
  229. SetLastError( GetLastError() );
  230. SaveLastError();
  231. DISPLAY_GET_REASON();
  232. FREE_MEMORY( lpwszFileName );
  233. return FALSE;
  234. }
  235. ASSIGN_MEMORY( lpwszPathName , WCHAR , dwFilePathLen + EXTRA_MEM ) ;
  236. if( NULL == lpwszPathName )
  237. {
  238. DISPLAY_MEMORY_ALLOC_FAIL();
  239. FREE_MEMORY( lpwszFileName );
  240. return FALSE;
  241. }
  242. dwTemp = SearchPath( NULL, lpwszFileName, L".exe",
  243. dwFilePathLen + EXTRA_MEM - 1,
  244. lpwszPathName, &lpwFilePtr );
  245. if( 0 == dwTemp )
  246. {
  247. SetLastError( GetLastError() );
  248. SaveLastError();
  249. DISPLAY_GET_REASON();
  250. FREE_MEMORY( lpwszFileName );
  251. FREE_MEMORY( lpwszPathName );
  252. return FALSE;
  253. }
  254. // Create a new process .
  255. if( FALSE == CreateProcess( lpwszPathName, g_lpszFileToSearch , NULL , NULL , FALSE ,
  256. 0 , NULL , NULL , &stInfo , &piProcess ) )
  257. {
  258. if( ERROR_BAD_EXE_FORMAT == GetLastError() )
  259. {
  260. ShowMessageEx( stderr, 5, FALSE, L"%1 %2%3%4%5", TAG_ERROR_DISPLAY,
  261. DOUBLE_QUOTES_TO_DISPLAY, _X3( lpwszFileName ),
  262. DOUBLE_QUOTES_TO_DISPLAY, NOT_WIN32_APPL ) ;
  263. }
  264. else
  265. {
  266. SaveLastError() ;
  267. DISPLAY_GET_REASON();
  268. }
  269. FREE_MEMORY( lpwszFileName );
  270. FREE_MEMORY( lpwszPathName );
  271. return FALSE;
  272. }
  273. // Wait infinitly for the object just executed to terminate .
  274. WaitForSingleObject( piProcess.hProcess , INFINITE ) ;
  275. CloseHandle( piProcess.hProcess ) ; // Close handle of process .
  276. CloseHandle( piProcess.hThread ) ; // Close handle of thread .
  277. FREE_MEMORY( lpwszPathName );
  278. FREE_MEMORY( lpwszFileName );
  279. return TRUE ;
  280. }
  281. BOOL
  282. ReplaceTokensWithValidValue(
  283. IN LPWSTR lpszPathName ,
  284. IN WIN32_FIND_DATA wfdFindFile
  285. )
  286. /*++
  287. Routine Description:
  288. Replaces tokens such as @flag , @path etc. with appropriate value .
  289. Arguments:
  290. [ IN ] lpszPathName - Contains current processes path name or CurrentDirectory .
  291. [ IN ] wfdFindFile - Conatins information about current file being opened .
  292. Return value:
  293. BOOL is returned .
  294. --*/
  295. {
  296. static BOOL bFirstLoop = TRUE ;
  297. DWORD dwLength = 0; // Contains length of a buffer.
  298. DWORD dwIndex = 0 ; // Contains number of flags for which space is allocated.
  299. LPWSTR pwTemporary = NULL ; // Temporary data . Points to a memory location .
  300. SYSTEMTIME stFileTime ; // Stores current file creation date and time information .
  301. FILETIME ftFileTime ;
  302. WCHAR szwCharSize[ MAX_PATH ] ;
  303. WCHAR szwCharSizeTemp[ MAX_PATH * 2 ] ;
  304. unsigned _int64 uint64FileSize = 0 ; // Used store data of 64 int .
  305. LCID lcidCurrentUserLocale = 0; // Stores current user locale.
  306. BOOL bLocaleChanged = FALSE ;
  307. if( ( NULL == lpszPathName ) ||
  308. ( NULL == g_lpszFileToSearch ) )
  309. {
  310. SetLastError( ERROR_INVALID_PARAMETER );
  311. SaveLastError() ;
  312. DISPLAY_GET_REASON();
  313. return FALSE ;
  314. }
  315. SecureZeroMemory( szwCharSize, MAX_PATH * sizeof( WCHAR ) );
  316. SecureZeroMemory( szwCharSizeTemp, MAX_PATH * 2 * sizeof( WCHAR ) );
  317. SecureZeroMemory( &stFileTime, sizeof( SYSTEMTIME ) );
  318. SecureZeroMemory( &ftFileTime, sizeof( FILETIME ) );
  319. // Replacement of '%NUMBER' to '%%NUMBER' is done once only.
  320. if( TRUE == bFirstLoop )
  321. {
  322. if( FALSE == ReplacePercentChar() )
  323. {
  324. return FALSE ;
  325. }
  326. }
  327. // Search for @fname.
  328. if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_WITHOUT_EXT ) ) )
  329. {
  330. REPLACE_PERC_CHAR( bFirstLoop, FILE_WITHOUT_EXT, dwIndex );
  331. dwLength = StringLength( wfdFindFile.cFileName, 0 ) + EXTRA_MEM;
  332. // Assign memory to the buffer.
  333. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  334. dwIndex += 1;
  335. // Check whether memory allocation is successful.
  336. if( NULL == szValue[ dwIndex - 1 ] )
  337. {
  338. // Memory allocation failed.
  339. // Release buffers.
  340. DISPLAY_MEMORY_ALLOC_FAIL() ;
  341. ReleaseFlagArray( dwIndex );
  342. return FALSE ;
  343. }
  344. // Copy file name to the buffer.
  345. StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  346. // ConCat file name .
  347. StringConcat( szValue[ dwIndex - 1 ] , wfdFindFile.cFileName, dwLength ) ;
  348. // Search for a '.' which separetes a file name with extension and put '\0' at '.' .
  349. if( NULL != ( pwTemporary =StrRChr( szValue[ dwIndex - 1 ] , NULL, _T( '.' ) ) ) )
  350. {
  351. *pwTemporary = L'\0' ;
  352. }
  353. StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ; // Copy file name .
  354. }
  355. // Search for @file.
  356. if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_NAME ) ) )
  357. {
  358. REPLACE_PERC_CHAR( bFirstLoop, FILE_NAME, dwIndex );
  359. dwLength = StringLength( wfdFindFile.cFileName, 0 ) + EXTRA_MEM ;
  360. // Assign memory to the buffer.
  361. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  362. dwIndex += 1;
  363. // Check whether memory allocation is successful.
  364. if( NULL == szValue[ dwIndex - 1 ] )
  365. {
  366. // Memory allocation failed.
  367. // Release buffers.
  368. DISPLAY_MEMORY_ALLOC_FAIL() ;
  369. ReleaseFlagArray( dwIndex );
  370. return FALSE ;
  371. }
  372. // Copy file name to the buffer.
  373. StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  374. StringConcat( szValue[ dwIndex - 1 ], wfdFindFile.cFileName, dwLength );
  375. StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  376. }
  377. // Search for @ext.
  378. if( NULL != ( FindSubString( g_lpszFileToSearch, EXTENSION ) ) )
  379. {
  380. REPLACE_PERC_CHAR( bFirstLoop, EXTENSION, dwIndex );
  381. // Check '.' character exist or not.
  382. // Check for '.' and replace ext .
  383. if( NULL != StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ) )
  384. {
  385. dwLength = StringLength( StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ), 0 ) + EXTRA_MEM;
  386. // Assign memory to the buffer.
  387. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  388. dwIndex += 1;
  389. // Check whether memory allocation is successful.
  390. if( NULL == szValue[ dwIndex - 1 ] )
  391. {
  392. // Memory allocation failed.
  393. // Release buffers.
  394. DISPLAY_MEMORY_ALLOC_FAIL() ;
  395. ReleaseFlagArray( dwIndex );
  396. return FALSE ;
  397. }
  398. // If number of characters appearing after '.' is zero, than assign '\0'.
  399. if( StringLength( ( StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ) + 1 ), 0 ) > 0 )
  400. {
  401. StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  402. StringConcat( szValue[ dwIndex - 1 ] ,
  403. ( StrRChr( wfdFindFile.cFileName, NULL, _T( '.' ) ) + 1 ), dwLength ) ;
  404. StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength) ;
  405. }
  406. else
  407. { // If the filename has a '.' at the end , no extension . EX: File.
  408. StringCopy( szValue[ dwIndex - 1 ], L"\"\"", dwLength );
  409. }
  410. }
  411. else
  412. {
  413. dwLength = EXTRA_MEM + StringLength( L"\"\"", 0 );
  414. // Assign memory to the buffer.
  415. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  416. dwIndex += 1;
  417. // Check whether memory allocation is successful.
  418. if( NULL == szValue[ dwIndex - 1 ] )
  419. {
  420. // Memory allocation failed.
  421. // Release buffers.
  422. DISPLAY_MEMORY_ALLOC_FAIL() ;
  423. ReleaseFlagArray( dwIndex );
  424. return FALSE ;
  425. }
  426. StringCopy( szValue[ dwIndex - 1 ], L"\"\"", dwLength );
  427. }
  428. }
  429. // Search for @path.
  430. if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_PATH ) ) )
  431. {
  432. REPLACE_PERC_CHAR( bFirstLoop, FILE_PATH, dwIndex );
  433. dwLength = StringLength( lpszPathName, 0 ) + StringLength( wfdFindFile.cFileName, 0 )+ EXTRA_MEM ;
  434. // Assign memory to the buffer.
  435. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  436. dwIndex += 1;
  437. // Check whether memory allocation is successful.
  438. if( NULL == szValue[ dwIndex - 1 ] )
  439. {
  440. // Memory allocation failed.
  441. // Release buffers.
  442. DISPLAY_MEMORY_ALLOC_FAIL() ;
  443. ReleaseFlagArray( dwIndex );
  444. return FALSE ;
  445. }
  446. // Copy path to the buffer. Path copied should be enclosed in '\"' .
  447. StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  448. StringConcat( szValue[ dwIndex - 1 ] , lpszPathName, dwLength ) ;
  449. StringConcat( szValue[ dwIndex - 1 ] , wfdFindFile.cFileName, dwLength ) ;
  450. StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  451. }
  452. // Search for @relpath.
  453. if( NULL != ( FindSubString( g_lpszFileToSearch, RELATIVE_PATH ) ) )
  454. {
  455. REPLACE_PERC_CHAR( bFirstLoop, RELATIVE_PATH, dwIndex );
  456. StringCopy( szwCharSizeTemp , lpszPathName, MAX_PATH * 2 ) ;
  457. StringConcat( szwCharSizeTemp , wfdFindFile.cFileName, MAX_PATH * 2 ) ;
  458. // Obtain relative path to the current file.
  459. if( FALSE == PathRelativePathTo( szwCharSize , g_lpszStartPath ,
  460. FILE_ATTRIBUTE_DIRECTORY ,
  461. szwCharSizeTemp , wfdFindFile.dwFileAttributes ) )
  462. {
  463. // Failed to find relative path.
  464. SaveLastError() ;
  465. DISPLAY_GET_REASON();
  466. ReleaseFlagArray( dwIndex );
  467. return FALSE ;
  468. }
  469. dwLength = StringLength( szwCharSize, 0 ) + EXTRA_MEM;
  470. // Assign memory to the buffer.
  471. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  472. dwIndex += 1;
  473. // Check whether memory allocation is successful.
  474. if( NULL == szValue[ dwIndex - 1 ] )
  475. {
  476. // Memory allocation failed.
  477. // Release buffers.
  478. DISPLAY_MEMORY_ALLOC_FAIL() ;
  479. ReleaseFlagArray( dwIndex );
  480. return FALSE ;
  481. }
  482. // Copy relative path.
  483. StringCopy( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  484. StringConcat( szValue[ dwIndex - 1 ] , szwCharSize, dwLength ) ;
  485. StringConcat( szValue[ dwIndex - 1 ] , L"\"", dwLength ) ;
  486. }
  487. // Search for @ext
  488. if( NULL != ( FindSubString( g_lpszFileToSearch, IS_DIRECTORY ) ) )
  489. {
  490. REPLACE_PERC_CHAR( bFirstLoop, IS_DIRECTORY, dwIndex );
  491. if( 0 != ( wfdFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  492. {
  493. dwLength = StringLength( GetResString( IDS_TRUE ), 0 ) + EXTRA_MEM ;
  494. // Assign memory to the buffer.
  495. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  496. dwIndex += 1;
  497. // Check whether memory allocation is successful.
  498. if( NULL == szValue[ dwIndex - 1 ] )
  499. {
  500. // Memory allocation failed.
  501. // Release buffers.
  502. DISPLAY_MEMORY_ALLOC_FAIL() ;
  503. ReleaseFlagArray( dwIndex );
  504. return FALSE ;
  505. }
  506. StringCopy( szValue[ dwIndex - 1 ] , GetResString( IDS_TRUE ), dwLength ) ;
  507. }
  508. else
  509. {
  510. dwLength = StringLength( GetResString( IDS_FALSE ), 0 ) + EXTRA_MEM;
  511. // Assign memory to the buffer.
  512. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  513. dwIndex += 1;
  514. // Check whether memory allocation is successful.
  515. if( NULL == szValue[ dwIndex - 1 ] )
  516. {
  517. // Memory allocation failed.
  518. // Release buffers.
  519. DISPLAY_MEMORY_ALLOC_FAIL() ;
  520. ReleaseFlagArray( dwIndex );
  521. return FALSE ;
  522. }
  523. // Copy 'false' to the buffer.
  524. StringCopy( szValue[ dwIndex - 1 ] , GetResString( IDS_FALSE ), dwLength ) ;
  525. }
  526. }
  527. // Search for @fsize
  528. if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_SIZE ) ) )
  529. {
  530. REPLACE_PERC_CHAR( bFirstLoop, FILE_SIZE, dwIndex );
  531. uint64FileSize = wfdFindFile.nFileSizeHigh * MAXDWORD ;
  532. uint64FileSize += wfdFindFile.nFileSizeHigh + wfdFindFile.nFileSizeLow ;
  533. #if _UNICODE // If Unicode .
  534. _ui64tow( uint64FileSize , ( WCHAR * )szwCharSize , 10 ) ;
  535. #else // If Multibyte .
  536. _ui64toa( uint64FileSize , ( WCHAR * )szwCharSize , 10 ) ;
  537. #endif
  538. dwLength = StringLength( szwCharSize, 0 )+ EXTRA_MEM ;
  539. // Assign memory to the buffer.
  540. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  541. dwIndex += 1;
  542. // Check whether memory allocation is successful.
  543. if( NULL == szValue[ dwIndex - 1 ] )
  544. {
  545. // Memory allocation failed.
  546. // Release buffers.
  547. DISPLAY_MEMORY_ALLOC_FAIL() ;
  548. ReleaseFlagArray( dwIndex );
  549. return FALSE ;
  550. }
  551. StringCopy( szValue[ dwIndex - 1 ] , ( WCHAR * )szwCharSize, dwLength ) ;
  552. }
  553. // Convert obtained file date time information to user locale .
  554. // Convert file date time to SYSTEMTIME structure.
  555. if( ( TRUE == FileTimeToLocalFileTime( &wfdFindFile.ftLastWriteTime , &ftFileTime ) ) &&
  556. ( TRUE == FileTimeToSystemTime( &ftFileTime , &stFileTime ) ) )
  557. {
  558. // verify whether console supports the current locale 100% or not
  559. lcidCurrentUserLocale = GetSupportedUserLocale( &bLocaleChanged ) ;
  560. // Check whether @fdate exist in the user specified string.
  561. if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_DATE ) ) )
  562. {
  563. REPLACE_PERC_CHAR( bFirstLoop, FILE_DATE, dwIndex );
  564. if( 0 == GetDateFormat( lcidCurrentUserLocale , DATE_SHORTDATE , &stFileTime ,
  565. ((bLocaleChanged == TRUE) ? L"MM/dd/yyyy" : NULL) ,
  566. szwCharSize , MAX_STRING_LENGTH ) )
  567. {
  568. SaveLastError() ;
  569. DISPLAY_GET_REASON();
  570. ReleaseFlagArray( dwIndex );
  571. return FALSE ;
  572. }
  573. dwLength = StringLength( szwCharSize, 0 )+ EXTRA_MEM;
  574. // Assign memory to the buffer.
  575. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  576. dwIndex += 1;
  577. // Check whether memory allocation is successful.
  578. if( NULL == szValue[ dwIndex - 1 ] )
  579. {
  580. // Memory allocation failed.
  581. // Release buffers.
  582. DISPLAY_MEMORY_ALLOC_FAIL() ;
  583. ReleaseFlagArray( dwIndex );
  584. return FALSE ;
  585. }
  586. StringCopy( szValue[ dwIndex - 1 ] , szwCharSize, dwLength ) ;
  587. }
  588. // Check whether @ftime exist in the user specified string.
  589. if( NULL != ( FindSubString( g_lpszFileToSearch, FILE_TIME ) ) )
  590. {
  591. REPLACE_PERC_CHAR( bFirstLoop, FILE_TIME, dwIndex );
  592. if( 0 == GetTimeFormat( LOCALE_USER_DEFAULT , 0 , &stFileTime ,
  593. ((bLocaleChanged == TRUE) ? L"HH:mm:ss" : NULL) ,
  594. szwCharSize , MAX_STRING_LENGTH ) )
  595. {
  596. SaveLastError() ;
  597. DISPLAY_GET_REASON();
  598. ReleaseFlagArray( dwIndex );
  599. return FALSE ;
  600. }
  601. dwLength = StringLength( szwCharSize, 0 )+ EXTRA_MEM ;
  602. // Assign memory to the buffer.
  603. ASSIGN_MEMORY( szValue[ dwIndex ] , WCHAR , dwLength ) ;
  604. dwIndex += 1;
  605. // Check whether memory allocation is successful.
  606. if( NULL == szValue[ dwIndex - 1 ] )
  607. {
  608. // Memory allocation failed.
  609. // Release buffers.
  610. DISPLAY_MEMORY_ALLOC_FAIL() ;
  611. ReleaseFlagArray( dwIndex );
  612. return FALSE ;
  613. }
  614. StringCopy( szValue[ dwIndex - 1 ] , szwCharSize, dwLength ) ;
  615. }
  616. }
  617. if( TRUE == bFirstLoop )
  618. {
  619. dwLength = StringLength( g_lpszFileToSearch, 0 ) + EXTRA_MEM ;
  620. REALLOC_MEMORY( g_f_lpszStoreCommand , WCHAR , dwLength ) ;
  621. if( NULL == g_f_lpszStoreCommand )
  622. {
  623. DISPLAY_MEMORY_ALLOC_FAIL() ;
  624. ReleaseFlagArray( dwIndex );
  625. return FALSE ;
  626. }
  627. StringCopy( g_f_lpszStoreCommand, g_lpszFileToSearch, dwLength );
  628. }
  629. // Make 'bFirstLoop' flase, so we don't have to replace @FLAG for
  630. // command store in 'g_f_lpszStoreCommand' in '%NUMBER' format for furthur loops.
  631. bFirstLoop = FALSE ;
  632. if( FALSE == FormatMessageString( dwIndex ) )
  633. {
  634. ReleaseFlagArray( dwIndex );
  635. return FALSE ;
  636. }
  637. ReleaseFlagArray( dwIndex );
  638. return TRUE ;
  639. }
  640. BOOL
  641. ReplaceString(
  642. IN OUT LPWSTR lpszString ,
  643. IN DWORD dwIndex
  644. )
  645. /*++
  646. Routine Description:
  647. This function replaces flags with '%NUMBER' string so to
  648. make FormatMEssage() comaptible.
  649. Arguments:
  650. [ IN OUT ] lpszString - Contains string which is a command to execute
  651. having flags which will be replace by "%NUMBER".
  652. [ IN ] dwIndex - Conatins a number which will form 'NUMBER' of '%NUMBER'.
  653. Return value:
  654. If success returns TRUE else FALSE.
  655. --*/
  656. {
  657. DWORD dwLength = 0; // Contains length of a buffer.
  658. DWORD dwNumOfChars = 0 ; // Contains index from where search has to be started.
  659. LPWSTR lpszStoreData = NULL ; // Temporary variable to hold data.
  660. // Conatins number in string format which forms 'NUMBER' of '%NUMBER'.
  661. // 15 is because a number or DWORD cannot be more than 10 digits.
  662. WCHAR szStoreIndex[ 15 ] ;
  663. WCHAR *pwTemporary = NULL ; // Temporary variable, points to an index in a buffer.
  664. #ifdef _WIN64
  665. __int64 dwStringLen = 0 ;
  666. #else
  667. DWORD dwStringLen = 0 ;
  668. #endif
  669. if( ( NULL == g_lpszFileToSearch ) ||
  670. ( NULL == lpszString ) )
  671. {
  672. SetLastError( ERROR_INVALID_PARAMETER );
  673. SaveLastError() ;
  674. DISPLAY_GET_REASON();
  675. return FALSE ;
  676. }
  677. SecureZeroMemory( szStoreIndex, 15 * sizeof( WCHAR ) );
  678. // If Unicode .
  679. _ultow( dwIndex, ( WCHAR * )szStoreIndex, 10 );
  680. // Loops till @FLAG to be searched doesn't get replaced by a '%NUMBER' string.
  681. while( NULL != ( pwTemporary = FindSubString( g_lpszFileToSearch + dwNumOfChars , lpszString ) ) )
  682. {
  683. dwLength = StringLength( pwTemporary, 0 ) + EXTRA_MEM;
  684. // Get memory in which to store the data present after the @FLAG.
  685. ASSIGN_MEMORY( lpszStoreData , WCHAR , dwLength ) ;
  686. // Check whether memory allocation was successful.
  687. if( NULL == lpszStoreData )
  688. { // Memory allocation was unsuccessful.
  689. DISPLAY_MEMORY_ALLOC_FAIL();
  690. return FALSE ;
  691. }
  692. // Copy data appering after @FLAG into temporary variable.
  693. StringCopy( lpszStoreData , ( pwTemporary + StringLength( lpszString, 0 ) ), dwLength ) ;
  694. // Replace @FLAG with '%NUMBER' string.
  695. if( NULL != ( pwTemporary = FindSubString( g_lpszFileToSearch + dwNumOfChars , lpszString ) ) )
  696. {
  697. dwStringLen = pwTemporary - g_lpszFileToSearch;
  698. // Copy '%' character.
  699. StringCopy( pwTemporary , L"%",
  700. ( ( GetBufferSize( g_lpszFileToSearch )/ sizeof( WCHAR ) ) - (DWORD)dwStringLen ) ) ;
  701. // Copy 'NUMBER' string into buffer.
  702. StringConcat( pwTemporary , szStoreIndex,
  703. ( ( GetBufferSize( g_lpszFileToSearch )/ sizeof( WCHAR ) ) - (DWORD)dwStringLen ) ) ;
  704. }
  705. // Get index from where to start search for next @FLAG.
  706. dwNumOfChars = StringLength( g_lpszFileToSearch, 0 ) ;
  707. // Concat data which was appearing after replaced @FLAG.
  708. StringConcat( g_lpszFileToSearch , lpszStoreData,
  709. ( GetBufferSize( g_lpszFileToSearch )/sizeof( WCHAR ) ) ) ;
  710. // Free memory.
  711. FREE_MEMORY( lpszStoreData ) ;
  712. }
  713. return TRUE;
  714. }
  715. BOOL
  716. ReplacePercentChar(
  717. void
  718. )
  719. /*++
  720. Routine Description:
  721. This function replaces '%' characters with '%%' string.
  722. This is needed to distinguish between '%NUMBER' character which
  723. is replaced by FormatMessageString() .
  724. Arguments:
  725. Return value:
  726. If success returns TRUE else FALSE.
  727. --*/
  728. {
  729. DWORD dwLength = 0; //Contains length of a buffer.
  730. DWORD dwReallocLength = 0;
  731. DWORD dwPercentChar = 0 ; // Keep record of number '%' char to be replaced.
  732. #ifdef _WIN64
  733. __int64 dwNumOfChars = 0 ;
  734. #else
  735. DWORD dwNumOfChars = 0 ; // Keep record of position or index from where to start next search.
  736. #endif
  737. LPWSTR lpszStoreData = NULL ; // Temporary variable to store data.
  738. WCHAR *pwTemporary = NULL ; // Temporary pointer.
  739. // Check whether variable is valid.
  740. if( NULL == g_lpszFileToSearch )
  741. {
  742. SetLastError( ERROR_INVALID_PARAMETER );
  743. SaveLastError() ;
  744. DISPLAY_GET_REASON();
  745. return FALSE ;
  746. }
  747. // Check number of '%' characters to replace with '%%'.
  748. while( NULL != ( pwTemporary = StrPBrk( g_lpszFileToSearch + dwNumOfChars , L"%" ) ) )
  749. {
  750. dwPercentChar += 1;
  751. // Point index to present char plus 2.
  752. dwNumOfChars = pwTemporary - g_lpszFileToSearch + 1 ;
  753. }
  754. dwNumOfChars = 0 ; // Initialize variable to zero.
  755. dwReallocLength = StringLength( g_lpszFileToSearch, 0 ) + dwPercentChar + EXTRA_MEM;
  756. // Reallocate the orginal buffer and copy path to traverse .
  757. REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwReallocLength ) ;
  758. if( NULL == g_lpszFileToSearch )
  759. { // Reallocation failed .'g_lpszFileToSearch' will be freed in calling function.
  760. DISPLAY_MEMORY_ALLOC_FAIL() ;
  761. return FALSE ;
  762. }
  763. // Loop till '%' character exist.
  764. while( NULL != ( pwTemporary = StrPBrk( g_lpszFileToSearch + dwNumOfChars , L"%" ) ) )
  765. {
  766. dwLength = StringLength( pwTemporary, 0 ) + EXTRA_MEM;
  767. // Assign memory.
  768. ASSIGN_MEMORY( lpszStoreData , WCHAR , dwLength ) ;
  769. // Check is memory allocation successful.
  770. if( NULL == lpszStoreData )
  771. {
  772. // Memory allocation failed.
  773. DISPLAY_MEMORY_ALLOC_FAIL() ;
  774. return FALSE ;
  775. }
  776. // Copy data appearing after '%'.
  777. StringCopy( lpszStoreData , ( pwTemporary + StringLength( L"%", 0 ) ), dwLength ) ;
  778. // Replace '%' with '%%'.
  779. if( NULL != ( pwTemporary = FindSubString( g_lpszFileToSearch + dwNumOfChars , L"%" ) ) )
  780. {
  781. StringCopy( pwTemporary , L"%%",
  782. ( ( GetBufferSize( g_lpszFileToSearch )/ sizeof( WCHAR ) ) - (LONG)dwNumOfChars ) );
  783. }
  784. // Point index to position which is not searched till.
  785. dwNumOfChars = StringLength( g_lpszFileToSearch, 0 ) ;
  786. // Concat data appearing after '%'.
  787. StringConcat( g_lpszFileToSearch , lpszStoreData, dwReallocLength ) ;
  788. FREE_MEMORY( lpszStoreData ) ;
  789. }
  790. return TRUE;
  791. }
  792. void
  793. ReleaseStoreCommand(
  794. void
  795. )
  796. /*++
  797. Routine Description:
  798. Releases 'g_f_lpszStoreCommand' global variable to this file.
  799. Arguments:
  800. Return value:
  801. VOID is returned.
  802. --*/
  803. {
  804. FREE_MEMORY( g_f_lpszStoreCommand ) ;
  805. return;
  806. }
  807. void
  808. ReleaseFlagArray(
  809. IN DWORD dwTotalFlags
  810. )
  811. /*++
  812. Routine Description:
  813. Releases variables used to store values replacing @FLAG.
  814. Arguments:
  815. [ IN ] dwTotalFlags - Contains index of an array till which memory is assigned.
  816. Return value:
  817. VOID is returned.
  818. --*/
  819. {
  820. DWORD i = 0 ;
  821. for( i = 0 ; i < dwTotalFlags ; i++ )
  822. {
  823. FREE_MEMORY( szValue[ i ] ) ;
  824. }
  825. return ;
  826. }
  827. BOOL
  828. FormatMessageString(
  829. DWORD dwIndex
  830. )
  831. /*++
  832. Routine Description:
  833. Replaces '%NUMBER' with its appropriate values.
  834. Arguments:
  835. [ IN ] dwIndex - Contains index of an array till which memory is assigned.
  836. Return value:
  837. FALSE is returned when memory allocation failed else TRUE is returned..
  838. --*/
  839. {
  840. DWORD dwLength = 0 ; //Contains length of a string.
  841. DWORD dwTemp = 0 ;
  842. DWORD dwNumber = 0 ; // Stores 'NUMBER' %NUMBER to replace.
  843. // Keep record of position or index from where to start next search.
  844. #ifdef _WIN64
  845. __int64 dwLocation = 0 ;
  846. #else
  847. DWORD dwLocation = 0 ;
  848. #endif
  849. LPWSTR lpszTempStr = NULL ;
  850. LPWSTR lpszTempStr1 = NULL ;
  851. LPWSTR lpszDataToStore = NULL ;
  852. if( NULL == g_f_lpszStoreCommand )
  853. {
  854. SetLastError( ERROR_INVALID_PARAMETER );
  855. SaveLastError();
  856. DISPLAY_GET_REASON();
  857. return FALSE ;
  858. }
  859. dwLength = StringLength( g_f_lpszStoreCommand, 0 ) + EXTRA_MEM ;
  860. // Realloc memory.
  861. REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ;
  862. if( NULL == g_lpszFileToSearch )
  863. {
  864. DISPLAY_MEMORY_ALLOC_FAIL() ;
  865. return FALSE ;
  866. }
  867. StringCopy( g_lpszFileToSearch, g_f_lpszStoreCommand, dwLength );
  868. // Loop until no more '%' are left.
  869. while( NULL != ( lpszTempStr = FindAChar( ( g_lpszFileToSearch + dwLocation ), _T( '%' ) ) ) )
  870. {
  871. // Check whether '%' or 'NUMBER' is present after '%'.
  872. if( _T( '%' ) == *( lpszTempStr + 1 ) )
  873. {
  874. // If '%%' is present then replace it with '%'.
  875. dwLocation = lpszTempStr - g_lpszFileToSearch ;
  876. // Set pointer to point to first '%'
  877. lpszTempStr1 = lpszTempStr;
  878. // Move pointer to point to second '%'.
  879. lpszTempStr += 1 ;
  880. // Copy.
  881. StringCopy( lpszTempStr1, lpszTempStr, ( dwLength - ( DWORD ) dwLocation ) ) ;
  882. dwLocation += 1 ;
  883. }
  884. else
  885. {
  886. // Replace '%NUMBER' with appropriate value.
  887. dwNumber = *( lpszTempStr + 1 ) - 48 ;
  888. if( dwIndex >= dwNumber )
  889. {
  890. ASSIGN_MEMORY( lpszDataToStore , WCHAR ,
  891. StringLength( lpszTempStr, 0 ) + EXTRA_MEM ) ;
  892. if( NULL == lpszDataToStore )
  893. { // No need to worry for 'g_lpszFileToSearch',
  894. // will be freed in calling function.
  895. DISPLAY_MEMORY_ALLOC_FAIL() ;
  896. return FALSE ;
  897. }
  898. dwTemp = StringLength( szValue[ dwNumber - 1 ], 0 ) ;
  899. dwLength = StringLength( g_lpszFileToSearch, 0 ) + dwTemp + EXTRA_MEM ;
  900. REALLOC_MEMORY( g_lpszFileToSearch , WCHAR , dwLength ) ;
  901. if( NULL == g_lpszFileToSearch )
  902. {
  903. FREE_MEMORY( lpszDataToStore ) ;
  904. DISPLAY_MEMORY_ALLOC_FAIL() ;
  905. return FALSE ;
  906. }
  907. // Check for '%' in the string after reallocation.
  908. if( NULL != ( lpszTempStr = FindAChar( ( g_lpszFileToSearch + dwLocation ), _T( '%' ) ) ) )
  909. {
  910. // Store data after '%NUMBER' into a different string.
  911. StringCopy( lpszDataToStore, ( lpszTempStr + 2 ),
  912. ( GetBufferSize( lpszDataToStore )/ sizeof( WCHAR ) ) );
  913. // Copy value to be replaced by '%NUMBER'.
  914. dwLocation = lpszTempStr - g_lpszFileToSearch;
  915. StringCopy( lpszTempStr, szValue[ dwNumber - 1 ], ( dwLength - ( DWORD ) dwLocation ) );
  916. // Copy string present after '%NUMBER' to origiinal strnig.
  917. StringConcat( lpszTempStr, lpszDataToStore,
  918. ( dwLength - ( DWORD ) dwLocation ) );
  919. dwLocation = ( lpszTempStr - g_lpszFileToSearch ) + dwTemp ;
  920. }
  921. FREE_MEMORY( lpszDataToStore ) ;
  922. }
  923. else
  924. {
  925. dwLocation += 1 ;
  926. }
  927. }
  928. }
  929. return TRUE;
  930. }
  931. BOOL
  932. SeperateFileAndArgs(
  933. IN OUT LPWSTR* lpszArguments,
  934. OUT LPWSTR* lpszFileName
  935. )
  936. /*++
  937. Routine Description:
  938. Separates EXE and ARGUMENTS from a command line argument.
  939. Arguments:
  940. [ IN OUT ] *lpszArguments - Contains command line arguments.
  941. [ IN ] *lpszFileName - Contains file name to execute.
  942. Return value:
  943. FALSE is returned when memory allocation failed els TRUE is returned..
  944. --*/
  945. {
  946. LPWSTR lpTemp = NULL;
  947. LPWSTR lpDummy = NULL;
  948. DWORD dwLength = 0;
  949. // Check for invalid parameter.
  950. if( ( NULL == lpszArguments ) ||
  951. ( NULL == *lpszArguments ) ||
  952. ( NULL == lpszFileName ) ||
  953. ( NULL != *lpszFileName ) )
  954. {
  955. SetLastError( ERROR_INVALID_PARAMETER );
  956. SaveLastError();
  957. DISPLAY_GET_REASON();
  958. return FALSE ;
  959. }
  960. // Initialize.
  961. lpTemp = *lpszArguments;
  962. // Remove any spaces appearing before the EXE.
  963. if( _T( ' ' ) == lpTemp[ 0 ] )
  964. {
  965. TrimString2( lpTemp, _T( " " ), TRIM_LEFT );
  966. }
  967. // Search for end of the EXE
  968. if( _T( '\"' ) == lpTemp[ 0 ] )
  969. { // EXE is wrapped in quotes.
  970. lpTemp += 1;
  971. lpDummy = FindAChar( lpTemp, _T( '\"' ) );
  972. }
  973. else
  974. { // Assumed that EXE is not wrapped in quotes.
  975. lpDummy = FindAChar( lpTemp, _T( ' ' ) );
  976. }
  977. // Get length of buffer to allocate.
  978. if( NULL == lpDummy )
  979. {
  980. dwLength = StringLength( lpTemp, 0 );
  981. }
  982. else
  983. {
  984. dwLength = ( DWORD ) ( DWORD_PTR ) ( lpDummy - lpTemp );
  985. }
  986. // Assign memory.
  987. ASSIGN_MEMORY( *lpszFileName , WCHAR , dwLength + EXTRA_MEM ) ;
  988. if( NULL == *lpszFileName )
  989. {
  990. DISPLAY_MEMORY_ALLOC_FAIL();
  991. return FALSE;
  992. }
  993. // '+1' for null termination.
  994. StringCopy( *lpszFileName, lpTemp, dwLength + 1 );
  995. if( NULL == lpDummy )
  996. {
  997. StringCopy( lpTemp, _T( "" ), StringLength( lpTemp, 0 ) );
  998. }
  999. else
  1000. {
  1001. if( _T( '\"' ) == *lpDummy )
  1002. {
  1003. StringCopy( lpTemp, lpTemp + dwLength + 2, StringLength( lpTemp, 0 ) );
  1004. }
  1005. else
  1006. {
  1007. StringCopy( lpTemp, lpTemp + dwLength + 1, StringLength( lpTemp, 0 ) );
  1008. }
  1009. }
  1010. return TRUE;
  1011. }