diff --git a/.metadata/options.rsp b/.metadata/options.rsp index 2063624..d1e7dbc 100644 --- a/.metadata/options.rsp +++ b/.metadata/options.rsp @@ -6,4 +6,6 @@ SymTagEnum __MIDL___MIDL_itf_dia2_0000_0000_0001 __MIDL___MIDL_itf_dia2_0000_0033_0001 __MIDL___MIDL_itf_dia2_0000_0034_0001 -PfnPDBDebugDirV \ No newline at end of file +PfnPDBDebugDirV +--memberRemap +IDiaSourceFile::get_checksum::pbData=[Optional] diff --git a/.windows/winmd/Microsoft.Dia.winmd b/.windows/winmd/Microsoft.Dia.winmd index 8f8d449..c965a6d 100644 Binary files a/.windows/winmd/Microsoft.Dia.winmd and b/.windows/winmd/Microsoft.Dia.winmd differ diff --git a/crates/samples/checksum/Cargo.toml b/crates/samples/checksum/Cargo.toml new file mode 100644 index 0000000..10628d2 --- /dev/null +++ b/crates/samples/checksum/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "sample_checksum" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies.windows] +version = "0.53" + +[dependencies.microsoft-dia] +path = "../../../" diff --git a/crates/samples/checksum/src/main.rs b/crates/samples/checksum/src/main.rs new file mode 100644 index 0000000..87a2562 --- /dev/null +++ b/crates/samples/checksum/src/main.rs @@ -0,0 +1,61 @@ +use microsoft_dia::{nsNone, DiaSource, IDiaDataSource, SymTagCompiland}; +use windows::{ + core::*, + Win32::System::Com::{CoInitializeEx, COINIT_MULTITHREADED}, +}; + +fn main() -> Result<()> { + unsafe { + // Initialize COM and DIA + CoInitializeEx(None, COINIT_MULTITHREADED).ok()?; + let source: IDiaDataSource = microsoft_dia::helpers::NoRegCoCreate( + s!( + r#"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\DIA SDK\bin\amd64\msdia140.dll"# + ), + &DiaSource, + )?; + + // Open session against own symbols + let executable = std::env::current_exe().unwrap(); + source.loadDataForExe(&HSTRING::from(executable.as_os_str()), None, None)?; + let session = source.openSession()?; + + // Get compilands + let symbols = + session + .globalScope()? + .findChildren(SymTagCompiland, None, nsNone.0 as u32)?; + + // Get source files + for i in 0..symbols.Count()? { + let symbol = symbols.Item(i as u32)?; + let files = session.findFile(&symbol, PCWSTR::null(), nsNone.0 as u32)?; + + // Find files with a checksum and print out details + for j in 0..files.Count()? { + let file = files.Item(j as u32)?; + if file.checksumType()? == 0 { + continue; + } + + let mut byte_count = 0u32; + file.get_checksum(&mut byte_count, None)?; + + let mut bytes = vec![0; byte_count as usize]; + file.get_checksum(&mut byte_count, Some(&mut bytes))?; + + println!("File: {}", file.fileName()?); + println!( + "{:02x}: {}\n", + file.checksumType()?, + bytes + .iter() + .map(|b| format!("{:02x}", b).to_string()) + .collect::() + ); + } + } + + Ok(()) + } +} diff --git a/src/bindings.rs b/src/bindings.rs index e9cd737..258292e 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -4609,13 +4609,19 @@ pub mod Dia { pub unsafe fn get_checksum( &self, pcbdata: *mut u32, - pbdata: &mut [u8], + pbdata: ::core::option::Option<&mut [u8]>, ) -> ::windows_core::Result<()> { (::windows_core::Interface::vtable(self).get_checksum)( ::windows_core::Interface::as_raw(self), - pbdata.len().try_into().unwrap(), + pbdata + .as_deref() + .map_or(0, |slice| slice.len().try_into().unwrap()), pcbdata, - ::core::mem::transmute(pbdata.as_ptr()), + ::core::mem::transmute( + pbdata + .as_deref() + .map_or(::core::ptr::null(), |slice| slice.as_ptr()), + ), ) .ok() }