CryptDecode con modificador CRYPT_ARCH_ZIP - ¿Cómo utilizarlo? - página 6

 
Mikalas:

Descomprimir archivos ZIP estándar

(por ahora, sólo con un archivo empaquetado en el archivo, más adelante lo haré para varios (si es necesario) )

Gracias. Justo lo que necesitaba. Michael, lo has hecho muy bien. Empezaré a trabajar por la noche. Pero los comentarios de MQ siguen siendo necesarios.
 
El mío no se descomprimió, sino que dio un error interno (4024)
 
Mikalas:

Descomprimir archivos ZIP estándar

(por ahora, sólo con un archivo empaquetado en el archivo, más adelante lo haré para varios (si es necesario) )

Adjunta el archivo zip que has descomprimido.
 

¿Así que tiene su propio archivo?

y yo era feliz )

ZS: seguramente aunque sólo sea el suyo ya es grande

 
sanyooooook:

¿Así que tiene su propio archivo?

y yo era feliz )

ZS: seguramente aunque sólo sea el suyo ya es grande

Intentaré hacerlo hoy.
Archivos adjuntos:
GAZR-6_15.zip  1 kb
 

¡Vasiliy!

¿Es necesario hacerlo o no?

 
Mikalas:

¡Vasiliy!

¿Hay que hacerlo o no?

Todavía no. Veremos los comentarios de MQ el lunes. Por el post de Alexander está claro que es tu archivador de zip. Otros archivos su código no se descompone:

sanyooooook:
Tuve problemas para descomprimir causando un error interno (4024)

s.s. Al menos el error es diferente.

Mikalas:

Descomprime archivos ZIP estándar.

(por ahora, sólo con un archivo empaquetado en el archivo, luego lo haré para varios (si es necesario) )

Otra pregunta. Qué archivador zip utilizó y qué parámetros utilizó (relación de compresión, tamaño del diccionario).
 
C-4:

Todavía no. Veremos los comentarios de MQ el lunes. Por el post de Alexander está claro que es tu archivador de zip. Otros archivos su código no se descomprime:

s.s. Al menos el error es diferente.

Otra pregunta. Qué archivador zip utilizó para crear el archivo y qué parámetros utilizó (relación de compresión, tamaño del diccionario).

WinRar con la configuración por defecto.

Sé cómo descomprimir todos los archivos.

Pero se necesita un poco para averiguar los 4 bytes del empaquetador MQ

Si es necesario, lo haré.

Puede que MQ no responda:)

 

Los últimos 4 bytes del paquete MQ son hash o CRC

(información de servicio).

Pero no está claro si se trata de los datos empaquetados o de los datos brutos.

Habrá que esperar la respuesta de MQ

 

Mientras tanto, es así:

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

Funciones de llamada:

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

Extrae el segundo fichero (GAZR-6.15.dat) del archivo. El archivo está hecho por WinRar con la configuración estándar.

En la función GetFile() la posición del parámetro (1), es necesaria para la identificación exacta del fichero en el archivo ZIP.

El archivo puede contener ficheros con nombres idénticos.

2015.03.29 21:38:05.553 Zip_test (GAZR-6.15,M1) Файл распакован. Имя файла = GAZR-6.15.dat
Archivos adjuntos:
Files.zip  1 kb
Razón de la queja: