ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

assembly.c
Go to the documentation of this file.
00001 /*
00002  * assembly parser
00003  *
00004  * Copyright 2008 James Hawkins
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include <stdarg.h>
00022 #include <stdio.h>
00023 
00024 #include "windef.h"
00025 #include "winbase.h"
00026 #include "winuser.h"
00027 #include "winver.h"
00028 #include "dbghelp.h"
00029 #include "ole2.h"
00030 #include "mscoree.h"
00031 #include "corhdr.h"
00032 #include "metahost.h"
00033 #include "cordebug.h"
00034 #include "wine/list.h"
00035 #include "mscoree_private.h"
00036 
00037 #include "wine/debug.h"
00038 #include "wine/unicode.h"
00039 
00040 typedef struct
00041 {
00042     ULONG Signature;
00043     USHORT MajorVersion;
00044     USHORT MinorVersion;
00045     ULONG Reserved;
00046     ULONG VersionLength;
00047     LPSTR Version;
00048     BYTE Flags;
00049     WORD Streams;
00050 } METADATAHDR;
00051 
00052 typedef struct
00053 {
00054     DWORD Offset;
00055     DWORD Size;
00056 } METADATASTREAMHDR;
00057 
00058 typedef struct tagCLRTABLE
00059 {
00060     INT rows;
00061     DWORD offset;
00062 } CLRTABLE;
00063 
00064 struct tagASSEMBLY
00065 {
00066     LPWSTR path;
00067 
00068     HANDLE hfile;
00069     HANDLE hmap;
00070     BYTE *data;
00071 
00072     IMAGE_NT_HEADERS *nthdr;
00073     IMAGE_COR20_HEADER *corhdr;
00074 
00075     METADATAHDR *metadatahdr;
00076 };
00077 
00078 static inline LPWSTR strdupW(LPCWSTR src)
00079 {
00080     LPWSTR dest;
00081 
00082     if (!src)
00083         return NULL;
00084 
00085     dest = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src) + 1) * sizeof(WCHAR));
00086     if (dest)
00087         lstrcpyW(dest, src);
00088 
00089     return dest;
00090 }
00091 
00092 static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz)
00093 {
00094     METADATAHDR *metadatahdr;
00095     BYTE *ptr, *dest;
00096     DWORD size, ofs;
00097     ULONG rva;
00098 
00099     rva = assembly->corhdr->MetaData.VirtualAddress;
00100     ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
00101     if (!ptr)
00102         return E_FAIL;
00103 
00104     metadatahdr = (METADATAHDR *)ptr;
00105 
00106     assembly->metadatahdr = HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR));
00107     if (!assembly->metadatahdr)
00108         return E_OUTOFMEMORY;
00109 
00110     size = FIELD_OFFSET(METADATAHDR, Version);
00111     memcpy(assembly->metadatahdr, metadatahdr, size);
00112 
00113     assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version;
00114 
00115     ofs = FIELD_OFFSET(METADATAHDR, Flags);
00116     ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1;
00117     dest = (BYTE *)assembly->metadatahdr + ofs;
00118     memcpy(dest, ptr, sizeof(METADATAHDR) - ofs);
00119 
00120     *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1;
00121 
00122     return S_OK;
00123 }
00124 
00125 static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
00126 {
00127     HRESULT hr;
00128     DWORD hdrsz;
00129 
00130     hr = parse_metadata_header(assembly, &hdrsz);
00131     if (FAILED(hr))
00132         return hr;
00133 
00134     return S_OK;
00135 }
00136 
00137 static HRESULT parse_pe_header(ASSEMBLY *assembly)
00138 {
00139     IMAGE_DATA_DIRECTORY *datadirs;
00140 
00141     assembly->nthdr = ImageNtHeader(assembly->data);
00142     if (!assembly->nthdr)
00143         return E_FAIL;
00144 
00145     if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
00146     {
00147         IMAGE_OPTIONAL_HEADER64 *opthdr =
00148                 (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
00149         datadirs = opthdr->DataDirectory;
00150     }
00151     else
00152     {
00153         IMAGE_OPTIONAL_HEADER32 *opthdr =
00154                 (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
00155         datadirs = opthdr->DataDirectory;
00156     }
00157 
00158     if (!datadirs)
00159         return E_FAIL;
00160 
00161     if (!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress ||
00162         !datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
00163     {
00164         return E_FAIL;
00165     }
00166 
00167     assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data,
00168         datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress, NULL);
00169     if (!assembly->corhdr)
00170         return E_FAIL;
00171 
00172     return S_OK;
00173 }
00174 
00175 HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
00176 {
00177     ASSEMBLY *assembly;
00178     HRESULT hr;
00179 
00180     *out = NULL;
00181 
00182     assembly = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ASSEMBLY));
00183     if (!assembly)
00184         return E_OUTOFMEMORY;
00185 
00186     assembly->path = strdupW(file);
00187     if (!assembly->path)
00188     {
00189         hr = E_OUTOFMEMORY;
00190         goto failed;
00191     }
00192 
00193     assembly->hfile = CreateFileW(file, GENERIC_READ, FILE_SHARE_READ,
00194                                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00195     if (assembly->hfile == INVALID_HANDLE_VALUE)
00196     {
00197         hr = HRESULT_FROM_WIN32(GetLastError());
00198         goto failed;
00199     }
00200 
00201     assembly->hmap = CreateFileMappingW(assembly->hfile, NULL, PAGE_READONLY,
00202                                         0, 0, NULL);
00203     if (!assembly->hmap)
00204     {
00205         hr = HRESULT_FROM_WIN32(GetLastError());
00206         goto failed;
00207     }
00208 
00209     assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0);
00210     if (!assembly->data)
00211     {
00212         hr = HRESULT_FROM_WIN32(GetLastError());
00213         goto failed;
00214     }
00215 
00216     hr = parse_pe_header(assembly);
00217     if (FAILED(hr)) goto failed;
00218 
00219     hr = parse_clr_metadata(assembly);
00220     if (FAILED(hr)) goto failed;
00221 
00222     *out = assembly;
00223     return S_OK;
00224 
00225 failed:
00226     assembly_release(assembly);
00227     return hr;
00228 }
00229 
00230 HRESULT assembly_release(ASSEMBLY *assembly)
00231 {
00232     if (!assembly)
00233         return S_OK;
00234 
00235     HeapFree(GetProcessHeap(), 0, assembly->metadatahdr);
00236     HeapFree(GetProcessHeap(), 0, assembly->path);
00237     UnmapViewOfFile(assembly->data);
00238     CloseHandle(assembly->hmap);
00239     CloseHandle(assembly->hfile);
00240     HeapFree(GetProcessHeap(), 0, assembly);
00241 
00242     return S_OK;
00243 }
00244 
00245 HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
00246 {
00247     *version = assembly->metadatahdr->Version;
00248 
00249     return S_OK;
00250 }

Generated on Mon May 28 2012 04:23:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.