home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1999 October / VPR9910A.BIN / OLS / unrar32005 / unrar32005.lzh / src / unrar32.cxx < prev    next >
C/C++ Source or Header  |  1998-04-03  |  13KB  |  595 lines

  1. /*
  2.  *   Copyright (c) 1998 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 5
  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 ())
  197.         && !(rd.hd.Flags & FRAR_NEXTVOL)
  198.         && !(e = rd.skip ()));
  199.        nfiles++)
  200.     ;
  201.   return !e || e == ERAR_END_ARCHIVE ? nfiles : -1;
  202. }
  203.  
  204. BOOL WINAPI
  205. UnrarQueryFunctionList (int i)
  206. {
  207.   switch (i)
  208.     {
  209.     case ISARC:
  210.     case ISARC_GET_VERSION:
  211.     case ISARC_GET_CURSOR_INTERVAL:
  212.     case ISARC_SET_CURSOR_INTERVAL:
  213.     case ISARC_GET_BACK_GROUND_MODE:
  214.     case ISARC_SET_BACK_GROUND_MODE:
  215.     case ISARC_GET_CURSOR_MODE:
  216.     case ISARC_SET_CURSOR_MODE:
  217.     case ISARC_GET_RUNNING:
  218.     case ISARC_CHECK_ARCHIVE:
  219.     //case ISARC_CONFIG_DIALOG:
  220.     case ISARC_GET_FILE_COUNT:
  221.     case ISARC_QUERY_FUNCTION_LIST:
  222.     case ISARC_GET_ARC_FILE_INFO:
  223.     case ISARC_OPEN_ARCHIVE:
  224.     case ISARC_CLOSE_ARCHIVE:
  225.     case ISARC_FIND_FIRST:
  226.     case ISARC_FIND_NEXT:
  227.     case ISARC_GET_ARC_FILE_NAME:
  228.     case ISARC_GET_ARC_FILE_SIZE:
  229.     case ISARC_GET_ARC_ORIGINAL_SIZE:
  230.     case ISARC_GET_ARC_COMPRESSED_SIZE:
  231.     case ISARC_GET_ARC_RATIO:
  232.     case ISARC_GET_ARC_DATE:
  233.     case ISARC_GET_ARC_TIME:
  234.     case ISARC_GET_ARC_OS_TYPE:
  235.     case ISARC_GET_ARC_IS_SFX_FILE:
  236.     case ISARC_GET_FILE_NAME:
  237.     case ISARC_GET_ORIGINAL_SIZE:
  238.     case ISARC_GET_COMPRESSED_SIZE:
  239.     case ISARC_GET_RATIO:
  240.     case ISARC_GET_DATE:
  241.     case ISARC_GET_TIME:
  242.     case ISARC_GET_CRC:
  243.     case ISARC_GET_ATTRIBUTE:
  244.     case ISARC_GET_OS_TYPE:
  245.     case ISARC_GET_METHOD:
  246.     //case ISARC_GET_WRITE_TIME:
  247.     //case ISARC_GET_CREATE_TIME:
  248.     //case ISARC_GET_ACCESS_TIME:
  249.       return 1;
  250.     }
  251.   return 0;
  252. }
  253.  
  254. BOOL WINAPI
  255. UnrarConfigDialog (HWND hwnd, LPSTR szOptionBuffer, int iMode)
  256. {
  257.   if (!lstate.hrardll)
  258.     no_unrar_dll (hwnd);
  259.   IN_API (0, ERROR_ALREADY_RUNNING);
  260.   char buf[256];
  261.   sprintf (buf, "UNRAR32.DLL Version %d.%02d",
  262.            UNRAR32_VERSION / 100, UNRAR32_VERSION % 100);
  263.   MessageBox (hwnd, buf, "Info", MB_OK | MB_ICONINFORMATION);
  264.   return 0;
  265. }
  266.  
  267. int WINAPI
  268. UnrarExtractMem (HWND hwnd, LPCSTR szCmdLine,
  269.                  LPBYTE szBuffer, DWORD dwSize, time_t *lpTime,
  270.                  LPWORD lpwAttr, LPDWORD lpdwWriteSize)
  271. {
  272.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  273.   return ERROR_NOT_SUPPORT;
  274. }
  275.  
  276. int WINAPI
  277. UnrarCompressMem (HWND hwnd, LPCSTR szCmdLine,
  278.                   const BYTE *szBuffer, DWORD dwSize,
  279.                   const time_t *_lpTime, const WORD *lpwAttr,
  280.                   LPDWORD lpdwWriteSize)
  281. {
  282.   return ERROR_NOT_SUPPORT;
  283. }
  284.  
  285. HARC WINAPI
  286. UnrarOpenArchive (HWND hwnd, LPCSTR path, DWORD mode)
  287. {
  288.   if (!lstate.hrardll)
  289.     no_unrar_dll (hwnd);
  290.   IN_API (0, 0);
  291.   arcinfo *info = new arcinfo;
  292.   if (!info)
  293.     return 0;
  294.   if (!info->open (path, mode))
  295.     {
  296.       delete info;
  297.       return 0;
  298.     }
  299.   return HARC (info);
  300. }
  301.  
  302. int WINAPI
  303. UnrarCloseArchive (HARC harc)
  304. {
  305.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  306.   arcinfo *info = arcinfo::find (harc);
  307.   if (!info)
  308.     return ERROR_HARC_ISNOT_OPENED;
  309.   info->close ();
  310.   delete info;
  311.   return 0;
  312. }
  313.  
  314. int WINAPI
  315. UnrarFindFirst (HARC harc, LPCSTR pattern, INDIVIDUALINFO *vinfo)
  316. {
  317.   IN_API (-1, -1);
  318.   arcinfo *info = arcinfo::find (harc);
  319.   if (!info || !info->a_first_time)
  320.     return -1;
  321.  
  322.   if (info->a_cl.parse (pattern, 0))
  323.     return -1;
  324.   info->a_glob.set_pattern (info->a_cl.argc (), info->a_cl.argv ());
  325.   info->a_first_time = 0;
  326.   return info->findnext (vinfo, 0);
  327. }
  328.  
  329. int WINAPI
  330. UnrarFindNext (HARC harc, INDIVIDUALINFO *vinfo)
  331. {
  332.   IN_API (-1, -1);
  333.   arcinfo *info = arcinfo::find (harc);
  334.   if (!info || info->a_first_time)
  335.     return -1;
  336.   return info->findnext (vinfo, 1);
  337. }
  338.  
  339. int WINAPI
  340. UnrarGetArcFileName (HARC harc, LPSTR buf, int size)
  341. {
  342.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  343.   arcinfo *info = arcinfo::find (harc);
  344.   if (!info)
  345.     return ERROR_HARC_ISNOT_OPENED;
  346.   if (int (strlen (info->a_arcpath)) >= size)
  347.     return ERROR_BUF_TOO_SMALL;
  348.   strcpy (buf, info->a_arcpath);
  349.   return 0;
  350. }
  351.  
  352. DWORD WINAPI
  353. UnrarGetArcFileSize (HARC harc)
  354. {
  355.   IN_API (DWORD (-1), DWORD (-1));
  356.   arcinfo *info = arcinfo::find (harc);
  357.   return info ? info->a_arcsize : -1;
  358. }
  359.  
  360. DWORD WINAPI
  361. UnrarGetArcOriginalSize (HARC harc)
  362. {
  363.   IN_API (DWORD (-1), DWORD (-1));
  364.   arcinfo *info = arcinfo::find (harc);
  365.   return info ? info->a_orig_sz : -1;
  366. }
  367.  
  368. DWORD WINAPI
  369. UnrarGetArcCompressedSize (HARC harc)
  370. {
  371.   IN_API (DWORD (-1), DWORD (-1));
  372.   arcinfo *info = arcinfo::find (harc);
  373.   return info ? info->a_comp_sz : -1;
  374. }
  375.  
  376. WORD WINAPI
  377. UnrarGetArcRatio (HARC harc)
  378. {
  379.   IN_API (WORD (-1), WORD (-1));
  380.   arcinfo *info = arcinfo::find (harc);
  381.   return info ? calc_ratio (info->a_comp_sz, info->a_orig_sz) : -1;
  382. }
  383.  
  384. WORD WINAPI
  385. UnrarGetArcDate (HARC harc)
  386. {
  387.   IN_API (WORD (-1), WORD (-1));
  388.   arcinfo *info = arcinfo::find (harc);
  389.   return info ? info->a_arcdate : -1;
  390. }
  391.  
  392. WORD WINAPI
  393. UnrarGetArcTime (HARC harc)
  394. {
  395.   IN_API (WORD (-1), WORD (-1));
  396.   arcinfo *info = arcinfo::find (harc);
  397.   return info ? info->a_arctime : -1;
  398. }
  399.  
  400. UINT WINAPI
  401. UnrarGetArcOSType (HARC harc)
  402. {
  403.   IN_API (UINT (-1), UINT (-1));
  404.   arcinfo *info = arcinfo::find (harc);
  405.   return info ? OSTYPE_UNKNOWN : -1;
  406. }
  407.  
  408. int WINAPI
  409. UnrarIsSFXFile (HARC harc)
  410. {
  411.   IN_API (-1, -1);
  412.   arcinfo *info = arcinfo::find (harc);
  413.   return info ? info->a_sfx : -1;
  414. }
  415.  
  416. int WINAPI
  417. UnrarGetFileName (HARC harc, LPSTR buf, int size)
  418. {
  419.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  420.   arcinfo *info = arcinfo::find (harc);
  421.   if (!info)
  422.     return ERROR_HARC_ISNOT_OPENED;
  423.   if (!info->a_valid)
  424.     return ERROR_NOT_SEARCH_MODE;
  425.   if (int (strlen (info->a_hd.FileName)) >= size)
  426.     return ERROR_BUF_TOO_SMALL;
  427.   strcpy (buf, info->a_hd.FileName);
  428.   return 0;
  429. }
  430.  
  431. int WINAPI
  432. UnrarGetMethod (HARC harc, LPSTR buf, int size)
  433. {
  434.   IN_API (ERROR_NOT_SUPPORT, ERROR_ALREADY_RUNNING);
  435.   arcinfo *info = arcinfo::find (harc);
  436.   if (!info)
  437.     return ERROR_HARC_ISNOT_OPENED;
  438.   if (!info->a_valid)
  439.     return ERROR_NOT_SEARCH_MODE;
  440.   const char *method = method_string (info->a_hd.Method);
  441.   if (int (strlen (method)) >= size)
  442.     return ERROR_BUF_TOO_SMALL;
  443.   strcpy (buf, method);
  444.   return 0;
  445. }
  446.  
  447. DWORD WINAPI
  448. UnrarGetOriginalSize (HARC harc)
  449. {
  450.   IN_API (DWORD (-1), DWORD (-1));
  451.   arcinfo *info = arcinfo::find (harc);
  452.   return info && info->a_valid ? info->a_hd.UnpSize : -1;
  453. }
  454.  
  455. DWORD WINAPI
  456. UnrarGetCompressedSize (HARC harc)
  457. {
  458.   IN_API (DWORD (-1), DWORD (-1));
  459.   arcinfo *info = arcinfo::find (harc);
  460.   return info && info->a_valid ? info->a_hd.PackSize : -1;
  461. }
  462.  
  463. WORD WINAPI
  464. UnrarGetRatio (HARC harc)
  465. {
  466.   IN_API (WORD (-1), WORD (-1));
  467.   arcinfo *info = arcinfo::find (harc);
  468.   return (info && info->a_valid
  469.           ? calc_ratio (info->a_hd.PackSize, info->a_hd.UnpSize)
  470.           : -1);
  471. }
  472.  
  473. WORD WINAPI
  474. UnrarGetDate (HARC harc)
  475. {
  476.   IN_API (WORD (-1), WORD (-1));
  477.   arcinfo *info = arcinfo::find (harc);
  478.   return info && info->a_valid ? HIWORD (info->a_hd.FileTime) : -1;
  479. }
  480.  
  481. WORD WINAPI
  482. UnrarGetTime (HARC harc)
  483. {
  484.   IN_API (WORD (-1), WORD (-1));
  485.   arcinfo *info = arcinfo::find (harc);
  486.   return info && info->a_valid ? LOWORD (info->a_hd.FileTime) : -1;
  487. }
  488.  
  489. DWORD WINAPI
  490. UnrarGetWriteTime (HARC harc)
  491. {
  492.   return DWORD (-1);
  493. }
  494.  
  495. DWORD WINAPI
  496. UnrarGetCreateTime (HARC harc)
  497. {
  498.   return DWORD (-1);
  499. }
  500.  
  501. DWORD WINAPI
  502. UnrarGetAccessTime (HARC harc)
  503. {
  504.   return DWORD (-1);
  505. }
  506.  
  507. DWORD WINAPI
  508. UnrarGetCRC (HARC harc)
  509. {
  510.   IN_API (DWORD (-1), DWORD (-1));
  511.   arcinfo *info = arcinfo::find (harc);
  512.   return info && info->a_valid ? info->a_hd.FileCRC : -1;
  513. }
  514.  
  515. int WINAPI
  516. UnrarGetAttribute (HARC harc)
  517. {
  518.   IN_API (-1, -1);
  519.   arcinfo *info = arcinfo::find (harc);
  520.   return info && info->a_valid ? info->a_hd.FileAttr : -1;
  521. }
  522.  
  523. UINT WINAPI
  524. UnrarGetOSType (HARC harc)
  525. {
  526.   IN_API (UINT (-1), UINT (-1));
  527.   arcinfo *info = arcinfo::find (harc);
  528.   if (!info || !info->a_valid)
  529.     return UINT (-1);
  530.   return os_type (info->a_hd.HostOS);
  531. }
  532.  
  533. BOOL WINAPI
  534. UnrarSetOwnerWindow (HWND hwnd)
  535. {
  536.   IN_API (0, 0);
  537.   if (lstate.hwnd_owner)
  538.     return 0;
  539.   lstate.hwnd_owner = hwnd;
  540.   lstate.callback = 0;
  541.   return 1;
  542. }
  543.  
  544. BOOL WINAPI
  545. UnrarClearOwnerWindow ()
  546. {
  547.   IN_API (0, 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.hwnd_owner)
  558.     return 0;
  559.   lstate.hwnd_owner = hwnd;
  560.   lstate.callback = proc;
  561.   return 1;
  562. }
  563.  
  564. BOOL WINAPI
  565. UnrarKillOwnerWindowEx (HWND hwnd)
  566. {
  567.   IN_API (0, 0);
  568.   if (hwnd != lstate.hwnd_owner)
  569.     return 0;
  570.   lstate.hwnd_owner = 0;
  571.   lstate.callback = 0;
  572.   return 1;
  573. }
  574.  
  575. int WINAPI
  576. DllMain (HINSTANCE hinst, DWORD reason, VOID *static_load)
  577. {
  578.   switch (reason)
  579.     {
  580.     case DLL_PROCESS_ATTACH:
  581.       lstate.hinst = hinst;
  582.       lstate.hrardll = load_rarapi ();
  583.       init_table ();
  584.       InitCommonControls ();
  585.       break;
  586.  
  587.     case DLL_PROCESS_DETACH:
  588.       arcinfo::cleanup ();
  589.       if (lstate.hrardll)
  590.         FreeLibrary (lstate.hrardll);
  591.       break;
  592.     }
  593.   return 1;
  594. }
  595.