1 /* fhandler_mem.cc. See fhandler.h for a description of the fhandler classes.
3 Copyright 1999, 2000 Cygnus Solutions.
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
23 * The following both data structures aren't defined anywhere in the Microsoft
24 * header files. Taken from the book "Windows NT/2000 Native API Reference"
27 typedef enum _SYSTEM_INFORMATION_CLASS {
28 SystemBasicInformation = 0
29 /* Dropped each other since not used here. */
30 } SYSTEM_INFORMATION_CLASS;
32 typedef struct _SYSTEM_BASIC_INFORMATION {
34 ULONG MaximumIncrement;
35 ULONG PhysicalPageSize;
36 ULONG NumberOfPhysicalPages;
37 ULONG LowestPhysicalPage;
38 ULONG HighestPhysicalPage;
39 ULONG AllocationGranularity;
40 ULONG LowestUserAddress;
41 ULONG HighestUserAddress;
42 ULONG ActiveProcessors;
43 ULONG NumberProcessors;
44 } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
47 NTSTATUS NTAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,ULONG,
48 PLARGE_INTEGER,PULONG,SECTION_INHERIT,
50 NTSTATUS NTAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,
52 NTSTATUS NTAPI NtOpenSection(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
53 NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE,PVOID);
54 VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
55 ULONG NTAPI RtlNtStatusToDosError(NTSTATUS);
58 /**********************************************************************/
59 /* fhandler_dev_mem */
61 fhandler_dev_mem::fhandler_dev_mem (const char *name, int nunit)
62 : fhandler_base (FH_MEM, name),
65 /* Reading physical memory only supported on NT/W2K. */
66 if (os_being_run != winNT)
72 if (unit == 1) /* /dev/mem */
75 SYSTEM_BASIC_INFORMATION sbi;
76 if ((ret = NtQuerySystemInformation (SystemBasicInformation, (PVOID) &sbi,
77 sizeof sbi, NULL)) != STATUS_SUCCESS)
79 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
80 debug_printf("NtQuerySystemInformation: ret = %d, Dos(ret) = %d",
81 ret, RtlNtStatusToDosError (ret));
85 mem_size = sbi.PhysicalPageSize * sbi.NumberOfPhysicalPages;
86 debug_printf ("MemSize: %d MB", mem_size >>= 20);
88 else if (unit == 2) /* /dev/kmem - Not yet supported */
91 debug_printf ("KMemSize: %d MB", mem_size >>= 20);
93 else if (unit == 4) /* /dev/port == First 64K of /dev/mem */
96 debug_printf ("PortSize: 64 KB");
101 debug_printf ("Illegal minor number!!!");
105 fhandler_dev_mem::~fhandler_dev_mem (void)
110 fhandler_dev_mem::open (const char *, int flags, mode_t)
112 if (os_being_run != winNT)
115 debug_printf ("%s is accessible under NT/W2K only",
116 unit == 1 ? "/dev/mem" :
117 unit == 2 ? "/dev/kmem" :
122 /* Check for illegal flags. */
123 if (flags & (O_APPEND | O_TRUNC | O_EXCL))
129 UNICODE_STRING memstr;
130 RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory");
132 OBJECT_ATTRIBUTES attr;
133 InitializeObjectAttributes(&attr, &memstr, OBJ_CASE_INSENSITIVE, NULL, NULL);
135 ACCESS_MASK section_access;
136 if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
138 set_access (GENERIC_READ);
139 section_access = SECTION_MAP_READ;
141 else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
143 set_access (GENERIC_WRITE);
144 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
148 set_access (GENERIC_READ | GENERIC_WRITE);
149 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
153 NTSTATUS ret = NtOpenSection (&mem, section_access, &attr);
154 if (!NT_SUCCESS(ret))
156 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
157 set_io_handle (NULL);
166 fhandler_dev_mem::write (const void *ptr, size_t ulen)
168 if (!ulen || pos >= mem_size)
171 if (!(get_access () & GENERIC_WRITE))
177 if (pos + ulen > mem_size)
178 ulen = mem_size - pos;
180 PHYSICAL_ADDRESS phys;
182 void *viewmem = NULL;
183 DWORD len = ulen + getpagesize () - 1;
185 phys.QuadPart = (ULONGLONG) pos;
186 if ((ret = NtMapViewOfSection (get_handle (),
187 INVALID_HANDLE_VALUE,
195 PAGE_READONLY)) != STATUS_SUCCESS)
197 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
201 memcpy ((char *) viewmem + (pos - phys.QuadPart), ptr, ulen);
203 if (!NT_SUCCESS(ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
205 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
214 fhandler_dev_mem::read (void *ptr, size_t ulen)
216 if (!ulen || pos >= mem_size)
219 if (!(get_access () & GENERIC_READ))
225 if (pos + ulen > mem_size)
226 ulen = mem_size - pos;
228 PHYSICAL_ADDRESS phys;
230 void *viewmem = NULL;
231 DWORD len = ulen + getpagesize () - 1;
233 phys.QuadPart = (ULONGLONG) pos;
234 if ((ret = NtMapViewOfSection (get_handle (),
235 INVALID_HANDLE_VALUE,
243 PAGE_READONLY)) != STATUS_SUCCESS)
245 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
249 memcpy (ptr, (char *) viewmem + (pos - phys.QuadPart), ulen);
251 if (!NT_SUCCESS(ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
253 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
262 fhandler_dev_mem::close (void)
264 return fhandler_base::close ();
268 fhandler_dev_mem::lseek (off_t offset, int whence)
300 fhandler_dev_mem::mmap (caddr_t *addr, size_t len, DWORD access,
301 int flags, off_t off)
303 if ((DWORD) off >= mem_size
304 || (DWORD) len >= mem_size
305 || (DWORD) off + len >= mem_size)
308 syscall_printf ("-1 = mmap(): illegal parameter, set EINVAL");
309 return INVALID_HANDLE_VALUE;
312 UNICODE_STRING memstr;
313 RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory");
315 OBJECT_ATTRIBUTES attr;
316 InitializeObjectAttributes(&attr, &memstr, OBJ_CASE_INSENSITIVE, NULL, NULL);
318 ACCESS_MASK section_access;
321 if (access & FILE_MAP_COPY)
323 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
324 protect = PAGE_WRITECOPY;
326 else if (access & FILE_MAP_WRITE)
328 section_access = SECTION_MAP_READ | SECTION_MAP_WRITE;
329 protect = PAGE_READWRITE;
333 section_access = SECTION_MAP_READ;
334 protect = PAGE_READONLY;
338 NTSTATUS ret = NtOpenSection (&h, section_access, &attr);
339 if (!NT_SUCCESS(ret))
341 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
342 syscall_printf ("-1 = mmap(): NtOpenSection failed with %E");
343 return INVALID_HANDLE_VALUE;
346 PHYSICAL_ADDRESS phys;
350 phys.QuadPart = (ULONGLONG) off;
352 if ((ret = NtMapViewOfSection (h,
353 INVALID_HANDLE_VALUE,
361 protect)) != STATUS_SUCCESS)
363 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
364 syscall_printf ("-1 = mmap(): NtMapViewOfSection failed with %E");
365 return INVALID_HANDLE_VALUE;
367 if ((flags & MAP_FIXED) && base != addr)
370 syscall_printf ("-1 = mmap(): address shift with MAP_FIXED given");
371 NtUnmapViewOfSection (INVALID_HANDLE_VALUE, base);
372 return INVALID_HANDLE_VALUE;
375 *addr = (caddr_t) base;
380 fhandler_dev_mem::munmap (HANDLE h, caddr_t addr, size_t len)
383 if (!NT_SUCCESS(ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, addr)))
385 __seterrno_from_win_error (RtlNtStatusToDosError (ret));
393 fhandler_dev_mem::msync (HANDLE h, caddr_t addr, size_t len, int flags)
399 fhandler_dev_mem::fstat (struct stat *buf)
407 memset (buf, 0, sizeof *buf);
408 buf->st_mode = S_IFCHR;
409 if (os_being_run != winNT)
410 buf->st_mode |= S_IRUSR | S_IWUSR |
414 buf->st_blksize = getpagesize ();
415 buf->st_dev = buf->st_rdev = get_device () << 8 | (unit & 0xff);
421 fhandler_dev_mem::dup (fhandler_base *child)
423 int ret = fhandler_base::dup (child);
427 fhandler_dev_mem *fhc = (fhandler_dev_mem *) child;
429 fhc->mem_size = mem_size;
436 fhandler_dev_mem::dump ()
438 paranoid_printf("here, fhandler_dev_mem");
443 LoadDLLinitfunc (ntdll)
446 static NO_COPY LONG here = -1L;
448 while (InterlockedIncrement (&here))
450 InterlockedDecrement (&here);
451 small_printf ("Multiple tries to read ntdll.dll\n");
457 else if ((h = LoadLibrary ("ntdll.dll")) != NULL)
459 else if (!ntdll_handle)
460 api_fatal ("could not load ntdll.dll, %E");
462 InterlockedDecrement (&here);
466 static void dummy_autoload (void) __attribute__ ((unused));
468 dummy_autoload (void)
471 LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
472 LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
473 LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
474 LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
475 LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
476 LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)