-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathwin32util.cpp
93 lines (89 loc) · 3.48 KB
/
win32util.cpp
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "win32util.h"
#include "util.h"
#include <io.h>
#include <fcntl.h>
#include "strutil.h"
namespace win32 {
void throw_error(const std::wstring &msg, DWORD code)
{
LPWSTR pszMsg;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
0,
code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&pszMsg,
0,
0);
std::wstring ss;
if (pszMsg) {
strutil::squeeze(pszMsg, L"\r\n");
ss = strutil::format(L"%s: %s", msg.c_str(), pszMsg);
LocalFree(pszMsg);
}
else if (code < 0xfe00)
ss = strutil::format(L"%d: %s", code, msg.c_str());
else
ss = strutil::format(L"%08x: %s", code, msg.c_str());
throw std::runtime_error(strutil::w2us(ss));
}
FILE *tmpfile(const wchar_t *prefix)
{
std::wstring sprefix =
strutil::format(L"%s.%d.", prefix, GetCurrentProcessId());
wchar_t *tmpname = _wtempnam(0, sprefix.c_str());
std::shared_ptr<wchar_t> tmpname_p(tmpname, std::free);
HANDLE fh = CreateFileW(prefixed_path(tmpname).c_str(),
GENERIC_READ | GENERIC_WRITE,
0, 0, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY |
FILE_FLAG_DELETE_ON_CLOSE,
0);
if (fh == INVALID_HANDLE_VALUE)
throw_error(tmpname, GetLastError());
int fd = _open_osfhandle(reinterpret_cast<intptr_t>(fh),
_O_BINARY|_O_RDWR);
if (fd == -1) {
CloseHandle(fh);
util::throw_crt_error("win32::tmpfile: open_osfhandle()");
}
FILE *fp = _fdopen(fd, "w+");
if (!fp) {
_close(fd);
util::throw_crt_error("win32::tmpfile: _fdopen()");
}
return fp;
}
char *load_with_mmap(const wchar_t *path, uint64_t *size)
{
std::wstring fullpath = prefixed_path(path);
HANDLE hFile = CreateFileW(fullpath.c_str(), GENERIC_READ,
0, 0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
throw_error(fullpath, GetLastError());
DWORD sizeHi, sizeLo;
sizeLo = GetFileSize(hFile, &sizeHi);
*size = (static_cast<uint64_t>(sizeHi) << 32) | sizeLo;
HANDLE hMap = CreateFileMappingW(hFile, 0, PAGE_READONLY, 0, 0, 0);
DWORD err = GetLastError();
CloseHandle(hFile);
if (hMap <= 0) throw_error("CreateFileMapping", err);
char *view =
reinterpret_cast<char*>( MapViewOfFile(hMap, FILE_MAP_READ,
0, 0, 0));
CloseHandle(hMap);
return view;
}
int create_named_pipe(const wchar_t *path)
{
HANDLE fh = CreateNamedPipeW(path,
PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE | PIPE_WAIT,
1, 0, 0, 0, 0);
if (fh == INVALID_HANDLE_VALUE)
throw_error(path, GetLastError());
ConnectNamedPipe(fh, 0);
return _open_osfhandle(reinterpret_cast<intptr_t>(fh),
_O_WRONLY | _O_BINARY);
}
}