Delphi使用440字节的CreateFile或WriteFile

Delphi使用440字节的CreateFile或WriteFile,delphi,winapi,Delphi,Winapi,看看下面的例子,请帮助我 如果是WriteFile(hDevice,bfile,512,size,nil),那么ShowMessage('Ok') 如上所述,我使用512,它工作,但与440如下,没有 如果是WriteFile(hDevice,bfile,440,size,nil),那么ShowMessage('Ok') 我的问题是,如何编写440字节或小于512字节的文件 hDevice := CreateFile('\\.\PHYSICALDRIVE1', GENERIC_READ or G

看看下面的例子,请帮助我

如果是WriteFile(hDevice,bfile,512,size,nil),那么ShowMessage('Ok')

如上所述,我使用512,它工作,但与440如下,没有

如果是WriteFile(hDevice,bfile,440,size,nil),那么ShowMessage('Ok')

我的问题是,如何编写440字节或小于512字节的文件

hDevice := CreateFile('\\.\PHYSICALDRIVE1', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if hDevice <> INVALID_HANDLE_VALUE then
    begin
      bfile := CreateFile('C:\Users\Administrator\Downloads\bfile', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
      if bfile <> INVALID_HANDLE_VALUE then
        begin
          ShowMessage(IntToStr(getlasterror));
          //SetFilePointer(hDevice,0,nil,FILE_BEGIN); // replace 0 with sector that you wish to read
          if WriteFile(hDevice, bfile, 440, size, nil) then ShowMessage('b');
          ShowMessage(IntToStr(getlasterror));
          CloseHandle(hDevice);
        end;
    end;
hDevice:=CreateFile('\\.\PHYSICALDRIVE1',GENERIC\u READ或GENERIC\u WRITE,FILE\u SHARE\u READ或FILE\u SHARE\u WRITE,nil,OPEN\u EXISTING,FILE\u ATTRIBUTE\u NORMAL,0);
如果hDevice的句柄值无效,则
开始
bfile:=CreateFile('C:\Users\Administrator\Downloads\bfile',GENERIC\u READ或GENERIC\u WRITE,FILE\u SHARE\u READ或FILE\u SHARE\u WRITE,无,OPEN\u EXISTING,FILE\u ATTRIBUTE\u NORMAL,0);
如果文件句柄值无效,则
开始
ShowMessage(IntToStr(getlasterror));
//SetFilePointer(hDevice,0,nil,FILE_BEGIN);//将0替换为要读取的扇区
如果是WriteFile(hDevice,bfile,440,size,nil),那么ShowMessage('b');
ShowMessage(IntToStr(getlasterror));
闭合手柄(hDevice);
结束;
结束;
将指向内存缓冲区的指针作为其第二个参数

您将向其传递一个文件句柄

此外,目标不是普通文件,而是硬盘块设备(可能有特殊限制)

我假设您希望将数据从文件复制到块设备上的某个原始位置。解决方案:使用
ReadFile()
将数据从
bfile
读取到内存缓冲区,然后将该内存缓冲区传递到
WriteFile()
以写入
hDevice

如果
WriteFile()
仍然拒绝接受512次写入,请从
hDevice
读取扇区,并在第一个字节上复制440个字节,或者在440个字节上填充例如零

当然,如果使用不当,此代码会弄乱硬盘的引导扇区(如果Windows和BIOS允许),而且由于您似乎不知道自己在做什么,我希望您只在临时系统上测试此代码。

将指向内存缓冲区的指针作为其第二个参数

您将向其传递一个文件句柄

此外,目标不是普通文件,而是硬盘块设备(可能有特殊限制)

我假设您希望将数据从文件复制到块设备上的某个原始位置。解决方案:使用
ReadFile()
将数据从
bfile
读取到内存缓冲区,然后将该内存缓冲区传递到
WriteFile()
以写入
hDevice

如果
WriteFile()
仍然拒绝接受512次写入,请从
hDevice
读取扇区,并在第一个字节上复制440个字节,或者在440个字节上填充例如零

当然,如果使用不当,此代码会弄乱硬盘的引导扇区(如果Windows和BIOS允许),而且由于您似乎不知道自己在做什么,我希望您只在一个临时系统上测试此代码。

相关文档说明:

卷包含一个或多个已装入的文件系统。卷句柄可以 由特定文件自行决定是否以非缓存方式打开 系统,即使在CreateFile中未指定非缓存选项。 您应该假定所有Microsoft文件系统都打开卷句柄 作为非缓存。对文件的非缓存I/O的限制也适用 到卷

文件系统可能需要也可能不需要缓冲区对齐,即使 数据是非缓存的。但是,如果在 打开卷时,无论文件是什么,都会强制执行缓冲区对齐 卷上的系统。建议您使用的所有文件系统都使用此选项 以非缓存方式打开卷句柄,并遵循非缓存I/O 限制

这样做的后果之一是必须以扇区大小的倍数进行读写。所有访问都必须在扇区边界上

除此之外,您的代码在这一点上被严重破坏:

WriteFile(hDevice, bfile, 440, size, nil);
第二个参数应该是指向要写入
hDevice
的内存块的指针。而是提供一个文件句柄值。您可能需要将文件读入缓冲区,然后将其写入设备

如果您使用streams,这段代码会容易得多。您可以使用
TFileStream
读取文件,使用
THandleStream
写入设备。

相关文档说明:

卷包含一个或多个已装入的文件系统。卷句柄可以 由特定文件自行决定是否以非缓存方式打开 系统,即使在CreateFile中未指定非缓存选项。 您应该假定所有Microsoft文件系统都打开卷句柄 作为非缓存。对文件的非缓存I/O的限制也适用 到卷

文件系统可能需要也可能不需要缓冲区对齐,即使 数据是非缓存的。但是,如果在 打开卷时,无论文件是什么,都会强制执行缓冲区对齐 卷上的系统。建议您使用的所有文件系统都使用此选项 以非缓存方式打开卷句柄,并遵循非缓存I/O 限制

这样做的后果之一是必须以扇区大小的倍数进行读写。所有访问都必须在扇区边界上

除此之外,您的代码在这一点上被严重破坏:

WriteFile(hDevice, bfile, 440, size, nil);
第二个参数应该是指向要写入
hDevice
的内存块的指针。而是提供一个文件句柄值。您可能需要将文件读入缓冲区,然后将其写入设备

如果您使用streams,这段代码会容易得多。您可以使用
TFileStream
读取文件和
THandleStre