Reputation: 45
Just look at the example below and please help me.
if WriteFile(hDevice, bfile, 512, size, nil) then ShowMessage('Ok');
As above I use the 512, it worked, but with 440 as below, no.
if WriteFile(hDevice, bfile, 440, size, nil) then ShowMessage('Ok');
My question, how can write a file size of 440 or less than 512 byte?
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;
Upvotes: 0
Views: 3909
Reputation: 26356
WriteFile()
takes a pointer to a memory buffer as its second argument.
You are passing it a file handle instead.
Moreover, the destination is not an ordinary file, but a harddisk block device (which might have special limitations).
I assume you want to copy data from a file to some raw location on the block device. Solution: read the data from bfile
into a memory buffer with ReadFile()
, then pass that memory buffer to WriteFile()
to write to hDevice
.
If WriteFile()
still refuses to accept 512 writes, either read the sector from hDevice
, and copy the 440 bytes over the first bytes, or pad the 440 bytes with e.g. zeroes.
Of course, when used incorrectly, this code will mess up the boot sector of your harddisk (if Windows and the BIOS lets you), and since you don't seem to know what you are doing I hope for your sake that you are testing this only on a scratch system.
Upvotes: 0
Reputation: 612993
The documentation for CreateFile
says this:
A volume contains one or more mounted file systems. Volume handles can be opened as noncached at the discretion of the particular file system, even when the noncached option is not specified in CreateFile. You should assume that all Microsoft file systems open volume handles as noncached. The restrictions on noncached I/O for files also apply to volumes.
A file system may or may not require buffer alignment even though the data is noncached. However, if the noncached option is specified when opening a volume, buffer alignment is enforced regardless of the file system on the volume. It is recommended on all file systems that you open volume handles as noncached, and follow the noncached I/O restrictions.
One of the consequences of this is that you must read and write in multiples of the sector size. And all access must be on sector boundaries.
On top of that your code is badly broken at this point:
WriteFile(hDevice, bfile, 440, size, nil);
The second argument should be a pointer to a block of memory that is to be written to hDevice
. You are instead supplying a file handle value. You presumably need to read from a file into a buffer, and then write that to the device.
This code would be a lot easier if you used streams. You can use a TFileStream
to read from a file and THandleStream
for writing to the device.
Upvotes: 2