Unicode Inno WriteBuffer

juanpablo

Новичок
Is there any way/trick for writing string into binary data with UNICODE Inno version without using external .dll (crypt32.dll)?

Here's my example, when I compile this with ANSI 5.6.1 Inno everything is ok, but when I compile it with UNICODE version I'm getting unicode style writing (letters with 00 between)
In this example I need $48 $69 hex at specified offset, not $48 $00 $69 $00 but, as I said, I can only get this with ANSI. Is there Unicode way without calling external CryptStringToBinary? :unknown:

Код:
procedure CurStepChanged(CurStep: TSetupStep);
var
  Stream: TFileStream;
begin
  if CurStep = ssPostInstall then
  begin
    Stream := TFileStream.Create(ExpandConstant('{app}\test.exe'), fmOpenReadWrite or fmShareDenyNone);
    try
      Stream.Seek($40000, soFromBeginning);
      #ifdef UNICODE
        Stream.WriteBuffer('Hi',2);
      #else
        Stream.WriteBuffer('Hi',2);
      #endif
    finally
      Stream.Free;
    end;
  end;
end;
 

sergey3695

Ветеран
Модератор
@juanpablo, look this
 

juanpablo

Новичок
Thank you sergey3695, however I'm trying to accomplish this without external programs/dll, only with Inno.
I can use crypt32.dll function with WriteHexToFile procedure and it works...but I'm trying to compile my installer without any dependencies if it is possible.
 

juanpablo

Новичок
I see your point, but I know why I'm trying to do it this way.. I'm building installer for legacy OS and it would be better if I can do it just with Inno.
Anyway...I after reading your post I tested some ideas and found solution. For example, to write $48 $69 to some offset you have to replace Inno version WriteBuffer in my example with
Код:
Stream.WriteBuffer(#$FF6948, 2);
There is no mentioning of this anywhere, at least I could not found any example like this but it works.
 

sergey3695

Ветеран
Модератор
@juanpablo,
code_language.pascal:
function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD; lpWideCharStr: PAnsiChar; cchWideChar: Integer; lpMultiByteStr: PAnsiChar; cbMultiByte: Integer; lpDefaultChar: Integer; lpUsedDefaultChar: Integer): Longint;  external 'WideCharToMultiByte@kernel32.dll stdcall';

function WideStringToString(const wStr: string; codePage: Word): string;
var
  len: Integer;
begin
  len := WideCharToMultiByte(codePage, 0, wStr, -1, '', 0, 0, 0);
  if len > 0 then
    begin
      SetLength(Result, len-1);
      WideCharToMultiByte(codePage, 0, wStr, -1, Result, Length(Result), 0, 0);
    end;
end;

const
  CP_ACP    = 0;             { default to ANSI code page }

function InitializeSetup(): Boolean;
var
  Stream: TFileStream;
begin
    Stream := TFileStream.Create(ExpandConstant('{src}\test.exe'), fmOpenReadWrite or fmShareDenyNone);
    try
      Stream.Seek($40000, soFromBeginning);
      #ifdef UNICODE
        Stream.WriteBuffer(WideStringToString('Hi', CP_ACP),2);
      #else
        Stream.WriteBuffer('Hi',2);
      #endif
    finally
      Stream.Free;
    end;
  Result:= False;
end;
ConvertString.iss
 

juanpablo

Новичок
Fantastic, exactly what I was looking for, can't thank you enough! :clapping:'cause with $#FF.... way it is needed to convert all chars to hex, with your solution I can "process" large strings and WideCharToMultiByte is working in legacy OS :ok:
 
Последнее редактирование:
Сверху