Link to home
Start Free TrialLog in
Avatar of jlsjls
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)szInternalFileName,
                  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
Avatar of jkr
jkr
Flag of Germany image

>>How should I do this allocation (VirtualAlloc??) and alignement for writing/reading when sectorsize=512?

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_SIZE,MEM_COMMIT,PAGE_READWRITE);
Avatar of jlsjls
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
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_SIZE,MEM_COMMIT,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,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, 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);

Avatar of jlsjls

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)szInternalFileName,
            GENERIC_READ | GENERIC_WRITE,      //read + write
            0,                                    
            NULL,                                    
            OPEN_ALWAYS,                        
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,                  NULL);

dwReturn = SetFilePointer(hHardTotalsFile,0,NULL,FILE_BEGIN);
if (dwReturn == INVALID_SET_FILE_POINTER)
{
...
}

...


pDataWrite = NULL;
pDataWrite = (BYTE*)VirtualAlloc(NULL,lMaxSize,MEM_COMMIT,PAGE_READWRITE);

pDataRead = NULL;
pDataRead = (BYTE*)VirtualAlloc(NULL,lMaxSize,MEM_COMMIT,PAGE_READWRITE);

//read all data from file
memset(pDataRead,0x00,lMaxSize);
bReturn = ReadFile(hHardTotalsFile,pDataRead,lMaxSize,&dwBytesRead,NULL);
if (!bReturn)
{
....
}

//set new data
memset(pDataWrite,0x00,lMaxSize);
memcpy(pDataWrite,pDataRead,lMaxSize);
memcpy(pDataWrite+lOffset,pRawData,dwBytesToWrite);

//write to file
dwBytesWritten = 0;
bReturn = WriteFile(hHardTotalsFile,pDataWrite,lMaxSize,&dwBytesWritten,NULL);
if (!bReturn)
{
...
}
else
{
bReturn = FlushFileBuffers(hHardTotalsFile);
if (!bReturn)
{
...
}
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial