Skip to content

Commit c314ee8

Browse files
authored
Add support for duplex and console handles to withHandleToHANDLE with winio (#192)
1 parent f8f3c78 commit c314ee8

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

System/Win32/Types.hsc

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ finiteBitSize = bitSize
5757
#endif
5858

5959
##if defined(__IO_MANAGER_WINIO__)
60+
import GHC.IO.Exception (ioException, IOException(..), IOErrorType(InappropriateType))
6061
import GHC.IO.SubSystem ((<!>))
6162
import 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)
6465
import qualified GHC.Event.Windows as Mgr
6566
import 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

298318
withHandleToHANDLEPosix :: Handle -> (HANDLE -> IO a) -> IO a

Win32.cabal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Win32
2-
version: 2.13.1.0
2+
version: 2.13.2.0
33
license: BSD3
44
license-file: LICENSE
55
author: Alastair Reid, shelarcy, Tamar Christina
@@ -11,7 +11,7 @@ category: System, Graphics
1111
synopsis: A binding to Windows Win32 API.
1212
description: This library contains direct bindings to the Windows Win32 APIs for Haskell.
1313
build-type: Simple
14-
cabal-version: >= 2.0
14+
cabal-version: 2.0
1515
extra-source-files:
1616
include/diatemp.h include/dumpBMP.h include/ellipse.h include/errors.h
1717
include/Win32Aux.h include/win32debug.h include/alignment.h

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## New - Unreleased
44

55
* Set maximum string size for getComputerName. (See #190)
6+
* Update withHandleToHANDLENative to handle duplex and console handles (See #191)
67

78
## 2.13.1.0 November 2021
89

0 commit comments

Comments
 (0)