-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfile-map.h
134 lines (114 loc) · 2.93 KB
/
file-map.h
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
/*
** ÎļþÄÚ´æÓ³Éä·â×°
** author
*/
#ifndef ULT_FILE_FILEMAP_H_
#define ULT_FILE_FILEMAP_H_
#include <windows.h>
#include <cassert>
#include <string>
namespace ult {
class FileMap {
public:
FileMap(void) :
file_(NULL),
file_mapping_(NULL),
pfile_view_(NULL) {
}
~FileMap(void) {
Close();
}
bool Open(const std::wstring& filename, DWORD dwaccess = GENERIC_READ) {
file_ = ::CreateFile(filename.c_str(), dwaccess, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_ == INVALID_HANDLE_VALUE) {
return false;
}
return true;
}
bool CreateMapping(DWORD flprotect = PAGE_READONLY, ULONGLONG maximum_size = 0) {
if (0 == this->GetFileSize()) {
return false;
}
file_mapping_ = ::CreateFileMapping(file_, NULL, flprotect, maximum_size >> 32,
maximum_size & 0xffffffff, NULL);
if (file_mapping_ == NULL) {
return false;
}
return true;
}
void* MapView(ULONGLONG offset, SIZE_T map_bytes, DWORD dwaccess = FILE_MAP_READ) {
UnmapView();
DWORD glt = GetAllocationGranularity();
ULONGLONG real_offset = GranularityFloor(offset, glt);
DWORD distance = static_cast<DWORD>(offset - real_offset);
SIZE_T real_map_bytes = map_bytes + distance;
pfile_view_ = ::MapViewOfFile(file_mapping_, dwaccess, real_offset >> 32,
real_offset & 0xffffffff, real_map_bytes);
if (pfile_view_ == NULL) {
return NULL;
}
return static_cast<void*>((unsigned char*)pfile_view_ + distance);
}
void UnmapView(void) {
if (pfile_view_ != NULL) {
::UnmapViewOfFile(pfile_view_);
pfile_view_ = NULL;
}
}
void Close(void) {
UnmapView();
CloseMapping();
CloseFile();
}
ULONGLONG GetFileSize(void) {
DWORD size_high;
DWORD size_low = ::GetFileSize(file_, &size_high);
if (size_low == INVALID_FILE_SIZE && GetLastError != NO_ERROR) {
return 0;
}
return (((ULONGLONG)size_high) << 32) + size_low;
}
private:
DWORD GetAllocationGranularity(void) {
static DWORD glt = 0;
if (glt == 0) {
SYSTEM_INFO sys_info;
::GetSystemInfo(&sys_info);
glt = sys_info.dwAllocationGranularity;
}
return glt;
}
ULONGLONG GranularityCeil(ULONGLONG number, ULONGLONG granularity) {
assert(granularity != 0);
while (number % granularity != 0) {
++number;
}
return number;
}
ULONGLONG GranularityFloor(ULONGLONG number, ULONGLONG granularity) {
assert(granularity != 0);
while (number % granularity != 0) {
--number;
}
return number;
}
void CloseMapping(void) {
if (file_mapping_ != NULL) {
::CloseHandle(file_mapping_);
file_mapping_ = NULL;
}
}
void CloseFile(void) {
if (file_ != NULL) {
::CloseHandle(file_);
file_ = NULL;
}
}
HANDLE file_;
HANDLE file_mapping_;
PVOID pfile_view_;
}; //class FileMap
} //namespace ult
#endif