summaryrefslogtreecommitdiff
path: root/libraries/base/cbits
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2019-11-19 07:07:15 +0000
committerBen Gamari <ben@smart-cactus.org>2020-07-15 16:41:02 -0400
commit9b38427045b8f1621f607fa7ab9c6353aa479ac5 (patch)
tree76e1dd229cc9f4266f48b7d63f01519576712255 /libraries/base/cbits
parent4b69004f3c9518f59a8f0b6f7f77aa92bea85adf (diff)
downloadhaskell-9b38427045b8f1621f607fa7ab9c6353aa479ac5.tar.gz
winio: Implement new tempfile routines for winio
Diffstat (limited to 'libraries/base/cbits')
-rw-r--r--libraries/base/cbits/Win32Utils.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/libraries/base/cbits/Win32Utils.c b/libraries/base/cbits/Win32Utils.c
index 7b9c9cd244..4181e6105f 100644
--- a/libraries/base/cbits/Win32Utils.c
+++ b/libraries/base/cbits/Win32Utils.c
@@ -16,6 +16,8 @@
#include <wchar.h>
#include <windows.h>
#include <io.h>
+#include <objbase.h>
+#include "fs.h"
/* This is the error table that defines the mapping between OS error
codes and errno values */
@@ -162,6 +164,52 @@ BOOL file_exists(LPCTSTR path)
return r != INVALID_FILE_ATTRIBUTES;
}
+/* If true then caller needs to free tempFileName. */
+bool __createUUIDTempFileErrNo (wchar_t* pathName, wchar_t* prefix,
+ wchar_t* suffix, wchar_t** tempFileName)
+{
+ int retry = 5;
+ bool success = false;
+ while (retry-- > 0 && !success)
+ {
+ GUID guid;
+ ZeroMemory (&guid, sizeof (guid));
+ if (CoCreateGuid (&guid) != S_OK)
+ goto fail;
+
+ RPC_WSTR guidStr;
+ if (UuidToStringW ((UUID*)&guid, &guidStr) != S_OK)
+ goto fail;
+
+ wchar_t* devName = FS(create_device_name) ((wchar_t*)pathName);
+ int len = wcslen (devName) + wcslen (suffix) + wcslen (prefix)
+ + wcslen (guidStr) + 3;
+ *tempFileName = malloc (len * sizeof (wchar_t));
+ if (*tempFileName == NULL)
+ goto fail;
+
+ if (-1 == swprintf_s (*tempFileName, len, L"%ls\\%ls-%ls%ls",
+ devName, prefix, guidStr, suffix))
+ goto fail;
+
+ free (devName);
+ RpcStringFreeW (&guidStr);
+ /* This should never happen because GUIDs are unique. But in case hell
+ froze over let's check anyway. */
+ DWORD dwAttrib = GetFileAttributesW (*tempFileName);
+ success = (dwAttrib == INVALID_FILE_ATTRIBUTES
+ || (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
+ if (!success)
+ free (*tempFileName);
+ }
+
+ return success;
+
+fail:
+ maperrno();
+ return false;
+}
+
bool getTempFileNameErrorNo (wchar_t* pathName, wchar_t* prefix,
wchar_t* suffix, uint32_t uUnique,
wchar_t* tempFileName)