ACCESS_STATUS_VIOLATION, reading a file with the windows API (windows.rs)

Hello, I use BackupRead from the windows API with windows.rs.(Windows API | windows.rs)

But everytime i try to use it, windows throws an ACCESS_STATUS_VIOLATION and i can´t figure out, why.

Open the file:

// Attributeflags for reading the file data and the security descriptor
let mode = READ_CONTROL.0 | FILE_READ_DATA.0;
        
let file = OpenOptions::new()
    .access_mode(mode)
    .share_mode(0)
    .attributes(FILE_FLAG_BACKUP_SEMANTICS.0)
    .open("Test/test.txt")?;

Read file data. Here occures the ACCESS_STATUS_VIOLATION:

// windows file handle
let handle = file.as_raw_handle() as isize;

// input buffer 
let buf = &mut [0u8; 4095];
let buf_ptr = buf.as_ptr();

// size of the input buffer
let buf_size = buf.len() as u32;

// bytes that have been read
let mut bytes_read: u32 = 0;
let bytes_read: *mut u32 = &mut bytes_read;

// Special backup file context
let context: *mut *mut c_void = std::ptr::null_mut();

unsafe {
    // Read file data
    BackupRead(
        HANDLE(handle), 
        buf_ptr, 
        buf_size,
        bytes_read, 
        false,    // Abort status 
        true,     // Indicates if the function will restore the access-control list data.  
        context
    );

    // Drop the context. 
    // All other input except the context and abort status will be ignored
    BackupRead(
        HANDLE::default(), 
        std::ptr::null_mut() as *mut u8, 
        0,
        std::ptr::null_mut() as *mut u32, 
        true, 
        true, 
        context
    ); 
};

This is probably not the cause of your problem, but do note that let buf_ptr = buf.as_ptr(); doesn't give you a pointer valid for writes, you need to call .as_mut_ptr() instead

1 Like

I think the problem is that you are passing a null pointer for context instead of a pointer to a null pointer. BackupRead writes a pointer to a newly allocated context to the memory referenced by the context pointer. If you pass a null pointer you get a null pointer dereference.

2 Likes

My first guess would be this line:

let context: *mut *mut c_void = std::ptr::null_mut();

It should be:

let mut context: *mut c_void = std::ptr::null_mut();

And then you use it like:

// windows file handle
let handle = file.as_raw_handle() as isize;

// input buffer 
let mut buf = [0u8; 4095];

// bytes that have been read
let mut bytes_read: u32 = 0;

// Special backup file context
let mut context: *mut c_void = std::ptr::null_mut();

BackupRead(
    HANDLE(handle),
    &mut buf,
    buf.len() as u32,
    &mut bytes_read,
    false,
    true
    &mut context
);

I've not tried this though.

1 Like

Thanks for your help. This is the solution :grinning:

let mut context: *mut c_void = std::ptr::null_mut()

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.