Repaired shared PE data sections.
diff --git a/server/mapping.c b/server/mapping.c
index 2bfdd77..c87c6d3 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -19,15 +19,17 @@
struct mapping
{
- struct object obj; /* object header */
- int size_high; /* mapping size */
- int size_low; /* mapping size */
- int protect; /* protection flags */
- struct file *file; /* file mapped */
- int header_size; /* size of headers (for PE image mapping) */
- void *base; /* default base addr (for PE image mapping) */
- struct file *shared_file; /* temp file for shared PE mapping */
- int shared_size; /* shared mapping total size */
+ struct object obj; /* object header */
+ int size_high; /* mapping size */
+ int size_low; /* mapping size */
+ int protect; /* protection flags */
+ struct file *file; /* file mapped */
+ int header_size; /* size of headers (for PE image mapping) */
+ void *base; /* default base addr (for PE image mapping) */
+ struct file *shared_file; /* temp file for shared PE mapping */
+ int shared_size; /* shared mapping total size */
+ struct mapping *shared_next; /* next in shared PE mapping list */
+ struct mapping *shared_prev; /* prev in shared PE mapping list */
};
static int mapping_get_fd( struct object *obj );
@@ -50,6 +52,8 @@
mapping_destroy /* destroy */
};
+static struct mapping *shared_first;
+
#ifdef __i386__
/* These are always the same on an i386, and it will be faster this way */
@@ -99,6 +103,17 @@
return obj->ops->get_fd( obj );
}
+/* find the shared PE mapping for a given mapping */
+static struct file *get_shared_file( struct mapping *mapping )
+{
+ struct mapping *ptr;
+
+ for (ptr = shared_first; ptr; ptr = ptr->shared_next)
+ if (is_same_file( ptr->file, mapping->file ))
+ return (struct file *)grab_object( ptr->shared_file );
+ return NULL;
+}
+
/* allocate and fill the temp file for a shared PE image mapping */
static int build_shared_mapping( struct mapping *mapping, int fd,
IMAGE_SECTION_HEADER *sec, int nb_sec )
@@ -123,6 +138,8 @@
}
if (!(mapping->shared_size = total_size)) return 1; /* nothing to do */
+ if ((mapping->shared_file = get_shared_file( mapping ))) return 1;
+
/* create a temp file for the mapping */
if (!(mapping->shared_file = create_temp_file( GENERIC_READ|GENERIC_WRITE ))) goto error;
@@ -185,6 +202,13 @@
if (!build_shared_mapping( mapping, fd, sec, nt.FileHeader.NumberOfSections )) goto error;
+ if (mapping->shared_file) /* link it in the list */
+ {
+ if ((mapping->shared_next = shared_first)) shared_first->shared_prev = mapping;
+ mapping->shared_prev = NULL;
+ shared_first = mapping;
+ }
+
mapping->size_low = ROUND_SIZE( 0, nt.OptionalHeader.SizeOfImage );
mapping->size_high = 0;
mapping->base = (void *)nt.OptionalHeader.ImageBase;
@@ -290,7 +314,13 @@
struct mapping *mapping = (struct mapping *)obj;
assert( obj->ops == &mapping_ops );
if (mapping->file) release_object( mapping->file );
- if (mapping->shared_file) release_object( mapping->shared_file );
+ if (mapping->shared_file)
+ {
+ release_object( mapping->shared_file );
+ if (mapping->shared_next) mapping->shared_next->shared_prev = mapping->shared_prev;
+ if (mapping->shared_prev) mapping->shared_prev->shared_next = mapping->shared_next;
+ else shared_first = mapping->shared_next;
+ }
}
int get_page_size(void)