1 /* ----------------------------------------------------------------------------
2 (c) The University of Glasgow 2006, Lifted from Bases
3
4 Useful Win32 bits
5 ------------------------------------------------------------------------- */
6
7 #if defined(_WIN32)
8
9 #include "HsBase.h"
10 #include <stdbool.h>
11 #include <stdint.h>
12 /* Using Secure APIs */
13 #define MINGW_HAS_SECURE_API 1
14 #include <wchar.h>
15 #include <windows.h>
16
17 /* Copied from getTempFileNameErrorNo in base's cbits/Win32Utils.c in GHC 8.10.
18 Check there for any bugfixes first and please keep in sync when making
19 changes. */
20
__get_temp_file_name(wchar_t * pathName,wchar_t * prefix,wchar_t * suffix,uint32_t uUnique,wchar_t * tempFileName)21 bool __get_temp_file_name (wchar_t* pathName, wchar_t* prefix,
22 wchar_t* suffix, uint32_t uUnique,
23 wchar_t* tempFileName)
24 {
25 int retry = 5;
26 bool success = false;
27 while (retry > 0 && !success)
28 {
29 // TODO: This needs to handle long file names.
30 if (!GetTempFileNameW(pathName, prefix, uUnique, tempFileName))
31 {
32 maperrno();
33 return false;
34 }
35
36 wchar_t* drive = malloc (sizeof(wchar_t) * _MAX_DRIVE);
37 wchar_t* dir = malloc (sizeof(wchar_t) * _MAX_DIR);
38 wchar_t* fname = malloc (sizeof(wchar_t) * _MAX_FNAME);
39 if (_wsplitpath_s (tempFileName, drive, _MAX_DRIVE, dir, _MAX_DIR,
40 fname, _MAX_FNAME, NULL, 0) != 0)
41 {
42 success = false;
43 maperrno ();
44 }
45 else
46 {
47 wchar_t* temp = _wcsdup (tempFileName);
48 if (wcsnlen(drive, _MAX_DRIVE) == 0)
49 swprintf_s(tempFileName, MAX_PATH, L"%s\%s%s",
50 dir, fname, suffix);
51 else
52 swprintf_s(tempFileName, MAX_PATH, L"%s\%s\%s%s",
53 drive, dir, fname, suffix);
54 success
55 = MoveFileExW(temp, tempFileName, MOVEFILE_WRITE_THROUGH
56 | MOVEFILE_COPY_ALLOWED) != 0;
57 errno = 0;
58 if (!success && (GetLastError () != ERROR_FILE_EXISTS || --retry < 0))
59 {
60 success = false;
61 maperrno ();
62 DeleteFileW (temp);
63 }
64
65
66 free(temp);
67 }
68
69 free(drive);
70 free(dir);
71 free(fname);
72 }
73
74 return success;
75 }
76 #endif