OSDN Git Service

* fhandler_mem.cc: Load ntdll functions via autoload method.
[pf3gnuchains/pf3gnuchains3x.git] / winsup / cygwin / fhandler_mem.cc
1 /* fhandler_mem.cc.  See fhandler.h for a description of the fhandler classes.
2
3    Copyright 1999, 2000 Cygnus Solutions.
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 <sys/termios.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <ntdef.h>
17
18 #include "autoload.h"
19 #include "cygheap.h"
20 #include "cygerrno.h"
21 #include "fhandler.h"
22 #include "path.h"
23
24 extern "C" {
25 NTSTATUS NTAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,ULONG,
26                                       PLARGE_INTEGER,PULONG,SECTION_INHERIT,
27                                       ULONG,ULONG);
28 NTSTATUS NTAPI NtOpenSection(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
29 NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE,PVOID);
30 VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
31 ULONG NTAPI RtlNtStatusToDosError(NTSTATUS);
32 }
33
34 /**********************************************************************/
35 /* fhandler_dev_mem */
36
37 fhandler_dev_mem::fhandler_dev_mem (const char *name, int)
38 : fhandler_base (FH_MEM, name),
39   pos(0UL)
40 {
41 }
42
43 fhandler_dev_mem::~fhandler_dev_mem (void)
44 {
45 }
46
47 int
48 fhandler_dev_mem::open (const char *, int flags, mode_t)
49 {
50   if (os_being_run != winNT)
51     {
52       set_errno (ENOENT);
53       debug_printf ("/dev/mem is accessible under NT/W2K only");
54       return 0;
55     }
56
57   UNICODE_STRING memstr;
58   RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory");
59
60   OBJECT_ATTRIBUTES attr;
61   InitializeObjectAttributes(&attr, &memstr, OBJ_CASE_INSENSITIVE, NULL, NULL);
62
63   if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY)
64     set_access (SECTION_MAP_READ);
65   else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY)
66     set_access (SECTION_MAP_WRITE);
67   else
68     set_access (SECTION_MAP_READ | SECTION_MAP_WRITE);
69
70   HANDLE mem;
71   NTSTATUS ret = NtOpenSection (&mem, get_access (), &attr);
72   if (!NT_SUCCESS(ret))
73     {
74       __seterrno_from_win_error (RtlNtStatusToDosError (ret));
75       set_io_handle (NULL);
76       return 0;
77     }
78
79   set_io_handle (mem);
80   return 1;
81 }
82
83 int
84 fhandler_dev_mem::write (const void *ptr, size_t len)
85 {
86   set_errno (ENOSYS);
87   return -1;
88 }
89
90 int
91 fhandler_dev_mem::read (void *ptr, size_t ulen)
92 {
93   if (!ulen)
94     return 0;
95
96   PHYSICAL_ADDRESS phys;
97   NTSTATUS ret;
98   void *viewmem = NULL;
99   DWORD len = ulen + 4095;
100
101   phys.QuadPart = (ULONGLONG) pos;
102   if ((ret = NtMapViewOfSection (get_handle (),
103                                  INVALID_HANDLE_VALUE,
104                                  &viewmem,
105                                  0L,
106                                  len,
107                                  &phys,
108                                  &len,
109                                  ViewShare,
110                                  0,
111                                  PAGE_READONLY)) != STATUS_SUCCESS)
112     {
113       __seterrno_from_win_error (RtlNtStatusToDosError (ret));
114       return -1;
115     }
116
117   memcpy (ptr, (char *) viewmem + (pos - phys.QuadPart), ulen);
118
119   if (!NT_SUCCESS(ret = NtUnmapViewOfSection (INVALID_HANDLE_VALUE, viewmem)))
120     {
121       __seterrno_from_win_error (RtlNtStatusToDosError (ret));
122       return -1;
123     }
124
125   pos += ulen;
126
127   return ulen;
128 }
129
130 int
131 fhandler_dev_mem::close (void)
132 {
133   return fhandler_base::close ();
134 }
135
136 off_t
137 fhandler_dev_mem::lseek (off_t offset, int whence)
138 {
139   switch (whence)
140     {
141     case SEEK_SET:
142       pos = offset;
143       break;
144     
145     case SEEK_CUR:
146       pos += offset;
147       break;
148
149     case SEEK_END:
150       pos = 0;
151       pos -= offset;
152       break;
153     
154     default:
155       set_errno (EINVAL);
156       return (off_t) -1;
157     }
158
159   return pos;
160 }
161
162 int
163 fhandler_dev_mem::fstat (struct stat *buf)
164 {
165   if (!buf)
166     {
167       set_errno (EINVAL);
168       return -1;
169     }
170
171   memset (buf, 0, sizeof *buf);
172   buf->st_mode = S_IFCHR;
173   if (os_being_run != winNT)
174     buf->st_mode |= S_IRUSR | S_IWUSR |
175                     S_IRGRP | S_IWGRP |
176                     S_IROTH | S_IWOTH;
177   buf->st_nlink = 1;
178   buf->st_blksize = 4096;
179   buf->st_dev = buf->st_rdev = get_device () << 8;
180
181   return 0;
182 }
183
184 int
185 fhandler_dev_mem::dup (fhandler_base *child)
186 {
187   set_errno (ENOSYS);
188   return -1;
189 }
190
191 void
192 fhandler_dev_mem::dump ()
193 {
194   paranoid_printf("here, fhandler_dev_mem");
195 }
196
197 extern "C" {
198
199 LoadDLLinitfunc (ntdll)
200 {
201   HANDLE h;
202   static NO_COPY LONG here = -1L;
203
204   while (InterlockedIncrement (&here))
205     {
206       InterlockedDecrement (&here);
207 small_printf ("Multiple tries to read ntdll.dll\n");
208       Sleep (0);
209     }
210
211   if (ntdll_handle)
212     /* nothing to do */;
213   else if ((h = LoadLibrary ("ntdll.dll")) != NULL)
214     ntdll_handle = h;
215   else if (!ntdll_handle)
216     api_fatal ("could not load ntdll.dll, %E");
217
218   InterlockedDecrement (&here);
219   return 0;
220 }
221
222 static void dummy_autoload (void) __attribute__ ((unused));
223 static void
224 dummy_autoload (void)
225 {
226 LoadDLLinit (ntdll)
227 LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
228 LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
229 LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
230 LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
231 LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
232 }
233 }