"Fossies" - the Fresh Open Source Software Archive

Member "uzexampl.c" (25 Jan 2009, 14167 Bytes) of package /windows/misc/unz600dn.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "uzexampl.c" see the Fossies "Dox" file reference documentation.

    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 }