00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
#include "mi.h"
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 typedef struct _LOAD_IMPORTS {
00042     SIZE_T                  
Count;
00043     PLDR_DATA_TABLE_ENTRY   
Entry[1];
00044 } 
LOAD_IMPORTS, *
PLOAD_IMPORTS;
00045 
00046 #define LOADED_AT_BOOT  ((PLOAD_IMPORTS)0)
00047 #define NO_IMPORTS_USED ((PLOAD_IMPORTS)-2)
00048 
00049 #define SINGLE_ENTRY(ImportVoid)    ((ULONG)((ULONG_PTR)(ImportVoid) & 0x1))
00050 
00051 #define SINGLE_ENTRY_TO_POINTER(ImportVoid)    ((PLDR_DATA_TABLE_ENTRY)((ULONG_PTR)(ImportVoid) & ~0x1))
00052 
00053 #define POINTER_TO_SINGLE_ENTRY(Pointer)    ((PLDR_DATA_TABLE_ENTRY)((ULONG_PTR)(Pointer) | 0x1))
00054 
00055 KMUTANT MmSystemLoadLock;
00056 
00057 ULONG 
MmTotalSystemDriverPages;
00058 
00059 ULONG 
MmDriverCommit;
00060 
00061 BOOLEAN 
MiFirstDriverLoadEver = 
TRUE;
00062 
00063 
00064 
00065 
00066 
00067 
00068 LOGICAL 
MmMakeLowMemory = 
TRUE;
00069 
00070 
00071 
00072 
00073 
00074 
00075 PUNLOADED_DRIVERS MiUnloadedDrivers;
00076 
00077 ULONG 
MiLastUnloadedDriver;
00078 ULONG 
MiTotalUnloads;
00079 ULONG 
MiUnloadsSkipped;
00080 
00081 
00082 
00083 
00084 
00085 ULONG 
MmEnforceWriteProtection = 1;
00086 
00087 
00088 
00089 
00090 
00091 PVOID 
ExPoolCodeStart;
00092 PVOID 
ExPoolCodeEnd;
00093 PVOID 
MmPoolCodeStart;
00094 PVOID 
MmPoolCodeEnd;
00095 PVOID 
MmPteCodeStart;
00096 PVOID 
MmPteCodeEnd;
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 extern KSPIN_LOCK 
PsLoadedModuleSpinLock;
00107 
00108 ULONG
00109 
LdrDoubleRelocateImage (
00110     IN PVOID NewBase,
00111     IN PVOID CurrentBase,
00112     IN PUCHAR LoaderName,
00113     IN ULONG Success,
00114     IN ULONG Conflict,
00115     IN ULONG Invalid
00116     );
00117 
00118 
#if DBG
00119 
PFN_NUMBER MiPagesConsumed;
00120 
#endif
00121 
00122 ULONG
00123 
CacheImageSymbols(
00124     IN PVOID ImageBase
00125     );
00126 
00127 
NTSTATUS
00128 
MiResolveImageReferences(
00129     PVOID ImageBase,
00130     IN PUNICODE_STRING ImageFileDirectory,
00131     IN PUNICODE_STRING NamePrefix OPTIONAL,
00132     IN BOOLEAN LoadInSessionSpace,
00133     OUT PCHAR *MissingProcedureName,
00134     OUT PWSTR *MissingDriverName,
00135     OUT PLOAD_IMPORTS *LoadedImports
00136     );
00137 
00138 
NTSTATUS
00139 
MiSnapThunk(
00140     IN PVOID DllBase,
00141     IN PVOID ImageBase,
00142     IN PIMAGE_THUNK_DATA NameThunk,
00143     OUT PIMAGE_THUNK_DATA AddrThunk,
00144     IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
00145     IN ULONG ExportSize,
00146     IN BOOLEAN SnapForwarder,
00147     OUT PCHAR *MissingProcedureName
00148     );
00149 
00150 
NTSTATUS
00151 
MiLoadImageSection (
00152     IN PSECTION SectionPointer,
00153     OUT PVOID *ImageBase,
00154     IN PUNICODE_STRING ImageFileName,
00155     IN BOOLEAN LoadInSessionSpace
00156     );
00157 
00158 
VOID
00159 
MiEnablePagingOfDriver (
00160     IN PVOID ImageHandle
00161     );
00162 
00163 
VOID
00164 
MiSetPagingOfDriver (
00165     IN 
PMMPTE PointerPte,
00166     IN 
PMMPTE LastPte,
00167     IN BOOLEAN SessionSpace
00168     );
00169 
00170 PVOID
00171 
MiLookupImageSectionByName (
00172     IN PVOID Base,
00173     IN BOOLEAN MappedAsImage,
00174     IN PCHAR SectionName,
00175     OUT PULONG SectionSize
00176     );
00177 
00178 
VOID
00179 
MiClearImports(
00180     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
00181     );
00182 
00183 
NTSTATUS
00184 
MiBuildImportsForBootDrivers(
00185     VOID
00186     );
00187 
00188 
NTSTATUS
00189 
MmCheckSystemImage(
00190     IN HANDLE ImageFileHandle
00191     );
00192 
00193 LONG
00194 
MiMapCacheExceptionFilter (
00195     OUT PNTSTATUS Status,
00196     IN PEXCEPTION_POINTERS ExceptionPointer
00197     );
00198 
00199 ULONG
00200 
MiSetProtectionOnTransitionPte (
00201     IN 
PMMPTE PointerPte,
00202     IN ULONG ProtectionMask
00203     );
00204 
00205 
NTSTATUS
00206 
MiDereferenceImports (
00207     IN PLOAD_IMPORTS ImportList
00208     );
00209 
00210 LOGICAL
00211 
MiCallDllUnloadAndUnloadDll(
00212     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
00213     );
00214 
00215 PVOID
00216 
MiLocateExportName (
00217     IN PVOID DllBase,
00218     IN PCHAR FunctionName
00219     );
00220 
00221 
NTSTATUS
00222 
MiLoadSystemImage (
00223     IN PUNICODE_STRING ImageFileName,
00224     IN PUNICODE_STRING NamePrefix OPTIONAL,
00225     IN PUNICODE_STRING LoadedBaseName OPTIONAL,
00226     IN BOOLEAN LoadInSessionSpace,
00227     OUT PVOID *ImageHandle,
00228     OUT PVOID *ImageBaseAddress,
00229     IN BOOLEAN LockDownPages
00230     );
00231 
00232 
VOID
00233 
MiRememberUnloadedDriver (
00234     IN PUNICODE_STRING DriverName,
00235     IN PVOID Address,
00236     IN ULONG Length
00237     );
00238 
00239 
VOID
00240 
MiWriteProtectSystemImage (
00241     IN PVOID DllBase
00242     );
00243 
00244 
VOID
00245 
MiLocateKernelSections (
00246     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
00247     );
00248 
00249 
VOID
00250 
MiUpdateThunks (
00251     IN 
PLOADER_PARAMETER_BLOCK LoaderBlock,
00252     IN PVOID OldAddress,
00253     IN PVOID NewAddress,
00254     IN ULONG NumberOfBytes
00255     );
00256 
00257 
NTSTATUS
00258 
MiCheckPageFilePath (
00259     
PFILE_OBJECT FileObject
00260     );
00261 
00262 PVOID
00263 
MiFindExportedRoutineByName(
00264     IN PLDR_DATA_TABLE_ENTRY DataTableEntry,
00265     IN PANSI_STRING AnsiImageRoutineName
00266     );
00267 
00268 extern LOGICAL 
MiNoLowMemory;
00269 
00270 
VOID
00271 
MiRemoveLowPages (
00272     VOID
00273     );
00274 
00275 
#ifdef ALLOC_PRAGMA
00276 
#pragma alloc_text(PAGE,MmCheckSystemImage)
00277 
#pragma alloc_text(PAGE,MmLoadSystemImage)
00278 
#pragma alloc_text(PAGE,MmLoadAndLockSystemImage)
00279 
#pragma alloc_text(PAGE,MiLoadSystemImage)
00280 
#pragma alloc_text(PAGE,MiResolveImageReferences)
00281 
#pragma alloc_text(PAGE,MiSnapThunk)
00282 
#pragma alloc_text(PAGE,MiEnablePagingOfDriver)
00283 
#pragma alloc_text(PAGE,MmPageEntireDriver)
00284 
#pragma alloc_text(PAGE,MiSetImageProtect)
00285 
#pragma alloc_text(PAGE,MiDereferenceImports)
00286 
#pragma alloc_text(PAGE,MiCallDllUnloadAndUnloadDll)
00287 
#pragma alloc_text(PAGE,MiLocateExportName)
00288 
#pragma alloc_text(PAGE,MiClearImports)
00289 
#pragma alloc_text(PAGE,MiWriteProtectSystemImage)
00290 
#pragma alloc_text(PAGE,MmGetSystemRoutineAddress)
00291 
#pragma alloc_text(PAGE,MiFindExportedRoutineByName)
00292 
#pragma alloc_text(INIT,MiBuildImportsForBootDrivers)
00293 
#pragma alloc_text(INIT,MiReloadBootLoadedDrivers)
00294 
#pragma alloc_text(INIT,MiUpdateThunks)
00295 
#pragma alloc_text(INIT,MiInitializeLoadedModuleList)
00296 
#pragma alloc_text(INIT,MiLocateKernelSections)
00297 
#pragma alloc_text(INIT,MmCallDllInitialize)
00298 
00299 
#if !defined(NT_UP)
00300 
#pragma alloc_text(PAGE,MmVerifyImageIsOkForMpUse)
00301 
#endif // NT_UP
00302 
00303 
#pragma alloc_text(PAGELK,MiLoadImageSection)
00304 
#pragma alloc_text(PAGELK,MmFreeDriverInitialization)
00305 
#pragma alloc_text(PAGELK,MmUnloadSystemImage)
00306 
#pragma alloc_text(PAGELK,MiRememberUnloadedDriver)
00307 
#pragma alloc_text(PAGELK,MiSetPagingOfDriver)
00308 
#pragma alloc_text(PAGELK,MmResetDriverPaging)
00309 
#endif
00310 
00311 CHAR MiPteStr[] = 
"\0";
00312 
00313 
00314 
NTSTATUS
00315 MmLoadSystemImage (
00316     IN PUNICODE_STRING ImageFileName,
00317     IN PUNICODE_STRING NamePrefix OPTIONAL,
00318     IN PUNICODE_STRING LoadedBaseName OPTIONAL,
00319     IN BOOLEAN LoadInSessionSpace,
00320     OUT PVOID *ImageHandle,
00321     OUT PVOID *ImageBaseAddress
00322     )
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 {
00365     
PAGED_CODE();
00366 
00367     
return MiLoadSystemImage (
00368         ImageFileName,
00369         NamePrefix,
00370         LoadedBaseName,
00371         LoadInSessionSpace,
00372         ImageHandle,
00373         ImageBaseAddress,
00374         
FALSE
00375         );
00376 }
00377 
00378 
NTSTATUS
00379 MmLoadAndLockSystemImage (
00380     IN PUNICODE_STRING ImageFileName,
00381     IN PUNICODE_STRING NamePrefix OPTIONAL,
00382     IN PUNICODE_STRING LoadedBaseName OPTIONAL,
00383     OUT PVOID *ImageHandle,
00384     OUT PVOID *ImageBaseAddress
00385     )
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 {
00428     
PAGED_CODE();
00429 
00430     
return MiLoadSystemImage (
00431         ImageFileName,
00432         NamePrefix,
00433         LoadedBaseName,
00434         
FALSE,
00435         ImageHandle,
00436         ImageBaseAddress,
00437         
TRUE
00438         );
00439 }
00440 
00441 
00442 
NTSTATUS
00443 MiLoadSystemImage (
00444     IN PUNICODE_STRING ImageFileName,
00445     IN PUNICODE_STRING NamePrefix OPTIONAL,
00446     IN PUNICODE_STRING LoadedBaseName OPTIONAL,
00447     IN BOOLEAN LoadInSessionSpace,
00448     OUT PVOID *ImageHandle,
00449     OUT PVOID *ImageBaseAddress,
00450     IN BOOLEAN LockDownPages
00451     )
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 {
00494     KIRQL OldIrql;
00495     PLDR_DATA_TABLE_ENTRY DataTableEntry;
00496     LDR_DATA_TABLE_ENTRY TempDataTableEntry;
00497     
NTSTATUS Status;
00498     
PSECTION SectionPointer;
00499     PIMAGE_NT_HEADERS NtHeaders;
00500     UNICODE_STRING PrefixedImageName;
00501     UNICODE_STRING 
BaseName;
00502     UNICODE_STRING BaseDirectory;
00503     OBJECT_ATTRIBUTES 
ObjectAttributes;
00504     HANDLE FileHandle;
00505     HANDLE SectionHandle;
00506     IO_STATUS_BLOCK IoStatus;
00507     
CHAR NameBuffer[ MAXIMUM_FILENAME_LENGTH ];
00508     PLIST_ENTRY NextEntry;
00509     ULONG NumberOfPtes;
00510     ULONG_PTR ViewSize;
00511     PCHAR MissingProcedureName;
00512     PWSTR MissingDriverName;
00513     
PLOAD_IMPORTS LoadedImports;
00514     
PMMSESSION Session;
00515     BOOLEAN AlreadyOpen;
00516     BOOLEAN IssueUnloadOnFailure;
00517     ULONG SectionAccess;
00518     
volatile PMMPTE PointerPpe;
00519     
MMPTE PpeContents;
00520 
00521     
PAGED_CODE();
00522 
00523     LoadedImports = (
PLOAD_IMPORTS)
NO_IMPORTS_USED;
00524     SectionPointer = (PVOID)-1;
00525     FileHandle = (HANDLE)0;
00526     MissingProcedureName = 
NULL;
00527     MissingDriverName = 
NULL;
00528     IssueUnloadOnFailure = 
FALSE;
00529 
00530     
if (LoadInSessionSpace == 
TRUE) {
00531 
00532         
ASSERT (NamePrefix == 
NULL);
00533         
ASSERT (LoadedBaseName == 
NULL);
00534 
00535         
if (
MiHydra == 
TRUE) {
00536 
00537             
if (
PsGetCurrentProcess()->Vm.u.Flags.ProcessInSession == 0) {
00538 
#if DBG
00539 
                DbgPrint (
"MiLoadSystemImage: no session space!\n");
00540 
#endif
00541 
                return STATUS_NO_MEMORY;
00542             }
00543 
00544             
ASSERT (
MmIsAddressValid (
MmSessionSpace) == 
TRUE);
00545 
00546             Session = &
MmSessionSpace->
Session;
00547         }
00548         
else {
00549             Session = &
MmSession;
00550             LoadInSessionSpace = 
FALSE;
00551         }
00552     }
00553     
else {
00554         Session = &
MmSession;
00555     }
00556 
00557     
00558     
00559     
00560 
00561     
if (ImageFileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) {
00562         PWCHAR p;
00563         ULONG l;
00564 
00565         p = &ImageFileName->Buffer[ImageFileName->Length>>1];
00566         
while (*(p-1) != OBJ_NAME_PATH_SEPARATOR) {
00567             p--;
00568         }
00569         l = (ULONG)(&ImageFileName->Buffer[ImageFileName->Length>>1] - p);
00570         l *= 
sizeof(WCHAR);
00571         
BaseName.Length = (
USHORT)l;
00572         
BaseName.Buffer = p;
00573     } 
else {
00574         
BaseName.Length = ImageFileName->Length;
00575         
BaseName.Buffer = ImageFileName->Buffer;
00576     }
00577 
00578     
BaseName.MaximumLength = 
BaseName.Length;
00579     BaseDirectory = *ImageFileName;
00580     BaseDirectory.Length -= 
BaseName.Length;
00581     BaseDirectory.MaximumLength = BaseDirectory.Length;
00582     PrefixedImageName = *ImageFileName;
00583 
00584     
00585     
00586     
00587 
00588     
if (NamePrefix) {
00589         PrefixedImageName.MaximumLength =
00590                 BaseDirectory.Length + NamePrefix->Length + 
BaseName.Length;
00591 
00592         PrefixedImageName.Buffer = 
ExAllocatePoolWithTag (
00593                                     
NonPagedPool,
00594                                     PrefixedImageName.MaximumLength,
00595                                     'dLmM'
00596                                     );
00597 
00598         
if (!PrefixedImageName.Buffer) {
00599             
return STATUS_INSUFFICIENT_RESOURCES;
00600         }
00601 
00602         PrefixedImageName.Length = 0;
00603         
RtlAppendUnicodeStringToString(&PrefixedImageName, &BaseDirectory);
00604         
RtlAppendUnicodeStringToString(&PrefixedImageName, NamePrefix);
00605         
RtlAppendUnicodeStringToString(&PrefixedImageName, &
BaseName);
00606 
00607         
00608         
00609         
00610 
00611         
BaseName.Buffer = PrefixedImageName.Buffer + BaseDirectory.Length / 
sizeof(WCHAR);
00612         
BaseName.Length += NamePrefix->Length;
00613         
BaseName.MaximumLength += NamePrefix->Length;
00614     }
00615 
00616     
00617     
00618     
00619 
00620     
if (LoadedBaseName) {
00621         
BaseName = *LoadedBaseName;
00622     }
00623 
00624 
#if DBG
00625 
    if ( 
NtGlobalFlag & FLG_SHOW_LDR_SNAPS ) {
00626         
DbgPrint( 
"MM:SYSLDR Loading %wZ (%wZ) %s\n",
00627             &PrefixedImageName,
00628             &
BaseName,
00629             LoadInSessionSpace ? 
"in session space" : 
" ");
00630     }
00631 
#endif
00632 
00633     AlreadyOpen = 
FALSE;
00634 
00635     
00636     
00637     
00638 
00639     
KeEnterCriticalRegion();
00640 
00641     
KeWaitForSingleObject (&
MmSystemLoadLock,
00642                            
WrVirtualMemory,
00643                            
KernelMode,
00644                            
FALSE,
00645                            (PLARGE_INTEGER)
NULL);
00646 
00647     
00648     
00649     
00650 
00651     NextEntry = 
PsLoadedModuleList.Flink;
00652     
while (NextEntry != &
PsLoadedModuleList) {
00653 
00654         DataTableEntry = CONTAINING_RECORD(NextEntry,
00655                                            LDR_DATA_TABLE_ENTRY,
00656                                            InLoadOrderLinks);
00657 
00658         
if (
RtlEqualUnicodeString (&PrefixedImageName,
00659                                    &DataTableEntry->FullDllName,
00660                                    
TRUE)) {
00661 
00662             
if (LoadInSessionSpace == 
TRUE) {
00663 
00664                 
if (
MI_IS_SESSION_ADDRESS (DataTableEntry->DllBase) == 
FALSE) {
00665 
00666                     
00667                     
00668                     
00669                     
00670                     
00671 
00672                     
Status = STATUS_CONFLICTING_ADDRESSES;
00673                     
goto return2;
00674                 }
00675 
00676                 AlreadyOpen = 
TRUE;
00677 
00678                 
00679                 
00680                 
00681                 
00682                 
00683                 
00684 
00685                 DataTableEntry->LoadCount += 1;
00686                 SectionPointer = DataTableEntry->SectionPointer;
00687                 
break;
00688             }
00689             
else {
00690                 
if (
MI_IS_SESSION_ADDRESS (DataTableEntry->DllBase) == 
TRUE) {
00691 
00692                     
00693                     
00694                     
00695                     
00696                     
00697 
00698                     
Status = STATUS_CONFLICTING_ADDRESSES;
00699                     
goto return2;
00700                 }
00701             }
00702 
00703             *ImageHandle = DataTableEntry;
00704             *ImageBaseAddress = DataTableEntry->DllBase;
00705             
Status = STATUS_IMAGE_ALREADY_LOADED;
00706             
goto return2;
00707         }
00708 
00709         NextEntry = NextEntry->Flink;
00710     }
00711 
00712     
ASSERT (AlreadyOpen == 
TRUE || NextEntry == &
PsLoadedModuleList);
00713 
00714     
if (AlreadyOpen == 
FALSE) {
00715 
00716         DataTableEntry = 
NULL;
00717 
00718         
00719         
00720         
00721         
00722 
00723         InitializeObjectAttributes (&
ObjectAttributes,
00724                                     ImageFileName,
00725                                     OBJ_CASE_INSENSITIVE,
00726                                     
NULL,
00727                                     
NULL );
00728 
00729         
Status = 
ZwOpenFile (&FileHandle,
00730                              FILE_EXECUTE,
00731                              &
ObjectAttributes,
00732                              &IoStatus,
00733                              FILE_SHARE_READ | FILE_SHARE_DELETE,
00734                              0 );
00735 
00736         
if (!
NT_SUCCESS(
Status)) {
00737 
00738 
#if DBG
00739 
            if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
00740                 
DbgPrint (
"MiLoadImageSection: cannot open %wZ\n",
00741                     ImageFileName);
00742             }
00743 
#endif
00744 
            
00745             
00746             
00747 
00748             
goto return2;
00749         }
00750 
00751         
Status = 
MmCheckSystemImage(FileHandle);
00752         
if ((
Status == STATUS_IMAGE_CHECKSUM_MISMATCH) ||
00753             (
Status == STATUS_IMAGE_MP_UP_MISMATCH) ||
00754             (
Status == STATUS_INVALID_IMAGE_PROTECT)) {
00755             
goto return1;
00756         }
00757 
00758         
00759         
00760         
00761         
00762         
00763 
00764         
if (LoadInSessionSpace == 
TRUE) {
00765             SectionAccess = SECTION_MAP_READ | SECTION_MAP_EXECUTE;
00766         }
00767         
else {
00768             SectionAccess = SECTION_ALL_ACCESS;
00769         }
00770 
00771         
Status = ZwCreateSection (&SectionHandle,
00772                                   SectionAccess,
00773                                   (POBJECT_ATTRIBUTES) 
NULL,
00774                                   (PLARGE_INTEGER) 
NULL,
00775                                   PAGE_EXECUTE,
00776                                   SEC_IMAGE,
00777                                   FileHandle );
00778 
00779         
if (!
NT_SUCCESS(
Status)) {
00780             
goto return1;
00781         }
00782 
00783         
00784         
00785         
00786 
00787         
Status = 
ObReferenceObjectByHandle (SectionHandle,
00788                                         SECTION_MAP_EXECUTE,
00789                                         
MmSectionObjectType,
00790                                         
KernelMode,
00791                                         (PVOID *) &SectionPointer,
00792                                         (
POBJECT_HANDLE_INFORMATION) 
NULL );
00793 
00794         ZwClose (SectionHandle);
00795         
if (!
NT_SUCCESS (
Status)) {
00796             
goto return1;
00797         }
00798 
00799         
if (SectionPointer->Segment->ControlArea->NumberOfSubsections == 1) {
00800             
if ((LoadInSessionSpace == 
FALSE) &&
00801                 (SectionPointer->Segment->BasedAddress != (PVOID)Session->
SystemSpaceViewStart)) {
00802 
00803                 
PSECTION SectionPointer2;
00804 
00805                 
00806                 
00807                 
00808                 
00809                 
00810                 
00811                 
00812 
00813                 
Status = ZwCreateSection (&SectionHandle,
00814                                           SectionAccess,
00815                                           (POBJECT_ATTRIBUTES) 
NULL,
00816                                           (PLARGE_INTEGER) 
NULL,
00817                                           PAGE_EXECUTE,
00818                                           SEC_COMMIT,
00819                                           FileHandle );
00820 
00821                 
if (
NT_SUCCESS(
Status)) {
00822 
00823                     
Status = 
ObReferenceObjectByHandle (
00824                                             SectionHandle,
00825                                             SECTION_MAP_EXECUTE,
00826                                             
MmSectionObjectType,
00827                                             
KernelMode,
00828                                             (PVOID *) &SectionPointer2,
00829                                             (
POBJECT_HANDLE_INFORMATION) 
NULL );
00830 
00831                     ZwClose (SectionHandle);
00832 
00833                     
if (
NT_SUCCESS (
Status)) {
00834 
00835                         
00836                         
00837                         
00838                         
00839                         
00840                         
00841                         
00842 
00843                         
if (SectionPointer->Segment->TotalNumberOfPtes == SectionPointer2->Segment->TotalNumberOfPtes) {
00844                             
ObDereferenceObject (SectionPointer);
00845                             SectionPointer = SectionPointer2;
00846                         }
00847                         
else {
00848                             
ObDereferenceObject (SectionPointer2);
00849                         }
00850                     }
00851                 }
00852             }
00853         }
00854 
00855     }
00856 
00857     
if ((LoadInSessionSpace == 
FALSE) &&
00858         (SectionPointer->Segment->BasedAddress == (PVOID)Session->
SystemSpaceViewStart) &&
00859         (SectionPointer->Segment->ControlArea->NumberOfMappedViews == 0)) {
00860         NumberOfPtes = 0;
00861         ViewSize = 0;
00862 
00863         
Status = 
MmMapViewInSystemSpace (SectionPointer,
00864                                          ImageBaseAddress,
00865                                          &ViewSize);
00866         
if ((
NT_SUCCESS( 
Status ) &&
00867             (*ImageBaseAddress == SectionPointer->Segment->BasedAddress))) {
00868 
00869             SectionPointer->Segment->SystemImageBase = *ImageBaseAddress;
00870             SectionPointer->Segment->ControlArea->u.Flags.ImageMappedInSystemSpace = 1;
00871             NumberOfPtes = (ULONG)((ViewSize + 1) >> 
PAGE_SHIFT);
00872             
MiSetImageProtect(SectionPointer->Segment, 
MM_EXECUTE_READWRITE);
00873 
00874 
#if defined (_AXP64_)
00875 
00876             
00877             
00878             
00879             
00880             
00881             
00882 
00883             PointerPpe = 
MiGetPpeAddress (*ImageBaseAddress);
00884             
ASSERT (PointerPpe->
u.Long != 0);
00885             PpeContents = *PointerPpe;
00886             
KeAttachProcess (&
PsInitialSystemProcess->
Pcb);
00887             
ASSERT (PointerPpe->u.Long == 0);
00888             *PointerPpe = PpeContents;
00889             
KeDetachProcess();
00890 
#endif
00891 
            goto BindImage;
00892         }
00893     }
00894 
00895     
MmLockPagableSectionByHandle (
ExPageLockHandle);
00896 
00897     
00898     
00899     
00900     
00901     
00902     
00903     
00904     
00905     
00906 
00907     
Status = 
MiLoadImageSection (SectionPointer,
00908                                  ImageBaseAddress,
00909                                  ImageFileName,
00910                                  LoadInSessionSpace);
00911 
00912     
MmUnlockPagableImageSection (
ExPageLockHandle);
00913 
00914     NumberOfPtes = SectionPointer->Segment->TotalNumberOfPtes;
00915 
00916     
if (
Status == STATUS_ALREADY_COMMITTED) {
00917 
00918         
00919         
00920         
00921         
00922         
00923         
00924 
00925         
ASSERT (
MiHydra == 
TRUE);
00926         
ASSERT (AlreadyOpen == 
TRUE);
00927         
ASSERT (LoadInSessionSpace == 
TRUE);
00928         
ASSERT (DataTableEntry != 
NULL);
00929         
ASSERT (DataTableEntry->LoadCount > 1);
00930 
00931         *ImageHandle = DataTableEntry;
00932         *ImageBaseAddress = DataTableEntry->DllBase;
00933 
00934         DataTableEntry->LoadCount -= 1;
00935         
Status = STATUS_SUCCESS;
00936         
goto return1;
00937     }
00938 
00939     
if (
MiFirstDriverLoadEver == 
TRUE) {
00940 
00941         
NTSTATUS PagingPathStatus;
00942 
00943         
00944         
00945         
00946         
00947         
00948         
00949         
00950 
00951         
00952         
00953         
00954         
00955         
00956         
00957 
00958         PagingPathStatus = 
MiCheckPageFilePath (SectionPointer->Segment->ControlArea->FilePointer);
00959 
00960         
if (!
NT_SUCCESS(PagingPathStatus)) {
00961 
00962             KdPrint(( 
"MiCheckPageFilePath FAILED for win32k.sys: %x\n",
00963                 PagingPathStatus ));
00964 
00965             
00966             
00967             
00968             
00969             
00970             
00971         }
00972 
00973         
MiFirstDriverLoadEver = 
FALSE;
00974     }
00975 
00976     
00977     
00978     
00979     
00980     
00981     
00982     
00983     
00984     
00985     
00986 
00987     
if (LoadInSessionSpace == 
FALSE) {
00988         
ObDereferenceObject (SectionPointer);
00989         SectionPointer = (PVOID)-1;
00990     }
00991 
00992     
00993     
00994     
00995     
00996     
00997 
00998     
if (!
NT_SUCCESS(
Status)) {
00999         
if (AlreadyOpen == 
TRUE) {
01000 
01001             
01002             
01003             
01004             
01005             
01006             
01007             
01008 
01009             
ASSERT (DataTableEntry != 
NULL);
01010             DataTableEntry->LoadCount -= 1;
01011             DataTableEntry = 
NULL;
01012         }
01013         
goto return1;
01014     }
01015 
01016     
01017     
01018     
01019     
01020     
01021     
01022     
01023     
01024     
01025     
01026     
01027     
01028     
01029     
01030     
01031     
01032 
01033     IssueUnloadOnFailure = 
TRUE;
01034 
01035     
if (LoadInSessionSpace == 
FALSE || *ImageBaseAddress != SectionPointer->Segment->BasedAddress) {
01036 
01037 
#if DBG
01038 
01039         
01040         
01041         
01042         
01043 
01044         
if (LoadInSessionSpace == 
TRUE && 
MmSessionSpace->
SessionId) {
01045             
DbgPrint (
"MM: Session %d image %wZ is linked at a nonsharable address (%p)\n",
01046                     
MmSessionSpace->
SessionId,
01047                     ImageFileName,
01048                     SectionPointer->Segment->BasedAddress);
01049             
DbgPrint (
"MM: Image %wZ has been moved to address (%p) by the system so it can run,\n",
01050                     ImageFileName,
01051                     *ImageBaseAddress);
01052             
DbgPrint (
" but this needs to be fixed in the image for sharing to occur.\n");
01053         }
01054 
#endif
01055 
01056         
01057         
01058         
01059 
01060         
try {
01061             
Status = (
NTSTATUS)
LdrRelocateImage(*ImageBaseAddress,
01062                                                 
"SYSLDR",
01063                                                 (ULONG)STATUS_SUCCESS,
01064                                                 (ULONG)STATUS_CONFLICTING_ADDRESSES,
01065                                                 (ULONG)STATUS_INVALID_IMAGE_FORMAT
01066                                                 );
01067         } except (
EXCEPTION_EXECUTE_HANDLER) {
01068             
Status = GetExceptionCode();
01069             KdPrint((
"MM:sysload - LdrRelocateImage failed status %lx\n",
01070                       
Status));
01071         }
01072 
01073         
if (!
NT_SUCCESS(
Status)) {
01074 
01075             
01076             
01077             
01078 
01079             
goto return1;
01080         }
01081     }
01082 
01083 BindImage:
01084 
01085     
try {
01086         MissingProcedureName = NameBuffer;
01087 
01088         
01089         
01090         
01091         
01092         
01093         
01094         
01095         
01096         
01097         
01098         
01099 
01100         
Status = 
MiResolveImageReferences(*ImageBaseAddress,
01101                                           &BaseDirectory,
01102                                           NamePrefix,
01103                                           
FALSE,
01104                                           &MissingProcedureName,
01105                                           &MissingDriverName,
01106                                           &LoadedImports
01107                                          );
01108     } except (
EXCEPTION_EXECUTE_HANDLER) {
01109         
Status = GetExceptionCode();
01110         KdPrint((
"MM:sysload - ResolveImageReferences failed status %x\n",
01111                     
Status));
01112     }
01113 
01114     
if (!
NT_SUCCESS(
Status)) {
01115 
#if DBG
01116 
        if (
Status == STATUS_DRIVER_ORDINAL_NOT_FOUND ||
01117             
Status == STATUS_DRIVER_ENTRYPOINT_NOT_FOUND) {
01118 
01119             
if ((ULONG_PTR)MissingProcedureName & ~((ULONG_PTR) (
X64K-1))) {
01120                 
01121                 
01122                 
01123                 
DbgPrint(
"MissingProcedureName %s\n", MissingProcedureName);
01124             }
01125             
else {
01126                 
DbgPrint(
"MissingProcedureName 0x%p\n", MissingProcedureName);
01127             }
01128 
01129             
if (MissingDriverName) {
01130                 
DbgPrint(
"MissingDriverName %ws\n", MissingDriverName);
01131             }
01132         }
01133 
#endif
01134 
        goto return1;
01135     }
01136 
01137 
#if DBG
01138 
    if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01139         KdPrint ((
"MM:loaded driver - consumed %ld. pages\n",MiPagesConsumed));
01140     }
01141 
#endif
01142 
01143     
if (AlreadyOpen == 
FALSE) {
01144 
01145         
01146         
01147         
01148         
01149 
01150 
#if DBG
01151 
        NextEntry = 
PsLoadedModuleList.Flink;
01152         
while (NextEntry != &
PsLoadedModuleList) {
01153             DataTableEntry = CONTAINING_RECORD(NextEntry,
01154                                                LDR_DATA_TABLE_ENTRY,
01155                                                InLoadOrderLinks);
01156 
01157             
if (
RtlEqualUnicodeString (ImageFileName,
01158                                        &DataTableEntry->FullDllName,
01159                                        
TRUE)) {
01160 
01161                 
DbgPrint(
"MM SYSLDR: Image already loaded! RefCount %x\n",
01162                     DataTableEntry->LoadCount);
01163                 DbgBreakPoint();
01164             }
01165 
01166             NextEntry = NextEntry->Flink;
01167         }
01168 
#endif
01169 
01170         
01171         
01172         
01173 
01174         DataTableEntry = 
ExAllocatePoolWithTag (
NonPagedPool,
01175                                                 
sizeof(LDR_DATA_TABLE_ENTRY),
01176                                                 'dLmM');
01177 
01178         
if (DataTableEntry == 
NULL) {
01179             
Status = STATUS_INSUFFICIENT_RESOURCES;
01180             
goto return1;
01181         }
01182 
01183         DataTableEntry->BaseDllName.Buffer = 
ExAllocatePoolWithTag (
01184                                         
NonPagedPool,
01185                                         
BaseName.Length + 
sizeof(UNICODE_NULL),
01186                                         'dLmM');
01187 
01188         
if (DataTableEntry->BaseDllName.Buffer == 
NULL) {
01189             
ExFreePool (DataTableEntry);
01190             DataTableEntry = 
NULL;
01191             
Status = STATUS_INSUFFICIENT_RESOURCES;
01192             
goto return1;
01193         }
01194 
01195         
01196         
01197         
01198         
01199 
01200         NtHeaders = 
RtlImageNtHeader(*ImageBaseAddress);
01201 
01202         DataTableEntry->DllBase = *ImageBaseAddress;
01203         DataTableEntry->EntryPoint =
01204             ((PCHAR)*ImageBaseAddress + NtHeaders->OptionalHeader.AddressOfEntryPoint);
01205         DataTableEntry->SizeOfImage = NumberOfPtes << 
PAGE_SHIFT;
01206         DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
01207         DataTableEntry->SectionPointer = (PVOID)SectionPointer;
01208 
01209         
01210         
01211         
01212 
01213         DataTableEntry->BaseDllName.Length = 
BaseName.Length;
01214         DataTableEntry->BaseDllName.MaximumLength = 
BaseName.Length;
01215         RtlMoveMemory (DataTableEntry->BaseDllName.Buffer,
01216                        
BaseName.Buffer,
01217                        
BaseName.Length );
01218         DataTableEntry->BaseDllName.Buffer[
BaseName.Length/
sizeof(WCHAR)] = UNICODE_NULL;
01219 
01220         DataTableEntry->FullDllName.Buffer = 
ExAllocatePoolWithTag (
PagedPool,
01221                                                          PrefixedImageName.Length + 
sizeof(UNICODE_NULL),
01222                                                          'TDmM');
01223         
if (DataTableEntry->FullDllName.Buffer == 
NULL) {
01224 
01225             
01226             
01227             
01228 
01229             DataTableEntry->FullDllName.Length = 0;
01230             DataTableEntry->FullDllName.MaximumLength = 0;
01231         } 
else {
01232             DataTableEntry->FullDllName.Length = PrefixedImageName.Length;
01233             DataTableEntry->FullDllName.MaximumLength = PrefixedImageName.Length;
01234             RtlMoveMemory (DataTableEntry->FullDllName.Buffer,
01235                            PrefixedImageName.Buffer,
01236                            PrefixedImageName.Length);
01237             DataTableEntry->FullDllName.Buffer[PrefixedImageName.Length/
sizeof(WCHAR)] = UNICODE_NULL;
01238         }
01239 
01240         
PERFINFO_IMAGE_LOAD(DataTableEntry);
01241 
01242         
01243         
01244         
01245         
01246 
01247         DataTableEntry->Flags = LDRP_ENTRY_PROCESSED | LDRP_SYSTEM_MAPPED;
01248         DataTableEntry->LoadCount = 1;
01249         DataTableEntry->LoadedImports = (PVOID)LoadedImports;
01250 
01251         
if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
01252             (NtHeaders->OptionalHeader.MajorImageVersion >= 5)) {
01253             DataTableEntry->Flags |= LDRP_ENTRY_NATIVE;
01254         }
01255 
01256         
MiApplyDriverVerifier (DataTableEntry, 
NULL);
01257 
01258         
MiWriteProtectSystemImage (DataTableEntry->DllBase);
01259 
01260         
if (
PsImageNotifyEnabled) {
01261             
IMAGE_INFO ImageInfo;
01262 
01263             ImageInfo.
Properties = 0;
01264             ImageInfo.
ImageAddressingMode = 
IMAGE_ADDRESSING_MODE_32BIT;
01265             ImageInfo.
SystemModeImage = 
TRUE;
01266             ImageInfo.
ImageSize = DataTableEntry->SizeOfImage;
01267             ImageInfo.
ImageBase = *ImageBaseAddress;
01268             ImageInfo.
ImageSelector = 0;
01269             ImageInfo.
ImageSectionNumber = 0;
01270 
01271             
PsCallImageNotifyRoutines(ImageFileName, (HANDLE)
NULL, &ImageInfo);
01272         }
01273 
01274         
01275         
01276         
01277         
01278 
01279         
KeEnterCriticalRegion();
01280         
ExAcquireResourceExclusive (&
PsLoadedModuleResource, 
TRUE);
01281 
01282         ExAcquireSpinLock (&
PsLoadedModuleSpinLock, &OldIrql);
01283 
01284         InsertTailList(&
PsLoadedModuleList, &DataTableEntry->InLoadOrderLinks);
01285 
01286         ExReleaseSpinLock (&
PsLoadedModuleSpinLock, OldIrql);
01287 
01288         
ExReleaseResource (&
PsLoadedModuleResource);
01289         
KeLeaveCriticalRegion();
01290 
01291         
if (
CacheImageSymbols (*ImageBaseAddress)) {
01292 
01293             
01294             
01295             
01296 
01297             ANSI_STRING AnsiName;
01298             UNICODE_STRING UnicodeName;
01299 
01300             
01301             
01302             
01303             
if (PrefixedImageName.Length > (11 * 
sizeof( WCHAR )) &&
01304                 !_wcsnicmp( PrefixedImageName.Buffer, 
L"\\SystemRoot", 11 )
01305                ) {
01306                 UnicodeName = PrefixedImageName;
01307                 UnicodeName.Buffer += 11;
01308                 UnicodeName.Length -= (11 * 
sizeof( WCHAR ));
01309                 
sprintf (NameBuffer, 
"%ws%wZ", &SharedUserData->NtSystemRoot[2], &UnicodeName);
01310             } 
else {
01311                 
sprintf (NameBuffer, 
"%wZ", &
BaseName);
01312             }
01313             
RtlInitString (&AnsiName, NameBuffer);
01314             DbgLoadImageSymbols (&AnsiName,
01315                                  *ImageBaseAddress,
01316                                  (ULONG_PTR) -1
01317                                );
01318             DataTableEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
01319         }
01320     }
01321 
01322     
01323     
01324     
01325 
01326     
KeSweepIcache (
TRUE);
01327     *ImageHandle = DataTableEntry;
01328     
Status = STATUS_SUCCESS;
01329 
01330     
if (LoadInSessionSpace == 
TRUE) {
01331         
MmPageEntireDriver (DataTableEntry->EntryPoint);
01332     }
01333     
else if (SectionPointer == (PVOID)-1 && LockDownPages == 
FALSE) {
01334         
MiEnablePagingOfDriver (DataTableEntry);
01335     }
01336 
01337 return1:
01338 
01339     
if (!
NT_SUCCESS(
Status)) {
01340 
01341 
#if DBG
01342 
01343         
01344         
01345         
01346         
01347 
01348         
if (DataTableEntry) {
01349             
ASSERT (
MiHydra == 
TRUE && AlreadyOpen == 
TRUE && DataTableEntry->LoadCount > 1);
01350         }
01351 
#endif
01352 
01353         
if (AlreadyOpen == 
FALSE && SectionPointer != (PVOID)-1) {
01354 
01355             
01356             
01357             
01358             
01359 
01360             
ObDereferenceObject (SectionPointer);
01361         }
01362 
01363         
if (IssueUnloadOnFailure == 
TRUE) {
01364             
01365             
if (DataTableEntry == 
NULL) {
01366                 RtlZeroMemory (&TempDataTableEntry, 
sizeof(LDR_DATA_TABLE_ENTRY));
01367             
01368                 DataTableEntry = &TempDataTableEntry;
01369         
01370                 DataTableEntry->DllBase = *ImageBaseAddress;
01371                 DataTableEntry->SizeOfImage = NumberOfPtes << 
PAGE_SHIFT;
01372                 DataTableEntry->LoadCount = 1;
01373                 DataTableEntry->LoadedImports = LoadedImports;
01374             }
01375 
#if DBG
01376 
            else {
01377         
01378                 
01379                 
01380                 
01381                 
01382                 
01383                 
01384         
01385                 
ASSERT (
MiHydra == 
TRUE);
01386                 
ASSERT (DataTableEntry->LoadCount > 1);
01387             }
01388 
#endif
01389 
            
01390             
MmUnloadSystemImage ((PVOID)DataTableEntry);
01391         }
01392     }
01393 
01394     
if (FileHandle) {
01395         ZwClose (FileHandle);
01396     }
01397     
if (!
NT_SUCCESS(
Status)) {
01398 
01399         ULONG_PTR ErrorParameters[ 3 ];
01400         ULONG NumberOfParameters;
01401         ULONG UnicodeStringParameterMask;
01402         ULONG ErrorResponse;
01403         ANSI_STRING AnsiString;
01404         UNICODE_STRING ProcedureName;
01405         UNICODE_STRING DriverName;
01406 
01407         
01408         
01409         
01410 
01411         
KeReleaseMutant (&
MmSystemLoadLock, 1, 
FALSE, 
FALSE);
01412         
KeLeaveCriticalRegion();
01413         ErrorParameters[ 0 ] = (ULONG_PTR)ImageFileName;
01414         NumberOfParameters = 1;
01415         UnicodeStringParameterMask = 1;
01416 
01417         
RtlInitUnicodeString( &ProcedureName, 
NULL );
01418         
if (
Status == STATUS_DRIVER_ORDINAL_NOT_FOUND ||
01419             
Status == STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ||
01420             
Status == STATUS_PROCEDURE_NOT_FOUND
01421            ) {
01422             NumberOfParameters = 3;
01423             UnicodeStringParameterMask = 0x5;
01424             
RtlInitUnicodeString( &DriverName, MissingDriverName );
01425             ErrorParameters[ 2 ] = (ULONG_PTR)&DriverName;
01426 
01427             
if ((ULONG_PTR)MissingProcedureName & ~((ULONG_PTR) (
X64K-1))) {
01428                 
01429                 
01430                 
01431 
01432                 
RtlInitAnsiString( &AnsiString, MissingProcedureName );
01433                 
RtlAnsiStringToUnicodeString( &ProcedureName, &AnsiString, 
TRUE );
01434                 ErrorParameters[ 1 ] = (ULONG_PTR)&ProcedureName;
01435                 UnicodeStringParameterMask |= 0x2;
01436             } 
else {
01437                 
01438                 
01439                 
01440 
01441                 ErrorParameters[ 1 ] = (ULONG_PTR)MissingProcedureName;
01442             }
01443         } 
else {
01444             NumberOfParameters = 2;
01445             ErrorParameters[ 1 ] = (ULONG)
Status;
01446             
Status = STATUS_DRIVER_UNABLE_TO_LOAD;
01447             }
01448 
01449         ZwRaiseHardError (
Status,
01450                           NumberOfParameters,
01451                           UnicodeStringParameterMask,
01452                           ErrorParameters,
01453                           OptionOkNoWait,
01454                           &ErrorResponse);
01455 
01456         
if (ProcedureName.Buffer != 
NULL) {
01457             
RtlFreeUnicodeString( &ProcedureName );
01458         }
01459         
return Status;
01460     }
01461 
01462 return2:
01463     
if (NamePrefix) {
01464         
ExFreePool (PrefixedImageName.Buffer);
01465     }
01466 
01467     
KeReleaseMutant (&
MmSystemLoadLock, 1, 
FALSE, 
FALSE);
01468     
KeLeaveCriticalRegion();
01469     
return Status;
01470 }
01471 
01472 
01473 
NTSTATUS
01474 MiLoadImageSection (
01475     IN PSECTION SectionPointer,
01476     OUT PVOID *ImageBaseAddress,
01477     IN PUNICODE_STRING ImageFileName,
01478     IN BOOLEAN LoadInSessionSpace
01479     )
01480 
01481 
01482 
01483 
01484 
01485 
01486 
01487 
01488 
01489 
01490 
01491 
01492 
01493 
01494 
01495 
01496 
01497 
01498 
01499 
01500 
01501 
01502 
01503 
01504 
01505 
01506 
01507 {
01508     PFN_NUMBER PagesRequired;
01509     
PMMPTE ProtoPte;
01510     
PMMPTE FirstPte;
01511     
PMMPTE LastPte;
01512     
PMMPTE PointerPte;
01513     
PEPROCESS Process;
01514     
PEPROCESS TargetProcess;
01515     ULONG NumberOfPtes;
01516     
MMPTE PteContents;
01517     
MMPTE TempPte;
01518     
PMMPFN Pfn1;
01519     PFN_NUMBER PageFrameIndex;
01520     KIRQL OldIrql;
01521     PVOID UserVa;
01522     PVOID SystemVa;
01523     
NTSTATUS Status;
01524     
NTSTATUS ExceptionStatus;
01525     PVOID Base;
01526     ULONG_PTR ViewSize;
01527     LARGE_INTEGER SectionOffset;
01528     BOOLEAN LoadSymbols;
01529     PVOID BaseAddress;
01530     PFN_NUMBER CommittedPages;
01531     SIZE_T SectionSize;
01532     BOOLEAN AlreadyLoaded;
01533     
PMM_SESSION_SPACE SessionGlobal;
01534     LOGICAL ProcessReferenced;
01535     PLIST_ENTRY NextProcessEntry;
01536 
01537     
PAGED_CODE();
01538 
01539     PagesRequired = 0;
01540 
01541     
01542     
01543     
01544 
01545     ProtoPte = SectionPointer->Segment->PrototypePte;
01546     NumberOfPtes = SectionPointer->Segment->TotalNumberOfPtes;
01547 
01548     
while (NumberOfPtes != 0) {
01549         PteContents = *ProtoPte;
01550 
01551         
if ((PteContents.
u.Hard.Valid == 1) ||
01552             (PteContents.
u.Soft.Protection != 
MM_NOACCESS)) {
01553             PagesRequired += 1;
01554         }
01555         NumberOfPtes -= 1;
01556         ProtoPte += 1;
01557     }
01558 
01559     
if (LoadInSessionSpace == 
TRUE) {
01560 
01561         
ASSERT (
MiHydra == 
TRUE);
01562 
01563         SectionSize = (ULONG_PTR)SectionPointer->Segment->TotalNumberOfPtes * 
PAGE_SIZE;
01564 
01565         
01566         
01567         
01568         
01569 
01570         
Status = 
MiSessionWideReserveImageAddress (ImageFileName,
01571                                                    SectionPointer,
01572                                                    
PAGE_SIZE,
01573                                                    &BaseAddress,
01574                                                    &AlreadyLoaded);
01575 
01576         
if (!
NT_SUCCESS(
Status)) {
01577 
#if DBG
01578 
            if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01579                 
DbgPrint (
"MiLoadImageSection: Error 0x%x Allocating session space %p Bytes\n",
Status,SectionSize);
01580             }
01581 
#endif
01582 
            return Status;
01583         }
01584 
01585         
01586         
01587         
01588         
01589 
01590         
if (AlreadyLoaded == 
TRUE) {
01591             *ImageBaseAddress = BaseAddress;
01592             
return STATUS_ALREADY_COMMITTED;
01593         }
01594 
01595 
#if DBG
01596 
        if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01597             
if (ImageFileName) {
01598                 
DbgPrint (
"MM: MiLoadImageSection: Image %wZ, BasedAddress 0x%p, SegmentBaseAddress 0x%p, Allocated Session BaseAddress 0x%p\n",
01599                     ImageFileName,
01600                     SectionPointer->Segment->BasedAddress,
01601                     SectionPointer->Segment->SegmentBaseAddress,
01602                     BaseAddress);
01603             }
01604             
else {
01605                 
DbgPrint (
"MM: MiLoadImageSection: Image <NULL> BasedAddress 0x%p, SegmentBaseAddress 0x%p, Allocated Session BaseAddress 0x%p\n",
01606                     SectionPointer->Segment->BasedAddress,
01607                     SectionPointer->Segment->SegmentBaseAddress,
01608                     BaseAddress);
01609             }
01610         }
01611 
#endif
01612 
01613         
if (BaseAddress == SectionPointer->Segment->BasedAddress) {
01614 
01615             
01616             
01617             
01618             
01619             
01620             
01621             
01622             
01623             
01624 
01625 
#if DBG
01626 
            if (SectionPointer->Segment->SystemImageBase != 0) {
01627                 
ASSERT (BaseAddress == SectionPointer->Segment->SystemImageBase);
01628             }
01629 
#endif
01630 
01631             
01632             
01633             
01634 
01635             
Status = 
MiShareSessionImage (SectionPointer, &SectionSize);
01636 
01637             
if (!
NT_SUCCESS(
Status)) {
01638 
#if DBG
01639 
                if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01640                     
DbgPrint (
"MM: MiLoadImageSection: Error 0x%x Allocating session space %p Bytes\n", 
Status, SectionSize);
01641                 }
01642 
#endif
01643 
                MiRemoveImageSessionWide (BaseAddress);
01644                 
return Status;
01645             }
01646 
01647             
ASSERT (BaseAddress == SectionPointer->Segment->BasedAddress);
01648 
01649             *ImageBaseAddress = BaseAddress;
01650 
01651             
01652             
01653             
01654 
01655             SectionPointer->Segment->SystemImageBase = BaseAddress;
01656 
01657 
#if DBG
01658 
            if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01659                 
if (ImageFileName) {
01660                     
DbgPrint (
"MM: MiLoadImageSection: Mapped image %wZ at requested session address 0x%p\n",
01661                         ImageFileName,
01662                         BaseAddress);
01663                 }
01664                 
else {
01665                     
DbgPrint (
"MM: MiLoadImageSection: Mapped a session image at requested address 0x%p\n",
01666                         BaseAddress);
01667                 }
01668             }
01669 
#endif
01670 
01671             
return Status;
01672         }
01673 
01674         
01675         
01676         
01677         
01678         
01679         
01680 
01681         
Status = 
MiSessionCommitImagePages (BaseAddress, SectionSize);
01682 
01683         
if (!
NT_SUCCESS(
Status)) {
01684 
#if DBG
01685 
            if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01686                 
DbgPrint (
"MM: MiLoadImageSection: Error 0x%x Allocating session space %p Bytes\n", 
Status, SectionSize);
01687             }
01688 
#endif
01689 
            MiRemoveImageSessionWide (BaseAddress);
01690             
return Status;
01691         }
01692         SystemVa = BaseAddress;
01693     }
01694     
else {
01695 
01696         
01697         
01698         
01699 
01700 
#if DBG
01701 
        MiPagesConsumed = PagesRequired;
01702 
#endif
01703 
01704         
LOCK_PFN (OldIrql);
01705 
01706         
if (
MmResidentAvailablePages <= (SPFN_NUMBER)PagesRequired) {
01707             
UNLOCK_PFN (OldIrql);
01708             
return STATUS_INSUFFICIENT_RESOURCES;
01709         }
01710         
MmResidentAvailablePages -= PagesRequired;
01711         
MM_BUMP_COUNTER(14, PagesRequired);
01712         
UNLOCK_PFN (OldIrql);
01713 
01714         
01715         
01716         
01717 
01718         FirstPte = 
MiReserveSystemPtes (SectionPointer->Segment->TotalNumberOfPtes,
01719                                         
SystemPteSpace,
01720                                         0,
01721                                         0,
01722                                         
FALSE );
01723 
01724         
if (FirstPte == 
NULL) {
01725             
LOCK_PFN (OldIrql);
01726             
MmResidentAvailablePages += PagesRequired;
01727             
MM_BUMP_COUNTER(15, PagesRequired);
01728             
UNLOCK_PFN (OldIrql);
01729             
return STATUS_INSUFFICIENT_RESOURCES;
01730         }
01731         PointerPte = FirstPte;
01732         SystemVa = 
MiGetVirtualAddressMappedByPte (PointerPte);
01733     }
01734 
01735     
01736     
01737     
01738 
01739     Process = 
PsGetCurrentProcess();
01740 
01741     
01742     
01743     
01744     
01745     
01746 
01747     ProcessReferenced = 
FALSE;
01748     TargetProcess = Process;
01749     
if (Process->Peb && Process->Vm.u.Flags.SessionLeader == 0) {
01750         
if (
MiHydra == 
FALSE) {
01751             
if (
ExpDefaultErrorPortProcess && (Process != 
ExpDefaultErrorPortProcess)) {
01752                 TargetProcess = 
ExpDefaultErrorPortProcess;
01753                 
KeAttachProcess (&TargetProcess->
Pcb);
01754             }
01755         }
01756         
else {
01757 
01758             SessionGlobal = 
SESSION_GLOBAL(
MmSessionSpace);
01759             
LOCK_EXPANSION (OldIrql);
01760             NextProcessEntry = SessionGlobal->
ProcessList.Flink;
01761 
01762             
if ((SessionGlobal->
u.Flags.DeletePending == 0) &&
01763                 (NextProcessEntry != &SessionGlobal->
ProcessList)) {
01764 
01765                 TargetProcess = CONTAINING_RECORD (NextProcessEntry,
01766                                                    
EPROCESS,
01767                                                    SessionProcessLinks);
01768 
01769                 
if (Process != TargetProcess) {
01770                     
ObReferenceObject (TargetProcess);
01771                     ProcessReferenced = 
TRUE;
01772                 }
01773             }
01774             
else {
01775                 
UNLOCK_EXPANSION (OldIrql);
01776 
01777                 
LOCK_PFN (OldIrql);
01778                 
MmResidentAvailablePages += PagesRequired;
01779                 
MM_BUMP_COUNTER(15, PagesRequired);
01780                 
UNLOCK_PFN (OldIrql);
01781 
01782                 CommittedPages = 
MiDeleteSystemPagableVm (
01783                                           
MiGetPteAddress (BaseAddress),
01784                                           
BYTES_TO_PAGES (SectionSize),
01785                                           
ZeroKernelPte,
01786                                           
TRUE,
01787                                           
NULL);
01788     
01789                 
LOCK_SESSION_SPACE_WS (OldIrql);
01790                 
MmSessionSpace->
CommittedPages -= CommittedPages;
01791     
01792                 
MM_BUMP_SESS_COUNTER(
MM_DBG_SESSION_COMMIT_IMAGELOAD_FAILED1,
01793                     CommittedPages);
01794     
01795                 
UNLOCK_SESSION_SPACE_WS (OldIrql);
01796     
01797                 
01798                 
01799                 
01800                 
01801                 
01802     
01803                 
MiRemoveImageSessionWide (BaseAddress);
01804 
01805                 
return STATUS_PROCESS_IS_TERMINATING;
01806             }
01807 
01808             
UNLOCK_EXPANSION (OldIrql);
01809 
01810             
if (Process != TargetProcess) {
01811                 
KeAttachProcess (&TargetProcess->
Pcb);
01812             }
01813         }
01814     }
01815 
01816     
ZERO_LARGE (SectionOffset);
01817     Base = 
NULL;
01818     ViewSize = 0;
01819 
01820     
if (
NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD) {
01821         LoadSymbols = 
TRUE;
01822         
NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
01823     }
01824     
else {
01825         LoadSymbols = 
FALSE;
01826     }
01827 
01828     
Status = 
MmMapViewOfSection ( SectionPointer,
01829                                   TargetProcess,
01830                                   &Base,
01831                                   0,
01832                                   0,
01833                                   &SectionOffset,
01834                                   &ViewSize,
01835                                   ViewUnmap,
01836                                   0,
01837                                   PAGE_EXECUTE);
01838 
01839     
if (LoadSymbols) {
01840         
NtGlobalFlag |= FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
01841     }
01842 
01843     
if (
Status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) {
01844         
Status = STATUS_INVALID_IMAGE_FORMAT;
01845     }
01846 
01847     
if (!
NT_SUCCESS(
Status)) {
01848         
if (TargetProcess != Process) {
01849             
KeDetachProcess();
01850             
if (ProcessReferenced == 
TRUE) {
01851                 
ObDereferenceObject (TargetProcess);
01852             }
01853         }
01854 
01855         
if (LoadInSessionSpace == 
TRUE) {
01856 
01857 
#if DBG
01858 
            if (
NtGlobalFlag & FLG_SHOW_LDR_SNAPS) {
01859                 
DbgPrint (
"MiLoadImageSection: Error 0x%x in session space mapping via MmMapViewOfSection\n", 
Status);
01860             }
01861 
#endif
01862 
01863             CommittedPages = 
MiDeleteSystemPagableVm (
01864                                       
MiGetPteAddress (BaseAddress),
01865                                       
BYTES_TO_PAGES (SectionSize),
01866                                       
ZeroKernelPte,
01867                                       
TRUE,
01868                                       
NULL);
01869 
01870             
LOCK_SESSION_SPACE_WS (OldIrql);
01871             
MmSessionSpace->
CommittedPages -= CommittedPages;
01872 
01873             
MM_BUMP_SESS_COUNTER(
MM_DBG_SESSION_COMMIT_IMAGELOAD_FAILED1,
01874                 CommittedPages);
01875 
01876             
UNLOCK_SESSION_SPACE_WS (OldIrql);
01877 
01878             
01879             
01880             
01881             
01882             
01883 
01884             
MiRemoveImageSessionWide (BaseAddress);
01885         }
01886         
else {
01887             
LOCK_PFN (OldIrql);
01888             
MmResidentAvailablePages += PagesRequired;
01889             
MM_BUMP_COUNTER(16, PagesRequired);
01890             
UNLOCK_PFN (OldIrql);
01891             
MiReleaseSystemPtes (FirstPte,
01892                                  SectionPointer->Segment->TotalNumberOfPtes,
01893                                  
SystemPteSpace);
01894         }
01895 
01896         
return Status;
01897     }
01898 
01899     
01900     
01901     
01902     
01903     
01904 
01905     ProtoPte = SectionPointer->Segment->PrototypePte;
01906     NumberOfPtes = SectionPointer->Segment->TotalNumberOfPtes;
01907 
01908     *ImageBaseAddress = SystemVa;
01909 
01910     UserVa = Base;
01911     TempPte = 
ValidKernelPte;
01912 
#if defined(_IA64_)
01913 
    TempPte.
u.Long |= 
MM_PTE_EXECUTE;
01914 
#endif
01915 
01916     
while (NumberOfPtes != 0) {
01917         PteContents = *ProtoPte;
01918         
if ((PteContents.
u.Hard.Valid == 1) ||
01919             (PteContents.
u.Soft.Protection != 
MM_NOACCESS)) {
01920 
01921             
if (LoadInSessionSpace == 
FALSE) {
01922                 
LOCK_PFN (OldIrql);
01923                 
MiEnsureAvailablePageOrWait (
NULL, 
NULL);
01924                 PageFrameIndex = 
MiRemoveAnyPage(
01925                                     
MI_GET_PAGE_COLOR_FROM_PTE (PointerPte));
01926                 PointerPte->u.Long = 
MM_KERNEL_DEMAND_ZERO_PTE;
01927 
#if defined(_IA64_)
01928 
01929                 
01930                 
01931                 
01932 
01933                 PointerPte->u.Soft.Protection |= 
MM_EXECUTE;
01934 
01935 
#endif
01936 
                MiInitializePfn (PageFrameIndex, PointerPte, 1);
01937 
01938                 
UNLOCK_PFN (OldIrql);
01939                 TempPte.
u.Hard.PageFrameNumber = PageFrameIndex;
01940                 
MI_WRITE_VALID_PTE (PointerPte, TempPte);
01941                 LastPte = PointerPte;
01942 
01943                 
ASSERT (
MI_PFN_ELEMENT (PageFrameIndex)->u1.WsIndex == 0);
01944             }
01945 
01946             
try {
01947 
01948                 RtlMoveMemory (SystemVa, UserVa, 
PAGE_SIZE);
01949 
01950             } except (
MiMapCacheExceptionFilter (&ExceptionStatus,
01951                                                  GetExceptionInformation())) {
01952 
01953                 
01954                 
01955                 
01956                 
01957 
01958 
#if DBG
01959 
                DbgPrint(
"MiLoadImageSection: Exception 0x%x copying driver SystemVa 0x%p, UserVa 0x%p\n",ExceptionStatus,SystemVa,UserVa);
01960 
#endif
01961 
01962                 
if (LoadInSessionSpace == 
TRUE) {
01963                     
ASSERT (
MiHydra == 
TRUE);
01964                     CommittedPages = 
MiDeleteSystemPagableVm (
01965                                               
MiGetPteAddress (BaseAddress),
01966                                               
BYTES_TO_PAGES (SectionSize),
01967                                               
ZeroKernelPte,
01968                                               
TRUE,
01969                                               
NULL);
01970 
01971                     
LOCK_SESSION_SPACE_WS (OldIrql);
01972                     
MmSessionSpace->
CommittedPages -= CommittedPages;
01973 
01974                     
MM_BUMP_SESS_COUNTER(
MM_DBG_SESSION_COMMIT_IMAGELOAD_FAILED2,
01975                         CommittedPages);
01976 
01977                     
UNLOCK_SESSION_SPACE_WS (OldIrql);
01978 
01979                     
01980                     
01981                     
01982                     
01983                     
01984                     
01985 
01986                     
MiReturnCommitment (CommittedPages);
01987                     
MM_TRACK_COMMIT (
MM_DBG_COMMIT_RETURN_SESSION_DRIVER_LOAD_FAILURE1, CommittedPages);
01988                 }
01989                 
else {
01990                     ProtoPte = FirstPte;
01991                     
LOCK_PFN (OldIrql);
01992                     
while (ProtoPte <= PointerPte) {
01993                         
if (ProtoPte->u.Hard.Valid == 1) {
01994 
01995                             
01996                             
01997                             
01998 
01999                             PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (ProtoPte);
02000 
02001                             
02002                             
02003                             
02004                             
02005 
02006                             Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
02007                             
MiDecrementShareAndValidCount (Pfn1->
PteFrame);
02008                             
MI_SET_PFN_DELETED (Pfn1);
02009                             
MiDecrementShareCountOnly (PageFrameIndex);
02010 
02011                             
MI_WRITE_INVALID_PTE (ProtoPte, 
ZeroPte);
02012                         }
02013                         ProtoPte += 1;
02014                     }
02015 
02016                     
MmResidentAvailablePages += PagesRequired;
02017                     
MM_BUMP_COUNTER(17, PagesRequired);
02018                     
UNLOCK_PFN (OldIrql);
02019                     
MiReleaseSystemPtes (FirstPte,
02020                                          SectionPointer->Segment->TotalNumberOfPtes,
02021                                          
SystemPteSpace);
02022                 }
02023 
02024                 
Status = 
MmUnmapViewOfSection (TargetProcess, Base);
02025 
02026                 
ASSERT (
NT_SUCCESS (
Status));
02027 
02028                 
if (TargetProcess != Process) {
02029                     
KeDetachProcess();
02030                     
if (ProcessReferenced == 
TRUE) {
02031                         
ObDereferenceObject (TargetProcess);
02032                     }
02033                 }
02034 
02035                 
if (LoadInSessionSpace == 
TRUE) {
02036                     
MiRemoveImageSessionWide (BaseAddress);
02037                 }
02038 
02039                 
return ExceptionStatus;
02040             }
02041 
02042         }
02043         
else {
02044 
02045             
02046             
02047             
02048             
02049             
02050 
02051             
if (LoadInSessionSpace == 
TRUE) {
02052                 
ASSERT (
MiHydra == 
TRUE);
02053                 CommittedPages = 
MiDeleteSystemPagableVm (
02054                                           
MiGetPteAddress (SystemVa),
02055                                           1,
02056                                           
ZeroKernelPte,
02057                                           
TRUE,
02058                                           
NULL);
02059 
02060                 
MM_BUMP_SESS_COUNTER(
MM_DBG_SESSION_COMMIT_IMAGELOAD_NOACCESS,
02061                     1);
02062             }
02063             
else {
02064                 
MI_WRITE_INVALID_PTE (PointerPte, 
ZeroKernelPte);
02065             }
02066         }
02067 
02068         NumberOfPtes -= 1;
02069         ProtoPte += 1;
02070         PointerPte += 1;
02071         SystemVa = ((PCHAR)SystemVa + 
PAGE_SIZE);
02072         UserVa = ((PCHAR)UserVa + 
PAGE_SIZE);
02073     }
02074 
02075     
Status = 
MmUnmapViewOfSection (TargetProcess, Base);
02076     
ASSERT (
NT_SUCCESS (
Status));
02077 
02078     
if (TargetProcess != Process) {
02079         
KeDetachProcess();
02080         
if (ProcessReferenced == 
TRUE) {
02081             
ObDereferenceObject (TargetProcess);
02082         }
02083     }
02084 
02085     
02086     
02087     
02088 
02089     SectionPointer->Segment->SystemImageBase = *ImageBaseAddress;
02090 
02091     
02092     
02093     
02094     
02095 
02096     
if (LoadInSessionSpace == 
FALSE) {
02097         
MiChargeCommitmentCantExpand (PagesRequired, 
TRUE);
02098         
MM_TRACK_COMMIT (
MM_DBG_COMMIT_DRIVER_PAGES, PagesRequired);
02099         
MmDriverCommit += (ULONG)PagesRequired;
02100     }
02101 
02102     
return Status;
02103 }
02104 
02105 
VOID
02106 MmFreeDriverInitialization (
02107     IN PVOID ImageHandle
02108     )
02109 
02110 
02111 
02112 
02113 
02114 
02115 
02116 
02117 
02118 
02119 
02120 
02121 
02122 
02123 
02124 
02125 
02126 
02127 
02128 
02129 
02130 
02131 
02132 
02133 {
02134     PLDR_DATA_TABLE_ENTRY DataTableEntry;
02135     
PMMPTE PointerPte;
02136     
PMMPTE LastPte;
02137     PFN_NUMBER NumberOfPtes;
02138     PVOID Base;
02139     ULONG i;
02140     PIMAGE_NT_HEADERS NtHeaders;
02141     PIMAGE_SECTION_HEADER NtSection;
02142     PIMAGE_SECTION_HEADER FoundSection;
02143     PFN_NUMBER PagesDeleted;
02144 
02145     
MmLockPagableSectionByHandle(
ExPageLockHandle);
02146     DataTableEntry = (PLDR_DATA_TABLE_ENTRY)ImageHandle;
02147     Base = DataTableEntry->DllBase;
02148 
02149     
ASSERT (
MI_IS_SESSION_ADDRESS (Base) == 
FALSE);
02150 
02151     NumberOfPtes = DataTableEntry->SizeOfImage >> 
PAGE_SHIFT;
02152     LastPte = 
MiGetPteAddress (Base) + NumberOfPtes;
02153 
02154     NtHeaders = (PIMAGE_NT_HEADERS)
RtlImageNtHeader(Base);
02155 
02156     NtSection = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeaders +
02157                         
sizeof(ULONG) +
02158                         
sizeof(IMAGE_FILE_HEADER) +
02159                         NtHeaders->FileHeader.SizeOfOptionalHeader
02160                         );
02161 
02162     NtSection += NtHeaders->FileHeader.NumberOfSections;
02163 
02164     FoundSection = 
NULL;
02165     
for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i += 1) {
02166         NtSection -= 1;
02167         
if ((NtSection->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0) {
02168             FoundSection = NtSection;
02169         } 
else {
02170 
02171             
02172             
02173             
02174             
02175             
02176 
02177             
break;
02178         }
02179     }
02180 
02181     
if (FoundSection != 
NULL) {
02182 
02183         PointerPte = 
MiGetPteAddress (
ROUND_TO_PAGES (
02184                                     (PCHAR)Base + FoundSection->VirtualAddress));
02185         NumberOfPtes = (PFN_NUMBER)(LastPte - PointerPte);
02186 
02187         PagesDeleted = 
MiDeleteSystemPagableVm (PointerPte,
02188                                                 NumberOfPtes,
02189                                                 
ZeroKernelPte,
02190                                                 
FALSE,
02191                                                 
NULL);
02192 
02193         
MmResidentAvailablePages += PagesDeleted;
02194         
MM_BUMP_COUNTER(18, PagesDeleted);
02195         
MiReturnCommitment (PagesDeleted);
02196         
MM_TRACK_COMMIT (
MM_DBG_COMMIT_RETURN_DRIVER_INIT_CODE, PagesDeleted);
02197         
MmDriverCommit -= (ULONG)PagesDeleted;
02198 
#if DBG
02199 
        MiPagesConsumed -= PagesDeleted;
02200 
#endif
02201 
    }
02202 
02203     
MmUnlockPagableImageSection(
ExPageLockHandle);
02204     
return;
02205 }
02206 
02207 
VOID
02208 MiEnablePagingOfDriver (
02209     IN PVOID ImageHandle
02210     )
02211 
02212 {
02213     PLDR_DATA_TABLE_ENTRY DataTableEntry;
02214     
PMMPTE LastPte;
02215     
PMMPTE PointerPte;
02216     PVOID Base;
02217     ULONG i;
02218     PIMAGE_NT_HEADERS NtHeaders;
02219     PIMAGE_SECTION_HEADER FoundSection;
02220     PIMAGE_OPTIONAL_HEADER OptionalHeader;
02221 
02222     
02223     
02224     
02225 
02226     
if (
MmDisablePagingExecutive) {
02227         
return;
02228     }
02229 
02230     
02231     
02232     
02233 
02234     DataTableEntry = (PLDR_DATA_TABLE_ENTRY)ImageHandle;
02235     Base = DataTableEntry->DllBase;
02236 
02237     NtHeaders = (PIMAGE_NT_HEADERS)
RtlImageNtHeader(Base);
02238 
02239     OptionalHeader = (PIMAGE_OPTIONAL_HEADER)((PCHAR)NtHeaders +
02240 
#if defined (_WIN64)
02241 
                        FIELD_OFFSET (IMAGE_NT_HEADERS64, OptionalHeader));
02242 
#else
02243 
                        FIELD_OFFSET (IMAGE_NT_HEADERS32, OptionalHeader));
02244 
#endif
02245 
02246     FoundSection = IMAGE_FIRST_SECTION (NtHeaders);
02247 
02248     i = NtHeaders->FileHeader.NumberOfSections;
02249 
02250     PointerPte = 
NULL;
02251 
02252     
while (i > 0) {
02253 
#if DBG
02254 
            if ((*(PULONG)FoundSection->Name == 'tini') ||
02255                 (*(PULONG)FoundSection->Name == 'egap')) {
02256                 
DbgPrint(
"driver %wZ has lower case sections (init or pagexxx)\n",
02257                     &DataTableEntry->FullDllName);
02258             }
02259 
#endif //DBG
02260 
02261         
02262         
02263         
02264         
02265 
02266         
if ((*(PULONG)FoundSection->Name == 'EGAP') ||
02267            (*(PULONG)FoundSection->Name == 'ade.')) {
02268 
02269             
02270             
02271             
02272 
02273             
if (PointerPte == 
NULL) {
02274 
02275                 
02276                 
02277                 
02278 
02279                 PointerPte = 
MiGetPteAddress (
ROUND_TO_PAGES (
02280                                    (PCHAR)Base + FoundSection->VirtualAddress));
02281             }
02282             LastPte = 
MiGetPteAddress ((PCHAR)Base +
02283                                        FoundSection->VirtualAddress +
02284                                        (OptionalHeader->SectionAlignment - 1) +
02285                                        FoundSection->SizeOfRawData - 
PAGE_SIZE);
02286 
02287         } 
else {
02288 
02289             
02290             
02291             
02292             
02293 
02294             
if (PointerPte != 
NULL) {
02295                 
MiSetPagingOfDriver (PointerPte, LastPte, 
FALSE);
02296                 PointerPte = 
NULL;
02297             }
02298         }
02299         i -= 1;
02300         FoundSection += 1;
02301     }
02302     
if (PointerPte != 
NULL) {
02303         
MiSetPagingOfDriver (PointerPte, LastPte, 
FALSE);
02304     }
02305 }
02306 
02307 
02308 
VOID
02309 MiSetPagingOfDriver (
02310     IN 
PMMPTE PointerPte,
02311     IN 
PMMPTE LastPte,
02312     IN BOOLEAN SessionSpace
02313     )
02314 
02315 
02316 
02317 
02318 
02319 
02320 
02321 
02322 
02323 
02324 
02325 
02326 
02327 
02328 
02329 
02330 
02331 
02332 
02333 {
02334     PVOID Base;
02335     PFN_NUMBER PageCount;
02336     PFN_NUMBER PageFrameIndex;
02337     
PMMPFN Pfn;
02338     
MMPTE TempPte;
02339     
MMPTE PreviousPte;
02340     KIRQL OldIrql1;
02341     KIRQL OldIrql;
02342 
02343     
PAGED_CODE ();
02344 
02345     
ASSERT ((SessionSpace == 
FALSE) ||
02346             (
MmIsAddressValid(
MmSessionSpace) == 
TRUE));
02347 
02348     
if (
MI_IS_PHYSICAL_ADDRESS(
MiGetVirtualAddressMappedByPte(PointerPte))) {
02349 
02350         
02351         
02352         
02353 
02354         
return;
02355     }
02356 
02357     PageCount = 0;
02358 
02359     
02360     
02361     
02362 
02363     
MmLockPagableSectionByHandle(
ExPageLockHandle);
02364 
02365     
if (SessionSpace == 
TRUE) {
02366         
LOCK_SESSION_SPACE_WS (OldIrql1);
02367     }
02368     
else {
02369         
LOCK_SYSTEM_WS (OldIrql1);
02370     }
02371 
02372     
LOCK_PFN (OldIrql);
02373 
02374     Base = 
MiGetVirtualAddressMappedByPte (PointerPte);
02375 
02376     
while (PointerPte <= LastPte) {
02377 
02378         
02379         
02380         
02381         
02382         
02383         
02384 
02385         
if (PointerPte->u.Hard.Valid == 1) {
02386             PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
02387             Pfn = 
MI_PFN_ELEMENT (PageFrameIndex);
02388             
ASSERT (Pfn->
u2.ShareCount == 1);
02389 
02390             
if (Pfn->
u1.WsIndex == 0) {
02391 
02392                 
02393                 
02394                 
02395                 
02396     
02397                 
if (Pfn->
OriginalPte.
u.Long == 0) {
02398                     Pfn->
OriginalPte.
u.Long = 
MM_KERNEL_DEMAND_ZERO_PTE;
02399 
#if defined(_IA64_)
02400 
                    Pfn->
OriginalPte.
u.Soft.Protection |= 
MM_EXECUTE;
02401 
#endif
02402 
                }
02403     
02404                 TempPte = *PointerPte;
02405 
02406                 
MI_MAKE_VALID_PTE_TRANSITION (TempPte,
02407                                            Pfn->
OriginalPte.
u.Soft.Protection);
02408 
02409                 PreviousPte.
u.Flush = 
KeFlushSingleTb (Base,
02410                                                        
TRUE,
02411                                                        
TRUE,
02412                                                        (PHARDWARE_PTE)PointerPte,
02413                                                        TempPte.
u.Flush);
02414 
02415                 
MI_CAPTURE_DIRTY_BIT_TO_PFN (&PreviousPte, Pfn);
02416 
02417                 
02418                 
02419                 
02420                 
02421                 
02422                 
02423 
02424                 
MiDecrementShareCount (PageFrameIndex);
02425                 
MmResidentAvailablePages += 1;
02426                 
MM_BUMP_COUNTER(19, 1);
02427                 
MmTotalSystemDriverPages += 1;
02428                 PageCount += 1;
02429             }
02430             
else {
02431                 
02432                 
02433                 
02434                 
02435                 
02436             }
02437         }
02438         Base = (PVOID)((PCHAR)Base + 
PAGE_SIZE);
02439         PointerPte += 1;
02440     }
02441 
02442     
if (SessionSpace == 
TRUE) {
02443 
02444         
02445         
02446         
02447     
02448         
MI_FLUSH_ENTIRE_SESSION_TB (
TRUE, 
TRUE);
02449     }
02450 
02451     
UNLOCK_PFN (OldIrql);
02452 
02453     
if (SessionSpace == 
TRUE) {
02454 
02455         
02456         
02457         
02458 
02459         
MmSessionSpace->
NonPagablePages -= PageCount;
02460         
MM_BUMP_SESS_COUNTER(
MM_DBG_SESSION_DRIVER_PAGES_UNLOCKED, PageCount);
02461 
02462         
UNLOCK_SESSION_SPACE_WS (OldIrql1);
02463     }
02464     
else {
02465         
UNLOCK_SYSTEM_WS (OldIrql1);
02466     }
02467     
MmUnlockPagableImageSection(
ExPageLockHandle);
02468 }
02469 
02470 
02471 PVOID
02472 MmPageEntireDriver (
02473     IN PVOID AddressWithinSection
02474     )
02475 
02476 
02477 
02478 
02479 
02480 
02481 
02482 
02483 
02484 
02485 
02486 
02487 
02488 
02489 
02490 
02491 
02492 
02493 
02494 
02495 
02496 
02497 
02498 
02499 
02500 
02501 {
02502     PLDR_DATA_TABLE_ENTRY DataTableEntry;
02503     
PMMPTE FirstPte;
02504     
PMMPTE LastPte;
02505     PVOID BaseAddress;
02506     
PSECTION SectionPointer;
02507     BOOLEAN SessionSpace;
02508 
02509     
PAGED_CODE();
02510 
02511     
02512     
02513     
02514 
02515     DataTableEntry = 
MiLookupDataTableEntry (AddressWithinSection, 
FALSE);
02516 
02517     
if (DataTableEntry == 
NULL) {
02518         
return NULL;
02519     }
02520 
02521     SectionPointer = (
PSECTION)DataTableEntry->SectionPointer;
02522 
02523     
if (
MmDisablePagingExecutive) {
02524         
return DataTableEntry->DllBase;
02525     }
02526 
02527     SessionSpace = 
MI_IS_SESSION_IMAGE_ADDRESS (AddressWithinSection);
02528 
02529     
if ((SectionPointer != 
NULL) && (SectionPointer != (PVOID)-1)) {
02530 
02531         
02532         
02533         
02534         
02535         
02536         
02537 
02538         
if (SessionSpace == 
TRUE) {
02539             
if (SectionPointer->Segment &&
02540                 SectionPointer->Segment->BasedAddress == SectionPointer->Segment->SystemImageBase) {
02541                 
return DataTableEntry->DllBase;
02542             }
02543         }
02544         
else {
02545             
return DataTableEntry->DllBase;
02546         }
02547     }
02548 
02549     BaseAddress = DataTableEntry->DllBase;
02550     FirstPte = 
MiGetPteAddress (BaseAddress);
02551     LastPte = (FirstPte - 1) + (DataTableEntry->SizeOfImage >> 
PAGE_SHIFT);
02552 
02553     
MiSetPagingOfDriver (FirstPte, LastPte, SessionSpace);
02554 
02555     
return BaseAddress;
02556 }
02557 
02558 
02559 
VOID
02560 MmResetDriverPaging (
02561     IN PVOID AddressWithinSection
02562     )
02563 
02564 
02565 
02566 
02567 
02568 
02569 
02570 
02571 
02572 
02573 
02574 
02575 
02576 
02577 
02578 
02579 
02580 
02581 
02582 
02583 
02584 
02585 
02586 
02587 
02588 
02589 {
02590     PLDR_DATA_TABLE_ENTRY DataTableEntry;
02591     
PMMPTE LastPte;
02592     
PMMPTE PointerPte;
02593     PVOID Base;
02594     ULONG i;
02595     PIMAGE_NT_HEADERS NtHeaders;
02596     PIMAGE_SECTION_HEADER FoundSection;
02597     KIRQL OldIrql;
02598     KIRQL OldIrqlWs;
02599 
02600     
PAGED_CODE();
02601 
02602     
02603     
02604     
02605 
02606     
if (
MmDisablePagingExecutive) {
02607         
return;
02608     }
02609 
02610     
if (
MI_IS_PHYSICAL_ADDRESS(AddressWithinSection)) {
02611         
return;
02612     }
02613 
02614     
02615     
02616     
02617 
02618     DataTableEntry = 
MiLookupDataTableEntry (AddressWithinSection, 
FALSE);
02619 
02620     
if ((DataTableEntry->SectionPointer != 
NULL) &&
02621         (DataTableEntry->SectionPointer != (PVOID)-1)) {
02622 
02623         
02624         
02625         
02626 
02627         
return;
02628     }
02629 
02630     Base = DataTableEntry->DllBase;
02631 
02632     NtHeaders = (PIMAGE_NT_HEADERS)
RtlImageNtHeader(Base);
02633 
02634     FoundSection = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeaders +
02635                         
sizeof(ULONG) +
02636                         
sizeof(IMAGE_FILE_HEADER) +
02637                         NtHeaders->FileHeader.SizeOfOptionalHeader
02638                         );
02639 
02640     i = NtHeaders->FileHeader.NumberOfSections;
02641     PointerPte = 
NULL;
02642 
02643     
while (i > 0) {
02644 
#if DBG
02645 
            if ((*(PULONG)FoundSection->Name == 'tini') ||
02646                 (*(PULONG)FoundSection->Name == 'egap')) {
02647                 
DbgPrint(
"driver %wZ has lower case sections (init or pagexxx)\n",
02648                     &DataTableEntry->FullDllName);
02649             }
02650 
#endif
02651 
02652         
02653         
02654         
02655         
02656         
02657 
02658         
if (((FoundSection->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0) ||
02659            (*(PULONG)FoundSection->Name == 'EGAP') ||
02660            (*(PULONG)FoundSection->Name == 'ade.') ||
02661            (*(PULONG)FoundSection->Name == 'TINI')) {
02662 
02663             NOTHING;
02664 
02665         } 
else {
02666 
02667             
02668             
02669             
02670 
02671             PointerPte = 
MiGetPteAddress (
02672                                    (PCHAR)Base + FoundSection->VirtualAddress);
02673             LastPte = 
MiGetPteAddress ((PCHAR)Base +
02674                                        FoundSection->VirtualAddress +
02675                                       (FoundSection->SizeOfRawData - 1));
02676             
ASSERT (PointerPte <= LastPte);
02677             
MmLockPagableSectionByHandle(
ExPageLockHandle);
02678             
LOCK_SYSTEM_WS (OldIrqlWs);
02679             
LOCK_PFN (OldIrql);
02680             
MiLockCode (PointerPte, LastPte, 
MM_LOCK_BY_NONPAGE);
02681             
UNLOCK_PFN (OldIrql);
02682             
UNLOCK_SYSTEM_WS (OldIrqlWs);
02683             
MmUnlockPagableImageSection(
ExPageLockHandle);
02684         }
02685         i -= 1;
02686         FoundSection += 1;
02687     }
02688     
return;
02689 }
02690 
02691 
02692 
VOID
02693 MiClearImports(
02694     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
02695     )
02696 
02697 
02698 
02699 
02700 
02701 
02702 
02703 
02704 
02705 
02706 
02707 
02708 
02709 
02710 
02711 
02712 
02713 {
02714     
PAGED_CODE();
02715 
02716     
if (DataTableEntry->LoadedImports == (PVOID)
LOADED_AT_BOOT) {
02717         
return;
02718     }
02719 
02720     
if (DataTableEntry->LoadedImports == (PVOID)
NO_IMPORTS_USED) {
02721         NOTHING;
02722     }
02723     
else if (
SINGLE_ENTRY(DataTableEntry->LoadedImports)) {
02724         NOTHING;
02725     }
02726     
else {
02727         
02728         
02729         
02730         
ExFreePool ((PVOID)DataTableEntry->LoadedImports);
02731     }
02732 
02733     
02734     
02735     
02736     DataTableEntry->LoadedImports = (PVOID)
LOADED_AT_BOOT;
02737 }
02738 
02739 
VOID
02740 MiRememberUnloadedDriver (
02741     IN PUNICODE_STRING DriverName,
02742     IN PVOID Address,
02743     IN ULONG Length
02744     )
02745 
02746 
02747 
02748 
02749 
02750 
02751 
02752 
02753 
02754 
02755 
02756 
02757 
02758 
02759 
02760 
02761 
02762 
02763 
02764 
02765 
02766 
02767 {
02768     
PUNLOADED_DRIVERS Entry;
02769     ULONG NumberOfBytes;
02770 
02771     
if (DriverName->Length == 0) {
02772 
02773         
02774         
02775         
02776         
02777 
02778         
return;
02779     }
02780 
02781     
02782     
02783     
02784     
02785     
02786 
02787     
if (
MiUnloadedDrivers == 
NULL) {
02788         NumberOfBytes = 
MI_UNLOADED_DRIVERS * 
sizeof (
UNLOADED_DRIVERS);
02789 
02790         
MiUnloadedDrivers = (
PUNLOADED_DRIVERS)
ExAllocatePoolWithTag (
NonPagedPool,
02791                                                                       NumberOfBytes,
02792                                                                       'TDmM');
02793         
if (
MiUnloadedDrivers == 
NULL) {
02794             
return;
02795         }
02796         RtlZeroMemory (
MiUnloadedDrivers, NumberOfBytes);
02797         
MiLastUnloadedDriver = 0;
02798     }
02799     
else if (
MiLastUnloadedDriver >= 
MI_UNLOADED_DRIVERS) {
02800         
MiLastUnloadedDriver = 0;
02801     }
02802 
02803     Entry = &
MiUnloadedDrivers[
MiLastUnloadedDriver];
02804 
02805     
02806     
02807     
02808 
02809     
RtlFreeUnicodeString (&Entry->
Name);
02810 
02811     Entry->
Name.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
02812                                                 DriverName->Length,
02813                                                 'TDmM');
02814 
02815     
if (Entry->
Name.Buffer == 
NULL) {
02816         Entry->
Name.MaximumLength = 0;
02817         Entry->
Name.Length = 0;
02818         
MiUnloadsSkipped += 1;
02819         
return;
02820     }
02821 
02822     RtlMoveMemory(Entry->
Name.Buffer, DriverName->Buffer, DriverName->Length);
02823     Entry->
Name.Length = DriverName->Length;
02824     Entry->
Name.MaximumLength = DriverName->MaximumLength;
02825 
02826     Entry->
StartAddress = Address;
02827     Entry->
EndAddress = (PVOID)((PCHAR)Address + Length);
02828 
02829     
KeQuerySystemTime (&Entry->
CurrentTime);
02830 
02831     
MiTotalUnloads += 1;
02832     
MiLastUnloadedDriver += 1;
02833 }
02834 
02835 PUNICODE_STRING
02836 MmLocateUnloadedDriver (
02837     IN PVOID VirtualAddress
02838     )
02839 
02840 
02841 
02842 
02843 
02844 
02845 
02846 
02847 
02848 
02849 
02850 
02851 
02852 
02853 
02854 
02855 
02856 
02857 
02858 
02859 
02860 
02861 
02862 {
02863     
PUNLOADED_DRIVERS Entry;
02864     ULONG i;
02865     ULONG 
Index;
02866 
02867     
02868     
02869     
02870 
02871     
if (
MiUnloadedDrivers == 
NULL) {
02872         
return NULL;
02873     }
02874 
02875     
Index = 
MiLastUnloadedDriver - 1;
02876 
02877     
for (i = 0; i < 
MI_UNLOADED_DRIVERS; i += 1) {
02878         
if (
Index >= 
MI_UNLOADED_DRIVERS) {
02879             
Index = 
MI_UNLOADED_DRIVERS - 1;
02880         }
02881         Entry = &
MiUnloadedDrivers[
Index];
02882         
if (Entry->
Name.Buffer != 
NULL) {
02883             
if ((VirtualAddress >= Entry->
StartAddress) &&
02884                 (VirtualAddress < Entry->
EndAddress)) {
02885                     
return &Entry->
Name;
02886             }
02887         }
02888         
Index -= 1;
02889     }
02890 
02891     
return NULL;
02892 }
02893 
02894 
02895 
NTSTATUS
02896 MmUnloadSystemImage (
02897     IN PVOID ImageHandle
02898     )
02899 
02900 
02901 
02902 
02903 
02904 
02905 
02906 
02907 
02908 
02909 
02910 
02911 
02912 
02913 
02914 
02915 
02916 
02917 
02918 {
02919     PLDR_DATA_TABLE_ENTRY DataTableEntry;
02920     
PMMPTE LastPte;
02921     PFN_NUMBER PagesRequired;
02922     PFN_NUMBER ResidentPages;
02923     
PMMPTE PointerPte;
02924     PFN_NUMBER NumberOfPtes;
02925     KIRQL OldIrql;
02926     PVOID BasedAddress;
02927     SIZE_T NumberOfBytes;
02928     BOOLEAN MustFree;
02929     SIZE_T CommittedPages;
02930     BOOLEAN ViewDeleted;
02931     
PIMAGE_ENTRY_IN_SESSION DriverImage;
02932     
NTSTATUS Status;
02933     PVOID StillQueued;
02934     
PSECTION SectionPointer;
02935 
02936     
02937     
02938     
02939 
02940     
KeEnterCriticalRegion();
02941 
02942     
KeWaitForSingleObject (&
MmSystemLoadLock,
02943                            
WrVirtualMemory,
02944                            
KernelMode,
02945                            
FALSE,
02946                            (PLARGE_INTEGER)
NULL);
02947 
02948     
MmLockPagableSectionByHandle(
ExPageLockHandle);
02949 
02950     ViewDeleted = 
FALSE;
02951     DataTableEntry = (PLDR_DATA_TABLE_ENTRY)ImageHandle;
02952     BasedAddress = DataTableEntry->DllBase;
02953 
02954 
#if DBGXX
02955 
    
02956     
02957     
02958 
02959     
if (
PsLoadedModuleList.Flink) {
02960         LOGICAL Found;
02961         PLIST_ENTRY NextEntry;
02962         PLDR_DATA_TABLE_ENTRY DataTableEntry2;
02963 
02964         Found = 
FALSE;
02965         NextEntry = 
PsLoadedModuleList.Flink;
02966         
while (NextEntry != &
PsLoadedModuleList) {
02967     
02968             DataTableEntry2 = CONTAINING_RECORD(NextEntry,
02969                                                 LDR_DATA_TABLE_ENTRY,
02970                                                 InLoadOrderLinks);
02971             
if (DataTableEntry == DataTableEntry2) {
02972                 Found = 
TRUE;
02973                 
break;
02974             }
02975             NextEntry = NextEntry->Flink;
02976         }
02977         
ASSERT (Found == 
TRUE);
02978     }
02979 
#endif
02980 
02981 
#if DBG_SYSLOAD
02982 
    if (DataTableEntry->SectionPointer == 
NULL) {
02983         
DbgPrint (
"MM: Called to unload boot driver %wZ\n",
02984             &DataTableEntry->FullDllName);
02985     }
02986     
else {
02987         
DbgPrint (
"MM: Called to unload non-boot driver %wZ\n",
02988             &DataTableEntry->FullDllName);
02989     }
02990 
#endif
02991 
02992     
02993     
02994     
02995     
02996     
02997 
02998     
if (DataTableEntry->LoadedImports == (PVOID)
LOADED_AT_BOOT) {
02999         
MmUnlockPagableImageSection(
ExPageLockHandle);
03000         
KeReleaseMutant (&
MmSystemLoadLock, 1, 
FALSE, 
FALSE);
03001         
KeLeaveCriticalRegion();
03002         
return STATUS_SUCCESS;
03003     }
03004 
03005     
ASSERT (DataTableEntry->LoadCount != 0);
03006 
03007     
if (
MI_IS_SESSION_IMAGE_ADDRESS (BasedAddress)) {
03008 
03009         
03010         
03011         
03012         
03013 
03014         DriverImage = 
MiSessionLookupImage (BasedAddress);
03015 
03016         
ASSERT (DriverImage);
03017 
03018         
ASSERT (DriverImage->
ImageCountInThisSession);
03019 
03020         
if (DriverImage->
ImageCountInThisSession > 1) {
03021 
03022             DriverImage->
ImageCountInThisSession -= 1;
03023             
MmUnlockPagableImageSection(
ExPageLockHandle);
03024             
KeReleaseMutant (&
MmSystemLoadLock, 1, 
FALSE, 
FALSE);
03025             
KeLeaveCriticalRegion();
03026 
03027             
return STATUS_SUCCESS;
03028         }
03029 
03030         
03031         
03032         
03033         
03034 
03035         
Status = 
MiSessionWideGetImageSize (BasedAddress,
03036                                             &NumberOfBytes,
03037                                             &CommittedPages);
03038 
03039         
if (!
NT_SUCCESS(
Status)) {
03040 
03041             
KeBugCheckEx (MEMORY_MANAGEMENT,
03042                           0x41286,
03043                           (ULONG_PTR)
MmSessionSpace->
SessionId,
03044                           (ULONG_PTR)BasedAddress,
03045                           0);
03046         }
03047 
03048         
03049         
03050         
03051         
03052         
03053         
03054         
03055 
03056         PointerPte = 
MiGetPteAddress (BasedAddress);
03057         LastPte = 
MiGetPteAddress ((ULONG_PTR)BasedAddress + NumberOfBytes);
03058 
03059         PagesRequired = 
MiDeleteSystemPagableVm (PointerPte,
03060                                                  (PFN_NUMBER)(LastPte - PointerPte),
03061                                                  
ZeroKernelPte,
03062                                                  
TRUE,
03063                                                  &ResidentPages);
03064 
03065         
if (
MmDisablePagingExecutive == 0) {
03066 
03067             SectionPointer = (
PSECTION)DataTableEntry->SectionPointer;
03068         
03069             
if ((SectionPointer == 
NULL) ||
03070                 (SectionPointer == (PVOID)-1) ||
03071                 (SectionPointer->Segment == 
NULL) ||
03072                 (SectionPointer->Segment->BasedAddress != SectionPointer->Segment->SystemImageBase)) {
03073 
03074                 
MmTotalSystemDriverPages -= (ULONG)(PagesRequired - ResidentPages);
03075             }
03076         }
03077 
03078         
LOCK_SESSION_SPACE_WS (OldIrql);
03079         
MmSessionSpace->
CommittedPages -= CommittedPages;
03080 
03081         
MM_BUMP_SESS_COUNTER(
MM_DBG_SESSION_COMMIT_IMAGE_UNLOAD,
03082             CommittedPages);
03083 
03084         
UNLOCK_SESSION_SPACE_WS (OldIrql);
03085 
03086         ViewDeleted = 
TRUE;
03087 
03088         
03089         
03090         
03091         
03092 
03093         
MiReturnCommitment (CommittedPages);
03094         
MM_TRACK_COMMIT (
MM_DBG_COMMIT_RETURN_DRIVER_UNLOAD, CommittedPages);
03095 
03096         
03097         
03098         
03099         
03100 
03101         
Status = 
MiRemoveImageSessionWide (BasedAddress);
03102 
03103         
ASSERT (
NT_SUCCESS (
Status));
03104     }
03105 
03106     
ASSERT (DataTableEntry->LoadCount != 0);
03107 
03108     DataTableEntry->LoadCount -= 1;
03109 
03110     
if (DataTableEntry->LoadCount != 0) {
03111         
MmUnlockPagableImageSection(
ExPageLockHandle);
03112         
KeReleaseMutant (&
MmSystemLoadLock, 1, 
FALSE, 
FALSE);
03113         
KeLeaveCriticalRegion();
03114         
return STATUS_SUCCESS;
03115     }
03116 
03117 
#if DBG
03118 
    if (
MI_IS_SESSION_IMAGE_ADDRESS (BasedAddress)) {
03119         
ASSERT (
MiSessionLookupImage (BasedAddress) == 
NULL);
03120     }
03121 
#endif
03122 
03123     
if (
MmSnapUnloads) {
03124 
#if 0
03125 
        StillQueued = 
KeCheckForTimer (DataTableEntry->DllBase,
03126                                        DataTableEntry->SizeOfImage);
03127 
03128         
if (StillQueued != 
NULL) {
03129             
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
03130                           0x18,
03131                           (ULONG_PTR)StillQueued,
03132                           (ULONG_PTR)-1,
03133                           (ULONG_PTR)DataTableEntry->DllBase);
03134         }
03135 
03136         StillQueued = 
ExpCheckForResource (DataTableEntry->DllBase,
03137                                            DataTableEntry->SizeOfImage);
03138 
03139         
if (StillQueued != 
NULL) {
03140             
KeBugCheckEx (DRIVER_VERIFIER_DETECTED_VIOLATION,
03141                           0x19,
03142                           (ULONG_PTR)StillQueued,
03143                           (ULONG_PTR)-1,
03144                           (ULONG_PTR)DataTableEntry->DllBase);
03145         }
03146 
#endif
03147 
    }
03148 
03149     
if (DataTableEntry->Flags & LDRP_IMAGE_VERIFYING) {
03150         
MiVerifyingDriverUnloading (DataTableEntry);
03151     }
03152 
03153     
if (
MiActiveVerifierThunks != 0) {
03154         
MiVerifierCheckThunks (DataTableEntry);
03155     }
03156 
03157     
03158     
03159     
03160 
03161     
if (DataTableEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED) {
03162 
03163         
03164         
03165         
03166 
03167         ANSI_STRING AnsiName;
03168         
NTSTATUS Status;
03169 
03170         
Status = 
RtlUnicodeStringToAnsiString( &AnsiName,
03171                                                &DataTableEntry->BaseDllName,
03172                                                
TRUE );
03173 
03174         
if (
NT_SUCCESS( 
Status)) {
03175             DbgUnLoadImageSymbols( &AnsiName,
03176                                    BasedAddress,
03177                                    (ULONG)-1);
03178             
RtlFreeAnsiString( &AnsiName );
03179         }
03180     }
03181 
03182     
03183     
03184     
03185     
03186     
03187 
03188     
if (ViewDeleted == 
FALSE) {
03189 
03190         NumberOfPtes = DataTableEntry->SizeOfImage >> 
PAGE_SHIFT;
03191 
03192         
if (
MmSnapUnloads) {
03193             
MiRememberUnloadedDriver (&DataTableEntry->BaseDllName,
03194                                       BasedAddress,
03195                                       (ULONG)(NumberOfPtes << 
PAGE_SHIFT));
03196         }
03197 
03198         
if (DataTableEntry->Flags & LDRP_SYSTEM_MAPPED) {
03199 
03200             PointerPte = 
MiGetPteAddress (BasedAddress);
03201 
03202             PagesRequired = 
MiDeleteSystemPagableVm (PointerPte,
03203                                                      NumberOfPtes,
03204                                                      
ZeroKernelPte,
03205                                                      
FALSE,
03206                                                      &ResidentPages);
03207     
03208             
MmTotalSystemDriverPages -= (ULONG)(PagesRequired - ResidentPages);
03209 
03210             
03211             
03212             
03213             
03214     
03215             
MiReleaseSystemPtes (PointerPte,
03216                                  (ULONG)NumberOfPtes,
03217                                  
SystemPteSpace);
03218 
03219             
LOCK_PFN (OldIrql);
03220             
MmResidentAvailablePages += ResidentPages;
03221             
MM_BUMP_COUNTER(21, ResidentPages);
03222             
UNLOCK_PFN (OldIrql);
03223 
03224             
03225             
03226             
03227             
03228     
03229             
if (DataTableEntry->SectionPointer != 
NULL) {
03230                 
MiReturnCommitment (PagesRequired);
03231                 
MM_TRACK_COMMIT (
MM_DBG_COMMIT_RETURN_DRIVER_UNLOAD1, PagesRequired);
03232                 
MmDriverCommit -= (ULONG)PagesRequired;
03233             }
03234         }
03235         
else {
03236 
03237             
03238             
03239             
03240             
03241             
03242             
03243             
03244 
03245             
03246             
03247             
03248             
03249         }
03250     }
03251 
03252     
03253     
03254     
03255     
03256     
03257     
03258 
03259     
if (DataTableEntry->InLoadOrderLinks.Flink != 
NULL) {
03260         
KeEnterCriticalRegion();
03261         
ExAcquireResourceExclusive (&
PsLoadedModuleResource, 
TRUE);
03262 
03263         ExAcquireSpinLock (&
PsLoadedModuleSpinLock, &OldIrql);
03264 
03265         RemoveEntryList(&DataTableEntry->InLoadOrderLinks);
03266         ExReleaseSpinLock (&
PsLoadedModuleSpinLock, OldIrql);
03267 
03268         
ExReleaseResource (&
PsLoadedModuleResource);
03269         
KeLeaveCriticalRegion();
03270 
03271         MustFree = 
TRUE;
03272     }
03273     
else {
03274         MustFree = 
FALSE;
03275     }
03276 
03277     
03278     
03279     
03280     
03281 
03282     
MiDereferenceImports ((
PLOAD_IMPORTS)DataTableEntry->LoadedImports);
03283 
03284     
MiClearImports (DataTableEntry);
03285 
03286     
03287     
03288     
03289 
03290     
if (MustFree == 
TRUE) {
03291 
03292         
if (DataTableEntry->FullDllName.Buffer != 
NULL) {
03293             
ExFreePool (DataTableEntry->FullDllName.Buffer);
03294         }
03295 
03296         
if (DataTableEntry->BaseDllName.Buffer != 
NULL) {
03297             
ExFreePool (DataTableEntry->BaseDllName.Buffer);
03298         }
03299 
03300         
03301         
03302         
03303         
03304 
03305         
if ((DataTableEntry->SectionPointer != 
NULL) &&
03306             (DataTableEntry->SectionPointer != (PVOID)-1)) {
03307 
03308             
ObDereferenceObject (DataTableEntry->SectionPointer);
03309         }
03310 
03311         
ExFreePool((PVOID)DataTableEntry);
03312     }
03313 
03314     
MmUnlockPagableImageSection(
ExPageLockHandle);
03315 
03316     
KeReleaseMutant (&
MmSystemLoadLock, 1, 
FALSE, 
FALSE);
03317     
KeLeaveCriticalRegion();
03318 
03319     
PERFINFO_IMAGE_UNLOAD(BasedAddress);
03320 
03321     
return STATUS_SUCCESS;
03322 }
03323 
03324 
03325 
NTSTATUS
03326 MiBuildImportsForBootDrivers(
03327     VOID
03328     )
03329 
03330 
03331 
03332 
03333 
03334 
03335 
03336 
03337 
03338 
03339 
03340 
03341 
03342 
03343 
03344 
03345 
03346 
03347 
03348 
03349 
03350 
03351 
03352 
03353 
03354 
03355 {
03356     PLDR_DATA_TABLE_ENTRY DataTableEntry;
03357     PLIST_ENTRY NextEntry;
03358     PLDR_DATA_TABLE_ENTRY DataTableEntry2;
03359     PLIST_ENTRY NextEntry2;
03360     ULONG i;
03361     ULONG j;
03362     ULONG ImageCount;
03363     PVOID *ImageReferences;
03364     PVOID LastImageReference;
03365     PULONG_PTR ImportThunk;
03366     ULONG_PTR BaseAddress;
03367     ULONG_PTR LastAddress;
03368     ULONG ImportSize;
03369     ULONG ImportListSize;
03370     
PLOAD_IMPORTS ImportList;
03371     LOGICAL UndoEverything;
03372     PLDR_DATA_TABLE_ENTRY KernelDataTableEntry;
03373     PLDR_DATA_TABLE_ENTRY HalDataTableEntry;
03374     UNICODE_STRING KernelString;
03375     UNICODE_STRING HalString;
03376 
03377     
PAGED_CODE();
03378 
03379     ImageCount = 0;
03380 
03381     KernelDataTableEntry = 
NULL;
03382     HalDataTableEntry = 
NULL;
03383 
03384     
RtlInitUnicodeString (&KernelString, 
L"ntoskrnl.exe");
03385     
RtlInitUnicodeString (&HalString, 
L"hal.dll");
03386 
03387     NextEntry = 
PsLoadedModuleList.Flink;
03388     
while (NextEntry != &
PsLoadedModuleList) {
03389 
03390         DataTableEntry = CONTAINING_RECORD(NextEntry,
03391                                            LDR_DATA_TABLE_ENTRY,
03392                                            InLoadOrderLinks);
03393 
03394         
if (
RtlEqualUnicodeString (&KernelString,
03395                                    &DataTableEntry->BaseDllName,
03396                                    
TRUE)) {
03397 
03398             KernelDataTableEntry = CONTAINING_RECORD(NextEntry,
03399                                                      LDR_DATA_TABLE_ENTRY,
03400                                                      InLoadOrderLinks);
03401         }
03402         
else if (
RtlEqualUnicodeString (&HalString,
03403                                         &DataTableEntry->BaseDllName,
03404                                         
TRUE)) {
03405 
03406             HalDataTableEntry = CONTAINING_RECORD(NextEntry,
03407                                                   LDR_DATA_TABLE_ENTRY,
03408                                                   InLoadOrderLinks);
03409         }
03410 
03411         
03412         
03413         
03414 
03415         DataTableEntry->LoadCount = 1;
03416         DataTableEntry->LoadedImports = (PVOID)
LOADED_AT_BOOT;
03417 
03418         ImageCount += 1;
03419         NextEntry = NextEntry->Flink;
03420     }
03421 
03422     
if (KernelDataTableEntry == 
NULL || HalDataTableEntry == 
NULL) {
03423         
return STATUS_NOT_FOUND;
03424     }
03425 
03426     ImageReferences = (PVOID *) 
ExAllocatePoolWithTag (
PagedPool,
03427                                                        ImageCount * 
sizeof (PVOID),
03428                                                        'TDmM');
03429 
03430     
if (ImageReferences == 
NULL) {
03431         
return STATUS_INSUFFICIENT_RESOURCES;
03432     }
03433 
03434     UndoEverything = 
FALSE;
03435 
03436     NextEntry = 
PsLoadedModuleList.Flink;
03437 
03438     
for ( ; NextEntry != &
PsLoadedModuleList; NextEntry = NextEntry->Flink) {
03439 
03440         DataTableEntry = CONTAINING_RECORD(NextEntry,
03441                                            LDR_DATA_TABLE_ENTRY,
03442                                            InLoadOrderLinks);
03443 
03444         ImportThunk = (PULONG_PTR)
RtlImageDirectoryEntryToData(
03445                                            DataTableEntry->DllBase,
03446                                            
TRUE,
03447                                            IMAGE_DIRECTORY_ENTRY_IAT,
03448                                            &ImportSize);
03449     
03450         
if (ImportThunk == 
NULL) {
03451             DataTableEntry->LoadedImports = 
NO_IMPORTS_USED;
03452             
continue;
03453         }
03454     
03455         RtlZeroMemory (ImageReferences, ImageCount * 
sizeof (PVOID));
03456 
03457         ImportSize /= 
sizeof(PULONG_PTR);
03458 
03459         BaseAddress = 0;
03460         
for (i = 0; i < ImportSize; i += 1, ImportThunk += 1) {
03461 
03462             
03463             
03464             
03465 
03466             
if (BaseAddress) {
03467                 
if (*ImportThunk >= BaseAddress && *ImportThunk < LastAddress) {
03468                     
ASSERT (ImageReferences[j]);
03469                     
continue;
03470                 }
03471             }
03472 
03473             j = 0;
03474             NextEntry2 = 
PsLoadedModuleList.Flink;
03475 
03476             
while (NextEntry2 != &
PsLoadedModuleList) {
03477 
03478                 DataTableEntry2 = CONTAINING_RECORD(NextEntry2,
03479                                                     LDR_DATA_TABLE_ENTRY,
03480                                                     InLoadOrderLinks);
03481     
03482                 BaseAddress = (ULONG_PTR) DataTableEntry2->DllBase;
03483                 LastAddress = BaseAddress + DataTableEntry2->SizeOfImage;
03484 
03485                 
if (*ImportThunk >= BaseAddress && *ImportThunk < LastAddress) {
03486                     ImageReferences[j] = DataTableEntry2;
03487                     
break;
03488                 }
03489 
03490                 NextEntry2 = NextEntry2->Flink;
03491                 j += 1;
03492             }
03493 
03494             
if (*ImportThunk < BaseAddress || *ImportThunk >= LastAddress) {
03495                 
if (*ImportThunk) {
03496 
#if DBG
03497 
                    DbgPrint (
"MM: broken import linkage %p %p %p\n",
03498                         DataTableEntry,
03499                         ImportThunk,
03500                         *ImportThunk);
03501                     DbgBreakPoint ();
03502 
#endif
03503 
                    UndoEverything = 
TRUE;
03504                     
goto finished;
03505                 }
03506 
03507                 BaseAddress = 0;
03508             }
03509         }
03510 
03511         ImportSize = 0;
03512 
03513         
for (i = 0; i < ImageCount; i += 1) {
03514 
03515             
if ((ImageReferences[i] != 
NULL) &&
03516                 (ImageReferences[i] != KernelDataTableEntry) &&
03517                 (ImageReferences[i] != HalDataTableEntry)) {
03518 
03519                     LastImageReference = ImageReferences[i];
03520                     ImportSize += 1;
03521             }
03522         }
03523 
03524         
if (ImportSize == 0) {
03525             DataTableEntry->LoadedImports = 
NO_IMPORTS_USED;
03526         }
03527         
else if (ImportSize == 1) {
03528 
#if DBG_SYSLOAD
03529 
            DbgPrint(
"driver %wZ imports %wZ\n",
03530                 &DataTableEntry->FullDllName,
03531                 &((PLDR_DATA_TABLE_ENTRY)LastImageReference)->FullDllName);
03532 
#endif
03533 
03534             DataTableEntry->LoadedImports = 
POINTER_TO_SINGLE_ENTRY (LastImageReference);
03535             ((PLDR_DATA_TABLE_ENTRY)LastImageReference)->LoadCount += 1;
03536         }
03537         
else {
03538 
#if DBG_SYSLOAD
03539 
            DbgPrint(
"driver %wZ imports many\n", &DataTableEntry->FullDllName);
03540 
#endif
03541 
03542             ImportListSize = ImportSize * 
sizeof(PVOID) + 
sizeof(SIZE_T);
03543 
03544             ImportList = (
PLOAD_IMPORTS) 
ExAllocatePoolWithTag (
PagedPool,
03545                                                                 ImportListSize,
03546                                                                 'TDmM');
03547 
03548             
if (ImportList == 
NULL) {
03549                 UndoEverything = 
TRUE;
03550                 
break;
03551             }
03552 
03553             ImportList->
Count = ImportSize;
03554 
03555             j = 0;
03556             
for (i = 0; i < ImageCount; i += 1) {
03557     
03558                 
if ((ImageReferences[i] != 
NULL) &&
03559                     (ImageReferences[i] != KernelDataTableEntry) &&
03560                     (ImageReferences[i] != HalDataTableEntry)) {
03561     
03562 
#if DBG_SYSLOAD
03563 
                        DbgPrint(
"driver %wZ imports %wZ\n",
03564                             &DataTableEntry->FullDllName,
03565                             &((PLDR_DATA_TABLE_ENTRY)ImageReferences[i])->FullDllName);
03566 
#endif
03567 
03568                         ImportList->
Entry[j] = ImageReferences[i];
03569                         ((PLDR_DATA_TABLE_ENTRY)ImageReferences[i])->LoadCount += 1;
03570                         j += 1;
03571                 }
03572             }
03573 
03574             
ASSERT (j == ImportSize);
03575 
03576             DataTableEntry->LoadedImports = ImportList;
03577         }
03578 
#if DBG_SYSLOAD
03579 
        DbgPrint(
"\n");
03580 
#endif
03581 
    }
03582 
03583 finished:
03584 
03585     
ExFreePool ((PVOID)ImageReferences);
03586 
03587     
03588     
03589     
03590 
03591     
if ((KernelDataTableEntry->LoadedImports != 
NO_IMPORTS_USED) &&
03592         (!
POINTER_TO_SINGLE_ENTRY(KernelDataTableEntry->LoadedImports))) {
03593             
ExFreePool ((PVOID)KernelDataTableEntry->LoadedImports);
03594     }
03595 
03596     
if ((HalDataTableEntry->LoadedImports != 
NO_IMPORTS_USED) &&
03597         (!
POINTER_TO_SINGLE_ENTRY(HalDataTableEntry->LoadedImports))) {
03598             
ExFreePool ((PVOID)HalDataTableEntry->LoadedImports);
03599     }
03600 
03601     KernelDataTableEntry->LoadedImports = (PVOID)
LOADED_AT_BOOT;
03602     HalDataTableEntry->LoadedImports = (PVOID)
LOADED_AT_BOOT;
03603 
03604     
if (UndoEverything == 
TRUE) {
03605 
03606 
#if DBG_SYSLOAD
03607 
        DbgPrint(
"driver %wZ import rebuild failed\n",
03608             &DataTableEntry->FullDllName);
03609         DbgBreakPoint();
03610 
#endif
03611 
03612         
03613         
03614         
03615         
03616     
03617         NextEntry = 
PsLoadedModuleList.Flink;
03618         
while (NextEntry != &
PsLoadedModuleList) {
03619             DataTableEntry = CONTAINING_RECORD(NextEntry,
03620                                                LDR_DATA_TABLE_ENTRY,
03621                                                InLoadOrderLinks);
03622 
03623             ImportList = DataTableEntry->LoadedImports;
03624             
if (ImportList == 
LOADED_AT_BOOT || ImportList == 
NO_IMPORTS_USED ||
03625                 
SINGLE_ENTRY(ImportList)) {
03626                     NOTHING;
03627             }
03628             
else {
03629                 
ExFreePool (ImportList);
03630             }
03631 
03632             DataTableEntry->LoadedImports = (PVOID)
LOADED_AT_BOOT;
03633             DataTableEntry->LoadCount = 1;
03634             NextEntry = NextEntry->Flink;
03635         }
03636 
03637         
return STATUS_INSUFFICIENT_RESOURCES;
03638     }
03639 
03640     
return STATUS_SUCCESS;
03641 }
03642 
03643 
03644 LOGICAL
03645 MiCallDllUnloadAndUnloadDll(
03646     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
03647     )
03648 
03649 
03650 
03651 
03652 
03653 
03654 
03655 
03656 
03657 
03658 
03659 
03660 
03661 
03662 
03663 
03664 
03665 
03666 
03667 
03668 
03669 
03670 
03671 
03672 
03673 {
03674     
PMM_DLL_UNLOAD Func;
03675     
NTSTATUS Status;
03676     LOGICAL Unloaded;
03677 
03678     
PAGED_CODE();
03679 
03680     Unloaded = 
FALSE;
03681 
03682     Func = 
MiLocateExportName (DataTableEntry->DllBase, 
"DllUnload");
03683 
03684     
if (Func) {
03685 
03686         
03687         
03688         
03689 
03690         
Status = Func();
03691 
03692         
if (
NT_SUCCESS(
Status)) {
03693 
03694             
03695             
03696             
03697             
03698 
03699             
ASSERT (DataTableEntry->LoadCount == 0);
03700             DataTableEntry->LoadCount = 1;
03701 
03702             
MmUnloadSystemImage ((PVOID)DataTableEntry);
03703             Unloaded = 
TRUE;
03704         }
03705     }
03706 
03707     
return Unloaded;
03708 }
03709 
03710 
03711 PVOID
03712 MiLocateExportName (
03713     IN PVOID DllBase,
03714     IN PCHAR FunctionName
03715     )
03716 
03717 
03718 
03719 
03720 
03721 
03722 
03723 
03724 
03725 
03726 
03727 
03728 
03729 
03730 
03731 
03732 
03733 
03734 
03735 {
03736     PVOID Func = 
NULL;
03737     PULONG NameTableBase;
03738     
PUSHORT NameOrdinalTableBase;
03739     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
03740     PULONG Addr;
03741     ULONG ExportSize;
03742     ULONG Low;
03743     ULONG Middle;
03744     ULONG High;
03745     LONG Result;
03746     
USHORT OrdinalNumber;
03747 
03748     
PAGED_CODE();
03749 
03750     
03751     
03752     
03753 
03754     ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(
03755                                 DllBase,
03756                                 
TRUE,
03757                                 IMAGE_DIRECTORY_ENTRY_EXPORT,
03758                                 &ExportSize
03759                                 );
03760     
if (ExportDirectory) {
03761 
03762         NameTableBase =  (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
03763         NameOrdinalTableBase = (
PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
03764 
03765         
03766         
03767         
03768 
03769         Low = 0;
03770         High = ExportDirectory->NumberOfNames - 1;
03771 
03772         
while (High >= Low && (LONG)High >= 0) {
03773 
03774             
03775             
03776             
03777             
03778 
03779             Middle = (Low + High) >> 1;
03780             Result = strcmp(FunctionName,
03781                             (PCHAR)((PCHAR)DllBase + NameTableBase[Middle]));
03782 
03783             
if (Result < 0) {
03784                 High = Middle - 1;
03785             } 
else if (Result > 0) {
03786                 Low = Middle + 1;
03787             } 
else {
03788                 
break;
03789             }
03790         }
03791 
03792         
03793         
03794         
03795         
03796         
03797 
03798         
if ((LONG)High >= (LONG)Low) {
03799 
03800             OrdinalNumber = NameOrdinalTableBase[Middle];
03801             Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
03802             Func = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]);
03803 
03804             
03805             
03806             
03807             
03808             
03809 
03810             
if ((ULONG_PTR)Func > (ULONG_PTR)ExportDirectory &&
03811                 (ULONG_PTR)Func < ((ULONG_PTR)ExportDirectory + ExportSize)) {
03812                 Func = 
NULL;
03813             }
03814         }
03815     }
03816 
03817     
return Func;
03818 }
03819 
03820 
03821 
NTSTATUS
03822 MiDereferenceImports (
03823     IN PLOAD_IMPORTS ImportList
03824     )
03825 
03826 
03827 
03828 
03829 
03830 
03831 
03832 
03833 
03834 
03835 
03836 
03837 
03838 
03839 
03840 
03841 
03842 
03843 
03844 
03845 
03846 
03847 {
03848     ULONG i;
03849     LOGICAL Unloaded;
03850     PVOID SavedImports;
03851     
LOAD_IMPORTS SingleTableEntry;
03852     PLDR_DATA_TABLE_ENTRY ImportTableEntry;
03853 
03854     
PAGED_CODE();
03855 
03856     
if (ImportList == 
LOADED_AT_BOOT || ImportList == 
NO_IMPORTS_USED) {
03857         
return STATUS_SUCCESS;
03858     }
03859 
03860     
if (
SINGLE_ENTRY(ImportList)) {
03861         SingleTableEntry.
Count = 1;
03862         SingleTableEntry.
Entry[0] = 
SINGLE_ENTRY_TO_POINTER(ImportList);
03863         ImportList = &SingleTableEntry;
03864     }
03865 
03866     
for (i = 0; i < ImportList->Count && ImportList->Entry[i]; i += 1) {
03867         ImportTableEntry = ImportList->
Entry[i];
03868 
03869         
if (ImportTableEntry->LoadedImports == (PVOID)
LOADED_AT_BOOT) {
03870 
03871             
03872             
03873             
03874 
03875             
continue;
03876         }
03877 
03878 
#if DBG
03879 
        {
03880             ULONG ImageCount;
03881             PLIST_ENTRY NextEntry;
03882             PLDR_DATA_TABLE_ENTRY DataTableEntry;
03883 
03884             
03885             
03886             
03887             
03888 
03889             NextEntry = 
PsLoadedModuleList.Flink;
03890 
03891             ImageCount = 0;
03892             
while (NextEntry != &
PsLoadedModuleList && ImageCount < 2) {
03893                 DataTableEntry = CONTAINING_RECORD(NextEntry,
03894                                                    LDR_DATA_TABLE_ENTRY,
03895                                                    InLoadOrderLinks);
03896                 
ASSERT (ImportTableEntry != DataTableEntry);
03897                 
ASSERT (DataTableEntry->LoadCount == 1);
03898                 NextEntry = NextEntry->Flink;
03899                 ImageCount += 1;
03900             }
03901         }
03902 
#endif
03903 
03904         
ASSERT (ImportTableEntry->LoadCount >= 1);
03905 
03906         ImportTableEntry->LoadCount -= 1;
03907 
03908         
if (ImportTableEntry->LoadCount == 0) {
03909 
03910             
03911             
03912             
03913             
03914             
03915             
03916             
03917             
03918             
03919 
03920             SavedImports = ImportTableEntry->LoadedImports;
03921 
03922             ImportTableEntry->LoadedImports = (PVOID)
NO_IMPORTS_USED;
03923 
03924             Unloaded = 
MiCallDllUnloadAndUnloadDll ((PVOID)ImportTableEntry);
03925 
03926             
if (Unloaded == 
TRUE) {
03927 
03928                 
03929                 
03930                 
03931                 
03932 
03933                 
MiDereferenceImports ((
PLOAD_IMPORTS)SavedImports);
03934 
03935                 
if ((SavedImports != (PVOID)
LOADED_AT_BOOT) &&
03936                     (SavedImports != (PVOID)
NO_IMPORTS_USED) &&
03937                     (!
SINGLE_ENTRY(SavedImports))) {
03938 
03939                         
ExFreePool (SavedImports);
03940                 }
03941             }
03942             
else {
03943                 ImportTableEntry->LoadedImports = SavedImports;
03944             }
03945         }
03946     }
03947 
03948     
return STATUS_SUCCESS;
03949 }
03950 
03951 
03952 
NTSTATUS
03953 MiResolveImageReferences (
03954     PVOID ImageBase,
03955     IN PUNICODE_STRING ImageFileDirectory,
03956     IN PUNICODE_STRING NamePrefix OPTIONAL,
03957     IN BOOLEAN LoadInSessionSpace,
03958     OUT PCHAR *MissingProcedureName,
03959     OUT PWSTR *MissingDriverName,
03960     OUT PLOAD_IMPORTS *LoadedImports
03961     )
03962 
03963 
03964 
03965 
03966 
03967 
03968 
03969 
03970 
03971 
03972 
03973 
03974 
03975 
03976 
03977 
03978 
03979 
03980 
03981 
03982 {
03983     PCHAR MissingProcedureStorageArea;
03984     PVOID ImportBase;
03985     ULONG ImportSize;
03986     ULONG ImportListSize;
03987     ULONG 
Count;
03988     ULONG i;
03989     PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
03990     PIMAGE_IMPORT_DESCRIPTOR Imp;
03991     
NTSTATUS st;
03992     ULONG ExportSize;
03993     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
03994     PIMAGE_THUNK_DATA NameThunk;
03995     PIMAGE_THUNK_DATA AddrThunk;
03996     PSZ ImportName;
03997     PLIST_ENTRY NextEntry;
03998     PLDR_DATA_TABLE_ENTRY DataTableEntry;
03999     PLDR_DATA_TABLE_ENTRY SingleEntry;
04000     ANSI_STRING AnsiString;
04001     UNICODE_STRING ImportName_U;
04002     UNICODE_STRING ImportDescriptorName_U;
04003     UNICODE_STRING DllToLoad;
04004     PVOID Section;
04005     PVOID BaseAddress;
04006     BOOLEAN PrefixedNameAllocated;
04007     BOOLEAN ReferenceImport;
04008     ULONG LinkWin32k = 0;
04009     ULONG LinkNonWin32k = 0;
04010     
PLOAD_IMPORTS ImportList;
04011     
PLOAD_IMPORTS CompactedImportList;
04012     BOOLEAN Loaded;
04013 
04014     
PAGED_CODE();
04015 
04016     *LoadedImports = 
NO_IMPORTS_USED;
04017 
04018     MissingProcedureStorageArea = *MissingProcedureName;
04019 
04020     ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(
04021                         ImageBase,
04022                         
TRUE,
04023                         IMAGE_DIRECTORY_ENTRY_IMPORT,
04024                         &ImportSize);
04025 
04026     
if (ImportDescriptor == 
NULL) {
04027         
return STATUS_SUCCESS;
04028     }
04029 
04030     
04031     
04032     
04033 
04034     
Count = 0;
04035     
for (Imp = ImportDescriptor; Imp->Name && Imp->OriginalFirstThunk; Imp += 1) {
04036         
Count += 1;
04037     }
04038 
04039     
if (
Count) {
04040         ImportListSize = 
Count * 
sizeof(PVOID) + 
sizeof(SIZE_T);
04041 
04042         ImportList = (
PLOAD_IMPORTS) 
ExAllocatePoolWithTag (
PagedPool,
04043                                              ImportListSize,
04044                                              'TDmM');
04045 
04046         
04047         
04048         
04049         
04050     
04051         
if (ImportList) {
04052             RtlZeroMemory (ImportList, ImportListSize);
04053             ImportList->
Count = 
Count;
04054         }
04055     }
04056     
else {
04057         ImportList = (
PLOAD_IMPORTS) 0;
04058     }
04059 
04060     
Count = 0;
04061     
while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk) {
04062 
04063         ImportName = (PSZ)((PCHAR)ImageBase + ImportDescriptor->Name);
04064 
04065         
04066         
04067         
04068         
04069         
04070         
04071         
04072         
04073 
04074         LinkWin32k = LinkWin32k |
04075              (!_strnicmp(ImportName, 
"win32k", 
sizeof(
"win32k") - 1));
04076 
04077         
04078         
04079         
04080         
04081 
04082         LinkNonWin32k = LinkNonWin32k |
04083             ((_strnicmp(ImportName, 
"win32k", 
sizeof(
"win32k") - 1)) &&
04084              (_strnicmp(ImportName, 
"dxapi", 
sizeof(
"dxapi") - 1)) &&
04085              (_strnicmp(ImportName, 
"coverage", 
sizeof(
"coverage") - 1)) &&
04086              (_strnicmp(ImportName, 
"irt", 
sizeof(
"irt") - 1)));
04087 
04088 
04089         
if (LinkNonWin32k && LinkWin32k) {
04090             
MiDereferenceImports (ImportList);
04091             
if (ImportList) {
04092                 
ExFreePool (ImportList);
04093             }
04094             
return (STATUS_PROCEDURE_NOT_FOUND);
04095         }
04096 
04097         
if ((!_strnicmp(ImportName, 
"ntdll",    
sizeof(
"ntdll") - 1))    ||
04098             (!_strnicmp(ImportName, 
"winsrv",   
sizeof(
"winsrv") - 1))   ||
04099             (!_strnicmp(ImportName, 
"advapi32", 
sizeof(
"advapi32") - 1)) ||
04100             (!_strnicmp(ImportName, 
"kernel32", 
sizeof(
"kernel32") - 1)) ||
04101             (!_strnicmp(ImportName, 
"user32",   
sizeof(
"user32") - 1))   ||
04102             (!_strnicmp(ImportName, 
"gdi32",    
sizeof(
"gdi32") - 1)) ) {
04103 
04104             
MiDereferenceImports (ImportList);
04105 
04106             
if (ImportList) {
04107                 
ExFreePool (ImportList);
04108             }
04109             
return (STATUS_PROCEDURE_NOT_FOUND);
04110         }
04111 
04112         
if ((!_strnicmp(ImportName, 
"ntoskrnl", 
sizeof(
"ntoskrnl") - 1)) ||
04113             (!_strnicmp(ImportName, 
"win32k", 
sizeof(
"win32k") - 1))     ||
04114             (!_strnicmp(ImportName, 
"hal",   
sizeof(
"hal") - 1))) {
04115 
04116                 
04117                 
04118                 
04119                 
04120 
04121                 ReferenceImport = 
FALSE;
04122         }
04123         
else {
04124                 ReferenceImport = 
TRUE;
04125         }
04126 
04127         
RtlInitAnsiString(&AnsiString, ImportName);
04128         st = 
RtlAnsiStringToUnicodeString(&ImportName_U, &AnsiString, 
TRUE);
04129         
if (!
NT_SUCCESS(st)) {
04130             
MiDereferenceImports (ImportList);
04131             
if (ImportList) {
04132                 
ExFreePool (ImportList);
04133             }
04134             
return st;
04135         }
04136 
04137         
if (NamePrefix  &&
04138             (_strnicmp(ImportName, 
"ntoskrnl", 
sizeof(
"ntoskrnl") - 1) &&
04139              _strnicmp(ImportName, 
"hal", 
sizeof(
"hal") - 1))) {
04140 
04141             ImportDescriptorName_U.MaximumLength = ImportName_U.Length + NamePrefix->Length;
04142             ImportDescriptorName_U.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
04143                                                 ImportDescriptorName_U.MaximumLength,
04144                                                 'TDmM');
04145             
if (!ImportDescriptorName_U.Buffer) {
04146                 
RtlFreeUnicodeString(&ImportName_U);
04147                 
MiDereferenceImports (ImportList);
04148                 
if (ImportList) {
04149                     
ExFreePool (ImportList);
04150                 }
04151                 
return STATUS_INSUFFICIENT_RESOURCES;
04152             }
04153 
04154             ImportDescriptorName_U.Length = 0;
04155             
RtlAppendUnicodeStringToString(&ImportDescriptorName_U, NamePrefix);
04156             
RtlAppendUnicodeStringToString(&ImportDescriptorName_U, &ImportName_U);
04157             PrefixedNameAllocated = 
TRUE;
04158         } 
else {
04159             ImportDescriptorName_U = ImportName_U;
04160             PrefixedNameAllocated = 
FALSE;
04161         }
04162 
04163         Loaded = 
FALSE;
04164 
04165 ReCheck:
04166         NextEntry = 
PsLoadedModuleList.Flink;
04167         ImportBase = 
NULL;
04168 
04169         
while (NextEntry != &
PsLoadedModuleList) {
04170 
04171             DataTableEntry = CONTAINING_RECORD(NextEntry,
04172                                                LDR_DATA_TABLE_ENTRY,
04173                                                InLoadOrderLinks);
04174 
04175             
if (
RtlEqualUnicodeString (&ImportDescriptorName_U,
04176                                        &DataTableEntry->BaseDllName,
04177                                        
TRUE
04178                                        )) {
04179 
04180                 ImportBase = DataTableEntry->DllBase;
04181 
04182                 
04183                 
04184                 
04185                 
04186                 
04187                 
04188                 
04189 
04190                 
if (Loaded == 
FALSE && ReferenceImport == 
TRUE) {
04191                     DataTableEntry->LoadCount += 1;
04192                 }
04193 
04194                 
break;
04195             }
04196             NextEntry = NextEntry->Flink;
04197         }
04198 
04199         
if (!ImportBase) {
04200 
04201             
04202             
04203             
04204 
04205             DllToLoad.MaximumLength = ImportName_U.Length +
04206                                         ImageFileDirectory->Length +
04207                                         (
USHORT)
sizeof(WCHAR);
04208 
04209             DllToLoad.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
04210                                                DllToLoad.MaximumLength,
04211                                                'TDmM');
04212 
04213             
if (DllToLoad.Buffer) {
04214                 DllToLoad.Length = ImageFileDirectory->Length;
04215                 RtlMoveMemory (DllToLoad.Buffer,
04216                                ImageFileDirectory->Buffer,
04217                                ImageFileDirectory->Length);
04218 
04219                 
RtlAppendStringToString ((PSTRING)&DllToLoad,
04220                                          (PSTRING)&ImportName_U);
04221 
04222                 st = 
MmLoadSystemImage (&DllToLoad,
04223                                         NamePrefix,
04224                                         
NULL,
04225                                         LoadInSessionSpace,
04226                                         &Section,
04227                                         &BaseAddress);
04228 
04229                 
ExFreePool (DllToLoad.Buffer);
04230             } 
else {
04231                 st = STATUS_INSUFFICIENT_RESOURCES;
04232             }
04233 
04234             
04235             
04236             
04237 
04238             
if (
NT_SUCCESS(st)) {
04239 
04240                 
PMM_DLL_INITIALIZE Func;
04241                 UNICODE_STRING RegistryPath;
04242 
04243                 Loaded = 
TRUE;
04244 
04245                 Func = 
MiLocateExportName (BaseAddress, 
"DllInitialize");
04246                 
if (Func) {
04247 
04248                     
04249                     
04250                     
04251                     
04252                     
04253 
04254                     RegistryPath.MaximumLength = 
CmRegistryMachineSystemCurrentControlSetServices.Length +
04255                                                     ImportName_U.Length +
04256                                                     (
USHORT)(2*
sizeof(WCHAR));
04257                     RegistryPath.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
04258                                                     RegistryPath.MaximumLength,
04259                                                     'TDmM');
04260                     
if (RegistryPath.Buffer) {
04261                         PWCHAR Dot;
04262 
04263                         RegistryPath.Length = 
CmRegistryMachineSystemCurrentControlSetServices.Length;
04264                         RtlMoveMemory (RegistryPath.Buffer,
04265                                        
CmRegistryMachineSystemCurrentControlSetServices.Buffer,
04266                                        
CmRegistryMachineSystemCurrentControlSetServices.Length);
04267 
04268                         
RtlAppendUnicodeToString (&RegistryPath, 
L"\\");
04269                         Dot = wcschr (ImportName_U.Buffer, 
L'.');
04270                         
if (Dot) {
04271                             ImportName_U.Length = (
USHORT)((Dot - ImportName_U.Buffer)*
sizeof(WCHAR));
04272                         }
04273                         
RtlAppendUnicodeStringToString (&RegistryPath,
04274                                                         &ImportName_U);
04275 
04276                         
04277                         
04278                         
04279 
04280                         st = Func (&RegistryPath);
04281                         
ExFreePool (RegistryPath.Buffer);
04282 
04283                         
if (!
NT_SUCCESS(st)) {
04284 
04285                             
04286                             
04287                             
04288                             
04289 
04290                             BOOLEAN Found;
04291                             PLIST_ENTRY Entry;
04292                             PLDR_DATA_TABLE_ENTRY DataTableEntry2;
04293 
04294                             Entry = 
PsLoadedModuleList.Flink;
04295 
04296                             Found = 
FALSE;
04297                             
while (Entry != &
PsLoadedModuleList) {
04298 
04299                                 DataTableEntry2 = CONTAINING_RECORD(
04300                                                        Entry,
04301                                                        LDR_DATA_TABLE_ENTRY,
04302                                                        InLoadOrderLinks);
04303 
04304                                 
if (BaseAddress == DataTableEntry2->DllBase) {
04305 
04306                                     Found = 
TRUE;
04307                                     
break;
04308                                 }
04309 
04310                                 Entry = Entry->Flink;
04311                             }
04312 
04313                             
ASSERT (Found == 
TRUE);
04314                             
MmUnloadSystemImage ((PVOID)DataTableEntry2);
04315                         }
04316                     }
04317 
04318                 }
04319             }
04320 
04321             
if (!
NT_SUCCESS(st)) {
04322 
04323                 
RtlFreeUnicodeString( &ImportName_U );
04324                 
if (PrefixedNameAllocated) {
04325                     
ExFreePool( ImportDescriptorName_U.Buffer );
04326                 }
04327                 
MiDereferenceImports (ImportList);
04328                 
if (ImportList) {
04329                     
ExFreePool (ImportList);
04330                 }
04331                 
return st;
04332             }
04333 
04334             
goto ReCheck;
04335         }
04336 
04337         
if (ReferenceImport == 
TRUE && ImportList) {
04338             ImportList->
Entry[
Count] = DataTableEntry;
04339             
Count += 1;
04340         }
04341 
04342         
RtlFreeUnicodeString( &ImportName_U );
04343         
if (PrefixedNameAllocated) {
04344             
ExFreePool ( ImportDescriptorName_U.Buffer );
04345         }
04346 
04347         *MissingDriverName = DataTableEntry->BaseDllName.Buffer;
04348 
04349         ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(
04350                                     ImportBase,
04351                                     
TRUE,
04352                                     IMAGE_DIRECTORY_ENTRY_EXPORT,
04353                                     &ExportSize
04354                                     );
04355 
04356         
if (!ExportDirectory) {
04357             
MiDereferenceImports (ImportList);
04358             
if (ImportList) {
04359                 
ExFreePool (ImportList);
04360             }
04361             
return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
04362         }
04363 
04364         
04365         
04366         
04367 
04368         
if (ImportDescriptor->OriginalFirstThunk) {
04369 
04370             NameThunk = (PIMAGE_THUNK_DATA)((PCHAR)ImageBase + (ULONG)ImportDescriptor->OriginalFirstThunk);
04371             AddrThunk = (PIMAGE_THUNK_DATA)((PCHAR)ImageBase + (ULONG)ImportDescriptor->FirstThunk);
04372 
04373             
while (NameThunk->u1.AddressOfData) {
04374                 st = 
MiSnapThunk(ImportBase,
04375                        ImageBase,
04376                        NameThunk++,
04377                        AddrThunk++,
04378                        ExportDirectory,
04379                        ExportSize,
04380                        
FALSE,
04381                        MissingProcedureName
04382                        );
04383                 
if (!
NT_SUCCESS(st) ) {
04384                     
MiDereferenceImports (ImportList);
04385                     
if (ImportList) {
04386                         
ExFreePool (ImportList);
04387                     }
04388                     
return st;
04389                 }
04390                 *MissingProcedureName = MissingProcedureStorageArea;
04391             }
04392         }
04393 
04394         ImportDescriptor += 1;
04395     }
04396 
04397     
04398     
04399     
04400     
04401 
04402     
if (ImportList) {
04403 
04404         
04405         
04406         
04407         
04408         
04409 
04410         
Count = 0;
04411         
for (i = 0; i < ImportList->
Count; i += 1) {
04412             
if (ImportList->
Entry[i]) {
04413                 
Count += 1;
04414             }
04415         }
04416 
04417         
if (
Count == 0) {
04418 
04419             
ExFreePool(ImportList);
04420             ImportList = 
NO_IMPORTS_USED;
04421         }
04422         
else if (
Count == 1) {
04423             
for (i = 0; i < ImportList->
Count; i += 1) {
04424                 
if (ImportList->
Entry[i]) {
04425                     SingleEntry = 
POINTER_TO_SINGLE_ENTRY(ImportList->
Entry[i]);
04426                     
break;
04427                 }
04428             }
04429 
04430             
ExFreePool(ImportList);
04431             ImportList = (
PLOAD_IMPORTS)SingleEntry;
04432         }
04433         
else if (
Count != ImportList->
Count) {
04434 
04435             ImportListSize = 
Count * 
sizeof(PVOID) + 
sizeof(SIZE_T);
04436 
04437             CompactedImportList = (
PLOAD_IMPORTS)
04438                                         
ExAllocatePoolWithTag (
PagedPool,
04439                                         ImportListSize,
04440                                         'TDmM');
04441             
if (CompactedImportList) {
04442                 CompactedImportList->
Count = 
Count;
04443 
04444                 
Count = 0;
04445                 
for (i = 0; i < ImportList->
Count; i += 1) {
04446                     
if (ImportList->
Entry[i]) {
04447                         CompactedImportList->
Entry[
Count] = ImportList->
Entry[i];
04448                         
Count += 1;
04449                     }
04450                 }
04451 
04452                 
ExFreePool(ImportList);
04453                 ImportList = CompactedImportList;
04454             }
04455         }
04456 
04457         *LoadedImports = ImportList;
04458     }
04459     
return STATUS_SUCCESS;
04460 }
04461 
04462 
04463 
NTSTATUS
04464 MiSnapThunk(
04465     IN PVOID DllBase,
04466     IN PVOID ImageBase,
04467     IN PIMAGE_THUNK_DATA NameThunk,
04468     OUT PIMAGE_THUNK_DATA AddrThunk,
04469     IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
04470     IN ULONG ExportSize,
04471     IN BOOLEAN SnapForwarder,
04472     OUT PCHAR *MissingProcedureName
04473     )
04474 
04475 
04476 
04477 
04478 
04479 
04480 
04481 
04482 
04483 
04484 
04485 
04486 
04487 
04488 
04489 
04490 
04491 
04492 
04493 
04494 
04495 
04496 
04497 
04498 
04499 
04500 
04501 
04502 
04503 
04504 
04505 
04506 
04507 {
04508     BOOLEAN Ordinal;
04509     
USHORT OrdinalNumber;
04510     PULONG NameTableBase;
04511     
PUSHORT NameOrdinalTableBase;
04512     PULONG Addr;
04513     
USHORT HintIndex;
04514     ULONG High;
04515     ULONG Low;
04516     ULONG Middle;
04517     LONG Result;
04518     
NTSTATUS Status;
04519     PCHAR MissingProcedureName2;
04520     
CHAR NameBuffer[ MAXIMUM_FILENAME_LENGTH ];
04521 
04522     
PAGED_CODE();
04523 
04524     
04525     
04526     
04527 
04528     Ordinal = (BOOLEAN)IMAGE_SNAP_BY_ORDINAL(NameThunk->u1.Ordinal);
04529 
04530     
if (Ordinal && !SnapForwarder) {
04531 
04532         OrdinalNumber = (
USHORT)(IMAGE_ORDINAL(NameThunk->u1.Ordinal) -
04533                          ExportDirectory->Base);
04534 
04535         *MissingProcedureName = (PCHAR)(ULONG_PTR)OrdinalNumber;
04536 
04537     } 
else {
04538 
04539         
04540         
04541         
04542 
04543         
if (!SnapForwarder) {
04544             NameThunk->u1.AddressOfData = (ULONG_PTR)ImageBase + NameThunk->u1.AddressOfData;
04545         }
04546 
04547         strncpy( *MissingProcedureName,
04548                  &((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Name[0],
04549                  MAXIMUM_FILENAME_LENGTH - 1
04550                );
04551 
04552         
04553         
04554         
04555 
04556         NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
04557         NameOrdinalTableBase = (
PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
04558 
04559         
04560         
04561         
04562         
04563         
04564         
04565 
04566         HintIndex = ((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Hint;
04567         
if ((ULONG)HintIndex < ExportDirectory->NumberOfNames &&
04568             !strcmp((PSZ)((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Name,
04569              (PSZ)((PCHAR)DllBase + NameTableBase[HintIndex]))) {
04570             OrdinalNumber = NameOrdinalTableBase[HintIndex];
04571 
04572         } 
else {
04573 
04574             
04575             
04576             
04577 
04578             Low = 0;
04579             High = ExportDirectory->NumberOfNames - 1;
04580 
04581             
while (High >= Low) {
04582 
04583                 
04584                 
04585                 
04586                 
04587 
04588                 Middle = (Low + High) >> 1;
04589                 Result = strcmp(&((PIMAGE_IMPORT_BY_NAME)NameThunk->u1.AddressOfData)->Name[0],
04590                                 (PCHAR)((PCHAR)DllBase + NameTableBase[Middle]));
04591 
04592                 
if (Result < 0) {
04593                     High = Middle - 1;
04594 
04595                 } 
else if (Result > 0) {
04596                     Low = Middle + 1;
04597 
04598                 } 
else {
04599                     
break;
04600                 }
04601             }
04602 
04603             
04604             
04605             
04606             
04607             
04608 
04609             
if (High < Low) {
04610                 
return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
04611             } 
else {
04612                 OrdinalNumber = NameOrdinalTableBase[Middle];
04613             }
04614         }
04615     }
04616 
04617     
04618     
04619     
04620     
04621 
04622     
if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
04623         
Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;
04624 
04625     } 
else {
04626 
04627         MissingProcedureName2 = NameBuffer;
04628 
04629         Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
04630         (PULONG)(AddrThunk->u1.Function) = (PULONG)((PCHAR)DllBase + Addr[OrdinalNumber]);
04631 
04632         
04633 
04634         
Status = STATUS_SUCCESS;
04635 
04636         
if ( ((ULONG_PTR)AddrThunk->u1.Function > (ULONG_PTR)ExportDirectory) &&
04637              ((ULONG_PTR)AddrThunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)) ) {
04638 
04639             UNICODE_STRING UnicodeString;
04640             ANSI_STRING ForwardDllName;
04641 
04642             PLIST_ENTRY NextEntry;
04643             PLDR_DATA_TABLE_ENTRY DataTableEntry;
04644             ULONG ExportSize;
04645             PIMAGE_EXPORT_DIRECTORY ExportDirectory;
04646 
04647             
Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
04648 
04649             
04650             
04651             
04652 
04653             ForwardDllName.Buffer = (PCHAR)AddrThunk->u1.Function;
04654             ForwardDllName.Length = (
USHORT)(strchr(ForwardDllName.Buffer, 
'.') -
04655                                            ForwardDllName.Buffer + 1);
04656             ForwardDllName.MaximumLength = ForwardDllName.Length;
04657 
04658             
if (
NT_SUCCESS(
RtlAnsiStringToUnicodeString(&UnicodeString,
04659                                                         &ForwardDllName,
04660                                                         
TRUE))) {
04661 
04662                 NextEntry = 
PsLoadedModuleList.Flink;
04663 
04664                 
while (NextEntry != &
PsLoadedModuleList) {
04665 
04666                     DataTableEntry = CONTAINING_RECORD(NextEntry,
04667                                                        LDR_DATA_TABLE_ENTRY,
04668                                                        InLoadOrderLinks);
04669 
04670                     
04671                     
04672                     
04673                     
04674                     
04675                     
04676                     
04677                     
04678 
04679                     
if (
RtlPrefixString((PSTRING)&UnicodeString,
04680                                         (PSTRING)&DataTableEntry->BaseDllName,
04681                                         
TRUE)) {
04682 
04683                         ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
04684                             
RtlImageDirectoryEntryToData(DataTableEntry->DllBase,
04685                                                          
TRUE,
04686                                                          IMAGE_DIRECTORY_ENTRY_EXPORT,
04687                                                          &ExportSize);
04688 
04689                         
if (ExportDirectory) {
04690 
04691                             IMAGE_THUNK_DATA thunkData;
04692                             PIMAGE_IMPORT_BY_NAME addressOfData;
04693                             ULONG length;
04694 
04695                             
04696 
04697                             length = 
strlen(ForwardDllName.Buffer +
04698                                                 ForwardDllName.Length) + 1;
04699 
04700                             addressOfData = (PIMAGE_IMPORT_BY_NAME)
04701                                 
ExAllocatePoolWithTag (
PagedPool,
04702                                                       length +
04703                                                    
sizeof(IMAGE_IMPORT_BY_NAME),
04704                                                    '  mM');
04705 
04706                             
if (addressOfData) {
04707 
04708                                 RtlCopyMemory(&(addressOfData->Name[0]),
04709                                               ForwardDllName.Buffer +
04710                                                   ForwardDllName.Length,
04711                                               length);
04712 
04713                                 addressOfData->Hint = 0;
04714 
04715                                 (PIMAGE_IMPORT_BY_NAME)(thunkData.u1.AddressOfData) = addressOfData;
04716 
04717                                 
Status = 
MiSnapThunk(DataTableEntry->DllBase,
04718                                                      ImageBase,
04719                                                      &thunkData,
04720                                                      &thunkData,
04721                                                      ExportDirectory,
04722                                                      ExportSize,
04723                                                      
TRUE,
04724                                                      &MissingProcedureName2
04725                                                     );
04726 
04727                                 
ExFreePool(addressOfData);
04728 
04729                                 AddrThunk->u1 = thunkData.u1;
04730                             }
04731                         }
04732 
04733                         
break;
04734                     }
04735 
04736                     NextEntry = NextEntry->Flink;
04737                 }
04738 
04739                 
RtlFreeUnicodeString(&UnicodeString);
04740             }
04741 
04742         }
04743 
04744     }
04745     
return Status;
04746 }
04747 
#if 0
04748 
PVOID
04749 
MiLookupImageSectionByName (
04750     IN PVOID Base,
04751     IN BOOLEAN MappedAsImage,
04752     IN PCHAR SectionName,
04753     OUT PULONG SectionSize
04754     )
04755 
04756 
04757 
04758 
04759 
04760 
04761 
04762 
04763 
04764 
04765 
04766 
04767 
04768 
04769 
04770 
04771 
04772 
04773 
04774 
04775 
04776 
04777 
04778 
04779 
04780 
04781 
04782 
04783 {
04784     ULONG i, j, Match;
04785     PIMAGE_NT_HEADERS NtHeaders;
04786     PIMAGE_SECTION_HEADER NtSection;
04787 
04788     NtHeaders = 
RtlImageNtHeader(Base);
04789     NtSection = IMAGE_FIRST_SECTION( NtHeaders );
04790     
for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++) {
04791         Match = 
TRUE;
04792         
for (j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
04793             
if (SectionName[j] != NtSection->Name[j]) {
04794                 Match = 
FALSE;
04795                 
break;
04796             }
04797             
if (SectionName[j] == 
'\0') {
04798                 
break;
04799             }
04800         }
04801         
if (Match) {
04802             
break;
04803         }
04804         NtSection += 1;
04805     }
04806     
if (Match) {
04807         *SectionSize = NtSection->SizeOfRawData;
04808         
if (MappedAsImage) {
04809             
return( ((PCHAR)Base + NtSection->VirtualAddress));
04810         } 
else {
04811             
return( ((PCHAR)Base + NtSection->PointerToRawData));
04812         }
04813     }
04814     
return( 
NULL );
04815 }
04816 
#endif //0
04817 
04818 
04819 
NTSTATUS
04820 MmCheckSystemImage(
04821     IN HANDLE ImageFileHandle
04822     )
04823 
04824 
04825 
04826 
04827 
04828 
04829 
04830 
04831 
04832 
04833 
04834 
04835 
04836 
04837 
04838 
04839 
04840 
04841 {
04842 
04843     
NTSTATUS Status;
04844     HANDLE Section;
04845     PVOID ViewBase;
04846     SIZE_T ViewSize;
04847     IO_STATUS_BLOCK IoStatusBlock;
04848     FILE_STANDARD_INFORMATION StandardInfo;
04849 
04850     
PAGED_CODE();
04851 
04852     
Status = ZwCreateSection(
04853                 &Section,
04854                 SECTION_MAP_EXECUTE,
04855                 
NULL,
04856                 
NULL,
04857                 PAGE_EXECUTE,
04858                 SEC_COMMIT,
04859                 ImageFileHandle
04860                 );
04861 
04862     
if ( !
NT_SUCCESS(
Status) ) {
04863         
return Status;
04864     }
04865 
04866     ViewBase = 
NULL;
04867     ViewSize = 0;
04868 
04869     
Status = ZwMapViewOfSection(
04870                 Section,
04871                 NtCurrentProcess(),
04872                 (PVOID *)&ViewBase,
04873                 0
L,
04874                 0
L,
04875                 
NULL,
04876                 &ViewSize,
04877                 ViewShare,
04878                 0
L,
04879                 PAGE_EXECUTE
04880                 );
04881 
04882     
if ( !
NT_SUCCESS(
Status) ) {
04883         ZwClose(Section);
04884         
return Status;
04885     }
04886 
04887     
04888     
04889     
04890     
04891 
04892     
Status = ZwQueryInformationFile(
04893                 ImageFileHandle,
04894                 &IoStatusBlock,
04895                 &StandardInfo,
04896                 
sizeof(StandardInfo),
04897                 FileStandardInformation
04898                 );
04899 
04900     
if ( 
NT_SUCCESS(
Status) ) {
04901 
04902         
try {
04903             
if (!
LdrVerifyMappedImageMatchesChecksum(ViewBase,StandardInfo.EndOfFile.LowPart)) {
04904                 
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
04905             }
04906 
#if !defined(NT_UP)
04907 
            if ( !
MmVerifyImageIsOkForMpUse(ViewBase) ) {
04908                 
Status = STATUS_IMAGE_MP_UP_MISMATCH;
04909                 }
04910 
#endif // NT_UP
04911 
        } except (
EXCEPTION_EXECUTE_HANDLER) {
04912             
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
04913         }
04914     }
04915 
04916     ZwUnmapViewOfSection(NtCurrentProcess(),ViewBase);
04917     ZwClose(Section);
04918     
return Status;
04919 }
04920 
04921 
#if !defined(NT_UP)
04922 
BOOLEAN
04923 MmVerifyImageIsOkForMpUse(
04924     IN PVOID BaseAddress
04925     )
04926 {
04927     PIMAGE_NT_HEADERS NtHeaders;
04928 
04929     
PAGED_CODE();
04930 
04931     
04932     
04933     
04934     
04935     
04936 
04937     NtHeaders = 
RtlImageNtHeader(BaseAddress);
04938     
if (NtHeaders != 
NULL) {
04939         
if ( 
KeNumberProcessors > 1 &&
04940              (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) ) {
04941             
return FALSE;
04942         }
04943     }
04944     
return TRUE;
04945 }
04946 
#endif // NT_UP
04947 
04948 
04949 PFN_NUMBER
04950 MiDeleteSystemPagableVm (
04951     IN 
PMMPTE PointerPte,
04952     IN PFN_NUMBER NumberOfPtes,
04953     IN 
MMPTE NewPteValue,
04954     IN LOGICAL SessionAllocation,
04955     OUT PPFN_NUMBER ResidentPages
04956     )
04957 
04958 
04959 
04960 
04961 
04962 
04963 
04964 
04965 
04966 
04967 
04968 
04969 
04970 
04971 
04972 
04973 
04974 
04975 
04976 
04977 
04978 
04979 
04980 
04981 
04982 
04983 
04984 
04985 
04986 
04987 
04988 
04989 {
04990     PFN_NUMBER PageFrameIndex;
04991     
MMPTE PteContents;
04992     
PMMPFN Pfn1;
04993     PFN_NUMBER ValidPages;
04994     PFN_NUMBER PagesRequired;
04995     
MMPTE NewContents;
04996     
WSLE_NUMBER WsIndex;
04997     KIRQL OldIrql;
04998     
MMPTE_FLUSH_LIST PteFlushList;
04999     
MMPTE JunkPte;
05000     
MMWSLENTRY Locked;
05001 
05002     
ASSERT (KeGetCurrentIrql() <= 
APC_LEVEL);
05003 
05004     ValidPages = 0;
05005     PagesRequired = 0;
05006     PteFlushList.
Count = 0;
05007     NewContents = NewPteValue;
05008     
while (NumberOfPtes != 0) {
05009         PteContents = *PointerPte;
05010 
05011         
if (PteContents.
u.Long != 
ZeroKernelPte.
u.Long) {
05012 
05013             
if (PteContents.
u.Hard.Valid == 1) {
05014 
05015                 
if (SessionAllocation == 
TRUE) {
05016                     
LOCK_SESSION_SPACE_WS (OldIrql);
05017                 }
05018                 
else {
05019                     
LOCK_SYSTEM_WS (OldIrql);
05020                 }
05021 
05022                 PteContents = *(
volatile MMPTE *)PointerPte;
05023                 
if (PteContents.
u.Hard.Valid == 0) {
05024                     
if (SessionAllocation == 
TRUE) {
05025                         
UNLOCK_SESSION_SPACE_WS (OldIrql);
05026                     }
05027                     
else {
05028                         
UNLOCK_SYSTEM_WS (OldIrql);
05029                     }
05030 
05031                     
continue;
05032                 }
05033 
05034                 
05035                 
05036                 
05037 
05038                 PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (&PteContents);
05039 
05040                 Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
05041 
05042                 
05043                 
05044                 
05045                 
05046 
05047                 WsIndex = Pfn1->
u1.WsIndex;
05048                 
if (WsIndex == 0) {
05049                     ValidPages += 1;
05050                 } 
else {
05051                     
if (SessionAllocation == 
FALSE) {
05052                         
MiRemoveWsle (WsIndex,
05053                                       
MmSystemCacheWorkingSetList );
05054                         
MiReleaseWsle (WsIndex, &
MmSystemCacheWs);
05055                     }
05056                     
else {
05057                         WsIndex = 
MiLocateWsle(
05058                                               
MiGetVirtualAddressMappedByPte(PointerPte),
05059                                               
MmSessionSpace->
Vm.
VmWorkingSetList,
05060                                               WsIndex
05061                                               );
05062 
05063                         
ASSERT (WsIndex != 
WSLE_NULL_INDEX);
05064 
05065                         
05066                         
05067                         
05068                         
05069 
05070                         Locked = 
MmSessionSpace->
Wsle[WsIndex].
u1.e1;
05071 
05072                         
MiRemoveWsle (WsIndex, 
MmSessionSpace->
Vm.
VmWorkingSetList);
05073 
05074                         
MiReleaseWsle (WsIndex, &
MmSessionSpace->
Vm);
05075 
05076                         
if (Locked.
LockedInWs == 1 || Locked.
LockedInMemory == 1) {
05077 
05078                             
05079                             
05080                             
05081 
#if DBG
05082 
                            DbgPrint(
"MiDeleteSystemPagableVm: Session PointerPte 0x%p, Pfn 0x%p Locked in memory\n",
05083                                 PointerPte,
05084                                 Pfn1);
05085 
05086                             DbgBreakPoint();
05087 
#endif
05088 
                            ASSERT (WsIndex < MmSessionSpace->Vm.VmWorkingSetList->FirstDynamic);
05089                             
MmSessionSpace->
Vm.
VmWorkingSetList->
FirstDynamic -= 1;
05090 
05091                             
if (WsIndex != 
MmSessionSpace->
Vm.
VmWorkingSetList->
FirstDynamic) {
05092                                 ULONG Entry;
05093                                 PVOID SwapVa;
05094 
05095                                 Entry = 
MmSessionSpace->
Vm.
VmWorkingSetList->
FirstDynamic;
05096                                 
ASSERT (
MmSessionSpace->
Wsle[Entry].
u1.e1.Valid);
05097                                 SwapVa = 
MmSessionSpace->
Wsle[Entry].
u1.VirtualAddress;
05098                                 SwapVa = 
PAGE_ALIGN (SwapVa);
05099 
05100                                 
MiSwapWslEntries (Entry,
05101                                                   WsIndex,
05102                                                   &
MmSessionSpace->
Vm);
05103                             }
05104                         }
05105                         
else {
05106                             
ASSERT (WsIndex >= 
MmSessionSpace->
Vm.
VmWorkingSetList->
FirstDynamic);
05107                         }
05108                     }
05109                 }
05110 
05111                 
if (SessionAllocation == 
TRUE) {
05112                     
UNLOCK_SESSION_SPACE_WS (OldIrql);
05113                 }
05114                 
else {
05115                     
UNLOCK_SYSTEM_WS (OldIrql);
05116                 }
05117 
05118                 
LOCK_PFN (OldIrql);
05119 
#if DBG
05120 
                if ((Pfn1->
u3.e2.ReferenceCount > 1) &&
05121                     (Pfn1->
u3.e1.WriteInProgress == 0)) {
05122                     
DbgPrint (
"MM:SYSLOAD - deleting pool locked for I/O pte %p, pfn %p, share=%x, refcount=%x, wsindex=%x\n",
05123                              PointerPte,
05124                              PageFrameIndex,
05125                              Pfn1->
u2.ShareCount,
05126                              Pfn1->
u3.e2.ReferenceCount,
05127                              Pfn1->
u1.WsIndex);
05128                     
05129                     
05130                     
05131                     
05132                     
05133                     
05134                     
05135                     
05136                     
05137                     
05138                     
05139                     
05140                     
05141                     
05142                     
05143                     
05144                     
05145                     
05146                     
05147                     
05148                     
05149                     
05150                     
05151                     
05152                     
05153                 }
05154 
#endif //DBG
05155 
                
05156                 
05157                 
05158                 
if (Pfn1->
u3.e1.PrototypePte == 1) {
05159 
05160                     
PMMPTE PointerPde;
05161 
05162                     
ASSERT (SessionAllocation == 
TRUE);
05163 
05164                     
05165                     
05166                     
05167                     
05168 
05169                     
MI_CAPTURE_DIRTY_BIT_TO_PFN (PointerPte, Pfn1);
05170 
05171                     
05172                     
05173                     
05174                     
05175 
05176                     PointerPde = 
MiGetPteAddress (PointerPte);
05177                     
if (PointerPde->
u.Hard.Valid == 0) {
05178 
#if !defined (_WIN64)
05179 
                        if (!
NT_SUCCESS(
MiCheckPdeForPagedPool (PointerPte))) {
05180 
#endif
05181 
                            KeBugCheckEx (MEMORY_MANAGEMENT,
05182                                           0x61940, 
05183                                           (ULONG_PTR)PointerPte,
05184                                           (ULONG_PTR)PointerPde->
u.Long,
05185                                           (ULONG_PTR)
MiGetVirtualAddressMappedByPte(PointerPte));
05186 
#if !defined (_WIN64)
05187 
                        }
05188 
#endif
05189 
                    }
05190 
05191                     
MiDecrementShareAndValidCount (
MI_GET_PAGE_FRAME_FROM_PTE (PointerPde));
05192 
05193                     
05194                     
05195                     
05196 
05197                     
MiDecrementShareCount (PageFrameIndex);
05198 
05199                     
05200                     
05201                     
05202                     
05203 
05204                     
ASSERT (PointerPte > 
MiHighestUserPte);
05205 
05206                 } 
else {
05207                     
MiDecrementShareAndValidCount (Pfn1->
PteFrame);
05208                     
MI_SET_PFN_DELETED (Pfn1);
05209                     
MiDecrementShareCountOnly (PageFrameIndex);
05210                 }
05211 
05212                 
MI_WRITE_INVALID_PTE (PointerPte, NewContents);
05213                 
UNLOCK_PFN (OldIrql);
05214 
05215                 
05216                 
05217                 
05218 
05219                 
if (PteFlushList.
Count != 
MM_MAXIMUM_FLUSH_COUNT) {
05220 
05221                     
05222                     
05223                     
05224                     
05225                     
05226                     
05227 
05228                     PteFlushList.
FlushPte[PteFlushList.
Count] =
05229                         (
PMMPTE)&JunkPte;
05230 
05231                     PteFlushList.
FlushVa[PteFlushList.
Count] =
05232                                     
MiGetVirtualAddressMappedByPte (PointerPte);
05233                     PteFlushList.
Count += 1;
05234                 }
05235 
05236             } 
else if (PteContents.
u.Soft.Prototype) {
05237 
05238                 
ASSERT (SessionAllocation == 
TRUE);
05239 
05240                 
05241                 
05242                 
05243                 
05244 
05245                 
ASSERT (PointerPte >= 
MiHighestUserPte);
05246 
05247                 
MI_WRITE_INVALID_PTE (PointerPte, NewContents);
05248 
05249                 
05250                 
05251                 
05252                 
05253 
05254             } 
else if (PteContents.
u.Soft.Transition == 1) {
05255 
05256                 
LOCK_PFN (OldIrql);
05257 
05258                 PteContents = *(
volatile MMPTE *)PointerPte;
05259 
05260                 
if (PteContents.
u.Soft.Transition == 0) {
05261                     
UNLOCK_PFN (OldIrql);
05262                     
continue;
05263                 }
05264 
05265                 
05266                 
05267                 
05268 
05269                 PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE (&PteContents);
05270 
05271                 
05272                 
05273                 
05274                 
05275 
05276                 Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
05277 
05278                 
MI_SET_PFN_DELETED (Pfn1);
05279 
05280                 
MiDecrementShareCount (Pfn1->
PteFrame);
05281 
05282                 
05283                 
05284                 
05285                 
05286                 
05287                 
05288                 
05289 
05290                 
if (Pfn1->
u3.e2.ReferenceCount == 0) {
05291                     
MiUnlinkPageFromList (Pfn1);
05292                     
MiReleasePageFileSpace (Pfn1->
OriginalPte);
05293                     
MiInsertPageInList (
MmPageLocationList[
FreePageList],
05294                                         PageFrameIndex);
05295                 }
05296 
#if DBG
05297 
                if ((Pfn1->
u3.e2.ReferenceCount > 1) &&
05298                     (Pfn1->
u3.e1.WriteInProgress == 0)) {
05299                     
DbgPrint (
"MM:SYSLOAD - deleting pool locked for I/O %p\n",
05300                              PageFrameIndex);
05301                     DbgBreakPoint();
05302                 }
05303 
#endif //DBG
05304 
05305                 
MI_WRITE_INVALID_PTE (PointerPte, NewContents);
05306                 
UNLOCK_PFN (OldIrql);
05307             } 
else {
05308 
05309                 
05310                 
05311                 
05312                 
if (PteContents.
u.Soft.PageFileHigh != 0) {
05313                     
LOCK_PFN (OldIrql);
05314                     
MiReleasePageFileSpace (PteContents);
05315                     
UNLOCK_PFN (OldIrql);
05316                 }
05317 
05318                 
MI_WRITE_INVALID_PTE (PointerPte, NewContents);
05319             }
05320 
05321             PagesRequired += 1;
05322         }
05323 
05324         NumberOfPtes -= 1;
05325         PointerPte += 1;
05326     }
05327 
05328     
05329     
05330     
05331     
05332     
05333     
05334     
05335     
05336     
05337     
05338     
05339     
05340     
05341     
05342     
05343     
05344     
05345     
05346     
05347     
05348     
05349     
05350     
05351     
05352     
05353     
05354 
05355     
if (SessionAllocation == 
TRUE) {
05356 
05357         
05358         
05359         
05360     
05361         
MI_FLUSH_ENTIRE_SESSION_TB (
TRUE, 
TRUE);
05362     }
05363 
05364     
LOCK_PFN (OldIrql);
05365     
MiFlushPteList (&PteFlushList, 
TRUE, NewContents);
05366     
UNLOCK_PFN (OldIrql);
05367 
05368     
if (ARGUMENT_PRESENT(ResidentPages)) {
05369         *ResidentPages = ValidPages;
05370     }
05371 
05372     
return PagesRequired;
05373 }
05374 
05375 
VOID
05376 MiSetImageProtect (
05377     IN 
PSEGMENT Segment,
05378     IN ULONG Protection
05379     )
05380 
05381 
05382 
05383 
05384 
05385 
05386 
05387 
05388 
05389 
05390 
05391 
05392 
05393 
05394 
05395 
05396 
05397 
05398 
05399 
05400 {
05401     
PMMPTE PointerPte;
05402     
PMMPTE LastPte;
05403     
MMPTE PteContents;
05404     
PSUBSECTION SubSection;
05405 
05406     
05407     
05408     
05409 
05410     
ASSERT (Segment->ControlArea->u.Flags.GlobalOnlyPerSession == 0);
05411 
05412     
if ((Protection & 
MM_PROTECTION_WRITE_MASK) == 0) {
05413         SubSection = (
PSUBSECTION)(Segment->ControlArea + 1);
05414         SubSection->
u.SubsectionFlags.Protection = Protection;
05415         SubSection->
u.SubsectionFlags.ReadOnly = 1;
05416     }
05417 
05418     PointerPte = Segment->PrototypePte;
05419     LastPte = PointerPte + Segment->NonExtendedPtes;
05420 
05421     
MmLockPagedPool (PointerPte, (LastPte - PointerPte) * 
sizeof (
MMPTE));
05422 
05423     
do {
05424         PteContents = *PointerPte;
05425         
ASSERT (PteContents.
u.Hard.Valid == 0);
05426         
if (PteContents.
u.Long != 
ZeroPte.
u.Long) {
05427             
if ((PteContents.
u.Soft.Prototype == 0) &&
05428                 (PteContents.
u.Soft.Transition == 1)) {
05429                 
if (
MiSetProtectionOnTransitionPte (PointerPte, Protection)) {
05430                     
continue;
05431                 }
05432             }
05433             
else {
05434                 PointerPte->u.Soft.Protection = Protection;
05435             }
05436         }
05437         PointerPte += 1;
05438     } 
while (PointerPte < LastPte);
05439 
05440     PointerPte = Segment->PrototypePte;
05441     
MmUnlockPagedPool (PointerPte, (LastPte - PointerPte) * 
sizeof (
MMPTE));
05442 
05443     
return;
05444 }
05445 
05446 
05447 
VOID
05448 MiSetSystemCodeProtection (
05449     IN 
PMMPTE FirstPte,
05450     IN 
PMMPTE LastPte
05451     )
05452 
05453 
05454 
05455 
05456 
05457 
05458 
05459 
05460 
05461 
05462 
05463 
05464 
05465 
05466 
05467 
05468 
05469 
05470 
05471 
05472 {
05473     KIRQL OldIrql;
05474     
MMPTE PteContents;
05475     
MMPTE TempPte;
05476     
MMPTE PreviousPte;
05477     
PMMPTE PointerPte;
05478     
PMMPTE PointerPde;
05479     
PMMPTE PointerProtoPte;
05480     ULONG ProtectionMask;
05481     
PMMPFN Pfn1;
05482     
PMMPFN ProtoPfn;
05483     LOGICAL SessionAddress;
05484 
05485 
#if defined(_X86_)
05486 
    ASSERT (
MI_IS_PHYSICAL_ADDRESS(
MiGetVirtualAddressMappedByPte(FirstPte)) == 0);
05487 
#endif
05488 
05489     SessionAddress = 
FALSE;
05490 
05491     
if (
MI_IS_SESSION_ADDRESS(
MiGetVirtualAddressMappedByPte(FirstPte))) {
05492         SessionAddress = 
TRUE;
05493     }
05494     
05495     ProtectionMask = 
MM_EXECUTE_READ;
05496 
05497     
05498     
05499     
05500     
05501     
05502     
05503     
05504 
05505     PointerPte = FirstPte;
05506 
05507     
LOCK_PFN (OldIrql);
05508 
05509     
while (PointerPte <= LastPte) {
05510 
05511         PteContents = *PointerPte;
05512 
05513         
if ((PteContents.
u.Long == 0) || (!*
MiPteStr)) {
05514             PointerPte += 1;
05515             
continue;
05516         }
05517 
05518         
if (PteContents.
u.Hard.Valid == 1) {
05519 
05520             Pfn1 = 
MI_PFN_ELEMENT (PteContents.
u.Hard.PageFrameNumber);
05521             Pfn1->
OriginalPte.
u.Soft.Protection = ProtectionMask;
05522 
05523             
05524             
05525             
05526             
05527 
05528             
if (
MI_IS_PTE_DIRTY(PteContents)) {
05529                 
MI_CAPTURE_DIRTY_BIT_TO_PFN (&PteContents, Pfn1);
05530             }
05531 
05532             
MI_MAKE_VALID_PTE (TempPte,
05533                                PteContents.
u.Hard.PageFrameNumber,
05534                                Pfn1->
OriginalPte.
u.Soft.Protection,
05535                                PointerPte);
05536 
05537             
if (SessionAddress == 
TRUE) {
05538         
05539                 
05540                 
05541                 
05542             
05543                 
MI_FLUSH_SINGLE_SESSION_TB (
MiGetVirtualAddressMappedByPte (PointerPte),
05544                              
TRUE,
05545                              
TRUE,
05546                              (PHARDWARE_PTE)PointerPte,
05547                              TempPte.
u.Flush,
05548                              PreviousPte);
05549             }
05550             
else {
05551                 
KeFlushSingleTb (
MiGetVirtualAddressMappedByPte (PointerPte),
05552                                  
TRUE,
05553                                  
TRUE,
05554                                  (PHARDWARE_PTE)PointerPte,
05555                                  TempPte.
u.Flush);
05556             }
05557         }
05558         
else if (PteContents.
u.Soft.Prototype == 1) {
05559 
05560             
if (SessionAddress == 
TRUE) {
05561                 PointerPte->u.Proto.ReadOnly = 1;
05562             }
05563             
else {
05564                 PointerProtoPte = 
MiPteToProto(PointerPte);
05565     
05566                 
if (!
MI_IS_PHYSICAL_ADDRESS(PointerProtoPte)) {
05567                     PointerPde = 
MiGetPteAddress (PointerProtoPte);
05568                     
if (PointerPde->
u.Hard.Valid == 0) {
05569                         
MiMakeSystemAddressValidPfn (PointerProtoPte);
05570     
05571                         
05572                         
05573                         
05574         
05575                         PteContents = *PointerPte;
05576                         
if ((PteContents.
u.Hard.Valid == 1) ||
05577                             (PteContents.
u.Soft.Prototype == 0)) {
05578                                 
continue;
05579                         }
05580                     }
05581     
05582                     ProtoPfn = 
MI_PFN_ELEMENT (PointerPde->
u.Hard.PageFrameNumber);
05583                     
MI_ADD_LOCKED_PAGE_CHARGE(ProtoPfn, 12);
05584                     ProtoPfn->
u3.e2.ReferenceCount += 1;
05585                     
ASSERT (ProtoPfn->
u3.e2.ReferenceCount > 1);
05586                 }
05587     
05588                 PteContents = *PointerProtoPte;
05589     
05590                 
if (PteContents.
u.Long != 
ZeroPte.
u.Long) {
05591     
05592                     
ASSERT (PteContents.
u.Hard.Valid == 0);
05593     
05594                     PointerProtoPte->u.Soft.Protection = ProtectionMask;
05595     
05596                     
if ((PteContents.
u.Soft.Prototype == 0) &&
05597                         (PteContents.
u.Soft.Transition == 1)) {
05598                         Pfn1 = 
MI_PFN_ELEMENT (PteContents.
u.Trans.PageFrameNumber);
05599                         Pfn1->
OriginalPte.
u.Soft.Protection = ProtectionMask;
05600                     }
05601                 }
05602 
05603                 
if (!
MI_IS_PHYSICAL_ADDRESS(PointerProtoPte)) {
05604                     
ASSERT (ProtoPfn->
u3.e2.ReferenceCount > 1);
05605                     
MI_REMOVE_LOCKED_PAGE_CHARGE(ProtoPfn, 13);
05606                     ProtoPfn->
u3.e2.ReferenceCount -= 1;
05607                 }
05608             }
05609         }
05610         
else if (PteContents.
u.Soft.Transition == 1) {
05611 
05612             Pfn1 = 
MI_PFN_ELEMENT (PteContents.
u.Trans.PageFrameNumber);
05613             Pfn1->
OriginalPte.
u.Soft.Protection = ProtectionMask;
05614             PointerPte->u.Soft.Protection = ProtectionMask;
05615 
05616         }
05617         
else {
05618 
05619             
05620             
05621             
05622 
05623             PointerPte->u.Soft.Protection = ProtectionMask;
05624         }
05625         PointerPte += 1;
05626     }
05627 
05628     
UNLOCK_PFN (OldIrql);
05629 }
05630 
05631 
05632 
VOID
05633 MiWriteProtectSystemImage (
05634     IN PVOID DllBase
05635     )
05636 
05637 
05638 
05639 
05640 
05641 
05642 
05643 
05644 
05645 
05646 
05647 
05648 
05649 
05650 
05651 
05652 
05653 {
05654     ULONG SectionProtection;
05655     ULONG NumberOfSubsections;
05656     ULONG SectionVirtualSize;
05657     ULONG ImageAlignment;
05658     ULONG OffsetToSectionTable;
05659     ULONG NumberOfPtes;
05660     ULONG_PTR VirtualAddress;
05661     ULONG_PTR LastVirtualAddress;
05662     
PMMPTE PointerPte;
05663     
PMMPTE FirstPte;
05664     
PMMPTE LastPte;
05665     
PMMPTE LastImagePte;
05666     
PMMPTE WritablePte;
05667     PIMAGE_NT_HEADERS NtHeader;
05668     PIMAGE_FILE_HEADER FileHeader;
05669     PIMAGE_SECTION_HEADER SectionTableEntry;
05670 
05671     
PAGED_CODE();
05672 
05673     
if (
MI_IS_PHYSICAL_ADDRESS(DllBase)) {
05674         
return;
05675     }
05676 
05677     NtHeader = 
RtlImageNtHeader (DllBase);
05678 
05679     
ASSERT (NtHeader);
05680 
05681     ImageAlignment = NtHeader->OptionalHeader.SectionAlignment;
05682 
05683     
05684     
05685     
05686     
05687 
05688     
if (
MI_IS_SESSION_ADDRESS(DllBase) == 0) {
05689 
05690         
05691         
05692         
05693         
05694         
05695 
05696         
05697         
05698         
05699         
05700 
05701         
if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion < 5) ||
05702             (NtHeader->OptionalHeader.MajorOperatingSystemVersion > 10)) {
05703             
return;
05704         }
05705     
05706         
if ((NtHeader->OptionalHeader.MajorImageVersion < 5) ||
05707             (NtHeader->OptionalHeader.MajorImageVersion > 10)) {
05708             
return;
05709         }
05710     }
05711 
05712     NumberOfPtes = 
BYTES_TO_PAGES (NtHeader->OptionalHeader.SizeOfImage);
05713 
05714     FileHeader = &NtHeader->FileHeader;
05715 
05716     NumberOfSubsections = FileHeader->NumberOfSections;
05717 
05718     
ASSERT (NumberOfSubsections != 0);
05719 
05720     OffsetToSectionTable = 
sizeof(ULONG) +
05721                               
sizeof(IMAGE_FILE_HEADER) +
05722                               FileHeader->SizeOfOptionalHeader;
05723 
05724     SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
05725                             OffsetToSectionTable);
05726 
05727     
05728     
05729     
05730     
05731 
05732     FirstPte = 
NULL;
05733     LastVirtualAddress = (ULONG_PTR)DllBase;
05734 
05735     
for ( ; NumberOfSubsections > 0; NumberOfSubsections -= 1, SectionTableEntry += 1) {
05736 
05737         
if (SectionTableEntry->Misc.VirtualSize == 0) {
05738             SectionVirtualSize = SectionTableEntry->SizeOfRawData;
05739         }
05740         
else {
05741             SectionVirtualSize = SectionTableEntry->Misc.VirtualSize;
05742         }
05743 
05744         VirtualAddress = (ULONG_PTR)DllBase + SectionTableEntry->VirtualAddress;
05745         
if (VirtualAddress <= LastVirtualAddress) {
05746 
05747             
05748             
05749             
05750             
05751 
05752             KdPrint ((
"MM:sysload - Image at %p is badly linked\n", DllBase));
05753             
return;
05754         }
05755         LastVirtualAddress = VirtualAddress + SectionVirtualSize - 1;
05756     }
05757 
05758     NumberOfSubsections = FileHeader->NumberOfSections;
05759     
ASSERT (NumberOfSubsections != 0);
05760 
05761     SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
05762                             OffsetToSectionTable);
05763 
05764     LastVirtualAddress = 0;
05765 
05766     
05767     
05768     
05769     
05770     
05771 
05772     WritablePte = 
MiGetPteAddress ((ULONG_PTR)(SectionTableEntry + NumberOfSubsections) - 1);
05773     LastImagePte = 
MiGetPteAddress(DllBase) + NumberOfPtes;
05774 
05775     
for ( ; NumberOfSubsections > 0; NumberOfSubsections -= 1, SectionTableEntry += 1) {
05776 
05777         
if (SectionTableEntry->Misc.VirtualSize == 0) {
05778             SectionVirtualSize = SectionTableEntry->SizeOfRawData;
05779         }
05780         
else {
05781             SectionVirtualSize = SectionTableEntry->Misc.VirtualSize;
05782         }
05783 
05784         VirtualAddress = (ULONG_PTR)DllBase + SectionTableEntry->VirtualAddress;
05785 
05786         PointerPte = 
MiGetPteAddress (VirtualAddress);
05787 
05788         
if (PointerPte >= LastImagePte) {
05789 
05790             
05791             
05792             
05793 
05794             
break;
05795         }
05796 
05797         SectionProtection = (SectionTableEntry->Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE));
05798 
05799         
if (SectionProtection & IMAGE_SCN_MEM_WRITE) {
05800 
05801             
05802             
05803             
05804             
05805             
05806             
05807 
05808             WritablePte = 
MiGetPteAddress (VirtualAddress + SectionVirtualSize - 1);
05809 
05810             
if (LastVirtualAddress) {
05811                 LastPte = 
MiGetPteAddress (LastVirtualAddress);
05812 
05813                 
if (LastPte == PointerPte) {
05814                     LastPte -= 1;
05815                 }
05816 
05817                 
if (FirstPte <= LastPte) {
05818 
05819                     
ASSERT (PointerPte < LastImagePte);
05820 
05821                     
if (LastPte >= LastImagePte) {
05822                         LastPte = LastImagePte - 1;
05823                     }
05824 
05825                     
MiSetSystemCodeProtection (FirstPte, LastPte);
05826                 }
05827 
05828                 LastVirtualAddress = 0;
05829             }
05830             
continue;
05831         }
05832 
05833         
if (LastVirtualAddress == 0) {
05834 
05835             
05836             
05837             
05838             
05839             
05840             
05841             
05842 
05843             
if (PointerPte == WritablePte) {
05844                 LastPte = 
MiGetPteAddress (VirtualAddress + SectionVirtualSize - 1);
05845                 
if (PointerPte == LastPte) {
05846 
05847                     
05848                     
05849                     
05850                     
05851 
05852                     
continue;
05853                 }
05854                 PointerPte += 1;
05855             }
05856             FirstPte = PointerPte;
05857         }
05858 
05859         LastVirtualAddress = VirtualAddress + SectionVirtualSize - 1;
05860     }
05861 
05862     
if (LastVirtualAddress) {
05863         LastPte = 
MiGetPteAddress (LastVirtualAddress);
05864 
05865         
if ((FirstPte <= LastPte) && (FirstPte < LastImagePte)) {
05866 
05867             
if (LastPte >= LastImagePte) {
05868                 LastPte = LastImagePte - 1;
05869             }
05870 
05871             
MiSetSystemCodeProtection (FirstPte, LastPte);
05872         }
05873     }
05874 }
05875 
05876 
05877 
VOID
05878 MiUpdateThunks (
05879     IN 
PLOADER_PARAMETER_BLOCK LoaderBlock,
05880     IN PVOID OldAddress,
05881     IN PVOID NewAddress,
05882     IN ULONG NumberOfBytes
05883     )
05884 
05885 
05886 
05887 
05888 
05889 
05890 
05891 
05892 
05893 
05894 
05895 
05896 
05897 
05898 
05899 
05900 
05901 
05902 
05903 
05904 
05905 
05906 
05907 
05908 {
05909     PULONG_PTR ImportThunk;
05910     ULONG_PTR OldAddressHigh;
05911     ULONG_PTR AddressDifference;
05912     PLDR_DATA_TABLE_ENTRY DataTableEntry;
05913     PLIST_ENTRY NextEntry;
05914     ULONG_PTR i;
05915     ULONG ImportSize;
05916 
05917     
05918     
05919     
05920     
05921     
05922 
05923     OldAddressHigh = (ULONG_PTR)((PCHAR)OldAddress + NumberOfBytes - 1);
05924     AddressDifference = (ULONG_PTR)NewAddress - (ULONG_PTR)OldAddress;
05925 
05926     NextEntry = LoaderBlock->LoadOrderListHead.Flink;
05927 
05928     
for ( ; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink) {
05929 
05930         DataTableEntry = CONTAINING_RECORD(NextEntry,
05931                                            LDR_DATA_TABLE_ENTRY,
05932                                            InLoadOrderLinks);
05933 
05934         ImportThunk = (PULONG_PTR)
RtlImageDirectoryEntryToData(
05935                                            DataTableEntry->DllBase,
05936                                            
TRUE,
05937                                            IMAGE_DIRECTORY_ENTRY_IAT,
05938                                            &ImportSize);
05939     
05940         
if (ImportThunk == 
NULL) {
05941             
continue;
05942         }
05943 
05944         ImportSize /= 
sizeof(PULONG_PTR);
05945 
05946         
for (i = 0; i < ImportSize; i += 1, ImportThunk += 1) {
05947             
if (*ImportThunk >= (ULONG_PTR)OldAddress && *ImportThunk <= OldAddressHigh) {
05948                 *ImportThunk += AddressDifference;
05949             }
05950         }
05951     }
05952 }
05953 
05954 
05955 
VOID
05956 MiReloadBootLoadedDrivers (
05957     IN 
PLOADER_PARAMETER_BLOCK LoaderBlock
05958     )
05959 
05960 
05961 
05962 
05963 
05964 
05965 
05966 
05967 
05968 
05969 
05970 
05971 
05972 
05973 
05974 
05975 
05976 
05977 
05978 
05979 
05980 
05981 
05982 
05983 
05984 
05985 
05986 
05987 
05988 
05989 
05990 
05991 {
05992     PLDR_DATA_TABLE_ENTRY DataTableEntry;
05993     PLIST_ENTRY NextEntry;
05994     PIMAGE_NT_HEADERS NtHeader;
05995     PIMAGE_DATA_DIRECTORY DataDirectory;
05996     ULONG_PTR i;
05997     ULONG NumberOfPtes;
05998     ULONG NumberOfLoaderPtes;
05999     
PMMPTE PointerPte;
06000     
PMMPTE LastPte;
06001     
PMMPTE LoaderPte;
06002     
MMPTE PteContents;
06003     
MMPTE TempPte;
06004     PVOID LoaderImageAddress;
06005     PVOID NewImageAddress;
06006     
NTSTATUS Status;
06007     PFN_NUMBER PageFrameIndex;
06008     PFN_NUMBER PteFramePage;
06009     
PMMPTE PteFramePointer;
06010     
PMMPFN Pfn1;
06011     
PMMPFN Pfn2;
06012     KIRQL OldIrql;
06013     PCHAR RelocatedVa;
06014     PCHAR NonRelocatedVa;
06015     LOGICAL StopMoving;
06016 
06017 
#if !defined (_X86_)
06018 
06019     
06020     
06021     
06022 
06023     
MmMakeLowMemory = 
FALSE;
06024 
#endif
06025 
    StopMoving = 
FALSE;
06026 
06027     i = 0;
06028     NextEntry = LoaderBlock->LoadOrderListHead.Flink;
06029 
06030     
for ( ; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink) {
06031 
06032         
06033         
06034         
06035         
06036 
06037         i += 1;
06038         
if (i <= 2) {
06039             
continue;
06040         }
06041 
06042         DataTableEntry = CONTAINING_RECORD(NextEntry,
06043                                            LDR_DATA_TABLE_ENTRY,
06044                                            InLoadOrderLinks);
06045 
06046         
06047         
06048         
06049         
06050 
06051         NtHeader = 
RtlImageNtHeader(DataTableEntry->DllBase);
06052 
06053         
if (NtHeader == 
NULL) {
06054             
continue;
06055         }
06056 
06057         
if (IMAGE_DIRECTORY_ENTRY_BASERELOC >= NtHeader->OptionalHeader.NumberOfRvaAndSizes) {
06058             
continue;
06059         }
06060     
06061         DataDirectory = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
06062 
06063         
if (DataDirectory->VirtualAddress == 0) {
06064             
continue;
06065         }
06066 
06067         
if (DataDirectory->VirtualAddress + DataDirectory->Size > DataTableEntry->SizeOfImage) {
06068 
06069             
06070             
06071             
06072             
06073 
06074             
continue;
06075         }
06076 
06077         LoaderImageAddress = DataTableEntry->DllBase;
06078         LoaderPte = 
MiGetPteAddress(DataTableEntry->DllBase);
06079         NumberOfLoaderPtes = (ULONG)((
ROUND_TO_PAGES(DataTableEntry->SizeOfImage)) >> 
PAGE_SHIFT);
06080 
06081         
LOCK_PFN (OldIrql);
06082 
06083         PointerPte = LoaderPte;
06084         LastPte = PointerPte + NumberOfLoaderPtes;
06085 
06086         
while (PointerPte < LastPte) {
06087             
ASSERT (PointerPte->
u.Hard.Valid == 1);
06088             PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
06089             Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
06090 
06091             
06092             
06093             
06094             
06095         
06096             Pfn1->
u3.e1.Modified = 1;
06097             PointerPte += 1;
06098         }
06099 
06100         
UNLOCK_PFN (OldIrql);
06101 
06102         
06103         
06104         
06105         
06106 
06107         NumberOfPtes = NumberOfLoaderPtes;
06108 
06109         PointerPte = 
MiReserveSystemPtes (NumberOfPtes,
06110                                           
SystemPteSpace,
06111                                           0,
06112                                           0,
06113                                           
FALSE);
06114 
06115         
if (PointerPte == 
NULL) {
06116             
continue;
06117         }
06118 
06119         LastPte = PointerPte + NumberOfPtes;
06120 
06121         NewImageAddress = 
MiGetVirtualAddressMappedByPte (PointerPte);
06122 
06123 
#if DBG_SYSLOAD
06124 
        DbgPrint (
"Relocating %wZ from %p to %p, %x bytes\n",
06125                         &DataTableEntry->FullDllName,
06126                         DataTableEntry->DllBase,
06127                         NewImageAddress,
06128                         DataTableEntry->SizeOfImage
06129                         );
06130 
#endif
06131 
06132         
06133         
06134         
06135         
06136 
06137         
ASSERT (
InitializationPhase == 0);
06138 
06139         
06140         
06141         
06142         
06143         
06144         
06145 
06146         RelocatedVa = NewImageAddress;
06147         NonRelocatedVa = (PCHAR) DataTableEntry->DllBase;
06148 
06149         
while (PointerPte < LastPte) {
06150 
06151             PteContents = *LoaderPte;
06152             
ASSERT (PteContents.
u.Hard.Valid == 1);
06153 
06154             
if (
MmMakeLowMemory == 
TRUE) {
06155 
#if DBG
06156 
                PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (LoaderPte);
06157                 Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
06158                 
ASSERT (Pfn1->
u1.WsIndex == 0);
06159 
#endif
06160 
                LOCK_PFN (OldIrql);
06161                 
MiEnsureAvailablePageOrWait (
NULL, 
NULL);
06162                 PageFrameIndex = 
MiRemoveAnyPage(
06163                                     
MI_GET_PAGE_COLOR_FROM_PTE (PointerPte));
06164 
06165                 
if (PageFrameIndex < (16*1024*1024)/
PAGE_SIZE) {
06166 
06167                     
06168                     
06169                     
06170                     
06171 
06172 
#if defined (_X86PAE_)
06173 
                  if (
MiNoLowMemory == 
FALSE)
06174 
#endif
06175 
                    StopMoving = 
TRUE;
06176                 }
06177 
06178                 
MI_MAKE_VALID_PTE (TempPte,
06179                                    PageFrameIndex,
06180                                    
MM_EXECUTE_READWRITE,
06181                                    PointerPte);
06182 
06183                 
MI_SET_PTE_DIRTY (TempPte);
06184                 
MI_SET_ACCESSED_IN_PTE (&TempPte, 1);
06185                 
MI_WRITE_VALID_PTE (PointerPte, TempPte);
06186 
06187                 
MiInitializePfn (PageFrameIndex, PointerPte, 1);
06188                 Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
06189                 Pfn1->
u3.e1.Modified = 1;
06190 
06191                 
06192                 
06193                 
06194 
06195                 Pfn1->
u1.WsIndex = 0;
06196 
06197                 
UNLOCK_PFN (OldIrql);
06198                 RtlMoveMemory (RelocatedVa, NonRelocatedVa, 
PAGE_SIZE);
06199                 RelocatedVa += 
PAGE_SIZE;
06200                 NonRelocatedVa += 
PAGE_SIZE;
06201             }
06202             
else {
06203                 
MI_MAKE_VALID_PTE (TempPte,
06204                                    PteContents.
u.Hard.PageFrameNumber,
06205                                    
MM_EXECUTE_READWRITE,
06206                                    PointerPte);
06207     
06208                 
MI_WRITE_VALID_PTE (PointerPte, TempPte);
06209             }
06210 
06211             PointerPte += 1;
06212             LoaderPte += 1;
06213         }
06214         PointerPte -= NumberOfPtes;
06215 
06216         
ASSERT (*(PULONG)NewImageAddress == *(PULONG)LoaderImageAddress);
06217 
06218         
06219         
06220         
06221 
06222 
#if defined(_ALPHA_)
06223 
06224         
06225         
06226         
06227         
06228 
06229         
Status = (
NTSTATUS)
LdrDoubleRelocateImage(NewImageAddress,
06230                                             LoaderImageAddress,
06231                                             
"SYSLDR",
06232                                             (ULONG)STATUS_SUCCESS,
06233                                             (ULONG)STATUS_CONFLICTING_ADDRESSES,
06234                                             (ULONG)STATUS_INVALID_IMAGE_FORMAT
06235                                             );
06236 
#endif
06237 
06238         NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)LoaderImageAddress;
06239         
if (
MmMakeLowMemory == 
TRUE) {
06240             PIMAGE_NT_HEADERS NtHeader2;
06241 
06242             NtHeader2 = (PIMAGE_NT_HEADERS)((PCHAR)NtHeader + (RelocatedVa - NonRelocatedVa));
06243             NtHeader2->OptionalHeader.ImageBase = (ULONG_PTR)LoaderImageAddress;
06244         }
06245 
06246         
Status = (
NTSTATUS)
LdrRelocateImage(NewImageAddress,
06247                                             
"SYSLDR",
06248                                             (ULONG)STATUS_SUCCESS,
06249                                             (ULONG)STATUS_CONFLICTING_ADDRESSES,
06250                                             (ULONG)STATUS_INVALID_IMAGE_FORMAT
06251                                             );
06252 
06253         
if (!
NT_SUCCESS(
Status)) {
06254 
06255             
if (
MmMakeLowMemory == 
TRUE) {
06256                 
while (PointerPte < LastPte) {
06257                     PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
06258                     Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
06259                     
MiDecrementShareAndValidCount (Pfn1->
PteFrame);
06260                     
MI_SET_PFN_DELETED (Pfn1);
06261                     
MiDecrementShareCountOnly (PageFrameIndex);
06262                     PointerPte += 1;
06263                 }
06264             }
06265 
06266             
MiReleaseSystemPtes (PointerPte,
06267                                  NumberOfPtes,
06268                                  
SystemPteSpace);
06269 
06270             
if (StopMoving == 
TRUE) {
06271                 
MmMakeLowMemory = 
FALSE;
06272             }
06273 
06274             
continue;
06275         }
06276 
06277         
06278         
06279         
06280 
06281         NonRelocatedVa = (PCHAR) DataTableEntry->DllBase;
06282         DataTableEntry->DllBase = NewImageAddress;
06283 
06284         
MiUpdateThunks (LoaderBlock,
06285                         LoaderImageAddress,
06286                         NewImageAddress,
06287                         DataTableEntry->SizeOfImage);
06288 
06289 
06290         
06291         
06292         
06293 
06294         DataTableEntry->Flags |= LDRP_SYSTEM_MAPPED;
06295         DataTableEntry->DllBase = NewImageAddress;
06296         DataTableEntry->EntryPoint =
06297             (PVOID)((PCHAR)NewImageAddress + NtHeader->OptionalHeader.AddressOfEntryPoint);
06298         DataTableEntry->SizeOfImage = NumberOfPtes << 
PAGE_SHIFT;
06299 
06300         
06301         
06302         
06303         
06304         
06305 
06306         LoaderPte = 
MiGetPteAddress (NonRelocatedVa);
06307 
06308         
LOCK_PFN (OldIrql);
06309 
06310         
while (PointerPte < LastPte) {
06311             
ASSERT (PointerPte->
u.Hard.Valid == 1);
06312 
06313             
if (
MmMakeLowMemory == 
TRUE) {
06314                 
ASSERT (LoaderPte->u.Hard.Valid == 1);
06315                 PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (LoaderPte);
06316                 Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
06317 
06318 
#if defined (_X86_) || defined (_IA64_)
06319 
06320                 
06321                 
06322                 
06323                 
06324 
06325                 
MiDecrementShareAndValidCount (Pfn1->
PteFrame);
06326 
#endif
06327 
06328                 
MI_SET_PFN_DELETED (Pfn1);
06329                 
MiDecrementShareCountOnly (PageFrameIndex);
06330                 LoaderPte += 1;
06331             }
06332             
else {
06333 
06334                 PageFrameIndex = 
MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
06335                 Pfn1 = 
MI_PFN_ELEMENT (PageFrameIndex);
06336 
06337 
#if defined (_X86_) || defined (_IA64_)
06338 
06339                 
06340                 
06341                 
06342                 
06343 
06344                 
MiDecrementShareAndValidCount (Pfn1->
PteFrame);
06345                 *Pfn1->
PteAddress = 
ZeroPte;
06346 
#endif
06347 
06348                 
06349                 
06350                 
06351     
06352                 PteFramePointer = 
MiGetPteAddress(PointerPte);
06353                 PteFramePage = 
MI_GET_PAGE_FRAME_FROM_PTE (PteFramePointer);
06354     
06355                 Pfn1->
PteFrame = PteFramePage;
06356                 Pfn1->
PteAddress = PointerPte;
06357     
06358                 
06359                 
06360                 
06361                 
06362             
06363                 Pfn2 = 
MI_PFN_ELEMENT (PteFramePage);
06364                 Pfn2->
u2.ShareCount += 1;
06365             }
06366 
06367             PointerPte += 1;
06368         }
06369 
06370         
UNLOCK_PFN (OldIrql);
06371 
06372         
06373         
06374         
06375         
06376         
06377 
06378         
if (StopMoving == 
TRUE) {
06379             
MmMakeLowMemory = 
FALSE;
06380         }
06381     }
06382 
#if defined (_X86PAE_)
06383 
    if (
MiNoLowMemory == 
TRUE) {
06384         
MiRemoveLowPages ();
06385     }
06386 
#endif
06387 
}
06388 
06389 
#if defined (_X86_)
06390 
PMMPTE MiKernelResourceStartPte;
06391 
PMMPTE MiKernelResourceEndPte;
06392 
#endif
06393 
06394 
VOID
06395 MiLocateKernelSections (
06396     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
06397     )
06398 
06399 
06400 
06401 
06402 
06403 
06404 
06405 
06406 
06407 
06408 
06409 
06410 
06411 
06412 
06413 
06414 
06415 
06416 
06417 
06418 
06419 
06420 
06421 {
06422     PVOID CurrentBase;
06423     PIMAGE_NT_HEADERS NtHeader;
06424     PIMAGE_SECTION_HEADER SectionTableEntry;
06425     LONG i;
06426     
PMMPTE PointerPte;
06427     PVOID SectionBaseAddress;
06428 
06429     CurrentBase = (PVOID)DataTableEntry->DllBase;
06430 
06431     NtHeader = 
RtlImageNtHeader(CurrentBase);
06432 
06433     SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeader +
06434                             
sizeof(ULONG) +
06435                             
sizeof(IMAGE_FILE_HEADER) +
06436                             NtHeader->FileHeader.SizeOfOptionalHeader);
06437 
06438     
06439     
06440     
06441 
06442     i = NtHeader->FileHeader.NumberOfSections;
06443 
06444     PointerPte = 
NULL;
06445 
06446     
while (i > 0) {
06447 
06448         SectionBaseAddress = 
SECTION_BASE_ADDRESS(SectionTableEntry);
06449 
06450 
#if defined (_X86_)
06451 
        if (*(PULONG)SectionTableEntry->Name == 'rsr.') {
06452 
06453             MiKernelResourceStartPte = 
MiGetPteAddress ((ULONG_PTR)CurrentBase +
06454                                              SectionTableEntry->VirtualAddress);
06455 
06456             MiKernelResourceEndPte = 
MiGetPteAddress (
ROUND_TO_PAGES((ULONG_PTR)CurrentBase +
06457                          SectionTableEntry->VirtualAddress +
06458                          (NtHeader->OptionalHeader.SectionAlignment - 1) +
06459                          SectionTableEntry->SizeOfRawData -
06460                          
PAGE_SIZE));
06461             
break;
06462         }
06463 
#endif
06464 
        if (*(PULONG)SectionTableEntry->Name == 'LOOP') {
06465             
if (*(PULONG)&SectionTableEntry->Name[4] == 'EDOC') {
06466                 
ExPoolCodeStart = (PVOID)((ULONG_PTR)CurrentBase +
06467                                              SectionTableEntry->VirtualAddress);
06468                 
ExPoolCodeEnd = (PVOID)((ULONG_PTR)CurrentBase +
06469                                              SectionTableEntry->VirtualAddress +
06470                                              SectionTableEntry->SizeOfRawData);
06471             }
06472             
else if (*(
PUSHORT)&SectionTableEntry->Name[4] == 'IM') {
06473                 
MmPoolCodeStart = (PVOID)((ULONG_PTR)CurrentBase +
06474                                              SectionTableEntry->VirtualAddress);
06475                 
MmPoolCodeEnd = (PVOID)((ULONG_PTR)CurrentBase +
06476                                              SectionTableEntry->VirtualAddress +
06477                                              SectionTableEntry->SizeOfRawData);
06478             }
06479         }
06480         
else if ((*(PULONG)SectionTableEntry->Name == 'YSIM') &&
06481                  (*(PULONG)&SectionTableEntry->Name[4] == 'ETPS')) {
06482                 
MmPteCodeStart = (PVOID)((ULONG_PTR)CurrentBase +
06483                                              SectionTableEntry->VirtualAddress);
06484                 
MmPteCodeEnd = (PVOID)((ULONG_PTR)CurrentBase +
06485                                              SectionTableEntry->VirtualAddress +
06486                                              SectionTableEntry->SizeOfRawData);
06487         }
06488 
06489         i -= 1;
06490         SectionTableEntry += 1;
06491     }
06492 }
06493 
06494 
VOID
06495 MmMakeKernelResourceSectionWritable (
06496     VOID
06497     )
06498 
06499 
06500 
06501 
06502 
06503 
06504 
06505 
06506 
06507 
06508 
06509 
06510 
06511 
06512 
06513 
06514 
06515 
06516 
06517 
06518 
06519 
06520 {
06521 
#if defined (_X86_)
06522 
    MMPTE TempPte;
06523     
MMPTE PteContents;
06524     
PMMPTE PointerPte;
06525 
06526     
if (MiKernelResourceStartPte == 
NULL) {
06527         
return;
06528     }
06529 
06530     PointerPte = MiKernelResourceStartPte;
06531 
06532     
if (
MI_IS_PHYSICAL_ADDRESS (
MiGetVirtualAddressMappedByPte (PointerPte))) {
06533 
06534         
06535         
06536         
06537 
06538         
return;
06539     }
06540 
06541     
06542     
06543     
06544     
06545 
06546     
do {
06547         PteContents = *PointerPte;
06548 
#if defined(NT_UP)
06549 
        if (PteContents.
u.Hard.Write == 0)
06550 
#else
06551 
        if (PteContents.
u.Hard.Writable == 0)
06552 
#endif
06553 
        {
06554             
MI_MAKE_VALID_PTE (TempPte,
06555                                PteContents.
u.Hard.PageFrameNumber,
06556                                
MM_READWRITE,
06557                                PointerPte);
06558 
#if !defined(NT_UP)
06559 
            TempPte.
u.Hard.Writable = 1;
06560 
#endif
06561 
            MI_WRITE_VALID_PTE_NEW_PROTECTION (PointerPte, TempPte);
06562         }
06563         PointerPte += 1;
06564     } 
while (PointerPte <= MiKernelResourceEndPte); 
06565 
06566     
06567     
06568     
06569 
06570     MiKernelResourceStartPte = 
NULL;
06571 
06572     
06573     
06574     
06575 
06576     
KeFlushCurrentTb ();
06577 
#endif
06578 
}
06579 
06580 
#ifdef i386
06581 
PVOID 
PsNtosImageBase = (PVOID)0x80100000;
06582 
#else
06583 PVOID 
PsNtosImageBase;
06584 
#endif
06585 
06586 LIST_ENTRY 
PsLoadedModuleList;
06587 ERESOURCE PsLoadedModuleResource;
06588 
extern KSPIN_LOCK 
PsLoadedModuleSpinLock;
06589 
06590 LOGICAL
06591 MiInitializeLoadedModuleList (
06592     IN 
PLOADER_PARAMETER_BLOCK LoaderBlock
06593     )
06594 
06595 
06596 
06597 
06598 
06599 
06600 
06601 
06602 
06603 
06604 
06605 
06606 
06607 
06608 
06609 
06610 
06611 
06612 
06613 
06614 
06615 {
06616     PLIST_ENTRY NextEntry;
06617     PLDR_DATA_TABLE_ENTRY DataTableEntry1;
06618     PLDR_DATA_TABLE_ENTRY DataTableEntry2;
06619 
06620     
06621     
06622     
06623 
06624     
ExInitializeResource (&
PsLoadedModuleResource);
06625     
KeInitializeSpinLock (&
PsLoadedModuleSpinLock);
06626 
06627     InitializeListHead (&
PsLoadedModuleList);
06628 
06629     
06630     
06631     
06632     
06633     
06634     
06635     
06636 
06637     NextEntry = LoaderBlock->LoadOrderListHead.Flink;
06638     DataTableEntry2 = CONTAINING_RECORD(NextEntry,
06639                                         LDR_DATA_TABLE_ENTRY,
06640                                         InLoadOrderLinks);
06641     
PsNtosImageBase = DataTableEntry2->DllBase;
06642 
06643     
MiLocateKernelSections (DataTableEntry2);
06644 
06645     
while (NextEntry != &LoaderBlock->LoadOrderListHead) {
06646 
06647         DataTableEntry2 = CONTAINING_RECORD(NextEntry,
06648                                             LDR_DATA_TABLE_ENTRY,
06649                                             InLoadOrderLinks);
06650 
06651         
06652         
06653         
06654 
06655         DataTableEntry1 = 
ExAllocatePoolWithTag (
NonPagedPool,
06656                                                  
sizeof(LDR_DATA_TABLE_ENTRY),
06657                                                  'dLmM');
06658 
06659         
if (DataTableEntry1 == 
NULL) {
06660             
return FALSE;
06661         }
06662 
06663         
06664         
06665         
06666 
06667         *DataTableEntry1 = *DataTableEntry2;
06668 
06669         DataTableEntry1->FullDllName.Buffer = 
ExAllocatePoolWithTag (
PagedPool,
06670             DataTableEntry2->FullDllName.MaximumLength + 
sizeof(UNICODE_NULL),
06671             'TDmM');
06672 
06673         
if (DataTableEntry1->FullDllName.Buffer == 
NULL) {
06674             
ExFreePool (DataTableEntry1);
06675             
return FALSE;
06676         }
06677 
06678         DataTableEntry1->BaseDllName.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
06679             DataTableEntry2->BaseDllName.MaximumLength + 
sizeof(UNICODE_NULL),
06680             'dLmM');
06681 
06682         
if (DataTableEntry1->BaseDllName.Buffer == 
NULL) {
06683             
ExFreePool (DataTableEntry1->FullDllName.Buffer);
06684             
ExFreePool (DataTableEntry1);
06685             
return FALSE;
06686         }
06687 
06688         
06689         
06690         
06691 
06692         RtlMoveMemory (DataTableEntry1->FullDllName.Buffer,
06693                        DataTableEntry2->FullDllName.Buffer,
06694                        DataTableEntry1->FullDllName.MaximumLength);
06695 
06696         RtlMoveMemory (DataTableEntry1->BaseDllName.Buffer,
06697                        DataTableEntry2->BaseDllName.Buffer,
06698                        DataTableEntry1->BaseDllName.MaximumLength);
06699 
06700         
06701         
06702         
06703         
06704 
06705         InsertTailList(&
PsLoadedModuleList,
06706                        &DataTableEntry1->InLoadOrderLinks);
06707 
06708         NextEntry = NextEntry->Flink;
06709     }
06710 
06711     
MiBuildImportsForBootDrivers ();
06712 
06713     
return TRUE;
06714 }
06715 
06716 
NTSTATUS
06717 MmCallDllInitialize(
06718     IN PLDR_DATA_TABLE_ENTRY DataTableEntry
06719 )
06720 
06721 
06722 
06723 
06724 
06725 
06726 
06727 
06728 
06729 
06730 
06731 
06732 
06733 
06734 
06735 
06736 
06737 
06738 
06739 
06740 
06741 {
06742     
NTSTATUS st;
06743     PWCHAR Dot;
06744     
PMM_DLL_INITIALIZE Func;
06745     UNICODE_STRING RegistryPath;
06746     UNICODE_STRING ImportName;
06747 
06748     Func = 
MiLocateExportName (DataTableEntry->DllBase, 
"DllInitialize");
06749 
06750     
if (!Func) {
06751         
return STATUS_SUCCESS;
06752     }
06753 
06754     ImportName.MaximumLength = DataTableEntry->BaseDllName.Length;
06755     ImportName.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
06756                                                ImportName.MaximumLength,
06757                                                'TDmM');
06758 
06759     
if (ImportName.Buffer == 
NULL) {
06760         
return STATUS_INSUFFICIENT_RESOURCES;
06761     }
06762 
06763     ImportName.Length = DataTableEntry->BaseDllName.Length;
06764     RtlMoveMemory (ImportName.Buffer,
06765                    DataTableEntry->BaseDllName.Buffer,
06766                    ImportName.Length);
06767 
06768     RegistryPath.MaximumLength = 
CmRegistryMachineSystemCurrentControlSetServices.Length +
06769                                     ImportName.Length +
06770                                     (
USHORT)(2*
sizeof(WCHAR));
06771 
06772     RegistryPath.Buffer = 
ExAllocatePoolWithTag (
NonPagedPool,
06773                                                  RegistryPath.MaximumLength,
06774                                                  'TDmM');
06775 
06776     
if (RegistryPath.Buffer == 
NULL) {
06777         
ExFreePool (ImportName.Buffer);
06778         
return STATUS_INSUFFICIENT_RESOURCES;
06779     }
06780 
06781     RegistryPath.Length = 
CmRegistryMachineSystemCurrentControlSetServices.Length;
06782     RtlMoveMemory (RegistryPath.Buffer,
06783                    
CmRegistryMachineSystemCurrentControlSetServices.Buffer,
06784                    
CmRegistryMachineSystemCurrentControlSetServices.Length);
06785 
06786     
RtlAppendUnicodeToString (&RegistryPath, 
L"\\");
06787     Dot = wcschr (ImportName.Buffer, 
L'.');
06788     
if (Dot) {
06789         ImportName.Length = (
USHORT)((Dot - ImportName.Buffer) * 
sizeof(WCHAR));
06790     }
06791 
06792     
RtlAppendUnicodeStringToString (&RegistryPath, &ImportName);
06793     
ExFreePool (ImportName.Buffer);
06794 
06795     
06796     
06797     
06798 
06799     st = Func (&RegistryPath);
06800 
06801     
ExFreePool (RegistryPath.Buffer);
06802 
06803     
return st;
06804 }
06805 
06806 
NTKERNELAPI
06807 PVOID
06808 MmGetSystemRoutineAddress (
06809     IN PUNICODE_STRING SystemRoutineName
06810 )
06811 
06812 
06813 
06814 
06815 
06816 
06817 
06818 
06819 
06820 
06821 
06822 
06823 
06824 
06825 
06826 
06827 
06828 
06829 
06830 
06831 
06832 
06833 {
06834     ULONG AnsiLength;
06835     
NTSTATUS Status;
06836     PLDR_DATA_TABLE_ENTRY DataTableEntry;
06837     ANSI_STRING AnsiString;
06838     PLIST_ENTRY NextEntry;
06839     UNICODE_STRING KernelString;
06840     UNICODE_STRING HalString;
06841     PVOID FunctionAddress;
06842     LOGICAL Found;
06843     ULONG EntriesChecked;
06844 
06845     
ASSERT (KeGetCurrentIrql() == 
PASSIVE_LEVEL);
06846 
06847     EntriesChecked = 0;
06848     FunctionAddress = 
NULL;
06849 
06850     
RtlInitUnicodeString (&KernelString, 
L"ntoskrnl.exe");
06851     
RtlInitUnicodeString (&HalString, 
L"hal.dll");
06852 
06853     
do {
06854         
Status = 
RtlUnicodeStringToAnsiString( &AnsiString,
06855                                                SystemRoutineName,
06856                                                
TRUE );
06857     
06858         
if (
NT_SUCCESS( 
Status)) {
06859             
break;
06860         }
06861 
06862         
KeDelayExecutionThread (
KernelMode, 
FALSE, &
MmShortTime);
06863 
06864     } 
while (
TRUE);
06865     
06866     
06867     
06868     
06869 
06870     
KeEnterCriticalRegion();
06871     
ExAcquireResourceShared (&
PsLoadedModuleResource, 
TRUE);
06872 
06873     
06874     
06875     
06876 
06877     NextEntry = 
PsLoadedModuleList.Flink;
06878     
while (NextEntry != &
PsLoadedModuleList) {
06879 
06880         Found = 
FALSE;
06881 
06882         DataTableEntry = CONTAINING_RECORD(NextEntry,
06883                                            LDR_DATA_TABLE_ENTRY,
06884                                            InLoadOrderLinks);
06885 
06886         
if (
RtlEqualUnicodeString (&KernelString,
06887                                    &DataTableEntry->BaseDllName,
06888                                    
TRUE)) {
06889 
06890             Found = 
TRUE;
06891             EntriesChecked += 1;
06892 
06893         }
06894         
else if (
RtlEqualUnicodeString (&HalString,
06895                                         &DataTableEntry->BaseDllName,
06896                                         
TRUE)) {
06897 
06898             Found = 
TRUE;
06899             EntriesChecked += 1;
06900         }
06901 
06902         
if (Found == 
TRUE) {
06903 
06904             FunctionAddress = 
MiFindExportedRoutineByName (DataTableEntry,
06905                                                            &AnsiString);
06906 
06907             
if (FunctionAddress != 
NULL) {
06908                 
break;
06909             }
06910 
06911             
if (EntriesChecked == 2) {
06912                 
break;
06913             }
06914         }
06915 
06916         NextEntry = NextEntry->Flink;
06917     }
06918 
06919     
ExReleaseResource (&
PsLoadedModuleResource);
06920     
KeLeaveCriticalRegion();
06921 
06922     
RtlFreeAnsiString (&AnsiString);
06923 
06924     
return FunctionAddress;
06925 }
06926 
06927 PVOID
06928 MiFindExportedRoutineByName(
06929     IN PLDR_DATA_TABLE_ENTRY DataTableEntry,
06930     IN PANSI_STRING AnsiImageRoutineName
06931     )
06932 
06933 
06934 
06935 
06936 
06937 
06938 
06939 
06940 
06941 
06942 
06943 
06944 
06945 
06946 
06947 
06948 
06949 
06950 
06951 
06952 
06953 
06954 
06955 
06956 
06957 
06958 
06959 
06960 
06961 
06962 
06963 
06964 
06965 {
06966     PCHAR DllBase;
06967     
USHORT OrdinalNumber;
06968     PULONG NameTableBase;
06969     
PUSHORT NameOrdinalTableBase;
06970     PULONG Addr;
06971     ULONG High;
06972     ULONG Low;
06973     ULONG Middle;
06974     LONG Result;
06975     ULONG ExportSize;
06976     PVOID FunctionAddress;
06977     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
06978 
06979     
PAGED_CODE();
06980 
06981     DllBase = DataTableEntry->DllBase;
06982 
06983     ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
RtlImageDirectoryEntryToData(
06984                                 DllBase,
06985                                 
TRUE,
06986                                 IMAGE_DIRECTORY_ENTRY_EXPORT,
06987                                 &ExportSize
06988                                 );
06989 
06990     
ASSERT (ExportDirectory != 
NULL);
06991 
06992     
06993     
06994     
06995 
06996     NameTableBase = (PULONG)(DllBase + (ULONG)ExportDirectory->AddressOfNames);
06997 
06998     
06999     
07000     
07001 
07002     NameOrdinalTableBase = (
PUSHORT)(DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
07003 
07004     
07005     
07006     
07007 
07008     Low = 0;
07009     High = ExportDirectory->NumberOfNames - 1;
07010 
07011     
while (High >= Low) {
07012 
07013         
07014         
07015         
07016         
07017 
07018         Middle = (Low + High) >> 1;
07019 
07020         Result = strcmp(AnsiImageRoutineName->Buffer,
07021                         (PCHAR)(DllBase + NameTableBase[Middle]));
07022 
07023         
if (Result < 0) {
07024             High = Middle - 1;
07025         }
07026         
else if (Result > 0) {
07027             Low = Middle + 1;
07028         }
07029         
else {
07030             
break;
07031         }
07032     }
07033 
07034     
07035     
07036     
07037     
07038     
07039 
07040     
if (High < Low) {
07041         
return NULL;
07042     }
07043 
07044     OrdinalNumber = NameOrdinalTableBase[Middle];
07045 
07046     
07047     
07048     
07049     
07050 
07051     
if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) {
07052         
return NULL;
07053     }
07054 
07055     
07056     
07057     
07058 
07059     Addr = (PULONG)(DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
07060 
07061     FunctionAddress = (PVOID)(DllBase + Addr[OrdinalNumber]);
07062 
07063     
07064     
07065     
07066 
07067     
ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) ||
07068             (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize)));
07069 
07070     
return FunctionAddress;
07071 }