Most of the parameters are optional and unused by Chrome so it’s not too hard to call, once you've parsed the JSON state file and Base64-decoded the encrypted key with normal Rust code:
fn unprotect(data: &mut [u8]) -> windows::core::Result<Vec<u8>> {
let data_in = CRYPTOAPI_BLOB { cbData: data.len() as u32, pbData: data.as_mut_ptr() };
let mut data_out = CRYPTOAPI_BLOB { cbData: 0, pbData: null_mut() };
unsafe {
CryptUnprotectData(&data_in, null_mut(), null_mut(), null_mut(), null(), 0, &mut data_out).ok()?;
let bytes = slice::from_raw_parts(data_out.pbData, data_out.cbData as usize).to_vec();
LocalFree(data_out.pbData as isize);
Ok(bytes)
}
}
That code will leak memory if to_vec() panics, but I don’t think that’s a big problem in this case.