2 * Win32 virtual memory functions
4 * Copyright 1997 Alexandre Julliard
12 #include <sys/types.h>
36 struct _FV
*next
; /* Next view */
37 struct _FV
*prev
; /* Prev view */
38 UINT32 base
; /* Base address */
39 UINT32 size
; /* Size in bytes */
40 UINT32 flags
; /* Allocation flags */
41 FILE_MAPPING
*mapping
; /* File mapping */
42 BYTE protect
; /* Protection for all pages at allocation time */
43 BYTE prot
[1]; /* Protection byte for each page */
46 /* Per-page protection byte values */
47 #define VPROT_READ 0x01
48 #define VPROT_WRITE 0x02
49 #define VPROT_EXEC 0x04
50 #define VPROT_WRITECOPY 0x08
51 #define VPROT_GUARD 0x10
52 #define VPROT_NOCACHE 0x20
53 #define VPROT_COMMITTED 0x40
56 #define VFLAG_SYSTEM 0x01
58 /* Conversion from VPROT_* to Win32 flags */
59 static const BYTE VIRTUAL_Win32Flags
[16] =
61 PAGE_NOACCESS
, /* 0 */
62 PAGE_READONLY
, /* READ */
63 PAGE_READWRITE
, /* WRITE */
64 PAGE_READWRITE
, /* READ | WRITE */
65 PAGE_EXECUTE
, /* EXEC */
66 PAGE_EXECUTE_READ
, /* READ | EXEC */
67 PAGE_EXECUTE_READWRITE
, /* WRITE | EXEC */
68 PAGE_EXECUTE_READWRITE
, /* READ | WRITE | EXEC */
69 PAGE_WRITECOPY
, /* WRITECOPY */
70 PAGE_WRITECOPY
, /* READ | WRITECOPY */
71 PAGE_WRITECOPY
, /* WRITE | WRITECOPY */
72 PAGE_WRITECOPY
, /* READ | WRITE | WRITECOPY */
73 PAGE_EXECUTE_WRITECOPY
, /* EXEC | WRITECOPY */
74 PAGE_EXECUTE_WRITECOPY
, /* READ | EXEC | WRITECOPY */
75 PAGE_EXECUTE_WRITECOPY
, /* WRITE | EXEC | WRITECOPY */
76 PAGE_EXECUTE_WRITECOPY
/* READ | WRITE | EXEC | WRITECOPY */
80 static FILE_VIEW
*VIRTUAL_FirstView
;
82 static UINT32 page_shift
;
83 static UINT32 page_mask
;
85 #define ROUND_ADDR(addr) \
86 ((UINT32)(addr) & ~page_mask)
88 #define ROUND_SIZE(addr,size) \
89 (((UINT32)(size) + ((UINT32)(addr) & page_mask) + page_mask) & ~page_mask)
92 /***********************************************************************
93 * VIRTUAL_DestroyMapping
95 * Destroy a FILE_MAPPING object.
97 void VIRTUAL_DestroyMapping( K32OBJ
*ptr
)
99 FILE_MAPPING
*mapping
= (FILE_MAPPING
*)ptr
;
100 assert( ptr
->type
== K32OBJ_MEM_MAPPED_FILE
);
102 if (mapping
->file
) K32OBJ_DecCount( &mapping
->file
->header
);
103 ptr
->type
= K32OBJ_UNKNOWN
;
104 HeapFree( SystemHeap
, 0, mapping
);
108 /***********************************************************************
111 static const char *VIRTUAL_GetProtStr( BYTE prot
)
113 static char buffer
[6];
114 buffer
[0] = (prot
& VPROT_COMMITTED
) ? 'c' : '-';
115 buffer
[1] = (prot
& VPROT_GUARD
) ? 'g' : '-';
116 buffer
[2] = (prot
& VPROT_READ
) ? 'r' : '-';
117 buffer
[3] = (prot
& VPROT_WRITE
) ?
118 ((prot
& VPROT_WRITECOPY
) ? 'w' : 'W') : '-';
119 buffer
[4] = (prot
& VPROT_EXEC
) ? 'x' : '-';
125 /***********************************************************************
128 static void VIRTUAL_DumpView( FILE_VIEW
*view
)
131 UINT32 addr
= view
->base
;
132 BYTE prot
= view
->prot
[0];
134 dprintf_virtual( stddeb
, "View: %08x - %08x%s\n",
135 view
->base
, view
->base
+ view
->size
- 1,
136 (view
->flags
& VFLAG_SYSTEM
) ? " (system)" : "" );
138 for (count
= i
= 1; i
< view
->size
>> page_shift
; i
++, count
++)
140 if (view
->prot
[i
] == prot
) continue;
141 dprintf_virtual( stddeb
, " %08x - %08x %s\n",
142 addr
, addr
+ (count
<< page_shift
) - 1,
143 VIRTUAL_GetProtStr(prot
) );
144 addr
+= (count
<< page_shift
);
145 prot
= view
->prot
[i
];
149 dprintf_virtual( stddeb
, " %08x - %08x %s\n",
150 addr
, addr
+ (count
<< page_shift
) - 1,
151 VIRTUAL_GetProtStr(prot
) );
155 /***********************************************************************
158 void VIRTUAL_Dump(void)
160 FILE_VIEW
*view
= VIRTUAL_FirstView
;
161 dprintf_virtual( stddeb
, "\nDump of all virtual memory views:\n\n" );
164 VIRTUAL_DumpView( view
);
170 /***********************************************************************
173 * Find the view containing a given address.
175 static FILE_VIEW
*VIRTUAL_FindView( UINT32 addr
)
177 FILE_VIEW
*view
= VIRTUAL_FirstView
;
180 if (view
->base
> addr
) return NULL
;
181 if (view
->base
+ view
->size
> addr
) return view
;
188 /***********************************************************************
191 * Create a new view and add it in the linked list.
193 static FILE_VIEW
*VIRTUAL_CreateView( UINT32 base
, UINT32 size
,
194 UINT32 flags
, BYTE vprot
)
196 FILE_VIEW
*view
, *prev
;
198 /* Create the view structure */
201 view
= (FILE_VIEW
*)xmalloc( sizeof(*view
) + size
- 1 );
203 view
->size
= size
<< page_shift
;
205 view
->protect
= vprot
;
206 memset( view
->prot
, vprot
, size
);
208 /* Insert it in the linked list */
210 if (!VIRTUAL_FirstView
|| (VIRTUAL_FirstView
->base
> base
))
212 view
->next
= VIRTUAL_FirstView
;
214 if (view
->next
) view
->next
->prev
= view
;
215 VIRTUAL_FirstView
= view
;
219 prev
= VIRTUAL_FirstView
;
220 while (prev
->next
&& (prev
->next
->base
< base
)) prev
= prev
->next
;
221 view
->next
= prev
->next
;
223 if (view
->next
) view
->next
->prev
= view
;
226 if (debugging_virtual
) VIRTUAL_DumpView( view
);
231 /***********************************************************************
236 static void VIRTUAL_DeleteView( FILE_VIEW
*view
)
238 munmap( (void *)view
->base
, view
->size
);
239 if (view
->next
) view
->next
->prev
= view
->prev
;
240 if (view
->prev
) view
->prev
->next
= view
->next
;
241 else VIRTUAL_FirstView
= view
->next
;
246 /***********************************************************************
247 * VIRTUAL_GetUnixProt
249 * Convert page protections to protection for mmap/mprotect.
251 static int VIRTUAL_GetUnixProt( BYTE vprot
)
254 if ((vprot
& VPROT_COMMITTED
) && !(vprot
& VPROT_GUARD
))
256 if (vprot
& VPROT_READ
) prot
|= PROT_READ
;
257 if (vprot
& VPROT_WRITE
) prot
|= PROT_WRITE
;
258 if (vprot
& VPROT_EXEC
) prot
|= PROT_EXEC
;
264 /***********************************************************************
265 * VIRTUAL_GetWin32Prot
267 * Convert page protections to Win32 flags.
269 static void VIRTUAL_GetWin32Prot( BYTE vprot
, DWORD
*protect
, DWORD
*state
)
271 *protect
= VIRTUAL_Win32Flags
[vprot
& 0x0f];
272 if (vprot
& VPROT_GUARD
) *protect
|= PAGE_GUARD
;
273 if (vprot
& VPROT_NOCACHE
) *protect
|= PAGE_NOCACHE
;
275 if (state
) *state
= (vprot
& VPROT_COMMITTED
) ? MEM_COMMIT
: MEM_RESERVE
;
279 /***********************************************************************
282 * Build page protections from Win32 flags.
284 static BYTE
VIRTUAL_GetProt( DWORD protect
)
288 switch(protect
& 0xff)
294 vprot
= VPROT_READ
| VPROT_WRITE
;
297 vprot
= VPROT_READ
| VPROT_WRITE
| VPROT_WRITECOPY
;
302 case PAGE_EXECUTE_READ
:
303 vprot
= VPROT_EXEC
| VPROT_READ
;
305 case PAGE_EXECUTE_READWRITE
:
306 vprot
= VPROT_EXEC
| VPROT_READ
| VPROT_WRITE
| VPROT_WRITECOPY
;
308 case PAGE_EXECUTE_WRITECOPY
:
309 vprot
= VPROT_EXEC
| VPROT_READ
| VPROT_WRITE
;
316 if (protect
& PAGE_GUARD
) vprot
|= VPROT_GUARD
;
317 if (protect
& PAGE_NOCACHE
) vprot
|= VPROT_NOCACHE
;
322 /***********************************************************************
325 * Change the protection of a range of pages.
327 static BOOL32
VIRTUAL_SetProt( FILE_VIEW
*view
, UINT32 base
,
328 UINT32 size
, BYTE vprot
)
330 dprintf_virtual( stddeb
, "VIRTUAL_SetProt: %08x-%08x %s\n",
331 base
, base
+ size
- 1, VIRTUAL_GetProtStr( vprot
) );
333 if (mprotect( (void *)base
, size
, VIRTUAL_GetUnixProt(vprot
) ))
334 return FALSE
; /* FIXME: last error */
336 memset( view
->prot
+ ((base
- view
->base
) >> page_shift
),
337 vprot
, size
>> page_shift
);
338 if (debugging_virtual
) VIRTUAL_DumpView( view
);
343 /***********************************************************************
346 * Check that all pages in a range have the given flags.
348 static BOOL32
VIRTUAL_CheckFlags( UINT32 base
, UINT32 size
, BYTE flags
)
353 if (!size
) return TRUE
;
354 if (!(view
= VIRTUAL_FindView( base
))) return FALSE
;
355 if (view
->base
+ view
->size
< base
+ size
) return FALSE
;
356 page
= (base
- view
->base
) >> page_shift
;
357 size
= ROUND_SIZE( base
, size
) >> page_shift
;
358 while (size
--) if ((view
->prot
[page
++] & flags
) != flags
) return FALSE
;
363 /***********************************************************************
366 BOOL32
VIRTUAL_Init(void)
369 GetSystemInfo( &sysinfo
);
371 page_mask
= sysinfo
.dwPageSize
- 1;
372 /* Make sure we have a power of 2 */
373 assert( !(sysinfo
.dwPageSize
& page_mask
) );
375 while ((1 << page_shift
) != sysinfo
.dwPageSize
) page_shift
++;
379 FILE *f
= fopen( "/proc/self/maps", "r" );
383 while (fgets( buffer
, sizeof(buffer
), f
))
385 int start
, end
, offset
;
387 BYTE vprot
= VPROT_COMMITTED
;
389 sscanf( buffer
, "%x-%x %c%c%c%c %x",
390 &start
, &end
, &r
, &w
, &x
, &p
, &offset
);
391 if (r
== 'r') vprot
|= VPROT_READ
;
392 if (w
== 'w') vprot
|= VPROT_WRITE
;
393 if (x
== 'x') vprot
|= VPROT_EXEC
;
394 if (p
== 'p') vprot
|= VPROT_WRITECOPY
;
395 VIRTUAL_CreateView( start
, end
- start
, VFLAG_SYSTEM
, vprot
);
405 /***********************************************************************
406 * VirtualAlloc (KERNEL32.548)
408 LPVOID
VirtualAlloc( LPVOID addr
, DWORD size
, DWORD type
, DWORD protect
)
411 UINT32 base
, ptr
, view_size
;
414 dprintf_virtual( stddeb
, "VirtualAlloc: %08x %08lx %lx %08lx\n",
415 (UINT32
)addr
, size
, type
, protect
);
417 /* Round parameters to a page boundary */
419 if (size
> 0x7fc00000) /* 2Gb - 4Mb */
421 SetLastError( ERROR_OUTOFMEMORY
);
426 if (type
& MEM_RESERVE
) /* Round down to 64k boundary */
427 base
= ((UINT32
)addr
+ 0xffff) & ~0xffff;
429 base
= ROUND_ADDR( addr
);
430 size
= (((UINT32
)addr
+ size
+ page_mask
) & ~page_mask
) - base
;
431 if (base
+ size
< base
) /* Disallow wrap-around */
433 SetLastError( ERROR_INVALID_PARAMETER
);
440 size
= (size
+ page_mask
) & ~page_mask
;
443 /* Compute the protection flags */
445 if (!(type
& (MEM_COMMIT
| MEM_RESERVE
)) ||
446 (type
& ~(MEM_COMMIT
| MEM_RESERVE
)))
448 SetLastError( ERROR_INVALID_PARAMETER
);
451 if (type
& MEM_COMMIT
)
452 vprot
= VIRTUAL_GetProt( protect
) | VPROT_COMMITTED
;
455 /* Reserve the memory */
457 if ((type
& MEM_RESERVE
) || !base
)
459 view_size
= size
+ (base
? 0 : 0x10000);
460 ptr
= (UINT32
)FILE_mmap( NULL
, (LPVOID
)base
, 0, view_size
, 0, 0,
461 VIRTUAL_GetUnixProt( vprot
), MAP_PRIVATE
);
462 if (ptr
== (UINT32
)-1)
464 SetLastError( ERROR_OUTOFMEMORY
);
469 /* Release the extra memory while keeping the range */
470 /* starting on a 64k boundary. */
472 if (ptr
& 0xffff0000)
474 munmap( (void *)ptr
, 0x10000 - (ptr
& 0xffff) );
475 view_size
-= (ptr
& 0xffff);
476 ptr
= (ptr
+ 0x10000) & 0xffff0000;
478 if (view_size
> size
)
479 munmap( (void *)(ptr
+ size
), view_size
- size
);
481 if (!(view
= VIRTUAL_CreateView( ptr
, size
, 0, vprot
)))
483 munmap( (void *)ptr
, size
);
484 return NULL
; /* FIXME: last error */
486 if (debugging_virtual
) VIRTUAL_DumpView( view
);
490 /* Commit the pages */
492 if (!(view
= VIRTUAL_FindView( base
)) ||
493 (base
+ size
> view
->base
+ view
->size
))
495 SetLastError( ERROR_INVALID_PARAMETER
);
499 if (!VIRTUAL_SetProt( view
, base
, size
, vprot
)) return NULL
;
504 /***********************************************************************
505 * VirtualFree (KERNEL32.550)
507 BOOL32
VirtualFree( LPVOID addr
, DWORD size
, DWORD type
)
512 dprintf_virtual( stddeb
, "VirtualFree: %08x %08lx %lx\n",
513 (UINT32
)addr
, size
, type
);
515 /* Fix the parameters */
517 size
= ROUND_SIZE( addr
, size
);
518 base
= ROUND_ADDR( addr
);
520 if (!(view
= VIRTUAL_FindView( base
)) ||
521 (base
+ size
> view
->base
+ view
->size
))
523 SetLastError( ERROR_INVALID_PARAMETER
);
527 /* Compute the protection flags */
529 if ((type
!= MEM_DECOMMIT
) && (type
!= MEM_RELEASE
))
531 SetLastError( ERROR_INVALID_PARAMETER
);
537 if (type
== MEM_RELEASE
)
539 if (size
|| (base
!= view
->base
))
541 SetLastError( ERROR_INVALID_PARAMETER
);
544 VIRTUAL_DeleteView( view
);
548 /* Decommit the pages */
550 return VIRTUAL_SetProt( view
, base
, size
, 0 );
554 /***********************************************************************
555 * VirtualLock (KERNEL32.551)
557 BOOL32
VirtualLock( LPVOID addr
, DWORD size
)
563 /***********************************************************************
564 * VirtualUnlock (KERNEL32.556)
566 BOOL32
VirtualUnlock( LPVOID addr
, DWORD size
)
572 /***********************************************************************
573 * VirtualProtect (KERNEL32.552)
575 BOOL32
VirtualProtect( LPVOID addr
, DWORD size
, DWORD new_prot
,
582 dprintf_virtual( stddeb
, "VirtualProtect: %08x %08lx %08lx\n",
583 (UINT32
)addr
, size
, new_prot
);
585 /* Fix the parameters */
587 size
= ROUND_SIZE( addr
, size
);
588 base
= ROUND_ADDR( addr
);
590 if (!(view
= VIRTUAL_FindView( base
)) ||
591 (base
+ size
> view
->base
+ view
->size
))
593 SetLastError( ERROR_INVALID_PARAMETER
);
597 /* Make sure all the pages are committed */
599 p
= view
->prot
+ ((base
- view
->base
) >> page_shift
);
600 for (i
= size
>> page_shift
; i
; i
--, p
++)
602 if (!(*p
& VPROT_COMMITTED
))
604 SetLastError( ERROR_INVALID_PARAMETER
);
609 VIRTUAL_GetWin32Prot( view
->prot
[0], old_prot
, NULL
);
610 vprot
= VIRTUAL_GetProt( new_prot
) | VPROT_COMMITTED
;
611 return VIRTUAL_SetProt( view
, base
, size
, vprot
);
615 /***********************************************************************
616 * VirtualProtectEx (KERNEL32.553)
618 BOOL32
VirtualProtectEx( HANDLE32 handle
, LPVOID addr
, DWORD size
,
619 DWORD new_prot
, LPDWORD old_prot
)
623 PDB32
*pdb
= (PDB32
*)PROCESS_GetObjPtr( handle
, K32OBJ_PROCESS
);
626 if (pdb
== pCurrentProcess
)
627 ret
= VirtualProtect( addr
, size
, new_prot
, old_prot
);
629 fprintf(stderr
,"Unsupported: VirtualProtectEx on other process\n");
630 K32OBJ_DecCount( &pdb
->header
);
636 /***********************************************************************
637 * VirtualQuery (KERNEL32.554)
639 BOOL32
VirtualQuery( LPCVOID addr
, LPMEMORY_BASIC_INFORMATION info
, DWORD len
)
641 FILE_VIEW
*view
= VIRTUAL_FirstView
;
642 UINT32 base
= ROUND_ADDR( addr
);
643 UINT32 alloc_base
= 0;
646 /* Find the view containing the address */
652 size
= 0xffff0000 - alloc_base
;
655 if (view
->base
> base
)
657 size
= view
->base
- alloc_base
;
661 if (view
->base
+ view
->size
> base
)
663 alloc_base
= view
->base
;
667 alloc_base
= view
->base
+ view
->size
;
671 /* Fill the info structure */
675 info
->State
= MEM_FREE
;
677 info
->AllocationProtect
= 0;
682 BYTE vprot
= view
->prot
[(base
- alloc_base
) >> page_shift
];
683 VIRTUAL_GetWin32Prot( vprot
, &info
->Protect
, &info
->State
);
684 for (size
= base
- alloc_base
; size
< view
->size
; size
+= page_mask
+1)
685 if (view
->prot
[size
>> page_shift
] != vprot
) break;
686 info
->AllocationProtect
= view
->protect
;
687 info
->Type
= MEM_PRIVATE
; /* FIXME */
690 info
->BaseAddress
= (LPVOID
)base
;
691 info
->AllocationBase
= (LPVOID
)alloc_base
;
692 info
->RegionSize
= size
- (base
- alloc_base
);
697 /***********************************************************************
698 * VirtualQueryEx (KERNEL32.555)
700 BOOL32
VirtualQueryEx( HANDLE32 handle
, LPCVOID addr
,
701 LPMEMORY_BASIC_INFORMATION info
, DWORD len
)
705 PDB32
*pdb
= (PDB32
*)PROCESS_GetObjPtr( handle
, K32OBJ_PROCESS
);
708 if (pdb
== pCurrentProcess
)
709 ret
= VirtualQuery( addr
, info
, len
);
711 fprintf(stderr
,"Unsupported: VirtualQueryEx on other process\n");
712 K32OBJ_DecCount( &pdb
->header
);
718 /***********************************************************************
719 * IsBadReadPtr32 (KERNEL32.354)
721 BOOL32
IsBadReadPtr32( LPCVOID ptr
, UINT32 size
)
723 return !VIRTUAL_CheckFlags( (UINT32
)ptr
, size
,
724 VPROT_READ
| VPROT_COMMITTED
);
728 /***********************************************************************
729 * IsBadWritePtr32 (KERNEL32.357)
731 BOOL32
IsBadWritePtr32( LPVOID ptr
, UINT32 size
)
733 return !VIRTUAL_CheckFlags( (UINT32
)ptr
, size
,
734 VPROT_WRITE
| VPROT_COMMITTED
);
738 /***********************************************************************
739 * IsBadHugeReadPtr32 (KERNEL32.352)
741 BOOL32
IsBadHugeReadPtr32( LPCVOID ptr
, UINT32 size
)
743 return IsBadReadPtr32( ptr
, size
);
747 /***********************************************************************
748 * IsBadHugeWritePtr32 (KERNEL32.353)
750 BOOL32
IsBadHugeWritePtr32( LPVOID ptr
, UINT32 size
)
752 return IsBadWritePtr32( ptr
, size
);
756 /***********************************************************************
757 * IsBadCodePtr32 (KERNEL32.351)
759 BOOL32
IsBadCodePtr32( FARPROC32 ptr
)
761 return !VIRTUAL_CheckFlags( (UINT32
)ptr
, 1, VPROT_EXEC
| VPROT_COMMITTED
);
765 /***********************************************************************
766 * IsBadStringPtr32A (KERNEL32.355)
768 BOOL32
IsBadStringPtr32A( LPCSTR str
, UINT32 max
)
773 if (!max
) return FALSE
;
774 if (!(view
= VIRTUAL_FindView( (UINT32
)str
))) return TRUE
;
775 page
= ((UINT32
)str
- view
->base
) >> page_shift
;
776 count
= page_mask
+ 1 - ((UINT32
)str
& page_mask
);
780 if ((view
->prot
[page
] & (VPROT_READ
| VPROT_COMMITTED
)) !=
781 (VPROT_READ
| VPROT_COMMITTED
))
783 if (count
> max
) count
= max
;
785 while (count
--) if (!*str
++) return FALSE
;
786 if (++page
>= view
->size
>> page_shift
) return TRUE
;
787 count
= page_mask
+ 1;
793 /***********************************************************************
794 * IsBadStringPtr32W (KERNEL32.356)
796 BOOL32
IsBadStringPtr32W( LPCWSTR str
, UINT32 max
)
801 if (!max
) return FALSE
;
802 if (!(view
= VIRTUAL_FindView( (UINT32
)str
))) return TRUE
;
803 page
= ((UINT32
)str
- view
->base
) >> page_shift
;
804 count
= (page_mask
+ 1 - ((UINT32
)str
& page_mask
)) / sizeof(WCHAR
);
808 if ((view
->prot
[page
] & (VPROT_READ
| VPROT_COMMITTED
)) !=
809 (VPROT_READ
| VPROT_COMMITTED
))
811 if (count
> max
) count
= max
;
813 while (count
--) if (!*str
++) return FALSE
;
814 if (++page
>= view
->size
>> page_shift
) return TRUE
;
815 count
= (page_mask
+ 1) / sizeof(WCHAR
);
821 /***********************************************************************
822 * CreateFileMapping32A (KERNEL32.46)
824 HANDLE32
CreateFileMapping32A( HFILE32 hFile
, LPSECURITY_ATTRIBUTES attr
,
825 DWORD protect
, DWORD size_high
, DWORD size_low
,
828 FILE_MAPPING
*mapping
= NULL
;
831 K32OBJ
*obj
= K32OBJ_FindName( name
);
834 if (obj
->type
== K32OBJ_MEM_MAPPED_FILE
)
836 SetLastError( ERROR_ALREADY_EXISTS
);
837 return PROCESS_AllocHandle( obj
, 0 );
839 SetLastError( ERROR_DUP_NAME
);
843 printf( "CreateFileMapping32A(%x,%p,%08lx,%08lx%08lx,%s)\n",
844 hFile
, attr
, protect
, size_high
, size_low
, name
);
846 if (hFile
== INVALID_HANDLE_VALUE32
)
848 if (!size_high
&& !size_low
)
850 SetLastError( ERROR_INVALID_PARAMETER
);
855 else /* We have a file */
857 BY_HANDLE_FILE_INFORMATION info
;
858 if (!(obj
= PROCESS_GetObjPtr( hFile
, K32OBJ_FILE
))) goto error
;
859 if (!GetFileInformationByHandle( hFile
, &info
)) goto error
;
860 if (!size_high
&& !size_low
)
862 size_high
= info
.nFileSizeHigh
;
863 size_low
= info
.nFileSizeLow
;
865 else if ((size_high
> info
.nFileSizeHigh
) ||
866 ((size_high
== info
.nFileSizeHigh
) &&
867 (size_low
> info
.nFileSizeLow
)))
869 /* We have to grow the file */
870 if (SetFilePointer( hFile
, size_low
, &size_high
,
871 FILE_BEGIN
) == 0xffffffff) goto error
;
872 if (!SetEndOfFile( hFile
)) goto error
;
876 if (!(mapping
= HeapAlloc( SystemHeap
, 0, sizeof(*mapping
) ))) goto error
;
877 mapping
->protect
= VIRTUAL_GetProt( protect
) | VPROT_COMMITTED
;
878 mapping
->size_high
= size_high
;
879 mapping
->size_low
= size_low
;
880 mapping
->file
= (FILE_OBJECT
*)obj
;
882 handle
= PROCESS_AllocHandle( &mapping
->header
, 0 );
883 if (handle
!= INVALID_HANDLE_VALUE32
) return handle
;
886 if (obj
) K32OBJ_DecCount( obj
);
887 if (mapping
) HeapFree( SystemHeap
, 0, mapping
);
892 /***********************************************************************
893 * CreateFileMapping32W (KERNEL32.47)
895 HANDLE32
CreateFileMapping32W( HFILE32 hFile
, LPSECURITY_ATTRIBUTES attr
,
896 DWORD protect
, DWORD size_high
, DWORD size_low
,
899 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
900 HANDLE32 ret
= CreateFileMapping32A( hFile
, attr
, protect
,
901 size_high
, size_low
, nameA
);
902 HeapFree( GetProcessHeap(), 0, nameA
);
907 /***********************************************************************
908 * OpenFileMapping32A (KERNEL32.397)
910 HANDLE32
OpenFileMapping32A( DWORD access
, BOOL32 inherit
, LPCSTR name
)
912 K32OBJ
*obj
= K32OBJ_FindNameType( name
, K32OBJ_MEM_MAPPED_FILE
);
914 return PROCESS_AllocHandle( obj
, 0 );
918 /***********************************************************************
919 * OpenFileMapping32W (KERNEL32.398)
921 HANDLE32
OpenFileMapping32W( DWORD access
, BOOL32 inherit
, LPCWSTR name
)
923 LPSTR nameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
924 HANDLE32 ret
= OpenFileMapping32A( access
, inherit
, nameA
);
925 HeapFree( GetProcessHeap(), 0, nameA
);
930 /***********************************************************************
931 * MapViewOfFile (KERNEL32.385)
933 LPVOID
MapViewOfFile( HANDLE32 mapping
, DWORD access
, DWORD offset_high
,
934 DWORD offset_low
, DWORD count
)
936 return MapViewOfFileEx( mapping
, access
, offset_high
,
937 offset_low
, count
, NULL
);
941 /***********************************************************************
942 * MapViewOfFileEx (KERNEL32.386)
944 LPVOID
MapViewOfFileEx( HANDLE32 handle
, DWORD access
, DWORD offset_high
,
945 DWORD offset_low
, DWORD count
, LPVOID addr
)
947 FILE_MAPPING
*mapping
;
950 if (!(mapping
= (FILE_MAPPING
*)PROCESS_GetObjPtr( handle
,
951 K32OBJ_MEM_MAPPED_FILE
)))
954 ret
= FILE_mmap(mapping
->file
, addr
, mapping
->size_high
, mapping
->size_low
,
955 offset_high
, offset_low
, mapping
->protect
, MAP_PRIVATE
);
957 K32OBJ_DecCount( &mapping
->header
);
962 /***********************************************************************
963 * UnmapViewOfFile (KERNEL32.540)
965 BOOL32
UnmapViewOfFile( LPVOID addr
)
968 UINT32 base
= ROUND_ADDR( addr
);
969 if (!(view
= VIRTUAL_FindView( base
)) || (base
!= view
->base
))
971 SetLastError( ERROR_INVALID_PARAMETER
);
974 VIRTUAL_DeleteView( view
);