Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ldrrsrc.c File Reference

#include "ntrtlp.h"

Go to the source code of this file.

Defines

#define MEMBLOCKSIZE   16
#define RESMODSIZE   sizeof(ALT_RESOURCE_MODULE)
#define USE_FIRSTAVAILABLE_LANGID   (0xFFFFFFFF & ~LDR_RESOURCE_ID_NAME_MASK)

Functions

NTSTATUS LdrAccessResource (IN PVOID DllHandle, IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, OUT PVOID *Address OPTIONAL, OUT PULONG Size OPTIONAL)
NTSTATUS LdrpAccessResourceData (IN PVOID DllHandle, IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, OUT PVOID *Address OPTIONAL, OUT PULONG Size OPTIONAL)
NTSTATUS LdrFindEntryForAddress (IN PVOID Address, OUT PLDR_DATA_TABLE_ENTRY *TableEntry)
NTSTATUS LdrFindResource_U (IN PVOID DllHandle, IN PULONG_PTR ResourceIdPath, IN ULONG ResourceIdPathLength, OUT PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
NTSTATUS LdrFindResourceDirectory_U (IN PVOID DllHandle, IN PULONG_PTR ResourceIdPath, IN ULONG ResourceIdPathLength, OUT PIMAGE_RESOURCE_DIRECTORY *ResourceDirectory)
LONG LdrpCompareResourceNames_U (IN ULONG_PTR ResourceName, IN PIMAGE_RESOURCE_DIRECTORY ResourceDirectory, IN PIMAGE_RESOURCE_DIRECTORY_ENTRY ResourceDirectoryEntry)
NTSTATUS LdrpSearchResourceSection_U (IN PVOID DllHandle, IN PULONG_PTR ResourceIdPath, IN ULONG ResourceIdPathLength, IN BOOLEAN FindDirectoryEntry, IN BOOLEAN ExactLangMatchOnly, OUT PVOID *ResourceDirectoryOrData)
NTSTATUS LdrEnumResources (IN PVOID DllHandle, IN PULONG_PTR ResourceIdPath, IN ULONG ResourceIdPathLength, IN OUT PULONG NumberOfResources, OUT PLDR_ENUM_RESOURCE_ENTRY Resources OPTIONAL)
BOOLEAN LdrAlternateResourcesEnabled (VOID)
PVOID LdrGetAlternateResourceModuleHandle (IN PVOID Module)
BOOLEAN LdrpGetFileVersion (IN PVOID ImageBase, IN LANGID LangId, OUT PULONGLONG Version)
BOOLEAN LdrpVerifyAlternateResourceModule (IN PVOID Module, IN PVOID AlternateModule)
BOOLEAN LdrpSetAlternateResourceModuleHandle (IN PVOID Module, IN PVOID AlternateModule)
PVOID LdrLoadAlternateResourceModule (IN PVOID Module, IN LPCWSTR PathToAlternateModule OPTIONAL)
BOOLEAN LdrUnloadAlternateResourceModule (IN PVOID Module)
BOOLEAN LdrFlushAlternateResourceModules (VOID)

Variables

PALT_RESOURCE_MODULE AlternateResourceModules
ULONG AlternateResourceModuleCount
ULONG AltResMemBlockCount
LANGID UILangId
LANGID InstallLangId


Define Documentation

#define MEMBLOCKSIZE   16
 

Definition at line 41 of file ldrrsrc.c.

Referenced by LdrpSetAlternateResourceModuleHandle(), and LdrUnloadAlternateResourceModule().

#define RESMODSIZE   sizeof(ALT_RESOURCE_MODULE)
 

Definition at line 42 of file ldrrsrc.c.

Referenced by LdrpSetAlternateResourceModuleHandle(), and LdrUnloadAlternateResourceModule().

#define USE_FIRSTAVAILABLE_LANGID   (0xFFFFFFFF & ~LDR_RESOURCE_ID_NAME_MASK)
 

Definition at line 489 of file ldrrsrc.c.

Referenced by LdrpSearchResourceSection_U().


Function Documentation

NTSTATUS LdrAccessResource IN PVOID  DllHandle,
IN PIMAGE_RESOURCE_DATA_ENTRY  ResourceDataEntry,
OUT PVOID *Address  OPTIONAL,
OUT PULONG Size  OPTIONAL
 

Definition at line 47 of file ldrrsrc.c.

References LdrpAccessResourceData(), RTL_PAGED_CODE, and Size.

00056 : 00057 00058 This function locates the address of the specified resource in the 00059 specified DLL and returns its address. 00060 00061 Arguments: 00062 00063 DllHandle - Supplies a handle to the image file that the resource is 00064 contained in. 00065 00066 ResourceDataEntry - Supplies a pointer to the resource data entry in 00067 the resource data section of the image file specified by the 00068 DllHandle parameter. This pointer should have been one returned 00069 by the LdrFindResource function. 00070 00071 Address - Optional pointer to a variable that will receive the 00072 address of the resource specified by the first two parameters. 00073 00074 Size - Optional pointer to a variable that will receive the size of 00075 the resource specified by the first two parameters. 00076 00077 Return Value: 00078 00079 TBD 00080 00081 --*/ 00082 00083 { 00084 RTL_PAGED_CODE(); 00085 00086 return LdrpAccessResourceData( 00087 DllHandle, 00088 ResourceDataEntry, 00089 Address, 00090 Size 00091 ); 00092 }

BOOLEAN LdrAlternateResourcesEnabled VOID   ) 
 

Definition at line 1220 of file ldrrsrc.c.

References FALSE, InstallLangId, NT_SUCCESS, NtQueryDefaultUILanguage(), NtQueryInstallUILanguage(), NTSTATUS(), Status, TRUE, and UILangId.

Referenced by LdrLoadAlternateResourceModule().

01226 : 01227 01228 This function determines if the althernate resources are enabled. 01229 01230 Arguments: 01231 01232 None. 01233 01234 Return Value: 01235 01236 True - Alternate Resource enabled. 01237 False - Alternate Resource not enabled. 01238 01239 --*/ 01240 01241 { 01242 NTSTATUS Status; 01243 01244 if (!UILangId){ 01245 Status = NtQueryDefaultUILanguage( &UILangId ); 01246 01247 if (!NT_SUCCESS( Status )) { 01248 // 01249 // Failed to get UI LangID. AltResource not enabled. 01250 // 01251 return FALSE; 01252 } 01253 } 01254 01255 if (!InstallLangId){ 01256 Status = NtQueryInstallUILanguage( &InstallLangId); 01257 01258 if (!NT_SUCCESS( Status )) { 01259 // 01260 // Failed to get Intall LangID. AltResource not enabled. 01261 // 01262 return FALSE; 01263 } 01264 } 01265 01266 if (UILangId == InstallLangId) { 01267 // 01268 // UI Lang matches Installed Lang. AltResource not enabled. 01269 // 01270 return FALSE; 01271 } 01272 01273 return TRUE; 01274 }

NTSTATUS LdrEnumResources IN PVOID  DllHandle,
IN PULONG_PTR  ResourceIdPath,
IN ULONG  ResourceIdPathLength,
IN OUT PULONG  NumberOfResources,
OUT PLDR_ENUM_RESOURCE_ENTRY Resources  OPTIONAL
 

Definition at line 1039 of file ldrrsrc.c.

References LdrpCompareResourceNames_U(), NTSTATUS(), RtlImageDirectoryEntryToData(), Size, Status, and TRUE.

01046 { 01047 NTSTATUS Status; 01048 PIMAGE_RESOURCE_DIRECTORY TopResourceDirectory; 01049 PIMAGE_RESOURCE_DIRECTORY TypeResourceDirectory; 01050 PIMAGE_RESOURCE_DIRECTORY NameResourceDirectory; 01051 PIMAGE_RESOURCE_DIRECTORY LangResourceDirectory; 01052 PIMAGE_RESOURCE_DIRECTORY_ENTRY TypeResourceDirectoryEntry; 01053 PIMAGE_RESOURCE_DIRECTORY_ENTRY NameResourceDirectoryEntry; 01054 PIMAGE_RESOURCE_DIRECTORY_ENTRY LangResourceDirectoryEntry; 01055 ULONG TypeDirectoryIndex, NumberOfTypeDirectoryEntries; 01056 ULONG NameDirectoryIndex, NumberOfNameDirectoryEntries; 01057 ULONG LangDirectoryIndex, NumberOfLangDirectoryEntries; 01058 BOOLEAN ScanTypeDirectory; 01059 BOOLEAN ScanNameDirectory; 01060 BOOLEAN ReturnThisResource; 01061 PIMAGE_RESOURCE_DIR_STRING_U ResourceNameString; 01062 ULONG_PTR TypeResourceNameOrId; 01063 ULONG_PTR NameResourceNameOrId; 01064 ULONG_PTR LangResourceNameOrId; 01065 PLDR_ENUM_RESOURCE_ENTRY ResourceInfo; 01066 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; 01067 ULONG ResourceIndex, MaxResourceIndex; 01068 ULONG Size; 01069 01070 ResourceIndex = 0; 01071 if (!ARGUMENT_PRESENT( Resources )) { 01072 MaxResourceIndex = 0; 01073 } 01074 else { 01075 MaxResourceIndex = *NumberOfResources; 01076 } 01077 *NumberOfResources = 0; 01078 01079 TopResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 01080 RtlImageDirectoryEntryToData( DllHandle, 01081 TRUE, 01082 IMAGE_DIRECTORY_ENTRY_RESOURCE, 01083 &Size 01084 ); 01085 if (!TopResourceDirectory) { 01086 return STATUS_RESOURCE_DATA_NOT_FOUND; 01087 } 01088 01089 TypeResourceDirectory = TopResourceDirectory; 01090 TypeResourceDirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(TypeResourceDirectory+1); 01091 NumberOfTypeDirectoryEntries = TypeResourceDirectory->NumberOfNamedEntries + 01092 TypeResourceDirectory->NumberOfIdEntries; 01093 TypeDirectoryIndex = 0; 01094 Status = STATUS_SUCCESS; 01095 for (TypeDirectoryIndex=0; 01096 TypeDirectoryIndex<NumberOfTypeDirectoryEntries; 01097 TypeDirectoryIndex++, TypeResourceDirectoryEntry++ 01098 ) { 01099 if (ResourceIdPathLength > 0) { 01100 ScanTypeDirectory = LdrpCompareResourceNames_U( ResourceIdPath[ 0 ], 01101 TopResourceDirectory, 01102 TypeResourceDirectoryEntry 01103 ) == 0; 01104 } 01105 else { 01106 ScanTypeDirectory = TRUE; 01107 } 01108 if (ScanTypeDirectory) { 01109 if (!TypeResourceDirectoryEntry->DataIsDirectory) { 01110 return STATUS_INVALID_IMAGE_FORMAT; 01111 } 01112 if (TypeResourceDirectoryEntry->NameIsString) { 01113 ResourceNameString = (PIMAGE_RESOURCE_DIR_STRING_U) 01114 ((PCHAR)TopResourceDirectory + TypeResourceDirectoryEntry->NameOffset); 01115 01116 TypeResourceNameOrId = (ULONG_PTR)ResourceNameString; 01117 } 01118 else { 01119 TypeResourceNameOrId = (ULONG_PTR)TypeResourceDirectoryEntry->Id; 01120 } 01121 01122 NameResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 01123 ((PCHAR)TopResourceDirectory + TypeResourceDirectoryEntry->OffsetToDirectory); 01124 NameResourceDirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(NameResourceDirectory+1); 01125 NumberOfNameDirectoryEntries = NameResourceDirectory->NumberOfNamedEntries + 01126 NameResourceDirectory->NumberOfIdEntries; 01127 NameDirectoryIndex = 0; 01128 for (NameDirectoryIndex=0; 01129 NameDirectoryIndex<NumberOfNameDirectoryEntries; 01130 NameDirectoryIndex++, NameResourceDirectoryEntry++ 01131 ) { 01132 if (ResourceIdPathLength > 1) { 01133 ScanNameDirectory = LdrpCompareResourceNames_U( ResourceIdPath[ 1 ], 01134 TopResourceDirectory, 01135 NameResourceDirectoryEntry 01136 ) == 0; 01137 } 01138 else { 01139 ScanNameDirectory = TRUE; 01140 } 01141 if (ScanNameDirectory) { 01142 if (!NameResourceDirectoryEntry->DataIsDirectory) { 01143 return STATUS_INVALID_IMAGE_FORMAT; 01144 } 01145 01146 if (NameResourceDirectoryEntry->NameIsString) { 01147 ResourceNameString = (PIMAGE_RESOURCE_DIR_STRING_U) 01148 ((PCHAR)TopResourceDirectory + NameResourceDirectoryEntry->NameOffset); 01149 01150 NameResourceNameOrId = (ULONG_PTR)ResourceNameString; 01151 } 01152 else { 01153 NameResourceNameOrId = (ULONG_PTR)NameResourceDirectoryEntry->Id; 01154 } 01155 01156 LangResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 01157 ((PCHAR)TopResourceDirectory + NameResourceDirectoryEntry->OffsetToDirectory); 01158 01159 LangResourceDirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(LangResourceDirectory+1); 01160 NumberOfLangDirectoryEntries = LangResourceDirectory->NumberOfNamedEntries + 01161 LangResourceDirectory->NumberOfIdEntries; 01162 LangDirectoryIndex = 0; 01163 for (LangDirectoryIndex=0; 01164 LangDirectoryIndex<NumberOfLangDirectoryEntries; 01165 LangDirectoryIndex++, LangResourceDirectoryEntry++ 01166 ) { 01167 if (ResourceIdPathLength > 2) { 01168 ReturnThisResource = LdrpCompareResourceNames_U( ResourceIdPath[ 2 ], 01169 TopResourceDirectory, 01170 LangResourceDirectoryEntry 01171 ) == 0; 01172 } 01173 else { 01174 ReturnThisResource = TRUE; 01175 } 01176 if (ReturnThisResource) { 01177 if (LangResourceDirectoryEntry->DataIsDirectory) { 01178 return STATUS_INVALID_IMAGE_FORMAT; 01179 } 01180 01181 if (LangResourceDirectoryEntry->NameIsString) { 01182 ResourceNameString = (PIMAGE_RESOURCE_DIR_STRING_U) 01183 ((PCHAR)TopResourceDirectory + LangResourceDirectoryEntry->NameOffset); 01184 01185 LangResourceNameOrId = (ULONG_PTR)ResourceNameString; 01186 } 01187 else { 01188 LangResourceNameOrId = (ULONG_PTR)LangResourceDirectoryEntry->Id; 01189 } 01190 01191 ResourceDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY) 01192 ((PCHAR)TopResourceDirectory + LangResourceDirectoryEntry->OffsetToData); 01193 01194 ResourceInfo = &Resources[ ResourceIndex++ ]; 01195 if (ResourceIndex <= MaxResourceIndex) { 01196 ResourceInfo->Path[ 0 ].NameOrId = TypeResourceNameOrId; 01197 ResourceInfo->Path[ 1 ].NameOrId = NameResourceNameOrId; 01198 ResourceInfo->Path[ 2 ].NameOrId = LangResourceNameOrId; 01199 ResourceInfo->Data = (PVOID)((ULONG_PTR)DllHandle + ResourceDataEntry->OffsetToData); 01200 ResourceInfo->Size = ResourceDataEntry->Size; 01201 ResourceInfo->Reserved = 0; 01202 } 01203 else { 01204 Status = STATUS_INFO_LENGTH_MISMATCH; 01205 } 01206 } 01207 } 01208 } 01209 } 01210 } 01211 } 01212 01213 *NumberOfResources = ResourceIndex; 01214 return Status; 01215 }

NTSTATUS LdrFindEntryForAddress IN PVOID  Address,
OUT PLDR_DATA_TABLE_ENTRY *  TableEntry
 

Definition at line 278 of file ldrrsrc.c.

References NULL, and RtlImageNtHeader().

Referenced by LdrLoadAlternateResourceModule().

00284 : 00285 00286 This function returns the load data table entry that describes the virtual 00287 address range that contains the passed virtual address. 00288 00289 Arguments: 00290 00291 Address - Supplies a 32-bit virtual address. 00292 00293 TableEntry - Supplies a pointer to the variable that will receive the 00294 address of the loader data table entry. 00295 00296 00297 Return Value: 00298 00299 Status 00300 00301 --*/ 00302 { 00303 PPEB_LDR_DATA Ldr; 00304 PLIST_ENTRY Head, Next; 00305 PLDR_DATA_TABLE_ENTRY Entry; 00306 PIMAGE_NT_HEADERS NtHeaders; 00307 PVOID ImageBase; 00308 PVOID EndOfImage; 00309 00310 Ldr = NtCurrentPeb()->Ldr; 00311 if (Ldr == NULL) { 00312 return( STATUS_NO_MORE_ENTRIES ); 00313 } 00314 00315 Head = &Ldr->InMemoryOrderModuleList; 00316 Next = Head->Flink; 00317 while ( Next != Head ) { 00318 Entry = CONTAINING_RECORD( Next, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks ); 00319 00320 NtHeaders = RtlImageNtHeader( Entry->DllBase ); 00321 if (NtHeaders != NULL) { 00322 ImageBase = (PVOID)Entry->DllBase; 00323 00324 EndOfImage = (PVOID) 00325 ((ULONG_PTR)ImageBase + NtHeaders->OptionalHeader.SizeOfImage); 00326 00327 if ((ULONG_PTR)Address >= (ULONG_PTR)ImageBase && (ULONG_PTR)Address < (ULONG_PTR)EndOfImage) { 00328 *TableEntry = Entry; 00329 return( STATUS_SUCCESS ); 00330 } 00331 } 00332 00333 Next = Next->Flink; 00334 } 00335 00336 return( STATUS_NO_MORE_ENTRIES ); 00337 }

NTSTATUS LdrFindResource_U IN PVOID  DllHandle,
IN PULONG_PTR  ResourceIdPath,
IN ULONG  ResourceIdPathLength,
OUT PIMAGE_RESOURCE_DATA_ENTRY *  ResourceDataEntry
 

Definition at line 341 of file ldrrsrc.c.

References FALSE, LdrpSearchResourceSection_U(), and RTL_PAGED_CODE.

00350 : 00351 00352 This function locates the address of the specified resource in the 00353 specified DLL and returns its address. 00354 00355 Arguments: 00356 00357 DllHandle - Supplies a handle to the image file that the resource is 00358 contained in. 00359 00360 ResourceIdPath - Supplies a pointer to an array of 32-bit resource 00361 identifiers. Each identifier is either an integer or a pointer 00362 to a STRING structure that specifies a resource name. The array 00363 is used to traverse the directory structure contained in the 00364 resource section in the image file specified by the DllHandle 00365 parameter. 00366 00367 ResourceIdPathLength - Supplies the number of elements in the 00368 ResourceIdPath array. 00369 00370 ResourceDataEntry - Supplies a pointer to a variable that will 00371 receive the address of the resource data entry in the resource 00372 data section of the image file specified by the DllHandle 00373 parameter. 00374 00375 Return Value: 00376 00377 TBD 00378 00379 --*/ 00380 00381 { 00382 RTL_PAGED_CODE(); 00383 00384 return LdrpSearchResourceSection_U( 00385 DllHandle, 00386 ResourceIdPath, 00387 ResourceIdPathLength, 00388 FALSE, // Look for a leaf node 00389 FALSE, 00390 (PVOID *)ResourceDataEntry 00391 ); 00392 }

NTSTATUS LdrFindResourceDirectory_U IN PVOID  DllHandle,
IN PULONG_PTR  ResourceIdPath,
IN ULONG  ResourceIdPathLength,
OUT PIMAGE_RESOURCE_DIRECTORY *  ResourceDirectory
 

Definition at line 396 of file ldrrsrc.c.

References FALSE, LdrpSearchResourceSection_U(), RTL_PAGED_CODE, and TRUE.

00405 : 00406 00407 This function locates the address of the specified resource directory in 00408 specified DLL and returns its address. 00409 00410 Arguments: 00411 00412 DllHandle - Supplies a handle to the image file that the resource 00413 directory is contained in. 00414 00415 ResourceIdPath - Supplies a pointer to an array of 32-bit resource 00416 identifiers. Each identifier is either an integer or a pointer 00417 to a STRING structure that specifies a resource name. The array 00418 is used to traverse the directory structure contained in the 00419 resource section in the image file specified by the DllHandle 00420 parameter. 00421 00422 ResourceIdPathLength - Supplies the number of elements in the 00423 ResourceIdPath array. 00424 00425 ResourceDirectory - Supplies a pointer to a variable that will 00426 receive the address of the resource directory specified by 00427 ResourceIdPath in the resource data section of the image file 00428 the DllHandle parameter. 00429 00430 Return Value: 00431 00432 TBD 00433 00434 --*/ 00435 00436 { 00437 RTL_PAGED_CODE(); 00438 00439 return LdrpSearchResourceSection_U( 00440 DllHandle, 00441 ResourceIdPath, 00442 ResourceIdPathLength, 00443 TRUE, // Look for a directory node 00444 FALSE, 00445 (PVOID *)ResourceDirectory 00446 ); 00447 }

BOOLEAN LdrFlushAlternateResourceModules VOID   ) 
 

Definition at line 1989 of file ldrrsrc.c.

References _ALT_RESOURCE_MODULE::AlternateModule, AlternateResourceModuleCount, AlternateResourceModules, AltResMemBlockCount, LoaderLock, NO_ALTERNATE_RESOURCE_MODULE, NtUnmapViewOfSection(), NULL, RtlFreeHeap, TRUE, and UILangId.

Referenced by SrvLogon().

01995 : 01996 01997 This function unmaps all the alternate resouce modules for the 01998 process address space. This function would be used mainly by 01999 CSRSS, and any sub-systems that are permanent during logon and 02000 logoff. 02001 02002 02003 Arguments: 02004 02005 None 02006 02007 Return Value: 02008 02009 TRUE : Successful 02010 FALSE : Failed 02011 02012 --*/ 02013 02014 { 02015 ULONG ModuleIndex; 02016 PALT_RESOURCE_MODULE AltModule; 02017 02018 // 02019 // Grab the loader lock 02020 // 02021 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 02022 02023 if (AlternateResourceModuleCount > 0) { 02024 // 02025 // Let's unmap the alternate resource modules from the process 02026 // address space 02027 // 02028 for (ModuleIndex=0; 02029 ModuleIndex<AlternateResourceModuleCount; 02030 ModuleIndex++) { 02031 02032 AltModule = &AlternateResourceModules[ModuleIndex]; 02033 02034 if (AltModule->AlternateModule != NO_ALTERNATE_RESOURCE_MODULE) { 02035 NtUnmapViewOfSection(NtCurrentProcess(), 02036 (PVOID)((ULONG_PTR)AltModule->AlternateModule & ~0x00000001)); 02037 } 02038 } 02039 02040 // 02041 // Cleanup alternate resource modules memory 02042 // 02043 RtlFreeHeap(RtlProcessHeap(), 0, AlternateResourceModules); 02044 AlternateResourceModules = NULL; 02045 AlternateResourceModuleCount = 0; 02046 AltResMemBlockCount = 0; 02047 02048 } 02049 02050 // 02051 // Re-Initialize the UI language for the current process, 02052 // and leave the LoaderLock 02053 // 02054 UILangId = 0; 02055 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 02056 02057 return TRUE; 02058 }

PVOID LdrGetAlternateResourceModuleHandle IN PVOID  Module  ) 
 

Definition at line 1277 of file ldrrsrc.c.

References _ALT_RESOURCE_MODULE::AlternateModule, AlternateResourceModuleCount, AlternateResourceModules, _ALT_RESOURCE_MODULE::ModuleBase, and NULL.

Referenced by LdrLoadAlternateResourceModule().

01282 : 01283 01284 This function gets the alternate resource module from the table 01285 containing the handle. 01286 01287 Arguments: 01288 01289 Module - Module of which alternate resource module needs to loaded. 01290 01291 Return Value: 01292 01293 Handle of the alternate resource module. 01294 01295 --*/ 01296 01297 { 01298 ULONG ModuleIndex; 01299 01300 for (ModuleIndex = 0; 01301 ModuleIndex < AlternateResourceModuleCount; 01302 ModuleIndex++ ){ 01303 if (AlternateResourceModules[ModuleIndex].ModuleBase == 01304 Module){ 01305 return AlternateResourceModules[ModuleIndex].AlternateModule; 01306 } 01307 } 01308 return NULL; 01309 }

PVOID LdrLoadAlternateResourceModule IN PVOID  Module,
IN LPCWSTR PathToAlternateModule  OPTIONAL
 

Definition at line 1563 of file ldrrsrc.c.

References Buffer, L, LdrAlternateResourcesEnabled(), LdrFindEntryForAddress(), LdrGetAlternateResourceModuleHandle(), LdrpSetAlternateResourceModuleHandle(), LoaderLock, NO_ALTERNATE_RESOURCE_MODULE, NT_SUCCESS, NtClose(), NtCreateFile(), NtCreateSection(), NtMapViewOfSection(), NtQueryDefaultUILanguage(), NTSTATUS(), NtSystemRoot, NtUnmapViewOfSection(), NULL, ObjectAttributes, RelativeName, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlCopyUnicodeString(), RtlDosPathNameToNtPathName_U(), RtlFreeHeap, RtlImageNtHeader(), RtlInitUnicodeString(), Status, and UILangId.

Referenced by LdrpAccessResourceData(), and LdrpSearchResourceSection_U().

01570 : 01571 01572 This function does the acutally loading into memory of the alternate 01573 resource module, or loads from the table if it was loaded before. 01574 01575 Arguments: 01576 01577 Module - The handle of the base module. 01578 PathToAlternateModule - Optional path from which module is being loaded. 01579 01580 Return Value: 01581 01582 Handle to the alternate resource module. 01583 01584 --*/ 01585 01586 { 01587 PVOID AlternateModule, DllBase; 01588 PLDR_DATA_TABLE_ENTRY Entry; 01589 HANDLE FileHandle, MappingHandle; 01590 PIMAGE_NT_HEADERS NtHeaders; 01591 NTSTATUS Status; 01592 OBJECT_ATTRIBUTES ObjectAttributes; 01593 UNICODE_STRING AltDllName; 01594 PVOID FreeBuffer; 01595 LPWSTR BaseDllName, p; 01596 WCHAR DllPathName[DOS_MAX_PATH_LENGTH]; 01597 ULONG DllPathNameLength, BaseDllNameLength, CopyCount; 01598 ULONG Digit; 01599 int i, RetryCount; 01600 WCHAR AltModulePath[DOS_MAX_PATH_LENGTH]; 01601 WCHAR AltModulePathMUI[DOS_MAX_PATH_LENGTH]; 01602 WCHAR AltModulePathFallback[DOS_MAX_PATH_LENGTH]; 01603 IO_STATUS_BLOCK IoStatusBlock; 01604 RTL_RELATIVE_NAME RelativeName; 01605 SIZE_T ViewSize; 01606 LARGE_INTEGER SectionOffset; 01607 WCHAR LangIdDir[6]; 01608 UNICODE_STRING AltModulePathList[3]; 01609 UNICODE_STRING NtSystemRoot; 01610 01611 01612 if (!LdrAlternateResourcesEnabled()) { 01613 return NULL; 01614 } 01615 01616 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01617 01618 AlternateModule = LdrGetAlternateResourceModuleHandle(Module); 01619 if (AlternateModule == NO_ALTERNATE_RESOURCE_MODULE){ 01620 // 01621 // We tried to load this module before but failed. Don't try 01622 // again in the future. 01623 // 01624 RtlLeaveCriticalSection( 01625 (PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01626 return NULL; 01627 } 01628 else if (AlternateModule > 0){ 01629 // 01630 // We found the previously loaded match 01631 // 01632 RtlLeaveCriticalSection( 01633 (PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01634 return AlternateModule; 01635 } 01636 01637 if (ARGUMENT_PRESENT(PathToAlternateModule)){ 01638 // 01639 // Caller suplied path. 01640 // 01641 01642 CopyCount = wcslen(PathToAlternateModule); 01643 01644 for (p = (LPWSTR) PathToAlternateModule + CopyCount; 01645 p > PathToAlternateModule; 01646 p--){ 01647 if (*(p-1) == L'\\'){ 01648 break; 01649 } 01650 } 01651 01652 if (p == PathToAlternateModule){ 01653 goto error_exit; 01654 } 01655 01656 DllPathNameLength = (ULONG)(p - PathToAlternateModule) * sizeof(WCHAR); 01657 01658 RtlCopyMemory( 01659 DllPathName, 01660 PathToAlternateModule, 01661 DllPathNameLength 01662 ); 01663 01664 BaseDllName = p ; 01665 BaseDllNameLength = CopyCount * sizeof(WCHAR) - DllPathNameLength; 01666 01667 } 01668 else{ 01669 // 01670 // Try to get full dll path from Ldr data table. 01671 // 01672 Status = LdrFindEntryForAddress(Module, &Entry); 01673 if (!NT_SUCCESS( Status )){ 01674 goto error_exit; 01675 } 01676 01677 DllPathNameLength = Entry->FullDllName.Length - 01678 Entry->BaseDllName.Length; 01679 01680 RtlCopyMemory( 01681 DllPathName, 01682 Entry->FullDllName.Buffer, 01683 DllPathNameLength); 01684 01685 BaseDllName = Entry->BaseDllName.Buffer; 01686 BaseDllNameLength = Entry->BaseDllName.Length; 01687 } 01688 01689 DllPathName[DllPathNameLength / sizeof(WCHAR)] = UNICODE_NULL; 01690 01691 // 01692 // Generate the langid directory like "0804\" 01693 // 01694 if (!UILangId){ 01695 Status = NtQueryDefaultUILanguage( &UILangId ); 01696 if (!NT_SUCCESS( Status )) { 01697 goto error_exit; 01698 } 01699 } 01700 01701 CopyCount = 0; 01702 for (i = 12; i >= 0; i -= 4){ 01703 Digit = ((UILangId >> i) & 0xF); 01704 if (Digit >= 10){ 01705 LangIdDir[CopyCount++] = (WCHAR) (Digit - 10 + L'A'); 01706 } 01707 else{ 01708 LangIdDir[CopyCount++] = (WCHAR) (Digit + L'0'); 01709 } 01710 } 01711 01712 LangIdDir[CopyCount++] = L'\\'; 01713 LangIdDir[CopyCount++] = UNICODE_NULL; 01714 01715 // 01716 // Generate the first path c:\winnt\system32\mui\0804\ntdll.dll.mui 01717 // 01718 AltModulePathList[1].Buffer = AltModulePath; 01719 AltModulePathList[1].Length = 0; 01720 AltModulePathList[1].MaximumLength = sizeof(AltModulePath); 01721 01722 RtlAppendUnicodeToString(&AltModulePathList[1], DllPathName); 01723 RtlAppendUnicodeToString(&AltModulePathList[1], L"mui\\"); 01724 RtlAppendUnicodeToString(&AltModulePathList[1], LangIdDir); 01725 RtlAppendUnicodeToString(&AltModulePathList[1], BaseDllName); 01726 01727 // 01728 // Generate the first path c:\winnt\system32\mui\0804\ntdll.dll 01729 // 01730 AltModulePathList[0].Buffer = AltModulePathMUI; 01731 AltModulePathList[0].Length = 0; 01732 AltModulePathList[0].MaximumLength = sizeof(AltModulePathMUI); 01733 01734 RtlCopyUnicodeString(&AltModulePathList[0], &AltModulePathList[1]); 01735 RtlAppendUnicodeToString(&AltModulePathList[0], L".mui"); 01736 01737 // 01738 // Generate path c:\winnt\mui\fallback\0804\foo.exe.mui 01739 // 01740 AltModulePathList[2].Buffer = AltModulePathFallback; 01741 AltModulePathList[2].Length = 0; 01742 AltModulePathList[2].MaximumLength = sizeof(AltModulePathFallback); 01743 01744 RtlInitUnicodeString(&NtSystemRoot, USER_SHARED_DATA->NtSystemRoot); 01745 RtlAppendUnicodeStringToString(&AltModulePathList[2], &NtSystemRoot); 01746 RtlAppendUnicodeToString(&AltModulePathList[2], L"\\mui\\fallback\\"); 01747 RtlAppendUnicodeToString(&AltModulePathList[2], LangIdDir); 01748 RtlAppendUnicodeToString(&AltModulePathList[2], BaseDllName); 01749 RtlAppendUnicodeToString(&AltModulePathList[2], L".mui"); 01750 01751 // 01752 // Try name with .mui extesion first. 01753 // 01754 RetryCount = 0; 01755 while (RetryCount < sizeof(AltModulePathList)/sizeof(UNICODE_STRING)){ 01756 if (!RtlDosPathNameToNtPathName_U( 01757 AltModulePathList[RetryCount].Buffer, 01758 &AltDllName, 01759 NULL, 01760 &RelativeName 01761 )){ 01762 goto error_exit; 01763 } 01764 01765 FreeBuffer = AltDllName.Buffer; 01766 if ( RelativeName.RelativeName.Length ) { 01767 AltDllName = *(PUNICODE_STRING)&RelativeName.RelativeName; 01768 } 01769 else { 01770 RelativeName.ContainingDirectory = NULL; 01771 } 01772 01773 InitializeObjectAttributes( 01774 &ObjectAttributes, 01775 &AltDllName, 01776 OBJ_CASE_INSENSITIVE, 01777 RelativeName.ContainingDirectory, 01778 NULL 01779 ); 01780 01781 01782 Status = NtCreateFile( 01783 &FileHandle, 01784 (ACCESS_MASK) GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES, 01785 &ObjectAttributes, 01786 &IoStatusBlock, 01787 NULL, 01788 0L, 01789 FILE_SHARE_READ | FILE_SHARE_DELETE, 01790 FILE_OPEN, 01791 0L, 01792 NULL, 01793 0L 01794 ); 01795 01796 RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer); 01797 01798 if (NT_SUCCESS( Status )){ 01799 break; 01800 } 01801 if (Status != STATUS_OBJECT_NAME_NOT_FOUND && RetryCount == 0) { 01802 // 01803 // Error other than the file name with .mui not found. 01804 // Most likely directory is missing. Skip file name w/o .mui 01805 // and goto fallback directory. 01806 // 01807 RetryCount++; 01808 } 01809 01810 RetryCount++; 01811 } 01812 01813 Status = NtCreateSection( 01814 &MappingHandle, 01815 STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 01816 NULL, 01817 NULL, 01818 PAGE_WRITECOPY, 01819 SEC_COMMIT, 01820 FileHandle 01821 ); 01822 01823 if (!NT_SUCCESS( Status )){ 01824 goto error_exit; 01825 } 01826 01827 NtClose( FileHandle ); 01828 01829 SectionOffset.LowPart = 0; 01830 SectionOffset.HighPart = 0; 01831 ViewSize = 0; 01832 DllBase = NULL; 01833 01834 Status = NtMapViewOfSection( 01835 MappingHandle, 01836 NtCurrentProcess(), 01837 &DllBase, 01838 0L, 01839 0L, 01840 &SectionOffset, 01841 &ViewSize, 01842 ViewShare, 01843 0L, 01844 PAGE_WRITECOPY 01845 ); 01846 01847 NtClose( MappingHandle ); 01848 01849 if (!NT_SUCCESS( Status )){ 01850 goto error_exit; 01851 } 01852 01853 NtHeaders = RtlImageNtHeader( DllBase ); 01854 if (!NtHeaders) { 01855 NtUnmapViewOfSection(NtCurrentProcess(), (PVOID) DllBase); 01856 goto error_exit; 01857 } 01858 01859 AlternateModule = (HANDLE)((ULONG_PTR)DllBase | 0x00000001); 01860 01861 // 01862 // Disable version check now to make testing with an earlier 01863 // localized version easier. 01864 // 01865 // if(!LdrpVerifyAlternateResourceModule(Module, AlternateModule)){ 01866 // NtUnmapViewOfSection(NtCurrentProcess(), (PVOID) DllBase); 01867 // goto error_exit; 01868 // } 01869 01870 01871 LdrpSetAlternateResourceModuleHandle(Module, AlternateModule); 01872 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01873 return AlternateModule; 01874 01875 error_exit: 01876 LdrpSetAlternateResourceModuleHandle(Module, NO_ALTERNATE_RESOURCE_MODULE); 01877 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01878 return NULL; 01879 }

NTSTATUS LdrpAccessResourceData IN PVOID  DllHandle,
IN PIMAGE_RESOURCE_DATA_ENTRY  ResourceDataEntry,
OUT PVOID *Address  OPTIONAL,
OUT PULONG Size  OPTIONAL
 

Definition at line 96 of file ldrrsrc.c.

References EXCEPTION_EXECUTE_HANDLER, LdrLoadAlternateResourceModule(), NT_SUCCESS, NtQueryVirtualMemory(), NTSTATUS(), NULL, RTL_PAGED_CODE, RtlAddressInSectionTable(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlSectionTableFromVirtualAddress(), Size, Status, and TRUE.

Referenced by LdrAccessResource(), LdrpGetFileVersion(), LdrQueryApplicationCompatibilityGoo(), and RtlFindMessage().

00105 : 00106 00107 This function returns the data necessary to actually examine the 00108 contents of a particular resource. 00109 00110 Arguments: 00111 00112 DllHandle - Supplies a handle to the image file that the resource is 00113 contained in. 00114 00115 ResourceDataEntry - Supplies a pointer to the resource data entry in 00116 the resource data directory of the image file specified by the 00117 DllHandle parameter. This pointer should have been one returned 00118 by the LdrFindResource function. 00119 00120 Address - Optional pointer to a variable that will receive the 00121 address of the resource specified by the first two parameters. 00122 00123 Size - Optional pointer to a variable that will receive the size of 00124 the resource specified by the first two parameters. 00125 00126 00127 Return Value: 00128 00129 TBD 00130 00131 --*/ 00132 00133 { 00134 PIMAGE_RESOURCE_DIRECTORY ResourceDirectory; 00135 ULONG ResourceSize; 00136 PIMAGE_NT_HEADERS NtHeaders; 00137 ULONG_PTR VirtualAddressOffset; 00138 PIMAGE_SECTION_HEADER NtSection; 00139 00140 RTL_PAGED_CODE(); 00141 00142 #ifndef NTOS_KERNEL_RUNTIME 00143 ResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 00144 RtlImageDirectoryEntryToData(DllHandle, 00145 TRUE, 00146 IMAGE_DIRECTORY_ENTRY_RESOURCE, 00147 &ResourceSize 00148 ); 00149 if (!ResourceDirectory) { 00150 return( STATUS_RESOURCE_DATA_NOT_FOUND ); 00151 } 00152 00153 if ((ULONG_PTR)ResourceDataEntry < (ULONG_PTR) ResourceDirectory ){ 00154 DllHandle = LdrLoadAlternateResourceModule (DllHandle, NULL); 00155 } else{ 00156 NtHeaders = RtlImageNtHeader( 00157 (PVOID)((ULONG_PTR)DllHandle & ~0x00000001) 00158 ); 00159 if (NtHeaders) { 00160 // Find the bounds of the image so we can see if this resource entry is in an alternate 00161 // resource dll. 00162 00163 ULONG_PTR ImageStart = (ULONG_PTR)DllHandle & ~0x00000001; 00164 SIZE_T ImageSize = 0; 00165 00166 if ((ULONG_PTR)DllHandle & 0x00000001) { 00167 // mapped as datafile. Ask mm for the size 00168 NTSTATUS Status; 00169 MEMORY_BASIC_INFORMATION MemInfo; 00170 00171 Status = NtQueryVirtualMemory( 00172 NtCurrentProcess(), 00173 (PVOID) ImageStart, 00174 MemoryBasicInformation, 00175 (PVOID)&MemInfo, 00176 sizeof(MemInfo), 00177 NULL 00178 ); 00179 00180 if ( !NT_SUCCESS(Status) ) { 00181 ImageSize = 0; 00182 } else { 00183 ImageSize = MemInfo.RegionSize; 00184 } 00185 } else { 00186 ImageSize = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.SizeOfImage; 00187 } 00188 00189 if (!(((ULONG_PTR)ResourceDataEntry >= ImageStart) && ((ULONG_PTR)ResourceDataEntry < (ImageStart + ImageSize)))) { 00190 // Doesn't fall within the specified image. Must be an alternate dll. 00191 DllHandle = LdrLoadAlternateResourceModule (DllHandle, NULL); 00192 } 00193 } 00194 } 00195 00196 if (!DllHandle){ 00197 return ( STATUS_RESOURCE_DATA_NOT_FOUND ); 00198 } 00199 00200 #endif 00201 try { 00202 ResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 00203 RtlImageDirectoryEntryToData(DllHandle, 00204 TRUE, 00205 IMAGE_DIRECTORY_ENTRY_RESOURCE, 00206 &ResourceSize 00207 ); 00208 if (!ResourceDirectory) { 00209 return( STATUS_RESOURCE_DATA_NOT_FOUND ); 00210 } 00211 00212 if ((ULONG_PTR)DllHandle & 0x00000001) { 00213 ULONG ResourceRVA; 00214 DllHandle = (PVOID)((ULONG_PTR)DllHandle & ~0x00000001); 00215 NtHeaders = RtlImageNtHeader( DllHandle ); 00216 if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 00217 ResourceRVA=((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_RESOURCE ].VirtualAddress; 00218 } else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 00219 ResourceRVA=((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_RESOURCE ].VirtualAddress; 00220 } else { 00221 ResourceRVA = 0; 00222 } 00223 00224 if (!ResourceRVA) { 00225 return( STATUS_RESOURCE_DATA_NOT_FOUND ); 00226 } 00227 00228 VirtualAddressOffset = (ULONG_PTR)DllHandle + ResourceRVA - (ULONG_PTR)ResourceDirectory; 00229 00230 // 00231 // Now, we must check to see if the resource is not in the 00232 // same section as the resource table. If it's in .rsrc1, 00233 // we've got to adjust the RVA in the ResourceDataEntry 00234 // to point to the correct place in the non-VA data file. 00235 // 00236 NtSection= RtlSectionTableFromVirtualAddress( NtHeaders, DllHandle, ResourceRVA); 00237 00238 if (!NtSection) { 00239 return( STATUS_RESOURCE_DATA_NOT_FOUND ); 00240 } 00241 00242 if ( ResourceDataEntry->OffsetToData > NtSection->Misc.VirtualSize ) { 00243 ULONG rva; 00244 00245 rva = NtSection->VirtualAddress; 00246 NtSection= RtlSectionTableFromVirtualAddress(NtHeaders, 00247 DllHandle, 00248 ResourceDataEntry->OffsetToData 00249 ); 00250 VirtualAddressOffset += 00251 ((ULONG_PTR)NtSection->VirtualAddress - rva) - 00252 ((ULONG_PTR)RtlAddressInSectionTable ( NtHeaders, DllHandle, NtSection->VirtualAddress ) - (ULONG_PTR)ResourceDirectory); 00253 } 00254 } 00255 else { 00256 VirtualAddressOffset = 0; 00257 } 00258 00259 if (ARGUMENT_PRESENT( Address )) { 00260 *Address = (PVOID)( (PCHAR)DllHandle + 00261 (ResourceDataEntry->OffsetToData - VirtualAddressOffset) 00262 ); 00263 } 00264 00265 if (ARGUMENT_PRESENT( Size )) { 00266 *Size = ResourceDataEntry->Size; 00267 } 00268 } 00269 except (EXCEPTION_EXECUTE_HANDLER) { 00270 return GetExceptionCode(); 00271 } 00272 00273 return( STATUS_SUCCESS ); 00274 }

LONG LdrpCompareResourceNames_U IN ULONG_PTR  ResourceName,
IN PIMAGE_RESOURCE_DIRECTORY  ResourceDirectory,
IN PIMAGE_RESOURCE_DIRECTORY_ENTRY  ResourceDirectoryEntry
 

Definition at line 451 of file ldrrsrc.c.

Referenced by LdrEnumResources(), and LdrpSearchResourceSection_U().

00456 { 00457 LONG li; 00458 PIMAGE_RESOURCE_DIR_STRING_U ResourceNameString; 00459 00460 if (ResourceName & LDR_RESOURCE_ID_NAME_MASK) { 00461 if (!ResourceDirectoryEntry->NameIsString) { 00462 return( -1 ); 00463 } 00464 00465 ResourceNameString = (PIMAGE_RESOURCE_DIR_STRING_U) 00466 ((PCHAR)ResourceDirectory + ResourceDirectoryEntry->NameOffset); 00467 00468 li = wcsncmp( (LPWSTR)ResourceName, 00469 ResourceNameString->NameString, 00470 ResourceNameString->Length 00471 ); 00472 00473 if (!li && wcslen((PWSTR)ResourceName) != ResourceNameString->Length) { 00474 return( 1 ); 00475 } 00476 00477 return(li); 00478 } 00479 else { 00480 if (ResourceDirectoryEntry->NameIsString) { 00481 return( 1 ); 00482 } 00483 00484 return( (ULONG)(ResourceName - ResourceDirectoryEntry->Name) ); 00485 } 00486 }

BOOLEAN LdrpGetFileVersion IN PVOID  ImageBase,
IN LANGID  LangId,
OUT PULONGLONG  Version
 

Definition at line 1312 of file ldrrsrc.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, L, LdrpAccessResourceData(), LdrpSearchResourceSection_U(), Name, NT_SUCCESS, NTSTATUS(), Resource, Status, TRUE, USHORT, and Version.

Referenced by LdrpVerifyAlternateResourceModule().

01320 : 01321 01322 Get the version stamp out of the VS_FIXEDFILEINFO resource in a PE 01323 image. 01324 01325 Arguments: 01326 01327 ImageBase - supplies the address in memory where the file is mapped in. 01328 01329 Version - receives 64bit version number, or 0 if the file is not 01330 a PE image or has no version data. 01331 01332 Return Value: 01333 01334 None. 01335 01336 --*/ 01337 01338 { 01339 PIMAGE_RESOURCE_DATA_ENTRY DataEntry; 01340 NTSTATUS Status; 01341 ULONG_PTR IdPath[3]; 01342 ULONG ResourceSize; 01343 01344 01345 typedef struct tagVS_FIXEDFILEINFO 01346 { 01347 LONG dwSignature; /* e.g. 0xfeef04bd */ 01348 LONG dwStrucVersion; /* e.g. 0x00000042 = "0.42" */ 01349 LONG dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */ 01350 LONG dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */ 01351 LONG dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */ 01352 LONG dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */ 01353 LONG dwFileFlagsMask; /* = 0x3F for version "0.42" */ 01354 LONG dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */ 01355 LONG dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */ 01356 LONG dwFileType; /* e.g. VFT_DRIVER */ 01357 LONG dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */ 01358 LONG dwFileDateMS; /* e.g. 0 */ 01359 LONG dwFileDateLS; /* e.g. 0 */ 01360 } VS_FIXEDFILEINFO; 01361 01362 struct { 01363 USHORT TotalSize; 01364 USHORT DataSize; 01365 USHORT Type; 01366 WCHAR Name[16]; // L"VS_VERSION_INFO" + unicode nul 01367 VS_FIXEDFILEINFO FixedFileInfo; 01368 } *Resource; 01369 01370 *Version = 0; 01371 01372 01373 IdPath[0] = 16; 01374 IdPath[1] = 1; 01375 IdPath[2] = LangId; 01376 01377 try { 01378 Status = LdrpSearchResourceSection_U( 01379 ImageBase, 01380 IdPath, 01381 3, 01382 FALSE, 01383 TRUE, 01384 &DataEntry); 01385 } except(EXCEPTION_EXECUTE_HANDLER) { 01386 Status = STATUS_UNSUCCESSFUL; 01387 } 01388 01389 if(!NT_SUCCESS(Status)) { 01390 return FALSE; 01391 } 01392 01393 try { 01394 Status = LdrpAccessResourceData( 01395 ImageBase, 01396 DataEntry, 01397 &Resource, 01398 &ResourceSize); 01399 } except(EXCEPTION_EXECUTE_HANDLER) { 01400 Status = STATUS_UNSUCCESSFUL; 01401 } 01402 01403 if(!NT_SUCCESS(Status)) { 01404 return FALSE; 01405 } 01406 01407 try { 01408 if((ResourceSize >= sizeof(*Resource)) 01409 && !_wcsicmp(Resource->Name,L"VS_VERSION_INFO")) { 01410 01411 *Version = ((ULONGLONG)Resource->FixedFileInfo.dwFileVersionMS << 32 01412 ) 01413 | (ULONGLONG)Resource->FixedFileInfo.dwFileVersionLS; 01414 01415 } else { 01416 DbgPrint(("LDR: Warning: invalid version resource\n")); 01417 return FALSE; 01418 } 01419 } except(EXCEPTION_EXECUTE_HANDLER) { 01420 DbgPrint(("LDR: Exception encountered processing bogus version resource\n")); 01421 return FALSE; 01422 } 01423 return TRUE; 01424 }

NTSTATUS LdrpSearchResourceSection_U IN PVOID  DllHandle,
IN PULONG_PTR  ResourceIdPath,
IN ULONG  ResourceIdPathLength,
IN BOOLEAN  FindDirectoryEntry,
IN BOOLEAN  ExactLangMatchOnly,
OUT PVOID *  ResourceDirectoryOrData
 

Definition at line 492 of file ldrrsrc.c.

References dir(), EXCEPTION_EXECUTE_HANDLER, FALSE, InstallLangId, LdrLoadAlternateResourceModule(), LdrpCompareResourceNames_U(), n, NT_SUCCESS, NtQueryDefaultLocale(), NtQueryDefaultUILanguage(), NtQueryInstallUILanguage(), NTSTATUS(), NULL, PsDefaultSystemLocaleId, PsInstallUILanguageId, RTL_PAGED_CODE, RtlImageDirectoryEntryToData(), Status, TRUE, UILangId, USE_FIRSTAVAILABLE_LANGID, and USHORT.

Referenced by LdrFindResource_U(), LdrFindResourceDirectory_U(), LdrpGetFileVersion(), LdrQueryApplicationCompatibilityGoo(), and RtlFindMessage().

00503 : 00504 00505 This function locates the address of the specified resource in the 00506 specified DLL and returns its address. 00507 00508 Arguments: 00509 00510 DllHandle - Supplies a handle to the image file that the resource is 00511 contained in. 00512 00513 ResourceIdPath - Supplies a pointer to an array of 32-bit resource 00514 identifiers. Each identifier is either an integer or a pointer 00515 to a null terminated string (PSZ) that specifies a resource 00516 name. The array is used to traverse the directory structure 00517 contained in the resource section in the image file specified by 00518 the DllHandle parameter. 00519 00520 ResourceIdPathLength - Supplies the number of elements in the 00521 ResourceIdPath array. 00522 00523 FindDirectoryEntry - Supplies a boolean that is TRUE if caller is 00524 searching for a resource directory, otherwise the caller is 00525 searching for a resource data entry. 00526 00527 ExactLangMatchOnly - Supplies a boolean that is TRUE if caller is 00528 searching for a resource with, and only with, the language id 00529 specified in ResourceIdPath, otherwise the caller wants the routine 00530 to come up with default when specified langid is not found. 00531 00532 ResourceDirectoryOrData - Supplies a pointer to a variable that will 00533 receive the address of the resource directory or data entry in 00534 the resource data section of the image file specified by the 00535 DllHandle parameter. 00536 00537 Return Value: 00538 00539 TBD 00540 00541 --*/ 00542 00543 { 00544 NTSTATUS Status; 00545 PIMAGE_RESOURCE_DIRECTORY LanguageResourceDirectory, ResourceDirectory, TopResourceDirectory; 00546 PIMAGE_RESOURCE_DIRECTORY_ENTRY ResourceDirEntLow; 00547 PIMAGE_RESOURCE_DIRECTORY_ENTRY ResourceDirEntMiddle; 00548 PIMAGE_RESOURCE_DIRECTORY_ENTRY ResourceDirEntHigh; 00549 PIMAGE_RESOURCE_DATA_ENTRY ResourceEntry; 00550 USHORT n, half; 00551 LONG dir; 00552 ULONG size; 00553 ULONG_PTR ResourceIdRetry; 00554 ULONG RetryCount; 00555 LANGID NewLangId; 00556 PULONG_PTR IdPath = ResourceIdPath; 00557 ULONG IdPathLength = ResourceIdPathLength; 00558 BOOLEAN fIsNeutral = FALSE; 00559 LANGID GivenLanguage; 00560 #ifndef NTOS_KERNEL_RUNTIME 00561 LCID DefaultThreadLocale, DefaultSystemLocale; 00562 PVOID AltResourceDllHandle = NULL; 00563 ULONG_PTR UIResourceIdPath[3]; 00564 #endif 00565 00566 RTL_PAGED_CODE(); 00567 00568 try { 00569 TopResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 00570 RtlImageDirectoryEntryToData(DllHandle, 00571 TRUE, 00572 IMAGE_DIRECTORY_ENTRY_RESOURCE, 00573 &size 00574 ); 00575 if (!TopResourceDirectory) { 00576 return( STATUS_RESOURCE_DATA_NOT_FOUND ); 00577 } 00578 00579 ResourceDirectory = TopResourceDirectory; 00580 ResourceIdRetry = USE_FIRSTAVAILABLE_LANGID; 00581 RetryCount = 0; 00582 ResourceEntry = NULL; 00583 LanguageResourceDirectory = NULL; 00584 while (ResourceDirectory != NULL && ResourceIdPathLength--) { 00585 // 00586 // If search path includes a language id, then attempt to 00587 // match the following language ids in this order: 00588 // 00589 // (0) use given language id 00590 // (1) use primary language of given language id 00591 // (2) use id 0 (neutral resource) 00592 // (3) use default UI language id 00593 // 00594 // If the PRIMARY language id is ZERO, then ALSO attempt to 00595 // match the following language ids in this order: 00596 // 00597 // (4) use lang id of TEB if different from user locale 00598 // (5) use UI lang from exe resource 00599 // (6) use primary UI lang from exe resource 00600 // (7) use Install Language 00601 // (8) use lang id from user's locale id 00602 // (9) use primary language of user's locale id 00603 // (10) use lang id from system default locale id 00604 // (11) use primary language of system default locale id 00605 // (12) use US English lang id 00606 // (13) use any lang id that matches requested info 00607 // 00608 if (ResourceIdPathLength == 0 && IdPathLength == 3) { 00609 LanguageResourceDirectory = ResourceDirectory; 00610 } 00611 00612 if (LanguageResourceDirectory != NULL) { 00613 GivenLanguage = (LANGID)IdPath[ 2 ]; 00614 fIsNeutral = (PRIMARYLANGID( GivenLanguage ) == LANG_NEUTRAL); 00615 TryNextLangId: 00616 switch( RetryCount++ ) { 00617 #ifdef NTOS_KERNEL_RUNTIME 00618 case 0: // Use given language id 00619 NewLangId = GivenLanguage; 00620 break; 00621 00622 case 1: // Use primary language of given language id 00623 NewLangId = PRIMARYLANGID( GivenLanguage ); 00624 break; 00625 00626 case 2: // Use id 0 (neutral resource) 00627 NewLangId = 0; 00628 break; 00629 00630 case 3: // Use user's default UI language 00631 NewLangId = (LANGID)ResourceIdRetry; 00632 break; 00633 00634 case 4: // Use native UI language 00635 if ( !fIsNeutral ) { 00636 // Stop looking - Not in the neutral case 00637 goto ReturnFailure; 00638 break; 00639 } 00640 NewLangId = PsInstallUILanguageId; 00641 break; 00642 00643 case 5: // Use default system locale 00644 NewLangId = LANGIDFROMLCID(PsDefaultSystemLocaleId); 00645 break; 00646 00647 case 6: 00648 // Use US English language 00649 NewLangId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); 00650 break; 00651 00652 case 7: // Take any lang id that matches 00653 NewLangId = USE_FIRSTAVAILABLE_LANGID; 00654 break; 00655 00656 #else 00657 case 0: // Use given language id 00658 NewLangId = GivenLanguage; 00659 break; 00660 00661 case 1: // Use primary language of given language id 00662 if ( ExactLangMatchOnly) { 00663 // 00664 // Did not find an exact language match. 00665 // Stop looking. 00666 // 00667 goto ReturnFailure; 00668 } 00669 NewLangId = PRIMARYLANGID( GivenLanguage ); 00670 break; 00671 00672 case 2: // Use id 0 (neutral resource) 00673 NewLangId = 0; 00674 break; 00675 00676 case 3: // Use user's default UI language 00677 00678 if (!UILangId){ 00679 Status = NtQueryDefaultUILanguage( &UILangId ); 00680 if (!NT_SUCCESS( Status )) { 00681 // 00682 // Failed reading key. Skip this lookup. 00683 // 00684 NewLangId = (LANGID)ResourceIdRetry; 00685 break; 00686 } 00687 } 00688 NewLangId = UILangId; 00689 // 00690 // Arabic/Hebrew MUI files may contain resources with LANG ID different than 401/40d. 00691 // e.g. Comdlg32.dll has two sets of Arabic/Hebrew resources one mirrored (401/40d) 00692 // and one flipped (801/80d). 00693 // 00694 if( !fIsNeutral && 00695 ((PRIMARYLANGID (GivenLanguage) == LANG_ARABIC) || (PRIMARYLANGID (GivenLanguage) == LANG_HEBREW)) && 00696 (PRIMARYLANGID (GivenLanguage) == PRIMARYLANGID (NewLangId)) 00697 ) { 00698 NewLangId = GivenLanguage; 00699 } 00700 00701 if (fIsNeutral || GivenLanguage == NewLangId){ 00702 // 00703 // Load alternate resource dll. 00704 // 00705 AltResourceDllHandle=LdrLoadAlternateResourceModule( 00706 DllHandle, 00707 NULL); 00708 00709 if (!AltResourceDllHandle){ 00710 // 00711 // Alternate resource dll not available. 00712 // Skip this lookup. 00713 // 00714 NewLangId = (LANGID)ResourceIdRetry; 00715 break; 00716 00717 } 00718 00719 // 00720 // Map to alternate resource dll and search 00721 // it instead. 00722 // 00723 00724 UIResourceIdPath[0]=IdPath[0]; 00725 UIResourceIdPath[1]=IdPath[1]; 00726 UIResourceIdPath[2]=NewLangId; 00727 00728 Status = LdrpSearchResourceSection_U( 00729 AltResourceDllHandle, 00730 UIResourceIdPath, 00731 3, 00732 FindDirectoryEntry, 00733 TRUE, 00734 (PVOID *)ResourceDirectoryOrData 00735 ); 00736 00737 if (NT_SUCCESS(Status)){ 00738 // 00739 // We sucessfully found alternate resource, 00740 // return it. 00741 // 00742 return Status; 00743 } 00744 00745 00746 } 00747 // 00748 // Caller does not want alternate resource, or 00749 // alternate resource not found. 00750 // 00751 NewLangId = (LANGID)ResourceIdRetry; 00752 break; 00753 00754 00755 case 4: // Use langid of ThreadLocale if different from user locale 00756 if ( !fIsNeutral ) { 00757 // Stop looking - Not in the neutral case 00758 goto ReturnFailure; 00759 break; 00760 } 00761 00762 // 00763 // Try the thread locale language-id if it is different from 00764 // user locale. 00765 // 00766 if (NtCurrentTeb()){ 00767 Status = NtQueryDefaultLocale( 00768 TRUE, 00769 &DefaultThreadLocale 00770 ); 00771 if (NT_SUCCESS( Status ) && 00772 DefaultThreadLocale != 00773 NtCurrentTeb()->CurrentLocale) { 00774 // 00775 // Thread locale is different from 00776 // default locale. 00777 // 00778 NewLangId = LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale); 00779 break; 00780 } 00781 } 00782 00783 NewLangId = (LANGID)ResourceIdRetry; 00784 break; 00785 00786 00787 case 5: // UI language from the executable resource 00788 00789 if (!UILangId){ 00790 NewLangId = (LANGID)ResourceIdRetry; 00791 } else { 00792 NewLangId = UILangId; 00793 } 00794 break; 00795 00796 case 6: // Parimary lang of UI language from the executable resource 00797 00798 if (!UILangId){ 00799 NewLangId = (LANGID)ResourceIdRetry; 00800 } else { 00801 NewLangId = PRIMARYLANGID( (LANGID) UILangId ); 00802 } 00803 break; 00804 00805 case 7: // Use install -native- language 00806 // 00807 // Thread locale is the same as the user locale, then let's 00808 // try loading the native (install) ui language resources. 00809 // 00810 if (!InstallLangId){ 00811 Status = NtQueryInstallUILanguage(&InstallLangId); 00812 if (!NT_SUCCESS( Status )) { 00813 // 00814 // Failed reading key. Skip this lookup. 00815 // 00816 NewLangId = (LANGID)ResourceIdRetry; 00817 break; 00818 00819 } 00820 } 00821 00822 NewLangId = InstallLangId; 00823 break; 00824 00825 case 8: // Use lang id from locale in TEB 00826 if (SUBLANGID( GivenLanguage ) == SUBLANG_SYS_DEFAULT) { 00827 // Skip over all USER locale options 00828 DefaultThreadLocale = 0; 00829 RetryCount += 2; 00830 break; 00831 } 00832 00833 if (NtCurrentTeb() != NULL) { 00834 NewLangId = LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale); 00835 } 00836 break; 00837 00838 case 9: // Use User's default locale 00839 Status = NtQueryDefaultLocale( TRUE, &DefaultThreadLocale ); 00840 if (NT_SUCCESS( Status )) { 00841 NewLangId = LANGIDFROMLCID(DefaultThreadLocale); 00842 break; 00843 } 00844 00845 RetryCount++; 00846 break; 00847 00848 case 10: // Use primary language of User's default locale 00849 NewLangId = PRIMARYLANGID( (LANGID)ResourceIdRetry ); 00850 break; 00851 00852 case 11: // Use System default locale 00853 Status = NtQueryDefaultLocale( FALSE, &DefaultSystemLocale ); 00854 if (!NT_SUCCESS( Status )) { 00855 RetryCount++; 00856 break; 00857 } 00858 if (DefaultSystemLocale != DefaultThreadLocale) { 00859 NewLangId = LANGIDFROMLCID(DefaultSystemLocale); 00860 break; 00861 } 00862 00863 RetryCount += 2; 00864 // fall through 00865 00866 case 13: // Use US English language 00867 NewLangId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); 00868 break; 00869 00870 case 12: // Use primary language of System default locale 00871 NewLangId = PRIMARYLANGID( (LANGID)ResourceIdRetry ); 00872 break; 00873 00874 case 14: // Take any lang id that matches 00875 NewLangId = USE_FIRSTAVAILABLE_LANGID; 00876 break; 00877 #endif 00878 default: // No lang ids to match 00879 goto ReturnFailure; 00880 break; 00881 } 00882 00883 // 00884 // If looking for a specific language id and same as the 00885 // one we just looked up, then skip it. 00886 // 00887 if (NewLangId != USE_FIRSTAVAILABLE_LANGID && 00888 NewLangId == ResourceIdRetry 00889 ) { 00890 goto TryNextLangId; 00891 } 00892 00893 // 00894 // Try this new language Id 00895 // 00896 ResourceIdRetry = (ULONG_PTR)NewLangId; 00897 ResourceIdPath = &ResourceIdRetry; 00898 ResourceDirectory = LanguageResourceDirectory; 00899 } 00900 00901 n = ResourceDirectory->NumberOfNamedEntries; 00902 ResourceDirEntLow = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResourceDirectory+1); 00903 if (!(*ResourceIdPath & LDR_RESOURCE_ID_NAME_MASK)) { 00904 ResourceDirEntLow += n; 00905 n = ResourceDirectory->NumberOfIdEntries; 00906 } 00907 00908 if (!n) { 00909 ResourceDirectory = NULL; 00910 goto NotFound; 00911 } 00912 00913 if (LanguageResourceDirectory != NULL && 00914 *ResourceIdPath == USE_FIRSTAVAILABLE_LANGID 00915 ) { 00916 ResourceDirectory = NULL; 00917 ResourceIdRetry = ResourceDirEntLow->Name; 00918 ResourceEntry = (PIMAGE_RESOURCE_DATA_ENTRY) 00919 ((PCHAR)TopResourceDirectory + 00920 ResourceDirEntLow->OffsetToData 00921 ); 00922 00923 break; 00924 } 00925 00926 ResourceDirectory = NULL; 00927 ResourceDirEntHigh = ResourceDirEntLow + n - 1; 00928 while (ResourceDirEntLow <= ResourceDirEntHigh) { 00929 if ((half = (n >> 1)) != 0) { 00930 ResourceDirEntMiddle = ResourceDirEntLow; 00931 if (*(PUCHAR)&n & 1) { 00932 ResourceDirEntMiddle += half; 00933 } 00934 else { 00935 ResourceDirEntMiddle += half - 1; 00936 } 00937 dir = LdrpCompareResourceNames_U( *ResourceIdPath, 00938 TopResourceDirectory, 00939 ResourceDirEntMiddle 00940 ); 00941 if (!dir) { 00942 if (ResourceDirEntMiddle->DataIsDirectory) { 00943 ResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 00944 ((PCHAR)TopResourceDirectory + 00945 ResourceDirEntMiddle->OffsetToDirectory 00946 ); 00947 } 00948 else { 00949 ResourceDirectory = NULL; 00950 ResourceEntry = (PIMAGE_RESOURCE_DATA_ENTRY) 00951 ((PCHAR)TopResourceDirectory + 00952 ResourceDirEntMiddle->OffsetToData 00953 ); 00954 } 00955 00956 break; 00957 } 00958 else { 00959 if (dir < 0) { 00960 ResourceDirEntHigh = ResourceDirEntMiddle - 1; 00961 if (*(PUCHAR)&n & 1) { 00962 n = half; 00963 } 00964 else { 00965 n = half - 1; 00966 } 00967 } 00968 else { 00969 ResourceDirEntLow = ResourceDirEntMiddle + 1; 00970 n = half; 00971 } 00972 } 00973 } 00974 else { 00975 if (n != 0) { 00976 dir = LdrpCompareResourceNames_U( *ResourceIdPath, 00977 TopResourceDirectory, 00978 ResourceDirEntLow 00979 ); 00980 if (!dir) { 00981 if (ResourceDirEntLow->DataIsDirectory) { 00982 ResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY) 00983 ((PCHAR)TopResourceDirectory + 00984 ResourceDirEntLow->OffsetToDirectory 00985 ); 00986 } 00987 else { 00988 ResourceEntry = (PIMAGE_RESOURCE_DATA_ENTRY) 00989 ((PCHAR)TopResourceDirectory + 00990 ResourceDirEntLow->OffsetToData 00991 ); 00992 } 00993 } 00994 } 00995 00996 break; 00997 } 00998 } 00999 01000 ResourceIdPath++; 01001 } 01002 01003 if (ResourceEntry != NULL && !FindDirectoryEntry) { 01004 *ResourceDirectoryOrData = (PVOID)ResourceEntry; 01005 Status = STATUS_SUCCESS; 01006 } 01007 else 01008 if (ResourceDirectory != NULL && FindDirectoryEntry) { 01009 *ResourceDirectoryOrData = (PVOID)ResourceDirectory; 01010 Status = STATUS_SUCCESS; 01011 } 01012 else { 01013 NotFound: 01014 switch( IdPathLength - ResourceIdPathLength) { 01015 case 3: Status = STATUS_RESOURCE_LANG_NOT_FOUND; break; 01016 case 2: Status = STATUS_RESOURCE_NAME_NOT_FOUND; break; 01017 case 1: Status = STATUS_RESOURCE_TYPE_NOT_FOUND; break; 01018 default: Status = STATUS_INVALID_PARAMETER; break; 01019 } 01020 } 01021 01022 if (Status == STATUS_RESOURCE_LANG_NOT_FOUND && 01023 LanguageResourceDirectory != NULL 01024 ) { 01025 ResourceEntry = NULL; 01026 goto TryNextLangId; 01027 ReturnFailure: ; 01028 Status = STATUS_RESOURCE_LANG_NOT_FOUND; 01029 } 01030 } 01031 except (EXCEPTION_EXECUTE_HANDLER) { 01032 Status = GetExceptionCode(); 01033 } 01034 01035 return Status; 01036 }

BOOLEAN LdrpSetAlternateResourceModuleHandle IN PVOID  Module,
IN PVOID  AlternateModule
 

Definition at line 1492 of file ldrrsrc.c.

References _ALT_RESOURCE_MODULE::AlternateModule, AlternateResourceModuleCount, AlternateResourceModules, AltResMemBlockCount, FALSE, MEMBLOCKSIZE, _ALT_RESOURCE_MODULE::ModuleBase, NULL, RESMODSIZE, RtlAllocateHeap, RtlReAllocateHeap(), and TRUE.

Referenced by LdrLoadAlternateResourceModule().

01499 : 01500 01501 This function records the handle of the base module and alternate 01502 resource module in an array. 01503 01504 Arguments: 01505 01506 Module - The handle of the base module. 01507 AlternateModule - The handle of the alternate resource module 01508 01509 Return Value: 01510 01511 TBD. 01512 01513 --*/ 01514 01515 { 01516 PALT_RESOURCE_MODULE NewModules; 01517 01518 if (AlternateResourceModules == NULL){ 01519 // 01520 // Allocate memory of initial size MEMBLOCKSIZE. 01521 // 01522 NewModules = RtlAllocateHeap( 01523 RtlProcessHeap(), 01524 HEAP_ZERO_MEMORY, 01525 RESMODSIZE * MEMBLOCKSIZE); 01526 if (!NewModules){ 01527 return FALSE; 01528 } 01529 AlternateResourceModules = NewModules; 01530 AltResMemBlockCount = MEMBLOCKSIZE; 01531 } 01532 else 01533 if (AlternateResourceModuleCount >= AltResMemBlockCount ){ 01534 // 01535 // ReAllocate another chunk of memory. 01536 // 01537 NewModules = RtlReAllocateHeap( 01538 RtlProcessHeap(), 01539 0, 01540 AlternateResourceModules, 01541 (AltResMemBlockCount + MEMBLOCKSIZE) * RESMODSIZE 01542 ); 01543 01544 if (!NewModules){ 01545 return FALSE; 01546 } 01547 AlternateResourceModules = NewModules; 01548 AltResMemBlockCount += MEMBLOCKSIZE; 01549 } 01550 01551 AlternateResourceModules[AlternateResourceModuleCount].ModuleBase = Module; 01552 AlternateResourceModules[AlternateResourceModuleCount].AlternateModule = AlternateModule; 01553 01554 01555 01556 AlternateResourceModuleCount++; 01557 01558 return TRUE; 01559 01560 }

BOOLEAN LdrpVerifyAlternateResourceModule IN PVOID  Module,
IN PVOID  AlternateModule
 

Definition at line 1427 of file ldrrsrc.c.

References FALSE, InstallLangId, LdrpGetFileVersion(), NT_SUCCESS, NtQueryDefaultUILanguage(), NtQueryInstallUILanguage(), NTSTATUS(), Status, TRUE, and UILangId.

01434 : 01435 01436 This function verifies if the alternate resource module has the same 01437 version of the base module. 01438 01439 Arguments: 01440 01441 Module - The handle of the base module. 01442 AlternateModule - The handle of the alternate resource module 01443 01444 Return Value: 01445 01446 TBD. 01447 01448 --*/ 01449 01450 { 01451 ULONGLONG ModuleVersion; 01452 ULONGLONG AltModuleVersion; 01453 NTSTATUS Status; 01454 01455 if (!UILangId){ 01456 Status = NtQueryDefaultUILanguage( &UILangId); 01457 if (!NT_SUCCESS( Status )) { 01458 // 01459 // Failed to get UI LangID. AltResource not enabled. 01460 // 01461 return FALSE; 01462 } 01463 } 01464 01465 if (!LdrpGetFileVersion(AlternateModule, UILangId, &AltModuleVersion)){ 01466 return FALSE; 01467 } 01468 01469 if (!InstallLangId){ 01470 Status = NtQueryInstallUILanguage (&InstallLangId); 01471 if (!NT_SUCCESS( Status )) { 01472 // 01473 // Failed to get Install LangID. AltResource not enabled. 01474 // 01475 return FALSE; 01476 } 01477 } 01478 01479 if (!LdrpGetFileVersion(Module, InstallLangId, &ModuleVersion)){ 01480 return FALSE; 01481 } 01482 01483 if (ModuleVersion == AltModuleVersion){ 01484 return TRUE; 01485 } 01486 else{ 01487 return FALSE; 01488 } 01489 }

BOOLEAN LdrUnloadAlternateResourceModule IN PVOID  Module  ) 
 

Definition at line 1882 of file ldrrsrc.c.

References _ALT_RESOURCE_MODULE::AlternateModule, AlternateResourceModuleCount, AlternateResourceModules, AltResMemBlockCount, EXCEPTION_EXECUTE_HANDLER, FALSE, LoaderLock, MEMBLOCKSIZE, _ALT_RESOURCE_MODULE::ModuleBase, NO_ALTERNATE_RESOURCE_MODULE, NtUnmapViewOfSection(), NULL, RESMODSIZE, RtlFreeHeap, RtlReAllocateHeap(), and TRUE.

Referenced by LdrUnloadDll().

01888 : 01889 01890 This function unmaps an alternate resource module from the process' 01891 address space and updates alternate resource module table. 01892 01893 Arguments: 01894 01895 Module - handle of the base module. 01896 01897 Return Value: 01898 01899 TBD. 01900 01901 --*/ 01902 01903 { 01904 ULONG ModuleIndex; 01905 PALT_RESOURCE_MODULE AltModule; 01906 01907 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01908 if (AlternateResourceModuleCount == 0){ 01909 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01910 return TRUE; 01911 } 01912 01913 for (ModuleIndex = AlternateResourceModuleCount; 01914 ModuleIndex > 0; 01915 ModuleIndex--){ 01916 if (AlternateResourceModules[ModuleIndex-1].ModuleBase == Module){ 01917 break; 01918 } 01919 } 01920 01921 if (ModuleIndex == 0){ 01922 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01923 return FALSE; 01924 } 01925 // 01926 // Adjust to the actual index 01927 // 01928 ModuleIndex --; 01929 01930 AltModule = &AlternateResourceModules[ModuleIndex]; 01931 if (AltModule->AlternateModule != NO_ALTERNATE_RESOURCE_MODULE) { 01932 NtUnmapViewOfSection( 01933 NtCurrentProcess(), 01934 (PVOID)((ULONG_PTR)AltModule->AlternateModule & ~0x00000001) 01935 ); 01936 } 01937 01938 __try { 01939 if (ModuleIndex != AlternateResourceModuleCount - 1){ 01940 // 01941 // Consolidate the array. Skip this if unloaded item 01942 // is the last element. 01943 // 01944 RtlMoveMemory( 01945 AltModule, 01946 AltModule + 1, 01947 (AlternateResourceModuleCount - ModuleIndex - 1) * RESMODSIZE 01948 ); 01949 } 01950 } 01951 __except (EXCEPTION_EXECUTE_HANDLER) { 01952 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01953 return FALSE; 01954 } 01955 01956 AlternateResourceModuleCount --; 01957 01958 if (AlternateResourceModuleCount == 0){ 01959 RtlFreeHeap( 01960 RtlProcessHeap(), 01961 0, 01962 AlternateResourceModules 01963 ); 01964 AlternateResourceModules = NULL; 01965 AltResMemBlockCount = 0; 01966 } 01967 else 01968 if (AlternateResourceModuleCount < AltResMemBlockCount - MEMBLOCKSIZE){ 01969 AltModule = RtlReAllocateHeap( 01970 RtlProcessHeap(), 01971 0, 01972 AlternateResourceModules, 01973 (AltResMemBlockCount - MEMBLOCKSIZE) * RESMODSIZE); 01974 01975 if (!AltModule){ 01976 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01977 return FALSE; 01978 } 01979 01980 AlternateResourceModules = AltModule; 01981 AltResMemBlockCount -= MEMBLOCKSIZE; 01982 } 01983 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01984 return TRUE; 01985 }


Variable Documentation

ULONG AlternateResourceModuleCount
 

Definition at line 37 of file ldrrsrc.c.

Referenced by LdrFlushAlternateResourceModules(), LdrGetAlternateResourceModuleHandle(), LdrpSetAlternateResourceModuleHandle(), and LdrUnloadAlternateResourceModule().

PALT_RESOURCE_MODULE AlternateResourceModules
 

Definition at line 36 of file ldrrsrc.c.

Referenced by LdrFlushAlternateResourceModules(), LdrGetAlternateResourceModuleHandle(), LdrpSetAlternateResourceModuleHandle(), and LdrUnloadAlternateResourceModule().

ULONG AltResMemBlockCount
 

Definition at line 38 of file ldrrsrc.c.

Referenced by LdrFlushAlternateResourceModules(), LdrpSetAlternateResourceModuleHandle(), and LdrUnloadAlternateResourceModule().

LANGID InstallLangId
 

Definition at line 39 of file ldrrsrc.c.

Referenced by LdrAlternateResourcesEnabled(), LdrpSearchResourceSection_U(), and LdrpVerifyAlternateResourceModule().

LANGID UILangId
 

Definition at line 39 of file ldrrsrc.c.

Referenced by LdrAlternateResourcesEnabled(), LdrFlushAlternateResourceModules(), LdrLoadAlternateResourceModule(), LdrpSearchResourceSection_U(), and LdrpVerifyAlternateResourceModule().


Generated on Sat May 15 19:44:31 2004 for test by doxygen 1.3.7