Skip to content

Instantly share code, notes, and snippets.

@Lait-au-Cafe
Created May 4, 2023 07:33
Show Gist options
  • Save Lait-au-Cafe/ccc1082c58e6eb275c4a0c98062e280f to your computer and use it in GitHub Desktop.
Save Lait-au-Cafe/ccc1082c58e6eb275c4a0c98062e280f to your computer and use it in GitHub Desktop.
GetAllocatedString crashes with STATUS_ACCESS_VIOLATION.
#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;
}
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