1

I am trying to write some data to an SD card from a specific physical sector. I received a code to do this from a company and they say it works ok on windows-xp. This is the same case with WriteFile error #5 "denied access" under win Vista/seven
Here is the part writing the data to SD card (in my cae drv value is 'F'). Reading from others, I added locking and dismont but the lock fails (and dismount too). I'm not so familiar with windows programming. Can anybody tell me what's wrong in this code? Thanks for any help. (BTW I;m locking 3GiB)

u32 HDD_write(u8 drv, u32 SecAddr, u32 blocks, u8 *buf) 
{
  u32 ret = 0;
  u32 ldistanceLow, ldistanceHigh, dwpointer, bytestoread, numread;
  char cur_drv[100];
  HANDLE g_hDevice;

  sprintf(cur_drv, "\\\\.\\%c:",drv); // , (u32)drv);
  g_hDevice = CreateFile(cur_drv, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

  if(g_hDevice == INVALID_HANDLE_VALUE)
    return 0;

  // lock and dismount
  ret = LockFile(g_hDevice, 0, 0, 3 * 1023 * 1023 * 1023, 0);
  printf("ret = %d", ret);
  DeviceIoControl(g_hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, NULL, NULL);
  printf("error = %d", GetLastError());

  ldistanceLow = SecAddr << 9;
  ldistanceHigh = SecAddr >> (32-9);
  dwpointer = SetFilePointer(g_hDevice, ldistanceLow, (long *)&ldistanceHigh, FILE_BEGIN);

  if(dwpointer != 0xFFFFFFFF) {
    bytestoread = blocks * 512;
    ret = WriteFile(g_hDevice, buf, bytestoread, (unsigned long *)&numread, NULL);
    if(ret)   ret = 1;
    else      {
        ret = 0;
        printf("error = %d", GetLastError());
    }
  }

  CloseHandle(g_hDevice);
  return ret;
}
Community
  • 1
  • 1
Chan Kim
  • 5,177
  • 12
  • 57
  • 112
  • What does `GetLastError()` return when `LockFile()` fails? – Cyclonecode Nov 25 '14 at 08:26
  • Have you tried locking the volume using `DeviceIoControl(g_hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);`? – Cyclonecode Nov 25 '14 at 08:37
  • possible duplicate of [CreateFile: direct write operation to raw disk "Access is denied" - Vista, Win7](http://stackoverflow.com/questions/8694713/createfile-direct-write-operation-to-raw-disk-access-is-denied-vista-win7) – Xearinox Nov 25 '14 at 11:18
  • @Krister Andersson, sorry I didn't see your question. maybe device busy for the lock and access denied for the WriteFile. I also used FSCTL_LOCK_VOLUME later. thanks! – Chan Kim Dec 03 '14 at 11:40

1 Answers1

3

I solved this problem several days ago and forgot to check my question here. This is the code I used. We need GENERIC_READ also for block device when creating the file (for partitioned disk). and the key was dismount first and then lock.

u32 HDD_write(u8 drv, u32 SecAddr, u32 blocks, u8 *buf) {
  u32 ret = 0;
  u32 ldistanceLow, ldistanceHigh, dwpointer, bytestoread, numread;
  char cur_drv[100];
  HANDLE g_hDevice;
  DWORD status;

  //sprintf(cur_drv, "\\\\.\\PhysicalDrive%d", drv);
  sprintf(cur_drv, "\\\\.\\%c:",drv);
  g_hDevice = CreateFile(cur_drv, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

  if(g_hDevice == INVALID_HANDLE_VALUE)
    return 0;

// dismout and lock added by ckim

  if (!DeviceIoControl(g_hDevice, FSCTL_DISMOUNT_VOLUME,
      NULL, 0, NULL, 0, &status, NULL))
  {
      DWORD err = GetLastError();
      printf("Error %d attempting to dismount volume, error code\n",err);
  }

  // lock volume
  if (!DeviceIoControl(g_hDevice, FSCTL_LOCK_VOLUME,
      NULL, 0, NULL, 0, &status, NULL))
  {
      printf("Error %d attempting to lock device\n", GetLastError());
  }

  ldistanceLow = SecAddr << 9;
  ldistanceHigh = SecAddr >> (32-9);
  dwpointer = SetFilePointer(g_hDevice, ldistanceLow, (long *)&ldistanceHigh, FILE_BEGIN);

  if(dwpointer != 0xFFFFFFFF) {
    bytestoread = blocks * 512;
    ret = WriteFile(g_hDevice, buf, bytestoread, (unsigned long *)&numread, NULL);
    if(ret)   ret = 1;
    else      {
        ret = 0;
        printf("error = %d", GetLastError());
    }
  }

  CloseHandle(g_hDevice);
  return ret;
}
Chan Kim
  • 5,177
  • 12
  • 57
  • 112