2 * Server-side file mapping management
4 * Copyright (C) 1999 Alexandre Julliard
15 #include "server/process.h"
16 #include "server/thread.h"
20 struct object obj
; /* object header */
21 int size_high
; /* mapping size */
22 int size_low
; /* mapping size */
23 int protect
; /* protection flags */
24 struct file
*file
; /* file mapped */
27 static void mapping_dump( struct object
*obj
, int verbose
);
28 static void mapping_destroy( struct object
*obj
);
30 static const struct object_ops mapping_ops
=
34 NULL
, /* should never get called */
35 NULL
, /* should never get called */
36 NULL
, /* should never get called */
46 /* These are always the same on an i386, and it will be faster this way */
47 # define page_mask 0xfff
48 # define page_shift 12
49 # define init_page_size() /* nothing */
53 static int page_shift
, page_mask
;
55 static void init_page_size(void)
58 # ifdef HAVE_GETPAGESIZE
59 page_size
= getpagesize();
62 page_size
= sysconf(_SC_PAGESIZE
);
64 # error Cannot get the page size on this platform
67 page_mask
= page_size
- 1;
68 /* Make sure we have a power of 2 */
69 assert( !(page_size
& page_mask
) );
71 while ((1 << page_shift
) != page_size
) page_shift
++;
75 #define ROUND_ADDR(addr) \
76 ((int)(addr) & ~page_mask)
78 #define ROUND_SIZE(addr,size) \
79 (((int)(size) + ((int)(addr) & page_mask) + page_mask) & ~page_mask)
82 struct object
*create_mapping( int size_high
, int size_low
, int protect
,
83 int handle
, const char *name
)
85 struct mapping
*mapping
;
88 if (!page_mask
) init_page_size();
90 if (!(mapping
= (struct mapping
*)create_named_object( name
, &mapping_ops
,
93 if (GET_ERROR() == ERROR_ALREADY_EXISTS
)
94 return &mapping
->obj
; /* Nothing else to do */
96 if (protect
& VPROT_READ
) access
|= GENERIC_READ
;
97 if (protect
& VPROT_WRITE
) access
|= GENERIC_WRITE
;
99 size_low
= ROUND_SIZE( 0, size_low
);
102 if (!(mapping
->file
= get_file_obj( current
->process
, handle
, access
))) goto error
;
103 if (!size_high
&& !size_low
)
105 struct get_file_info_reply reply
;
106 struct object
*obj
= (struct object
*)mapping
->file
;
107 obj
->ops
->get_file_info( obj
, &reply
);
108 size_high
= reply
.size_high
;
109 size_low
= ROUND_SIZE( 0, reply
.size_low
);
111 else if (!grow_file( mapping
->file
, size_high
, size_low
)) goto error
;
113 else /* Anonymous mapping (no associated file) */
115 if (!size_high
&& !size_low
)
117 SET_ERROR( ERROR_INVALID_PARAMETER
);
118 mapping
->file
= NULL
;
121 if (!(mapping
->file
= create_temp_file( access
))) goto error
;
122 if (!grow_file( mapping
->file
, size_high
, size_low
)) goto error
;
124 mapping
->size_high
= size_high
;
125 mapping
->size_low
= size_low
;
126 mapping
->protect
= protect
;
127 return &mapping
->obj
;
130 release_object( mapping
);
134 int open_mapping( unsigned int access
, int inherit
, const char *name
)
136 return open_object( name
, &mapping_ops
, access
, inherit
);
139 int get_mapping_info( int handle
, struct get_mapping_info_reply
*reply
)
141 struct mapping
*mapping
;
144 if (!(mapping
= (struct mapping
*)get_handle_obj( current
->process
, handle
,
147 reply
->size_high
= mapping
->size_high
;
148 reply
->size_low
= mapping
->size_low
;
149 reply
->protect
= mapping
->protect
;
150 if (mapping
->file
) fd
= file_get_mmap_fd( mapping
->file
);
152 release_object( mapping
);
156 static void mapping_dump( struct object
*obj
, int verbose
)
158 struct mapping
*mapping
= (struct mapping
*)obj
;
159 assert( obj
->ops
== &mapping_ops
);
160 fprintf( stderr
, "Mapping size=%08x%08x prot=%08x file=%p name='%s'\n",
161 mapping
->size_high
, mapping
->size_low
, mapping
->protect
,
162 mapping
->file
, get_object_name( &mapping
->obj
) );
165 static void mapping_destroy( struct object
*obj
)
167 struct mapping
*mapping
= (struct mapping
*)obj
;
168 assert( obj
->ops
== &mapping_ops
);
169 if (mapping
->file
) release_object( mapping
->file
);