Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.   Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
  3.  
  4.   See the accompanying file LICENSE, version 2009-Jan-02 or later
  5.   (the contents of which are also included in unzip.h) for terms of use.
  6.   If, for some reason, all these files are missing, the Info-ZIP license
  7.   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
  8. */
  9. /*
  10.    This is a very simplistic example of how to load and make a call into the
  11.    dll. This has been compiled and tested for a 32-bit console version, but
  12.    not under 16-bit windows. However, the #ifdef's have been left in for the
  13.    16-bit code, simply as an example.
  14.  
  15.  */
  16.  
  17. #ifndef WIN32   /* this code is currently only tested for 32-bit console */
  18. #  define WIN32
  19. #endif
  20.  
  21. #if defined(__WIN32__) && !defined(WIN32)
  22. #  define WIN32
  23. #endif
  24.  
  25. /* Tell Microsoft Visual C++ 2005 to leave us alone and
  26.  * let us use standard C functions the way we're supposed to.
  27.  */
  28. #if defined(_MSC_VER) && (_MSC_VER >= 1400)
  29. #  ifndef _CRT_SECURE_NO_WARNINGS
  30. #    define _CRT_SECURE_NO_WARNINGS
  31. #  endif
  32. #  ifndef _CRT_NONSTDC_NO_WARNINGS
  33. #    define _CRT_NONSTDC_NO_WARNINGS
  34. #  endif
  35. #endif
  36.  
  37. #include <stddef.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40. #include <time.h>
  41. #include <string.h>
  42. #include "uzexampl.h"
  43. #include "../unzvers.h"
  44. #ifdef WIN32
  45. #  include <winver.h>
  46. #else
  47. #  include <ver.h>
  48. #endif
  49.  
  50. #ifndef _MAX_PATH
  51. #  define _MAX_PATH 260           /* max total file or directory name path */
  52. #endif
  53.  
  54. #ifdef WIN32
  55. #define UNZ_DLL_NAME "UNZIP32.DLL\0"
  56. #else
  57. #define UNZ_DLL_NAME "UNZIP16.DLL\0"
  58. #endif
  59.  
  60. #define DLL_WARNING "Cannot find %s."\
  61.             " The Dll must be in the application directory, the path, "\
  62.             "the Windows directory or the Windows System directory."
  63. #define DLL_VERSION_WARNING "%s has the wrong version number."\
  64.             " Insure that you have the correct dll's installed, and that "\
  65.             "an older dll is not in your path or Windows System directory."
  66.  
  67. int hFile;              /* file handle */
  68.  
  69. LPUSERFUNCTIONS lpUserFunctions;
  70. HANDLE hUF = (HANDLE)NULL;
  71. LPDCL lpDCL = NULL;
  72. HANDLE hDCL = (HANDLE)NULL;
  73. HINSTANCE hUnzipDll;
  74. HANDLE hZCL = (HANDLE)NULL;
  75. #ifdef WIN32
  76. DWORD dwPlatformId = 0xFFFFFFFF;
  77. #endif
  78. static ZCONST UzpVer *lpUzVersInfo = NULL;
  79.  
  80.  
  81. /* Forward References */
  82. int WINAPI DisplayBuf(LPSTR, unsigned long);
  83. int WINAPI GetReplaceDlgRetVal(LPSTR, unsigned);
  84. int WINAPI password(LPSTR, int, LPCSTR, LPCSTR);
  85.  
  86. ZCONST UzpVer * UZ_EXP UzpVersion  OF((void));
  87. _DLL_UZVER pUzpVersion;
  88. _DLL_UNZIP pWiz_SingleEntryUnzip;
  89.  
  90. static void FreeUpMemory(void);
  91.  
  92. int main(int argc, char **argv)
  93. {
  94. int exfc, infc;
  95. char **exfv, **infv;
  96. char *x_opt;
  97. DWORD dwVerInfoSize;
  98. DWORD dwVerHnd;
  99. char szFullPath[_MAX_PATH];
  100. int retcode;
  101. #ifdef WIN32
  102. char *ptr;
  103. #else
  104. HFILE hfile;
  105. OFSTRUCT ofs;
  106. #endif
  107. HANDLE  hMem;         /* handle to mem alloc'ed */
  108.  
  109. if (argc < 2)   /* We must have an archive to unzip */
  110.    {
  111.    char *progname = strrchr(argv[0], '\\');
  112.  
  113.    if (progname != NULL)
  114.       progname++;
  115.    else
  116.       {
  117.       progname = argv[0];
  118.       if (progname == NULL || *progname == '\0') progname = "example";
  119.       }
  120.    printf("usage: %s <zipfile> [entry1 [entry2 [...]]] [-x xentry1 [...]]",
  121.           progname);
  122.    return 0;
  123.    }
  124.  
  125. hDCL = GlobalAlloc( GPTR, (DWORD)sizeof(DCL));
  126. if (!hDCL)
  127.    {
  128.    return -1;
  129.    }
  130. lpDCL = (LPDCL)GlobalLock(hDCL);
  131. if (!lpDCL)
  132.    {
  133.    GlobalFree(hDCL);
  134.    return -1;
  135.    }
  136.  
  137. hUF = GlobalAlloc( GPTR, (DWORD)sizeof(USERFUNCTIONS));
  138. if (!hUF)
  139.    {
  140.    GlobalUnlock(hDCL);
  141.    GlobalFree(hDCL);
  142.    return -1;
  143.    }
  144. lpUserFunctions = (LPUSERFUNCTIONS)GlobalLock(hUF);
  145.  
  146. if (!lpUserFunctions)
  147.    {
  148.    GlobalFree(hUF);
  149.    GlobalUnlock(hDCL);
  150.    GlobalFree(hDCL);
  151.    return -1;
  152.    }
  153.  
  154. lpUserFunctions->password = password;
  155. lpUserFunctions->print = DisplayBuf;
  156. lpUserFunctions->sound = NULL;
  157. lpUserFunctions->replace = GetReplaceDlgRetVal;
  158. lpUserFunctions->SendApplicationMessage = ReceiveDllMessage;
  159.  
  160. /* First we go look for the unzip dll */
  161. #ifdef WIN32
  162. if (SearchPath(
  163.     NULL,               /* address of search path               */
  164.     UNZ_DLL_NAME,       /* address of filename                  */
  165.     NULL,               /* address of extension                 */
  166.     _MAX_PATH,           /* size, in characters, of buffer       */
  167.     szFullPath,         /* address of buffer for found filename */
  168.     &ptr                /* address of pointer to file component */
  169.    ) == 0)
  170. #else
  171. hfile = OpenFile(UNZ_DLL_NAME,  &ofs, OF_SEARCH);
  172. if (hfile == HFILE_ERROR)
  173. #endif
  174.    {
  175.    char str[256];
  176.    wsprintf (str, DLL_WARNING, UNZ_DLL_NAME);
  177.    printf("%s\n", str);
  178.    FreeUpMemory();
  179.    return -1;
  180.    }
  181. #ifndef WIN32
  182. else
  183.    lstrcpy(szFullPath, ofs.szPathName);
  184. _lclose(hfile);
  185. #endif
  186.  
  187. /* Now we'll check the unzip dll version information. Note that this is
  188.    not the same information as is returned from a call to UzpVersion()
  189.  */
  190. dwVerInfoSize =
  191.     GetFileVersionInfoSize(szFullPath, &dwVerHnd);
  192.  
  193. if (dwVerInfoSize)
  194.    {
  195.    BOOL  fRet, fRetName;
  196.    char str[256];
  197.    LPSTR   lpstrVffInfo; /* Pointer to block to hold info */
  198.    LPSTR lszVer = NULL;
  199.    LPSTR lszVerName = NULL;
  200.    UINT  cchVer = 0;
  201.  
  202.    /* Get a block big enough to hold the version information */
  203.    hMem          = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  204.    lpstrVffInfo  = GlobalLock(hMem);
  205.  
  206.    /* Get the version information */
  207.    if (GetFileVersionInfo(szFullPath, 0L, dwVerInfoSize, lpstrVffInfo))
  208.       {
  209.       fRet = VerQueryValue(lpstrVffInfo,
  210.                TEXT("\\StringFileInfo\\040904E4\\FileVersion"),
  211.               (LPVOID)&lszVer,
  212.               &cchVer);
  213.       fRetName = VerQueryValue(lpstrVffInfo,
  214.                TEXT("\\StringFileInfo\\040904E4\\CompanyName"),
  215.                (LPVOID)&lszVerName,
  216.                &cchVer);
  217.       if (!fRet || !fRetName ||
  218.          (lstrcmpi(lszVer, UNZ_DLL_VERSION) != 0) ||
  219.          (lstrcmpi(lszVerName, IZ_COMPANY_NAME) != 0))
  220.          {
  221.          wsprintf (str, DLL_VERSION_WARNING, UNZ_DLL_NAME);
  222.          printf("%s\n", str);
  223.          GlobalUnlock(hMem);
  224.          GlobalFree(hMem);
  225.          FreeUpMemory();
  226.          return -1;
  227.          }
  228.       }
  229.       /* free memory */
  230.    GlobalUnlock(hMem);
  231.    GlobalFree(hMem);
  232.    }
  233. else
  234.    {
  235.    char str[256];
  236.    wsprintf (str, DLL_VERSION_WARNING, UNZ_DLL_NAME);
  237.    printf("%s\n", str);
  238.    FreeUpMemory();
  239.    return -1;
  240.    }
  241. /* Okay, now we know that the dll exists, and has the proper version
  242.  * information in it. We can go ahead and load it.
  243.  */
  244. hUnzipDll = LoadLibrary(UNZ_DLL_NAME);
  245. #ifndef WIN32
  246. if (hUnzipDll > HINSTANCE_ERROR)
  247. #else
  248. if (hUnzipDll != NULL)
  249. #endif
  250.    {
  251.    pUzpVersion =
  252.      (_DLL_UZVER)GetProcAddress(hUnzipDll, "UzpVersion");
  253.    pWiz_SingleEntryUnzip =
  254.      (_DLL_UNZIP)GetProcAddress(hUnzipDll, "Wiz_SingleEntryUnzip");
  255.    }
  256. else
  257.    {
  258.    char str[256];
  259.    wsprintf (str, "Could not load %s", UNZ_DLL_NAME);
  260.    printf("%s\n", str);
  261.    FreeUpMemory();
  262.    return -1;
  263.    }
  264.  
  265. /*
  266.    Before we actually start with the extraction process, we should first
  267.    check whether the API of the loaded dll is compatible with the API
  268.    definition used to compile this frontend program.
  269.  */
  270. lpUzVersInfo = (*pUzpVersion)();
  271.  
  272. /* The UnZip WinDLL code may change quite frequently.  To be safe, we
  273.  * require the DLL to be at least at the release level of this example
  274.  * frontend code.
  275.  */
  276. #   define UZDLL_MINVERS_MAJOR          UZ_MAJORVER
  277. #   define UZDLL_MINVERS_MINOR          UZ_MINORVER
  278. #   define UZDLL_MINVERS_PATCHLEVEL     UZ_PATCHLEVEL
  279. /* This UnZip DLL stub requires a DLL version of at least: */
  280. if ( (lpUzVersInfo->unzip.major < UZDLL_MINVERS_MAJOR) ||
  281.      ((lpUzVersInfo->unzip.major == UZDLL_MINVERS_MAJOR) &&
  282.       ((lpUzVersInfo->unzip.minor < UZDLL_MINVERS_MINOR) ||
  283.        ((lpUzVersInfo->unzip.minor == UZDLL_MINVERS_MINOR) &&
  284.         (lpUzVersInfo->unzip.patchlevel < UZDLL_MINVERS_PATCHLEVEL)
  285.        )
  286.       )
  287.      ) )
  288. {
  289.   char str[256];
  290.   wsprintf(str, "The version %u.%u%u of the loaded UnZip DLL is too old!",
  291.            lpUzVersInfo->unzip.major, lpUzVersInfo->unzip.minor,
  292.            lpUzVersInfo->unzip.patchlevel);
  293.   printf("%s\n", str);
  294.   FreeLibrary(hUnzipDll);
  295.   FreeUpMemory();
  296.   return -1;
  297. }
  298.  
  299. if (lpUzVersInfo->structlen >=
  300.     (offsetof(UzpVer, dllapimin) + sizeof(_version_type)))
  301. {
  302.   if ( (lpUzVersInfo->dllapimin.major > UZ_WINAPI_COMP_MAJOR) ||
  303.        ((lpUzVersInfo->dllapimin.major == UZ_WINAPI_COMP_MAJOR) &&
  304.         ((lpUzVersInfo->dllapimin.minor > UZ_WINAPI_COMP_MINOR) ||
  305.          ((lpUzVersInfo->dllapimin.minor == UZ_WINAPI_COMP_MINOR) &&
  306.           (lpUzVersInfo->dllapimin.patchlevel > UZ_WINAPI_COMP_REVIS)
  307.          )
  308.         )
  309.        ) )
  310.   {
  311.     char str[256];
  312.     wsprintf(str, "Found incompatible WinDLL API version %u.%u%u, aborting!",
  313.              lpUzVersInfo->dllapimin.major, lpUzVersInfo->dllapimin.minor,
  314.              lpUzVersInfo->dllapimin.patchlevel);
  315.     printf("%s\n", str);
  316.     FreeLibrary(hUnzipDll);
  317.     FreeUpMemory();
  318.     return -1;
  319.   }
  320. }
  321.  
  322. /*
  323.    Here is where the actual extraction process begins. First we set up the
  324.    flags to be passed into the dll.
  325.  */
  326. lpDCL->StructVersID = UZ_DCL_STRUCTVER; /* version of this structure */
  327. lpDCL->ncflag = 0;              /* write to stdout if true */
  328. lpDCL->fQuiet = 0;              /* we want all messages
  329.                                    1 = fewer messages,
  330.                                    2 = no messages */
  331. lpDCL->ntflag = 0;              /* test zip file if true */
  332. lpDCL->nvflag = 0;              /* give a verbose listing if true */
  333. lpDCL->nzflag = 0;              /* display zip file comment if true */
  334. lpDCL->ndflag = 1;              /* recreate directories != 0,
  335.                                    skip "../" if < 2 */
  336. lpDCL->naflag = 0;              /* do not convert CR to CRLF */
  337. lpDCL->nfflag = 0;              /* do not freshen existing files only */
  338. lpDCL->noflag = 1;              /* over-write all files if true */
  339. lpDCL->nZIflag = 0;             /* no ZipInfo output mode */
  340. lpDCL->B_flag = 0;              /* do not backup existing files */
  341. lpDCL->C_flag = 0;              /* do not match case-insensitive */
  342. lpDCL->D_flag = 0;              /* restore all timestamps */
  343. lpDCL->U_flag = 0;              /* do not disable UTF-8 support */
  344. lpDCL->ExtractOnlyNewer = 0;    /* do not extract only newer */
  345. lpDCL->SpaceToUnderscore = 0;   /* do not convert space to '_' in filenames */
  346. lpDCL->PromptToOverwrite = 0;   /* "overwrite all" selected -> no query mode */
  347. lpDCL->lpszZipFN = argv[1];     /* the archive name */
  348. lpDCL->lpszExtractDir = NULL;   /* the directory to extract to.
  349.                                    This is set to NULL if you are extracting
  350.                                    to the current directory.
  351.                                  */
  352. /*
  353.    As this is a quite short example, intended primarily to show how to
  354.    load and call in to the dll, the command-line parameters are only
  355.    parsed in a very simplistic way:
  356.    We assume that the command-line parameters after the zip archive
  357.    make up a list of file patterns:
  358.    " [file_i1] [file_i2] ... [file_iN] [-x file_x1 [file_x2] ...]".
  359.    We scan for an argument "-x"; all arguments in front are
  360.    "include file patterns", all arguments after are "exclude file patterns".
  361.    If no more arguments are given, we extract ALL files.
  362.  
  363.    In summary, the example program should be run like:
  364.    example <archive.name> [files to include] [-x files to exclude]
  365.    ("<...> denotes mandatory arguments, "[...]" optional arguments)
  366.  */
  367. x_opt = NULL;
  368. if (argc > 2) {
  369.   infv = &argv[2];
  370.   for (infc = 0; infc < argc-2; infc++)
  371.     if (!strcmp("-x", infv[infc])) {
  372.         x_opt = infv[infc];
  373.         infv[infc] = NULL;
  374.         break;
  375.     }
  376.   exfc = argc - infc - 3;
  377.   if (exfc > 0)
  378.     exfv = &argv[infc+3];
  379.   else {
  380.     exfc = 0;
  381.     exfv = NULL;
  382.   }
  383. } else {
  384.   infc = exfc = 0;
  385.   infv = exfv = NULL;
  386. }
  387. retcode = (*pWiz_SingleEntryUnzip)(infc, infv, exfc, exfv, lpDCL,
  388.                                    lpUserFunctions);
  389. if (x_opt) {
  390.   infv[infc] = x_opt;
  391.   x_opt = NULL;
  392. }
  393.  
  394. if (retcode != 0)
  395.    printf("Error unzipping (error/warning code %d)...\n", retcode);
  396.  
  397. FreeLibrary(hUnzipDll);
  398. FreeUpMemory();
  399. return retcode;
  400. }
  401.  
  402. int WINAPI GetReplaceDlgRetVal(LPSTR filename, unsigned fnbufsiz)
  403. {
  404. /* This is where you will decide if you want to replace, rename etc existing
  405.    files.
  406.  */
  407. return 1;
  408. }
  409.  
  410. static void FreeUpMemory(void)
  411. {
  412. if (hUF)
  413.    {
  414.    GlobalUnlock(hUF);
  415.    GlobalFree(hUF);
  416.    }
  417. if (hDCL)
  418.    {
  419.    GlobalUnlock(hDCL);
  420.    GlobalFree(hDCL);
  421.    }
  422. }
  423.  
  424. /* This is a very stripped down version of what is done in Wiz. Essentially
  425.    what this function is for is to do a listing of an archive contents. It
  426.    is actually never called in this example, but a dummy procedure had to
  427.    be put in, so this was used.
  428.  */
  429. #ifdef Z_UINT8_DEFINED
  430. void WINAPI ReceiveDllMessage(z_uint8 ucsize, z_uint8 csiz,
  431.     unsigned cfactor, unsigned mo, unsigned dy, unsigned yr,
  432.     unsigned hh, unsigned mm, char c, LPCSTR filename,
  433.     LPCSTR methbuf, unsigned long crc, char fCrypt)
  434. #else
  435. void WINAPI ReceiveDllMessage(unsigned long ucsize, unsigned long csiz,
  436.     unsigned cfactor,
  437.     unsigned mo, unsigned dy, unsigned yr, unsigned hh, unsigned mm,
  438.     char c, LPCSTR filename, LPCSTR methbuf, unsigned long crc, char fCrypt)
  439. #endif
  440. {
  441. char psLBEntry[_MAX_PATH];
  442. char LongHdrStats[] =
  443.           "%7lu  %7lu %4s  %02u-%02u-%02u  %02u:%02u  %c%s";
  444. char CompFactorStr[] = "%c%d%%";
  445. char CompFactor100[] = "100%%";
  446. char szCompFactor[10];
  447. char sgn;
  448.  
  449. if (csiz > ucsize)
  450.    sgn = '-';
  451. else
  452.    sgn = ' ';
  453. if (cfactor == 100)
  454.    lstrcpy(szCompFactor, CompFactor100);
  455. else
  456.    sprintf(szCompFactor, CompFactorStr, sgn, cfactor);
  457.    wsprintf(psLBEntry, LongHdrStats,
  458.       ucsize, csiz, szCompFactor, mo, dy, yr, hh, mm, c, filename);
  459.  
  460. printf("%s\n", psLBEntry);
  461. }
  462.  
  463. /* Password entry routine - see password.c in the wiz directory for how
  464.    this is actually implemented in WiZ. If you have an encrypted file,
  465.    this will probably give you great pain.
  466.  */
  467. int WINAPI password(LPSTR p, int n, LPCSTR m, LPCSTR name)
  468. {
  469. return 1;
  470. }
  471.  
  472. /* Dummy "print" routine that simply outputs what is sent from the dll */
  473. int WINAPI DisplayBuf(LPSTR buf, unsigned long size)
  474. {
  475. printf("%s", (char *)buf);
  476. return (int)(unsigned int) size;
  477. }
  478.