test: ldrinit.c File Reference

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

# ldrinit.c File Reference

`#include <ntos.h>`
`#include <nt.h>`
`#include <ntrtl.h>`
`#include <nturtl.h>`
`#include <heap.h>`
`#include <apcompat.h>`
`#include "ldrp.h"`
`#include <ctype.h>`

Go to the source code of this file.

## Functions

VOID | LdrpRelocateStartContext (IN PCONTEXT Context, IN LONG_PTR Diff)
NTSTATUS | LdrpForkProcess (VOID)
VOID | LdrpInitializeThread (IN PCONTEXT Context)
BOOLEAN | NtdllOkayToLockRoutine (IN PVOID Lock)
VOID | RtlpInitDeferedCriticalSection (VOID)
VOID | LdrQueryApplicationCompatibilityGoo (IN PUNICODE_STRING UnicodeImageName)
NTSTATUS | LdrFindAppCompatVariableInfo (IN ULONG dwTypeSeeking, OUT PAPP_VARIABLE_INFO *AppVariableInfo)
NTSTATUS | LdrpSearchResourceSection_U (IN PVOID DllHandle, IN PULONG_PTR ResourceIdPath, IN ULONG ResourceIdPathLength, IN BOOLEAN FindDirectoryEntry, IN BOOLEAN ExactLangMatchOnly, OUT PVOID *ResourceDirectoryOrData)
NTSTATUS | LdrpAccessResourceData (IN PVOID DllHandle, IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, OUT PVOID *Address OPTIONAL, OUT PULONG Size OPTIONAL)
PVOID | NtdllpAllocateStringRoutine (SIZE_T NumberOfBytes)
VOID | NtdllpFreeStringRoutine (PVOID Buffer)
VOID | LdrpInitializationFailure (IN NTSTATUS FailureCode)
VOID | LdrpInitialize (IN PCONTEXT Context, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
NTSTATUS | LdrpInitializeProcess (IN PCONTEXT Context OPTIONAL, IN PVOID SystemDllBase, IN PUNICODE_STRING UnicodeImageName)
VOID | LdrShutdownProcess (VOID)
VOID | LdrShutdownThread (VOID)
NTSTATUS | LdrQueryImageFileExecutionOptions (IN PUNICODE_STRING ImagePathName, IN PWSTR OptionName, IN ULONG Type, OUT PVOID Buffer, IN ULONG BufferSize, OUT PULONG ResultSize OPTIONAL)
NTSTATUS | LdrpInitializeTls (VOID)
NTSTATUS | LdrpAllocateTls (VOID)
VOID | LdrpFreeTls (VOID)
VOID | LdrpCallTlsInitializers (PVOID DllBase, ULONG Reason)
ULONG | GetNextCommaValue (IN OUT WCHAR **p, IN OUT ULONG *len)

## Variables

BOOLEAN | LdrpShutdownInProgress = FALSE
BOOLEAN | LdrpImageHasTls = FALSE
BOOLEAN | LdrpVerifyDlls = FALSE
BOOLEAN | LdrpLdrDatabaseIsSetup = FALSE
BOOLEAN | LdrpInLdrInit = FALSE
PVOID | NtDllBase
ULONG | RtlpDisableHeapLookaside
PRTL_ALLOCATE_STRING_ROUTINE | RtlAllocateStringRoutine
PRTL_FREE_STRING_ROUTINE | RtlFreeStringRoutine
RTL_BITMAP | TlsBitMap
RTL_BITMAP | TlsExpansionBitMap
RTL_CRITICAL_SECTION_DEBUG | LoaderLockDebug
RTL_CRITICAL_SECTION | LoaderLock
BOOLEAN | LoaderLockInitialized

## Function Documentation

ULONG GetNextCommaValue | ( | IN OUT WCHAR ** | p,
|  | IN OUT ULONG * | len
| ) |

Definition at line 2246 of file ldrinit.c.

References L.

Referenced by LdrQueryApplicationCompatibilityGoo().

    02247 {
    02248     ULONG Number = 0;
    02249
    02250     while (*len && (UNICODE_NULL != **p) && **p != L',')
    02251     {
    02252         // Let's ignore spaces
    02253         if ( L' ' != **p )
    02254         {
    02255             Number = (Number * 10) + ( (ULONG)**p - L'0' );
    02256         }
    02257
    02258         (*p)++;
    02259         (*len)--;
    02260     }
    02261
    02262     //
    02263     // If we're at a comma, get past it for the next call
    02264     //
    02265     if ( L',' == **p )
    02266     {
    02267         (*p)++;
    02268         (*len)--;
    02269     }
    02270
    02271     return Number;
    02272 }

NTSTATUS LdrFindAppCompatVariableInfo | ( | IN ULONG | dwTypeSeeking,
|  | OUT PAPP_VARIABLE_INFO * | AppVariableInfo
| ) |

Definition at line 2683 of file ldrinit.c.

Referenced by LdrQueryApplicationCompatibilityGoo().

    02690                    :
    02691
    02692     This function is used to find a variable length struct by its type.
    02693     The caller specifies what type its looking for and this function chews
    02694     thru all the variable length structs to find it.  If it does it returns
    02695     the pointer and TRUE, else FALSE.
    02696
    02697 Arguments:
    02698
    02699     dwTypeSeeking - AVT that you are looking for
    02700
    02701     AppVariableInfo - pointer to pointer of variable info to be returned
    02702
    02703 Return Value:
    02704
    02705     TRUE or FALSE if entry is found
    02706
    02707 --*/
    02708
    02709 {
    02710     PPEB Peb;
    02711     ULONG TotalSize;
    02712     ULONG CurOffset;
    02713     PAPP_VARIABLE_INFO pCurrentEntry;
    02714
    02715     Peb = NtCurrentPeb();
    02716     if (Peb->AppCompatInfo) {
    02717
    02718         //
    02719         // Since we're not dealing with a fixed-size structure, TotalSize
    02720         // will keep us from running off the end of the data list
    02721         //
    02722         TotalSize = ((PAPP_COMPAT_INFO) Peb->AppCompatInfo)->dwTotalSize;
    02723
    02724         //
    02725         // The first variable structure (if there is one) will start
    02726         // immediately after the fixed stuff
    02727         //
    02728         CurOffset = sizeof(APP_COMPAT_INFO);
    02729
    02730         while (CurOffset < TotalSize) {
    02731
    02732             pCurrentEntry = (PAPP_VARIABLE_INFO) ((PUCHAR)(Peb->AppCompatInfo) + CurOffset);
    02733
    02734             //
    02735             // Have we found what we're looking for?
    02736             //
    02737             if (dwTypeSeeking == pCurrentEntry->dwVariableType) {
    02738                 *AppVariableInfo = pCurrentEntry;
    02739                 return (STATUS_SUCCESS);
    02740             }
    02741
    02742             //
    02743             // Let's go look at the next blob
    02744             //
    02745             CurOffset += (ULONG)(pCurrentEntry->dwVariableInfoSize);
    02746         }
    02747
    02748     }
    02749
    02750     return (STATUS_NOT_FOUND);
    02751 }
    }

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

Definition at line 96 of file ldrrsrc.c.

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

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 }

NTSTATUS LdrpForkProcess | ( | VOID |  | ) |

Definition at line 575 of file ldrinit.c.

References FALSE, FastPebLock, LoaderLock, LoaderLockInitialized, NT_SUCCESS, NTSTATUS(), NULL, RtlCreateHeap(), RtlCriticalSectionList, RtlInitializeCriticalSection(), RtlInitializeHeapManager(), RtlpInitDeferedCriticalSection(), RtlRaiseStatus(), and TRUE.

Referenced by LdrpInitialize().

    00576 {
    00577     NTSTATUS st;
    00578     PPEB Peb;
    00579
    00580     Peb = NtCurrentPeb();
    00581
    00582     //
    00583     // Initialize the critical section package.
    00584     //
    00585
    00586     RtlpInitDeferedCriticalSection();
    00587
    00588     InsertTailList(&RtlCriticalSectionList, &LoaderLock.DebugInfo->ProcessLocksList);
    00589     LoaderLock.DebugInfo->CriticalSection = &LoaderLock;
    00590     LoaderLockInitialized = TRUE;
    00591
    00592     st = RtlInitializeCriticalSection(&FastPebLock);
    00593     if ( !NT_SUCCESS(st) ) {
    00594         RtlRaiseStatus(st);
    00595         }
    00596     Peb->FastPebLock = &FastPebLock;
    00597     Peb->FastPebLockRoutine = (PVOID)&RtlEnterCriticalSection;
    00598     Peb->FastPebUnlockRoutine = (PVOID)&RtlLeaveCriticalSection;
    00599     Peb->InheritedAddressSpace = FALSE;
    00600     RtlInitializeHeapManager();
    00601     Peb->ProcessHeap = RtlCreateHeap( HEAP_GROWABLE,    // Flags
    00602                                       NULL,             // HeapBase
    00603                                       64 * 1024,        // ReserveSize
    00604                                       4096,             // CommitSize
    00605                                       NULL,             // Lock to use for serialization
    00606                                       NULL              // GrowthThreshold
    00607                                     );
    00608     if (Peb->ProcessHeap == NULL) {
    00609         return STATUS_NO_MEMORY;
    00610     }
    00611
    00612     return st;
    00613 }

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 }

VOID LdrpInitializationFailure | ( | IN NTSTATUS | FailureCode | ) |

Definition at line 157 of file ldrinit.c.

References LdrpFatalHardErrorCount, NtRaiseHardError(), and NTSTATUS().

Referenced by LdrpInitialize(), and LdrpInitializeProcess().

    00160 {
    00161
    00162     NTSTATUS ErrorStatus;
    00163     ULONG_PTR ErrorParameter;
    00164     ULONG ErrorResponse;
    00165
    00166     if ( LdrpFatalHardErrorCount ) {
    00167         return;
    00168         }
    00169
    00170     //
    00171     // Its error time...
    00172     //
    00173     ErrorParameter = (ULONG_PTR)FailureCode;
    00174     ErrorStatus = NtRaiseHardError(
    00175                     STATUS_APP_INIT_FAILURE,
    00176                     1,
    00177                     0,
    00178                     &ErrorParameter,
    00179                     OptionOk,
    00180                     &ErrorResponse
    00181                     );
    00182 }

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 }

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 }

VOID LdrpInitializeThread | ( | IN PCONTEXT | Context | ) |

Definition at line 1702 of file ldrinit.c.

References LdrpAllocateTls(), LdrpCallInitRoutine, LdrpCallTlsInitializers(), LdrpImageHasTls, LdrpShutdownInProgress, and NULL.

Referenced by LdrpInitialize().

    01708                    :
    01709
    01710     This function is called by a thread that is terminating cleanly.
    01711     It's purpose is to call all of the processes DLLs to notify them
    01712     that the thread is detaching.
    01713
    01714 Arguments:
    01715
    01716     Context - Context that will be restored after loader initializes.
    01717
    01718 Return Value:
    01719
    01720     None.
    01721
    01722 --*/
    01723
    01724 {
    01725     PPEB Peb;
    01726     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    01727     PDLL_INIT_ROUTINE InitRoutine;
    01728     PLIST_ENTRY Next;
    01729
    01730     Peb = NtCurrentPeb();
    01731
    01732     if ( LdrpShutdownInProgress ) {
    01733         return;
    01734         }
    01735
    01736     LdrpAllocateTls();
    01737
    01738     Next = Peb->Ldr->InMemoryOrderModuleList.Flink;
    01739     while (Next != &Peb->Ldr->InMemoryOrderModuleList) {
    01740         LdrDataTableEntry
    01741             = (PLDR_DATA_TABLE_ENTRY)
    01742               (CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
    01743
    01744         //
    01745         // Walk through the entire list looking for
    01746         // entries. For each entry, that has an init
    01747         // routine, call it.
    01748         //
    01749         if (Peb->ImageBaseAddress != LdrDataTableEntry->DllBase) {
    01750             if ( !(LdrDataTableEntry->Flags & LDRP_DONT_CALL_FOR_THREADS)) {
    01751                 InitRoutine = (PDLL_INIT_ROUTINE)LdrDataTableEntry->EntryPoint;
    01752                 if (InitRoutine && (LdrDataTableEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) ) {
    01753                     if (LdrDataTableEntry->Flags & LDRP_IMAGE_DLL) {
    01754                         if ( LdrDataTableEntry->TlsIndex ) {
    01755                             if ( !LdrpShutdownInProgress ) {
    01756                                 LdrpCallTlsInitializers(LdrDataTableEntry->DllBase,DLL_THREAD_ATTACH);
    01757                                 }
    01758                             }
    01759
    01760 #if defined (WX86)
    01761                         if (!Wx86ProcessInit ||
    01762                             LdrpRunWx86DllEntryPoint(InitRoutine,
    01763                                                     NULL,
    01764                                                     LdrDataTableEntry->DllBase,
    01765                                                     DLL_THREAD_ATTACH,
    01766                                                     NULL
    01767                                                     ) ==  STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
    01768 #endif
    01769                            {
    01770                             if ( !LdrpShutdownInProgress ) {
    01771                                 LdrpCallInitRoutine(InitRoutine,
    01772                                                     LdrDataTableEntry->DllBase,
    01773                                                     DLL_THREAD_ATTACH,
    01774                                                     NULL);
    01775                                 }
    01776                             }
    01777                         }
    01778                     }
    01779                 }
    01780             }
    01781         Next = Next->Flink;
    01782         }
    01783
    01784     //
    01785     // If the image has tls than call its initializers
    01786     //
    01787
    01788     if ( LdrpImageHasTls && !LdrpShutdownInProgress ) {
    01789         LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_THREAD_ATTACH);
    01790         }
    01791
    01792 }

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 LdrpRelocateStartContext | ( | IN PCONTEXT | Context,
|  | IN LONG_PTR | Diff
| ) |

Definition at line 28 of file alpha/ldrctx.c.

Referenced by LdrpInitializeProcess().

    00034                    :
    00035
    00036    This routine relocates the start context to mesh with the
    00037    executable that has just been relocated.
    00038
    00039 Arguments:
    00040
    00041    Context - Supplies a context that needs editing.
    00042
    00043    Diff - Supplies the difference from the based address to the relocated
    00044           address.
    00045
    00046 Return Value:
    00047
    00048    None.
    00049
    00050 --*/
    00051 {
    00052     Context->IntA0 += (ULONGLONG)Diff;
    00053     Context->IntGp += (ULONGLONG)Diff;
    00054 }
    }

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

Definition at line 492 of file ldrrsrc.c.

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

VOID LdrQueryApplicationCompatibilityGoo | ( | IN PUNICODE_STRING | UnicodeImageName | ) |

Definition at line 2277 of file ldrinit.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, GetNextCommaValue(), L, LdrFindAppCompatVariableInfo(), LdrpAccessResourceData(), LdrpSearchResourceSection_U(), LdrQueryImageFileExecutionOptions(), Name, NT_SUCCESS, NTSTATUS(), NULL, Resource, RtlAllocateHeap, RtlFreeHeap, RtlInitUnicodeString(), RtlQueryEnvironmentVariable_U(), TRUE, and USHORT.

Referenced by LdrpInitializeProcess().

    02283                    :
    02284
    02285     This function is called by LdrpInitialize after its initialized the
    02286     process.  It's purpose is to query any application specific flags,
    02287     hacks, etc.  If any app specific information is found, its hung off
    02288     the PEB for other components to test against.
    02289
    02290     Besides setting hanging the AppCompatInfo struct off the PEB, the
    02291     only other action that will occur in here is setting OS version
    02292     numbers in the PEB if the appropriate Version lie app flag is set.
    02293
    02294 Arguments:
    02295
    02296     UnicodeImageName - Actual image name (including path)
    02297
    02298 Return Value:
    02299
    02300     None.
    02301
    02302 --*/
    02303
    02304 {
    02305
    02306     PPEB Peb;
    02307     PVOID ResourceInfo;
    02308     ULONG TotalGooLength;
    02309     ULONG AppCompatLength;
    02310     ULONG ResultSize;
    02311     ULONG ResourceSize;
    02312     ULONG InputCompareLength;
    02313     ULONG OutputCompareLength;
    02314     LANGID LangId;
    02315     NTSTATUS st;
    02316     BOOLEAN bImageContainsVersionResourceInfo;
    02317     ULONG_PTR IdPath[3];
    02318     APP_COMPAT_GOO LocalAppCompatGoo;
    02319     PAPP_COMPAT_GOO AppCompatGoo;
    02320     PAPP_COMPAT_INFO AppCompatInfo;
    02321     PAPP_VARIABLE_INFO AppVariableInfo;
    02322     PPRE_APP_COMPAT_INFO AppCompatEntry;
    02323     PIMAGE_RESOURCE_DATA_ENTRY DataEntry;
    02324     PEFFICIENTOSVERSIONINFOEXW OSVerInfo;
    02325     UNICODE_STRING EnvName;
    02326     UNICODE_STRING EnvValue;
    02327     WCHAR *NewCSDString;
    02328     WCHAR TempString[ 128 ];   // is the size of szCSDVersion in OSVERSIONINFOW
    02329     BOOLEAN fNewCSDVersionBuffer = FALSE;
    02330
    02331     struct {
    02332         USHORT TotalSize;
    02333         USHORT DataSize;
    02334         USHORT Type;
    02335         WCHAR Name[16];              // L"VS_VERSION_INFO" + unicode nul
    02336     } *Resource;
    02337
    02338
    02339     //
    02340     // Check execution options to see if there's any Goo for this app.
    02341     // We purposely feed a small struct to LdrQueryImageFileExecOptions,
    02342     // so that it can come back with success/failure, and if success we see
    02343     // how much we need to alloc.  As the results coming back will be of
    02344     // variable length.
    02345     //
    02346     Peb = NtCurrentPeb();
    02347     Peb->AppCompatInfo = NULL;
    02348     RtlInitUnicodeString(&Peb->CSDVersion, NULL);
    02349
    02350     st = LdrQueryImageFileExecutionOptions( UnicodeImageName,
    02351                                             L"ApplicationGoo",
    02352                                             REG_BINARY,
    02353                                             &LocalAppCompatGoo,
    02354                                             sizeof(APP_COMPAT_GOO),
    02355                                             &ResultSize
    02356                                           );
    02357
    02358     //
    02359     // If there's an entry there, we're guaranteed to get overflow error.
    02360     //
    02361     if (st == STATUS_BUFFER_OVERFLOW) {
    02362
    02363         //
    02364         // Something is there, alloc memory for the "Pre" Goo struct right now
    02365         //
    02366         AppCompatGoo = \
    02367             RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, ResultSize);
    02368
    02369         if (!AppCompatGoo) {
    02370             return;
    02371         }
    02372
    02373         //
    02374         // Now that we've got the memory, hit it again
    02375         //
    02376         st = LdrQueryImageFileExecutionOptions( UnicodeImageName,
    02377                                                 L"ApplicationGoo",
    02378                                                 REG_BINARY,
    02379                                                 AppCompatGoo,
    02380                                                 ResultSize,
    02381                                                 &ResultSize
    02382                                               );
    02383
    02384         if (!NT_SUCCESS( st )) {
    02385             RtlFreeHeap(Peb->ProcessHeap, 0, AppCompatGoo);
    02386             return;
    02387         }
    02388
    02389         //
    02390         // Got a hit on this key, however we don't know fer sure that its
    02391         // an exact match.  There could be multiple App Compat entries
    02392         // within this Goo.  So we get the version resource information out
    02393         // of the Image hdr (if avail) and later we compare it against all of
    02394         // the entries found within the Goo hoping for a match.
    02395         //
    02396         // Need Language Id in order to query the resource info
    02397         //
    02398         bImageContainsVersionResourceInfo = FALSE;
    02399 //        NtQueryDefaultUILanguage(&LangId);
    02400         IdPath[0] = 16;                             // RT_VERSION
    02401         IdPath[1] = 1;                              // VS_VERSION_INFO
    02402         IdPath[2] = 0; // LangId;
    02403
    02404         //
    02405         // Search for version resource information
    02406         //
    02407         try {
    02408             st = LdrpSearchResourceSection_U(
    02409                     Peb->ImageBaseAddress,
    02410                     IdPath,
    02411                     3,
    02412                     FALSE,
    02413                     FALSE,   // TRUE,
    02414                     &DataEntry
    02415                     );
    02416
    02417         } except(EXCEPTION_EXECUTE_HANDLER) {
    02418             st = STATUS_UNSUCCESSFUL;
    02419         }
    02420
    02421         if (NT_SUCCESS( st )) {
    02422
    02423             //
    02424             // Give us a pointer to the resource information
    02425             //
    02426             try {
    02427                 st = LdrpAccessResourceData(
    02428                         Peb->ImageBaseAddress,
    02429                         DataEntry,
    02430                         &Resource,
    02431                         &ResourceSize
    02432                         );
    02433
    02434             } except(EXCEPTION_EXECUTE_HANDLER) {
    02435                 st = STATUS_UNSUCCESSFUL;
    02436             }
    02437
    02438             if (NT_SUCCESS( st )) {
    02439                 bImageContainsVersionResourceInfo = TRUE;
    02440             }
    02441
    02442         }
    02443
    02444         //
    02445         // Now that we either have (or have not) the version resource info,
    02446         // bounce down each app compat entry looking for a match.  If there
    02447         // wasn't any version resource info in the image hdr, its going to be
    02448         // an automatic match to an entry that also doesn't have anything for
    02449         // its version resource info.  Obviously there can be only one of these
    02450         // "empty" entries within the Goo (as the first one will always be
    02451         // matched first.
    02452         //
    02453         st = STATUS_SUCCESS;
    02454         AppCompatEntry = AppCompatGoo->AppCompatEntry;
    02455         TotalGooLength = \
    02456             AppCompatGoo->dwTotalGooSize - sizeof(AppCompatGoo->dwTotalGooSize);
    02457         while (TotalGooLength) {
    02458
    02459             try {
    02460
    02461                 //
    02462                 // Compare what we're told to by the resource info size.  The
    02463                 // ResourceInfo (if avail) is directly behind the AppCompatEntry
    02464                 //
    02465                 InputCompareLength = AppCompatEntry->dwResourceInfoSize;
    02466                 ResourceInfo = AppCompatEntry + 1;
    02467                 if (bImageContainsVersionResourceInfo) {
    02468
    02469                     if (InputCompareLength > Resource->TotalSize) {
    02470                         InputCompareLength = Resource->TotalSize;
    02471                     }
    02472
    02473                     OutputCompareLength = \
    02474                         (ULONG)RtlCompareMemory(
    02475                             ResourceInfo,
    02476                             Resource,
    02477                             InputCompareLength
    02478                             );
    02479
    02480                 }
    02481
    02482                 //
    02483                 // In this case, we don't have any version resource info in
    02484                 // the image header, so set OutputCompareLength to zero.
    02485                 // If InputCompareLength was set to zero (above) due to the
    02486                 // AppCompatEntry also having no version resource info, then
    02487                 // the test will succeed (below) and we've found our match.
    02488                 // Otherwise, this is not the same app and it won't be a match.
    02489                 //
    02490                 else {
    02491                     OutputCompareLength = 0;
    02492                 }
    02493
    02494             } except(EXCEPTION_EXECUTE_HANDLER) {
    02495                 st = STATUS_UNSUCCESSFUL;
    02496             }
    02497
    02498             if ((!NT_SUCCESS( st )) ||
    02499                 (InputCompareLength != OutputCompareLength)) {
    02500
    02501                 //
    02502                 // Wasn't a match for some reason or another, goto next entry
    02503                 //
    02504                 TotalGooLength -= AppCompatEntry->dwEntryTotalSize;
    02505                 (PUCHAR) AppCompatEntry += AppCompatEntry->dwEntryTotalSize;
    02506                 continue;
    02507             }
    02508
    02509             //
    02510             // We're a match!!!  Now we have to create the final "Post"
    02511             // app compat structure that will be used by everyone to follow.
    02512             // This guy hangs off the Peb and it doesn't have the resource
    02513             // info still lying around in there.
    02514             //
    02515             AppCompatLength = AppCompatEntry->dwEntryTotalSize;
    02516             AppCompatLength -= AppCompatEntry->dwResourceInfoSize;
    02517             Peb->AppCompatInfo = \
    02518                 RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, AppCompatLength);
    02519
    02520             if (!Peb->AppCompatInfo) {
    02521                 break;
    02522             }
    02523
    02524             AppCompatInfo = Peb->AppCompatInfo;
    02525             AppCompatInfo->dwTotalSize = AppCompatLength;
    02526
    02527             //
    02528             // Copy what was beyond the resource info to near the top starting at
    02529             // the Application compat flags.
    02530             //
    02531             RtlMoveMemory(
    02532                 &AppCompatInfo->CompatibilityFlags,
    02533                 (PUCHAR) ResourceInfo + AppCompatEntry->dwResourceInfoSize,
    02534                 AppCompatInfo->dwTotalSize - FIELD_OFFSET(APP_COMPAT_INFO, CompatibilityFlags)
    02535                 );
    02536
    02537             //
    02538             // Now that we've created the "Post" app compat info struct to be
    02539             // used by everyone, we need to check if version lying for this
    02540             // app is requested.  If so, we need to stuff the Peb right now.
    02541             //
    02542             if (AppCompatInfo->CompatibilityFlags.QuadPart & KACF_VERSIONLIE) {
    02543
    02544                 //
    02545                 // Find the variable version lie struct somwhere within
    02546                 //
    02547                 if( STATUS_SUCCESS != LdrFindAppCompatVariableInfo(AVT_OSVERSIONINFO, &AppVariableInfo)) {
    02548                     break;
    02549                 }
    02550
    02551                 //
    02552                 // The variable length information itself comes at the end
    02553                 // of the normal struct and could be of any aribitrary length
    02554                 //
    02555                 AppVariableInfo++;
    02556                 OSVerInfo = (PEFFICIENTOSVERSIONINFOEXW) AppVariableInfo;
    02557                 Peb->OSMajorVersion = OSVerInfo->dwMajorVersion;
    02558                 Peb->OSMinorVersion = OSVerInfo->dwMinorVersion;
    02559                 Peb->OSBuildNumber = (USHORT) OSVerInfo->dwBuildNumber;
    02560                 Peb->OSCSDVersion = (OSVerInfo->wServicePackMajor << 8) & 0xFF00;
    02561                 Peb->OSCSDVersion |= OSVerInfo->wServicePackMinor;
    02562                 Peb->OSPlatformId = OSVerInfo->dwPlatformId;
    02563
    02564                 Peb->CSDVersion.Length = (USHORT)wcslen(&OSVerInfo->szCSDVersion[0])*sizeof(WCHAR);
    02565                 Peb->CSDVersion.MaximumLength = Peb->CSDVersion.Length + sizeof(WCHAR);
    02566                 Peb->CSDVersion.Buffer = \
    02567                     RtlAllocateHeap(
    02568                         Peb->ProcessHeap,
    02569                         HEAP_ZERO_MEMORY,
    02570                         Peb->CSDVersion.MaximumLength
    02571                         );
    02572
    02573                 if (!Peb->CSDVersion.Buffer) {
    02574                     break;
    02575                 }
    02576                 wcscpy(Peb->CSDVersion.Buffer, &OSVerInfo->szCSDVersion[0]);
    02577                 fNewCSDVersionBuffer = TRUE;
    02578
    02579             }
    02580
    02581             break;
    02582
    02583         }
    02584
    02585         RtlFreeHeap(Peb->ProcessHeap, 0, AppCompatGoo);
    02586     }
    02587
    02588
    02589     //
    02590     // Only look at the ENV stuff if haven't already gotten new version info from the registry
    02591     //
    02592     if ( FALSE == fNewCSDVersionBuffer )
    02593     {
    02594         //
    02595         // The format of this string is:
    02596         // _COMPAT_VER_NNN = MajOSVer, MinOSVer, OSBldNum, MajCSD, MinCSD, PlatformID, CSDString
    02597         //  eg:  _COMPAT_VER_NNN=4,0,1381,3,0,2,Service Pack 3
    02598         //   (for NT 4 SP3)
    02599
    02600         RtlInitUnicodeString(&EnvName, L"_COMPAT_VER_NNN");
    02601
    02602         EnvValue.Buffer = TempString;
    02603         EnvValue.Length = 0;
    02604         EnvValue.MaximumLength = sizeof(TempString);
    02605
    02606
    02607         st = RtlQueryEnvironmentVariable_U(
    02608             NULL,
    02609             &EnvName,
    02610             &EnvValue
    02611             );
    02612
    02613         //
    02614         // One of the possible error codes is BUFFER_TOO_SMALL - this indicates a
    02615         // string that's wacko - they should not be larger than the size we define/expect
    02616         // In this case, we'll ignore that string
    02617         //
    02618         if ( STATUS_SUCCESS == st )
    02619         {
    02620             WCHAR *p = EnvValue.Buffer;
    02621             WCHAR *NewSPString;
    02622             ULONG len = EnvValue.Length / sizeof(WCHAR);  // (Length is bytes, not chars)
    02623
    02624             //
    02625             // Ok, someone wants different version info.
    02626             //
    02627             Peb->OSMajorVersion = GetNextCommaValue( &p, &len );
    02628             Peb->OSMinorVersion = GetNextCommaValue( &p, &len );
    02629             Peb->OSBuildNumber = (USHORT)GetNextCommaValue( &p, &len );
    02630             Peb->OSCSDVersion = (USHORT)(GetNextCommaValue( &p, &len )) << 8;
    02631             Peb->OSCSDVersion |= (USHORT)GetNextCommaValue( &p, &len );
    02632             Peb->OSPlatformId = GetNextCommaValue( &p, &len );
    02633
    02634
    02635             //
    02636             // Need to free the old buffer if there is one...
    02637             //
    02638             if ( fNewCSDVersionBuffer )
    02639             {
    02640                 RtlFreeHeap( Peb->ProcessHeap, 0, Peb->CSDVersion.Buffer );
    02641                 Peb->CSDVersion.Buffer = NULL;
    02642             }
    02643
    02644             if ( len )
    02645             {
    02646                 NewCSDString = \
    02647                         RtlAllocateHeap(
    02648                             Peb->ProcessHeap,
    02649                             HEAP_ZERO_MEMORY,
    02650                             ( len + 1 ) * sizeof(WCHAR)
    02651                             );
    02652
    02653                 if ( NULL == NewCSDString )
    02654                 {
    02655                     return;
    02656                 }
    02657
    02658                 //
    02659                 // Now copy the string to memory that we'll keep
    02660                 //
    02661                 // We do a movemem here rather than a string copy because current comments in
    02662                 // RtlQueryEnvironmentVariable() indicate that in an edge case, we might not
    02663                 // have a trailing NULL - berniem 7/7/99
    02664                 //
    02665                 RtlMoveMemory( NewCSDString, p, len * sizeof(WCHAR) );
    02666
    02667             }
    02668             else
    02669             {
    02670                 NewCSDString = NULL;
    02671             }
    02672
    02673             RtlInitUnicodeString( &(Peb->CSDVersion), NewCSDString );
    02674
    02675         }
    02676     }
    02677
    02678     return;
    02679 }

NTSTATUS LdrQueryImageFileExecutionOptions | ( | IN PUNICODE_STRING | ImagePathName,
|  | IN PWSTR | OptionName,
|  | IN ULONG | Type,
|  | OUT PVOID | Buffer,
|  | IN ULONG | BufferSize,
|  | OUT PULONG ResultSize | OPTIONAL
| ) |

Definition at line 1796 of file ldrinit.c.

References Buffer, BufferSize, FALSE, KeyPath, KeyPathBuffer, L, MAKE_TAG, NT_SUCCESS, NtClose(), NtOpenKey(), NtQueryValueKey(), NTSTATUS(), NULL, ObjectAttributes, RtlAllocateHeap, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlFreeHeap, RtlInitUnicodeString(), RtlUnicodeStringToInteger(), Status, TEMP_TAG, TRUE, and USHORT.

Referenced by LdrpInitialize(), LdrpInitializeProcess(), LdrpRunInitializeRoutines(), and LdrQueryApplicationCompatibilityGoo().

    01804 {
    01805     BOOLEAN bNeedToFree=FALSE;
    01806     NTSTATUS Status;
    01807     UNICODE_STRING UnicodeString;
    01808     PWSTR pw;
    01809     OBJECT_ATTRIBUTES ObjectAttributes;
    01810     HANDLE KeyHandle;
    01811     UNICODE_STRING KeyPath;
    01812     WCHAR KeyPathBuffer[ DOS_MAX_COMPONENT_LENGTH + 100 ];
    01813     ULONG KeyValueBuffer[ 256 ];
    01814     PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
    01815     ULONG AllocLength;
    01816     ULONG ResultLength;
    01817
    01818     KeyPath.Buffer = KeyPathBuffer;
    01819     KeyPath.Length = 0;
    01820     KeyPath.MaximumLength = sizeof( KeyPathBuffer );
    01821
    01822     RtlAppendUnicodeToString( &KeyPath,
    01823         L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\"
    01824         );
    01825
    01826     UnicodeString = *ImagePathName;
    01827     pw = (PWSTR)((PCHAR)UnicodeString.Buffer + UnicodeString.Length);
    01828     UnicodeString.MaximumLength = UnicodeString.Length;
    01829     while (UnicodeString.Length != 0) {
    01830         if (pw[ -1 ] == OBJ_NAME_PATH_SEPARATOR) {
    01831             break;
    01832         }
    01833         pw--;
    01834         UnicodeString.Length -= sizeof( *pw );
    01835     }
    01836     UnicodeString.Buffer = pw;
    01837     UnicodeString.Length = UnicodeString.MaximumLength - UnicodeString.Length;
    01838
    01839     RtlAppendUnicodeStringToString( &KeyPath, &UnicodeString );
    01840
    01841     InitializeObjectAttributes( &ObjectAttributes,
    01842         &KeyPath,
    01843         OBJ_CASE_INSENSITIVE,
    01844         NULL,
    01845         NULL
    01846         );
    01847
    01848     Status = NtOpenKey( &KeyHandle,
    01849         GENERIC_READ,
    01850         &ObjectAttributes
    01851         );
    01852
    01853     if (!NT_SUCCESS( Status )) {
    01854         return Status;
    01855     }
    01856
    01857     RtlInitUnicodeString( &UnicodeString, OptionName );
    01858     KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)&KeyValueBuffer;
    01859     Status = NtQueryValueKey( KeyHandle,
    01860         &UnicodeString,
    01861         KeyValuePartialInformation,
    01862         KeyValueInformation,
    01863         sizeof( KeyValueBuffer ),
    01864         &ResultLength
    01865         );
    01866     if (Status == STATUS_BUFFER_OVERFLOW) {
    01867         //
    01868         // This function can be called before the process heap gets created
    01869         // therefore we need to protect against this case. The majority of the
    01870         // code will not hit this code path because they read just strings
    01871         // containing hex numbers and for this the size of KeyValueBuffer is
    01872         // more than sufficient.
    01873         //
    01874
    01875         if (RtlProcessHeap()) {
    01876
    01877             AllocLength = sizeof( *KeyValueInformation ) +
    01878                 KeyValueInformation->DataLength;
    01879             KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
    01880             RtlAllocateHeap( RtlProcessHeap(), MAKE_TAG( TEMP_TAG ), AllocLength);
    01881
    01882             if (KeyValueInformation == NULL) {
    01883                 Status = STATUS_NO_MEMORY;
    01884             }
    01885             else {
    01886                 bNeedToFree = TRUE;
    01887                 Status = NtQueryValueKey( KeyHandle,
    01888                     &UnicodeString,
    01889                     KeyValuePartialInformation,
    01890                     KeyValueInformation,
    01891                     AllocLength,
    01892                     &ResultLength
    01893                     );
    01894             }
    01895         }
    01896         else {
    01897
    01898             Status = STATUS_NO_MEMORY;
    01899         }
    01900     }
    01901
    01902     if (NT_SUCCESS( Status )) {
    01903         if (KeyValueInformation->Type == REG_BINARY) {
    01904             if ((Buffer) &&
    01905                 (KeyValueInformation->DataLength <= BufferSize)) {
    01906                 RtlMoveMemory( Buffer, &KeyValueInformation->Data, KeyValueInformation->DataLength);
    01907             }
    01908             else {
    01909                 Status = STATUS_BUFFER_OVERFLOW;
    01910             }
    01911             if (ARGUMENT_PRESENT( ResultSize )) {
    01912                 *ResultSize = KeyValueInformation->DataLength;
    01913             }
    01914         }
    01915         else if (KeyValueInformation->Type == REG_DWORD) {
    01916
    01917             if (Type != REG_DWORD) {
    01918                 Status = STATUS_OBJECT_TYPE_MISMATCH;
    01919             }
    01920             else {
    01921                 if ((Buffer)
    01922                     && (BufferSize == sizeof(ULONG))
    01923                     && (KeyValueInformation->DataLength == BufferSize)) {
    01924
    01925                     RtlMoveMemory( Buffer, &KeyValueInformation->Data, KeyValueInformation->DataLength);
    01926                 }
    01927                 else {
    01928                     Status = STATUS_BUFFER_OVERFLOW;
    01929                 }
    01930
    01931                 if (ARGUMENT_PRESENT( ResultSize )) {
    01932                     *ResultSize = KeyValueInformation->DataLength;
    01933                 }
    01934             }
    01935         }
    01936         else if (KeyValueInformation->Type != REG_SZ) {
    01937             Status = STATUS_OBJECT_TYPE_MISMATCH;
    01938         }
    01939         else {
    01940             if (Type == REG_DWORD) {
    01941                 if (BufferSize != sizeof( ULONG )) {
    01942                     BufferSize = 0;
    01943                     Status = STATUS_INFO_LENGTH_MISMATCH;
    01944                 }
    01945                 else {
    01946                     UnicodeString.Buffer = (PWSTR)&KeyValueInformation->Data;
    01947                     UnicodeString.Length = (USHORT)
    01948                     (KeyValueInformation->DataLength - sizeof( UNICODE_NULL ));
    01949                     UnicodeString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
    01950                     Status = RtlUnicodeStringToInteger( &UnicodeString, 0, (PULONG)Buffer );
    01951                 }
    01952             }
    01953             else {
    01954                 if (KeyValueInformation->DataLength > BufferSize) {
    01955                     Status = STATUS_BUFFER_OVERFLOW;
    01956                 }
    01957                 else {
    01958                     BufferSize = KeyValueInformation->DataLength;
    01959                 }
    01960
    01961                 RtlMoveMemory( Buffer, &KeyValueInformation->Data, BufferSize );
    01962             }
    01963
    01964             if (ARGUMENT_PRESENT( ResultSize )) {
    01965                 *ResultSize = BufferSize;
    01966             }
    01967         }
    01968     }
    01969
    01970     if (bNeedToFree)
    01971         RtlFreeHeap(RtlProcessHeap(), 0, KeyValueInformation);
    01972     NtClose( KeyHandle );
    01973     return Status;
    01974 }

VOID LdrShutdownProcess | ( | VOID |  | ) |

Definition at line 1462 of file ldrinit.c.

References CommandLine, DbgPrint, LdrpCallInitRoutine, LdrpCallTlsInitializers(), LdrpImageHasTls, LdrpShutdownInProgress, LdrpShutdownThreadId, LoaderLock, NULL, RtlpHeapIsLocked(), RtlValidateProcessHeaps(), ShowSnaps, and TRUE.

    01468                    :
    01469
    01470     This function is called by a process that is terminating cleanly.
    01471     It's purpose is to call all of the processes DLLs to notify them
    01472     that the process is detaching.
    01473
    01474 Arguments:
    01475
    01476     None
    01477
    01478 Return Value:
    01479
    01480     None.
    01481
    01482 --*/
    01483
    01484 {
    01485     PPEB Peb;
    01486     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    01487     PDLL_INIT_ROUTINE InitRoutine;
    01488     PLIST_ENTRY Next;
    01489
    01490     //
    01491     // only unload once ! DllTerm routines might call exit process in fatal situations
    01492     //
    01493
    01494     if ( LdrpShutdownInProgress ) {
    01495         return;
    01496         }
    01497
    01498     Peb = NtCurrentPeb();
    01499
    01500     if (ShowSnaps) {
    01501         UNICODE_STRING CommandLine;
    01502
    01503         CommandLine = Peb->ProcessParameters->CommandLine;
    01504         if (!(Peb->ProcessParameters->Flags & RTL_USER_PROC_PARAMS_NORMALIZED)) {
    01505             CommandLine.Buffer = (PWSTR)((PCHAR)CommandLine.Buffer + (ULONG_PTR)(Peb->ProcessParameters));
    01506         }
    01507
    01508         DbgPrint( "LDR: PID: 0x%x finished - '%wZ'\n",
    01509                   NtCurrentTeb()->ClientId.UniqueProcess,
    01510                   &CommandLine
    01511                 );
    01512     }
    01513
    01514     LdrpShutdownThreadId = NtCurrentTeb()->ClientId.UniqueThread;
    01515     LdrpShutdownInProgress = TRUE;
    01516     RtlEnterCriticalSection(&LoaderLock);
    01517
    01518     try {
    01519
    01520         //
    01521         // check to see if the heap is locked. If so, do not do ANY
    01522         // dll processing since it is very likely that a dll will need
    01523         // to do heap operations, but that the heap is not in good shape.
    01524         // ExitProcess called in a very active app can leave threads terminated
    01525         // in the middle of the heap code or in other very bad places. Checking the
    01526         // heap lock is a good indication that the process was very active when it
    01527         // called ExitProcess
    01528         //
    01529
    01530         if ( RtlpHeapIsLocked( RtlProcessHeap() )) {
    01531             ;
    01532             }
    01533         else {
    01534             if ( Peb->BeingDebugged ) {
    01535                 RtlValidateProcessHeaps();
    01536                 }
    01537
    01538             //
    01539             // Go in reverse order initialization order and build
    01540             // the unload list
    01541             //
    01542
    01543             Next = Peb->Ldr->InInitializationOrderModuleList.Blink;
    01544             while ( Next != &Peb->Ldr->InInitializationOrderModuleList) {
    01545                 LdrDataTableEntry
    01546                     = (PLDR_DATA_TABLE_ENTRY)
    01547                       (CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,InInitializationOrderLinks));
    01548
    01549                 Next = Next->Blink;
    01550
    01551                 //
    01552                 // Walk through the entire list looking for
    01553                 // entries. For each entry, that has an init
    01554                 // routine, call it.
    01555                 //
    01556
    01557                 if (Peb->ImageBaseAddress != LdrDataTableEntry->DllBase) {
    01558                     InitRoutine = (PDLL_INIT_ROUTINE)LdrDataTableEntry->EntryPoint;
    01559                     if (InitRoutine && (LdrDataTableEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) ) {
    01560                         if (LdrDataTableEntry->Flags) {
    01561                             if ( LdrDataTableEntry->TlsIndex ) {
    01562                                 LdrpCallTlsInitializers(LdrDataTableEntry->DllBase,DLL_PROCESS_DETACH);
    01563                                 }
    01564
    01565 #if defined (WX86)
    01566                             if (!Wx86ProcessInit ||
    01567                                 LdrpRunWx86DllEntryPoint(InitRoutine,
    01568                                                         NULL,
    01569                                                         LdrDataTableEntry->DllBase,
    01570                                                         DLL_PROCESS_DETACH,
    01571                                                         (PVOID)1
    01572                                                         ) ==  STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
    01573 #endif
    01574                                {
    01575                                 LdrpCallInitRoutine(InitRoutine,
    01576                                                     LdrDataTableEntry->DllBase,
    01577                                                     DLL_PROCESS_DETACH,
    01578                                                     (PVOID)1);
    01579                                 }
    01580
    01581                             }
    01582                         }
    01583                     }
    01584                 }
    01585
    01586             //
    01587             // If the image has tls than call its initializers
    01588             //
    01589
    01590             if ( LdrpImageHasTls ) {
    01591                 LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_PROCESS_DETACH);
    01592                 }
    01593             }
    01594
    01595     } finally {
    01596         RtlLeaveCriticalSection(&LoaderLock);
    01597     }
    01598
    01599 }

VOID LdrShutdownThread | ( | VOID |  | ) |

Definition at line 1602 of file ldrinit.c.

References LdrpCallInitRoutine, LdrpCallTlsInitializers(), LdrpFreeTls(), LdrpImageHasTls, LoaderLock, and NULL.

    01608                    :
    01609
    01610     This function is called by a thread that is terminating cleanly.
    01611     It's purpose is to call all of the processes DLLs to notify them
    01612     that the thread is detaching.
    01613
    01614 Arguments:
    01615
    01616     None
    01617
    01618 Return Value:
    01619
    01620     None.
    01621
    01622 --*/
    01623
    01624 {
    01625     PPEB Peb;
    01626     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    01627     PDLL_INIT_ROUTINE InitRoutine;
    01628     PLIST_ENTRY Next;
    01629
    01630     Peb = NtCurrentPeb();
    01631
    01632     RtlEnterCriticalSection(&LoaderLock);
    01633
    01634     try {
    01635
    01636
    01637         //
    01638         // Go in reverse order initialization order and build
    01639         // the unload list
    01640         //
    01641
    01642         Next = Peb->Ldr->InInitializationOrderModuleList.Blink;
    01643         while ( Next != &Peb->Ldr->InInitializationOrderModuleList) {
    01644             LdrDataTableEntry
    01645                 = (PLDR_DATA_TABLE_ENTRY)
    01646                   (CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,InInitializationOrderLinks));
    01647
    01648             Next = Next->Blink;
    01649
    01650             //
    01651             // Walk through the entire list looking for
    01652             // entries. For each entry, that has an init
    01653             // routine, call it.
    01654             //
    01655
    01656             if (Peb->ImageBaseAddress != LdrDataTableEntry->DllBase) {
    01657                 if ( !(LdrDataTableEntry->Flags & LDRP_DONT_CALL_FOR_THREADS)) {
    01658                     InitRoutine = (PDLL_INIT_ROUTINE)LdrDataTableEntry->EntryPoint;
    01659                     if (InitRoutine && (LdrDataTableEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) ) {
    01660                         if (LdrDataTableEntry->Flags & LDRP_IMAGE_DLL) {
    01661                             if ( LdrDataTableEntry->TlsIndex ) {
    01662                                 LdrpCallTlsInitializers(LdrDataTableEntry->DllBase,DLL_THREAD_DETACH);
    01663                                 }
    01664
    01665 #if defined (WX86)
    01666                             if (!Wx86ProcessInit ||
    01667                                 LdrpRunWx86DllEntryPoint(InitRoutine,
    01668                                                         NULL,
    01669                                                         LdrDataTableEntry->DllBase,
    01670                                                         DLL_THREAD_DETACH,
    01671                                                         NULL
    01672                                                         ) ==  STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
    01673 #endif
    01674                                {
    01675                                 LdrpCallInitRoutine(InitRoutine,
    01676                                                     LdrDataTableEntry->DllBase,
    01677                                                     DLL_THREAD_DETACH,
    01678                                                     NULL);
    01679                                 }
    01680                             }
    01681                         }
    01682                     }
    01683                 }
    01684             }
    01685
    01686         //
    01687         // If the image has tls than call its initializers
    01688         //
    01689
    01690         if ( LdrpImageHasTls ) {
    01691             LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_THREAD_DETACH);
    01692             }
    01693         LdrpFreeTls();
    01694
    01695     } finally {
    01696
    01697         RtlLeaveCriticalSection(&LoaderLock);
    01698     }
    01699 }

BOOLEAN NtdllOkayToLockRoutine | ( | IN PVOID | Lock | ) |

Definition at line 236 of file dll/resource.c.

    00239 {
    00240     return TRUE;
    00241 }

PVOID NtdllpAllocateStringRoutine | ( | SIZE_T | NumberOfBytes | ) |

Definition at line 121 of file ldrinit.c.

References RtlAllocateHeap.

Referenced by LdrpInitializeProcess().

    00124 {
    00125     return RtlAllocateHeap(RtlProcessHeap(), 0, NumberOfBytes);
    00126 }

VOID NtdllpFreeStringRoutine | ( | PVOID | Buffer | ) |

Definition at line 129 of file ldrinit.c.

References Buffer, and RtlFreeHeap.

Referenced by LdrpInitializeProcess().

    00132 {
    00133     RtlFreeHeap(RtlProcessHeap(), 0, Buffer);
    00134 }

VOID RtlpInitDeferedCriticalSection | ( | VOID |  | ) |

Definition at line 211 of file dll/resource.c.

References DbgPrint, DeferedCriticalSection, RtlCriticalSectionList, RtlCriticalSectionLock, RtlInitializeCriticalSectionAndSpinCount(), RtlpChainDebugInfo(), RtlpCreateCriticalSectionSem(), RtlpCritSectInitialized, RtlpDebugInfoFreeList, RtlpStaticDebugInfo, and TRUE.

    00212 {
    00213
    00214     InitializeListHead( &RtlCriticalSectionList );
    00215
    00216     if (sizeof( RTL_CRITICAL_SECTION_DEBUG ) != sizeof( RTL_RESOURCE_DEBUG )) {
    00217         DbgPrint( "NTDLL: Critical Section & Resource Debug Info length mismatch.\n" );
    00218         return;
    00219         }
    00220
    00221     RtlpDebugInfoFreeList = RtlpChainDebugInfo( RtlpStaticDebugInfo,
    00222                                                 sizeof( RtlpStaticDebugInfo )
    00223                                               );
    00224
    00225     RtlInitializeCriticalSectionAndSpinCount( &RtlCriticalSectionLock, 1000 );
    00226     RtlInitializeCriticalSectionAndSpinCount( &DeferedCriticalSection, 1000 );
    00227
    00228     RtlpCreateCriticalSectionSem(&DeferedCriticalSection);
    00229
    00230     RtlpCritSectInitialized = TRUE;
    00231     return;
    00232 }

## Variable Documentation

BOOLEAN LdrpImageHasTls = FALSE

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

BOOLEAN LdrpInLdrInit = FALSE

| Definition at line 35 of file ldrinit.c. Referenced by LdrDisableThreadCalloutsForDll(), LdrGetDllHandle(), LdrpCreateDllSection(), LdrpGetProcedureAddress(), LdrpInitialize(), LdrpLoadDll(), LdrpMapDll(), LdrpSnapThunk(), LdrQueryProcessModuleInformation(), and LdrUnloadDll().

BOOLEAN LdrpLdrDatabaseIsSetup = FALSE

| Definition at line 34 of file ldrinit.c. Referenced by LdrpInitializeProcess(), and LdrpLoadDll().

BOOLEAN LdrpShutdownInProgress = FALSE

| Definition at line 31 of file ldrinit.c. Referenced by LdrDisableThreadCalloutsForDll(), LdrpInitializeThread(), LdrShutdownProcess(), LdrUnloadDll(), RtlCheckForOrphanedCriticalSections(), RtlpNotOwnerCriticalSection(), and RtlpWaitForCriticalSection().

BOOLEAN LdrpVerifyDlls = FALSE

| Definition at line 33 of file ldrinit.c. Referenced by LdrpInitializeProcess().

RTL_CRITICAL_SECTION LoaderLock

Initial value:

     {
        &LoaderLockDebug,
        -1
        }

Definition at line 142 of file ldrinit.c.

Referenced by LdrDisableThreadCalloutsForDll(), LdrFlushAlternateResourceModules(), LdrGetDllHandle(), LdrLoadAlternateResourceModule(), LdrpForkProcess(), LdrpGetProcedureAddress(), LdrpInitialize(), LdrpInitializeProcess(), LdrpLoadDll(), LdrQueryProcessModuleInformation(), LdrShutdownProcess(), LdrShutdownThread(), LdrUnloadAlternateResourceModule(), LdrUnloadDll(), RtlAddFunctionTable(), RtlDeleteFunctionTable(), RtlLookupDynamicFunctionEntry(), and RtlPcToFileHeader().

RTL_CRITICAL_SECTION_DEBUG LoaderLockDebug

| Definition at line 141 of file ldrinit.c.

BOOLEAN LoaderLockInitialized

| Definition at line 146 of file ldrinit.c. Referenced by LdrpForkProcess(), LdrpInitialize(), and LdrpInitializeProcess().

PVOID NtDllBase

| Definition at line 45 of file ldrinit.c. Referenced by CsrClientConnectToServer(), LdrpInitializeProcess(), and RtlPcToFileHeader().

PRTL_ALLOCATE_STRING_ROUTINE RtlAllocateStringRoutine

| Definition at line 136 of file ldrinit.c. Referenced by IoInitSystem(), LdrpInitializeProcess(), RtlAnsiStringToUnicodeString(), RtlCreateUnicodeString(), RtlDowncaseUnicodeString(), RtlFormatCurrentUserKeyPath(), RtlOemStringToCountedUnicodeString(), RtlOemStringToUnicodeString(), RtlUnicodeStringToAnsiString(), RtlUnicodeStringToCountedOemString(), RtlUnicodeStringToOemString(), RtlUpcaseUnicodeString(), RtlUpcaseUnicodeStringToAnsiString(), RtlUpcaseUnicodeStringToCountedOemString(), and RtlUpcaseUnicodeStringToOemString().

PRTL_FREE_STRING_ROUTINE RtlFreeStringRoutine

| Definition at line 137 of file ldrinit.c. Referenced by CmpSetVersionData(), LdrpInitializeProcess(), RtlAnsiStringToUnicodeString(), RtlFreeAnsiString(), RtlFreeOemString(), RtlFreeUnicodeString(), RtlOemStringToCountedUnicodeString(), RtlOemStringToUnicodeString(), RtlUnicodeStringToAnsiString(), RtlUnicodeStringToCountedOemString(), RtlUnicodeStringToOemString(), RtlUpcaseUnicodeStringToAnsiString(), RtlUpcaseUnicodeStringToCountedOemString(), and RtlUpcaseUnicodeStringToOemString().

ULONG RtlpDisableHeapLookaside

| Definition at line 47 of file ldrinit.c. Referenced by LdrpInitialize(), and RtlCreateHeap().

RTL_BITMAP TlsBitMap

| Definition at line 138 of file ldrinit.c. Referenced by LdrpInitializeProcess().

RTL_BITMAP TlsExpansionBitMap

| Definition at line 139 of file ldrinit.c. Referenced by LdrpInitializeProcess().