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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
/* ----------------------------------------------------------------------------
(c) The University of Glasgow 2006, Lifted from Bases
Useful Win32 bits
------------------------------------------------------------------------- */
#if defined(_WIN32)
#include "HsBase.h"
#include <stdbool.h>
#include <stdint.h>
/* Using Secure APIs */
#define MINGW_HAS_SECURE_API 1
#include <wchar.h>
#include <windows.h>
/* Copied from getTempFileNameErrorNo in base's cbits/Win32Utils.c in GHC 8.10.
Check there for any bugfixes first and please keep in sync when making
changes. */
bool __get_temp_file_name (wchar_t* pathName, wchar_t* prefix,
wchar_t* suffix, uint32_t uUnique,
wchar_t* tempFileName)
{
int retry = 5;
bool success = false;
while (retry > 0 && !success)
{
// TODO: This needs to handle long file names.
if (!GetTempFileNameW(pathName, prefix, uUnique, tempFileName))
{
maperrno();
return false;
}
wchar_t* drive = malloc (sizeof(wchar_t) * _MAX_DRIVE);
wchar_t* dir = malloc (sizeof(wchar_t) * _MAX_DIR);
wchar_t* fname = malloc (sizeof(wchar_t) * _MAX_FNAME);
if (_wsplitpath_s (tempFileName, drive, _MAX_DRIVE, dir, _MAX_DIR,
fname, _MAX_FNAME, NULL, 0) != 0)
{
success = false;
maperrno ();
}
else
{
wchar_t* temp = _wcsdup (tempFileName);
if (wcsnlen(drive, _MAX_DRIVE) == 0)
swprintf_s(tempFileName, MAX_PATH, L"%s\%s%s",
dir, fname, suffix);
else
swprintf_s(tempFileName, MAX_PATH, L"%s\%s\%s%s",
drive, dir, fname, suffix);
success
= MoveFileExW(temp, tempFileName, MOVEFILE_WRITE_THROUGH
| MOVEFILE_COPY_ALLOWED) != 0;
errno = 0;
if (!success && (GetLastError () != ERROR_FILE_EXISTS || --retry < 0))
{
success = false;
maperrno ();
DeleteFileW (temp);
}
free(temp);
}
free(drive);
free(dir);
free(fname);
}
return success;
}
#endif
|