1 /* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes.
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009,
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
20 /**********************************************************************/
21 /* fhandler_dev_mem */
23 fhandler_dev_mem::fhandler_dev_mem ()
28 fhandler_dev_mem::~fhandler_dev_mem ()
33 fhandler_dev_mem::open (int flags, mode_t)
35 if (!wincap.has_physical_mem_access ())
38 debug_printf ("%s is accessible under NT4/W2K/XP only", dev ().name);
42 if (dev () == FH_MEM) /* /dev/mem */
45 SYSTEM_BASIC_INFORMATION sbi;
46 if ((ret = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi,
47 sizeof sbi, NULL)) != STATUS_SUCCESS)
49 __seterrno_from_nt_status (ret);
50 debug_printf("NtQuerySystemInformation: ret %d, Dos(ret) %E", ret);
54 mem_size = sbi.PhysicalPageSize * sbi.NumberOfPhysicalPages;
55 debug_printf ("MemSize: %d MB", mem_size >> 20);
57 else if (dev () == FH_KMEM) /* /dev/kmem - Not yet supported */
60 debug_printf ("KMemSize: %d MB", mem_size >> 20);
62 else if (dev () == FH_PORT) /* /dev/port == First 64K of /dev/mem */
65 debug_printf ("PortSize: 64 KB");
70 debug_printf ("Illegal minor number!!!");
73 /* Check for illegal flags. */
74 if (flags & (O_APPEND | O_TRUNC | O_EXCL))
80 OBJECT_ATTRIBUTES attr;
81 InitializeObjectAttributes (&attr, &ro_u_pmem,
83 | (flags & O_CLOEXEC ? 0 : OBJ_INHERIT),
86 ACCESS_MASK section_access;
87 if ((flags & O_ACCMODE) == O_RDONLY)
89 set_access (GENERIC_READ);
90 section_access = SECTION_MAP_READ;
92 else if ((flags & O_ACCMODE) == O_WRONLY)
94 set_access (GENERIC_WRITE);
95 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
99 set_access (GENERIC_READ | GENERIC_WRITE);
100 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
104 NTSTATUS ret = NtOpenSection (&mem, section_access, &attr);
105 if (!NT_SUCCESS (ret))
107 __seterrno_from_nt_status (ret);
108 set_io_handle (NULL);
118 fhandler_dev_mem::write (const void *ptr, size_t ulen)
120 if (!ulen || pos >= mem_size)
123 if (!(get_access () & GENERIC_WRITE))
129 if (pos + ulen > mem_size)
130 ulen = mem_size - pos;
132 PHYSICAL_ADDRESS phys;
134 void *viewmem = NULL;
135 DWORD len = ulen + getsystempagesize () - 1;
137 phys.QuadPart = (ULONGLONG) pos;
138 if ((ret = NtMapViewOfSection (get_handle (),
139 INVALID_HANDLE_VALUE,
147 PAGE_READONLY)) != STATUS_SUCCESS)
149 __seterrno_from_nt_status (ret);
153 memcpy ((char *) viewmem + (pos - phys.QuadPart), ptr, ulen);
155 if (!NT_SUCCESS (ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
157 __seterrno_from_nt_status (ret);
166 fhandler_dev_mem::read (void *ptr, size_t& ulen)
168 if (!ulen || pos >= mem_size)
174 if (!(get_access () & GENERIC_READ))
181 if (pos + ulen > mem_size)
182 ulen = mem_size - pos;
184 PHYSICAL_ADDRESS phys;
186 void *viewmem = NULL;
187 DWORD len = ulen + getsystempagesize () - 1;
189 phys.QuadPart = (ULONGLONG) pos;
190 if ((ret = NtMapViewOfSection (get_handle (),
191 INVALID_HANDLE_VALUE,
199 PAGE_READONLY)) != STATUS_SUCCESS)
201 __seterrno_from_nt_status (ret);
206 memcpy (ptr, (char *) viewmem + (pos - phys.QuadPart), ulen);
208 if (!NT_SUCCESS (ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
210 __seterrno_from_nt_status (ret);
219 fhandler_dev_mem::lseek (_off64_t offset, int whence)
251 fhandler_dev_mem::fstat (struct __stat64 *buf)
253 fhandler_base::fstat (buf);
254 buf->st_blksize = getsystempagesize ();
255 if (is_auto_device ())
257 buf->st_mode = S_IFCHR;
258 if (wincap.has_physical_mem_access ())
259 buf->st_mode |= S_IRUSR | S_IWUSR |
268 fhandler_dev_mem::dup (fhandler_base *child)
270 int ret = fhandler_base::dup (child);
274 fhandler_dev_mem *fhc = (fhandler_dev_mem *) child;
276 fhc->mem_size = mem_size;