CryptDecode with modifier CRYPT_ARCH_ZIP - How to use? - ページ 6

 
Mikalas:

標準的なZIPファイルを解凍することができます。

(今は、アーカイブの中の1つのパックされたファイルだけですが、後で、(必要なら)複数のファイルに対して作るつもりです)

ありがとうございます。まさに私が必要としていたものですマイケル、よく頑張ったね。夕方から取りかかります。しかし、MQのコメントはまだ必要です。
 
私のは解凍されず、内部エラー(4024)が発生しました。
 
Mikalas:

標準的なZIPファイルを解凍することができます。

(今は、アーカイブの中の1つのパックされたファイルだけですが、後で、(必要なら)複数のファイルに対して作るつもりです)

解凍したZIPファイルを添付してください。
 

自分のファイルがあるんですね?

と喜んでいたのですが )

ZS: 確かに、自分のものだけでもすごいと思います。

 
sanyooooook:

自分のファイルがあるんですね?

と喜んでいたのですが )

ZS: 確かに、自分のものだけでもすごいと思います。

今日からやってみます。
ファイル:
GAZR-6_15.zip  1 kb
 

バシリー!

これは必要なことなのでしょうか、そうでないのでしょうか。

 
Mikalas:

バシリー!

やらなきゃいけないのか、やらなくていいのか。

まだです。月曜日にMQのコメントを見ることになる。Alexanderの投稿から、ZIP-archiverのせいであることは明らかです。その他のアーカイブは、あなたのコードが解凍されません。

サンユウク
解凍時に内部エラー(4024)が発生するトラブルがありました。

s.s. 少なくともエラーは違う。

ミカラス

標準的なZIPファイルを解凍できる!

(今のところ、アーカイブ内の1つのパックされたファイルのみですが、その後、(必要に応じて)複数のファイルに対して行う予定です)

もうひとつ質問です。使用したZIPアーカイバと、使用したパラメータ(圧縮率、辞書サイズ)を教えてください。
 
C-4:

まだです。月曜日にMQのコメントを見ることになる。Alexanderの投稿から、ZIP-archiverのせいであることは明らかです。その他のアーカイブは、あなたのコードが解凍されません。

s.s. 少なくともエラーは違う。

もうひとつ質問です。アーカイブの作成に使用したZIPアーカイバと、使用したパラメータ(圧縮率、辞書サイズ)を教えてください。

WinRarはデフォルトの設定で。

すべてのアーカイブを解凍する方法を知っています。

しかし、MQパッカーの4バイトを把握するのに少し時間がかかる

必要であれば、やります。

MQは出ないかもしれません:)

 

MQパッカーの最後の4バイトはハッシュまたはCRC

(サービス情報)。

しかし、それがパックされたデータなのか、生データなのかは不明です。

MQの回答を待つ必要があります。

 

一応、こんな感じです。

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

機能を呼び出す

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

アーカイブ内の2番目のファイル(GAZR-6.15.dat)を解凍します。アーカイブはWinRarで標準的な設定で作成されています。

関数 GetFile()のパラメータ位置(1)で、ZIP アーカイブ内のファイルを正確に識別する必要がある。

アーカイブには、同じ名前のファイルが含まれることがあります。

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