CryptDecode avec modificateur CRYPT_ARCH_ZIP - Comment l'utiliser ? - page 6

 
Mikalas:

Décompressez les fichiers ZIP standard !

(pour l'instant, seulement avec un fichier emballé dans l'archive, plus tard je le ferai pour plusieurs (si nécessaire) )

Merci. Juste ce dont j'avais besoin ! Michael, tu as très bien fait. Je vais commencer à travailler sur le sujet dans la soirée. Mais les commentaires de MQ sont toujours nécessaires.
 
Le mien ne s'est pas décompressé, mais a donné une erreur interne (4024).
 
Mikalas:

Décompressez les fichiers ZIP standard !

(pour l'instant, seulement avec un fichier emballé dans l'archive, plus tard je le ferai pour plusieurs (si nécessaire) )

Joignez le fichier zip que vous avez décompressé.
 

Il a donc son propre dossier ?

et j'étais heureux )

ZS : sûrement, même si ce n'est que le sien, c'est déjà génial.

 
sanyooooook:

Il a donc son propre dossier ?

et j'étais heureux )

ZS : sûrement, même si ce n'est que le sien, c'est déjà génial.

Je vais essayer de le faire aujourd'hui.
Dossiers :
GAZR-6_15.zip  1 kb
 

Vasiliy !

Est-il nécessaire de le faire ou non ?

 
Mikalas:

Vasiliy !

Tu es obligé de le faire ou pas ?

Pas encore. Nous verrons les commentaires de MQ lundi. Il est clair d'après le post d'Alexander que c'est votre archiveur de zip. D'autres archives que votre code ne déballe pas :

sanyooooook:
J'ai eu des problèmes de décompression causant une erreur interne (4024)

s.s. Au moins l'erreur est différente.

Mikalas:

Décompresse les fichiers ZIP standard !

(pour l'instant, seulement avec un fichier emballé dans l'archive, ensuite je ferai pour plusieurs (si nécessaire) )

Une autre question. Quel archiveur zip avez-vous utilisé, et quels paramètres avez-vous utilisés (taux de compression, taille du dictionnaire).
 
C-4:

Pas encore. Nous verrons les commentaires de MQ lundi. Il est clair d'après le post d'Alexander que c'est votre archiveur de zip. D'autres archives que votre code ne décompresse pas :

s.s. Au moins l'erreur est différente.

Une autre question. Quel archiveur zip avez-vous utilisé pour créer l'archive, et quels paramètres avez-vous utilisés (taux de compression, taille du dictionnaire).

WinRar avec les paramètres par défaut.

Je sais comment décompresser toutes les archives.

Mais il faut un peu de temps pour comprendre les 4 octets de l'empaqueteur MQ.

Si nécessaire, je le ferai.

MQ ne répondra peut-être pas :)

 

Les 4 derniers octets du packer MQ sont des hashs ou des CRC.

(informations sur le service).

Mais il n'est pas clair s'il s'agit des données emballées ou des données brutes.

Nous devrons attendre la réponse de MQ.

 

En attendant, c'est comme ça :

//+------------------------------------------------------------------+
//|                                                  Zip_decoder.mqh |
//|                                          Copyright 2015, Mikalas |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
struct ZIP_HEADER
{
  uint   sign;
  ushort a_version;
  ushort bit_flag;
  ushort comp_method;
  ushort last_mod_time;
  ushort last_mod_date;
  int    crc_32;
  uint   pack_size;
  uint   unpack_size;
  ushort fn_len;
  ushort extr_field_len;
};
//
ZIP_HEADER zip_header;
bool f_found;
//+------------------------------------------------------------------+
//| Get entryes in ZIP file                                          |
//+------------------------------------------------------------------+
uint GetEntryesZip( const string file_name, string  &f_names[] )
{
  uint a_cnt = 0;
  uchar array[];
  int handle = FileOpen( file_name, FILE_READ | FILE_BIN );
  if ( handle != INVALID_HANDLE )
  {
    ulong file_size = FileSize( handle );
    if ( file_size > 0 ) 
    {
      while ( FileTell( handle ) < file_size - 4 )
      {
        zip_header.sign = FileReadInteger( handle, 4 );
        
        if ( zip_header.sign == 0x04034b50 )
        {
          a_cnt++;  
          ArrayResize( f_names, a_cnt );
          f_names[ a_cnt - 1] = "";  
          FileSeek( handle, -4, SEEK_CUR );
          FileReadStruct( handle, zip_header ); 
          if ( zip_header.extr_field_len != 0 )
          {
            FileSeek( handle, zip_header.extr_field_len, SEEK_CUR );
          }
          ArrayResize( array, int( zip_header.fn_len ) );
          uint fn_res = FileReadArray( handle, array, 0, int( zip_header.fn_len ) );
          for ( int i = 0; i < int( fn_res ); i++ )
          {
            f_names[a_cnt - 1] += CharToString( array[i] );
          }
          FileSeek( handle, zip_header.pack_size, SEEK_CUR );
        }
      }
    }
    FileClose( handle );
  }
  return( a_cnt );
}
bool GetFile( const string src_name, const string dest_name, const int position, uchar &unp_data[] )
{
  uchar array[];
  uchar key[];
  f_found = false;
  int f_cnt = 0;
  int handle = FileOpen( src_name, FILE_READ | FILE_BIN );
  if ( handle != INVALID_HANDLE )
  {
    ulong file_size = FileSize( handle );
    if ( file_size > 0 ) 
    {
      while ( FileTell( handle ) < file_size - 4 )
      {
        zip_header.sign = FileReadInteger( handle, 4 );
        
        if ( zip_header.sign == 0x04034b50 )
        {
          f_cnt++;
          FileSeek( handle, -4, SEEK_CUR );
          FileReadStruct( handle, zip_header ); 
          if ( zip_header.extr_field_len != 0 )
          {
            FileSeek( handle, zip_header.extr_field_len, SEEK_CUR );
          }
          ArrayResize( array, int( zip_header.fn_len ) );
          
          uint fn_res = FileReadArray( handle, array, 0, int( zip_header.fn_len ) );
          
          string file_name = "";
          for ( int i = 0; i < int( fn_res ); i++ )
          {
            file_name += CharToString( array[i] );
          }  
          if ( ( file_name == dest_name ) && ( position == f_cnt - 1 ) )
          {
            f_found = true;
            ArrayResize( array, int( zip_header.pack_size ) + 6 );
            
            uint ar_res = FileReadArray( handle, array, 2, int( zip_header.pack_size ) );  
            if ( ar_res == uint( zip_header.pack_size ) ) 
            {
              array[0] = 0x78;
              array[1] = 0x5E;
              array[int( zip_header.pack_size ) + 2] = 193;  //Wait MQ !!!!!!!!!!!!!!!!!!!!!!!!!
              array[int( zip_header.pack_size ) + 3] = 12;   //Wait MQ !!!!!!!!!!!!!!!!!!!!!!!!
              array[int( zip_header.pack_size ) + 4] = 31;   //Wait MQ !!!!!!!!!!!!!!!!!!!!!!!!!
              array[int( zip_header.pack_size ) + 5] = 159;  //Wait MQ !!!!!!!!!!!!!!!!!!!!!!!!!!!
              ArrayResize( key, int( zip_header.pack_size ) + 6 );
              for ( int j = 0; j < int( zip_header.pack_size ) + 6; j++ ) key[j] = 0;
              ResetLastError();
              int dec_res = CryptDecode( CRYPT_ARCH_ZIP, array, key, unp_data );
              if ( dec_res == int( zip_header.unpack_size ) )
              {
                FileClose( handle );
                return( true );
              }
              else
              {
                Print( " Ошибка распаковки = ", GetLastError() );
                FileClose( handle );
                return( false );
              }
            } 
            break;
          }
          if ( f_found ) break;  
          FileSeek( handle, zip_header.pack_size, SEEK_CUR );
        }
      }
    }
    FileClose( handle );
  }
  return( false );
}

Fonctions d'appel:

//+------------------------------------------------------------------+
//|                                                     Zip_test.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//
#include "Zip_decoder.mqh";
//
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   string file_name = "Files.zip";
   string file_names[];
   uchar result[];
   uint files_tot = GetEntryesZip( file_name, file_names );
   if ( GetFile( file_name, file_names[1], 1, result ) )
   {
     Print( "Файл распакован. Имя файла = ", file_names[1] );
   }
//---
   return(INIT_SUCCEEDED);
  }

Extrait le 2ème fichier (GAZR-6.15.dat) de l'archive. L'archive est créée par WinRar avec des paramètres standard.

Dans la fonction GetFile(), la position du paramètre (1) est nécessaire pour l'identification exacte du fichier dans l'archive ZIP.

L'archive peut contenir des fichiers avec des noms identiques.

2015.03.29 21:38:05.553 Zip_test (GAZR-6.15,M1) Файл распакован. Имя файла = GAZR-6.15.dat
Dossiers :
Files.zip  1 kb