Convert to unix line endings.
[wincetools.git] / loader / server_mapping.c
1 /* From wine1.2-1.1.42/server/mapping.c  */
2
3 /*
4  * Server-side file mapping management
5  *
6  * Copyright (C) 1999 Alexandre Julliard
7  * Copyright 2010 g10 Code GmbH
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #include "wine.h"
25 #include <assert.h>
26
27 /* These are always the same.  */
28 # define page_mask  0xfff
29 # define page_shift 12
30 # define init_page_size() do { /* nothing */ } while(0)
31
32 #define set_error(x) SetLastError(x)
33
34 #define ROUND_SIZE(size)  (((size) + page_mask) & ~page_mask)
35
36
37
38 struct mapping
39 {
40   void           *obj;
41   mem_size_t      size;            /* mapping size */
42   int             protect;         /* protection flags */
43   HANDLE         *fhnd;             /* handle for file */
44   HANDLE         *hnd;             /* handle for mapped file */
45   int             header_size;     /* size of headers (for PE image mapping) */
46   void           *base;            /* default base addr (for PE image mapping) */
47 };
48
49
50
51 /* retrieve the mapping parameters for an executable (PE) image */
52 static int get_image_params( struct mapping *mapping, HANDLE unix_fd )
53 {
54   IMAGE_DOS_HEADER dos;
55   IMAGE_SECTION_HEADER *sec = NULL;
56   struct
57   {
58     DWORD Signature;
59     IMAGE_FILE_HEADER FileHeader;
60     union
61     {
62       IMAGE_OPTIONAL_HEADER32 hdr32;
63       IMAGE_OPTIONAL_HEADER64 hdr64;
64     } opt;
65   } nt;
66   off_t pos;
67   int size;
68
69     /* load the headers */
70
71     if (pread( unix_fd, (char *) &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;
72     if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;
73     pos = dos.e_lfanew;
74
75     size = pread( unix_fd, (char *) &nt, sizeof(nt), pos );
76     if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) goto error;
77     /* zero out Optional header in the case it's not present or partial */
78     if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );
79     if (nt.Signature != IMAGE_NT_SIGNATURE) goto error;
80
81     switch (nt.opt.hdr32.Magic)
82       {
83       case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
84         mapping->size        = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
85         mapping->base        = (void *) nt.opt.hdr32.ImageBase;
86         mapping->header_size = nt.opt.hdr32.SizeOfHeaders;
87         break;
88       case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
89         mapping->size        = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
90         mapping->base        = (void *) nt.opt.hdr64.ImageBase;
91         mapping->header_size = nt.opt.hdr64.SizeOfHeaders;
92         break;
93       default:
94         goto error;
95       }
96
97     /* load the section headers */
98
99     pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;
100     size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
101     if (pos + size > mapping->size) goto error;
102     if (pos + size > mapping->header_size) mapping->header_size = pos + size;
103     if (!(sec = malloc( size ))) goto error;
104     if (pread( unix_fd, (void *) sec, size, pos ) != size) goto error;
105
106     // if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error;
107
108     // if (mapping->shared_file) list_add_head( &shared_list, &mapping->shared_entry );
109
110     mapping->protect = VPROT_IMAGE;
111     free( sec );
112     return 1;
113
114  error:
115     free( sec );
116     set_error( STATUS_INVALID_FILE_FOR_SECTION );
117     return 0;
118 }
119
120
121 void *create_mapping(/* struct directory *root */ void *root,
122                      /* const struct unicode_str *name */ void *name,
123                      unsigned int attr, mem_size_t size, int protect,
124                      HANDLE handle, /* const struct security_descriptor *sd */ void *sd)
125 {
126   struct mapping *mapping;
127 #if 0
128   struct file *file;
129   struct fd *fd;
130 #endif
131   int access = 0;
132 #if 0
133   int unix_fd;
134 #endif
135
136   if (!page_mask) init_page_size();
137
138   if (!(mapping = malloc (sizeof (struct mapping))))
139     return NULL;
140
141   mapping->obj         = NULL;
142   mapping->header_size = 0;
143   mapping->base        = 0;
144   mapping->fhnd        = handle;
145   mapping->hnd         = 0;
146
147   if (protect & VPROT_READ) access |= FILE_READ_DATA;
148   if (protect & VPROT_WRITE) access |= FILE_WRITE_DATA;
149
150   if (handle)
151     {
152       // unsigned int mapping_access = FILE_MAPPING_ACCESS;
153
154       if (!(protect & VPROT_COMMITTED))
155         {
156           SetLastError( STATUS_INVALID_PARAMETER );
157           goto error;
158         }
159     
160       mapping->hnd = CreateFileMapping (handle, NULL, get_prot_flags (protect),
161                                         0, size, NULL);
162       if (mapping->hnd == INVALID_HANDLE_VALUE)
163         goto error;
164
165 #if 0
166       /* file sharing rules for mappings are different so we use magic the access rights */
167       if (protect & VPROT_IMAGE) mapping_access |= FILE_MAPPING_IMAGE;
168       else if (protect & VPROT_WRITE) mapping_access |= FILE_MAPPING_WRITE;
169 #endif
170
171       if (protect & VPROT_IMAGE)
172         {
173           if (!get_image_params( mapping, handle )) goto error;
174           return &mapping->obj;
175         }
176 #if 0
177       if (fstat( unix_fd, &st ) == -1)
178         {
179           file_set_error();
180           goto error;
181         }
182       if (!size)
183         {
184           if (!(size = st.st_size))
185             {
186               set_error( STATUS_MAPPED_FILE_SIZE_ZERO );
187               goto error;
188             }
189         }
190       else if (st.st_size < size && !grow_file( unix_fd, size )) goto error;
191 #endif
192     }
193   else  /* Anonymous mapping (no associated file) */
194     {
195 #if 0
196       if (!size || (protect & VPROT_IMAGE))
197         {
198           set_error( STATUS_INVALID_PARAMETER );
199           goto error;
200         }
201       if (!(protect & VPROT_COMMITTED))
202         {
203           if (!(mapping->committed = mem_alloc( offsetof(struct ranges, ranges[8]) ))) goto error;
204           mapping->committed->count = 0;
205           mapping->committed->max   = 8;
206         }
207       if ((unix_fd = create_temp_file( size )) == -1) goto error;
208       if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj,
209                                                FILE_SYNCHRONOUS_IO_NONALERT ))) goto error;
210 #endif
211       assert (!"Not implemented.");
212     }
213   mapping->size    = (size + page_mask) & ~((mem_size_t)page_mask);
214   mapping->protect = protect;
215   return &mapping->obj;
216   
217  error:
218   free( mapping );
219   return NULL;
220 }
221
222
223 /* create a file mapping */
224 NTSTATUS SERVER_create_mapping (ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
225                                 HANDLE file_handle, long long size, unsigned int protect, HANDLE *handle)
226 {
227   void *obj;
228   
229   *handle = 0;
230
231   obj = create_mapping( NULL, NULL, 0, (mem_size_t) size, protect, file_handle, NULL );
232   if (! obj)
233     return GetLastError ();
234
235   *handle = (HANDLE)obj;
236
237   return STATUS_SUCCESS;
238 }
239
240
241 NTSTATUS SERVER_get_mapping_info (HANDLE _mapping, ACCESS_MASK access, unsigned int *protect,
242                                   void **base, mem_size_t *size, int *header_size, HANDLE *fhandle,
243                                   HANDLE *handle)
244 {
245   struct mapping *mapping = (struct mapping *) _mapping;
246
247   /* Ignore access.  */
248
249   *size        = mapping->size;
250   *protect     = mapping->protect;
251   *fhandle     = mapping->fhnd;
252   *handle      = mapping->hnd;
253   *header_size = mapping->header_size;
254   *base        = mapping->base;
255
256   return STATUS_SUCCESS;
257 }
258