mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #5085 from youknowone/windows
port winapi to windows-sys
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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
68
vm/src/windows.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user