{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
module GHC.Windows (
#if defined(javascript_HOST_ARCH)
) where
#else
BOOL,
LPBOOL,
BYTE,
DWORD,
DDWORD,
UINT,
ULONG,
ErrCode,
HANDLE,
LPWSTR,
LPTSTR,
LPCTSTR,
LPVOID,
LPDWORD,
LPSTR,
LPCSTR,
LPCWSTR,
WORD,
UCHAR,
NTSTATUS,
iNFINITE,
iNVALID_HANDLE_VALUE,
throwGetLastError,
failWith,
getLastError,
getErrorMessage,
errCodeToIOError,
failIf,
failIf_,
failIfNull,
failIfZero,
failIfFalse_,
failUnlessSuccess,
failUnlessSuccessOr,
c_maperrno,
c_maperrno_func,
ddwordToDwords,
dwordsToDdword,
nullHANDLE,
) where
import Data.Bits (finiteBitSize, shiftL, shiftR, (.|.), (.&.))
import Data.Char
import Data.OldList
import Data.Maybe
import Data.Word
import Data.Int
import Foreign.C.Error
import Foreign.C.String
import Foreign.C.Types
import Foreign.Ptr
import GHC.Base
import GHC.Enum (maxBound)
import GHC.IO
import GHC.Num
import GHC.Real (fromIntegral)
import System.IO.Error
import qualified Numeric
#include "windows_cconv.h"
type BOOL = Bool
type LPBOOL = Ptr BOOL
type BYTE = Word8
type DWORD = Word32
type UINT = Word32
type ULONG = Word32
type ErrCode = DWORD
type HANDLE = Ptr ()
type LPWSTR = Ptr CWchar
type LPCTSTR = LPTSTR
type LPVOID = Ptr ()
type LPDWORD = Ptr DWORD
type LPSTR = Ptr CChar
type LPCSTR = LPSTR
type LPCWSTR = LPWSTR
type WORD = Word16
type UCHAR = Word8
type NTSTATUS = Int32
nullHANDLE :: HANDLE
nullHANDLE :: HANDLE
nullHANDLE = HANDLE
forall a. Ptr a
nullPtr
type DDWORD = Word64
type LPTSTR = LPWSTR
iNFINITE :: DWORD
iNFINITE :: DWORD
iNFINITE = DWORD
0xFFFFFFFF
iNVALID_HANDLE_VALUE :: HANDLE
iNVALID_HANDLE_VALUE :: HANDLE
iNVALID_HANDLE_VALUE = WordPtr -> HANDLE
forall a. WordPtr -> Ptr a
wordPtrToPtr (-WordPtr
1)
throwGetLastError :: String -> IO a
throwGetLastError :: forall a. String -> IO a
throwGetLastError String
where_from =
IO DWORD
getLastError IO DWORD -> (DWORD -> IO a) -> IO a
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> DWORD -> IO a
forall a. String -> DWORD -> IO a
failWith String
where_from
failWith :: String -> ErrCode -> IO a
failWith :: forall a. String -> DWORD -> IO a
failWith String
fn_name DWORD
err_code =
String -> DWORD -> IO IOError
errCodeToIOError String
fn_name DWORD
err_code IO IOError -> (IOError -> IO a) -> IO a
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IOError -> IO a
forall e a. Exception e => e -> IO a
throwIO
errCodeToIOError :: String -> ErrCode -> IO IOError
errCodeToIOError :: String -> DWORD -> IO IOError
errCodeToIOError String
fn_name DWORD
err_code = do
String
msg <- DWORD -> IO String
getErrorMessage DWORD
err_code
let errno :: Errno
errno = DWORD -> Errno
c_maperrno_func DWORD
err_code
let msg' :: String
msg' = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd Char -> Bool
isSpace String
msg
ioerror :: IOError
ioerror = String -> Errno -> Maybe Handle -> Maybe String -> IOError
errnoToIOError String
fn_name Errno
errno Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing
IOError -> String -> IOError
`ioeSetErrorString` String
msg'
IOError -> IO IOError
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IOError
ioerror
getErrorMessage :: ErrCode -> IO String
getErrorMessage :: DWORD -> IO String
getErrorMessage DWORD
err_code =
IO String -> IO String
forall a. IO a -> IO a
mask_ (IO String -> IO String) -> IO String -> IO String
forall a b. (a -> b) -> a -> b
$ do
LPWSTR
c_msg <- DWORD -> IO LPWSTR
c_getErrorMessage DWORD
err_code
if LPWSTR
c_msg LPWSTR -> LPWSTR -> Bool
forall a. Eq a => a -> a -> Bool
== LPWSTR
forall a. Ptr a
nullPtr
then String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
"Error 0x" String -> String -> String
forall a. [a] -> [a] -> [a]
++ DWORD -> String -> String
forall a. Integral a => a -> String -> String
Numeric.showHex DWORD
err_code String
""
else do String
msg <- LPWSTR -> IO String
peekCWString LPWSTR
c_msg
LPWSTR
_ <- LPWSTR -> IO LPWSTR
forall a. Ptr a -> IO (Ptr a)
localFree LPWSTR
c_msg
String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
msg
failIf :: (a -> Bool) -> String -> IO a -> IO a
failIf :: forall a. (a -> Bool) -> String -> IO a -> IO a
failIf a -> Bool
p String
wh IO a
act = do
a
v <- IO a
act
if a -> Bool
p a
v then String -> IO a
forall a. String -> IO a
throwGetLastError String
wh else a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
v
failIf_ :: (a -> Bool) -> String -> IO a -> IO ()
failIf_ :: forall a. (a -> Bool) -> String -> IO a -> IO ()
failIf_ a -> Bool
p String
wh IO a
act = do
a
v <- IO a
act
if a -> Bool
p a
v then String -> IO ()
forall a. String -> IO a
throwGetLastError String
wh else () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
failIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
failIfNull :: forall a. String -> IO (Ptr a) -> IO (Ptr a)
failIfNull = (Ptr a -> Bool) -> String -> IO (Ptr a) -> IO (Ptr a)
forall a. (a -> Bool) -> String -> IO a -> IO a
failIf (Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr)
failIfZero :: (Eq a, Num a) => String -> IO a -> IO a
failIfZero :: forall a. (Eq a, Num a) => String -> IO a -> IO a
failIfZero = (a -> Bool) -> String -> IO a -> IO a
forall a. (a -> Bool) -> String -> IO a -> IO a
failIf (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0)
failIfFalse_ :: String -> IO Bool -> IO ()
failIfFalse_ :: String -> IO Bool -> IO ()
failIfFalse_ = (Bool -> Bool) -> String -> IO Bool -> IO ()
forall a. (a -> Bool) -> String -> IO a -> IO ()
failIf_ Bool -> Bool
not
failUnlessSuccess :: String -> IO ErrCode -> IO ()
failUnlessSuccess :: String -> IO DWORD -> IO ()
failUnlessSuccess String
fn_name IO DWORD
act = do
DWORD
r <- IO DWORD
act
if DWORD
r DWORD -> DWORD -> Bool
forall a. Eq a => a -> a -> Bool
== DWORD
0 then () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return () else String -> DWORD -> IO ()
forall a. String -> DWORD -> IO a
failWith String
fn_name DWORD
r
failUnlessSuccessOr :: ErrCode -> String -> IO ErrCode -> IO Bool
failUnlessSuccessOr :: DWORD -> String -> IO DWORD -> IO Bool
failUnlessSuccessOr DWORD
val String
fn_name IO DWORD
act = do
DWORD
r <- IO DWORD
act
if DWORD
r DWORD -> DWORD -> Bool
forall a. Eq a => a -> a -> Bool
== DWORD
0 then Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else if DWORD
r DWORD -> DWORD -> Bool
forall a. Eq a => a -> a -> Bool
== DWORD
val then Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
else String -> DWORD -> IO Bool
forall a. String -> DWORD -> IO a
failWith String
fn_name DWORD
r
foreign import ccall unsafe "maperrno"
c_maperrno :: IO ()
foreign import ccall unsafe "maperrno_func"
c_maperrno_func :: ErrCode -> Errno
foreign import ccall unsafe "base_getErrorMessage"
c_getErrorMessage :: DWORD -> IO LPWSTR
foreign import WINDOWS_CCONV unsafe "windows.h LocalFree"
localFree :: Ptr a -> IO (Ptr a)
foreign import WINDOWS_CCONV unsafe "windows.h GetLastError"
getLastError :: IO ErrCode
ddwordToDwords :: DDWORD -> (DWORD,DWORD)
ddwordToDwords :: DDWORD -> (DWORD, DWORD)
ddwordToDwords DDWORD
n =
(DDWORD -> DWORD
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DDWORD
n DDWORD -> Int -> DDWORD
forall a. Bits a => a -> Int -> a
`shiftR` DWORD -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (DWORD
forall a. HasCallStack => a
undefined :: DWORD))
,DDWORD -> DWORD
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DDWORD
n DDWORD -> DDWORD -> DDWORD
forall a. Bits a => a -> a -> a
.&. DWORD -> DDWORD
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DWORD
forall a. Bounded a => a
maxBound :: DWORD)))
dwordsToDdword:: (DWORD,DWORD) -> DDWORD
dwordsToDdword :: (DWORD, DWORD) -> DDWORD
dwordsToDdword (DWORD
hi,DWORD
low) = (DWORD -> DDWORD
forall a b. (Integral a, Num b) => a -> b
fromIntegral DWORD
low) DDWORD -> DDWORD -> DDWORD
forall a. Bits a => a -> a -> a
.|. (DWORD -> DDWORD
forall a b. (Integral a, Num b) => a -> b
fromIntegral DWORD
hi DDWORD -> Int -> DDWORD
forall a. Bits a => a -> Int -> a
`shiftL` DWORD -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize DWORD
hi)
#endif