- Fixed up KdComPortInUse so that we don't crash when using TinyKRNL/Windows kdcom.dll anymore (due to serial.sys). WinDBG should work a lot better now.

- Implemented hack so that NT-style sprintf can work.
- Implement MiCacheImageSymbols and upgrade MmLoadSystemImage to load symbols for drivers/images which have a debug section.
- Implemented a case in MiResolveImageReferences which was getting hit.
- Don't leak a section object reference each time we load a driver.
- Set the LoadedImports pointer in the loader entry, and set the proper flags after loading a driver.
- Do image notifications after loading a driver, if they're enabled.

svn path=/trunk/; revision=26006
This commit is contained in:
Alex Ionescu 2007-03-05 19:24:54 +00:00
parent 47dae7de28
commit 4b3c677fe7
4 changed files with 153 additions and 14 deletions

View file

@ -78,10 +78,6 @@ typedef struct _KD_PORT_INFORMATION
/* GLOBAL VARIABLES *********************************************************/ /* GLOBAL VARIABLES *********************************************************/
#define KdComPortInUse _KdComPortInUse
ULONG KdComPortInUse = 0;
/* STATIC VARIABLES *********************************************************/ /* STATIC VARIABLES *********************************************************/
@ -272,7 +268,7 @@ KdPortInitialize (
/* /*
* set global info * set global info
*/ */
KdComPortInUse = (ULONG)PortBase; *KdComPortInUse = PortBase;
/* /*
* print message to blue screen * print message to blue screen

View file

@ -219,7 +219,8 @@ SerialPnpStartDevice(
ComPortBase = (PUCHAR)DeviceExtension->BaseAddress; ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
/* Test if we are trying to start the serial port used for debugging */ /* Test if we are trying to start the serial port used for debugging */
if (KdComPortInUse && *KdComPortInUse == ULongToPtr(DeviceExtension->BaseAddress)) DPRINT1("KdComPort: %p\n", KdComPortInUse);
if (KdComPortInUse == ULongToPtr(DeviceExtension->BaseAddress))
{ {
DPRINT("Failing IRP_MN_START_DEVICE as this serial port is used for debugging\n"); DPRINT("Failing IRP_MN_START_DEVICE as this serial port is used for debugging\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;

View file

@ -224,7 +224,7 @@ extern NTSYSAPI HAL_PRIVATE_DISPATCH HalPrivateDispatchTable;
// HAL Exports // HAL Exports
// //
#ifndef _NTHAL_ #ifndef _NTHAL_
extern PUCHAR NTSYSAPI *KdComPortInUse; extern PUCHAR *KdComPortInUse;
#endif #endif
#endif #endif

View file

@ -12,6 +12,19 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* GCC's incompetence strikes again */
FORCEINLINE
VOID
sprintf_nt(IN PCHAR Buffer,
IN PCHAR Format,
IN ...)
{
va_list ap;
va_start(ap, Format);
sprintf(Buffer, Format, ap);
va_end(ap);
}
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
LIST_ENTRY PsLoadedModuleList; LIST_ENTRY PsLoadedModuleList;
@ -22,6 +35,33 @@ extern ULONG NtGlobalFlag;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
PVOID
NTAPI
MiCacheImageSymbols(IN PVOID BaseAddress)
{
ULONG DebugSize;
PVOID DebugDirectory = NULL;
PAGED_CODE();
/* Make sure it's safe to access the image */
_SEH_TRY
{
/* Get the debug directory */
DebugDirectory = RtlImageDirectoryEntryToData(BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_DEBUG,
&DebugSize);
}
_SEH_HANDLE
{
/* Nothing */
}
_SEH_END;
/* Return the directory */
return DebugDirectory;
}
VOID VOID
NTAPI NTAPI
MiFreeBootDriverMemory(PVOID BaseAddress, MiFreeBootDriverMemory(PVOID BaseAddress,
@ -729,7 +769,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
PCHAR MissingApiBuffer = *MissingApi, ImportName; PCHAR MissingApiBuffer = *MissingApi, ImportName;
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport; PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize; ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
PLOAD_IMPORTS LoadedImports; PLOAD_IMPORTS LoadedImports, NewImports;
ULONG GdiLink, NormalLink, i; ULONG GdiLink, NormalLink, i;
BOOLEAN ReferenceNeeded, Loaded; BOOLEAN ReferenceNeeded, Loaded;
ANSI_STRING TempString; ANSI_STRING TempString;
@ -1056,9 +1096,32 @@ CheckDllState:
} }
else if (ImportCount != LoadedImports->Count) else if (ImportCount != LoadedImports->Count)
{ {
/* FIXME: Can this happen? */ /* Allocate a new list */
DPRINT1("Unhandled scenario\n"); LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
while (TRUE); NewImports = ExAllocatePoolWithTag(PagedPool,
LoadedImportsSize,
TAG_LDR_WSTR);
if (NewImports)
{
/* Set count */
NewImports->Count = ImportCount;
/* Loop all the imports */
for (i = 0, ImportCount = 0; i < LoadedImports->Count; i++)
{
/* Make sure it's valid */
if (LoadedImports->Entry[i])
{
/* Copy it */
NewImports->Entry[i] = LoadedImports->Entry[i];
ImportCount++;
}
}
/* Free the old copy */
ExFreePool(LoadedImports);
LoadedImports = NewImports;
}
} }
/* Return the list */ /* Return the list */
@ -1400,9 +1463,9 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PIMAGE_NT_HEADERS NtHeader; PIMAGE_NT_HEADERS NtHeader;
UNICODE_STRING BaseName, BaseDirectory, PrefixName; UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;
PLDR_DATA_TABLE_ENTRY LdrEntry = NULL; PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
ULONG EntrySize; ULONG EntrySize, DriverSize;
PLOAD_IMPORTS LoadedImports = (PVOID)-2; PLOAD_IMPORTS LoadedImports = (PVOID)-2;
PCHAR MissingApiName, Buffer; PCHAR MissingApiName, Buffer;
PWCHAR MissingDriverName; PWCHAR MissingDriverName;
@ -1411,6 +1474,8 @@ MmLoadSystemImage(IN PUNICODE_STRING FileName,
PVOID Section = NULL; PVOID Section = NULL;
BOOLEAN LockOwned = FALSE; BOOLEAN LockOwned = FALSE;
PLIST_ENTRY NextEntry; PLIST_ENTRY NextEntry;
IMAGE_INFO ImageInfo;
ANSI_STRING AnsiTemp;
PAGED_CODE(); PAGED_CODE();
/* Detect session-load */ /* Detect session-load */
@ -1637,6 +1702,23 @@ LoaderScan:
NULL); NULL);
ASSERT(Status != STATUS_ALREADY_COMMITTED); ASSERT(Status != STATUS_ALREADY_COMMITTED);
/* Get the size of the driver */
DriverSize = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageSize;
/* Make sure we're not being loaded into session space */
if (!Flags)
{
/* Check for success */
if (NT_SUCCESS(Status))
{
/* FIXME: Support large pages for drivers */
}
/* Dereference the section */
ObDereferenceObject(Section);
Section = NULL;
}
/* Get the NT Header */ /* Get the NT Header */
NtHeader = RtlImageNtHeader(ModuleLoadBase); NtHeader = RtlImageNtHeader(ModuleLoadBase);
@ -1681,7 +1763,7 @@ LoaderScan:
LdrEntry->DllBase = ModuleLoadBase; LdrEntry->DllBase = ModuleLoadBase;
LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase + LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
NtHeader->OptionalHeader.AddressOfEntryPoint); NtHeader->OptionalHeader.AddressOfEntryPoint);
LdrEntry->SizeOfImage = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageSize; LdrEntry->SizeOfImage = DriverSize;
LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum; LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
LdrEntry->SectionPointer = LdrEntry; LdrEntry->SectionPointer = LdrEntry;
@ -1749,6 +1831,66 @@ LoaderScan:
goto Quickie; goto Quickie;
} }
/* Update the loader entry */
LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
LDRP_ENTRY_PROCESSED |
LDRP_MM_LOADED);
LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
LdrEntry->LoadedImports = LoadedImports;
/* FIXME: Apply driver verifier */
/* FIXME: Write-protect the system image */
/* Check if notifications are enabled */
if (PsImageNotifyEnabled)
{
/* Fill out the notification data */
ImageInfo.Properties = 0;
ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
ImageInfo.SystemModeImage = TRUE;
ImageInfo.ImageSize = LdrEntry->SizeOfImage;
ImageInfo.ImageBase = LdrEntry->DllBase;
ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
/* Send the notification */
PspRunLoadImageNotifyRoutines(FileName, NULL, &ImageInfo);
}
/* Check if there's symbols */
if (MiCacheImageSymbols(LdrEntry->DllBase))
{
/* Check if the system root is present */
if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
!(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
{
/* Add the system root */
UnicodeTemp = PrefixName;
UnicodeTemp.Buffer += 11;
UnicodeTemp.Length -= (11 * sizeof(WCHAR));
sprintf_nt(Buffer,
"%ws%wZ",
&SharedUserData->NtSystemRoot[2],
&UnicodeTemp);
}
else
{
/* Build the name */
sprintf_nt(Buffer, "%wZ", &BaseName);
}
/* Setup the ansi string */
RtlInitString(&AnsiTemp, Buffer);
/* Notify the debugger */
DbgLoadImageSymbols(&AnsiTemp, LdrEntry->DllBase, -1);
LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
}
/* FIXME: Page the driver */
ASSERT(Section == NULL);
/* Return pointers */
if (ModuleObject) *ModuleObject = LdrEntry; if (ModuleObject) *ModuleObject = LdrEntry;
if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase; if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;