Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/windows-bindgen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: windows-bindgen

on:
pull_request:
push:
paths-ignore:
- '.github/ISSUE_TEMPLATE/**'
branches:
- master

env:
RUSTFLAGS: -Dwarnings

jobs:
cargo_sys:
name: Check
strategy:
matrix:
rust: [1.70.0, stable, nightly]
runs-on:
- windows-latest
- ubuntu-latest
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Prepare
run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
- name: Check
run: cargo check -p windows-bindgen --all-features
30 changes: 30 additions & 0 deletions .github/workflows/windows-metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: windows-metadata

on:
pull_request:
push:
paths-ignore:
- '.github/ISSUE_TEMPLATE/**'
branches:
- master

env:
RUSTFLAGS: -Dwarnings

jobs:
cargo_sys:
name: Check
strategy:
matrix:
rust: [1.70.0, stable, nightly]
runs-on:
- windows-latest
- ubuntu-latest
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Prepare
run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
- name: Check
run: cargo check -p windows-metadata --all-features
30 changes: 30 additions & 0 deletions .github/workflows/windows-version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: windows-version

on:
pull_request:
push:
paths-ignore:
- '.github/ISSUE_TEMPLATE/**'
branches:
- master

env:
RUSTFLAGS: -Dwarnings

jobs:
cargo_sys:
name: Check
strategy:
matrix:
rust: [1.56.0, stable, nightly]
runs-on:
- windows-latest
- ubuntu-latest
runs-on: ${{ matrix.runs-on }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Prepare
run: rustup update --no-self-update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
- name: Check
run: cargo check -p windows-version --all-features
2 changes: 1 addition & 1 deletion crates/libs/bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "windows-bindgen"
version = "0.52.0"
authors = ["Microsoft"]
edition = "2021"
rust-version = "1.56"
rust-version = "1.70"
license = "MIT OR Apache-2.0"
description = "Windows metadata compiler"
repository = "https://github.com/microsoft/windows-rs"
Expand Down
5 changes: 1 addition & 4 deletions crates/libs/bindgen/src/rust/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ pub fn writer(writer: &Writer, def: metadata::Field) -> TokenStream {
}

fn initializer(writer: &Writer, def: metadata::Field) -> Option<TokenStream> {
let Some(value) = constant(def) else {
return None;
};

let value = constant(def)?;
let mut input = value.as_str();

let metadata::Type::TypeDef(def, _) = def.ty(None) else {
Expand Down
6 changes: 1 addition & 5 deletions crates/libs/core/src/strings/hstring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,7 @@ impl HSTRING {
}

fn get_header(&self) -> Option<&Header> {
if let Some(header) = &self.0 {
unsafe { Some(header.as_ref()) }
} else {
None
}
self.0.map(|header| unsafe { header.as_ref() })
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/libs/metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "windows-metadata"
version = "0.52.0"
authors = ["Microsoft"]
edition = "2021"
rust-version = "1.64"
rust-version = "1.70"
license = "MIT OR Apache-2.0"
description = "Windows metadata reader"
repository = "https://github.com/microsoft/windows-rs"
Expand Down
61 changes: 28 additions & 33 deletions crates/libs/metadata/src/file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::*;
type Result<T> = std::result::Result<T, ()>;

pub struct File {
pub reader: *const Reader,
Expand Down Expand Up @@ -45,16 +44,12 @@ unsafe impl Sync for File {}

impl File {
pub fn new(bytes: Vec<u8>) -> Option<Self> {
Self::ok(bytes).ok()
}

fn ok(bytes: Vec<u8>) -> Result<Self> {
let mut result = File { bytes, reader: std::ptr::null(), strings: 0, blobs: 0, tables: Default::default() };

let dos = result.bytes.view_as::<IMAGE_DOS_HEADER>(0)?;

if dos.e_magic != IMAGE_DOS_SIGNATURE || result.bytes.copy_as::<u32>(dos.e_lfanew as usize)? != IMAGE_NT_SIGNATURE {
return Err(());
return None;
}

let file_offset = dos.e_lfanew as usize + std::mem::size_of::<u32>();
Expand All @@ -71,20 +66,20 @@ impl File {
let optional = result.bytes.view_as::<IMAGE_OPTIONAL_HEADER64>(optional_offset)?;
(optional.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR as usize].VirtualAddress, result.bytes.view_as_slice_of::<IMAGE_SECTION_HEADER>(optional_offset + std::mem::size_of::<IMAGE_OPTIONAL_HEADER64>(), file.NumberOfSections as usize)?)
}
_ => return Err(()),
_ => return None,
};

let clr = result.bytes.view_as::<IMAGE_COR20_HEADER>(offset_from_rva(section_from_rva(sections, com_virtual_address)?, com_virtual_address))?;

if clr.cb != std::mem::size_of::<IMAGE_COR20_HEADER>() as u32 {
return Err(());
return None;
}

let metadata_offset = offset_from_rva(section_from_rva(sections, clr.MetaData.VirtualAddress)?, clr.MetaData.VirtualAddress);
let metadata = result.bytes.view_as::<METADATA_HEADER>(metadata_offset)?;

if metadata.signature != METADATA_SIGNATURE {
return Err(());
return None;
}

// The METADATA_HEADER struct is not a fixed size so have to offset a little more carefully.
Expand Down Expand Up @@ -306,7 +301,7 @@ impl File {
result.tables[NestedClass::TABLE].set_data(&mut view);
result.tables[GenericParam::TABLE].set_data(&mut view);

Ok(result)
Some(result)
}

pub fn usize(&self, row: usize, table: usize, column: usize) -> usize {
Expand Down Expand Up @@ -356,64 +351,64 @@ impl File {
}
}

fn section_from_rva(sections: &[IMAGE_SECTION_HEADER], rva: u32) -> Result<&IMAGE_SECTION_HEADER> {
sections.iter().find(|&s| rva >= s.VirtualAddress && rva < s.VirtualAddress + unsafe { s.Misc.VirtualSize }).ok_or(())
fn section_from_rva(sections: &[IMAGE_SECTION_HEADER], rva: u32) -> Option<&IMAGE_SECTION_HEADER> {
sections.iter().find(|&s| rva >= s.VirtualAddress && rva < s.VirtualAddress + unsafe { s.Misc.VirtualSize })
}

fn offset_from_rva(section: &IMAGE_SECTION_HEADER, rva: u32) -> usize {
(rva - section.VirtualAddress + section.PointerToRawData) as usize
}

trait View {
fn view_as<T>(&self, offset: usize) -> Result<&T>;
fn view_as_slice_of<T>(&self, offset: usize, len: usize) -> Result<&[T]>;
fn copy_as<T: Copy>(&self, offset: usize) -> Result<T>;
fn view_as_str(&self, offset: usize) -> Result<&[u8]>;
fn is_proper_length<T>(&self, offset: usize) -> Result<()>;
fn is_proper_length_and_alignment<T>(&self, offset: usize, count: usize) -> Result<*const T>;
fn view_as<T>(&self, offset: usize) -> Option<&T>;
fn view_as_slice_of<T>(&self, offset: usize, len: usize) -> Option<&[T]>;
fn copy_as<T: Copy>(&self, offset: usize) -> Option<T>;
fn view_as_str(&self, offset: usize) -> Option<&[u8]>;
fn is_proper_length<T>(&self, offset: usize) -> Option<()>;
fn is_proper_length_and_alignment<T>(&self, offset: usize, count: usize) -> Option<*const T>;
}

impl View for [u8] {
fn view_as<T>(&self, offset: usize) -> Result<&T> {
unsafe { Ok(&*self.is_proper_length_and_alignment(offset, 1)?) }
fn view_as<T>(&self, offset: usize) -> Option<&T> {
unsafe { Some(&*self.is_proper_length_and_alignment(offset, 1)?) }
}

fn view_as_slice_of<T>(&self, offset: usize, len: usize) -> Result<&[T]> {
unsafe { Ok(std::slice::from_raw_parts(self.is_proper_length_and_alignment(offset, len)?, len)) }
fn view_as_slice_of<T>(&self, offset: usize, len: usize) -> Option<&[T]> {
unsafe { Some(std::slice::from_raw_parts(self.is_proper_length_and_alignment(offset, len)?, len)) }
}

fn copy_as<T>(&self, offset: usize) -> Result<T> {
fn copy_as<T>(&self, offset: usize) -> Option<T> {
self.is_proper_length::<T>(offset)?;

unsafe {
let mut data = std::mem::MaybeUninit::zeroed().assume_init();
std::ptr::copy_nonoverlapping(self[offset..].as_ptr(), &mut data as *mut T as *mut u8, std::mem::size_of::<T>());
Ok(data)
Some(data)
}
}

fn view_as_str(&self, offset: usize) -> Result<&[u8]> {
fn view_as_str(&self, offset: usize) -> Option<&[u8]> {
let buffer = &self[offset..];
let index = buffer.iter().position(|c| *c == b'\0').ok_or(())?;
Ok(&self[offset..offset + index])
let index = buffer.iter().position(|c| *c == b'\0')?;
Some(&self[offset..offset + index])
}

fn is_proper_length<T>(&self, offset: usize) -> Result<()> {
fn is_proper_length<T>(&self, offset: usize) -> Option<()> {
if offset + std::mem::size_of::<T>() <= self.len() {
Ok(())
Some(())
} else {
Err(())
None
}
}

fn is_proper_length_and_alignment<T>(&self, offset: usize, count: usize) -> Result<*const T> {
fn is_proper_length_and_alignment<T>(&self, offset: usize, count: usize) -> Option<*const T> {
self.is_proper_length::<T>(offset * count)?;
let ptr = &self[offset] as *const u8 as *const T;

if ptr.align_offset(std::mem::align_of::<T>()) == 0 {
Ok(ptr)
Some(ptr)
} else {
Err(())
None
}
}
}