diff --git a/System/Win32.hs b/System/Win32.hs
--- a/System/Win32.hs
+++ b/System/Win32.hs
@@ -19,6 +19,7 @@
 
 module System.Win32
         ( module System.Win32.DLL
+        , module System.Win32.Event
         , module System.Win32.File
         , module System.Win32.FileMapping
         , module System.Win32.Info
@@ -40,6 +41,7 @@
         ) where
 
 import System.Win32.DLL
+import System.Win32.Event
 import System.Win32.File
 import System.Win32.FileMapping
 import System.Win32.Info
diff --git a/System/Win32/Event.hsc b/System/Win32/Event.hsc
new file mode 100644
--- /dev/null
+++ b/System/Win32/Event.hsc
@@ -0,0 +1,133 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  System.Win32.Event
+-- Copyright   :  (c) Esa Ilari Vuokko, 2006
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Esa Ilari Vuokko <ei@vuokko.info>
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- A collection of FFI declarations for interfacing with Win32 event system between
+-- processes.
+--
+-----------------------------------------------------------------------------
+module System.Win32.Event where
+
+import Foreign.Marshal.Alloc     ( alloca )
+import Foreign.Marshal.Array     ( withArrayLen )
+import Foreign.Marshal.Utils     ( maybeWith, with )
+import Foreign.Ptr               ( Ptr, nullPtr )
+import Foreign.Storable          ( Storable(..) )
+import Graphics.Win32.Misc       ( MilliSeconds )
+import System.Win32.File         ( AccessMode, LPSECURITY_ATTRIBUTES, SECURITY_ATTRIBUTES )
+import System.Win32.Types        ( LPCTSTR, HANDLE, BOOL, withTString, failIf, failIfFalse_  )
+import System.Win32.Word         ( DWORD )
+
+##include "windows_cconv.h"
+
+#include "windows.h"
+#include "winuser_compat.h"
+#include "alignment.h"
+
+---------------------------------------------------------------------------
+-- Enums
+---------------------------------------------------------------------------
+type DuplicateOption = DWORD
+#{enum DuplicateOption,
+    , dUPLICATE_CLOSE_SOURCE = DUPLICATE_CLOSE_SOURCE
+    , dUPLICATE_SAME_ACCESS  = DUPLICATE_SAME_ACCESS
+    }
+
+#{enum AccessMode,
+    , eVENT_ALL_ACCESS   = EVENT_ALL_ACCESS
+    , eVENT_MODIFY_STATE = EVENT_MODIFY_STATE
+    }
+
+type WaitResult = DWORD
+#{enum WaitResult,
+    , wAIT_ABANDONED     = WAIT_ABANDONED
+    , wAIT_IO_COMPLETION = WAIT_IO_COMPLETION
+    , wAIT_OBJECT_0      = WAIT_OBJECT_0
+    , wAIT_TIMEOUT       = WAIT_TIMEOUT
+    , wAIT_FAILED        = WAIT_FAILED
+    }
+
+---------------------------------------------------------------------------
+-- API in Haskell
+---------------------------------------------------------------------------
+openEvent :: AccessMode -> Bool -> String -> IO HANDLE
+openEvent amode inherit name = withTString name $ \c_name ->
+    failIf (==nullPtr) "openEvent: OpenEvent" $ c_OpenEvent (fromIntegral amode) inherit c_name
+
+createEvent :: Maybe SECURITY_ATTRIBUTES -> Bool -> Bool -> String -> IO HANDLE
+createEvent msecurity manual initial name = withTString name $ \c_name ->
+    maybeWith with msecurity $ \c_sec ->
+        failIf (==nullPtr) "createEvent: CreateEvent" $ c_CreateEvent c_sec manual initial c_name
+
+duplicateHandle :: HANDLE -> HANDLE -> HANDLE -> AccessMode -> Bool -> DuplicateOption -> IO HANDLE
+duplicateHandle srcProccess srcHandler targetProcess access inherit opts = alloca $ \res -> do
+    failIfFalse_ "duplicateHandle: DuplicateHandle" $ c_DuplicateHandle srcProccess srcHandler targetProcess res (fromIntegral access) inherit opts
+    peek res
+
+setEvent :: HANDLE -> IO ()
+setEvent event = failIfFalse_ "setEvent: SetEvent" $ c_SetEvent event
+
+resetEvent :: HANDLE -> IO ()
+resetEvent event = failIfFalse_ "resetEvent: ResetEvent" $ c_ResetEvent event
+
+pulseEvent :: HANDLE -> IO ()
+pulseEvent event = failIfFalse_ "pulseEvent: PulseEvent" $ c_PulseEvent event
+
+signalObjectAndWait :: HANDLE -> HANDLE -> MilliSeconds -> Bool -> IO WaitResult
+signalObjectAndWait toSignal toWaitOn millis alterable = c_SignalObjectAndWait toSignal toWaitOn millis alterable
+
+waitForSingleObject :: HANDLE -> MilliSeconds -> IO WaitResult
+waitForSingleObject toWaitOn millis = c_WaitForSingleObject toWaitOn millis
+
+waitForSingleObjectEx :: HANDLE -> MilliSeconds -> Bool -> IO WaitResult
+waitForSingleObjectEx toWaitOn millis alterable = c_WaitForSingleObjectEx toWaitOn millis alterable
+
+waitForMultipleObjects :: [HANDLE] -> Bool -> MilliSeconds -> IO WaitResult
+waitForMultipleObjects hs waitAll millis = withArrayLen hs $ \n hsp ->
+  c_WaitForMultipleObjects (fromIntegral n) hsp waitAll millis
+
+waitForMultipleObjectsEx :: [HANDLE] -> Bool -> MilliSeconds -> Bool -> IO WaitResult
+waitForMultipleObjectsEx hs waitAll millis alterable = withArrayLen hs $ \n hsp ->
+  c_WaitForMultipleObjectsEx (fromIntegral n) hsp waitAll millis alterable
+
+---------------------------------------------------------------------------
+-- Imports
+---------------------------------------------------------------------------
+foreign import WINDOWS_CCONV "windows.h OpenEventW"
+    c_OpenEvent :: DWORD -> BOOL -> LPCTSTR -> IO HANDLE
+
+foreign import WINDOWS_CCONV "windows.h CreateEventW"
+    c_CreateEvent :: LPSECURITY_ATTRIBUTES -> BOOL -> BOOL -> LPCTSTR -> IO HANDLE
+
+foreign import WINDOWS_CCONV "windows.h DuplicateHandle"
+    c_DuplicateHandle :: HANDLE -> HANDLE -> HANDLE -> Ptr HANDLE -> DWORD -> BOOL -> DWORD -> IO BOOL
+
+foreign import WINDOWS_CCONV "windows.h SetEvent"
+    c_SetEvent :: HANDLE -> IO Bool
+
+foreign import WINDOWS_CCONV "windows.h ResetEvent"
+    c_ResetEvent :: HANDLE -> IO Bool
+
+foreign import WINDOWS_CCONV "windows.h PulseEvent"
+    c_PulseEvent :: HANDLE -> IO Bool
+
+foreign import WINDOWS_CCONV "windows.h SignalObjectAndWait"
+    c_SignalObjectAndWait :: HANDLE -> HANDLE -> DWORD -> BOOL -> IO DWORD
+
+foreign import WINDOWS_CCONV "windows.h WaitForSingleObject"
+    c_WaitForSingleObject :: HANDLE -> DWORD -> IO DWORD
+
+foreign import WINDOWS_CCONV "windows.h WaitForSingleObjectEx"
+    c_WaitForSingleObjectEx :: HANDLE -> DWORD -> BOOL -> IO DWORD
+
+foreign import WINDOWS_CCONV "windows.h WaitForMultipleObjects"
+    c_WaitForMultipleObjects :: DWORD -> Ptr HANDLE -> BOOL -> DWORD -> IO DWORD
+
+foreign import WINDOWS_CCONV "windows.h WaitForMultipleObjectsEx"
+    c_WaitForMultipleObjectsEx :: DWORD -> Ptr HANDLE -> BOOL -> DWORD -> BOOL -> IO DWORD
diff --git a/System/Win32/File.hsc b/System/Win32/File.hsc
--- a/System/Win32/File.hsc
+++ b/System/Win32/File.hsc
@@ -239,8 +239,28 @@
 
 ----------------------------------------------------------------
 
-type LPSECURITY_ATTRIBUTES = Ptr ()
+data SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES
+    { nLength              :: !DWORD
+    , lpSecurityDescriptor :: !LPVOID
+    , bInheritHandle       :: !BOOL
+    } deriving Show
+
+type PSECURITY_ATTRIBUTES = Ptr SECURITY_ATTRIBUTES
+type LPSECURITY_ATTRIBUTES = Ptr SECURITY_ATTRIBUTES
 type MbLPSECURITY_ATTRIBUTES = Maybe LPSECURITY_ATTRIBUTES
+
+instance Storable SECURITY_ATTRIBUTES where
+    sizeOf = const #{size SECURITY_ATTRIBUTES}
+    alignment _ = #alignment SECURITY_ATTRIBUTES
+    poke buf input = do
+        (#poke SECURITY_ATTRIBUTES, nLength)              buf (nLength input)
+        (#poke SECURITY_ATTRIBUTES, lpSecurityDescriptor) buf (lpSecurityDescriptor input)
+        (#poke SECURITY_ATTRIBUTES, bInheritHandle)       buf (bInheritHandle input)
+    peek buf = do
+        nLength'              <- (#peek SECURITY_ATTRIBUTES, nLength)              buf
+        lpSecurityDescriptor' <- (#peek SECURITY_ATTRIBUTES, lpSecurityDescriptor) buf
+        bInheritHandle'       <- (#peek SECURITY_ATTRIBUTES, bInheritHandle)       buf
+        return $ SECURITY_ATTRIBUTES nLength' lpSecurityDescriptor' bInheritHandle'
 
 ----------------------------------------------------------------
 -- Other types
diff --git a/Win32.cabal b/Win32.cabal
--- a/Win32.cabal
+++ b/Win32.cabal
@@ -1,9 +1,9 @@
 name:           Win32
-version:        2.10.0.0
+version:        2.10.1.0
 license:        BSD3
 license-file:   LICENSE
 author:         Alastair Reid, shelarcy, Tamar Christina
-copyright:      Alastair Reid, 1999-2003; shelarcy, 2012-2013; Tamar Christina, 2016-2018
+copyright:      Alastair Reid, 1999-2003; shelarcy, 2012-2013; Tamar Christina, 2016-2020
 maintainer:     Haskell Libraries <libraries@haskell.org>
 bug-reports:    https://github.com/haskell/win32/issues
 homepage:       https://github.com/haskell/win32
@@ -69,6 +69,7 @@
         System.Win32
         System.Win32.DebugApi
         System.Win32.DLL
+        System.Win32.Event
         System.Win32.File
         System.Win32.FileMapping
         System.Win32.Info
@@ -107,7 +108,7 @@
     ghc-options:      -Wall
     include-dirs:     include
     includes:         "alphablend.h", "diatemp.h", "dumpBMP.h", "ellipse.h", "errors.h", "HsGDI.h", "HsWin32.h", "Win32Aux.h", "win32debug.h", "windows_cconv.h", "WndProc.h", "alignment.h"
-    install-includes: "HsWin32.h", "HsGDI.h", "WndProc.h", "windows_cconv.h", "alphablend.h", "winternl_compat.h", "winuser_compat.h", "winreg_compat.h", "tlhelp32_compat.h"
+    install-includes: "HsWin32.h", "HsGDI.h", "WndProc.h", "windows_cconv.h", "alphablend.h", "winternl_compat.h", "winuser_compat.h", "winreg_compat.h", "tlhelp32_compat.h", "winnls_compat.h", "winnt_compat.h"
     c-sources:
         cbits/HsGDI.c
         cbits/HsWin32.c
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,24 @@
 # Changelog for [`Win32` package](http://hackage.haskell.org/package/Win32)
 
+## 2.10.1.0 October 2020
+
+* Add `System.Win32.Event` module
+* Add function `openEvent`
+* Add function `createEvent`
+* Add function `duplicateHandle`
+* Add function `setEvent`
+* Add function `resetEvent`
+* Add function `pulseEvent`
+* Add function `signalObjectAndWait`
+* Add function `waitForSingleObject`
+* Add function `waitForSingleObjectEx`
+* Add function `waitForMultipleObjects`
+* Add function `waitForMultipleObjectsEx`
+* Add enums `DUPLICATE_CLOSE_SOURCE`, `DUPLICATE_SAME_ACCESS`,
+  `EVENT_ALL_ACCESS`, `EVENT_MODIFY_STATE`, `WAIT_ABANDONED`,
+  `WAIT_IO_COMPLETION`, `WAIT_OBJECT_0`, `WAIT_TIMEOUT` and `WAIT_FAILED`.
+* Add struct `SECURITY_ATTRIBUTES`
+
 ## 2.10.0.0 September 2020
 
 * Add function `isWindowVisible`
diff --git a/include/winnls_compat.h b/include/winnls_compat.h
new file mode 100644
--- /dev/null
+++ b/include/winnls_compat.h
@@ -0,0 +1,105 @@
+/* The version of winnls.h provided by the version of MSYS2 included with
+ * versions of GHC before GHC 7.10 excludes certain components introduced with
+ * Windows Vista.
+ */
+
+#ifndef WINNLS_COMPAT_H
+#define WINNLS_COMPAT_H
+
+#if __GLASGOW_HASKELL__ < 710
+// Locale information constants
+#define LOCALE_IGEOID 0x0000005b
+#define LOCALE_SCONSOLEFALLBACKNAME 0x0000006e
+#define LOCALE_SDURATION 0x0000005d
+#define LOCALE_SENGLISHCOUNTRYNAME 0x00001002
+#define LOCALE_SENGLISHLANGUAGENAME 0x00001001
+#define LOCALE_SISO3166CTRYNAME2 0x00000068
+#define LOCALE_SISO639LANGNAME2 0x00000067
+#define LOCALE_SKEYBOARDSTOINSTALL 0x0000005e
+#define LOCALE_SNAME 0x0000005c
+#define LOCALE_SNAN 0x00000069
+#define LOCALE_SNATIVECOUNTRYNAME 0x00000008
+#define LOCALE_SNEGINFINITY 0x0000006b
+#define LOCALE_SPARENT 0x0000006d
+#define LOCALE_SPOSINFINITY 0x0000006a
+#define LOCALE_SSCRIPTS 0x0000006c
+#define LOCALE_SSHORTESTDAYNAME1 0x00000060
+#define LOCALE_SSHORTESTDAYNAME2 0x00000061
+#define LOCALE_SSHORTESTDAYNAME3 0x00000062
+#define LOCALE_SSHORTESTDAYNAME4 0x00000063
+#define LOCALE_SSHORTESTDAYNAME5 0x00000064
+#define LOCALE_SSHORTESTDAYNAME6 0x00000065
+#define LOCALE_SSHORTESTDAYNAME7 0x00000066
+// Locale map flag constants
+#define LINGUISTIC_IGNORECASE 0x00000010
+#define LINGUISTIC_IGNOREDIACRITIC 0x00000020
+#define NORM_LINGUISTIC_CASING 0x08000000
+// Locale enumeration flag constants
+#define LOCALE_ALL                  0
+#define LOCALE_ALTERNATE_SORTS      0x00000004
+#define LOCALE_REPLACEMENT          0x00000008
+#define LOCALE_SUPPLEMENTAL         0x00000002
+#define LOCALE_WINDOWS              0x00000001
+// Other
+WINBASEAPI WINBOOL WINAPI IsValidLocaleName (LPCWSTR lpLocaleName);
+#endif
+
+#if __GLASGOW_HASKELL__ < 710 && defined(i386_HOST_ARCH)
+// Locale information constants
+#define LOCALE_IDEFAULTMACCODEPAGE 0x00001011
+// Other
+typedef struct _nlsversioninfoex {
+  DWORD dwNLSVersionInfoSize;
+  DWORD dwNLSVersion;
+  DWORD dwDefinedVersion;
+  DWORD dwEffectiveId;
+  GUID  guidCustomVersion;
+} NLSVERSIONINFOEX, *LPNLSVERSIONINFOEX;
+
+WINBASEAPI int WINAPI GetLocaleInfoEx(
+  LPCWSTR lpLocaleName,
+  LCTYPE LCType,
+  LPWSTR lpLCData,
+  int cchData
+);
+
+WINBASEAPI WINBOOL WINAPI GetNLSVersionEx(
+  NLS_FUNCTION function,
+  LPCWSTR lpLocaleName,
+  LPNLSVERSIONINFOEX lpVersionInformation
+);
+
+WINBASEAPI int WINAPI LCMapStringEx(
+  LPCWSTR lpLocaleName,
+  DWORD dwMapFlags,
+  LPCWSTR lpSrcStr,
+  int cchSrc,
+  LPWSTR lpDestStr,
+  int cchDest,
+  LPNLSVERSIONINFO lpVersionInformation,
+  LPVOID lpReserved,
+  LPARAM lParam
+);
+
+
+WINBASEAPI int WINAPI GetTimeFormatEx(
+  LPCWSTR lpLocaleName,
+  DWORD dwFlags,
+  const SYSTEMTIME *lpTime,
+  LPCWSTR lpFormat,
+  LPWSTR lpTimeStr,
+  int cchTime
+);
+
+WINBASEAPI int WINAPI GetSystemDefaultLocaleName(
+  LPWSTR lpLocaleName,
+  int cchLocaleName
+);
+
+WINBASEAPI int WINAPI GetUserDefaultLocaleName(
+  LPWSTR lpLocaleName,
+  int cchLocaleName
+);
+#endif
+
+#endif /* #ifndef WINNLS_COMPAT_H */
diff --git a/include/winnt_compat.h b/include/winnt_compat.h
new file mode 100644
--- /dev/null
+++ b/include/winnt_compat.h
@@ -0,0 +1,13 @@
+/* The version of winnt.h provided by the version of MSYS2 included with
+ * versions of GHC before GHC 7.10 excludes certain components introduced with
+ * Windows Vista.
+ */
+
+#ifndef WINNT_COMPAT_H
+#define WINNT_COMPAT_H
+
+#if __GLASGOW_HASKELL__ < 710 && defined(i386_HOST_ARCH)
+#define LOCALE_NAME_MAX_LENGTH 85
+#endif
+
+#endif /* #ifndef WINNT_COMPAT_H */
