WriteFile 失败超过 4700 个块(SD 卡原始写入/Window)

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

我正在 SD 卡上写入/读取原始数据。编写代码的工作量约为。 4700 块并在此限制后失败。这是代码:

   //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);

问题出在函数 "Writefile" (windows.h) 上。如果块数小于 4700。一切正常(数据写入 SD 卡)但如果块数为 5000 或 10000,则函数失败 "Written 0".

请注意,如果没有 FILE_FLAG_NO_BUFFERING,则无法打开驱动器(SD 卡)。 "OVERLAPPED" 是使其工作的失败尝试,不使用它 (WriteFile(hDisk,sessions,2048,&dwWrite,NULL) ) 会导致相同的行为。 "SetFilePointer" 也适用于高于 4700 的块。还测试了 2 种不同的 SD 卡。我在 Windows 10.

关于发生了什么的任何提示?

感谢您的意见

您应该将 Null 作为 SetFilePointerlpDistanceToMoveHigh 的第三个参数传递,除非您使用 64 位地址的高阶 32 位。此外,如果您不使用 OVERLAPPED 结构,请确保将 Null 传递给 WriteFile 作为该参数。

此外,请确保您使用的数据类型没有任何溢出。并且,请注意您正在使用的系统的寻址限制。

MSDN WriteFile
MSDN SetFilePointer

来自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.)

您可以写入前几兆字节,因为(出于历史原因)文件系统不使用 space。为了写入卷的其余部分,您首先必须使用 FSCTL_LOCK_VOLUME control code.

锁定卷