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 );