module System.Win32.File
where
import System.Win32.Types
import System.Win32.Time
import Foreign hiding (void)
import Control.Monad
import Control.Concurrent
type AccessMode = UINT
gENERIC_NONE :: AccessMode
gENERIC_NONE = 0
gENERIC_READ :: AccessMode
gENERIC_READ = 2147483648
gENERIC_WRITE :: AccessMode
gENERIC_WRITE = 1073741824
gENERIC_EXECUTE :: AccessMode
gENERIC_EXECUTE = 536870912
gENERIC_ALL :: AccessMode
gENERIC_ALL = 268435456
dELETE :: AccessMode
dELETE = 65536
rEAD_CONTROL :: AccessMode
rEAD_CONTROL = 131072
wRITE_DAC :: AccessMode
wRITE_DAC = 262144
wRITE_OWNER :: AccessMode
wRITE_OWNER = 524288
sYNCHRONIZE :: AccessMode
sYNCHRONIZE = 1048576
sTANDARD_RIGHTS_REQUIRED :: AccessMode
sTANDARD_RIGHTS_REQUIRED = 983040
sTANDARD_RIGHTS_READ :: AccessMode
sTANDARD_RIGHTS_READ = 131072
sTANDARD_RIGHTS_WRITE :: AccessMode
sTANDARD_RIGHTS_WRITE = 131072
sTANDARD_RIGHTS_EXECUTE :: AccessMode
sTANDARD_RIGHTS_EXECUTE = 131072
sTANDARD_RIGHTS_ALL :: AccessMode
sTANDARD_RIGHTS_ALL = 2031616
sPECIFIC_RIGHTS_ALL :: AccessMode
sPECIFIC_RIGHTS_ALL = 65535
aCCESS_SYSTEM_SECURITY :: AccessMode
aCCESS_SYSTEM_SECURITY = 16777216
mAXIMUM_ALLOWED :: AccessMode
mAXIMUM_ALLOWED = 33554432
type ShareMode = UINT
fILE_SHARE_NONE :: ShareMode
fILE_SHARE_NONE = 0
fILE_SHARE_READ :: ShareMode
fILE_SHARE_READ = 1
fILE_SHARE_WRITE :: ShareMode
fILE_SHARE_WRITE = 2
type CreateMode = UINT
cREATE_NEW :: CreateMode
cREATE_NEW = 1
cREATE_ALWAYS :: CreateMode
cREATE_ALWAYS = 2
oPEN_EXISTING :: CreateMode
oPEN_EXISTING = 3
oPEN_ALWAYS :: CreateMode
oPEN_ALWAYS = 4
tRUNCATE_EXISTING :: CreateMode
tRUNCATE_EXISTING = 5
type FileAttributeOrFlag = UINT
fILE_ATTRIBUTE_READONLY :: FileAttributeOrFlag
fILE_ATTRIBUTE_READONLY = 1
fILE_ATTRIBUTE_HIDDEN :: FileAttributeOrFlag
fILE_ATTRIBUTE_HIDDEN = 2
fILE_ATTRIBUTE_SYSTEM :: FileAttributeOrFlag
fILE_ATTRIBUTE_SYSTEM = 4
fILE_ATTRIBUTE_DIRECTORY :: FileAttributeOrFlag
fILE_ATTRIBUTE_DIRECTORY = 16
fILE_ATTRIBUTE_ARCHIVE :: FileAttributeOrFlag
fILE_ATTRIBUTE_ARCHIVE = 32
fILE_ATTRIBUTE_NORMAL :: FileAttributeOrFlag
fILE_ATTRIBUTE_NORMAL = 128
fILE_ATTRIBUTE_TEMPORARY :: FileAttributeOrFlag
fILE_ATTRIBUTE_TEMPORARY = 256
fILE_ATTRIBUTE_COMPRESSED :: FileAttributeOrFlag
fILE_ATTRIBUTE_COMPRESSED = 2048
fILE_FLAG_WRITE_THROUGH :: FileAttributeOrFlag
fILE_FLAG_WRITE_THROUGH = 2147483648
fILE_FLAG_OVERLAPPED :: FileAttributeOrFlag
fILE_FLAG_OVERLAPPED = 1073741824
fILE_FLAG_NO_BUFFERING :: FileAttributeOrFlag
fILE_FLAG_NO_BUFFERING = 536870912
fILE_FLAG_RANDOM_ACCESS :: FileAttributeOrFlag
fILE_FLAG_RANDOM_ACCESS = 268435456
fILE_FLAG_SEQUENTIAL_SCAN :: FileAttributeOrFlag
fILE_FLAG_SEQUENTIAL_SCAN = 134217728
fILE_FLAG_DELETE_ON_CLOSE :: FileAttributeOrFlag
fILE_FLAG_DELETE_ON_CLOSE = 67108864
fILE_FLAG_BACKUP_SEMANTICS :: FileAttributeOrFlag
fILE_FLAG_BACKUP_SEMANTICS = 33554432
fILE_FLAG_POSIX_SEMANTICS :: FileAttributeOrFlag
fILE_FLAG_POSIX_SEMANTICS = 16777216
sECURITY_ANONYMOUS :: FileAttributeOrFlag
sECURITY_ANONYMOUS = 0
sECURITY_IDENTIFICATION :: FileAttributeOrFlag
sECURITY_IDENTIFICATION = 65536
sECURITY_IMPERSONATION :: FileAttributeOrFlag
sECURITY_IMPERSONATION = 131072
sECURITY_DELEGATION :: FileAttributeOrFlag
sECURITY_DELEGATION = 196608
sECURITY_CONTEXT_TRACKING :: FileAttributeOrFlag
sECURITY_CONTEXT_TRACKING = 262144
sECURITY_EFFECTIVE_ONLY :: FileAttributeOrFlag
sECURITY_EFFECTIVE_ONLY = 524288
sECURITY_SQOS_PRESENT :: FileAttributeOrFlag
sECURITY_SQOS_PRESENT = 1048576
sECURITY_VALID_SQOS_FLAGS :: FileAttributeOrFlag
sECURITY_VALID_SQOS_FLAGS = 2031616
type MoveFileFlag = DWORD
mOVEFILE_REPLACE_EXISTING :: MoveFileFlag
mOVEFILE_REPLACE_EXISTING = 1
mOVEFILE_COPY_ALLOWED :: MoveFileFlag
mOVEFILE_COPY_ALLOWED = 2
mOVEFILE_DELAY_UNTIL_REBOOT :: MoveFileFlag
mOVEFILE_DELAY_UNTIL_REBOOT = 4
type FilePtrDirection = DWORD
fILE_BEGIN :: FilePtrDirection
fILE_BEGIN = 0
fILE_CURRENT :: FilePtrDirection
fILE_CURRENT = 1
fILE_END :: FilePtrDirection
fILE_END = 2
type DriveType = UINT
dRIVE_UNKNOWN :: DriveType
dRIVE_UNKNOWN = 0
dRIVE_NO_ROOT_DIR :: DriveType
dRIVE_NO_ROOT_DIR = 1
dRIVE_REMOVABLE :: DriveType
dRIVE_REMOVABLE = 2
dRIVE_FIXED :: DriveType
dRIVE_FIXED = 3
dRIVE_REMOTE :: DriveType
dRIVE_REMOTE = 4
dRIVE_CDROM :: DriveType
dRIVE_CDROM = 5
dRIVE_RAMDISK :: DriveType
dRIVE_RAMDISK = 6
type DefineDosDeviceFlags = DWORD
dDD_RAW_TARGET_PATH :: DefineDosDeviceFlags
dDD_RAW_TARGET_PATH = 1
dDD_REMOVE_DEFINITION :: DefineDosDeviceFlags
dDD_REMOVE_DEFINITION = 2
dDD_EXACT_MATCH_ON_REMOVE :: DefineDosDeviceFlags
dDD_EXACT_MATCH_ON_REMOVE = 4
type BinaryType = DWORD
sCS_32BIT_BINARY :: BinaryType
sCS_32BIT_BINARY = 0
sCS_DOS_BINARY :: BinaryType
sCS_DOS_BINARY = 1
sCS_WOW_BINARY :: BinaryType
sCS_WOW_BINARY = 2
sCS_PIF_BINARY :: BinaryType
sCS_PIF_BINARY = 3
sCS_POSIX_BINARY :: BinaryType
sCS_POSIX_BINARY = 4
sCS_OS216_BINARY :: BinaryType
sCS_OS216_BINARY = 5
type FileNotificationFlag = DWORD
fILE_NOTIFY_CHANGE_FILE_NAME :: FileNotificationFlag
fILE_NOTIFY_CHANGE_FILE_NAME = 1
fILE_NOTIFY_CHANGE_DIR_NAME :: FileNotificationFlag
fILE_NOTIFY_CHANGE_DIR_NAME = 2
fILE_NOTIFY_CHANGE_ATTRIBUTES :: FileNotificationFlag
fILE_NOTIFY_CHANGE_ATTRIBUTES = 4
fILE_NOTIFY_CHANGE_SIZE :: FileNotificationFlag
fILE_NOTIFY_CHANGE_SIZE = 8
fILE_NOTIFY_CHANGE_LAST_WRITE :: FileNotificationFlag
fILE_NOTIFY_CHANGE_LAST_WRITE = 16
fILE_NOTIFY_CHANGE_SECURITY :: FileNotificationFlag
fILE_NOTIFY_CHANGE_SECURITY = 256
type FileType = DWORD
fILE_TYPE_UNKNOWN :: FileType
fILE_TYPE_UNKNOWN = 0
fILE_TYPE_DISK :: FileType
fILE_TYPE_DISK = 1
fILE_TYPE_CHAR :: FileType
fILE_TYPE_CHAR = 2
fILE_TYPE_PIPE :: FileType
fILE_TYPE_PIPE = 3
fILE_TYPE_REMOTE :: FileType
fILE_TYPE_REMOTE = 32768
type LPSECURITY_ATTRIBUTES = Ptr ()
type MbLPSECURITY_ATTRIBUTES = Maybe LPSECURITY_ATTRIBUTES
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 ((52))
alignment = sizeOf
poke buf bhi = do
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) buf (bhfiFileAttributes bhi)
((\hsc_ptr -> pokeByteOff hsc_ptr 4)) buf (bhfiCreationTime bhi)
((\hsc_ptr -> pokeByteOff hsc_ptr 12)) buf (bhfiLastAccessTime bhi)
((\hsc_ptr -> pokeByteOff hsc_ptr 20)) buf (bhfiLastWriteTime bhi)
((\hsc_ptr -> pokeByteOff hsc_ptr 28)) buf (bhfiVolumeSerialNumber bhi)
((\hsc_ptr -> pokeByteOff hsc_ptr 32)) buf sizeHi
((\hsc_ptr -> pokeByteOff hsc_ptr 36)) buf sizeLow
((\hsc_ptr -> pokeByteOff hsc_ptr 40)) buf (bhfiNumberOfLinks bhi)
((\hsc_ptr -> pokeByteOff hsc_ptr 44)) buf idxHi
((\hsc_ptr -> pokeByteOff hsc_ptr 48)) buf idxLow
where
(sizeHi,sizeLow) = ddwordToDwords $ bhfiSize bhi
(idxHi,idxLow) = ddwordToDwords $ bhfiFileIndex bhi
peek buf = do
attr <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) buf
ctim <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) buf
lati <- ((\hsc_ptr -> peekByteOff hsc_ptr 12)) buf
lwti <- ((\hsc_ptr -> peekByteOff hsc_ptr 20)) buf
vser <- ((\hsc_ptr -> peekByteOff hsc_ptr 28)) buf
fshi <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) buf
fslo <- ((\hsc_ptr -> peekByteOff hsc_ptr 36)) buf
link <- ((\hsc_ptr -> peekByteOff hsc_ptr 40)) buf
idhi <- ((\hsc_ptr -> peekByteOff hsc_ptr 44)) buf
idlo <- ((\hsc_ptr -> peekByteOff hsc_ptr 48)) buf
return $ BY_HANDLE_FILE_INFORMATION attr ctim lati lwti vser
(dwordsToDdword (fshi,fslo)) link (dwordsToDdword (idhi,idlo))
failIfWithRetry :: (a -> Bool) -> String -> IO a -> IO a
failIfWithRetry cond msg action = retryOrFail retries
where
delay = 100*1000
retries = 20 :: Int
retryOrFail times
| times <= 0 = errorWin msg
| otherwise = do
ret <- action
if not (cond ret)
then return ret
else do
err_code <- getLastError
if err_code == (32)
then do threadDelay delay; retryOrFail (times 1)
else errorWin msg
failIfWithRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
failIfWithRetry_ cond msg action = void $ failIfWithRetry cond msg action
failIfFalseWithRetry_ :: String -> IO Bool -> IO ()
failIfFalseWithRetry_ = failIfWithRetry_ not
deleteFile :: String -> IO ()
deleteFile name =
withTString name $ \ c_name ->
failIfFalseWithRetry_ (unwords ["DeleteFile",show name]) $
c_DeleteFile c_name
foreign import stdcall unsafe "windows.h DeleteFileW"
c_DeleteFile :: LPCTSTR -> IO Bool
copyFile :: String -> String -> 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
foreign import stdcall unsafe "windows.h CopyFileW"
c_CopyFile :: LPCTSTR -> LPCTSTR -> Bool -> IO Bool
moveFile :: String -> String -> 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
foreign import stdcall unsafe "windows.h MoveFileW"
c_MoveFile :: LPCTSTR -> LPCTSTR -> IO Bool
moveFileEx :: String -> String -> MoveFileFlag -> IO ()
moveFileEx src dest flags =
withTString src $ \ c_src ->
withTString dest $ \ c_dest ->
failIfFalseWithRetry_ (unwords ["MoveFileEx",show src,show dest]) $
c_MoveFileEx c_src c_dest flags
foreign import stdcall 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 stdcall 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 stdcall unsafe "windows.h CreateDirectoryW"
c_CreateDirectory :: LPCTSTR -> LPSECURITY_ATTRIBUTES -> IO Bool
createDirectoryEx :: String -> String -> 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)
foreign import stdcall 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 stdcall unsafe "windows.h RemoveDirectoryW"
c_RemoveDirectory :: LPCTSTR -> IO Bool
getBinaryType :: String -> 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
foreign import stdcall unsafe "windows.h GetBinaryTypeW"
c_GetBinaryType :: LPCTSTR -> Ptr DWORD -> IO Bool
createFile :: String -> 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)
foreign import stdcall 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 stdcall unsafe "windows.h CloseHandle"
c_CloseHandle :: HANDLE -> IO Bool
foreign import ccall "HsWin32.h &CloseHandleFinaliser"
c_CloseHandleFinaliser :: FunPtr (Ptr a -> IO ())
foreign import stdcall unsafe "windows.h GetFileType"
getFileType :: HANDLE -> IO FileType
flushFileBuffers :: HANDLE -> IO ()
flushFileBuffers h =
failIfFalse_ "FlushFileBuffers" $ c_FlushFileBuffers h
foreign import stdcall unsafe "windows.h FlushFileBuffers"
c_FlushFileBuffers :: HANDLE -> IO Bool
setEndOfFile :: HANDLE -> IO ()
setEndOfFile h =
failIfFalse_ "SetEndOfFile" $ c_SetEndOfFile h
foreign import stdcall 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 stdcall 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 stdcall unsafe "windows.h GetFileAttributesW"
c_GetFileAttributes :: LPCTSTR -> IO FileAttributeOrFlag
getFileInformationByHandle :: HANDLE -> IO BY_HANDLE_FILE_INFORMATION
getFileInformationByHandle h = alloca $ \res -> do
failIfFalseWithRetry_ "GetFileInformationByHandle" $ c_GetFileInformationByHandle h res
peek res
foreign import stdcall unsafe "windows.h GetFileInformationByHandle"
c_GetFileInformationByHandle :: HANDLE -> Ptr BY_HANDLE_FILE_INFORMATION -> IO BOOL
type LPOVERLAPPED = Ptr ()
type MbLPOVERLAPPED = Maybe LPOVERLAPPED
win32_ReadFile :: HANDLE -> Ptr a -> DWORD -> Maybe LPOVERLAPPED -> IO DWORD
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 stdcall 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 stdcall unsafe "windows.h WriteFile"
c_WriteFile :: HANDLE -> Ptr a -> DWORD -> Ptr DWORD -> LPOVERLAPPED -> IO Bool
findFirstChangeNotification :: String -> Bool -> FileNotificationFlag -> IO HANDLE
findFirstChangeNotification path watch flag =
withTString path $ \ c_path ->
failIfNull (unwords ["FindFirstChangeNotification",show path]) $
c_FindFirstChangeNotification c_path watch flag
foreign import stdcall unsafe "windows.h FindFirstChangeNotificationW"
c_FindFirstChangeNotification :: LPCTSTR -> Bool -> FileNotificationFlag -> IO HANDLE
findNextChangeNotification :: HANDLE -> IO ()
findNextChangeNotification h =
failIfFalse_ "FindNextChangeNotification" $ c_FindNextChangeNotification h
foreign import stdcall unsafe "windows.h FindNextChangeNotification"
c_FindNextChangeNotification :: HANDLE -> IO Bool
findCloseChangeNotification :: HANDLE -> IO ()
findCloseChangeNotification h =
failIfFalse_ "FindCloseChangeNotification" $ c_FindCloseChangeNotification h
foreign import stdcall unsafe "windows.h FindCloseChangeNotification"
c_FindCloseChangeNotification :: HANDLE -> IO Bool
type WIN32_FIND_DATA = ()
newtype FindData = FindData (ForeignPtr WIN32_FIND_DATA)
getFindDataFileName :: FindData -> IO FilePath
getFindDataFileName (FindData fp) =
withForeignPtr fp $ \p ->
peekTString (((\hsc_ptr -> hsc_ptr `plusPtr` 44)) p)
findFirstFile :: String -> IO (HANDLE, FindData)
findFirstFile str = do
fp_finddata <- mallocForeignPtrBytes (592)
withForeignPtr fp_finddata $ \p_finddata -> do
handle <- withTString str $ \tstr -> do
failIf (== iNVALID_HANDLE_VALUE) "findFirstFile" $
c_FindFirstFile tstr p_finddata
return (handle, FindData fp_finddata)
foreign import stdcall unsafe "windows.h FindFirstFileW"
c_FindFirstFile :: LPCTSTR -> Ptr WIN32_FIND_DATA -> IO HANDLE
findNextFile :: HANDLE -> FindData -> IO Bool
findNextFile h (FindData finddata) = do
withForeignPtr finddata $ \p_finddata -> do
b <- c_FindNextFile h p_finddata
if b
then return True
else do
err_code <- getLastError
if err_code == (18)
then return False
else failWith "findNextFile" err_code
foreign import stdcall 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 stdcall unsafe "windows.h FindClose"
c_FindClose :: HANDLE -> IO BOOL
defineDosDevice :: DefineDosDeviceFlags -> String -> String -> IO ()
defineDosDevice flags name path =
withTString path $ \ c_path ->
withTString name $ \ c_name ->
failIfFalse_ "DefineDosDevice" $ c_DefineDosDevice flags c_name c_path
foreign import stdcall unsafe "windows.h DefineDosDeviceW"
c_DefineDosDevice :: DefineDosDeviceFlags -> LPCTSTR -> LPCTSTR -> IO Bool
foreign import stdcall unsafe "windows.h AreFileApisANSI"
areFileApisANSI :: IO Bool
foreign import stdcall unsafe "windows.h SetFileApisToOEM"
setFileApisToOEM :: IO ()
foreign import stdcall unsafe "windows.h SetFileApisToANSI"
setFileApisToANSI :: IO ()
foreign import stdcall unsafe "windows.h SetHandleCount"
setHandleCount :: UINT -> IO UINT
getLogicalDrives :: IO DWORD
getLogicalDrives =
failIfZero "GetLogicalDrives" $ c_GetLogicalDrives
foreign import stdcall unsafe "windows.h GetLogicalDrives"
c_GetLogicalDrives :: IO DWORD
getDiskFreeSpace :: Maybe String -> 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)
foreign import stdcall unsafe "windows.h GetDiskFreeSpaceW"
c_GetDiskFreeSpace :: LPCTSTR -> Ptr DWORD -> Ptr DWORD -> Ptr DWORD -> Ptr DWORD -> IO Bool
setVolumeLabel :: String -> String -> IO ()
setVolumeLabel path name =
withTString path $ \ c_path ->
withTString name $ \ c_name ->
failIfFalse_ "SetVolumeLabel" $ c_SetVolumeLabel c_path c_name
foreign import stdcall unsafe "windows.h SetVolumeLabelW"
c_SetVolumeLabel :: LPCTSTR -> LPCTSTR -> IO Bool