Generar unrar.lib y hb_unrar.lib con Borland

Post Reply
User avatar
Baxajaun
Posts: 853
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Generar unrar.lib y hb_unrar.lib con Borland

Post by Baxajaun »

Buenas noches !

En primer lugar dar las gracias públicamente a Antonio y a Cristobal por su ayuda y amistad.

He descargado la última versión de UnRar.dll del sitio web http://www.winrar.es/descargas/32/desca ... -en-ingles.

He usado los siguientes fuentes de P.Chornyj <myorg63@mail.ru>

unrar.ch

Code: Select all

#define RAR_ARCNAME        1
#define RAR_FILENAME       2
#define RAR_FLAGS          3
#define RAR_PACKSIZE       4
#define RAR_UNPSIZE        5
#define RAR_HOSTOS         6
#define RAR_FILECRC        7
#define RAR_FILETIME       8
#define RAR_UNPVER         9
#define RAR_METHOD         10
#define RAR_FILEATTR       11

#define RAR_OM_LIST        0
#define RAR_OM_EXTRACT     1

#define RAR_SKIP           0
#define RAR_TEST           1
#define RAR_EXTRACT        2

#define RAR_VOL_ASK        0
#define RAR_VOL_NOTIFY     1

#define UCM_CHANGEVOLUME   0
#define UCM_PROCESSDATA    1
#define UCM_NEEDPASSWORD   2

#define RAR_ST_SUCCESS     0
#define RAR_ST_OPEN        1
#define RAR_ST_OUT         2
#define RAR_ST_OPEN_OUT    3
#define RAR_ST_HBROKEN     4

#define ERAR_END_ARCHIVE   10
#define ERAR_NO_MEMORY     11
#define ERAR_BAD_DATA      12
#define ERAR_BAD_ARCHIVE      13
#define ERAR_UNKNOWN_FORMAT   14
#define ERAR_EOPEN            15
#define ERAR_ECREATE       16
#define ERAR_ECLOSE        17
#define ERAR_EREAD         18
#define ERAR_EWRITE        19
#define ERAR_SMALL_BUF     20
#define ERAR_UNKNOWN          21
#define ERAR_MISSING_PASSWORD 22
 
unrar.prg

Code: Select all

/*
 * Author: P.Chornyj <myorg63@mail.ru>
 *
 * Last revision : 2007.12.06
 *
*/

#include "common.ch"
#include "unrar.ch"

FUNCTION Hb_RarGetFilesList( ArchiveName, cPassWord, lFileTimeAsDate, lIncludeTime, lIncludeSeconds )
   LOCAL aResult

   DEFAULT lFileTimeAsDate TO FALSE
   DEFAULT lIncludeTime    TO TRUE
   DEFAULT lIncludeSeconds TO FALSE

   IF File( ArchiveName )
      aResult := Hb_RGetFilesList( ArchiveName, cPassWord, lFileTimeAsDate, lIncludeTime, lIncludeSeconds )
   ENDIF

RETURN iif( ValType( aResult ) == "A", aResult, {} )

/*
*/
FUNCTION Hb_UnrarFiles( ArchiveName, cPassWord, cPath, File )
RETURN Hb_ProcessFile( ArchiveName, cPassWord, cPath, File, RAR_EXTRACT )

/*
*/
FUNCTION Hb_RarTestFiles( ArchiveName, cPassWord, File )
RETURN Hb_ProcessFile( ArchiveName, cPassWord, , File, RAR_TEST )

   /*
*/
STATIC FUNCTION Hb_ProcessFile( ArchiveName, cPassWord, cPath, File, Operation )
   LOCAL lSuccess := .F.
   LOCAL sw, sw1, i, j
   LOCAL aFileList := {}, aFile := {}

   IF File( ArchiveName )
      IF ( HB_ISNIL( File ) )       
         lSuccess := Hb_RProcessFiles( Operation, ArchiveName, cPassWord, cPath )   
      ELSE
         aFileList := Hb_RGetFileNamesList( ArchiveName, cPassWord )

         sw := ValType( File )
         SWITCH sw
      CASE "N"
         IF ( File >= 1 .AND. File <= Len( aFileList ) )
            AAdd( aFile, aFileList[ File ] )
         ENDIF
         EXIT
      CASE "C"
         IF ( AScan( aFileList, {|e| e == File  } ) > 0  )
            AAdd( aFile, File )
         ENDIF
         EXIT
      CASE "A"
         FOR i := 1 TO Len( File )

            sw1 := ValType( File[i] )
            SWITCH sw1
         CASE "N"
            IF ( File[i] >= 1 .AND. File[i] <= Len( aFileList ) )
               AAdd( aFile, aFileList[ File[ i ] ] )
            ENDIF
            EXIT
         CASE "C"
            j := AScan( aFileList, {|e| e == File[i] } )
            IF ( j > 0 )
               AAdd( aFile, aFileList[ j ] )
            ENDIF
            EXIT
            END SWITCH
         NEXT

         END SWITCH     

         IF .NOT. Empty ( aFile )
            lSuccess := Hb_RProcessFiles( Operation, ArchiveName, cPassWord, cPath, aFile ) 
         ENDIF
      ENDIF
   ENDIF

RETURN lSuccess
 
unrar.h

Code: Select all

#ifndef _UNRAR_DLL_
#define _UNRAR_DLL_

#pragma pack(push, 1)

#define ERAR_SUCCESS             0
#define ERAR_END_ARCHIVE        10
#define ERAR_NO_MEMORY          11
#define ERAR_BAD_DATA           12
#define ERAR_BAD_ARCHIVE        13
#define ERAR_UNKNOWN_FORMAT     14
#define ERAR_EOPEN              15
#define ERAR_ECREATE            16
#define ERAR_ECLOSE             17
#define ERAR_EREAD              18
#define ERAR_EWRITE             19
#define ERAR_SMALL_BUF          20
#define ERAR_UNKNOWN            21
#define ERAR_MISSING_PASSWORD   22
#define ERAR_EREFERENCE         23
#define ERAR_BAD_PASSWORD       24

#define RAR_OM_LIST              0
#define RAR_OM_EXTRACT           1
#define RAR_OM_LIST_INCSPLIT     2

#define RAR_SKIP              0
#define RAR_TEST              1
#define RAR_EXTRACT           2

#define RAR_VOL_ASK           0
#define RAR_VOL_NOTIFY        1

#define RAR_DLL_VERSION       8

#define RAR_HASH_NONE         0
#define RAR_HASH_CRC32        1
#define RAR_HASH_BLAKE2       2


#ifdef _UNIX
#define CALLBACK
#define PASCAL
#define LONG long
#define HANDLE void *
#define LPARAM long
#define UINT unsigned int
#endif

#define RHDF_SPLITBEFORE 0x01
#define RHDF_SPLITAFTER  0x02
#define RHDF_ENCRYPTED   0x04
#define RHDF_SOLID       0x10
#define RHDF_DIRECTORY   0x20


struct RARHeaderData
{
  char         ArcName[260];
  char         FileName[260];
  unsigned int Flags;
  unsigned int PackSize;
  unsigned int UnpSize;
  unsigned int HostOS;
  unsigned int FileCRC;
  unsigned int FileTime;
  unsigned int UnpVer;
  unsigned int Method;
  unsigned int FileAttr;
  char         *CmtBuf;
  unsigned int CmtBufSize;
  unsigned int CmtSize;
  unsigned int CmtState;
};


struct RARHeaderDataEx
{
  char         ArcName[1024];
  wchar_t      ArcNameW[1024];
  char         FileName[1024];
  wchar_t      FileNameW[1024];
  unsigned int Flags;
  unsigned int PackSize;
  unsigned int PackSizeHigh;
  unsigned int UnpSize;
  unsigned int UnpSizeHigh;
  unsigned int HostOS;
  unsigned int FileCRC;
  unsigned int FileTime;
  unsigned int UnpVer;
  unsigned int Method;
  unsigned int FileAttr;
  char         *CmtBuf;
  unsigned int CmtBufSize;
  unsigned int CmtSize;
  unsigned int CmtState;
  unsigned int DictSize;
  unsigned int HashType;
  char         Hash[32];
  unsigned int RedirType;
  wchar_t      *RedirName;
  unsigned int RedirNameSize;
  unsigned int DirTarget;
  unsigned int MtimeLow;
  unsigned int MtimeHigh;
  unsigned int CtimeLow;
  unsigned int CtimeHigh;
  unsigned int AtimeLow;
  unsigned int AtimeHigh;
  unsigned int Reserved[988];
};


struct RAROpenArchiveData
{
  char         *ArcName;
  unsigned int OpenMode;
  unsigned int OpenResult;
  char         *CmtBuf;
  unsigned int CmtBufSize;
  unsigned int CmtSize;
  unsigned int CmtState;
};

typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2);

#define ROADF_VOLUME       0x0001
#define ROADF_COMMENT      0x0002
#define ROADF_LOCK         0x0004
#define ROADF_SOLID        0x0008
#define ROADF_NEWNUMBERING 0x0010
#define ROADF_SIGNED       0x0020
#define ROADF_RECOVERY     0x0040
#define ROADF_ENCHEADERS   0x0080
#define ROADF_FIRSTVOLUME  0x0100

#define ROADOF_KEEPBROKEN  0x0001

struct RAROpenArchiveDataEx
{
  char         *ArcName;
  wchar_t      *ArcNameW;
  unsigned int  OpenMode;
  unsigned int  OpenResult;
  char         *CmtBuf;
  unsigned int  CmtBufSize;
  unsigned int  CmtSize;
  unsigned int  CmtState;
  unsigned int  Flags;
  UNRARCALLBACK Callback;
  LPARAM        UserData;
  unsigned int  OpFlags;
  wchar_t      *CmtBufW;
  unsigned int  Reserved[25];
};

enum UNRARCALLBACK_MESSAGES {
  UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD,UCM_CHANGEVOLUMEW,
  UCM_NEEDPASSWORDW
};

typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode);
typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size);

#ifdef __cplusplus
extern "C" {
#endif

HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData);
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData);
int    PASCAL RARCloseArchive(HANDLE hArcData);
int    PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData);
int    PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData);
int    PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName);
int    PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName);
void   PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData);
void   PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc);
void   PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc);
void   PASCAL RARSetPassword(HANDLE hArcData,char *Password);
int    PASCAL RARGetDllVersion();

#ifdef __cplusplus
}
#endif

#pragma pack(pop)

#endif
 
hb_unrar.c

Code: Select all

/*
 * Harbour Project source code:
 * UnRar library low level (client api) interface code
 *
 * Copyright 2007 P.Chornyj <myorg63@mail.ru>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <windows.h>
#include "unrar.h"
#include "hbapi.h"
#include "hbvm.h"
#include "hbstack.h"
#include "hbapiitm.h"
#include "hbapifs.h"
#include "hbver.h"

#if HB_VER_MAJOR < 1
#error Too old version [x]Harbour
#endif
#define RAR_ARCNAME     1
#define RAR_FILENAME    2
#define RAR_FLAGS       3
#define RAR_PACKSIZE    4
#define RAR_UNPSIZE     5
#define RAR_HOSTOS      6
#define RAR_FILECRC     7
#define RAR_FILETIME    8
#define RAR_UNPVER      9
#define RAR_METHOD      10
#define RAR_FILEATTR    11

#define RAR_ST_SUCCESS  0
#define RAR_ST_OPEN     1
#define RAR_ST_OUT      2
#define RAR_ST_OPEN_OUT 3
#define RAR_ST_HBROKEN  4

typedef UINT ( CALLBACK *RGetApiDllVersion ) ( void );

static void       OpenProcessFileError( int Error );
static void       OutProcessFileError( int Error, const char *Filename );
static void       ClearError( void );
int CALLBACK      CallbackProc( UINT msg, LONG UserData, LONG P1, LONG P2 );
static PHB_ITEM   RGetDate( UINT FileTime );
static PHB_ITEM   RConvertFileTimeToString( UINT FileTime, BOOL includeTime, BOOL includeSeconds );

static UINT       s_CmtBufSize = 16384;
static int        s_iOpenError = 0;
static char       s_msgOpenError[64];
static int        s_iOutError = 0;
static char       s_msgOutError[64];
static char       s_FName[_MAX_PATH + 1];
static BOOL       s_bHeaderBroken = FALSE;
static PHB_SYMB   pSymbolCallback = 0;

/*
   Get Unrar.DLL API version
*/

HB_FUNC( HB_RARGETDLLVERSION )
{
   int               iResult = 0;
   HINSTANCE         m_hDLL;
   RGetApiDllVersion m_UnRarDllApiVersion;

   m_hDLL = LoadLibrary( "unrar.dll" );

   if( m_hDLL != NULL )
   {
      m_UnRarDllApiVersion = ( (RGetApiDllVersion) GetProcAddress(m_hDLL, "RARGetDllVersion") );
      if( m_UnRarDllApiVersion != NULL )
      {
         iResult = m_UnRarDllApiVersion();
      }

      FreeLibrary( m_hDLL );
   }
   else
   {
      iResult = -1;
   }

   hb_retni( iResult );
}

/*
   Archive comments operations  
*/

HB_FUNC( HB_RARSETCMTBUFSIZE )
{
   BOOL  bResult = FALSE;
   int   iSize = hb_parni( 1 );

   if( iSize >= 64 && iSize <= 56535 )
   {
      s_CmtBufSize = hb_parni( 1 );

      bResult = TRUE;
   }
   else
   {
      s_CmtBufSize = 16384;
   }

   hb_retl( bResult );
}

HB_FUNC( HB_RARGETCMTBUFSIZE )
{
   hb_retni( s_CmtBufSize );
}

HB_FUNC( HB_RARGETCOMMENT )
{
   PHB_ITEM                      pCmtState = hb_param( 2, HB_IT_INTEGER );
   HANDLE                        hArcData;
   char                          *CmtBuf = ( char * ) hb_xgrab( s_CmtBufSize );
   struct RAROpenArchiveDataEx   OpenArchiveData;

   hb_xmemset( &OpenArchiveData, 0, sizeof(OpenArchiveData) );
   OpenArchiveData.ArcName = ( char * ) hb_parc( 1 );
   OpenArchiveData.CmtBuf = CmtBuf;
   OpenArchiveData.CmtBufSize = s_CmtBufSize;
   OpenArchiveData.OpenMode = RAR_OM_LIST;

   ClearError();

   hArcData = RAROpenArchiveEx( &OpenArchiveData );
   if( OpenArchiveData.OpenResult == 0 )
   {
      if( OpenArchiveData.CmtState == 1 )
      {
         char  *szTempR = ( char * ) hb_xgrab( OpenArchiveData.CmtSize + 1 );

         hb_xmemset( szTempR, 0, OpenArchiveData.CmtSize + 1 );
         hb_strncpy( szTempR, OpenArchiveData.CmtBuf, OpenArchiveData.CmtSize );

         hb_retclen_buffer( szTempR, OpenArchiveData.CmtSize );
      }
      else
      {
         hb_retc( "" );
      }

      if( pCmtState != NULL )
      {
         hb_storni( OpenArchiveData.CmtState, 2 );
      }
   }
   else
   {
      OpenProcessFileError( OpenArchiveData.OpenResult );

      hb_retc( "" );
   }

   RARCloseArchive( hArcData );

   hb_xfree( CmtBuf );
}

/*
   Get archive info     
*/

HB_FUNC( HB_RARGETARCHIVEINFO )
{
   HANDLE                        hArcData;
   int                           iResult = 0;
   char                          *CmtBuf = ( char * ) hb_xgrab( s_CmtBufSize );
   struct RAROpenArchiveDataEx   OpenArchiveData;

   hb_xmemset( &OpenArchiveData, 0, sizeof(OpenArchiveData) );
   OpenArchiveData.ArcName = ( char * ) hb_parc( 1 );
   OpenArchiveData.CmtBuf = CmtBuf;
   OpenArchiveData.CmtBufSize = s_CmtBufSize;
   OpenArchiveData.OpenMode = RAR_OM_LIST;

   ClearError();

   hArcData = RAROpenArchiveEx( &OpenArchiveData );
   if( OpenArchiveData.OpenResult == 0 )
   {
      iResult = OpenArchiveData.Flags;
   }
   else
   {
      OpenProcessFileError( OpenArchiveData.OpenResult );
   }

   RARCloseArchive( hArcData );

   hb_xfree( CmtBuf );

   hb_retni( iResult );
}

/*
   Get Number Of Files in Archive   
*/

HB_FUNC( HB_RARGETFILESCOUNT )
{
   HANDLE                        hArcData;
   int                           RHCode;
   struct RAROpenArchiveDataEx   OpenArchiveData;
   LONG                          lFileCount = 0;

   hb_xmemset( &OpenArchiveData, 0, sizeof(OpenArchiveData) );
   OpenArchiveData.ArcName = ( char * ) hb_parc( 1 );
   OpenArchiveData.CmtBuf = NULL;
   OpenArchiveData.OpenMode = RAR_OM_LIST;

   ClearError();

   hArcData = RAROpenArchiveEx( &OpenArchiveData );
   if( OpenArchiveData.OpenResult == 0 )
   {
      struct RARHeaderDataEx  HeaderData;
      int                     PFCode;
      PHB_ITEM                pPassword = hb_param( 2, HB_IT_STRING );
      BOOL                    bIncludeDirectory = hb_parl( 3 );

      if( pPassword != NULL )
      {
         RARSetPassword( hArcData, ( char * ) hb_itemGetCPtr(pPassword) );
      }

      //  RARSetCallback( hArcData, CallbackProc, 0 );

      HeaderData.CmtBuf = NULL;
      while( (RHCode = RARReadHeaderEx(hArcData, &HeaderData)) == 0 )
      {
         if( bIncludeDirectory )
         {
            lFileCount++;
         }
         else
         {
            if( !(HeaderData.FileAttr & HB_FA_DIRECTORY) )
            {
               lFileCount++;
            }
         }

         if( (PFCode = RARProcessFile(hArcData, RAR_SKIP, NULL, NULL)) != 0 )
         {
            OutProcessFileError( PFCode, HeaderData.FileName );
            break;
         }
      }

      if( RHCode == ERAR_BAD_DATA )
      {
         s_bHeaderBroken = TRUE;
      }
   }
   else
   {
      OpenProcessFileError( OpenArchiveData.OpenResult );
   }

   hb_retnl( lFileCount );

   RARCloseArchive( hArcData );
}

/*
   Get file list from archive
*/

HB_FUNC( HB_RGETFILESLIST )
{
   PHB_ITEM                      pFileList = hb_itemArrayNew( 0 );
   HANDLE                        hArcData;
   int                           RHCode;
   struct RAROpenArchiveDataEx   OpenArchiveData;

   hb_xmemset( &OpenArchiveData, 0, sizeof(OpenArchiveData) );
   OpenArchiveData.ArcName = ( char * ) hb_parc( 1 );
   OpenArchiveData.CmtBuf = NULL;
   OpenArchiveData.OpenMode = RAR_OM_LIST;

   ClearError();

   hArcData = RAROpenArchiveEx( &OpenArchiveData );
   if( OpenArchiveData.OpenResult == 0 )
   {
      struct RARHeaderDataEx  HeaderData;
      int                     PFCode;

      PHB_ITEM                pPassword = hb_param( 2, HB_IT_STRING );

      BOOL                    fFileTimeAsDate = hb_parl( 3 );
      BOOL                    fIncludeTime = hb_parl( 4 );
      BOOL                    fIncludeSeconds = hb_parl( 5 );

      PHB_ITEM                pArcName = hb_itemNew( NULL );
      PHB_ITEM                pFileName = hb_itemNew( NULL );
      PHB_ITEM                pFlags = hb_itemNew( NULL );
      PHB_ITEM                pUnpSize = hb_itemNew( NULL );
      PHB_ITEM                pPackSize = hb_itemNew( NULL );
      PHB_ITEM                pHostOS = hb_itemNew( NULL );
      PHB_ITEM                pFileCRC = hb_itemNew( NULL );
      PHB_ITEM                pUnpVer = hb_itemNew( NULL );
      PHB_ITEM                pMethod = hb_itemNew( NULL );
      PHB_ITEM                pFileAttr = hb_itemNew( NULL );

      if( pPassword != NULL )
      {
         RARSetPassword( hArcData, ( char * ) hb_itemGetCPtr(pPassword) );
      }

      RARSetCallback( hArcData, CallbackProc, 0 );

      HeaderData.CmtBuf = NULL;
      while( (RHCode = RARReadHeaderEx(hArcData, &HeaderData)) == 0 )
      {
         PHB_ITEM pSubarray = hb_itemArrayNew( 11 );
         __int64  PackSize = HeaderData.PackSize + ( ((__int64) HeaderData.PackSizeHigh) << 32 );
         __int64  UnpSize = HeaderData.UnpSize + ( ((__int64) HeaderData.UnpSizeHigh) << 32 );
         char     buff[32];

         hb_arraySet( pSubarray, RAR_ARCNAME, hb_itemPutC(pArcName, HeaderData.ArcName) );
         hb_arraySet( pSubarray, RAR_FILENAME, hb_itemPutC(pFileName, HeaderData.FileName) );
         hb_arraySet( pSubarray, RAR_FLAGS, hb_itemPutNI(pFlags, HeaderData.Flags) );
         hb_arraySet( pSubarray, RAR_PACKSIZE, hb_itemPutND(pPackSize, PackSize) );
         hb_arraySet( pSubarray, RAR_UNPSIZE, hb_itemPutND(pUnpSize, UnpSize) );
         hb_arraySet( pSubarray, RAR_HOSTOS, hb_itemPutNI(pHostOS, HeaderData.HostOS) );
         hb_arraySet( pSubarray, RAR_FILECRC, hb_itemPutNI(pFileCRC, HeaderData.FileCRC) );

         if( fFileTimeAsDate )
         {
            hb_arraySet( pSubarray, RAR_FILETIME, RGetDate(HeaderData.FileTime) );
         }
         else
         {
            hb_arraySet( pSubarray, RAR_FILETIME, RConvertFileTimeToString(HeaderData.FileTime, fIncludeTime, fIncludeSeconds) );
         }

         hb_arraySet( pSubarray, RAR_UNPVER, hb_itemPutNI(pUnpVer, HeaderData.UnpVer) );
         hb_arraySet( pSubarray, RAR_METHOD, hb_itemPutNI(pMethod, HeaderData.Method) );
         hb_arraySet( pSubarray, RAR_FILEATTR, hb_itemPutC(pFileAttr, hb_fsAttrDecode(HeaderData.FileAttr, buff)) );

         hb_arrayAdd( pFileList, pSubarray );
         hb_itemRelease( pSubarray );

         if( (PFCode = RARProcessFile(hArcData, RAR_SKIP, NULL, NULL)) != 0 )
         {
            OutProcessFileError( PFCode, HeaderData.FileName );
            break;
         }
      }

      hb_itemRelease( pArcName );
      hb_itemRelease( pFileName );
      hb_itemRelease( pFlags );
      hb_itemRelease( pUnpSize );
      hb_itemRelease( pPackSize );
      hb_itemRelease( pHostOS );
      hb_itemRelease( pFileCRC );
      hb_itemRelease( pUnpVer );
      hb_itemRelease( pMethod );
      hb_itemRelease( pFileAttr );

      if( RHCode == ERAR_BAD_DATA )
      {
         s_bHeaderBroken = TRUE;
      }
   }
   else
   {
      OpenProcessFileError( OpenArchiveData.OpenResult );
   }

   #ifdef __XHARBOUR__
   hb_itemRelease( hb_itemReturn(pFileList) );
   #else
   hb_itemReturnRelease( pFileList );
   #endif

   RARCloseArchive( hArcData );
}

HB_FUNC( HB_RGETFILENAMESLIST )
{
   PHB_ITEM                      pFileList = hb_itemArrayNew( 0 );
   HANDLE                        hArcData;
   int                           RHCode;
   struct RAROpenArchiveDataEx   OpenArchiveData;

   hb_xmemset( &OpenArchiveData, 0, sizeof(OpenArchiveData) );
   OpenArchiveData.ArcName = ( char * ) hb_parc( 1 );
   OpenArchiveData.CmtBuf = NULL;
   OpenArchiveData.OpenMode = RAR_OM_LIST;

   ClearError();
   hArcData = RAROpenArchiveEx( &OpenArchiveData );
   if( OpenArchiveData.OpenResult == 0 )
   {
      struct RARHeaderDataEx  HeaderData;
      int                     PFCode;
      PHB_ITEM                pPassword = hb_param( 2, HB_IT_STRING );
      PHB_ITEM                pFileName = hb_itemNew( NULL );

      if( pPassword != NULL )
      {
         RARSetPassword( hArcData, ( char * ) hb_itemGetCPtr(pPassword) );
      }

      RARSetCallback( hArcData, CallbackProc, 0 );

      HeaderData.CmtBuf = NULL;
      while( (RHCode = RARReadHeaderEx(hArcData, &HeaderData)) == 0 )
      {
         hb_arrayAdd( pFileList, hb_itemPutC(pFileName, HeaderData.FileName) );

         if( (PFCode = RARProcessFile(hArcData, RAR_SKIP, NULL, NULL)) != 0 )
         {
            OutProcessFileError( PFCode, HeaderData.FileName );
            break;
         }
      }

      hb_itemRelease( pFileName );

      if( RHCode == ERAR_BAD_DATA )
      {
         s_bHeaderBroken = TRUE;
      }
   }
   else
   {
      OpenProcessFileError( OpenArchiveData.OpenResult );
   }

   #ifdef __XHARBOUR__
   hb_itemRelease( hb_itemReturn(pFileList) );
   #else
   hb_itemReturnRelease( pFileList );
   #endif

   RARCloseArchive( hArcData );
}

/*
   Process Files
*/

HB_FUNC( HB_RPROCESSFILES )
{
   BOOL                          fResult = TRUE;
   HANDLE                        hArcData;
   int                           RHCode;
   struct RAROpenArchiveDataEx   OpenArchiveData;

   int                           Operation = hb_parni( 1 );
   PHB_ITEM                      pArray = hb_param( 5, HB_IT_ARRAY );

   hb_xmemset( &OpenArchiveData, 0, sizeof(OpenArchiveData) );
   OpenArchiveData.ArcName = ( char * ) hb_parc( 2 );
   OpenArchiveData.CmtBuf = NULL;
   OpenArchiveData.OpenMode = RAR_OM_EXTRACT;

   ClearError();

   hArcData = RAROpenArchiveEx( &OpenArchiveData );
   if( OpenArchiveData.OpenResult == 0 )
   {
      struct RARHeaderDataEx  HeaderData;
      int                     PFCode;

      PHB_ITEM                pPassword = hb_param( 3, HB_IT_STRING );
      PHB_ITEM                pPath = hb_param( 4, HB_IT_STRING );

      DWORD                   ulLen = hb_itemGetCLen( pPath );
      char                    *pszDst = ( char * ) hb_xgrab( ulLen + 1 );

      hb_xmemset( pszDst, 0, ulLen + 1 );

      // Convert path from ANSI to OEM. Is need ?

      CharToOemBuff( (LPCSTR) hb_itemGetCPtr(pPath), (LPSTR) pszDst, ulLen );

      if( pPassword != NULL )
      {
         RARSetPassword( hArcData, ( char * ) hb_itemGetCPtr(pPassword) );
      }

      RARSetCallback( hArcData, CallbackProc, Operation );

      HeaderData.CmtBuf = NULL;

      while( (RHCode = RARReadHeaderEx(hArcData, &HeaderData)) == 0 )
      {
         PHB_ITEM pValue = hb_itemNew( NULL );
         hb_itemPutC( pValue, HeaderData.FileName );

         if( pArray != NULL )
         {
            if( (PFCode = RARProcessFile(hArcData, (hb_arrayScan(pArray, pValue, NULL, NULL,
            #ifdef __XHARBOUR__
            FALSE,
            #endif
            FALSE) > 0) ? Operation : RAR_SKIP, pszDst, NULL)) != 0 )
            {
               OutProcessFileError( PFCode, HeaderData.FileName );
               fResult = FALSE;
               break;
            }
         }
         else
         {
            if( (PFCode = RARProcessFile(hArcData, Operation, pszDst, NULL)) != 0 )
            {
               OutProcessFileError( PFCode, HeaderData.FileName );
               fResult = FALSE;
               break;
            }
         }

         hb_itemRelease( pValue );
      }

      if( RHCode == ERAR_BAD_DATA )
      {
         fResult = FALSE;
         s_bHeaderBroken = TRUE;
      }

      hb_xfree( pszDst );
   }
   else
   {
      fResult = FALSE;
      OpenProcessFileError( OpenArchiveData.OpenResult );
   }

   RARCloseArchive( hArcData );

   hb_retl( fResult );
}

/*
   Error processing
*/

static void OutProcessFileError( int Error, const char *FileName )
{
   switch( Error )
   {
      case ERAR_UNKNOWN_FORMAT:     strcpy( s_msgOutError, "Unknown archive format" ); break;
      case ERAR_BAD_ARCHIVE:        strcpy( s_msgOutError, "Bad volume" ); break;
      case ERAR_ECREATE:            strcpy( s_msgOutError, "File create error" ); break;
      case ERAR_EOPEN:              strcpy( s_msgOutError, "Volume open error" ); break;
      case ERAR_ECLOSE:             strcpy( s_msgOutError, "File close error" ); break;
      case ERAR_EREAD:              strcpy( s_msgOutError, "Read error" ); break;
      case ERAR_EWRITE:             strcpy( s_msgOutError, "Write error" ); break;
      case ERAR_BAD_DATA:           strcpy( s_msgOutError, "CRC error" ); break;
      case ERAR_UNKNOWN:            strcpy( s_msgOutError, "Unknown error" ); break;
      case ERAR_MISSING_PASSWORD:   strcpy( s_msgOutError, "Password for encrypted file is not specified" ); break;
   }

   s_iOutError = Error;
   strcpy( s_FName, FileName );
}

static void OpenProcessFileError( int Error )
{
   switch( Error )
   {
      case ERAR_NO_MEMORY:       strcpy( s_msgOpenError, "Not enough memory to initialize data structures" ); break;
      case ERAR_BAD_DATA:        strcpy( s_msgOpenError, "Archive header broken" ); break;
      case ERAR_BAD_ARCHIVE:     strcpy( s_msgOpenError, "File is not valid RAR archive" ); break;
      case ERAR_UNKNOWN_FORMAT:  strcpy( s_msgOpenError, "Unknown encryption used for archive headers" ); break;
      case ERAR_EOPEN:           strcpy( s_msgOpenError, "File open error" ); break;
   }

   s_iOpenError = Error;
}

HB_FUNC( HB_RARGETPROCSTATUS )
{
   INT   iResult;

   if( (s_iOpenError == 0) && (s_iOutError == 0) )
   {
      iResult = RAR_ST_SUCCESS;
   }
   else if( (s_iOpenError != 0) && (s_iOutError != 0) )
   {
      iResult = RAR_ST_OPEN_OUT;
   }
   else if( s_iOpenError != 0 )
   {
      iResult = RAR_ST_OPEN;
   }
   else
   {
      iResult = RAR_ST_OUT;
   }

   if( iResult == RAR_ST_SUCCESS )
   {
      iResult = ( s_bHeaderBroken ) ? RAR_ST_HBROKEN : iResult;
   }

   hb_retni( iResult );
}

static void ClearError( void )
{
   s_iOpenError = 0;
   s_msgOpenError[0] = '\0';

   s_iOutError = 0;
   s_msgOutError[64] = '\0';
   s_FName[0] = '\0';

   s_bHeaderBroken = FALSE;
}

HB_FUNC( HB_RARGETERRORINFO )
{
   PHB_ITEM pResult = hb_itemArrayNew( 5 );
   PHB_ITEM tmp;

   tmp = hb_itemPutNI( NULL, s_iOpenError );
   hb_arraySet( pResult, 1, tmp );

   tmp = hb_itemPutC( NULL, s_msgOpenError );
   hb_arraySet( pResult, 2, tmp );

   tmp = hb_itemPutNI( NULL, s_iOutError );
   hb_arraySet( pResult, 3, tmp );

   tmp = hb_itemPutC( NULL, s_msgOutError );
   hb_arraySet( pResult, 4, tmp );

   tmp = hb_itemPutC( NULL, s_FName );
   hb_arraySet( pResult, 5, tmp );

   hb_itemRelease( tmp );

   ClearError();

   #ifdef __XHARBOUR__
   hb_itemRelease( hb_itemReturn(pResult) );
   #else
   hb_itemReturnRelease( pResult );
   #endif
}

/*
   Convert FileTime to date or string
*/

static PHB_ITEM RGetDate( UINT FileTime )
{
   FILETIME    ft;
   SYSTEMTIME  st;
   PHB_ITEM    pResult = hb_itemNew( NULL );

   DosDateTimeToFileTime( HIWORD(FileTime), LOWORD(FileTime), &ft );
   FileTimeToSystemTime( &ft, &st );

   return( hb_itemPutD(pResult, st.wYear, st.wMonth, st.wDay) );
}

static PHB_ITEM RConvertFileTimeToString( UINT FileTime, BOOL includeTime, BOOL includeSeconds )
{
   PHB_ITEM    pResult = hb_itemNew( NULL );
   FILETIME    ft;
   SYSTEMTIME  st;
   char        buff[20];
   ULONG       i;

   DosDateTimeToFileTime( HIWORD(FileTime), LOWORD(FileTime), &ft );
   FileTimeToSystemTime( &ft, &st );

   buff[0] = '\0';
   i = sprintf( buff, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay );

   if( includeTime )
   {
      i += sprintf( buff + i, " %02d:%02d", st.wHour, st.wMinute );
      if( includeSeconds )
      {
         i += sprintf( buff + i, ":%02d", st.wSecond );
      }
   }

   return( hb_itemPutCL(pResult, buff, i) );
}

/*
   CALLBACK
*/

static int CALLBACK CallbackProc( UINT msg, LONG UserData, LONG P1, LONG P2 )
{
   if( !pSymbolCallback )
   {
      pSymbolCallback = hb_dynsymSymbol( hb_dynsymGet("HB_RARCALLBACKFUNC") );
   }

   if( pSymbolCallback )
   {
      hb_vmPushSymbol( pSymbolCallback );
      hb_vmPushNil();
      hb_vmPushInteger( msg );
      hb_vmPushLong( UserData );

      switch( msg )
      {
         case UCM_CHANGEVOLUME:
            {
               ULONG ulLen;
               char  buffer[_MAX_PATH+1];

               buffer[0] = '\0';
               ulLen = sprintf( buffer, "%s", ( char * ) P1 );

               hb_vmPushString( ( const char * ) buffer, ulLen );
               hb_vmPushLong( P2 );

               hb_vmDo( 4 );
               if( P2 == RAR_VOL_NOTIFY )
               {
                  return( hb_parni(-1) );
               }
               else if( P2 == RAR_VOL_ASK )
               {
                  if( HB_IS_STRING(hb_param(-1, HB_IT_ANY)) )
                  {
                     hb_strncpy( ( char * ) P1, hb_parc(-1), _MAX_PATH );

                     return( 0 );
                  }
                  else
                  {
                     return( hb_parni(-1) );
                  }
               }
            }

         case UCM_NEEDPASSWORD:
            {
               hb_vmPushLong( P1 );
               hb_vmPushLong( P2 );

               hb_vmDo( 4 );

               hb_strncpy( ( char * ) P1, hb_parc(-1), P2 );

               return( 0 );
            }

         case UCM_PROCESSDATA:
            {
               /* TODO? */

               hb_vmPushPointer( ( void * ) &P1 );
               hb_vmPushLong( P2 );

               hb_vmDo( 4 );
            }
      }
   }

   return( 0 );
}
 
He podido generar las librerias mediante un fichero hbmk2

make-hb_unrar.bat

Code: Select all

REM Borland 7.40 32 bits
set PATH=%PATH%;F:\Develop\HarbourBinaries\Borland\7432\bin;F:\Develop\HarbourBinaries\Borland\7432\include;F:\Develop\HarbourBinaries\Borland\7432\lib;F:\Develop\Borland\BCC74_32\bin

hbmk2 -hbimplib unrar.dll
hbmk2 hb_unrar.hbp
hb_unrar.hbp

Code: Select all

-hblib
-inc

-o${hb_name}
-w0 -es2
-trace

-depkeyhead=unrar.h
#-depcontrol=no{HB_BUILD_3RDEXT='no'}
-depimplibs=Unrar.dll

${hb_name}.hbx

unrar.prg
hb_unrar.c
y mediante un fichero makelib.bat

Code: Select all

REM Borland 7.40 32 bits
set PATH=%PATH%;F:\Develop\HarbourBinaries\Borland\7432\bin;F:\Develop\HarbourBinaries\Borland\7432\include;F:\Develop\HarbourBinaries\Borland\7432\lib\win\bcc;F:\Develop\Borland\BCC74_32\bin;F:\Develop\Borland\BCC74_32\include;F:\Develop\Borland\BCC74_32\lib\win32;F:\Develop\Borland\BCC74_32\lib\win32\;F:\Develop\Borland\BCC74_32\lib\win32;F:\Develop\Borland\BCC74_32\lib\win32\psdk\

@echo off


F:\Develop\Borland\BCC74_32\bin\impdef unrar.def unrar.dll
F:\Develop\Borland\BCC74_32\bin\implib unrar.lib unrar.def

  
F:\Develop\HarbourBinaries\Borland\7432\bin\harbour unrar.prg -n -q0 -w -es2 -gc0 -iF:\Develop\HarbourBinaries\Borland\7432\include;F:\Develop\Borland\BCC74_32\include
F:\Develop\CCompilers\BCC7432\bin\bcc32 -c -O2 -tW -tWM -d -a8 -OS -IF:\Develop\HarbourBinaries\Borland\7432\include;F:\Develop\Borland\BCC74_32\include -LF:\Develop\Borland\BCC74_32\lib\win32;F:\Develop\Borland\BCC74_32\lib\win32\psdk unrar.c
F:\Develop\CCompilers\BCC7432\bin\bcc32 -c -O2 -tW -tWM -d -a8 -OS -IF:\Develop\HarbourBinaries\Borland\7432\include;F:\Develop\Borland\BCC74_32\include -LF:\Develop\Borland\BCC74_32\lib\win32;F:\Develop\Borland\BCC74_32\lib\win32\psdk hb_unrar.c

F:\Develop\Borland\BCC74_32\bin\tlib hb_unrar.lib +unrar.obj +hb_unrar.obj
 
Nuevamente, muchas gracias.

Si alguno de vosotros ve algún error o mejora esto, por favor actualizar el hilo.

Saludos,
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Generar unrar.lib y hb_unrar.lib con Borland

Post by Antonio Linares »

Felix,

De esta forma anidamos dos ficheros hbp para que se construya el fichero de importación:

unrarimp.hbp

Code: Select all

-hbimplib

unrar.dll
unrar.hbp

Code: Select all

-hblib

hb_unrar.c
unrar.prg
unrar.a

unrarimp.hbp
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Baxajaun
Posts: 853
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: Generar unrar.lib y hb_unrar.lib con Borland

Post by Baxajaun »

Buenos días !

Por si alguien quiere probar la librería con Harbour y FWH.

demo_unrar.prg

Code: Select all

    /*
     * Fivewin UnRar Demo
     * Author: P.Chornyj <myorg63@mail.ru>
    */

    #include "Fivewin.ch"
    #include "common.ch"
    #include "unrar.ch"
    #translate And ( <p1> , <p2> ) ;
    => ;
    hb_BitAnd( <p1> , <p2> )
    static oWnd, oMenu, oFont, oIcon
    #define cTab CHR(9)
    #define msginfo( c ) MsgInfo( c, , , .f. )
    #include "unrar.prg"


    FUNCTION Main

       DEFINE FONT oFont NAME "Arial"  SIZE 0,-12
       DEFINE ICON oIcon FILE "Unrar.ico"
       DEFINE WINDOW oWnd TITLE 'UNRAR Test' ;
         ICON oIcon MENU BuildMenu() MDI      

         ACTIVATE WINDOW oWnd CENTERED VALID MsgYesNo( "¿   Está seguro de querer Salir   ?", "!!! Atención !!!" )

    Return NIL

    /*
       Test 0:
       -------
       Hb_RarTestFiles( ArchiveName, cPassWord, File ) ---> lSuccess
       Hb_RarGetProcStatus() ---> nLastUnRarProcessStatus

       nLastUnRarProcessStatus is one from possible values:

       RAR_ST_SUCCESS     0  - an          action is successful
       RAR_ST_OPEN        1  - open archive process error
       RAR_ST_OUT         2  - out  archive process error
       RAR_ST_OPEN_OUT    3
       RAR_ST_HBROKEN     4  - file header broken

    */
    Procedure Test0()
       Local x

       x := cGetFile( "Rar Files (*.rar)|*.rar|All files (*.*)|*.*" , "Open archive" , GetCurDir() , "Test.rar" , .T. )

       IF ( ! Empty( x ) )
          IF ( Hb_RarTestFiles( x ) )   
             msginfo ( "Testing is OK for" + CRLF + x )
          ELSE
             UnRarErrorInfo( x, Hb_RarGetProcStatus() )
          ENDIF
       ENDIF

    Return

    /*
       Test 1:
       -------
       Hb_RarGetArchiveInfo( ArchiveName ) ---> nFlags

       nFlags - combination of bit flags.

       Possible values:

       0x0001  - Volume attribute (archive volume)
       0x0002  - Archive comment present
       0x0004  - Archive lock attribute
       0x0008  - Solid attribute (solid archive)
       0x0010  - New volume naming scheme ('volname.partN.rar')
       0x0020  - Authenticity information present
       0x0040  - Recovery record present
       0x0080  - Block headers are encrypted
       0x0100  - First volume (set only by RAR 3.0 and later)
    */
    Procedure Test1()
       Local x, msg := ""
       Local flags
       Local status := 0

       x := cGetFile( "Rar Files (*.rar)|*.rar|All files (*.*)|*.*" , "Open archive" , GetCurDir() , "Test.rar" , .T. )

       IF ( ! Empty( x ) )
          flags := Hb_RarGetArchiveInfo( x )    

          status := Hb_RarGetProcStatus()
          IF ( status <> RAR_ST_SUCCESS )
             UnRarErrorInfo( x, status )
             RETURN
          ENDIF

          msg += ( "Archive     " + cTab + " : " + x + CRLF )
          msg += ( "Volume      " + cTab + " : " + iif( lAnd( flags,  1 ), "yes", "no" ) + CRLF )
          msg += ( "Comment     " + cTab + " : " + iif( lAnd( flags,  2 ), "yes", "no" ) + CRLF )
          msg += ( "Locked      " + cTab + " : " + iif( lAnd( flags,  4 ), "yes", "no" ) + CRLF )
          msg += ( "Solid" + cTab + cTab + " : " + iif( lAnd( flags,  8 ), "yes", "no" ) + CRLF )
          msg += ( "New naming  " + cTab + " : " + iif( lAnd( flags, 16 ), "yes", "no" ) + CRLF )
          msg += ( "Authenticity" + cTab + " : " + iif( lAnd( flags, 32 ), "yes", "no" ) + CRLF )
          msg += ( "Recovery    " + cTab + " : " + iif( lAnd( flags, 64 ), "yes", "no" ) + CRLF )
          msg += ( "Encr.headers" + cTab + " : " + iif( lAnd( flags,128 ), "yes", "no" ) + CRLF )
          msg += ( "First volume" + cTab + " : " + iif( lAnd( flags,256 ), "yes", "no or older than 3.0" ) )

          MsgInfo( msg, "Archive Info" )
       ENDIF

    Return

    /*
       Test 2:
       -------
       Hb_RarGetFilesCount( ArchiveName, cPassWord, lIncludeDirectory ) ---> nNumberOfFiles
    */
    Procedure Test2()
       Local x
       Local nCount1 := 0, nCount2 := 0, status := 0
       Local msg := ""

       x := cGetFile( "Rar Files (*.rar)|*.rar|All files (*.*)|*.*" , "Open archive" , GetCurDir() , "Test.rar" , .T. )
       IF ( ! Empty( x ) )
          nCount1 := Hb_RarGetFilesCount( x, , .T. )
          nCount2 := Hb_RarGetFilesCount( x, , .F. )

          status := Hb_RarGetProcStatus()
          IF ( status == RAR_ST_SUCCESS )
             msg += ( "Archive name " + cTab + ": " + x + CRLF )
             msg += ( "The number of files in archive" + cTab + " : " +  str( nCount2 ) + CRLF )
             msg += ( "number of folders "  + cTab + cTab + " : " +  str( nCount1 - nCount2 ) + CRLF )
             msginfo( msg )
          ELSE
             UnRarErrorInfo( x, status )
          ENDIF
       ENDIF

    Return

    /*
       Test 3:
       --------
       Hb_RarGetFilesCount( ArchiveName, cPassWord, lIncludeDirectory ) ---> nNumberOfFiles
       Hb_RarGetFilesList( ArchiveName, cPassWord, lFileTimeAsDate, lIncludeTime, lIncludeSeconds )
    */
    Procedure Test3()
       Local x
       Local nCount := 0, i := 1
       Local lFileTimeAsDate := .F., lIncludeTime := .T., lIncludeSeconds := .T.
       Local msg := "", OsName := ""
       Local aFiles
       Local status := 0

       x := cGetFile( "Rar Files (*.rar)|*.rar|All files (*.*)|*.*" , "Open archive" , GetCurDir() , "Test.rar" , .T. )
       IF ( ! Empty( x ) )
          nCount = Hb_RarGetFilesCount( x )    

          status := Hb_RarGetProcStatus()
          IF ( status <> RAR_ST_SUCCESS )
             UnRarErrorInfo( x, status )
             RETURN
          ENDIF

          IF nCount > 0    

             aFiles := Hb_RarGetFilesList( x,, lFileTimeAsDate, lIncludeTime, lIncludeSeconds )

             status := Hb_RarGetProcStatus()
             IF ( status <> RAR_ST_SUCCESS )
                UnRarErrorInfo( x, status )
                RETURN
             ENDIF

             FOR i := 1 TO nCount
                msg = ""
                msg += ( "Archive name " + cTab + ": " + aFiles[ i ][ RAR_ARCNAME ] + CRLF )
                msg += ( "File name    " + cTab + ": " + Hb_OemToAnsi( aFiles[ i ][ RAR_FILENAME ] )  + CRLF )
                msg += ( "Packed size, b  " + cTab + ": " + ltrim( transform( aFiles[i][ RAR_PACKSIZE ], "999 999 999" ) ) + CRLF )
                msg += ( "Unpacked size, b" + cTab + ": " + ltrim( transform( aFiles[i][ RAR_UNPSIZE ], "999 999 999" ) ) + CRLF )

                msg += ( "file continued from previous volume " + cTab + ": " + iif( lAnd( aFiles[ i ][ RAR_FLAGS ],  1 ), "yes", "no" ) + CRLF )
                msg += ( "file continued on next volume       " + cTab + ": " + iif( lAnd( aFiles[ i ][ RAR_FLAGS ],  2 ), "yes", "no" ) + CRLF )
                msg += ( "file encrypted with password        " + cTab + ": " + iif( lAnd( aFiles[ i ][ RAR_FLAGS ],  4 ), "yes", "no" ) + CRLF )
                msg += ( "file comment present                " + cTab + ": " + iif( lAnd( aFiles[ i ][ RAR_FLAGS ],  8 ), "yes", "no" ) + CRLF )
                msg += ( "compression of previous files is used (solid flag)" + cTab + ": " + iif( lAnd( aFiles[ i ][ RAR_FLAGS ],  16 ), "yes", "no" ) + CRLF )

                SWITCH aFiles[ i ][ RAR_HOSTOS ]
             CASE 0
                OsName := "MS DOS"
                EXIT
             CASE 1
                OsName := "OS/2"
                EXIT
             CASE 2
                OsName := "Win32"
                EXIT
             CASE 3
                OsName := "Unix"
                EXIT
                END SWITCH

                msg += ( "Host OS      "    + cTab + ": " + OsName       + CRLF )
                msg += ( "File time    "    + cTab + ": " + aFiles[ i ][ RAR_FILETIME ] + CRLF )
    /*
                UnpVer - RAR version needed to extract file.
                It is encoded as 10 * Major version + minor version.
    */
                msg += ( "Unpack version "  + cTab + ": " + str( aFiles[ i ][ RAR_UNPVER ]/10 ) + CRLF )
                msg += ( "File attribute "  + cTab + ": " + aFiles[ i ][ RAR_FILEATTR ] + CRLF )

                MsgInfo( msg, "File Info : " + Hb_OemToAnsi( aFiles[ i ][ RAR_FILENAME ] ) )
             NEXT
          ENDIF
       ENDIF

    Return

    /*
       Test 4:
       -------
       Hb_UnrarFiles( ArchiveName, cPassWord, cOutPath, File )
    */
    Procedure Test4( cOutDir, lAllFiles )
       Local x := cGetFile( "Rar Files (*.rar)|*.rar|All files (*.*)|*.*" , "Open archive" , GetCurDir() , "Test.rar" , .T. )
       Local status := 0

       IF ! Empty( x )
          IF lAllFiles
             Hb_UnrarFiles( x, , cOutDir ) 
          ELSE
             Hb_UnrarFiles( x, , cOutDir, { "eis.ico", "rhs.file", 8 } )   
          ENDIF

          status := Hb_RarGetProcStatus()
          IF ( status <> RAR_ST_SUCCESS )
             UnRarErrorInfo( x, status )
             RETURN
          ENDIF
       ENDIF

    Return

    /*
       Test 5:  get archive comments
       ----------------------------
       Hb_RarSetCmtBufSize( [ nCmtBufSize ] ) ---> lSucces

       nCmtBufSize - contain size of buffer for archive comments ( in bytes ).
       Manimum comment size is 64.
       Maximum comment size is limited to 64Kb ( 65536-1 bytes ).
       Default value is 16384 bytes.

       If the comment text is larger than the buffer size,
          the comment text will be truncated.

          Hb_RarGetCmtBufSize( ) ---> nCmtBufSize
          CmtBufSize is size ( in bytes ) of buffer for archive comments.

          Hb_RarGetComment( ArchiveName, [ @CmtState ] ) ---> cArchiveComments
    */
    Procedure Test5()
       Local x
       Local cmt, CmtState := 0
       Local msg

       Hb_RarSetCmtBufSize( 1024 )

       x := cGetFile( "Rar Files (*.rar)|*.rar|All files (*.*)|*.*" , "Open archive" , GetCurDir() , "Test.rar" , .T. )
       IF ( ! Empty( x ) )

          cmt := Hb_RarGetComment( x, @CmtState )

          SWITCH CmtState
       CASE 1
          msg := cmt
          EXIT
       CASE 0
          msg := "Absent comments"
          EXIT
       CASE ERAR_NO_MEMORY
          msg := "Not enough memory to extract comments"
          EXIT
       CASE ERAR_BAD_DATA
          msg :=  "Broken comment"
          EXIT
       CASE ERAR_UNKNOWN_FORMAT
          msg :=  "Unknown comment format"
          EXIT
       CASE ERAR_SMALL_BUF
          msg := "Buffer too small, comments not completely read"
          EXIT
          END SWITCH
          MsgInfo( msg, iif( CmtState == 1, "Archive comments", "Error" ) )
       ENDIF

       Return

    /*
       Get Unrar.dll API version
       -------------------------
       Hb_RarGetDllVersion( ) ---> nAPIVersion

       Returns an integer value denoting UnRAR.dll API version,
       which is also defined in unrar.h as RAR_DLL_VERSION.
       API version number is incremented only in case of
       noticeable changes in UnRAR.dll API.
       Do not confuse it with version of UnRAR.dll stored in DLL resources,
       which is incremented with every DLL rebuild.

       If Hb_RarGetDllVersion() returns a value lower than UnRAR.dll
       which your application was designed for, it may indicate
       that DLL version is too old and it will fail to provide
       all necessary functions to your application.

        Hb_RarGetDllVersion( ) returns 0 for old versions of UnRAR.dll.
    */
    Procedure Test6()
       Local n := Hb_RarGetDllVersion( )

       IF n > 0
          msginfo ( "UnRar.DLL API Version is " + Ltrim( Str( Hb_RarGetDllVersion( ), 3 ) ) )
       ELSEIF n == 0   
          msginfo ( "Warning: your UnRar.DLL version is too old !!" )
       END

    Return

    /*
    */
    Function lAnd( n1, n2 )
    Return ( AND( n1, n2 ) <> 0 )

    /*
       Hb_RarGetErrorInfo() ---> aUnRarErrorInfo

       Warning:
       Hb_RarGetProcStatus after a call HbRarGetErrorInfo()
       always returns RAR_ST_SUCCESS ;(
    */
    Procedure UnRarErrorInfo( ArchiveName, ErrorStatus )
       Local msg := ""
       Local aUnRarErrorInfo := Hb_RarGetErrorInfo()

       msg += ( ArchiveName + CRLF )
       IF ErrorStatus == RAR_ST_OPEN
          msg += ( "Error Code   " + cTab + " : " + str( aUnRarErrorInfo[ 1 ] ) + CRLF )
          msg += ( "Error Message" + cTab + " : " + aUnRarErrorInfo[ 2 ]        + CRLF )
       ELSEIF ErrorStatus == RAR_ST_OUT 
          msg += ( "Bad   File   " + cTab + " : " + aUnRarErrorInfo[ 5 ]        + CRLF )
          msg += ( "Error Code   " + cTab + " : " + str( aUnRarErrorInfo[ 3 ] ) + CRLF )
          msg += ( "Error Message" + cTab + " : " + aUnRarErrorInfo[ 4 ]        + CRLF )
       ELSEIF ErrorStatus == RAR_ST_OPEN_OUT   
          msg += ( "Error Code   " + cTab + " : " + str( aUnRarErrorInfo[ 1 ] ) + CRLF )
          msg += ( "Error Message" + cTab + " : " + aUnRarErrorInfo[ 2 ]        + CRLF )
          msg += CRLF
          msg += ( "Bad   File   " + cTab + " : " + aUnRarErrorInfo[ 5 ]        + CRLF )
          msg += ( "Error Code   " + cTab + " : " + str( aUnRarErrorInfo[ 3 ] ) + CRLF )
          msg += ( "Error Message" + cTab + " : " + aUnRarErrorInfo[ 4 ]        + CRLF )
       ELSE
          msg += ( "File header broken!" + CRLF )
       ENDIF

       MsgStop( msg, "Error" )

    Return

    /*
    */
    Function HB_RarCallBackFunc( p1, p2, p3, p4 )
    LOCAL result := 0

       IF p1 == UCM_CHANGEVOLUME

          IF p4 == RAR_VOL_NOTIFY
              //oWnd.StatusBar.Item(1) := Hb_OemToAnsi( p3 )
              result := 0

          ELSEIF p4 == RAR_VOL_ASK
             result := GetInput( "Volume", "Can't open", p3 )
             IF result == ""
                result := -1
             ENDIF
          ENDIF

       ELSEIF p1 == UCM_NEEDPASSWORD
             result := GetInput( "", "Password" )

       ENDIF

    Return result

    FUNCTION BuildMenu()
        LOCAL oMenu
        LOCAL oFont
        DEFINE FONT oFont NAME "Arial"  SIZE 0,-12
       
        MENU oMenu FONT oFont
             MENUITEM 'File'
             MENU
                MENUITEM 'Test 0: Testing archive..'    RESOURCE "cascade"      ACTION Test0()
                MENUITEM 'Test 1: Get archive info..'       RESOURCE "cascade"  ACTION Test1()
                MENUITEM 'Test 2: The number of files in archive..' RESOURCE "cascade"  ACTION Test2()
                MENUITEM 'Test 3: Get file info..'      RESOURCE "cascade"      ACTION Test3()
                MENUITEM 'Test 4: Extract all files from archive..' RESOURCE "cascade"  ACTION Test4("out\", .T. )
                MENUITEM 'Test 4: Extract some files from archive..' RESOURCE "cascade" ACTION Test4("out\", .F. )
                MENUITEM 'Test 5: Get archive comments..'   RESOURCE "cascade"      ACTION Test5()
                SEPARATOR                                          
                MENUITEM 'Test 6: Get Unrar.dll API version'    RESOURCE "cascade"  ACTION Test6()
                SEPARATOR
                MENUITEM 'Exit' ACTION oWnd:End()
             ENDMENU
          ENDMENU
         
    Return oMenu     
Muchas gracias.

Saludos
Post Reply