dist-install\build\System\Win32\File.hs

    {-# LINE 1 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    {-# LINE 2 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
    {-# LANGUAGE Safe #-}

    {-# LINE 6 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  System.Win32.File
    -- Copyright   :  (c) Alastair Reid, 1997-2003
    -- License     :  BSD-style (see the file libraries/base/LICENSE)
    --
    -- Maintainer  :  Esa Ilari Vuokko <ei@vuokko.info>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- A collection of FFI declarations for interfacing with Win32.
    --
    -----------------------------------------------------------------------------

    module System.Win32.File
    {-
            ( AccessMode, ShareMode, CreateMode, FileAttributeOrFlag
            , CreateFile, CloseHandle, DeleteFile, CopyFile
            , MoveFileFlag, MoveFile, MoveFileEx,
            )
    -}
    where

    import System.Win32.Types
    import System.Win32.Time

    import Foreign hiding (void)
    import Control.Monad
    import Control.Concurrent

    #include "windows_cconv.h"

    {-# LINE 39 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------
    -- Enumeration types
    ----------------------------------------------------------------

    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

    {-# LINE 68 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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
    fILE_SHARE_DELETE     :: ShareMode
    fILE_SHARE_DELETE     =  4

    {-# LINE 81 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 93 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 116 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    {-# LINE 117 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
    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

    {-# LINE 127 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    {-# LINE 128 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 138 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    type FilePtrDirection   = DWORD

    fILE_BEGIN    :: FilePtrDirection
    fILE_BEGIN    =  0
    fILE_CURRENT  :: FilePtrDirection
    fILE_CURRENT  =  1
    fILE_END      :: FilePtrDirection
    fILE_END      =  2

    {-# LINE 148 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 162 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 172 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 185 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 198 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    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

    {-# LINE 210 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    newtype GET_FILEEX_INFO_LEVELS = GET_FILEEX_INFO_LEVELS (Word32)
    {-# LINE 214 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
        deriving (Eq, Ord)

    getFileExInfoStandard  :: GET_FILEEX_INFO_LEVELS
    getFileExInfoStandard  = GET_FILEEX_INFO_LEVELS 0
    getFileExMaxInfoLevel  :: GET_FILEEX_INFO_LEVELS
    getFileExMaxInfoLevel  = GET_FILEEX_INFO_LEVELS 1

    {-# LINE 220 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    ----------------------------------------------------------------

    type LPSECURITY_ATTRIBUTES = Ptr ()
    type MbLPSECURITY_ATTRIBUTES = Maybe LPSECURITY_ATTRIBUTES

    ----------------------------------------------------------------
    -- 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 ((52))
    {-# LINE 241 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
        alignment = sizeOf
        poke buf bhi = do
            ((\hsc_ptr -> pokeByteOff hsc_ptr 0))     buf (bhfiFileAttributes bhi)
    {-# LINE 244 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 4))       buf (bhfiCreationTime bhi)
    {-# LINE 245 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 12))     buf (bhfiLastAccessTime bhi)
    {-# LINE 246 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 20))      buf (bhfiLastWriteTime bhi)
    {-# LINE 247 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 28)) buf (bhfiVolumeSerialNumber bhi)
    {-# LINE 248 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 32))        buf sizeHi
    {-# LINE 249 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 36))         buf sizeLow
    {-# LINE 250 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 40))       buf (bhfiNumberOfLinks bhi)
    {-# LINE 251 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 44))       buf idxHi
    {-# LINE 252 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 48))        buf idxLow
    {-# LINE 253 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            where
                (sizeHi,sizeLow) = ddwordToDwords $ bhfiSize bhi
                (idxHi,idxLow) = ddwordToDwords $ bhfiFileIndex bhi

        peek buf = do
            attr <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))     buf
    {-# LINE 259 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ctim <- ((\hsc_ptr -> peekByteOff hsc_ptr 4))       buf
    {-# LINE 260 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            lati <- ((\hsc_ptr -> peekByteOff hsc_ptr 12))     buf
    {-# LINE 261 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            lwti <- ((\hsc_ptr -> peekByteOff hsc_ptr 20))      buf
    {-# LINE 262 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            vser <- ((\hsc_ptr -> peekByteOff hsc_ptr 28)) buf
    {-# LINE 263 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            fshi <- ((\hsc_ptr -> peekByteOff hsc_ptr 32))        buf
    {-# LINE 264 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            fslo <- ((\hsc_ptr -> peekByteOff hsc_ptr 36))         buf
    {-# LINE 265 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            link <- ((\hsc_ptr -> peekByteOff hsc_ptr 40))       buf
    {-# LINE 266 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            idhi <- ((\hsc_ptr -> peekByteOff hsc_ptr 44))       buf
    {-# LINE 267 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            idlo <- ((\hsc_ptr -> peekByteOff hsc_ptr 48))        buf
    {-# LINE 268 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            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 ((36))
    {-# LINE 281 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
        alignment = sizeOf
        poke buf ad = do
            ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) buf (fadFileAttributes ad)
    {-# LINE 284 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 4))   buf (fadCreationTime ad)
    {-# LINE 285 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 12)) buf (fadLastAccessTime ad)
    {-# LINE 286 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 20))  buf (fadLastWriteTime ad)
    {-# LINE 287 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 28))    buf sizeHi
    {-# LINE 288 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 32))     buf sizeLo
    {-# LINE 289 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            where
                (sizeHi,sizeLo) = ddwordToDwords $ fadFileSize ad

        peek buf = do
            attr <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) buf
    {-# LINE 294 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            ctim <- ((\hsc_ptr -> peekByteOff hsc_ptr 4))   buf
    {-# LINE 295 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            lati <- ((\hsc_ptr -> peekByteOff hsc_ptr 12)) buf
    {-# LINE 296 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            lwti <- ((\hsc_ptr -> peekByteOff hsc_ptr 20))  buf
    {-# LINE 297 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            fshi <- ((\hsc_ptr -> peekByteOff hsc_ptr 28))    buf
    {-# LINE 298 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            fslo <- ((\hsc_ptr -> peekByteOff hsc_ptr 32))     buf
    {-# LINE 299 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
            return $ WIN32_FILE_ATTRIBUTE_DATA attr ctim lati lwti
                (dwordsToDdword (fshi,fslo))

    ----------------------------------------------------------------
    -- File operations
    ----------------------------------------------------------------

    -- | like failIfFalse_, but retried on sharing violations.
    -- This is necessary for many file operations; see
    --   http://support.microsoft.com/kb/316609
    --
    failIfWithRetry :: (a -> Bool) -> String -> IO a -> IO a
    failIfWithRetry cond msg action = retryOrFail retries
      where
        delay   = 100*1000 -- in ms, we use threadDelay
        retries = 20 :: Int
          -- KB article recommends 250/5

        -- retryOrFail :: Int -> IO a
        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)
    {-# LINE 327 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
                    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 WINDOWS_CCONV 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 WINDOWS_CCONV 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 WINDOWS_CCONV 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 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 =
      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 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 =
      withTString name $ \ c_name ->
      alloca $ \ p_btype -> do
      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
    ----------------------------------------------------------------

    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 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

    {-# CFILES cbits/HsWin32.c #-}
    foreign import ccall "HsWin32.h &CloseHandleFinaliser"
        c_CloseHandleFinaliser :: FunPtr (Ptr a -> IO ())

    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
      withTString name $ \ c_name ->
        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
    --type OVERLAPPED =
    -- (DWORD,  -- Offset
    --  DWORD,  -- OffsetHigh
    --  HANDLE) -- hEvent

    type LPOVERLAPPED = Ptr ()

    type MbLPOVERLAPPED = Maybe LPOVERLAPPED

    --Sigh - I give up & prefix win32_ to the next two to avoid
    -- senseless Prelude name clashes. --sof.

    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 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

    -- missing Seek functioinality; GSL ???
    -- Dont have Word64; ADR
    -- %fun SetFilePointer :: HANDLE -> Word64 -> FilePtrDirection -> IO Word64

    ----------------------------------------------------------------
    -- File Notifications
    --
    -- Use these to initialise, "increment" and close a HANDLE you can wait
    -- on.
    ----------------------------------------------------------------

    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 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 ->
        peekTString (((\hsc_ptr -> hsc_ptr `plusPtr` 44)) p)
    {-# LINE 560 "libraries\\Win32\\System\\Win32\\File.hsc" #-}

    findFirstFile :: String -> IO (HANDLE, FindData)
    findFirstFile str = do
      fp_finddata <- mallocForeignPtrBytes (592)
    {-# LINE 564 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
      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 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
      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)
    {-# LINE 581 "libraries\\Win32\\System\\Win32\\File.hsc" #-}
                    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
    ----------------------------------------------------------------

    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 WINDOWS_CCONV unsafe "windows.h DefineDosDeviceW"
      c_DefineDosDevice :: DefineDosDeviceFlags -> LPCTSTR -> LPCTSTR -> IO Bool

    ----------------------------------------------------------------

    -- These functions are very unusual in the Win32 API:
    -- They dont 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

    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 WINDOWS_CCONV 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 WINDOWS_CCONV unsafe "windows.h SetVolumeLabelW"
      c_SetVolumeLabel :: LPCTSTR -> LPCTSTR -> IO Bool

    ----------------------------------------------------------------
    -- End
    ----------------------------------------------------------------