home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2003 August / VPR0308.ISO / OLS / ZIP3J037 / zip3j037.lzh / zip32j / SRC / ZIP32J / FINDZIP.C < prev    next >
C/C++ Source or Header  |  2000-12-16  |  12KB  |  427 lines

  1. /* 
  2.     findzip.c
  3.     by 吉岡 恒夫(email:QWF00133@niftyserve.or.jp)
  4.     コピー、改造、利用、再配布等自由
  5.     (PDSと同等に扱ってもらって結構です)
  6.  
  7.     目的:
  8.     unzip32.dllのUnZip()APIを利用して
  9.     UnZipFindFirst/UnZipFindNext等のAPIを実現 
  10.     # unzip32.dllがこれらのAPIをサポートしたらもはや用なしです。(^^;
  11.     
  12.     UnZip()コマンドの -l オプションから情報を取得。
  13.                                                         */
  14.  
  15. #include <wtypes.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include "findzip.h"
  20.  
  21. #define FINDZIP_VERSION_NUM 1
  22. #define UNZIP32_DLL_NAME "unzip32.dll"
  23. #define UNZIP32_MAX_OUTPUT_SIZE 100000
  24.  
  25. static BOOL orig_findfirst;    //unzip32.dllのfindfirstが使えるか?(自動判定)
  26.  
  27. static HINSTANCE hLib;                    // unzip32 のライブラリのハンドル
  28.  
  29. // unzip32.dllの関数(の一部)
  30.  
  31. // オリジナルの関数。
  32. static BOOL (WINAPI *OrigUnZipQueryFunctionList)(const int iFunction);
  33. static WORD (WINAPI *OrigUnZipGetVersion)(VOID);
  34. int (WINAPI *OrigUnZip)(const HWND hWnd,LPCSTR szCmdLine,LPSTR szOutput,const DWORD dwSize);
  35. static HARC (WINAPI *OrigUnZipOpenArchive)(const HWND hWnd,LPCSTR szFileName,const DWORD dwMode);
  36. static int (WINAPI *OrigUnZipFindFirst)(HARC hArc,
  37.             LPCSTR szWildName,INDIVIDUALINFO *lpSubInfo);
  38. static int (WINAPI *OrigUnZipCloseArchive)(HARC hArc);
  39. static int (WINAPI *OrigUnZipFindNext)(HARC hArc,INDIVIDUALINFO *lpSubInfo);
  40.  
  41. // 書庫内容(INDIVIDUALINFO形式)のリスト
  42. typedef struct FINDZIP_FIND_LIST_
  43. {
  44.     INDIVIDUALINFO info;
  45.     struct FINDZIP_FIND_LIST_ *next;
  46. }FINDZIP_FIND_LIST;
  47.  
  48.  
  49. // OpenArchiveなどの情報はここえ貯える。
  50. typedef struct FINDZIP_FIND_INFO_
  51. {
  52.     FINDZIP_FIND_LIST *list;
  53.     FINDZIP_FIND_LIST *current;
  54.     char arcfilename[FNAME_MAX32];
  55.     HWND hwnd;
  56.     DWORD mode;
  57. }FINDZIP_FIND_INFO;
  58.  
  59. WORD WINAPI ZipUnZipGetVersion(VOID){return UnZipGetVersion();}
  60. WORD WINAPI UnZipGetVersion(VOID)
  61. {
  62.     if(!finddll_init()){return 0;}
  63.     return OrigUnZipGetVersion();
  64. }
  65.  
  66. int WINAPI ZipUnZip(const HWND hWnd,LPCSTR szCmdLine,LPSTR szOutput,const DWORD dwSize){
  67.     return UnZip(hWnd,szCmdLine,szOutput,dwSize);
  68. }
  69. int WINAPI UnZip(const HWND hWnd,LPCSTR szCmdLine,LPSTR szOutput,const DWORD dwSize)
  70. {
  71.     if(!finddll_init()){return -1;}
  72.     return OrigUnZip(hWnd,szCmdLine,szOutput,dwSize);
  73. }
  74. HARC WINAPI ZipUnZipOpenArchive(const HWND hWnd,LPCSTR szFileName,const DWORD dwMode){
  75.     return  UnZipOpenArchive(hWnd,szFileName,dwMode);
  76. }
  77. HARC WINAPI UnZipOpenArchive(const HWND hWnd,LPCSTR szFileName,const DWORD dwMode)
  78. {
  79.     FINDZIP_FIND_INFO *handle;
  80.  
  81.     if(!finddll_init()){return 0;}
  82.     {
  83.         // オリジナルのUnZipOpenArchiveが使えるかチェック
  84.         HARC ret=OrigUnZipOpenArchive(hWnd,szFileName,dwMode);
  85.         if(orig_findfirst){return ret;}
  86.         if(ret!=NULL){
  87.             orig_findfirst=TRUE;
  88.             return ret;
  89.         }
  90.     }
  91.  
  92.     if((handle=malloc(sizeof(FINDZIP_FIND_INFO)))==NULL){
  93.         return (HARC)NULL;
  94.     }
  95.     if((handle->list=malloc(sizeof(FINDZIP_FIND_LIST)))==NULL){
  96.         return (HARC)NULL;
  97.     }
  98.     handle->list->next=NULL;
  99.     strcpy(handle->arcfilename,szFileName);
  100.     handle->hwnd=hWnd;
  101.     handle->mode=dwMode;
  102.     return handle;
  103. }
  104. /* 右側の空白類を削る*/
  105. static void RightTrim(char *str)
  106. {
  107.     char *ptr;
  108.     for(ptr=str+strlen(str)-1;ptr>=str && isspace(*ptr);ptr--){
  109.         ;
  110.     }
  111.     *(ptr+1)='\0';
  112. }
  113. int UnZip32OutputLineToIndividualInfo(char *line,INDIVIDUALINFO *info)
  114. {
  115.     /*
  116.     result of zip -v 
  117. 0         1         2         3         4         5         6
  118. 0123456789012345678901234567890123456789012345678901234567890123456789
  119.  Length  Method   Size  Ratio   Date    Time   CRC-32     Name
  120.  ------  ------   ----  -----   ----    ----   ------     ----
  121.   13092  Deflate   5384  59%  95-08-25  14:48  e5081f1b   aiueo
  122.  ------          ------  ---                              -------
  123.   13092            5384  58%                              1      
  124.  
  125.     result of zip -l
  126. 0         1         2         3         4         5         6         7         8
  127. 012345678901234567890123456789012345678901234567890123456789012345678901234567890123
  128.   Name          Original    Packed  Ratio   Date     Time   Attr Method   CRC-32
  129. --------------  --------  -------- ------ -------- -------- ---- -------- --------
  130. aiueo              13092      5384  59.4% 95-08-25  14:48:34 a--w Deflate e5081f1b
  131.     
  132.     */
  133.     char method[100];
  134.     char attr[100];
  135.     int ratio1,ratio2;
  136.     int year,month,date,hour,min,sec;
  137.     int ret;
  138.     char *line2;
  139.  
  140.     if(strlen(line)<82){return -1;}
  141.  
  142.     line2=line+strlen(line)-(82-14);    //ファイル名を除いた部分
  143.     *line2='\0';line2+=2;
  144.     
  145.     strcpy(info->szFileName,line);
  146.     RightTrim(info->szFileName);    //右の空白削除
  147.     /* -l オプションの結果を解析 */
  148.     ret=sscanf(line2,"%d %d %d.%d%% %d-%d-%d %d:%d:%d %s %s %x"
  149.         ,&(info->dwOriginalSize)
  150.         ,&(info->dwCompressedSize)
  151.         ,&ratio1,&ratio2
  152.         ,&year,&month,&date
  153.         ,&hour,&min,&sec
  154.         ,attr
  155.         ,method
  156.         ,&(info->dwCRC));
  157.     if(ret!=13){
  158.         return -1;
  159.     }
  160.     info->uFlag=0;
  161.     info->uOSType=(UINT)-1;
  162.     info->wRatio=ratio1*10+ratio2;
  163.     if(year<80){year=year+100;}
  164.     info->wDate=(year-80 << 4+5) | (month <<5) | (date);
  165.     info->wTime=(hour <<5+6) | (min <<5) | (sec / 2);
  166.     strncpy(info->szAttribute,attr,8);
  167.     strcpy(info->szMode,"-zip-");
  168.     
  169.     /* -v オプションの結果を解析
  170.     ret=sscanf(line,"%d %s %d %d%% %d-%d-%d %d:%d %x"
  171.         ,&(info->dwOriginalSize)
  172.         ,&method
  173.         ,&(info->dwCompressedSize)
  174.         ,&ratio
  175.         ,&year,&month,&date
  176.         ,&hour,&second
  177.         ,&(info->dwCRC)
  178.     );
  179.     if(ret!=10){
  180.         return -1;
  181.     }
  182.     info->wRatio=ratio*10;
  183.     info->wDate=(year << 4+5) & (month <<5) & (date);
  184.     info->wTime=(hour <<5+6) & (second <<6);
  185.     strcpy(info->szFileName,line+58);
  186.     */
  187.     return 0;
  188. }
  189. int WINAPI ZipUnZipFindFirst(HARC hArc,LPCSTR szWildName,INDIVIDUALINFO *lpSubInfo){
  190.     return UnZipFindFirst(hArc,szWildName,lpSubInfo);
  191. }
  192. int WINAPI UnZipFindFirst(HARC hArc,LPCSTR szWildName,INDIVIDUALINFO *lpSubInfo)
  193. {
  194.     FINDZIP_FIND_INFO *handle=(FINDZIP_FIND_INFO*)hArc;
  195.     char szOutput[UNZIP32_MAX_OUTPUT_SIZE];
  196.     char szCmdLine[FNAME_MAX32+100];
  197.     char *ptr,*oldptr;
  198.     int ret;
  199.     FINDZIP_FIND_LIST *find_list_ptr;
  200.  
  201.     if(orig_findfirst){
  202.         return OrigUnZipFindFirst(hArc,szWildName,lpSubInfo);
  203.     }
  204.  
  205.     // UnZipのコマンドラインを作成
  206.     strcpy(szCmdLine,"-l ");
  207.     strcat(szCmdLine,"\"");
  208.     strcat(szCmdLine,handle->arcfilename);
  209.     strcat(szCmdLine,"\"");
  210.     strcat(szCmdLine," ");
  211.     strcat(szCmdLine,szWildName);
  212.  
  213.     ret=UnZip(handle->hwnd,szCmdLine,szOutput,UNZIP32_MAX_OUTPUT_SIZE-1);
  214.     if(strlen(szOutput)>=UNZIP32_MAX_OUTPUT_SIZE-3){
  215.         return -1;
  216.     }
  217.     ptr=szOutput;
  218.     while((ptr=strchr(ptr,'\n')) && *ptr++){
  219.         if(strlen(ptr)>10 && strncmp(ptr,"--------------",14)==0){
  220.             break;
  221.         }
  222.     }
  223.     if(ptr==NULL){return -1;}
  224.     (ptr=strchr(ptr,'\n')) && ptr++;
  225.     find_list_ptr=handle->list;
  226.     oldptr=ptr;
  227.     while(ptr=strchr(ptr,'\n')){
  228.         INDIVIDUALINFO info;
  229.  
  230.         *ptr='\0';ptr++;
  231.  
  232.  
  233.         if(strlen(oldptr)>10 && strncmp(oldptr,"--------------",7)==0){
  234.             break;
  235.         }
  236.  
  237.         if(UnZip32OutputLineToIndividualInfo(oldptr,&info)==-1){
  238.             while(find_list_ptr!=NULL){
  239.                 FINDZIP_FIND_LIST *oldfindptr=find_list_ptr;
  240.                 find_list_ptr=find_list_ptr->next;
  241.                 free(oldfindptr);
  242.             }
  243.             return -1;
  244.         }
  245.         if((find_list_ptr->next=malloc(sizeof(FINDZIP_FIND_LIST)))==NULL){
  246.             FINDZIP_FIND_LIST *oldfindptr;
  247.             find_list_ptr=handle->list;
  248.             while(find_list_ptr!=NULL){
  249.                 oldfindptr=find_list_ptr;
  250.                 find_list_ptr=find_list_ptr->next;
  251.                 free(oldfindptr);
  252.             }
  253.             return -1;
  254.         }
  255.         find_list_ptr=find_list_ptr->next;
  256.         find_list_ptr->next=NULL;
  257.         find_list_ptr->info=info;
  258.         
  259.         oldptr=ptr;
  260.     }
  261.     handle->current=handle->list->next;
  262.     return UnZipFindNext(hArc,lpSubInfo);
  263. }
  264. int WINAPI ZipUnZipCloseArchive(HARC hArc){
  265.     return UnZipCloseArchive(hArc);
  266. }
  267. int WINAPI UnZipCloseArchive(HARC hArc)
  268. {
  269.     FINDZIP_FIND_LIST *find_list_ptr;
  270.  
  271.     if(orig_findfirst){
  272.         return OrigUnZipCloseArchive(hArc);
  273.     }
  274.     find_list_ptr=((FINDZIP_FIND_INFO*)hArc)->list;
  275.  
  276.     while(find_list_ptr!=NULL){
  277.         FINDZIP_FIND_LIST *oldfindptr;
  278.         oldfindptr=find_list_ptr;
  279.         find_list_ptr=find_list_ptr->next;
  280.         free(oldfindptr);
  281.     }
  282.     free((FINDZIP_FIND_INFO*)hArc);
  283.     return 0;
  284. }
  285. int WINAPI ZipUnZipFindNext(HARC hArc,INDIVIDUALINFO *lpSubInfo){
  286.     return UnZipFindNext(hArc,lpSubInfo);
  287. }
  288. int WINAPI UnZipFindNext(HARC hArc,INDIVIDUALINFO *lpSubInfo)
  289. {
  290.     FINDZIP_FIND_INFO *ptr=(FINDZIP_FIND_INFO*)hArc;
  291.  
  292.     if(orig_findfirst){
  293.         return OrigUnZipFindNext(hArc,lpSubInfo);
  294.     }
  295.     
  296.     if(ptr->current ==NULL){return -1;}
  297.     *lpSubInfo=(ptr->current->info);
  298.     ptr->current = ptr->current->next;
  299.     return 0;
  300. }
  301. #define ISARC_OPEN_ARCHIVE                23    /* UnlhaOpenArchive */
  302. #define ISARC_CLOSE_ARCHIVE                24    /* UnlhaCloseArchive */
  303. #define ISARC_FIND_FIRST                25    /* UnlhaFindFirst */
  304. #define ISARC_FIND_NEXT                    26    /* UnlhaFindNext */
  305. BOOL WINAPI ZipUnZipQueryFunctionList(const int iFunction){
  306.     return UnZipQueryFunctionList(iFunction);
  307. }
  308. BOOL WINAPI UnZipQueryFunctionList(const int iFunction)
  309. {
  310.     if(finddll_init()==0){return FALSE;}
  311.     switch(iFunction){
  312.     case ISARC_OPEN_ARCHIVE:
  313.     case ISARC_CLOSE_ARCHIVE:
  314.     case ISARC_FIND_FIRST:
  315.     case ISARC_FIND_NEXT:
  316.         return TRUE;
  317.     default:
  318.         return OrigUnZipQueryFunctionList(iFunction);
  319.     }
  320. }
  321.  
  322.  
  323. // DLLの初期化 
  324. static BOOL finddll_init(void)
  325. {
  326.     if(hLib){return TRUE;}
  327.     if((hLib=LoadLibrary(UNZIP32_DLL_NAME))<(HINSTANCE)HINSTANCE_ERROR){
  328.         return FALSE;
  329.     }
  330. #if 0
  331.     // 型チェック警告を出さないようにする(うっとおしいので、、)
  332. #pragma warning(disable:4113)
  333.     UnZip=GetProcAddress(hLib,"UnZip");
  334. #pragma warning(default:4113)
  335. #endif /* if 0 */
  336.     
  337.     OrigUnZipQueryFunctionList=(BOOL (WINAPI *)(const int iFunction))
  338.         GetProcAddress(hLib,"UnZipQueryFunctionList");
  339.     OrigUnZipGetVersion=(WORD (WINAPI *)(VOID))
  340.         GetProcAddress(hLib,"UnZipGetVersion");
  341.     OrigUnZip=(int (WINAPI *)(const HWND hWnd,LPCSTR szCmdLine,LPSTR szOutput,const DWORD dwSize))
  342.         GetProcAddress(hLib,"UnZip");
  343.  
  344.     OrigUnZipOpenArchive=(HARC (WINAPI *)(const HWND hWnd,LPCSTR szFileName,const DWORD dwMode))
  345.         GetProcAddress(hLib,"UnZipOpenArchive");
  346.     OrigUnZipFindFirst= (int (WINAPI *)(HARC hArc,
  347.             LPCSTR szWildName,INDIVIDUALINFO *lpSubInfo))
  348.         GetProcAddress(hLib,"UnZipFindFirst");
  349.     OrigUnZipCloseArchive= (int (WINAPI *)(HARC hArc))
  350.         GetProcAddress(hLib,"UnZipCloseArchive");
  351.     OrigUnZipFindNext=( int (WINAPI *)(HARC hArc,INDIVIDUALINFO *lpSubInfo))
  352.         GetProcAddress(hLib,"UnZipFindNext");
  353.     
  354.     //orig_findfirst=UnZipQueryFunctionList(ISARC_FIND_FIRST);
  355.     orig_findfirst=FALSE;
  356.  
  357.     return TRUE;
  358. }
  359. BOOL finddll_end(void)
  360. {
  361.     if(hLib==NULL){return TRUE;}
  362.     FreeLibrary(hLib);
  363.     hLib = NULL;
  364.     return TRUE;
  365. }
  366. #if 0
  367. BOOL   WINAPI   DllMain (HANDLE hInst, ULONG ul_reason_for_call,LPVOID lpReserved)
  368. {
  369.    switch( ul_reason_for_call) {
  370.     case DLL_PROCESS_ATTACH:
  371.         return dll_init();
  372.         break;
  373.     case DLL_THREAD_ATTACH:
  374.         break;
  375.     case DLL_PROCESS_DETACH:
  376.         return dll_end();
  377.         break;
  378.     case DLL_THREAD_DETACH:
  379.         break;
  380.     }
  381.     return TRUE;
  382. }    
  383. #endif    /* if 0 */
  384.  
  385. #if 0
  386. //int WINAPI WinMain(HINSTANCE hThisInst,HINSTANCE hPrevInst,LPSTR lpszArgs,int nWinMode)
  387. // デバッグ用のメイン関数(DLLでは不要)
  388. int main(int argc,char *argv[])
  389. {
  390.     HINSTANCE hThisInst=NULL;
  391.  
  392.     HARC harc;
  393.     INDIVIDUALINFO info;
  394.     int ret;
  395.  
  396.     DllMain(hThisInst,DLL_PROCESS_ATTACH,0);
  397.     harc=FindZipOpenArchive(NULL,"c:\\tmp\\tar\\aa.zip",0);
  398.     if(harc==NULL){
  399.         exit(1);
  400.     }
  401.     ret=FindZipFindFirst(harc,"",&info);
  402.     printf("original:compress:crc:flag:os:ratio:yy-mm-dd:hh-mm-ss:filename:attr:mode\n");
  403.  
  404.     while(ret==0){
  405.         printf("%d:%d:%x:%u:%d:%d:%d-%d-%d:%d-%d-%d:%s:%s:%s\n"
  406.             ,info.dwOriginalSize
  407.             ,info.dwCompressedSize
  408.             ,info.dwCRC
  409.             ,info.uFlag
  410.             ,info.uOSType
  411.             ,(int)info.wRatio
  412.             ,(info.wDate>>4+5) & 0x7f, (info.wDate>>5) & 0x0f,(info.wDate) & 0x1f
  413.             ,(info.wTime>>6+5) & 0x1f,(info.wTime>>5)&0x2f,((info.wTime) & 0x1f)*2
  414.             ,info.szFileName
  415.             ,info.szAttribute
  416.             ,info.szMode);
  417.         /*printf("%s:%d:%d:\n"
  418.             ,info.szFileName
  419.             ,info.dwOriginalSize
  420.             ,info.dwCompressedSize);*/
  421.         ret=FindZipFindNext(harc,&info);
  422.     }
  423.     FindZipCloseArchive(harc);    
  424.     DllMain(hThisInst,DLL_PROCESS_DETACH,0);
  425.     return 0;
  426. }
  427. #endif /* if 0 */