|
@@ -0,0 +1,147 @@
|
|
|
|
+{$MODE objfpc}{$H+}
|
|
|
|
+
|
|
|
|
+uses
|
|
|
|
+ SysUtils, StrUtils;
|
|
|
|
+
|
|
|
|
+function GenerateTempDir: string;
|
|
|
|
+var
|
|
|
|
+ FileName: string;
|
|
|
|
+ TempDir: string;
|
|
|
|
+ Done: Boolean = False;
|
|
|
|
+begin
|
|
|
|
+ TempDir := GetTempDir(False);
|
|
|
|
+ repeat
|
|
|
|
+ try
|
|
|
|
+ FileName := TempDir + 'dosboxwrappertmp_' + IntToStr(Random(100000));
|
|
|
|
+ MkDir(FileName);
|
|
|
|
+ Done := True;
|
|
|
|
+ except
|
|
|
|
+ on E: EInOutError do
|
|
|
|
+ begin
|
|
|
|
+ { 5 = Access Denied, returned when a file is duplicated }
|
|
|
|
+ if E.ErrorCode <> 5 then
|
|
|
|
+ raise;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ until Done;
|
|
|
|
+ Result := FileName + DirectorySeparator;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure GenerateDosBoxConf(const ADosBoxDir: string);
|
|
|
|
+var
|
|
|
|
+ SourceConfFileName, TargetConfFileName: string;
|
|
|
|
+ SourceFile, TargetFile: TextFile;
|
|
|
|
+ S: string;
|
|
|
|
+begin
|
|
|
|
+ SourceConfFileName := ExtractFilePath(ParamStr(0)) + 'dosbox.conf';
|
|
|
|
+ TargetConfFileName := ADosBoxDir + 'dosbox.conf';
|
|
|
|
+ AssignFile(SourceFile, SourceConfFileName);
|
|
|
|
+ AssignFile(TargetFile, TargetConfFileName);
|
|
|
|
+ Reset(SourceFile);
|
|
|
|
+ try
|
|
|
|
+ Rewrite(TargetFile);
|
|
|
|
+ try
|
|
|
|
+ while not EoF(SourceFile) do
|
|
|
|
+ begin
|
|
|
|
+ Readln(SourceFile, S);
|
|
|
|
+ S := AnsiReplaceStr(S, '$DosBoxDir', ADosBoxDir);
|
|
|
|
+ Writeln(TargetFile, S);
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ CloseFile(TargetFile);
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ CloseFile(SourceFile);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure CopyFile(const ASrcFileName, ADestFileName: string);
|
|
|
|
+var
|
|
|
|
+ SrcF, DestF: File;
|
|
|
|
+ OldFileMode: Integer;
|
|
|
|
+ Buf: array [0..4095] of Byte;
|
|
|
|
+ BytesRead: Integer;
|
|
|
|
+begin
|
|
|
|
+ OldFileMode := FileMode;
|
|
|
|
+ try
|
|
|
|
+ AssignFile(SrcF, ASrcFileName);
|
|
|
|
+ AssignFile(DestF, ADestFileName);
|
|
|
|
+ FileMode := fmOpenRead;
|
|
|
|
+ Reset(SrcF, 1);
|
|
|
|
+ try
|
|
|
|
+ FileMode := fmOpenWrite;
|
|
|
|
+ try
|
|
|
|
+ Rewrite(DestF, 1);
|
|
|
|
+ repeat
|
|
|
|
+ BlockRead(SrcF, Buf, SizeOf(Buf), BytesRead);
|
|
|
|
+ BlockWrite(DestF, Buf, BytesRead);
|
|
|
|
+ until BytesRead < SizeOf(Buf);
|
|
|
|
+ finally
|
|
|
|
+ CloseFile(DestF);
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ CloseFile(SrcF);
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ FileMode := OldFileMode;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function ReadExitCode(const ADosBoxDir: string): Integer;
|
|
|
|
+var
|
|
|
|
+ F: TextFile;
|
|
|
|
+begin
|
|
|
|
+ AssignFile(F, ADosBoxDir + 'EXITCODE.TXT');
|
|
|
|
+ Reset(F);
|
|
|
|
+ try
|
|
|
|
+ Readln(F, Result);
|
|
|
|
+ finally
|
|
|
|
+ CloseFile(F);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure Cleanup(const ADosBoxDir: string);
|
|
|
|
+
|
|
|
|
+ procedure DeleteIfExists(const AFileName: string);
|
|
|
|
+ begin
|
|
|
|
+ if FileExists(AFileName) then
|
|
|
|
+ DeleteFile(AFileName);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ DeleteIfExists(ADosBoxDir + 'dosbox.conf');
|
|
|
|
+ DeleteIfExists(ADosBoxDir + 'EXITCODE.TXT');
|
|
|
|
+ DeleteIfExists(ADosBoxDir + 'EXITCODE.EXE');
|
|
|
|
+ DeleteIfExists(ADosBoxDir + 'TEST.EXE');
|
|
|
|
+ RmDir(ADosBoxDir);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+var
|
|
|
|
+ DosBoxDir: string;
|
|
|
|
+ ExitCode: Integer = 255;
|
|
|
|
+ DosBoxBinaryPath: string;
|
|
|
|
+begin
|
|
|
|
+ Randomize;
|
|
|
|
+ if ParamCount = 0 then
|
|
|
|
+ begin
|
|
|
|
+ Writeln('Usage: ' + ParamStr(0) + ' <executable>');
|
|
|
|
+ halt(1);
|
|
|
|
+ end;
|
|
|
|
+ DosBoxBinaryPath := GetEnvironmentVariable('DOSBOX');
|
|
|
|
+ if DosBoxBinaryPath = '' then
|
|
|
|
+ begin
|
|
|
|
+ Writeln('Please set the DOSBOX environment variable to the dosbox executable');
|
|
|
|
+ halt(1);
|
|
|
|
+ end;
|
|
|
|
+ DosBoxDir := GenerateTempDir;
|
|
|
|
+ try
|
|
|
|
+ GenerateDosBoxConf(DosBoxDir);
|
|
|
|
+ CopyFile(ExtractFilePath(ParamStr(0)) + 'exitcode.exe', DosBoxDir + 'EXITCODE.EXE');
|
|
|
|
+ CopyFile(ParamStr(1), DosBoxDir + 'TEST.EXE');
|
|
|
|
+ ExecuteProcess(DosBoxBinaryPath, '-conf ' + DosBoxDir + 'dosbox.conf');
|
|
|
|
+ ExitCode := ReadExitCode(DosBoxDir);
|
|
|
|
+ finally
|
|
|
|
+ Cleanup(DosBoxDir);
|
|
|
|
+ end;
|
|
|
|
+ halt(ExitCode);
|
|
|
|
+end.
|