Merge pull request #5085 from youknowone/windows

port winapi to windows-sys
This commit is contained in:
Jeong, YunWon
2023-10-07 14:14:51 +09:00
committed by GitHub
4 changed files with 111 additions and 103 deletions

View File

@@ -130,8 +130,10 @@ features = [
"Win32_System_Console",
"Win32_System_LibraryLoader",
"Win32_System_Pipes",
"Win32_System_SystemServices",
"Win32_System_Threading",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
]
[target.'cfg(windows)'.dependencies.winapi]

View File

@@ -79,6 +79,8 @@ pub mod utils;
pub mod version;
pub mod vm;
pub mod warn;
#[cfg(windows)]
pub mod windows;
pub use self::compiler::parser::source_code;
pub use self::convert::{TryFromBorrowedObject, TryFromObject};

View File

@@ -6,13 +6,13 @@ mod _winapi {
use crate::{
builtins::PyStrRef,
common::windows::ToWideString,
convert::{ToPyException, ToPyObject, ToPyResult},
convert::{ToPyException, ToPyResult},
function::{ArgMapping, ArgSequence, OptionalArg},
stdlib::os::errno_err,
windows::WindowsSysResult,
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
};
use std::ptr::{null, null_mut};
use winapi::um::winbase;
use windows::{
core::PCWSTR,
Win32::Foundation::{HANDLE, HINSTANCE, MAX_PATH},
@@ -20,109 +20,43 @@ mod _winapi {
use windows_sys::Win32::Foundation::{BOOL, HANDLE as RAW_HANDLE};
#[pyattr]
use winapi::{
shared::winerror::{
ERROR_ALREADY_EXISTS, ERROR_BROKEN_PIPE, ERROR_IO_PENDING, ERROR_MORE_DATA,
ERROR_NETNAME_DELETED, ERROR_NO_DATA, ERROR_NO_SYSTEM_RESOURCES,
ERROR_OPERATION_ABORTED, ERROR_PIPE_BUSY, ERROR_PIPE_CONNECTED, ERROR_SEM_TIMEOUT,
WAIT_TIMEOUT,
use windows_sys::Win32::{
Foundation::{
DUPLICATE_CLOSE_SOURCE, DUPLICATE_SAME_ACCESS, ERROR_ALREADY_EXISTS, ERROR_BROKEN_PIPE,
ERROR_IO_PENDING, ERROR_MORE_DATA, ERROR_NETNAME_DELETED, ERROR_NO_DATA,
ERROR_NO_SYSTEM_RESOURCES, ERROR_OPERATION_ABORTED, ERROR_PIPE_BUSY,
ERROR_PIPE_CONNECTED, ERROR_SEM_TIMEOUT, GENERIC_READ, GENERIC_WRITE, STILL_ACTIVE,
WAIT_ABANDONED, WAIT_ABANDONED_0, WAIT_OBJECT_0, WAIT_TIMEOUT,
},
um::{
fileapi::OPEN_EXISTING,
memoryapi::{
FILE_MAP_ALL_ACCESS, FILE_MAP_COPY, FILE_MAP_EXECUTE, FILE_MAP_READ, FILE_MAP_WRITE,
Storage::FileSystem::{
FILE_FLAG_FIRST_PIPE_INSTANCE, FILE_FLAG_OVERLAPPED, FILE_GENERIC_READ,
FILE_GENERIC_WRITE, FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE, FILE_TYPE_REMOTE,
FILE_TYPE_UNKNOWN, OPEN_EXISTING, PIPE_ACCESS_DUPLEX, PIPE_ACCESS_INBOUND, SYNCHRONIZE,
},
System::{
Console::{STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE},
Memory::{
FILE_MAP_ALL_ACCESS, MEM_COMMIT, MEM_FREE, MEM_IMAGE, MEM_MAPPED, MEM_PRIVATE,
MEM_RESERVE, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE,
PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, PAGE_NOACCESS, PAGE_NOCACHE, PAGE_READONLY,
PAGE_READWRITE, PAGE_WRITECOMBINE, PAGE_WRITECOPY, SEC_COMMIT, SEC_IMAGE,
SEC_LARGE_PAGES, SEC_NOCACHE, SEC_RESERVE, SEC_WRITECOMBINE,
},
minwinbase::STILL_ACTIVE,
winbase::{
Pipes::{
PIPE_READMODE_MESSAGE, PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_WAIT,
},
SystemServices::LOCALE_NAME_MAX_LENGTH,
Threading::{
ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS,
CREATE_BREAKAWAY_FROM_JOB, CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE,
CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW, DETACHED_PROCESS,
FILE_FLAG_FIRST_PIPE_INSTANCE, FILE_FLAG_OVERLAPPED, FILE_TYPE_CHAR,
FILE_TYPE_DISK, FILE_TYPE_PIPE, FILE_TYPE_REMOTE, FILE_TYPE_UNKNOWN,
HIGH_PRIORITY_CLASS, IDLE_PRIORITY_CLASS, INFINITE, NORMAL_PRIORITY_CLASS,
PIPE_ACCESS_DUPLEX, PIPE_ACCESS_INBOUND, PIPE_READMODE_MESSAGE, PIPE_TYPE_MESSAGE,
PIPE_UNLIMITED_INSTANCES, PIPE_WAIT, REALTIME_PRIORITY_CLASS, STARTF_USESHOWWINDOW,
STARTF_USESTDHANDLES, STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
WAIT_ABANDONED, WAIT_ABANDONED_0, WAIT_OBJECT_0,
CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW, DETACHED_PROCESS, HIGH_PRIORITY_CLASS,
IDLE_PRIORITY_CLASS, INFINITE, NORMAL_PRIORITY_CLASS, PROCESS_DUP_HANDLE,
REALTIME_PRIORITY_CLASS, STARTF_USESHOWWINDOW, STARTF_USESTDHANDLES,
},
winnt::{
DUPLICATE_CLOSE_SOURCE, DUPLICATE_SAME_ACCESS, FILE_GENERIC_READ,
FILE_GENERIC_WRITE, GENERIC_READ, GENERIC_WRITE, LOCALE_NAME_MAX_LENGTH,
MEM_COMMIT, MEM_FREE, MEM_IMAGE, MEM_MAPPED, MEM_PRIVATE, MEM_RESERVE,
PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY,
PAGE_GUARD, PAGE_NOACCESS, PAGE_NOCACHE, PAGE_READONLY, PAGE_READWRITE,
PAGE_WRITECOMBINE, PAGE_WRITECOPY, PROCESS_DUP_HANDLE, SEC_COMMIT, SEC_IMAGE,
SEC_LARGE_PAGES, SEC_NOCACHE, SEC_RESERVE, SEC_WRITECOMBINE, SYNCHRONIZE,
},
winuser::SW_HIDE,
},
UI::WindowsAndMessaging::SW_HIDE,
};
fn GetLastError() -> u32 {
unsafe { winapi::um::errhandlingapi::GetLastError() }
}
trait WindowsSysResultValue {
type Ok: ToPyObject;
fn is_err(&self) -> bool;
fn into_ok(self) -> Self::Ok;
}
impl WindowsSysResultValue for RAW_HANDLE {
type Ok = HANDLE;
fn is_err(&self) -> bool {
*self == windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE
}
fn into_ok(self) -> Self::Ok {
HANDLE(self)
}
}
impl WindowsSysResultValue for BOOL {
type Ok = ();
fn is_err(&self) -> bool {
*self == 0
}
fn into_ok(self) -> Self::Ok {}
}
struct WindowsSysResult<T>(T);
impl<T: WindowsSysResultValue> WindowsSysResult<T> {
fn is_err(&self) -> bool {
self.0.is_err()
}
fn into_pyresult(self, vm: &VirtualMachine) -> PyResult<T::Ok> {
if self.is_err() {
Err(errno_err(vm))
} else {
Ok(self.0.into_ok())
}
}
}
impl<T: WindowsSysResultValue> ToPyResult for WindowsSysResult<T> {
fn to_pyresult(self, vm: &VirtualMachine) -> PyResult {
let ok = self.into_pyresult(vm)?;
Ok(ok.to_pyobject(vm))
}
}
type HandleInt = usize; // TODO: change to isize when fully ported to windows-rs
impl TryFromObject for HANDLE {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let handle = HandleInt::try_from_object(vm, obj)?;
Ok(HANDLE(handle as isize))
}
}
impl ToPyObject for HANDLE {
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
(self.0 as HandleInt).to_pyobject(vm)
}
}
#[pyfunction]
fn CloseHandle(handle: HANDLE) -> WindowsSysResult<BOOL> {
WindowsSysResult(unsafe { windows_sys::Win32::Foundation::CloseHandle(handle.0) })
@@ -193,7 +127,7 @@ mod _winapi {
vm: &VirtualMachine,
) -> PyResult<windows_sys::Win32::Storage::FileSystem::FILE_TYPE> {
let file_type = unsafe { windows_sys::Win32::Storage::FileSystem::GetFileType(h.0) };
if file_type == 0 && GetLastError() != 0 {
if file_type == 0 && unsafe { windows_sys::Win32::Foundation::GetLastError() } != 0 {
Err(errno_err(vm))
} else {
Ok(file_type)
@@ -227,7 +161,8 @@ mod _winapi {
args: CreateProcessArgs,
vm: &VirtualMachine,
) -> PyResult<(HANDLE, HANDLE, u32, u32)> {
let mut si = winbase::STARTUPINFOEXW::default();
let mut si: windows_sys::Win32::System::Threading::STARTUPINFOEXW =
unsafe { std::mem::zeroed() };
si.StartupInfo.cb = std::mem::size_of_val(&si) as _;
macro_rules! si_attr {
@@ -292,11 +227,11 @@ mod _winapi {
std::ptr::null(),
args.inherit_handles,
args.creation_flags
| winbase::EXTENDED_STARTUPINFO_PRESENT
| winbase::CREATE_UNICODE_ENVIRONMENT,
| windows_sys::Win32::System::Threading::EXTENDED_STARTUPINFO_PRESENT
| windows_sys::Win32::System::Threading::CREATE_UNICODE_ENVIRONMENT,
env as _,
current_dir,
&mut si as *mut winbase::STARTUPINFOEXW as _,
&mut si as *mut _ as *mut _,
procinfo.as_mut_ptr(),
))
.into_pyresult(vm)?;
@@ -390,7 +325,8 @@ mod _winapi {
(result, size.assume_init())
};
if !result.is_err()
|| GetLastError() != winapi::shared::winerror::ERROR_INSUFFICIENT_BUFFER
|| unsafe { windows_sys::Win32::Foundation::GetLastError() }
!= windows_sys::Win32::Foundation::ERROR_INSUFFICIENT_BUFFER
{
return Err(errno_err(vm));
}

68
vm/src/windows.rs Normal file
View File

@@ -0,0 +1,68 @@
use crate::{
convert::{ToPyObject, ToPyResult},
stdlib::os::errno_err,
PyObjectRef, PyResult, TryFromObject, VirtualMachine,
};
use windows::Win32::Foundation::HANDLE;
use windows_sys::Win32::Foundation::{BOOL, HANDLE as RAW_HANDLE};
pub(crate) trait WindowsSysResultValue {
type Ok: ToPyObject;
fn is_err(&self) -> bool;
fn into_ok(self) -> Self::Ok;
}
impl WindowsSysResultValue for RAW_HANDLE {
type Ok = HANDLE;
fn is_err(&self) -> bool {
*self == windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE
}
fn into_ok(self) -> Self::Ok {
HANDLE(self)
}
}
impl WindowsSysResultValue for BOOL {
type Ok = ();
fn is_err(&self) -> bool {
*self == 0
}
fn into_ok(self) -> Self::Ok {}
}
pub(crate) struct WindowsSysResult<T>(pub T);
impl<T: WindowsSysResultValue> WindowsSysResult<T> {
pub fn is_err(&self) -> bool {
self.0.is_err()
}
pub fn into_pyresult(self, vm: &VirtualMachine) -> PyResult<T::Ok> {
if self.is_err() {
Err(errno_err(vm))
} else {
Ok(self.0.into_ok())
}
}
}
impl<T: WindowsSysResultValue> ToPyResult for WindowsSysResult<T> {
fn to_pyresult(self, vm: &VirtualMachine) -> PyResult {
let ok = self.into_pyresult(vm)?;
Ok(ok.to_pyobject(vm))
}
}
type HandleInt = usize; // TODO: change to isize when fully ported to windows-rs
impl TryFromObject for HANDLE {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let handle = HandleInt::try_from_object(vm, obj)?;
Ok(HANDLE(handle as isize))
}
}
impl ToPyObject for HANDLE {
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
(self.0 as HandleInt).to_pyobject(vm)
}
}