CryptDecode con modificatore CRYPT_ARCH_ZIP - Come usare? - pagina 6

 
Mikalas:

Decomprimere i file ZIP standard!

(per ora, solo con un file impacchettato nell'archivio, più tardi lo farò per diversi (se necessario))

Grazie. Proprio quello di cui avevo bisogno! Michael, sei stato molto bravo. Inizierò a lavorarci in serata. Ma i commenti di MQ sono ancora necessari.
 
Il mio non si è scompattato, ma ha dato un errore interno (4024)
 
Mikalas:

Decomprimere i file ZIP standard!

(per ora, solo con un file impacchettato nell'archivio, più tardi lo farò per diversi (se necessario))

Allega il file zip che hai decompresso.
 

quindi ha il suo file personale?

ed ero felice)

ZS: sicuramente anche se è solo il suo è già grande

 
sanyooooook:

Quindi ha il suo file personale?

ed ero felice)

ZS: sicuramente anche se è solo il suo è già grande

Cercherò di farlo oggi.
File:
GAZR-6_15.zip  1 kb
 

Vasiliy!

È necessario farlo o no?

 
Mikalas:

Vasiliy!

Dovete farlo o no?

Non ancora. Vedremo i commenti di MQ lunedì. È chiaro dal post di Alexander che è il tuo zip-archiver. Altri archivi il tuo codice non si scompatta:

sanyooooook:
Ho avuto problemi a decomprimere causando un errore interno (4024)

s.s. Almeno l'errore è diverso.

Mikalas:

Decomprime i file ZIP standard!

(per ora, solo con un file impacchettato nell'archivio, poi lo farò per diversi (se necessario))

Un'altra domanda. Che archiviatore zip hai usato, e quali parametri hai usato (rapporto di compressione, dimensione del dizionario).
 
C-4:

Non ancora. Vedremo i commenti di MQ lunedì. È chiaro dal post di Alexander che è il tuo zip-archiver. Altri archivi il tuo codice non si decomprime:

s.s. Almeno l'errore è diverso.

Un'altra domanda. Quale archiviatore zip hai usato per creare l'archivio, e quali parametri hai usato (rapporto di compressione, dimensione del dizionario).

WinRar con impostazioni predefinite.

So come decomprimere tutti gli archivi.

Ma ci vuole un po' per capire i 4 byte del packer MQ

Se necessario, lo farò.

MQ potrebbe non rispondere:)

 

Gli ultimi 4 byte nel packer MQ sono hash o CRC

(informazioni di servizio).

Ma non è chiaro se si tratta dei dati confezionati o dei dati grezzi.

Dovremo aspettare la risposta di MQ

 

Nel frattempo, è così:

//+------------------------------------------------------------------+
//|                                                  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 );
}

Funzioni di chiamata:

//+------------------------------------------------------------------+
//|                                                     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);
  }

Estrae il 2° file (GAZR-6.15.dat) nell'archivio. L'archivio è fatto da WinRar con impostazioni standard.

Nella funzione GetFile() la posizione del parametro (1), è necessaria per l'esatta identificazione del file nell'archivio ZIP.

L'archivio può contenere file con nomi identici.

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