Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenassembly.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
1.7.6.1
|