Author: ion Date: Mon Mar 5 22:24:54 2007 New Revision: 26006
URL: http://svn.reactos.org/svn/reactos?rev=26006&view=rev Log: - 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.
Modified: trunk/reactos/drivers/base/kdcom/kdbg.c trunk/reactos/drivers/base/serial/pnp.c trunk/reactos/include/ndk/haltypes.h trunk/reactos/ntoskrnl/mm/sysldr.c
Modified: trunk/reactos/drivers/base/kdcom/kdbg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdcom/kdbg.c?r... ============================================================================== --- trunk/reactos/drivers/base/kdcom/kdbg.c (original) +++ trunk/reactos/drivers/base/kdcom/kdbg.c Mon Mar 5 22:24:54 2007 @@ -78,10 +78,6 @@
/* GLOBAL VARIABLES *********************************************************/ -#define KdComPortInUse _KdComPortInUse - -ULONG KdComPortInUse = 0; -
/* STATIC VARIABLES *********************************************************/
@@ -272,7 +268,7 @@ /* * set global info */ - KdComPortInUse = (ULONG)PortBase; + *KdComPortInUse = PortBase;
/* * print message to blue screen
Modified: trunk/reactos/drivers/base/serial/pnp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/serial/pnp.c?r... ============================================================================== --- trunk/reactos/drivers/base/serial/pnp.c (original) +++ trunk/reactos/drivers/base/serial/pnp.c Mon Mar 5 22:24:54 2007 @@ -219,7 +219,8 @@ ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
/* 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"); return STATUS_INSUFFICIENT_RESOURCES;
Modified: trunk/reactos/include/ndk/haltypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/haltypes.h?rev=... ============================================================================== --- trunk/reactos/include/ndk/haltypes.h (original) +++ trunk/reactos/include/ndk/haltypes.h Mon Mar 5 22:24:54 2007 @@ -224,10 +224,10 @@ // HAL Exports // #ifndef _NTHAL_ -extern PUCHAR NTSYSAPI *KdComPortInUse; -#endif - -#endif -#endif - - +extern PUCHAR *KdComPortInUse; +#endif + +#endif +#endif + +
Modified: trunk/reactos/ntoskrnl/mm/sysldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/sysldr.c?rev=26... ============================================================================== --- trunk/reactos/ntoskrnl/mm/sysldr.c (original) +++ trunk/reactos/ntoskrnl/mm/sysldr.c Mon Mar 5 22:24:54 2007 @@ -12,6 +12,19 @@ #define NDEBUG #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 *******************************************************************/
LIST_ENTRY PsLoadedModuleList; @@ -21,6 +34,33 @@ extern ULONG NtGlobalFlag;
/* 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 NTAPI @@ -729,7 +769,7 @@ PCHAR MissingApiBuffer = *MissingApi, ImportName; PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport; ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize; - PLOAD_IMPORTS LoadedImports; + PLOAD_IMPORTS LoadedImports, NewImports; ULONG GdiLink, NormalLink, i; BOOLEAN ReferenceNeeded, Loaded; ANSI_STRING TempString; @@ -1056,9 +1096,32 @@ } else if (ImportCount != LoadedImports->Count) { - /* FIXME: Can this happen? */ - DPRINT1("Unhandled scenario\n"); - while (TRUE); + /* Allocate a new list */ + LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T); + 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 */ @@ -1400,9 +1463,9 @@ OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; PIMAGE_NT_HEADERS NtHeader; - UNICODE_STRING BaseName, BaseDirectory, PrefixName; + UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp; PLDR_DATA_TABLE_ENTRY LdrEntry = NULL; - ULONG EntrySize; + ULONG EntrySize, DriverSize; PLOAD_IMPORTS LoadedImports = (PVOID)-2; PCHAR MissingApiName, Buffer; PWCHAR MissingDriverName; @@ -1411,6 +1474,8 @@ PVOID Section = NULL; BOOLEAN LockOwned = FALSE; PLIST_ENTRY NextEntry; + IMAGE_INFO ImageInfo; + ANSI_STRING AnsiTemp; PAGED_CODE();
/* Detect session-load */ @@ -1637,6 +1702,23 @@ NULL); 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 */ NtHeader = RtlImageNtHeader(ModuleLoadBase);
@@ -1681,7 +1763,7 @@ LdrEntry->DllBase = ModuleLoadBase; LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase + NtHeader->OptionalHeader.AddressOfEntryPoint); - LdrEntry->SizeOfImage = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageSize; + LdrEntry->SizeOfImage = DriverSize; LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum; LdrEntry->SectionPointer = LdrEntry;
@@ -1749,6 +1831,66 @@ 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 (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;