C# WriteFile() Stops Writing at Sector 242 on USB Drives

There is a confusion between disk and drive here.

If you want full access to a disk (which is your case as you're using \\.\PHYSICALDRIVE), you must lock all mounted volumes, which are basically all partitions (i.e. drives) of your physical disk.

Instead of using FSCTL_LOCK_VOLUME on the handle returned by CreateFile("\\.\PHYSICALDRIVE"...), get a handle to each mounted volume (which is a drive, not a physical disk) using the string.Replace("\\\\.\\{0}:", DriveLetter) pattern.

You can get the list of mounted volumes (ultimately, you want a list of letters) for a given physical disk using IOCTL_DISK_GET_DRIVE_LAYOUT.


EDIT:

From MSDN :

A write on a disk handle will succeed if one of the following conditions is true:

The sectors to be written to do not fall within a volume's extents.

The sectors to be written to fall within a mounted volume, but you have explicitly locked or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.

The sectors to be written to fall within a volume that has no mounted file system other than RAW.

So basically, what you should do is:

  • get a handle to each of the volumes
  • use FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME on each volume. If no file is being used in the volume (i.e. no opened handle by any process to any file), FSCTL_LOCK_VOLUME is enough
  • get a handle to the physical disk
  • write to the physical disk
  • close both handles. Closing the volume handle will release the lock.

Also make sure you're running your application with admin rights (elevated process).