Skip to content

Commit

Permalink
Merge pull request #265 from dscho/fix-cygwin-symlinks-in-non-US-locales
Browse files Browse the repository at this point in the history
Teach the installer to create Cygwin symlinks even in non-US locales
  • Loading branch information
dscho authored Nov 5, 2019
2 parents 64aa691 + ec601d9 commit d57b587
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions installer/install.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2368,24 +2368,50 @@ function GetFileAttributes(Path:PAnsiChar):DWORD;
function SetFileAttributes(Path:PAnsiChar;dwFileAttributes:DWORD):BOOL;
external '[email protected] stdcall';
function CryptStringToBinary(sz:string;cch:LongWord;flags:LongWord;binary:string;var size:LongWord;skip:LongWord;flagsused:LongWord):Integer;
external '[email protected] stdcall';
const
CRYPT_STRING_HEX = $04;
HEX_CHARS = '0123456789abcdef';
function CharToHex(C:Integer):string;
begin
Result:=HEX_CHARS[((C div 16) and 15)+1]+HEX_CHARS[(C and 15)+1];
end;
function CreateCygwinSymlink(SymlinkPath,TargetPath:String):Boolean;
var
Attribute:DWord;
i:Integer;
Hex,Buffer:string;
Stream:TStream;
Size:LongWord;
begin
Result:=True;
// assuming that the target is actually all-ASCII, convert to UTF-16
for i:=Length(TargetPath) downto 1 do
TargetPath:=Copy(TargetPath,1,i)+#0+Copy(TargetPath,i+1,Length(TargetPath)-i);
// insert `!<symlink>\xff\xfe` prefix, and append `\0\0`
TargetPath:='!<symlink>'+#255+#254+TargetPath+#0+#0;
Hex:='213c73796d6c696e6b3efffe'; // "!<symlink>\xff\xfe"
for i:=1 to Length(TargetPath) do
Hex:=Hex+CharToHex(Ord(TargetPath[i])); // append wide characters as hex
Hex:=Hex+'0000'; // append a wide NUL
// write the file
if not SaveStringToFile(SymlinkPath,TargetPath,False) then begin
LogError('Could not write "'+SymlinkPath+'"');
Stream:=TFileStream.Create(SymlinkPath,fmCreate);
try
Size:=Length(Hex) div 2;
SetLength(Buffer,Size);
if (CryptStringToBinary(Hex,Length(Hex),CRYPT_STRING_HEX,Buffer,Size,0,0)=0) or (Size<>Length(Hex) div 2) then
RaiseException('could not decode hex '+Hex);
Stream.WriteBuffer(Buffer,Size);
except
LogError('Could not write "'+SymlinkPath+'" '+GetExceptionMessage());
Result:=False;
finally
Stream.Free
end;
// Set system bit (required for Cygwin to interpret this as a symlink)
Expand Down

0 comments on commit d57b587

Please sign in to comment.