diff --git a/System/Win32/DLL.hsc b/System/Win32/DLL.hsc index 59edd61..008aea0 100644 --- a/System/Win32/DLL.hsc +++ b/System/Win32/DLL.hsc @@ -31,76 +31,49 @@ module System.Win32.DLL , lOAD_WITH_ALTERED_SEARCH_PATH ) where +import System.Win32.DLL.Internal import System.Win32.Types import Foreign import Foreign.C import Data.Maybe (fromMaybe) -##include "windows_cconv.h" - -#include - disableThreadLibraryCalls :: HMODULE -> IO () disableThreadLibraryCalls hmod = failIfFalse_ "DisableThreadLibraryCalls" $ c_DisableThreadLibraryCalls hmod -foreign import WINDOWS_CCONV unsafe "windows.h DisableThreadLibraryCalls" - c_DisableThreadLibraryCalls :: HMODULE -> IO Bool freeLibrary :: HMODULE -> IO () freeLibrary hmod = failIfFalse_ "FreeLibrary" $ c_FreeLibrary hmod -foreign import WINDOWS_CCONV unsafe "windows.h FreeLibrary" - c_FreeLibrary :: HMODULE -> IO Bool getModuleFileName :: HMODULE -> IO String getModuleFileName hmod = allocaArray 512 $ \ c_str -> do failIfFalse_ "GetModuleFileName" $ c_GetModuleFileName hmod c_str 512 peekTString c_str -foreign import WINDOWS_CCONV unsafe "windows.h GetModuleFileNameW" - c_GetModuleFileName :: HMODULE -> LPTSTR -> Int -> IO Bool getModuleHandle :: Maybe String -> IO HMODULE getModuleHandle mb_name = maybeWith withTString mb_name $ \ c_name -> failIfNull "GetModuleHandle" $ c_GetModuleHandle c_name -foreign import WINDOWS_CCONV unsafe "windows.h GetModuleHandleW" - c_GetModuleHandle :: LPCTSTR -> IO HMODULE getProcAddress :: HMODULE -> String -> IO Addr getProcAddress hmod procname = withCAString procname $ \ c_procname -> failIfNull "GetProcAddress" $ c_GetProcAddress hmod c_procname -foreign import WINDOWS_CCONV unsafe "windows.h GetProcAddress" - c_GetProcAddress :: HMODULE -> LPCSTR -> IO Addr - loadLibrary :: String -> IO HINSTANCE loadLibrary name = withTString name $ \ c_name -> failIfNull "LoadLibrary" $ c_LoadLibrary c_name -foreign import WINDOWS_CCONV unsafe "windows.h LoadLibraryW" - c_LoadLibrary :: LPCTSTR -> IO HINSTANCE - -type LoadLibraryFlags = DWORD - -#{enum LoadLibraryFlags, - , lOAD_LIBRARY_AS_DATAFILE = LOAD_LIBRARY_AS_DATAFILE - , lOAD_WITH_ALTERED_SEARCH_PATH = LOAD_WITH_ALTERED_SEARCH_PATH - } loadLibraryEx :: String -> HANDLE -> LoadLibraryFlags -> IO HINSTANCE loadLibraryEx name h flags = withTString name $ \ c_name -> failIfNull "LoadLibraryEx" $ c_LoadLibraryEx c_name h flags -foreign import WINDOWS_CCONV unsafe "windows.h LoadLibraryExW" - c_LoadLibraryEx :: LPCTSTR -> HANDLE -> LoadLibraryFlags -> IO HINSTANCE setDllDirectory :: Maybe String -> IO () setDllDirectory name = maybeWith withTString name $ \ c_name -> failIfFalse_ (unwords ["SetDllDirectory", fromMaybe "NULL" name]) $ c_SetDllDirectory c_name -foreign import WINDOWS_CCONV unsafe "windows.h SetDllDirectoryW" - c_SetDllDirectory :: LPTSTR -> IO BOOL diff --git a/System/Win32/DLL/Internal.hsc b/System/Win32/DLL/Internal.hsc new file mode 100644 index 0000000..9746f84 --- /dev/null +++ b/System/Win32/DLL/Internal.hsc @@ -0,0 +1,57 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.DLL.Internal +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.DLL.Internal where + +import System.Win32.Types + +##include "windows_cconv.h" + +#include + +foreign import WINDOWS_CCONV unsafe "windows.h DisableThreadLibraryCalls" + c_DisableThreadLibraryCalls :: HMODULE -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h FreeLibrary" + c_FreeLibrary :: HMODULE -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h GetModuleFileNameW" + c_GetModuleFileName :: HMODULE -> LPTSTR -> Int -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h GetModuleHandleW" + c_GetModuleHandle :: LPCTSTR -> IO HMODULE + +foreign import WINDOWS_CCONV unsafe "windows.h GetProcAddress" + c_GetProcAddress :: HMODULE -> LPCSTR -> IO Addr + +foreign import WINDOWS_CCONV unsafe "windows.h LoadLibraryW" + c_LoadLibrary :: LPCTSTR -> IO HINSTANCE + +type LoadLibraryFlags = DWORD + +#{enum LoadLibraryFlags, + , lOAD_LIBRARY_AS_DATAFILE = LOAD_LIBRARY_AS_DATAFILE + , lOAD_WITH_ALTERED_SEARCH_PATH = LOAD_WITH_ALTERED_SEARCH_PATH + } + +foreign import WINDOWS_CCONV unsafe "windows.h LoadLibraryExW" + c_LoadLibraryEx :: LPCTSTR -> HANDLE -> LoadLibraryFlags -> IO HINSTANCE + +foreign import WINDOWS_CCONV unsafe "windows.h SetDllDirectoryW" + c_SetDllDirectory :: LPTSTR -> IO BOOL diff --git a/System/Win32/DebugApi.hsc b/System/Win32/DebugApi.hsc index b18c3eb..2c5caa6 100644 --- a/System/Win32/DebugApi.hsc +++ b/System/Win32/DebugApi.hsc @@ -70,29 +70,18 @@ module System.Win32.DebugApi , outputDebugString ) where +import System.Win32.DebugApi.Internal import Control.Exception( bracket_ ) -import Data.Word ( Word8, Word32 ) import Foreign ( Ptr, nullPtr, ForeignPtr, mallocForeignPtrBytes , peekByteOff, plusPtr, allocaBytes, castPtr, poke , withForeignPtr, Storable, sizeOf, peek, pokeByteOff ) import System.IO ( fixIO ) -import System.Win32.Types ( HANDLE, BOOL, WORD, DWORD, failIf_, failWith - , getLastError, failIf, LPTSTR, withTString ) +import System.Win32.Types ( WORD, DWORD, failIf_, failWith + , getLastError, failIf, withTString ) ##include "windows_cconv.h" #include "windows.h" -type PID = DWORD -type TID = DWORD -type DebugEventId = (PID, TID) -type ForeignAddress = Word32 - -type PHANDLE = Ptr () -type THANDLE = Ptr () - -type ThreadInfo = (THANDLE, ForeignAddress, ForeignAddress) -- handle to thread, thread local, thread start -type ImageInfo = (HANDLE, ForeignAddress, DWORD, DWORD, ForeignAddress) -type ExceptionInfo = (Bool, Bool, ForeignAddress) -- First chance, continuable, address data Exception @@ -416,48 +405,3 @@ modifyThreadContext t a = withThreadContext t $ makeModThreadContext a outputDebugString :: String -> IO () outputDebugString s = withTString s $ \c_s -> c_OutputDebugString c_s --------------------------------------------------------------------------- --- Raw imports - -foreign import WINDOWS_CCONV "windows.h SuspendThread" - c_SuspendThread :: THANDLE -> IO DWORD - -foreign import WINDOWS_CCONV "windows.h ResumeThread" - c_ResumeThread :: THANDLE -> IO DWORD - -foreign import WINDOWS_CCONV "windows.h WaitForDebugEvent" - c_WaitForDebugEvent :: Ptr () -> DWORD -> IO BOOL - -foreign import WINDOWS_CCONV "windows.h ContinueDebugEvent" - c_ContinueDebugEvent :: DWORD -> DWORD -> DWORD -> IO BOOL - -foreign import WINDOWS_CCONV "windows.h DebugActiveProcess" - c_DebugActiveProcess :: DWORD -> IO Bool - --- Windows XP --- foreign import WINDOWS_CCONV "windows.h DebugActiveProcessStop" --- c_DebugActiveProcessStop :: DWORD -> IO Bool - -foreign import WINDOWS_CCONV "windows.h ReadProcessMemory" c_ReadProcessMemory :: - PHANDLE -> Ptr () -> Ptr Word8 -> DWORD -> Ptr DWORD -> IO BOOL - -foreign import WINDOWS_CCONV "windows.h WriteProcessMemory" c_WriteProcessMemory :: - PHANDLE -> Ptr () -> Ptr Word8 -> DWORD -> Ptr DWORD -> IO BOOL - -foreign import WINDOWS_CCONV "windows.h GetThreadContext" - c_GetThreadContext :: THANDLE -> Ptr () -> IO BOOL - -foreign import WINDOWS_CCONV "windows.h SetThreadContext" - c_SetThreadContext :: THANDLE -> Ptr () -> IO BOOL - ---foreign import WINDOWS_CCONV "windows.h GetThreadId" --- c_GetThreadId :: THANDLE -> IO TID - -foreign import WINDOWS_CCONV "windows.h OutputDebugStringW" - c_OutputDebugString :: LPTSTR -> IO () - -foreign import WINDOWS_CCONV "windows.h IsDebuggerPresent" - isDebuggerPresent :: IO BOOL - -foreign import WINDOWS_CCONV "windows.h DebugBreak" - debugBreak :: IO () diff --git a/System/Win32/DebugApi/Internal.hsc b/System/Win32/DebugApi/Internal.hsc new file mode 100644 index 0000000..5d0a606 --- /dev/null +++ b/System/Win32/DebugApi/Internal.hsc @@ -0,0 +1,80 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.WindowsString.DebugApi.Internal +-- Copyright : (c) Esa Ilari Vuokko, 2006 +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for using Windows DebugApi. +-- +----------------------------------------------------------------------------- + +module System.Win32.DebugApi.Internal where + +import Data.Word ( Word8, Word32 ) +import Foreign ( Ptr ) +import System.Win32.Types ( BOOL, DWORD, HANDLE, LPTSTR ) + +##include "windows_cconv.h" +#include "windows.h" + +type PID = DWORD +type TID = DWORD +type DebugEventId = (PID, TID) +type ForeignAddress = Word32 + +type PHANDLE = Ptr () +type THANDLE = Ptr () + +type ThreadInfo = (THANDLE, ForeignAddress, ForeignAddress) -- handle to thread, thread local, thread start +type ImageInfo = (HANDLE, ForeignAddress, DWORD, DWORD, ForeignAddress) +type ExceptionInfo = (Bool, Bool, ForeignAddress) -- First chance, continuable, address + +-------------------------------------------------------------------------- +-- Raw imports + +foreign import WINDOWS_CCONV "windows.h SuspendThread" + c_SuspendThread :: THANDLE -> IO DWORD + +foreign import WINDOWS_CCONV "windows.h ResumeThread" + c_ResumeThread :: THANDLE -> IO DWORD + +foreign import WINDOWS_CCONV "windows.h WaitForDebugEvent" + c_WaitForDebugEvent :: Ptr () -> DWORD -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h ContinueDebugEvent" + c_ContinueDebugEvent :: DWORD -> DWORD -> DWORD -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h DebugActiveProcess" + c_DebugActiveProcess :: DWORD -> IO Bool + +-- Windows XP +-- foreign import WINDOWS_CCONV "windows.h DebugActiveProcessStop" +-- c_DebugActiveProcessStop :: DWORD -> IO Bool + +foreign import WINDOWS_CCONV "windows.h ReadProcessMemory" c_ReadProcessMemory :: + PHANDLE -> Ptr () -> Ptr Word8 -> DWORD -> Ptr DWORD -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h WriteProcessMemory" c_WriteProcessMemory :: + PHANDLE -> Ptr () -> Ptr Word8 -> DWORD -> Ptr DWORD -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h GetThreadContext" + c_GetThreadContext :: THANDLE -> Ptr () -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h SetThreadContext" + c_SetThreadContext :: THANDLE -> Ptr () -> IO BOOL + +--foreign import WINDOWS_CCONV "windows.h GetThreadId" +-- c_GetThreadId :: THANDLE -> IO TID + +foreign import WINDOWS_CCONV "windows.h OutputDebugStringW" + c_OutputDebugString :: LPTSTR -> IO () + +foreign import WINDOWS_CCONV "windows.h IsDebuggerPresent" + isDebuggerPresent :: IO BOOL + +foreign import WINDOWS_CCONV "windows.h DebugBreak" + debugBreak :: IO () diff --git a/System/Win32/File.hsc b/System/Win32/File.hsc index 69e19ec..0283db4 100644 --- a/System/Win32/File.hsc +++ b/System/Win32/File.hsc @@ -238,8 +238,8 @@ module System.Win32.File , unlockFile ) where +import System.Win32.File.Internal import System.Win32.Types -import System.Win32.Time import Foreign hiding (void) import Control.Monad @@ -250,313 +250,6 @@ import Control.Concurrent #include #include "alignment.h" ----------------------------------------------------------------- --- Enumeration types ----------------------------------------------------------------- - -type AccessMode = UINT - -gENERIC_NONE :: AccessMode -gENERIC_NONE = 0 - -#{enum AccessMode, - , gENERIC_READ = GENERIC_READ - , gENERIC_WRITE = GENERIC_WRITE - , gENERIC_EXECUTE = GENERIC_EXECUTE - , gENERIC_ALL = GENERIC_ALL - , dELETE = DELETE - , rEAD_CONTROL = READ_CONTROL - , wRITE_DAC = WRITE_DAC - , wRITE_OWNER = WRITE_OWNER - , sYNCHRONIZE = SYNCHRONIZE - , sTANDARD_RIGHTS_REQUIRED = STANDARD_RIGHTS_REQUIRED - , sTANDARD_RIGHTS_READ = STANDARD_RIGHTS_READ - , sTANDARD_RIGHTS_WRITE = STANDARD_RIGHTS_WRITE - , sTANDARD_RIGHTS_EXECUTE = STANDARD_RIGHTS_EXECUTE - , sTANDARD_RIGHTS_ALL = STANDARD_RIGHTS_ALL - , sPECIFIC_RIGHTS_ALL = SPECIFIC_RIGHTS_ALL - , aCCESS_SYSTEM_SECURITY = ACCESS_SYSTEM_SECURITY - , mAXIMUM_ALLOWED = MAXIMUM_ALLOWED - , fILE_ADD_FILE = FILE_ADD_FILE - , fILE_ADD_SUBDIRECTORY = FILE_ADD_SUBDIRECTORY - , fILE_ALL_ACCESS = FILE_ALL_ACCESS - , fILE_APPEND_DATA = FILE_APPEND_DATA - , fILE_CREATE_PIPE_INSTANCE = FILE_CREATE_PIPE_INSTANCE - , fILE_DELETE_CHILD = FILE_DELETE_CHILD - , fILE_EXECUTE = FILE_EXECUTE - , fILE_LIST_DIRECTORY = FILE_LIST_DIRECTORY - , fILE_READ_ATTRIBUTES = FILE_READ_ATTRIBUTES - , fILE_READ_DATA = FILE_READ_DATA - , fILE_READ_EA = FILE_READ_EA - , fILE_TRAVERSE = FILE_TRAVERSE - , fILE_WRITE_ATTRIBUTES = FILE_WRITE_ATTRIBUTES - , fILE_WRITE_DATA = FILE_WRITE_DATA - , fILE_WRITE_EA = FILE_WRITE_EA - } - ----------------------------------------------------------------- - -type ShareMode = UINT - -fILE_SHARE_NONE :: ShareMode -fILE_SHARE_NONE = 0 - -#{enum ShareMode, - , fILE_SHARE_READ = FILE_SHARE_READ - , fILE_SHARE_WRITE = FILE_SHARE_WRITE - , fILE_SHARE_DELETE = FILE_SHARE_DELETE - } - ----------------------------------------------------------------- - -type CreateMode = UINT - -#{enum CreateMode, - , cREATE_NEW = CREATE_NEW - , cREATE_ALWAYS = CREATE_ALWAYS - , oPEN_EXISTING = OPEN_EXISTING - , oPEN_ALWAYS = OPEN_ALWAYS - , tRUNCATE_EXISTING = TRUNCATE_EXISTING - } - ----------------------------------------------------------------- - -type FileAttributeOrFlag = UINT - -#{enum FileAttributeOrFlag, - , fILE_ATTRIBUTE_READONLY = FILE_ATTRIBUTE_READONLY - , fILE_ATTRIBUTE_HIDDEN = FILE_ATTRIBUTE_HIDDEN - , fILE_ATTRIBUTE_SYSTEM = FILE_ATTRIBUTE_SYSTEM - , fILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY - , fILE_ATTRIBUTE_ARCHIVE = FILE_ATTRIBUTE_ARCHIVE - , fILE_ATTRIBUTE_NORMAL = FILE_ATTRIBUTE_NORMAL - , fILE_ATTRIBUTE_TEMPORARY = FILE_ATTRIBUTE_TEMPORARY - , fILE_ATTRIBUTE_COMPRESSED = FILE_ATTRIBUTE_COMPRESSED - , fILE_ATTRIBUTE_REPARSE_POINT = FILE_ATTRIBUTE_REPARSE_POINT - , fILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH - , fILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED - , fILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING - , fILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS - , fILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN - , fILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE - , fILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS - , fILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS - } -#ifndef __WINE_WINDOWS_H -#{enum FileAttributeOrFlag, - , sECURITY_ANONYMOUS = SECURITY_ANONYMOUS - , sECURITY_IDENTIFICATION = SECURITY_IDENTIFICATION - , sECURITY_IMPERSONATION = SECURITY_IMPERSONATION - , sECURITY_DELEGATION = SECURITY_DELEGATION - , sECURITY_CONTEXT_TRACKING = SECURITY_CONTEXT_TRACKING - , sECURITY_EFFECTIVE_ONLY = SECURITY_EFFECTIVE_ONLY - , sECURITY_SQOS_PRESENT = SECURITY_SQOS_PRESENT - , sECURITY_VALID_SQOS_FLAGS = SECURITY_VALID_SQOS_FLAGS - } -#endif - ----------------------------------------------------------------- - -type MoveFileFlag = DWORD - -#{enum MoveFileFlag, - , mOVEFILE_REPLACE_EXISTING = MOVEFILE_REPLACE_EXISTING - , mOVEFILE_COPY_ALLOWED = MOVEFILE_COPY_ALLOWED - , mOVEFILE_DELAY_UNTIL_REBOOT = MOVEFILE_DELAY_UNTIL_REBOOT - } - ----------------------------------------------------------------- - -type FilePtrDirection = DWORD - -#{enum FilePtrDirection, - , fILE_BEGIN = FILE_BEGIN - , fILE_CURRENT = FILE_CURRENT - , fILE_END = FILE_END - } - ----------------------------------------------------------------- - -type DriveType = UINT - -#{enum DriveType, - , dRIVE_UNKNOWN = DRIVE_UNKNOWN - , dRIVE_NO_ROOT_DIR = DRIVE_NO_ROOT_DIR - , dRIVE_REMOVABLE = DRIVE_REMOVABLE - , dRIVE_FIXED = DRIVE_FIXED - , dRIVE_REMOTE = DRIVE_REMOTE - , dRIVE_CDROM = DRIVE_CDROM - , dRIVE_RAMDISK = DRIVE_RAMDISK - } - ----------------------------------------------------------------- - -type DefineDosDeviceFlags = DWORD - -#{enum DefineDosDeviceFlags, - , dDD_RAW_TARGET_PATH = DDD_RAW_TARGET_PATH - , dDD_REMOVE_DEFINITION = DDD_REMOVE_DEFINITION - , dDD_EXACT_MATCH_ON_REMOVE = DDD_EXACT_MATCH_ON_REMOVE - } - ----------------------------------------------------------------- - -type BinaryType = DWORD - -#{enum BinaryType, - , sCS_32BIT_BINARY = SCS_32BIT_BINARY - , sCS_DOS_BINARY = SCS_DOS_BINARY - , sCS_WOW_BINARY = SCS_WOW_BINARY - , sCS_PIF_BINARY = SCS_PIF_BINARY - , sCS_POSIX_BINARY = SCS_POSIX_BINARY - , sCS_OS216_BINARY = SCS_OS216_BINARY - } - ----------------------------------------------------------------- - -type FileNotificationFlag = DWORD - -#{enum FileNotificationFlag, - , fILE_NOTIFY_CHANGE_FILE_NAME = FILE_NOTIFY_CHANGE_FILE_NAME - , fILE_NOTIFY_CHANGE_DIR_NAME = FILE_NOTIFY_CHANGE_DIR_NAME - , fILE_NOTIFY_CHANGE_ATTRIBUTES = FILE_NOTIFY_CHANGE_ATTRIBUTES - , fILE_NOTIFY_CHANGE_SIZE = FILE_NOTIFY_CHANGE_SIZE - , fILE_NOTIFY_CHANGE_LAST_WRITE = FILE_NOTIFY_CHANGE_LAST_WRITE - , fILE_NOTIFY_CHANGE_SECURITY = FILE_NOTIFY_CHANGE_SECURITY - } - ----------------------------------------------------------------- - -type FileType = DWORD - -#{enum FileType, - , fILE_TYPE_UNKNOWN = FILE_TYPE_UNKNOWN - , fILE_TYPE_DISK = FILE_TYPE_DISK - , fILE_TYPE_CHAR = FILE_TYPE_CHAR - , fILE_TYPE_PIPE = FILE_TYPE_PIPE - , fILE_TYPE_REMOTE = FILE_TYPE_REMOTE - } - ----------------------------------------------------------------- - -type LockMode = DWORD - -#{enum LockMode, - , lOCKFILE_EXCLUSIVE_LOCK = LOCKFILE_EXCLUSIVE_LOCK - , lOCKFILE_FAIL_IMMEDIATELY = LOCKFILE_FAIL_IMMEDIATELY - } - ----------------------------------------------------------------- - -newtype GET_FILEEX_INFO_LEVELS = GET_FILEEX_INFO_LEVELS (#type GET_FILEEX_INFO_LEVELS) - deriving (Eq, Ord) - -#{enum GET_FILEEX_INFO_LEVELS, GET_FILEEX_INFO_LEVELS - , getFileExInfoStandard = GetFileExInfoStandard - , getFileExMaxInfoLevel = GetFileExMaxInfoLevel - } - ----------------------------------------------------------------- - -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 ----------------------------------------------------------------- - -data BY_HANDLE_FILE_INFORMATION = BY_HANDLE_FILE_INFORMATION - { bhfiFileAttributes :: FileAttributeOrFlag - , bhfiCreationTime, bhfiLastAccessTime, bhfiLastWriteTime :: FILETIME - , bhfiVolumeSerialNumber :: DWORD - , bhfiSize :: DDWORD - , bhfiNumberOfLinks :: DWORD - , bhfiFileIndex :: DDWORD - } deriving (Show) - -instance Storable BY_HANDLE_FILE_INFORMATION where - sizeOf = const (#size BY_HANDLE_FILE_INFORMATION) - alignment _ = #alignment BY_HANDLE_FILE_INFORMATION - poke buf bhi = do - (#poke BY_HANDLE_FILE_INFORMATION, dwFileAttributes) buf (bhfiFileAttributes bhi) - (#poke BY_HANDLE_FILE_INFORMATION, ftCreationTime) buf (bhfiCreationTime bhi) - (#poke BY_HANDLE_FILE_INFORMATION, ftLastAccessTime) buf (bhfiLastAccessTime bhi) - (#poke BY_HANDLE_FILE_INFORMATION, ftLastWriteTime) buf (bhfiLastWriteTime bhi) - (#poke BY_HANDLE_FILE_INFORMATION, dwVolumeSerialNumber) buf (bhfiVolumeSerialNumber bhi) - (#poke BY_HANDLE_FILE_INFORMATION, nFileSizeHigh) buf sizeHi - (#poke BY_HANDLE_FILE_INFORMATION, nFileSizeLow) buf sizeLow - (#poke BY_HANDLE_FILE_INFORMATION, nNumberOfLinks) buf (bhfiNumberOfLinks bhi) - (#poke BY_HANDLE_FILE_INFORMATION, nFileIndexHigh) buf idxHi - (#poke BY_HANDLE_FILE_INFORMATION, nFileIndexLow) buf idxLow - where - (sizeHi,sizeLow) = ddwordToDwords $ bhfiSize bhi - (idxHi,idxLow) = ddwordToDwords $ bhfiFileIndex bhi - - peek buf = do - attr <- (#peek BY_HANDLE_FILE_INFORMATION, dwFileAttributes) buf - ctim <- (#peek BY_HANDLE_FILE_INFORMATION, ftCreationTime) buf - lati <- (#peek BY_HANDLE_FILE_INFORMATION, ftLastAccessTime) buf - lwti <- (#peek BY_HANDLE_FILE_INFORMATION, ftLastWriteTime) buf - vser <- (#peek BY_HANDLE_FILE_INFORMATION, dwVolumeSerialNumber) buf - fshi <- (#peek BY_HANDLE_FILE_INFORMATION, nFileSizeHigh) buf - fslo <- (#peek BY_HANDLE_FILE_INFORMATION, nFileSizeLow) buf - link <- (#peek BY_HANDLE_FILE_INFORMATION, nNumberOfLinks) buf - idhi <- (#peek BY_HANDLE_FILE_INFORMATION, nFileIndexHigh) buf - idlo <- (#peek BY_HANDLE_FILE_INFORMATION, nFileIndexLow) buf - return $ BY_HANDLE_FILE_INFORMATION attr ctim lati lwti vser - (dwordsToDdword (fshi,fslo)) link (dwordsToDdword (idhi,idlo)) - ----------------------------------------------------------------- - -data WIN32_FILE_ATTRIBUTE_DATA = WIN32_FILE_ATTRIBUTE_DATA - { fadFileAttributes :: DWORD - , fadCreationTime , fadLastAccessTime , fadLastWriteTime :: FILETIME - , fadFileSize :: DDWORD - } deriving (Show) - -instance Storable WIN32_FILE_ATTRIBUTE_DATA where - sizeOf = const (#size WIN32_FILE_ATTRIBUTE_DATA) - alignment _ = #alignment WIN32_FILE_ATTRIBUTE_DATA - poke buf ad = do - (#poke WIN32_FILE_ATTRIBUTE_DATA, dwFileAttributes) buf (fadFileAttributes ad) - (#poke WIN32_FILE_ATTRIBUTE_DATA, ftCreationTime) buf (fadCreationTime ad) - (#poke WIN32_FILE_ATTRIBUTE_DATA, ftLastAccessTime) buf (fadLastAccessTime ad) - (#poke WIN32_FILE_ATTRIBUTE_DATA, ftLastWriteTime) buf (fadLastWriteTime ad) - (#poke WIN32_FILE_ATTRIBUTE_DATA, nFileSizeHigh) buf sizeHi - (#poke WIN32_FILE_ATTRIBUTE_DATA, nFileSizeLow) buf sizeLo - where - (sizeHi,sizeLo) = ddwordToDwords $ fadFileSize ad - - peek buf = do - attr <- (#peek WIN32_FILE_ATTRIBUTE_DATA, dwFileAttributes) buf - ctim <- (#peek WIN32_FILE_ATTRIBUTE_DATA, ftCreationTime) buf - lati <- (#peek WIN32_FILE_ATTRIBUTE_DATA, ftLastAccessTime) buf - lwti <- (#peek WIN32_FILE_ATTRIBUTE_DATA, ftLastWriteTime) buf - fshi <- (#peek WIN32_FILE_ATTRIBUTE_DATA, nFileSizeHigh) buf - fslo <- (#peek WIN32_FILE_ATTRIBUTE_DATA, nFileSizeLow) buf - return $ WIN32_FILE_ATTRIBUTE_DATA attr ctim lati lwti - (dwordsToDdword (fshi,fslo)) - ---------------------------------------------------------------- -- File operations ---------------------------------------------------------------- @@ -596,8 +289,6 @@ deleteFile name = withTString name $ \ c_name -> failIfFalseWithRetry_ (unwords ["DeleteFile",show name]) $ c_DeleteFile c_name -foreign import WINDOWS_CCONV unsafe "windows.h DeleteFileW" - c_DeleteFile :: LPCTSTR -> IO Bool copyFile :: String -> String -> Bool -> IO () copyFile src dest over = @@ -605,8 +296,6 @@ copyFile src dest over = withTString dest $ \ c_dest -> failIfFalseWithRetry_ (unwords ["CopyFile",show src,show dest]) $ c_CopyFile c_src c_dest over -foreign import WINDOWS_CCONV unsafe "windows.h CopyFileW" - c_CopyFile :: LPCTSTR -> LPCTSTR -> Bool -> IO Bool moveFile :: String -> String -> IO () moveFile src dest = @@ -614,8 +303,6 @@ moveFile src dest = withTString dest $ \ c_dest -> failIfFalseWithRetry_ (unwords ["MoveFile",show src,show dest]) $ c_MoveFile c_src c_dest -foreign import WINDOWS_CCONV unsafe "windows.h MoveFileW" - c_MoveFile :: LPCTSTR -> LPCTSTR -> IO Bool moveFileEx :: String -> Maybe String -> MoveFileFlag -> IO () moveFileEx src dest flags = @@ -623,24 +310,18 @@ moveFileEx src dest flags = maybeWith withTString dest $ \ c_dest -> failIfFalseWithRetry_ (unwords ["MoveFileEx",show src,show dest]) $ c_MoveFileEx c_src c_dest flags -foreign import WINDOWS_CCONV unsafe "windows.h MoveFileExW" - c_MoveFileEx :: LPCTSTR -> LPCTSTR -> MoveFileFlag -> IO Bool setCurrentDirectory :: String -> IO () setCurrentDirectory name = withTString name $ \ c_name -> failIfFalse_ (unwords ["SetCurrentDirectory",show name]) $ c_SetCurrentDirectory c_name -foreign import WINDOWS_CCONV unsafe "windows.h SetCurrentDirectoryW" - c_SetCurrentDirectory :: LPCTSTR -> IO Bool createDirectory :: String -> Maybe LPSECURITY_ATTRIBUTES -> IO () createDirectory name mb_attr = withTString name $ \ c_name -> failIfFalseWithRetry_ (unwords ["CreateDirectory",show name]) $ c_CreateDirectory c_name (maybePtr mb_attr) -foreign import WINDOWS_CCONV unsafe "windows.h CreateDirectoryW" - c_CreateDirectory :: LPCTSTR -> LPSECURITY_ATTRIBUTES -> IO Bool createDirectoryEx :: String -> String -> Maybe LPSECURITY_ATTRIBUTES -> IO () createDirectoryEx template name mb_attr = @@ -648,16 +329,12 @@ createDirectoryEx template name mb_attr = withTString name $ \ c_name -> failIfFalseWithRetry_ (unwords ["CreateDirectoryEx",show template,show name]) $ c_CreateDirectoryEx c_template c_name (maybePtr mb_attr) -foreign import WINDOWS_CCONV unsafe "windows.h CreateDirectoryExW" - c_CreateDirectoryEx :: LPCTSTR -> LPCTSTR -> LPSECURITY_ATTRIBUTES -> IO Bool removeDirectory :: String -> IO () removeDirectory name = withTString name $ \ c_name -> failIfFalseWithRetry_ (unwords ["RemoveDirectory",show name]) $ c_RemoveDirectory c_name -foreign import WINDOWS_CCONV unsafe "windows.h RemoveDirectoryW" - c_RemoveDirectory :: LPCTSTR -> IO Bool getBinaryType :: String -> IO BinaryType getBinaryType name = @@ -666,8 +343,6 @@ getBinaryType name = failIfFalse_ (unwords ["GetBinaryType",show name]) $ c_GetBinaryType c_name p_btype peek p_btype -foreign import WINDOWS_CCONV unsafe "windows.h GetBinaryTypeW" - c_GetBinaryType :: LPCTSTR -> Ptr DWORD -> IO Bool ---------------------------------------------------------------- -- HANDLE operations @@ -678,46 +353,32 @@ createFile name access share mb_attr mode flag mb_h = withTString name $ \ c_name -> failIfWithRetry (==iNVALID_HANDLE_VALUE) (unwords ["CreateFile",show name]) $ c_CreateFile c_name access share (maybePtr mb_attr) mode flag (maybePtr mb_h) -foreign import WINDOWS_CCONV unsafe "windows.h CreateFileW" - c_CreateFile :: LPCTSTR -> AccessMode -> ShareMode -> LPSECURITY_ATTRIBUTES -> CreateMode -> FileAttributeOrFlag -> HANDLE -> IO HANDLE closeHandle :: HANDLE -> IO () closeHandle h = failIfFalse_ "CloseHandle" $ c_CloseHandle h -foreign import WINDOWS_CCONV unsafe "windows.h CloseHandle" - c_CloseHandle :: HANDLE -> IO Bool -foreign import WINDOWS_CCONV unsafe "windows.h GetFileType" - getFileType :: HANDLE -> IO FileType --Apparently no error code flushFileBuffers :: HANDLE -> IO () flushFileBuffers h = failIfFalse_ "FlushFileBuffers" $ c_FlushFileBuffers h -foreign import WINDOWS_CCONV unsafe "windows.h FlushFileBuffers" - c_FlushFileBuffers :: HANDLE -> IO Bool setEndOfFile :: HANDLE -> IO () setEndOfFile h = failIfFalse_ "SetEndOfFile" $ c_SetEndOfFile h -foreign import WINDOWS_CCONV unsafe "windows.h SetEndOfFile" - c_SetEndOfFile :: HANDLE -> IO Bool setFileAttributes :: String -> FileAttributeOrFlag -> IO () setFileAttributes name attr = withTString name $ \ c_name -> failIfFalseWithRetry_ (unwords ["SetFileAttributes",show name]) $ c_SetFileAttributes c_name attr -foreign import WINDOWS_CCONV unsafe "windows.h SetFileAttributesW" - c_SetFileAttributes :: LPCTSTR -> FileAttributeOrFlag -> IO Bool getFileAttributes :: String -> IO FileAttributeOrFlag getFileAttributes name = withTString name $ \ c_name -> failIfWithRetry (== 0xFFFFFFFF) (unwords ["GetFileAttributes",show name]) $ c_GetFileAttributes c_name -foreign import WINDOWS_CCONV unsafe "windows.h GetFileAttributesW" - c_GetFileAttributes :: LPCTSTR -> IO FileAttributeOrFlag getFileAttributesExStandard :: String -> IO WIN32_FILE_ATTRIBUTE_DATA getFileAttributesExStandard name = alloca $ \res -> do @@ -725,51 +386,16 @@ getFileAttributesExStandard name = alloca $ \res -> do failIfFalseWithRetry_ "getFileAttributesExStandard" $ c_GetFileAttributesEx c_name getFileExInfoStandard res peek res -foreign import WINDOWS_CCONV unsafe "windows.h GetFileAttributesExW" - c_GetFileAttributesEx :: LPCTSTR -> GET_FILEEX_INFO_LEVELS -> Ptr a -> IO BOOL getFileInformationByHandle :: HANDLE -> IO BY_HANDLE_FILE_INFORMATION getFileInformationByHandle h = alloca $ \res -> do failIfFalseWithRetry_ "GetFileInformationByHandle" $ c_GetFileInformationByHandle h res peek res -foreign import WINDOWS_CCONV unsafe "windows.h GetFileInformationByHandle" - c_GetFileInformationByHandle :: HANDLE -> Ptr BY_HANDLE_FILE_INFORMATION -> IO BOOL ---------------------------------------------------------------- -- Read/write files ---------------------------------------------------------------- --- No support for this yet -data OVERLAPPED - = OVERLAPPED { ovl_internal :: ULONG_PTR - , ovl_internalHigh :: ULONG_PTR - , ovl_offset :: DWORD - , ovl_offsetHigh :: DWORD - , ovl_hEvent :: HANDLE - } deriving (Show) - -instance Storable OVERLAPPED where - sizeOf = const (#size OVERLAPPED) - alignment _ = #alignment OVERLAPPED - poke buf ad = do - (#poke OVERLAPPED, Internal ) buf (ovl_internal ad) - (#poke OVERLAPPED, InternalHigh) buf (ovl_internalHigh ad) - (#poke OVERLAPPED, Offset ) buf (ovl_offset ad) - (#poke OVERLAPPED, OffsetHigh ) buf (ovl_offsetHigh ad) - (#poke OVERLAPPED, hEvent ) buf (ovl_hEvent ad) - - peek buf = do - intnl <- (#peek OVERLAPPED, Internal ) buf - intnl_high <- (#peek OVERLAPPED, InternalHigh) buf - off <- (#peek OVERLAPPED, Offset ) buf - off_high <- (#peek OVERLAPPED, OffsetHigh ) buf - hevnt <- (#peek OVERLAPPED, hEvent ) buf - return $ OVERLAPPED intnl intnl_high off off_high hevnt - -type LPOVERLAPPED = Ptr OVERLAPPED - -type MbLPOVERLAPPED = Maybe LPOVERLAPPED - --Sigh - I give up & prefix win32_ to the next two to avoid -- senseless Prelude name clashes. --sof. @@ -778,24 +404,18 @@ win32_ReadFile h buf n mb_over = alloca $ \ p_n -> do failIfFalse_ "ReadFile" $ c_ReadFile h buf n p_n (maybePtr mb_over) peek p_n -foreign import WINDOWS_CCONV unsafe "windows.h ReadFile" - c_ReadFile :: HANDLE -> Ptr a -> DWORD -> Ptr DWORD -> LPOVERLAPPED -> IO Bool win32_WriteFile :: HANDLE -> Ptr a -> DWORD -> Maybe LPOVERLAPPED -> IO DWORD win32_WriteFile h buf n mb_over = alloca $ \ p_n -> do failIfFalse_ "WriteFile" $ c_WriteFile h buf n p_n (maybePtr mb_over) peek p_n -foreign import WINDOWS_CCONV unsafe "windows.h WriteFile" - c_WriteFile :: HANDLE -> Ptr a -> DWORD -> Ptr DWORD -> LPOVERLAPPED -> IO Bool setFilePointerEx :: HANDLE -> LARGE_INTEGER -> FilePtrDirection -> IO LARGE_INTEGER setFilePointerEx h dist dir = alloca $ \p_pos -> do failIfFalse_ "SetFilePointerEx" $ c_SetFilePointerEx h dist p_pos dir peek p_pos -foreign import WINDOWS_CCONV unsafe "windows.h SetFilePointerEx" - c_SetFilePointerEx :: HANDLE -> LARGE_INTEGER -> Ptr LARGE_INTEGER -> FilePtrDirection -> IO Bool ---------------------------------------------------------------- -- File Notifications @@ -809,29 +429,19 @@ findFirstChangeNotification path watch flag = withTString path $ \ c_path -> failIfNull (unwords ["FindFirstChangeNotification",show path]) $ c_FindFirstChangeNotification c_path watch flag -foreign import WINDOWS_CCONV unsafe "windows.h FindFirstChangeNotificationW" - c_FindFirstChangeNotification :: LPCTSTR -> Bool -> FileNotificationFlag -> IO HANDLE findNextChangeNotification :: HANDLE -> IO () findNextChangeNotification h = failIfFalse_ "FindNextChangeNotification" $ c_FindNextChangeNotification h -foreign import WINDOWS_CCONV unsafe "windows.h FindNextChangeNotification" - c_FindNextChangeNotification :: HANDLE -> IO Bool findCloseChangeNotification :: HANDLE -> IO () findCloseChangeNotification h = failIfFalse_ "FindCloseChangeNotification" $ c_FindCloseChangeNotification h -foreign import WINDOWS_CCONV unsafe "windows.h FindCloseChangeNotification" - c_FindCloseChangeNotification :: HANDLE -> IO Bool ---------------------------------------------------------------- -- Directories ---------------------------------------------------------------- -type WIN32_FIND_DATA = () - -newtype FindData = FindData (ForeignPtr WIN32_FIND_DATA) - getFindDataFileName :: FindData -> IO FilePath getFindDataFileName (FindData fp) = withForeignPtr fp $ \p -> @@ -845,8 +455,6 @@ findFirstFile str = do failIf (== iNVALID_HANDLE_VALUE) "findFirstFile" $ c_FindFirstFile tstr p_finddata return (handle, FindData fp_finddata) -foreign import WINDOWS_CCONV unsafe "windows.h FindFirstFileW" - c_FindFirstFile :: LPCTSTR -> Ptr WIN32_FIND_DATA -> IO HANDLE findNextFile :: HANDLE -> FindData -> IO Bool -- False -> no more files findNextFile h (FindData finddata) = do @@ -859,13 +467,9 @@ findNextFile h (FindData finddata) = do if err_code == (# const ERROR_NO_MORE_FILES ) then return False else failWith "findNextFile" err_code -foreign import WINDOWS_CCONV unsafe "windows.h FindNextFileW" - c_FindNextFile :: HANDLE -> Ptr WIN32_FIND_DATA -> IO BOOL findClose :: HANDLE -> IO () findClose h = failIfFalse_ "findClose" $ c_FindClose h -foreign import WINDOWS_CCONV unsafe "windows.h FindClose" - c_FindClose :: HANDLE -> IO BOOL ---------------------------------------------------------------- -- DOS Device flags @@ -876,33 +480,12 @@ defineDosDevice flags name path = maybeWith withTString path $ \ c_path -> withTString name $ \ c_name -> failIfFalse_ "DefineDosDevice" $ c_DefineDosDevice flags c_name c_path -foreign import WINDOWS_CCONV unsafe "windows.h DefineDosDeviceW" - c_DefineDosDevice :: DefineDosDeviceFlags -> LPCTSTR -> LPCTSTR -> IO Bool - ----------------------------------------------------------------- - --- These functions are very unusual in the Win32 API: --- They don't return error codes - -foreign import WINDOWS_CCONV unsafe "windows.h AreFileApisANSI" - areFileApisANSI :: IO Bool - -foreign import WINDOWS_CCONV unsafe "windows.h SetFileApisToOEM" - setFileApisToOEM :: IO () - -foreign import WINDOWS_CCONV unsafe "windows.h SetFileApisToANSI" - setFileApisToANSI :: IO () - -foreign import WINDOWS_CCONV unsafe "windows.h SetHandleCount" - setHandleCount :: UINT -> IO UINT ---------------------------------------------------------------- getLogicalDrives :: IO DWORD getLogicalDrives = failIfZero "GetLogicalDrives" $ c_GetLogicalDrives -foreign import WINDOWS_CCONV unsafe "windows.h GetLogicalDrives" - c_GetLogicalDrives :: IO DWORD -- %fun GetDriveType :: Maybe String -> IO DriveType @@ -920,16 +503,12 @@ getDiskFreeSpace path = nfree <- peek p_nfree nclusters <- peek p_nclusters return (sectors, bytes, nfree, nclusters) -foreign import WINDOWS_CCONV unsafe "windows.h GetDiskFreeSpaceW" - c_GetDiskFreeSpace :: LPCTSTR -> Ptr DWORD -> Ptr DWORD -> Ptr DWORD -> Ptr DWORD -> IO Bool setVolumeLabel :: Maybe String -> Maybe String -> IO () setVolumeLabel path name = maybeWith withTString path $ \ c_path -> maybeWith withTString name $ \ c_name -> failIfFalse_ "SetVolumeLabel" $ c_SetVolumeLabel c_path c_name -foreign import WINDOWS_CCONV unsafe "windows.h SetVolumeLabelW" - c_SetVolumeLabel :: LPCTSTR -> LPCTSTR -> IO Bool ---------------------------------------------------------------- -- File locks @@ -951,10 +530,6 @@ lockFile hwnd mode size f_offset = ovlp = OVERLAPPED 0 0 o_low o_hi nullPtr with ovlp $ \ptr -> c_LockFileEx hwnd mode 0 s_low s_hi ptr -foreign import WINDOWS_CCONV unsafe "LockFileEx" - c_LockFileEx :: HANDLE -> DWORD -> DWORD -> DWORD -> DWORD -> LPOVERLAPPED - -> IO BOOL - -- | Unlocks a given range in a file handle, To unlock an entire file -- use 0xFFFFFFFFFFFFFFFF for size and 0 for offset. unlockFile :: HANDLE -- ^ CreateFile handle @@ -970,9 +545,6 @@ unlockFile hwnd size f_offset = ovlp = OVERLAPPED 0 0 o_low o_hi nullPtr with ovlp $ \ptr -> c_UnlockFileEx hwnd 0 s_low s_hi ptr -foreign import WINDOWS_CCONV unsafe "UnlockFileEx" - c_UnlockFileEx :: HANDLE -> DWORD -> DWORD -> DWORD -> LPOVERLAPPED -> IO BOOL - ---------------------------------------------------------------- -- End ---------------------------------------------------------------- diff --git a/System/Win32/File/Internal.hsc b/System/Win32/File/Internal.hsc new file mode 100644 index 0000000..a7a3b07 --- /dev/null +++ b/System/Win32/File/Internal.hsc @@ -0,0 +1,529 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.File.Internal +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.File.Internal where + +import System.Win32.Types +import System.Win32.Time + +import Foreign hiding (void) + +##include "windows_cconv.h" + +#include +#include "alignment.h" + +---------------------------------------------------------------- +-- Enumeration types +---------------------------------------------------------------- + +type AccessMode = UINT + +gENERIC_NONE :: AccessMode +gENERIC_NONE = 0 + +#{enum AccessMode, + , gENERIC_READ = GENERIC_READ + , gENERIC_WRITE = GENERIC_WRITE + , gENERIC_EXECUTE = GENERIC_EXECUTE + , gENERIC_ALL = GENERIC_ALL + , dELETE = DELETE + , rEAD_CONTROL = READ_CONTROL + , wRITE_DAC = WRITE_DAC + , wRITE_OWNER = WRITE_OWNER + , sYNCHRONIZE = SYNCHRONIZE + , sTANDARD_RIGHTS_REQUIRED = STANDARD_RIGHTS_REQUIRED + , sTANDARD_RIGHTS_READ = STANDARD_RIGHTS_READ + , sTANDARD_RIGHTS_WRITE = STANDARD_RIGHTS_WRITE + , sTANDARD_RIGHTS_EXECUTE = STANDARD_RIGHTS_EXECUTE + , sTANDARD_RIGHTS_ALL = STANDARD_RIGHTS_ALL + , sPECIFIC_RIGHTS_ALL = SPECIFIC_RIGHTS_ALL + , aCCESS_SYSTEM_SECURITY = ACCESS_SYSTEM_SECURITY + , mAXIMUM_ALLOWED = MAXIMUM_ALLOWED + , fILE_ADD_FILE = FILE_ADD_FILE + , fILE_ADD_SUBDIRECTORY = FILE_ADD_SUBDIRECTORY + , fILE_ALL_ACCESS = FILE_ALL_ACCESS + , fILE_APPEND_DATA = FILE_APPEND_DATA + , fILE_CREATE_PIPE_INSTANCE = FILE_CREATE_PIPE_INSTANCE + , fILE_DELETE_CHILD = FILE_DELETE_CHILD + , fILE_EXECUTE = FILE_EXECUTE + , fILE_LIST_DIRECTORY = FILE_LIST_DIRECTORY + , fILE_READ_ATTRIBUTES = FILE_READ_ATTRIBUTES + , fILE_READ_DATA = FILE_READ_DATA + , fILE_READ_EA = FILE_READ_EA + , fILE_TRAVERSE = FILE_TRAVERSE + , fILE_WRITE_ATTRIBUTES = FILE_WRITE_ATTRIBUTES + , fILE_WRITE_DATA = FILE_WRITE_DATA + , fILE_WRITE_EA = FILE_WRITE_EA + } + +---------------------------------------------------------------- + +type ShareMode = UINT + +fILE_SHARE_NONE :: ShareMode +fILE_SHARE_NONE = 0 + +#{enum ShareMode, + , fILE_SHARE_READ = FILE_SHARE_READ + , fILE_SHARE_WRITE = FILE_SHARE_WRITE + , fILE_SHARE_DELETE = FILE_SHARE_DELETE + } + +---------------------------------------------------------------- + +type CreateMode = UINT + +#{enum CreateMode, + , cREATE_NEW = CREATE_NEW + , cREATE_ALWAYS = CREATE_ALWAYS + , oPEN_EXISTING = OPEN_EXISTING + , oPEN_ALWAYS = OPEN_ALWAYS + , tRUNCATE_EXISTING = TRUNCATE_EXISTING + } + +---------------------------------------------------------------- + +type FileAttributeOrFlag = UINT + +#{enum FileAttributeOrFlag, + , fILE_ATTRIBUTE_READONLY = FILE_ATTRIBUTE_READONLY + , fILE_ATTRIBUTE_HIDDEN = FILE_ATTRIBUTE_HIDDEN + , fILE_ATTRIBUTE_SYSTEM = FILE_ATTRIBUTE_SYSTEM + , fILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY + , fILE_ATTRIBUTE_ARCHIVE = FILE_ATTRIBUTE_ARCHIVE + , fILE_ATTRIBUTE_NORMAL = FILE_ATTRIBUTE_NORMAL + , fILE_ATTRIBUTE_TEMPORARY = FILE_ATTRIBUTE_TEMPORARY + , fILE_ATTRIBUTE_COMPRESSED = FILE_ATTRIBUTE_COMPRESSED + , fILE_ATTRIBUTE_REPARSE_POINT = FILE_ATTRIBUTE_REPARSE_POINT + , fILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH + , fILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED + , fILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING + , fILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS + , fILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN + , fILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE + , fILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS + , fILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS + } +#ifndef __WINE_WINDOWS_H +#{enum FileAttributeOrFlag, + , sECURITY_ANONYMOUS = SECURITY_ANONYMOUS + , sECURITY_IDENTIFICATION = SECURITY_IDENTIFICATION + , sECURITY_IMPERSONATION = SECURITY_IMPERSONATION + , sECURITY_DELEGATION = SECURITY_DELEGATION + , sECURITY_CONTEXT_TRACKING = SECURITY_CONTEXT_TRACKING + , sECURITY_EFFECTIVE_ONLY = SECURITY_EFFECTIVE_ONLY + , sECURITY_SQOS_PRESENT = SECURITY_SQOS_PRESENT + , sECURITY_VALID_SQOS_FLAGS = SECURITY_VALID_SQOS_FLAGS + } +#endif + +---------------------------------------------------------------- + +type MoveFileFlag = DWORD + +#{enum MoveFileFlag, + , mOVEFILE_REPLACE_EXISTING = MOVEFILE_REPLACE_EXISTING + , mOVEFILE_COPY_ALLOWED = MOVEFILE_COPY_ALLOWED + , mOVEFILE_DELAY_UNTIL_REBOOT = MOVEFILE_DELAY_UNTIL_REBOOT + } + +---------------------------------------------------------------- + +type FilePtrDirection = DWORD + +#{enum FilePtrDirection, + , fILE_BEGIN = FILE_BEGIN + , fILE_CURRENT = FILE_CURRENT + , fILE_END = FILE_END + } + +---------------------------------------------------------------- + +type DriveType = UINT + +#{enum DriveType, + , dRIVE_UNKNOWN = DRIVE_UNKNOWN + , dRIVE_NO_ROOT_DIR = DRIVE_NO_ROOT_DIR + , dRIVE_REMOVABLE = DRIVE_REMOVABLE + , dRIVE_FIXED = DRIVE_FIXED + , dRIVE_REMOTE = DRIVE_REMOTE + , dRIVE_CDROM = DRIVE_CDROM + , dRIVE_RAMDISK = DRIVE_RAMDISK + } + +---------------------------------------------------------------- + +type DefineDosDeviceFlags = DWORD + +#{enum DefineDosDeviceFlags, + , dDD_RAW_TARGET_PATH = DDD_RAW_TARGET_PATH + , dDD_REMOVE_DEFINITION = DDD_REMOVE_DEFINITION + , dDD_EXACT_MATCH_ON_REMOVE = DDD_EXACT_MATCH_ON_REMOVE + } + +---------------------------------------------------------------- + +type BinaryType = DWORD + +#{enum BinaryType, + , sCS_32BIT_BINARY = SCS_32BIT_BINARY + , sCS_DOS_BINARY = SCS_DOS_BINARY + , sCS_WOW_BINARY = SCS_WOW_BINARY + , sCS_PIF_BINARY = SCS_PIF_BINARY + , sCS_POSIX_BINARY = SCS_POSIX_BINARY + , sCS_OS216_BINARY = SCS_OS216_BINARY + } + +---------------------------------------------------------------- + +type FileNotificationFlag = DWORD + +#{enum FileNotificationFlag, + , fILE_NOTIFY_CHANGE_FILE_NAME = FILE_NOTIFY_CHANGE_FILE_NAME + , fILE_NOTIFY_CHANGE_DIR_NAME = FILE_NOTIFY_CHANGE_DIR_NAME + , fILE_NOTIFY_CHANGE_ATTRIBUTES = FILE_NOTIFY_CHANGE_ATTRIBUTES + , fILE_NOTIFY_CHANGE_SIZE = FILE_NOTIFY_CHANGE_SIZE + , fILE_NOTIFY_CHANGE_LAST_WRITE = FILE_NOTIFY_CHANGE_LAST_WRITE + , fILE_NOTIFY_CHANGE_SECURITY = FILE_NOTIFY_CHANGE_SECURITY + } + +---------------------------------------------------------------- + +type FileType = DWORD + +#{enum FileType, + , fILE_TYPE_UNKNOWN = FILE_TYPE_UNKNOWN + , fILE_TYPE_DISK = FILE_TYPE_DISK + , fILE_TYPE_CHAR = FILE_TYPE_CHAR + , fILE_TYPE_PIPE = FILE_TYPE_PIPE + , fILE_TYPE_REMOTE = FILE_TYPE_REMOTE + } + +---------------------------------------------------------------- + +type LockMode = DWORD + +#{enum LockMode, + , lOCKFILE_EXCLUSIVE_LOCK = LOCKFILE_EXCLUSIVE_LOCK + , lOCKFILE_FAIL_IMMEDIATELY = LOCKFILE_FAIL_IMMEDIATELY + } + +---------------------------------------------------------------- + +newtype GET_FILEEX_INFO_LEVELS = GET_FILEEX_INFO_LEVELS (#type GET_FILEEX_INFO_LEVELS) + deriving (Eq, Ord) + +#{enum GET_FILEEX_INFO_LEVELS, GET_FILEEX_INFO_LEVELS + , getFileExInfoStandard = GetFileExInfoStandard + , getFileExMaxInfoLevel = GetFileExMaxInfoLevel + } + +---------------------------------------------------------------- + +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 +---------------------------------------------------------------- + +data BY_HANDLE_FILE_INFORMATION = BY_HANDLE_FILE_INFORMATION + { bhfiFileAttributes :: FileAttributeOrFlag + , bhfiCreationTime, bhfiLastAccessTime, bhfiLastWriteTime :: FILETIME + , bhfiVolumeSerialNumber :: DWORD + , bhfiSize :: DDWORD + , bhfiNumberOfLinks :: DWORD + , bhfiFileIndex :: DDWORD + } deriving (Show) + +instance Storable BY_HANDLE_FILE_INFORMATION where + sizeOf = const (#size BY_HANDLE_FILE_INFORMATION) + alignment _ = #alignment BY_HANDLE_FILE_INFORMATION + poke buf bhi = do + (#poke BY_HANDLE_FILE_INFORMATION, dwFileAttributes) buf (bhfiFileAttributes bhi) + (#poke BY_HANDLE_FILE_INFORMATION, ftCreationTime) buf (bhfiCreationTime bhi) + (#poke BY_HANDLE_FILE_INFORMATION, ftLastAccessTime) buf (bhfiLastAccessTime bhi) + (#poke BY_HANDLE_FILE_INFORMATION, ftLastWriteTime) buf (bhfiLastWriteTime bhi) + (#poke BY_HANDLE_FILE_INFORMATION, dwVolumeSerialNumber) buf (bhfiVolumeSerialNumber bhi) + (#poke BY_HANDLE_FILE_INFORMATION, nFileSizeHigh) buf sizeHi + (#poke BY_HANDLE_FILE_INFORMATION, nFileSizeLow) buf sizeLow + (#poke BY_HANDLE_FILE_INFORMATION, nNumberOfLinks) buf (bhfiNumberOfLinks bhi) + (#poke BY_HANDLE_FILE_INFORMATION, nFileIndexHigh) buf idxHi + (#poke BY_HANDLE_FILE_INFORMATION, nFileIndexLow) buf idxLow + where + (sizeHi,sizeLow) = ddwordToDwords $ bhfiSize bhi + (idxHi,idxLow) = ddwordToDwords $ bhfiFileIndex bhi + + peek buf = do + attr <- (#peek BY_HANDLE_FILE_INFORMATION, dwFileAttributes) buf + ctim <- (#peek BY_HANDLE_FILE_INFORMATION, ftCreationTime) buf + lati <- (#peek BY_HANDLE_FILE_INFORMATION, ftLastAccessTime) buf + lwti <- (#peek BY_HANDLE_FILE_INFORMATION, ftLastWriteTime) buf + vser <- (#peek BY_HANDLE_FILE_INFORMATION, dwVolumeSerialNumber) buf + fshi <- (#peek BY_HANDLE_FILE_INFORMATION, nFileSizeHigh) buf + fslo <- (#peek BY_HANDLE_FILE_INFORMATION, nFileSizeLow) buf + link <- (#peek BY_HANDLE_FILE_INFORMATION, nNumberOfLinks) buf + idhi <- (#peek BY_HANDLE_FILE_INFORMATION, nFileIndexHigh) buf + idlo <- (#peek BY_HANDLE_FILE_INFORMATION, nFileIndexLow) buf + return $ BY_HANDLE_FILE_INFORMATION attr ctim lati lwti vser + (dwordsToDdword (fshi,fslo)) link (dwordsToDdword (idhi,idlo)) + +---------------------------------------------------------------- + +data WIN32_FILE_ATTRIBUTE_DATA = WIN32_FILE_ATTRIBUTE_DATA + { fadFileAttributes :: DWORD + , fadCreationTime , fadLastAccessTime , fadLastWriteTime :: FILETIME + , fadFileSize :: DDWORD + } deriving (Show) + +instance Storable WIN32_FILE_ATTRIBUTE_DATA where + sizeOf = const (#size WIN32_FILE_ATTRIBUTE_DATA) + alignment _ = #alignment WIN32_FILE_ATTRIBUTE_DATA + poke buf ad = do + (#poke WIN32_FILE_ATTRIBUTE_DATA, dwFileAttributes) buf (fadFileAttributes ad) + (#poke WIN32_FILE_ATTRIBUTE_DATA, ftCreationTime) buf (fadCreationTime ad) + (#poke WIN32_FILE_ATTRIBUTE_DATA, ftLastAccessTime) buf (fadLastAccessTime ad) + (#poke WIN32_FILE_ATTRIBUTE_DATA, ftLastWriteTime) buf (fadLastWriteTime ad) + (#poke WIN32_FILE_ATTRIBUTE_DATA, nFileSizeHigh) buf sizeHi + (#poke WIN32_FILE_ATTRIBUTE_DATA, nFileSizeLow) buf sizeLo + where + (sizeHi,sizeLo) = ddwordToDwords $ fadFileSize ad + + peek buf = do + attr <- (#peek WIN32_FILE_ATTRIBUTE_DATA, dwFileAttributes) buf + ctim <- (#peek WIN32_FILE_ATTRIBUTE_DATA, ftCreationTime) buf + lati <- (#peek WIN32_FILE_ATTRIBUTE_DATA, ftLastAccessTime) buf + lwti <- (#peek WIN32_FILE_ATTRIBUTE_DATA, ftLastWriteTime) buf + fshi <- (#peek WIN32_FILE_ATTRIBUTE_DATA, nFileSizeHigh) buf + fslo <- (#peek WIN32_FILE_ATTRIBUTE_DATA, nFileSizeLow) buf + return $ WIN32_FILE_ATTRIBUTE_DATA attr ctim lati lwti + (dwordsToDdword (fshi,fslo)) + +---------------------------------------------------------------- +-- File operations +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "windows.h DeleteFileW" + c_DeleteFile :: LPCTSTR -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h CopyFileW" + c_CopyFile :: LPCTSTR -> LPCTSTR -> Bool -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h MoveFileW" + c_MoveFile :: LPCTSTR -> LPCTSTR -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h MoveFileExW" + c_MoveFileEx :: LPCTSTR -> LPCTSTR -> MoveFileFlag -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h SetCurrentDirectoryW" + c_SetCurrentDirectory :: LPCTSTR -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h CreateDirectoryW" + c_CreateDirectory :: LPCTSTR -> LPSECURITY_ATTRIBUTES -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h CreateDirectoryExW" + c_CreateDirectoryEx :: LPCTSTR -> LPCTSTR -> LPSECURITY_ATTRIBUTES -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h RemoveDirectoryW" + c_RemoveDirectory :: LPCTSTR -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h GetBinaryTypeW" + c_GetBinaryType :: LPCTSTR -> Ptr DWORD -> IO Bool + +---------------------------------------------------------------- +-- HANDLE operations +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "windows.h CreateFileW" + c_CreateFile :: LPCTSTR -> AccessMode -> ShareMode -> LPSECURITY_ATTRIBUTES -> CreateMode -> FileAttributeOrFlag -> HANDLE -> IO HANDLE + +foreign import WINDOWS_CCONV unsafe "windows.h CloseHandle" + c_CloseHandle :: HANDLE -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h GetFileType" + getFileType :: HANDLE -> IO FileType +--Apparently no error code + +foreign import WINDOWS_CCONV unsafe "windows.h FlushFileBuffers" + c_FlushFileBuffers :: HANDLE -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h SetEndOfFile" + c_SetEndOfFile :: HANDLE -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h SetFileAttributesW" + c_SetFileAttributes :: LPCTSTR -> FileAttributeOrFlag -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h GetFileAttributesW" + c_GetFileAttributes :: LPCTSTR -> IO FileAttributeOrFlag + +foreign import WINDOWS_CCONV unsafe "windows.h GetFileAttributesExW" + c_GetFileAttributesEx :: LPCTSTR -> GET_FILEEX_INFO_LEVELS -> Ptr a -> IO BOOL + +foreign import WINDOWS_CCONV unsafe "windows.h GetFileInformationByHandle" + c_GetFileInformationByHandle :: HANDLE -> Ptr BY_HANDLE_FILE_INFORMATION -> IO BOOL + +---------------------------------------------------------------- +-- Read/write files +---------------------------------------------------------------- + +-- No support for this yet +data OVERLAPPED + = OVERLAPPED { ovl_internal :: ULONG_PTR + , ovl_internalHigh :: ULONG_PTR + , ovl_offset :: DWORD + , ovl_offsetHigh :: DWORD + , ovl_hEvent :: HANDLE + } deriving (Show) + +instance Storable OVERLAPPED where + sizeOf = const (#size OVERLAPPED) + alignment _ = #alignment OVERLAPPED + poke buf ad = do + (#poke OVERLAPPED, Internal ) buf (ovl_internal ad) + (#poke OVERLAPPED, InternalHigh) buf (ovl_internalHigh ad) + (#poke OVERLAPPED, Offset ) buf (ovl_offset ad) + (#poke OVERLAPPED, OffsetHigh ) buf (ovl_offsetHigh ad) + (#poke OVERLAPPED, hEvent ) buf (ovl_hEvent ad) + + peek buf = do + intnl <- (#peek OVERLAPPED, Internal ) buf + intnl_high <- (#peek OVERLAPPED, InternalHigh) buf + off <- (#peek OVERLAPPED, Offset ) buf + off_high <- (#peek OVERLAPPED, OffsetHigh ) buf + hevnt <- (#peek OVERLAPPED, hEvent ) buf + return $ OVERLAPPED intnl intnl_high off off_high hevnt + +type LPOVERLAPPED = Ptr OVERLAPPED + +type MbLPOVERLAPPED = Maybe LPOVERLAPPED + +foreign import WINDOWS_CCONV unsafe "windows.h ReadFile" + c_ReadFile :: HANDLE -> Ptr a -> DWORD -> Ptr DWORD -> LPOVERLAPPED -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h WriteFile" + c_WriteFile :: HANDLE -> Ptr a -> DWORD -> Ptr DWORD -> LPOVERLAPPED -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h SetFilePointerEx" + c_SetFilePointerEx :: HANDLE -> LARGE_INTEGER -> Ptr LARGE_INTEGER -> FilePtrDirection -> IO Bool + +---------------------------------------------------------------- +-- File Notifications +-- +-- Use these to initialise, "increment" and close a HANDLE you can wait +-- on. +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "windows.h FindFirstChangeNotificationW" + c_FindFirstChangeNotification :: LPCTSTR -> Bool -> FileNotificationFlag -> IO HANDLE + +foreign import WINDOWS_CCONV unsafe "windows.h FindNextChangeNotification" + c_FindNextChangeNotification :: HANDLE -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h FindCloseChangeNotification" + c_FindCloseChangeNotification :: HANDLE -> IO Bool + +---------------------------------------------------------------- +-- Directories +---------------------------------------------------------------- + +type WIN32_FIND_DATA = () + +newtype FindData = FindData (ForeignPtr WIN32_FIND_DATA) + +foreign import WINDOWS_CCONV unsafe "windows.h FindFirstFileW" + c_FindFirstFile :: LPCTSTR -> Ptr WIN32_FIND_DATA -> IO HANDLE + +foreign import WINDOWS_CCONV unsafe "windows.h FindNextFileW" + c_FindNextFile :: HANDLE -> Ptr WIN32_FIND_DATA -> IO BOOL + +foreign import WINDOWS_CCONV unsafe "windows.h FindClose" + c_FindClose :: HANDLE -> IO BOOL + +---------------------------------------------------------------- +-- DOS Device flags +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "windows.h DefineDosDeviceW" + c_DefineDosDevice :: DefineDosDeviceFlags -> LPCTSTR -> LPCTSTR -> IO Bool + +---------------------------------------------------------------- + +-- These functions are very unusual in the Win32 API: +-- They don't return error codes + +foreign import WINDOWS_CCONV unsafe "windows.h AreFileApisANSI" + areFileApisANSI :: IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h SetFileApisToOEM" + setFileApisToOEM :: IO () + +foreign import WINDOWS_CCONV unsafe "windows.h SetFileApisToANSI" + setFileApisToANSI :: IO () + +foreign import WINDOWS_CCONV unsafe "windows.h SetHandleCount" + setHandleCount :: UINT -> IO UINT + +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "windows.h GetLogicalDrives" + c_GetLogicalDrives :: IO DWORD + +-- %fun GetDriveType :: Maybe String -> IO DriveType + +foreign import WINDOWS_CCONV unsafe "windows.h GetDiskFreeSpaceW" + c_GetDiskFreeSpace :: LPCTSTR -> Ptr DWORD -> Ptr DWORD -> Ptr DWORD -> Ptr DWORD -> IO Bool + +foreign import WINDOWS_CCONV unsafe "windows.h SetVolumeLabelW" + c_SetVolumeLabel :: LPCTSTR -> LPCTSTR -> IO Bool + +---------------------------------------------------------------- +-- File locks +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "LockFileEx" + c_LockFileEx :: HANDLE -> DWORD -> DWORD -> DWORD -> DWORD -> LPOVERLAPPED + -> IO BOOL + +foreign import WINDOWS_CCONV unsafe "UnlockFileEx" + c_UnlockFileEx :: HANDLE -> DWORD -> DWORD -> DWORD -> LPOVERLAPPED -> IO BOOL + +---------------------------------------------------------------- +-- End +---------------------------------------------------------------- diff --git a/System/Win32/FileMapping.hsc b/System/Win32/FileMapping.hsc index be12ad1..9330e48 100644 --- a/System/Win32/FileMapping.hsc +++ b/System/Win32/FileMapping.hsc @@ -44,7 +44,9 @@ module System.Win32.FileMapping , unmapViewOfFile ) where -import System.Win32.Types ( HANDLE, DWORD, BOOL, SIZE_T, LPCTSTR, withTString + +import System.Win32.FileMapping.Internal +import System.Win32.Types ( HANDLE, BOOL, SIZE_T, withTString , failIf, failIfNull, DDWORD, ddwordToDwords , iNVALID_HANDLE_VALUE ) import System.Win32.Mem @@ -52,9 +54,8 @@ import System.Win32.File import System.Win32.Info import Control.Exception ( mask_, bracket ) -import Foreign ( Ptr, nullPtr, plusPtr, maybeWith, FunPtr +import Foreign ( Ptr, nullPtr, plusPtr, maybeWith , ForeignPtr, newForeignPtr ) -import Foreign.C.Types (CUIntPtr(..)) ##include "windows_cconv.h" @@ -81,8 +82,6 @@ mapFile path = do newForeignPtr c_UnmapViewOfFileFinaliser ptr return (fp, fromIntegral $ bhfiSize fi) -data MappedObject = MappedObject HANDLE HANDLE FileMapAccess - -- | Opens an existing file and creates mapping object to it. withMappedFile :: FilePath -- ^ Path @@ -127,24 +126,6 @@ withMappedArea (MappedObject _ mh access) pos size act = do (unmapViewOfFile) (act . flip plusPtr (fromIntegral offset)) ---------------------------------------------------------------------------- --- Enums ---------------------------------------------------------------------------- -type ProtectSectionFlags = DWORD -#{enum ProtectSectionFlags, - , sEC_COMMIT = SEC_COMMIT - , sEC_IMAGE = SEC_IMAGE - , sEC_NOCACHE = SEC_NOCACHE - , sEC_RESERVE = SEC_RESERVE - } -type FileMapAccess = DWORD -#{enum FileMapAccess, - , fILE_MAP_ALL_ACCESS = FILE_MAP_ALL_ACCESS - , fILE_MAP_COPY = FILE_MAP_COPY - , fILE_MAP_READ = FILE_MAP_READ - , fILE_MAP_WRITE = FILE_MAP_WRITE - } - --------------------------------------------------------------------------- -- API in Haskell --------------------------------------------------------------------------- @@ -175,21 +156,3 @@ mapViewOfFile h a o s = mapViewOfFileEx h a o s nullPtr unmapViewOfFile :: Ptr a -> IO () unmapViewOfFile v = c_UnmapViewOfFile v >> return () ---------------------------------------------------------------------------- --- Imports ---------------------------------------------------------------------------- -foreign import WINDOWS_CCONV "windows.h OpenFileMappingW" - c_OpenFileMapping :: DWORD -> BOOL -> LPCTSTR -> IO HANDLE - -foreign import WINDOWS_CCONV "windows.h CreateFileMappingW" - c_CreateFileMapping :: HANDLE -> Ptr () -> DWORD -> DWORD -> DWORD -> LPCTSTR -> IO HANDLE - -foreign import WINDOWS_CCONV "windows.h MapViewOfFileEx" - c_MapViewOfFileEx :: HANDLE -> DWORD -> DWORD -> DWORD -> SIZE_T -> Ptr a -> IO (Ptr b) - -foreign import WINDOWS_CCONV "windows.h UnmapViewOfFile" - c_UnmapViewOfFile :: Ptr a -> IO BOOL - -{-# CFILES cbits/HsWin32.c #-} -foreign import ccall "HsWin32.h &UnmapViewOfFileFinaliser" - c_UnmapViewOfFileFinaliser :: FunPtr (Ptr a -> IO ()) diff --git a/System/Win32/FileMapping/Internal.hsc b/System/Win32/FileMapping/Internal.hsc new file mode 100644 index 0000000..3fc9725 --- /dev/null +++ b/System/Win32/FileMapping/Internal.hsc @@ -0,0 +1,72 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.FileMapping.Internal +-- Copyright : (c) Esa Ilari Vuokko, 2006 +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32 mapped files. +-- +----------------------------------------------------------------------------- +module System.Win32.FileMapping.Internal where + +import System.Win32.Types ( HANDLE, DWORD, BOOL, SIZE_T, LPCTSTR ) + +import Foreign ( Ptr, FunPtr ) +import Foreign.C.Types (CUIntPtr(..)) + +##include "windows_cconv.h" + +#include "windows.h" + +--------------------------------------------------------------------------- +-- Derived functions +--------------------------------------------------------------------------- + +data MappedObject = MappedObject HANDLE HANDLE FileMapAccess + + +--------------------------------------------------------------------------- +-- Enums +--------------------------------------------------------------------------- +type ProtectSectionFlags = DWORD +#{enum ProtectSectionFlags, + , sEC_COMMIT = SEC_COMMIT + , sEC_IMAGE = SEC_IMAGE + , sEC_NOCACHE = SEC_NOCACHE + , sEC_RESERVE = SEC_RESERVE + } +type FileMapAccess = DWORD +#{enum FileMapAccess, + , fILE_MAP_ALL_ACCESS = FILE_MAP_ALL_ACCESS + , fILE_MAP_COPY = FILE_MAP_COPY + , fILE_MAP_READ = FILE_MAP_READ + , fILE_MAP_WRITE = FILE_MAP_WRITE + } + +--------------------------------------------------------------------------- +-- Imports +--------------------------------------------------------------------------- +foreign import WINDOWS_CCONV "windows.h OpenFileMappingW" + c_OpenFileMapping :: DWORD -> BOOL -> LPCTSTR -> IO HANDLE + +foreign import WINDOWS_CCONV "windows.h CreateFileMappingW" + c_CreateFileMapping :: HANDLE -> Ptr () -> DWORD -> DWORD -> DWORD -> LPCTSTR -> IO HANDLE + +foreign import WINDOWS_CCONV "windows.h MapViewOfFileEx" + c_MapViewOfFileEx :: HANDLE -> DWORD -> DWORD -> DWORD -> SIZE_T -> Ptr a -> IO (Ptr b) + +foreign import WINDOWS_CCONV "windows.h UnmapViewOfFile" + c_UnmapViewOfFile :: Ptr a -> IO BOOL + +{-# CFILES cbits/HsWin32.c #-} +foreign import ccall "HsWin32.h &UnmapViewOfFileFinaliser" + c_UnmapViewOfFileFinaliser :: FunPtr (Ptr a -> IO ()) diff --git a/System/Win32/HardLink.hs b/System/Win32/HardLink.hs index 2b3275d..3ba8e9b 100644 --- a/System/Win32/HardLink.hs +++ b/System/Win32/HardLink.hs @@ -21,9 +21,10 @@ module System.Win32.HardLink , createHardLink' ) where -import System.Win32.File ( LPSECURITY_ATTRIBUTES, failIfFalseWithRetry_ ) -import System.Win32.String ( LPCTSTR, withTString ) -import System.Win32.Types ( BOOL, nullPtr ) +import System.Win32.HardLink.Internal +import System.Win32.File ( failIfFalseWithRetry_ ) +import System.Win32.String ( withTString ) +import System.Win32.Types ( nullPtr ) #include "windows_cconv.h" @@ -44,11 +45,6 @@ createHardLink' link target = failIfFalseWithRetry_ (unwords ["CreateHardLinkW",show link,show target]) $ c_CreateHardLink c_link c_target nullPtr -foreign import WINDOWS_CCONV unsafe "windows.h CreateHardLinkW" - c_CreateHardLink :: LPCTSTR -- ^ Hard link name - -> LPCTSTR -- ^ Target file path - -> LPSECURITY_ATTRIBUTES -- ^ This parameter is reserved. You should pass just /nullPtr/. - -> IO BOOL {- -- We plan to check file system type internally. diff --git a/System/Win32/HardLink/Internal.hs b/System/Win32/HardLink/Internal.hs new file mode 100644 index 0000000..633e530 --- /dev/null +++ b/System/Win32/HardLink/Internal.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE CPP #-} +{- | + Module : System.Win32.HardLink.Internal + Copyright : 2013 shelarcy + License : BSD-style + + Maintainer : shelarcy@gmail.com + Stability : Provisional + Portability : Non-portable (Win32 API) + + Handling hard link using Win32 API. [NTFS only] + + Note: You should worry about file system type when use this module's function in your application: + + * NTFS only supprts this functionality. + + * ReFS doesn't support hard link currently. +-} +module System.Win32.HardLink.Internal where + +import System.Win32.File ( LPSECURITY_ATTRIBUTES ) +import System.Win32.String ( LPCTSTR ) +import System.Win32.Types ( BOOL ) + +#include "windows_cconv.h" + +foreign import WINDOWS_CCONV unsafe "windows.h CreateHardLinkW" + c_CreateHardLink :: LPCTSTR -- ^ Hard link name + -> LPCTSTR -- ^ Target file path + -> LPSECURITY_ATTRIBUTES -- ^ This parameter is reserved. You should pass just /nullPtr/. + -> IO BOOL diff --git a/System/Win32/Info.hsc b/System/Win32/Info.hsc index dc21d57..82fea45 100644 --- a/System/Win32/Info.hsc +++ b/System/Win32/Info.hsc @@ -129,14 +129,14 @@ module System.Win32.Info , getUserName ) where +import System.Win32.Info.Internal import Control.Exception (catch) import Foreign.Marshal.Alloc (alloca) import Foreign.Marshal.Utils (with, maybeWith) import Foreign.Marshal.Array (allocaArray) -import Foreign.Ptr (Ptr, nullPtr) +import Foreign.Ptr (nullPtr) import Foreign.Storable (Storable(..)) import System.IO.Error (isDoesNotExistError) -import System.Win32.Types (DWORD, LPDWORD, LPCTSTR, LPTSTR, LPVOID, UINT, WORD) import System.Win32.Types (failIfFalse_, peekTStringLen, withTString, try) #if !MIN_VERSION_base(4,6,0) @@ -174,41 +174,6 @@ import Prelude hiding (catch) -- %fun GetKeyboardType :: KeyboardTypeKind -> IO KeyboardType ----------------------------------------------------------------- --- System Color ----------------------------------------------------------------- - -type SystemColor = UINT - --- ToDo: This list is out of date. - -#{enum SystemColor, - , cOLOR_SCROLLBAR = COLOR_SCROLLBAR - , cOLOR_BACKGROUND = COLOR_BACKGROUND - , cOLOR_ACTIVECAPTION = COLOR_ACTIVECAPTION - , cOLOR_INACTIVECAPTION = COLOR_INACTIVECAPTION - , cOLOR_MENU = COLOR_MENU - , cOLOR_WINDOW = COLOR_WINDOW - , cOLOR_WINDOWFRAME = COLOR_WINDOWFRAME - , cOLOR_MENUTEXT = COLOR_MENUTEXT - , cOLOR_WINDOWTEXT = COLOR_WINDOWTEXT - , cOLOR_CAPTIONTEXT = COLOR_CAPTIONTEXT - , cOLOR_ACTIVEBORDER = COLOR_ACTIVEBORDER - , cOLOR_INACTIVEBORDER = COLOR_INACTIVEBORDER - , cOLOR_APPWORKSPACE = COLOR_APPWORKSPACE - , cOLOR_HIGHLIGHT = COLOR_HIGHLIGHT - , cOLOR_HIGHLIGHTTEXT = COLOR_HIGHLIGHTTEXT - , cOLOR_BTNFACE = COLOR_BTNFACE - , cOLOR_BTNSHADOW = COLOR_BTNSHADOW - , cOLOR_GRAYTEXT = COLOR_GRAYTEXT - , cOLOR_BTNTEXT = COLOR_BTNTEXT - , cOLOR_INACTIVECAPTIONTEXT = COLOR_INACTIVECAPTIONTEXT - , cOLOR_BTNHIGHLIGHT = COLOR_BTNHIGHLIGHT - } - --- %fun GetSysColor :: SystemColor -> IO COLORREF --- %fun SetSysColors :: [(SystemColor,COLORREF)] -> IO () - ---------------------------------------------------------------- -- Standard Directories ---------------------------------------------------------------- @@ -256,204 +221,15 @@ searchPath path filename ext = then return Nothing else ioError e -foreign import WINDOWS_CCONV unsafe "GetWindowsDirectoryW" - c_getWindowsDirectory :: LPTSTR -> UINT -> IO UINT - -foreign import WINDOWS_CCONV unsafe "GetSystemDirectoryW" - c_getSystemDirectory :: LPTSTR -> UINT -> IO UINT - -foreign import WINDOWS_CCONV unsafe "GetCurrentDirectoryW" - c_getCurrentDirectory :: DWORD -> LPTSTR -> IO UINT - -foreign import WINDOWS_CCONV unsafe "GetTempPathW" - c_getTempPath :: DWORD -> LPTSTR -> IO UINT - -foreign import WINDOWS_CCONV unsafe "GetFullPathNameW" - c_GetFullPathName :: LPCTSTR -> DWORD -> LPTSTR -> Ptr LPTSTR -> IO DWORD - -foreign import WINDOWS_CCONV unsafe "GetLongPathNameW" - c_GetLongPathName :: LPCTSTR -> LPTSTR -> DWORD -> IO DWORD - -foreign import WINDOWS_CCONV unsafe "GetShortPathNameW" - c_GetShortPathName :: LPCTSTR -> LPTSTR -> DWORD -> IO DWORD - -foreign import WINDOWS_CCONV unsafe "SearchPathW" - c_SearchPath :: LPCTSTR -> LPCTSTR -> LPCTSTR -> DWORD -> LPTSTR -> Ptr LPTSTR - -> IO DWORD - ---------------------------------------------------------------- -- System Info (Info about processor and memory subsystem) ---------------------------------------------------------------- -data ProcessorArchitecture = PaUnknown WORD | PaIntel | PaMips | PaAlpha | PaPpc | PaIa64 | PaIa32OnIa64 | PaAmd64 - deriving (Show,Eq) - -instance Storable ProcessorArchitecture where - sizeOf _ = sizeOf (undefined::WORD) - alignment _ = alignment (undefined::WORD) - poke buf pa = pokeByteOff buf 0 $ case pa of - PaUnknown w -> w - PaIntel -> #const PROCESSOR_ARCHITECTURE_INTEL - PaMips -> #const PROCESSOR_ARCHITECTURE_MIPS - PaAlpha -> #const PROCESSOR_ARCHITECTURE_ALPHA - PaPpc -> #const PROCESSOR_ARCHITECTURE_PPC - PaIa64 -> #const PROCESSOR_ARCHITECTURE_IA64 -#ifndef __WINE_WINDOWS_H - PaIa32OnIa64 -> #const PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 -#endif - PaAmd64 -> #const PROCESSOR_ARCHITECTURE_AMD64 - peek buf = do - v <- (peekByteOff buf 0:: IO WORD) - return $ case v of - (#const PROCESSOR_ARCHITECTURE_INTEL) -> PaIntel - (#const PROCESSOR_ARCHITECTURE_MIPS) -> PaMips - (#const PROCESSOR_ARCHITECTURE_ALPHA) -> PaAlpha - (#const PROCESSOR_ARCHITECTURE_PPC) -> PaPpc - (#const PROCESSOR_ARCHITECTURE_IA64) -> PaIa64 -#ifndef __WINE_WINDOWS_H - (#const PROCESSOR_ARCHITECTURE_IA32_ON_WIN64) -> PaIa32OnIa64 -#endif - (#const PROCESSOR_ARCHITECTURE_AMD64) -> PaAmd64 - w -> PaUnknown w - -data SYSTEM_INFO = SYSTEM_INFO - { siProcessorArchitecture :: ProcessorArchitecture - , siPageSize :: DWORD - , siMinimumApplicationAddress, siMaximumApplicationAddress :: LPVOID - , siActiveProcessorMask :: DWORD - , siNumberOfProcessors :: DWORD - , siProcessorType :: DWORD - , siAllocationGranularity :: DWORD - , siProcessorLevel :: WORD - , siProcessorRevision :: WORD - } deriving (Show) - -instance Storable SYSTEM_INFO where - sizeOf = const #size SYSTEM_INFO - alignment _ = #alignment SYSTEM_INFO - poke buf si = do - (#poke SYSTEM_INFO, wProcessorArchitecture) buf (siProcessorArchitecture si) - (#poke SYSTEM_INFO, dwPageSize) buf (siPageSize si) - (#poke SYSTEM_INFO, lpMinimumApplicationAddress) buf (siMinimumApplicationAddress si) - (#poke SYSTEM_INFO, lpMaximumApplicationAddress) buf (siMaximumApplicationAddress si) - (#poke SYSTEM_INFO, dwActiveProcessorMask) buf (siActiveProcessorMask si) - (#poke SYSTEM_INFO, dwNumberOfProcessors) buf (siNumberOfProcessors si) - (#poke SYSTEM_INFO, dwProcessorType) buf (siProcessorType si) - (#poke SYSTEM_INFO, dwAllocationGranularity) buf (siAllocationGranularity si) - (#poke SYSTEM_INFO, wProcessorLevel) buf (siProcessorLevel si) - (#poke SYSTEM_INFO, wProcessorRevision) buf (siProcessorRevision si) - - peek buf = do - processorArchitecture <- - (#peek SYSTEM_INFO, wProcessorArchitecture) buf - pageSize <- (#peek SYSTEM_INFO, dwPageSize) buf - minimumApplicationAddress <- - (#peek SYSTEM_INFO, lpMinimumApplicationAddress) buf - maximumApplicationAddress <- - (#peek SYSTEM_INFO, lpMaximumApplicationAddress) buf - activeProcessorMask <- (#peek SYSTEM_INFO, dwActiveProcessorMask) buf - numberOfProcessors <- (#peek SYSTEM_INFO, dwNumberOfProcessors) buf - processorType <- (#peek SYSTEM_INFO, dwProcessorType) buf - allocationGranularity <- - (#peek SYSTEM_INFO, dwAllocationGranularity) buf - processorLevel <- (#peek SYSTEM_INFO, wProcessorLevel) buf - processorRevision <- (#peek SYSTEM_INFO, wProcessorRevision) buf - return $ SYSTEM_INFO { - siProcessorArchitecture = processorArchitecture, - siPageSize = pageSize, - siMinimumApplicationAddress = minimumApplicationAddress, - siMaximumApplicationAddress = maximumApplicationAddress, - siActiveProcessorMask = activeProcessorMask, - siNumberOfProcessors = numberOfProcessors, - siProcessorType = processorType, - siAllocationGranularity = allocationGranularity, - siProcessorLevel = processorLevel, - siProcessorRevision = processorRevision - } - -foreign import WINDOWS_CCONV unsafe "windows.h GetSystemInfo" - c_GetSystemInfo :: Ptr SYSTEM_INFO -> IO () - getSystemInfo :: IO SYSTEM_INFO getSystemInfo = alloca $ \ret -> do c_GetSystemInfo ret peek ret ----------------------------------------------------------------- --- System metrics ----------------------------------------------------------------- - -type SMSetting = UINT - -#{enum SMSetting, - , sM_ARRANGE = SM_ARRANGE - , sM_CLEANBOOT = SM_CLEANBOOT - , sM_CMETRICS = SM_CMETRICS - , sM_CMOUSEBUTTONS = SM_CMOUSEBUTTONS - , sM_CXBORDER = SM_CXBORDER - , sM_CYBORDER = SM_CYBORDER - , sM_CXCURSOR = SM_CXCURSOR - , sM_CYCURSOR = SM_CYCURSOR - , sM_CXDLGFRAME = SM_CXDLGFRAME - , sM_CYDLGFRAME = SM_CYDLGFRAME - , sM_CXDOUBLECLK = SM_CXDOUBLECLK - , sM_CYDOUBLECLK = SM_CYDOUBLECLK - , sM_CXDRAG = SM_CXDRAG - , sM_CYDRAG = SM_CYDRAG - , sM_CXEDGE = SM_CXEDGE - , sM_CYEDGE = SM_CYEDGE - , sM_CXFRAME = SM_CXFRAME - , sM_CYFRAME = SM_CYFRAME - , sM_CXFULLSCREEN = SM_CXFULLSCREEN - , sM_CYFULLSCREEN = SM_CYFULLSCREEN - , sM_CXHSCROLL = SM_CXHSCROLL - , sM_CYVSCROLL = SM_CYVSCROLL - , sM_CXICON = SM_CXICON - , sM_CYICON = SM_CYICON - , sM_CXICONSPACING = SM_CXICONSPACING - , sM_CYICONSPACING = SM_CYICONSPACING - , sM_CXMAXIMIZED = SM_CXMAXIMIZED - , sM_CYMAXIMIZED = SM_CYMAXIMIZED - , sM_CXMENUCHECK = SM_CXMENUCHECK - , sM_CYMENUCHECK = SM_CYMENUCHECK - , sM_CXMENUSIZE = SM_CXMENUSIZE - , sM_CYMENUSIZE = SM_CYMENUSIZE - , sM_CXMIN = SM_CXMIN - , sM_CYMIN = SM_CYMIN - , sM_CXMINIMIZED = SM_CXMINIMIZED - , sM_CYMINIMIZED = SM_CYMINIMIZED - , sM_CXMINTRACK = SM_CXMINTRACK - , sM_CYMINTRACK = SM_CYMINTRACK - , sM_CXSCREEN = SM_CXSCREEN - , sM_CYSCREEN = SM_CYSCREEN - , sM_CXSIZE = SM_CXSIZE - , sM_CYSIZE = SM_CYSIZE - , sM_CXSIZEFRAME = SM_CXSIZEFRAME - , sM_CYSIZEFRAME = SM_CYSIZEFRAME - , sM_CXSMICON = SM_CXSMICON - , sM_CYSMICON = SM_CYSMICON - , sM_CXSMSIZE = SM_CXSMSIZE - , sM_CYSMSIZE = SM_CYSMSIZE - , sM_CXVSCROLL = SM_CXVSCROLL - , sM_CYHSCROLL = SM_CYHSCROLL - , sM_CYVTHUMB = SM_CYVTHUMB - , sM_CYCAPTION = SM_CYCAPTION - , sM_CYKANJIWINDOW = SM_CYKANJIWINDOW - , sM_CYMENU = SM_CYMENU - , sM_CYSMCAPTION = SM_CYSMCAPTION - , sM_DBCSENABLED = SM_DBCSENABLED - , sM_DEBUG = SM_DEBUG - , sM_MENUDROPALIGNMENT = SM_MENUDROPALIGNMENT - , sM_MIDEASTENABLED = SM_MIDEASTENABLED - , sM_MOUSEPRESENT = SM_MOUSEPRESENT - , sM_NETWORK = SM_NETWORK - , sM_PENWINDOWS = SM_PENWINDOWS - , sM_SECURE = SM_SECURE - , sM_SHOWSOUNDS = SM_SHOWSOUNDS - , sM_SLOWMACHINE = SM_SLOWMACHINE - , sM_SWAPBUTTON = SM_SWAPBUTTON - } - -- %fun GetSystemMetrics :: SMSetting -> IO Int ---------------------------------------------------------------- @@ -469,9 +245,6 @@ type SMSetting = UINT -- %fun GetUserName :: IO String -foreign import WINDOWS_CCONV unsafe "windows.h GetUserNameW" - c_GetUserName :: LPTSTR -> LPDWORD -> IO Bool - getUserName :: IO String getUserName = allocaArray 512 $ \ c_str -> diff --git a/System/Win32/Info/Internal.hsc b/System/Win32/Info/Internal.hsc new file mode 100644 index 0000000..d85e5cb --- /dev/null +++ b/System/Win32/Info/Internal.hsc @@ -0,0 +1,313 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Info.Internal +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.Info.Internal where + +import Foreign.Ptr (Ptr) +import Foreign.Storable (Storable(..)) +import System.Win32.Types (DWORD, LPDWORD, LPCTSTR, LPTSTR, LPVOID, UINT, WORD) + +#if !MIN_VERSION_base(4,6,0) +import Prelude hiding (catch) +#endif + +##include "windows_cconv.h" + +#include +#include "alignment.h" + +---------------------------------------------------------------- +-- Environment Strings +---------------------------------------------------------------- + +-- %fun ExpandEnvironmentStrings :: String -> IO String + +---------------------------------------------------------------- +-- Computer Name +---------------------------------------------------------------- + +-- %fun GetComputerName :: IO String +-- %fun SetComputerName :: String -> IO () +-- %end free(arg1) + +---------------------------------------------------------------- +-- Hardware Profiles +---------------------------------------------------------------- + +-- %fun GetCurrentHwProfile :: IO HW_PROFILE_INFO + +---------------------------------------------------------------- +-- Keyboard Type +---------------------------------------------------------------- + +-- %fun GetKeyboardType :: KeyboardTypeKind -> IO KeyboardType + +---------------------------------------------------------------- +-- System Color +---------------------------------------------------------------- + +type SystemColor = UINT + +-- ToDo: This list is out of date. + +#{enum SystemColor, + , cOLOR_SCROLLBAR = COLOR_SCROLLBAR + , cOLOR_BACKGROUND = COLOR_BACKGROUND + , cOLOR_ACTIVECAPTION = COLOR_ACTIVECAPTION + , cOLOR_INACTIVECAPTION = COLOR_INACTIVECAPTION + , cOLOR_MENU = COLOR_MENU + , cOLOR_WINDOW = COLOR_WINDOW + , cOLOR_WINDOWFRAME = COLOR_WINDOWFRAME + , cOLOR_MENUTEXT = COLOR_MENUTEXT + , cOLOR_WINDOWTEXT = COLOR_WINDOWTEXT + , cOLOR_CAPTIONTEXT = COLOR_CAPTIONTEXT + , cOLOR_ACTIVEBORDER = COLOR_ACTIVEBORDER + , cOLOR_INACTIVEBORDER = COLOR_INACTIVEBORDER + , cOLOR_APPWORKSPACE = COLOR_APPWORKSPACE + , cOLOR_HIGHLIGHT = COLOR_HIGHLIGHT + , cOLOR_HIGHLIGHTTEXT = COLOR_HIGHLIGHTTEXT + , cOLOR_BTNFACE = COLOR_BTNFACE + , cOLOR_BTNSHADOW = COLOR_BTNSHADOW + , cOLOR_GRAYTEXT = COLOR_GRAYTEXT + , cOLOR_BTNTEXT = COLOR_BTNTEXT + , cOLOR_INACTIVECAPTIONTEXT = COLOR_INACTIVECAPTIONTEXT + , cOLOR_BTNHIGHLIGHT = COLOR_BTNHIGHLIGHT + } + +-- %fun GetSysColor :: SystemColor -> IO COLORREF +-- %fun SetSysColors :: [(SystemColor,COLORREF)] -> IO () + +---------------------------------------------------------------- +-- Standard Directories +---------------------------------------------------------------- + +foreign import WINDOWS_CCONV unsafe "GetWindowsDirectoryW" + c_getWindowsDirectory :: LPTSTR -> UINT -> IO UINT + +foreign import WINDOWS_CCONV unsafe "GetSystemDirectoryW" + c_getSystemDirectory :: LPTSTR -> UINT -> IO UINT + +foreign import WINDOWS_CCONV unsafe "GetCurrentDirectoryW" + c_getCurrentDirectory :: DWORD -> LPTSTR -> IO UINT + +foreign import WINDOWS_CCONV unsafe "GetTempPathW" + c_getTempPath :: DWORD -> LPTSTR -> IO UINT + +foreign import WINDOWS_CCONV unsafe "GetFullPathNameW" + c_GetFullPathName :: LPCTSTR -> DWORD -> LPTSTR -> Ptr LPTSTR -> IO DWORD + +foreign import WINDOWS_CCONV unsafe "GetLongPathNameW" + c_GetLongPathName :: LPCTSTR -> LPTSTR -> DWORD -> IO DWORD + +foreign import WINDOWS_CCONV unsafe "GetShortPathNameW" + c_GetShortPathName :: LPCTSTR -> LPTSTR -> DWORD -> IO DWORD + +foreign import WINDOWS_CCONV unsafe "SearchPathW" + c_SearchPath :: LPCTSTR -> LPCTSTR -> LPCTSTR -> DWORD -> LPTSTR -> Ptr LPTSTR + -> IO DWORD + +---------------------------------------------------------------- +-- System Info (Info about processor and memory subsystem) +---------------------------------------------------------------- + +data ProcessorArchitecture = PaUnknown WORD | PaIntel | PaMips | PaAlpha | PaPpc | PaIa64 | PaIa32OnIa64 | PaAmd64 + deriving (Show,Eq) + +instance Storable ProcessorArchitecture where + sizeOf _ = sizeOf (undefined::WORD) + alignment _ = alignment (undefined::WORD) + poke buf pa = pokeByteOff buf 0 $ case pa of + PaUnknown w -> w + PaIntel -> #const PROCESSOR_ARCHITECTURE_INTEL + PaMips -> #const PROCESSOR_ARCHITECTURE_MIPS + PaAlpha -> #const PROCESSOR_ARCHITECTURE_ALPHA + PaPpc -> #const PROCESSOR_ARCHITECTURE_PPC + PaIa64 -> #const PROCESSOR_ARCHITECTURE_IA64 +#ifndef __WINE_WINDOWS_H + PaIa32OnIa64 -> #const PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 +#endif + PaAmd64 -> #const PROCESSOR_ARCHITECTURE_AMD64 + peek buf = do + v <- (peekByteOff buf 0:: IO WORD) + return $ case v of + (#const PROCESSOR_ARCHITECTURE_INTEL) -> PaIntel + (#const PROCESSOR_ARCHITECTURE_MIPS) -> PaMips + (#const PROCESSOR_ARCHITECTURE_ALPHA) -> PaAlpha + (#const PROCESSOR_ARCHITECTURE_PPC) -> PaPpc + (#const PROCESSOR_ARCHITECTURE_IA64) -> PaIa64 +#ifndef __WINE_WINDOWS_H + (#const PROCESSOR_ARCHITECTURE_IA32_ON_WIN64) -> PaIa32OnIa64 +#endif + (#const PROCESSOR_ARCHITECTURE_AMD64) -> PaAmd64 + w -> PaUnknown w + +data SYSTEM_INFO = SYSTEM_INFO + { siProcessorArchitecture :: ProcessorArchitecture + , siPageSize :: DWORD + , siMinimumApplicationAddress, siMaximumApplicationAddress :: LPVOID + , siActiveProcessorMask :: DWORD + , siNumberOfProcessors :: DWORD + , siProcessorType :: DWORD + , siAllocationGranularity :: DWORD + , siProcessorLevel :: WORD + , siProcessorRevision :: WORD + } deriving (Show) + +instance Storable SYSTEM_INFO where + sizeOf = const #size SYSTEM_INFO + alignment _ = #alignment SYSTEM_INFO + poke buf si = do + (#poke SYSTEM_INFO, wProcessorArchitecture) buf (siProcessorArchitecture si) + (#poke SYSTEM_INFO, dwPageSize) buf (siPageSize si) + (#poke SYSTEM_INFO, lpMinimumApplicationAddress) buf (siMinimumApplicationAddress si) + (#poke SYSTEM_INFO, lpMaximumApplicationAddress) buf (siMaximumApplicationAddress si) + (#poke SYSTEM_INFO, dwActiveProcessorMask) buf (siActiveProcessorMask si) + (#poke SYSTEM_INFO, dwNumberOfProcessors) buf (siNumberOfProcessors si) + (#poke SYSTEM_INFO, dwProcessorType) buf (siProcessorType si) + (#poke SYSTEM_INFO, dwAllocationGranularity) buf (siAllocationGranularity si) + (#poke SYSTEM_INFO, wProcessorLevel) buf (siProcessorLevel si) + (#poke SYSTEM_INFO, wProcessorRevision) buf (siProcessorRevision si) + + peek buf = do + processorArchitecture <- + (#peek SYSTEM_INFO, wProcessorArchitecture) buf + pageSize <- (#peek SYSTEM_INFO, dwPageSize) buf + minimumApplicationAddress <- + (#peek SYSTEM_INFO, lpMinimumApplicationAddress) buf + maximumApplicationAddress <- + (#peek SYSTEM_INFO, lpMaximumApplicationAddress) buf + activeProcessorMask <- (#peek SYSTEM_INFO, dwActiveProcessorMask) buf + numberOfProcessors <- (#peek SYSTEM_INFO, dwNumberOfProcessors) buf + processorType <- (#peek SYSTEM_INFO, dwProcessorType) buf + allocationGranularity <- + (#peek SYSTEM_INFO, dwAllocationGranularity) buf + processorLevel <- (#peek SYSTEM_INFO, wProcessorLevel) buf + processorRevision <- (#peek SYSTEM_INFO, wProcessorRevision) buf + return $ SYSTEM_INFO { + siProcessorArchitecture = processorArchitecture, + siPageSize = pageSize, + siMinimumApplicationAddress = minimumApplicationAddress, + siMaximumApplicationAddress = maximumApplicationAddress, + siActiveProcessorMask = activeProcessorMask, + siNumberOfProcessors = numberOfProcessors, + siProcessorType = processorType, + siAllocationGranularity = allocationGranularity, + siProcessorLevel = processorLevel, + siProcessorRevision = processorRevision + } + +foreign import WINDOWS_CCONV unsafe "windows.h GetSystemInfo" + c_GetSystemInfo :: Ptr SYSTEM_INFO -> IO () + +---------------------------------------------------------------- +-- System metrics +---------------------------------------------------------------- + +type SMSetting = UINT + +#{enum SMSetting, + , sM_ARRANGE = SM_ARRANGE + , sM_CLEANBOOT = SM_CLEANBOOT + , sM_CMETRICS = SM_CMETRICS + , sM_CMOUSEBUTTONS = SM_CMOUSEBUTTONS + , sM_CXBORDER = SM_CXBORDER + , sM_CYBORDER = SM_CYBORDER + , sM_CXCURSOR = SM_CXCURSOR + , sM_CYCURSOR = SM_CYCURSOR + , sM_CXDLGFRAME = SM_CXDLGFRAME + , sM_CYDLGFRAME = SM_CYDLGFRAME + , sM_CXDOUBLECLK = SM_CXDOUBLECLK + , sM_CYDOUBLECLK = SM_CYDOUBLECLK + , sM_CXDRAG = SM_CXDRAG + , sM_CYDRAG = SM_CYDRAG + , sM_CXEDGE = SM_CXEDGE + , sM_CYEDGE = SM_CYEDGE + , sM_CXFRAME = SM_CXFRAME + , sM_CYFRAME = SM_CYFRAME + , sM_CXFULLSCREEN = SM_CXFULLSCREEN + , sM_CYFULLSCREEN = SM_CYFULLSCREEN + , sM_CXHSCROLL = SM_CXHSCROLL + , sM_CYVSCROLL = SM_CYVSCROLL + , sM_CXICON = SM_CXICON + , sM_CYICON = SM_CYICON + , sM_CXICONSPACING = SM_CXICONSPACING + , sM_CYICONSPACING = SM_CYICONSPACING + , sM_CXMAXIMIZED = SM_CXMAXIMIZED + , sM_CYMAXIMIZED = SM_CYMAXIMIZED + , sM_CXMENUCHECK = SM_CXMENUCHECK + , sM_CYMENUCHECK = SM_CYMENUCHECK + , sM_CXMENUSIZE = SM_CXMENUSIZE + , sM_CYMENUSIZE = SM_CYMENUSIZE + , sM_CXMIN = SM_CXMIN + , sM_CYMIN = SM_CYMIN + , sM_CXMINIMIZED = SM_CXMINIMIZED + , sM_CYMINIMIZED = SM_CYMINIMIZED + , sM_CXMINTRACK = SM_CXMINTRACK + , sM_CYMINTRACK = SM_CYMINTRACK + , sM_CXSCREEN = SM_CXSCREEN + , sM_CYSCREEN = SM_CYSCREEN + , sM_CXSIZE = SM_CXSIZE + , sM_CYSIZE = SM_CYSIZE + , sM_CXSIZEFRAME = SM_CXSIZEFRAME + , sM_CYSIZEFRAME = SM_CYSIZEFRAME + , sM_CXSMICON = SM_CXSMICON + , sM_CYSMICON = SM_CYSMICON + , sM_CXSMSIZE = SM_CXSMSIZE + , sM_CYSMSIZE = SM_CYSMSIZE + , sM_CXVSCROLL = SM_CXVSCROLL + , sM_CYHSCROLL = SM_CYHSCROLL + , sM_CYVTHUMB = SM_CYVTHUMB + , sM_CYCAPTION = SM_CYCAPTION + , sM_CYKANJIWINDOW = SM_CYKANJIWINDOW + , sM_CYMENU = SM_CYMENU + , sM_CYSMCAPTION = SM_CYSMCAPTION + , sM_DBCSENABLED = SM_DBCSENABLED + , sM_DEBUG = SM_DEBUG + , sM_MENUDROPALIGNMENT = SM_MENUDROPALIGNMENT + , sM_MIDEASTENABLED = SM_MIDEASTENABLED + , sM_MOUSEPRESENT = SM_MOUSEPRESENT + , sM_NETWORK = SM_NETWORK + , sM_PENWINDOWS = SM_PENWINDOWS + , sM_SECURE = SM_SECURE + , sM_SHOWSOUNDS = SM_SHOWSOUNDS + , sM_SLOWMACHINE = SM_SLOWMACHINE + , sM_SWAPBUTTON = SM_SWAPBUTTON + } + +-- %fun GetSystemMetrics :: SMSetting -> IO Int + +---------------------------------------------------------------- +-- Thread Desktops +---------------------------------------------------------------- + +-- %fun GetThreadDesktop :: ThreadId -> IO HDESK +-- %fun SetThreadDesktop :: ThreadId -> HDESK -> IO () + +---------------------------------------------------------------- +-- User name +---------------------------------------------------------------- + +-- %fun GetUserName :: IO String + +foreign import WINDOWS_CCONV unsafe "windows.h GetUserNameW" + c_GetUserName :: LPTSTR -> LPDWORD -> IO Bool + +---------------------------------------------------------------- +-- End +---------------------------------------------------------------- diff --git a/System/Win32/Path.hsc b/System/Win32/Path.hsc index cb45308..8296766 100644 --- a/System/Win32/Path.hsc +++ b/System/Win32/Path.hsc @@ -22,6 +22,7 @@ module System.Win32.Path ( , pathRelativePathTo ) where +import System.Win32.Path.Internal import System.Win32.Types import System.Win32.File @@ -53,5 +54,3 @@ pathRelativePathTo from from_attr to to_attr = _ <- localFree p_AbsPath return path -foreign import WINDOWS_CCONV unsafe "Shlwapi.h PathRelativePathToW" - c_pathRelativePathTo :: LPTSTR -> LPCTSTR -> DWORD -> LPCTSTR -> DWORD -> IO UINT diff --git a/System/Win32/Path/Internal.hsc b/System/Win32/Path/Internal.hsc new file mode 100644 index 0000000..695c72b --- /dev/null +++ b/System/Win32/Path/Internal.hsc @@ -0,0 +1,29 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Path.Internal +-- Copyright : (c) Tamar Christina, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Tamar Christina +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.Path.Internal where + +import System.Win32.Types + +##include "windows_cconv.h" + +#include + +foreign import WINDOWS_CCONV unsafe "Shlwapi.h PathRelativePathToW" + c_pathRelativePathTo :: LPTSTR -> LPCTSTR -> DWORD -> LPCTSTR -> DWORD -> IO UINT diff --git a/System/Win32/Shell.hsc b/System/Win32/Shell.hsc index d503cae..89e6b6d 100644 --- a/System/Win32/Shell.hsc +++ b/System/Win32/Shell.hsc @@ -32,13 +32,13 @@ module System.Win32.Shell ( sHGFP_TYPE_DEFAULT ) where +import System.Win32.Shell.Internal import System.Win32.Types import Graphics.Win32.GDI.Types (HWND) import Foreign import Foreign.C import Control.Monad -import System.IO.Error ##include "windows_cconv.h" @@ -79,11 +79,3 @@ sHGetFolderPath hwnd csidl hdl flags = r <- c_SHGetFolderPath hwnd csidl hdl flags pstr when (r < 0) $ raiseUnsupported "sHGetFolderPath" peekTString pstr - -raiseUnsupported :: String -> IO () -raiseUnsupported loc = - ioError (ioeSetErrorString (mkIOError illegalOperationErrorType loc Nothing Nothing) "unsupported operation") - -foreign import WINDOWS_CCONV unsafe "SHGetFolderPathW" - c_SHGetFolderPath :: HWND -> CInt -> HANDLE -> DWORD -> LPTSTR - -> IO HRESULT diff --git a/System/Win32/Shell/Internal.hsc b/System/Win32/Shell/Internal.hsc new file mode 100644 index 0000000..dd1d0ec --- /dev/null +++ b/System/Win32/Shell/Internal.hsc @@ -0,0 +1,50 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Shell.Internal +-- Copyright : (c) The University of Glasgow 2009 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- Win32 stuff from shell32.dll +-- +----------------------------------------------------------------------------- + +module System.Win32.Shell.Internal ( + c_SHGetFolderPath + , raiseUnsupported + ) where + +import System.Win32.Types +import Graphics.Win32.GDI.Types (HWND) + +import Foreign.C +import System.IO.Error + +##include "windows_cconv.h" + +-- for SHGetFolderPath stuff +#define _WIN32_IE 0x500 +#include +#include + +---------------------------------------------------------------- +-- SHGetFolderPath +-- +-- XXX: this is deprecated in Vista and later +---------------------------------------------------------------- + +raiseUnsupported :: String -> IO () +raiseUnsupported loc = + ioError (ioeSetErrorString (mkIOError illegalOperationErrorType loc Nothing Nothing) "unsupported operation") + +foreign import WINDOWS_CCONV unsafe "SHGetFolderPathW" + c_SHGetFolderPath :: HWND -> CInt -> HANDLE -> DWORD -> LPTSTR + -> IO HRESULT diff --git a/System/Win32/SymbolicLink.hsc b/System/Win32/SymbolicLink.hsc index e7867e6..de8bb4a 100644 --- a/System/Win32/SymbolicLink.hsc +++ b/System/Win32/SymbolicLink.hsc @@ -35,19 +35,13 @@ module System.Win32.SymbolicLink , createSymbolicLinkDirectory ) where +import System.Win32.SymbolicLink.Internal import Data.Bits ((.|.)) import System.Win32.Types import System.Win32.File ( failIfFalseWithRetry_ ) ##include "windows_cconv.h" -type SymbolicLinkFlags = DWORD - -#{enum SymbolicLinkFlags, - , sYMBOLIC_LINK_FLAG_FILE = 0x0 - , sYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 - , sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 -} -- | createSymbolicLink* functions don't check that file is exist or not. -- @@ -97,5 +91,3 @@ createSymbolicLink' link target flag = do failIfFalseWithRetry_ (unwords ["CreateSymbolicLink",show link,show target]) $ c_CreateSymbolicLink c_link c_target flag -foreign import WINDOWS_CCONV unsafe "windows.h CreateSymbolicLinkW" - c_CreateSymbolicLink :: LPTSTR -> LPTSTR -> SymbolicLinkFlags -> IO BOOL diff --git a/System/Win32/SymbolicLink/Internal.hsc b/System/Win32/SymbolicLink/Internal.hsc new file mode 100644 index 0000000..a88a058 --- /dev/null +++ b/System/Win32/SymbolicLink/Internal.hsc @@ -0,0 +1,26 @@ +{-# LANGUAGE CPP #-} +{- | + Module : System.Win32.SymbolicLink.Internal + Copyright : 2012 shelarcy + License : BSD-style + + Maintainer : shelarcy@gmail.com + Stability : Provisional + Portability : Non-portable (Win32 API) +-} +module System.Win32.SymbolicLink.Internal where + +import System.Win32.Types + +##include "windows_cconv.h" + +type SymbolicLinkFlags = DWORD + +#{enum SymbolicLinkFlags, + , sYMBOLIC_LINK_FLAG_FILE = 0x0 + , sYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 + , sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 +} + +foreign import WINDOWS_CCONV unsafe "windows.h CreateSymbolicLinkW" + c_CreateSymbolicLink :: LPTSTR -> LPTSTR -> SymbolicLinkFlags -> IO BOOL diff --git a/System/Win32/Time.hsc b/System/Win32/Time.hsc index 29f3025..bba194b 100644 --- a/System/Win32/Time.hsc +++ b/System/Win32/Time.hsc @@ -52,21 +52,19 @@ module System.Win32.Time , getTimeFormat ) where +import System.Win32.Time.Internal import System.Win32.String ( peekTStringLen, withTString ) -import System.Win32.Types ( BOOL, DDWORD, DWORD, HANDLE, LARGE_INTEGER, LCID - , LONG, LPCTSTR, LPCWSTR, LPTSTR, LPWSTR, UINT, WORD - , dwordsToDdword, ddwordToDwords, failIf +import System.Win32.Types ( DWORD, HANDLE, LCID + , failIf , failIfFalse_, failIf_ ) import System.Win32.Utils ( trySized ) -import Control.Monad ( when, liftM3, liftM ) -import Data.Word ( Word8 ) -import Foreign ( Storable(sizeOf, alignment, peekByteOff, peek, - pokeByteOff, poke) - , Ptr, nullPtr, castPtr, plusPtr, advancePtr - , with, alloca, allocaBytes, copyArray ) -import Foreign.C ( CInt(..), CWchar(..) - , peekCWString, withCWStringLen, withCWString ) +import Control.Monad ( liftM3, liftM ) +import Foreign ( Storable(sizeOf, peek) + , Ptr, nullPtr, castPtr + , with, alloca, allocaBytes ) +import Foreign.C ( CWchar(..) + , withCWString ) import Foreign.Marshal.Utils (maybeWith) ##include "windows_cconv.h" @@ -74,145 +72,30 @@ import Foreign.Marshal.Utils (maybeWith) #include "alignment.h" #include "winnls_compat.h" ----------------------------------------------------------------- --- data types ----------------------------------------------------------------- -newtype FILETIME = FILETIME DDWORD deriving (Show, Eq, Ord) - -data SYSTEMTIME = SYSTEMTIME { - wYear, wMonth, wDayOfWeek, wDay, wHour, wMinute, wSecond, wMilliseconds :: WORD } - deriving (Show, Eq, Ord) - -data TIME_ZONE_INFORMATION = TIME_ZONE_INFORMATION - { tziBias :: LONG - , tziStandardName :: String - , tziStandardDate :: SYSTEMTIME - , tziStandardBias :: LONG - , tziDaylightName :: String - , tziDaylightDate :: SYSTEMTIME - , tziDaylightBias :: LONG - } deriving (Show,Eq,Ord) - -data TimeZoneId = TzIdUnknown | TzIdStandard | TzIdDaylight - deriving (Show, Eq, Ord) - -data LASTINPUTINFO = LASTINPUTINFO DWORD deriving (Show) - ----------------------------------------------------------------- --- Instances ----------------------------------------------------------------- - -instance Storable FILETIME where - sizeOf = const (#size FILETIME) - alignment _ = #alignment FILETIME - poke buf (FILETIME n) = do - (#poke FILETIME, dwLowDateTime) buf low - (#poke FILETIME, dwHighDateTime) buf hi - where (hi,low) = ddwordToDwords n - peek buf = do - low <- (#peek FILETIME, dwLowDateTime) buf - hi <- (#peek FILETIME, dwHighDateTime) buf - return $ FILETIME $ dwordsToDdword (hi,low) - -instance Storable SYSTEMTIME where - sizeOf _ = #size SYSTEMTIME - alignment _ = #alignment SYSTEMTIME - poke buf st = do - (#poke SYSTEMTIME, wYear) buf (wYear st) - (#poke SYSTEMTIME, wMonth) buf (wMonth st) - (#poke SYSTEMTIME, wDayOfWeek) buf (wDayOfWeek st) - (#poke SYSTEMTIME, wDay) buf (wDay st) - (#poke SYSTEMTIME, wHour) buf (wHour st) - (#poke SYSTEMTIME, wMinute) buf (wMinute st) - (#poke SYSTEMTIME, wSecond) buf (wSecond st) - (#poke SYSTEMTIME, wMilliseconds) buf (wMilliseconds st) - peek buf = do - year <- (#peek SYSTEMTIME, wYear) buf - month <- (#peek SYSTEMTIME, wMonth) buf - dow <- (#peek SYSTEMTIME, wDayOfWeek) buf - day <- (#peek SYSTEMTIME, wDay) buf - hour <- (#peek SYSTEMTIME, wHour) buf - mins <- (#peek SYSTEMTIME, wMinute) buf - sec <- (#peek SYSTEMTIME, wSecond) buf - ms <- (#peek SYSTEMTIME, wMilliseconds) buf - return $ SYSTEMTIME year month dow day hour mins sec ms - -instance Storable TIME_ZONE_INFORMATION where - sizeOf _ = (#size TIME_ZONE_INFORMATION) - alignment _ = #alignment TIME_ZONE_INFORMATION - poke buf tzi = do - (#poke TIME_ZONE_INFORMATION, Bias) buf (tziBias tzi) - (#poke TIME_ZONE_INFORMATION, StandardDate) buf (tziStandardDate tzi) - (#poke TIME_ZONE_INFORMATION, StandardBias) buf (tziStandardBias tzi) - (#poke TIME_ZONE_INFORMATION, DaylightDate) buf (tziDaylightDate tzi) - (#poke TIME_ZONE_INFORMATION, DaylightBias) buf (tziDaylightBias tzi) - write buf (#offset TIME_ZONE_INFORMATION, StandardName) (tziStandardName tzi) - write buf (#offset TIME_ZONE_INFORMATION, DaylightName) (tziDaylightName tzi) - where - write buf_ offset str = withCWStringLen str $ \(c_str,len) -> do - when (len>31) $ fail "Storable TIME_ZONE_INFORMATION.poke: Too long string." - let len' = len * sizeOf (undefined :: CWchar) - start = (advancePtr (castPtr buf_) offset) - end = advancePtr start len' - copyArray start (castPtr c_str :: Ptr Word8) len' - poke (castPtr end) (0 :: CWchar) - - peek buf = do - bias <- (#peek TIME_ZONE_INFORMATION, Bias) buf - sdat <- (#peek TIME_ZONE_INFORMATION, StandardDate) buf - sbia <- (#peek TIME_ZONE_INFORMATION, StandardBias) buf - ddat <- (#peek TIME_ZONE_INFORMATION, DaylightDate) buf - dbia <- (#peek TIME_ZONE_INFORMATION, DaylightBias) buf - snam <- peekCWString (plusPtr buf (#offset TIME_ZONE_INFORMATION, StandardName)) - dnam <- peekCWString (plusPtr buf (#offset TIME_ZONE_INFORMATION, DaylightName)) - return $ TIME_ZONE_INFORMATION bias snam sdat sbia dnam ddat dbia - -instance Storable LASTINPUTINFO where - sizeOf = const (#size LASTINPUTINFO) - alignment = sizeOf - poke buf (LASTINPUTINFO t) = do - (#poke LASTINPUTINFO, cbSize) buf ((#size LASTINPUTINFO) :: UINT) - (#poke LASTINPUTINFO, dwTime) buf t - peek buf = do - t <- (#peek LASTINPUTINFO, dwTime) buf - return $ LASTINPUTINFO t - -foreign import WINDOWS_CCONV "windows.h GetSystemTime" - c_GetSystemTime :: Ptr SYSTEMTIME -> IO () getSystemTime :: IO SYSTEMTIME getSystemTime = alloca $ \res -> do c_GetSystemTime res peek res -foreign import WINDOWS_CCONV "windows.h SetSystemTime" - c_SetSystemTime :: Ptr SYSTEMTIME -> IO BOOL setSystemTime :: SYSTEMTIME -> IO () setSystemTime st = with st $ \c_st -> failIf_ not "setSystemTime: SetSystemTime" $ c_SetSystemTime c_st -foreign import WINDOWS_CCONV "windows.h GetSystemTimeAsFileTime" - c_GetSystemTimeAsFileTime :: Ptr FILETIME -> IO () getSystemTimeAsFileTime :: IO FILETIME getSystemTimeAsFileTime = alloca $ \ret -> do c_GetSystemTimeAsFileTime ret peek ret -foreign import WINDOWS_CCONV "windows.h GetLocalTime" - c_GetLocalTime :: Ptr SYSTEMTIME -> IO () getLocalTime :: IO SYSTEMTIME getLocalTime = alloca $ \res -> do c_GetLocalTime res peek res -foreign import WINDOWS_CCONV "windows.h SetLocalTime" - c_SetLocalTime :: Ptr SYSTEMTIME -> IO BOOL setLocalTime :: SYSTEMTIME -> IO () setLocalTime st = with st $ \c_st -> failIf_ not "setLocalTime: SetLocalTime" $ c_SetLocalTime c_st -foreign import WINDOWS_CCONV "windows.h GetSystemTimeAdjustment" - c_GetSystemTimeAdjustment :: Ptr DWORD -> Ptr DWORD -> Ptr BOOL -> IO BOOL getSystemTimeAdjustment :: IO (Maybe (Int, Int)) getSystemTimeAdjustment = alloca $ \ta -> alloca $ \ti -> alloca $ \enabled -> do failIf_ not "getSystemTimeAdjustment: GetSystemTimeAdjustment" $ @@ -225,10 +108,6 @@ getSystemTimeAdjustment = alloca $ \ta -> alloca $ \ti -> alloca $ \enabled -> d return $ Just (fromIntegral ta', fromIntegral ti') else return Nothing -foreign import WINDOWS_CCONV "windows.h GetTickCount" getTickCount :: IO DWORD - -foreign import WINDOWS_CCONV unsafe "windows.h GetLastInputInfo" - c_GetLastInputInfo :: Ptr LASTINPUTINFO -> IO Bool getLastInputInfo :: IO DWORD getLastInputInfo = with (LASTINPUTINFO 0) $ \lii_p -> do @@ -242,8 +121,6 @@ getIdleTime = do now <- getTickCount return $ fromIntegral $ now - lii -foreign import WINDOWS_CCONV "windows.h SetSystemTimeAdjustment" - c_SetSystemTimeAdjustment :: DWORD -> BOOL -> IO BOOL setSystemTimeAdjustment :: Maybe Int -> IO () setSystemTimeAdjustment ta = failIf_ not "setSystemTimeAjustment: SetSystemTimeAdjustment" $ @@ -253,8 +130,6 @@ setSystemTimeAdjustment ta = Nothing -> (0,True) Just x -> (fromIntegral x,False) -foreign import WINDOWS_CCONV "windows.h GetTimeZoneInformation" - c_GetTimeZoneInformation :: Ptr TIME_ZONE_INFORMATION -> IO DWORD getTimeZoneInformation :: IO (TimeZoneId, TIME_ZONE_INFORMATION) getTimeZoneInformation = alloca $ \tzi -> do tz <- failIf (==(#const TIME_ZONE_ID_INVALID)) "getTimeZoneInformation: GetTimeZoneInformation" $ @@ -266,24 +141,18 @@ getTimeZoneInformation = alloca $ \tzi -> do (#const TIME_ZONE_ID_DAYLIGHT) -> TzIdDaylight _ -> TzIdUnknown -- to remove warning -foreign import WINDOWS_CCONV "windows.h SystemTimeToFileTime" - c_SystemTimeToFileTime :: Ptr SYSTEMTIME -> Ptr FILETIME -> IO BOOL systemTimeToFileTime :: SYSTEMTIME -> IO FILETIME systemTimeToFileTime s = with s $ \c_s -> alloca $ \ret -> do failIf_ not "systemTimeToFileTime: SystemTimeToFileTime" $ c_SystemTimeToFileTime c_s ret peek ret -foreign import WINDOWS_CCONV "windows.h FileTimeToSystemTime" - c_FileTimeToSystemTime :: Ptr FILETIME -> Ptr SYSTEMTIME -> IO BOOL fileTimeToSystemTime :: FILETIME -> IO SYSTEMTIME fileTimeToSystemTime s = with s $ \c_s -> alloca $ \ret -> do failIf_ not "fileTimeToSystemTime: FileTimeToSystemTime" $ c_FileTimeToSystemTime c_s ret peek ret -foreign import WINDOWS_CCONV "windows.h GetFileTime" - c_GetFileTime :: HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL getFileTime :: HANDLE -> IO (FILETIME,FILETIME,FILETIME) getFileTime h = alloca $ \crt -> alloca $ \acc -> alloca $ \wrt -> do failIf_ not "getFileTime: GetFileTime" $ c_GetFileTime h crt acc wrt @@ -292,8 +161,6 @@ getFileTime h = alloca $ \crt -> alloca $ \acc -> alloca $ \wrt -> do invalidFileTime :: FILETIME invalidFileTime = FILETIME 0 -foreign import WINDOWS_CCONV "windows.h SetFileTime" - c_SetFileTime :: HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL setFileTime :: HANDLE -> Maybe FILETIME -> Maybe FILETIME -> Maybe FILETIME -> IO () setFileTime h crt acc wrt = withTime crt $ \c_crt -> withTime acc $ @@ -305,16 +172,12 @@ setFileTime h crt acc wrt = withTime crt $ withTime Nothing k = k nullPtr withTime (Just t) k = with t k -foreign import WINDOWS_CCONV "windows.h FileTimeToLocalFileTime" - c_FileTimeToLocalFileTime :: Ptr FILETIME -> Ptr FILETIME -> IO BOOL fileTimeToLocalFileTime :: FILETIME -> IO FILETIME fileTimeToLocalFileTime ft = with ft $ \c_ft -> alloca $ \res -> do failIf_ not "fileTimeToLocalFileTime: FileTimeToLocalFileTime" $ c_FileTimeToLocalFileTime c_ft res peek res -foreign import WINDOWS_CCONV "windows.h LocalFileTimeToFileTime" - c_LocalFileTimeToFileTime :: Ptr FILETIME -> Ptr FILETIME -> IO BOOL localFileTimeToFileTime :: FILETIME -> IO FILETIME localFileTimeToFileTime ft = with ft $ \c_ft -> alloca $ \res -> do failIf_ not "localFileTimeToFileTime: LocalFileTimeToFileTime" @@ -350,31 +213,18 @@ tzSpecificLocalTimeToSystemTime tzi st = with tzi $ \tzi -> with st $ \st -> all peek res -} -foreign import WINDOWS_CCONV "windows.h QueryPerformanceFrequency" - c_QueryPerformanceFrequency :: Ptr LARGE_INTEGER -> IO BOOL queryPerformanceFrequency :: IO Integer queryPerformanceFrequency = alloca $ \res -> do failIf_ not "queryPerformanceFrequency: QueryPerformanceFrequency" $ c_QueryPerformanceFrequency res liftM fromIntegral $ peek res -foreign import WINDOWS_CCONV "windows.h QueryPerformanceCounter" - c_QueryPerformanceCounter:: Ptr LARGE_INTEGER -> IO BOOL queryPerformanceCounter:: IO Integer queryPerformanceCounter= alloca $ \res -> do failIf_ not "queryPerformanceCounter: QueryPerformanceCounter" $ c_QueryPerformanceCounter res liftM fromIntegral $ peek res -type GetTimeFormatFlags = DWORD -#{enum GetTimeFormatFlags, - , lOCALE_NOUSEROVERRIDE = LOCALE_NOUSEROVERRIDE - , lOCALE_USE_CP_ACP = LOCALE_USE_CP_ACP - , tIME_NOMINUTESORSECONDS = TIME_NOMINUTESORSECONDS - , tIME_NOSECONDS = TIME_NOSECONDS - , tIME_NOTIMEMARKER = TIME_NOTIMEMARKER - , tIME_FORCE24HOURFORMAT= TIME_FORCE24HOURFORMAT - } getTimeFormatEx :: Maybe String -> GetTimeFormatFlags @@ -387,17 +237,7 @@ getTimeFormatEx locale flags st fmt = maybeWith withTString fmt $ \c_fmt -> do let c_func = c_GetTimeFormatEx c_locale flags c_st c_fmt trySized "GetTimeFormatEx" c_func -foreign import WINDOWS_CCONV "windows.h GetTimeFormatEx" - c_GetTimeFormatEx :: LPCWSTR - -> GetTimeFormatFlags - -> Ptr SYSTEMTIME - -> LPCWSTR - -> LPWSTR - -> CInt - -> IO CInt -foreign import WINDOWS_CCONV "windows.h GetTimeFormatW" - c_GetTimeFormat :: LCID -> GetTimeFormatFlags -> Ptr SYSTEMTIME -> LPCTSTR -> LPTSTR -> CInt -> IO CInt getTimeFormat :: LCID -> GetTimeFormatFlags -> Maybe SYSTEMTIME -> Maybe String -> IO String getTimeFormat locale flags st fmt = maybeWith with st $ \c_st -> diff --git a/System/Win32/Time/Internal.hsc b/System/Win32/Time/Internal.hsc new file mode 100644 index 0000000..c88795c --- /dev/null +++ b/System/Win32/Time/Internal.hsc @@ -0,0 +1,245 @@ +#if __GLASGOW_HASKELL__ >= 709 +{-# LANGUAGE Safe #-} +#else +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Time.Internal +-- Copyright : (c) Esa Ilari Vuokko, 2006 +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32 Time API. +-- +----------------------------------------------------------------------------- +module System.Win32.Time.Internal where + +import System.Win32.Types ( BOOL, DDWORD, DWORD, HANDLE, LARGE_INTEGER, LCID + , LONG, LPCTSTR, LPCWSTR, LPTSTR, LPWSTR, UINT, WORD + , dwordsToDdword, ddwordToDwords + ) +import Control.Monad ( when ) +import Data.Word ( Word8 ) +import Foreign ( Storable(sizeOf, alignment, peekByteOff, peek, + pokeByteOff, poke) + , Ptr, castPtr, plusPtr, advancePtr + , copyArray ) +import Foreign.C ( CInt(..), CWchar(..) + , peekCWString, withCWStringLen ) + +##include "windows_cconv.h" +#include +#include "alignment.h" +#include "winnls_compat.h" + +---------------------------------------------------------------- +-- data types +---------------------------------------------------------------- + +newtype FILETIME = FILETIME DDWORD deriving (Show, Eq, Ord) + +data SYSTEMTIME = SYSTEMTIME { + wYear, wMonth, wDayOfWeek, wDay, wHour, wMinute, wSecond, wMilliseconds :: WORD } + deriving (Show, Eq, Ord) + +data TIME_ZONE_INFORMATION = TIME_ZONE_INFORMATION + { tziBias :: LONG + , tziStandardName :: String + , tziStandardDate :: SYSTEMTIME + , tziStandardBias :: LONG + , tziDaylightName :: String + , tziDaylightDate :: SYSTEMTIME + , tziDaylightBias :: LONG + } deriving (Show,Eq,Ord) + +data TimeZoneId = TzIdUnknown | TzIdStandard | TzIdDaylight + deriving (Show, Eq, Ord) + +data LASTINPUTINFO = LASTINPUTINFO DWORD deriving (Show) + +---------------------------------------------------------------- +-- Instances +---------------------------------------------------------------- + +instance Storable FILETIME where + sizeOf = const (#size FILETIME) + alignment _ = #alignment FILETIME + poke buf (FILETIME n) = do + (#poke FILETIME, dwLowDateTime) buf low + (#poke FILETIME, dwHighDateTime) buf hi + where (hi,low) = ddwordToDwords n + peek buf = do + low <- (#peek FILETIME, dwLowDateTime) buf + hi <- (#peek FILETIME, dwHighDateTime) buf + return $ FILETIME $ dwordsToDdword (hi,low) + +instance Storable SYSTEMTIME where + sizeOf _ = #size SYSTEMTIME + alignment _ = #alignment SYSTEMTIME + poke buf st = do + (#poke SYSTEMTIME, wYear) buf (wYear st) + (#poke SYSTEMTIME, wMonth) buf (wMonth st) + (#poke SYSTEMTIME, wDayOfWeek) buf (wDayOfWeek st) + (#poke SYSTEMTIME, wDay) buf (wDay st) + (#poke SYSTEMTIME, wHour) buf (wHour st) + (#poke SYSTEMTIME, wMinute) buf (wMinute st) + (#poke SYSTEMTIME, wSecond) buf (wSecond st) + (#poke SYSTEMTIME, wMilliseconds) buf (wMilliseconds st) + peek buf = do + year <- (#peek SYSTEMTIME, wYear) buf + month <- (#peek SYSTEMTIME, wMonth) buf + dow <- (#peek SYSTEMTIME, wDayOfWeek) buf + day <- (#peek SYSTEMTIME, wDay) buf + hour <- (#peek SYSTEMTIME, wHour) buf + mins <- (#peek SYSTEMTIME, wMinute) buf + sec <- (#peek SYSTEMTIME, wSecond) buf + ms <- (#peek SYSTEMTIME, wMilliseconds) buf + return $ SYSTEMTIME year month dow day hour mins sec ms + +instance Storable TIME_ZONE_INFORMATION where + sizeOf _ = (#size TIME_ZONE_INFORMATION) + alignment _ = #alignment TIME_ZONE_INFORMATION + poke buf tzi = do + (#poke TIME_ZONE_INFORMATION, Bias) buf (tziBias tzi) + (#poke TIME_ZONE_INFORMATION, StandardDate) buf (tziStandardDate tzi) + (#poke TIME_ZONE_INFORMATION, StandardBias) buf (tziStandardBias tzi) + (#poke TIME_ZONE_INFORMATION, DaylightDate) buf (tziDaylightDate tzi) + (#poke TIME_ZONE_INFORMATION, DaylightBias) buf (tziDaylightBias tzi) + write buf (#offset TIME_ZONE_INFORMATION, StandardName) (tziStandardName tzi) + write buf (#offset TIME_ZONE_INFORMATION, DaylightName) (tziDaylightName tzi) + where + write buf_ offset str = withCWStringLen str $ \(c_str,len) -> do + when (len>31) $ fail "Storable TIME_ZONE_INFORMATION.poke: Too long string." + let len' = len * sizeOf (undefined :: CWchar) + start = (advancePtr (castPtr buf_) offset) + end = advancePtr start len' + copyArray start (castPtr c_str :: Ptr Word8) len' + poke (castPtr end) (0 :: CWchar) + + peek buf = do + bias <- (#peek TIME_ZONE_INFORMATION, Bias) buf + sdat <- (#peek TIME_ZONE_INFORMATION, StandardDate) buf + sbia <- (#peek TIME_ZONE_INFORMATION, StandardBias) buf + ddat <- (#peek TIME_ZONE_INFORMATION, DaylightDate) buf + dbia <- (#peek TIME_ZONE_INFORMATION, DaylightBias) buf + snam <- peekCWString (plusPtr buf (#offset TIME_ZONE_INFORMATION, StandardName)) + dnam <- peekCWString (plusPtr buf (#offset TIME_ZONE_INFORMATION, DaylightName)) + return $ TIME_ZONE_INFORMATION bias snam sdat sbia dnam ddat dbia + +instance Storable LASTINPUTINFO where + sizeOf = const (#size LASTINPUTINFO) + alignment = sizeOf + poke buf (LASTINPUTINFO t) = do + (#poke LASTINPUTINFO, cbSize) buf ((#size LASTINPUTINFO) :: UINT) + (#poke LASTINPUTINFO, dwTime) buf t + peek buf = do + t <- (#peek LASTINPUTINFO, dwTime) buf + return $ LASTINPUTINFO t + +foreign import WINDOWS_CCONV "windows.h GetSystemTime" + c_GetSystemTime :: Ptr SYSTEMTIME -> IO () + +foreign import WINDOWS_CCONV "windows.h SetSystemTime" + c_SetSystemTime :: Ptr SYSTEMTIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h GetSystemTimeAsFileTime" + c_GetSystemTimeAsFileTime :: Ptr FILETIME -> IO () + +foreign import WINDOWS_CCONV "windows.h GetLocalTime" + c_GetLocalTime :: Ptr SYSTEMTIME -> IO () + +foreign import WINDOWS_CCONV "windows.h SetLocalTime" + c_SetLocalTime :: Ptr SYSTEMTIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h GetSystemTimeAdjustment" + c_GetSystemTimeAdjustment :: Ptr DWORD -> Ptr DWORD -> Ptr BOOL -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h GetTickCount" getTickCount :: IO DWORD + +foreign import WINDOWS_CCONV unsafe "windows.h GetLastInputInfo" + c_GetLastInputInfo :: Ptr LASTINPUTINFO -> IO Bool + +foreign import WINDOWS_CCONV "windows.h SetSystemTimeAdjustment" + c_SetSystemTimeAdjustment :: DWORD -> BOOL -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h GetTimeZoneInformation" + c_GetTimeZoneInformation :: Ptr TIME_ZONE_INFORMATION -> IO DWORD + +foreign import WINDOWS_CCONV "windows.h SystemTimeToFileTime" + c_SystemTimeToFileTime :: Ptr SYSTEMTIME -> Ptr FILETIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h FileTimeToSystemTime" + c_FileTimeToSystemTime :: Ptr FILETIME -> Ptr SYSTEMTIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h GetFileTime" + c_GetFileTime :: HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h SetFileTime" + c_SetFileTime :: HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h FileTimeToLocalFileTime" + c_FileTimeToLocalFileTime :: Ptr FILETIME -> Ptr FILETIME -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h LocalFileTimeToFileTime" + c_LocalFileTimeToFileTime :: Ptr FILETIME -> Ptr FILETIME -> IO BOOL + +{- +-- Windows XP SP1 +foreign import WINDOWS_CCONV "windows.h GetSystemTimes" + c_GetSystemTimes :: Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO BOOL +getSystemTimes :: IO (FILETIME,FILETIME,FILETIME) +getSystemTimes = alloca $ \idle -> alloca $ \kernel -> alloca $ \user -> do + failIf not "getSystemTimes: GetSystemTimes" $ c_GetSystemTimes idle kernel user + liftM3 (,,) (peek idle) (peek kernel) (peek user) +-} + +{- +-- Windows XP +foreign import WINDOWS_CCONV "windows.h SystemTimeToTzSpecificLocalTime" + c_SystemTimeToTzSpecificLocalTime :: Ptr TIME_ZONE_INFORMATION -> Ptr SYSTEMTIME -> Ptr SYSTEMTIME -> IO BOOL +systemTimeToTzSpecificLocalTime :: TIME_ZONE_INFORMATION -> SYSTEMTIME -> IO SYSTEMTIME +systemTimeToTzSpecificLocalTime tzi st = with tzi $ \tzi -> with st $ \st -> alloca $ \res -> do + failIf not "systemTimeToTzSpecificLocalTime: SystemTimeToTzSpecificLocalTime" $ + c_SystemTimeToTzSpecificLocalTime tzi st res + peek res + +foreign import WINDOWS_CCONV "windows.h TzSpecificLocalTimeToSystemTime" + c_TzSpecificLocalTimeToSystemTime :: Ptr TIME_ZONE_INFORMATION -> Ptr SYSTEMTIME -> Ptr SYSTEMTIME -> IO BOOL +tzSpecificLocalTimeToSystemTime :: TIME_ZONE_INFORMATION -> SYSTEMTIME -> IO SYSTEMTIME +tzSpecificLocalTimeToSystemTime tzi st = with tzi $ \tzi -> with st $ \st -> alloca $ \res -> do + failIf not "tzSpecificLocalTimeToSystemTime: TzSpecificLocalTimeToSystemTime" $ + c_TzSpecificLocalTimeToSystemTime tzi st res + peek res +-} + +foreign import WINDOWS_CCONV "windows.h QueryPerformanceFrequency" + c_QueryPerformanceFrequency :: Ptr LARGE_INTEGER -> IO BOOL + +foreign import WINDOWS_CCONV "windows.h QueryPerformanceCounter" + c_QueryPerformanceCounter:: Ptr LARGE_INTEGER -> IO BOOL + +type GetTimeFormatFlags = DWORD +#{enum GetTimeFormatFlags, + , lOCALE_NOUSEROVERRIDE = LOCALE_NOUSEROVERRIDE + , lOCALE_USE_CP_ACP = LOCALE_USE_CP_ACP + , tIME_NOMINUTESORSECONDS = TIME_NOMINUTESORSECONDS + , tIME_NOSECONDS = TIME_NOSECONDS + , tIME_NOTIMEMARKER = TIME_NOTIMEMARKER + , tIME_FORCE24HOURFORMAT= TIME_FORCE24HOURFORMAT + } + +foreign import WINDOWS_CCONV "windows.h GetTimeFormatEx" + c_GetTimeFormatEx :: LPCWSTR + -> GetTimeFormatFlags + -> Ptr SYSTEMTIME + -> LPCWSTR + -> LPWSTR + -> CInt + -> IO CInt + +foreign import WINDOWS_CCONV "windows.h GetTimeFormatW" + c_GetTimeFormat :: LCID -> GetTimeFormatFlags -> Ptr SYSTEMTIME -> LPCTSTR -> LPTSTR -> CInt -> IO CInt diff --git a/System/Win32/WindowsString/DLL.hsc b/System/Win32/WindowsString/DLL.hsc new file mode 100644 index 0000000..cf126e5 --- /dev/null +++ b/System/Win32/WindowsString/DLL.hsc @@ -0,0 +1,67 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.DLL +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.WindowsString.DLL + ( module System.Win32.WindowsString.DLL + , module System.Win32.DLL + ) where + +import System.Win32.DLL hiding + ( disableThreadLibraryCalls + , freeLibrary + , getModuleFileName + , getModuleHandle + , getProcAddress + , loadLibrary + , loadLibraryEx + , setDllDirectory + , lOAD_LIBRARY_AS_DATAFILE + , lOAD_WITH_ALTERED_SEARCH_PATH + ) +import System.Win32.DLL.Internal +import System.Win32.WindowsString.Types + +import Foreign +import Data.Maybe (fromMaybe) +import System.OsString.Windows +import GHC.IO.Encoding.UTF16 ( mkUTF16le ) +import GHC.IO.Encoding.Failure ( CodingFailureMode(..) ) + +getModuleFileName :: HMODULE -> IO WindowsString +getModuleFileName hmod = + allocaArray 512 $ \ c_str -> do + failIfFalse_ "GetModuleFileName" $ c_GetModuleFileName hmod c_str 512 + peekTString c_str + +getModuleHandle :: Maybe WindowsString -> IO HMODULE +getModuleHandle mb_name = + maybeWith withTString mb_name $ \ c_name -> + failIfNull "GetModuleHandle" $ c_GetModuleHandle c_name + +loadLibrary :: WindowsString -> IO HINSTANCE +loadLibrary name = + withTString name $ \ c_name -> + failIfNull "LoadLibrary" $ c_LoadLibrary c_name + +loadLibraryEx :: WindowsString -> HANDLE -> LoadLibraryFlags -> IO HINSTANCE +loadLibraryEx name h flags = + withTString name $ \ c_name -> + failIfNull "LoadLibraryEx" $ c_LoadLibraryEx c_name h flags + +setDllDirectory :: Maybe WindowsString -> IO () +setDllDirectory name = + maybeWith withTString name $ \ c_name -> do + let nameS = name >>= either (const Nothing) Just . decodeWith (mkUTF16le TransliterateCodingFailure) + failIfFalse_ (unwords ["SetDllDirectory", fromMaybe "NULL" nameS]) $ c_SetDllDirectory c_name + diff --git a/System/Win32/WindowsString/DebugApi.hsc b/System/Win32/WindowsString/DebugApi.hsc new file mode 100644 index 0000000..e0e7f55 --- /dev/null +++ b/System/Win32/WindowsString/DebugApi.hsc @@ -0,0 +1,33 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.WindowsString.DebugApi +-- Copyright : (c) Esa Ilari Vuokko, 2006 +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for using Windows DebugApi. +-- +----------------------------------------------------------------------------- +module System.Win32.WindowsString.DebugApi + ( module System.Win32.WindowsString.DebugApi + , module System.Win32.DebugApi + ) where + +import System.Win32.DebugApi.Internal +import System.Win32.DebugApi hiding (outputDebugString) +import System.Win32.WindowsString.Types ( withTString ) +import System.OsString.Windows + +##include "windows_cconv.h" +#include "windows.h" + + +-------------------------------------------------------------------------- +-- On process being debugged + +outputDebugString :: WindowsString -> IO () +outputDebugString s = withTString s $ \c_s -> c_OutputDebugString c_s + diff --git a/System/Win32/WindowsString/File.hsc b/System/Win32/WindowsString/File.hsc new file mode 100644 index 0000000..857f203 --- /dev/null +++ b/System/Win32/WindowsString/File.hsc @@ -0,0 +1,238 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.File +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.WindowsString.File + ( deleteFile + , copyFile + , moveFile + , moveFileEx + , setCurrentDirectory + , createDirectory + , createDirectoryEx + , removeDirectory + , getBinaryType + , createFile + , setFileAttributes + , getFileAttributes + , getFileAttributesExStandard + , findFirstChangeNotification + , getFindDataFileName + , findFirstFile + , defineDosDevice + , getDiskFreeSpace + , setVolumeLabel + , getFileExInfoStandard + , getFileExMaxInfoLevel + , module System.Win32.File + ) where + +import System.Win32.File.Internal +import System.Win32.File hiding ( + deleteFile + , copyFile + , moveFile + , moveFileEx + , setCurrentDirectory + , createDirectory + , createDirectoryEx + , removeDirectory + , getBinaryType + , createFile + , setFileAttributes + , getFileAttributes + , getFileAttributesExStandard + , findFirstChangeNotification + , getFindDataFileName + , findFirstFile + , defineDosDevice + , getDiskFreeSpace + , setVolumeLabel + , getFileExInfoStandard + , getFileExMaxInfoLevel + ) +import System.Win32.WindowsString.Types +import System.OsString.Windows +import Unsafe.Coerce (unsafeCoerce) + +import Foreign hiding (void) + +##include "windows_cconv.h" + +#include +#include "alignment.h" + +deleteFile :: WindowsString -> IO () +deleteFile name = + withTString name $ \ c_name -> + failIfFalseWithRetry_ (unwords ["DeleteFile",show name]) $ + c_DeleteFile c_name + +copyFile :: WindowsString -> WindowsString -> Bool -> IO () +copyFile src dest over = + withTString src $ \ c_src -> + withTString dest $ \ c_dest -> + failIfFalseWithRetry_ (unwords ["CopyFile",show src,show dest]) $ + c_CopyFile c_src c_dest over + +moveFile :: WindowsString -> WindowsString -> IO () +moveFile src dest = + withTString src $ \ c_src -> + withTString dest $ \ c_dest -> + failIfFalseWithRetry_ (unwords ["MoveFile",show src,show dest]) $ + c_MoveFile c_src c_dest + +moveFileEx :: WindowsString -> Maybe WindowsString -> MoveFileFlag -> IO () +moveFileEx src dest flags = + withTString src $ \ c_src -> + maybeWith withTString dest $ \ c_dest -> + failIfFalseWithRetry_ (unwords ["MoveFileEx",show src,show dest]) $ + c_MoveFileEx c_src c_dest flags + +setCurrentDirectory :: WindowsString -> IO () +setCurrentDirectory name = + withTString name $ \ c_name -> + failIfFalse_ (unwords ["SetCurrentDirectory",show name]) $ + c_SetCurrentDirectory c_name + +createDirectory :: WindowsString -> Maybe LPSECURITY_ATTRIBUTES -> IO () +createDirectory name mb_attr = + withTString name $ \ c_name -> + failIfFalseWithRetry_ (unwords ["CreateDirectory",show name]) $ + c_CreateDirectory c_name (maybePtr mb_attr) + +createDirectoryEx :: WindowsString -> WindowsString -> Maybe LPSECURITY_ATTRIBUTES -> IO () +createDirectoryEx template name mb_attr = + withTString template $ \ c_template -> + withTString name $ \ c_name -> + failIfFalseWithRetry_ (unwords ["CreateDirectoryEx",show template,show name]) $ + c_CreateDirectoryEx c_template c_name (maybePtr mb_attr) + +removeDirectory :: WindowsString -> IO () +removeDirectory name = + withTString name $ \ c_name -> + failIfFalseWithRetry_ (unwords ["RemoveDirectory",show name]) $ + c_RemoveDirectory c_name + +getBinaryType :: WindowsString -> IO BinaryType +getBinaryType name = + withTString name $ \ c_name -> + alloca $ \ p_btype -> do + failIfFalse_ (unwords ["GetBinaryType",show name]) $ + c_GetBinaryType c_name p_btype + peek p_btype + +---------------------------------------------------------------- +-- HANDLE operations +---------------------------------------------------------------- + +createFile :: WindowsString -> AccessMode -> ShareMode -> Maybe LPSECURITY_ATTRIBUTES -> CreateMode -> FileAttributeOrFlag -> Maybe HANDLE -> IO HANDLE +createFile name access share mb_attr mode flag mb_h = + withTString name $ \ c_name -> + failIfWithRetry (==iNVALID_HANDLE_VALUE) (unwords ["CreateFile",show name]) $ + c_CreateFile c_name access share (maybePtr mb_attr) mode flag (maybePtr mb_h) + +setFileAttributes :: WindowsString -> FileAttributeOrFlag -> IO () +setFileAttributes name attr = + withTString name $ \ c_name -> + failIfFalseWithRetry_ (unwords ["SetFileAttributes",show name]) + $ c_SetFileAttributes c_name attr + +getFileAttributes :: WindowsString -> IO FileAttributeOrFlag +getFileAttributes name = + withTString name $ \ c_name -> + failIfWithRetry (== 0xFFFFFFFF) (unwords ["GetFileAttributes",show name]) $ + c_GetFileAttributes c_name + +getFileAttributesExStandard :: WindowsString -> IO WIN32_FILE_ATTRIBUTE_DATA +getFileAttributesExStandard name = alloca $ \res -> do + withTString name $ \ c_name -> + failIfFalseWithRetry_ "getFileAttributesExStandard" $ + c_GetFileAttributesEx c_name (unsafeCoerce getFileExInfoStandard) res + peek res + + +---------------------------------------------------------------- +-- File Notifications +-- +-- Use these to initialise, "increment" and close a HANDLE you can wait +-- on. +---------------------------------------------------------------- + +findFirstChangeNotification :: WindowsString -> Bool -> FileNotificationFlag -> IO HANDLE +findFirstChangeNotification path watch flag = + withTString path $ \ c_path -> + failIfNull (unwords ["FindFirstChangeNotification",show path]) $ + c_FindFirstChangeNotification c_path watch flag + + +---------------------------------------------------------------- +-- Directories +---------------------------------------------------------------- + + +getFindDataFileName :: FindData -> IO WindowsString +getFindDataFileName fd = case unsafeCoerce fd of + (FindData fp) -> + withForeignPtr fp $ \p -> + peekTString ((# ptr WIN32_FIND_DATAW, cFileName ) p) + +findFirstFile :: WindowsString -> IO (HANDLE, FindData) +findFirstFile str = do + fp_finddata <- mallocForeignPtrBytes (# const sizeof(WIN32_FIND_DATAW) ) + withForeignPtr fp_finddata $ \p_finddata -> do + handle <- withTString str $ \tstr -> do + failIf (== iNVALID_HANDLE_VALUE) "findFirstFile" $ + c_FindFirstFile tstr p_finddata + return (handle, unsafeCoerce (FindData fp_finddata)) + + +---------------------------------------------------------------- +-- DOS Device flags +---------------------------------------------------------------- + +defineDosDevice :: DefineDosDeviceFlags -> WindowsString -> Maybe WindowsString -> IO () +defineDosDevice flags name path = + maybeWith withTString path $ \ c_path -> + withTString name $ \ c_name -> + failIfFalse_ "DefineDosDevice" $ c_DefineDosDevice flags c_name c_path + +---------------------------------------------------------------- + + +-- %fun GetDriveType :: Maybe String -> IO DriveType + +getDiskFreeSpace :: Maybe WindowsString -> IO (DWORD,DWORD,DWORD,DWORD) +getDiskFreeSpace path = + maybeWith withTString path $ \ c_path -> + alloca $ \ p_sectors -> + alloca $ \ p_bytes -> + alloca $ \ p_nfree -> + alloca $ \ p_nclusters -> do + failIfFalse_ "GetDiskFreeSpace" $ + c_GetDiskFreeSpace c_path p_sectors p_bytes p_nfree p_nclusters + sectors <- peek p_sectors + bytes <- peek p_bytes + nfree <- peek p_nfree + nclusters <- peek p_nclusters + return (sectors, bytes, nfree, nclusters) + +setVolumeLabel :: Maybe WindowsString -> Maybe WindowsString -> IO () +setVolumeLabel path name = + maybeWith withTString path $ \ c_path -> + maybeWith withTString name $ \ c_name -> + failIfFalse_ "SetVolumeLabel" $ c_SetVolumeLabel c_path c_name + +---------------------------------------------------------------- +-- End +---------------------------------------------------------------- diff --git a/System/Win32/WindowsString/FileMapping.hsc b/System/Win32/WindowsString/FileMapping.hsc new file mode 100644 index 0000000..a3c8569 --- /dev/null +++ b/System/Win32/WindowsString/FileMapping.hsc @@ -0,0 +1,107 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.FileMapping +-- Copyright : (c) Esa Ilari Vuokko, 2006 +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32 mapped files. +-- +----------------------------------------------------------------------------- +module System.Win32.WindowsString.FileMapping + ( module System.Win32.WindowsString.FileMapping + , module System.Win32.FileMapping + ) where + +import System.Win32.FileMapping hiding + ( + mapFile + , withMappedFile + , createFileMapping + , openFileMapping + ) + +import System.Win32.FileMapping.Internal +import System.Win32.WindowsString.Types ( HANDLE, BOOL, withTString + , failIf, DDWORD, ddwordToDwords + , iNVALID_HANDLE_VALUE ) +import System.Win32.Mem +import System.Win32.WindowsString.File +import System.OsString.Windows +import System.OsPath.Windows + +import Control.Exception ( mask_, bracket ) +import Foreign ( nullPtr, maybeWith + , ForeignPtr, newForeignPtr ) + +##include "windows_cconv.h" + +#include "windows.h" + +--------------------------------------------------------------------------- +-- Derived functions +--------------------------------------------------------------------------- + +-- | Maps file fully and returns ForeignPtr and length of the mapped area. +-- The mapped file is opened read-only and shared reading. +mapFile :: WindowsPath -> IO (ForeignPtr a, Int) +mapFile path = do + bracket + (createFile path gENERIC_READ fILE_SHARE_READ Nothing oPEN_EXISTING fILE_ATTRIBUTE_NORMAL Nothing) + (closeHandle) + $ \fh -> bracket + (createFileMapping (Just fh) pAGE_READONLY 0 Nothing) + (closeHandle) + $ \fm -> do + fi <- getFileInformationByHandle fh + fp <- mask_ $ do + ptr <- mapViewOfFile fm fILE_MAP_READ 0 0 + newForeignPtr c_UnmapViewOfFileFinaliser ptr + return (fp, fromIntegral $ bhfiSize fi) + +-- | Opens an existing file and creates mapping object to it. +withMappedFile + :: WindowsPath -- ^ Path + -> Bool -- ^ Write? (False = read-only) + -> Maybe Bool -- ^ Sharing mode, no sharing, share read, share read+write + -> (Integer -> MappedObject -> IO a) -- ^ Action + -> IO a +withMappedFile path write share act = + bracket + (createFile path access share' Nothing oPEN_EXISTING fILE_ATTRIBUTE_NORMAL Nothing) + (closeHandle) + $ \fh -> bracket + (createFileMapping (Just fh) page 0 Nothing) + (closeHandle) + $ \fm -> do + bhfi <- getFileInformationByHandle fh + act (fromIntegral $ bhfiSize bhfi) (MappedObject fh fm mapaccess) + where + access = if write then gENERIC_READ+gENERIC_WRITE else gENERIC_READ + page = if write then pAGE_READWRITE else pAGE_READONLY + mapaccess = if write then fILE_MAP_ALL_ACCESS else fILE_MAP_READ + share' = case share of + Nothing -> fILE_SHARE_NONE + Just False -> fILE_SHARE_READ + Just True -> fILE_SHARE_READ + fILE_SHARE_WRITE + +--------------------------------------------------------------------------- +-- API in Haskell +--------------------------------------------------------------------------- +createFileMapping :: Maybe HANDLE -> ProtectFlags -> DDWORD -> Maybe WindowsString -> IO HANDLE +createFileMapping mh flags mosize name = + maybeWith withTString name $ \c_name -> + failIf (==nullPtr) "createFileMapping: CreateFileMapping" $ c_CreateFileMapping handle nullPtr flags moshi moslow c_name + where + (moshi,moslow) = ddwordToDwords mosize + handle = maybe iNVALID_HANDLE_VALUE id mh + +openFileMapping :: FileMapAccess -> BOOL -> Maybe WindowsString -> IO HANDLE +openFileMapping access inherit name = + maybeWith withTString name $ \c_name -> + failIf (==nullPtr) "openFileMapping: OpenFileMapping" $ + c_OpenFileMapping access inherit c_name + diff --git a/System/Win32/WindowsString/HardLink.hs b/System/Win32/WindowsString/HardLink.hs new file mode 100644 index 0000000..be6c7c1 --- /dev/null +++ b/System/Win32/WindowsString/HardLink.hs @@ -0,0 +1,47 @@ +{-# LANGUAGE CPP #-} +{- | + Module : System.Win32.HardLink + Copyright : 2013 shelarcy + License : BSD-style + + Maintainer : shelarcy@gmail.com + Stability : Provisional + Portability : Non-portable (Win32 API) + + Handling hard link using Win32 API. [NTFS only] + + Note: You should worry about file system type when use this module's function in your application: + + * NTFS only supprts this functionality. + + * ReFS doesn't support hard link currently. +-} +module System.Win32.WindowsString.HardLink + ( createHardLink + , createHardLink' + ) where + +import System.Win32.HardLink.Internal +import System.Win32.WindowsString.File ( failIfFalseWithRetry_ ) +import System.Win32.WindowsString.String ( withTString ) +import System.Win32.WindowsString.Types ( nullPtr ) +import System.OsPath.Windows + +#include "windows_cconv.h" + +-- | NOTE: createHardLink is /flipped arguments/ to provide compatibility for Unix. +-- +-- If you want to create hard link by Windows way, use 'createHardLink'' instead. +createHardLink :: WindowsPath -- ^ Target file path + -> WindowsPath -- ^ Hard link name + -> IO () +createHardLink = flip createHardLink' + +createHardLink' :: WindowsPath -- ^ Hard link name + -> WindowsPath -- ^ Target file path + -> IO () +createHardLink' link target = + withTString target $ \c_target -> + withTString link $ \c_link -> + failIfFalseWithRetry_ (unwords ["CreateHardLinkW",show link,show target]) $ + c_CreateHardLink c_link c_target nullPtr diff --git a/System/Win32/WindowsString/Info.hsc b/System/Win32/WindowsString/Info.hsc new file mode 100644 index 0000000..aacf074 --- /dev/null +++ b/System/Win32/WindowsString/Info.hsc @@ -0,0 +1,114 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Info +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.WindowsString.Info + ( module System.Win32.WindowsString.Info + , module System.Win32.Info + ) where + +import System.Win32.Info.Internal +import System.Win32.Info hiding ( + getSystemDirectory + , getWindowsDirectory + , getCurrentDirectory + , getTemporaryDirectory + , getFullPathName + , getLongPathName + , getShortPathName + , searchPath + , getUserName + ) +import Control.Exception (catch) +import Foreign.Marshal.Alloc (alloca) +import Foreign.Marshal.Utils (with, maybeWith) +import Foreign.Marshal.Array (allocaArray) +import Foreign.Ptr (nullPtr) +import Foreign.Storable (Storable(..)) +import System.IO.Error (isDoesNotExistError) +import System.Win32.WindowsString.Types (failIfFalse_, peekTStringLen, withTString, try) +import System.OsPath.Windows + +#if !MIN_VERSION_base(4,6,0) +import Prelude hiding (catch) +#endif + +##include "windows_cconv.h" + +#include +#include "alignment.h" + +---------------------------------------------------------------- +-- Standard Directories +---------------------------------------------------------------- + +getSystemDirectory :: IO WindowsString +getSystemDirectory = try "GetSystemDirectory" c_getSystemDirectory 512 + +getWindowsDirectory :: IO WindowsString +getWindowsDirectory = try "GetWindowsDirectory" c_getWindowsDirectory 512 + +getCurrentDirectory :: IO WindowsString +getCurrentDirectory = try "GetCurrentDirectory" (flip c_getCurrentDirectory) 512 + +getTemporaryDirectory :: IO WindowsString +getTemporaryDirectory = try "GetTempPath" (flip c_getTempPath) 512 + +getFullPathName :: WindowsPath -> IO WindowsPath +getFullPathName name = do + withTString name $ \ c_name -> + try "getFullPathName" + (\buf len -> c_GetFullPathName c_name len buf nullPtr) 512 + +getLongPathName :: WindowsPath -> IO WindowsPath +getLongPathName name = do + withTString name $ \ c_name -> + try "getLongPathName" + (c_GetLongPathName c_name) 512 + +getShortPathName :: WindowsPath -> IO WindowsPath +getShortPathName name = do + withTString name $ \ c_name -> + try "getShortPathName" + (c_GetShortPathName c_name) 512 + +searchPath :: Maybe WindowsString -> WindowsPath -> Maybe WindowsString -> IO (Maybe WindowsPath) +searchPath path filename ext = + maybe ($ nullPtr) withTString path $ \p_path -> + withTString filename $ \p_filename -> + maybeWith withTString ext $ \p_ext -> + alloca $ \ppFilePart -> (do + s <- try "searchPath" (\buf len -> c_SearchPath p_path p_filename p_ext + len buf ppFilePart) 512 + return (Just s)) + `catch` \e -> if isDoesNotExistError e + then return Nothing + else ioError e + +---------------------------------------------------------------- +-- User name +---------------------------------------------------------------- + +-- %fun GetUserName :: IO String + +getUserName :: IO WindowsString +getUserName = + allocaArray 512 $ \ c_str -> + with 512 $ \ c_len -> do + failIfFalse_ "GetUserName" $ c_GetUserName c_str c_len + len <- peek c_len + peekTStringLen (c_str, fromIntegral len - 1) + +---------------------------------------------------------------- +-- End +---------------------------------------------------------------- diff --git a/System/Win32/WindowsString/Path.hsc b/System/Win32/WindowsString/Path.hsc new file mode 100644 index 0000000..86740ec --- /dev/null +++ b/System/Win32/WindowsString/Path.hsc @@ -0,0 +1,52 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Path +-- Copyright : (c) Tamar Christina, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Tamar Christina +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.WindowsString.Path ( + filepathRelativePathTo + , pathRelativePathTo + ) where + +import System.Win32.Path.Internal +import System.Win32.WindowsString.Types +import System.Win32.WindowsString.File +import System.OsPath.Windows + +import Foreign + +##include "windows_cconv.h" + +#include + +filepathRelativePathTo :: WindowsPath -> WindowsPath -> IO WindowsPath +filepathRelativePathTo from to = + withTString from $ \p_from -> + withTString to $ \p_to -> + allocaArray ((#const MAX_PATH) * (#size TCHAR)) $ \p_AbsPath -> do + _ <- failIfZero "PathRelativePathTo" (c_pathRelativePathTo p_AbsPath p_from fILE_ATTRIBUTE_DIRECTORY + p_to fILE_ATTRIBUTE_NORMAL) + path <- peekTString p_AbsPath + _ <- localFree p_AbsPath + return path + +pathRelativePathTo :: WindowsPath -> FileAttributeOrFlag -> WindowsPath -> FileAttributeOrFlag -> IO WindowsPath +pathRelativePathTo from from_attr to to_attr = + withTString from $ \p_from -> + withTString to $ \p_to -> + allocaArray ((#const MAX_PATH) * (#size TCHAR)) $ \p_AbsPath -> do + _ <- failIfZero "PathRelativePathTo" (c_pathRelativePathTo p_AbsPath p_from from_attr + p_to to_attr) + path <- peekTString p_AbsPath + _ <- localFree p_AbsPath + return path + diff --git a/System/Win32/WindowsString/Shell.hsc b/System/Win32/WindowsString/Shell.hsc new file mode 100644 index 0000000..d82aa4b --- /dev/null +++ b/System/Win32/WindowsString/Shell.hsc @@ -0,0 +1,59 @@ +{-# LANGUAGE Trustworthy #-} +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.WindowsString.Shell +-- Copyright : (c) The University of Glasgow 2009 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- Win32 stuff from shell32.dll +-- +----------------------------------------------------------------------------- + +module System.Win32.WindowsString.Shell ( + sHGetFolderPath, + CSIDL, + cSIDL_PROFILE, + cSIDL_APPDATA, + cSIDL_WINDOWS, + cSIDL_PERSONAL, + cSIDL_LOCAL_APPDATA, + cSIDL_DESKTOPDIRECTORY, + cSIDL_PROGRAM_FILES, + SHGetFolderPathFlags, + sHGFP_TYPE_CURRENT, + sHGFP_TYPE_DEFAULT + ) where + +import System.OsString.Windows (WindowsString) +import System.Win32.Shell.Internal +import System.Win32.Shell hiding (sHGetFolderPath) +import System.Win32.WindowsString.Types +import Graphics.Win32.GDI.Types (HWND) + +import Foreign +import Control.Monad + +##include "windows_cconv.h" + +-- for SHGetFolderPath stuff +#define _WIN32_IE 0x500 +#include +#include + +---------------------------------------------------------------- +-- SHGetFolderPath +-- +-- XXX: this is deprecated in Vista and later +---------------------------------------------------------------- + + +sHGetFolderPath :: HWND -> CSIDL -> HANDLE -> SHGetFolderPathFlags -> IO WindowsString +sHGetFolderPath hwnd csidl hdl flags = + allocaBytes ((#const MAX_PATH) * (#size TCHAR)) $ \pstr -> do + r <- c_SHGetFolderPath hwnd csidl hdl flags pstr + when (r < 0) $ raiseUnsupported "sHGetFolderPath" + peekTString pstr diff --git a/System/Win32/WindowsString/String.hs b/System/Win32/WindowsString/String.hs new file mode 100644 index 0000000..1c7c72c --- /dev/null +++ b/System/Win32/WindowsString/String.hs @@ -0,0 +1,67 @@ +{- | + Module : System.Win32.String + Copyright : 2013 shelarcy + License : BSD-style + + Maintainer : shelarcy@gmail.com + Stability : Provisional + Portability : Non-portable (Win32 API) + + Utilities for primitive marshalling of Windows' C strings. +-} +module System.Win32.WindowsString.String + ( LPSTR, LPCSTR, LPWSTR, LPCWSTR + , TCHAR, LPTSTR, LPCTSTR, LPCTSTR_ + , withTString, withTStringLen, peekTString, peekTStringLen + , newTString + , withTStringBuffer, withTStringBufferLen + ) where + +import System.Win32.String hiding + ( withTStringBuffer + , withTStringBufferLen + , withTString + , withTStringLen + , peekTString + , peekTStringLen + , newTString + ) +import System.Win32.WindowsString.Types +import System.OsString.Internal.Types +import qualified System.OsPath.Data.ByteString.Short as SBS +import Data.Word (Word8) + +-- | Marshal a dummy Haskell string into a NUL terminated C wide string +-- using temporary storage. +-- +-- * the Haskell string is created by length parameter. And the Haskell +-- string contains /only/ NUL characters. +-- +-- * the memory is freed when the subcomputation terminates (either +-- normally or via an exception), so the pointer to the temporary +-- storage must /not/ be used after this. +-- +withTStringBuffer :: Int -> (LPTSTR -> IO a) -> IO a +withTStringBuffer maxLength + = let dummyBuffer = WindowsString $ SBS.pack $ replicate (if even maxLength then maxLength else maxLength + 1) _nul + in withTString dummyBuffer + +-- | Marshal a dummy Haskell string into a C wide string (i.e. wide +-- character array) in temporary storage, with explicit length +-- information. +-- +-- * the Haskell string is created by length parameter. And the Haskell +-- string contains /only/ NUL characters. +-- +-- * the memory is freed when the subcomputation terminates (either +-- normally or via an exception), so the pointer to the temporary +-- storage must /not/ be used after this. +-- +withTStringBufferLen :: Int -> ((LPTSTR, Int) -> IO a) -> IO a +withTStringBufferLen maxLength + = let dummyBuffer = WindowsString $ SBS.pack $ replicate (if even maxLength then maxLength else maxLength + 1) _nul + in withTStringLen dummyBuffer + + +_nul :: Word8 +_nul = 0x00 diff --git a/System/Win32/WindowsString/SymbolicLink.hsc b/System/Win32/WindowsString/SymbolicLink.hsc new file mode 100644 index 0000000..abc16f5 --- /dev/null +++ b/System/Win32/WindowsString/SymbolicLink.hsc @@ -0,0 +1,94 @@ +{-# LANGUAGE CPP #-} +{- | + Module : System.Win32.SymbolicLink + Copyright : 2012 shelarcy + License : BSD-style + + Maintainer : shelarcy@gmail.com + Stability : Provisional + Portability : Non-portable (Win32 API) + + Handling symbolic link using Win32 API. [Vista of later and desktop app only] + + Note: When using the createSymbolicLink* functions without the + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag, you should worry about UAC + (User Account Control) when use this module's function in your application: + + * require to use 'Run As Administrator' to run your application. + + * or modify your application's manifect file to add + \. + + Starting from Windows 10 version 1703 (Creators Update), after enabling + Developer Mode, users can create symbolic links without requiring the + Administrator privilege in the current process. Supply a 'True' flag in + addition to the target and link name to enable this behavior. +-} +module System.Win32.WindowsString.SymbolicLink + ( SymbolicLinkFlags + , sYMBOLIC_LINK_FLAG_FILE + , sYMBOLIC_LINK_FLAG_DIRECTORY + , sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE + , createSymbolicLink + , createSymbolicLink' + , createSymbolicLinkFile + , createSymbolicLinkDirectory + ) where + +import System.Win32.SymbolicLink.Internal +import Data.Bits ((.|.)) +import System.Win32.WindowsString.Types +import System.Win32.WindowsString.File ( failIfFalseWithRetry_ ) +import System.OsPath.Windows +import Unsafe.Coerce (unsafeCoerce) + +##include "windows_cconv.h" + +-- | createSymbolicLink* functions don't check that file is exist or not. +-- +-- 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. +createSymbolicLink :: WindowsPath -- ^ Target file path + -> WindowsPath -- ^ Symbolic link name + -> SymbolicLinkFlags -> IO () +createSymbolicLink = flip createSymbolicLink' + +createSymbolicLinkFile :: WindowsPath -- ^ Target file path + -> WindowsPath -- ^ Symbolic link name + -> Bool -- ^ Create the symbolic link with the unprivileged mode + -> IO () +createSymbolicLinkFile target link unprivileged = + createSymbolicLink' + link + target + ( if unprivileged + then sYMBOLIC_LINK_FLAG_FILE .|. sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE + else sYMBOLIC_LINK_FLAG_FILE + ) + +createSymbolicLinkDirectory :: WindowsPath -- ^ Target file path + -> WindowsPath -- ^ Symbolic link name + -> Bool -- ^ Create the symbolic link with the unprivileged mode + -> IO () +createSymbolicLinkDirectory target link unprivileged = + createSymbolicLink' + link + target + ( if unprivileged + then + sYMBOLIC_LINK_FLAG_DIRECTORY + .|. sYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE + else sYMBOLIC_LINK_FLAG_DIRECTORY + ) + +createSymbolicLink' :: WindowsPath -- ^ Symbolic link name + -> WindowsPath -- ^ Target file path + -> SymbolicLinkFlags -> IO () +createSymbolicLink' link target flag = do + withTString link $ \c_link -> + withTString target $ \c_target -> + failIfFalseWithRetry_ (unwords ["CreateSymbolicLink",show link,show target]) $ + c_CreateSymbolicLink c_link c_target (unsafeCoerce flag) + diff --git a/System/Win32/WindowsString/Time.hsc b/System/Win32/WindowsString/Time.hsc new file mode 100644 index 0000000..0fedc5f --- /dev/null +++ b/System/Win32/WindowsString/Time.hsc @@ -0,0 +1,60 @@ +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Time +-- Copyright : (c) Esa Ilari Vuokko, 2006 +-- License : BSD-style (see the file LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32 Time API. +-- +----------------------------------------------------------------------------- +module System.Win32.WindowsString.Time + ( module System.Win32.WindowsString.Time + , module System.Win32.Time + ) where + +import System.Win32.Time.Internal +import System.Win32.Time hiding (getTimeFormatEx, getTimeFormat) + +import System.Win32.WindowsString.String ( peekTStringLen, withTString ) +import System.Win32.WindowsString.Types ( LCID, failIf ) +import System.Win32.Utils ( trySized ) + +import Foreign ( Storable(sizeOf) + , nullPtr, castPtr + , with, allocaBytes ) +import Foreign.C ( CWchar(..) + , withCWString ) +import Foreign.Marshal.Utils (maybeWith) +import System.OsString.Windows + +##include "windows_cconv.h" +#include +#include "alignment.h" +#include "winnls_compat.h" + + +getTimeFormatEx :: Maybe WindowsString + -> GetTimeFormatFlags + -> Maybe SYSTEMTIME + -> Maybe WindowsString + -> IO String +getTimeFormatEx locale flags st fmt = + maybeWith withTString locale $ \c_locale -> + maybeWith with st $ \c_st -> + maybeWith withTString fmt $ \c_fmt -> do + let c_func = c_GetTimeFormatEx c_locale flags c_st c_fmt + trySized "GetTimeFormatEx" c_func + +getTimeFormat :: LCID -> GetTimeFormatFlags -> Maybe SYSTEMTIME -> Maybe String -> IO WindowsString +getTimeFormat locale flags st fmt = + maybeWith with st $ \c_st -> + maybeWith withCWString fmt $ \c_fmt -> do + size <- c_GetTimeFormat locale flags c_st c_fmt nullPtr 0 + allocaBytes ((fromIntegral size) * (sizeOf (undefined::CWchar))) $ \out -> do + size' <- failIf (==0) "getTimeFormat: GetTimeFormat" $ + c_GetTimeFormat locale flags c_st c_fmt (castPtr out) size + peekTStringLen (out,fromIntegral size') diff --git a/System/Win32/WindowsString/Types.hsc b/System/Win32/WindowsString/Types.hsc new file mode 100644 index 0000000..affdfa9 --- /dev/null +++ b/System/Win32/WindowsString/Types.hsc @@ -0,0 +1,166 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE Trustworthy #-} +----------------------------------------------------------------------------- +-- | +-- Module : System.Win32.Types +-- Copyright : (c) Alastair Reid, 1997-2003 +-- License : BSD-style (see the file libraries/base/LICENSE) +-- +-- Maintainer : Esa Ilari Vuokko +-- Stability : provisional +-- Portability : portable +-- +-- A collection of FFI declarations for interfacing with Win32. +-- +----------------------------------------------------------------------------- + +module System.Win32.WindowsString.Types + ( module System.Win32.WindowsString.Types + , module System.Win32.Types + ) where + +import System.Win32.Types hiding ( + withTString + , withTStringLen + , peekTString + , peekTStringLen + , newTString + , failIf + , failIf_ + , failIfNeg + , failIfNull + , failIfZero + , failIfFalse_ + , failUnlessSuccess + , failUnlessSuccessOr + , errorWin + , failWith + , try + ) + +import System.OsString.Windows +import System.OsString.Internal.Types +import System.OsPath.Data.ByteString.Short.Word16 ( + packCWString, + packCWStringLen, + useAsCWString, + useAsCWStringLen, + newCWString + ) +import Data.Bifunctor (first) +import Data.Char (isSpace) +import Numeric (showHex) +import qualified System.IO as IO () +import System.IO.Error (ioeSetErrorString) +import Foreign (allocaArray) +import Foreign.Ptr ( Ptr ) +import Foreign.C.Error ( errnoToIOError ) +import Control.Exception ( throwIO ) +import GHC.Ptr (castPtr) + +#if !MIN_VERSION_base(4,8,0) +import Data.Word (Word) +#endif + +import GHC.IO.Encoding.UTF16 ( mkUTF16le ) +import GHC.IO.Encoding.Failure ( CodingFailureMode(..) ) + +#include +#include +##include "windows_cconv.h" + + +---------------------------------------------------------------- +-- Chars and strings +---------------------------------------------------------------- + +withTString :: WindowsString -> (LPTSTR -> IO a) -> IO a +withTStringLen :: WindowsString -> ((LPTSTR, Int) -> IO a) -> IO a +peekTString :: LPCTSTR -> IO WindowsString +peekTStringLen :: (LPCTSTR, Int) -> IO WindowsString +newTString :: WindowsString -> IO LPCTSTR + +-- UTF-16 version: +-- the casts are from 'Ptr Word16' to 'Ptr CWchar', which is safe +withTString (WindowsString str) f = useAsCWString str (\ptr -> f (castPtr ptr)) +withTStringLen (WindowsString str) f = useAsCWStringLen str (\(ptr, len) -> f (castPtr ptr, len)) +peekTString = fmap WindowsString . packCWString . castPtr +peekTStringLen = fmap WindowsString . packCWStringLen . first castPtr +newTString (WindowsString str) = fmap castPtr $ newCWString str + +---------------------------------------------------------------- +-- Errors +---------------------------------------------------------------- + +failIf :: (a -> Bool) -> String -> IO a -> IO a +failIf p wh act = do + v <- act + if p v then errorWin wh else return v + +failIf_ :: (a -> Bool) -> String -> IO a -> IO () +failIf_ p wh act = do + v <- act + if p v then errorWin wh else return () + +failIfNeg :: (Num a, Ord a) => String -> IO a -> IO a +failIfNeg = failIf (< 0) + +failIfNull :: String -> IO (Ptr a) -> IO (Ptr a) +failIfNull = failIf (== nullPtr) + +failIfZero :: (Eq a, Num a) => String -> IO a -> IO a +failIfZero = failIf (== 0) + +failIfFalse_ :: String -> IO Bool -> IO () +failIfFalse_ = failIf_ not + +failUnlessSuccess :: String -> IO ErrCode -> IO () +failUnlessSuccess fn_name act = do + r <- act + if r == 0 then return () else failWith fn_name r + +failUnlessSuccessOr :: ErrCode -> String -> IO ErrCode -> IO Bool +failUnlessSuccessOr val fn_name act = do + r <- act + if r == 0 then return False + else if r == val then return True + else failWith fn_name r + + +errorWin :: String -> IO a +errorWin fn_name = do + err_code <- getLastError + failWith fn_name err_code + +failWith :: String -> ErrCode -> IO a +failWith fn_name err_code = do + c_msg <- getErrorMessage err_code + + msg <- either (fail . show) pure . decodeWith (mkUTF16le TransliterateCodingFailure) =<< if c_msg == nullPtr + then either (fail . show) pure . encodeWith (mkUTF16le TransliterateCodingFailure) $ "Error 0x" ++ Numeric.showHex err_code "" + else do msg <- peekTString c_msg + -- We ignore failure of freeing c_msg, given we're already failing + _ <- localFree c_msg + return msg + -- turn GetLastError() into errno, which errnoToIOError knows how to convert + -- to an IOException we can throw. + errno <- c_maperrno_func err_code + let msg' = reverse $ dropWhile isSpace $ reverse msg -- drop trailing \n + ioerror = errnoToIOError fn_name errno Nothing Nothing + `ioeSetErrorString` msg' + throwIO ioerror + + +-- Support for API calls that are passed a fixed-size buffer and tell +-- you via the return value if the buffer was too small. In that +-- case, we double the buffer size and try again. +try :: String -> (LPTSTR -> UINT -> IO UINT) -> UINT -> IO WindowsString +try loc f n = do + e <- allocaArray (fromIntegral n) $ \lptstr -> do + r <- failIfZero loc $ f lptstr n + if (r > n) then return (Left r) else do + str <- peekTStringLen (lptstr, fromIntegral r) + return (Right str) + case e of + Left n' -> try loc f n' + Right str -> return str diff --git a/System/Win32/WindowsString/Utils.hs b/System/Win32/WindowsString/Utils.hs new file mode 100644 index 0000000..dbb4399 --- /dev/null +++ b/System/Win32/WindowsString/Utils.hs @@ -0,0 +1,63 @@ +{- | + Module : System.Win32.Utils + Copyright : 2009 Balazs Komuves, 2013 shelarcy + License : BSD-style + + Maintainer : shelarcy@gmail.com + Stability : Provisional + Portability : Non-portable (Win32 API) + + Utilities for calling Win32 API +-} +module System.Win32.WindowsString.Utils + ( module System.Win32.WindowsString.Utils + , module System.Win32.Utils + ) where + +import Foreign.C.Types ( CInt ) +import Foreign.Marshal.Array ( allocaArray ) +import Foreign.Ptr ( nullPtr ) + +import System.Win32.Utils hiding + ( try + , tryWithoutNull + , trySized + ) +import System.Win32.WindowsString.String ( LPTSTR, peekTString, peekTStringLen + , withTStringBufferLen ) +import System.Win32.WindowsString.Types ( UINT + , failIfZero + ) +import qualified System.Win32.WindowsString.Types ( try ) +import System.OsString.Windows + + +-- | Support for API calls that are passed a fixed-size buffer and tell +-- you via the return value if the buffer was too small. In that +-- case, we extend the buffer size and try again. +try :: String -> (LPTSTR -> UINT -> IO UINT) -> UINT -> IO WindowsString +try = System.Win32.WindowsString.Types.try +{-# INLINE try #-} + +tryWithoutNull :: String -> (LPTSTR -> UINT -> IO UINT) -> UINT -> IO WindowsString +tryWithoutNull loc f n = do + e <- allocaArray (fromIntegral n) $ \lptstr -> do + r <- failIfZero loc $ f lptstr n + if r > n then return (Left r) else do + str <- peekTString lptstr + return (Right str) + case e of + Left r' -> tryWithoutNull loc f r' + Right str -> return str + +-- | Support for API calls that return the required size, in characters +-- including a null character, of the buffer when passed a buffer size of zero. +trySized :: String -> (LPTSTR -> CInt -> IO CInt) -> IO WindowsString +trySized wh f = do + c_len <- failIfZero wh $ f nullPtr 0 + let len = fromIntegral c_len + withTStringBufferLen len $ \(buf', len') -> do + let c_len' = fromIntegral len' + c_len'' <- failIfZero wh $ f buf' c_len' + let len'' = fromIntegral c_len'' + peekTStringLen (buf', len'' - 1) -- Drop final null character diff --git a/Win32.cabal b/Win32.cabal index 4c8c394..e986b7e 100644 --- a/Win32.cabal +++ b/Win32.cabal @@ -1,5 +1,5 @@ name: Win32 -version: 2.13.2.1 +version: 2.13.3.0 license: BSD3 license-file: LICENSE author: Alastair Reid, shelarcy, Tamar Christina @@ -28,7 +28,12 @@ Library build-depends: unbuildable<0 buildable: False - build-depends: base >= 4.5 && < 5, filepath + build-depends: base >= 4.5 && < 5 + + -- AFPP support + if impl(ghc >= 8.0) + build-depends: filepath >= 1.4.100.0 + -- Black list hsc2hs 0.68.6 which is horribly broken. build-tool-depends: hsc2hs:hsc2hs > 0 && < 0.68.6 || > 0.68.6 ghc-options: -Wall -fno-warn-name-shadowing @@ -103,6 +108,35 @@ Library System.Win32.Utils System.Win32.Word + -- AFPP support + if impl(ghc >= 8.0) + exposed-modules: + System.Win32.WindowsString.Types + System.Win32.WindowsString.DebugApi + System.Win32.WindowsString.DLL + System.Win32.WindowsString.Shell + System.Win32.WindowsString.String + System.Win32.WindowsString.File + System.Win32.WindowsString.Time + System.Win32.WindowsString.Info + System.Win32.WindowsString.FileMapping + System.Win32.WindowsString.HardLink + System.Win32.WindowsString.Path + System.Win32.WindowsString.SymbolicLink + System.Win32.WindowsString.Utils + + other-modules: + System.Win32.DebugApi.Internal + System.Win32.DLL.Internal + System.Win32.File.Internal + System.Win32.FileMapping.Internal + System.Win32.HardLink.Internal + System.Win32.Info.Internal + System.Win32.Path.Internal + System.Win32.Shell.Internal + System.Win32.SymbolicLink.Internal + System.Win32.Time.Internal + extra-libraries: "user32", "gdi32", "winmm", "advapi32", "shell32", "shfolder", "shlwapi", "msimg32", "imm32" ghc-options: -Wall diff --git a/appveyor.yml b/appveyor.yml index 0e74b13..d756191 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -76,15 +76,12 @@ before_build: - rmdir /Q /S dist-newstyle build_script: - - echo packages:. > cabal.project - - cabal configure --allow-newer --ghc-options="-Werror" - cabal %CABOPTS% build -j all --ghc-options="-Werror" # Build from sdist if required. - ps: >- If ($env:PKG_TEST -Match "yes") { cabal sdist - echo "packages: dist-newstyle/sdist/*.tar.gz" | Out-File -Encoding ASCII cabal.project + ((Get-Content -path cabal.project -Raw) -replace "packages: .", "packages: dist-newstyle/sdist/*.tar.gz") | Set-Content -Path cabal.project cat cabal.project - cabal configure --allow-newer --ghc-options="-Werror" cabal $env:CABOPTS build -j pkg:Win32 --ghc-options="-Werror" } diff --git a/cabal.project b/cabal.project new file mode 100644 index 0000000..e6fdbad --- /dev/null +++ b/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/changelog.md b/changelog.md index 53eb6aa..257b7e1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # Changelog for [`Win32` package](http://hackage.haskell.org/package/Win32) +## 2.13.3.0 July 2022 + +* Add AFPP support (see #198) + ## 2.13.2.1 July 2022 * Add function `createIcon` (see #194)