00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <ntos.h>
00022
#include <nt.h>
00023
#include <ntrtl.h>
00024
#include <nturtl.h>
00025
#include <heap.h>
00026
#include <apcompat.h>
00027
#include "ldrp.h"
00028
#include <ctype.h>
00029
00030
00031 BOOLEAN
LdrpShutdownInProgress =
FALSE;
00032 BOOLEAN
LdrpImageHasTls =
FALSE;
00033 BOOLEAN
LdrpVerifyDlls =
FALSE;
00034 BOOLEAN
LdrpLdrDatabaseIsSetup =
FALSE;
00035 BOOLEAN
LdrpInLdrInit =
FALSE;
00036
00037
#if defined(_WIN64)
00038
PVOID Wow64Handle;
00039 ULONG UseWOW64;
00040
typedef VOID (*tWOW64LdrpInitialize)(IN PCONTEXT Context);
00041 tWOW64LdrpInitialize Wow64LdrpInitialize;
00042 PVOID Wow64PrepareForException;
00043
#endif
00044
00045 PVOID
NtDllBase;
00046
00047 extern ULONG
RtlpDisableHeapLookaside;
00048
00049
#if defined(_ALPHA_)
00050
ULONG_PTR LdrpGpValue;
00051
#endif // ALPHA
00052
00053
#if defined (_X86_)
00054
void
00055 LdrpValidateImageForMp(
00056 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry
00057 );
00058
#endif
00059
00060
#if defined (_ALPHA_)
00061
VOID
00062 AlphaFindArchitectureFixups(
00063 PIMAGE_NT_HEADERS NtHeaders,
00064 PVOID ViewBase,
00065 BOOLEAN StaticLink
00066 );
00067
#endif
00068
00069
VOID
00070
LdrpRelocateStartContext (
00071 IN PCONTEXT Context,
00072 IN LONG_PTR Diff
00073 );
00074
00075
NTSTATUS
00076
LdrpForkProcess( VOID );
00077
00078
VOID
00079
LdrpInitializeThread(
00080 IN PCONTEXT Context
00081 );
00082
00083 BOOLEAN
00084
NtdllOkayToLockRoutine(
00085 IN PVOID Lock
00086 );
00087
00088
VOID
00089
RtlpInitDeferedCriticalSection( VOID );
00090
00091
VOID
00092
LdrQueryApplicationCompatibilityGoo(
00093 IN PUNICODE_STRING UnicodeImageName
00094 );
00095
00096
NTSTATUS
00097
LdrFindAppCompatVariableInfo(
00098 IN ULONG dwTypeSeeking,
00099 OUT PAPP_VARIABLE_INFO *AppVariableInfo
00100 );
00101
00102
NTSTATUS
00103
LdrpSearchResourceSection_U(
00104 IN PVOID DllHandle,
00105 IN PULONG_PTR ResourceIdPath,
00106 IN ULONG ResourceIdPathLength,
00107 IN BOOLEAN FindDirectoryEntry,
00108 IN BOOLEAN ExactLangMatchOnly,
00109 OUT PVOID *ResourceDirectoryOrData
00110 );
00111
00112
NTSTATUS
00113
LdrpAccessResourceData(
00114 IN PVOID DllHandle,
00115 IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
00116 OUT PVOID *Address OPTIONAL,
00117 OUT PULONG Size OPTIONAL
00118 );
00119
00120 PVOID
00121 NtdllpAllocateStringRoutine(
00122 SIZE_T NumberOfBytes
00123 )
00124 {
00125
return RtlAllocateHeap(RtlProcessHeap(), 0, NumberOfBytes);
00126 }
00127
00128
VOID
00129 NtdllpFreeStringRoutine(
00130 PVOID Buffer
00131 )
00132 {
00133
RtlFreeHeap(RtlProcessHeap(), 0,
Buffer);
00134 }
00135
00136 PRTL_ALLOCATE_STRING_ROUTINE
RtlAllocateStringRoutine;
00137 PRTL_FREE_STRING_ROUTINE
RtlFreeStringRoutine;
00138 RTL_BITMAP
TlsBitMap;
00139 RTL_BITMAP
TlsExpansionBitMap;
00140
00141 RTL_CRITICAL_SECTION_DEBUG
LoaderLockDebug;
00142 RTL_CRITICAL_SECTION
LoaderLock = {
00143 &
LoaderLockDebug,
00144 -1
00145 };
00146 BOOLEAN
LoaderLockInitialized;
00147
00148
00149
#if defined(_ALPHA_)
00150
VOID
00151 LdrpSetGp(
00152 IN ULONG_PTR GpValue
00153 );
00154
#endif // ALPHA
00155
00156
VOID
00157 LdrpInitializationFailure(
00158 IN NTSTATUS FailureCode
00159 )
00160 {
00161
00162
NTSTATUS ErrorStatus;
00163 ULONG_PTR ErrorParameter;
00164 ULONG ErrorResponse;
00165
00166
if (
LdrpFatalHardErrorCount ) {
00167
return;
00168 }
00169
00170
00171
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 }
00183
00184
00185
VOID
00186 LdrpInitialize (
00187 IN PCONTEXT Context,
00188 IN PVOID SystemArgument1,
00189 IN PVOID SystemArgument2
00190 )
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
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
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
00257
if (
TRUE)
00258
00259
00260
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
00274
00275
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
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
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
00337
00338
00339
00340
LdrQueryImageFileExecutionOptions(
00341 &UnicodeImageName,
00342
L"PageHeapFlags",
00343 REG_DWORD,
00344 &
RtlpDphGlobalFlags,
00345
sizeof(
RtlpDphGlobalFlags),
00346
NULL
00347 );
00348
00349
00350
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
00382
00383
00384
00385
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
00417
00418
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
00434
00435
00436 Peb->LoaderLock = (PVOID)&
LoaderLock;
00437
00438
if ( !RtlTryEnterCriticalSection(&
LoaderLock) ) {
00439
if (
LoaderLockInitialized ) {
00440 RtlEnterCriticalSection(&
LoaderLock);
00441 }
00442
else {
00443
00444
00445
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
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
00546
00547
if (UseWOW64) {
00548 RtlLeaveCriticalSection(&
LoaderLock);
00549 (*Wow64LdrpInitialize)(Context);
00550
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 }
00573
00574
NTSTATUS
00575 LdrpForkProcess( VOID )
00576 {
00577
NTSTATUS st;
00578 PPEB Peb;
00579
00580 Peb = NtCurrentPeb();
00581
00582
00583
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,
00602
NULL,
00603 64 * 1024,
00604 4096,
00605
NULL,
00606
NULL
00607 );
00608
if (Peb->ProcessHeap ==
NULL) {
00609
return STATUS_NO_MEMORY;
00610 }
00611
00612
return st;
00613 }
00614
00615
NTSTATUS
00616 LdrpInitializeProcess (
00617 IN PCONTEXT Context OPTIONAL,
00618 IN PVOID SystemDllBase,
00619 IN PUNICODE_STRING UnicodeImageName
00620 )
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
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
00688
00689
00690
00691
LdrpVerifyDlls =
TRUE;
00692
00693 }
00694
00695
00696 Peb = NtCurrentPeb();
00697
00698
#if defined(BUILD_WOW6432)
00699
{
00700
00701
00702
00703
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
00712 ))) {
00713
return st;
00714 }
00715 }
00716
#elif defined (_ALPHA_) && defined (WX86)
00717
00718
00719
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
00759
00760
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
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
00814
00815
00816
00817
00818
00819
00820
00821
00822
ShowSnaps = (BOOLEAN)(FLG_SHOW_LDR_SNAPS & Peb->NtGlobalFlag);
00823
00824
00825
00826
00827
00828
00829
00830
00831
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
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
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
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
00943
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,
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"
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
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
01037
RtlInitUnicodeString(&
LdrpKnownDllPath, SystemDllPath.Buffer);
01038
LdrpKnownDllPath.Length -=
sizeof(WCHAR);
01039 }
01040
else {
01041
01042
01043
01044
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
01080
01081
01082
01083
01084
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
01109
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
01126
01127
01128
01129
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
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
01178
01179
01180
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
01212
01213
01214 InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList,
01215 &LdrDataTableEntry->InInitializationOrderLinks);
01216
01217
01218
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
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
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
01268
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
01302
01303
01304
01305
if ( Peb->BeingDebugged ) {
01306 DbgBreakPoint();
01307 }
01308
01309
01310
01311
01312 RtlLeaveCriticalSection(&
LoaderLock);
01313
01314
01315
01316
01317 (*Wow64LdrpInitialize)(Context);
01318
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
01332
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
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
01380
01381
01382 AlphaFindArchitectureFixups(NtHeader, NtCurrentPeb()->ImageBaseAddress,
TRUE);
01383
#endif
01384
01385
LdrpReferenceLoadedDll(
LdrpImageEntry);
01386
01387
01388
01389
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
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
01426
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
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 }
01459
01460
01461
VOID
01462 LdrShutdownProcess (
01463 VOID
01464 )
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
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
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
01522
01523
01524
01525
01526
01527
01528
01529
01530
if (
RtlpHeapIsLocked( RtlProcessHeap() )) {
01531 ;
01532 }
01533
else {
01534
if ( Peb->BeingDebugged ) {
01535
RtlValidateProcessHeaps();
01536 }
01537
01538
01539
01540
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
01553
01554
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
01588
01589
01590
if (
LdrpImageHasTls ) {
01591
LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_PROCESS_DETACH);
01592 }
01593 }
01594
01595 } finally {
01596 RtlLeaveCriticalSection(&
LoaderLock);
01597 }
01598
01599 }
01600
01601
VOID
01602 LdrShutdownThread (
01603 VOID
01604 )
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
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
01639
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
01652
01653
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
01688
01689
01690
if (
LdrpImageHasTls ) {
01691
LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_THREAD_DETACH);
01692 }
01693
LdrpFreeTls();
01694
01695 } finally {
01696
01697 RtlLeaveCriticalSection(&
LoaderLock);
01698 }
01699 }
01700
01701
VOID
01702 LdrpInitializeThread(
01703 IN PCONTEXT Context
01704 )
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
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
01746
01747
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
01786
01787
01788
if (
LdrpImageHasTls && !
LdrpShutdownInProgress ) {
01789
LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_THREAD_ATTACH);
01790 }
01791
01792 }
01793
01794
01795
NTSTATUS
01796 LdrQueryImageFileExecutionOptions(
01797 IN PUNICODE_STRING ImagePathName,
01798 IN PWSTR OptionName,
01799 IN ULONG Type,
01800 OUT PVOID Buffer,
01801 IN ULONG BufferSize,
01802 OUT PULONG ResultSize OPTIONAL
01803 )
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
01869
01870
01871
01872
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 }
01975
01976
01977
NTSTATUS
01978 LdrpInitializeTls(
01979 VOID
01980 )
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
01993
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
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
02037
02038
02039 Entry->LoadCount = (
USHORT)0xffff;
02040
02041
02042
02043
02044
02045 Entry->TlsIndex = (
USHORT)0xffff;
02046
02047 TlsEntry->Tls = *TlsImage;
02048 InsertTailList(&
LdrpTlsList,&TlsEntry->Links);
02049
02050
02051
02052
02053
02054
02055 *(PLONG)TlsEntry->Tls.AddressOfIndex =
LdrpNumberOfTlsEntries;
02056 TlsEntry->Tls.Characteristics =
LdrpNumberOfTlsEntries++;
02057 }
02058 }
02059
02060
02061
02062
02063
02064
02065
02066
02067
return LdrpAllocateTls();
02068 }
02069
02070
NTSTATUS
02071 LdrpAllocateTls(
02072 VOID
02073 )
02074 {
02075 PTEB Teb;
02076 PLIST_ENTRY Head, Next;
02077
PLDRP_TLS_ENTRY TlsEntry;
02078 PVOID *TlsVector;
02079
02080 Teb = NtCurrentTeb();
02081
02082
02083
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
02126
02127
02128 }
02129 }
02130
return STATUS_SUCCESS;
02131 }
02132
02133
VOID
02134 LdrpFreeTls(
02135 VOID
02136 )
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
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 }
02176
02177
VOID
02178 LdrpCallTlsInitializers(
02179 PVOID DllBase,
02180 ULONG Reason
02181 )
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 }
02243
02244
02245
02246 ULONG
GetNextCommaValue( IN OUT WCHAR **p, IN OUT ULONG *len )
02247 {
02248 ULONG Number = 0;
02249
02250
while (*len && (UNICODE_NULL != **p) && **p !=
L',')
02251 {
02252
02253
if (
L' ' != **p )
02254 {
02255 Number = (Number * 10) + ( (ULONG)**p -
L'0' );
02256 }
02257
02258 (*p)++;
02259 (*len)--;
02260 }
02261
02262
02263
02264
02265
if (
L',' == **p )
02266 {
02267 (*p)++;
02268 (*len)--;
02269 }
02270
02271
return Number;
02272 }
02273
02274
02275
02276
VOID
02277 LdrQueryApplicationCompatibilityGoo(
02278 IN PUNICODE_STRING UnicodeImageName
02279 )
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
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 ];
02329 BOOLEAN fNewCSDVersionBuffer =
FALSE;
02330
02331
struct {
02332
USHORT TotalSize;
02333
USHORT DataSize;
02334
USHORT Type;
02335 WCHAR
Name[16];
02336 } *
Resource;
02337
02338
02339
02340
02341
02342
02343
02344
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
02360
02361
if (st == STATUS_BUFFER_OVERFLOW) {
02362
02363
02364
02365
02366 AppCompatGoo = \
02367
RtlAllocateHeap(Peb->ProcessHeap, HEAP_ZERO_MEMORY, ResultSize);
02368
02369
if (!AppCompatGoo) {
02370
return;
02371 }
02372
02373
02374
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
02391
02392
02393
02394
02395
02396
02397
02398 bImageContainsVersionResourceInfo =
FALSE;
02399
02400 IdPath[0] = 16;
02401 IdPath[1] = 1;
02402 IdPath[2] = 0;
02403
02404
02405
02406
02407
try {
02408 st =
LdrpSearchResourceSection_U(
02409 Peb->ImageBaseAddress,
02410 IdPath,
02411 3,
02412
FALSE,
02413
FALSE,
02414 &DataEntry
02415 );
02416
02417 } except(
EXCEPTION_EXECUTE_HANDLER) {
02418 st = STATUS_UNSUCCESSFUL;
02419 }
02420
02421
if (
NT_SUCCESS( st )) {
02422
02423
02424
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
02446
02447
02448
02449
02450
02451
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
02463
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
02484
02485
02486
02487
02488
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
02503
02504 TotalGooLength -= AppCompatEntry->dwEntryTotalSize;
02505 (PUCHAR) AppCompatEntry += AppCompatEntry->dwEntryTotalSize;
02506
continue;
02507 }
02508
02509
02510
02511
02512
02513
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
02529
02530
02531 RtlMoveMemory(
02532 &AppCompatInfo->CompatibilityFlags,
02533 (PUCHAR) ResourceInfo + AppCompatEntry->dwResourceInfoSize,
02534 AppCompatInfo->dwTotalSize - FIELD_OFFSET(APP_COMPAT_INFO, CompatibilityFlags)
02535 );
02536
02537
02538
02539
02540
02541
02542
if (AppCompatInfo->CompatibilityFlags.QuadPart & KACF_VERSIONLIE) {
02543
02544
02545
02546
02547
if( STATUS_SUCCESS !=
LdrFindAppCompatVariableInfo(AVT_OSVERSIONINFO, &AppVariableInfo)) {
02548
break;
02549 }
02550
02551
02552
02553
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
02591
02592
if (
FALSE == fNewCSDVersionBuffer )
02593 {
02594
02595
02596
02597
02598
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
02615
02616
02617
02618
if ( STATUS_SUCCESS == st )
02619 {
02620 WCHAR *p = EnvValue.Buffer;
02621 WCHAR *NewSPString;
02622 ULONG len = EnvValue.Length /
sizeof(WCHAR);
02623
02624
02625
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
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
02660
02661
02662
02663
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 }
02680
02681
02682
NTSTATUS
02683 LdrFindAppCompatVariableInfo(
02684 IN ULONG dwTypeSeeking,
02685 OUT PAPP_VARIABLE_INFO *AppVariableInfo
02686 )
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
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
02720
02721
02722 TotalSize = ((PAPP_COMPAT_INFO) Peb->AppCompatInfo)->dwTotalSize;
02723
02724
02725
02726
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
02736
02737
if (dwTypeSeeking == pCurrentEntry->dwVariableType) {
02738 *AppVariableInfo = pCurrentEntry;
02739
return (STATUS_SUCCESS);
02740 }
02741
02742
02743
02744
02745 CurOffset += (ULONG)(pCurrentEntry->dwVariableInfoSize);
02746 }
02747
02748 }
02749
02750
return (STATUS_NOT_FOUND);
02751 }