DLL CRC32

groovy

Новичок
Если прикрутить CreateFileW, то ANSI версия компиля не будет понимать эту функу, по крайней мере у меня пока так.
ISCopyFile я так понимаю можно с innocallback.dll прикрутить и к обычному Inno? Где-то я видел реализацию CopyFileEx на голых апи в Inno.
Исходники пересмотрю, пока мало что понял :)
 

Krinkels

Он где то тут
Администратор
Если прикрутить CreateFileW, то ANSI версия компиля не будет понимать эту функу, по крайней мере у меня пока так.
Дык строки перекодировать и дело с концом

ISCopyFile я так понимаю можно с innocallback.dll прикрутить и к обычному Inno?
Изначально так и было, но отдельное спасибо товарищу nik1967, он переписал скрипт на расширенную версию инно
 

groovy

Новичок
Перекодировать в самой dll?
Код:
function GetFileCRC32(const FileName: AnsiString):Cardinal;stdcall;
var
   wName: PWideChar;
begin
   GetMem(wName, (Length(FileName)+1) - SizeOf(WideChar));
  try
    StringToWideChar(FileName, wName, Length(FileName)+1);
    Result := GetFileCRC(wName);
  finally
    FreeMem(wName);
  end;
end;
А смысл? Инсталлятор не в состоянии передать юникодовое имя, вот что в справке Inno написано:
This means it does use Unicode string types as said, but any literal Unicode characters in the script will be converted to ANSI.
Так что все юникодовые имена будут "упрощаться" до ANSI принудительно, и соответственно, посчитать CRC32 на файлах с такими именами, ровно как и определить их, Inno Setup не может.

добавлено
в исходниках ISCopy указано, что библиотека с файлами самостоятельно работает, и ей передаются только параметры путей, далее она сама ищет и формирует список и копирует без участия Inno, т.е. обработку файлов берет на себя.

у меня же dll работает с входящим готовым параметром, который Inno некорректно передает.

p.s. твоя dll тоже не работает с юникод именами в путях, поздравляю :)
положи файлы для копирования из в папку с именем führe и пусть библиотека попробует их скопировать из этой папки, у меня по нулям.

#define PathOut "'d:\führe\*'" /* откуда копируем */
#define PathIn "'C:\123'" /* куда копируем */

но если положить файлы с Unicode именами в папку с обычным именем, например, DATA, то они скопируются.
 
Последнее редактирование:

groovy

Новичок
Изначально либа писалась для русскоговорящих пользователей, и тестировал я её только на русском и английском тексте
ну тогда ко мне тоже не должно быть претензий со стороны пользователей, файлы в основном с английскими именами будут проверяться, да и с русскими дружить будет :)
главное, что длинные пути с префиксом в любом случае понимает, для проверки в циклах можно использовать:
Код:
function ExtendPath(exPath: String): String;
begin
  if Length(exPath) > 259 then
  if Pos('\\?\',exPath) = 0 then
  begin
     exPath := '\\?\' + exPath;
  end;
  Result := exPath;
end;
и, соответственно:

ExtendPath(СТРОКОВАЯ ПЕРЕМЕННАЯ ИЛИ СТРОКА);

При обработке хэндла функции ROPS понимают префикс, а вот в функциях Insert, Delete и по моему Copy (может еще каких) нельзя использовать ExtendPath, потому что в этих функциях обрабатываются строки (с любой длиной), а не хэндлы.

Так что Inno понимает длинные пути для ANSI api с префиксом \\?\ в начале пути, возможно, сам движок конвертирует эти апи в юникодные версии с соответствующей заменой аргументов.

Но если кому надо вариант crc32.dll именно с api CreateFileW, дайте знать, выложу.
 
Последнее редактирование:

El Sanchez

Новичок
Стандартный дельфовский менеджер памяти лучше не использовать.
Это не так.
Да и я не зря советую отказаться от классов. Да, они дают удобство работы, но при этом имеют накладные расходы на инициализацию/разрушение класса.
И это не так.
Как бэ это физическое ограничение ANSI-строк.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
Нет, ANSI-строки ограничены размером допустимой памяти, для 32-разрядных программ (и Inno Setup в том числе) это максимум 2^32-1 байт, а значение MAX_PATH - это максимальный размер передаваемой в ANSI-версию функции ANSI-строки.
Инсталлятор не в состоянии передать юникодовое имя, вот что в справке Inno написано:
This means it does use Unicode string types as said, but any literal Unicode characters in the script will be converted to ANSI.
А еще там сказано, как в строковых литералах Unicode-символы писать. Вам с примером führe немного не повезло, т.к. ü вы попытались правильно передать через Chr($FC), но получили на выходе u без диарезиса, это уже не к разработчикам Inno, а к ROPS. Да и рядомстоящие с ü символы из latin-1 тоже некорректно конвертируются, другие вроде ничего так. Передать führe корректно можно так: MsgBox('fu'#$0308'hre', mbInformation, MB_OK).
Да, сабж без сторонних библиотек:
Код:
[Setup]
AppName=test
AppVerName=test
DefaultDirName={tmp}
CreateAppDir=no
Uninstallable=no
CreateUninstallRegKey=no

[Languages]
Name: ru; MessagesFile: compiler:Languages\russian.isl

[Code]
#define A = (Defined UNICODE) ? "W" : "A"
const
  GENERIC_READ = $80000000;
  FILE_SHARE_READ = $0001;
  OPEN_EXISTING = $0003;
  PAGE_READONLY = $0002;
  FILE_MAP_READ = $0004;
  INVALID_HANDLE_VALUE = (-1);
  HEAP_ZERO_MEMORY = $0008;
  FILE_FLAG_SEQUENTIAL_SCAN = $08000000;

function CreateFile(lpFileName: string; dwDesiredAccess, dwShareMode: DWORD; lpSecurityAttributes: Longint; dwCreationDisposition, dwFlagsAndAttributes: DWORD; hTemplateFile: THandle): THandle; external 'CreateFile{#A}@kernel32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';
function RtlComputeCrc32(dwInitial: DWORD; const pData: Longint; iLen: Integer): DWORD; external 'RtlComputeCrc32@ntdll.dll stdcall';
function ReadFile(hFile: THandle; lpBuffer: Longint; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: Longint): BOOL; external 'ReadFile@kernel32.dll stdcall';
function GetProcessHeap: THandle; external 'GetProcessHeap@kernel32.dll stdcall';
function HeapAlloc(hHeap: THandle; dwFlags, dwBytes: DWORD): Longint; external 'HeapAlloc@kernel32.dll stdcall';
function HeapSize(hHeap: THandle; dwFlags: DWORD; lpMem: Longint): DWORD; external 'HeapSize@kernel32.dll stdcall';
function HeapFree(hHeap: THandle; dwFlags: DWORD; lpMem: Longint): BOOL; external 'HeapFree@kernel32.dll stdcall';

///////////////////////////////////////////////////////
function GetCRC32OfFile(const FileName: string): DWORD;
var
  hFile, hHeap: THandle;
  lpBuffer: Longint;
  dwBufferSize, dwRead: DWORD;
begin
  Result := 0;
  hFile := CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
  if hFile = INVALID_HANDLE_VALUE then Exit;
  try
    hHeap := GetProcessHeap;
    if hHeap = 0 then Exit;
    lpBuffer := HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 32*1024);
    if lpBuffer = 0 then Exit;
    dwBufferSize := HeapSize(hHeap, 0, lpBuffer);
    if dwBufferSize = 0 then Exit;
    while ReadFile(hFile, lpBuffer, dwBufferSize, dwRead, 0) and BOOL(dwRead > 0) do
      Result := RtlComputeCrc32(Result, lpBuffer, dwRead);
  finally
    if hHeap <> 0 then
      HeapFree(hHeap, 0, lpBuffer);
    CloseHandle(hFile);
  end;
end;

///////////////////////////
procedure InitializeWizard;
var
  szFileName: string;
  dwCRC32: DWORD;
begin
  szFileName := ExpandConstant('{sys}\calc.exe');
  dwCRC32 := GetCRC32OfFile(szFileName);
  MsgBox(Format('File: %s'#13'CRC32: %x', [szFileName, dwCRC32]), mbInformation, MB_OK);
end;
 

groovy

Новичок
Да, сабж без сторонних библиотек ...
Круто, не знал о существовании этакой недокументированной функции.
И вообще примерчик знатный, я раньше hex представлял как Chr($31), с использованием # покороче будет :)
Да и выделение памяти под буфер через api в Inno хорошее дело.
 
Сверху