Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CreateFile: direct write operation to raw disk "Access is denied" - Vista, Win7

The relevant Microsoft doc is:
Blocking Direct Write Operations to Volumes and Disks
CreateFile, remarks on Physical Disks and Volumes

The executable is written in C++ and it calls CreateFile() to open an SD card that has no filesystem. The CreateFile() and consecutive ReadFile() calls are successful for GENERIC_READ without Administrator privileges.

CreateFile fails for GENERIC_WRITE even with Administrator privileges. In the explorer, I set Run as Administrator under Properties > Compatibility > Privilege Level. I also tried to run the executable from an Administrator cmd (started with Ctrl+Shift+Enter, "Administrator:" is in the window title, properly elevated). Still, I get ERROR_ACCESS_DENIED (0x5).

Do I have to pass something else to CreateFile? I have no idea what security attributes are, I just pass NULL, relevant code is here at line 92, and here at line 48.

Or is there anything else that should be set to run the process with Administrator privileges?


A related questions:

Can I get write access to raw disk sectors under Vista and Windows 7 in user mode?
Raw partition access in Windows Vista
How to obtain direct access to raw HD data in C?
Is there a clean way to obtain exclusive access to a physical partition under Windows?

like image 447
Ali Avatar asked Jan 01 '12 18:01

Ali


3 Answers

While the answer of @MSalters makes sense, it is not how my code works. In fact it is so counter-intuitive, I spent several days making sure the code does in fact work.

These code snippets are in a proven, mass consumer market software product. When it needs to modify an on-disk structure, it dismounts the win32 volume so it can modify NTFS or FAT filesystem structures. Interestingly, the volume access handle is read-only:

    char    fn [30];
    snprintf (fn, sizeof fn, "\\\\.\\%s:", vol -> GetVolName ());

    vol_handle = CreateFile (fn, GENERIC_READ,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
                            NULL);

    if (vol_handle == INVALID_HANDLE_VALUE)
    {
          // show error message and exit
    }

If unable to get write access to a volume or partition, this code forces a dismount if the user authorizes such after a stern warning:

if (!DeviceIoControl (vol_handle, FSCTL_DISMOUNT_VOLUME,
                                            NULL, 0, NULL, 0, &status, NULL))
{
    DWORD err = GetLastError ();
    errormsg ("Error %d attempting to dismount volume: %s",
                                                        err, w32errtxt (err));
}

// lock volume
if (!DeviceIoControl (vol_handle, FSCTL_LOCK_VOLUME,
                                            NULL, 0, NULL, 0, &status, NULL))
{
     // error handling; not sure if retrying is useful
}

Writing is then fairly straightforward, except for positioning the file pointer by 512-byte sector:

    long    hipart = sect >> (32-9);
    long    lopart = sect << 9;
    long    err;

    SetLastError (0);       // needed before SetFilePointer post err detection
    lopart = SetFilePointer (vol_handle, lopart, &hipart, FILE_BEGIN);

    if (lopart == -1  &&  NO_ERROR != (err = GetLastError ()))
    {
            errormsg ("HWWrite: error %d seeking drive %x sector %ld:  %s",
                            err, drive, sect, w32errtxt (err));
            return false;
    }

    DWORD   n;

    if (!WriteFile (vol_handle, buf, num_sects*512, &n, NULL))
    {
            err = GetLastError ();
            errormsg ("WriteFile: error %d writing drive %x sectors %lu..%lu:  %s",
                            err, drv, sect, sect + num_sects - 1,
                            w32errtxt (err));
            return false;
    }
like image 187
wallyk Avatar answered Sep 30 '22 12:09

wallyk


It's quite rare to want only GENERIC_WRITE. You most likely want GENERIC_READ|GENERIC_WRITE.

like image 43
MSalters Avatar answered Sep 30 '22 11:09

MSalters


There is note in MSDN in documentation of CreateFile:

Direct access to the disk or to a volume is restricted. For more information, see "Changes to the file system and to the storage stack to restrict direct disk access and direct volume access in Windows Vista and in Windows Server 2008" in the Help and Support Knowledge Base at http://support.microsoft.com/kb/942448.

It refers to Vista/2008, but maybe apply to Win7 also.

like image 30
rkosegi Avatar answered Sep 30 '22 13:09

rkosegi