1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! C definitions used by libnative that don't belong in liblibc
13 #![allow(overflowing_literals)]
15 #![allow(non_camel_case_types)]
20 pub const WSADESCRIPTION_LEN
: uint
= 256;
21 pub const WSASYS_STATUS_LEN
: uint
= 128;
22 pub const FIONBIO
: libc
::c_long
= 0x8004667e;
23 pub const FD_SETSIZE
: uint
= 64;
24 pub const MSG_DONTWAIT
: libc
::c_int
= 0;
25 pub const ERROR_ILLEGAL_CHARACTER
: libc
::c_int
= 582;
26 pub const ENABLE_ECHO_INPUT
: libc
::DWORD
= 0x4;
27 pub const ENABLE_EXTENDED_FLAGS
: libc
::DWORD
= 0x80;
28 pub const ENABLE_INSERT_MODE
: libc
::DWORD
= 0x20;
29 pub const ENABLE_LINE_INPUT
: libc
::DWORD
= 0x2;
30 pub const ENABLE_PROCESSED_INPUT
: libc
::DWORD
= 0x1;
31 pub const ENABLE_QUICK_EDIT_MODE
: libc
::DWORD
= 0x40;
32 pub const WSA_INVALID_EVENT
: WSAEVENT
= 0 as WSAEVENT
;
34 pub const FD_ACCEPT
: libc
::c_long
= 0x08;
35 pub const FD_MAX_EVENTS
: uint
= 10;
36 pub const WSA_INFINITE
: libc
::DWORD
= libc
::INFINITE
;
37 pub const WSA_WAIT_TIMEOUT
: libc
::DWORD
= libc
::consts
::os
::extra
::WAIT_TIMEOUT
;
38 pub const WSA_WAIT_EVENT_0
: libc
::DWORD
= libc
::consts
::os
::extra
::WAIT_OBJECT_0
;
39 pub const WSA_WAIT_FAILED
: libc
::DWORD
= libc
::consts
::os
::extra
::WAIT_FAILED
;
42 #[cfg(target_arch = "x86")]
44 pub wVersion
: libc
::WORD
,
45 pub wHighVersion
: libc
::WORD
,
46 pub szDescription
: [u8; WSADESCRIPTION_LEN
+ 1],
47 pub szSystemStatus
: [u8; WSASYS_STATUS_LEN
+ 1],
50 pub lpVendorInfo
: *mut u8,
53 #[cfg(target_arch = "x86_64")]
55 pub wVersion
: libc
::WORD
,
56 pub wHighVersion
: libc
::WORD
,
59 pub lpVendorInfo
: *mut u8,
60 pub szDescription
: [u8; WSADESCRIPTION_LEN
+ 1],
61 pub szSystemStatus
: [u8; WSASYS_STATUS_LEN
+ 1],
64 pub type LPWSADATA
= *mut WSADATA
;
67 pub struct WSANETWORKEVENTS
{
68 pub lNetworkEvents
: libc
::c_long
,
69 pub iErrorCode
: [libc
::c_int
; FD_MAX_EVENTS
],
72 pub type LPWSANETWORKEVENTS
= *mut WSANETWORKEVENTS
;
74 pub type WSAEVENT
= libc
::HANDLE
;
78 fd_count
: libc
::c_uint
,
79 fd_array
: [libc
::SOCKET
; FD_SETSIZE
],
82 pub fn fd_set(set
: &mut fd_set
, s
: libc
::SOCKET
) {
83 set
.fd_array
[set
.fd_count
as uint
] = s
;
87 pub type SHORT
= libc
::c_short
;
96 pub struct SMALL_RECT
{
104 pub struct CONSOLE_SCREEN_BUFFER_INFO
{
106 pub dwCursorPosition
: COORD
,
107 pub wAttributes
: libc
::WORD
,
108 pub srWindow
: SMALL_RECT
,
109 pub dwMaximumWindowSize
: COORD
,
111 pub type PCONSOLE_SCREEN_BUFFER_INFO
= *mut CONSOLE_SCREEN_BUFFER_INFO
;
113 #[link(name = "ws2_32")]
115 pub fn WSAStartup(wVersionRequested
: libc
::WORD
,
116 lpWSAData
: LPWSADATA
) -> libc
::c_int
;
117 pub fn WSAGetLastError() -> libc
::c_int
;
118 pub fn WSACloseEvent(hEvent
: WSAEVENT
) -> libc
::BOOL
;
119 pub fn WSACreateEvent() -> WSAEVENT
;
120 pub fn WSAEventSelect(s
: libc
::SOCKET
,
121 hEventObject
: WSAEVENT
,
122 lNetworkEvents
: libc
::c_long
) -> libc
::c_int
;
123 pub fn WSASetEvent(hEvent
: WSAEVENT
) -> libc
::BOOL
;
124 pub fn WSAWaitForMultipleEvents(cEvents
: libc
::DWORD
,
125 lphEvents
: *const WSAEVENT
,
126 fWaitAll
: libc
::BOOL
,
127 dwTimeout
: libc
::DWORD
,
128 fAltertable
: libc
::BOOL
) -> libc
::DWORD
;
129 pub fn WSAEnumNetworkEvents(s
: libc
::SOCKET
,
130 hEventObject
: WSAEVENT
,
131 lpNetworkEvents
: LPWSANETWORKEVENTS
)
134 pub fn ioctlsocket(s
: libc
::SOCKET
, cmd
: libc
::c_long
,
135 argp
: *mut libc
::c_ulong
) -> libc
::c_int
;
136 pub fn select(nfds
: libc
::c_int
,
137 readfds
: *mut fd_set
,
138 writefds
: *mut fd_set
,
139 exceptfds
: *mut fd_set
,
140 timeout
: *mut libc
::timeval
) -> libc
::c_int
;
141 pub fn getsockopt(sockfd
: libc
::SOCKET
,
143 optname
: libc
::c_int
,
144 optval
: *mut libc
::c_char
,
145 optlen
: *mut libc
::c_int
) -> libc
::c_int
;
147 pub fn SetEvent(hEvent
: libc
::HANDLE
) -> libc
::BOOL
;
148 pub fn WaitForMultipleObjects(nCount
: libc
::DWORD
,
149 lpHandles
: *const libc
::HANDLE
,
150 bWaitAll
: libc
::BOOL
,
151 dwMilliseconds
: libc
::DWORD
) -> libc
::DWORD
;
153 pub fn CancelIo(hFile
: libc
::HANDLE
) -> libc
::BOOL
;
154 pub fn CancelIoEx(hFile
: libc
::HANDLE
,
155 lpOverlapped
: libc
::LPOVERLAPPED
) -> libc
::BOOL
;
159 use intrinsics
::{atomic_store_relaxed, transmute}
;
160 use libc
::types
::os
::arch
::extra
::{LPCWSTR, HMODULE, LPCSTR, LPVOID}
;
165 fn GetModuleHandleW(lpModuleName
: LPCWSTR
) -> HMODULE
;
166 fn GetProcAddress(hModule
: HMODULE
, lpProcName
: LPCSTR
) -> LPVOID
;
169 // store_func() is idempotent, so using relaxed ordering for the atomics
170 // should be enough. This way, calling a function in this compatibility
171 // layer (after it's loaded) shouldn't be any slower than a regular DLL
173 unsafe fn store_func(ptr
: *mut uint
, module
: &str, symbol
: &str, fallback
: uint
) {
174 let mut module
: Vec
<u16> = module
.utf16_units().collect();
176 let symbol
= CString
::from_slice(symbol
.as_bytes());
177 let handle
= GetModuleHandleW(module
.as_ptr());
178 let func
: uint
= transmute(GetProcAddress(handle
, symbol
.as_ptr()));
179 atomic_store_relaxed(ptr
, if func
== 0 {
186 /// Macro for creating a compatibility fallback for a Windows function
190 /// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) {
191 /// // Fallback implementation
195 /// Note that arguments unused by the fallback implementation should not be called `_` as
196 /// they are used to be passed to the real function if available.
197 macro_rules
! compat_fn
{
198 ($module
:ident
::$symbol
:ident($
($argname
:ident
: $argtype
:ty
),*)
199 -> $rettype
:ty { $fallback:expr }
) => (
201 pub unsafe fn $
symbol($
($argname
: $argtype
),*) -> $rettype
{
202 static mut ptr
: extern "system" fn($
($argname
: $argtype
),*) -> $rettype
= thunk
;
204 extern "system" fn thunk($
($argname
: $argtype
),*) -> $rettype
{
206 ::sys
::c
::compat
::store_func(&mut ptr
as *mut _
as *mut uint
,
210 ::intrinsics
::atomic_load_relaxed(&ptr
)($
($argname
),*)
214 extern "system" fn fallback($
($argname
: $argtype
),*)
215 -> $rettype { $fallback }
217 ::intrinsics
::atomic_load_relaxed(&ptr
)($
($argname
),*)
222 /// Compatibility layer for functions in `kernel32.dll`
224 /// Latest versions of Windows this is needed for:
226 /// * `CreateSymbolicLinkW`: Windows XP, Windows Server 2003
227 /// * `GetFinalPathNameByHandleW`: Windows XP, Windows Server 2003
229 use libc
::types
::os
::arch
::extra
::{DWORD, LPCWSTR, BOOLEAN, HANDLE}
;
230 use libc
::consts
::os
::extra
::ERROR_CALL_NOT_IMPLEMENTED
;
233 fn SetLastError(dwErrCode
: DWORD
);
237 kernel32
::CreateSymbolicLinkW(_lpSymlinkFileName
: LPCWSTR
,
238 _lpTargetFileName
: LPCWSTR
,
239 _dwFlags
: DWORD
) -> BOOLEAN
{
240 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
245 kernel32
::GetFinalPathNameByHandleW(_hFile
: HANDLE
,
246 _lpszFilePath
: LPCWSTR
,
248 _dwFlags
: DWORD
) -> DWORD
{
249 unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
256 // FIXME - pInputControl should be PCONSOLE_READCONSOLE_CONTROL
257 pub fn ReadConsoleW(hConsoleInput
: libc
::HANDLE
,
258 lpBuffer
: libc
::LPVOID
,
259 nNumberOfCharsToRead
: libc
::DWORD
,
260 lpNumberOfCharsRead
: libc
::LPDWORD
,
261 pInputControl
: libc
::LPVOID
) -> libc
::BOOL
;
263 pub fn WriteConsoleW(hConsoleOutput
: libc
::HANDLE
,
264 lpBuffer
: libc
::types
::os
::arch
::extra
::LPCVOID
,
265 nNumberOfCharsToWrite
: libc
::DWORD
,
266 lpNumberOfCharsWritten
: libc
::LPDWORD
,
267 lpReserved
: libc
::LPVOID
) -> libc
::BOOL
;
269 pub fn GetConsoleMode(hConsoleHandle
: libc
::HANDLE
,
270 lpMode
: libc
::LPDWORD
) -> libc
::BOOL
;
272 pub fn SetConsoleMode(hConsoleHandle
: libc
::HANDLE
,
273 lpMode
: libc
::DWORD
) -> libc
::BOOL
;
274 pub fn GetConsoleScreenBufferInfo(
275 hConsoleOutput
: libc
::HANDLE
,
276 lpConsoleScreenBufferInfo
: PCONSOLE_SCREEN_BUFFER_INFO
,