如何在delphi 7中将资源作为基数加载?

时间:2018-08-12 15:38:42

标签: delphi delphi-7

我正在创建一个应用程序,它将读取部分(512KB)的嵌入式资源(8MB)并将其写入其中一个物理驱动器,但是当我尝试对其进行编译时,出现错误Incompatible types: 'Cardinal' and 'TResourceStream',现在我试图找出如何将资源作为基数加载而不将其保存为文件或以其他方式工作。甚至有可能吗?

DOS.dpr

program DOS;

uses
  SysUtils,
  Windows,
  ShellAPI,
  Classes;

type
  memory = array [0..524287] of byte;
{$R 'DOS.RES'}

var
  HDD,nr,nw : cardinal;
  MEM       : memory;
  DOS       : TResourceStream;
begin
 DOS := TResourceStream.Create(HInstance, 'DOS', RT_RCDATA);
 SetFilePointer(DOS,0,NIL,FILE_BEGIN);
 ReadFile(DOS,MEM,524288,nr,NIL);
 DOS.Free;

 HDD := CreateFileA('\\.\PhysicalDrive0',GENERIC_ALL,FILE_SHARE_WRITE + FILE_SHARE_READ,NIL,OPEN_EXISTING,0,0);
 SetFilePointer(HDD,0,NIL,FILE_BEGIN);
 WriteFile(HDD,MEM,524288,nw,NIL);
 CloseHandle(HDD);
end.

1 个答案:

答案 0 :(得分:4)

TResourceStream不是文件,因此无法在其上调用SetFilePointer()ReadFile()TResourceStreamTStream的后代。 TStream具有Position属性,以及Read/Buffer()Seek()方法,例如:

program DOS;

uses
  SysUtils, Windows, ShellAPI, Classes;

{$R 'DOS.RES'}

var
  HDD: THandle;
  nr: Integer;
  nw : DWORD;
  mem : array [0..524287] of Byte; // <-- for such large sizes, you should use a dynamic array instead...
  rs : TResourceStream;
begin
  rs := TResourceStream.Create(HInstance, 'DOS', RT_RCDATA);
  try
    rs.Position := 0; // <-- redundant!
    // rs.Seek(0, soBeginning); // <-- this, too
    nr := rs.Read(mem, sizeof(mem));
  finally
    rs.Free;
  end;

  HDD := CreateFile('\\.\PhysicalDrive0', GENERIC_ALL, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  try
    SetFilePointer(HDD, 0, nil, FILE_BEGIN); // <-- redundant!
    WriteFile(HDD, mem, nr, nw, nil);
  finally
    CloseHandle(HDD);
  end;
end.

或者,TResourceStreamTMemoryStream的后代,因此您根本不需要字节数组:

program DOS;

uses
  SysUtils, Windows, ShellAPI, Classes;

{$R 'DOS.RES'}

var
  HDD: THandle;
  nw : DWORD;
  rs : TResourceStream;
begin
  rs := TResourceStream.Create(HInstance, 'DOS', RT_RCDATA);
  try
    HDD := CreateFile('\\.\PhysicalDrive0', GENERIC_ALL, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
    try
      WriteFile(HDD, rs.Memory^, rs.Size, nw, nil);
    finally
      CloseHandle(HDD);
    end;
  finally
    rs.Free;
  end;
end.