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