Skip to content

Commit 6613574

Browse files
committed
---
yaml --- r: 234951 b: refs/heads/stable c: 10b103a h: refs/heads/master i: 234949: 9cfc3da 234947: c658bbc 234943: 26cbd69 v: v3
1 parent 6dcf421 commit 6613574

File tree

11 files changed

+354
-244
lines changed

11 files changed

+354
-244
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 87909582374be91bc5affdd2e74e265077a6e571
32+
refs/heads/stable: 10b103af48368c5df644fa61dc417a36083922c8
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/libstd/dynamic_lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ mod dl {
263263
use sys::os;
264264
use os::windows::prelude::*;
265265
use ptr;
266-
use sys::c::compat::kernel32::SetThreadErrorMode;
266+
use sys::c::SetThreadErrorMode;
267267

268268
pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
269269
// disable "dll load failed" error dialog.

branches/stable/src/libstd/sys/windows/c.rs

Lines changed: 96 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#![allow(bad_style, dead_code, overflowing_literals)]
1414

1515
use libc;
16+
use libc::{c_uint, c_ulong};
17+
use libc::{DWORD, BOOL, BOOLEAN, ERROR_CALL_NOT_IMPLEMENTED, LPVOID, HANDLE};
18+
use libc::{LPCWSTR, LONG};
1619

1720
pub use self::GET_FILEEX_INFO_LEVELS::*;
1821
pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
@@ -240,7 +243,32 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
240243
pub PathBuffer: libc::WCHAR,
241244
}
242245

246+
pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
247+
pub type PSRWLOCK = *mut SRWLOCK;
248+
pub type ULONG = c_ulong;
249+
pub type ULONG_PTR = c_ulong;
250+
251+
#[repr(C)]
252+
pub struct CONDITION_VARIABLE { pub ptr: LPVOID }
253+
#[repr(C)]
254+
pub struct SRWLOCK { pub ptr: LPVOID }
255+
#[repr(C)]
256+
pub struct CRITICAL_SECTION {
257+
CriticalSectionDebug: LPVOID,
258+
LockCount: LONG,
259+
RecursionCount: LONG,
260+
OwningThread: HANDLE,
261+
LockSemaphore: HANDLE,
262+
SpinCount: ULONG_PTR
263+
}
264+
265+
pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE {
266+
ptr: 0 as *mut _,
267+
};
268+
pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: 0 as *mut _ };
269+
243270
#[link(name = "ws2_32")]
271+
#[link(name = "userenv")]
244272
extern "system" {
245273
pub fn WSAStartup(wVersionRequested: libc::WORD,
246274
lpWSAData: LPWSADATA) -> libc::c_int;
@@ -295,115 +323,13 @@ extern "system" {
295323
pub fn CancelIo(hFile: libc::HANDLE) -> libc::BOOL;
296324
pub fn CancelIoEx(hFile: libc::HANDLE,
297325
lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
298-
}
299-
300-
pub mod compat {
301-
use prelude::v1::*;
302326

303-
use ffi::CString;
304-
use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
305-
use sync::atomic::{AtomicUsize, Ordering};
327+
pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
328+
pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
329+
pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
330+
pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
331+
pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
306332

307-
extern "system" {
308-
fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
309-
fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
310-
}
311-
312-
fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
313-
fallback: usize) -> usize {
314-
let mut module: Vec<u16> = module.utf16_units().collect();
315-
module.push(0);
316-
let symbol = CString::new(symbol).unwrap();
317-
let func = unsafe {
318-
let handle = GetModuleHandleW(module.as_ptr());
319-
GetProcAddress(handle, symbol.as_ptr()) as usize
320-
};
321-
let value = if func == 0 {fallback} else {func};
322-
ptr.store(value, Ordering::SeqCst);
323-
value
324-
}
325-
326-
/// Macro for creating a compatibility fallback for a Windows function
327-
///
328-
/// # Examples
329-
/// ```
330-
/// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) {
331-
/// // Fallback implementation
332-
/// })
333-
/// ```
334-
///
335-
/// Note that arguments unused by the fallback implementation should not be
336-
/// called `_` as they are used to be passed to the real function if
337-
/// available.
338-
macro_rules! compat_fn {
339-
($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*)
340-
-> $rettype:ty { $fallback:expr }) => (
341-
#[inline(always)]
342-
pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
343-
use sync::atomic::{AtomicUsize, Ordering};
344-
use mem;
345-
346-
static PTR: AtomicUsize = AtomicUsize::new(0);
347-
348-
fn load() -> usize {
349-
::sys::c::compat::store_func(&PTR,
350-
stringify!($module),
351-
stringify!($symbol),
352-
fallback as usize)
353-
}
354-
355-
extern "system" fn fallback($($argname: $argtype),*)
356-
-> $rettype { $fallback }
357-
358-
let addr = match PTR.load(Ordering::SeqCst) {
359-
0 => load(),
360-
n => n,
361-
};
362-
let f: extern "system" fn($($argtype),*) -> $rettype =
363-
mem::transmute(addr);
364-
f($($argname),*)
365-
}
366-
)
367-
}
368-
369-
/// Compatibility layer for functions in `kernel32.dll`
370-
///
371-
/// Latest versions of Windows this is needed for:
372-
///
373-
/// * `CreateSymbolicLinkW`: Windows XP, Windows Server 2003
374-
/// * `GetFinalPathNameByHandleW`: Windows XP, Windows Server 2003
375-
pub mod kernel32 {
376-
use libc::c_uint;
377-
use libc::types::os::arch::extra::{DWORD, LPCWSTR, BOOLEAN, HANDLE};
378-
use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
379-
use sys::c::SetLastError;
380-
381-
compat_fn! {
382-
kernel32::CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
383-
_lpTargetFileName: LPCWSTR,
384-
_dwFlags: DWORD) -> BOOLEAN {
385-
unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
386-
}
387-
}
388-
389-
compat_fn! {
390-
kernel32::GetFinalPathNameByHandleW(_hFile: HANDLE,
391-
_lpszFilePath: LPCWSTR,
392-
_cchFilePath: DWORD,
393-
_dwFlags: DWORD) -> DWORD {
394-
unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
395-
}
396-
}
397-
398-
compat_fn! {
399-
kernel32::SetThreadErrorMode(_dwNewMode: DWORD, _lpOldMode: *mut DWORD) -> c_uint {
400-
unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
401-
}
402-
}
403-
}
404-
}
405-
406-
extern "system" {
407333
// FIXME - pInputControl should be PCONSOLE_READCONSOLE_CONTROL
408334
pub fn ReadConsoleW(hConsoleInput: libc::HANDLE,
409335
lpBuffer: libc::LPVOID,
@@ -447,10 +373,6 @@ extern "system" {
447373
lpCreationTime: *const libc::FILETIME,
448374
lpLastAccessTime: *const libc::FILETIME,
449375
lpLastWriteTime: *const libc::FILETIME) -> libc::BOOL;
450-
pub fn SetFileInformationByHandle(hFile: libc::HANDLE,
451-
FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
452-
lpFileInformation: libc::LPVOID,
453-
dwBufferSize: libc::DWORD) -> libc::BOOL;
454376
pub fn GetTempPathW(nBufferLength: libc::DWORD,
455377
lpBuffer: libc::LPCWSTR) -> libc::DWORD;
456378
pub fn OpenProcessToken(ProcessHandle: libc::HANDLE,
@@ -483,11 +405,70 @@ extern "system" {
483405
pub fn SwitchToThread() -> libc::BOOL;
484406
pub fn Sleep(dwMilliseconds: libc::DWORD);
485407
pub fn GetProcessId(handle: libc::HANDLE) -> libc::DWORD;
486-
}
487-
488-
#[link(name = "userenv")]
489-
extern "system" {
490408
pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE,
491409
lpProfileDir: libc::LPCWSTR,
492410
lpcchSize: *mut libc::DWORD) -> libc::BOOL;
493411
}
412+
413+
// Functions that aren't available on Windows XP, but we still use them and just
414+
// provide some form of a fallback implementation.
415+
compat_fn! {
416+
kernel32:
417+
418+
pub fn CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
419+
_lpTargetFileName: LPCWSTR,
420+
_dwFlags: DWORD) -> BOOLEAN {
421+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
422+
}
423+
pub fn GetFinalPathNameByHandleW(_hFile: HANDLE,
424+
_lpszFilePath: LPCWSTR,
425+
_cchFilePath: DWORD,
426+
_dwFlags: DWORD) -> DWORD {
427+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
428+
}
429+
pub fn SetThreadErrorMode(_dwNewMode: DWORD,
430+
_lpOldMode: *mut DWORD) -> c_uint {
431+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
432+
}
433+
pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL {
434+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
435+
}
436+
pub fn SetFileInformationByHandle(_hFile: HANDLE,
437+
_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
438+
_lpFileInformation: LPVOID,
439+
_dwBufferSize: DWORD) -> BOOL {
440+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
441+
}
442+
pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE,
443+
SRWLock: PSRWLOCK,
444+
dwMilliseconds: DWORD,
445+
Flags: ULONG) -> BOOL {
446+
panic!("condition variables not available")
447+
}
448+
pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE)
449+
-> () {
450+
panic!("condition variables not available")
451+
}
452+
pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE)
453+
-> () {
454+
panic!("condition variables not available")
455+
}
456+
pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
457+
panic!("rwlocks not available")
458+
}
459+
pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK) -> () {
460+
panic!("rwlocks not available")
461+
}
462+
pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
463+
panic!("rwlocks not available")
464+
}
465+
pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK) -> () {
466+
panic!("rwlocks not available")
467+
}
468+
pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN {
469+
panic!("rwlocks not available")
470+
}
471+
pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN {
472+
panic!("rwlocks not available")
473+
}
474+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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.
4+
//
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.
10+
11+
//! A "compatibility layer" for spanning XP and Windows 7
12+
//!
13+
//! The standard library currently binds many functions that are not available
14+
//! on Windows XP, but we would also like to support building executables that
15+
//! run on XP. To do this we specify all non-XP APIs as having a fallback
16+
//! implementation to do something reasonable.
17+
//!
18+
//! This dynamic runtime detection of whether a function is available is
19+
//! implemented with `GetModuleHandle` and `GetProcAddress` paired with a
20+
//! static-per-function which caches the result of the first check. In this
21+
//! manner we pay a semi-large one-time cost up front for detecting whether a
22+
//! function is available but afterwards it's just a load and a jump.
23+
24+
use prelude::v1::*;
25+
26+
use ffi::CString;
27+
use libc::{LPVOID, LPCWSTR, HMODULE, LPCSTR};
28+
use sync::atomic::{AtomicUsize, Ordering};
29+
30+
extern "system" {
31+
fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
32+
fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
33+
}
34+
35+
pub fn lookup(module: &str, symbol: &str) -> Option<usize> {
36+
let mut module: Vec<u16> = module.utf16_units().collect();
37+
module.push(0);
38+
let symbol = CString::new(symbol).unwrap();
39+
unsafe {
40+
let handle = GetModuleHandleW(module.as_ptr());
41+
match GetProcAddress(handle, symbol.as_ptr()) as usize {
42+
0 => None,
43+
n => Some(n),
44+
}
45+
}
46+
}
47+
48+
pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
49+
fallback: usize) -> usize {
50+
let value = lookup(module, symbol).unwrap_or(fallback);
51+
ptr.store(value, Ordering::SeqCst);
52+
value
53+
}
54+
55+
macro_rules! compat_fn {
56+
($module:ident: $(
57+
pub fn $symbol:ident($($argname:ident: $argtype:ty),*)
58+
-> $rettype:ty {
59+
$($body:expr);*
60+
}
61+
)*) => ($(
62+
#[allow(unused_variables)]
63+
pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
64+
use sync::atomic::{AtomicUsize, Ordering};
65+
use mem;
66+
type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
67+
68+
static PTR: AtomicUsize = AtomicUsize::new(0);
69+
70+
fn load() -> usize {
71+
::sys::compat::store_func(&PTR,
72+
stringify!($module),
73+
stringify!($symbol),
74+
fallback as usize)
75+
}
76+
unsafe extern "system" fn fallback($($argname: $argtype),*)
77+
-> $rettype {
78+
$($body);*
79+
}
80+
81+
let addr = match PTR.load(Ordering::SeqCst) {
82+
0 => load(),
83+
n => n,
84+
};
85+
mem::transmute::<usize, F>(addr)($($argname),*)
86+
}
87+
)*)
88+
}

0 commit comments

Comments
 (0)