module System.Console.Haskeline.Directory(
getDirectoryContents,
doesDirectoryExist,
getHomeDirectory
) where
import Foreign
import Foreign.C
import System.Win32.Types
import qualified System.Directory
#if defined(i386_HOST_ARCH)
# define WINDOWS_CCONV stdcall
#elif defined(x86_64_HOST_ARCH)
# define WINDOWS_CCONV ccall
#else
# error Unknown mingw32 arch
#endif
foreign import WINDOWS_CCONV "FindFirstFileW" c_FindFirstFile
:: LPCTSTR -> Ptr () -> IO HANDLE
foreign import WINDOWS_CCONV "FindNextFileW" c_FindNextFile
:: HANDLE -> Ptr () -> IO Bool
foreign import WINDOWS_CCONV "FindClose" c_FindClose :: HANDLE -> IO BOOL
getDirectoryContents :: FilePath -> IO [FilePath]
getDirectoryContents fp = allocaBytes ((320)) $ \findP ->
withCWString (fp ++ "\\*") $ \t_arr -> do
h <- c_FindFirstFile t_arr findP
if h == iNVALID_HANDLE_VALUE
then return []
else loop h findP
where
loop h findP = do
f <- peekFileName findP
isNext <- c_FindNextFile h findP
if isNext
then do {fs <- loop h findP; return (f:fs)}
else c_FindClose h >> return [f]
peekFileName = peekCWString . ((\hsc_ptr -> hsc_ptr `plusPtr` 44))
foreign import WINDOWS_CCONV "GetFileAttributesW" c_GetFileAttributes
:: LPCTSTR -> IO DWORD
doesDirectoryExist :: FilePath -> IO Bool
doesDirectoryExist file = do
attrs <- withCWString file c_GetFileAttributes
return $ attrs /= (4294967295)
&& (attrs .&. (16)) /= 0
getHomeDirectory :: IO FilePath
getHomeDirectory = System.Directory.getHomeDirectory