]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/fhandler_mem.cc
Remove unneeded header files from source files throughout.
[newlib-cygwin.git] / winsup / cygwin / fhandler_mem.cc
1 /* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes.
2
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include <unistd.h>
13
14 #include "cygerrno.h"
15 #include "security.h"
16 #include "path.h"
17 #include "fhandler.h"
18 #include "ntdll.h"
19
20 /**********************************************************************/
21 /* fhandler_dev_mem */
22
23 fhandler_dev_mem::fhandler_dev_mem ()
24 : fhandler_base ()
25 {
26 }
27
28 fhandler_dev_mem::~fhandler_dev_mem ()
29 {
30 }
31
32 int
33 fhandler_dev_mem::open (int flags, mode_t)
34 {
35 if (!wincap.has_physical_mem_access ())
36 {
37 set_errno (ENOENT);
38 debug_printf ("%s is accessible under NT4/W2K/XP only", dev ().name);
39 return 0;
40 }
41
42 if (dev () == FH_MEM) /* /dev/mem */
43 {
44 NTSTATUS ret;
45 SYSTEM_BASIC_INFORMATION sbi;
46 if ((ret = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi,
47 sizeof sbi, NULL)) != STATUS_SUCCESS)
48 {
49 __seterrno_from_nt_status (ret);
50 debug_printf("NtQuerySystemInformation: ret %d, Dos(ret) %E", ret);
51 mem_size = 0;
52 }
53 else
54 mem_size = sbi.PhysicalPageSize * sbi.NumberOfPhysicalPages;
55 debug_printf ("MemSize: %d MB", mem_size >> 20);
56 }
57 else if (dev () == FH_KMEM) /* /dev/kmem - Not yet supported */
58 {
59 mem_size = 0;
60 debug_printf ("KMemSize: %d MB", mem_size >> 20);
61 }
62 else if (dev () == FH_PORT) /* /dev/port == First 64K of /dev/mem */
63 {
64 mem_size = 65536;
65 debug_printf ("PortSize: 64 KB");
66 }
67 else
68 {
69 mem_size = 0;
70 debug_printf ("Illegal minor number!!!");
71 }
72
73 /* Check for illegal flags. */
74 if (flags & (O_APPEND | O_TRUNC | O_EXCL))
75 {
76 set_errno (EINVAL);
77 return 0;
78 }
79
80 UNICODE_STRING memstr;
81 RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory");
82
83 OBJECT_ATTRIBUTES attr;
84 InitializeObjectAttributes (&attr, &memstr,
85 OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
86 NULL, NULL);
87
88 ACCESS_MASK section_access;
89 if ((flags & O_ACCMODE) == O_RDONLY)
90 {
91 set_access (GENERIC_READ);
92 section_access = SECTION_MAP_READ;
93 }
94 else if ((flags & O_ACCMODE) == O_WRONLY)
95 {
96 set_access (GENERIC_WRITE);
97 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
98 }
99 else
100 {
101 set_access (GENERIC_READ | GENERIC_WRITE);
102 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
103 }
104
105 HANDLE mem;
106 NTSTATUS ret = NtOpenSection (&mem, section_access, &attr);
107 if (!NT_SUCCESS (ret))
108 {
109 __seterrno_from_nt_status (ret);
110 set_io_handle (NULL);
111 return 0;
112 }
113
114 set_io_handle (mem);
115 set_open_status ();
116 return 1;
117 }
118
119 int
120 fhandler_dev_mem::write (const void *ptr, size_t ulen)
121 {
122 if (!ulen || pos >= mem_size)
123 return 0;
124
125 if (!(get_access () & GENERIC_WRITE))
126 {
127 set_errno (EINVAL);
128 return -1;
129 }
130
131 if (pos + ulen > mem_size)
132 ulen = mem_size - pos;
133
134 PHYSICAL_ADDRESS phys;
135 NTSTATUS ret;
136 void *viewmem = NULL;
137 DWORD len = ulen + getsystempagesize () - 1;
138
139 phys.QuadPart = (ULONGLONG) pos;
140 if ((ret = NtMapViewOfSection (get_handle (),
141 INVALID_HANDLE_VALUE,
142 &viewmem,
143 0L,
144 len,
145 &phys,
146 &len,
147 ViewShare,
148 0,
149 PAGE_READONLY)) != STATUS_SUCCESS)
150 {
151 __seterrno_from_nt_status (ret);
152 return -1;
153 }
154
155 memcpy ((char *) viewmem + (pos - phys.QuadPart), ptr, ulen);
156
157 if (!NT_SUCCESS (ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
158 {
159 __seterrno_from_nt_status (ret);
160 return -1;
161 }
162
163 pos += ulen;
164 return ulen;
165 }
166
167 void __stdcall
168 fhandler_dev_mem::read (void *ptr, size_t& ulen)
169 {
170 if (!ulen || pos >= mem_size)
171 {
172 ulen = 0;
173 return;
174 }
175
176 if (!(get_access () & GENERIC_READ))
177 {
178 set_errno (EINVAL);
179 ulen = (size_t) -1;
180 return;
181 }
182
183 if (pos + ulen > mem_size)
184 ulen = mem_size - pos;
185
186 PHYSICAL_ADDRESS phys;
187 NTSTATUS ret;
188 void *viewmem = NULL;
189 DWORD len = ulen + getsystempagesize () - 1;
190
191 phys.QuadPart = (ULONGLONG) pos;
192 if ((ret = NtMapViewOfSection (get_handle (),
193 INVALID_HANDLE_VALUE,
194 &viewmem,
195 0L,
196 len,
197 &phys,
198 &len,
199 ViewShare,
200 0,
201 PAGE_READONLY)) != STATUS_SUCCESS)
202 {
203 __seterrno_from_nt_status (ret);
204 ulen = (size_t) -1;
205 return;
206 }
207
208 memcpy (ptr, (char *) viewmem + (pos - phys.QuadPart), ulen);
209
210 if (!NT_SUCCESS (ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
211 {
212 __seterrno_from_nt_status (ret);
213 ulen = (size_t) -1;
214 return;
215 }
216
217 pos += ulen;
218 }
219
220 _off64_t
221 fhandler_dev_mem::lseek (_off64_t offset, int whence)
222 {
223 switch (whence)
224 {
225 case SEEK_SET:
226 pos = offset;
227 break;
228
229 case SEEK_CUR:
230 pos += offset;
231 break;
232
233 case SEEK_END:
234 pos = mem_size;
235 pos += offset;
236 break;
237
238 default:
239 set_errno (EINVAL);
240 return ILLEGAL_SEEK;
241 }
242
243 if (pos > mem_size)
244 {
245 set_errno (EINVAL);
246 return ILLEGAL_SEEK;
247 }
248
249 return pos;
250 }
251
252 int
253 fhandler_dev_mem::fstat (struct __stat64 *buf)
254 {
255 fhandler_base::fstat (buf);
256 buf->st_blksize = getsystempagesize ();
257 if (is_auto_device ())
258 {
259 buf->st_mode = S_IFCHR;
260 if (wincap.has_physical_mem_access ())
261 buf->st_mode |= S_IRUSR | S_IWUSR |
262 S_IRGRP | S_IWGRP |
263 S_IROTH | S_IWOTH;
264 }
265
266 return 0;
267 }
268
269 int
270 fhandler_dev_mem::dup (fhandler_base *child)
271 {
272 int ret = fhandler_base::dup (child);
273
274 if (! ret)
275 {
276 fhandler_dev_mem *fhc = (fhandler_dev_mem *) child;
277
278 fhc->mem_size = mem_size;
279 fhc->pos = pos;
280 }
281 return ret;
282 }
This page took 0.047298 seconds and 5 git commands to generate.