First version of DLL preloader.
[wincetools.git] / loader / server_mapping.c
index e07afac..3715864 100644 (file)
-/* From wine1.2-1.1.42/server/mapping.c  */
-
-/*
- * Server-side file mapping management
- *
- * Copyright (C) 1999 Alexandre Julliard
- * Copyright 2010 g10 Code GmbH
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "himemce.h"
-#include <assert.h>
-
-/* These are always the same.  */
-# define page_mask  0xfff
-# define page_shift 12
-# define init_page_size() do { /* nothing */ } while(0)
-
-#define set_error(x) SetLastError(x)
-
-#define ROUND_SIZE(size)  (((size) + page_mask) & ~page_mask)
-
-
-
-struct mapping
-{
-  void           *obj;
-  mem_size_t      size;            /* mapping size */
-  int             protect;         /* protection flags */
-  HANDLE         *fhnd;             /* handle for file */
-  HANDLE         *hnd;             /* handle for mapped file */
-  int             header_size;     /* size of headers (for PE image mapping) */
-  void           *base;            /* default base addr (for PE image mapping) */
-};
-
-
-
-/* retrieve the mapping parameters for an executable (PE) image */
-static int get_image_params( struct mapping *mapping, HANDLE unix_fd )
-{
-  IMAGE_DOS_HEADER dos;
-  IMAGE_SECTION_HEADER *sec = NULL;
-  struct
-  {
-    DWORD Signature;
-    IMAGE_FILE_HEADER FileHeader;
-    union
-    {
-      IMAGE_OPTIONAL_HEADER32 hdr32;
-      IMAGE_OPTIONAL_HEADER64 hdr64;
-    } opt;
-  } nt;
-  off_t pos;
-  int size;
-
-    /* load the headers */
-
-    if (pread( unix_fd, (char *) &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;
-    if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;
-    pos = dos.e_lfanew;
-
-    size = pread( unix_fd, (char *) &nt, sizeof(nt), pos );
-    if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) goto error;
-    /* zero out Optional header in the case it's not present or partial */
-    if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );
-    if (nt.Signature != IMAGE_NT_SIGNATURE) goto error;
-
-    switch (nt.opt.hdr32.Magic)
-      {
-      case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
-        mapping->size        = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );
-        mapping->base        = (void *) nt.opt.hdr32.ImageBase;
-        mapping->header_size = nt.opt.hdr32.SizeOfHeaders;
-        break;
-      case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
-        mapping->size        = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );
-        mapping->base        = (void *) nt.opt.hdr64.ImageBase;
-        mapping->header_size = nt.opt.hdr64.SizeOfHeaders;
-        break;
-      default:
-        goto error;
-      }
-
-    /* load the section headers */
-
-    pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;
-    size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
-    if (pos + size > mapping->size) goto error;
-    if (pos + size > mapping->header_size) mapping->header_size = pos + size;
-    if (!(sec = malloc( size ))) goto error;
-    if (pread( unix_fd, (void *) sec, size, pos ) != size) goto error;
-
-    // if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error;
-
-    // if (mapping->shared_file) list_add_head( &shared_list, &mapping->shared_entry );
-
-    mapping->protect = VPROT_IMAGE;
-    free( sec );
-    return 1;
-
- error:
-    free( sec );
-    set_error( STATUS_INVALID_FILE_FOR_SECTION );
-    return 0;
-}
-
-
-void *create_mapping(/* struct directory *root */ void *root,
-                    /* const struct unicode_str *name */ void *name,
-                    unsigned int attr, mem_size_t size, int protect,
-                    HANDLE handle, /* const struct security_descriptor *sd */ void *sd)
-{
-  struct mapping *mapping;
-#if 0
-  struct file *file;
-  struct fd *fd;
-#endif
-  int access = 0;
-#if 0
-  int unix_fd;
-#endif
-
-  if (!page_mask) init_page_size();
-
-  if (!(mapping = malloc (sizeof (struct mapping))))
-    return NULL;
-
-  mapping->obj         = NULL;
-  mapping->header_size = 0;
-  mapping->base        = 0;
-  mapping->fhnd         = handle;
-  mapping->hnd         = 0;
-
-  if (protect & VPROT_READ) access |= FILE_READ_DATA;
-  if (protect & VPROT_WRITE) access |= FILE_WRITE_DATA;
-
-  if (handle)
-    {
-      // unsigned int mapping_access = FILE_MAPPING_ACCESS;
-
-      if (!(protect & VPROT_COMMITTED))
-        {
-         SetLastError( STATUS_INVALID_PARAMETER );
-         goto error;
-        }
-    
-      mapping->hnd = CreateFileMapping (handle, NULL, get_prot_flags (protect),
-                                       0, size, NULL);
-      if (mapping->hnd == INVALID_HANDLE_VALUE)
-       goto error;
-
-#if 0
-      /* file sharing rules for mappings are different so we use magic the access rights */
-      if (protect & VPROT_IMAGE) mapping_access |= FILE_MAPPING_IMAGE;
-      else if (protect & VPROT_WRITE) mapping_access |= FILE_MAPPING_WRITE;
-#endif
-
-      if (protect & VPROT_IMAGE)
-        {
-         if (!get_image_params( mapping, handle )) goto error;
-         return &mapping->obj;
-        }
-#if 0
-      if (fstat( unix_fd, &st ) == -1)
-        {
-         file_set_error();
-         goto error;
-        }
-      if (!size)
-        {
-         if (!(size = st.st_size))
-            {
-             set_error( STATUS_MAPPED_FILE_SIZE_ZERO );
-             goto error;
-            }
-        }
-      else if (st.st_size < size && !grow_file( unix_fd, size )) goto error;
-#endif
-    }
-  else  /* Anonymous mapping (no associated file) */
-    {
-#if 0
-      if (!size || (protect & VPROT_IMAGE))
-        {
-         set_error( STATUS_INVALID_PARAMETER );
-         goto error;
-        }
-      if (!(protect & VPROT_COMMITTED))
-        {
-         if (!(mapping->committed = mem_alloc( offsetof(struct ranges, ranges[8]) ))) goto error;
-         mapping->committed->count = 0;
-         mapping->committed->max   = 8;
-        }
-      if ((unix_fd = create_temp_file( size )) == -1) goto error;
-      if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj,
-                                              FILE_SYNCHRONOUS_IO_NONALERT ))) goto error;
-#endif
-      assert (!"Not implemented.");
-    }
-  mapping->size    = (size + page_mask) & ~((mem_size_t)page_mask);
-  mapping->protect = protect;
-  return &mapping->obj;
-  
- error:
-  free( mapping );
-  return NULL;
-}
-
-
-/* create a file mapping */
-NTSTATUS SERVER_create_mapping (ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
-                               HANDLE file_handle, long long size, unsigned int protect, HANDLE *handle)
-{
-  void *obj;
-  
-  *handle = 0;
-
-  obj = create_mapping( NULL, NULL, 0, (mem_size_t) size, protect, file_handle, NULL );
-  if (! obj)
-    return GetLastError ();
-
-  *handle = (HANDLE)obj;
-
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS SERVER_get_mapping_info (HANDLE _mapping, ACCESS_MASK access, unsigned int *protect,
-                                 void **base, mem_size_t *size, int *header_size, HANDLE *fhandle,
-                                 HANDLE *handle)
-{
-  struct mapping *mapping = (struct mapping *) _mapping;
-
-  /* Ignore access.  */
-
-  *size        = mapping->size;
-  *protect     = mapping->protect;
-  *fhandle     = mapping->fhnd;
-  *handle     = mapping->hnd;
-  *header_size = mapping->header_size;
-  *base        = mapping->base;
-
-  return STATUS_SUCCESS;
-}
-
+/* From wine1.2-1.1.42/server/mapping.c  */\r
+\r
+/*\r
+ * Server-side file mapping management\r
+ *\r
+ * Copyright (C) 1999 Alexandre Julliard\r
+ * Copyright 2010 g10 Code GmbH\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+\r
+#include "wine.h"\r
+#include <assert.h>\r
+\r
+/* These are always the same.  */\r
+# define page_mask  0xfff\r
+# define page_shift 12\r
+# define init_page_size() do { /* nothing */ } while(0)\r
+\r
+#define set_error(x) SetLastError(x)\r
+\r
+#define ROUND_SIZE(size)  (((size) + page_mask) & ~page_mask)\r
+\r
+\r
+\r
+struct mapping\r
+{\r
+  void           *obj;\r
+  mem_size_t      size;            /* mapping size */\r
+  int             protect;         /* protection flags */\r
+  HANDLE         *fhnd;             /* handle for file */\r
+  HANDLE         *hnd;             /* handle for mapped file */\r
+  int             header_size;     /* size of headers (for PE image mapping) */\r
+  void           *base;            /* default base addr (for PE image mapping) */\r
+};\r
+\r
+\r
+\r
+/* retrieve the mapping parameters for an executable (PE) image */\r
+static int get_image_params( struct mapping *mapping, HANDLE unix_fd )\r
+{\r
+  IMAGE_DOS_HEADER dos;\r
+  IMAGE_SECTION_HEADER *sec = NULL;\r
+  struct\r
+  {\r
+    DWORD Signature;\r
+    IMAGE_FILE_HEADER FileHeader;\r
+    union\r
+    {\r
+      IMAGE_OPTIONAL_HEADER32 hdr32;\r
+      IMAGE_OPTIONAL_HEADER64 hdr64;\r
+    } opt;\r
+  } nt;\r
+  off_t pos;\r
+  int size;\r
+\r
+    /* load the headers */\r
+\r
+    if (pread( unix_fd, (char *) &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;\r
+    if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;\r
+    pos = dos.e_lfanew;\r
+\r
+    size = pread( unix_fd, (char *) &nt, sizeof(nt), pos );\r
+    if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) goto error;\r
+    /* zero out Optional header in the case it's not present or partial */\r
+    if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );\r
+    if (nt.Signature != IMAGE_NT_SIGNATURE) goto error;\r
+\r
+    switch (nt.opt.hdr32.Magic)\r
+      {\r
+      case IMAGE_NT_OPTIONAL_HDR32_MAGIC:\r
+        mapping->size        = ROUND_SIZE( nt.opt.hdr32.SizeOfImage );\r
+        mapping->base        = (void *) nt.opt.hdr32.ImageBase;\r
+        mapping->header_size = nt.opt.hdr32.SizeOfHeaders;\r
+        break;\r
+      case IMAGE_NT_OPTIONAL_HDR64_MAGIC:\r
+        mapping->size        = ROUND_SIZE( nt.opt.hdr64.SizeOfImage );\r
+        mapping->base        = (void *) nt.opt.hdr64.ImageBase;\r
+        mapping->header_size = nt.opt.hdr64.SizeOfHeaders;\r
+        break;\r
+      default:\r
+        goto error;\r
+      }\r
+\r
+    /* load the section headers */\r
+\r
+    pos += sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader;\r
+    size = sizeof(*sec) * nt.FileHeader.NumberOfSections;\r
+    if (pos + size > mapping->size) goto error;\r
+    if (pos + size > mapping->header_size) mapping->header_size = pos + size;\r
+    if (!(sec = malloc( size ))) goto error;\r
+    if (pread( unix_fd, (void *) sec, size, pos ) != size) goto error;\r
+\r
+    // if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error;\r
+\r
+    // if (mapping->shared_file) list_add_head( &shared_list, &mapping->shared_entry );\r
+\r
+    mapping->protect = VPROT_IMAGE;\r
+    free( sec );\r
+    return 1;\r
+\r
+ error:\r
+    free( sec );\r
+    set_error( STATUS_INVALID_FILE_FOR_SECTION );\r
+    return 0;\r
+}\r
+\r
+\r
+void *create_mapping(/* struct directory *root */ void *root,\r
+                    /* const struct unicode_str *name */ void *name,\r
+                    unsigned int attr, mem_size_t size, int protect,\r
+                    HANDLE handle, /* const struct security_descriptor *sd */ void *sd)\r
+{\r
+  struct mapping *mapping;\r
+#if 0\r
+  struct file *file;\r
+  struct fd *fd;\r
+#endif\r
+  int access = 0;\r
+#if 0\r
+  int unix_fd;\r
+#endif\r
+\r
+  if (!page_mask) init_page_size();\r
+\r
+  if (!(mapping = malloc (sizeof (struct mapping))))\r
+    return NULL;\r
+\r
+  mapping->obj         = NULL;\r
+  mapping->header_size = 0;\r
+  mapping->base        = 0;\r
+  mapping->fhnd        = handle;\r
+  mapping->hnd         = 0;\r
+\r
+  if (protect & VPROT_READ) access |= FILE_READ_DATA;\r
+  if (protect & VPROT_WRITE) access |= FILE_WRITE_DATA;\r
+\r
+  if (handle)\r
+    {\r
+      // unsigned int mapping_access = FILE_MAPPING_ACCESS;\r
+\r
+      if (!(protect & VPROT_COMMITTED))\r
+        {\r
+         SetLastError( STATUS_INVALID_PARAMETER );\r
+         goto error;\r
+        }\r
+    \r
+      mapping->hnd = CreateFileMapping (handle, NULL, get_prot_flags (protect),\r
+                                       0, size, NULL);\r
+      if (mapping->hnd == INVALID_HANDLE_VALUE)\r
+       goto error;\r
+\r
+#if 0\r
+      /* file sharing rules for mappings are different so we use magic the access rights */\r
+      if (protect & VPROT_IMAGE) mapping_access |= FILE_MAPPING_IMAGE;\r
+      else if (protect & VPROT_WRITE) mapping_access |= FILE_MAPPING_WRITE;\r
+#endif\r
+\r
+      if (protect & VPROT_IMAGE)\r
+        {\r
+         if (!get_image_params( mapping, handle )) goto error;\r
+         return &mapping->obj;\r
+        }\r
+#if 0\r
+      if (fstat( unix_fd, &st ) == -1)\r
+        {\r
+         file_set_error();\r
+         goto error;\r
+        }\r
+      if (!size)\r
+        {\r
+         if (!(size = st.st_size))\r
+            {\r
+             set_error( STATUS_MAPPED_FILE_SIZE_ZERO );\r
+             goto error;\r
+            }\r
+        }\r
+      else if (st.st_size < size && !grow_file( unix_fd, size )) goto error;\r
+#endif\r
+    }\r
+  else  /* Anonymous mapping (no associated file) */\r
+    {\r
+#if 0\r
+      if (!size || (protect & VPROT_IMAGE))\r
+        {\r
+         set_error( STATUS_INVALID_PARAMETER );\r
+         goto error;\r
+        }\r
+      if (!(protect & VPROT_COMMITTED))\r
+        {\r
+         if (!(mapping->committed = mem_alloc( offsetof(struct ranges, ranges[8]) ))) goto error;\r
+         mapping->committed->count = 0;\r
+         mapping->committed->max   = 8;\r
+        }\r
+      if ((unix_fd = create_temp_file( size )) == -1) goto error;\r
+      if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj,\r
+                                              FILE_SYNCHRONOUS_IO_NONALERT ))) goto error;\r
+#endif\r
+      assert (!"Not implemented.");\r
+    }\r
+  mapping->size    = (size + page_mask) & ~((mem_size_t)page_mask);\r
+  mapping->protect = protect;\r
+  return &mapping->obj;\r
+  \r
+ error:\r
+  free( mapping );\r
+  return NULL;\r
+}\r
+\r
+\r
+/* create a file mapping */\r
+NTSTATUS SERVER_create_mapping (ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,\r
+                               HANDLE file_handle, long long size, unsigned int protect, HANDLE *handle)\r
+{\r
+  void *obj;\r
+  \r
+  *handle = 0;\r
+\r
+  obj = create_mapping( NULL, NULL, 0, (mem_size_t) size, protect, file_handle, NULL );\r
+  if (! obj)\r
+    return GetLastError ();\r
+\r
+  *handle = (HANDLE)obj;\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+NTSTATUS SERVER_get_mapping_info (HANDLE _mapping, ACCESS_MASK access, unsigned int *protect,\r
+                                 void **base, mem_size_t *size, int *header_size, HANDLE *fhandle,\r
+                                 HANDLE *handle)\r
+{\r
+  struct mapping *mapping = (struct mapping *) _mapping;\r
+\r
+  /* Ignore access.  */\r
+\r
+  *size        = mapping->size;\r
+  *protect     = mapping->protect;\r
+  *fhandle     = mapping->fhnd;\r
+  *handle      = mapping->hnd;\r
+  *header_size = mapping->header_size;\r
+  *base        = mapping->base;\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r