3 -----------------------------------------------------------------------------
6 -- Module : Distribution.Compat.GetShortPathName
8 -- Maintainer : cabal-devel@haskell.org
9 -- Portability : Windows-only
11 -- Win32 API 'GetShortPathName' function.
12 module Distribution
.Compat
.GetShortPathName
(getShortPathName
)
15 import Distribution
.Compat
.Prelude
18 #ifdef mingw32_HOST_OS
20 import qualified Prelude
21 import qualified System
.Win32
as Win32
22 import System
.Win32
(LPCTSTR
, LPTSTR
, DWORD
)
23 import Foreign
.Marshal
.Array (allocaArray
)
25 {- FOURMOLU_DISABLE -}
26 #ifdef x86_64_HOST_ARCH
29 #define WINAPI stdcall
32 foreign import WINAPI unsafe
"windows.h GetShortPathNameW"
33 c_GetShortPathName
:: LPCTSTR
-> LPTSTR
-> DWORD
-> Prelude
.IO DWORD
35 -- | On Windows, retrieves the short path form of the specified path. On
36 -- non-Windows, does nothing. See https://github.com/haskell/cabal/issues/3185.
38 -- From MS's GetShortPathName docs:
40 -- Passing NULL for [the second] parameter and zero for cchBuffer
41 -- will always return the required buffer size for a
42 -- specified lpszLongPath.
44 getShortPathName
:: FilePath -> IO FilePath
45 getShortPathName path
=
46 Win32
.withTString path
$ \c_path
-> do
47 c_len
<- Win32
.failIfZero
"GetShortPathName #1 failed!" $
48 c_GetShortPathName c_path Win32
.nullPtr
0
49 let arr_len
= fromIntegral c_len
50 allocaArray arr_len
$ \c_out
-> do
51 void
$ Win32
.failIfZero
"GetShortPathName #2 failed!" $
52 c_GetShortPathName c_path c_out c_len
53 Win32
.peekTString c_out
57 getShortPathName
:: FilePath -> IO FilePath
58 getShortPathName path
= return path