1 /**
2 * plat_mmap_windows.c
3 *
4 * Copyright (c) 2005, 2006, 2010, 2012-2014
5 * libchewing Core Team. See ChangeLog for details.
6 *
7 * See the file "COPYING" for information on usage and redistribution
8 * of this file.
9 */
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15 #if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
16
17 # include "plat_mmap.h"
18
19 /* set the mmap handle an invalid value */
plat_mmap_set_invalid(plat_mmap * handle)20 void plat_mmap_set_invalid(plat_mmap *handle)
21 {
22 /* check error(s) */
23 if (!handle)
24 return;
25
26 handle->fd_file = NULL;
27 handle->address = NULL;
28 handle->fd_map = NULL;
29 handle->fAccessAttr = 0;
30 }
31
32 /* verify if the mmap handle is valid */
plat_mmap_is_valid(plat_mmap * handle)33 int plat_mmap_is_valid(plat_mmap *handle)
34 {
35 /* check error(s) */
36 if (!handle)
37 return 0;
38
39 return (int) (handle->fd_map != NULL);
40 }
41
42 /* map a file into system meory, return the file size */
plat_mmap_create(plat_mmap * handle,const char * file,int fileAccessAttr)43 size_t plat_mmap_create(plat_mmap *handle, const char *file, int fileAccessAttr)
44 {
45 LARGE_INTEGER sizet;
46
47 /* check error(s) */
48 if (!handle)
49 return 0;
50
51 handle->fd_map = NULL;
52 handle->address = NULL;
53
54 if (FLAG_ATTRIBUTE_READ & fileAccessAttr) {
55 # ifdef _WIN32_WCE
56 handle->fd_file = CreateFileForMappingA(file,
57 GENERIC_READ,
58 FILE_SHARE_READ, NULL,
59 OPEN_EXISTING,
60 FILE_ATTRIBUTE_NORMAL, NULL);
61 # else /* !_WIN32_WCE */
62 handle->fd_file = CreateFileA(file,
63 GENERIC_READ,
64 FILE_SHARE_READ,
65 NULL, OPEN_EXISTING,
66 FILE_ATTRIBUTE_READONLY |
67 FILE_FLAG_RANDOM_ACCESS, 0);
68 # endif /* _WIN32_WCE */
69
70 if (INVALID_HANDLE_VALUE == handle->fd_file)
71 return 0;
72
73 sizet.LowPart = GetFileSize(handle->fd_file,
74 (LPDWORD) & sizet.HighPart);
75 handle->fd_map = CreateFileMappingA(handle->fd_file, NULL,
76 PAGE_READONLY,
77 sizet.HighPart, sizet.LowPart, 0);
78 } else {
79 # ifdef _WIN32_WCE
80 handle->fd_file = CreateFileForMappingA(file,
81 GENERIC_WRITE | GENERIC_READ,
82 FILE_SHARE_WRITE, NULL,
83 CREATE_ALWAYS,
84 FILE_ATTRIBUTE_NORMAL, NULL);
85 # else /* !_WIN32_WCE */
86 handle->fd_file = CreateFileA(file,
87 GENERIC_WRITE | GENERIC_READ,
88 FILE_SHARE_WRITE, NULL,
89 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
90 # endif /* _WIN32_WCE */
91
92 if (INVALID_HANDLE_VALUE == handle->fd_file)
93 return 0;
94
95 sizet.LowPart = 0;
96 sizet.HighPart = 1;
97 handle->fd_map = CreateFileMapping(handle->fd_file, NULL,
98 PAGE_READWRITE, 0,
99 sizet.LowPart, 0);
100 sizet.LowPart = 1024 * 1024 * 1024;
101 sizet.HighPart = 0;
102
103 while (!handle->fd_map) {
104 DWORD error;
105
106 handle->fd_map = CreateFileMapping(handle->fd_file, NULL,
107 PAGE_READWRITE, 0,
108 sizet.LowPart, 0);
109 error = GetLastError();
110
111 if (ERROR_NOT_ENOUGH_MEMORY == error || ERROR_DISK_FULL == error)
112 sizet.LowPart /= 2;
113 else
114 break;
115 }
116 }
117
118 handle->fAccessAttr = fileAccessAttr;
119
120 if (FLAG_ATTRIBUTE_READ & fileAccessAttr ||
121 16 * 1024 * 1024 <= sizet.LowPart) {
122 if (handle->fd_map)
123 return (size_t) sizet.QuadPart;
124 }
125
126 plat_mmap_close(handle);
127
128 return 0;
129 }
130
131 /* obtain the a view of the mapped file */
plat_mmap_set_view(plat_mmap * handle,size_t * offset,size_t * sizet)132 void *plat_mmap_set_view(plat_mmap *handle, size_t * offset, size_t * sizet)
133 {
134 LARGE_INTEGER t_offset;
135 LARGE_INTEGER t_sizet;
136 SYSTEM_INFO info;
137 size_t pagesize;
138 size_t edge;
139
140 /* check error(s) */
141 if (!handle)
142 return NULL;
143
144 if (handle->address)
145 UnmapViewOfFile(handle->address);
146
147 GetSystemInfo(&info);
148 pagesize = info.dwAllocationGranularity;
149
150 edge = (*sizet) + (*offset);
151 t_offset.QuadPart = (*offset) = (size_t) ((*offset) / pagesize) * pagesize;
152
153 t_sizet.QuadPart = (*sizet) = edge - (*offset);
154
155 if (FLAG_ATTRIBUTE_READ & handle->fAccessAttr) {
156 handle->address = MapViewOfFile(handle->fd_map,
157 FILE_MAP_READ,
158 t_offset.HighPart,
159 t_offset.LowPart, t_sizet.LowPart);
160 } else {
161 handle->address = MapViewOfFile(handle->fd_map,
162 FILE_MAP_WRITE,
163 t_offset.HighPart,
164 t_offset.LowPart, t_sizet.LowPart);
165 }
166
167 return handle->address;
168 }
169
170 /* close the mmap */
plat_mmap_close(plat_mmap * handle)171 void plat_mmap_close(plat_mmap *handle)
172 {
173 /* check error(s) */
174 if (!handle)
175 return;
176
177 if (handle->address) {
178 UnmapViewOfFile(handle->address);
179 handle->address = NULL;
180 }
181
182 if (handle->fd_map) {
183 CloseHandle(handle->fd_map);
184 handle->fd_map = NULL;
185 }
186
187 if (INVALID_HANDLE_VALUE != handle->fd_file) {
188 CloseHandle(handle->fd_file);
189 handle->fd_file = INVALID_HANDLE_VALUE;
190 }
191 }
192
193 /* return page size*/
plat_mmap_get_page_size()194 unsigned int plat_mmap_get_page_size()
195 {
196 SYSTEM_INFO info;
197
198 GetSystemInfo(&info);
199 return info.dwPageSize;
200 }
201
plat_mmap_get_alloc_granularity()202 unsigned int plat_mmap_get_alloc_granularity()
203 {
204 SYSTEM_INFO info;
205
206 GetSystemInfo(&info);
207 return info.dwAllocationGranularity;
208 }
209
plat_mmap_unmap(plat_mmap * handle)210 void plat_mmap_unmap(plat_mmap *handle)
211 {
212 /* check error(s) */
213 if (!handle)
214 return;
215
216 if (handle->address) {
217 UnmapViewOfFile(handle->address);
218 handle->address = NULL;
219 }
220 }
221
222 #endif /* defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) */
223