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

前端 未结 4 1669
北恋
北恋 2020-11-27 05:50

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

The executable is wr

4条回答
  •  渐次进展
    2020-11-27 06:10

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

提交回复
热议问题