dosbox_wrapper.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. {$MODE objfpc}{$H+}
  2. uses
  3. SysUtils, StrUtils;
  4. function GenerateTempDir: string;
  5. var
  6. FileName: string;
  7. TempDir: string;
  8. Done: Boolean = False;
  9. begin
  10. TempDir := GetTempDir(False);
  11. repeat
  12. try
  13. FileName := TempDir + 'dosboxwrappertmp_' + IntToStr(Random(100000));
  14. MkDir(FileName);
  15. Done := True;
  16. except
  17. on E: EInOutError do
  18. begin
  19. { 5 = Access Denied, returned when a file is duplicated }
  20. if E.ErrorCode <> 5 then
  21. raise;
  22. end;
  23. end;
  24. until Done;
  25. Result := FileName + DirectorySeparator;
  26. end;
  27. procedure GenerateDosBoxConf(const ADosBoxDir: string);
  28. var
  29. SourceConfFileName, TargetConfFileName: string;
  30. SourceFile, TargetFile: TextFile;
  31. S: string;
  32. begin
  33. SourceConfFileName := ExtractFilePath(ParamStr(0)) + 'dosbox.conf';
  34. TargetConfFileName := ADosBoxDir + 'dosbox.conf';
  35. AssignFile(SourceFile, SourceConfFileName);
  36. AssignFile(TargetFile, TargetConfFileName);
  37. Reset(SourceFile);
  38. try
  39. Rewrite(TargetFile);
  40. try
  41. while not EoF(SourceFile) do
  42. begin
  43. Readln(SourceFile, S);
  44. S := AnsiReplaceStr(S, '$DosBoxDir', ADosBoxDir);
  45. Writeln(TargetFile, S);
  46. end;
  47. finally
  48. CloseFile(TargetFile);
  49. end;
  50. finally
  51. CloseFile(SourceFile);
  52. end;
  53. end;
  54. procedure CopyFile(const ASrcFileName, ADestFileName: string);
  55. var
  56. SrcF, DestF: File;
  57. OldFileMode: Integer;
  58. Buf: array [0..4095] of Byte;
  59. BytesRead: Integer;
  60. begin
  61. OldFileMode := FileMode;
  62. try
  63. AssignFile(SrcF, ASrcFileName);
  64. AssignFile(DestF, ADestFileName);
  65. FileMode := fmOpenRead;
  66. Reset(SrcF, 1);
  67. try
  68. FileMode := fmOpenWrite;
  69. try
  70. Rewrite(DestF, 1);
  71. repeat
  72. BlockRead(SrcF, Buf, SizeOf(Buf), BytesRead);
  73. BlockWrite(DestF, Buf, BytesRead);
  74. until BytesRead < SizeOf(Buf);
  75. finally
  76. CloseFile(DestF);
  77. end;
  78. finally
  79. CloseFile(SrcF);
  80. end;
  81. finally
  82. FileMode := OldFileMode;
  83. end;
  84. end;
  85. function ReadExitCode(const ADosBoxDir: string): Integer;
  86. var
  87. F: TextFile;
  88. begin
  89. AssignFile(F, ADosBoxDir + 'EXITCODE.TXT');
  90. Reset(F);
  91. try
  92. Readln(F, Result);
  93. finally
  94. CloseFile(F);
  95. end;
  96. end;
  97. procedure Cleanup(const ADosBoxDir: string);
  98. procedure DeleteIfExists(const AFileName: string);
  99. begin
  100. if FileExists(AFileName) then
  101. DeleteFile(AFileName);
  102. end;
  103. begin
  104. DeleteIfExists(ADosBoxDir + 'dosbox.conf');
  105. DeleteIfExists(ADosBoxDir + 'EXITCODE.TXT');
  106. DeleteIfExists(ADosBoxDir + 'EXITCODE.EXE');
  107. DeleteIfExists(ADosBoxDir + 'TEST.EXE');
  108. RmDir(ADosBoxDir);
  109. end;
  110. var
  111. DosBoxDir: string;
  112. ExitCode: Integer = 255;
  113. DosBoxBinaryPath: string;
  114. begin
  115. Randomize;
  116. if ParamCount = 0 then
  117. begin
  118. Writeln('Usage: ' + ParamStr(0) + ' <executable>');
  119. halt(1);
  120. end;
  121. DosBoxBinaryPath := GetEnvironmentVariable('DOSBOX');
  122. if DosBoxBinaryPath = '' then
  123. begin
  124. Writeln('Please set the DOSBOX environment variable to the dosbox executable');
  125. halt(1);
  126. end;
  127. DosBoxDir := GenerateTempDir;
  128. try
  129. GenerateDosBoxConf(DosBoxDir);
  130. CopyFile(ExtractFilePath(ParamStr(0)) + 'exitcode.exe', DosBoxDir + 'EXITCODE.EXE');
  131. CopyFile(ParamStr(1), DosBoxDir + 'TEST.EXE');
  132. ExecuteProcess(DosBoxBinaryPath, '-conf ' + DosBoxDir + 'dosbox.conf');
  133. ExitCode := ReadExitCode(DosBoxDir);
  134. finally
  135. Cleanup(DosBoxDir);
  136. end;
  137. halt(ExitCode);
  138. end.