jlsjls
asked on
Assist for sector aligned writing/reading needed
Hi,
I would like to receive some assistance (pls. code) on how to write/read on sector boundaries.
I need to create file without caching -> FILE_FLAG_NO_BUFFERING
hHardTotalsFile = CreateFile((LPCTSTR)szInte rnalFileNa me,
GENERIC_READ | GENERIC_WRITE, //read + write
0, //no sharing
NULL, //default security
OPEN_ALWAYS, //Opens a file, always.
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
NULL);
MSDN states :
" 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."
How should I do this allocation (VirtualAlloc??) and alignement for writing/reading when sectorsize=512?
Thanks in advance.
jlsjls
I would like to receive some assistance (pls. code) on how to write/read on sector boundaries.
I need to create file without caching -> FILE_FLAG_NO_BUFFERING
hHardTotalsFile = CreateFile((LPCTSTR)szInte
GENERIC_READ | GENERIC_WRITE, //read + write
0, //no sharing
NULL, //default security
OPEN_ALWAYS, //Opens a file, always.
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
NULL);
MSDN states :
" 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."
How should I do this allocation (VirtualAlloc??) and alignement for writing/reading when sectorsize=512?
Thanks in advance.
jlsjls
ASKER
Can you also assist me in how to align data.
I don't really understand the example given by MS (see below).
I suppose I need to provide a loop when my data to be written > SECTOR_SIZE
Can you explain me what happen in this code (second line??).
Microsoft gives following example :
char buf[2 * SECTOR_SIZE - 1], *p;
p = (char *) ((DWORD) (buf + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1));
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
WriteFile(h, p, SECTOR_SIZE, &dwWritten, NULL);
thx
jlsjls
I don't really understand the example given by MS (see below).
I suppose I need to provide a loop when my data to be written > SECTOR_SIZE
Can you explain me what happen in this code (second line??).
Microsoft gives following example :
char buf[2 * SECTOR_SIZE - 1], *p;
p = (char *) ((DWORD) (buf + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1));
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
WriteFile(h, p, SECTOR_SIZE, &dwWritten, NULL);
thx
jlsjls
Well, this example allocates data differently and is quite unrelated - it is way easier to use 'VirtualAlloc()', since that does not require the acrobatics they're using (allocating a buffer twice as much as the sector size and so on). That can be rewritten as
BYTE* p = VirtualAlloc(NULL,SECTOR_S IZE,MEM_CO MMIT,PAGE_ READWRITE) ;
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
WriteFile(h, p, SECTOR_SIZE, &dwWritten, NULL);
If you have a bigger buffer, you could just
BYTE* p = VirtualAlloc(NULL,10 * SECTOR_SIZE,MEM_COMMIT,PAG E_READWRIT E);
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
WriteFile(h, p, 10 * SECTOR_SIZE, &dwWritten, NULL);
or
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
for ( int i = 0; i < 10; ++i) WriteFile(h, p + i * SECTOR_SIZE, SECTOR_SIZE, &dwWritten, NULL);
BYTE* p = VirtualAlloc(NULL,SECTOR_S
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
WriteFile(h, p, SECTOR_SIZE, &dwWritten, NULL);
If you have a bigger buffer, you could just
BYTE* p = VirtualAlloc(NULL,10 * SECTOR_SIZE,MEM_COMMIT,PAG
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
WriteFile(h, p, 10 * SECTOR_SIZE, &dwWritten, NULL);
or
h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
for ( int i = 0; i < 10; ++i) WriteFile(h, p + i * SECTOR_SIZE, SECTOR_SIZE, &dwWritten, NULL);
ASKER
I'm trying to read the content of a file (created with FILE_FLAG_NO_BUFFERING).
Then update the content and write the new content to the file.
This size of the file is fixed (=32k).
I notice that the size after a second write always doubles the size of the file to 64k. How could this happen? What is wrong here?
No errors received during reading/writing.
Everything is aligned to sectorsize (512) -> allocation of 32k (32768 = 64*512)
hHardTotalsFile = INVALID_HANDLE_VALUE;
hHardTotalsFile = CreateFile((LPCTSTR)szInte rnalFileNa me,
GENERIC_READ | GENERIC_WRITE, //read + write
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
dwReturn = SetFilePointer(hHardTotals File,0,NUL L,FILE_BEG IN);
if (dwReturn == INVALID_SET_FILE_POINTER)
{
...
}
...
pDataWrite = NULL;
pDataWrite = (BYTE*)VirtualAlloc(NULL,l MaxSize,ME M_COMMIT,P AGE_READWR ITE);
pDataRead = NULL;
pDataRead = (BYTE*)VirtualAlloc(NULL,l MaxSize,ME M_COMMIT,P AGE_READWR ITE);
//read all data from file
memset(pDataRead,0x00,lMax Size);
bReturn = ReadFile(hHardTotalsFile,p DataRead,l MaxSize,&d wBytesRead ,NULL);
if (!bReturn)
{
....
}
//set new data
memset(pDataWrite,0x00,lMa xSize);
memcpy(pDataWrite,pDataRea d,lMaxSize );
memcpy(pDataWrite+lOffset, pRawData,d wBytesToWr ite);
//write to file
dwBytesWritten = 0;
bReturn = WriteFile(hHardTotalsFile, pDataWrite ,lMaxSize, &dwBytesWr itten,NULL );
if (!bReturn)
{
...
}
else
{
bReturn = FlushFileBuffers(hHardTota lsFile);
if (!bReturn)
{
...
}
Then update the content and write the new content to the file.
This size of the file is fixed (=32k).
I notice that the size after a second write always doubles the size of the file to 64k. How could this happen? What is wrong here?
No errors received during reading/writing.
Everything is aligned to sectorsize (512) -> allocation of 32k (32768 = 64*512)
hHardTotalsFile = INVALID_HANDLE_VALUE;
hHardTotalsFile = CreateFile((LPCTSTR)szInte
GENERIC_READ | GENERIC_WRITE, //read + write
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
dwReturn = SetFilePointer(hHardTotals
if (dwReturn == INVALID_SET_FILE_POINTER)
{
...
}
...
pDataWrite = NULL;
pDataWrite = (BYTE*)VirtualAlloc(NULL,l
pDataRead = NULL;
pDataRead = (BYTE*)VirtualAlloc(NULL,l
//read all data from file
memset(pDataRead,0x00,lMax
bReturn = ReadFile(hHardTotalsFile,p
if (!bReturn)
{
....
}
//set new data
memset(pDataWrite,0x00,lMa
memcpy(pDataWrite,pDataRea
memcpy(pDataWrite+lOffset,
//write to file
dwBytesWritten = 0;
bReturn = WriteFile(hHardTotalsFile,
if (!bReturn)
{
...
}
else
{
bReturn = FlushFileBuffers(hHardTota
if (!bReturn)
{
...
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Yes, exactly, 'VirtualAlloc()'will align that automatically to a page boundary, which on x86 systems is aligned to 2048 (and thus implicitly to 512), e.g.
BYTE pBuf = VirtualAlloc(NULL,BUFFER_S