[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Assist for sector aligned writing/reading needed

Posted on 2006-05-02
5
Medium Priority
?
962 Views
Last Modified: 2013-12-03
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
0
Comment
Question by:jlsjls
  • 3
  • 2
5 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 16587776
>>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);
0
 
LVL 3

Author Comment

by:jlsjls
ID: 16594126
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
0
 
LVL 86

Expert Comment

by:jkr
ID: 16596407
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);

0
 
LVL 3

Author Comment

by:jlsjls
ID: 16614562
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)
{
...
}
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 16618417
>>I notice that the size after a second write always doubles the size of the file to 64k. How could this happen?

Add a

SetFilePointer(hHardTotalsFile,0,NULL,FILE_BEGIN);

before writing back, otherwise you'll append to the end of the file.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question