{-# LINE 1 "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 "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 "System\\Win32\\NamedPipes.hsc" #-}
pIPE_UNLIMITED_INSTANCES :: DWORD
pIPE_UNLIMITED_INSTANCES = 255
{-# LINE 128 "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 "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
      Bool
r <- CString -> ErrCode -> IO Bool
c_WaitNamedPipe CString
c_name ErrCode
timeout
      ErrCode
e <- IO ErrCode
getLastError
      if | Bool
r                      -> Bool -> IO Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
r
         | ErrCode
e ErrCode -> ErrCode -> Bool
forall a. Eq a => a -> a -> Bool
== ErrCode
eRROR_SEM_TIMEOUT -> Bool -> IO Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
         | Bool
otherwise              -> String -> ErrCode -> IO Bool
forall a. String -> ErrCode -> IO a
failWith String
"waitNamedPipe" ErrCode
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
      
      
      Either IOException HANDLE
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 Either IOException HANDLE
mh :: Either IOException HANDLE of
        Left IOException
e -> do
          ErrCode
errorCode <- IO ErrCode
getLastError
          Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ErrCode
errorCode ErrCode -> ErrCode -> Bool
forall a. Eq a => a -> a -> Bool
/= ErrCode
eRROR_PIPE_BUSY)
            (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IOException -> IO ()
forall e a. Exception e => e -> IO a
throwIO IOException
e
          
          
          Bool
_ <- String -> ErrCode -> IO Bool
waitNamedPipe String
fileName ErrCode
5_000
          IO HANDLE
connectLoop
        Right HANDLE
h -> HANDLE -> IO HANDLE
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 "System\\Win32\\NamedPipes.hsc" #-}
eRROR_SEM_TIMEOUT :: ErrCode
eRROR_SEM_TIMEOUT :: ErrCode
eRROR_SEM_TIMEOUT = ErrCode
121
{-# LINE 278 "System\\Win32\\NamedPipes.hsc" #-}