{-# LINE 1 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NumericUnderscores #-}
module System.Win32.NamedPipes (
createNamedPipe,
pIPE_UNLIMITED_INSTANCES,
LPSECURITY_ATTRIBUTES,
OpenMode,
pIPE_ACCESS_DUPLEX,
pIPE_ACCESS_INBOUND,
pIPE_ACCESS_OUTBOUND,
fILE_FLAG_OVERLAPPED,
PipeMode,
pIPE_TYPE_BYTE,
pIPE_TYPE_MESSAGE,
pIPE_READMODE_BYTE,
pIPE_READMODE_MESSAGE,
pIPE_WAIT,
pIPE_NOWAIT,
pIPE_ACCEPT_REMOTE_CLIENTS,
pIPE_REJECT_REMOTE_CLIENTS,
connect,
waitNamedPipe,
TimeOut,
nMPWAIT_USE_DEFAULT_WAIT,
nMPWAIT_WAIT_FOREVER,
) where
import Control.Exception
import Control.Monad (when)
import Foreign.C.String (withCString)
import System.Win32.Types hiding (try)
import System.Win32.File
type OpenMode = UINT
pIPE_ACCESS_DUPLEX :: OpenMode
pIPE_ACCESS_DUPLEX :: ErrCode
pIPE_ACCESS_DUPLEX = ErrCode
3
pIPE_ACCESS_INBOUND :: OpenMode
pIPE_ACCESS_INBOUND :: ErrCode
pIPE_ACCESS_INBOUND = ErrCode
1
pIPE_ACCESS_OUTBOUND :: OpenMode
pIPE_ACCESS_OUTBOUND :: ErrCode
pIPE_ACCESS_OUTBOUND = ErrCode
2
{-# LINE 83 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
type PipeMode = UINT
pIPE_TYPE_BYTE :: PipeMode
pIPE_TYPE_BYTE :: ErrCode
pIPE_TYPE_BYTE = ErrCode
0
pIPE_TYPE_MESSAGE :: PipeMode
pIPE_TYPE_MESSAGE :: ErrCode
pIPE_TYPE_MESSAGE = ErrCode
4
pIPE_READMODE_BYTE :: PipeMode
pIPE_READMODE_BYTE :: ErrCode
pIPE_READMODE_BYTE = ErrCode
0
pIPE_READMODE_MESSAGE :: PipeMode
pIPE_READMODE_MESSAGE :: ErrCode
pIPE_READMODE_MESSAGE = ErrCode
2
pIPE_WAIT :: PipeMode
pIPE_WAIT :: ErrCode
pIPE_WAIT = ErrCode
0
pIPE_NOWAIT :: PipeMode
pIPE_NOWAIT :: ErrCode
pIPE_NOWAIT = ErrCode
1
pIPE_ACCEPT_REMOTE_CLIENTS :: PipeMode
pIPE_ACCEPT_REMOTE_CLIENTS :: ErrCode
pIPE_ACCEPT_REMOTE_CLIENTS = ErrCode
0
pIPE_REJECT_REMOTE_CLIENTS :: PipeMode
pIPE_REJECT_REMOTE_CLIENTS :: ErrCode
pIPE_REJECT_REMOTE_CLIENTS = ErrCode
8
{-# LINE 122 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
pIPE_UNLIMITED_INSTANCES :: DWORD
pIPE_UNLIMITED_INSTANCES = 255
{-# LINE 128 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
createNamedPipe :: String
-> OpenMode
-> PipeMode
-> DWORD
-> DWORD
-> DWORD
-> DWORD
-> Maybe LPSECURITY_ATTRIBUTES
-> IO HANDLE
createNamedPipe :: String
-> ErrCode
-> ErrCode
-> ErrCode
-> ErrCode
-> ErrCode
-> ErrCode
-> Maybe LPSECURITY_ATTRIBUTES
-> IO HANDLE
createNamedPipe String
name ErrCode
openMode ErrCode
pipeMode
ErrCode
nMaxInstances ErrCode
nOutBufferSize ErrCode
nInBufferSize
ErrCode
nDefaultTimeOut Maybe LPSECURITY_ATTRIBUTES
mb_attr =
String -> (LPTSTR -> IO HANDLE) -> IO HANDLE
forall a. String -> (LPTSTR -> IO a) -> IO a
withTString String
name ((LPTSTR -> IO HANDLE) -> IO HANDLE)
-> (LPTSTR -> IO HANDLE) -> IO HANDLE
forall a b. (a -> b) -> a -> b
$ \ LPTSTR
c_name ->
(HANDLE -> Bool) -> String -> IO HANDLE -> IO HANDLE
forall a. (a -> Bool) -> String -> IO a -> IO a
failIf (HANDLE -> HANDLE -> Bool
forall a. Eq a => a -> a -> Bool
==HANDLE
iNVALID_HANDLE_VALUE) (String
"CreateNamedPipe ('" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"')") (IO HANDLE -> IO HANDLE) -> IO HANDLE -> IO HANDLE
forall a b. (a -> b) -> a -> b
$
LPTSTR
-> ErrCode
-> ErrCode
-> ErrCode
-> ErrCode
-> ErrCode
-> ErrCode
-> LPSECURITY_ATTRIBUTES
-> IO HANDLE
c_CreateNamedPipe LPTSTR
c_name ErrCode
openMode ErrCode
pipeMode
ErrCode
nMaxInstances ErrCode
nOutBufferSize ErrCode
nInBufferSize
ErrCode
nDefaultTimeOut (Maybe LPSECURITY_ATTRIBUTES -> LPSECURITY_ATTRIBUTES
forall a. Maybe (Ptr a) -> Ptr a
maybePtr Maybe LPSECURITY_ATTRIBUTES
mb_attr)
foreign import ccall unsafe "windows.h CreateNamedPipeW"
c_CreateNamedPipe :: LPCTSTR
-> DWORD
-> DWORD
-> DWORD
-> DWORD
-> DWORD
-> DWORD
-> LPSECURITY_ATTRIBUTES
-> IO HANDLE
type TimeOut = DWORD
nMPWAIT_USE_DEFAULT_WAIT :: TimeOut
nMPWAIT_USE_DEFAULT_WAIT :: ErrCode
nMPWAIT_USE_DEFAULT_WAIT = ErrCode
0
nMPWAIT_WAIT_FOREVER :: TimeOut
nMPWAIT_WAIT_FOREVER :: ErrCode
nMPWAIT_WAIT_FOREVER = ErrCode
4294967295
{-# LINE 198 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
waitNamedPipe :: String
-> TimeOut
-> IO Bool
waitNamedPipe :: String -> ErrCode -> IO Bool
waitNamedPipe String
name ErrCode
timeout =
String -> (CString -> IO Bool) -> IO Bool
forall a. String -> (CString -> IO a) -> IO a
withCString String
name ((CString -> IO Bool) -> IO Bool)
-> (CString -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \ CString
c_name -> do
r <- CString -> ErrCode -> IO Bool
c_WaitNamedPipe CString
c_name ErrCode
timeout
e <- getLastError
if | r -> pure r
| e == eRROR_SEM_TIMEOUT -> pure False
| otherwise -> failWith "waitNamedPipe" e
foreign import ccall safe "windows.h WaitNamedPipeA"
c_WaitNamedPipe :: LPCSTR
-> DWORD
-> IO BOOL
connect :: String
-> AccessMode
-> ShareMode
-> Maybe LPSECURITY_ATTRIBUTES
-> CreateMode
-> FileAttributeOrFlag
-> Maybe HANDLE
-> IO HANDLE
connect :: String
-> ErrCode
-> ErrCode
-> Maybe LPSECURITY_ATTRIBUTES
-> ErrCode
-> ErrCode
-> Maybe HANDLE
-> IO HANDLE
connect String
fileName ErrCode
dwDesiredAccess ErrCode
dwSharedMode Maybe LPSECURITY_ATTRIBUTES
lpSecurityAttributes ErrCode
dwCreationDisposition ErrCode
dwFlagsAndAttributes Maybe HANDLE
hTemplateFile = IO HANDLE
connectLoop
where
connectLoop :: IO HANDLE
connectLoop = do
mh <- IO HANDLE -> IO (Either IOException HANDLE)
forall e a. Exception e => IO a -> IO (Either e a)
try (IO HANDLE -> IO (Either IOException HANDLE))
-> IO HANDLE -> IO (Either IOException HANDLE)
forall a b. (a -> b) -> a -> b
$
String
-> ErrCode
-> ErrCode
-> Maybe LPSECURITY_ATTRIBUTES
-> ErrCode
-> ErrCode
-> Maybe HANDLE
-> IO HANDLE
createFile String
fileName
ErrCode
dwDesiredAccess
ErrCode
dwSharedMode
Maybe LPSECURITY_ATTRIBUTES
lpSecurityAttributes
ErrCode
dwCreationDisposition
ErrCode
dwFlagsAndAttributes
Maybe HANDLE
hTemplateFile
case mh :: Either IOException HANDLE of
Left IOException
e -> do
errorCode <- IO ErrCode
getLastError
when (errorCode /= eRROR_PIPE_BUSY)
$ throwIO e
_ <- waitNamedPipe fileName 5_000
connectLoop
Right HANDLE
h -> HANDLE -> IO HANDLE
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure HANDLE
h
eRROR_PIPE_BUSY :: ErrCode
eRROR_PIPE_BUSY :: ErrCode
eRROR_PIPE_BUSY = ErrCode
231
{-# LINE 275 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
eRROR_SEM_TIMEOUT :: ErrCode
eRROR_SEM_TIMEOUT :: ErrCode
eRROR_SEM_TIMEOUT = ErrCode
121
{-# LINE 278 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}