Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenres.c
Go to the documentation of this file.
00001 /* 00002 * PE file resources 00003 * 00004 * Copyright 1995 Thomas Sandford 00005 * Copyright 1996 Martin von Loewis 00006 * Copyright 2003 Alexandre Julliard 00007 * Copyright 1993 Robert J. Amstadt 00008 * Copyright 1997 Marcus Meissner 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00023 */ 00024 00025 /* INCLUDES *****************************************************************/ 00026 00027 #include <rtl.h> 00028 00029 #define NDEBUG 00030 #include <debug.h> 00031 00032 NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info, 00033 ULONG level, void **ret, int want_dir ); 00034 00035 /* FUNCTIONS ****************************************************************/ 00036 00037 int page_fault(ULONG ExceptionCode) 00038 { 00039 if (ExceptionCode == EXCEPTION_ACCESS_VIOLATION || 00040 ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) 00041 return EXCEPTION_EXECUTE_HANDLER; 00042 return EXCEPTION_CONTINUE_SEARCH; 00043 } 00044 00045 /********************************************************************** 00046 * is_data_file_module 00047 * 00048 * Check if a module handle is for a LOAD_LIBRARY_AS_DATAFILE module. 00049 */ 00050 static int is_data_file_module( PVOID BaseAddress ) 00051 { 00052 return (ULONG_PTR)BaseAddress & 1; 00053 } 00054 00055 00056 /********************************************************************** 00057 * push_language 00058 * 00059 * push a language in the list of languages to try 00060 */ 00061 int push_language( USHORT *list, ULONG pos, WORD lang ) 00062 { 00063 ULONG i; 00064 for (i = 0; i < pos; i++) if (list[i] == lang) return pos; 00065 list[pos++] = lang; 00066 return pos; 00067 } 00068 00069 00070 /********************************************************************** 00071 * find_first_entry 00072 * 00073 * Find the first suitable entry in a resource directory 00074 */ 00075 IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir, 00076 void *root, int want_dir ) 00077 { 00078 const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); 00079 int pos; 00080 00081 for (pos = 0; pos < dir->NumberOfNamedEntries + dir->NumberOfIdEntries; pos++) 00082 { 00083 if (!entry[pos].DataIsDirectory == !want_dir) 00084 return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory); 00085 } 00086 return NULL; 00087 } 00088 00089 00090 /********************************************************************** 00091 * find_entry_by_id 00092 * 00093 * Find an entry by id in a resource directory 00094 */ 00095 IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir, 00096 WORD id, void *root, int want_dir ) 00097 { 00098 const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry; 00099 int min, max, pos; 00100 00101 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); 00102 min = dir->NumberOfNamedEntries; 00103 max = min + dir->NumberOfIdEntries - 1; 00104 while (min <= max) 00105 { 00106 pos = (min + max) / 2; 00107 if (entry[pos].Id == id) 00108 { 00109 if (!entry[pos].DataIsDirectory == !want_dir) 00110 { 00111 DPRINT("root %p dir %p id %04x ret %p\n", 00112 root, dir, id, (const char*)root + entry[pos].OffsetToDirectory); 00113 return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory); 00114 } 00115 break; 00116 } 00117 if (entry[pos].Id > id) max = pos - 1; 00118 else min = pos + 1; 00119 } 00120 DPRINT("root %p dir %p id %04x not found\n", root, dir, id ); 00121 return NULL; 00122 } 00123 00124 00125 /********************************************************************** 00126 * find_entry_by_name 00127 * 00128 * Find an entry by name in a resource directory 00129 */ 00130 IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir, 00131 LPCWSTR name, void *root, 00132 int want_dir ) 00133 { 00134 const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry; 00135 const IMAGE_RESOURCE_DIR_STRING_U *str; 00136 int min, max, res, pos; 00137 size_t namelen; 00138 00139 if (!((ULONG_PTR)name & 0xFFFF0000)) return find_entry_by_id( dir, (ULONG_PTR)name & 0xFFFF, root, want_dir ); 00140 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); 00141 namelen = wcslen(name); 00142 min = 0; 00143 max = dir->NumberOfNamedEntries - 1; 00144 while (min <= max) 00145 { 00146 pos = (min + max) / 2; 00147 str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const char *)root + entry[pos].NameOffset); 00148 res = _wcsnicmp( name, str->NameString, str->Length ); 00149 if (!res && namelen == str->Length) 00150 { 00151 if (!entry[pos].DataIsDirectory == !want_dir) 00152 { 00153 DPRINT("root %p dir %p name %ws ret %p\n", 00154 root, dir, name, (const char*)root + entry[pos].OffsetToDirectory); 00155 return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory); 00156 } 00157 break; 00158 } 00159 if (res < 0) max = pos - 1; 00160 else min = pos + 1; 00161 } 00162 DPRINT("root %p dir %p name %ws not found\n", root, dir, name); 00163 return NULL; 00164 } 00165 00166 #ifdef __i386__ 00167 NTSTATUS NTAPI LdrpAccessResource( PVOID BaseAddress, IMAGE_RESOURCE_DATA_ENTRY *entry, 00168 void **ptr, ULONG *size ) 00169 #else 00170 static NTSTATUS LdrpAccessResource( PVOID BaseAddress, IMAGE_RESOURCE_DATA_ENTRY *entry, 00171 void **ptr, ULONG *size ) 00172 #endif 00173 { 00174 NTSTATUS status = STATUS_SUCCESS; 00175 00176 _SEH2_TRY 00177 { 00178 ULONG dirsize; 00179 00180 if (!RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize )) 00181 status = STATUS_RESOURCE_DATA_NOT_FOUND; 00182 else 00183 { 00184 if (ptr) 00185 { 00186 if (is_data_file_module(BaseAddress)) 00187 { 00188 PVOID mod = (PVOID)((ULONG_PTR)BaseAddress & ~1); 00189 *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL ); 00190 } 00191 else *ptr = (char *)BaseAddress + entry->OffsetToData; 00192 } 00193 if (size) *size = entry->Size; 00194 } 00195 } 00196 _SEH2_EXCEPT(page_fault(_SEH2_GetExceptionCode())) 00197 { 00198 status = _SEH2_GetExceptionCode(); 00199 } 00200 _SEH2_END; 00201 return status; 00202 } 00203 00204 00205 /* 00206 * @implemented 00207 */ 00208 NTSTATUS NTAPI 00209 LdrFindResource_U(PVOID BaseAddress, 00210 PLDR_RESOURCE_INFO ResourceInfo, 00211 ULONG Level, 00212 PIMAGE_RESOURCE_DATA_ENTRY* ResourceDataEntry) 00213 { 00214 void *res; 00215 NTSTATUS status = STATUS_SUCCESS; 00216 00217 _SEH2_TRY 00218 { 00219 if (ResourceInfo) 00220 { 00221 DPRINT( "module %p type %ws name %ws lang %04lx level %ld\n", 00222 BaseAddress, (LPCWSTR)ResourceInfo->Type, 00223 Level > 1 ? (LPCWSTR)ResourceInfo->Name : L"", 00224 Level > 2 ? ResourceInfo->Language : 0, Level ); 00225 } 00226 00227 status = find_entry( BaseAddress, ResourceInfo, Level, &res, FALSE ); 00228 if (status == STATUS_SUCCESS) *ResourceDataEntry = res; 00229 } 00230 _SEH2_EXCEPT(page_fault(_SEH2_GetExceptionCode())) 00231 { 00232 status = _SEH2_GetExceptionCode(); 00233 } 00234 _SEH2_END; 00235 return status; 00236 } 00237 00238 #ifndef __i386__ 00239 /* 00240 * @implemented 00241 */ 00242 NTSTATUS NTAPI 00243 LdrAccessResource(IN PVOID BaseAddress, 00244 IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, 00245 OUT PVOID* Resource OPTIONAL, 00246 OUT PULONG Size OPTIONAL) 00247 { 00248 return LdrpAccessResource( BaseAddress, ResourceDataEntry, Resource, Size ); 00249 } 00250 #endif 00251 00252 /* 00253 * @implemented 00254 */ 00255 NTSTATUS NTAPI 00256 LdrFindResourceDirectory_U(IN PVOID BaseAddress, 00257 IN PLDR_RESOURCE_INFO info, 00258 IN ULONG level, 00259 OUT PIMAGE_RESOURCE_DIRECTORY* addr) 00260 { 00261 void *res; 00262 NTSTATUS status = STATUS_SUCCESS; 00263 00264 _SEH2_TRY 00265 { 00266 if (info) 00267 { 00268 DPRINT( "module %p type %ws name %ws lang %04lx level %ld\n", 00269 BaseAddress, (LPCWSTR)info->Type, 00270 level > 1 ? (LPCWSTR)info->Name : L"", 00271 level > 2 ? info->Language : 0, level ); 00272 } 00273 00274 status = find_entry( BaseAddress, info, level, &res, TRUE ); 00275 if (status == STATUS_SUCCESS) *addr = res; 00276 } 00277 _SEH2_EXCEPT(page_fault(_SEH2_GetExceptionCode())) 00278 { 00279 status = _SEH2_GetExceptionCode(); 00280 } 00281 _SEH2_END; 00282 return status; 00283 } 00284 00285 00286 /* 00287 * @unimplemented 00288 */ 00289 NTSTATUS NTAPI 00290 LdrEnumResources(IN PVOID BaseAddress, 00291 IN PLDR_RESOURCE_INFO ResourceInfo, 00292 IN ULONG Level, 00293 IN OUT PULONG ResourceCount, 00294 OUT PVOID Resources OPTIONAL) 00295 { 00296 UNIMPLEMENTED; 00297 return STATUS_NOT_IMPLEMENTED; 00298 } Generated on Sat May 26 2012 04:23:07 for ReactOS by
1.7.6.1
|