Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.12.2016, 12:39   #1
sav.a
 
Регистрация: 20.12.2016
Сообщений: 9
Вопрос Указатель на массив указателей (ExtractKey и EnCryptFileEx)

Ребятки помогите, никогда с указателями не работал. Нужно запихнуть ExtractKey в цикл:
Код:
var  
  err_code: Cardinal;
  Key1, Key2, Key3: array[0..304] of AnsiChar;
  node_To: array[0..n] of PAnsiChar; 
  ReceiverNo: TStringList;
begin
{ 
  заполнение ReceiverNo
}
........
err_code := ExtractKey(PAnsiChar(AnsiString(aBaseE)), PAnsiChar(AnsiString(ReceiverNo[0])),@Key1);
node_To[0] := @Key1

err_code := ExtractKey(PAnsiChar(AnsiString(aBaseE)), PAnsiChar(AnsiString(ReceiverNo[1])),@Key2);
node_To[1] := @Key2;

err_code := ExtractKey(PAnsiChar(AnsiString(aBaseE)), PAnsiChar(AnsiString(ReceiverNo[2])),@Key3);
node_To[2] := @Key3;

дальше node_To попадает в

err_code := EnCryptFileEx(PAnsiChar(AnsiString(vPathOut)),
                          PAnsiChar(AnsiString(vPathOut)),
                          PAnsiChar(AnsiString(myCrypKey)),
                          @node_To,
                          ReceiverNo.Count,
                          0);

end;

Код:
 for i := 0 to ReceiverNo.Count-1 do
   begin
     err_code := ExtractKey(PAnsiChar(AnsiString(aBaseE)),
                            PAnsiChar(AnsiString(ReceiverNo[i])),
                            @Key);

     node_To[i] := @Key;
   end;
но в таком виде шифруется n-раз одним ключом, который в списке последний.

Как записать в память все ключи?



ExtractKey:
Код:
//  Получить открытый ключ из справочника
// base_dir - базовый путь к справочнику открытых ключей
// open_key_ID - идентификатор открытого ключа
// key - указатель на буфер для открытого ключа(240 байт для Вербы версии 4.2 или 304 байта для версии 5.0)
//==============================================================================
function ExtractKey(base_dir,open_key_ID:LPSTR;key:Pointer):T16bit; stdcall; external cDLLFn name 'ExtractKey';
Код:
Считывание открытого ключа из справочника в память
Для считывания открытого ключа из справочника в память служит функция ExtractKey(wbotho,wsigno), прототип которой имеет вид:
T16bit WINAPI ExtractKey (LPSTR base_dir, LPSTR open_key_ID, LPVOID key);
	Параметрами функции являются:
(i) base_dir — указатель на строку пути к каталогу OPENKEY или FAXKEY (файл со справочником LPUB.SPR ищется в подкаталоге: base_dir\OPENKEY\SSSSSS\; файл со справочником LFAX.SPR ищется в подкаталоге: base_dir\FAXKEY\SSSSSS\); 
(i) open_key_ID — указатель на строку с идентификатором ключа.
Идентификатор открытого ключа шифрования должен быть указан в формате XXXXSSSSSS.
Идентификатор открытого ключа подписи должен быть указан в формате XXXXSSSSSSYY.
В данной функции явно не указывается, в справочнике подписи или шифрования хранится открытый ключ, это определяется по идентификатору ключа;
(o) key —указатель на блок памяти размером 304 байт, в который считывается данный открытый ключ (отводится пользователем).
	Пример вызова функции:
open_key_buff=(char*)malloc(304);
err_code=ExtractKey("open_dir", "000199999901", open_key_buff);

EnCryptFileEx
Код:
// file_in   - открытый файл
// file_out  - зашифрованный файл
// From - идентификатор ключа отправителя ("XXXXSSSSSS")
// open_keys_array   - массив указателей на открытые ключи получателей
// open_keys_quantity - количество получателей
//==============================================================================
function EnCryptFileEx(file_in,file_out,From:LPSTR;Open_Key_Array:Pointer;Open_Keys_Quantity:Word;Flags:T32bit):T16bit; stdcall; external cDLLFn name 'EnCryptFileEx';
Код:
Функция EnCryptFileEx(wbotho) служит для зашифрования файлов. Функция не обращается к справочникам открытых ключей, также допускается шифрование между абонентами из различных ключевых серий . Функция имеет следующий прототип:
T16bit WINAPI EnCryptFileEx (char *file_in,
char *file_out,
char * From,
void **open_keys_array,
unsigned short open_keys_quantity,
T32bit	flags);
	Функция имеет параметры:
(i) file_in — указатель на строку полного пути к незашифрованному файлу;
(i) file_out — указатель на строку полного пути к зашифрованному файлу;
Внимание. Размер файла при зашифровании округляется до кратного восьми в большую сторону, а затем увеличивается на (51 + число получателей * 48) байт.
(i) From — указатель на строку с идентификатором ключа отправителя в формате XXXXSSSSSS;
(i) open_keys_array — указатель на массив указателей на открытые ключи получателей;
(i) open_keys_quantity — количество получателей (количество открытых ключей).
(i) flags — зарезервированный параметр.
	Пример вызова функции зашифрования:
…
char	From[11] = “0001910000”;
static	char key1_91[304];
static	char key1_92[304];
void	*open_keys_array[]={key1_91,key1_92};
…
err_code=ExtractKey(CRYPT_SPR,"0001910000",key1_91);
if(err_code) goto error;
err_code=ExtractKey(CRYPT_SPR,"0001920000",key1_92);
if(err_code) goto error;
…
err_code=EnCryptFileEx (“C:\\test.org”,“C:\\test.cry”,From ,open_keys_array, 2,0);
…

Последний раз редактировалось sav.a; 21.12.2016 в 08:20.
sav.a вне форума Ответить с цитированием
Старый 25.12.2016, 12:29   #2
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

С ExtractKey и EnCryptFileEx я не знаком, но рискну предположить, что всё дело в том, что строка
Код:
node_To[i] := @Key;
в цикле бессмысленна ибо @Key - это всегда один и том же адрес.
Нужно как-то так
Код:
type
  TKey = array[0..304] of AnsiChar;
  PKey = ^TKey;

...

var
  Key: PKey;

...

 for i := 0 to ReceiverNo.Count-1 do
   begin
     New(Key);
     err_code := ExtractKey(PAnsiChar(AnsiString(aBaseE)),
                            PAnsiChar(AnsiString(ReceiverNo[i])),
                            Key);

     node_To[i] := Key;
   end;
Ну и не забываем освобождать память.
Sibedir вне форума Ответить с цитированием
Старый 26.12.2016, 07:35   #3
sav.a
 
Регистрация: 20.12.2016
Сообщений: 9
По умолчанию

Вот я Семен Сёменыч, читал же про NEW, но видимо не внимательно.

Да, вот это @Key мне и надо было раскидать по разным адресам.

От души Sibedir!

Достаточно будет освободить память так
Код:
try
....

finally
  Dispose(Key);
end;
или надо отдельно в цикле?

Последний раз редактировалось sav.a; 26.12.2016 в 09:06.
sav.a вне форума Ответить с цитированием
Старый 26.12.2016, 10:39   #4
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

В цикле. Для каждого node_To[i].

Добавлено -------------------------------------------------------------------
Код:
type
  TKey = array [0..303] of Byte; // 304 байта
  TKeyArray = array of TKey;

...

var
  i, err_code: Integer;
  node_To: TKeyArray;

...

  SetLength (node_To, ReceiverNo.Count); // выделяем память под буфер (SizeOf(TKey)*ReceiverNo.Count)

...

  for i := 0 to ReceiverNo.Count-1 do 
    err_code := ExtractKey(PAnsiChar(AnsiString(aBaseE)),
                           PAnsiChar(AnsiString(ReceiverNo[i])),
                           @node_To[i]);

...

  SetLength (node_To, 0); // освобождаем память

Последний раз редактировалось Sibedir; 26.12.2016 в 13:14.
Sibedir вне форума Ответить с цитированием
Старый 26.12.2016, 13:23   #5
sav.a
 
Регистрация: 20.12.2016
Сообщений: 9
По умолчанию

Я тоже решил использовать динамический массив, только допилил его к коду с New.
Благодарю за оптимизированный вариант!

*********************************** *

Второй вариант выдает Access violation at address в

Код:
err_code := EnCryptFileEx(PAnsiChar(AnsiString(vPathOut)),
                          PAnsiChar(AnsiString(vPathOut)),
                          PAnsiChar(AnsiString(myCrypKey)),
                          // node_To - указатель на массив указателей на открытые ключи получателей;
                          @node_To, // <- здесь как правильно надо указать с @ или без или другой вариант?
                          ReceiverNo.Count,
                          0);

Последний раз редактировалось sav.a; 26.12.2016 в 14:25.
sav.a вне форума Ответить с цитированием
Старый 26.12.2016, 17:31   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Переменная динамического массива - это, по сути, уже и есть ссылка на массив.
А еще
Цитата:
open_keys_array — указатель на массив указателей
Код:
type
  TKey = array [0..303] of Byte; // 304 байта
  PKey = ^TKey;
  TKeyArray = array of PKey;

...

var
  i, err_code: Integer;
  node_To: TKeyArray;

...

  // выделяем память под массив указателей
  SetLength (node_To, ReceiverNo.Count);

...

  for i := 0 to ReceiverNo.Count-1 do begin
    New(node_To[i]); // выделяем память под буфер
    if ExtractKey(PAnsiChar(AnsiString(aBaseE)),
                  PAnsiChar(AnsiString(ReceiverNo[i])),
                  @node_To[i]) <> 0 then Error;
    ...
  end;

...

  err_code := EnCryptFileEx(PAnsiChar(AnsiString(vPathOut)),
                            PAnsiChar(AnsiString(vPathOut)),
                            PAnsiChar(AnsiString(myCrypKey)),
                            Pointer(node_To),
                            ReceiverNo.Count,
                            0);

...

  // освобождаем память
  for i := 0 to Length(node_To)-1 do
    FreeMem(node_To[i]);
  SetLength (node_To, 0);
Ну-у-у, должно работать

Добавлено -------------------------------------------------------
Код:
type
  TDynArr = array of Integer;
  TArr = array [0..(MaxInt div SizeOf(Integer)) - 1] of Integer;
  PArr = ^TArr;

procedure TForm1.Button2Click(Sender: TObject);
var
  DA: TDynArr;
  A: PArr;
begin
  SetLength(DA, 5);
  DA[0] := 11;
  DA[1] := 22;
  DA[2] := 33;
  DA[3] := 44;
  DA[4] := 55;
  A := Pointer(DA);
  ShowMessage (IntToStr (A[1]));
end;

Последний раз редактировалось Sibedir; 26.12.2016 в 18:28.
Sibedir вне форума Ответить с цитированием
Старый 27.12.2016, 06:01   #7
sav.a
 
Регистрация: 20.12.2016
Сообщений: 9
По умолчанию

Особой разницы смотрю с первым вариантом незначительные. Вообщем более-менее принцип с указателями понял. Еще раз от души!
sav.a вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Я правильно понимаю, что это указатель на массив указателей на структуры? Кащей Общие вопросы C/C++ 3 14.08.2013 22:32
Указатель на массив указателей Pein95 Общие вопросы C/C++ 12 26.01.2013 17:59
Список указателей(TList). Как 100%-о вернуть не nil, указатель. Человек_Борща Общие вопросы Delphi 16 12.01.2012 11:56
Указатель на массив указателей на массив char'ов... SrgGld Общие вопросы C/C++ 0 19.11.2010 23:35
Указатель на массив указателей, и т.д. Bernarditto Общие вопросы C/C++ 1 09.07.2010 12:26