Skip to content

Commit b02af3b

Browse files
hasufellMistuke
authored andcommitted
Add getTempFileName
1 parent f3fb024 commit b02af3b

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

System/Win32/File.hsc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ module System.Win32.File
189189
, createDirectoryEx
190190
, removeDirectory
191191
, getBinaryType
192+
, getTempFileName
192193

193194
-- * HANDLE operations
194195
, createFile
@@ -245,6 +246,7 @@ import System.Win32.Types
245246
import Foreign hiding (void)
246247
import Control.Monad
247248
import Control.Concurrent
249+
import Data.Maybe (fromMaybe)
248250

249251
##include "windows_cconv.h"
250252

@@ -345,6 +347,22 @@ getBinaryType name =
345347
c_GetBinaryType c_name p_btype
346348
peek p_btype
347349

350+
-- | Get a unique temporary filename.
351+
--
352+
-- Calls 'GetTempFileNameW'.
353+
getTempFileName :: String -- ^ directory for the temporary file (must be at most MAX_PATH - 14 characters long)
354+
-> String -- ^ prefix for the temporary file name
355+
-> Maybe UINT -- ^ if 'Nothing', a unique name is generated
356+
-- otherwise a non-zero value is used as the unique part
357+
-> IO (String, UINT)
358+
getTempFileName dir prefix unique = allocaBytes ((#const MAX_PATH) * sizeOf (undefined :: TCHAR)) $ \c_buf -> do
359+
uid <- withFilePath dir $ \c_dir ->
360+
withFilePath prefix $ \ c_prefix -> do
361+
failIfZero "getTempFileName" $
362+
c_GetTempFileNameW c_dir c_prefix (fromMaybe 0 unique) c_buf
363+
fname <- peekTString c_buf
364+
return (fname, uid)
365+
348366
----------------------------------------------------------------
349367
-- HANDLE operations
350368
----------------------------------------------------------------

System/Win32/File/Internal.hsc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ foreign import WINDOWS_CCONV unsafe "windows.h GetFileAttributesExW"
399399
foreign import WINDOWS_CCONV unsafe "windows.h GetFileInformationByHandle"
400400
c_GetFileInformationByHandle :: HANDLE -> Ptr BY_HANDLE_FILE_INFORMATION -> IO BOOL
401401

402+
foreign import WINDOWS_CCONV unsafe "windows.h GetTempFileNameW"
403+
c_GetTempFileNameW :: LPCWSTR -> LPCWSTR -> UINT -> LPWSTR -> IO UINT
404+
402405
----------------------------------------------------------------
403406
-- Read/write files
404407
----------------------------------------------------------------

System/Win32/WindowsString/File.hsc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module System.Win32.WindowsString.File
2626
, setFileAttributes
2727
, getFileAttributes
2828
, getFileAttributesExStandard
29+
, getTempFileName
2930
, findFirstChangeNotification
3031
, getFindDataFileName
3132
, findFirstFile
@@ -52,6 +53,7 @@ import System.Win32.File hiding (
5253
, setFileAttributes
5354
, getFileAttributes
5455
, getFileAttributesExStandard
56+
, getTempFileName
5557
, findFirstChangeNotification
5658
, getFindDataFileName
5759
, findFirstFile
@@ -64,6 +66,7 @@ import System.Win32.File hiding (
6466
import System.Win32.WindowsString.Types
6567
import System.OsString.Windows
6668
import Unsafe.Coerce (unsafeCoerce)
69+
import Data.Maybe (fromMaybe)
6770

6871
import Foreign hiding (void)
6972

@@ -161,6 +164,23 @@ getFileAttributesExStandard name = alloca $ \res -> do
161164
c_GetFileAttributesEx c_name (unsafeCoerce getFileExInfoStandard) res
162165
peek res
163166

167+
-- | Get a unique temporary filename.
168+
--
169+
-- Calls 'GetTempFileNameW'.
170+
getTempFileName :: WindowsString -- ^ directory for the temporary file (must be at most MAX_PATH - 14 characters long)
171+
-> WindowsString -- ^ prefix for the temporary file name
172+
-> Maybe UINT -- ^ if 'Nothing', a unique name is generated
173+
-- otherwise a non-zero value is used as the unique part
174+
-> IO (WindowsString, UINT)
175+
getTempFileName dir prefix unique = allocaBytes ((#const MAX_PATH) * sizeOf (undefined :: TCHAR)) $ \c_buf -> do
176+
uid <- withFilePath dir $ \c_dir ->
177+
withFilePath prefix $ \ c_prefix -> do
178+
failIfZero "getTempFileName" $
179+
c_GetTempFileNameW c_dir c_prefix (fromMaybe 0 unique) c_buf
180+
fname <- peekTString c_buf
181+
pure (fname, uid)
182+
183+
164184

165185
----------------------------------------------------------------
166186
-- File Notifications

0 commit comments

Comments
 (0)