test: ldrp.h File Reference

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

# ldrp.h File Reference

`#include <nt.h>`
`#include <ntrtl.h>`
`#include <nturtl.h>`
`#include <string.h>`
`#include "wdbgexts.h"`
`#include <ntdbg.h>`

Go to the source code of this file.

## Classes

struct | _LDRP_PATH_CACHE
struct | _LDRP_TLS_ENTRY

## Defines

#define | NOEXTAPI
#define | LDRP_MAX_KNOWN_PATH 128
#define | NATIVE_PAGE_SIZE PAGE_SIZE
#define | NATIVE_PAGE_SHIFT PAGE_SHIFT
#define | NATIVE_BYTES_TO_PAGES(Size) BYTES_TO_PAGES(Size)
#define | LDRP_HASH_TABLE_SIZE 32
#define | LDRP_HASH_MASK (LDRP_HASH_TABLE_SIZE-1)
#define | LDRP_COMPUTE_HASH_INDEX(wch) ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK )
#define | LDRP_BAD_DLL LongToPtr(0xffbadd11)
#define | LdrpReferenceLoadedDll(lde) LdrpUpdateLoadCount( lde, TRUE )
#define | LdrpDereferenceLoadedDll(lde) LdrpUpdateLoadCount( lde, FALSE )
#define | MAKE_TAG(t) (RTL_HEAP_MAKE_TAG( NtdllBaseTag, t ))
#define | CSR_TAG 0
#define | LDR_TAG 1
#define | CURDIR_TAG 2
#define | TLS_TAG 3
#define | DBG_TAG 4
#define | SE_TAG 5
#define | TEMP_TAG 6
#define | ATOM_TAG 7
#define | LdrpCallInitRoutine(InitRoutine, DllHandle, Reason, Context) (InitRoutine)((DllHandle), (Reason), (Context))

## Typedefs

typedef _LDRP_PATH_CACHE | LDRP_PATH_CACHE
typedef _LDRP_PATH_CACHE * | PLDRP_PATH_CACHE
typedef _LDRP_TLS_ENTRY | LDRP_TLS_ENTRY
typedef _LDRP_TLS_ENTRY * | PLDRP_TLS_ENTRY

## Functions

NTSTATUS | LdrpSnapIAT (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Export, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Import, IN PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, IN BOOLEAN SnapForwardersOnly)
NTSTATUS | LdrpSnapLinksToDllHandle (IN PVOID DllHandle, IN ULONG NumberOfThunks, IN OUT PIMAGE_THUNK_DATA FirstThunk)
NTSTATUS | LdrpSnapThunk (IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN StaticSnap, IN PSZ DllName OPTIONAL)
USHORT | LdrpNameToOrdinal (IN PSZ Name, IN ULONG NumberOfNames, IN PVOID DllBase, IN PULONG NameTableBase, IN PUSHORT NameOrdinalTableBase)
PLDR_DATA_TABLE_ENTRY | LdrpAllocateDataTableEntry (IN PVOID DllBase)
BOOLEAN | LdrpCheckForLoadedDll (IN PWSTR DllPath OPTIONAL, IN PUNICODE_STRING DllName, IN BOOLEAN StaticLink, IN BOOLEAN Wx86KnownDll, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry)
BOOLEAN | LdrpCheckForLoadedDllHandle (IN PVOID DllHandle, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry)
NTSTATUS | LdrpMapDll (IN PWSTR DllPath OPTIONAL, IN PWSTR DllName, IN PULONG DllCharacteristics OPTIONAL, IN BOOLEAN StaticLink, IN BOOLEAN Wx86KnownDll, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry)
NTSTATUS | LdrpWalkImportDescriptor (IN PWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
NTSTATUS | LdrpRunInitializeRoutines (IN PCONTEXT Context OPTIONAL)
VOID | LdrpUpdateLoadCount (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry, IN BOOLEAN IncrementCount)
NTSTATUS | LdrpInitializeProcess (IN PCONTEXT Context OPTIONAL, IN PVOID SystemDllBase, IN PUNICODE_STRING UnicodeImageName)
VOID | LdrpInitialize (IN PCONTEXT Context, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID | LdrpInsertMemoryTableEntry (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
BOOLEAN | LdrpResolveDllName (IN PWSTR DllPath OPTIONAL, IN PWSTR DllName, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName, OUT PHANDLE DllFile)
NTSTATUS | LdrpCreateDllSection (IN PUNICODE_STRING FullDllName, IN HANDLE DllFile, IN PUNICODE_STRING BaseName, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
VOID | LdrpInitializePathCache (VOID)
PVOID | LdrpFetchAddressOfEntryPoint (IN PVOID Base)
BOOLEAN | xRtlDosPathNameToNtPathName (IN PSZ DosFileName, OUT PSTRING NtFileName, OUT PSZ *FilePart OPTIONAL, OUT PRTL_RELATIVE_NAME RelativeName OPTIONAL)
ULONG | xRtlDosSearchPath (PSZ lpPath, PSZ lpFileName, PSZ lpExtension, ULONG nBufferLength, PSZ lpBuffer, PSZ *lpFilePart OPTIONAL)
ULONG | xRtlGetFullPathName (PSZ lpFileName, ULONG nBufferLength, PSZ lpBuffer, PSZ *lpFilePart OPTIONAL)
PSZ | UnicodeToAnsii (IN PWSTR String)
HANDLE | LdrpCheckForKnownDll (IN PWSTR DllName, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName)
NTSTATUS | LdrpSetProtection (IN PVOID Base, IN BOOLEAN Reset, IN BOOLEAN StaticLink)
NTSTATUS | LdrpInitializeTls (VOID)
NTSTATUS | LdrpAllocateTls (VOID)
VOID | LdrpFreeTls (VOID)
VOID | LdrpCallTlsInitializers (PVOID DllBase, ULONG Reason)
NTSTATUS NTAPI | LdrpLoadDll (IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines)
NTSTATUS NTAPI | LdrpGetProcedureAddress (IN PVOID DllHandle, IN PANSI_STRING ProcedureName OPTIONAL, IN ULONG ProcedureNumber OPTIONAL, OUT PVOID *ProcedureAddress, IN BOOLEAN RunInitRoutines)
PLIST_ENTRY | RtlpLockProcessHeapsList (VOID)
VOID | RtlpUnlockProcessHeapsList (VOID)
BOOLEAN | RtlpSerializeHeap (IN PVOID HeapHandle)
PVOID | LdrpDefineDllTag (PWSTR TagName, PUSHORT TagIndex)

## Variables

BOOLEAN | LdrpImageHasTls
UNICODE_STRING | LdrpDefaultPath
HANDLE | LdrpKnownDllObjectDirectory
WCHAR | LdrpKnownDllPathBuffer [LDRP_MAX_KNOWN_PATH]
UNICODE_STRING | LdrpKnownDllPath
LIST_ENTRY | LdrpHashTable [LDRP_HASH_TABLE_SIZE]
LIST_ENTRY | LdrpDefaultPathCache
BOOLEAN | ShowSnaps
BOOLEAN | RtlpTimoutDisable
LARGE_INTEGER | RtlpTimeout
ULONG | NtGlobalFlag
LIST_ENTRY | RtlCriticalSectionList
RTL_CRITICAL_SECTION | RtlCriticalSectionLock
BOOLEAN | LdrpShutdownInProgress
BOOLEAN | LdrpInLdrInit
BOOLEAN | LdrpLdrDatabaseIsSetup
BOOLEAN | LdrpVerifyDlls
PLDR_DATA_TABLE_ENTRY | LdrpImageEntry
LIST_ENTRY | LdrpUnloadHead
BOOLEAN | LdrpActiveUnloadCount
PLDR_DATA_TABLE_ENTRY | LdrpGetModuleHandleCache
PLDR_DATA_TABLE_ENTRY | LdrpLoadedDllHandleCache
ULONG | LdrpFatalHardErrorCount
RTL_CRITICAL_SECTION | FastPebLock
HANDLE | LdrpShutdownThreadId
ULONG | LdrpNumberOfProcessors
LIST_ENTRY | LdrpTlsList
ULONG | LdrpNumberOfTlsEntries
ULONG | NtdllBaseTag

## Define Documentation

#define ATOM_TAG 7

| Definition at line 466 of file ldrp.h. Referenced by LdrpInitializeProcess().

#define CSR_TAG 0

| Definition at line 459 of file ldrp.h. Referenced by CsrClientConnectToServer(), and CsrpConnectToServer().

#define CURDIR_TAG 2

| Definition at line 461 of file ldrp.h.

#define DBG_TAG 4

| Definition at line 463 of file ldrp.h. Referenced by DbgSsHandleKmApiMsg().

#define LDR_TAG 1

| Definition at line 460 of file ldrp.h. Referenced by LdrpAllocateDataTableEntry(), LdrpCheckForKnownDll(), LdrpInitializeProcess(), and LdrpResolveDllName().

#define LDRP_BAD_DLL LongToPtr(0xffbadd11)

| Definition at line 166 of file ldrp.h. Referenced by LdrpSnapThunk().

#define LDRP_COMPUTE_HASH_INDEX | ( | wch |  | ) | ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK )

| Definition at line 161 of file ldrp.h. Referenced by LdrpCheckForLoadedDll(), and LdrpInsertMemoryTableEntry().

#define LDRP_HASH_MASK (LDRP_HASH_TABLE_SIZE-1)

| Definition at line 160 of file ldrp.h.

#define LDRP_HASH_TABLE_SIZE 32

| Definition at line 159 of file ldrp.h. Referenced by LdrpInitializeProcess().

#define LDRP_MAX_KNOWN_PATH 128

| Definition at line 35 of file ldrp.h.

#define LdrpCallInitRoutine | ( | InitRoutine,
|  | DllHandle,
|  | Reason,
|  | Context |  | ) | (InitRoutine)((DllHandle), (Reason), (Context))

| Definition at line 484 of file ldrp.h. Referenced by LdrpCallTlsInitializers(), LdrpInitializeThread(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), LdrShutdownThread(), and LdrUnloadDll().

#define LdrpDereferenceLoadedDll | ( | lde |  | ) | LdrpUpdateLoadCount( lde, FALSE )

| Definition at line 254 of file ldrp.h. Referenced by LdrUnloadDll().

#define LdrpReferenceLoadedDll | ( | lde |  | ) | LdrpUpdateLoadCount( lde, TRUE )

| Definition at line 253 of file ldrp.h. Referenced by LdrpInitializeProcess(), and LdrpLoadDll().

#define MAKE_TAG | ( | t |  | ) | (RTL_HEAP_MAKE_TAG( NtdllBaseTag, t ))

| Definition at line 457 of file ldrp.h. Referenced by AddAlias(), AddCommand(), AddExeAliasList(), AddFaceNode(), AllocateCommandHistory(), AllocateConsole(), AllocateScrollBuffer(), BeginPopup(), ConsoleAddProcessRoutine(), ConsoleClientConnectRoutine(), ConvertOutputToOem(), ConvertOutputToUnicode(), CookedRead(), CreateConsoleBitmap(), CreateDbcsScreenBuffer(), CreateInputBuffer(), CreateScreenBuffer(), CsrClientConnectToServer(), CsrpConnectToServer(), DbgSsHandleKmApiMsg(), DoStringPaste(), DrawCommandListPopup(), EnumerateFonts(), FalseUnicodeToRealUnicode(), FE_WriteRegionToScreenHW(), FindExe(), FindExeCommandHistory(), FlushAllButKeys(), FontEnum(), GrowConsoleHandleTable(), GrowIoHandleTable(), InheritIoHandleTable(), InitializeInputHandle(), InitializeScrollBuffer(), LdrpAllocateDataTableEntry(), LdrpAllocateTls(), LdrpCheckForKnownDll(), LdrpGetProcedureAddress(), LdrpInitializeProcess(), LdrpInitializeTls(), LdrpResolveDllName(), LdrpRunInitializeRoutines(), LdrQueryImageFileExecutionOptions(), MatchandCopyAlias(), MergeAttrStrings(), MyRegQueryValue(), PrependInputBuffer(), ProcessCommandListInput(), ProcessCtrlEvents(), QueueConsoleMessage(), QueueThreadMessage(), RawReadWaitRoutine(), ReadChars(), ReadOutputString(), ReallocCommandHistory(), RealUnicodeToFalseUnicode(), ReCreateDbcsScreenBuffer(), ReplaceAlias(), ResizeScreenBuffer(), RtlCopySecurityDescriptor(), RtlCreateAndSetSD(), RtlpConvertAclToAutoInherit(), RtlpConvertToAutoInheritSecurityObject(), RtlpCreateServerAcl(), RtlpGetDefaultsSubjectContext(), RtlpInheritAcl(), RtlpNewSecurityObject(), RtlpSetSecurityObject(), SetInputBufferSize(), SetRAMFont(), SetRAMFontCodePage(), SrvAddConsoleAlias(), SrvAllocConsole(), SrvGetConsoleAlias(), SrvSetConsoleTitle(), SrvVDMConsoleOperation(), SrvWriteConsoleOutput(), StoreSelection(), StoreTextBufferFontInfo(), TranslateConsoleTitle(), UpdateComplexRegion(), WaitForMoreToRead(), WWSB_DoSrvWriteConsole(), WWSB_DoWriteConsole(), WWSB_WriteChars(), WWSB_WriteOutputString(), WWSB_WriteRectToScreenBuffer(), and WWSB_WriteRegionToScreen().

#define NATIVE_BYTES_TO_PAGES | ( | Size |  | ) | BYTES_TO_PAGES(Size)

| Definition at line 155 of file ldrp.h.

#define NATIVE_PAGE_SHIFT PAGE_SHIFT

| Definition at line 154 of file ldrp.h.

#define NATIVE_PAGE_SIZE PAGE_SIZE

| Definition at line 153 of file ldrp.h. Referenced by LdrpInitializeProcess(), and LdrpMapDll().

#define NOEXTAPI

| Definition at line 28 of file ldrp.h.

#define SE_TAG 5

| Definition at line 464 of file ldrp.h. Referenced by RtlCopySecurityDescriptor(), RtlCreateAndSetSD(), RtlpConvertAclToAutoInherit(), RtlpConvertToAutoInheritSecurityObject(), RtlpCreateServerAcl(), RtlpGetDefaultsSubjectContext(), RtlpInheritAcl(), RtlpNewSecurityObject(), and RtlpSetSecurityObject().

#define TEMP_TAG 6

| Definition at line 465 of file ldrp.h. Referenced by LdrpGetProcedureAddress(), LdrpResolveDllName(), LdrpRunInitializeRoutines(), and LdrQueryImageFileExecutionOptions().

#define TLS_TAG 3

| Definition at line 462 of file ldrp.h. Referenced by LdrpAllocateTls(), and LdrpInitializeTls().

## Typedef Documentation

typedef struct _LDRP_PATH_CACHE LDRP_PATH_CACHE

typedef struct _LDRP_TLS_ENTRY LDRP_TLS_ENTRY

| Referenced by LdrpAllocateTls().

typedef struct _LDRP_PATH_CACHE * PLDRP_PATH_CACHE

typedef struct _LDRP_TLS_ENTRY * PLDRP_TLS_ENTRY

| Referenced by LdrpInitializeTls().

## Function Documentation

PLDR_DATA_TABLE_ENTRY LdrpAllocateDataTableEntry | ( | IN PVOID | DllBase | ) |

Definition at line 3043 of file ldrsnap.c.

References LDR_TAG, MAKE_TAG, NULL, RtlAllocateHeap, and RtlImageNtHeader().

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

    03049                    :
    03050
    03051     This function allocates an entry in the loader data table. If the
    03052     table is going to overflow, then a new table is allocated.
    03053
    03054 Arguments:
    03055
    03056     DllBase - Supplies the address of the base of the DLL Image.
    03057         be added to the loader data table.
    03058
    03059 Return Value:
    03060
    03061     Returns the address of the allocated loader data table entry
    03062
    03063 --*/
    03064
    03065 {
    03066     PLDR_DATA_TABLE_ENTRY Entry;
    03067     PIMAGE_NT_HEADERS NtHeaders;
    03068
    03069     NtHeaders = RtlImageNtHeader(DllBase);
    03070
    03071     Entry = NULL;
    03072     if ( NtHeaders ) {
    03073         Entry = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( LDR_TAG ) | HEAP_ZERO_MEMORY,sizeof( *Entry ));
    03074         if ( Entry ) {
    03075             Entry->DllBase = DllBase;
    03076             Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
    03077             Entry->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
    03078             }
    03079         }
    03080     return Entry;
    03081 }

NTSTATUS LdrpAllocateTls | ( | VOID |  | ) |

Definition at line 2071 of file ldrinit.c.

References DbgPrint, LDRP_TLS_ENTRY, LdrpNumberOfTlsEntries, LdrpTlsList, MAKE_TAG, RtlAllocateHeap, ShowSnaps, _LDRP_TLS_ENTRY::Tls, and TLS_TAG.

Referenced by LdrpInitializeThread(), and LdrpInitializeTls().

    02074 {
    02075     PTEB Teb;
    02076     PLIST_ENTRY Head, Next;
    02077     PLDRP_TLS_ENTRY TlsEntry;
    02078     PVOID *TlsVector;
    02079
    02080     Teb = NtCurrentTeb();
    02081
    02082     //
    02083     // Allocate the array of thread local storage pointers
    02084     //
    02085
    02086     if ( LdrpNumberOfTlsEntries ) {
    02087         TlsVector = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TLS_TAG ),sizeof(PVOID)*LdrpNumberOfTlsEntries);
    02088         if ( !TlsVector ) {
    02089             return STATUS_NO_MEMORY;
    02090             }
    02091
    02092         Teb->ThreadLocalStoragePointer = TlsVector;
    02093         Head = &LdrpTlsList;
    02094         Next = Head->Flink;
    02095
    02096         while ( Next != Head ) {
    02097             TlsEntry = CONTAINING_RECORD(Next, LDRP_TLS_ENTRY, Links);
    02098             Next = Next->Flink;
    02099             TlsVector[TlsEntry->Tls.Characteristics] = RtlAllocateHeap(
    02100                                                         RtlProcessHeap(),
    02101                                                         MAKE_TAG( TLS_TAG ),
    02102                                                         TlsEntry->Tls.EndAddressOfRawData - TlsEntry->Tls.StartAddressOfRawData
    02103                                                         );
    02104             if (!TlsVector[TlsEntry->Tls.Characteristics] ) {
    02105                 return STATUS_NO_MEMORY;
    02106                 }
    02107
    02108             if (ShowSnaps) {
    02109                 DbgPrint("LDR: TlsVector %x Index %d = %x copied from %x to %x\n",
    02110                     TlsVector,
    02111                     TlsEntry->Tls.Characteristics,
    02112                     &TlsVector[TlsEntry->Tls.Characteristics],
    02113                     TlsEntry->Tls.StartAddressOfRawData,
    02114                     TlsVector[TlsEntry->Tls.Characteristics]
    02115                     );
    02116                 }
    02117
    02118             RtlCopyMemory(
    02119                 TlsVector[TlsEntry->Tls.Characteristics],
    02120                 (PVOID)TlsEntry->Tls.StartAddressOfRawData,
    02121                 TlsEntry->Tls.EndAddressOfRawData - TlsEntry->Tls.StartAddressOfRawData
    02122                 );
    02123
    02124             //
    02125             // Do the TLS Callouts
    02126             //
    02127
    02128             }
    02129         }
    02130     return STATUS_SUCCESS;
    02131 }

VOID LdrpCallTlsInitializers | ( | PVOID | DllBase,
|  | ULONG | Reason
| ) |

Definition at line 2178 of file ldrinit.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, LdrpCallInitRoutine, NULL, RtlImageDirectoryEntryToData(), ShowSnaps, and TRUE.

Referenced by LdrpInitializeThread(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), and LdrShutdownThread().

    02182 {
    02183     PIMAGE_TLS_DIRECTORY TlsImage;
    02184     ULONG TlsSize;
    02185     PIMAGE_TLS_CALLBACK *CallBackArray;
    02186     PIMAGE_TLS_CALLBACK InitRoutine;
    02187
    02188     TlsImage = (PIMAGE_TLS_DIRECTORY)RtlImageDirectoryEntryToData(
    02189                        DllBase,
    02190                        TRUE,
    02191                        IMAGE_DIRECTORY_ENTRY_TLS,
    02192                        &TlsSize
    02193                        );
    02194
    02195
    02196     try {
    02197         if ( TlsImage ) {
    02198             CallBackArray = (PIMAGE_TLS_CALLBACK *)TlsImage->AddressOfCallBacks;
    02199             if ( CallBackArray ) {
    02200                 if (ShowSnaps) {
    02201                     DbgPrint( "LDR: Tls Callbacks Found. Imagebase %lx Tls %lx CallBacks %lx\n",
    02202                                 DllBase,
    02203                                 TlsImage,
    02204                                 CallBackArray
    02205                             );
    02206                     }
    02207
    02208                 while(*CallBackArray){
    02209                     InitRoutine = *CallBackArray++;
    02210
    02211                     if (ShowSnaps) {
    02212                         DbgPrint( "LDR: Calling Tls Callback Imagebase %lx Function %lx\n",
    02213                                     DllBase,
    02214                                     InitRoutine
    02215                                 );
    02216                         }
    02217
    02218 #if defined (WX86)
    02219                     if (!Wx86ProcessInit ||
    02220                         LdrpRunWx86DllEntryPoint(
    02221                              (PDLL_INIT_ROUTINE)InitRoutine,
    02222                              NULL,
    02223                              DllBase,
    02224                              Reason,
    02225                              NULL
    02226                              ) ==  STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
    02227 #endif
    02228                        {
    02229                         LdrpCallInitRoutine((PDLL_INIT_ROUTINE)InitRoutine,
    02230                                             DllBase,
    02231                                             Reason,
    02232                                             0);
    02233                         }
    02234
    02235                     }
    02236                 }
    02237             }
    02238         }
    02239     except (EXCEPTION_EXECUTE_HANDLER) {
    02240         ;
    02241         }
    02242 }

HANDLE LdrpCheckForKnownDll | ( | IN PWSTR | DllName,
|  | OUT PUNICODE_STRING | FullDllName,
|  | OUT PUNICODE_STRING | BaseDllName
| ) |

Definition at line 3283 of file ldrsnap.c.

References LDR_TAG, LdrpKnownDllObjectDirectory, LdrpKnownDllPath, MAKE_TAG, NT_SUCCESS, NtOpenSection(), NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlInitUnicodeString(), Status, Unicode, and USHORT.

Referenced by LdrpMapDll().

    03291                    :
    03292
    03293     This function checks to see if the specified DLL is a known DLL.
    03294     It assumes it is only called for static DLL's, and when
    03295     the know DLL directory structure has been set up.
    03296
    03297 Arguments:
    03298
    03299     DllName - Supplies the name of the DLL.
    03300
    03301     FullDllName - Returns the fully qualified pathname of the
    03302         DLL. The Buffer field of this string is dynamically
    03303         allocated from the processes heap.
    03304
    03305     BaseDLLName - Returns the base dll name of the dll.  The base name
    03306         is the file name portion of the dll path without the trailing
    03307         extension. The Buffer field of this string is dynamically
    03308         allocated from the processes heap.
    03309
    03310 Return Value:
    03311
    03312     NON-NULL - Returns an open handle to the section associated with
    03313         the DLL.
    03314
    03315     NULL - The DLL is not known.
    03316
    03317 --*/
    03318
    03319 {
    03320
    03321     UNICODE_STRING Unicode;
    03322     HANDLE Section;
    03323     NTSTATUS Status;
    03324     OBJECT_ATTRIBUTES Obja;
    03325     PSZ p;
    03326     PWSTR pw;
    03327
    03328     Section = NULL;
    03329
    03330     //
    03331     // calculate base name
    03332     //
    03333
    03334     RtlInitUnicodeString(&Unicode,DllName);
    03335
    03336
    03337     BaseDllName->Length = Unicode.Length;
    03338     BaseDllName->MaximumLength = Unicode.MaximumLength;
    03339     BaseDllName->Buffer = RtlAllocateHeap(
    03340                             RtlProcessHeap(),MAKE_TAG( LDR_TAG ),
    03341                             Unicode.MaximumLength
    03342                             );
    03343     if ( !BaseDllName->Buffer ) {
    03344         return NULL;
    03345         }
    03346
    03347     RtlMoveMemory(BaseDllName->Buffer,Unicode.Buffer,Unicode.MaximumLength);
    03348
    03349     //
    03350     // now compute the full name for the dll
    03351     //
    03352
    03353     FullDllName->Length = (USHORT)(LdrpKnownDllPath.Length +  // path prefix
    03354                                    (USHORT)sizeof(WCHAR)   +  // seperator
    03355                                    BaseDllName->Length        // base
    03356                                   );
    03357
    03358     FullDllName->MaximumLength = FullDllName->Length + (USHORT)sizeof(UNICODE_NULL);
    03359     FullDllName->Buffer = RtlAllocateHeap(
    03360                             RtlProcessHeap(),MAKE_TAG( LDR_TAG ),
    03361                             FullDllName->MaximumLength
    03362                             );
    03363     if ( !FullDllName->Buffer ) {
    03364         RtlFreeHeap(RtlProcessHeap(),0,BaseDllName->Buffer);
    03365         return NULL;
    03366         }
    03367
    03368     p = (PSZ)FullDllName->Buffer;
    03369     RtlMoveMemory(p,LdrpKnownDllPath.Buffer,LdrpKnownDllPath.Length);
    03370     p += LdrpKnownDllPath.Length;
    03371     pw = (PWSTR)p;
    03372     *pw++ = (WCHAR)'\\';
    03373     p = (PSZ)pw;
    03374
    03375     //
    03376     // This is the relative name of the section
    03377     //
    03378
    03379     Unicode.Buffer = (PWSTR)p;
    03380     Unicode.Length = BaseDllName->Length;       // base
    03381     Unicode.MaximumLength = Unicode.Length + (USHORT)sizeof(UNICODE_NULL);
    03382
    03383     RtlMoveMemory(p,BaseDllName->Buffer,BaseDllName->MaximumLength);
    03384
    03385     //
    03386     // open the section object
    03387     //
    03388
    03389     InitializeObjectAttributes(
    03390         &Obja,
    03391         &Unicode,
    03392         OBJ_CASE_INSENSITIVE,
    03393         LdrpKnownDllObjectDirectory,
    03394         NULL
    03395         );
    03396
    03397     Status = NtOpenSection(
    03398             &Section,
    03399             SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE,
    03400             &Obja
    03401             );
    03402
    03403     if ( !NT_SUCCESS(Status) ) {
    03404         Section = NULL;
    03405         RtlFreeHeap(RtlProcessHeap(),0,BaseDllName->Buffer);
    03406         RtlFreeHeap(RtlProcessHeap(),0,FullDllName->Buffer);
    03407         }
    03408 #if DBG
    03409     else {
    03410         LdrpSectionOpens++;
    03411         }
    03412 #endif // DBG
    03413     return Section;
    03414 }

BOOLEAN LdrpCheckForLoadedDll | ( | IN PWSTR DllPath | OPTIONAL,
|  | IN PUNICODE_STRING | DllName,
|  | IN BOOLEAN | StaticLink,
|  | IN BOOLEAN | Wx86KnownDll,
|  | OUT PLDR_DATA_TABLE_ENTRY * | LdrDataTableEntry
| ) |

Definition at line 832 of file ldrsnap.c.

References CHAR, DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, File, L, LDRP_COMPUTE_HASH_INDEX, LdrpDefaultPath, LdrpHashTable, NT_SUCCESS, NtAreMappedFilesTheSame(), NtClose(), NtCreateSection(), NtMapViewOfSection(), NtOpenFile(), NTSTATUS(), NtUnmapViewOfSection(), NULL, ObjectAttributes, RtlCopyUnicodeString(), RtlDosPathNameToNtPathName_U(), RtlDosSearchPath_U(), RtlEqualUnicodeString(), RtlFreeHeap, RtlImageNtHeader(), ShowSnaps, TRUE, and USHORT.

Referenced by LdrGetDllHandle(), LdrpDphDetectSnapRoutines(), LdrpDphInitializeTargetDll(), LdrpLoadDll(), LdrpLoadImportModule(), and LdrpUpdateLoadCount().

    00842                    :
    00843
    00844     This function scans the loader data table looking to see if
    00845     the specified DLL has already been mapped into the image. If
    00846     the dll has been loaded, the address of its data table entry
    00847     is returned.
    00848
    00849 Arguments:
    00850
    00851     DllPath - Supplies an optional search path used to locate the DLL.
    00852
    00853     DllName - Supplies the name to search for.
    00854
    00855     StaticLink - TRUE if performing a static link.
    00856
    00857     Wx86KnownDll - TRUE, treat Importer as x86
    00858
    00859     LdrDataTableEntry - Returns the address of the loader data table
    00860         entry that describes the first dll section that implements the
    00861         dll.
    00862
    00863 Return Value:
    00864
    00865     TRUE- The dll is already loaded.  The address of the data table
    00866         entries that implement the dll, and the number of data table
    00867         entries are returned.
    00868
    00869     FALSE - The dll is not already mapped.
    00870
    00871 --*/
    00872
    00873 {
    00874     BOOLEAN Result;
    00875     PLDR_DATA_TABLE_ENTRY Entry;
    00876     PLIST_ENTRY Head, Next;
    00877     UNICODE_STRING FullDllName;
    00878     HANDLE DllFile;
    00879     BOOLEAN HardCodedPath;
    00880     PWCH p;
    00881     WCHAR wch;
    00882     ULONG i;
    00883     CHAR FullDllNameBuffer[530+sizeof(UNICODE_NULL)];
    00884     ULONG Length = 0;
    00885     PWCH src,dest;
    00886
    00887
    00888
    00889     if (!DllName->Buffer || !DllName->Buffer[0]) {
    00890         return FALSE;
    00891         }
    00892
    00893 #if defined (WX86)
    00894     if (Wx86ProcessInit) {
    00895
    00896         FullDllName.Buffer = (PWCHAR)FullDllNameBuffer;
    00897         FullDllName.MaximumLength = sizeof(FullDllNameBuffer);
    00898         FullDllName.Length = 0;
    00899
    00900         Entry = LdrpWx86CheckForLoadedDll(DllPath,
    00901                                           DllName,
    00902                                           Wx86KnownDll,
    00903                                           &FullDllName
    00904                                           );
    00905
    00906         if (Entry) {
    00907             RtlCopyUnicodeString(DllName, &FullDllName);
    00908             *LdrDataTableEntry = Entry;
    00909             return TRUE;
    00910             }
    00911         else {
    00912             return FALSE;
    00913             }
    00914         }
    00915
    00916 #endif
    00917
    00918
    00919
    00920     //
    00921     // for static links, just go to the hash table
    00922     //
    00923 staticlink:
    00924     if ( StaticLink ) {
    00925
    00926         i = LDRP_COMPUTE_HASH_INDEX(DllName->Buffer[0]);
    00927         Head = &LdrpHashTable[i];
    00928         Next = Head->Flink;
    00929         while ( Next != Head ) {
    00930             Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, HashLinks);
    00931 #if DBG
    00932             LdrpCompareCount++;
    00933 #endif
    00934             if (RtlEqualUnicodeString(DllName,
    00935                         &Entry->BaseDllName,
    00936                         TRUE
    00937                         )) {
    00938
    00939                 *LdrDataTableEntry = Entry;
    00940                 return TRUE;
    00941                 }
    00942             Next = Next->Flink;
    00943             }
    00944         }
    00945
    00946     if ( StaticLink ) {
    00947         return FALSE;
    00948         }
    00949
    00950
    00951     //
    00952     // If the dll name contained a hard coded path
    00953     // (dynamic link only), then the fully qualified
    00954     // name needs to be compared to make sure we
    00955     // have the correct dll.
    00956     //
    00957
    00958     p = DllName->Buffer;
    00959     HardCodedPath = FALSE;
    00960     while (*p) {
    00961         wch = *p++;
    00962         if (wch == (WCHAR)'\\' || wch == (WCHAR)'/' ) {
    00963
    00964             HardCodedPath = TRUE;
    00965
    00966             //
    00967             // We have a hard coded path, so we have to search path
    00968             // for the DLL. We need the full DLL name so we can
    00969
    00970             FullDllName.Buffer = (WCHAR *)FullDllNameBuffer;
    00971
    00972             Length = RtlDosSearchPath_U(
    00973                         ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer,
    00974                         DllName->Buffer,
    00975                         NULL,
    00976                         sizeof(FullDllNameBuffer)-sizeof(UNICODE_NULL),
    00977                         FullDllName.Buffer,
    00978                         NULL
    00979                         );
    00980             if ( !Length || Length > sizeof(FullDllNameBuffer)-sizeof(UNICODE_NULL) ) {
    00981
    00982                 if (ShowSnaps) {
    00983                     DbgPrint("LDR: LdrpCheckForLoadedDll - Unable To Locate ");
    00984                     DbgPrint("%ws from %ws\n",
    00985                         DllName->Buffer,
    00986                         ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer
    00987                         );
    00988                     }
    00989
    00990                 return FALSE;
    00991                 }
    00992
    00993             FullDllName.Length = (USHORT)Length;
    00994             FullDllName.MaximumLength = FullDllName.Length + (USHORT)sizeof(UNICODE_NULL);
    00995             break;
    00996             }
    00997         }
    00998
    00999     //
    01000     // if this is a dynamic load lib, and there is not a hard
    01001     // coded path, then go to the static lib hash table for resolution
    01002     //
    01003
    01004     if ( !HardCodedPath ) {
    01005
    01006         StaticLink = TRUE;
    01007
    01008         goto staticlink;
    01009         }
    01010
    01011
    01012     Result = FALSE;
    01013     Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    01014     Next = Head->Flink;
    01015
    01016     while ( Next != Head ) {
    01017         Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    01018         Next = Next->Flink;
    01019
    01020         //
    01021         // when we unload, the memory order links flink field is nulled.
    01022         // this is used to skip the entry pending list removal.
    01023         //
    01024
    01025         if ( !Entry->InMemoryOrderLinks.Flink ) {
    01026             continue;
    01027         }
    01028
    01029
    01030         if (RtlEqualUnicodeString(
    01031                 &FullDllName,
    01032                 &Entry->FullDllName,
    01033                 TRUE
    01034                 ) ) {
    01035
    01036                 Result = TRUE;
    01037                 *LdrDataTableEntry = Entry;
    01038                 break;
    01039             }
    01040         }
    01041
    01042     if ( !Result ) {
    01043
    01044         //
    01045         // no names matched. This might be a long short name mismatch or
    01046         // any kind of alias pathname. Deal with this by opening and mapping
    01047         // full dll name and then repeat the scan this time checking for
    01048         // timedatestamp matches
    01049         //
    01050
    01051         HANDLE File;
    01052         HANDLE Section;
    01053         NTSTATUS st;
    01054         OBJECT_ATTRIBUTES ObjectAttributes;
    01055         IO_STATUS_BLOCK IoStatus;
    01056         PVOID ViewBase;
    01057         SIZE_T ViewSize;
    01058         PIMAGE_NT_HEADERS NtHeadersSrc,NtHeadersE;
    01059         UNICODE_STRING NtFileName;
    01060
    01061
    01062         if (!RtlDosPathNameToNtPathName_U( FullDllName.Buffer,
    01063                                            &NtFileName,
    01064                                            NULL,
    01065                                            NULL
    01066                                          )
    01067            ) {
    01068             goto alldone;
    01069             }
    01070
    01071         InitializeObjectAttributes(
    01072             &ObjectAttributes,
    01073             &NtFileName,
    01074             OBJ_CASE_INSENSITIVE,
    01075             NULL,
    01076             NULL
    01077             );
    01078
    01079         st = NtOpenFile(
    01080                 &File,
    01081                 SYNCHRONIZE | FILE_EXECUTE,
    01082                 &ObjectAttributes,
    01083                 &IoStatus,
    01084                 FILE_SHARE_READ | FILE_SHARE_DELETE,
    01085                 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
    01086                 );
    01087         RtlFreeHeap(RtlProcessHeap(), 0, NtFileName.Buffer);
    01088
    01089         if (!NT_SUCCESS(st)) {
    01090             goto alldone;
    01091             }
    01092
    01093         st = NtCreateSection(
    01094                 &Section,
    01095                 SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE,
    01096                 NULL,
    01097                 NULL,
    01098                 PAGE_EXECUTE,
    01099                 SEC_COMMIT,
    01100                 File
    01101                 );
    01102         NtClose( File );
    01103
    01104         if (!NT_SUCCESS(st)) {
    01105             goto alldone;
    01106             }
    01107
    01108         ViewBase = NULL;
    01109         ViewSize = 0;
    01110         st = NtMapViewOfSection(
    01111                 Section,
    01112                 NtCurrentProcess(),
    01113                 (PVOID *)&ViewBase,
    01114                 0L,
    01115                 0L,
    01116                 NULL,
    01117                 &ViewSize,
    01118                 ViewShare,
    01119                 0L,
    01120                 PAGE_EXECUTE
    01121                 );
    01122         NtClose(Section);
    01123         if (!NT_SUCCESS(st)) {
    01124             goto alldone;
    01125             }
    01126
    01127         //
    01128         // The section is mapped. Now find the headers
    01129         //
    01130         NtHeadersSrc = RtlImageNtHeader(ViewBase);
    01131         if ( !NtHeadersSrc ) {
    01132             NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01133             goto alldone;
    01134             }
    01135         Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    01136         Next = Head->Flink;
    01137
    01138         while ( Next != Head ) {
    01139             Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    01140             Next = Next->Flink;
    01141
    01142             //
    01143             // when we unload, the memory order links flink field is nulled.
    01144             // this is used to skip the entry pending list removal.
    01145             //
    01146
    01147             if ( !Entry->InMemoryOrderLinks.Flink ) {
    01148                 continue;
    01149             }
    01150
    01151             try {
    01152                 if ( Entry->TimeDateStamp == NtHeadersSrc->FileHeader.TimeDateStamp &&
    01153                      Entry->SizeOfImage == NtHeadersSrc->OptionalHeader.SizeOfImage ) {
    01154
    01155                     //
    01156                     // there is a very good chance we have an image match. Check the
    01157                     // entire file header and optional header. If they match, declare
    01158                     // this a match
    01159                     //
    01160
    01161                     NtHeadersE = RtlImageNtHeader(Entry->DllBase);
    01162
    01163                     if ( RtlCompareMemory(NtHeadersE,NtHeadersSrc,sizeof(*NtHeadersE)) ) {
    01164
    01165                         //
    01166                         // Now that it looks like we have a match, compare
    01167                         // volume serial number's and file index's
    01168                         //
    01169
    01170                         st = NtAreMappedFilesTheSame(Entry->DllBase,ViewBase);
    01171
    01172                         if ( !NT_SUCCESS(st) ) {
    01173                             continue;
    01174                             }
    01175                         else {
    01176                             Result = TRUE;
    01177                             *LdrDataTableEntry = Entry;
    01178                             break;
    01179                             }
    01180                         }
    01181                     }
    01182                 }
    01183             except (EXCEPTION_EXECUTE_HANDLER) {
    01184                 break;
    01185                 }
    01186             }
    01187         NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01188         }
    01189
    01190 alldone:
    01191     return Result;
    01192 }

BOOLEAN LdrpCheckForLoadedDllHandle | ( | IN PVOID | DllHandle,
|  | OUT PLDR_DATA_TABLE_ENTRY * | LdrDataTableEntry
| ) |

Definition at line 1196 of file ldrsnap.c.

References FALSE, LdrpLoadedDllHandleCache, and TRUE.

Referenced by LdrDisableThreadCalloutsForDll(), LdrpGetProcedureAddress(), and LdrUnloadDll().

    01203                    :
    01204
    01205     This function scans the loader data table looking to see if
    01206     the specified DLL has already been mapped into the image address
    01207     space. If the dll has been loaded, the address of its data table
    01208     entry that describes the dll is returned.
    01209
    01210 Arguments:
    01211
    01212     DllHandle - Supplies the DllHandle of the DLL being searched for.
    01213
    01214     LdrDataTableEntry - Returns the address of the loader data table
    01215         entry that describes the dll.
    01216
    01217 Return Value:
    01218
    01219     TRUE- The dll is loaded.  The address of the data table entry is
    01220         returned.
    01221
    01222     FALSE - The dll is not loaded.
    01223
    01224 --*/
    01225
    01226 {
    01227     PLDR_DATA_TABLE_ENTRY Entry;
    01228     PLIST_ENTRY Head,Next;
    01229
    01230     if ( LdrpLoadedDllHandleCache &&
    01231         (PVOID) LdrpLoadedDllHandleCache->DllBase == DllHandle ) {
    01232         *LdrDataTableEntry = LdrpLoadedDllHandleCache;
    01233         return TRUE;
    01234         }
    01235
    01236     Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    01237     Next = Head->Flink;
    01238
    01239     while ( Next != Head ) {
    01240         Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    01241         Next = Next->Flink;
    01242         //
    01243         // when we unload, the memory order links flink field is nulled.
    01244         // this is used to skip the entry pending list removal.
    01245         //
    01246
    01247         if ( !Entry->InMemoryOrderLinks.Flink ) {
    01248             continue;
    01249         }
    01250
    01251         if (DllHandle == (PVOID)Entry->DllBase ){
    01252             LdrpLoadedDllHandleCache = Entry;
    01253             *LdrDataTableEntry = Entry;
    01254             return TRUE;
    01255         }
    01256     }
    01257     return FALSE;
    01258 }

NTSTATUS LdrpCreateDllSection | ( | IN PUNICODE_STRING | FullDllName,
|  | IN HANDLE | DllFile,
|  | IN PUNICODE_STRING | BaseName,
|  | IN PULONG DllCharacteristics | OPTIONAL,
|  | OUT PHANDLE | SectionHandle
| ) |

Definition at line 2150 of file ldrsnap.c.

References DbgPrint, File, LdrpFatalHardErrorCount, LdrpInLdrInit, NT_SUCCESS, NtClose(), NtCreateSection(), NtOpenFile(), NtRaiseHardError(), NTSTATUS(), NULL, and ObjectAttributes.

Referenced by LdrpMapDll().

    02157 {
    02158     HANDLE File;
    02159     HANDLE Section;
    02160     NTSTATUS st;
    02161     OBJECT_ATTRIBUTES ObjectAttributes;
    02162     IO_STATUS_BLOCK IoStatus;
    02163
    02164     if ( !DllFile ) {
    02165         //
    02166         // Since ntsdk does not search paths well, we can't use
    02167         // relative object names
    02168         //
    02169
    02170         InitializeObjectAttributes(
    02171             &ObjectAttributes,
    02172             NtFullDllName,
    02173             OBJ_CASE_INSENSITIVE,
    02174             NULL,
    02175             NULL
    02176             );
    02177
    02178         st = NtOpenFile(
    02179                 &File,
    02180                 SYNCHRONIZE | FILE_EXECUTE,
    02181                 &ObjectAttributes,
    02182                 &IoStatus,
    02183                 FILE_SHARE_READ | FILE_SHARE_DELETE,
    02184                 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
    02185                 );
    02186         if (!NT_SUCCESS(st)) {
    02187
    02188 #if DBG
    02189             DbgPrint("LDR: LdrCreateDllSection - NtOpenFile( %wZ ) failed. Status == %X\n",
    02190                 NtFullDllName,
    02191                 st
    02192                 );
    02193 #endif
    02194             *SectionHandle = NULL;
    02195             return st;
    02196         }
    02197
    02198
    02199     } else {
    02200              File = DllFile;
    02201            }
    02202
    02203
    02204     st = NtCreateSection(
    02205             SectionHandle,
    02206             SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE | SECTION_QUERY,
    02207             NULL,
    02208             NULL,
    02209             PAGE_EXECUTE,
    02210             SEC_IMAGE,
    02211             File
    02212             );
    02213     NtClose( File );
    02214
    02215     if (!NT_SUCCESS(st)) {
    02216
    02217         //
    02218         // hard error time
    02219         //
    02220
    02221         ULONG_PTR ErrorParameters[1];
    02222         ULONG ErrorResponse;
    02223
    02224         *SectionHandle = NULL;
    02225         ErrorParameters[0] = (ULONG_PTR)NtFullDllName;
    02226
    02227         NtRaiseHardError(
    02228           STATUS_INVALID_IMAGE_FORMAT,
    02229           1,
    02230           1,
    02231           ErrorParameters,
    02232           OptionOk,
    02233           &ErrorResponse
    02234           );
    02235
    02236         if ( LdrpInLdrInit ) {
    02237             LdrpFatalHardErrorCount++;
    02238             }
    02239
    02240
    02241 #if DBG
    02242         if (st != STATUS_INVALID_IMAGE_NE_FORMAT &&
    02243             st != STATUS_INVALID_IMAGE_LE_FORMAT &&
    02244             st != STATUS_INVALID_IMAGE_WIN_16
    02245            ) {
    02246             DbgPrint("LDR: LdrCreateDllSection - NtCreateSection %wZ failed. Status == %X\n",
    02247                      NtFullDllName,
    02248                      st
    02249                     );
    02250         }
    02251 #endif
    02252     }
    02253
    02254     return st;
    02255 }

PVOID LdrpDefineDllTag | ( | PWSTR | TagName,
|  | PUSHORT | TagIndex
| ) |

Definition at line 191 of file heaptag.c.

References LDRP_MAXIMUM_DLL_TAGS, LdrpDllTagProcedures, LdrpDllTags, LdrpDllTagsInitialized, LdrpNumberOfDllTags, NULL, RtlAllocateHeap, RtlCreateTagHeap(), RtlpGlobalTagHeap, TRUE, USHORT, and _HEAP::VirtualAllocdBlocks.

Referenced by LdrpWalkImportDescriptor().

    00195 {
    00196     PVOID Result;
    00197     WCHAR TagNameBuffer[ 260 ];
    00198
    00199     if (RtlpGlobalTagHeap == NULL) {
    00200         RtlpGlobalTagHeap = RtlAllocateHeap( RtlProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( HEAP ));
    00201         if (RtlpGlobalTagHeap == NULL) {
    00202             return NULL;
    00203         }
    00204     }
    00205
    00206     if (!LdrpDllTagsInitialized) {
    00207         //
    00208         // Keep QUERY.C happy
    00209         //
    00210         InitializeListHead( &RtlpGlobalTagHeap->VirtualAllocdBlocks );
    00211         LdrpDllTagsInitialized = TRUE;
    00212         }
    00213
    00214     Result = NULL;
    00215     if (LdrpNumberOfDllTags < LDRP_MAXIMUM_DLL_TAGS) {
    00216         memset( TagNameBuffer, 0, sizeof( TagNameBuffer ) );
    00217         wcscpy( TagNameBuffer, TagName );
    00218         LdrpDllTags[ LdrpNumberOfDllTags ] =
    00219             RtlCreateTagHeap( NULL,
    00220                               0,
    00221                               NULL,
    00222                               TagNameBuffer
    00223                             );
    00224
    00225         if (LdrpDllTags[ LdrpNumberOfDllTags ] != 0) {
    00226             Result = LdrpDllTagProcedures[ LdrpNumberOfDllTags ];
    00227             }
    00228
    00229         if (Result != NULL) {
    00230             *TagIndex = (USHORT)(LdrpDllTags[ LdrpNumberOfDllTags ] >> HEAP_TAG_SHIFT);
    00231             LdrpNumberOfDllTags += 1;
    00232             }
    00233         }
    00234
    00235     return Result;
    00236 }

PVOID LdrpFetchAddressOfEntryPoint | ( | IN PVOID | Base | ) |

Definition at line 3249 of file ldrsnap.c.

References RtlImageNtHeader().

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

    03255                    :
    03256
    03257     This function returns the address of the initialization routine.
    03258
    03259 Arguments:
    03260
    03261     Base - Base of image.
    03262
    03263 Return Value:
    03264
    03265     Status value
    03266
    03267 --*/
    03268
    03269 {
    03270     PIMAGE_NT_HEADERS NtHeaders;
    03271     ULONG_PTR ep;
    03272
    03273     NtHeaders = RtlImageNtHeader(Base);
    03274     ep = NtHeaders->OptionalHeader.AddressOfEntryPoint;
    03275     if (ep) {
    03276         ep += (ULONG_PTR)Base;
    03277     }
    03278
    03279     return (PVOID)ep;
    03280 }

VOID LdrpFreeTls | ( | VOID |  | ) |

Definition at line 2134 of file ldrinit.c.

References LdrpTlsList, RtlFreeHeap, and _LDRP_TLS_ENTRY::Tls.

Referenced by LdrShutdownThread().

    02137 {
    02138     PTEB Teb;
    02139     PLIST_ENTRY Head, Next;
    02140     PLDRP_TLS_ENTRY TlsEntry;
    02141     PVOID *TlsVector;
    02142
    02143     Teb = NtCurrentTeb();
    02144
    02145     TlsVector = Teb->ThreadLocalStoragePointer;
    02146
    02147     if ( TlsVector ) {
    02148         Head = &LdrpTlsList;
    02149         Next = Head->Flink;
    02150
    02151         while ( Next != Head ) {
    02152             TlsEntry = CONTAINING_RECORD(Next, LDRP_TLS_ENTRY, Links);
    02153             Next = Next->Flink;
    02154
    02155             //
    02156             // Do the TLS callouts
    02157             //
    02158
    02159             if ( TlsVector[TlsEntry->Tls.Characteristics] ) {
    02160                 RtlFreeHeap(
    02161                     RtlProcessHeap(),
    02162                     0,
    02163                     TlsVector[TlsEntry->Tls.Characteristics]
    02164                     );
    02165
    02166                 }
    02167             }
    02168
    02169         RtlFreeHeap(
    02170             RtlProcessHeap(),
    02171             0,
    02172             TlsVector
    02173             );
    02174         }
    02175 }

NTSTATUS NTAPI LdrpGetProcedureAddress | ( | IN PVOID | DllHandle,
|  | IN PANSI_STRING ProcedureName | OPTIONAL,
|  | IN ULONG ProcedureNumber | OPTIONAL,
|  | OUT PVOID * | ProcedureAddress,
|  | IN BOOLEAN | RunInitRoutines
| ) |

Definition at line 851 of file ldrapi.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, LdrpCheckForLoadedDllHandle(), LdrpInLdrInit, LdrpRunInitializeRoutines(), LdrpSnapThunk(), LoaderLock, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), ShowSnaps, TEMP_TAG, TRUE, and USHORT.

Referenced by LdrGetProcedureAddress(), and LdrpSnapThunk().

    00861                    :
    00862
    00863     This function locates the address of the specified procedure in the
    00864     specified DLL and returns its address.
    00865
    00866 Arguments:
    00867
    00868     DllHandle - Supplies a handle to the DLL that the address is being
    00869         looked up in.
    00870
    00871     ProcedureName - Supplies that address of a string that contains the
    00872         name of the procedure to lookup in the DLL.  If this argument is
    00873         not specified, then the ProcedureNumber is used.
    00874
    00875     ProcedureNumber - Supplies the procedure number to lookup.  If
    00876         ProcedureName is specified, then this argument is ignored.
    00877         Otherwise, it specifies the procedure ordinal number to locate
    00878         in the DLL.
    00879
    00880     ProcedureAddress - Returns the address of the procedure found in
    00881         the DLL.
    00882
    00883 Return Value:
    00884
    00885     TBD
    00886
    00887 --*/
    00888
    00889 {
    00890     NTSTATUS st;
    00891     UCHAR FunctionNameBuffer[64];
    00892     PUCHAR src, dst;
    00893     ULONG cb, ExportSize;
    00894     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    00895     IMAGE_THUNK_DATA Thunk;
    00896     PVOID ImageBase;
    00897     PIMAGE_IMPORT_BY_NAME FunctionName;
    00898     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
    00899     PLIST_ENTRY Next;
    00900 #if defined (WX86)
    00901     PTEB Teb;
    00902     BOOLEAN Wx86KnownDll = FALSE;
    00903 #endif
    00904
    00905     if (ShowSnaps) {
    00906         DbgPrint("LDR: LdrGetProcedureAddress by ");
    00907     }
    00908
    00909 #if defined (WX86)
    00910     Teb = NtCurrentTeb();
    00911     if (Teb->Wx86Thread.UseKnownWx86Dll) {
    00912         Wx86KnownDll = Teb->Wx86Thread.UseKnownWx86Dll;
    00913         Teb->Wx86Thread.UseKnownWx86Dll = FALSE;
    00914         }
    00915 #endif
    00916
    00917     FunctionName = NULL;
    00918     if ( ARGUMENT_PRESENT(ProcedureName) ) {
    00919
    00920         if (ShowSnaps) {
    00921             DbgPrint("NAME - %s\n", ProcedureName->Buffer);
    00922         }
    00923
    00924         //
    00925         // BUGBUG need STRING to PSZ
    00926         //
    00927
    00928
    00929         if (ProcedureName->Length >= sizeof( FunctionNameBuffer )-1 ) {
    00930             FunctionName = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TEMP_TAG ),ProcedureName->Length+1+sizeof(USHORT));
    00931             if ( !FunctionName ) {
    00932                 return STATUS_INVALID_PARAMETER;
    00933                 }
    00934         } else {
    00935             FunctionName = (PIMAGE_IMPORT_BY_NAME) FunctionNameBuffer;
    00936         }
    00937
    00938         FunctionName->Hint = 0;
    00939
    00940         cb = ProcedureName->Length;
    00941         src = ProcedureName->Buffer;
    00942         dst = FunctionName->Name;
    00943
    00944         while (cb--) {
    00945             *dst++ = *src++;
    00946         }
    00947         *dst = '\0';
    00948
    00949         //
    00950         // Make sure we don't pass in address with high bit set so we
    00951         // can still use it as ordinal flag
    00952         //
    00953
    00954         ImageBase = FunctionName;
    00955         Thunk.u1.AddressOfData = 0;
    00956
    00957     } else {
    00958             ImageBase = NULL;
    00959              if (ShowSnaps) {
    00960                  DbgPrint("ORDINAL - %lx\n", ProcedureNumber);
    00961              }
    00962
    00963              if (ProcedureNumber) {
    00964                  Thunk.u1.Ordinal = ProcedureNumber | IMAGE_ORDINAL_FLAG;
    00965              } else {
    00966                       return STATUS_INVALID_PARAMETER;
    00967                     }
    00968           }
    00969
    00970     if ( LdrpInLdrInit == FALSE ) {
    00971         RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock);
    00972         }
    00973     try {
    00974
    00975         if (!LdrpCheckForLoadedDllHandle(DllHandle, &LdrDataTableEntry)) {
    00976             st = STATUS_DLL_NOT_FOUND;
    00977             return st;
    00978         }
    00979
    00980         ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(
    00981                            LdrDataTableEntry->DllBase,
    00982                            TRUE,
    00983                            IMAGE_DIRECTORY_ENTRY_EXPORT,
    00984                            &ExportSize
    00985                            );
    00986
    00987         if (!ExportDirectory) {
    00988             return STATUS_PROCEDURE_NOT_FOUND;
    00989         }
    00990
    00991         st = LdrpSnapThunk(LdrDataTableEntry->DllBase,
    00992                            ImageBase,
    00993                            &Thunk,
    00994                            &Thunk,
    00995                            ExportDirectory,
    00996                            ExportSize,
    00997                            FALSE,
    00998                            NULL
    00999                           );
    01000
    01001         if ( RunInitRoutines ) {
    01002             PLDR_DATA_TABLE_ENTRY LdrInitEntry;
    01003
    01004             //
    01005             // Look at last entry in init order list. If entry processed
    01006             // flag is not set, then a forwarded dll was loaded during the
    01007             // getprocaddr call and we need to run init routines
    01008             //
    01009
    01010             Next = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink;
    01011             LdrInitEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
    01012             if ( !(LdrInitEntry->Flags & LDRP_ENTRY_PROCESSED) ) {
    01013                 try {
    01014                     st = LdrpRunInitializeRoutines(NULL);
    01015                     }
    01016                 except( EXCEPTION_EXECUTE_HANDLER ) {
    01017                     st = GetExceptionCode();
    01018                     }
    01019
    01020                 }
    01021             }
    01022
    01023         if ( NT_SUCCESS(st) ) {
    01024             *ProcedureAddress = (PVOID)Thunk.u1.Function;
    01025 #if defined (WX86)
    01026             // For dlls loaded as a Wx86 plugin ...
    01027
    01028             if (Wx86ProcessInit && (LdrDataTableEntry->Flags & LDRP_WX86_PLUGIN)) {
    01029                 PVOID ExportThunk = NULL;
    01030                 USHORT MachineType = RtlImageNtHeader(LdrDataTableEntry->DllBase)->FileHeader.Machine;
    01031
    01032                 // and the GetProcAddress call is cross-architecture ...
    01033
    01034                 if ((!Wx86KnownDll && (MachineType == IMAGE_FILE_MACHINE_I386))
    01035                   || (Wx86KnownDll && (MachineType != IMAGE_FILE_MACHINE_I386))) {
    01036
    01037                     // Thunk the export
    01038
    01039                     st = Wx86ThunkPluginExport(LdrDataTableEntry->DllBase,
    01040                                                FunctionName? FunctionName->Name : NULL,
    01041                                                ProcedureNumber,
    01042                                                (PVOID)(Thunk.u1.Function),
    01043                                                &ExportThunk
    01044                                                );
    01045                     if (NT_SUCCESS(st) && ExportThunk) {
    01046                         *ProcedureAddress = ExportThunk;
    01047                     } else {
    01048                         // Don't let unthunked cross-architecture addresses get out
    01049                         *ProcedureAddress = NULL;
    01050                         st = STATUS_INVALID_IMAGE_FORMAT;
    01051                         }
    01052                     }
    01053                 }
    01054 #endif
    01055             }
    01056     } finally {
    01057         if ( FunctionName && (FunctionName != (PIMAGE_IMPORT_BY_NAME) FunctionNameBuffer) ) {
    01058             RtlFreeHeap(RtlProcessHeap(),0,FunctionName);
    01059             }
    01060         if ( LdrpInLdrInit == FALSE ) {
    01061             RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock);
    01062             }
    01063     }
    01064     return st;
    01065 }

VOID LdrpInitialize | ( | IN PCONTEXT | Context,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2
| ) |

Definition at line 186 of file ldrinit.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, L, LdrpForkProcess(), LdrpInitializationFailure(), LdrpInitializeProcess(), LdrpInitializeThread(), LdrpInLdrInit, LdrQueryImageFileExecutionOptions(), LoaderLock, LoaderLockInitialized, NT_SUCCESS, NtDelayExecution(), NtQueryPerformanceCounter(), NtQueryVirtualMemory(), NTSTATUS(), NtTestAlert(), NULL, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlpDebugPageHeap, RtlpDisableHeapLookaside, RtlpDphDllRangeEnd, RtlpDphDllRangeStart, RtlpDphGlobalFlags, RtlpDphRandomProbability, RtlpDphSizeRangeEnd, RtlpDphSizeRangeStart, RtlpDphTargetDlls, RtlRaiseStatus(), and TRUE.

    00194                    :
    00195
    00196     This function is called as a User-Mode APC routine as the first
    00197     user-mode code executed by a new thread. It's function is to initialize
    00198     loader context, perform module initialization callouts...
    00199
    00200 Arguments:
    00201
    00202     Context - Supplies an optional context buffer that will be restore
    00203               after all DLL initialization has been completed.  If this
    00204               parameter is NULL then this is a dynamic snap of this module.
    00205               Otherwise this is a static snap prior to the user process
    00206               gaining control.
    00207
    00208     SystemArgument1 - Supplies the base address of the System Dll.
    00209
    00210     SystemArgument2 - not used.
    00211
    00212 Return Value:
    00213
    00214     None.
    00215
    00216 --*/
    00217
    00218 {
    00219     NTSTATUS st, InitStatus;
    00220     PPEB Peb;
    00221     PTEB Teb;
    00222     UNICODE_STRING UnicodeImageName;
    00223     MEMORY_BASIC_INFORMATION MemInfo;
    00224     BOOLEAN AlreadyFailed;
    00225     LARGE_INTEGER DelayValue;
    00226 #if defined(_WIN64)
    00227     PIMAGE_NT_HEADERS NtHeader;
    00228 #endif
    00229
    00230     SystemArgument2;
    00231
    00232     AlreadyFailed = FALSE;
    00233     Peb = NtCurrentPeb();
    00234     Teb = NtCurrentTeb();
    00235
    00236     if (!Peb->Ldr) {
    00237 #if defined(_ALPHA_)
    00238         ULONG temp;
    00239
    00240         //
    00241         // Set GP register
    00242         //
    00243
    00244         LdrpGpValue = (ULONG_PTR)RtlImageDirectoryEntryToData(
    00245                 Peb->ImageBaseAddress,
    00246                 TRUE,
    00247                 IMAGE_DIRECTORY_ENTRY_GLOBALPTR,
    00248                 &temp
    00249                 );
    00250         if (Context != NULL) {
    00251             LdrpSetGp( LdrpGpValue );
    00252             Context->IntGp = LdrpGpValue;
    00253         }
    00254 #endif // ALPHA
    00255
    00256 //#if DBG
    00257         if (TRUE)
    00258 //#else
    00259 //        if (Peb->BeingDebugged || Peb->ReadImageFileExecOptions)
    00260 //#endif
    00261         {
    00262             PWSTR pw;
    00263
    00264             pw = (PWSTR)Peb->ProcessParameters->ImagePathName.Buffer;
    00265             if (!(Peb->ProcessParameters->Flags & RTL_USER_PROC_PARAMS_NORMALIZED)) {
    00266                 pw = (PWSTR)((PCHAR)pw + (ULONG_PTR)(Peb->ProcessParameters));
    00267                 }
    00268             UnicodeImageName.Buffer = pw;
    00269             UnicodeImageName.Length = Peb->ProcessParameters->ImagePathName.Length;
    00270             UnicodeImageName.MaximumLength = UnicodeImageName.Length;
    00271
    00272             //
    00273             //  Hack for NT4 SP4.  So we don't overload another GlobalFlag
    00274             //  bit that we have to be "compatible" with for NT5, look for
    00275             //  another value named "DisableHeapLookaside".
    00276             //
    00277
    00278             LdrQueryImageFileExecutionOptions( &UnicodeImageName,
    00279                                                L"DisableHeapLookaside",
    00280                                                REG_DWORD,
    00281                                                &RtlpDisableHeapLookaside,
    00282                                                sizeof( RtlpDisableHeapLookaside ),
    00283                                                NULL
    00284                                              );
    00285
    00286             st = LdrQueryImageFileExecutionOptions( &UnicodeImageName,
    00287                                                     L"GlobalFlag",
    00288                                                     REG_DWORD,
    00289                                                     &Peb->NtGlobalFlag,
    00290                                                     sizeof( Peb->NtGlobalFlag ),
    00291                                                     NULL
    00292                                                   );
    00293             if (!NT_SUCCESS( st )) {
    00294
    00295                 if (Peb->BeingDebugged) {
    00296                     Peb->NtGlobalFlag |= FLG_HEAP_ENABLE_FREE_CHECK |
    00297                                          FLG_HEAP_ENABLE_TAIL_CHECK |
    00298                                          FLG_HEAP_VALIDATE_PARAMETERS;
    00299                     }
    00300                 }
    00301
    00302 #if defined(_WIN64)
    00303             NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress);
    00304             if (NtHeader && NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    00305                 UseWOW64 = TRUE;
    00306             }
    00307 #endif
    00308         }
    00309
    00310         if ( Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS ) {
    00311
    00312             //
    00313             // We will enable page heap (RtlpDebugPageHeap) only after
    00314             // all other initializations for page heap are finished.
    00315             //
    00316
    00317             //
    00318             // If page heap is enabled we need to disable any flag that
    00319             // might force creation of debug heaps for normal NT heaps.
    00320             // This is due to a dependency between page heap and NT heap
    00321             // where the page heap within PageHeapCreate tries to create
    00322             // a normal NT heap to accomodate some of the allocations.
    00323             // If we do not disable these flags we will get an infinite
    00324             // recursion between RtlpDebugPageHeapCreate and RtlCreateHeap.
    00325             //
    00326
    00327             Peb->NtGlobalFlag &= ~( FLG_HEAP_ENABLE_TAGGING      |
    00328                 FLG_HEAP_ENABLE_TAG_BY_DLL   |
    00329                 FLG_HEAP_ENABLE_TAIL_CHECK   |
    00330                 FLG_HEAP_ENABLE_FREE_CHECK   |
    00331                 FLG_HEAP_VALIDATE_PARAMETERS |
    00332                 FLG_HEAP_VALIDATE_ALL        |
    00333                 FLG_USER_STACK_TRACE_DB      );
    00334
    00335             //
    00336             // Read page heap per process global flags. If we fail
    00337             // to read a value, the default ones are kept.
    00338             //
    00339
    00340             LdrQueryImageFileExecutionOptions(
    00341                 &UnicodeImageName,
    00342                 L"PageHeapFlags",
    00343                 REG_DWORD,
    00344                 &RtlpDphGlobalFlags,
    00345                 sizeof(RtlpDphGlobalFlags),
    00346                 NULL
    00347                 );
    00348
    00349             //
    00350             // Read several page heap parameters.
    00351             //
    00352
    00353             LdrQueryImageFileExecutionOptions(
    00354                 &UnicodeImageName,
    00355                 L"PageHeapSizeRangeStart",
    00356                 REG_DWORD,
    00357                 &RtlpDphSizeRangeStart,
    00358                 sizeof(RtlpDphSizeRangeStart),
    00359                 NULL
    00360                 );
    00361
    00362             LdrQueryImageFileExecutionOptions(
    00363                 &UnicodeImageName,
    00364                 L"PageHeapSizeRangeEnd",
    00365                 REG_DWORD,
    00366                 &RtlpDphSizeRangeEnd,
    00367                 sizeof(RtlpDphSizeRangeEnd),
    00368                 NULL
    00369                 );
    00370
    00371             LdrQueryImageFileExecutionOptions(
    00372                 &UnicodeImageName,
    00373                 L"PageHeapRandomProbability",
    00374                 REG_DWORD,
    00375                 &RtlpDphRandomProbability,
    00376                 sizeof(RtlpDphRandomProbability),
    00377                 NULL
    00378                 );
    00379
    00380             //
    00381             // The two values below should be read as PVOIDs so that
    00382             // this works on 64-bit architetures. However since this
    00383             // feature relies on good stack traces and since we can get
    00384             // reliable stack traces only on X86 architectures we will
    00385             // leave it as it is.
    00386             //
    00387
    00388             LdrQueryImageFileExecutionOptions(
    00389                 &UnicodeImageName,
    00390                 L"PageHeapDllRangeStart",
    00391                 REG_DWORD,
    00392                 &RtlpDphDllRangeStart,
    00393                 sizeof(RtlpDphDllRangeStart),
    00394                 NULL
    00395                 );
    00396
    00397             LdrQueryImageFileExecutionOptions(
    00398                 &UnicodeImageName,
    00399                 L"PageHeapDllRangeEnd",
    00400                 REG_DWORD,
    00401                 &RtlpDphDllRangeEnd,
    00402                 sizeof(RtlpDphDllRangeEnd),
    00403                 NULL
    00404                 );
    00405
    00406             LdrQueryImageFileExecutionOptions(
    00407                 &UnicodeImageName,
    00408                 L"PageHeapTargetDlls",
    00409                 REG_SZ,
    00410                 &RtlpDphTargetDlls,
    00411                 512,
    00412                 NULL
    00413                 );
    00414
    00415             //
    00416             //  Turn on BOOLEAN RtlpDebugPageHeap to indicate that
    00417             //  new heaps should be created with debug page heap manager
    00418             //  when possible.
    00419             //
    00420
    00421             RtlpDebugPageHeap = TRUE;
    00422         }
    00423     }
    00424 #if defined(_ALPHA_)
    00425     else
    00426     if (Context != NULL) {
    00427         LdrpSetGp( LdrpGpValue );
    00428         Context->IntGp = LdrpGpValue;
    00429     }
    00430 #endif // ALPHA
    00431
    00432     //
    00433     // Serialize for here on out
    00434     //
    00435
    00436     Peb->LoaderLock = (PVOID)&LoaderLock;
    00437
    00438     if ( !RtlTryEnterCriticalSection(&LoaderLock) ) {
    00439         if ( LoaderLockInitialized ) {
    00440             RtlEnterCriticalSection(&LoaderLock);
    00441             }
    00442         else {
    00443
    00444             //
    00445             // drop into a 30ms delay loop
    00446             //
    00447
    00448             DelayValue.QuadPart = Int32x32To64( 30, -10000 );
    00449             while ( !LoaderLockInitialized ) {
    00450                 NtDelayExecution(FALSE,&DelayValue);
    00451                 }
    00452             RtlEnterCriticalSection(&LoaderLock);
    00453             }
    00454         }
    00455
    00456     if (Teb->DeallocationStack == NULL) {
    00457         st = NtQueryVirtualMemory(
    00458                 NtCurrentProcess(),
    00459                 Teb->NtTib.StackLimit,
    00460                 MemoryBasicInformation,
    00461                 (PVOID)&MemInfo,
    00462                 sizeof(MemInfo),
    00463                 NULL
    00464                 );
    00465         if ( !NT_SUCCESS(st) ) {
    00466             LdrpInitializationFailure(st);
    00467             RtlRaiseStatus(st);
    00468             return;
    00469             }
    00470         else {
    00471             Teb->DeallocationStack = MemInfo.AllocationBase;
    00472 #if defined(_IA64_)
    00473             Teb->DeallocationBStore = (PVOID)((ULONG_PTR)MemInfo.AllocationBase + MemInfo.RegionSize);
    00474 #endif // defined(_IA64_)
    00475         }
    00476     }
    00477
    00478     InitStatus = STATUS_SUCCESS;
    00479     try {
    00480         if (!Peb->Ldr) {
    00481             LdrpInLdrInit = TRUE;
    00482 #if DBG
    00483             //
    00484             // Time the load.
    00485             //
    00486
    00487             if (LdrpDisplayLoadTime) {
    00488                 NtQueryPerformanceCounter(&BeginTime, NULL);
    00489             }
    00490 #endif // DBG
    00491
    00492             try {
    00493                 InitStatus = LdrpInitializeProcess( Context,
    00494                                                     SystemArgument1,
    00495                                                     &UnicodeImageName
    00496                                                   );
    00497                 }
    00498             except ( EXCEPTION_EXECUTE_HANDLER ) {
    00499                 InitStatus = GetExceptionCode();
    00500                 AlreadyFailed = TRUE;
    00501                 LdrpInitializationFailure(GetExceptionCode());
    00502                 }
    00503
    00504 #if DBG
    00505             if (LdrpDisplayLoadTime) {
    00506                 NtQueryPerformanceCounter(&EndTime, NULL);
    00507                 NtQueryPerformanceCounter(&ElapsedTime, &Interval);
    00508                 ElapsedTime.QuadPart = EndTime.QuadPart - BeginTime.QuadPart;
    00509                 DbgPrint("\nLoadTime %ld In units of %ld cycles/second \n",
    00510                     ElapsedTime.LowPart,
    00511                     Interval.LowPart
    00512                     );
    00513
    00514                 ElapsedTime.QuadPart = EndTime.QuadPart - InitbTime.QuadPart;
    00515                 DbgPrint("InitTime %ld\n",
    00516                     ElapsedTime.LowPart
    00517                     );
    00518                 DbgPrint("Compares %d Bypasses %d Normal Snaps %d\nSecOpens %d SecCreates %d Maps %d Relocates %d\n",
    00519                     LdrpCompareCount,
    00520                     LdrpSnapBypass,
    00521                     LdrpNormalSnap,
    00522                     LdrpSectionOpens,
    00523                     LdrpSectionCreates,
    00524                     LdrpSectionMaps,
    00525                     LdrpSectionRelocates
    00526                     );
    00527             }
    00528 #endif // DBG
    00529
    00530
    00531         } else {
    00532             if ( Peb->InheritedAddressSpace ) {
    00533                 InitStatus = LdrpForkProcess();
    00534                 }
    00535             else {
    00536
    00537 #if defined (WX86)
    00538                 if (Teb->Vdm) {
    00539                     InitStatus = LdrpInitWx86(Teb->Vdm, Context, TRUE);
    00540                     }
    00541 #endif
    00542
    00543 #if defined(_WIN64)
    00544                 //
    00545                 // Load in WOW64 if the image is supposed to run simulated
    00546                 //
    00547                 if (UseWOW64) {
    00548                     RtlLeaveCriticalSection(&LoaderLock);
    00549                     (*Wow64LdrpInitialize)(Context);
    00550                     // This never returns.  It will destroy the process.
    00551                 }
    00552 #endif
    00553                 LdrpInitializeThread(Context);
    00554                 }
    00555         }
    00556     } finally {
    00557         LdrpInLdrInit = FALSE;
    00558         RtlLeaveCriticalSection(&LoaderLock);
    00559         }
    00560
    00561     NtTestAlert();
    00562
    00563     if (!NT_SUCCESS(InitStatus)) {
    00564
    00565         if ( AlreadyFailed == FALSE ) {
    00566             LdrpInitializationFailure(InitStatus);
    00567             }
    00568         RtlRaiseStatus(InitStatus);
    00569     }
    00570
    00571
    00572 }

VOID LdrpInitializePathCache | ( | VOID |  | ) |

NTSTATUS LdrpInitializeProcess | ( | IN PCONTEXT Context | OPTIONAL,
|  | IN PVOID | SystemDllBase,
|  | IN PUNICODE_STRING | UnicodeImageName
| ) |

Definition at line 616 of file ldrinit.c.

References ASSERT, ATOM_TAG, CommandLine, DbgPrint, FALSE, FastPebLock, HeapParameters, InitTableInfo, L, LDR_TAG, LdrGetProcedureAddress(), LdrLoadDll(), LDRP_HASH_TABLE_SIZE, LdrpAllocateDataTableEntry(), LdrpDefaultPath, LdrpFetchAddressOfEntryPoint(), LdrpHashTable, LdrpImageEntry, LdrpInitializationFailure(), LdrpInitializeTls(), LdrpInsertMemoryTableEntry(), LdrpKnownDllObjectDirectory, LdrpKnownDllPath, LdrpKnownDllPathBuffer, LdrpLdrDatabaseIsSetup, LdrpNumberOfProcessors, LdrpReferenceLoadedDll, LdrpRelocateStartContext(), LdrpRunInitializeRoutines(), LdrpSetProtection(), LdrpVerifyDlls, LdrpWalkImportDescriptor(), LdrQueryApplicationCompatibilityGoo(), LdrQueryImageFileExecutionOptions(), LdrRelocateImage(), LoaderLock, LoaderLockInitialized, MAKE_TAG, NATIVE_PAGE_SIZE, NT_SUCCESS, NtAllocateVirtualMemory(), NtClose(), NtDllBase, NtdllBaseTag, NtdllpAllocateStringRoutine(), NtdllpFreeStringRoutine(), NtFreeVirtualMemory(), NtOpenDirectoryObject(), NtOpenSymbolicLinkObject(), NtQueryPerformanceCounter(), NtQuerySymbolicLinkObject(), NtSetInformationProcess(), NTSTATUS(), NtSystemRoot, NULL, PAGE_SIZE, RtlAllocateHeap, RtlAllocateStringRoutine, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlCreateHeap(), RtlCreateTagHeap(), RtlCriticalSectionList, RtlFreeStringRoutine, RtlFreeUnicodeString(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlInitAnsiString(), RtlInitializeAtomPackage(), RtlInitializeBitMap(), RtlInitializeCriticalSection(), RtlInitializeHeapManager(), RtlInitNlsTables(), RtlInitUnicodeString(), RtlNormalizeProcessParams(), RtlpDebugPageHeap, RtlpInitDeferedCriticalSection(), RtlpTimeout, RtlpTimoutDisable, RtlRaiseStatus(), RtlResetRtlTranslations(), RtlSetCurrentDirectory_U(), ShowSnaps, TlsBitMap, TlsExpansionBitMap, TRUE, Unicode, and USHORT.

Referenced by LdrpInitialize().

    00624                    :
    00625
    00626     This function initializes the loader for the process.
    00627     This includes:
    00628
    00629         - Initializing the loader data table
    00630
    00631         - Connecting to the loader subsystem
    00632
    00633         - Initializing all staticly linked DLLs
    00634
    00635 Arguments:
    00636
    00637     Context - Supplies an optional context buffer that will be restore
    00638               after all DLL initialization has been completed.  If this
    00639               parameter is NULL then this is a dynamic snap of this module.
    00640               Otherwise this is a static snap prior to the user process
    00641               gaining control.
    00642
    00643     SystemDllBase - Supplies the base address of the system dll.
    00644
    00645 Return Value:
    00646
    00647     Status value
    00648
    00649 --*/
    00650
    00651 {
    00652     PPEB Peb;
    00653     NTSTATUS st;
    00654     PWCH p, pp;
    00655     UNICODE_STRING CurDir;
    00656     UNICODE_STRING FullImageName;
    00657     UNICODE_STRING CommandLine;
    00658     ULONG DebugProcessHeapOnly = 0 ;
    00659     HANDLE LinkHandle;
    00660     WCHAR SystemDllPathBuffer[DOS_MAX_PATH_LENGTH];
    00661     UNICODE_STRING SystemDllPath;
    00662     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    00663     PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    00664     UNICODE_STRING Unicode;
    00665     OBJECT_ATTRIBUTES Obja;
    00666     BOOLEAN StaticCurDir = FALSE;
    00667     ULONG i;
    00668     PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader( NtCurrentPeb()->ImageBaseAddress );
    00669     PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
    00670     ULONG ProcessHeapFlags;
    00671     RTL_HEAP_PARAMETERS HeapParameters;
    00672     NLSTABLEINFO InitTableInfo;
    00673     LARGE_INTEGER LongTimeout;
    00674     UNICODE_STRING NtSystemRoot;
    00675     LONG_PTR Diff;
    00676     ULONG_PTR OldBase;
    00677
    00678     NtDllBase = SystemDllBase;
    00679
    00680     if (
    00681 #if defined(_WIN64)
    00682         NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC &&
    00683 #endif
    00684         NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE ) {
    00685
    00686         //
    00687         // Native subsystems load slower, but validate their DLLs
    00688         // This is to help CSR detect bad images faster
    00689         //
    00690
    00691         LdrpVerifyDlls = TRUE;
    00692
    00693         }
    00694
    00695
    00696     Peb = NtCurrentPeb();
    00697
    00698 #if defined(BUILD_WOW6432)
    00699     {
    00700         //
    00701         // The process is running in WOW64.  Sort out the optional header
    00702         // format and reformat the image if its page size is smaller than
    00703         // the native page size.
    00704         //
    00705         PIMAGE_NT_HEADERS32 NtHeader32 = (PIMAGE_NT_HEADERS32)NtHeader;
    00706
    00707         if (NtHeader32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 &&
    00708             NtHeader32->OptionalHeader.SectionAlignment < NATIVE_PAGE_SIZE &&
    00709             !NT_SUCCESS(st = LdrpWx86FormatVirtualImage(NtHeader32,
    00710                                  NtCurrentPeb()->ImageBaseAddress
    00711                                  //bugbug: should be:  (PVOID)NtHeader32->OptionalHeader.ImageBase
    00712                                  ))) {
    00713             return st;
    00714         }
    00715     }
    00716 #elif defined (_ALPHA_) && defined (WX86)
    00717      //
    00718      // Deal with the native page size which is larger than x86
    00719      // This needs to be done before any code reads beyond the file headers.
    00720      //
    00721     if (NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 &&
    00722         NtHeader->OptionalHeader.SectionAlignment < PAGE_SIZE &&
    00723         !NT_SUCCESS(st = LdrpWx86FormatVirtualImage((PIMAGE_NT_HEADERS32)NtHeader,
    00724                              (PVOID)NtHeader->OptionalHeader.ImageBase
    00725                              )))
    00726       {
    00727         return st;
    00728         }
    00729 #endif
    00730
    00731
    00732     LdrpNumberOfProcessors = Peb->NumberOfProcessors;
    00733     RtlpTimeout = Peb->CriticalSectionTimeout;
    00734     LongTimeout.QuadPart = Int32x32To64( 3600, -10000000 );
    00735
    00736     if (ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters)) {
    00737         FullImageName = *(PUNICODE_STRING)&ProcessParameters->ImagePathName;
    00738         CommandLine = *(PUNICODE_STRING)&ProcessParameters->CommandLine;
    00739         }
    00740     else {
    00741         RtlInitUnicodeString( &FullImageName, NULL );
    00742         RtlInitUnicodeString( &CommandLine, NULL );
    00743         }
    00744
    00745
    00746     RtlInitNlsTables(
    00747         Peb->AnsiCodePageData,
    00748         Peb->OemCodePageData,
    00749         Peb->UnicodeCaseTableData,
    00750         &InitTableInfo
    00751         );
    00752
    00753     RtlResetRtlTranslations(&InitTableInfo);
    00754
    00755 #if defined(_WIN64)
    00756     if (UseWOW64) {
    00757         //
    00758         // Ignore image config data when initializing the 64-bit loader.
    00759         // The 32-bit loader in ntdll32 will look at the config data
    00760         // and do the right thing.
    00761         //
    00762         ImageConfigData = NULL;
    00763     } else
    00764 #endif
    00765     {
    00766
    00767         ImageConfigData = RtlImageDirectoryEntryToData( Peb->ImageBaseAddress,
    00768                                                         TRUE,
    00769                                                         IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
    00770                                                         &i
    00771                                                       );
    00772     }
    00773
    00774     RtlZeroMemory( &HeapParameters, sizeof( HeapParameters ) );
    00775     ProcessHeapFlags = HEAP_GROWABLE | HEAP_CLASS_0;
    00776     HeapParameters.Length = sizeof( HeapParameters );
    00777     if (ImageConfigData != NULL && i == sizeof( *ImageConfigData )) {
    00778         Peb->NtGlobalFlag &= ~ImageConfigData->GlobalFlagsClear;
    00779         Peb->NtGlobalFlag |= ImageConfigData->GlobalFlagsSet;
    00780
    00781         if (ImageConfigData->CriticalSectionDefaultTimeout != 0) {
    00782             //
    00783             // Convert from milliseconds to NT time scale (100ns)
    00784             //
    00785             RtlpTimeout.QuadPart = Int32x32To64( (LONG)ImageConfigData->CriticalSectionDefaultTimeout,
    00786                                                  -10000
    00787                                                );
    00788
    00789             }
    00790
    00791         if (ImageConfigData->ProcessHeapFlags != 0) {
    00792             ProcessHeapFlags = ImageConfigData->ProcessHeapFlags;
    00793             }
    00794
    00795         if (ImageConfigData->DeCommitFreeBlockThreshold != 0) {
    00796             HeapParameters.DeCommitFreeBlockThreshold = ImageConfigData->DeCommitFreeBlockThreshold;
    00797             }
    00798
    00799         if (ImageConfigData->DeCommitTotalFreeThreshold != 0) {
    00800             HeapParameters.DeCommitTotalFreeThreshold = ImageConfigData->DeCommitTotalFreeThreshold;
    00801             }
    00802
    00803         if (ImageConfigData->MaximumAllocationSize != 0) {
    00804             HeapParameters.MaximumAllocationSize = ImageConfigData->MaximumAllocationSize;
    00805             }
    00806
    00807         if (ImageConfigData->VirtualMemoryThreshold != 0) {
    00808             HeapParameters.VirtualMemoryThreshold = ImageConfigData->VirtualMemoryThreshold;
    00809             }
    00810         }
    00811
    00812 //    //
    00813 //    // Check if the image has the fast heap flag set
    00814 //    //
    00815 //
    00816 //    if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_FAST_HEAP) {
    00817 //        RtlpDisableHeapLookaside = 0;
    00818 //    } else {
    00819 //        RtlpDisableHeapLookaside = 1;
    00820 //    }
    00821
    00822     ShowSnaps = (BOOLEAN)(FLG_SHOW_LDR_SNAPS & Peb->NtGlobalFlag);
    00823
    00824
    00825
    00826     //
    00827     // This field is non-zero if the image file that was used to create this
    00828     // process contained a non-zero value in its image header.  If so, then
    00829     // set the affinity mask for the process using this value.  It could also
    00830     // be non-zero if the parent process created us suspended and poked our
    00831     // PEB with a non-zero value before resuming.
    00832     //
    00833     if (Peb->ImageProcessAffinityMask) {
    00834         st = NtSetInformationProcess( NtCurrentProcess(),
    00835                                       ProcessAffinityMask,
    00836                                       &Peb->ImageProcessAffinityMask,
    00837                                       sizeof( Peb->ImageProcessAffinityMask )
    00838                                     );
    00839         if (NT_SUCCESS( st )) {
    00840             KdPrint(( "LDR: Using ProcessAffinityMask of 0x%x from image.\n",
    00841                       Peb->ImageProcessAffinityMask
    00842                    ));
    00843             }
    00844         else {
    00845             KdPrint(( "LDR: Failed to set ProcessAffinityMask of 0x%x from image (Status == %08x).\n",
    00846                       Peb->ImageProcessAffinityMask, st
    00847                    ));
    00848             }
    00849         }
    00850
    00851     if (RtlpTimeout.QuadPart < LongTimeout.QuadPart) {
    00852         RtlpTimoutDisable = TRUE;
    00853         }
    00854
    00855     if (ShowSnaps) {
    00856         DbgPrint( "LDR: PID: 0x%x started - '%wZ'\n",
    00857                   NtCurrentTeb()->ClientId.UniqueProcess,
    00858                   &CommandLine
    00859                 );
    00860     }
    00861
    00862     for(i=0;i<LDRP_HASH_TABLE_SIZE;i++) {
    00863         InitializeListHead(&LdrpHashTable[i]);
    00864     }
    00865
    00866     //
    00867     // Initialize the critical section package.
    00868     //
    00869
    00870     RtlpInitDeferedCriticalSection();
    00871
    00872     Peb->TlsBitmap = (PVOID)&TlsBitMap;
    00873     Peb->TlsExpansionBitmap = (PVOID)&TlsExpansionBitMap;
    00874
    00875     RtlInitializeBitMap (
    00876         &TlsBitMap,
    00877         &Peb->TlsBitmapBits[0],
    00878         TLS_MINIMUM_AVAILABLE
    00879         );
    00880
    00881     RtlInitializeBitMap (
    00882         &TlsExpansionBitMap,
    00883         &Peb->TlsExpansionBitmapBits[0],
    00884         TLS_EXPANSION_SLOTS
    00885         );
    00886
    00887     InsertTailList(&RtlCriticalSectionList, &LoaderLock.DebugInfo->ProcessLocksList);
    00888     LoaderLock.DebugInfo->CriticalSection = &LoaderLock;
    00889     LoaderLockInitialized = TRUE;
    00890
    00891     //
    00892     // Initialize the stack trace data base if requested
    00893     //
    00894
    00895 #if i386
    00896     if (Peb->NtGlobalFlag & FLG_USER_STACK_TRACE_DB) {
    00897         PVOID BaseAddress = NULL;
    00898         ULONG ReserveSize = 2 * 1024 * 1024;
    00899
    00900         st = NtAllocateVirtualMemory( NtCurrentProcess(),
    00901                                       (PVOID *)&BaseAddress,
    00902                                       0,
    00903                                       &ReserveSize,
    00904                                       MEM_RESERVE,
    00905                                       PAGE_READWRITE
    00906                                     );
    00907         if ( NT_SUCCESS( st ) ) {
    00908             st = RtlInitializeStackTraceDataBase( BaseAddress,
    00909                                                   0,
    00910                                                   ReserveSize
    00911                                                 );
    00912             if ( !NT_SUCCESS( st ) ) {
    00913                 NtFreeVirtualMemory( NtCurrentProcess(),
    00914                                      (PVOID *)&BaseAddress,
    00915                                      &ReserveSize,
    00916                                      MEM_RELEASE
    00917                                    );
    00918                 }
    00919             else {
    00920                 Peb->NtGlobalFlag |= FLG_HEAP_VALIDATE_PARAMETERS;
    00921                 }
    00922             }
    00923         }
    00924 #endif // i386
    00925
    00926     //
    00927     // Initialize the loader data based in the PEB.
    00928     //
    00929
    00930     st = RtlInitializeCriticalSection(&FastPebLock);
    00931     if ( !NT_SUCCESS(st) ) {
    00932         return st;
    00933         }
    00934     Peb->FastPebLock = &FastPebLock;
    00935     Peb->FastPebLockRoutine = (PVOID)&RtlEnterCriticalSection;
    00936     Peb->FastPebUnlockRoutine = (PVOID)&RtlLeaveCriticalSection;
    00937
    00938     RtlInitializeHeapManager();
    00939 #if defined(_WIN64)
    00940     if (UseWOW64) {
    00941         //
    00942         // Create a heap using all defaults.  The 32-bit process heap
    00943         // will be created later by ntdll32 using the parameters from the exe.
    00944         //
    00945         Peb->ProcessHeap = RtlCreateHeap( ProcessHeapFlags,
    00946                                           NULL,
    00947                                           0,
    00948                                           0,
    00949                                           NULL,
    00950                                           &HeapParameters
    00951                                         );
    00952     } else
    00953 #endif
    00954     {
    00955
    00956         if (NtHeader->OptionalHeader.MajorSubsystemVersion <= 3 &&
    00957             NtHeader->OptionalHeader.MinorSubsystemVersion < 51
    00958            ) {
    00959             ProcessHeapFlags |= HEAP_CREATE_ALIGN_16;
    00960             }
    00961
    00962         Peb->ProcessHeap = RtlCreateHeap( ProcessHeapFlags,
    00963                                           NULL,
    00964                                           NtHeader->OptionalHeader.SizeOfHeapReserve,
    00965                                           NtHeader->OptionalHeader.SizeOfHeapCommit,
    00966                                           NULL,             // Lock to use for serialization
    00967                                           &HeapParameters
    00968                                         );
    00969     }
    00970     if (Peb->ProcessHeap == NULL) {
    00971         return STATUS_NO_MEMORY;
    00972     }
    00973
    00974     NtdllBaseTag = RtlCreateTagHeap( Peb->ProcessHeap,
    00975                                      0,
    00976                                      L"NTDLL!",
    00977                                      L"!Process\0"                  // Heap Name
    00978                                      L"CSRSS Client\0"
    00979                                      L"LDR Database\0"
    00980                                      L"Current Directory\0"
    00981                                      L"TLS Storage\0"
    00982                                      L"DBGSS Client\0"
    00983                                      L"SE Temporary\0"
    00984                                      L"Temporary\0"
    00985                                      L"LocalAtom\0"
    00986                                    );
    00987
    00988     RtlAllocateStringRoutine = NtdllpAllocateStringRoutine;
    00989     RtlFreeStringRoutine = NtdllpFreeStringRoutine;
    00990
    00991     RtlInitializeAtomPackage( MAKE_TAG( ATOM_TAG ) );
    00992
    00993     //
    00994     // Allow only the process heap to have page allocations turned on
    00995     //
    00996
    00997     st = LdrQueryImageFileExecutionOptions( UnicodeImageName,
    00998                                             L"DebugProcessHeapOnly",
    00999                                             REG_DWORD,
    01000                                             &DebugProcessHeapOnly,
    01001                                             sizeof( DebugProcessHeapOnly ),
    01002                                             NULL
    01003                                           );
    01004     if (NT_SUCCESS( st )) {
    01005
    01006         if ( RtlpDebugPageHeap &&
    01007              ( DebugProcessHeapOnly != 0 ) ) {
    01008
    01009             RtlpDebugPageHeap = FALSE ;
    01010
    01011             }
    01012
    01013         }
    01014
    01015     SystemDllPath.Buffer = SystemDllPathBuffer;
    01016     SystemDllPath.Length = 0;
    01017     SystemDllPath.MaximumLength = sizeof( SystemDllPathBuffer );
    01018     RtlInitUnicodeString( &NtSystemRoot, USER_SHARED_DATA->NtSystemRoot );
    01019     RtlAppendUnicodeStringToString( &SystemDllPath, &NtSystemRoot );
    01020     RtlAppendUnicodeToString( &SystemDllPath, L"\\System32\\" );
    01021
    01022     RtlInitUnicodeString(&Unicode,L"\\KnownDlls");
    01023     InitializeObjectAttributes( &Obja,
    01024                                   &Unicode,
    01025                                   OBJ_CASE_INSENSITIVE,
    01026                                   NULL,
    01027                                   NULL
    01028                                 );
    01029     st = NtOpenDirectoryObject(
    01030             &LdrpKnownDllObjectDirectory,
    01031             DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
    01032             &Obja
    01033             );
    01034     if ( !NT_SUCCESS(st) ) {
    01035         LdrpKnownDllObjectDirectory = NULL;
    01036         // KnownDlls directory doesn't exist - assume it's system32.
    01037         RtlInitUnicodeString(&LdrpKnownDllPath, SystemDllPath.Buffer);
    01038         LdrpKnownDllPath.Length -= sizeof(WCHAR);    // remove trailing '\'
    01039         }
    01040     else {
    01041
    01042         //
    01043         // Open up the known dll pathname link
    01044         // and query its value
    01045         //
    01046
    01047         RtlInitUnicodeString(&Unicode,L"KnownDllPath");
    01048         InitializeObjectAttributes( &Obja,
    01049                                       &Unicode,
    01050                                       OBJ_CASE_INSENSITIVE,
    01051                                       LdrpKnownDllObjectDirectory,
    01052                                       NULL
    01053                                     );
    01054         st = NtOpenSymbolicLinkObject( &LinkHandle,
    01055                                        SYMBOLIC_LINK_QUERY,
    01056                                        &Obja
    01057                                      );
    01058         if (NT_SUCCESS( st )) {
    01059             LdrpKnownDllPath.Length = 0;
    01060             LdrpKnownDllPath.MaximumLength = sizeof(LdrpKnownDllPathBuffer);
    01061             LdrpKnownDllPath.Buffer = LdrpKnownDllPathBuffer;
    01062             st = NtQuerySymbolicLinkObject( LinkHandle,
    01063                                             &LdrpKnownDllPath,
    01064                                             NULL
    01065                                           );
    01066             NtClose(LinkHandle);
    01067             if ( !NT_SUCCESS(st) ) {
    01068                 return st;
    01069                 }
    01070             }
    01071         else {
    01072             return st;
    01073             }
    01074         }
    01075
    01076     if (ProcessParameters) {
    01077
    01078         //
    01079         // If the process was created with process parameters,
    01080         // than extract:
    01081         //
    01082         //      - Library Search Path
    01083         //
    01084         //      - Starting Current Directory
    01085         //
    01086
    01087         if (ProcessParameters->DllPath.Length) {
    01088             LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath;
    01089             }
    01090         else {
    01091             LdrpInitializationFailure( STATUS_INVALID_PARAMETER );
    01092             }
    01093
    01094         StaticCurDir = TRUE;
    01095         CurDir = ProcessParameters->CurrentDirectory.DosPath;
    01096         if (CurDir.Buffer == NULL || CurDir.Buffer[ 0 ] == UNICODE_NULL || CurDir.Length == 0) {
    01097             CurDir.Buffer = (RtlAllocateStringRoutine)( (3+1) * sizeof( WCHAR ) );
    01098             ASSERT(CurDir.Buffer != NULL);
    01099             RtlMoveMemory( CurDir.Buffer,
    01100                            USER_SHARED_DATA->NtSystemRoot,
    01101                            3 * sizeof( WCHAR )
    01102                          );
    01103             CurDir.Buffer[ 3 ] = UNICODE_NULL;
    01104             }
    01105         }
    01106
    01107     //
    01108     // Make sure the module data base is initialized before we take any
    01109     // exceptions.
    01110     //
    01111
    01112     Peb->Ldr = RtlAllocateHeap(Peb->ProcessHeap, MAKE_TAG( LDR_TAG ), sizeof(PEB_LDR_DATA));
    01113     if ( !Peb->Ldr ) {
    01114         RtlRaiseStatus(STATUS_NO_MEMORY);
    01115         }
    01116
    01117     Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
    01118     Peb->Ldr->Initialized = TRUE;
    01119     Peb->Ldr->SsHandle = NULL;
    01120     InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
    01121     InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
    01122     InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
    01123
    01124     //
    01125     // Allocate the first data table entry for the image. Since we
    01126     // have already mapped this one, we need to do the allocation by hand.
    01127     // Its characteristics identify it as not a Dll, but it is linked
    01128     // into the table so that pc correlation searching doesn't have to
    01129     // be special cased.
    01130     //
    01131
    01132     LdrDataTableEntry = LdrpImageEntry = LdrpAllocateDataTableEntry(Peb->ImageBaseAddress);
    01133     LdrDataTableEntry->LoadCount = (USHORT)0xffff;
    01134     LdrDataTableEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrDataTableEntry->DllBase);
    01135     LdrDataTableEntry->FullDllName = FullImageName;
    01136     LdrDataTableEntry->Flags = 0;
    01137
    01138     // p = strrchr(FullImageName, '\\');
    01139     pp = UNICODE_NULL;
    01140     p = FullImageName.Buffer;
    01141     while (*p) {
    01142         if (*p++ == (WCHAR)'\\') {
    01143             pp = p;
    01144         }
    01145     }
    01146
    01147     LdrDataTableEntry->FullDllName.Length = (USHORT)((ULONG_PTR)p - (ULONG_PTR)FullImageName.Buffer);
    01148     LdrDataTableEntry->FullDllName.MaximumLength = LdrDataTableEntry->FullDllName.Length + (USHORT)sizeof(UNICODE_NULL);
    01149
    01150     if (pp) {
    01151        LdrDataTableEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)p - (ULONG_PTR)pp);
    01152        LdrDataTableEntry->BaseDllName.MaximumLength = LdrDataTableEntry->BaseDllName.Length + (USHORT)sizeof(UNICODE_NULL);
    01153        LdrDataTableEntry->BaseDllName.Buffer = RtlAllocateHeap(Peb->ProcessHeap, MAKE_TAG( LDR_TAG ),
    01154                                                                LdrDataTableEntry->BaseDllName.MaximumLength
    01155                                                               );
    01156        RtlMoveMemory(LdrDataTableEntry->BaseDllName.Buffer,
    01157                      pp,
    01158                      LdrDataTableEntry->BaseDllName.MaximumLength
    01159                     );
    01160     }  else {
    01161               LdrDataTableEntry->BaseDllName = LdrDataTableEntry->FullDllName;
    01162             }
    01163     LdrpInsertMemoryTableEntry(LdrDataTableEntry);
    01164     LdrDataTableEntry->Flags |= LDRP_ENTRY_PROCESSED;
    01165
    01166     if (ShowSnaps) {
    01167         DbgPrint( "LDR: NEW PROCESS\n" );
    01168         DbgPrint( "     Image Path: %wZ (%wZ)\n",
    01169                   &LdrDataTableEntry->FullDllName,
    01170                   &LdrDataTableEntry->BaseDllName
    01171                 );
    01172         DbgPrint( "     Current Directory: %wZ\n", &CurDir );
    01173         DbgPrint( "     Search Path: %wZ\n", &LdrpDefaultPath );
    01174     }
    01175
    01176     //
    01177     // The process references the system DLL, so map this one next. Since
    01178     // we have already mapped this one, we need to do the allocation by
    01179     // hand. Since every application will be statically linked to the
    01180     // system Dll, we'll keep the LoadCount initialized to 0.
    01181     //
    01182
    01183     LdrDataTableEntry = LdrpAllocateDataTableEntry(SystemDllBase);
    01184     LdrDataTableEntry->Flags = (USHORT)LDRP_IMAGE_DLL;
    01185     LdrDataTableEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrDataTableEntry->DllBase);
    01186     LdrDataTableEntry->LoadCount = (USHORT)0xffff;
    01187
    01188     LdrDataTableEntry->BaseDllName.Length = SystemDllPath.Length;
    01189     RtlAppendUnicodeToString( &SystemDllPath, L"ntdll.dll" );
    01190     LdrDataTableEntry->BaseDllName.Length = SystemDllPath.Length - LdrDataTableEntry->BaseDllName.Length;
    01191     LdrDataTableEntry->BaseDllName.MaximumLength = LdrDataTableEntry->BaseDllName.Length + sizeof( UNICODE_NULL );
    01192
    01193     LdrDataTableEntry->FullDllName.Buffer =
    01194         (RtlAllocateStringRoutine)( SystemDllPath.Length + sizeof( UNICODE_NULL ) );
    01195     ASSERT(LdrDataTableEntry->FullDllName.Buffer != NULL);
    01196     RtlMoveMemory( LdrDataTableEntry->FullDllName.Buffer,
    01197                    SystemDllPath.Buffer,
    01198                    SystemDllPath.Length
    01199                  );
    01200     LdrDataTableEntry->FullDllName.Buffer[ SystemDllPath.Length / sizeof( WCHAR ) ] = UNICODE_NULL;
    01201     LdrDataTableEntry->FullDllName.Length = SystemDllPath.Length;
    01202     LdrDataTableEntry->FullDllName.MaximumLength = SystemDllPath.Length + sizeof( UNICODE_NULL );
    01203     LdrDataTableEntry->BaseDllName.Buffer = (PWSTR)
    01204         ((PCHAR)(LdrDataTableEntry->FullDllName.Buffer) +
    01205          LdrDataTableEntry->FullDllName.Length -
    01206          LdrDataTableEntry->BaseDllName.Length
    01207         );
    01208     LdrpInsertMemoryTableEntry(LdrDataTableEntry);
    01209
    01210     //
    01211     // Add init routine to list
    01212     //
    01213
    01214     InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList,
    01215                    &LdrDataTableEntry->InInitializationOrderLinks);
    01216
    01217     //
    01218     // Inherit the current directory
    01219     //
    01220
    01221     st = RtlSetCurrentDirectory_U(&CurDir);
    01222     if (!NT_SUCCESS(st)) {
    01223         if ( !StaticCurDir ) {
    01224             RtlFreeUnicodeString(&CurDir);
    01225             }
    01226         CurDir = NtSystemRoot;
    01227         st = RtlSetCurrentDirectory_U(&CurDir);
    01228         }
    01229     else {
    01230         if ( !StaticCurDir ) {
    01231             RtlFreeUnicodeString(&CurDir);
    01232             }
    01233         }
    01234
    01235 #if defined(WX86)
    01236
    01237     //
    01238     // Load in x86 emulator for risc (Wx86.dll)
    01239     //
    01240
    01241     if (NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
    01242         st = LdrpLoadWx86Dll(Context);
    01243         if (!NT_SUCCESS(st)) {
    01244             return st;
    01245             }
    01246         }
    01247
    01248 #endif
    01249
    01250 #if defined(_WIN64)
    01251     //
    01252     // Load in WOW64 if the image is supposed to run simulated
    01253     //
    01254     if (UseWOW64) {
    01255         UNICODE_STRING Wow64Name;
    01256         ANSI_STRING ProcName;
    01257         RtlInitUnicodeString(&Wow64Name, L"wow64.dll");
    01258         st = LdrLoadDll(NULL, NULL, &Wow64Name, &Wow64Handle);
    01259         if (!NT_SUCCESS(st)) {
    01260             if (ShowSnaps) {
    01261                 DbgPrint("wow64.dll not found.  Status=%x\n", st);
    01262             }
    01263             return st;
    01264         }
    01265
    01266         //
    01267         // Get the entrypoints.  They are roughly cloned from ntos\ps\psinit.c
    01268         // PspInitSystemDll().
    01269         //
    01270         RtlInitAnsiString(&ProcName, "Wow64LdrpInitialize");
    01271         st = LdrGetProcedureAddress(Wow64Handle,
    01272                                     &ProcName,
    01273                                     0,
    01274                                     (PVOID *)&Wow64LdrpInitialize);
    01275         if (!NT_SUCCESS(st)) {
    01276             if (ShowSnaps) {
    01277                 DbgPrint("Wow64LdrpInitialize not found.  Status=%x\n", st);
    01278             }
    01279             return st;
    01280         }
    01281
    01282         RtlInitAnsiString(&ProcName, "Wow64PrepareForException");
    01283         st = LdrGetProcedureAddress(Wow64Handle,
    01284                                     &ProcName,
    01285                                     0,
    01286                                     (PVOID *)&Wow64PrepareForException);
    01287         if (!NT_SUCCESS(st)) {
    01288             if (ShowSnaps) {
    01289                 DbgPrint("Wow64PrepareForException not found.  Status=%x\n", st);
    01290             }
    01291             return st;
    01292         }
    01293
    01294         DbgPrint("WARNING:  PROCESS HAS BEEN CONVERTED TO WOW64!!!\n");
    01295         if (Peb->ProcessParameters) {
    01296            DbgPrint("CommandLine: %wZ\n", &Peb->ProcessParameters->CommandLine);
    01297            DbgPrint("ImagePathName: %wZ\n", &Peb->ProcessParameters->ImagePathName);
    01298         }
    01299
    01300         //
    01301         // Now that all DLLs are loaded, if the process is being debugged,
    01302         // signal the debugger with an exception
    01303         //
    01304
    01305         if ( Peb->BeingDebugged ) {
    01306              DbgBreakPoint();
    01307         }
    01308
    01309         //
    01310         // Release the loaderlock now - this thread doesn't need it any more.
    01311         //
    01312         RtlLeaveCriticalSection(&LoaderLock);
    01313
    01314         //
    01315         // Call wow64 to load and run 32-bit ntdll.dll.
    01316         //
    01317         (*Wow64LdrpInitialize)(Context);
    01318         // This never returns.  It will destroy the process.
    01319     }
    01320 #endif
    01321
    01322
    01323     st = LdrpWalkImportDescriptor(
    01324             LdrpDefaultPath.Buffer,
    01325             LdrpImageEntry
    01326             );
    01327
    01328     if ((PVOID)NtHeader->OptionalHeader.ImageBase != NtCurrentPeb()->ImageBaseAddress ) {
    01329
    01330         //
    01331         // The executable is not at its original address.  It must be
    01332         // relocated now.
    01333         //
    01334
    01335         PVOID ViewBase;
    01336         NTSTATUS status;
    01337
    01338         ViewBase = NtCurrentPeb()->ImageBaseAddress;
    01339
    01340         status = LdrpSetProtection(ViewBase, FALSE, TRUE);
    01341
    01342         if (!NT_SUCCESS(status)) {
    01343             return status;
    01344         }
    01345
    01346         status = (NTSTATUS)LdrRelocateImage(ViewBase,
    01347                     "LDR",
    01348                     (ULONG)STATUS_SUCCESS,
    01349                     (ULONG)STATUS_CONFLICTING_ADDRESSES,
    01350                     (ULONG)STATUS_INVALID_IMAGE_FORMAT
    01351                     );
    01352
    01353         if (!NT_SUCCESS(status)) {
    01354             return status;
    01355         }
    01356
    01357         //
    01358         // Update the initial thread context record as per the relocation.
    01359         //
    01360
    01361         if (Context) {
    01362
    01363             OldBase = NtHeader->OptionalHeader.ImageBase;
    01364             Diff = (PCHAR)ViewBase - (PCHAR)OldBase;
    01365
    01366             LdrpRelocateStartContext(Context, Diff);
    01367         }
    01368
    01369         status = LdrpSetProtection(ViewBase, TRUE, TRUE);
    01370
    01371         if (!NT_SUCCESS(status)) {
    01372             return status;
    01373         }
    01374     }
    01375
    01376 #if defined (_ALPHA_)
    01377
    01378     //
    01379     // Find and apply Alpha architecture fixups for this image
    01380     //
    01381
    01382     AlphaFindArchitectureFixups(NtHeader, NtCurrentPeb()->ImageBaseAddress, TRUE);
    01383 #endif
    01384
    01385     LdrpReferenceLoadedDll(LdrpImageEntry);
    01386
    01387     //
    01388     // Lock the loaded DLLs to prevent dlls that back link to the exe to
    01389     // cause problems when they are unloaded.
    01390     //
    01391
    01392     {
    01393         PLDR_DATA_TABLE_ENTRY Entry;
    01394         PLIST_ENTRY Head,Next;
    01395
    01396         Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    01397         Next = Head->Flink;
    01398
    01399         while ( Next != Head ) {
    01400             Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    01401             Entry->LoadCount = 0xffff;
    01402             Next = Next->Flink;
    01403         }
    01404     }
    01405
    01406     //
    01407     // All static DLLs are now pinned in place. No init routines have been run yet
    01408     //
    01409
    01410     LdrpLdrDatabaseIsSetup = TRUE;
    01411
    01412
    01413     if (!NT_SUCCESS(st)) {
    01414 #if DBG
    01415         DbgPrint("LDR: Initialize of image failed. Returning Error Status\n");
    01416 #endif
    01417         return st;
    01418     }
    01419
    01420     if ( !NT_SUCCESS(LdrpInitializeTls()) ) {
    01421         return st;
    01422         }
    01423
    01424     //
    01425     // Now that all DLLs are loaded, if the process is being debugged,
    01426     // signal the debugger with an exception
    01427     //
    01428
    01429     if ( Peb->BeingDebugged ) {
    01430          DbgBreakPoint();
    01431          ShowSnaps = (BOOLEAN)(FLG_SHOW_LDR_SNAPS & Peb->NtGlobalFlag);
    01432     }
    01433
    01434 #if defined (_X86_)
    01435     if ( LdrpNumberOfProcessors > 1 ) {
    01436         LdrpValidateImageForMp(LdrDataTableEntry);
    01437         }
    01438 #endif
    01439
    01440 #if DBG
    01441     if (LdrpDisplayLoadTime) {
    01442         NtQueryPerformanceCounter(&InitbTime, NULL);
    01443     }
    01444 #endif // DBG
    01445
    01446     //
    01447     // Get all application goo here (hacks, flags, etc.)
    01448     //
    01449     LdrQueryApplicationCompatibilityGoo(UnicodeImageName);
    01450
    01451     st = LdrpRunInitializeRoutines(Context);
    01452
    01453     if ( NT_SUCCESS(st) && Peb->PostProcessInitRoutine ) {
    01454         (Peb->PostProcessInitRoutine)();
    01455         }
    01456
    01457     return st;
    01458 }

NTSTATUS LdrpInitializeTls | ( | VOID |  | ) |

Definition at line 1978 of file ldrinit.c.

References DbgPrint, FALSE, LdrpAllocateTls(), LdrpImageHasTls, LdrpNumberOfTlsEntries, LdrpTlsList, MAKE_TAG, PLDRP_TLS_ENTRY, RtlAllocateHeap, RtlImageDirectoryEntryToData(), RtlpSerializeHeap(), ShowSnaps, TLS_TAG, TRUE, and USHORT.

Referenced by LdrpInitializeProcess().

    01981 {
    01982     PLDR_DATA_TABLE_ENTRY Entry;
    01983     PLIST_ENTRY Head,Next;
    01984     PIMAGE_TLS_DIRECTORY TlsImage;
    01985     PLDRP_TLS_ENTRY TlsEntry;
    01986     ULONG TlsSize;
    01987     BOOLEAN FirstTimeThru = TRUE;
    01988
    01989     InitializeListHead(&LdrpTlsList);
    01990
    01991     //
    01992     // Walk through the loaded modules an look for TLS. If we find TLS,
    01993     // lock in the module and add to the TLS chain.
    01994     //
    01995
    01996     Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    01997     Next = Head->Flink;
    01998
    01999     while ( Next != Head ) {
    02000         Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    02001         Next = Next->Flink;
    02002
    02003         TlsImage = (PIMAGE_TLS_DIRECTORY)RtlImageDirectoryEntryToData(
    02004                            Entry->DllBase,
    02005                            TRUE,
    02006                            IMAGE_DIRECTORY_ENTRY_TLS,
    02007                            &TlsSize
    02008                            );
    02009
    02010         //
    02011         // mark whether or not the image file has TLS
    02012         //
    02013
    02014         if ( FirstTimeThru ) {
    02015             FirstTimeThru = FALSE;
    02016             if ( TlsImage && !LdrpImageHasTls) {
    02017                 RtlpSerializeHeap( RtlProcessHeap() );
    02018                 LdrpImageHasTls = TRUE;
    02019                 }
    02020             }
    02021
    02022         if ( TlsImage ) {
    02023             if (ShowSnaps) {
    02024                 DbgPrint( "LDR: Tls Found in %wZ at %lx\n",
    02025                             &Entry->BaseDllName,
    02026                             TlsImage
    02027                         );
    02028                 }
    02029
    02030             TlsEntry = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TLS_TAG ),sizeof(*TlsEntry));
    02031             if ( !TlsEntry ) {
    02032                 return STATUS_NO_MEMORY;
    02033                 }
    02034
    02035             //
    02036             // Since this DLL has TLS, lock it in
    02037             //
    02038
    02039             Entry->LoadCount = (USHORT)0xffff;
    02040
    02041             //
    02042             // Mark this as having thread local storage
    02043             //
    02044
    02045             Entry->TlsIndex = (USHORT)0xffff;
    02046
    02047             TlsEntry->Tls = *TlsImage;
    02048             InsertTailList(&LdrpTlsList,&TlsEntry->Links);
    02049
    02050             //
    02051             // Update the index for this dll's thread local storage
    02052             //
    02053
    02054
    02055             *(PLONG)TlsEntry->Tls.AddressOfIndex = LdrpNumberOfTlsEntries;
    02056             TlsEntry->Tls.Characteristics = LdrpNumberOfTlsEntries++;
    02057             }
    02058         }
    02059
    02060     //
    02061     // We now have walked through all static DLLs and know
    02062     // all DLLs that reference thread local storage. Now we
    02063     // just have to allocate the thread local storage for the current
    02064     // thread and for all subsequent threads
    02065     //
    02066
    02067     return LdrpAllocateTls();
    02068 }

VOID LdrpInsertMemoryTableEntry | ( | IN PLDR_DATA_TABLE_ENTRY | LdrDataTableEntry | ) |

Definition at line 3084 of file ldrsnap.c.

References LDRP_COMPUTE_HASH_INDEX, and LdrpHashTable.

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

    03090                    :
    03091
    03092     This function inserts a loader data table entry into the
    03093     list of loaded modules for this process. The insertion is
    03094     done in "image memory base order".
    03095
    03096 Arguments:
    03097
    03098     LdrDataTableEntry - Supplies the address of the loader data table
    03099         entry to insert in the list of loaded modules for this process.
    03100
    03101 Return Value:
    03102
    03103     None.
    03104
    03105 --*/
    03106
    03107 {
    03108     PPEB_LDR_DATA Ldr;
    03109     ULONG i;
    03110
    03111     Ldr = NtCurrentPeb()->Ldr;
    03112
    03113     i = LDRP_COMPUTE_HASH_INDEX(LdrDataTableEntry->BaseDllName.Buffer[0]);
    03114     InsertTailList(&LdrpHashTable[i],&LdrDataTableEntry->HashLinks);
    03115     InsertTailList(&Ldr->InLoadOrderModuleList, &LdrDataTableEntry->InLoadOrderLinks);
    03116     InsertTailList(&Ldr->InMemoryOrderModuleList, &LdrDataTableEntry->InMemoryOrderLinks);
    03117 }

NTSTATUS NTAPI LdrpLoadDll | ( | IN PWSTR DllPath | OPTIONAL,
|  | IN PULONG DllCharacteristics | OPTIONAL,
|  | IN PUNICODE_STRING | DllName,
|  | OUT PVOID * | DllHandle,
|  | IN BOOLEAN | RunInitRoutines
| ) |

Definition at line 70 of file ldrapi.c.

References DbgPrint, DLLEXTENSION, EXCEPTION_EXECUTE_HANDLER, FALSE, L, LdrpCheckForLoadedDll(), LdrpClearLoadInProgress(), LdrpInLdrInit, LdrpLdrDatabaseIsSetup, LdrpMapDll(), LdrpReferenceLoadedDll, LdrpRunInitializeRoutines(), LdrpWalkImportDescriptor(), LdrUnloadDll(), LoaderLock, NT_SUCCESS, NTSTATUS(), NULL, RtlInitUnicodeString(), and ShowSnaps.

Referenced by LdrLoadDll(), and LdrpSnapThunk().

    00078 {
    00079     PPEB Peb;
    00080     PTEB Teb;
    00081     NTSTATUS st;
    00082     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    00083     PWSTR ActualDllName;
    00084     PWCH p, pp;
    00085     UNICODE_STRING ActualDllNameStr;
    00086     BOOLEAN Wx86KnownDll = FALSE;
    00087     WCHAR FreeBuffer[266];
    00088
    00089     Peb = NtCurrentPeb();
    00090     Teb = NtCurrentTeb();
    00091
    00092     st = STATUS_SUCCESS;
    00093
    00094     try {
    00095
    00096         //
    00097         // Grab Peb lock and Snap All Links to specified DLL
    00098         //
    00099
    00100         if ( LdrpInLdrInit == FALSE ) {
    00101             RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock);
    00102             }
    00103
    00104
    00105
    00106 #if defined (WX86)
    00107
    00108         if (Teb->Wx86Thread.UseKnownWx86Dll) {
    00109             Wx86KnownDll = Teb->Wx86Thread.UseKnownWx86Dll;
    00110             Teb->Wx86Thread.UseKnownWx86Dll = FALSE;
    00111             }
    00112 #endif
    00113
    00114
    00115
    00116         p = DllName->Buffer;
    00117         pp = NULL;
    00118         while (*p) {
    00119             if (*p++ == (WCHAR)'.') {
    00120                 //
    00121                 // pp will point to first character after last '.'
    00122                 //
    00123                 pp = p;
    00124                 }
    00125             }
    00126
    00127
    00128         ActualDllName = FreeBuffer;
    00129         if ( DllName->Length >= sizeof(FreeBuffer)) {
    00130             return STATUS_NAME_TOO_LONG;
    00131             }
    00132         RtlMoveMemory(ActualDllName, DllName->Buffer, DllName->Length);
    00133
    00134
    00135         if (!pp || *pp == (WCHAR)'\\') {
    00136             //
    00137             // No extension found (just ..\)
    00138             //
    00139             if ( DllName->Length+10 >= sizeof(FreeBuffer) ) {
    00140                 return STATUS_NAME_TOO_LONG;
    00141                 }
    00142
    00143             RtlMoveMemory((PCHAR)ActualDllName+DllName->Length, DLLEXTENSION, 10);
    00144             }
    00145         else {
    00146             ActualDllName[DllName->Length >> 1] = UNICODE_NULL;
    00147             }
    00148
    00149         if (ShowSnaps) {
    00150             DbgPrint("LDR: LdrLoadDll, loading %ws from %ws\n",
    00151                      ActualDllName,
    00152                      ARGUMENT_PRESENT(DllPath) ? DllPath : L""
    00153                      );
    00154             }
    00155
    00156
    00157         RtlInitUnicodeString(&ActualDllNameStr,ActualDllName);
    00158         ActualDllNameStr.MaximumLength = sizeof(FreeBuffer);
    00159
    00160         if (!LdrpCheckForLoadedDll( DllPath,
    00161                                     &ActualDllNameStr,
    00162                                     FALSE,
    00163                                     Wx86KnownDll,
    00164                                     &LdrDataTableEntry
    00165                                   )
    00166            ) {
    00167             st = LdrpMapDll(DllPath,
    00168                             ActualDllName,
    00169                             DllCharacteristics,
    00170                             FALSE,
    00171                             Wx86KnownDll,
    00172                             &LdrDataTableEntry
    00173                             );
    00174
    00175             if (!NT_SUCCESS(st)) {
    00176                 return st;
    00177                 }
    00178
    00179             if (ARGUMENT_PRESENT( DllCharacteristics ) &&
    00180                 *DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE
    00181                ) {
    00182                 LdrDataTableEntry->EntryPoint = 0;
    00183                 LdrDataTableEntry->Flags &= ~LDRP_IMAGE_DLL;
    00184                 }
    00185
    00186             //
    00187             // and walk the import descriptor.
    00188             //
    00189
    00190             if (LdrDataTableEntry->Flags & LDRP_IMAGE_DLL) {
    00191
    00192                 try {
    00193                     st = LdrpWalkImportDescriptor(
    00194                               DllPath,
    00195                               LdrDataTableEntry
    00196                               );
    00197                     }
    00198                 except(EXCEPTION_EXECUTE_HANDLER) {
    00199                     st = GetExceptionCode();
    00200                     }
    00201                 if ( LdrDataTableEntry->LoadCount != 0xffff ) {
    00202                     LdrDataTableEntry->LoadCount++;
    00203                     }
    00204                 LdrpReferenceLoadedDll(LdrDataTableEntry);
    00205                 if (!NT_SUCCESS(st)) {
    00206                     LdrDataTableEntry->EntryPoint = NULL;
    00207                     InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
    00208                            &LdrDataTableEntry->InInitializationOrderLinks);
    00209                     LdrpClearLoadInProgress();
    00210                     LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase);
    00211                     return st;
    00212                     }
    00213                 }
    00214             else {
    00215                 if ( LdrDataTableEntry->LoadCount != 0xffff ) {
    00216                     LdrDataTableEntry->LoadCount++;
    00217                     }
    00218                 }
    00219
    00220             //
    00221             // Add init routine to list
    00222             //
    00223
    00224             InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
    00225                            &LdrDataTableEntry->InInitializationOrderLinks);
    00226
    00227
    00228             //
    00229             // If the loader data base is not fully setup, this load was because
    00230             // of a forwarder in the static load set. Can't run init routines
    00231             // yet because the load counts are NOT set
    00232             //
    00233
    00234             if ( RunInitRoutines && LdrpLdrDatabaseIsSetup ) {
    00235
    00236                 try {
    00237                     st = LdrpRunInitializeRoutines(NULL);
    00238                     if ( !NT_SUCCESS(st) ) {
    00239                         LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase);
    00240                         }
    00241                     }
    00242                 except( EXCEPTION_EXECUTE_HANDLER ) {
    00243                     LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase);
    00244                     return GetExceptionCode();
    00245                     }
    00246                 }
    00247             else {
    00248                 st = STATUS_SUCCESS;
    00249                 }
    00250
    00251             }
    00252         else {
    00253
    00254             //
    00255             // Count it. And everything that it imports.
    00256             //
    00257
    00258             if ( LdrDataTableEntry->Flags & LDRP_IMAGE_DLL &&
    00259                  LdrDataTableEntry->LoadCount != 0xffff  ) {
    00260
    00261                 LdrDataTableEntry->LoadCount++;
    00262
    00263                 LdrpReferenceLoadedDll(LdrDataTableEntry);
    00264
    00265                 //
    00266                 // Now clear the Load in progress bits
    00267                 //
    00268
    00269                 LdrpClearLoadInProgress();
    00270
    00271                 }
    00272             else {
    00273                 if ( LdrDataTableEntry->LoadCount != 0xffff ) {
    00274                     LdrDataTableEntry->LoadCount++;
    00275                     }
    00276                 }
    00277             }
    00278         }
    00279     finally {
    00280         if ( LdrpInLdrInit == FALSE ) {
    00281             RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock);
    00282             }
    00283
    00284         }
    00285     if ( NT_SUCCESS(st) ) {
    00286         *DllHandle = (PVOID)LdrDataTableEntry->DllBase;
    00287         }
    00288     else {
    00289         *DllHandle = NULL;
    00290         }
    00291     return st;
    00292 }

NTSTATUS LdrpMapDll | ( | IN PWSTR DllPath | OPTIONAL,
|  | IN PWSTR | DllName,
|  | IN PULONG DllCharacteristics | OPTIONAL,
|  | IN BOOLEAN | StaticLink,
|  | IN BOOLEAN | Wx86KnownDll,
|  | OUT PLDR_DATA_TABLE_ENTRY * | LdrDataTableEntry
| ) |

Definition at line 1261 of file ldrsnap.c.

References Action, DbgPrint, FALSE, L, LdrpAllocateDataTableEntry(), LdrpCheckForKnownDll(), LdrpCreateDllSection(), LdrpDefaultPath, LdrpFatalHardErrorCount, LdrpFetchAddressOfEntryPoint(), LdrpInLdrInit, LdrpInsertMemoryTableEntry(), LdrpKnownDllObjectDirectory, LdrpNumberOfProcessors, LdrpResolveDllName(), LdrpSetProtection(), LdrRelocateImage(), NATIVE_PAGE_SIZE, NT_ERROR, NT_SUCCESS, NtClose(), NtMapViewOfSection(), NtQueryPerformanceCounter(), NtRaiseHardError(), NTSTATUS(), NtUnmapViewOfSection(), NULL, PAGE_SIZE, RtlDosPathNameToNtPathName_U(), RtlEqualUnicodeString(), RtlFreeHeap, RtlFreeUnicodeString(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlInitUnicodeString(), ShowSnaps, TRUE, type, and USHORT.

Referenced by LdrpLoadDll(), and LdrpLoadImportModule().

    01272                    :
    01273
    01274     This routine maps the DLL into the users address space.
    01275
    01276 Arguments:
    01277
    01278     DllPath - Supplies an optional search path to be used to locate the DLL.
    01279
    01280     DllName - Supplies the name of the DLL to load.
    01281
    01282     StaticLink - TRUE if this DLL has a static link to it.
    01283
    01284     Wx86KnownDll - TRUE, treat Importer as x86
    01285
    01286     LdrDataTableEntry - Supplies the address of the data table entry.
    01287
    01288 Return Value:
    01289
    01290     Status value.
    01291
    01292 --*/
    01293
    01294 {
    01295     NTSTATUS st;
    01296     PVOID ViewBase;
    01297     PTEB Teb = NtCurrentTeb();
    01298     SIZE_T ViewSize;
    01299     HANDLE Section, DllFile;
    01300     UNICODE_STRING FullDllName, BaseDllName;
    01301     UNICODE_STRING NtFileName;
    01302     PLDR_DATA_TABLE_ENTRY Entry;
    01303     PIMAGE_NT_HEADERS NtHeaders;
    01304     PVOID ArbitraryUserPointer;
    01305     BOOLEAN KnownDll;
    01306     UNICODE_STRING CollidingDll;
    01307     PUCHAR ImageBase, ImageBounds, ScanBase, ScanTop;
    01308     PLDR_DATA_TABLE_ENTRY ScanEntry;
    01309     PLIST_ENTRY ScanHead,ScanNext;
    01310     BOOLEAN CollidingDllFound;
    01311     NTSTATUS ErrorStatus;
    01312     ULONG_PTR ErrorParameters[2];
    01313     ULONG ErrorResponse;
    01314 #if defined (WX86)
    01315     BOOLEAN Wx86Plugin = FALSE;
    01316 #endif
    01317
    01318
    01319     //
    01320     // Get section handle of DLL being snapped
    01321     //
    01322
    01323 #if LDRDBG
    01324     if (ShowSnaps) {
    01325         DbgPrint("LDR: LdrpMapDll: Image Name %ws, Search Path %ws\n",
    01326                 DllName,
    01327                 ARGUMENT_PRESENT(DllPath) ? DllPath : L""
    01328                 );
    01329     }
    01330 #endif
    01331
    01332     Entry = NULL;
    01333     KnownDll = FALSE;
    01334     Section = NULL;
    01335
    01336     if ( LdrpKnownDllObjectDirectory && !Wx86KnownDll) {
    01337
    01338         PWCH p = DllName;
    01339         WCHAR wch;
    01340
    01341         //
    01342         // Skip the KnownDll check if this is an explicit path.
    01343         //
    01344
    01345         while (*p) {
    01346             wch = *p++;
    01347             if (wch == (WCHAR)'\\' || wch == (WCHAR)'/' ) {
    01348                 goto SkipKnownDllCheck;
    01349                 }
    01350             }
    01351         Section = LdrpCheckForKnownDll(
    01352                         DllName,
    01353                         &FullDllName,
    01354                         &BaseDllName
    01355                         );
    01356
    01357         }
    01358
    01359 SkipKnownDllCheck:
    01360
    01361     if ( !Section ) {
    01362
    01363 #if defined (WX86)
    01364         if (Wx86ProcessInit) {
    01365             RtlInitUnicodeString(&BaseDllName, DllName);
    01366             st = LdrpWx86MapDll(DllPath,
    01367                                 DllCharacteristics,
    01368                                 Wx86KnownDll,
    01369                                 StaticLink,
    01370                                 &BaseDllName,
    01371                                 &Entry,
    01372                                 &ViewSize,
    01373                                 &Section
    01374                                 );
    01375
    01376             if (st == STATUS_DLL_NOT_FOUND) {
    01377                 goto Wx86MapDllNotFound;
    01378                 }
    01379
    01380             if (!NT_SUCCESS(st)) {
    01381                 return st;
    01382                 }
    01383
    01384
    01385             ViewBase    = Entry->DllBase;
    01386             FullDllName = Entry->FullDllName;
    01387             BaseDllName = Entry->BaseDllName;
    01388             NtHeaders = RtlImageNtHeader(ViewBase);
    01389
    01390             goto Wx86MapComplete;
    01391
    01392         } else
    01393 #endif
    01394
    01395         if (LdrpResolveDllName( DllPath,
    01396                                 DllName,
    01397                                 &FullDllName,
    01398                                 &BaseDllName,
    01399                                 &DllFile
    01400                               )
    01401            ) {
    01402             if (ShowSnaps) {
    01403                 PSZ type;
    01404                 type = StaticLink ? "STATIC" : "DYNAMIC";
    01405                 DbgPrint("LDR: Loading (%s) %wZ\n",
    01406                          type,
    01407                          &FullDllName
    01408                          );
    01409             }
    01410
    01411             if (!RtlDosPathNameToNtPathName_U( FullDllName.Buffer,
    01412                                                &NtFileName,
    01413                                                NULL,
    01414                                                NULL
    01415                                              )
    01416                ) {
    01417                 return STATUS_OBJECT_PATH_SYNTAX_BAD;
    01418                 }
    01419
    01420             st = LdrpCreateDllSection(&NtFileName,
    01421                                       DllFile,
    01422                                       &BaseDllName,
    01423                                       DllCharacteristics,
    01424                                       &Section
    01425                                      );
    01426
    01427             RtlFreeHeap(RtlProcessHeap(), 0, NtFileName.Buffer);
    01428
    01429             if (!NT_SUCCESS(st)) {
    01430                 RtlFreeUnicodeString(&FullDllName);
    01431                 RtlFreeUnicodeString(&BaseDllName);
    01432                 return st;
    01433             }
    01434 #if DBG
    01435             LdrpSectionCreates++;
    01436 #endif
    01437
    01438         } else {
    01439
    01440 #ifdef WX86
    01441 Wx86MapDllNotFound:
    01442 #endif
    01443             if ( StaticLink ) {
    01444                 PUNICODE_STRING ErrorStrings[2];
    01445                 UNICODE_STRING ErrorDllName, ErrorDllPath;
    01446                 ULONG ErrorResponse;
    01447
    01448                 ErrorStrings[0] = &ErrorDllName;
    01449                 ErrorStrings[1] = &ErrorDllPath;
    01450                 RtlInitUnicodeString(&ErrorDllName,DllName);
    01451                 RtlInitUnicodeString(&ErrorDllPath,
    01452                         ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer);
    01453                 NtRaiseHardError(
    01454                   (NTSTATUS)STATUS_DLL_NOT_FOUND,
    01455                   2,
    01456                   0x00000003,
    01457                   (PULONG_PTR)ErrorStrings,
    01458                   OptionOk,
    01459                   &ErrorResponse
    01460                   );
    01461                 if ( LdrpInLdrInit ) {
    01462                     LdrpFatalHardErrorCount++;
    01463                     }
    01464                 }
    01465
    01466             return STATUS_DLL_NOT_FOUND;
    01467         }
    01468     } else {
    01469         KnownDll = TRUE;
    01470     }
    01471
    01472     ViewBase = NULL;
    01473     ViewSize = 0;
    01474
    01475
    01476 #if DBG
    01477     LdrpSectionMaps++;
    01478     if (LdrpDisplayLoadTime) {
    01479         NtQueryPerformanceCounter(&MapBeginTime, NULL);
    01480     }
    01481 #endif
    01482
    01483     //
    01484     // arrange for debugger to pick up the image name
    01485     //
    01486
    01487     ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
    01488     Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer;
    01489     st = NtMapViewOfSection(
    01490             Section,
    01491             NtCurrentProcess(),
    01492             (PVOID *)&ViewBase,
    01493             0L,
    01494             0L,
    01495             NULL,
    01496             &ViewSize,
    01497             ViewShare,
    01498             0L,
    01499             PAGE_READWRITE
    01500             );
    01501     Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
    01502
    01503     if (!NT_SUCCESS(st)) {
    01504         NtClose(Section);
    01505         return st;
    01506     }
    01507
    01508     NtHeaders = RtlImageNtHeader(ViewBase);
    01509     if ( !NtHeaders ) {
    01510         NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01511         NtClose(Section);
    01512         return STATUS_INVALID_IMAGE_FORMAT;
    01513         }
    01514
    01515 #if DBG
    01516     if (LdrpDisplayLoadTime) {
    01517         NtQueryPerformanceCounter(&MapEndTime, NULL);
    01518         MapElapsedTime.QuadPart = MapEndTime.QuadPart - MapBeginTime.QuadPart;
    01519         DbgPrint("Map View of Section Time %ld %ws\n",
    01520             MapElapsedTime.LowPart,
    01521             DllName
    01522             );
    01523     }
    01524 #endif
    01525
    01526 #if defined (BUILD_WOW6432)
    01527     if (NtHeaders->OptionalHeader.SectionAlignment < NATIVE_PAGE_SIZE &&
    01528         !NT_SUCCESS(LdrpWx86FormatVirtualImage((PIMAGE_NT_HEADERS32)NtHeaders, ViewBase)))
    01529       {
    01530         NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01531         NtClose(Section);
    01532         return st;
    01533         }
    01534 #elif defined (_ALPHA_) && defined (WX86)
    01535     if ((NtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) &&
    01536         !NT_SUCCESS(LdrpWx86FormatVirtualImage((PIMAGE_NT_HEADERS32)NtHeaders, ViewBase)))
    01537       {
    01538         NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01539         NtClose(Section);
    01540         return STATUS_INVALID_IMAGE_FORMAT;
    01541         }
    01542
    01543     if (st == STATUS_IMAGE_MACHINE_TYPE_MISMATCH && !StaticLink) {
    01544
    01545         // Attempt to find a plugin provider dll that can thunk this interface
    01546         // temporarily insert the image in the loaded-module-list
    01547
    01548         Entry = LdrpAllocateDataTableEntry(ViewBase);
    01549         if (!Entry) {
    01550             return STATUS_NO_MEMORY;
    01551         }
    01552
    01553         Entry->Flags = 0;
    01554         Entry->LoadCount = 0;
    01555         Entry->FullDllName = FullDllName;
    01556         Entry->BaseDllName = BaseDllName;
    01557         Entry->EntryPoint = LdrpFetchAddressOfEntryPoint(Entry->DllBase);
    01558         LdrpInsertMemoryTableEntry(Entry);
    01559
    01560         // Determine if this dll can be thunked using a plugin
    01561
    01562         st = Wx86IdentifyPlugin(ViewBase, &FullDllName );
    01563
    01564          // remove the image from the loaded-module-list
    01565
    01566         RemoveEntryList(&Entry->InLoadOrderLinks);
    01567         RemoveEntryList(&Entry->InMemoryOrderLinks);
    01568         RemoveEntryList(&Entry->HashLinks);
    01569         RtlFreeHeap(RtlProcessHeap(), 0, Entry);
    01570         Entry = NULL;
    01571
    01572         if (st == STATUS_SUCCESS) {
    01573
    01574             // Release the previous mapping because it's going to
    01575             // be reloaded via Wx86.
    01576
    01577             NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01578             ViewBase = NULL;
    01579
    01580             // The plugin providers must be statically bound to Wx86
    01581             // or dynamically load it in their DllInit.
    01582
    01583             if (Wx86ProcessInit) {
    01584
    01585                 // Load the dll again using Wx86.
    01586
    01587                 st = LdrpWx86MapDll(NULL,
    01588                                     DllCharacteristics,
    01589                                     !Wx86KnownDll,          // swap sense so we don't get mismatch
    01590                                     StaticLink,
    01591                                     &FullDllName,
    01592                                     &Entry,
    01593                                     &ViewSize,
    01594                                     &Section
    01595                                     );
    01596
    01597                 // Load and thunk the plugin dll
    01598
    01599                 if (NT_SUCCESS(st)) {
    01600
    01601                     ViewBase    = Entry->DllBase;
    01602                     FullDllName = Entry->FullDllName;
    01603                     BaseDllName = Entry->BaseDllName;
    01604                     NtHeaders = RtlImageNtHeader(ViewBase);
    01605
    01606                 }
    01607             }
    01608
    01609             if (!Wx86ProcessInit || NT_ERROR(st)) {
    01610                 Wx86UnloadProviders(ViewBase);
    01611                 st = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
    01612             }
    01613         }
    01614
    01615         // Need to save the status here to put in loader ENTRY after it's allocated.
    01616
    01617         Wx86Plugin = (st == STATUS_SUCCESS);
    01618
    01619         if (ShowSnaps) {
    01620             PCHAR Action;
    01621
    01622             if (st == STATUS_SUCCESS) {
    01623                 Action = "Loaded";
    01624             } else if (st == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) {
    01625                 Action = "Unsupported";
    01626             } else {
    01627                 Action = "Failed";
    01628             }
    01629
    01630             DbgPrint("LDRWx86: Plugin: %wZ %s.\n",
    01631                 &FullDllName, Action
    01632                 );
    01633         }
    01634     }
    01635
    01636     if (!NT_SUCCESS(st) || (ViewBase == NULL)) {
    01637         if (ViewBase) NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01638         NtClose(Section);
    01639         return st;
    01640     } else if (Entry) {
    01641         goto Wx86MapComplete;
    01642     }
    01643 #endif
    01644
    01645     //
    01646     // Allocate a data table entry.
    01647     //
    01648
    01649     Entry = LdrpAllocateDataTableEntry(ViewBase);
    01650
    01651     if (!Entry) {
    01652         NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01653         NtClose(Section);
    01654         return STATUS_NO_MEMORY;
    01655     }
    01656
    01657
    01658     Entry->Flags = (USHORT)(StaticLink ? LDRP_STATIC_LINK : 0);
    01659     Entry->LoadCount = 0;
    01660     Entry->FullDllName = FullDllName;
    01661     Entry->BaseDllName = BaseDllName;
    01662     Entry->EntryPoint = LdrpFetchAddressOfEntryPoint(Entry->DllBase);
    01663
    01664 #ifdef WX86
    01665 Wx86MapComplete:
    01666     if (Wx86Plugin) {
    01667         Entry->Flags |= LDRP_WX86_PLUGIN;
    01668     }
    01669 #endif
    01670
    01671
    01672 #if LDRDBG
    01673     if (ShowSnaps) {
    01674         DbgPrint("LDR: LdrpMapDll: Full Name %wZ, Base Name %wZ\n",
    01675                 &FullDllName,
    01676                 &BaseDllName
    01677                 );
    01678     }
    01679 #endif
    01680
    01681     LdrpInsertMemoryTableEntry(Entry);
    01682
    01683     if ( st == STATUS_IMAGE_MACHINE_TYPE_MISMATCH ) {
    01684
    01685         PIMAGE_NT_HEADERS ImageHeader = RtlImageNtHeader( NtCurrentPeb()->ImageBaseAddress );
    01686
    01687         //
    01688         // apps compiled for NT 3.x and below can load cross architecture
    01689         // images
    01690         //
    01691
    01692         ErrorStatus = STATUS_SUCCESS;
    01693         ErrorResponse = ResponseCancel;
    01694
    01695         if ( ImageHeader->OptionalHeader.MajorSubsystemVersion <= 3 ) {
    01696
    01697             Entry->EntryPoint = 0;
    01698
    01699             //
    01700             // Hard Error Time
    01701             //
    01702
    01703             //
    01704             // Its error time...
    01705             //
    01706
    01707             ErrorParameters[0] = (ULONG_PTR)&FullDllName;
    01708
    01709             ErrorStatus = NtRaiseHardError(
    01710                             STATUS_IMAGE_MACHINE_TYPE_MISMATCH,
    01711                             1,
    01712                             1,
    01713                             ErrorParameters,
    01714                             OptionOkCancel,
    01715                             &ErrorResponse
    01716                             );
    01717             }
    01718         if ( NT_SUCCESS(ErrorStatus) && ErrorResponse == ResponseCancel ) {
    01719             RemoveEntryList(&Entry->InLoadOrderLinks);
    01720             RemoveEntryList(&Entry->InMemoryOrderLinks);
    01721             RemoveEntryList(&Entry->HashLinks);
    01722             RtlFreeHeap(RtlProcessHeap(), 0, Entry );
    01723             NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01724             NtClose(Section);
    01725
    01726             if ( ImageHeader->OptionalHeader.MajorSubsystemVersion <= 3 ) {
    01727                 if ( LdrpInLdrInit ) {
    01728                     LdrpFatalHardErrorCount++;
    01729                     }
    01730                 }
    01731             return STATUS_INVALID_IMAGE_FORMAT;
    01732             }
    01733         }
    01734     else {
    01735         if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) {
    01736             Entry->Flags |= LDRP_IMAGE_DLL;
    01737             }
    01738
    01739         if (!(Entry->Flags & LDRP_IMAGE_DLL)) {
    01740             Entry->EntryPoint = 0;
    01741             }
    01742         }
    01743     *LdrDataTableEntry = Entry;
    01744
    01745     if (st == STATUS_IMAGE_NOT_AT_BASE) {
    01746
    01747         Entry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
    01748
    01749         //
    01750         // now find the colliding dll. If we can not find a dll,
    01751         // then the colliding dll must be dynamic memory
    01752         //
    01753
    01754         ImageBase = (PUCHAR)NtHeaders->OptionalHeader.ImageBase;
    01755         ImageBounds = ImageBase + ViewSize;
    01756
    01757         CollidingDllFound = FALSE;
    01758
    01759         ScanHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
    01760         ScanNext = ScanHead->Flink;
    01761
    01762         while ( ScanNext != ScanHead ) {
    01763             ScanEntry = CONTAINING_RECORD(ScanNext, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
    01764             ScanNext = ScanNext->Flink;
    01765
    01766             ScanBase = (PUCHAR)ScanEntry->DllBase;
    01767             ScanTop = ScanBase + ScanEntry->SizeOfImage;
    01768
    01769             //
    01770             // when we unload, the memory order links flink field is nulled.
    01771             // this is used to skip the entry pending list removal.
    01772             //
    01773
    01774             if ( !ScanEntry->InMemoryOrderLinks.Flink ) {
    01775                 continue;
    01776                 }
    01777
    01778             //
    01779             // See if the base address of the scan image is within the relocating dll
    01780             // or if the top address of the scan image is within the relocating dll
    01781             //
    01782
    01783             if ( (ImageBase >= ScanBase && ImageBase <= ScanTop)
    01784
    01785                  ||
    01786
    01787                  (ImageBounds >= ScanBase && ImageBounds <= ScanTop)
    01788
    01789                  ||
    01790
    01791                  (ScanBase >= ImageBase && ScanBase <= ImageBounds)
    01792
    01793                  ){
    01794
    01795                 CollidingDllFound = TRUE;
    01796                 CollidingDll = ScanEntry->FullDllName;
    01797                 break;
    01798                 }
    01799             }
    01800
    01801         if ( !CollidingDllFound ) {
    01802             RtlInitUnicodeString(&CollidingDll,L"Dynamically Allocated Memory");
    01803             }
    01804
    01805 #if DBG
    01806         if ( BeginTime.LowPart || BeginTime.HighPart ) {
    01807             DbgPrint("\nLDR: LdrpMapDll Relocateing Image Name %ws\n",
    01808                     DllName
    01809                     );
    01810         }
    01811         LdrpSectionRelocates++;
    01812 #endif
    01813         if (Entry->Flags & LDRP_IMAGE_DLL) {
    01814
    01815             BOOLEAN AllowRelocation;
    01816             UNICODE_STRING SystemDll;
    01817
    01818             if (!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)) {
    01819
    01820                 PVOID pBaseRelocs;
    01821                 ULONG BaseRelocCountBytes = 0;
    01822
    01823                 //
    01824                 // If the iamge doesn't have the reloc stripped bit set and there's no
    01825                 // relocs in the data directory, allow this through.  This is probably
    01826                 // a pure forwarder dll or data w/o relocs.
    01827                 //
    01828
    01829                 pBaseRelocs = RtlImageDirectoryEntryToData(
    01830                         ViewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &BaseRelocCountBytes);
    01831
    01832                 if (!pBaseRelocs && !BaseRelocCountBytes) {
    01833                     goto NoRelocNeeded;
    01834                     }
    01835                 }
    01836
    01837             //
    01838             // decide whether or not to allow the relocation
    01839             // certain system dll's like user32 and kernel32 are not relocatable
    01840             // since addresses within these dll's are not always stored per process
    01841             // do not allow these dll's to be relocated
    01842             //
    01843
    01844             AllowRelocation = TRUE;
    01845             RtlInitUnicodeString(&SystemDll,L"user32.dll");
    01846             if ( RtlEqualUnicodeString(&BaseDllName,&SystemDll,TRUE) ) {
    01847                 AllowRelocation = FALSE;
    01848                 }
    01849             else {
    01850                 RtlInitUnicodeString(&SystemDll,L"kernel32.dll");
    01851                 if ( RtlEqualUnicodeString(&BaseDllName,&SystemDll,TRUE) ) {
    01852                     AllowRelocation = FALSE;
    01853                     }
    01854                 }
    01855             if ( !AllowRelocation && KnownDll ) {
    01856
    01857                 //
    01858                 // totally disallow the relocation since this is a knowndll
    01859                 // that matches our system binaries and is being relocated
    01860                 //
    01861
    01862                 //
    01863                 // Hard Error Time
    01864                 //
    01865
    01866                 ErrorParameters[0] = (ULONG_PTR)&SystemDll;
    01867                 ErrorParameters[1] = (ULONG_PTR)&CollidingDll;
    01868
    01869                 NtRaiseHardError(
    01870                   STATUS_ILLEGAL_DLL_RELOCATION,
    01871                   2,
    01872                   3,
    01873                   ErrorParameters,
    01874                   OptionOk,
    01875                   &ErrorResponse
    01876                   );
    01877
    01878                 if ( LdrpInLdrInit ) {
    01879                     LdrpFatalHardErrorCount++;
    01880                     }
    01881
    01882                 st = STATUS_CONFLICTING_ADDRESSES;
    01883                 goto skipreloc;
    01884                 }
    01885
    01886             st = LdrpSetProtection(ViewBase, FALSE, StaticLink );
    01887             if (NT_SUCCESS(st)) {
    01888                 st = (NTSTATUS)LdrRelocateImage(ViewBase,
    01889                             "LDR",
    01890                             (ULONG)STATUS_SUCCESS,
    01891                             (ULONG)STATUS_CONFLICTING_ADDRESSES,
    01892                             (ULONG)STATUS_INVALID_IMAGE_FORMAT
    01893                             );
    01894                 if (NT_SUCCESS(st)) {
    01895
    01896                     //
    01897                     // If we did relocations, then map the section again.
    01898                     // this will force the debug event
    01899                     //
    01900
    01901                     //
    01902                     // arrange for debugger to pick up the image name
    01903                     //
    01904
    01905                     ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
    01906                     Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer;
    01907                     NtMapViewOfSection(
    01908                         Section,
    01909                         NtCurrentProcess(),
    01910                         (PVOID *)&ViewBase,
    01911                         0L,
    01912                         0L,
    01913                         NULL,
    01914                         &ViewSize,
    01915                         ViewShare,
    01916                         0L,
    01917                         PAGE_READWRITE
    01918                         );
    01919                     Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
    01920
    01921                     st = LdrpSetProtection(ViewBase, TRUE, StaticLink);
    01922
    01923                 }
    01924             }
    01925 skipreloc:
    01926             //
    01927             // if the set protection failed, or if the relocation failed, then
    01928             // remove the partially loaded dll from the lists and clear entry
    01929             // that it has been freed.
    01930             //
    01931
    01932             if ( !NT_SUCCESS(st) ) {
    01933                 RemoveEntryList(&Entry->InLoadOrderLinks);
    01934                 RemoveEntryList(&Entry->InMemoryOrderLinks);
    01935                 RemoveEntryList(&Entry->HashLinks);
    01936                 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
    01937                 Entry = NULL;
    01938                 }
    01939
    01940             if (ShowSnaps) {
    01941                 DbgPrint("LDR: Fixups %successfully re-applied @ %lx\n",
    01942                        NT_SUCCESS(st) ? "s" : "uns", ViewBase);
    01943             }
    01944         } else {
    01945 NoRelocNeeded:
    01946                  st = STATUS_SUCCESS;
    01947
    01948                  //
    01949                  // arrange for debugger to pick up the image name
    01950                  //
    01951
    01952                  ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
    01953                  Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer;
    01954                  NtMapViewOfSection(
    01955                      Section,
    01956                      NtCurrentProcess(),
    01957                      (PVOID *)&ViewBase,
    01958                      0L,
    01959                      0L,
    01960                      NULL,
    01961                      &ViewSize,
    01962                      ViewShare,
    01963                      0L,
    01964                      PAGE_READWRITE
    01965                      );
    01966                  Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
    01967
    01968                  if (ShowSnaps) {
    01969                      DbgPrint("LDR: Fixups won't be re-applied to non-Dll @ %lx\n",
    01970                               ViewBase);
    01971                  }
    01972                }
    01973     }
    01974
    01975 #if defined (_ALPHA_)
    01976
    01977     //
    01978     // Find and apply Alpha architecture fixups for this dll
    01979     //
    01980     if (Entry->Flags & LDRP_IMAGE_DLL)
    01981         AlphaFindArchitectureFixups(NtHeaders, ViewBase, StaticLink);
    01982 #endif
    01983
    01984 #if defined(_X86_)
    01985     if ( LdrpNumberOfProcessors > 1 && Entry && (Entry->Flags & LDRP_IMAGE_DLL) ) {
    01986         LdrpValidateImageForMp(Entry);
    01987         }
    01988 #endif
    01989     NtClose(Section);
    01990     return st;
    01991 }

USHORT LdrpNameToOrdinal | ( | IN PSZ | Name,
|  | IN ULONG | NumberOfNames,
|  | IN PVOID | DllBase,
|  | IN PULONG | NameTableBase,
|  | IN PUSHORT | NameOrdinalTableBase
| ) |

Definition at line 2747 of file ldrsnap.c.

References Name, and USHORT.

Referenced by LdrpSnapThunk().

    02754 {
    02755     LONG High;
    02756     LONG Low;
    02757     LONG Middle;
    02758     LONG Result;
    02759
    02760     //
    02761     // Lookup the import name in the name table using a binary search.
    02762     //
    02763
    02764     Low = 0;
    02765     High = NumberOfNames - 1;
    02766     while (High >= Low) {
    02767
    02768         //
    02769         // Compute the next probe index and compare the import name
    02770         // with the export name entry.
    02771         //
    02772
    02773         Middle = (Low + High) >> 1;
    02774         Result = strcmp(Name, (PCHAR)((ULONG_PTR)DllBase + NameTableBase[Middle]));
    02775
    02776         if (Result < 0) {
    02777             High = Middle - 1;
    02778
    02779         } else if (Result > 0) {
    02780             Low = Middle + 1;
    02781
    02782         } else {
    02783             break;
    02784         }
    02785     }
    02786
    02787     //
    02788     // If the high index is less than the low index, then a matching
    02789     // table entry was not found. Otherwise, get the ordinal number
    02790     // from the ordinal table.
    02791     //
    02792
    02793     if (High < Low) {
    02794         return (USHORT)-1;
    02795     } else {
    02796         return NameOrdinalTableBase[Middle];
    02797     }
    02798
    02799 }

BOOLEAN LdrpResolveDllName | ( | IN PWSTR DllPath | OPTIONAL,
|  | IN PWSTR | DllName,
|  | OUT PUNICODE_STRING | FullDllName,
|  | OUT PUNICODE_STRING | BaseDllName,
|  | OUT PHANDLE | DllFile
| ) |

Definition at line 3120 of file ldrsnap.c.

References DbgPrint, FALSE, LDR_TAG, LdrpDefaultPath, MAKE_TAG, NULL, RtlAllocateHeap, RtlDosSearchPath_U(), RtlFreeHeap, RtlFreeUnicodeString(), ShowSnaps, TEMP_TAG, TRUE, and USHORT.

Referenced by LdrpMapDll().

    03130                    :
    03131
    03132     This function computes the DLL pathname and base dll name (the
    03133     unqualified, extensionless portion of the file name) for the specified
    03134     DLL.
    03135
    03136 Arguments:
    03137
    03138     DllPath - Supplies the DLL search path.
    03139
    03140     DllName - Supplies the name of the DLL.
    03141
    03142     FullDllName - Returns the fully qualified pathname of the
    03143         DLL. The Buffer field of this string is dynamically
    03144         allocated from the processes heap.
    03145
    03146     BaseDLLName - Returns the base dll name of the dll.  The base name
    03147         is the file name portion of the dll path without the trailing
    03148         extension. The Buffer field of this string is dynamically
    03149         allocated from the processes heap.
    03150
    03151     DllFile - Returns an open handle to the DLL file. This parameter may
    03152         still be NULL even upon success.
    03153
    03154 Return Value:
    03155
    03156     TRUE - The operation was successful. A DLL file was found, and the
    03157         FullDllName->Buffer & BaseDllName->Buffer field points to the
    03158         base of process heap allocated memory.
    03159
    03160     FALSE - The DLL could not be found.
    03161
    03162 --*/
    03163
    03164 {
    03165     ULONG Length;
    03166     PWCH p, pp;
    03167     PWCH FullBuffer;
    03168
    03169     *DllFile = NULL;
    03170     FullDllName->Buffer = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TEMP_TAG ),530+sizeof(UNICODE_NULL));
    03171     if (FullDllName->Buffer == NULL) {
    03172         return FALSE;
    03173         }
    03174
    03175     Length = RtlDosSearchPath_U(
    03176                 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer,
    03177                 DllName,
    03178                 NULL,
    03179                 530,
    03180                 FullDllName->Buffer,
    03181                 &BaseDllName->Buffer
    03182                 );
    03183
    03184     if ( !Length || Length > 530 ) {
    03185
    03186         if (ShowSnaps) {
    03187             DbgPrint("LDR: LdrResolveDllName - Unable To Locate ");
    03188             DbgPrint("%ws from %ws\n",
    03189                 DllName,
    03190                 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer
    03191                 );
    03192         }
    03193
    03194         RtlFreeUnicodeString(FullDllName);
    03195         return FALSE;
    03196     }
    03197
    03198     FullDllName->Length = (USHORT)Length;
    03199     FullDllName->MaximumLength = FullDllName->Length + (USHORT)sizeof(UNICODE_NULL);
    03200     FullBuffer = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( LDR_TAG ),FullDllName->MaximumLength);
    03201     if ( FullBuffer ) {
    03202         RtlCopyMemory(FullBuffer,FullDllName->Buffer,FullDllName->MaximumLength);
    03203         RtlFreeHeap(RtlProcessHeap(), 0, FullDllName->Buffer);
    03204         FullDllName->Buffer = FullBuffer;
    03205         }
    03206     else {
    03207         return FALSE;
    03208         }
    03209     //
    03210     // Compute Length of base dll name
    03211     //
    03212
    03213     pp = UNICODE_NULL;
    03214     p = FullDllName->Buffer;
    03215     while (*p) {
    03216         if (*p++ == (WCHAR)'\\') {
    03217             pp = p;
    03218         }
    03219     }
    03220
    03221     p = pp ? pp : DllName;
    03222     pp = p;
    03223
    03224     while (*p) {
    03225         ++p;
    03226     }
    03227
    03228     BaseDllName->Length = (USHORT)((ULONG_PTR)p - (ULONG_PTR)pp);
    03229     BaseDllName->MaximumLength = BaseDllName->Length + (USHORT)sizeof(UNICODE_NULL);
    03230     BaseDllName->Buffer = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( LDR_TAG ), BaseDllName->MaximumLength);
    03231     if ( BaseDllName->Buffer ) {
    03232         RtlMoveMemory(BaseDllName->Buffer,
    03233                        pp,
    03234                        BaseDllName->Length
    03235                      );
    03236
    03237         BaseDllName->Buffer[BaseDllName->Length >> 1] = UNICODE_NULL;
    03238         }
    03239     else {
    03240         RtlFreeHeap(RtlProcessHeap(), 0, FullBuffer);
    03241         return FALSE;
    03242         }
    03243
    03244     return TRUE;
    03245 }

NTSTATUS LdrpRunInitializeRoutines | ( | IN PCONTEXT Context | OPTIONAL | ) |

Definition at line 652 of file ldrsnap.c.

References DbgPrint, L, LdrpCallInitRoutine, LdrpCallTlsInitializers(), LdrpClearLoadInProgress(), LdrpImageHasTls, LdrQueryImageFileExecutionOptions(), MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlImageNtHeader(), ShowSnaps, Status, TEMP_TAG, and TRUE.

Referenced by LdrpGetProcedureAddress(), LdrpInitializeProcess(), and LdrpLoadDll().

    00655 {
    00656     PLIST_ENTRY Head, Next;
    00657     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    00658     PLDR_DATA_TABLE_ENTRY *LdrDataTableBase;
    00659     PDLL_INIT_ROUTINE InitRoutine;
    00660     BOOLEAN InitStatus;
    00661     ULONG NumberOfRoutines;
    00662     ULONG i;
    00663     NTSTATUS Status;
    00664     ULONG BreakOnDllLoad;
    00665
    00666     //
    00667     // Run the Init routines
    00668     //
    00669
    00670     //
    00671     // capture the entries that have init routines
    00672     //
    00673
    00674     NumberOfRoutines = LdrpClearLoadInProgress();
    00675     if ( NumberOfRoutines ) {
    00676         LdrDataTableBase = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TEMP_TAG ),NumberOfRoutines*sizeof(LdrDataTableBase));
    00677         if ( !LdrDataTableBase ) {
    00678             return STATUS_NO_MEMORY;
    00679             }
    00680         }
    00681     else {
    00682         LdrDataTableBase = NULL;
    00683         }
    00684
    00685     Head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
    00686     Next = Head->Flink;
    00687     if (ShowSnaps) {
    00688         DbgPrint("LDR: Real INIT LIST\n");
    00689         }
    00690
    00691     i = 0;
    00692     while ( Next != Head ) {
    00693         LdrDataTableEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
    00694
    00695 #if defined (WX86)
    00696         if (Wx86ProcessInit && !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED)) {
    00697             PIMAGE_NT_HEADERS NtHeaders;
    00698
    00699             NtHeaders = RtlImageNtHeader(LdrDataTableEntry->DllBase);
    00700             if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
    00701                 LdrpWx86DllMapNotify(LdrDataTableEntry->DllBase, TRUE);
    00702             }
    00703         }
    00704 #endif
    00705
    00706         if ( !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED) && LdrDataTableEntry->EntryPoint) {
    00707             LdrDataTableBase[i] = LdrDataTableEntry;
    00708             if (ShowSnaps) {
    00709                 DbgPrint("     %wZ init routine %x\n",
    00710                         &LdrDataTableEntry->FullDllName,
    00711                         LdrDataTableEntry->EntryPoint
    00712                         );
    00713                 }
    00714
    00715             i++;
    00716             }
    00717         LdrDataTableEntry->Flags |= LDRP_ENTRY_PROCESSED;
    00718
    00719         Next = Next->Flink;
    00720         }
    00721     if ( !LdrDataTableBase ) {
    00722         return STATUS_SUCCESS;
    00723         }
    00724
    00725     try {
    00726         i = 0;
    00727         while ( i < NumberOfRoutines ) {
    00728             LdrDataTableEntry = LdrDataTableBase[i];
    00729             i++;
    00730             InitRoutine = (PDLL_INIT_ROUTINE)LdrDataTableEntry->EntryPoint;
    00731
    00732             //
    00733             // Walk through the entire list looking for un-processed
    00734             // entries. For each entry, set the processed flag
    00735             // and optionally call it's init routine
    00736             //
    00737
    00738             BreakOnDllLoad = 0;
    00739 #if DBG
    00740             if (TRUE) {
    00741 #else
    00742             if (NtCurrentPeb()->BeingDebugged || NtCurrentPeb()->ReadImageFileExecOptions) {
    00743 #endif
    00744                 Status = LdrQueryImageFileExecutionOptions( &LdrDataTableEntry->BaseDllName,
    00745                                                             L"BreakOnDllLoad",
    00746                                                             REG_DWORD,
    00747                                                             &BreakOnDllLoad,
    00748                                                             sizeof( BreakOnDllLoad ),
    00749                                                             NULL
    00750                                                           );
    00751                 if (!NT_SUCCESS( Status )) {
    00752                     BreakOnDllLoad = 0;
    00753                     }
    00754                 }
    00755
    00756             if (BreakOnDllLoad) {
    00757                 if (ShowSnaps) {
    00758                     DbgPrint( "LDR: %wZ loaded.", &LdrDataTableEntry->BaseDllName );
    00759                     DbgPrint( " - About to call init routine at %lx\n", InitRoutine );
    00760                     }
    00761                 DbgBreakPoint();
    00762
    00763                 }
    00764             else if (ShowSnaps) {
    00765                 if ( InitRoutine ) {
    00766                     DbgPrint( "LDR: %wZ loaded.", &LdrDataTableEntry->BaseDllName );
    00767                     DbgPrint(" - Calling init routine at %lx\n", InitRoutine);
    00768                     }
    00769                 }
    00770
    00771             if ( InitRoutine ) {
    00772
    00773                 //
    00774                 // If the DLL has TLS data, then call the optional initializers
    00775                 //
    00776
    00777
    00778
    00779                 if ( LdrDataTableEntry->TlsIndex && Context) {
    00780                     LdrpCallTlsInitializers(LdrDataTableEntry->DllBase,DLL_PROCESS_ATTACH);
    00781                     }
    00782
    00783 #if defined (WX86)
    00784                 if (!Wx86ProcessInit ||
    00785                     LdrpRunWx86DllEntryPoint(InitRoutine,
    00786                                             &InitStatus,
    00787                                             LdrDataTableEntry->DllBase,
    00788                                             DLL_PROCESS_ATTACH,
    00789                                             Context
    00790                                             ) ==  STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
    00791                     {
    00792                     InitStatus = LdrpCallInitRoutine(InitRoutine,
    00793                                                      LdrDataTableEntry->DllBase,
    00794                                                      DLL_PROCESS_ATTACH,
    00795                                                      Context
    00796                                                     );
    00797                     }
    00798
    00799 #else
    00800                 InitStatus = LdrpCallInitRoutine(InitRoutine,
    00801                                                  LdrDataTableEntry->DllBase,
    00802                                                  DLL_PROCESS_ATTACH,
    00803                                                  Context
    00804                                                 );
    00805 #endif
    00806
    00807                 LdrDataTableEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED;
    00808
    00809                 if ( !InitStatus ) {
    00810                     return STATUS_DLL_INIT_FAILED;
    00811                     }
    00812                 }
    00813             }
    00814
    00815         //
    00816         // If the image has tls than call its initializers
    00817         //
    00818
    00819         if ( LdrpImageHasTls && Context ) {
    00820             LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_PROCESS_ATTACH);
    00821             }
    00822
    00823         }
    00824     finally {
    00825         RtlFreeHeap(RtlProcessHeap(),0,LdrDataTableBase);
    00826         }
    00827
    00828     return STATUS_SUCCESS;
    00829 }

NTSTATUS LdrpSetProtection | ( | IN PVOID | Base,
|  | IN BOOLEAN | Reset,
|  | IN BOOLEAN | StaticLink
| ) |

Definition at line 3417 of file ldrsnap.c.

References NT_SUCCESS, NtFlushInstructionCache(), NtProtectVirtualMemory(), NTSTATUS(), NULL, PAGE_SIZE, and RtlImageNtHeader().

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

    03425                    :
    03426
    03427     This function loops thru the images sections/objects, setting
    03428     all sections/objects marked r/o to r/w. It also resets the
    03429     original section/object protections.
    03430
    03431 Arguments:
    03432
    03433     Base - Base of image.
    03434
    03435     Reset - If TRUE, reset section/object protection to original
    03436             protection described by the section/object headers.
    03437             If FALSE, then set all sections/objects to r/w.
    03438
    03439     StaticLink - TRUE if this is a static link.
    03440
    03441 Return Value:
    03442
    03443     SUCCESS or reason NtProtectVirtualMemory failed.
    03444
    03445 --*/
    03446
    03447 {
    03448     HANDLE CurrentProcessHandle;
    03449     SIZE_T RegionSize;
    03450     ULONG NewProtect, OldProtect;
    03451     PVOID VirtualAddress;
    03452     ULONG i;
    03453     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    03454     PIMAGE_NT_HEADERS NtHeaders;
    03455     PIMAGE_SECTION_HEADER SectionHeader;
    03456     NTSTATUS st;
    03457
    03458     CurrentProcessHandle = NtCurrentProcess();
    03459
    03460     NtHeaders = RtlImageNtHeader(Base);
    03461
    03462 #if defined (_ALPHA_)
    03463     if (NtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) {
    03464         //
    03465         // if SectionAlignment < PAGE_SIZE the entire image is
    03466         // exec-copy on write, so we have nothing to do.
    03467         //
    03468         return STATUS_SUCCESS;
    03469         }
    03470 #endif
    03471
    03472     SectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NtHeaders + sizeof(ULONG) +
    03473                         sizeof(IMAGE_FILE_HEADER) +
    03474                         NtHeaders->FileHeader.SizeOfOptionalHeader
    03475                         );
    03476
    03477     for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
    03478         if (!(SectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) &&
    03479              (SectionHeader->SizeOfRawData))
    03480          {
    03481             //
    03482             // Object isn't writeable and has a non-zero on disk size, change it.
    03483             //
    03484             if (Reset) {
    03485                 if (SectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
    03486                     NewProtect = PAGE_EXECUTE;
    03487                 } else {
    03488                          NewProtect = PAGE_READONLY;
    03489                 }
    03490                 NewProtect |= (SectionHeader->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) ? PAGE_NOCACHE : 0;
    03491             } else {
    03492                 NewProtect = PAGE_READWRITE;
    03493             }
    03494             VirtualAddress = (PVOID)((ULONG_PTR)Base + SectionHeader->VirtualAddress);
    03495             RegionSize = SectionHeader->SizeOfRawData;
    03496
    03497             if (RegionSize != 0) {
    03498                 st = NtProtectVirtualMemory(CurrentProcessHandle, &VirtualAddress,
    03499                               &RegionSize, NewProtect, &OldProtect);
    03500
    03501                 if (!NT_SUCCESS(st)) {
    03502                     return st;
    03503                 }
    03504             }
    03505
    03506         }
    03507         ++SectionHeader;
    03508     }
    03509
    03510     if (Reset) {
    03511         NtFlushInstructionCache(NtCurrentProcess(), NULL, 0);
    03512     }
    03513     return STATUS_SUCCESS;
    03514 }

NTSTATUS LdrpSnapIAT | ( | IN PLDR_DATA_TABLE_ENTRY | LdrDataTableEntry_Export,
|  | IN PLDR_DATA_TABLE_ENTRY | LdrDataTableEntry_Import,
|  | IN PIMAGE_IMPORT_DESCRIPTOR | ImportDescriptor,
|  | IN BOOLEAN | SnapForwardersOnly
| ) |

Definition at line 2258 of file ldrsnap.c.

References EXCEPTION_EXECUTE_HANDLER, LdrpSnapThunk(), NT_SUCCESS, NtFlushInstructionCache(), NtProtectVirtualMemory(), NTSTATUS(), NULL, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), and TRUE.

Referenced by LdrpWalkImportDescriptor().

    02267                    :
    02268
    02269     This function snaps the Import Address Table for this
    02270     Import Descriptor.
    02271
    02272 Arguments:
    02273
    02274     LdrDataTableEntry_Export - Information about the image to import from.
    02275
    02276     LdrDataTableEntry_Import - Information about the image to import to.
    02277
    02278     ImportDescriptor - Contains a pointer to the IAT to snap.
    02279
    02280     SnapForwardersOnly - TRUE if just snapping forwarders only.
    02281
    02282 Return Value:
    02283
    02284     Status value
    02285
    02286 --*/
    02287
    02288 {
    02289     PPEB Peb;
    02290     NTSTATUS st;
    02291     ULONG ExportSize;
    02292     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
    02293     PIMAGE_THUNK_DATA Thunk, OriginalThunk;
    02294     PSZ ImportName;
    02295     ULONG ForwarderChain;
    02296     PIMAGE_NT_HEADERS NtHeaders;
    02297     PIMAGE_SECTION_HEADER NtSection;
    02298     ULONG i, Rva;
    02299     PVOID IATBase;
    02300     SIZE_T IATSize;
    02301     ULONG LittleIATSize;
    02302     ULONG OldProtect;
    02303
    02304     Peb = NtCurrentPeb();
    02305
    02306     ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(
    02307                        LdrDataTableEntry_Export->DllBase,
    02308                        TRUE,
    02309                        IMAGE_DIRECTORY_ENTRY_EXPORT,
    02310                        &ExportSize
    02311                        );
    02312
    02313     if (!ExportDirectory) {
    02314         KdPrint(("LDR: %wZ doesn't contain an EXPORT table\n", &LdrDataTableEntry_Export->BaseDllName));
    02315         return STATUS_INVALID_IMAGE_FORMAT;
    02316         }
    02317
    02318     //
    02319     // Determine the location and size of the IAT.  If the linker did
    02320     // not tell use explicitly, then use the location and size of the
    02321     // image section that contains the import table.
    02322     //
    02323
    02324     IATBase = RtlImageDirectoryEntryToData( LdrDataTableEntry_Import->DllBase,
    02325                                             TRUE,
    02326                                             IMAGE_DIRECTORY_ENTRY_IAT,
    02327                                             &LittleIATSize
    02328                                           );
    02329     IATSize = LittleIATSize;
    02330     if (IATBase == NULL) {
    02331         NtHeaders = RtlImageNtHeader( LdrDataTableEntry_Import->DllBase );
    02332         NtSection = IMAGE_FIRST_SECTION( NtHeaders );
    02333         Rva = NtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress;
    02334         if (Rva != 0) {
    02335             for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
    02336                 if (Rva >= NtSection->VirtualAddress &&
    02337                     Rva < (NtSection->VirtualAddress + NtSection->SizeOfRawData)
    02338                    ) {
    02339                     IATBase = (PVOID)
    02340                         ((ULONG_PTR)(LdrDataTableEntry_Import->DllBase) + NtSection->VirtualAddress);
    02341
    02342                     LittleIATSize = NtSection->Misc.VirtualSize;
    02343                     if (LittleIATSize == 0) {
    02344                         LittleIATSize = NtSection->SizeOfRawData;
    02345                         }
    02346                     break;
    02347                     }
    02348
    02349                 ++NtSection;
    02350                 }
    02351             }
    02352
    02353         if (IATBase == NULL) {
    02354             KdPrint(( "LDR: Unable to unprotect IAT for %wZ (Image Base %x)\n",
    02355                       &LdrDataTableEntry_Import->BaseDllName,
    02356                       LdrDataTableEntry_Import->DllBase
    02357                    ));
    02358             return STATUS_INVALID_IMAGE_FORMAT;
    02359             }
    02360         IATSize = LittleIATSize;
    02361         }
    02362
    02363     st = NtProtectVirtualMemory( NtCurrentProcess(),
    02364                                  &IATBase,
    02365                                  &IATSize,
    02366                                  PAGE_READWRITE,
    02367                                  &OldProtect
    02368                                );
    02369     if (!NT_SUCCESS(st)) {
    02370         KdPrint(( "LDR: Unable to unprotect IAT for %wZ (Status %x)\n",
    02371                   &LdrDataTableEntry_Import->BaseDllName,
    02372                   st
    02373                ));
    02374         return st;
    02375         }
    02376
    02377     //
    02378     // If just snapping forwarded entries, walk that list
    02379     //
    02380     if (SnapForwardersOnly) {
    02381         ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + ImportDescriptor->Name);
    02382         ForwarderChain = ImportDescriptor->ForwarderChain;
    02383         while (ForwarderChain != -1) {
    02384             OriginalThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase +
    02385                             ImportDescriptor->OriginalFirstThunk +
    02386                             (ForwarderChain * sizeof(IMAGE_THUNK_DATA)));
    02387             Thunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase +
    02388                             ImportDescriptor->FirstThunk +
    02389                             (ForwarderChain * sizeof(IMAGE_THUNK_DATA)));
    02390             ForwarderChain = (ULONG) Thunk->u1.Ordinal;
    02391             try {
    02392                 st = LdrpSnapThunk(LdrDataTableEntry_Export->DllBase,
    02393                         LdrDataTableEntry_Import->DllBase,
    02394                         OriginalThunk,
    02395                         Thunk,
    02396                         ExportDirectory,
    02397                         ExportSize,
    02398                         TRUE,
    02399                         ImportName
    02400                         );
    02401                 Thunk++;
    02402                 }
    02403             except (EXCEPTION_EXECUTE_HANDLER) {
    02404                 st = GetExceptionCode();
    02405                 }
    02406             if (!NT_SUCCESS(st) ) {
    02407                 break;
    02408                 }
    02409             }
    02410         }
    02411     else
    02412
    02413     //
    02414     // Otherwise, walk through the IAT and snap all the thunks.
    02415     //
    02416
    02417     if ( ImportDescriptor->FirstThunk ) {
    02418         Thunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + ImportDescriptor->FirstThunk);
    02419
    02420         NtHeaders = RtlImageNtHeader( LdrDataTableEntry_Import->DllBase );
    02421         //
    02422         // If the OriginalFirstThunk field does not point inside the image, then ignore
    02423         // it.  This is will detect bogus Borland Linker 2.25 images that did not fill
    02424         // this field in.
    02425         //
    02426
    02427         if (ImportDescriptor->Characteristics < NtHeaders->OptionalHeader.SizeOfHeaders ||
    02428             ImportDescriptor->Characteristics >= NtHeaders->OptionalHeader.SizeOfImage
    02429            ) {
    02430             OriginalThunk = Thunk;
    02431         } else {
    02432             OriginalThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase +
    02433                             ImportDescriptor->OriginalFirstThunk);
    02434         }
    02435         ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + ImportDescriptor->Name);
    02436         while (OriginalThunk->u1.AddressOfData) {
    02437             try {
    02438                 st = LdrpSnapThunk(LdrDataTableEntry_Export->DllBase,
    02439                         LdrDataTableEntry_Import->DllBase,
    02440                         OriginalThunk,
    02441                         Thunk,
    02442                         ExportDirectory,
    02443                         ExportSize,
    02444                         TRUE,
    02445                         ImportName
    02446                         );
    02447                 OriginalThunk++;
    02448                 Thunk++;
    02449                 }
    02450             except (EXCEPTION_EXECUTE_HANDLER) {
    02451                 st = GetExceptionCode();
    02452                 }
    02453
    02454             if (!NT_SUCCESS(st) ) {
    02455                 break;
    02456                 }
    02457             }
    02458         }
    02459
    02460     //
    02461     // Restore protection for IAT and flush instruction cache.
    02462     //
    02463
    02464     NtProtectVirtualMemory( NtCurrentProcess(),
    02465                             &IATBase,
    02466                             &IATSize,
    02467                             OldProtect,
    02468                             &OldProtect
    02469                           );
    02470     NtFlushInstructionCache( NtCurrentProcess(), IATBase, LittleIATSize );
    02471
    02472     return st;
    02473 }

NTSTATUS LdrpSnapLinksToDllHandle | ( | IN PVOID | DllHandle,
|  | IN ULONG | NumberOfThunks,
|  | IN OUT PIMAGE_THUNK_DATA | FirstThunk
| ) |

NTSTATUS LdrpSnapThunk | ( | IN PVOID | DllBase,
|  | IN PVOID | ImageBase,
|  | IN PIMAGE_THUNK_DATA | OriginalThunk,
|  | IN OUT PIMAGE_THUNK_DATA | Thunk,
|  | IN PIMAGE_EXPORT_DIRECTORY | ExportDirectory,
|  | IN ULONG | ExportSize,
|  | IN BOOLEAN | StaticSnap,
|  | IN PSZ DllName | OPTIONAL
| ) |

Definition at line 2476 of file ldrsnap.c.

References DbgPrint, FALSE, LDRP_BAD_DLL, LdrpFatalHardErrorCount, LdrpGetProcedureAddress(), LdrpInLdrInit, LdrpLoadDll(), LdrpNameToOrdinal(), NT_SUCCESS, NtRaiseHardError(), NTSTATUS(), NULL, PAGE_SIZE, PUSHORT, RtlAnsiStringToUnicodeString(), RtlCharToInteger(), RtlFreeUnicodeString(), RtlImageNtHeader(), RtlInitAnsiString(), RtlRaiseStatus(), ShowSnaps, TRUE, and USHORT.

Referenced by LdrpGetProcedureAddress(), and LdrpSnapIAT().

    02489                    :
    02490
    02491     This function snaps a thunk using the specified Export Section data.
    02492     If the section data does not support the thunk, then the thunk is
    02493     partially snapped (Dll field is still non-null, but snap address is
    02494     set).
    02495
    02496 Arguments:
    02497
    02498     DllBase - Base of Dll.
    02499
    02500     ImageBase - Base of image that contains the thunks to snap.
    02501
    02502     Thunk - On input, supplies the thunk to snap.  When successfully
    02503         snapped, the function field is set to point to the address in
    02504         the DLL, and the DLL field is set to NULL.
    02505
    02506     ExportDirectory - Supplies the Export Section data from a DLL.
    02507
    02508     StaticSnap - If TRUE, then loader is attempting a static snap,
    02509                  and any ordinal/name lookup failure will be reported.
    02510
    02511 Return Value:
    02512
    02513     STATUS_SUCCESS or STATUS_PROCEDURE_NOT_FOUND
    02514
    02515 --*/
    02516
    02517 {
    02518     BOOLEAN Ordinal;
    02519     USHORT OrdinalNumber;
    02520     ULONG OriginalOrdinalNumber;
    02521     PIMAGE_IMPORT_BY_NAME AddressOfData;
    02522     PULONG NameTableBase;
    02523     PUSHORT NameOrdinalTableBase;
    02524     PULONG Addr;
    02525     USHORT HintIndex;
    02526     NTSTATUS st;
    02527     PSZ ImportString;
    02528
    02529     //
    02530     // Determine if snap is by name, or by ordinal
    02531     //
    02532
    02533     Ordinal = (BOOLEAN)IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal);
    02534
    02535     if (Ordinal) {
    02536         OriginalOrdinalNumber = (ULONG)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal);
    02537         OrdinalNumber = (USHORT)(OriginalOrdinalNumber - ExportDirectory->Base);
    02538     } else {
    02539              //
    02540              // Change AddressOfData from an RVA to a VA.
    02541              //
    02542
    02543              AddressOfData = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)ImageBase + ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff));
    02544              ImportString = (PSZ)AddressOfData->Name;
    02545
    02546              //
    02547              // Lookup Name in NameTable
    02548              //
    02549
    02550              NameTableBase = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
    02551              NameOrdinalTableBase = (PUSHORT)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
    02552
    02553              //
    02554              // Before dropping into binary search, see if
    02555              // the hint index results in a successful
    02556              // match. If the hint index is zero, then
    02557              // drop into binary search.
    02558              //
    02559
    02560              HintIndex = AddressOfData->Hint;
    02561              if ((ULONG)HintIndex < ExportDirectory->NumberOfNames &&
    02562                  !strcmp(ImportString, (PSZ)((ULONG_PTR)DllBase + NameTableBase[HintIndex]))) {
    02563                  OrdinalNumber = NameOrdinalTableBase[HintIndex];
    02564 #if LDRDBG
    02565                  if (ShowSnaps) {
    02566                      DbgPrint("LDR: Snapping %s\n", ImportString);
    02567                  }
    02568 #endif
    02569              } else {
    02570 #if LDRDBG
    02571                       if (HintIndex) {
    02572                           DbgPrint("LDR: Warning HintIndex Failure. Name %s (%lx) Hint 0x%lx\n",
    02573                               ImportString,
    02574                               (ULONG)ImportString,
    02575                               (ULONG)HintIndex
    02576                               );
    02577                       }
    02578 #endif
    02579                       OrdinalNumber = LdrpNameToOrdinal(
    02580                                         ImportString,
    02581                                         ExportDirectory->NumberOfNames,
    02582                                         DllBase,
    02583                                         NameTableBase,
    02584                                         NameOrdinalTableBase
    02585                                         );
    02586                     }
    02587            }
    02588
    02589     //
    02590     // If OrdinalNumber is not within the Export Address Table,
    02591     // then DLL does not implement function. Snap to LDRP_BAD_DLL.
    02592     //
    02593
    02594     if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
    02595 baddllref:
    02596 #if DBG
    02597         if (StaticSnap) {
    02598             if (Ordinal) {
    02599                 DbgPrint("LDR: Can't locate ordinal 0x%lx\n", OriginalOrdinalNumber);
    02600                 }
    02601             else {
    02602                 DbgPrint("LDR: Can't locate %s\n", ImportString);
    02603                 }
    02604         }
    02605 #endif
    02606         if ( StaticSnap ) {
    02607             //
    02608             // Hard Error Time
    02609             //
    02610
    02611             ULONG_PTR ErrorParameters[3];
    02612             UNICODE_STRING ErrorDllName, ErrorEntryPointName;
    02613             ANSI_STRING AnsiScratch;
    02614             ULONG ParameterStringMask;
    02615             ULONG ErrorResponse;
    02616
    02617             RtlInitAnsiString(&AnsiScratch,DllName ? DllName : "Unknown");
    02618             RtlAnsiStringToUnicodeString(&ErrorDllName,&AnsiScratch,TRUE);
    02619             ErrorParameters[1] = (ULONG_PTR)&ErrorDllName;
    02620             ParameterStringMask = 2;
    02621
    02622             if ( Ordinal ) {
    02623                 ErrorParameters[0] = OriginalOrdinalNumber;
    02624                 }
    02625             else {
    02626                 RtlInitAnsiString(&AnsiScratch,ImportString);
    02627                 RtlAnsiStringToUnicodeString(&ErrorEntryPointName,&AnsiScratch,TRUE);
    02628                 ErrorParameters[0] = (ULONG_PTR)&ErrorEntryPointName;
    02629                 ParameterStringMask = 3;
    02630                 }
    02631
    02632
    02633             NtRaiseHardError(
    02634               Ordinal ? STATUS_ORDINAL_NOT_FOUND : STATUS_ENTRYPOINT_NOT_FOUND,
    02635               2,
    02636               ParameterStringMask,
    02637               ErrorParameters,
    02638               OptionOk,
    02639               &ErrorResponse
    02640               );
    02641
    02642             if ( LdrpInLdrInit ) {
    02643                 LdrpFatalHardErrorCount++;
    02644                 }
    02645             RtlFreeUnicodeString(&ErrorDllName);
    02646             if ( !Ordinal ) {
    02647                 RtlFreeUnicodeString(&ErrorEntryPointName);
    02648                 RtlRaiseStatus(STATUS_ENTRYPOINT_NOT_FOUND);
    02649                 }
    02650             RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND);
    02651             }
    02652         Thunk->u1.Function = (ULONG_PTR)LDRP_BAD_DLL;
    02653         st = Ordinal ? STATUS_ORDINAL_NOT_FOUND : STATUS_ENTRYPOINT_NOT_FOUND;
    02654     } else {
    02655              Addr = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
    02656              Thunk->u1.Function = ((ULONG_PTR)DllBase + Addr[OrdinalNumber]);
    02657              if (Thunk->u1.Function > (ULONG_PTR)ExportDirectory &&
    02658                  Thunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)
    02659                 ) {
    02660                 UNICODE_STRING UnicodeString;
    02661                 ANSI_STRING ForwardDllName;
    02662                 PVOID ForwardDllHandle;
    02663                 PUNICODE_STRING ForwardProcName;
    02664                 ULONG ForwardProcOrdinal;
    02665
    02666                 ImportString = (PSZ)Thunk->u1.Function;
    02667                 ForwardDllName.Buffer = ImportString,
    02668                 ForwardDllName.Length = (USHORT)(strchr(ImportString, '.') - ImportString);
    02669                 ForwardDllName.MaximumLength = ForwardDllName.Length;
    02670                 st = RtlAnsiStringToUnicodeString(&UnicodeString, &ForwardDllName, TRUE);
    02671
    02672                 if (NT_SUCCESS(st)) {
    02673 #if defined (WX86)
    02674                     if (Wx86ProcessInit) {
    02675                         NtCurrentTeb()->Wx86Thread.UseKnownWx86Dll = RtlImageNtHeader(DllBase)->FileHeader.Machine
    02676                                                    == IMAGE_FILE_MACHINE_I386;
    02677
    02678                         }
    02679 #endif
    02680
    02681
    02682                         st = LdrpLoadDll(NULL, NULL, &UnicodeString, &ForwardDllHandle,FALSE);
    02683                     RtlFreeUnicodeString(&UnicodeString);
    02684                     }
    02685
    02686                 if (!NT_SUCCESS(st)) {
    02687                     goto baddllref;
    02688                     }
    02689
    02690                 RtlInitAnsiString( &ForwardDllName,
    02691                                    ImportString + ForwardDllName.Length + 1
    02692                                  );
    02693                 if (ForwardDllName.Length > 1 &&
    02694                     *ForwardDllName.Buffer == '#'
    02695                    ) {
    02696                     ForwardProcName = NULL;
    02697                     st = RtlCharToInteger( ForwardDllName.Buffer+1,
    02698                                            0,
    02699                                            &ForwardProcOrdinal
    02700                                          );
    02701                     if (!NT_SUCCESS(st)) {
    02702                         goto baddllref;
    02703                         }
    02704                     }
    02705                 else {
    02706                     ForwardProcName = (PUNICODE_STRING)&ForwardDllName;
    02707
    02708                     //
    02709                     // Following line is not needed since this is a by name lookup
    02710                     //
    02711                     //
    02712                     //ForwardProcOrdinal = (ULONG)&ForwardDllName;
    02713                     //
    02714                     }
    02715
    02716                 st = LdrpGetProcedureAddress( ForwardDllHandle,
    02717                                               (PANSI_STRING )ForwardProcName,
    02718                                               ForwardProcOrdinal,
    02719                                               &(PVOID)Thunk->u1.Function,
    02720                                               FALSE
    02721                                             );
    02722                 if (!NT_SUCCESS(st)) {
    02723                     goto baddllref;
    02724                     }
    02725                 }
    02726              else {
    02727                 if ( !Addr[OrdinalNumber] ) {
    02728                     goto baddllref;
    02729                     }
    02730 #if defined (_ALPHA_) && defined (WX86)
    02731                 else {
    02732                    PIMAGE_NT_HEADERS ExportNtHeaders = RtlImageNtHeader(DllBase);
    02733
    02734                    if ((ExportNtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) &&
    02735                        (ExportNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)) {
    02736                        Thunk->u1.Function += LdrpWx86RelocatedFixupDiff(DllBase, Addr[OrdinalNumber]);
    02737                     }
    02738                 }
    02739 #endif //  defined (_ALPHA_) && defined (WX86)
    02740              }
    02741              st = STATUS_SUCCESS;
    02742            }
    02743     return st;
    02744 }

VOID LdrpUpdateLoadCount | ( | IN PLDR_DATA_TABLE_ENTRY | LdrDataTableEntry,
|  | IN BOOLEAN | IncrementCount
| ) |

Definition at line 2802 of file ldrsnap.c.

References DbgPrint, FALSE, LdrpCheckForLoadedDll(), NT_SUCCESS, NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlInitAnsiString(), ShowSnaps, and TRUE.

    02809                    :
    02810
    02811     This function dereferences a loaded DLL adjusting its reference
    02812     count.  It then dereferences each dll referenced by this dll.
    02813
    02814 Arguments:
    02815
    02816     LdrDataTableEntry - Supplies the address of the DLL to dereference
    02817
    02818     IncrementCount - TRUE if adding one to LoadCount, O.W. subtracting one
    02819
    02820 Return Value:
    02821
    02822     None.
    02823
    02824 --*/
    02825
    02826 {
    02827     PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
    02828     PIMAGE_BOUND_IMPORT_DESCRIPTOR NewImportDescriptor;
    02829     PIMAGE_BOUND_FORWARDER_REF NewImportForwarder;
    02830     PSZ ImportName, NewImportStringBase;
    02831     ULONG i, ImportSize, NewImportSize;
    02832     ANSI_STRING AnsiString;
    02833     PUNICODE_STRING ImportDescriptorName_U;
    02834     PLDR_DATA_TABLE_ENTRY Entry;
    02835     NTSTATUS st;
    02836     BOOLEAN Wx86KnownDll = FALSE;
    02837     PIMAGE_THUNK_DATA FirstThunk;
    02838
    02839     if (IncrementCount)
    02840         if (LdrDataTableEntry->Flags & LDRP_LOAD_IN_PROGRESS) {
    02841             return;
    02842         } else {
    02843             LdrDataTableEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
    02844         }
    02845     else
    02846         if (LdrDataTableEntry->Flags & LDRP_UNLOAD_IN_PROGRESS) {
    02847             return;
    02848         } else {
    02849             LdrDataTableEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
    02850         }
    02851
    02852     //
    02853     // For each DLL used by this DLL, reference or dereference the DLL.
    02854     //
    02855
    02856     ImportDescriptorName_U = &NtCurrentTeb()->StaticUnicodeString;
    02857
    02858 #if defined (WX86)
    02859     if (Wx86ProcessInit) {
    02860         Wx86KnownDll = RtlImageNtHeader(LdrDataTableEntry->DllBase)->FileHeader.Machine
    02861                            == IMAGE_FILE_MACHINE_I386;
    02862         }
    02863 #endif
    02864
    02865
    02866
    02867
    02868     //
    02869     // See if there is a bound import table.  If so, walk that to
    02870     // determine DLL names to reference or dereference.  Avoids touching
    02871     // the .idata section
    02872     //
    02873     NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(
    02874                            LdrDataTableEntry->DllBase,
    02875                            TRUE,
    02876                            IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
    02877                            &NewImportSize
    02878                            );
    02879     if (NewImportDescriptor) {
    02880         if (IncrementCount) {
    02881             LdrDataTableEntry->Flags |= LDRP_LOAD_IN_PROGRESS;
    02882         } else {
    02883             LdrDataTableEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS;
    02884         }
    02885
    02886         NewImportStringBase = (LPSTR)NewImportDescriptor;
    02887         while (NewImportDescriptor->OffsetModuleName) {
    02888             ImportName = NewImportStringBase +
    02889                          NewImportDescriptor->OffsetModuleName;
    02890             RtlInitAnsiString(&AnsiString, ImportName);
    02891             st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE);
    02892             if ( NT_SUCCESS(st) ) {
    02893                 if (LdrpCheckForLoadedDll( NULL,
    02894                                            ImportDescriptorName_U,
    02895                                            TRUE,
    02896                                            Wx86KnownDll,
    02897                                            &Entry
    02898                                          )
    02899                    ) {
    02900                     if ( Entry->LoadCount != 0xffff ) {
    02901                         if (IncrementCount) {
    02902                             Entry->LoadCount++;
    02903
    02904                             if (ShowSnaps) {
    02905                                 DbgPrint("LDR: Refcount   %wZ (%lx)\n",
    02906                                         ImportDescriptorName_U,
    02907                                         (ULONG)Entry->LoadCount
    02908                                         );
    02909                             }
    02910                         } else {
    02911                             Entry->LoadCount--;
    02912
    02913                             if (ShowSnaps) {
    02914                                 DbgPrint("LDR: Derefcount   %wZ (%lx)\n",
    02915                                         ImportDescriptorName_U,
    02916                                         (ULONG)Entry->LoadCount
    02917                                         );
    02918                             }
    02919                         }
    02920                     }
    02921                     LdrpUpdateLoadCount(Entry, IncrementCount);
    02922                 }
    02923             }
    02924
    02925             NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(NewImportDescriptor+1);
    02926             for (i=0; i<NewImportDescriptor->NumberOfModuleForwarderRefs; i++) {
    02927                 ImportName = NewImportStringBase +
    02928                              NewImportForwarder->OffsetModuleName;
    02929
    02930                 RtlInitAnsiString(&AnsiString, ImportName);
    02931                 st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE);
    02932                 if ( NT_SUCCESS(st) ) {
    02933                     if (LdrpCheckForLoadedDll( NULL,
    02934                                                ImportDescriptorName_U,
    02935                                                TRUE,
    02936                                                Wx86KnownDll,
    02937                                                &Entry
    02938                                              )
    02939                        ) {
    02940                         if ( Entry->LoadCount != 0xffff ) {
    02941                             if (IncrementCount) {
    02942                                 Entry->LoadCount++;
    02943
    02944                                 if (ShowSnaps) {
    02945                                     DbgPrint("LDR: Refcount   %wZ (%lx)\n",
    02946                                             ImportDescriptorName_U,
    02947                                             (ULONG)Entry->LoadCount
    02948                                             );
    02949                                 }
    02950                             } else {
    02951                                 Entry->LoadCount--;
    02952
    02953                                 if (ShowSnaps) {
    02954                                     DbgPrint("LDR: Derefcount   %wZ (%lx)\n",
    02955                                             ImportDescriptorName_U,
    02956                                             (ULONG)Entry->LoadCount
    02957                                             );
    02958                                 }
    02959                             }
    02960                         }
    02961                         LdrpUpdateLoadCount(Entry, IncrementCount);
    02962                     }
    02963                 }
    02964
    02965                 NewImportForwarder += 1;
    02966             }
    02967
    02968             NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder;
    02969         }
    02970
    02971         return;
    02972     }
    02973
    02974     ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(
    02975                         LdrDataTableEntry->DllBase,
    02976                         TRUE,
    02977                         IMAGE_DIRECTORY_ENTRY_IMPORT,
    02978                         &ImportSize
    02979                         );
    02980     if (ImportDescriptor) {
    02981
    02982         while (ImportDescriptor->Name && ImportDescriptor->FirstThunk) {
    02983
    02984             //
    02985             // Match code in walk that skips references like this. IE3 had
    02986             // some dll's with these bogus links to url.dll. On load, the url.dll
    02987             // ref was skipped. On unload, it was not skipped because
    02988             // this code was missing.
    02989             //
    02990             // Since the skip logic is only in the old style import
    02991             // descriptor path, it is only duplicated here.
    02992             //
    02993             // check for import that has no references
    02994             //
    02995             FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->FirstThunk);
    02996             if ( !FirstThunk->u1.Function ) {
    02997                 goto skipskippedimport;
    02998                 }
    02999
    03000             ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name);
    03001
    03002             RtlInitAnsiString(&AnsiString, ImportName);
    03003             st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE);
    03004             if ( NT_SUCCESS(st) ) {
    03005                 if (LdrpCheckForLoadedDll( NULL,
    03006                                            ImportDescriptorName_U,
    03007                                            TRUE,
    03008                                            Wx86KnownDll,
    03009                                            &Entry
    03010                                          )
    03011                    ) {
    03012                     if ( Entry->LoadCount != 0xffff ) {
    03013                         if (IncrementCount) {
    03014                             Entry->LoadCount++;
    03015
    03016                             if (ShowSnaps) {
    03017                                 DbgPrint("LDR: Refcount   %wZ (%lx)\n",
    03018                                         ImportDescriptorName_U,
    03019                                         (ULONG)Entry->LoadCount
    03020                                         );
    03021                             }
    03022                         } else {
    03023                             Entry->LoadCount--;
    03024
    03025                             if (ShowSnaps) {
    03026                                 DbgPrint("LDR: Derefcount   %wZ (%lx)\n",
    03027                                         ImportDescriptorName_U,
    03028                                         (ULONG)Entry->LoadCount
    03029                                         );
    03030                             }
    03031                         }
    03032                     }
    03033                     LdrpUpdateLoadCount(Entry, IncrementCount);
    03034                 }
    03035             }
    03036 skipskippedimport:
    03037             ++ImportDescriptor;
    03038         }
    03039     }
    03040 }

NTSTATUS LdrpWalkImportDescriptor | ( | IN PWSTR DllPath | OPTIONAL,
|  | IN PLDR_DATA_TABLE_ENTRY | LdrDataTableEntry
| ) |

Definition at line 214 of file ldrsnap.c.

References DbgPrint, FALSE, LdrpDefineDllTag(), LdrpDphInitializeTargetDll(), LdrpLoadImportModule(), LdrpSnapIAT(), Name, NT_SUCCESS, NtProtectVirtualMemory(), NTSTATUS(), NULL, PAGE_SIZE, RtlAllocateHeap, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), ShowSnaps, TRUE, and USHORT.

    00221                    :
    00222
    00223     This is a recursive routine which walks the Import Descriptor
    00224     Table and loads each DLL that is referenced.
    00225
    00226 Arguments:
    00227
    00228     DllPath - Supplies an optional search path to be used to locate
    00229         the DLL.
    00230
    00231     LdrDataTableEntry - Supplies the address of the data table entry
    00232         to initialize.
    00233
    00234 Return Value:
    00235
    00236     Status value.
    00237
    00238 --*/
    00239
    00240 {
    00241     ULONG i, ImportSize, NewImportSize;
    00242     BOOLEAN AlreadyLoaded, SnapForwardersOnly, StaleBinding;
    00243     PLDR_DATA_TABLE_ENTRY DataTableEntry, FwdDataTableEntry;
    00244     PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
    00245     PIMAGE_BOUND_IMPORT_DESCRIPTOR NewImportDescriptor;
    00246     PIMAGE_BOUND_FORWARDER_REF NewImportForwarder;
    00247     PSZ ImportName, NewImportName, NewFwdImportName, NewImportStringBase;
    00248     NTSTATUS st;
    00249     PIMAGE_NT_HEADERS ExportNtHeaders;
    00250     PVOID ImportBase;
    00251     ULONG RegionSize;
    00252     PIMAGE_THUNK_DATA Thunk,Name;
    00253     PIMAGE_THUNK_DATA FirstThunk;
    00254     PPEB Peb = NtCurrentPeb();
    00255
    00256     //
    00257     // See if there is a bound import table.  If so, walk that to
    00258     // verify if the binding is good.  If so, then succeed with
    00259     // having touched the .idata section, as all the information
    00260     // in the bound imports table is stored in the header.  If any
    00261     // are stale, then fall out into the unbound case.
    00262     //
    00263     NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(
    00264                            LdrDataTableEntry->DllBase,
    00265                            TRUE,
    00266                            IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
    00267                            &NewImportSize
    00268                            );
    00269
    00270     ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(
    00271                         LdrDataTableEntry->DllBase,
    00272                         TRUE,
    00273                         IMAGE_DIRECTORY_ENTRY_IMPORT,
    00274                         &ImportSize
    00275                         );
    00276
    00277
    00278     if (NewImportDescriptor) {
    00279         NewImportStringBase = (LPSTR)NewImportDescriptor;
    00280         while (NewImportDescriptor->OffsetModuleName) {
    00281             NewImportName = NewImportStringBase +
    00282                          NewImportDescriptor->OffsetModuleName;
    00283
    00284             if (ShowSnaps) {
    00285                 DbgPrint("LDR: %wZ bound to %s\n",
    00286                     &LdrDataTableEntry->BaseDllName,
    00287                     NewImportName
    00288                     );
    00289             }
    00290
    00291             st = LdrpLoadImportModule( DllPath,
    00292                                        NewImportName,
    00293                                        LdrDataTableEntry->DllBase,
    00294                                        &DataTableEntry,
    00295                                        &AlreadyLoaded
    00296                                        );
    00297             if ( !NT_SUCCESS(st) ) {
    00298                 return st;
    00299             }
    00300
    00301             //
    00302             // Add to initialization list.
    00303             //
    00304
    00305             if (!AlreadyLoaded) {
    00306                 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
    00307                                &DataTableEntry->InInitializationOrderLinks);
    00308             }
    00309
    00310 #if defined (_ALPHA_) && defined (WX86)
    00311             ExportNtHeaders = RtlImageNtHeader(LdrDataTableEntry->DllBase);
    00312
    00313             if ((ExportNtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) &&
    00314                 (ExportNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)) {
    00315                 if (LdrpWx86DllHasRelocatedSharedSection(LdrDataTableEntry->DllBase)) {
    00316                    DataTableEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
    00317                 }
    00318             }
    00319 #endif // defined (_ALPHA_) && defined (WX86)
    00320
    00321             if ( NewImportDescriptor->TimeDateStamp != DataTableEntry->TimeDateStamp ||
    00322                  (DataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE) ) {
    00323                 if (ShowSnaps) {
    00324                     DbgPrint("LDR: %wZ has stale binding to %s\n",
    00325                             &LdrDataTableEntry->BaseDllName,
    00326                             NewImportName
    00327                             );
    00328                 }
    00329                 StaleBinding = TRUE;
    00330             } else {
    00331 #if DBG
    00332                 LdrpSnapBypass++;
    00333 #endif
    00334                 if (ShowSnaps) {
    00335                     DbgPrint("LDR: %wZ has correct binding to %s\n",
    00336                             &LdrDataTableEntry->BaseDllName,
    00337                             NewImportName
    00338                             );
    00339                 }
    00340                 StaleBinding = FALSE;
    00341             }
    00342
    00343             NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(NewImportDescriptor+1);
    00344             for (i=0; i<NewImportDescriptor->NumberOfModuleForwarderRefs; i++) {
    00345                 NewFwdImportName = NewImportStringBase +
    00346                                 NewImportForwarder->OffsetModuleName;
    00347                 if (ShowSnaps) {
    00348                     DbgPrint("LDR: %wZ bound to %s via forwarder(s) from %wZ\n",
    00349                         &LdrDataTableEntry->BaseDllName,
    00350                         NewFwdImportName,
    00351                         &DataTableEntry->BaseDllName
    00352                         );
    00353                 }
    00354
    00355                 st = LdrpLoadImportModule( DllPath,
    00356                                            NewFwdImportName,
    00357                                            LdrDataTableEntry->DllBase,
    00358                                            &FwdDataTableEntry,
    00359                                            &AlreadyLoaded
    00360                                            );
    00361                 if ( NT_SUCCESS(st) ) {
    00362                     if (!AlreadyLoaded) {
    00363                         InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
    00364                                        &FwdDataTableEntry->InInitializationOrderLinks);
    00365                         }
    00366                     }
    00367
    00368                 if ( !NT_SUCCESS(st) ||
    00369                      NewImportForwarder->TimeDateStamp != FwdDataTableEntry->TimeDateStamp ||
    00370                      (FwdDataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE ) ) {
    00371                     if (ShowSnaps) {
    00372                         DbgPrint("LDR: %wZ has stale binding to %s\n",
    00373                                 &LdrDataTableEntry->BaseDllName,
    00374                                 NewFwdImportName
    00375                                 );
    00376                     }
    00377                     StaleBinding = TRUE;
    00378                 } else {
    00379 #if DBG
    00380                     LdrpSnapBypass++;
    00381 #endif
    00382                     if (ShowSnaps) {
    00383                         DbgPrint("LDR: %wZ has correct binding to %s\n",
    00384                                 &LdrDataTableEntry->BaseDllName,
    00385                                 NewFwdImportName
    00386                                 );
    00387                     }
    00388                 }
    00389
    00390                 NewImportForwarder += 1;
    00391             }
    00392             NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder;
    00393
    00394             if (StaleBinding) {
    00395 #if DBG
    00396                 LdrpNormalSnap++;
    00397 #endif
    00398                 //
    00399                 // Find the unbound import descriptor that matches this bound
    00400                 // import descriptor
    00401                 //
    00402
    00403                 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(
    00404                                     LdrDataTableEntry->DllBase,
    00405                                     TRUE,
    00406                                     IMAGE_DIRECTORY_ENTRY_IMPORT,
    00407                                     &ImportSize
    00408                                     );
    00409
    00410                 while (ImportDescriptor->Name) {
    00411                     ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name);
    00412                     if (!_stricmp(ImportName, NewImportName)) {
    00413                         break;
    00414                     }
    00415
    00416                     ImportDescriptor += 1;
    00417                 }
    00418
    00419                 if (!ImportDescriptor->Name) {
    00420                     return STATUS_OBJECT_NAME_INVALID;
    00421                 }
    00422
    00423                 if (ShowSnaps) {
    00424                     DbgPrint("LDR: Stale Bind %s from %wZ\n",ImportName,&LdrDataTableEntry->BaseDllName);
    00425                 }
    00426
    00427                 st = LdrpSnapIAT(
    00428                         DataTableEntry,
    00429                         LdrDataTableEntry,
    00430                         ImportDescriptor,
    00431                         FALSE
    00432                         );
    00433
    00434                 if (!NT_SUCCESS(st)) {
    00435                     return st;
    00436                 }
    00437             }
    00438         }
    00439     }
    00440     else
    00441     if (ImportDescriptor) {
    00442         //
    00443         // For each DLL used by this DLL, load the dll. Then snap
    00444         // the IAT, and call the DLL's init routine.
    00445         //
    00446
    00447         while (ImportDescriptor->Name && ImportDescriptor->FirstThunk) {
    00448             ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name);
    00449
    00450             //
    00451             // check for import that has no references
    00452             //
    00453             FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->FirstThunk);
    00454             if ( !FirstThunk->u1.Function ) {
    00455                 goto skipimport;
    00456                 }
    00457
    00458             if (ShowSnaps) {
    00459                 DbgPrint("LDR: %s used by %wZ\n",
    00460                     ImportName,
    00461                     &LdrDataTableEntry->BaseDllName
    00462                     );
    00463             }
    00464
    00465
    00466             st = LdrpLoadImportModule( DllPath,
    00467                                        ImportName,
    00468                                        LdrDataTableEntry->DllBase,
    00469                                        &DataTableEntry,
    00470                                        &AlreadyLoaded
    00471                                        );
    00472             if ( !NT_SUCCESS(st) ) {
    00473                 return st;
    00474             }
    00475
    00476             if (ShowSnaps) {
    00477                 DbgPrint("LDR: Snapping imports for %wZ from %s\n",
    00478                         &LdrDataTableEntry->BaseDllName,
    00479                         ImportName
    00480                         );
    00481             }
    00482
    00483             //
    00484             // If the image has been bound and the import date stamp
    00485             // matches the date time stamp in the export modules header,
    00486             // and the image was mapped at it's prefered base address,
    00487             // then we are done.
    00488             //
    00489
    00490             SnapForwardersOnly = FALSE;
    00491
    00492             if ( ImportDescriptor->OriginalFirstThunk ) {
    00493                 if ( ImportDescriptor->TimeDateStamp &&
    00494                      ImportDescriptor->TimeDateStamp == DataTableEntry->TimeDateStamp &&
    00495                      (! DataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE) ) {
    00496 #if DBG
    00497                     LdrpSnapBypass++;
    00498 #endif
    00499                     if (ShowSnaps) {
    00500                         DbgPrint("LDR: Snap bypass %s from %wZ\n",
    00501                             ImportName,
    00502                             &LdrDataTableEntry->BaseDllName
    00503                             );
    00504                     }
    00505
    00506                     if (ImportDescriptor->ForwarderChain == -1) {
    00507                         goto bypass_snap;
    00508                         }
    00509
    00510                     SnapForwardersOnly = TRUE;
    00511
    00512                     }
    00513             }
    00514 #if DBG
    00515             LdrpNormalSnap++;
    00516 #endif
    00517             //
    00518             // Add to initialization list.
    00519             //
    00520
    00521             if (!AlreadyLoaded) {
    00522                 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
    00523                                &DataTableEntry->InInitializationOrderLinks);
    00524             }
    00525             st = LdrpSnapIAT(
    00526                     DataTableEntry,
    00527                     LdrDataTableEntry,
    00528                     ImportDescriptor,
    00529                     SnapForwardersOnly
    00530                     );
    00531
    00532             if (!NT_SUCCESS(st)) {
    00533                 return st;
    00534             }
    00535             AlreadyLoaded = TRUE;
    00536 bypass_snap:
    00537             //
    00538             // Add to initialization list.
    00539             //
    00540
    00541             if (!AlreadyLoaded) {
    00542                 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
    00543                                &DataTableEntry->InInitializationOrderLinks);
    00544             }
    00545
    00546 skipimport:
    00547             ++ImportDescriptor;
    00548         }
    00549     }
    00550
    00551     if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAG_BY_DLL) {
    00552         PVOID IATBase;
    00553         SIZE_T BigIATSize;
    00554         ULONG  LittleIATSize;
    00555         PVOID *ProcAddresses;
    00556         ULONG NumberOfProcAddresses;
    00557         ULONG OldProtect;
    00558         USHORT TagIndex;
    00559
    00560         //
    00561         // Determine the location and size of the IAT.  If found, scan the
    00562         // IAT address to see if any are pointing to RtlAllocateHeap.  If so
    00563         // replace when with a pointer to a unique thunk function that will
    00564         // replace the tag with a unique tag for this image.
    00565         //
    00566
    00567         IATBase = RtlImageDirectoryEntryToData( LdrDataTableEntry->DllBase,
    00568                                                 TRUE,
    00569                                                 IMAGE_DIRECTORY_ENTRY_IAT,
    00570                                                 &LittleIATSize
    00571                                               );
    00572         BigIATSize = LittleIATSize;
    00573         if (IATBase != NULL) {
    00574             st = NtProtectVirtualMemory( NtCurrentProcess(),
    00575                                          &IATBase,
    00576                                          &BigIATSize,
    00577                                          PAGE_READWRITE,
    00578                                          &OldProtect
    00579                                        );
    00580             if (!NT_SUCCESS(st)) {
    00581                 DbgPrint( "LDR: Unable to unprotect IAT to enable tagging by DLL.\n" );
    00582             }
    00583             else {
    00584                 ProcAddresses = (PVOID *)IATBase;
    00585                 NumberOfProcAddresses = (ULONG)(BigIATSize / sizeof(PVOID));
    00586                 while (NumberOfProcAddresses--) {
    00587                     if (*ProcAddresses == RtlAllocateHeap) {
    00588                         *ProcAddresses = LdrpDefineDllTag( LdrDataTableEntry->BaseDllName.Buffer, &TagIndex );
    00589                         if (*ProcAddresses == NULL) {
    00590                             *ProcAddresses = RtlAllocateHeap;
    00591                         }
    00592                     }
    00593
    00594                     ProcAddresses += 1;
    00595                 }
    00596
    00597                 NtProtectVirtualMemory( NtCurrentProcess(),
    00598                                         &IATBase,
    00599                                         &BigIATSize,
    00600                                         OldProtect,
    00601                                         &OldProtect
    00602                                       );
    00603             }
    00604         }
    00605     }
    00606
    00607     //
    00608     // Check if we need to redirect some imports in case page heap
    00609     // is enabled and we target specific dlls.
    00610     //
    00611
    00612     if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS) {
    00613
    00614         LdrpDphInitializeTargetDll (LdrDataTableEntry);
    00615     }
    00616
    00617     return STATUS_SUCCESS;
    00618 }

PLIST_ENTRY RtlpLockProcessHeapsList | ( | VOID |  | ) |

BOOLEAN RtlpSerializeHeap | ( | IN PVOID | HeapHandle | ) |

Definition at line 323 of file heapdbg.c.

References FALSE, _HEAP::Flags, _HEAP::ForceFlags, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, Lock, _HEAP::LockVariable, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlInitializeLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapSerialize(), RtlpValidateHeapHeaders(), Status, and TRUE.

Referenced by LdrpInitializeTls().

    00329                    :
    00330
    00331 Arguments:
    00332
    00333 Return Value:
    00334
    00335 --*/
    00336
    00337 {
    00338     NTSTATUS Status;
    00339     PHEAP Heap = (PHEAP)HeapHandle;
    00340     PHEAP_LOCK Lock;
    00341
    00342     IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle,
    00343                                     RtlpDebugPageHeapSerialize( HeapHandle ));
    00344
    00345     //
    00346     //  Validate that HeapAddress points to a HEAP structure.
    00347     //
    00348
    00349     if (!RtlpCheckHeapSignature( Heap, "RtlpSerializeHeap" )) {
    00350
    00351         return FALSE;
    00352     }
    00353
    00354     //
    00355     //  Lock the heap.
    00356     //
    00357
    00358     if (Heap->Flags & HEAP_NO_SERIALIZE) {
    00359
    00360         Lock = RtlAllocateHeap( HeapHandle, HEAP_NO_SERIALIZE, sizeof( *Lock ) );
    00361
    00362         if ( Lock == NULL ) {
    00363
    00364             return FALSE;
    00365         }
    00366
    00367         Status = RtlInitializeLockRoutine( Lock );
    00368
    00369         if (!NT_SUCCESS( Status )) {
    00370
    00371             RtlFreeHeap( HeapHandle, HEAP_NO_SERIALIZE, Lock );
    00372
    00373             return FALSE;
    00374         }
    00375
    00376         Heap->LockVariable = Lock;
    00377         Heap->Flags &= ~HEAP_NO_SERIALIZE;
    00378         Heap->ForceFlags &= ~HEAP_NO_SERIALIZE;
    00379
    00380         RtlpValidateHeapHeaders( Heap, TRUE );
    00381     }
    00382
    00383     return TRUE;
    00384 }

VOID RtlpUnlockProcessHeapsList | ( | VOID |  | ) |

PSZ UnicodeToAnsii | ( | IN PWSTR | String | ) |

BOOLEAN xRtlDosPathNameToNtPathName | ( | IN PSZ | DosFileName,
|  | OUT PSTRING | NtFileName,
|  | OUT PSZ *FilePart | OPTIONAL,
|  | OUT PRTL_RELATIVE_NAME RelativeName | OPTIONAL
| ) |

ULONG xRtlDosSearchPath | ( | PSZ | lpPath,
|  | PSZ | lpFileName,
|  | PSZ | lpExtension,
|  | ULONG | nBufferLength,
|  | PSZ | lpBuffer,
|  | PSZ *lpFilePart | OPTIONAL
| ) |

ULONG xRtlGetFullPathName | ( | PSZ | lpFileName,
|  | ULONG | nBufferLength,
|  | PSZ | lpBuffer,
|  | PSZ *lpFilePart | OPTIONAL
| ) |

## Variable Documentation

RTL_CRITICAL_SECTION FastPebLock

| Definition at line 388 of file ldrp.h. Referenced by LdrpForkProcess(), and LdrpInitializeProcess().

BOOLEAN LdrpActiveUnloadCount

| Definition at line 383 of file ldrp.h. Referenced by LdrUnloadDll().

UNICODE_STRING LdrpDefaultPath

| Definition at line 387 of file ldrp.h. Referenced by LdrpCheckForLoadedDll(), LdrpInitializeProcess(), LdrpMapDll(), and LdrpResolveDllName().

LIST_ENTRY LdrpDefaultPathCache

| Definition at line 168 of file ldrp.h.

ULONG LdrpFatalHardErrorCount

| Definition at line 386 of file ldrp.h. Referenced by LdrpCreateDllSection(), LdrpInitializationFailure(), LdrpMapDll(), and LdrpSnapThunk().

PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache

| Definition at line 384 of file ldrp.h. Referenced by LdrGetDllHandle(), and LdrUnloadDll().

LIST_ENTRY LdrpHashTable[LDRP_HASH_TABLE_SIZE]

| Definition at line 162 of file ldrp.h. Referenced by LdrpCheckForLoadedDll(), LdrpInitializeProcess(), and LdrpInsertMemoryTableEntry().

PLDR_DATA_TABLE_ENTRY LdrpImageEntry

| Definition at line 390 of file ldrp.h. Referenced by LdrpInitializeProcess().

BOOLEAN LdrpImageHasTls

| Definition at line 32 of file ldrp.h. Referenced by LdrpInitializeThread(), LdrpInitializeTls(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), and LdrShutdownThread().

BOOLEAN LdrpInLdrInit

| Definition at line 374 of file ldrp.h. Referenced by LdrDisableThreadCalloutsForDll(), LdrGetDllHandle(), LdrpCreateDllSection(), LdrpGetProcedureAddress(), LdrpInitialize(), LdrpLoadDll(), LdrpMapDll(), LdrpSnapThunk(), LdrQueryProcessModuleInformation(), and LdrUnloadDll().

HANDLE LdrpKnownDllObjectDirectory

| Definition at line 34 of file ldrp.h. Referenced by LdrpCheckForKnownDll(), LdrpInitializeProcess(), and LdrpMapDll().

UNICODE_STRING LdrpKnownDllPath

| Definition at line 37 of file ldrp.h. Referenced by LdrpCheckForKnownDll(), and LdrpInitializeProcess().

WCHAR LdrpKnownDllPathBuffer[LDRP_MAX_KNOWN_PATH]

| Definition at line 36 of file ldrp.h. Referenced by LdrpInitializeProcess().

BOOLEAN LdrpLdrDatabaseIsSetup

| Definition at line 375 of file ldrp.h. Referenced by LdrpInitializeProcess(), and LdrpLoadDll().

PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache

| Definition at line 385 of file ldrp.h. Referenced by LdrpCheckForLoadedDllHandle(), and LdrUnloadDll().

ULONG LdrpNumberOfProcessors

| Definition at line 391 of file ldrp.h. Referenced by LdrpInitializeProcess(), and LdrpMapDll().

ULONG LdrpNumberOfTlsEntries

| Definition at line 401 of file ldrp.h. Referenced by LdrpAllocateTls(), and LdrpInitializeTls().

BOOLEAN LdrpShutdownInProgress

| Definition at line 373 of file ldrp.h.

HANDLE LdrpShutdownThreadId

| Definition at line 389 of file ldrp.h. Referenced by LdrShutdownProcess(), RtlpNotOwnerCriticalSection(), and RtlpWaitForCriticalSection().

LIST_ENTRY LdrpTlsList

| Definition at line 400 of file ldrp.h. Referenced by LdrpAllocateTls(), LdrpFreeTls(), and LdrpInitializeTls().

LIST_ENTRY LdrpUnloadHead

| Definition at line 382 of file ldrp.h. Referenced by LdrUnloadDll().

BOOLEAN LdrpVerifyDlls

| Definition at line 376 of file ldrp.h. Referenced by LdrpInitializeProcess().

ULONG NtdllBaseTag

| Definition at line 455 of file ldrp.h. Referenced by LdrpInitializeProcess().

ULONG NtGlobalFlag

| Definition at line 370 of file ldrp.h. Referenced by ExAllocatePoolWithQuotaTag(), ExInitializeResource(), ExInitializeResourceLite(), InitializePool(), IoInitSystem(), KdpTrap(), MiLoadImageSection(), MiLoadSystemImage(), MiMapViewOfImageSection(), MmCreatePeb(), MmInPageKernelStack(), MmOutPageKernelStack(), NtClose(), NtDuplicateObject(), NtQuerySystemInformation(), NtSetEvent(), NtSetSystemInformation(), NtWaitForMultipleObjects(), ObCreateObjectType(), ObDupHandleProcedure(), ObpCaptureHandleInformation(), ObpCreateHandle(), ObpCreateUnnamedHandle(), ObpEnumFindHandleProcedure(), ObReferenceObjectByHandle(), RtlCreateHeap(), RtlDispatchException(), RtlGetNtGlobalFlags(), RtlpInitializeHeapSegment(), and UserInitialize().

LIST_ENTRY RtlCriticalSectionList

| Definition at line 371 of file ldrp.h. Referenced by LdrpForkProcess(), LdrpInitializeProcess(), RtlCheckForOrphanedCriticalSections(), RtlInitializeCriticalSectionAndSpinCount(), RtlpInitDeferedCriticalSection(), and RtlQueryProcessLockInformation().

RTL_CRITICAL_SECTION RtlCriticalSectionLock

| Definition at line 372 of file ldrp.h. Referenced by RtlCheckForOrphanedCriticalSections(), RtlDeleteCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), RtlpInitDeferedCriticalSection(), and RtlQueryProcessLockInformation().

LARGE_INTEGER RtlpTimeout

| Definition at line 369 of file ldrp.h. Referenced by LdrpInitializeProcess(), RtlAcquireResourceExclusive(), RtlAcquireResourceShared(), RtlConvertSharedToExclusive(), and RtlpWaitForCriticalSection().

BOOLEAN RtlpTimoutDisable

| Definition at line 368 of file ldrp.h. Referenced by LdrpInitializeProcess(), and RtlpWaitForCriticalSection().

BOOLEAN ShowSnaps

| Definition at line 367 of file ldrp.h. Referenced by LdrGetDllHandle(), LdrpAllocateTls(), LdrpCallTlsInitializers(), LdrpCheckForLoadedDll(), LdrpGetProcedureAddress(), LdrpInitializeProcess(), LdrpInitializeTls(), LdrpLoadDll(), LdrpMapDll(), LdrpResolveDllName(), LdrpRunInitializeRoutines(), LdrpSnapThunk(), LdrpUpdateLoadCount(), LdrpWalkImportDescriptor(), LdrShutdownProcess(), and LdrUnloadDll().