|
13 | 13 | #![allow(bad_style, dead_code, overflowing_literals)]
|
14 | 14 |
|
15 | 15 | 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}; |
16 | 19 |
|
17 | 20 | pub use self::GET_FILEEX_INFO_LEVELS::*;
|
18 | 21 | pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
|
@@ -240,7 +243,32 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
|
240 | 243 | pub PathBuffer: libc::WCHAR,
|
241 | 244 | }
|
242 | 245 |
|
| 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 | + |
243 | 270 | #[link(name = "ws2_32")]
|
| 271 | +#[link(name = "userenv")] |
244 | 272 | extern "system" {
|
245 | 273 | pub fn WSAStartup(wVersionRequested: libc::WORD,
|
246 | 274 | lpWSAData: LPWSADATA) -> libc::c_int;
|
@@ -295,115 +323,13 @@ extern "system" {
|
295 | 323 | pub fn CancelIo(hFile: libc::HANDLE) -> libc::BOOL;
|
296 | 324 | pub fn CancelIoEx(hFile: libc::HANDLE,
|
297 | 325 | lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
|
298 |
| -} |
299 |
| - |
300 |
| -pub mod compat { |
301 |
| - use prelude::v1::*; |
302 | 326 |
|
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); |
306 | 332 |
|
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" { |
407 | 333 | // FIXME - pInputControl should be PCONSOLE_READCONSOLE_CONTROL
|
408 | 334 | pub fn ReadConsoleW(hConsoleInput: libc::HANDLE,
|
409 | 335 | lpBuffer: libc::LPVOID,
|
@@ -447,10 +373,6 @@ extern "system" {
|
447 | 373 | lpCreationTime: *const libc::FILETIME,
|
448 | 374 | lpLastAccessTime: *const libc::FILETIME,
|
449 | 375 | 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; |
454 | 376 | pub fn GetTempPathW(nBufferLength: libc::DWORD,
|
455 | 377 | lpBuffer: libc::LPCWSTR) -> libc::DWORD;
|
456 | 378 | pub fn OpenProcessToken(ProcessHandle: libc::HANDLE,
|
@@ -483,11 +405,70 @@ extern "system" {
|
483 | 405 | pub fn SwitchToThread() -> libc::BOOL;
|
484 | 406 | pub fn Sleep(dwMilliseconds: libc::DWORD);
|
485 | 407 | pub fn GetProcessId(handle: libc::HANDLE) -> libc::DWORD;
|
486 |
| -} |
487 |
| - |
488 |
| -#[link(name = "userenv")] |
489 |
| -extern "system" { |
490 | 408 | pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE,
|
491 | 409 | lpProfileDir: libc::LPCWSTR,
|
492 | 410 | lpcchSize: *mut libc::DWORD) -> libc::BOOL;
|
493 | 411 | }
|
| 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 | +} |
0 commit comments