Fix bugs in last change.
[wincetools.git] / loader / ntdll_virtual.c
1 /* From wine1.2-1.1.42/dlls/ntdll/virtual.c  */
2
3 /*
4  * Win32 virtual memory functions
5  *
6  * Copyright 1997, 2002 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
25 #include <windows.h>
26 #include <assert.h>
27
28 #include "himemce.h"
29
30 /* File view */
31 typedef struct file_view
32 {
33     void         *base;        /* Base address */
34     size_t        size;        /* Size in bytes */
35     HANDLE        mapping;     /* Handle to the file mapping */
36     unsigned int  protect;     /* Protection for all pages at allocation time */
37 } FILE_VIEW;
38
39
40 # define page_mask  0xfff
41 # define page_shift 12
42 # define page_size  0x1000
43
44
45 #define ROUND_SIZE(addr,size) \
46   (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
47
48
49 static size_t get_mask( ULONG zero_bits )
50 {
51   if (!zero_bits) return 0xffff;  /* allocations are aligned to 64K by default */
52   if (zero_bits < page_shift) zero_bits = page_shift;
53   return (1 << zero_bits) - 1;
54 }
55
56
57 static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot )
58 {
59   switch(protect & 0xff)
60     {
61     case PAGE_READONLY:
62       *vprot = VPROT_READ;
63       break;
64     case PAGE_READWRITE:
65       *vprot = VPROT_READ | VPROT_WRITE;
66       break;
67     case PAGE_WRITECOPY:
68       *vprot = VPROT_READ | VPROT_WRITECOPY;
69       break;
70     case PAGE_EXECUTE:
71       *vprot = VPROT_EXEC;
72       break;
73     case PAGE_EXECUTE_READ:
74       *vprot = VPROT_EXEC | VPROT_READ;
75       break;
76     case PAGE_EXECUTE_READWRITE:
77       *vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITE;
78       break;
79     case PAGE_EXECUTE_WRITECOPY:
80       *vprot = VPROT_EXEC | VPROT_READ | VPROT_WRITECOPY;
81       break;
82     case PAGE_NOACCESS:
83       *vprot = 0;
84       break;
85     default:
86       return STATUS_INVALID_PARAMETER;
87     }
88   if (protect & PAGE_GUARD) *vprot |= VPROT_GUARD;
89   if (protect & PAGE_NOCACHE) *vprot |= VPROT_NOCACHE;
90   return STATUS_SUCCESS;
91 }
92
93
94 static void delete_view( struct file_view *view ) /* [in] View */
95 {
96   VirtualFree (view->base, view->size, MEM_RELEASE);
97   // if (view->mapping) NtClose( view->mapping );
98   free (view);
99 }
100
101
102 static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, size_t mask,
103                           int top_down, unsigned int vprot )
104 {
105   int prot = get_prot_flags (vprot);
106   struct file_view *view;
107   void *ptr;
108
109   view = malloc (sizeof (struct file_view));
110   if (!view)
111     return STATUS_NO_MEMORY;
112   
113   // FIXME: Only with NOACCESS does Windows CE prefer the high mem area
114   // even for smaller areas.
115   ptr = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS /*prot*/);
116   if (!ptr)
117     {
118       free (view);
119       return GetLastError();
120     }
121   view->base = ptr;
122   view->size = size;
123   view->protect = vprot;
124   view->mapping = 0;
125   *view_ret = view;
126   return STATUS_SUCCESS;
127 }
128
129
130 static NTSTATUS map_file_into_view( struct file_view *view, HANDLE fhandle, size_t start, size_t size,
131                                     off_t offset, unsigned int vprot, BOOL removable )
132 {
133   void *ptr;
134   int prot = get_prot_flags (vprot);
135   BOOL shared_write = (vprot & VPROT_WRITE) != 0;
136
137   assert( start < view->size );
138   assert( start + size <= view->size );
139
140 #if 0
141   /* only try mmap if media is not removable (or if we require write access) */
142   if (!removable || shared_write)
143     {
144       int flags = MAP_FIXED | (shared_write ? MAP_SHARED : MAP_PRIVATE);
145
146       if (mmap( (char *)view->base + start, size, prot, flags, fd, offset ) != (void *)-1)
147         goto done;
148
149       /* mmap() failed; if this is because the file offset is not    */
150       /* page-aligned (EINVAL), or because the underlying filesystem */
151       /* does not support mmap() (ENOEXEC,ENODEV), we do it by hand. */
152       if ((errno != ENOEXEC) && (errno != EINVAL) && (errno != ENODEV)) return FILE_GetNtStatus();
153       if (shared_write)  /* we cannot fake shared write mappings */
154         {
155           if (errno == EINVAL) return STATUS_INVALID_PARAMETER;
156           ERR( "shared writable mmap not supported, broken filesystem?\n" );
157           return STATUS_NOT_SUPPORTED;
158         }
159     }
160 #endif
161
162   /* Reserve the memory with an anonymous mmap */
163   ptr = VirtualAlloc ((char *)view->base + start, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
164   if (ptr == (void *)-1) return GetLastError();
165   /* Now read in the file */
166   pread( fhandle, ptr, size, offset );
167   //  if (prot != (PROT_READ|PROT_WRITE)) mprotect( ptr, size, prot );  /* Set the right protection */
168   //done:
169   //  memset( view->prot + (start >> page_shift), vprot, ROUND_SIZE(start,size) >> page_shift );
170   return STATUS_SUCCESS;
171 }
172
173
174 static NTSTATUS map_image (HANDLE hmapping, HANDLE hfile, HANDLE hmap, char *base, SIZE_T total_size, SIZE_T mask,
175                            SIZE_T header_size, int shared_fd, HANDLE dup_mapping, PVOID *addr_ptr)
176 {
177     IMAGE_DOS_HEADER *dos;
178     IMAGE_NT_HEADERS *nt;
179     IMAGE_SECTION_HEADER *sec;
180     IMAGE_DATA_DIRECTORY *imports;
181     NTSTATUS status = STATUS_CONFLICTING_ADDRESSES;
182     int i;
183     off_t pos;
184     DWORD fsize;
185     struct file_view *view = NULL;
186     char *ptr, *header_end;
187     INT_PTR delta = 0;
188
189
190     /* zero-map the whole range */
191
192     if (base >= (char *)0x110000)  /* make sure the DOS area remains free */
193       status = map_view( &view, base, total_size, mask, FALSE,
194                          VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY | VPROT_IMAGE );
195
196     if (status != STATUS_SUCCESS)
197       status = map_view( &view, NULL, total_size, mask, FALSE,
198                          VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY | VPROT_IMAGE );
199
200     if (status != STATUS_SUCCESS) goto error;
201
202     ptr = view->base;
203     TRACE( "mapped PE file at %p-%p\n", ptr, ptr + total_size );
204
205     /* map the header */
206     
207     fsize = GetFileSize (hfile, NULL);
208     if (fsize == INVALID_FILE_SIZE)
209       {
210         status = GetLastError();
211         goto error;
212       }
213     status = STATUS_INVALID_IMAGE_FORMAT;  /* generic error */
214     header_size = min( header_size, fsize );
215     if (map_file_into_view( view, hfile, 0, header_size, 0, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
216                             !dup_mapping ) != STATUS_SUCCESS) goto error;
217     dos = (IMAGE_DOS_HEADER *)ptr;
218     nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew);
219     header_end = ptr + ROUND_SIZE( 0, header_size );
220     memset( ptr + header_size, 0, header_end - (ptr + header_size) );
221     if ((char *)(nt + 1) > header_end) goto error;
222     sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
223     if ((char *)(sec + nt->FileHeader.NumberOfSections) > header_end) goto error;
224
225     imports = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT;
226     if (!imports->Size || !imports->VirtualAddress) imports = NULL;
227
228     /* check the architecture */
229
230     if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_ARM
231         && nt->FileHeader.Machine != IMAGE_FILE_MACHINE_THUMB)
232         {
233           TRACE("Trying to load PE image for unsupported architecture (");
234           switch (nt->FileHeader.Machine)
235             {
236             case IMAGE_FILE_MACHINE_UNKNOWN: TRACE("Unknown"); break;
237             case IMAGE_FILE_MACHINE_I386:    TRACE("I386"); break;
238             case IMAGE_FILE_MACHINE_R3000:   TRACE("R3000"); break;
239             case IMAGE_FILE_MACHINE_R4000:   TRACE("R4000"); break;
240             case IMAGE_FILE_MACHINE_R10000:  TRACE("R10000"); break;
241             case IMAGE_FILE_MACHINE_ALPHA:   TRACE("Alpha"); break;
242             case IMAGE_FILE_MACHINE_POWERPC: TRACE("PowerPC"); break;
243             case IMAGE_FILE_MACHINE_IA64:    TRACE("IA-64"); break;
244             case IMAGE_FILE_MACHINE_ALPHA64: TRACE("Alpha-64"); break;
245             case IMAGE_FILE_MACHINE_ARM:     TRACE("ARM"); break;
246             default: TRACE("Unknown-%04x", nt->FileHeader.Machine); break;
247             }
248           TRACE(")\n");
249           goto error;
250         }
251     
252     /* check for non page-aligned binary */
253
254     if (nt->OptionalHeader.SectionAlignment <= page_mask)
255       {
256         /* unaligned sections, this happens for native subsystem binaries */
257         /* in that case Windows simply maps in the whole file */
258
259         if (map_file_into_view( view, hfile, 0, total_size, 0, VPROT_COMMITTED | VPROT_READ,
260                                 !dup_mapping ) != STATUS_SUCCESS) goto error;
261
262         /* check that all sections are loaded at the right offset */
263         if (nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) goto error;
264         for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
265           {
266             if (sec[i].VirtualAddress != sec[i].PointerToRawData)
267               goto error;  /* Windows refuses to load in that case too */
268           }
269 #if 0
270         /* set the image protections */
271         VIRTUAL_SetProt( view, ptr, total_size,
272                          VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
273 #endif
274
275 #if 0
276         /* no relocations are performed on non page-aligned binaries */
277         goto done;
278 #else
279         goto reloc;
280 #endif
281       }
282
283
284     /* map all the sections */
285
286     for (i = pos = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
287       {
288         static const SIZE_T sector_align = 0x1ff;
289         SIZE_T map_size, file_start, file_size, end;
290
291         if (!sec->Misc.VirtualSize)
292           map_size = ROUND_SIZE( 0, sec->SizeOfRawData );
293         else
294           map_size = ROUND_SIZE( 0, sec->Misc.VirtualSize );
295
296         /* file positions are rounded to sector boundaries regardless of OptionalHeader.FileAlignment */
297         file_start = sec->PointerToRawData & ~sector_align;
298         file_size = (sec->SizeOfRawData + (sec->PointerToRawData & sector_align) + sector_align) & ~sector_align;
299         if (file_size > map_size) file_size = map_size;
300
301         /* a few sanity checks */
302         end = sec->VirtualAddress + ROUND_SIZE( sec->VirtualAddress, map_size );
303         if (sec->VirtualAddress > total_size || end > total_size || end < sec->VirtualAddress)
304           {
305             ERR ( "Section %.8s too large (%x+%lx/%lx)\n",
306                   sec->Name, sec->VirtualAddress, map_size, total_size );
307             goto error;
308           }
309
310         if ((sec->Characteristics & IMAGE_SCN_MEM_SHARED) &&
311             (sec->Characteristics & IMAGE_SCN_MEM_WRITE))
312           {
313             TRACE( "mapping shared section %.8s at %p off %x (%x) size %lx (%lx) flags %x\n",
314                    sec->Name, ptr + sec->VirtualAddress,
315                    sec->PointerToRawData, (int)pos, file_size, map_size,
316                    sec->Characteristics );
317             if (map_file_into_view( view, hfile, sec->VirtualAddress, map_size, pos,
318                                     VPROT_COMMITTED | VPROT_READ | VPROT_WRITE,
319                                     FALSE ) != STATUS_SUCCESS)
320               {
321                 ERR ( "Could not map shared section %.8s\n", sec->Name );
322                 goto error;
323               }
324
325             /* check if the import directory falls inside this section */
326             if (imports && imports->VirtualAddress >= sec->VirtualAddress &&
327                 imports->VirtualAddress < sec->VirtualAddress + map_size)
328               {
329                 UINT_PTR base = imports->VirtualAddress & ~page_mask;
330                 UINT_PTR end = base + ROUND_SIZE( imports->VirtualAddress, imports->Size );
331                 if (end > sec->VirtualAddress + map_size) end = sec->VirtualAddress + map_size;
332                 if (end > base)
333                   map_file_into_view( view, hfile, base, end - base,
334                                       pos + (base - sec->VirtualAddress),
335                                       VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
336                                       FALSE );
337               }
338             pos += map_size;
339             continue;
340           }
341
342         ERR( "mapping section %.8s at %p off %x size %x virt %x flags %x\n",
343              sec->Name, ptr + sec->VirtualAddress,
344              sec->PointerToRawData, sec->SizeOfRawData,
345              sec->Misc.VirtualSize, sec->Characteristics );
346         
347         if (!sec->PointerToRawData || !file_size) continue;
348
349         /* Note: if the section is not aligned properly map_file_into_view will magically
350          *       fall back to read(), so we don't need to check anything here.
351          */
352         end = file_start + file_size;
353         if (sec->PointerToRawData >= fsize ||
354             end > ((fsize + sector_align) & ~sector_align) ||
355             end < file_start ||
356             map_file_into_view( view, hfile, sec->VirtualAddress, file_size, file_start,
357                                 VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
358                                 !dup_mapping ) != STATUS_SUCCESS)
359           {
360             ERR( "Could not map section %.8s, file probably truncated\n", sec->Name );
361             goto error;
362           }
363
364         if (file_size & page_mask)
365           {
366             end = ROUND_SIZE( 0, file_size );
367             if (end > map_size) end = map_size;
368             TRACE("clearing %p - %p\n",
369                   ptr + sec->VirtualAddress + file_size,
370                   ptr + sec->VirtualAddress + end );
371             memset( ptr + sec->VirtualAddress + file_size, 0, end - file_size );
372           }
373       }
374
375  reloc:
376     /* perform base relocation, if necessary */
377
378     if (ptr != base)
379       // &&
380       //        ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) ||
381       //         !NtCurrentTeb()->Peb->ImageBaseAddress) )
382       {
383         IMAGE_BASE_RELOCATION *rel, *end;
384         const IMAGE_DATA_DIRECTORY *relocs;
385
386         if (nt->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
387           {
388             TRACE( "Need to relocate module from %p to %p, but there are no relocation records\n",
389                    base, ptr );
390             status = STATUS_CONFLICTING_ADDRESSES;
391             goto error;
392           }
393
394         TRACE( "relocating from %p-%p to %p-%p\n",
395                base, base + total_size, ptr, ptr + total_size );
396
397         relocs = &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
398         rel = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress);
399         end = (IMAGE_BASE_RELOCATION *)(ptr + relocs->VirtualAddress + relocs->Size);
400         delta = ptr - base;
401
402         while (rel < end - 1 && rel->SizeOfBlock)
403           {
404             if (rel->VirtualAddress >= total_size)
405               {
406                 TRACE( "invalid address %p in relocation %p\n", ptr + rel->VirtualAddress, rel );
407                 status = STATUS_ACCESS_VIOLATION;
408                 goto error;
409               }
410             rel = MyLdrProcessRelocationBlock( ptr + rel->VirtualAddress,
411                                                (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT),
412                                                (USHORT *)(rel + 1), delta );
413             if (!rel) goto error;
414           }
415       }
416 #if 0
417     /* set the image protections */
418     VIRTUAL_SetProt( view, ptr, ROUND_SIZE( 0, header_size ), VPROT_COMMITTED | VPROT_READ );
419
420     sec = (IMAGE_SECTION_HEADER*)((char *)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
421     for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
422       {
423         SIZE_T size;
424         BYTE vprot = VPROT_COMMITTED;
425
426         if (sec->Misc.VirtualSize)
427           size = ROUND_SIZE( sec->VirtualAddress, sec->Misc.VirtualSize );
428         else
429           size = ROUND_SIZE( sec->VirtualAddress, sec->SizeOfRawData );
430
431         if (sec->Characteristics & IMAGE_SCN_MEM_READ)    vprot |= VPROT_READ;
432         if (sec->Characteristics & IMAGE_SCN_MEM_WRITE)   vprot |= VPROT_READ|VPROT_WRITECOPY;
433         if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) vprot |= VPROT_EXEC;
434
435         /* Dumb game crack lets the AOEP point into a data section. Adjust. */
436         if ((nt->OptionalHeader.AddressOfEntryPoint >= sec->VirtualAddress) &&
437             (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress + size))
438           vprot |= VPROT_EXEC;
439
440         VIRTUAL_SetProt( view, ptr + sec->VirtualAddress, size, vprot );
441       }
442 #endif
443
444     // done:
445     *addr_ptr = ptr;
446 #ifdef VALGRIND_LOAD_PDB_DEBUGINFO
447     VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta);
448 #endif
449     if (ptr != base) return STATUS_IMAGE_NOT_AT_BASE;
450     return STATUS_SUCCESS;
451
452  error:
453     if (view) delete_view( view );
454     return status;
455 }
456
457
458 NTSTATUS MyNtCreateSection (HANDLE *handle, ACCESS_MASK access,
459                             /* const OBJECT_ATTRIBUTES *attr */ void *attr,
460                             const LARGE_INTEGER *size, ULONG protect,
461                             ULONG sec_flags, HANDLE file)
462 {
463     NTSTATUS ret;
464     unsigned int vprot;
465     
466     if ((ret = get_vprot_flags( protect, &vprot ))) return ret;
467
468     assert (attr == NULL);
469
470     if (!(sec_flags & SEC_RESERVE)) vprot |= VPROT_COMMITTED;
471     if (sec_flags & SEC_NOCACHE) vprot |= VPROT_NOCACHE;
472     if (sec_flags & SEC_IMAGE) vprot |= VPROT_IMAGE;
473
474     ret = SERVER_create_mapping (access, attr, file, size ? size->QuadPart : 0,
475                                  vprot, handle);
476
477     return ret;
478 }
479
480
481 NTSTATUS MyNtMapViewOfSection (HANDLE handle, HANDLE process, PVOID *addr_ptr, ULONG zero_bits,
482                                SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
483                                SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect)
484 {
485   NTSTATUS res;
486   mem_size_t full_size;
487   ACCESS_MASK access;
488   SIZE_T size, mask = get_mask( zero_bits );
489   unsigned int map_vprot;
490   //  unsigned int vprot;
491   void *base;
492   //  struct file_view *view;
493   DWORD header_size;
494   HANDLE fhandle;
495   HANDLE mhandle;
496   LARGE_INTEGER offset;
497
498   offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
499
500   TRACE("handle=%p process=%p addr=%p off=%x%08x size=%lx access=%x\n",
501         handle, process, *addr_ptr, offset.u.HighPart, offset.u.LowPart, *size_ptr, protect );
502
503   /* Check parameters */
504
505   if ((offset.u.LowPart & mask) || (*addr_ptr && ((UINT_PTR)*addr_ptr & mask)))
506     return STATUS_INVALID_PARAMETER;
507
508   switch(protect)
509     {
510     case PAGE_NOACCESS:
511       access = 0;
512       break;
513     case PAGE_READWRITE:
514     case PAGE_EXECUTE_READWRITE:
515       access = SECTION_MAP_WRITE;
516       break;
517     case PAGE_READONLY:
518     case PAGE_WRITECOPY:
519     case PAGE_EXECUTE:
520     case PAGE_EXECUTE_READ:
521     case PAGE_EXECUTE_WRITECOPY:
522       access = SECTION_MAP_READ;
523       break;
524     default:
525       return STATUS_INVALID_PARAMETER;
526     }
527
528   res = SERVER_get_mapping_info (handle, access, &map_vprot, &base, &full_size, &header_size, &fhandle, &mhandle);
529   if (res) return res;
530
531   if (map_vprot & VPROT_IMAGE)
532     {
533       size = full_size;
534       if (size != full_size)  /* truncated */
535         {
536           TRACE( "Modules larger than 4Gb not supported\n");
537           res = STATUS_INVALID_PARAMETER;
538           goto done;
539         }
540       res = map_image( handle, fhandle, mhandle, base, size, mask, header_size,
541                        -1, INVALID_HANDLE_VALUE, addr_ptr );
542       if (res >= 0) *size_ptr = size;
543       return res;
544     }
545
546   assert (!"Not supported");
547 #if 0
548   res = STATUS_INVALID_PARAMETER;
549   if (offset.QuadPart >= full_size) goto done;
550   if (*size_ptr)
551     {
552       if (*size_ptr > full_size - offset.QuadPart) goto done;
553       size = ROUND_SIZE( offset.u.LowPart, *size_ptr );
554       if (size < *size_ptr) goto done;  /* wrap-around */
555     }
556   else
557     {
558       size = full_size - offset.QuadPart;
559       if (size != full_size - offset.QuadPart)  /* truncated */
560         {
561           WARN( "Files larger than 4Gb (%s) not supported on this platform\n",
562                 wine_dbgstr_longlong(full_size) );
563           goto done;
564         }
565     }
566
567   /* Reserve a properly aligned area */
568
569   server_enter_uninterrupted_section( &csVirtual, &sigset );
570
571   get_vprot_flags( protect, &vprot );
572   vprot |= (map_vprot & VPROT_COMMITTED);
573   res = map_view( &view, *addr_ptr, size, mask, FALSE, vprot );
574   if (res)
575     {
576       server_leave_uninterrupted_section( &csVirtual, &sigset );
577       goto done;
578     }
579
580   /* Map the file */
581
582   TRACE("handle=%p size=%lx offset=%x%08x\n",
583         handle, size, offset.u.HighPart, offset.u.LowPart );
584
585   res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, vprot, !dup_mapping );
586   if (res == STATUS_SUCCESS)
587     {
588       *addr_ptr = view->base;
589       *size_ptr = size;
590       view->mapping = dup_mapping;
591       dup_mapping = 0;  /* don't close it */
592     }
593   else
594     {
595       ERR( "map_file_into_view %p %lx %x%08x failed\n",
596            view->base, size, offset.u.HighPart, offset.u.LowPart );
597       delete_view( view );
598     }
599   
600   server_leave_uninterrupted_section( &csVirtual, &sigset );
601 #endif
602
603  done:
604   return res;
605
606   //  *addr_ptr = MapViewOfFile (handle, 
607   //                         protect == PAGE_READONLY ? FILE_MAP_READ : FILE_MAP_WRITE,
608   //                         offset_ptr ? offset_ptr->HighPart : 0,
609   //                         offset_ptr ? offset_ptr->LowPart : 0,
610   //                         size_ptr ? size_ptr->LowPart : 0);
611   //  if (*addr_ptr == NULL)
612   //    return GetLastError ();
613   //
614   //  return STATUS_SUCCESS;
615 }