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.

905 lines
32 KiB

  1. #include "pch.h"
  2. #include "compress.h"
  3. DWORD
  4. _cdecl wmain(DWORD argc,
  5. LPCWSTR argv[] )
  6. /*++
  7. Routine Description : This is the main routine which calls other routines
  8. for processing the options and finding the files.
  9. [ IN ] argc : A DWORD variable having the argument count.
  10. [ IN ] argv : An array of constant strings of command line options.
  11. Return Value : DWORD
  12. Returns successfully if function is success otherwise return failure.
  13. --*/
  14. {
  15. TARRAY FileArr;
  16. TARRAY OutFileArr;
  17. DWORD dwStatus = 0;
  18. DWORD dwCount = 0;
  19. DWORD dwLoop = 0;
  20. BOOL bStatus = FALSE;
  21. BOOL bRename = FALSE;
  22. BOOL bNoLogo = FALSE;
  23. BOOL bUpdate = FALSE;
  24. BOOL bZx = FALSE;
  25. BOOL bZ = FALSE;
  26. BOOL bUsage = FALSE;
  27. WCHAR *wszPattern = NULL;
  28. DWORD dw = 0;
  29. BOOL bFound = FALSE;
  30. BOOL bTarget = FALSE;
  31. WCHAR szFileName[MAX_RES_STRING] = NULL_STRING;
  32. WCHAR szFileName1[MAX_RES_STRING] = NULL_STRING;
  33. WCHAR szDirectory[MAX_RES_STRING] = NULL_STRING;
  34. WCHAR szBuffer[MAX_RES_STRING] = NULL_STRING;
  35. if( argc<=1 )
  36. {
  37. DISPLAY_MESSAGE( stderr, GetResString( IDS_INVALID_SYNTAX ) );
  38. DISPLAY_MESSAGE( stderr, GetResString( IDS_HELP_MESSAGE) );
  39. return( EXIT_FAILURE);
  40. }
  41. dwStatus = ProcessOptions( argc, argv,
  42. &bRename,
  43. &bNoLogo,
  44. &bUpdate,
  45. &bZ,
  46. &bZx,
  47. &FileArr,
  48. &bUsage);
  49. if( EXIT_FAILURE == dwStatus )
  50. {
  51. DestroyDynamicArray( &FileArr);
  52. ReleaseGlobals();
  53. return( EXIT_FAILURE );
  54. }
  55. if( TRUE == bUsage )
  56. {
  57. DisplayHelpUsage();
  58. DestroyDynamicArray( &FileArr);
  59. ReleaseGlobals();
  60. return(EXIT_SUCCESS);
  61. }
  62. OutFileArr = CreateDynamicArray();
  63. if( NULL == OutFileArr )
  64. {
  65. SetLastError( ERROR_OUTOFMEMORY );
  66. SaveLastError();
  67. swprintf( szBuffer, L"%s %s", GetResString(IDS_TAG_ERROR), GetReason() );
  68. DISPLAY_MESSAGE( stderr, _X(szBuffer) );
  69. DestroyDynamicArray( &FileArr);
  70. ReleaseGlobals();
  71. return EXIT_FAILURE;
  72. }
  73. dwStatus = CheckArguments( bRename, FileArr, &OutFileArr, &bTarget );
  74. if( EXIT_FAILURE == dwStatus )
  75. {
  76. DestroyDynamicArray( &OutFileArr);
  77. DestroyDynamicArray( &FileArr);
  78. ReleaseGlobals();
  79. return( EXIT_FAILURE );
  80. }
  81. dwCount = DynArrayGetCount( OutFileArr );
  82. //the input file list not neccessary, destroy it
  83. DestroyDynamicArray(&FileArr );
  84. dwStatus = DoCompress( OutFileArr, bRename, bUpdate, bNoLogo, bZx, bZ, bTarget);
  85. ReleaseGlobals();
  86. DestroyDynamicArray( &OutFileArr);
  87. return( dwStatus );
  88. }
  89. DWORD CheckArguments( IN BOOL bRename,
  90. IN TARRAY FileArr,
  91. OUT PTARRAY OutFileArr,
  92. OUT PBOOL bTarget
  93. )
  94. /*++
  95. Routine Description: Checks the validity of input files and returns
  96. full path names of files and target file specification.
  97. Arguments :
  98. [ IN ] bRename : A boolean variable specified whether rename option is specified
  99. or not.
  100. [ IN ] FileArr : A dynamic array of list of files specified at command prompt.
  101. [ OUT ] OutFileArr: A dynamic array consists of complete file paths to be compressed.
  102. [ OUT ] bTarget : A boolean variable represents whether target file is specified or
  103. not.
  104. Return Value : DWORD
  105. Returns EXIT_SUCCESS if syntax of files is correct, returns EXIT_FAILURE
  106. otherwise.
  107. --*/
  108. {
  109. WIN32_FIND_DATA fData;
  110. HANDLE hFData;
  111. DWORD dwCount = 0;
  112. DWORD dw = 0;
  113. DWORD dwAttr = 0;
  114. LPWSTR szTempFile = NULL;
  115. LPWSTR szTemp = NULL;
  116. WCHAR* szTemp1 = NULL;
  117. WCHAR* szTemp2 = NULL;
  118. WCHAR* szFileName1 = NULL;
  119. WCHAR* szDirectory = NULL;
  120. WCHAR szFileName[MAX_RES_STRING] = NULL_STRING;
  121. WCHAR szBuffer[MAX_RES_STRING] = NULL_STRING;
  122. BOOL bFound = FALSE;
  123. DWORD cb = 0;
  124. //get the count of files
  125. dwCount = DynArrayGetCount( FileArr );
  126. //check if destination is not specified without rename specification
  127. if( 1 == dwCount && FALSE == bRename)
  128. {
  129. DISPLAY_MESSAGE( stderr, GetResString( IDS_NO_DESTINATION_SPECIFIED ) );
  130. return( EXIT_FAILURE );
  131. }
  132. //convert the source file names into full path names
  133. for( dw=0; dw<=dwCount-1; dw++ )
  134. {
  135. szTempFile = (LPWSTR)DynArrayItemAsString( FileArr, dw );
  136. if( NULL == szTempFile )
  137. continue;
  138. lstrcpy( szFileName, szTempFile );
  139. //if the filename is a pattern, then find the matched files
  140. if( (szTemp=wcsstr(szFileName, L"?")) != NULL || (szTemp = wcsstr( szFileName, L"*" )) != NULL )
  141. {
  142. //get the directory path from given file pattern
  143. if( (szTemp = wcsstr(szFileName, L"\\")) != NULL )
  144. {
  145. szDirectory = malloc( lstrlen(szFileName)*sizeof(WCHAR) );
  146. if( NULL == szDirectory )
  147. {
  148. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  149. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  150. SetLastError( ERROR_OUTOFMEMORY );
  151. SaveLastError();
  152. DISPLAY_MESSAGE( stderr, GetReason() );
  153. return( EXIT_FAILURE );
  154. }
  155. lstrcpy( szDirectory, szFileName );
  156. szTemp1 = wcsrchr( szDirectory, L'\\');
  157. szTemp1++;
  158. *szTemp1 = 0;
  159. }
  160. hFData = FindFirstFileEx( szFileName,
  161. FindExInfoStandard,
  162. &fData,
  163. FindExSearchNameMatch,
  164. NULL,
  165. 0);
  166. //if no file found insert File Not Found code
  167. if( INVALID_HANDLE_VALUE == hFData )
  168. break;
  169. do
  170. {
  171. if( lstrcmp(fData.cFileName, L".")!=0 && lstrcmp(fData.cFileName, L"..") != 0 &&
  172. !(FILE_ATTRIBUTE_DIRECTORY & fData.dwFileAttributes) )
  173. {
  174. //copy the file into temporary file and get the full path for that file
  175. if( szDirectory != NULL )
  176. szFileName1 = malloc( (lstrlen(szDirectory)+lstrlen(fData.cFileName)+10)*sizeof(WCHAR) );
  177. else
  178. szFileName1 = malloc( (lstrlen(fData.cFileName)+10)*sizeof(WCHAR) );
  179. if(NULL == szFileName1 )
  180. {
  181. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  182. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  183. SetLastError( ERROR_OUTOFMEMORY );
  184. SaveLastError();
  185. DISPLAY_MESSAGE( stderr, GetReason() );
  186. return( EXIT_FAILURE );
  187. }
  188. if( szDirectory != NULL )
  189. swprintf( szFileName1, L"%s%s", szDirectory, fData.cFileName );
  190. else
  191. lstrcpy( szFileName1, fData.cFileName );
  192. DynArrayAppendString( *OutFileArr, szFileName1, lstrlen(szFileName1) );
  193. SAFE_FREE( szFileName1 );
  194. bFound = TRUE;
  195. }
  196. }while(FindNextFile(hFData, &fData));
  197. FindClose(hFData);
  198. //if not found insert file not found into array
  199. if( !bFound )
  200. DynArrayAppendString( *OutFileArr, FILE_NOT_FOUND, lstrlen(FILE_NOT_FOUND) );
  201. SAFE_FREE( szDirectory );
  202. }
  203. else
  204. {
  205. //append the file
  206. DynArrayAppendString( *OutFileArr, szFileName, lstrlen(szFileName) );
  207. }
  208. }
  209. //check if more than two source files specified and destination is a directory or not
  210. //get count
  211. dwCount = DynArrayGetCount( *OutFileArr );
  212. if( dwCount<=1 && FALSE == bRename )
  213. {
  214. DISPLAY_MESSAGE( stderr, GetResString( IDS_NO_DESTINATION_SPECIFIED ) );
  215. return( EXIT_FAILURE );
  216. }
  217. *bTarget = FALSE;
  218. if( 2==dwCount )
  219. {
  220. //get the target file
  221. szTempFile = (LPWSTR)DynArrayItemAsString( *OutFileArr, dwCount-1 );
  222. if ( NULL == szTempFile )
  223. {
  224. //No need to break here..continue..
  225. }
  226. dwAttr = GetFileAttributes( szTempFile );
  227. if( -1 == dwAttr )
  228. {
  229. if( FALSE == bRename )
  230. *bTarget = TRUE;
  231. }
  232. else
  233. if( (dwAttr & FILE_ATTRIBUTE_DIRECTORY) )
  234. *bTarget = TRUE;
  235. else
  236. if( FALSE == bRename )
  237. *bTarget = TRUE;
  238. }
  239. //if multiple source files specified
  240. if( dwCount > 2 )
  241. {
  242. //get the target file
  243. szTempFile = (LPWSTR)DynArrayItemAsString( *OutFileArr, dwCount-1 );
  244. if ( NULL == szTempFile )
  245. {
  246. //No need to break here..continue
  247. }
  248. dwAttr = GetFileAttributes( szTempFile );
  249. //check for nonexisting file
  250. if( -1 == dwAttr && FALSE == bRename )
  251. {
  252. DISPLAY_MESSAGE( stderr, GetResString( IDS_DIRECTORY_NOTFOUND) );
  253. return( EXIT_FAILURE );
  254. }
  255. //if target name is not directory and bRename is not specified
  256. if( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) && FALSE == bRename )
  257. {
  258. DISPLAY_MESSAGE( stderr, GetResString( IDS_INVALID_DIRECTORY ) );
  259. return( EXIT_FAILURE );
  260. }
  261. if( (dwAttr & FILE_ATTRIBUTE_DIRECTORY) )
  262. *bTarget = TRUE;
  263. }
  264. return EXIT_SUCCESS;
  265. }
  266. DWORD DoCompress( IN TARRAY FileArr,
  267. IN BOOL bRename,
  268. IN BOOL bUpdate,
  269. IN BOOL bNoLogo,
  270. IN BOOL bZx,
  271. IN BOOL bZ,
  272. IN BOOL bTarget
  273. )
  274. /*++
  275. Routine Description : This routine compresses the specified files into target files.
  276. Arguments:
  277. [ IN ] FileArr : A list of source and target files for compression.
  278. [ IN ] bRename : A boolean varaible specifies whether output file is a rename of
  279. source file or not.
  280. [ IN ] bUpdate : A boolean varaible specifies compress if outof date.
  281. [ IN ] bUpdate : A boolean varaible specifies if copy right info display or not.
  282. [ IN ] bZx : A boolean varaible specifies LZX compression apply or not.
  283. [ IN ] bZ : A boolean varaible specifies ZIP compression apply or not.
  284. [ IN ] dwZq : A varaible specifies level of Quantom compression to apply if specified.
  285. [ IN ] bTarget : A boolean varaible tells whether target file is specified or not.
  286. Return Value :
  287. EXIT_SUCCESS if succefully compressed all the files, return EXIT_FAILURE otherwise.
  288. --*/
  289. {
  290. TARRAY OutFileArr;
  291. PLZINFO pLZI;
  292. TCOMP Level;
  293. TCOMP Mem;
  294. DWORD dwStatus = 0;
  295. DWORD dwCount = 0;
  296. DWORD dwLoop = 0;
  297. DWORD dw = 0;
  298. DWORD dwAttr = 0;
  299. BOOL bFound = FALSE;
  300. WCHAR wchTemp = 0;
  301. LPWSTR szLastfile = NULL;
  302. LPWSTR szSourcefile = NULL;
  303. WCHAR* szTargetfile = NULL;
  304. WCHAR* szOutfile = NULL;
  305. CHAR* szSourcefiletmp = NULL;
  306. CHAR* szOutfiletmp = NULL;
  307. WCHAR szBuffer[MAX_PATH] = NULL_STRING;
  308. DWORD fError = 0;
  309. float cblTotInSize = 0.0;
  310. float cblTotOutSize = 0.0;
  311. float cblAdjInSize = 0;
  312. float cblAdjOutSize = 0;
  313. DWORD dwFilesCount = 0;
  314. int cb = 0;
  315. dwCount = dwLoop = DynArrayGetCount( FileArr );
  316. //take the last file as target file
  317. if( bTarget )
  318. {
  319. szLastfile = (LPWSTR)DynArrayItemAsString( FileArr, dwCount-1 );
  320. if ( NULL == szLastfile )
  321. {
  322. //No need to break here..continue..
  323. }
  324. dwLoop--;
  325. }
  326. //intialize the global buffers
  327. pLZI = InitGlobalBuffersEx();
  328. if (!pLZI)
  329. {
  330. DISPLAY_MESSAGE( stderr, L"Unable to initialize\n" );
  331. return EXIT_FAILURE;
  332. }
  333. if( bZx )
  334. {
  335. // LZX. Also set memory.
  336. //Mem = (TCOMP)atoi("");
  337. Mem = (TCOMP)0;
  338. if((Mem < (tcompLZX_WINDOW_LO >> tcompSHIFT_LZX_WINDOW))
  339. || (Mem > (tcompLZX_WINDOW_HI >> tcompSHIFT_LZX_WINDOW))) {
  340. Mem = (tcompLZX_WINDOW_LO >> tcompSHIFT_LZX_WINDOW);
  341. }
  342. byteAlgorithm = LZX_ALG;
  343. DiamondCompressionType = TCOMPfromLZXWindow( Mem );
  344. }
  345. else if( bZ )
  346. {
  347. DiamondCompressionType = tcompTYPE_MSZIP;
  348. byteAlgorithm = MSZIP_ALG;
  349. }
  350. else
  351. {
  352. DiamondCompressionType = 0;
  353. byteAlgorithm = DEFAULT_ALG;
  354. }
  355. /* no quantom support for this shipment
  356. if(dwZq != 0 )
  357. {
  358. //
  359. // Quantum. Also set level.
  360. //
  361. Level = (TCOMP)dwZq;
  362. //not supported yet, keep this for the time sake
  363. //Mem = (p = strchr(argv[i]+3,',')) ? (TCOMP)atoi(p+1) : 0;
  364. Mem = 0;
  365. if((Level < (tcompQUANTUM_LEVEL_LO >> tcompSHIFT_QUANTUM_LEVEL))
  366. || (Level > (tcompQUANTUM_LEVEL_HI >> tcompSHIFT_QUANTUM_LEVEL)))
  367. {
  368. Level = ((tcompQUANTUM_LEVEL_HI - tcompQUANTUM_LEVEL_LO) / 2)
  369. + tcompQUANTUM_LEVEL_LO;
  370. Level >>= tcompSHIFT_QUANTUM_LEVEL;
  371. }
  372. if((Mem < (tcompQUANTUM_MEM_LO >> tcompSHIFT_QUANTUM_MEM))
  373. || (Mem > (tcompQUANTUM_MEM_HI >> tcompSHIFT_QUANTUM_MEM)))
  374. {
  375. Mem = ((tcompQUANTUM_MEM_HI - tcompQUANTUM_MEM_LO) / 2)
  376. + tcompQUANTUM_MEM_LO;
  377. Mem >>= tcompSHIFT_QUANTUM_MEM;
  378. }
  379. byteAlgorithm = QUANTUM_ALG;
  380. DiamondCompressionType = TCOMPfromTypeLevelMemory(
  381. tcompTYPE_QUANTUM,
  382. Level,
  383. Mem
  384. );
  385. }
  386. */
  387. //display one blank line
  388. DISPLAY_MESSAGE( stdout, BLANK_LINE );
  389. if( !bNoLogo )
  390. {
  391. DISPLAY_MESSAGE( stdout, GetResString( IDS_BANNER_TEXT ) );
  392. DISPLAY_MESSAGE( stdout, GetResString( IDS_VER_PRODUCTVERSION_STR ) );
  393. }
  394. //now compress the source files one by one
  395. for( dw=0; dw<dwLoop; dw++ )
  396. {
  397. //get the source file
  398. szSourcefile = (LPWSTR)DynArrayItemAsString( FileArr, dw );
  399. if( NULL == szSourcefile )
  400. continue;
  401. if( lstrcmp( szSourcefile, FILE_NOT_FOUND) == 0 )
  402. {
  403. DISPLAY_MESSAGE( stderr, GetResString( IDS_FILE_NOTFOUND ) );
  404. continue;
  405. }
  406. //get file attributes
  407. dwAttr = GetFileAttributes( szSourcefile );
  408. //check if file exist or not
  409. if( -1 == dwAttr )
  410. {
  411. DISPLAY_MESSAGE1( stderr, szBuffer, GetResString( IDS_NO_SOURCEFILE ), szSourcefile );
  412. continue;
  413. }
  414. //skip if it is a direcotry
  415. if( dwAttr & FILE_ATTRIBUTE_DIRECTORY )
  416. continue;
  417. //make the target file
  418. //check if it is a directory
  419. if( bTarget )
  420. {
  421. dwAttr = GetFileAttributes( szLastfile );
  422. if( -1 != dwAttr && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
  423. {
  424. szTargetfile = malloc( (lstrlen(szLastfile)+lstrlen(szSourcefile)+10)*sizeof(WCHAR) );
  425. if(NULL == szTargetfile )
  426. {
  427. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  428. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  429. SetLastError( ERROR_OUTOFMEMORY );
  430. SaveLastError();
  431. DISPLAY_MESSAGE( stderr, GetReason() );
  432. return( EXIT_FAILURE );
  433. }
  434. swprintf( szTargetfile, L"%s\\%s", szLastfile, szSourcefile );
  435. }
  436. else
  437. {
  438. szTargetfile = malloc( (lstrlen(szLastfile)+10)*sizeof(WCHAR) );
  439. if(NULL == szTargetfile )
  440. {
  441. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  442. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  443. SetLastError( ERROR_OUTOFMEMORY );
  444. SaveLastError();
  445. DISPLAY_MESSAGE( stderr, GetReason() );
  446. return( EXIT_FAILURE );
  447. }
  448. swprintf( szTargetfile, L"%s", szLastfile );
  449. }
  450. }
  451. else
  452. {
  453. //obviously rename has specified, copy source file into target file
  454. szTargetfile = malloc( (lstrlen(szSourcefile)+10)*sizeof(WCHAR) );
  455. if(NULL == szTargetfile )
  456. {
  457. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  458. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  459. SetLastError( ERROR_OUTOFMEMORY );
  460. SaveLastError();
  461. DISPLAY_MESSAGE( stderr, GetReason() );
  462. return( EXIT_FAILURE );
  463. }
  464. lstrcpy( szTargetfile, szSourcefile);
  465. }
  466. //allocate memory for szOutfile
  467. szOutfile = malloc( (lstrlen(szTargetfile)+10)*sizeof(WCHAR) );
  468. if(NULL == szTargetfile )
  469. {
  470. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  471. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  472. SetLastError( ERROR_OUTOFMEMORY );
  473. SaveLastError();
  474. DISPLAY_MESSAGE( stderr, GetReason() );
  475. SAFE_FREE( szTargetfile );
  476. return( EXIT_FAILURE );
  477. }
  478. lstrcpy( szOutfile, szTargetfile );
  479. if( bRename )
  480. MakeCompressedNameW( szTargetfile );
  481. if (( !bUpdate ) ||
  482. ( FileTimeIsNewer( szSourcefile, szTargetfile )))
  483. {
  484. //if the diamond compression type is given
  485. if(DiamondCompressionType)
  486. {
  487. //convert source file and target file names from wide char string to char strings
  488. //this is because the API in lib is written for char strings only
  489. cb = WideCharToMultiByte( CP_THREAD_ACP, 0, szSourcefile, lstrlen( szSourcefile ),
  490. szSourcefiletmp, 0, NULL, NULL );
  491. szSourcefiletmp = malloc( (cb+10)*sizeof(char) );
  492. if(NULL == szTargetfile )
  493. {
  494. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  495. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  496. SetLastError( ERROR_OUTOFMEMORY );
  497. SaveLastError();
  498. DISPLAY_MESSAGE( stderr, GetReason() );
  499. SAFE_FREE( szTargetfile );
  500. SAFE_FREE( szOutfile );
  501. return( EXIT_FAILURE );
  502. }
  503. cb = WideCharToMultiByte( CP_THREAD_ACP, 0, szOutfile, lstrlen( szOutfile ),
  504. szOutfiletmp, 0, NULL, NULL );
  505. szOutfiletmp = malloc( (cb+10)*sizeof(char) );
  506. if(NULL == szTargetfile )
  507. {
  508. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  509. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  510. SetLastError( ERROR_OUTOFMEMORY );
  511. SaveLastError();
  512. DISPLAY_MESSAGE( stderr, GetReason() );
  513. SAFE_FREE( szTargetfile );
  514. SAFE_FREE( szOutfile );
  515. return( EXIT_FAILURE );
  516. }
  517. ZeroMemory(szSourcefiletmp, lstrlen(szSourcefile)+10 );
  518. ZeroMemory(szOutfiletmp, lstrlen(szOutfile)+10);
  519. if( FALSE == WideCharToMultiByte( CP_THREAD_ACP, 0, szSourcefile, lstrlen( szSourcefile ),
  520. szSourcefiletmp, cb+10, NULL, NULL ) )
  521. {
  522. SaveLastError();
  523. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  524. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  525. DISPLAY_MESSAGE( stderr, GetReason() );
  526. SAFE_FREE( szTargetfile );
  527. SAFE_FREE( szOutfile );
  528. SAFE_FREE( szSourcefiletmp );
  529. SAFE_FREE( szOutfiletmp );
  530. return EXIT_FAILURE;
  531. }
  532. if( FALSE == WideCharToMultiByte( CP_THREAD_ACP, 0, szOutfile, lstrlen( szOutfile ),
  533. szOutfiletmp, cb+10, NULL, NULL ) )
  534. {
  535. SaveLastError();
  536. DISPLAY_MESSAGE( stderr, GetResString(IDS_TAG_ERROR) );
  537. DISPLAY_MESSAGE( stderr, EMPTY_SPACE );
  538. DISPLAY_MESSAGE( stderr, GetReason() );
  539. SAFE_FREE( szTargetfile );
  540. SAFE_FREE( szOutfile );
  541. SAFE_FREE( szSourcefiletmp );
  542. SAFE_FREE( szOutfiletmp );
  543. return EXIT_FAILURE;
  544. }
  545. fError = DiamondCompressFile(ProcessNotification, szSourcefiletmp,
  546. szOutfiletmp,bRename,pLZI);
  547. }
  548. else
  549. {
  550. fError = Compress(ProcessNotification, szSourcefile,
  551. szOutfile, byteAlgorithm, bRename, pLZI);
  552. }
  553. if(fError == TRUE)
  554. {
  555. bFound = TRUE;
  556. dwFilesCount++;
  557. if (pLZI && pLZI->cblInSize && pLZI->cblOutSize)
  558. {
  559. // Keep track of cumulative statistics.
  560. cblTotInSize += pLZI->cblInSize;
  561. cblTotOutSize += pLZI->cblOutSize;
  562. // Display report for each file.
  563. fwprintf(stdout, GetResString( IDS_FILE_REPORT ),szSourcefile, pLZI->cblInSize, pLZI->cblOutSize,
  564. (INT)(100 - ((100 * (LONGLONG) pLZI->cblOutSize) / pLZI->cblInSize)));
  565. }
  566. else
  567. {
  568. fwprintf( stderr, GetResString( IDS_EMPTY_FILE_REPORT ), 0,0 );
  569. }
  570. // Separate individual file processing message blocks by a blank line.
  571. DISPLAY_MESSAGE( stdout, BLANK_LINE );
  572. }
  573. }
  574. else
  575. {
  576. DISPLAY_MESSAGE( stdout, GetResString( IDS_FILE_ALREADY_UPDATED ) );
  577. FreeGlobalBuffers(pLZI);
  578. SAFE_FREE( szTargetfile );
  579. SAFE_FREE( szOutfile );
  580. SAFE_FREE( szSourcefiletmp );
  581. SAFE_FREE( szOutfiletmp );
  582. return( EXIT_SUCCESS );
  583. }
  584. SAFE_FREE( szTargetfile );
  585. SAFE_FREE( szOutfile );
  586. SAFE_FREE( szSourcefiletmp );
  587. SAFE_FREE( szOutfiletmp );
  588. }
  589. // Free memory used by ring buffer and I/O buffers.
  590. FreeGlobalBuffers(pLZI);
  591. // Display cumulative report for multiple files.
  592. if (dwFilesCount >= 1 && bFound)
  593. {
  594. cblAdjInSize = cblTotInSize;
  595. cblAdjOutSize = cblTotOutSize;
  596. while (cblAdjInSize > 100000)
  597. {
  598. cblAdjInSize /= 2;
  599. cblAdjOutSize /= 2;
  600. }
  601. cblAdjOutSize += (cblAdjInSize / 200); // round off (+0.5%)
  602. if (cblAdjOutSize < 0)
  603. {
  604. cblAdjOutSize = 0;
  605. }
  606. fwprintf(stdout, GetResString( IDS_TOTAL_REPORT ), dwFilesCount, (DWORD)cblTotInSize, (DWORD)cblTotOutSize,
  607. (INT)(100 - 100 * cblAdjOutSize / cblAdjInSize));
  608. }
  609. SAFE_FREE( szTargetfile );
  610. SAFE_FREE( szOutfile );
  611. SAFE_FREE( szSourcefiletmp );
  612. SAFE_FREE( szOutfiletmp );
  613. if( bFound )
  614. return EXIT_SUCCESS;
  615. else
  616. return EXIT_FAILURE;
  617. }
  618. DWORD ProcessOptions( IN DWORD argc,
  619. IN LPCWSTR argv[],
  620. OUT PBOOL pbRename,
  621. OUT PBOOL pbNoLogo,
  622. OUT PBOOL pbUpdate,
  623. OUT PBOOL pbZ,
  624. OUT PBOOL pbZx,
  625. OUT PTARRAY pArrVal,
  626. OUT PBOOL pbUsage
  627. )
  628. /*++
  629. Routine Description : Function used to process the main options
  630. Arguments:
  631. [ in ] argc : Number of command line arguments
  632. [ in ] argv : Array containing command line arguments
  633. [ out ] pbRename : A pointer to boolean variable returns TRUE if Rename option is specified.
  634. [ out ] pbNoLogo : A pointer to boolean variable returns TRUE if Suppress option is specified.
  635. [ out ] pbUpdate : A pointer to boolean variable returns TRUE if Update option is specified.
  636. [ out ] pbZx : A pointer to boolean variable returns TRUE if Zx option is specified.
  637. [ out ] pbZ : A pointer to boolean variable returns TRUE if Z option is specified.
  638. [ out ] dwZq : A pointer to a DWORD variable returns value for quantom compression.
  639. [ out ] pArrVal : A pointer to dynamic array returns file names specified as default options.
  640. [ out ] pbUsage : A pointer to boolean variable returns TRUE if Usage option is specified.
  641. Return Type : DWORD
  642. A Integer value indicating EXIT_SUCCESS on successful parsing of
  643. command line else EXIT_FAILURE
  644. --*/
  645. {
  646. BOOL bStatus = 0;
  647. DWORD dwAttr = 0;
  648. LPWSTR szFilePart = NULL;
  649. LPWSTR szBuffer = NULL;
  650. WCHAR szBuffer1[MAX_PATH] = NULL_STRING;
  651. DWORD dwCount = 0;
  652. DWORD dw = 0;
  653. DWORD pos = 0;
  654. TCMDPARSER cmdOptions[]={
  655. {CMDOPTION_RENAME, 0, 1,0,pbRename, NULL_STRING,NULL,NULL},
  656. {CMDOPTION_UPDATE, 0, 1,0,pbUpdate, NULL_STRING,NULL,NULL},
  657. {CMDOPTION_SUPPRESS, 0, 1,0,pbNoLogo , NULL_STRING,NULL,NULL},
  658. {CMDOPTION_ZX, 0, 1,0,pbZx, NULL_STRING,NULL,NULL},
  659. {CMDOPTION_Z, 0, 1,0,pbZ, NULL_STRING,NULL,NULL},
  660. {CMDOPTION_DEFAULT, 0, 0,0,pArrVal, NULL_STRING,NULL,NULL},
  661. {CMDOPTION_USAGE, CP_USAGE, 1,0,pbUsage, NULL_STRING,NULL,NULL}
  662. };
  663. *pArrVal=CreateDynamicArray();
  664. if( NULL == *pArrVal )
  665. {
  666. DISPLAY_MESSAGE( stderr, GetResString(IDS_NO_MEMORY) );
  667. return( EXIT_FAILURE );
  668. }
  669. //set the flags for options
  670. cmdOptions[OI_DEFAULT].pValue = pArrVal;
  671. cmdOptions[OI_DEFAULT].dwFlags = CP_DEFAULT | CP_MODE_ARRAY | CP_TYPE_TEXT;
  672. // cmdOptions[OI_ZQ].dwFlags = CP_VALUE_MASK | CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY;
  673. //process the command line options and display error if it fails
  674. if( DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) == FALSE )
  675. {
  676. DISPLAY_MESSAGE(stderr, GetResString(IDS_ERROR_TAG) );
  677. DISPLAY_MESSAGE(stderr,GetReason());
  678. return( EXIT_FAILURE );
  679. }
  680. //if usage specified with any other value display error and return with failure
  681. if( ( TRUE == *pbUsage ) && ( argc > 2 ) )
  682. {
  683. DISPLAY_MESSAGE( stderr, GetResString(IDS_INVALID_SYNTAX) );
  684. return( EXIT_FAILURE );
  685. }
  686. if( TRUE == *pbUsage )
  687. return( EXIT_SUCCESS);
  688. /*
  689. if( cmdOptions[OI_ZQ].dwActuals != 0 && cmdOptions[OI_Z].dwActuals != 0 )
  690. {
  691. DISPLAY_MESSAGE( stderr, GetResString(IDS_MORETHAN_ONE_OPTION ) );
  692. DISPLAY_MESSAGE( stderr, GetResString( IDS_HELP_MESSAGE) );
  693. return( EXIT_FAILURE );
  694. }
  695. //dont allow more than one option
  696. if( cmdOptions[OI_ZQ].dwActuals != 0 && cmdOptions[OI_ZX].dwActuals != 0 )
  697. {
  698. DISPLAY_MESSAGE( stderr, GetResString(IDS_MORETHAN_ONE_OPTION ) );
  699. DISPLAY_MESSAGE( stderr, GetResString( IDS_HELP_MESSAGE) );
  700. return( EXIT_FAILURE );
  701. }
  702. */
  703. if( cmdOptions[OI_ZX].dwActuals != 0 && cmdOptions[OI_Z].dwActuals != 0 )
  704. {
  705. DISPLAY_MESSAGE( stderr, GetResString(IDS_MORETHAN_ONE_OPTION ) );
  706. DISPLAY_MESSAGE( stderr, GetResString( IDS_HELP_MESSAGE) );
  707. return( EXIT_FAILURE );
  708. }
  709. /*
  710. //check if wrong value is specified for zq quantom level
  711. if( cmdOptions[OI_ZQ].dwActuals != 0 && !(*pdwZq>=1 && *pdwZq<=7) )
  712. {
  713. DISPLAY_MESSAGE( stderr, GetResString( IDS_ERROR_QUANTOM_LEVEL ) );
  714. DISPLAY_MESSAGE( stderr, GetResString( IDS_HELP_MESSAGE) );
  715. return(EXIT_FAILURE);
  716. }
  717. */
  718. dwCount = DynArrayGetCount( *pArrVal );
  719. if( 0 == dwCount )
  720. {
  721. DISPLAY_MESSAGE( stderr, GetResString( IDS_NO_FILE_SPECIFIED ) );
  722. return( EXIT_FAILURE );
  723. }
  724. //this is to check if illegal characters are specified in file name
  725. for(dw=0; dw<dwCount; dw++ )
  726. {
  727. szBuffer=(LPWSTR)DynArrayItemAsString( *pArrVal, dw);
  728. if( NULL == szBuffer )
  729. continue;
  730. pos = wcscspn( szBuffer, ILLEGAL_CHR );
  731. if( pos< (DWORD)lstrlen(szBuffer) )
  732. {
  733. DISPLAY_MESSAGE1( stderr, szBuffer1, GetResString( INVALID_FILE_NAME ), szBuffer );
  734. return( EXIT_FAILURE );
  735. }
  736. }
  737. return( EXIT_SUCCESS );
  738. }
  739. DWORD DisplayHelpUsage()
  740. /*++
  741. Routine Description : This routine is to display the help usage.
  742. Return Value : DWORD
  743. Returns success.
  744. --*/
  745. {
  746. DWORD dw = 0;
  747. for(dw=IDS_MAIN_HELP_BEGIN;dw<=IDS_MAIN_HELP_END;dw++)
  748. DISPLAY_MESSAGE(stdout, GetResString(dw) );
  749. return( EXIT_SUCCESS);
  750. }