Re: read data from a disk
bob@coolgroups.com wrote:
This works:
hDevice = CreateFile("\\\\.\\A:",
GENERIC_READ, // no access to the
FILE_SHARE_READ ,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
char inBuffer[65536];
bResult = ReadFile(hDevice, inBuffer, 65536, &nBytesRead, NULL);
Interestingly, if I change the buffer size to 1000, nBytesRead is 0.
Anyone know what's up with that?
Probably has to do with sector alignment and device-specific restrictions.
See the notes in the documentation for CreateFile that pertain to physical
devices.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfile.asp
In particular:
<quote>
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.
</quote>
and, in the same topic, the documentation for FILE_FLAG_NO_BUFFERING (which
you should be using) says:
<quote>
The system opens a file with no system caching. This flag does not affect
hard disk caching. When combined with FILE_FLAG_OVERLAPPED, the flag gives
maximum asynchronous performance, because the I/O does not rely on the
synchronous operations of the memory manager. However, some I/O operations
take more time, because data is not being held in the cache. Also, the file
metadata may still be cached. To flush the metadata to disk, use the
FlushFileBuffers function.
An application must meet certain requirements when working with files that
are opened with FILE_FLAG_NO_BUFFERING:
* File access must begin at byte offsets within a file that are integer
multiples of the volume sector size.
* File access must be for numbers of bytes that are integer multiples of the
volume sector size. For example, if the sector size is 512 bytes, an
application can request reads and writes of 512, 1024, 1536, or 2048 bytes,
but not of 335, 981, or 7171 bytes.
* Buffer addresses for read and write operations should be sector aligned,
which means aligned on addresses in memory that are integer multiples of the
volume sector size. Depending on the disk, this requirement may not be
enforced.
One way to align buffers on integer multiples of the volume sector size is
to use VirtualAlloc to allocate the buffers. It allocates memory that is
aligned on addresses that are integer multiples of the operating system's
memory page size. Because both memory page and volume sector sizes are
powers of 2, this memory is also aligned on addresses that are integer
multiples of a volume sector size. Memory pages are 4-8 KB in size; sectors
are 512 bytes (hard disks) or 2048 bytes (CD), and therefore, volume sectors
can never be larger than memory pages.
An application can determine a volume sector size by calling the
GetDiskFreeSpace function.
</quote>
Read the CreateFile documentation carefully and fully - there's a lot of
subtle information in that topic.
-cd