1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 #include "windows_.h"
17 #include <string>
18 #include <sstream>
19 #include <windows.storage.h>
20 #include <wrl/client.h>
21 #include <wrl/wrappers/corewrappers.h>
22 
GetTempPathWRT(DWORD nBufferLength,LPWSTR lpBuffer)23 extern "C" DWORD GetTempPathWRT(DWORD nBufferLength, LPWSTR lpBuffer)
24 {
25     try
26     {
27         HRESULT hr;
28         Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> applicationDataStatics;
29 
30         hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(
31                  RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics);
32         if (FAILED(hr))
33             return 0;
34 
35         Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> applicationData;
36         hr = applicationDataStatics->get_Current(&applicationData);
37         if (FAILED(hr))
38             return 0;
39 
40         Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storageFolder;
41         hr = applicationData->get_TemporaryFolder(&storageFolder);
42         if (FAILED(hr))
43             return 0;
44 
45         Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageItem;
46         hr = storageFolder.As(&storageItem);
47         if (FAILED(hr))
48             return 0;
49 
50         HSTRING folderName;
51         hr = storageItem->get_Path(&folderName);
52         if (FAILED(hr))
53             return 0;
54 
55         UINT32 length;
56         PCWSTR value = WindowsGetStringRawBuffer(folderName, &length);
57         std::wstring ws(value);
58         wcsncpy(lpBuffer, ws.c_str(), nBufferLength);
59         lpBuffer[nBufferLength-1] = 0;
60         WindowsDeleteString(folderName);
61         return ws.length();
62     }
63     catch(...)
64     {
65         return 0;
66     }
67 }
68 
GetTempFileNameWRT(LPCWSTR lpPathName,LPCWSTR lpPrefixString,LPWSTR lpTempFileName)69 extern "C" UINT GetTempFileNameWRT(LPCWSTR lpPathName, LPCWSTR lpPrefixString, LPWSTR lpTempFileName)
70 {
71     try
72     {
73        std::wstring path(lpPathName);
74        std::wstring prefix(lpPrefixString);
75        FILETIME systemTimeAsFileTime;
76 
77        if (!path.empty() && path.back() != '\\')
78            path.push_back('\\');
79 
80        if (path.length() > _MAX_PATH - 14)
81            return ERROR_BUFFER_OVERFLOW;
82 
83        GetSystemTimeAsFileTime(&systemTimeAsFileTime);
84 
85        DWORD time = systemTimeAsFileTime.dwLowDateTime;
86        while(true)
87        {
88            // Create file name of at most 13 characters, using at most 10
89            // digits of time, and as many of the prefix characters as can fit
90            std::wstring num(std::to_wstring((UINT)time));
91            if (num.length() > 10)
92                num = num.substr(num.length() - 10);
93            std::wstring pf(prefix);
94            if (num.length() + pf.length() > 13)
95                pf.resize(13 - num.length());
96            std::wstring fullpath = path+pf+num;
97 
98            // Test that the file doesn't already exist
99            LPWIN32_FIND_DATA find_data;
100            HANDLE h = FindFirstFileExW(fullpath.c_str(), FindExInfoStandard, &find_data, FindExSearchNameMatch, NULL, 0);
101            if (h == INVALID_HANDLE_VALUE)
102            {
103                // File doesn't exist
104                wcscpy(lpTempFileName, fullpath.c_str());
105                return fullpath.length();
106            }
107 
108            // File exists. Increment time and try again
109            FindClose(h);
110            time++;
111        }
112 
113        return ERROR_BUFFER_OVERFLOW;
114     }
115     catch(...)
116     {
117         return ERROR_BUFFER_OVERFLOW;
118     }
119 }
120 
OutputDebugStringWRT(LPCSTR str,DWORD len)121 extern "C" void OutputDebugStringWRT(LPCSTR str, DWORD len)
122 {
123 	try
124 	{
125 		std::string s(str, len);
126 		std::wstring w(s.begin(), s.end());
127 		OutputDebugStringW(w.c_str());
128 	}
129 	catch(...)
130 	{
131 	}
132 }
133