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

res.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 doxygen 1.7.6.1

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