Created
May 4, 2023 07:33
-
-
Save Lait-au-Cafe/ccc1082c58e6eb275c4a0c98062e280f to your computer and use it in GitHub Desktop.
GetAllocatedString crashes with STATUS_ACCESS_VIOLATION.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <mfapi.h> | |
#include <mfidl.h> | |
void listup_webcams() { | |
IMFAttributes *p_attr = NULL; | |
HRESULT hr = MFCreateAttributes(&p_attr, 1); | |
if(FAILED(hr)){ | |
std::cout | |
<< std::hex | |
<< "Failed. (MFCreateAttributes 0x" << hr << ")" | |
<< std::dec | |
<< std::endl; | |
return; | |
} | |
hr = p_attr->SetGUID( | |
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, | |
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); | |
if(FAILED(hr)){ | |
std::cout | |
<< std::hex | |
<< "Failed. (SetGUID 0x" << hr << ")" | |
<< std::dec | |
<< std::endl; | |
return; | |
} | |
IMFActivate **pp_devices = NULL; | |
UINT32 count; | |
hr = MFEnumDeviceSources(p_attr, &pp_devices, &count); | |
if(FAILED(hr)){ | |
std::cout | |
<< std::hex | |
<< "Failed. (GetString 0x" << hr << ")" | |
<< std::dec | |
<< std::endl; | |
return; | |
} | |
if(count == 0) { | |
std::cout | |
<< "There's no webcam device available. " | |
<< std::endl; | |
} | |
for(unsigned int i = 0; i < count; i++) { | |
UINT32 length = 0; | |
WCHAR *p_str = NULL; | |
hr = pp_devices[i]->GetAllocatedString( | |
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, | |
&p_str, &length); | |
if(FAILED(hr)){ | |
std::cout | |
<< std::hex | |
<< "Failed. (GetAllocatedString 0x" << hr << ")" | |
<< std::dec | |
<< std::endl; | |
return; | |
} | |
std::wcout << "Device Name: " << p_str << std::endl; | |
} | |
if(pp_devices != NULL) { | |
for(unsigned int i = 0; i < count; i++) { | |
pp_devices[i]->Release(); | |
} | |
CoTaskMemFree(pp_devices); | |
} | |
} | |
int main() { | |
listup_webcams(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ptr; | |
use windows::{ | |
core::*, | |
Win32::Media::MediaFoundation::*, | |
}; | |
fn main() -> Result<()> { | |
unsafe { | |
let mut imf_attr_opt: Option<IMFAttributes> = None; | |
MFCreateAttributes(&mut imf_attr_opt, 1)?; | |
let imf_attr = imf_attr_opt.unwrap(); | |
println!("Set GUID. "); | |
imf_attr.SetGUID(&MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)?; | |
let mut devices_opt_ptr: *mut Option<IMFActivate> = ptr::null_mut(); | |
let mut num_of_devices: u32 = 0; | |
println!("Acquire webcam devices list. "); | |
MFEnumDeviceSources(&imf_attr, &mut devices_opt_ptr, &mut num_of_devices)?; | |
if num_of_devices == 0 { | |
println!("There's no webcam device available. "); | |
return Ok(()) | |
} | |
else { | |
println!("{} device[s] found. ", num_of_devices); | |
} | |
let mut length: u32 = 0; | |
let device_name: *mut PWSTR = ptr::null_mut(); | |
println!("Enumerate webcam devices. "); | |
for i in 0..num_of_devices { | |
let device_opt: *mut Option<IMFActivate> = devices_opt_ptr.offset(i as isize); | |
let device: &IMFActivate = (*device_opt).as_ref().unwrap(); | |
if let Ok(_) = device.GetAllocatedString( | |
&MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, | |
device_name, | |
&mut length) { | |
println!("length: {}", length); | |
let device_name = (*device_name).to_string()?; | |
println!("{}: {}", i, device_name); | |
} | |
else { | |
println!("Failed to allocate string. "); | |
} | |
} | |
} | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment