Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
369 views
in Technique[技术] by (71.8m points)

c++ - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...