@@ -57,10 +57,11 @@ finiteBitSize = bitSize
5757#endif
5858
5959##if defined(__IO_MANAGER_WINIO__)
60+ import GHC.IO.Exception (ioException , IOException (.. ), IOErrorType (InappropriateType ))
6061import GHC.IO.SubSystem ((<!>) )
6162import GHC.IO.Handle.Windows
62- import GHC.IO.Windows.Handle (fromHANDLE , Io (), NativeHandle (),
63- handleToMode , optimizeFileAccess )
63+ import GHC.IO.Windows.Handle (fromHANDLE , Io (), NativeHandle (), ConsoleHandle (),
64+ toHANDLE , handleToMode , optimizeFileAccess )
6465import qualified GHC.Event.Windows as Mgr
6566import GHC.IO.Device (IODeviceType (.. ))
6667##endif
@@ -290,9 +291,28 @@ withHandleToHANDLENative haskell_handle action =
290291 -- getting to it while we are doing horrible manipulations with it, and hence
291292 -- stops it being finalized (and closed).
292293 withStablePtr haskell_handle $ const $ do
293- windows_handle <- handleToHANDLE haskell_handle
294+ -- Grab the write handle variable from the Handle
295+ let write_handle_mvar = case haskell_handle of
296+ FileHandle _ handle_mvar -> handle_mvar
297+ DuplexHandle _ _ handle_mvar -> handle_mvar
298+
299+ -- This is "write" MVar, we could also take the "read" one
300+ windows_handle <- readMVar write_handle_mvar >>= handle_ToHANDLE
301+
294302 -- Do what the user originally wanted
295303 action windows_handle
304+ where
305+ -- | Turn an existing Handle into a Win32 HANDLE. This function throws an
306+ -- IOError if the Handle does not reference a HANDLE
307+ handle_ToHANDLE :: Handle__ -> IO HANDLE
308+ handle_ToHANDLE (Handle__ {haDevice = dev}) =
309+ case (cast dev :: Maybe (Io NativeHandle ), cast dev :: Maybe (Io ConsoleHandle )) of
310+ (Just hwnd, Nothing ) -> return $ toHANDLE hwnd
311+ (Nothing , Just hwnd) -> return $ toHANDLE hwnd
312+ _ -> throwErr " not a known HANDLE"
313+
314+ throwErr msg = ioException $ IOError (Just haskell_handle)
315+ InappropriateType " withHandleToHANDLENative" msg Nothing Nothing
296316##endif
297317
298318withHandleToHANDLEPosix :: Handle -> (HANDLE -> IO a ) -> IO a
0 commit comments