diff options
author | Tamar Christina <tamar@zhox.com> | 2019-11-19 07:07:15 +0000 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-07-15 16:41:02 -0400 |
commit | 9b38427045b8f1621f607fa7ab9c6353aa479ac5 (patch) | |
tree | 76e1dd229cc9f4266f48b7d63f01519576712255 /libraries/base/cbits | |
parent | 4b69004f3c9518f59a8f0b6f7f77aa92bea85adf (diff) | |
download | haskell-9b38427045b8f1621f607fa7ab9c6353aa479ac5.tar.gz |
winio: Implement new tempfile routines for winio
Diffstat (limited to 'libraries/base/cbits')
-rw-r--r-- | libraries/base/cbits/Win32Utils.c | 48 |
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) |