-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathimpl.win32.cpp
143 lines (136 loc) · 3.81 KB
/
impl.win32.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#pragma once
namespace MemoryMapped
{
size_t GetPageSize()
{
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
return sysInfo.dwAllocationGranularity;
}
bool File::openReal(size_t mappedBytes, CacheHint hint)
{
DWORD winHint;
// already open ?
if(isValid())
{
return false;
}
m_handle = 0;
m_filesize = 0;
m_hint = hint;
m_mappedFile = NULL;
m_mappedView = NULL;
winHint = 0;
switch (m_hint)
{
case Normal:
winHint = FILE_ATTRIBUTE_NORMAL;
break;
case SequentialScan:
winHint = FILE_FLAG_SEQUENTIAL_SCAN;
break;
case RandomAccess:
winHint = FILE_FLAG_RANDOM_ACCESS;
break;
default:
break;
}
// open file
m_handle = ::CreateFileA(
m_filename.c_str(),
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, winHint, NULL);
if(!m_handle)
{
throw IOError(m_filename, "CreateFileA() failed");
return false;
}
// file size
LARGE_INTEGER result;
if (!GetFileSizeEx(m_handle, &result))
{
throw IOError(m_filename, "GetFileSizeEx() failed");
return false;
}
m_filesize = static_cast<uint64_t>(result.QuadPart);
// convert to mapped mode
m_mappedFile = ::CreateFileMapping(m_handle, NULL, PAGE_READONLY, 0, 0, NULL);
if (!m_mappedFile)
{
throw IOError(m_filename, "CreateFileMapping() failed");
return false;
}
// initial mapping
remap(0, mappedBytes);
if (!m_mappedView)
{
// remap() may throw an exception already
return false;
}
// everything's fine
return true;
}
void File::close()
{
m_filesize = 0;
// kill pointer
if (m_mappedView)
{
::UnmapViewOfFile(m_mappedView);
m_mappedView = NULL;
}
if(m_mappedFile)
{
::CloseHandle(m_mappedFile);
m_mappedFile = NULL;
}
//close underlying file
if(m_handle)
{
::CloseHandle(m_handle);
m_handle = 0;
}
}
bool File::remap(uint64_t offset, size_t mappedBytes)
{
DWORD offsetLow;
DWORD offsetHigh;
if(!m_handle)
{
throw IOError(m_filename, "trying to operate on a closed handle");
return false;
}
if (mappedBytes == WholeFile)
{
mappedBytes = m_filesize;
}
// close old mapping
if(m_mappedView)
{
::UnmapViewOfFile(m_mappedView);
m_mappedView = NULL;
}
// don't go further than end of file
if(offset > m_filesize)
{
return errOffset();
}
if((offset + mappedBytes) > m_filesize)
{
mappedBytes = size_t(m_filesize - offset);
}
offsetLow = DWORD(offset & 0xFFFFFFFF);
offsetHigh = DWORD(offset >> 32);
m_mappedBytes = mappedBytes;
// get memory address
m_mappedView = ::MapViewOfFile(m_mappedFile, FILE_MAP_READ, offsetHigh, offsetLow, mappedBytes);
if(m_mappedView == NULL)
{
m_mappedBytes = 0;
m_mappedView = NULL;
throw IOError(m_filename, "MapViewOfFile() == NULL");
return false;
}
return true;
}
}