Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Как узнать установлен на архиве пароль?


Автор: Eleet 9.5.2005, 01:08
Необходимо узнать стоит ли на архиве пароль при обращении к архиву из приложения, если стоит, то необходимо выводить окно запроса пароля. Работа с архивом производится через консоль,поэтому перехват функций Windows не очень подходит.

Автор: Alex 9.5.2005, 09:36
Перенесено из раздела Дельфи

Автор: Eleet 10.5.2005, 00:00
Поясняю : Архив WinRAR, распаковщик используется этот же, т.е. работа идёт с самим WinRar'ом только из командной строки, вопросы по поводу установлен ли сам WinRar уже решены, теперь стоит вопрос как узнать стоит ли на данном архиве пароль?

Автор: kucik 10.5.2005, 01:29
Немножко поправлю Eleet'a:
Используется архиватор WinRAR, а точнее его консольная версия .. модуль Rar.exe
Значится при помощи обращения к этому файлику с определёнными параметрами можно добится архивации и разархивации!
Нужно определить защищён ли архив паролем, так как при разархивации (если на архиве стоит пароль а мы его не вводим) происходит простой:
Привожу код запуска RAR'a (обрезан):
Код

...
 // Запускаем приложение 
  Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false,
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                          PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);  
    // Ожидаем завершения приложения ... а оно ждёт пока мы введём пароль :)
  if Result then  
    begin
      WaitForSingleObject(ProcInfo.hProcess, INFINITE);
      CloseHandle(ProcInfo.hProcess);
      CloseHandle(ProcInfo.hThread);
    end;
...

Поэтому надо как то обратится к архиву (непосредственно до архивации) и узнать стоит ли на архиве пароль, чтобы как только пользователь выбрал архив ... его любезно попросили ввести пароль!

Я думаю понятно изложил проблему!
Спасибо за ответы!!!

Автор: Alex 10.5.2005, 02:33
Плохо товарищи читаете замечательный файл Rar.txt, а в нем описан замечательный параметр:
Цитата
-p-    Не спрашивать пароль.

А еще в нем описаны коды возврата:
Цитата
Коды возврата
~~~~~~~~~~~~~

    В случае успешного завершения операции RAR выходит с нулевым (0) кодом
    возврата. Если операция прервана из-за ошибки, то код возврата будет
    ненулевым. (Коды возврата можно, например, использовать в пакетных
    файлах с помощью переменной ERRORLEVEL.)

    255  ПРЕРВАНО        Операция была прервана пользователем.
          ПОЛЬЗОВАТЕЛЕМ

      9  ОШИБКА СОЗДАНИЯ  Ошибка при создании файла

      8  ОШИБКА ПАМЯТИ    Недостаточно памяти для выполнения операции.

      7  ОШИБКА          Ошибка при указании команды/параметра в
          ПОЛЬЗОВАТЕЛЯ    командной строке.

      6  ОШИБКА ОТКРЫТИЯ  Произошла ошибка открытия файла.

      5  ОШИБКА ЗАПИСИ    Произошла ошибка записи на диск.

      4  ЗАБЛОКИРОВАННЫЙ  Попытка изменения архива, заблокированного
          АРХИВ            ранее командой 'k' или ключом '-k'.

      3  ОШИБКА CRC      Во время распаковки обнаружена ошибка CRC.

      2  ФАТАЛЬНАЯ        Произошла критическая ошибка.
          ОШИБКА

      1  ПРЕДУПРЕЖДЕНИЕ  Произошла некритическая ошибка.

      0  УСПЕШНОЕ        Работа завершена без ошибок.
          ЗАВЕРШЕНИЕ

И если вы попытаетесь обратиться к файлу, защищенному паролем с ключом -p-, то вам вернут код возврата 3. Дальше я думаю, объяснять не стоит.

PS:
Если решили работать с rar через консоль, то Rar.txt должен стать вашей настольной книгой.

Автор: kucik 10.5.2005, 16:18
Пасибо Alex!
Насчёт кода возврата не подумал smile а про параметр /p- знаю ...
Только где его ловить этот код возврата? Выполнение этой строчки нам даёт логическое значение
Код

  Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false,
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                          PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);  

т.е. если приложение завершилось, значит Result = True иначе False ...

Автор: Alex 10.5.2005, 16:52
http://vingrad.ru/DELPHI-DLP-000765

Автор: kucik 10.5.2005, 20:31
Спасибо Alex! smile
Вот то, что вышло у меня smile :
Код

...   ...   ...
Function ExecAndWait(const FileName, Params: String; const WinState: Word; Var ExitCode: DWORD): boolean;
                                          // FileName = Имя внешней программы.
                                          // Params = Параметры, необходимые для запуска внешней программы
                                          // WinState = Указывает - как будет показано окно:
                                          //            SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_SHOWNORMAL
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: String;
begin
    // Помещаем имя файла между кавычками, с соблюдением всех пробелов в именах
  CmdLine := '"' + Filename + '" ' + Params;
  FillChar(StartInfo, SizeOf(StartInfo), #0);
  ZeroMemory(@StartInfo, sizeof(StartInfo));
  with StartInfo do
    begin
      cb := SizeOf(StartInfo);
      dwFlags := STARTF_USESHOWWINDOW;
      wShowWindow := WinState;
    end;
  Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false,
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                          PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);
    // Ожидаем завершения приложения
  if Result then
    begin
      while WaitforSingleObject(ProcInfo.hProcess,200)=WAIT_TIMEOUT do
        Application.ProcessMessages;
    // Получаем код возврата
      GetExitCodeProcess(ProcInfo.hProcess, ExitCode);
          //Free the Handles
      CloseHandle(ProcInfo.hProcess);
      CloseHandle(ProcInfo.hThread);
    end;
end;


Вызываю следующим образом (напишу, дабы у других вопросов не возникло):
Код

...
Var
  ErrCode : DWord;
...
  If ExecAndWait(RarPath, CmdLine, SW_SHOWNORMAL, ErrCode) = False then
    begin
      // Здёсь код, выполняемый при отсутствии запускаемой программы или подобной ошибке
      // (Программа не выполнилась)
    end
  else
    begin
      // Если программа выполнилась, то выполняется всё что здесь
      If ErrCode <= 0 then
        begin
          // Если код возврата <= 0 (т.е. в процессе выполнения сторонней программы ошибок не возникло), то
          // что-то делаем ...
        end
      else
        Case ErrCode of
          1  : begin
                end;
          ... : ... ... ...
        end;
    end;
...

Вопрос исчерпан!
Всё вроде работает!

Только остаётся вопрос по консоли RAR'a ... Как сделать так, чтобы не извлекая из архива его содержимое определить стоит ли пароль или нет? Так как если применить команду
Цитата
Rar.exe e -p- c:\abc.rar

то если на архиве не стоит пароль, то содержимое архива будет извлеченно!

Автор: kucik 11.5.2005, 00:13
Возник ещё один вопросик ...
В RAR'e есть такой ключик -ierr - перенаправление всех сообщений на стандартное устройство ошибки.
Как принять все эти сообщения?
Прочитал эту тему http://forum.vingrad.ru/index.php?showtopic=25023&unread=1&hl=stderr, но моя проблемма немного в другом (на мой взгляд), т.к. в моём случае информация уже выводится на стандартное устройство ошибки!?
Попробовал такой вариант:
Код

...
  if Result then
    begin
      Line := '';
      REPEAT
        Result := ReadFile(StartInfo.hStdError, Buffer, 255, BytesRead, nil);
        if BytesRead > 0 then
          begin
              // завершаем буфер PChar-ом
            Buffer[BytesRead] := #0;
              // добавляем буфер в общий вывод
            Line := Line + Buffer;
          end;
      UNTIL NOT Result or (BytesRead = 0);

      while WaitforSingleObject(ProcInfo.hProcess,200)=WAIT_TIMEOUT do
        Application.ProcessMessages;
...

... он не проходит, BytesRead всегда 0 smile
Alex Help Please!!!
Thanks!

Автор: Alex 11.5.2005, 16:09
Модератор: Пожалуйста, один топик - один вопрос. Тема закрыта.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)