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

ldrapi.c File Reference

#include "ldrp.h"

Go to the source code of this file.

Defines

#define DLLEXTENSION   ((PWSTR)".\0d\0l\0l\0\0")

Functions

ULONG LdrpClearLoadInProgress (VOID)
NTSTATUS LdrLoadDll (IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle)
NTSTATUS NTAPI LdrpLoadDll (IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines)
NTSTATUS LdrGetDllHandle (IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle)
NTSTATUS LdrDisableThreadCalloutsForDll (IN PVOID DllHandle)
NTSTATUS LdrUnloadDll (IN PVOID DllHandle)
NTSTATUS LdrGetProcedureAddress (IN PVOID DllHandle, IN PANSI_STRING ProcedureName OPTIONAL, IN ULONG ProcedureNumber OPTIONAL, OUT PVOID *ProcedureAddress)
NTSTATUS LdrpGetProcedureAddress (IN PVOID DllHandle, IN PANSI_STRING ProcedureName OPTIONAL, IN ULONG ProcedureNumber OPTIONAL, OUT PVOID *ProcedureAddress, IN BOOLEAN RunInitRoutines)
NTSTATUS NTAPI LdrVerifyImageMatchesChecksum (IN HANDLE ImageFileHandle, IN PLDR_IMPORT_MODULE_CALLBACK ImportCallbackRoutine OPTIONAL, IN PVOID ImportCallbackParameter, OUT PUSHORT ImageCharacteristics OPTIONAL)
NTSTATUS LdrQueryProcessModuleInformation (OUT PRTL_PROCESS_MODULES ModuleInformation, IN ULONG ModuleInformationLength, OUT PULONG ReturnLength OPTIONAL)


Define Documentation

#define DLLEXTENSION   ((PWSTR)".\0d\0l\0l\0\0")
 

Definition at line 26 of file ldrapi.c.

Referenced by LdrGetDllHandle(), and LdrpLoadDll().


Function Documentation

NTSTATUS LdrDisableThreadCalloutsForDll IN PVOID  DllHandle  ) 
 

Definition at line 474 of file ldrapi.c.

References FALSE, LdrpCheckForLoadedDllHandle(), LdrpInLdrInit, LdrpShutdownInProgress, LoaderLock, and NTSTATUS().

Referenced by CsrClientConnectToServer().

00480 : 00481 00482 This function disables thread attach and detach notification 00483 for the specified DLL. 00484 00485 Arguments: 00486 00487 DllHandle - Supplies a handle to the DLL to disable. 00488 00489 Return Value: 00490 00491 TBD 00492 00493 --*/ 00494 00495 { 00496 NTSTATUS st; 00497 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00498 00499 st = STATUS_SUCCESS; 00500 00501 try { 00502 00503 if ( LdrpInLdrInit == FALSE ) { 00504 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00505 } 00506 if ( LdrpShutdownInProgress ) { 00507 return STATUS_SUCCESS; 00508 } 00509 00510 if (LdrpCheckForLoadedDllHandle(DllHandle, &LdrDataTableEntry)) { 00511 if ( LdrDataTableEntry->TlsIndex ) { 00512 st = STATUS_DLL_NOT_FOUND; 00513 } 00514 else { 00515 LdrDataTableEntry->Flags |= LDRP_DONT_CALL_FOR_THREADS; 00516 } 00517 } 00518 } 00519 finally { 00520 if ( LdrpInLdrInit == FALSE ) { 00521 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00522 } 00523 } 00524 return st; 00525 }

NTSTATUS LdrGetDllHandle IN PWSTR DllPath  OPTIONAL,
IN PULONG DllCharacteristics  OPTIONAL,
IN PUNICODE_STRING  DllName,
OUT PVOID *  DllHandle
 

Definition at line 295 of file ldrapi.c.

References DbgPrint, DLLEXTENSION, FALSE, L, LdrpCheckForLoadedDll(), LdrpGetModuleHandleCache, LdrpInLdrInit, LoaderLock, NTSTATUS(), NULL, RtlEqualUnicodeString(), RtlInitUnicodeString(), ShowSnaps, and TRUE.

Referenced by CsrClientConnectToServer().

00304 : 00305 00306 This function locates the specified DLL and returns its handle. 00307 00308 Arguments: 00309 00310 DllPath - Supplies the search path to be used to locate the DLL. 00311 00312 DllCharacteristics - Supplies an optional DLL characteristics flag, 00313 that if specified is used to match against the dll being loaded. 00314 00315 DllName - Supplies the name of the DLL to load. 00316 00317 DllHandle - Returns a handle to the loaded DLL. 00318 00319 Return Value: 00320 00321 TBD 00322 00323 --*/ 00324 00325 { 00326 NTSTATUS st; 00327 PPEB Peb; 00328 PTEB Teb; 00329 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00330 PWSTR ActualDllName; 00331 PWCH p, pp; 00332 UNICODE_STRING ActualDllNameStr; 00333 BOOLEAN Wx86KnownDll = FALSE; 00334 WCHAR FreeBuffer[266]; 00335 00336 00337 DllCharacteristics; 00338 00339 Peb = NtCurrentPeb(); 00340 Teb = NtCurrentTeb(); 00341 00342 st = STATUS_DLL_NOT_FOUND; 00343 00344 try { 00345 00346 // 00347 // Grab Peb lock 00348 // 00349 00350 if ( LdrpInLdrInit == FALSE ) { 00351 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00352 } 00353 00354 #if defined (WX86) 00355 00356 00357 if (Teb->Wx86Thread.UseKnownWx86Dll) { 00358 Wx86KnownDll = Teb->Wx86Thread.UseKnownWx86Dll; 00359 Teb->Wx86Thread.UseKnownWx86Dll = FALSE; 00360 } 00361 00362 // 00363 // No module handle cache lookup for Wx86, 00364 // (relies on unique basename) 00365 // 00366 if (Wx86ProcessInit) { 00367 LdrpGetModuleHandleCache = NULL; 00368 } 00369 00370 #endif 00371 00372 00373 if ( LdrpGetModuleHandleCache ) { 00374 if (RtlEqualUnicodeString(DllName, 00375 &LdrpGetModuleHandleCache->BaseDllName, 00376 TRUE 00377 )) { 00378 *DllHandle = (PVOID)LdrpGetModuleHandleCache->DllBase; 00379 st = STATUS_SUCCESS; 00380 leave; 00381 } 00382 } 00383 00384 00385 00386 p = DllName->Buffer; 00387 pp = NULL; 00388 while (*p) { 00389 if (*p++ == (WCHAR)'.') { 00390 // 00391 // pp will point to first character after last '.' 00392 // 00393 pp = p; 00394 } 00395 } 00396 00397 ActualDllName = FreeBuffer; 00398 if ( DllName->Length >= sizeof(FreeBuffer)) { 00399 return STATUS_NAME_TOO_LONG; 00400 } 00401 RtlMoveMemory(ActualDllName, DllName->Buffer, DllName->Length); 00402 00403 if (!pp || *pp == (WCHAR)'\\') { 00404 // 00405 // No extension found (just ..\) 00406 // 00407 if ( DllName->Length+10 >= sizeof(FreeBuffer) ) { 00408 return STATUS_NAME_TOO_LONG; 00409 } 00410 00411 RtlMoveMemory((PCHAR)ActualDllName+DllName->Length, DLLEXTENSION, 10); 00412 } 00413 00414 else { 00415 00416 // 00417 // see if the name ends in . If it does, trim out the trailing 00418 // . 00419 // 00420 00421 if ( ActualDllName[ (DllName->Length-2) >> 1] == L'.' ) { 00422 DllName->Length -= 2; 00423 } 00424 00425 ActualDllName[DllName->Length >> 1] = UNICODE_NULL; 00426 } 00427 00428 00429 00430 // 00431 // Check the LdrTable to see if Dll has already been loaded 00432 // into this image. 00433 // 00434 00435 RtlInitUnicodeString(&ActualDllNameStr,ActualDllName); 00436 ActualDllNameStr.MaximumLength = sizeof(FreeBuffer); 00437 00438 if (ShowSnaps) { 00439 DbgPrint("LDR: LdrGetDllHandle, searching for %ws from %ws\n", 00440 ActualDllName, 00441 ARGUMENT_PRESENT(DllPath) ? (DllPath == (PWSTR)1 ? L"" : DllPath) : L"" 00442 ); 00443 } 00444 00445 00446 // 00447 // sort of a hack, but done to speed up GetModuleHandle. kernel32 00448 // now does a two pass call here to avoid computing 00449 // process dll path 00450 // 00451 00452 00453 if (LdrpCheckForLoadedDll( DllPath, 00454 &ActualDllNameStr, 00455 (BOOLEAN)(DllPath == (PWSTR)1 ? TRUE : FALSE), 00456 Wx86KnownDll, 00457 &LdrDataTableEntry 00458 ) 00459 ) { 00460 *DllHandle = (PVOID)LdrDataTableEntry->DllBase; 00461 LdrpGetModuleHandleCache = LdrDataTableEntry; 00462 st = STATUS_SUCCESS; 00463 00464 } 00465 } finally { 00466 if ( LdrpInLdrInit == FALSE ) { 00467 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00468 } 00469 } 00470 return st; 00471 }

NTSTATUS LdrGetProcedureAddress IN PVOID  DllHandle,
IN PANSI_STRING ProcedureName  OPTIONAL,
IN ULONG ProcedureNumber  OPTIONAL,
OUT PVOID *  ProcedureAddress
 

Definition at line 838 of file ldrapi.c.

References LdrpGetProcedureAddress(), and TRUE.

Referenced by CsrClientConnectToServer(), and LdrpInitializeProcess().

00844 { 00845 00846 return LdrpGetProcedureAddress(DllHandle,ProcedureName,ProcedureNumber,ProcedureAddress,TRUE); 00847 00848 }

NTSTATUS LdrLoadDll IN PWSTR DllPath  OPTIONAL,
IN PULONG DllCharacteristics  OPTIONAL,
IN PUNICODE_STRING  DllName,
OUT PVOID *  DllHandle
 

Definition at line 35 of file ldrapi.c.

References LdrpLoadDll(), and TRUE.

Referenced by LdrpInitializeProcess(), and SetConsolePalette().

00044 : 00045 00046 This function loads a DLL into the calling process address space. 00047 00048 Arguments: 00049 00050 DllPath - Supplies the search path to be used to locate the DLL. 00051 00052 DllCharacteristics - Supplies an optional DLL characteristics flag, 00053 that if specified is used to match against the dll being loaded. 00054 00055 DllName - Supplies the name of the DLL to load. 00056 00057 DllHandle - Returns a handle to the loaded DLL. 00058 00059 Return Value: 00060 00061 TBD 00062 00063 --*/ 00064 { 00065 return LdrpLoadDll(DllPath,DllCharacteristics,DllName,DllHandle,TRUE); 00066 }

ULONG LdrpClearLoadInProgress VOID   ) 
 

Definition at line 622 of file ldrsnap.c.

Referenced by LdrpLoadDll(), and LdrpRunInitializeRoutines().

00625 { 00626 PLIST_ENTRY Head, Next; 00627 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00628 ULONG i; 00629 00630 Head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; 00631 Next = Head->Flink; 00632 i = 0; 00633 while ( Next != Head ) { 00634 LdrDataTableEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks); 00635 LdrDataTableEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS; 00636 00637 // 00638 // return the number of entries that have not been processed, but 00639 // have init routines 00640 // 00641 00642 if ( !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED) && LdrDataTableEntry->EntryPoint) { 00643 i++; 00644 } 00645 00646 Next = Next->Flink; 00647 } 00648 return i; 00649 }

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

Definition at line 851 of file ldrapi.c.

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

Referenced by LdrGetProcedureAddress(), and LdrpSnapThunk().

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

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

Definition at line 70 of file ldrapi.c.

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

Referenced by LdrLoadDll(), and LdrpSnapThunk().

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

NTSTATUS LdrQueryProcessModuleInformation OUT PRTL_PROCESS_MODULES  ModuleInformation,
IN ULONG  ModuleInformationLength,
OUT PULONG ReturnLength  OPTIONAL
 

Definition at line 1210 of file ldrapi.c.

References FALSE, LdrpInLdrInit, LoaderLock, NTSTATUS(), NULL, RtlUnicodeStringToAnsiString(), Status, and USHORT.

Referenced by RtlQueryProcessModuleInformation().

01215 { 01216 NTSTATUS Status; 01217 PPEB Peb; 01218 PLIST_ENTRY LoadOrderListHead; 01219 PLIST_ENTRY InitOrderListHead; 01220 ULONG RequiredLength; 01221 PLIST_ENTRY Next; 01222 PLIST_ENTRY Next1; 01223 PRTL_PROCESS_MODULE_INFORMATION ModuleInfo; 01224 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 01225 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry1; 01226 ANSI_STRING AnsiString; 01227 PUCHAR s; 01228 01229 Peb = NtCurrentPeb(); 01230 01231 // 01232 // Grab Peb lock and capture information about of DLLs loaded in current process. 01233 // 01234 01235 if ( LdrpInLdrInit == FALSE ) { 01236 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01237 } 01238 01239 try { 01240 RequiredLength = FIELD_OFFSET( RTL_PROCESS_MODULES, Modules ); 01241 if (ModuleInformationLength < RequiredLength) { 01242 Status = STATUS_INFO_LENGTH_MISMATCH; 01243 ModuleInfo = NULL; 01244 } 01245 else { 01246 ModuleInformation->NumberOfModules = 0; 01247 ModuleInfo = &ModuleInformation->Modules[ 0 ]; 01248 Status = STATUS_SUCCESS; 01249 } 01250 01251 LoadOrderListHead = &Peb->Ldr->InLoadOrderModuleList; 01252 InitOrderListHead = &Peb->Ldr->InInitializationOrderModuleList; 01253 Next = LoadOrderListHead->Flink; 01254 while ( Next != LoadOrderListHead ) { 01255 LdrDataTableEntry = CONTAINING_RECORD( Next, 01256 LDR_DATA_TABLE_ENTRY, 01257 InLoadOrderLinks 01258 ); 01259 01260 RequiredLength += sizeof( RTL_PROCESS_MODULE_INFORMATION ); 01261 if (ModuleInformationLength < RequiredLength) { 01262 Status = STATUS_INFO_LENGTH_MISMATCH; 01263 } 01264 else { 01265 ModuleInfo->MappedBase = NULL; 01266 ModuleInfo->ImageBase = LdrDataTableEntry->DllBase; 01267 ModuleInfo->ImageSize = LdrDataTableEntry->SizeOfImage; 01268 ModuleInfo->Flags = LdrDataTableEntry->Flags; 01269 ModuleInfo->LoadCount = LdrDataTableEntry->LoadCount; 01270 01271 ModuleInfo->LoadOrderIndex = (USHORT)(ModuleInformation->NumberOfModules); 01272 01273 ModuleInfo->InitOrderIndex = 0; 01274 Next1 = InitOrderListHead->Flink; 01275 while ( Next1 != InitOrderListHead ) { 01276 LdrDataTableEntry1 = CONTAINING_RECORD( Next1, 01277 LDR_DATA_TABLE_ENTRY, 01278 InInitializationOrderLinks 01279 ); 01280 01281 ModuleInfo->InitOrderIndex++; 01282 if (LdrDataTableEntry1 == LdrDataTableEntry) { 01283 break; 01284 } 01285 01286 Next1 = Next1->Flink; 01287 } 01288 01289 AnsiString.Buffer = ModuleInfo->FullPathName; 01290 AnsiString.Length = 0; 01291 AnsiString.MaximumLength = sizeof( ModuleInfo->FullPathName ); 01292 RtlUnicodeStringToAnsiString( &AnsiString, 01293 &LdrDataTableEntry->FullDllName, 01294 FALSE 01295 ); 01296 s = AnsiString.Buffer + AnsiString.Length; 01297 while (s > AnsiString.Buffer && *--s) { 01298 if (*s == (UCHAR)OBJ_NAME_PATH_SEPARATOR) { 01299 s++; 01300 break; 01301 } 01302 } 01303 ModuleInfo->OffsetToFileName = (USHORT)(s - AnsiString.Buffer); 01304 01305 ModuleInfo++; 01306 } 01307 01308 if (ModuleInformation != NULL) { 01309 ModuleInformation->NumberOfModules++; 01310 } 01311 01312 Next = Next->Flink; 01313 } 01314 01315 if (ARGUMENT_PRESENT( ReturnLength )) { 01316 *ReturnLength = RequiredLength; 01317 } 01318 } 01319 finally { 01320 if ( LdrpInLdrInit == FALSE ) { 01321 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01322 } 01323 } 01324 01325 return( Status ); 01326 }

NTSTATUS LdrUnloadDll IN PVOID  DllHandle  ) 
 

Definition at line 528 of file ldrapi.c.

References ASSERT, DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, LdrpActiveUnloadCount, LdrpCallInitRoutine, LdrpCheckForLoadedDllHandle(), LdrpDereferenceLoadedDll, LdrpGetModuleHandleCache, LdrpInLdrInit, LdrpLoadedDllHandleCache, LdrpShutdownInProgress, LdrpUnloadHead, LdrUnloadAlternateResourceModule(), LoaderLock, NT_SUCCESS, NTSTATUS(), NtUnmapViewOfSection(), NULL, RtlFreeHeap, RtlFreeUnicodeString(), and ShowSnaps.

Referenced by LdrpLoadDll().

00534 : 00535 00536 This function unloads the DLL from the specified process 00537 00538 Arguments: 00539 00540 DllHandle - Supplies a handle to the DLL to unload. 00541 00542 Return Value: 00543 00544 TBD 00545 00546 --*/ 00547 00548 { 00549 NTSTATUS st; 00550 PPEB Peb; 00551 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00552 PLDR_DATA_TABLE_ENTRY Entry; 00553 PDLL_INIT_ROUTINE InitRoutine; 00554 LIST_ENTRY LocalUnloadHead; 00555 PLIST_ENTRY Next; 00556 #if defined (WX86) 00557 PVOID Wx86Plugin = NULL; 00558 #endif 00559 00560 Peb = NtCurrentPeb(); 00561 st = STATUS_SUCCESS; 00562 00563 try { 00564 00565 // 00566 // Grab Peb lock and decrement reference count of all affected DLLs 00567 // 00568 00569 00570 if ( LdrpInLdrInit == FALSE ) { 00571 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00572 } 00573 00574 LdrpActiveUnloadCount++; 00575 00576 if ( LdrpShutdownInProgress ) { 00577 goto leave_finally; 00578 } 00579 00580 if (!LdrpCheckForLoadedDllHandle(DllHandle, &LdrDataTableEntry)) { 00581 st = STATUS_DLL_NOT_FOUND; 00582 goto leave_finally; 00583 } 00584 00585 // 00586 // Now that we have the data table entry, unload it 00587 // 00588 00589 if ( LdrDataTableEntry->LoadCount != 0xffff ) { 00590 LdrDataTableEntry->LoadCount--; 00591 if ( LdrDataTableEntry->Flags & LDRP_IMAGE_DLL ) { 00592 LdrpDereferenceLoadedDll(LdrDataTableEntry); 00593 } 00594 } else { 00595 00596 // 00597 // if the load count is 0xffff, then we do not need to recurse 00598 // through this DLL's import table. 00599 // 00600 // Additionally, we don't have to scan more LoadCount == 0 00601 // modules since nothing could have happened as a result of a free on this 00602 // DLL. 00603 00604 goto leave_finally; 00605 } 00606 00607 // 00608 // Now process init routines and then in a second pass, unload 00609 // DLLs 00610 // 00611 00612 if (ShowSnaps) { 00613 DbgPrint("LDR: UNINIT LIST\n"); 00614 } 00615 00616 if (LdrpActiveUnloadCount == 1 ) { 00617 InitializeListHead(&LdrpUnloadHead); 00618 } 00619 00620 // 00621 // Go in reverse order initialization order and build 00622 // the unload list 00623 // 00624 00625 Next = Peb->Ldr->InInitializationOrderModuleList.Blink; 00626 while ( Next != &Peb->Ldr->InInitializationOrderModuleList) { 00627 LdrDataTableEntry 00628 = (PLDR_DATA_TABLE_ENTRY) 00629 (CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,InInitializationOrderLinks)); 00630 00631 Next = Next->Blink; 00632 LdrDataTableEntry->Flags &= ~LDRP_UNLOAD_IN_PROGRESS; 00633 00634 if (LdrDataTableEntry->LoadCount == 0) { 00635 00636 if (ShowSnaps) { 00637 DbgPrint(" (%d) [%ws] %ws (%lx) deinit %lx\n", 00638 LdrpActiveUnloadCount, 00639 LdrDataTableEntry->BaseDllName.Buffer, 00640 LdrDataTableEntry->FullDllName.Buffer, 00641 (ULONG)LdrDataTableEntry->LoadCount, 00642 LdrDataTableEntry->EntryPoint 00643 ); 00644 } 00645 00646 Entry = LdrDataTableEntry; 00647 00648 RemoveEntryList(&Entry->InInitializationOrderLinks); 00649 RemoveEntryList(&Entry->InMemoryOrderLinks); 00650 RemoveEntryList(&Entry->HashLinks); 00651 00652 if ( LdrpActiveUnloadCount > 1 ) { 00653 LdrpLoadedDllHandleCache = NULL; 00654 Entry->InMemoryOrderLinks.Flink = NULL; 00655 } 00656 InsertTailList(&LdrpUnloadHead,&Entry->HashLinks); 00657 } 00658 } 00659 // 00660 // End of new code 00661 // 00662 00663 // 00664 // We only do init routine call's and module free's at the top level, 00665 // so if the active count is > 1, just return 00666 // 00667 00668 if (LdrpActiveUnloadCount > 1 ) { 00669 goto leave_finally; 00670 } 00671 00672 // 00673 // Now that the unload list is built, walk through the unload 00674 // list in order and call the init routine. The dll must remain 00675 // on the InLoadOrderLinks so that the pctoheader stuff will 00676 // still work 00677 // 00678 00679 InitializeListHead(&LocalUnloadHead); 00680 Entry = NULL; 00681 Next = LdrpUnloadHead.Flink; 00682 while ( Next != &LdrpUnloadHead ) { 00683 top: 00684 if ( Entry ) { 00685 RemoveEntryList(&(Entry->InLoadOrderLinks)); 00686 Entry = NULL; 00687 Next = LdrpUnloadHead.Flink; 00688 if (Next == &LdrpUnloadHead ) { 00689 goto bottom; 00690 } 00691 } 00692 LdrDataTableEntry 00693 = (PLDR_DATA_TABLE_ENTRY) 00694 (CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,HashLinks)); 00695 00696 // 00697 // Remove dll from the global unload list and place 00698 // on the local unload list. This is because the global list 00699 // can change during the callout to the init routine 00700 // 00701 00702 Entry = LdrDataTableEntry; 00703 LdrpLoadedDllHandleCache = NULL; 00704 Entry->InMemoryOrderLinks.Flink = NULL; 00705 00706 RemoveEntryList(&Entry->HashLinks); 00707 InsertTailList(&LocalUnloadHead,&Entry->HashLinks); 00708 00709 // 00710 // If the function has an init routine, call it. 00711 // 00712 00713 InitRoutine = (PDLL_INIT_ROUTINE)LdrDataTableEntry->EntryPoint; 00714 00715 #if defined (WX86) 00716 if (Wx86ProcessInit) { 00717 try { 00718 LdrpWx86DllProcessDetach(LdrDataTableEntry); 00719 RemoveEntryList(&Entry->InLoadOrderLinks); 00720 Entry = NULL; 00721 Next = LdrpUnloadHead.Flink; 00722 } 00723 except(EXCEPTION_EXECUTE_HANDLER){ 00724 goto top; 00725 } 00726 } 00727 else 00728 #endif 00729 if (InitRoutine && (LdrDataTableEntry->Flags & LDRP_PROCESS_ATTACH_CALLED) ) { 00730 try { 00731 if (ShowSnaps) { 00732 DbgPrint("LDR: Calling deinit %lx\n",InitRoutine); 00733 } 00734 00735 LdrpCallInitRoutine(InitRoutine, 00736 LdrDataTableEntry->DllBase, 00737 DLL_PROCESS_DETACH, 00738 NULL); 00739 00740 RemoveEntryList(&Entry->InLoadOrderLinks); 00741 Entry = NULL; 00742 Next = LdrpUnloadHead.Flink; 00743 } 00744 except(EXCEPTION_EXECUTE_HANDLER){ 00745 goto top; 00746 } 00747 } else { 00748 RemoveEntryList(&(Entry->InLoadOrderLinks)); 00749 Entry = NULL; 00750 Next = LdrpUnloadHead.Flink; 00751 } 00752 } 00753 bottom: 00754 00755 #if defined (WX86) 00756 if (Wx86ProcessInit) { 00757 00758 // 00759 // Notify Wx86 that the modules are about to be unmapped. This 00760 // must be done in a separate pass from the unmap loop, as wx86.dll 00761 // might be in the list of modules to unmap. 00762 // 00763 Next = LocalUnloadHead.Flink; 00764 while ( Next != &LocalUnloadHead ) { 00765 LdrDataTableEntry 00766 = (PLDR_DATA_TABLE_ENTRY) 00767 (CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,HashLinks)); 00768 00769 Next = Next->Flink; 00770 00771 LdrpWx86DllMapNotify(LdrDataTableEntry->DllBase, FALSE); 00772 00773 // Remember if we are unloading a plugin dll 00774 00775 if ((LdrDataTableEntry->DllBase == DllHandle) && 00776 (LdrDataTableEntry->Flags & LDRP_WX86_PLUGIN)) { 00777 Wx86Plugin = DllHandle; 00778 } 00779 } 00780 } 00781 #endif 00782 00783 // 00784 // Now, go through the modules and unmap them 00785 // 00786 00787 Next = LocalUnloadHead.Flink; 00788 while ( Next != &LocalUnloadHead ) { 00789 LdrDataTableEntry 00790 = (PLDR_DATA_TABLE_ENTRY) 00791 (CONTAINING_RECORD(Next,LDR_DATA_TABLE_ENTRY,HashLinks)); 00792 00793 Next = Next->Flink; 00794 Entry = LdrDataTableEntry; 00795 00796 if (ShowSnaps) { 00797 DbgPrint("LDR: Unmapping [%ws]\n", 00798 LdrDataTableEntry->BaseDllName.Buffer 00799 ); 00800 } 00801 st = NtUnmapViewOfSection(NtCurrentProcess(),Entry->DllBase); 00802 ASSERT(NT_SUCCESS(st)); 00803 00804 LdrUnloadAlternateResourceModule(Entry->DllBase); 00805 00806 if (Entry->FullDllName.Buffer) { 00807 RtlFreeUnicodeString(&Entry->FullDllName); 00808 } 00809 if (Entry->BaseDllName.Buffer) { 00810 RtlFreeUnicodeString(&Entry->BaseDllName); 00811 } 00812 00813 if ( Entry == LdrpGetModuleHandleCache ) { 00814 LdrpGetModuleHandleCache = NULL; 00815 } 00816 00817 RtlFreeHeap(Peb->ProcessHeap, 0,Entry); 00818 } 00819 00820 leave_finally:; 00821 } 00822 finally { 00823 LdrpActiveUnloadCount--; 00824 if ( LdrpInLdrInit == FALSE ) { 00825 00826 #if defined (WX86) 00827 if (Wx86ProcessInit && Wx86Plugin) { 00828 Wx86UnloadProviders( Wx86Plugin ); 00829 } 00830 #endif 00831 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00832 } 00833 } 00834 return st; 00835 }

NTSTATUS NTAPI LdrVerifyImageMatchesChecksum IN HANDLE  ImageFileHandle,
IN PLDR_IMPORT_MODULE_CALLBACK ImportCallbackRoutine  OPTIONAL,
IN PVOID  ImportCallbackParameter,
OUT PUSHORT ImageCharacteristics  OPTIONAL
 

Definition at line 1069 of file ldrapi.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, L, LdrVerifyMappedImageMatchesChecksum(), NT_SUCCESS, NtClose(), NtCreateSection(), NtMapViewOfSection(), NtQueryInformationFile(), NTSTATUS(), NtUnmapViewOfSection(), NULL, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlImageRvaToVa(), Status, and TRUE.

01075 { 01076 01077 NTSTATUS Status; 01078 HANDLE Section; 01079 PVOID ViewBase; 01080 SIZE_T ViewSize; 01081 IO_STATUS_BLOCK IoStatusBlock; 01082 FILE_STANDARD_INFORMATION StandardInfo; 01083 PIMAGE_SECTION_HEADER LastRvaSection; 01084 BOOLEAN b; 01085 BOOLEAN JustDoSideEffects; 01086 01087 // 01088 // stevewo added all sorts of side effects to this API. We want to stop 01089 // doing checksums for known dll's, but really want the sideeffects 01090 // (ImageCharacteristics write, and Import descriptor walk). 01091 // 01092 01093 if ( (UINT_PTR) ImageFileHandle & 1 ) { 01094 JustDoSideEffects = TRUE; 01095 } 01096 else { 01097 JustDoSideEffects = FALSE; 01098 } 01099 01100 Status = NtCreateSection( 01101 &Section, 01102 SECTION_MAP_EXECUTE, 01103 NULL, 01104 NULL, 01105 PAGE_EXECUTE, 01106 SEC_COMMIT, 01107 ImageFileHandle 01108 ); 01109 if ( !NT_SUCCESS(Status) ) { 01110 return Status; 01111 } 01112 01113 ViewBase = NULL; 01114 ViewSize = 0; 01115 01116 Status = NtMapViewOfSection( 01117 Section, 01118 NtCurrentProcess(), 01119 (PVOID *)&ViewBase, 01120 0L, 01121 0L, 01122 NULL, 01123 &ViewSize, 01124 ViewShare, 01125 0L, 01126 PAGE_EXECUTE 01127 ); 01128 01129 if ( !NT_SUCCESS(Status) ) { 01130 NtClose(Section); 01131 return Status; 01132 } 01133 01134 // 01135 // now the image is mapped as a data file... Calculate it's size and then 01136 // check it's checksum 01137 // 01138 01139 Status = NtQueryInformationFile( 01140 ImageFileHandle, 01141 &IoStatusBlock, 01142 &StandardInfo, 01143 sizeof(StandardInfo), 01144 FileStandardInformation 01145 ); 01146 01147 if ( !NT_SUCCESS(Status) ) { 01148 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01149 NtClose(Section); 01150 return Status; 01151 } 01152 01153 try { 01154 if ( JustDoSideEffects ) { 01155 b = TRUE; 01156 } 01157 else { 01158 b = LdrVerifyMappedImageMatchesChecksum(ViewBase,StandardInfo.EndOfFile.LowPart); 01159 } 01160 if (b && ARGUMENT_PRESENT( ImportCallbackRoutine )) { 01161 PIMAGE_NT_HEADERS NtHeaders; 01162 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; 01163 ULONG ImportSize; 01164 PCHAR ImportName; 01165 01166 // 01167 // Caller wants to enumerate the import descriptors while we have 01168 // the image mapped. Call back to their routine for each module 01169 // name in the import descriptor table. 01170 // 01171 LastRvaSection = NULL; 01172 NtHeaders = RtlImageNtHeader( ViewBase ); 01173 if (ARGUMENT_PRESENT( ImageCharacteristics )) { 01174 *ImageCharacteristics = NtHeaders->FileHeader.Characteristics; 01175 } 01176 01177 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR) 01178 RtlImageDirectoryEntryToData( ViewBase, 01179 FALSE, 01180 IMAGE_DIRECTORY_ENTRY_IMPORT, 01181 &ImportSize 01182 ); 01183 if (ImportDescriptor != NULL) { 01184 while (ImportDescriptor->Name) { 01185 ImportName = (PSZ)RtlImageRvaToVa( NtHeaders, 01186 ViewBase, 01187 ImportDescriptor->Name, 01188 &LastRvaSection 01189 ); 01190 (*ImportCallbackRoutine)( ImportCallbackParameter, ImportName ); 01191 ImportDescriptor += 1; 01192 } 01193 } 01194 } 01195 } 01196 except (EXCEPTION_EXECUTE_HANDLER) { 01197 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01198 NtClose(Section); 01199 return STATUS_IMAGE_CHECKSUM_MISMATCH; 01200 } 01201 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01202 NtClose(Section); 01203 if ( !b ) { 01204 Status = STATUS_IMAGE_CHECKSUM_MISMATCH; 01205 } 01206 return Status; 01207 }


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