{-# 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 :: Word32
pIPE_ACCESS_DUPLEX = Word32
3
pIPE_ACCESS_INBOUND :: OpenMode
pIPE_ACCESS_INBOUND :: Word32
pIPE_ACCESS_INBOUND = Word32
1
pIPE_ACCESS_OUTBOUND :: OpenMode
pIPE_ACCESS_OUTBOUND :: Word32
pIPE_ACCESS_OUTBOUND = Word32
2
{-# LINE 83 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
type PipeMode = UINT
pIPE_TYPE_BYTE :: PipeMode
pIPE_TYPE_BYTE :: Word32
pIPE_TYPE_BYTE = Word32
0
pIPE_TYPE_MESSAGE :: PipeMode
pIPE_TYPE_MESSAGE :: Word32
pIPE_TYPE_MESSAGE = Word32
4
pIPE_READMODE_BYTE :: PipeMode
pIPE_READMODE_BYTE :: Word32
pIPE_READMODE_BYTE = Word32
0
pIPE_READMODE_MESSAGE :: PipeMode
pIPE_READMODE_MESSAGE :: Word32
pIPE_READMODE_MESSAGE = Word32
2
pIPE_WAIT :: PipeMode
pIPE_WAIT :: Word32
pIPE_WAIT = Word32
0
pIPE_NOWAIT :: PipeMode
pIPE_NOWAIT :: Word32
pIPE_NOWAIT = Word32
1
pIPE_ACCEPT_REMOTE_CLIENTS :: PipeMode
pIPE_ACCEPT_REMOTE_CLIENTS :: Word32
pIPE_ACCEPT_REMOTE_CLIENTS = Word32
0
pIPE_REJECT_REMOTE_CLIENTS :: PipeMode
pIPE_REJECT_REMOTE_CLIENTS :: Word32
pIPE_REJECT_REMOTE_CLIENTS = Word32
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
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Maybe LPSECURITY_ATTRIBUTES
-> IO HANDLE
createNamedPipe String
name Word32
openMode Word32
pipeMode
Word32
nMaxInstances Word32
nOutBufferSize Word32
nInBufferSize
Word32
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
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> Word32
-> LPSECURITY_ATTRIBUTES
-> IO HANDLE
c_CreateNamedPipe LPTSTR
c_name Word32
openMode Word32
pipeMode
Word32
nMaxInstances Word32
nOutBufferSize Word32
nInBufferSize
Word32
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 :: Word32
nMPWAIT_USE_DEFAULT_WAIT = Word32
0
nMPWAIT_WAIT_FOREVER :: TimeOut
nMPWAIT_WAIT_FOREVER :: Word32
nMPWAIT_WAIT_FOREVER = Word32
4294967295
{-# LINE 198 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
waitNamedPipe :: String
-> TimeOut
-> IO Bool
waitNamedPipe :: String -> Word32 -> IO Bool
waitNamedPipe String
name Word32
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 -> Word32 -> IO Bool
c_WaitNamedPipe CString
c_name Word32
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
-> Word32
-> Word32
-> Maybe LPSECURITY_ATTRIBUTES
-> Word32
-> Word32
-> Maybe HANDLE
-> IO HANDLE
connect String
fileName Word32
dwDesiredAccess Word32
dwSharedMode Maybe LPSECURITY_ATTRIBUTES
lpSecurityAttributes Word32
dwCreationDisposition Word32
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
-> Word32
-> Word32
-> Maybe LPSECURITY_ATTRIBUTES
-> Word32
-> Word32
-> Maybe HANDLE
-> IO HANDLE
createFile String
fileName
Word32
dwDesiredAccess
Word32
dwSharedMode
Maybe LPSECURITY_ATTRIBUTES
lpSecurityAttributes
Word32
dwCreationDisposition
Word32
dwFlagsAndAttributes
Maybe HANDLE
hTemplateFile
case mh :: Either IOException HANDLE of
Left IOException
e -> do
errorCode <- IO Word32
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 :: Word32
eRROR_PIPE_BUSY = Word32
231
{-# LINE 275 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}
eRROR_SEM_TIMEOUT :: ErrCode
eRROR_SEM_TIMEOUT :: Word32
eRROR_SEM_TIMEOUT = Word32
121
{-# LINE 278 "libraries\\Win32\\System\\Win32\\NamedPipes.hsc" #-}