我正在创建一个应用程序,它将读取部分(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.
答案 0 :(得分:4)
TResourceStream
不是文件,因此无法在其上调用SetFilePointer()
和ReadFile()
。 TResourceStream
是TStream
的后代。 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.
或者,TResourceStream
是TMemoryStream
的后代,因此您根本不需要字节数组:
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.