diff --git a/Graphics/Win32/Window.hsc b/Graphics/Win32/Window.hsc
--- a/Graphics/Win32/Window.hsc
+++ b/Graphics/Win32/Window.hsc
@@ -51,7 +51,7 @@
 
 type ClassName   = LPCTSTR
 
--- Note: this is one of those rare functions which doesnt free all
+-- Note: this is one of those rare functions which doesn't free all
 -- its String arguments.
 
 mkClassName :: String -> ClassName
diff --git a/System/Win32/HardLink.hs b/System/Win32/HardLink.hs
--- a/System/Win32/HardLink.hs
+++ b/System/Win32/HardLink.hs
@@ -25,7 +25,7 @@
 
 #include "windows_cconv.h"
 
--- | NOTE: createHardLink is /flipped arguments/ to provide compatiblity for Unix.
+-- | NOTE: createHardLink is /flipped arguments/ to provide compatibility for Unix.
 -- 
 -- If you want to create hard link by Windows way, use 'createHardLink'' instead.
 createHardLink :: FilePath -- ^ Target file path
diff --git a/System/Win32/Mem.hsc b/System/Win32/Mem.hsc
--- a/System/Win32/Mem.hsc
+++ b/System/Win32/Mem.hsc
@@ -268,10 +268,11 @@
 foreign import WINDOWS_CCONV unsafe "windows.h VirtualAlloc"
   c_VirtualAlloc :: Addr -> DWORD -> DWORD -> DWORD -> IO Addr
 
--- %fun VirtualAllocEx :: HANDLE -> Addr -> DWORD -> VirtualAllocFlags -> ProtectFlags ->IO Addr
--- %code extern LPVOID WINAPI VirtualAllocEx(HANDLE,LPVOID,DWORD,DWORD,DWORD);
--- %     LPVOID res1=VirtualAllocEx(arg1,arg2,arg3,arg4,arg5);
--- %fail {res1==NULL}{ErrorWin("VirtualAllocEx")}
+virtualAllocEx :: HANDLE -> Addr -> DWORD -> VirtualAllocFlags -> ProtectFlags -> IO Addr
+virtualAllocEx proc addt size ty flags =
+  failIfNull "VirtualAllocEx" $ c_VirtualAllocEx proc addt size ty flags
+foreign import WINDOWS_CCONV unsafe "windows.h VirtualAllocEx"
+  c_VirtualAllocEx :: HANDLE -> Addr -> DWORD -> DWORD -> DWORD -> IO Addr
 
 virtualFree :: Addr -> DWORD -> FreeFlags -> IO ()
 virtualFree addr size flags =
@@ -279,10 +280,11 @@
 foreign import WINDOWS_CCONV unsafe "windows.h VirtualFree"
   c_VirtualFree :: Addr -> DWORD -> FreeFlags -> IO Bool
 
--- %fun VirtualFreeEx :: HANDLE -> Addr -> DWORD -> FreeFlags -> IO ()
--- %code extern BOOL WINAPI VirtualFreeEx(HANDLE,LPVOID,DWORD,DWORD);
--- %     BOOL res1=VirtualFreeEx(arg1,arg2,arg3,arg4);
--- %fail {res1=0}{ErrorWin("VirtualFreeEx")}
+virtualFreeEx :: HANDLE -> Addr -> DWORD -> FreeFlags -> IO ()
+virtualFreeEx proc addr size flags =
+  failIfFalse_ "VirtualFreeEx" $ c_VirtualFreeEx proc addr size flags
+foreign import WINDOWS_CCONV unsafe "windows.h VirtualFreeEx"
+  c_VirtualFreeEx :: HANDLE -> Addr -> DWORD -> FreeFlags -> IO Bool
 
 virtualLock :: Addr -> DWORD -> IO ()
 virtualLock addr size =
diff --git a/System/Win32/Process.hsc b/System/Win32/Process.hsc
--- a/System/Win32/Process.hsc
+++ b/System/Win32/Process.hsc
@@ -18,18 +18,20 @@
 -----------------------------------------------------------------------------
 
 module System.Win32.Process where
-import Control.Exception    ( bracket )
-import Control.Monad        ( liftM5 )
-import Foreign              ( Ptr, peekByteOff, allocaBytes, pokeByteOff
-                            , plusPtr )
-import Foreign.C.Types      ( CUInt(..) )
-import System.Win32.File    ( closeHandle )
+import Control.Exception     ( bracket )
+import Control.Monad         ( liftM5 )
+import Foreign               ( Ptr, peekByteOff, allocaBytes, pokeByteOff
+                             , plusPtr )
+import Foreign.C.Types       ( CUInt(..) )
+import System.Win32.File     ( closeHandle )
+import System.Win32.DebugApi ( ForeignAddress )
 import System.Win32.Types
 
 ##include "windows_cconv.h"
 
 #include <windows.h>
 #include <tlhelp32.h>
+#include "tlhelp32_compat.h"
 
 -- constant to wait for a very long time.
 iNFINITE :: DWORD
@@ -38,7 +40,6 @@
 foreign import WINDOWS_CCONV unsafe "windows.h Sleep"
   sleep :: DWORD -> IO ()
 
-
 type ProcessId = DWORD
 type ProcessHandle = HANDLE
 type ProcessAccessRights = DWORD
@@ -59,7 +60,6 @@
 foreign import WINDOWS_CCONV unsafe "windows.h OpenProcess"
     c_OpenProcess :: ProcessAccessRights -> BOOL -> ProcessId -> IO ProcessHandle
 
-
 openProcess :: ProcessAccessRights -> BOOL -> ProcessId -> IO ProcessHandle
 openProcess r inh i = failIfNull "OpenProcess" $ c_OpenProcess r inh i
 
@@ -94,11 +94,14 @@
 type Th32SnapFlags = DWORD
 -- | ProcessId, number of threads, parent ProcessId, process base priority, path of executable file
 type ProcessEntry32 = (ProcessId, Int, ProcessId, LONG, String)
+type ModuleEntry32 = (ForeignAddress, Int, HMODULE, String, String)
 
 #{enum Th32SnapFlags,
     , tH32CS_SNAPALL        = TH32CS_SNAPALL
     , tH32CS_SNAPHEAPLIST   = TH32CS_SNAPHEAPLIST
     , tH32CS_SNAPMODULE     = TH32CS_SNAPMODULE
+    , tH32CS_SNAPMODULE32   = TH32CS_SNAPMODULE32
+    , tH32CS_SNAPMODULE64   = (TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32)
     , tH32CS_SNAPPROCESS    = TH32CS_SNAPPROCESS
     , tH32CS_SNAPTHREAD     = TH32CS_SNAPTHREAD
     }
@@ -116,6 +119,12 @@
 foreign import WINDOWS_CCONV unsafe "tlhelp32.h Process32NextW"
     c_Process32Next :: Th32SnapHandle -> Ptr ProcessEntry32 -> IO BOOL
 
+foreign import WINDOWS_CCONV unsafe "tlhelp32.h Module32FirstW"
+    c_Module32First :: Th32SnapHandle -> Ptr ModuleEntry32 -> IO BOOL
+
+foreign import WINDOWS_CCONV unsafe "tlhelp32.h Module32NextW"
+    c_Module32Next :: Th32SnapHandle -> Ptr ModuleEntry32 -> IO BOOL
+
 -- | Create a snapshot of specified resources.  Call closeHandle to close snapshot.
 createToolhelp32Snapshot :: Th32SnapFlags -> Maybe ProcessId -> IO Th32SnapHandle
 createToolhelp32Snapshot f p
@@ -125,7 +134,6 @@
 withTh32Snap :: Th32SnapFlags -> Maybe ProcessId -> (Th32SnapHandle -> IO a) -> IO a
 withTh32Snap f p = bracket (createToolhelp32Snapshot f p) (closeHandle)
 
-
 peekProcessEntry32 :: Ptr ProcessEntry32 -> IO ProcessEntry32
 peekProcessEntry32 buf = liftM5 (,,,,)
     ((#peek PROCESSENTRY32W, th32ProcessID) buf)
@@ -134,6 +142,14 @@
     ((#peek PROCESSENTRY32W, pcPriClassBase) buf)
     (peekTString $ (#ptr PROCESSENTRY32W, szExeFile) buf)
 
+peekModuleEntry32 :: Ptr ModuleEntry32 -> IO ModuleEntry32
+peekModuleEntry32 buf = liftM5 (,,,,)
+    ((#peek MODULEENTRY32W, modBaseAddr) buf)
+    ((#peek MODULEENTRY32W, modBaseSize) buf)
+    ((#peek MODULEENTRY32W, hModule) buf)
+    (peekTString $ (#ptr MODULEENTRY32W, szModule) buf)
+    (peekTString $ (#ptr MODULEENTRY32W, szExePath) buf)
+
 -- | Enumerate processes using Process32First and Process32Next
 th32SnapEnumProcesses :: Th32SnapHandle -> IO [ProcessEntry32]
 th32SnapEnumProcesses h = allocaBytes (#size PROCESSENTRY32W) $ \pe -> do
@@ -150,4 +166,22 @@
             | otherwise = do
                 entry <- peekProcessEntry32 pe
                 ok' <- c_Process32Next h pe
+                readAndNext ok' pe (entry:res)
+
+-- | Enumerate moduless using Module32First and Module32Next
+th32SnapEnumModules :: Th32SnapHandle -> IO [ModuleEntry32]
+th32SnapEnumModules h = allocaBytes (#size MODULEENTRY32W) $ \pe -> do
+    (#poke MODULEENTRY32W, dwSize) pe ((#size MODULEENTRY32W)::DWORD)
+    ok <- c_Module32First h pe
+    readAndNext ok pe []
+    where
+        readAndNext ok pe res
+            | not ok    = do
+                err <- getLastError
+                if err == (#const ERROR_NO_MORE_FILES)
+                    then return $ reverse res
+                    else failWith "th32SnapEnumModules: Module32First/Module32Next" err
+            | otherwise = do
+                entry <- peekModuleEntry32 pe
+                ok' <- c_Module32Next h pe
                 readAndNext ok' pe (entry:res)
diff --git a/System/Win32/SimpleMAPI.hsc b/System/Win32/SimpleMAPI.hsc
--- a/System/Win32/SimpleMAPI.hsc
+++ b/System/Win32/SimpleMAPI.hsc
@@ -98,7 +98,7 @@
     , ((#const MAPI_E_TOO_MANY_SESSIONS), "Too many open sessions")
     , ((#const MAPI_E_TOO_MANY_FILES)   , "Too many open files")
     , ((#const MAPI_E_TOO_MANY_RECIPIENTS)      , "Too many recipients")
-    , ((#const MAPI_E_ATTACHMENT_NOT_FOUND)     , "Attachemnt not found")
+    , ((#const MAPI_E_ATTACHMENT_NOT_FOUND)     , "Attachment not found")
     , ((#const MAPI_E_ATTACHMENT_OPEN_FAILURE)  , "Couldn't open attachment")
     , ((#const MAPI_E_ATTACHMENT_WRITE_FAILURE) , "Couldn't write attachment")
     , ((#const MAPI_E_UNKNOWN_RECIPIENT)        , "Unknown recipient")
diff --git a/System/Win32/SymbolicLink.hsc b/System/Win32/SymbolicLink.hsc
--- a/System/Win32/SymbolicLink.hsc
+++ b/System/Win32/SymbolicLink.hsc
@@ -35,7 +35,7 @@
 
 -- | createSymbolicLink* functions don't check that file is exist or not.
 --
--- NOTE: createSymbolicLink* functions are /flipped arguments/ to provide compatiblity for Unix,
+-- NOTE: createSymbolicLink* functions are /flipped arguments/ to provide compatibility for Unix,
 -- except 'createSymbolicLink''.
 -- 
 -- If you want to create symbolic link by Windows way, use 'createSymbolicLink'' instead.
diff --git a/Win32.cabal b/Win32.cabal
--- a/Win32.cabal
+++ b/Win32.cabal
@@ -1,5 +1,5 @@
 name:		Win32
-version:	2.8.2.0
+version:	2.8.3.0
 license:	BSD3
 license-file:	LICENSE
 author:		Alastair Reid, shelarcy, Tamar Christina
@@ -105,7 +105,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"
+    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"
     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,10 @@
 # Changelog for [`Win32` package](http://hackage.haskell.org/package/Win32)
 
+## 2.8.3.0 *Feb 2019*
+
+* Add `Module32FirstW` and `Module32NextW` (See #121)
+* Add `Virtual[Alloc/Free]Ex` (See #124)
+
 ## 2.8.2.0 *Dec 2018*
 
 * Drop use of NegativeLiterals (See #118)
diff --git a/include/tlhelp32_compat.h b/include/tlhelp32_compat.h
new file mode 100644
--- /dev/null
+++ b/include/tlhelp32_compat.h
@@ -0,0 +1,15 @@
+#ifndef TLHELP32_COMPAT_H
+#define TLHELP32_COMPAT_H
+ /*
+ * tlhelp32.h is not included in MinGW, which was shipped with the 32-bit
+ * Windows version of GHC prior to the 7.10.3 release.
+ */
+#if __GLASGOW_HASKELL__ > 708
+#else
+// Some declarations from tlhelp32.h that we need in Win32
+#include <windows.h>
+
+#define TH32CS_SNAPMODULE32 0x00000010
+
+#endif
+#endif /* TLHELP32_COMPAT_H */
