CryptDecode com modificador CRYPT_ARCH_ZIP - Como usar? - página 6

 
Mikalas:

Desembalar os arquivos ZIP padrão!

(por enquanto, apenas com um arquivo embalado no arquivo, mais tarde eu o farei para vários (se necessário) )

Obrigado. Exatamente o que eu precisava! Michael, você se saiu muito bem. Começarei a trabalhar à noite. Mas os comentários da MQ ainda são necessários.
 
O meu não desempacotou, mas deu um erro interno (4024)
 
Mikalas:

Desembalar os arquivos ZIP padrão!

(por enquanto, apenas com um arquivo embalado no arquivo, mais tarde eu o farei para vários (se necessário) )

Anexe o arquivo zip que você descompactou.
 

então ele tem seu próprio arquivo?

e eu estava feliz )

ZS: certamente mesmo que seja só dele, já é ótimo

 
sanyooooook:

Então ele tem seu próprio arquivo?

e eu estava feliz )

ZS: certamente mesmo que seja só dele, já é ótimo

Vou tentar fazer isso hoje.
Arquivos anexados:
GAZR-6_15.zip  1 kb
 

Vasiliy!

É necessário fazer isso ou não?

 
Mikalas:

Vasiliy!

Você tem que fazer isso ou não?

Ainda não. Veremos os comentários da MQ na segunda-feira. Está claro pelo correio de Alexander que é o seu zíper. Outros arquivos que seu código não desembala:

sanyooooooook:
Tive problemas de descompressão causando um erro interno (4024)

s.s. Ao menos o erro é diferente.

Mikalas:

Descomprime arquivos ZIP padrão!

(por enquanto, apenas com um arquivo embalado no arquivo, então eu farei para vários (se necessário) )

Outra pergunta. Que arquivador de zip você usou, e que parâmetros usou (taxa de compressão, tamanho do dicionário).
 
C-4:

Ainda não. Veremos os comentários da MQ na segunda-feira. Está claro pelo correio de Alexander que é o seu zíper. Outros arquivos seu código não descomprime:

s.s. Ao menos o erro é diferente.

Outra pergunta. Que arquivador zip você usou para criar o arquivo, e que parâmetros usou (taxa de compressão, tamanho do dicionário).

WinRar com configurações padrão.

Eu sei como descomprimir todos os arquivos.

Mas é preciso um pouco para descobrir os 4 bytes do empacotador MQ

Se necessário, eu o farei.

MQ pode não responder:)

 

Os últimos 4 bytes no empacotador MQ são hash ou CRC

(informações de serviço).

Mas não está claro se são os dados embalados ou os dados brutos.

Teremos que esperar pela resposta da MQ

 

Nesse meio tempo, é assim:

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

Funções de chamada:

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

Extrai o 2º arquivo (GAZR-6.15.dat) no arquivo. O arquivo é feito pelo WinRar com configurações padrão.

Na função GetFile() posição de parâmetro (1), é necessário para a identificação exata do arquivo em arquivo ZIP.

O arquivo pode conter arquivos com nomes idênticos.

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