Search code examples
c++windowswinapisd-cardwritefile

WriteFile fails for > 4700 blocks (SD card raw write / Window)


I am writing / reading raw data on a SD card. The code for writing is working up to approx. 4700 blocks and fails after this limit. Here is the code:

   //Data to be written
   uint8_t* sessions;
   sessions = (uint8_t *) malloc(2048*sizeof(uint8_t));
   unsigned int i;
   for(i=0;i<(2048*sizeof(uint8_t));i++) sessions[i]=8;

   DWORD dwWrite;

   HANDLE hDisk=CreateFileA("\\\\.\\K:",  // drive to open = SD CARD
            GENERIC_WRITE,                // access to the drive
            FILE_SHARE_READ | // share mode
            FILE_SHARE_WRITE,
            NULL,             // default security attributes
            OPEN_EXISTING,    // disposition
            FILE_FLAG_NO_BUFFERING,               // file attributes
            NULL);            // do not copy file attributes


   if(hDisk==INVALID_HANDLE_VALUE) 
   {
      CloseHandle(hDisk);
      printf("ERROR opening the file !!! ");
   }

   DWORD dwPtr = SetFilePointer(hDisk,10000*512,0,FILE_BEGIN); //4700 OK 

   if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
   {
     printf("CANNOT move the file pointer !!! ");
   }

   //Try using this structure but same results: CAN BE IGNORED
   OVERLAPPED osWrite      = {0,0,0};
   memset(&osWrite, 0, sizeof(osWrite));
   osWrite.Offset = 10000*512;                //4700 OK
   osWrite.hEvent = CreateEvent(FALSE, FALSE, FALSE, FALSE);

   if( FALSE ==  WriteFile(hDisk,sessions,2048,&dwWrite,&osWrite) ){
       printf("CANNOT write data to the SD card!!! %lu",dwWrite);
   }else{
       printf("Written %lu on SD card",dwWrite);
   }

   CloseHandle(hDisk);

The issue is with the function "Writefile" (windows.h). If the number of block is less than 4700. everything is fine (data are written on the SD card) but if the block number is let's say 5000 or 10000, the function fails "Written 0".

Notice that without FILE_FLAG_NO_BUFFERING, no way to open the drive (SD card). The "OVERLAPPED" is a failed attempt to make it works, not using it (WriteFile(hDisk,sessions,2048,&dwWrite,NULL) )leads to the same behaviour. "SetFilePointer" works also for blocks higher than 4700. Have tested as well 2 different SD cards. I am on Windows 10.

Any hint as to what is happening?

Thank you for your input


Solution

  • From the documentation for WriteFile:

    A write on a volume handle will succeed if the volume does not have a mounted file system, or if one of the following conditions is true:

    • The sectors to be written to are boot sectors.

    • The sectors to be written to reside outside of file system space.

    • You have explicitly locked or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.

    • The volume has no actual file system. (In other words, it has a RAW file system mounted.)

    You are able to write to the first couple of megabytes because (for historical reasons) the file system doesn't use that space. In order to write to the rest of the volume, you'll first have to lock the volume using the FSCTL_LOCK_VOLUME control code.