home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2002 July / VPR0207A.ISO / OLS / UNRAR32007 / unrar32007.lzh / src.lzh / src / unrar32.cxx < prev    next >
C/C++ Source or Header  |  2001-02-12  |  14KB  |  597 lines

  1. /*
  2.  *   Copyright (c) 1998-2001 T. Kamei (kamei@jsdlab.co.jp)
  3.  *
  4.  *   Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for any purpose is hereby granted provided
  6.  * that the above copyright notice and this permission notice appear
  7.  * in all copies of the software and related documentation.
  8.  *
  9.  *                          NO WARRANTY
  10.  *
  11.  *   THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY WARRANTIES;
  12.  * WITHOUT EVEN THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
  13.  * FOR A PARTICULAR PURPOSE.
  14.  */
  15.  
  16. #include "comm-arc.h"
  17. #include <commctrl.h>
  18. #include <stdio.h>
  19. #define EXTERN /* empty */
  20. #include "unrarapi.h"
  21. #include "util.h"
  22. #include "arcinfo.h"
  23. #include "rar.h"
  24. #include "unrar32.h"
  25. #include "resource.h"
  26. #include "dialog.h"
  27.  
  28. #define UNRAR32_VERSION 7
  29.  
  30. class in_progress
  31. {
  32.   static long lock;
  33.   int non_zero;
  34. public:
  35.   in_progress () {non_zero = InterlockedIncrement (&lock);}
  36.   ~in_progress () {InterlockedDecrement (&lock);}
  37.   int locked () const {return non_zero;}
  38. };
  39.  
  40. long in_progress::lock = -1;
  41.  
  42. static void
  43. no_unrar_dll (HWND hwnd)
  44. {
  45.   char buf[1024];
  46.   if (!LoadString (lstate.hinst, IDS_UNRAR_NOT_LOADED, buf, sizeof buf))
  47.     strcpy (buf, "Unable to load UnRAR.DLL");
  48.   MessageBox (hwnd, buf, 0, MB_ICONHAND);
  49. }
  50.  
  51. #define IN_API(not_loaded, busy) \
  52.   if (!lstate.hrardll) return (not_loaded); \
  53.   in_progress in_progress__; \
  54.   if (in_progress__.locked ()) return (busy)
  55.  
  56. WORD WINAPI
  57. UnrarGetVersion ()
  58. {
  59.   return lstate.hrardll ? UNRAR32_VERSION : 0;
  60. }
  61.  
  62. BOOL WINAPI
  63. UnrarGetRunning ()
  64. {
  65.   IN_API (1, 1);
  66.   return 0;
  67. }
  68.  
  69. BOOL WINAPI
  70. UnrarGetBackGroundMode ()
  71. {
  72.   return lstate.s_bg_mode;
  73. }
  74.  
  75. BOOL WINAPI
  76. UnrarSetBackGroundMode (BOOL mode)
  77. {
  78.   IN_API (0, 0);
  79.   lstate.s_bg_mode = mode;
  80.   return 1;
  81. }
  82.  
  83. BOOL WINAPI
  84. UnrarGetCursorMode ()
  85. {
  86.   return lstate.s_cursor_mode;
  87. }
  88.  
  89. BOOL WINAPI
  90. UnrarSetCursorMode (BOOL cursor_mode)
  91. {
  92.   IN_API (0, 0);
  93.   lstate.s_cursor_mode = cursor_mode;
  94.   return 1;
  95. }
  96.  
  97. WORD WINAPI
  98. UnrarGetCursorInterval ()
  99. {
  100.   return lstate.s_cursor_interval;
  101. }
  102.  
  103. BOOL WINAPI
  104. UnrarSetCursorInterval (WORD interval)
  105. {
  106.   IN_API (0, 0);
  107.   lstate.s_cursor_interval = interval;
  108.   return 1;
  109. }
  110.  
  111. int WINAPI
  112. Unrar (HWND hwnd, LPCSTR args, LPSTR buf, DWORD size)
  113. {
  114.   if (!lstate.hrardll)
  115.     no_unrar_dll (hwnd);
  116.  
  117.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  118.  
  119.   cmdline cl;
  120.   int e = cl.parse (args, 1);
  121.   if (e)
  122.     return e;
  123.  
  124.   int disable = hwnd ? EnableWindow (hwnd, 0) : 1;
  125.  
  126.   ostrbuf obuf (buf, size);
  127.   UnRAR unrar (hwnd, obuf);
  128.   int x = unrar.xmain (cl.argc (), cl.argv ());
  129.   if (!disable)
  130.     EnableWindow (hwnd, 1);
  131.   return x;
  132. }
  133.  
  134. static int
  135. setpass (HANDLE h, char *&passwd)
  136. {
  137.   if (!passwd)
  138.     passwd = askpass_dialog (0);
  139.   if (!passwd)
  140.     return ERAR_BAD_DATA;
  141.   rarSetPassword (h, passwd);
  142.   return 0;
  143. }
  144.  
  145. BOOL WINAPI
  146. UnrarCheckArchive (const char *path, int mode)
  147. {
  148.   IN_API (0, 0);
  149.  
  150.   if ((mode & (CHECKARCHIVE_MASK | CHECKARCHIVE_ALL))
  151.       == (CHECKARCHIVE_RAPID | CHECKARCHIVE_ALL))
  152.     mode = (mode & ~CHECKARCHIVE_MASK) | CHECKARCHIVE_BASIC;
  153.  
  154.   rarData rd;
  155.   if (!rd.open (path,
  156.                 ((mode & CHECKARCHIVE_MASK) == CHECKARCHIVE_FULLCRC
  157.                  ? RAR_OM_EXTRACT : RAR_OM_LIST)))
  158.     return 0;
  159.  
  160.   char *passwd = 0;
  161.   int e, nfiles = 0;
  162.   while (!(e = rd.read_header ())
  163.          && !(rd.hd.Flags & FRAR_NEXTVOL)
  164.          && ((mode & CHECKARCHIVE_MASK) != CHECKARCHIVE_FULLCRC
  165.              || !(rd.hd.Flags & FRAR_ENCRYPTED)
  166.              || !(e = setpass (rd.h, passwd)))
  167.          && (!(e = rd.test ())
  168.              || (e == ERAR_BAD_DATA
  169.                  && mode & CHECKARCHIVE_RECOVERY)))
  170.     if ((mode & CHECKARCHIVE_MASK) == CHECKARCHIVE_RAPID
  171.         && ++nfiles == 3)
  172.       {
  173.         e = ERAR_END_ARCHIVE;
  174.         break;
  175.       }
  176.   if (e && e != ERAR_END_ARCHIVE)
  177.     return 0;
  178.  
  179.   if (mode & CHECKARCHIVE_SFX
  180.       && file_executable_p (path))
  181.     return 0x8000 + SFX_WIN32_UNKNOWN;
  182.  
  183.   return 1;
  184. }
  185.  
  186. int WINAPI
  187. UnrarGetFileCount (const char *path)
  188. {
  189.   IN_API (-1, -1);
  190.  
  191.   rarData rd;
  192.   if (!rd.open (path, RAR_OM_LIST))
  193.     return -1;
  194.   int e;
  195.   for (int nfiles = 0;
  196.        !(e = rd.read_header ()) && !(e = rd.skip ());
  197.        nfiles++)
  198.     ;
  199.   return !e || e == ERAR_END_ARCHIVE ? nfiles : -1;
  200. }
  201.  
  202. BOOL WINAPI
  203. UnrarQueryFunctionList (int i)
  204. {
  205.   switch (i)
  206.     {
  207.     case ISARC:
  208.     case ISARC_GET_VERSION:
  209.     case ISARC_GET_CURSOR_INTERVAL:
  210.     case ISARC_SET_CURSOR_INTERVAL:
  211.     case ISARC_GET_BACK_GROUND_MODE:
  212.     case ISARC_SET_BACK_GROUND_MODE:
  213.     case ISARC_GET_CURSOR_MODE:
  214.     case ISARC_SET_CURSOR_MODE:
  215.     case ISARC_GET_RUNNING:
  216.     case ISARC_CHECK_ARCHIVE:
  217.     //case ISARC_CONFIG_DIALOG:
  218.     case ISARC_GET_FILE_COUNT:
  219.     case ISARC_QUERY_FUNCTION_LIST:
  220.     case ISARC_GET_ARC_FILE_INFO:
  221.     case ISARC_OPEN_ARCHIVE:
  222.     case ISARC_CLOSE_ARCHIVE:
  223.     case ISARC_FIND_FIRST:
  224.     case ISARC_FIND_NEXT:
  225.     case ISARC_GET_ARC_FILE_NAME:
  226.     case ISARC_GET_ARC_FILE_SIZE:
  227.     case ISARC_GET_ARC_ORIGINAL_SIZE:
  228.     case ISARC_GET_ARC_COMPRESSED_SIZE:
  229.     case ISARC_GET_ARC_RATIO:
  230.     case ISARC_GET_ARC_DATE:
  231.     case ISARC_GET_ARC_TIME:
  232.     case ISARC_GET_ARC_OS_TYPE:
  233.     case ISARC_GET_ARC_IS_SFX_FILE:
  234.     case ISARC_GET_FILE_NAME:
  235.     case ISARC_GET_ORIGINAL_SIZE:
  236.     case ISARC_GET_COMPRESSED_SIZE:
  237.     case ISARC_GET_RATIO:
  238.     case ISARC_GET_DATE:
  239.     case ISARC_GET_TIME:
  240.     case ISARC_GET_CRC:
  241.     case ISARC_GET_ATTRIBUTE:
  242.     case ISARC_GET_OS_TYPE:
  243.     case ISARC_GET_METHOD:
  244.     //case ISARC_GET_WRITE_TIME:
  245.     //case ISARC_GET_CREATE_TIME:
  246.     //case ISARC_GET_ACCESS_TIME:
  247.       return 1;
  248.     }
  249.   return 0;
  250. }
  251.  
  252. BOOL WINAPI
  253. UnrarConfigDialog (HWND hwnd, LPSTR szOptionBuffer, int iMode)
  254. {
  255.   if (!lstate.hrardll)
  256.     no_unrar_dll (hwnd);
  257.   IN_API (0, ERROR_ALREADY_RUNNING);
  258.   char buf[256];
  259.   sprintf (buf, "UNRAR32.DLL Version %d.%02d",
  260.            UNRAR32_VERSION / 100, UNRAR32_VERSION % 100);
  261.   MessageBox (hwnd, buf, "Info", MB_OK | MB_ICONINFORMATION);
  262.   return 0;
  263. }
  264.  
  265. int WINAPI
  266. UnrarExtractMem (HWND hwnd, LPCSTR szCmdLine,
  267.                  LPBYTE szBuffer, DWORD dwSize, time_t *lpTime,
  268.                  LPWORD lpwAttr, LPDWORD lpdwWriteSize)
  269. {
  270.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  271.   return ERROR_NOT_SUPPORT;
  272. }
  273.  
  274. int WINAPI
  275. UnrarCompressMem (HWND hwnd, LPCSTR szCmdLine,
  276.                   const BYTE *szBuffer, DWORD dwSize,
  277.                   const time_t *_lpTime, const WORD *lpwAttr,
  278.                   LPDWORD lpdwWriteSize)
  279. {
  280.   return ERROR_NOT_SUPPORT;
  281. }
  282.  
  283. HARC WINAPI
  284. UnrarOpenArchive (HWND hwnd, LPCSTR path, DWORD mode)
  285. {
  286.   if (!lstate.hrardll)
  287.     no_unrar_dll (hwnd);
  288.   IN_API (0, 0);
  289.   arcinfo *info = new arcinfo;
  290.   if (!info)
  291.     return 0;
  292.   if (!info->open (path, mode))
  293.     {
  294.       delete info;
  295.       return 0;
  296.     }
  297.   return HARC (info);
  298. }
  299.  
  300. int WINAPI
  301. UnrarCloseArchive (HARC harc)
  302. {
  303.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  304.   arcinfo *info = arcinfo::find (harc);
  305.   if (!info)
  306.     return ERROR_HARC_ISNOT_OPENED;
  307.   info->close ();
  308.   delete info;
  309.   return 0;
  310. }
  311.  
  312. int WINAPI
  313. UnrarFindFirst (HARC harc, LPCSTR pattern, INDIVIDUALINFO *vinfo)
  314. {
  315.   IN_API (-1, -1);
  316.   arcinfo *info = arcinfo::find (harc);
  317.   if (!info || !info->a_first_time)
  318.     return -1;
  319.  
  320.   if (info->a_cl.parse (pattern, 0))
  321.     return -1;
  322.   info->a_glob.set_pattern (info->a_cl.argc (), info->a_cl.argv ());
  323.   info->a_first_time = 0;
  324.   return info->findnext (vinfo, 0);
  325. }
  326.  
  327. int WINAPI
  328. UnrarFindNext (HARC harc, INDIVIDUALINFO *vinfo)
  329. {
  330.   IN_API (-1, -1);
  331.   arcinfo *info = arcinfo::find (harc);
  332.   if (!info || info->a_first_time)
  333.     return -1;
  334.   return info->findnext (vinfo, 1);
  335. }
  336.  
  337. int WINAPI
  338. UnrarGetArcFileName (HARC harc, LPSTR buf, int size)
  339. {
  340.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  341.   arcinfo *info = arcinfo::find (harc);
  342.   if (!info)
  343.     return ERROR_HARC_ISNOT_OPENED;
  344.   if (int (strlen (info->a_arcpath)) >= size)
  345.     return ERROR_BUF_TOO_SMALL;
  346.   strcpy (buf, info->a_arcpath);
  347.   return 0;
  348. }
  349.  
  350. DWORD WINAPI
  351. UnrarGetArcFileSize (HARC harc)
  352. {
  353.   IN_API (DWORD (-1), DWORD (-1));
  354.   arcinfo *info = arcinfo::find (harc);
  355.   return info ? info->a_arcsize : -1;
  356. }
  357.  
  358. DWORD WINAPI
  359. UnrarGetArcOriginalSize (HARC harc)
  360. {
  361.   IN_API (DWORD (-1), DWORD (-1));
  362.   arcinfo *info = arcinfo::find (harc);
  363.   return info ? info->a_orig_sz : -1;
  364. }
  365.  
  366. DWORD WINAPI
  367. UnrarGetArcCompressedSize (HARC harc)
  368. {
  369.   IN_API (DWORD (-1), DWORD (-1));
  370.   arcinfo *info = arcinfo::find (harc);
  371.   return info ? info->a_comp_sz : -1;
  372. }
  373.  
  374. WORD WINAPI
  375. UnrarGetArcRatio (HARC harc)
  376. {
  377.   IN_API (WORD (-1), WORD (-1));
  378.   arcinfo *info = arcinfo::find (harc);
  379.   return info ? calc_ratio (info->a_comp_sz, info->a_orig_sz) : -1;
  380. }
  381.  
  382. WORD WINAPI
  383. UnrarGetArcDate (HARC harc)
  384. {
  385.   IN_API (WORD (-1), WORD (-1));
  386.   arcinfo *info = arcinfo::find (harc);
  387.   return info ? info->a_arcdate : -1;
  388. }
  389.  
  390. WORD WINAPI
  391. UnrarGetArcTime (HARC harc)
  392. {
  393.   IN_API (WORD (-1), WORD (-1));
  394.   arcinfo *info = arcinfo::find (harc);
  395.   return info ? info->a_arctime : -1;
  396. }
  397.  
  398. UINT WINAPI
  399. UnrarGetArcOSType (HARC harc)
  400. {
  401.   IN_API (UINT (-1), UINT (-1));
  402.   arcinfo *info = arcinfo::find (harc);
  403.   return info ? OSTYPE_UNKNOWN : -1;
  404. }
  405.  
  406. int WINAPI
  407. UnrarIsSFXFile (HARC harc)
  408. {
  409.   IN_API (-1, -1);
  410.   arcinfo *info = arcinfo::find (harc);
  411.   return info ? info->a_sfx : -1;
  412. }
  413.  
  414. int WINAPI
  415. UnrarGetFileName (HARC harc, LPSTR buf, int size)
  416. {
  417.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  418.   arcinfo *info = arcinfo::find (harc);
  419.   if (!info)
  420.     return ERROR_HARC_ISNOT_OPENED;
  421.   if (!info->a_valid)
  422.     return ERROR_NOT_SEARCH_MODE;
  423.   if (int (strlen (info->a_hd.FileName)) >= size)
  424.     return ERROR_BUF_TOO_SMALL;
  425.   strcpy (buf, info->a_hd.FileName);
  426.   return 0;
  427. }
  428.  
  429. int WINAPI
  430. UnrarGetMethod (HARC harc, LPSTR buf, int size)
  431. {
  432.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  433.   arcinfo *info = arcinfo::find (harc);
  434.   if (!info)
  435.     return ERROR_HARC_ISNOT_OPENED;
  436.   if (!info->a_valid)
  437.     return ERROR_NOT_SEARCH_MODE;
  438.   const char *method = method_string (info->a_hd.Method);
  439.   if (int (strlen (method)) >= size)
  440.     return ERROR_BUF_TOO_SMALL;
  441.   strcpy (buf, method);
  442.   return 0;
  443. }
  444.  
  445. DWORD WINAPI
  446. UnrarGetOriginalSize (HARC harc)
  447. {
  448.   IN_API (DWORD (-1), DWORD (-1));
  449.   arcinfo *info = arcinfo::find (harc);
  450.   return info && info->a_valid ? info->a_hd.UnpSize : -1;
  451. }
  452.  
  453. DWORD WINAPI
  454. UnrarGetCompressedSize (HARC harc)
  455. {
  456.   IN_API (DWORD (-1), DWORD (-1));
  457.   arcinfo *info = arcinfo::find (harc);
  458.   return info && info->a_valid ? info->a_hd.PackSize : -1;
  459. }
  460.  
  461. WORD WINAPI
  462. UnrarGetRatio (HARC harc)
  463. {
  464.   IN_API (WORD (-1), WORD (-1));
  465.   arcinfo *info = arcinfo::find (harc);
  466.   return (info && info->a_valid
  467.           ? calc_ratio (info->a_hd.PackSize, info->a_hd.UnpSize)
  468.           : -1);
  469. }
  470.  
  471. WORD WINAPI
  472. UnrarGetDate (HARC harc)
  473. {
  474.   IN_API (WORD (-1), WORD (-1));
  475.   arcinfo *info = arcinfo::find (harc);
  476.   return info && info->a_valid ? HIWORD (info->a_hd.FileTime) : -1;
  477. }
  478.  
  479. WORD WINAPI
  480. UnrarGetTime (HARC harc)
  481. {
  482.   IN_API (WORD (-1), WORD (-1));
  483.   arcinfo *info = arcinfo::find (harc);
  484.   return info && info->a_valid ? LOWORD (info->a_hd.FileTime) : -1;
  485. }
  486.  
  487. DWORD WINAPI
  488. UnrarGetWriteTime (HARC harc)
  489. {
  490.   return DWORD (-1);
  491. }
  492.  
  493. DWORD WINAPI
  494. UnrarGetCreateTime (HARC harc)
  495. {
  496.   return DWORD (-1);
  497. }
  498.  
  499. DWORD WINAPI
  500. UnrarGetAccessTime (HARC harc)
  501. {
  502.   return DWORD (-1);
  503. }
  504.  
  505. DWORD WINAPI
  506. UnrarGetCRC (HARC harc)
  507. {
  508.   IN_API (DWORD (-1), DWORD (-1));
  509.   arcinfo *info = arcinfo::find (harc);
  510.   return info && info->a_valid ? info->a_hd.FileCRC : -1;
  511. }
  512.  
  513. int WINAPI
  514. UnrarGetAttribute (HARC harc)
  515. {
  516.   IN_API (-1, -1);
  517.   arcinfo *info = arcinfo::find (harc);
  518.   return info && info->a_valid ? info->a_hd.FileAttr : -1;
  519. }
  520.  
  521. UINT WINAPI
  522. UnrarGetOSType (HARC harc)
  523. {
  524.   IN_API (UINT (-1), UINT (-1));
  525.   arcinfo *info = arcinfo::find (harc);
  526.   if (!info || !info->a_valid)
  527.     return UINT (-1);
  528.   return os_type (info->a_hd.HostOS);
  529. }
  530.  
  531. BOOL WINAPI
  532. UnrarSetOwnerWindow (HWND hwnd)
  533. {
  534.   IN_API (0, 0);
  535.   if (lstate.has_callback)
  536.     return 0;
  537.   lstate.has_callback = 1;
  538.   lstate.hwnd_owner = hwnd;
  539.   lstate.callback = 0;
  540.   return 1;
  541. }
  542.  
  543. BOOL WINAPI
  544. UnrarClearOwnerWindow ()
  545. {
  546.   IN_API (0, 0);
  547.   lstate.has_callback = 0;
  548.   lstate.hwnd_owner = 0;
  549.   lstate.callback = 0;
  550.   return 1;
  551. }
  552.  
  553. BOOL WINAPI
  554. UnrarSetOwnerWindowEx (HWND hwnd, LPARCHIVERPROC proc)
  555. {
  556.   IN_API (0, 0);
  557.   if (lstate.has_callback)
  558.     return 0;
  559.   lstate.has_callback = 1;
  560.   lstate.hwnd_owner = hwnd;
  561.   lstate.callback = proc;
  562.   return 1;
  563. }
  564.  
  565. BOOL WINAPI
  566. UnrarKillOwnerWindowEx (HWND hwnd)
  567. {
  568.   IN_API (0, 0);
  569.   if (!lstate.has_callback || hwnd != lstate.hwnd_owner)
  570.     return 0;
  571.   lstate.has_callback = 0;
  572.   lstate.hwnd_owner = 0;
  573.   lstate.callback = 0;
  574.   return 1;
  575. }
  576.  
  577. int WINAPI
  578. DllMain (HINSTANCE hinst, DWORD reason, VOID *static_load)
  579. {
  580.   switch (reason)
  581.     {
  582.     case DLL_PROCESS_ATTACH:
  583.       lstate.hinst = hinst;
  584.       lstate.hrardll = load_rarapi ();
  585.       init_table ();
  586.       InitCommonControls ();
  587.       break;
  588.  
  589.     case DLL_PROCESS_DETACH:
  590.       arcinfo::cleanup ();
  591.       if (lstate.hrardll)
  592.         FreeLibrary (lstate.hrardll);
  593.       break;
  594.     }
  595.   return 1;
  596. }
  597.