summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/IO/Windows/Paths.hs
blob: add56030d7bcb363d1b5c6cc84831a2a8244fd79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{-# LANGUAGE Trustworthy          #-}
{-# LANGUAGE NoImplicitPrelude    #-}
{-# LANGUAGE CPP                  #-}
-- Whether there are identities depends on the platform
{-# OPTIONS_HADDOCK hide #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.IO.Windows.Paths
-- Copyright   :  (c) The University of Glasgow, 2017
-- License     :  see libraries/base/LICENSE
--
-- Maintainer  :  libraries@haskell.org
-- Stability   :  internal
-- Portability :  non-portable
--
-- Windows FilePath handling utility for GHC code.
--
-----------------------------------------------------------------------------

module GHC.IO.Windows.Paths
 (getDevicePath
 ) where

#include "windows_cconv.h"

import GHC.Base
import GHC.IO

import Foreign.C.String
import Foreign.Marshal.Alloc (free)

foreign import ccall safe "__hs_create_device_name"
    c_GetDevicePath :: CWString -> IO CWString

-- | This function converts Windows paths between namespaces. More specifically
-- It converts an explorer style path into a NT or Win32 namespace.
-- This has several caveats but they are caveats that are native to Windows and
-- not POSIX. See
-- https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx.
-- Anything else such as raw device paths we leave untouched.  The main benefit
-- of doing any of this is that we can break the MAX_PATH restriction and also
-- access raw handles that we couldn't before.
getDevicePath :: FilePath -> IO FilePath
getDevicePath path
  = do str <- withCWString path c_GetDevicePath
       newPath <- peekCWString str
       free str
       return newPath