packages feed

Win32 2.14.1.0 → 2.14.2.0

raw patch · 10 files changed

+260/−13 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ System.Win32.Console: FOCUS_EVENT_RECORD :: BOOL -> FOCUS_EVENT_RECORD
+ System.Win32.Console: FocusEvent :: FOCUS_EVENT_RECORD -> INPUT_RECORD
+ System.Win32.Console: KEY_EVENT_RECORD :: BOOL -> WORD -> WORD -> WORD -> CWchar -> DWORD -> KEY_EVENT_RECORD
+ System.Win32.Console: KeyEvent :: KEY_EVENT_RECORD -> INPUT_RECORD
+ System.Win32.Console: MENU_EVENT_RECORD :: UINT -> MENU_EVENT_RECORD
+ System.Win32.Console: MOUSE_EVENT_RECORD :: COORD -> DWORD -> DWORD -> DWORD -> MOUSE_EVENT_RECORD
+ System.Win32.Console: MenuEvent :: MENU_EVENT_RECORD -> INPUT_RECORD
+ System.Win32.Console: MouseEvent :: MOUSE_EVENT_RECORD -> INPUT_RECORD
+ System.Win32.Console: WINDOW_BUFFER_SIZE_RECORD :: COORD -> WINDOW_BUFFER_SIZE_RECORD
+ System.Win32.Console: WindowBufferSizeEvent :: WINDOW_BUFFER_SIZE_RECORD -> INPUT_RECORD
+ System.Win32.Console: [buttonState] :: MOUSE_EVENT_RECORD -> DWORD
+ System.Win32.Console: [commandId] :: MENU_EVENT_RECORD -> UINT
+ System.Win32.Console: [controlKeyStateK] :: KEY_EVENT_RECORD -> DWORD
+ System.Win32.Console: [controlKeyStateM] :: MOUSE_EVENT_RECORD -> DWORD
+ System.Win32.Console: [eventFlags] :: MOUSE_EVENT_RECORD -> DWORD
+ System.Win32.Console: [keyDown] :: KEY_EVENT_RECORD -> BOOL
+ System.Win32.Console: [mousePosition] :: MOUSE_EVENT_RECORD -> COORD
+ System.Win32.Console: [repeatCount] :: KEY_EVENT_RECORD -> WORD
+ System.Win32.Console: [setFocus] :: FOCUS_EVENT_RECORD -> BOOL
+ System.Win32.Console: [uChar] :: KEY_EVENT_RECORD -> CWchar
+ System.Win32.Console: [virtualKeyCode] :: KEY_EVENT_RECORD -> WORD
+ System.Win32.Console: [virtualScanCode] :: KEY_EVENT_RECORD -> WORD
+ System.Win32.Console: [windowSize] :: WINDOW_BUFFER_SIZE_RECORD -> COORD
+ System.Win32.Console: data INPUT_RECORD
+ System.Win32.Console: data KEY_EVENT_RECORD
+ System.Win32.Console: data MOUSE_EVENT_RECORD
+ System.Win32.Console: newtype FOCUS_EVENT_RECORD
+ System.Win32.Console: newtype MENU_EVENT_RECORD
+ System.Win32.Console: newtype WINDOW_BUFFER_SIZE_RECORD
+ System.Win32.Console: readConsoleInput :: HANDLE -> Int -> Ptr INPUT_RECORD -> IO Int
+ System.Win32.File: replaceFile :: LPCWSTR -> LPCWSTR -> LPCWSTR -> DWORD -> IO ()
+ System.Win32.WindowsString.File: replaceFile :: WindowsString -> WindowsString -> Maybe WindowsString -> DWORD -> IO ()

Files

Graphics/Win32/Window.hsc view
@@ -238,7 +238,7 @@ -} #if defined(i386_HOST_ARCH) foreign import WINDOWS_CCONV unsafe "windows.h SetWindowLongW"-#elif defined(x86_64_HOST_ARCH)+#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import WINDOWS_CCONV unsafe "windows.h SetWindowLongPtrW" #else # error Unknown mingw32 arch@@ -247,7 +247,7 @@  #if defined(i386_HOST_ARCH) foreign import WINDOWS_CCONV unsafe "windows.h GetWindowLongW"-#elif defined(x86_64_HOST_ARCH)+#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import WINDOWS_CCONV unsafe "windows.h GetWindowLongPtrW" #else # error Unknown mingw32 arch
System/Win32/Console.hsc view
@@ -60,7 +60,15 @@ 
         -- * Env
         getEnv,
-        getEnvironment
+        getEnvironment,
+        -- * Console I/O
+        KEY_EVENT_RECORD(..),
+        MOUSE_EVENT_RECORD(..),
+        WINDOW_BUFFER_SIZE_RECORD(..),
+        MENU_EVENT_RECORD(..),
+        FOCUS_EVENT_RECORD(..),
+        INPUT_RECORD(..),
+        readConsoleInput
   ) where
 
 #include <windows.h>
@@ -77,7 +85,7 @@ 
 import GHC.IO (bracket)
 import GHC.IO.Exception (IOException(..), IOErrorType(OtherError))
-import Foreign.Ptr (plusPtr)
+import Foreign.Ptr (plusPtr, Ptr)
 import Foreign.C.Types (CWchar)
 import Foreign.C.String (withCWString, CWString)
 import Foreign.Storable (Storable(..))
@@ -232,3 +240,13 @@   fromUTF16 (c:wcs) = c : fromUTF16 wcs
   fromUTF16 [] = []
 
+-- | Reads all available input records up to the amount specified by the
+-- len parameter.
+readConsoleInput :: HANDLE -> Int -> Ptr INPUT_RECORD -> IO Int
+readConsoleInput handle len inputRecordPtr =
+  alloca $ \numEventsReadPtr -> do
+    poke numEventsReadPtr 0
+    failIfFalse_ "ReadConsoleInput" $
+      c_ReadConsoleInput handle inputRecordPtr (fromIntegral len) numEventsReadPtr
+    numEvents <- peek numEventsReadPtr
+    return $ fromIntegral numEvents
System/Win32/Console/Internal.hsc view
@@ -27,7 +27,7 @@ import System.Win32.Types import Graphics.Win32.GDI.Types (COLORREF) -import Foreign.C.Types (CInt(..))+import Foreign.C.Types (CInt(..), CWchar) import Foreign.C.String (CWString) import Foreign.Ptr (Ptr, plusPtr) import Foreign.Storable (Storable(..))@@ -188,3 +188,149 @@ foreign import WINDOWS_CCONV safe "windows.h GetConsoleScreenBufferInfoEx"     c_GetConsoleScreenBufferInfoEx :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFOEX -> IO BOOL +-- | This type represents a keyboard input event. The structure is documented here:+-- https://learn.microsoft.com/en-us/windows/console/key-event-record-str+data KEY_EVENT_RECORD = KEY_EVENT_RECORD+    { keyDown          :: BOOL+    , repeatCount      :: WORD+    , virtualKeyCode   :: WORD+    , virtualScanCode  :: WORD+    , uChar            :: CWchar+    , controlKeyStateK :: DWORD+    } deriving (Eq, Show)++-- | This type represents a mouse event. The structure is documented here:+-- https://learn.microsoft.com/en-us/windows/console/mouse-event-record-str+data MOUSE_EVENT_RECORD = MOUSE_EVENT_RECORD+  { mousePosition    :: COORD+  , buttonState      :: DWORD+  , controlKeyStateM :: DWORD+  , eventFlags       :: DWORD+  } deriving (Eq, Show)++-- | This type represents a window size change event. The structure is documented here:+-- https://learn.microsoft.com/en-us/windows/console/window-buffer-size-record-str+newtype WINDOW_BUFFER_SIZE_RECORD = WINDOW_BUFFER_SIZE_RECORD+  { windowSize :: COORD+  } deriving (Eq, Show)++-- | This type represents a window menu event. (Current ignored by VTY). The structure+-- is documented here: https://learn.microsoft.com/en-us/windows/console/menu-event-record-str+newtype MENU_EVENT_RECORD = MENU_EVENT_RECORD+  { commandId :: UINT+  } deriving (Eq, Show)++-- | This type represents a window focus change event. The structure is documented here:+-- https://learn.microsoft.com/en-us/windows/console/focus-event-record-str+newtype FOCUS_EVENT_RECORD = FOCUS_EVENT_RECORD+  { setFocus :: BOOL+  } deriving (Eq, Show)++-- | Description of a Windows console input event. Documented here:+-- https://learn.microsoft.com/en-us/windows/console/input-record-str+data INPUT_RECORD =+    KeyEvent KEY_EVENT_RECORD+  | MouseEvent MOUSE_EVENT_RECORD+  | WindowBufferSizeEvent WINDOW_BUFFER_SIZE_RECORD+  | MenuEvent MENU_EVENT_RECORD+  | FocusEvent FOCUS_EVENT_RECORD+  deriving (Eq, Show)++instance Storable KEY_EVENT_RECORD where+    sizeOf = const #{size KEY_EVENT_RECORD}+    alignment _ = #alignment KEY_EVENT_RECORD+    poke buf input = do+        (#poke KEY_EVENT_RECORD, bKeyDown)          buf (keyDown input)+        (#poke KEY_EVENT_RECORD, wRepeatCount)      buf (repeatCount input)+        (#poke KEY_EVENT_RECORD, wVirtualKeyCode)   buf (virtualKeyCode input)+        (#poke KEY_EVENT_RECORD, wVirtualScanCode)  buf (virtualScanCode input)+        (#poke KEY_EVENT_RECORD, uChar)             buf (uChar input)+        (#poke KEY_EVENT_RECORD, dwControlKeyState) buf (controlKeyStateK input)+    peek buf = do+        keyDown'          <- (#peek KEY_EVENT_RECORD, bKeyDown) buf+        repeatCount'      <- (#peek KEY_EVENT_RECORD, wRepeatCount) buf+        virtualKeyCode'   <- (#peek KEY_EVENT_RECORD, wVirtualKeyCode) buf+        virtualScanCode'  <- (#peek KEY_EVENT_RECORD, wVirtualScanCode) buf+        uChar'            <- (#peek KEY_EVENT_RECORD, uChar) buf+        controlKeyStateK' <- (#peek KEY_EVENT_RECORD, dwControlKeyState) buf+        return $ KEY_EVENT_RECORD keyDown' repeatCount' virtualKeyCode' virtualScanCode' uChar' controlKeyStateK'++instance Storable MOUSE_EVENT_RECORD where+    sizeOf = const #{size MOUSE_EVENT_RECORD}+    alignment _ = #alignment MOUSE_EVENT_RECORD+    poke buf input = do+        (#poke MOUSE_EVENT_RECORD, dwMousePosition)   buf (mousePosition input)+        (#poke MOUSE_EVENT_RECORD, dwButtonState)     buf (buttonState input)+        (#poke MOUSE_EVENT_RECORD, dwControlKeyState) buf (controlKeyStateM input)+        (#poke MOUSE_EVENT_RECORD, dwEventFlags)      buf (eventFlags input)+    peek buf = do+        mousePosition'    <- (#peek MOUSE_EVENT_RECORD, dwMousePosition) buf+        buttonState'      <- (#peek MOUSE_EVENT_RECORD, dwButtonState) buf+        controlKeyStateM' <- (#peek MOUSE_EVENT_RECORD, dwControlKeyState) buf+        eventFlags'       <- (#peek MOUSE_EVENT_RECORD, dwEventFlags) buf+        return $ MOUSE_EVENT_RECORD mousePosition' buttonState' controlKeyStateM' eventFlags'++instance Storable WINDOW_BUFFER_SIZE_RECORD where+    sizeOf = const #{size WINDOW_BUFFER_SIZE_RECORD}+    alignment _ = #alignment WINDOW_BUFFER_SIZE_RECORD+    poke buf input = do+        (#poke WINDOW_BUFFER_SIZE_RECORD, dwSize) buf (windowSize input)+    peek buf = do+        size' <- (#peek WINDOW_BUFFER_SIZE_RECORD, dwSize) buf+        return $ WINDOW_BUFFER_SIZE_RECORD size'++instance Storable MENU_EVENT_RECORD where+    sizeOf = const #{size MENU_EVENT_RECORD}+    alignment _ = #alignment MENU_EVENT_RECORD+    poke buf input = do+        (#poke MENU_EVENT_RECORD, dwCommandId) buf (commandId input)+    peek buf = do+        commandId' <- (#peek MENU_EVENT_RECORD, dwCommandId) buf+        return $ MENU_EVENT_RECORD commandId'++instance Storable FOCUS_EVENT_RECORD where+    sizeOf = const #{size FOCUS_EVENT_RECORD}+    alignment _ = #alignment FOCUS_EVENT_RECORD+    poke buf input = do+        (#poke FOCUS_EVENT_RECORD, bSetFocus) buf (setFocus input)+    peek buf = do+        setFocus' <- (#peek FOCUS_EVENT_RECORD, bSetFocus) buf+        return $ FOCUS_EVENT_RECORD setFocus'++instance Storable INPUT_RECORD where+    sizeOf = const #{size INPUT_RECORD}+    alignment _ = #alignment INPUT_RECORD++    poke buf (KeyEvent key) = do+        (#poke INPUT_RECORD, EventType) buf (#{const KEY_EVENT} :: WORD)+        (#poke INPUT_RECORD, Event) buf key+    poke buf (MouseEvent mouse) = do+        (#poke INPUT_RECORD, EventType) buf (#{const MOUSE_EVENT} :: WORD)+        (#poke INPUT_RECORD, Event) buf mouse+    poke buf (WindowBufferSizeEvent window) = do+        (#poke INPUT_RECORD, EventType) buf (#{const WINDOW_BUFFER_SIZE_EVENT} :: WORD)+        (#poke INPUT_RECORD, Event) buf window+    poke buf (MenuEvent menu) = do+        (#poke INPUT_RECORD, EventType) buf (#{const MENU_EVENT} :: WORD)+        (#poke INPUT_RECORD, Event) buf menu+    poke buf (FocusEvent focus) = do+        (#poke INPUT_RECORD, EventType) buf (#{const FOCUS_EVENT} :: WORD)+        (#poke INPUT_RECORD, Event) buf focus++    peek buf = do+        event <- (#peek INPUT_RECORD, EventType) buf :: IO WORD+        case event of+          #{const KEY_EVENT} ->+              KeyEvent `fmap` (#peek INPUT_RECORD, Event) buf+          #{const MOUSE_EVENT} ->+              MouseEvent `fmap` (#peek INPUT_RECORD, Event) buf+          #{const WINDOW_BUFFER_SIZE_EVENT} ->+              WindowBufferSizeEvent `fmap` (#peek INPUT_RECORD, Event) buf+          #{const MENU_EVENT} ->+              MenuEvent `fmap` (#peek INPUT_RECORD, Event) buf+          #{const FOCUS_EVENT} ->+              FocusEvent `fmap` (#peek INPUT_RECORD, Event) buf+          _ -> error $ "Unknown input event type " ++ show event++foreign import WINDOWS_CCONV unsafe "windows.h ReadConsoleInputW"+    c_ReadConsoleInput :: HANDLE -> Ptr INPUT_RECORD -> DWORD -> LPDWORD -> IO BOOL
System/Win32/DebugApi.hsc view
@@ -54,14 +54,22 @@     , useAllRegs     , withThreadContext -#if __i386__+#if defined(i386_HOST_ARCH)     , eax, ebx, ecx, edx, esi, edi, ebp, eip, esp-#elif __x86_64__+#elif defined(x86_64_HOST_ARCH)     , rax, rbx, rcx, rdx, rsi, rdi, rbp, rip, rsp #endif+#if defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH)     , segCs, segDs, segEs, segFs, segGs     , eFlags     , dr+#endif+#if defined(aarch64_HOST_ARCH)+    , x0,   x1,  x2,  x3,  x4,  x5,  x6,  x7,  x8+    , x9,  x10, x11, x12, x13, x14, x15, x16, x17+    , x18, x19, x20, x21, x22, x23, x24, x25, x26+    , x27, x28,  fp,  lr,  sp,  pc+#endif     , setReg, getReg, modReg     , makeModThreadContext     , modifyThreadContext@@ -331,7 +339,7 @@             (act buf)  -#if __i386__+#if defined(i386_HOST_ARCH) eax, ebx, ecx, edx :: Int esi, edi :: Int ebp, eip, esp :: Int@@ -344,7 +352,7 @@ ebp = (#offset CONTEXT, Ebp) eip = (#offset CONTEXT, Eip) esp = (#offset CONTEXT, Esp)-#elif __x86_64__+#elif defined(x86_64_HOST_ARCH) rax, rbx, rcx, rdx :: Int rsi, rdi :: Int rbp, rip, rsp :: Int@@ -357,10 +365,49 @@ rbp = (#offset CONTEXT, Rbp) rip = (#offset CONTEXT, Rip) rsp = (#offset CONTEXT, Rsp)+#elif defined(aarch64_HOST_ARCH)+x0,   x1,  x2,  x3,  x4,  x5,  x6,  x7,  x8 :: Int+x9,  x10, x11, x12, x13, x14, x15, x16, x17 :: Int+x18, x19, x20, x21, x22, x23, x24, x25, x26 :: Int+x27, x28,  fp,  lr,  sp,  pc                :: Int+x0  = (#offset CONTEXT, X0 )+x1  = (#offset CONTEXT, X1 )+x2  = (#offset CONTEXT, X2 )+x3  = (#offset CONTEXT, X3 )+x4  = (#offset CONTEXT, X4 )+x5  = (#offset CONTEXT, X5 )+x6  = (#offset CONTEXT, X6 )+x7  = (#offset CONTEXT, X7 )+x8  = (#offset CONTEXT, X8 )+x9  = (#offset CONTEXT, X9 )+x10 = (#offset CONTEXT, X10)+x11 = (#offset CONTEXT, X11)+x12 = (#offset CONTEXT, X12)+x13 = (#offset CONTEXT, X13)+x14 = (#offset CONTEXT, X14)+x15 = (#offset CONTEXT, X15)+x16 = (#offset CONTEXT, X16)+x17 = (#offset CONTEXT, X17)+x18 = (#offset CONTEXT, X18)+x19 = (#offset CONTEXT, X19)+x20 = (#offset CONTEXT, X20)+x21 = (#offset CONTEXT, X21)+x22 = (#offset CONTEXT, X22)+x23 = (#offset CONTEXT, X23)+x24 = (#offset CONTEXT, X24)+x25 = (#offset CONTEXT, X25)+x26 = (#offset CONTEXT, X26)+x27 = (#offset CONTEXT, X27)+x28 = (#offset CONTEXT, X28)+fp  = (#offset CONTEXT, Fp)+lr  = (#offset CONTEXT, Lr)+sp  = (#offset CONTEXT, Sp)+pc  = (#offset CONTEXT, Pc) #else-#error Unsupported architecture+#error Unknown mingw32 arch #endif +#if defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH) segCs, segDs, segEs, segFs, segGs :: Int segCs = (#offset CONTEXT, SegCs) segDs = (#offset CONTEXT, SegDs)@@ -380,6 +427,7 @@     6 -> (#offset CONTEXT, Dr6)     7 -> (#offset CONTEXT, Dr7)     _ -> undefined+#endif  setReg :: Ptr a -> Int -> DWORD -> IO () setReg = pokeByteOff
System/Win32/File.hsc view
@@ -190,6 +190,7 @@     , removeDirectory     , getBinaryType     , getTempFileName+    , replaceFile        -- * HANDLE operations     , createFile@@ -418,6 +419,10 @@ getFileInformationByHandle h = alloca $ \res -> do     failIfFalseWithRetry_ "GetFileInformationByHandle" $ c_GetFileInformationByHandle h res     peek res++replaceFile :: LPCWSTR -> LPCWSTR -> LPCWSTR -> DWORD -> IO ()+replaceFile replacedFile replacementFile backupFile replaceFlags =+  failIfFalse_ "ReplaceFile" $ c_ReplaceFile replacedFile replacementFile backupFile replaceFlags nullPtr nullPtr  ---------------------------------------------------------------- -- Read/write files
System/Win32/File/Internal.hsc view
@@ -193,6 +193,16 @@  ---------------------------------------------------------------- +type ReplaceType = DWORD++#{enum ReplaceType,+ , rEPLACEFILE_WRITE_THROUGH       = REPLACEFILE_WRITE_THROUGH+ , rEPLACEFILE_IGNORE_MERGE_ERRORS = REPLACEFILE_IGNORE_MERGE_ERRORS+ , rEPLACEFILE_IGNORE_ACL_ERRORS   = REPLACEFILE_IGNORE_ACL_ERRORS+ }++----------------------------------------------------------------+ type FileNotificationFlag = DWORD  #{enum FileNotificationFlag,@@ -366,6 +376,9 @@  foreign import WINDOWS_CCONV unsafe "windows.h GetBinaryTypeW"   c_GetBinaryType :: LPCTSTR -> Ptr DWORD -> IO Bool++foreign import WINDOWS_CCONV unsafe "windows.h ReplaceFileW"+  c_ReplaceFile :: LPCWSTR -> LPCWSTR -> LPCWSTR -> DWORD -> LPVOID -> LPVOID -> IO Bool  ---------------------------------------------------------------- -- HANDLE operations
System/Win32/WindowsString/File.hsc view
@@ -35,6 +35,7 @@     , setVolumeLabel
     , getFileExInfoStandard
     , getFileExMaxInfoLevel
+    , replaceFile
     , module System.Win32.File
     ) where
 
@@ -62,6 +63,7 @@   , setVolumeLabel
   , getFileExInfoStandard
   , getFileExMaxInfoLevel
+  , replaceFile
   )
 import System.Win32.WindowsString.Types
 import System.OsString.Windows
@@ -180,7 +182,16 @@   fname <- peekTString c_buf
   pure (fname, uid)
 
-
+replaceFile :: WindowsString -> WindowsString -> Maybe WindowsString -> DWORD -> IO ()
+replaceFile replacedFile replacementFile mBackupFile replaceFlags =
+  withFilePath replacedFile $ \ c_replacedFile ->
+    withFilePath replacementFile $ \ c_replacementFile ->
+      let getResult f = 
+            case mBackupFile of
+              Nothing -> f nullPtr
+              Just backupFile -> withFilePath backupFile f
+      in getResult $ \ c_backupFile ->
+           failIfFalse_ "ReplaceFile" $ c_ReplaceFile c_replacedFile c_replacementFile c_backupFile replaceFlags nullPtr nullPtr
 
 ----------------------------------------------------------------
 -- File Notifications
Win32.cabal view
@@ -1,6 +1,6 @@ cabal-version:  2.0 name:           Win32-version:        2.14.1.0+version:        2.14.2.0 license:        BSD3 license-file:   LICENSE author:         Alastair Reid, shelarcy, Tamar Christina
changelog.md view
@@ -1,5 +1,11 @@ # Changelog for [`Win32` package](http://hackage.haskell.org/package/Win32) +## 2.14.2.0 November 2024++* Add ReplaceFileW+* Add support for Windows on Arm+* Add ReadConsoleInput+ ## 2.14.1.0 November 2024  * Add getTempFileName
include/windows_cconv.h view
@@ -3,7 +3,7 @@  #if defined(i386_HOST_ARCH) # define WINDOWS_CCONV stdcall-#elif defined(x86_64_HOST_ARCH)+#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) # define WINDOWS_CCONV ccall #else # error Unknown mingw32 arch