chore!: upgrade windows crate

This commit is contained in:
ArcticLampyrid committed 2024-03-10 02:25:18 +08:00
1 parent 23bb7ee04a
commit 29f8fe7313
8 files changed
+88 -92

No files matched your search

+14 -6
View File
@@ -1,22 +1,30 @@
[package]
edition = "2018"
edition = "2021"
name = "winprint"
version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
lazy_static = "1.4.0"
scopeguard = "1.1"
thiserror = "1.0"
windows = "0.20"
[dependencies.windows]
version = "0.54"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_Graphics_Gdi",
"Win32_System_Com",
"Win32_Storage_Xps_Printing",
"Win32_System_Threading",
"Win32_Graphics_Printing",
]
[build-dependencies]
windows = "0.20"
reqwest = { version = "0.11", features = ["blocking"] }
flate2 = "1.0"
tar = "0.4"
[features]
default = ["pdfium"]
pdfium = []
pdfium = []
+13 -30
View File
@@ -21,21 +21,18 @@ fn try_link_pdfium() -> Result<(), Box<dyn Error>> {
target_path.push("pdfium_binaries");
fs::create_dir_all(target_path.as_path())?;
let has_bin = fs::read_dir(target_path.as_path())?.any(|x| {
bin_ext
.iter()
.find(|s| {
x.as_ref()
.ok()
.and_then(|d| {
if Path::new(d.file_name().as_os_str()).extension() == Some(s) {
Some(())
} else {
None
}
})
.is_some()
})
.is_some()
bin_ext.iter().any(|s| {
x.as_ref()
.ok()
.and_then(|d| {
if Path::new(d.file_name().as_os_str()).extension() == Some(s) {
Some(())
} else {
None
}
})
.is_some()
})
});
if !has_bin {
let build_id = 4660;
@@ -52,7 +49,7 @@ fn try_link_pdfium() -> Result<(), Box<dyn Error>> {
if file.header().entry_type() == EntryType::Regular {
let file_path = file.path()?;
let file_extension = file_path.extension();
let is_bin = bin_ext.iter().find(|s| file_extension == Some(s)).is_some();
let is_bin = bin_ext.iter().any(|s| file_extension == Some(s));
if is_bin {
if let Some(file_name_raw) = file_path.file_name() {
let mut file_name_str = file_name_raw.to_string_lossy();
@@ -79,18 +76,4 @@ fn try_link_pdfium() -> Result<(), Box<dyn Error>> {
fn main() {
#[cfg(feature = "pdfium")]
try_link_pdfium().unwrap();
windows::build! {
Windows::Win32::Graphics::Gdi::{
CreateDCW, DeleteDC, GetDeviceCaps, SetViewportOrgEx, GET_DEVICE_CAPS_INDEX, HDC,
LOGPIXELSX, LOGPIXELSY, PHYSICALHEIGHT, PHYSICALOFFSETX, PHYSICALOFFSETY,
PHYSICALWIDTH,
},
Windows::Win32::Graphics::Printing::*,
Windows::Win32::System::Com::{CoCreateInstance, CoInitializeEx, CoUninitialize},
Windows::Win32::Storage::Xps::*,
Windows::Win32::Storage::Xps::Printing::*,
Windows::Win32::Foundation::CloseHandle,
Windows::Win32::System::Threading::{CreateEventW, SetEvent, WaitForSingleObject},
Windows::Win32::System::WindowsProgramming::INFINITE
};
}
-1
View File
@@ -1,3 +1,2 @@
windows::include_bindings!();
#[cfg(feature = "pdfium")]
pub(crate) mod pdfium;
+1 -1
View File
@@ -1,6 +1,6 @@
#![allow(warnings, unused)]
use super::Windows::Win32::Graphics::Gdi::HDC;
use windows::Win32::Graphics::Gdi::HDC;
/*
generated by rust-bindgen 0.59.1
cmdline:
+1 -1
View File
@@ -9,7 +9,7 @@ mod tests {
use std::path::Path;
#[test]
fn it_works() {
let printers = PrinterInfo::all();
let printers = PrinterInfo::all().unwrap();
println!("{:#?}", printers);
let my_printer = printers.iter().find(|x| x.name() == "pdfFactory Pro").unwrap();
let xps = XpsPrinter::new(my_printer.clone());
+21 -10
View File
@@ -3,7 +3,9 @@ use scopeguard::defer;
use std::alloc::{alloc, dealloc, Layout};
use std::ffi::{OsStr, OsString};
use std::mem;
use std::ptr;
use thiserror::Error;
use windows::core::PCWSTR;
use windows::Win32::Graphics::Printing::*;
#[derive(Clone, Debug)]
pub struct PrinterInfo {
name: String,
@@ -11,20 +13,26 @@ pub struct PrinterInfo {
os_name: OsString,
os_attributes: u32,
}
#[derive(Error, Debug)]
pub enum EnumPrinterError {
#[error("Failed to enum printer: {0}")]
FailedToEnumPrinter(windows::core::Error),
}
impl PrinterInfo {
pub fn all() -> Vec<Self> {
pub fn all() -> Result<Vec<Self>, EnumPrinterError> {
let mut bytes_needed = 0;
let mut count_returned = 0;
let flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;
let name = PWSTR::default();
let name = PCWSTR::null();
let level = 4;
unsafe {
EnumPrintersW(
let _ = EnumPrintersW(
flags,
name,
level,
ptr::null_mut(),
0,
None,
&mut bytes_needed,
&mut count_returned,
);
@@ -40,11 +48,14 @@ impl PrinterInfo {
flags,
name,
level,
buffer,
bytes_needed,
Some(std::slice::from_raw_parts_mut(
buffer,
bytes_needed as usize,
)),
&mut bytes_needed,
&mut count_returned,
);
)
.map_err(EnumPrinterError::FailedToEnumPrinter)?;
let mut result = Vec::<PrinterInfo>::with_capacity(count_returned as usize);
for i in 0..count_returned {
let info = &*(buffer as *const PRINTER_INFO_4W).offset(i as isize);
@@ -56,7 +67,7 @@ impl PrinterInfo {
os_name,
});
}
result
Ok(result)
}
}
+23 -28
View File
@@ -2,25 +2,21 @@ use crate::bindings::pdfium::*;
use crate::printer::FilePrinter;
use crate::printer::FilePrinterError;
use crate::printer::PrinterInfo;
use crate::utils::pdfium::PdfiumCustomDocument;
use crate::utils::pdfium::PdfiumGuard;
use crate::utils::wchar;
use crate::{
bindings::Windows::Win32::{
Foundation::PWSTR,
Graphics::Gdi::{
CreateDCW, DeleteDC, GetDeviceCaps, SetViewportOrgEx, GET_DEVICE_CAPS_INDEX, HDC,
LOGPIXELSX, LOGPIXELSY, PHYSICALHEIGHT, PHYSICALOFFSETX, PHYSICALOFFSETY,
PHYSICALWIDTH,
},
Storage::Xps::*,
},
utils::pdfium::PdfiumCustomDocument,
};
use scopeguard::defer;
use std::path::Path;
use std::ptr;
use std::{fs::File, mem};
use windows::Handle;
use windows::{
core::PCWSTR,
Win32::Graphics::Gdi::{
CreateDCW, DeleteDC, GetDeviceCaps, SetViewportOrgEx, GET_DEVICE_CAPS_INDEX, LOGPIXELSX,
LOGPIXELSY, PHYSICALHEIGHT, PHYSICALOFFSETX, PHYSICALOFFSETY, PHYSICALWIDTH,
},
Win32::Storage::Xps::*,
};
pub struct PdfiumPrinter {
printer: PrinterInfo,
}
@@ -34,25 +30,25 @@ impl PdfiumPrinter {
impl FilePrinter for PdfiumPrinter {
fn print(&self, path: &Path) -> std::result::Result<(), FilePrinterError> {
unsafe {
let created_hdc_print = CreateDCW(
let hdc_print = CreateDCW(
None,
PWSTR(wchar::to_wide_chars(self.printer.os_name()).as_mut_ptr()),
PCWSTR(wchar::to_wide_chars(self.printer.os_name()).as_ptr()),
None,
ptr::null(),
)
.ok()
.map_err(|_| FilePrinterError::FailedToOpenPrinter)?;
None,
);
if hdc_print.is_invalid() {
return Err(FilePrinterError::FailedToOpenPrinter);
}
defer! {
DeleteDC(created_hdc_print);
DeleteDC(hdc_print);
}
let hdc_print = HDC(created_hdc_print.0);
let mut doc_name = wchar::to_wide_chars(path.file_name().unwrap_or(path.as_ref()));
let doc_info = DOCINFOW {
cbSize: mem::size_of::<DOCINFOW>() as i32,
fwType: 0,
lpszDocName: PWSTR(doc_name.as_mut_ptr()),
lpszOutput: PWSTR::default(),
lpszDatatype: PWSTR::default(),
lpszDocName: PCWSTR(doc_name.as_mut_ptr()),
lpszOutput: PCWSTR::null(),
lpszDatatype: PCWSTR::null(),
};
StartDocW(hdc_print, &doc_info);
{
@@ -71,9 +67,8 @@ impl FilePrinter for PdfiumPrinter {
FPDF_ClosePage(page);
}
StartPage(hdc_print);
let get_attr = |kind: u32| -> i32 {
GetDeviceCaps(hdc_print, GET_DEVICE_CAPS_INDEX(kind))
};
let get_attr =
|kind: GET_DEVICE_CAPS_INDEX| -> i32 { GetDeviceCaps(hdc_print, kind) };
let dpi_x = get_attr(LOGPIXELSX);
let dpi_y = get_attr(LOGPIXELSY);
let page_width = FPDF_GetPageWidth(page) * dpi_x as f64 / 72.0;
@@ -86,7 +81,7 @@ impl FilePrinter for PdfiumPrinter {
let h = page_height * scale;
let org_x = -get_attr(PHYSICALOFFSETX);
let org_y = -get_attr(PHYSICALOFFSETY);
SetViewportOrgEx(hdc_print, org_x, org_y, ptr::null_mut());
SetViewportOrgEx(hdc_print, org_x, org_y, None);
FPDF_RenderPage(hdc_print, page, 0, 0, w as i32, h as i32, 0, FPDF_PRINTING);
EndPage(hdc_print);
}
+15 -15
View File
@@ -1,8 +1,3 @@
use crate::bindings::Windows::Win32::{
Foundation::{CloseHandle, PWSTR},
Storage::Xps::{Printing::*, *},
System::{Com::*, Threading::*, WindowsProgramming::INFINITE},
};
use crate::printer::FilePrinter;
use crate::printer::FilePrinterError;
use crate::printer::PrinterInfo;
@@ -10,7 +5,14 @@ use crate::utils::wchar;
use scopeguard::defer;
use std::path::Path;
use std::ptr;
use windows::Handle;
use windows::{
core::PCWSTR,
Win32::{
Foundation::CloseHandle,
Storage::Xps::{Printing::*, *},
System::{Com::*, Threading::*},
},
};
pub struct XpsPrinter {
printer: PrinterInfo,
@@ -25,28 +27,26 @@ impl XpsPrinter {
impl FilePrinter for XpsPrinter {
fn print(&self, path: &Path) -> std::result::Result<(), FilePrinterError> {
unsafe {
let _ = CoInitializeEx(std::ptr::null_mut(), COINIT_MULTITHREADED);
let _ = CoInitializeEx(None, COINIT_MULTITHREADED);
defer! {
CoUninitialize();
}
let event = CreateEventW(ptr::null_mut(), true, false, None)
.ok()
let event = CreateEventW(None, true, false, None)
.map_err(|_| FilePrinterError::FailedToCreateJob)?;
defer! {
CloseHandle(event);
let _ = CloseHandle(event);
}
let xps_factory: IXpsOMObjectFactory =
CoCreateInstance(&XpsOMObjectFactory, None, CLSCTX_ALL)
.map_err(|_| FilePrinterError::FailedToOpenPrinter)?;
let mut document_stream_container = Option::<IXpsPrintJobStream>::None;
StartXpsPrintJob(
PWSTR(wchar::to_wide_chars(self.printer.os_name()).as_mut_ptr()),
PWSTR(wchar::to_wide_chars(path.file_name().unwrap_or(path.as_ref())).as_mut_ptr()),
PCWSTR(wchar::to_wide_chars(self.printer.os_name()).as_ptr()),
PCWSTR(wchar::to_wide_chars(path.file_name().unwrap_or(path.as_ref())).as_ptr()),
None,
None,
event,
ptr::null(),
0,
&[],
ptr::null_mut(),
ptr::addr_of_mut!(document_stream_container),
ptr::null_mut(),
@@ -55,7 +55,7 @@ impl FilePrinter for XpsPrinter {
let document_stream =
document_stream_container.ok_or(FilePrinterError::FailedToCreateJob)?;
let xps_package = xps_factory
.CreatePackageFromFile(PWSTR(wchar::to_wide_chars(path).as_mut_ptr()), false)
.CreatePackageFromFile(PCWSTR(wchar::to_wide_chars(path).as_ptr()), false)
.map_err(|_| FilePrinterError::FailedToWriteDocument)?;
xps_package
.WriteToStream(&document_stream, false)