1 /* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes.
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 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 UNICODE_STRING memstr
;
81 RtlInitUnicodeString (&memstr
, L
"\\device\\physicalmemory");
83 OBJECT_ATTRIBUTES attr
;
84 InitializeObjectAttributes (&attr
, &memstr
,
85 OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
,
88 ACCESS_MASK section_access
;
89 if ((flags
& O_ACCMODE
) == O_RDONLY
)
91 set_access (GENERIC_READ
);
92 section_access
= SECTION_MAP_READ
;
94 else if ((flags
& O_ACCMODE
) == O_WRONLY
)
96 set_access (GENERIC_WRITE
);
97 section_access
= SECTION_MAP_READ
| SECTION_MAP_WRITE
;
101 set_access (GENERIC_READ
| GENERIC_WRITE
);
102 section_access
= SECTION_MAP_READ
| SECTION_MAP_WRITE
;
106 NTSTATUS ret
= NtOpenSection (&mem
, section_access
, &attr
);
107 if (!NT_SUCCESS (ret
))
109 __seterrno_from_nt_status (ret
);
110 set_io_handle (NULL
);
120 fhandler_dev_mem::write (const void *ptr
, size_t ulen
)
122 if (!ulen
|| pos
>= mem_size
)
125 if (!(get_access () & GENERIC_WRITE
))
131 if (pos
+ ulen
> mem_size
)
132 ulen
= mem_size
- pos
;
134 PHYSICAL_ADDRESS phys
;
136 void *viewmem
= NULL
;
137 DWORD len
= ulen
+ getsystempagesize () - 1;
139 phys
.QuadPart
= (ULONGLONG
) pos
;
140 if ((ret
= NtMapViewOfSection (get_handle (),
141 INVALID_HANDLE_VALUE
,
149 PAGE_READONLY
)) != STATUS_SUCCESS
)
151 __seterrno_from_nt_status (ret
);
155 memcpy ((char *) viewmem
+ (pos
- phys
.QuadPart
), ptr
, ulen
);
157 if (!NT_SUCCESS (ret
= NtUnmapViewOfSection (INVALID_HANDLE_VALUE
, viewmem
)))
159 __seterrno_from_nt_status (ret
);
168 fhandler_dev_mem::read (void *ptr
, size_t& ulen
)
170 if (!ulen
|| pos
>= mem_size
)
176 if (!(get_access () & GENERIC_READ
))
183 if (pos
+ ulen
> mem_size
)
184 ulen
= mem_size
- pos
;
186 PHYSICAL_ADDRESS phys
;
188 void *viewmem
= NULL
;
189 DWORD len
= ulen
+ getsystempagesize () - 1;
191 phys
.QuadPart
= (ULONGLONG
) pos
;
192 if ((ret
= NtMapViewOfSection (get_handle (),
193 INVALID_HANDLE_VALUE
,
201 PAGE_READONLY
)) != STATUS_SUCCESS
)
203 __seterrno_from_nt_status (ret
);
208 memcpy (ptr
, (char *) viewmem
+ (pos
- phys
.QuadPart
), ulen
);
210 if (!NT_SUCCESS (ret
= NtUnmapViewOfSection (INVALID_HANDLE_VALUE
, viewmem
)))
212 __seterrno_from_nt_status (ret
);
221 fhandler_dev_mem::lseek (_off64_t offset
, int whence
)
253 fhandler_dev_mem::fstat (struct __stat64
*buf
)
255 fhandler_base::fstat (buf
);
256 buf
->st_blksize
= getsystempagesize ();
257 if (is_auto_device ())
259 buf
->st_mode
= S_IFCHR
;
260 if (wincap
.has_physical_mem_access ())
261 buf
->st_mode
|= S_IRUSR
| S_IWUSR
|
270 fhandler_dev_mem::dup (fhandler_base
*child
)
272 int ret
= fhandler_base::dup (child
);
276 fhandler_dev_mem
*fhc
= (fhandler_dev_mem
*) child
;
278 fhc
->mem_size
= mem_size
;