#include "precomp.h" // Precompiled header /**************************************************************************************** * * * Module: SPX_INIT.C * * * * Creation: 27th September 1998 * * * * Author: Paul Smith * * * * Version: 1.0.0 * * * * Description: This module contains the code that load the driver. * * * ****************************************************************************************/ #define FILE_ID SPX_INIT_C // File ID for Event Logging see SPX_DEFS.H for values. // Function Prototypes NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); // End function prototypes. // Paging.. #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, DriverUnload) #endif // Gloabal Driver Data UNICODE_STRING SavedRegistryPath; #if DBG ULONG SpxDebugLevel = 0; // Debug level for checked build #endif ////////////////////////////////////////////////////////////////////////////////////////// // DriverEntry - Load first and initialises entry points. // ////////////////////////////////////////////////////////////////////////////////////////// /* Routine Description: The entry point that the system point calls to initialize any driver. Arguments: DriverObject - Just what it says, really of little use to the driver itself, it is something that the IO system cares more about. RegistryPath - points to the entry for this driver in the current control set of the registry. Return Value: STATUS_SUCCESS */ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { // Holds status information return by various OS and driver initialization routines. NTSTATUS status; // We use this to query into the registry as to whether we should break at driver entry. RTL_QUERY_REGISTRY_TABLE paramTable[3]; ULONG zero = 0; ULONG debugLevel = 0; ULONG shouldBreak = 0; PWCHAR path = NULL; PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL #if DBG DbgPrint( "%s: In DriverEntry\n", PRODUCT_NAME); #endif // Store Registry Path SavedRegistryPath.MaximumLength = RegistryPath->MaximumLength; SavedRegistryPath.Length = RegistryPath->Length; SavedRegistryPath.Buffer = SpxAllocateMem(PagedPool, SavedRegistryPath.MaximumLength); if(SavedRegistryPath.Buffer) { RtlMoveMemory(SavedRegistryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length); RtlZeroMemory(¶mTable[0], sizeof(paramTable)); paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; paramTable[0].Name = L"BreakOnEntry"; paramTable[0].EntryContext = &shouldBreak; paramTable[0].DefaultType = REG_DWORD; paramTable[0].DefaultData = &zero; paramTable[0].DefaultLength = sizeof(ULONG); paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; paramTable[1].Name = L"DebugLevel"; paramTable[1].EntryContext = &debugLevel; paramTable[1].DefaultType = REG_DWORD; paramTable[1].DefaultData = &zero; paramTable[1].DefaultLength = sizeof(ULONG); if(!SPX_SUCCESS(status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, RegistryPath->Buffer, ¶mTable[0], NULL, NULL))) { shouldBreak = 0; debugLevel = 0; } } else status = STATUS_INSUFFICIENT_RESOURCES; #if DBG SpxDebugLevel = debugLevel; // SpxDebugLevel = (ULONG)-1; // Prints all debug messages // shouldBreak = 1; // HARD CODED BREAKPOINT WITH CHECKED BUILD !!! #endif if(shouldBreak) { DbgBreakPoint(); // Break Debugger. } if(SPX_SUCCESS(status)) { // Initialize the Driver Object with driver's entry points DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = Spx_AddDevice; DriverObject->MajorFunction[IRP_MJ_PNP] = Spx_DispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = Spx_DispatchPower; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Spx_Flush; DriverObject->MajorFunction[IRP_MJ_WRITE] = Spx_Write; DriverObject->MajorFunction[IRP_MJ_READ] = Spx_Read; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Spx_IoControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = Spx_InternalIoControl; DriverObject->MajorFunction[IRP_MJ_CREATE] = Spx_CreateOpen; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Spx_Close; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Spx_Cleanup; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = Spx_QueryInformationFile; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Spx_SetInformationFile; #ifdef WMI_SUPPORT DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Spx_DispatchSystemControl; #endif } else { // Free if(SavedRegistryPath.Buffer) { SpxFreeMem(SavedRegistryPath.Buffer); SavedRegistryPath.Buffer = NULL; } } return(status); } // DriverEntry ////////////////////////////////////////////////////////////////////////////////////////// // DriverUnload - Called as driver unloads. ////////////////////////////////////////////////////////////////////////////////////////// VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) /*++ Routine Description: This routine cleans up all of the resources allocated in DriverEntry. Arguments: pDriverObject - Pointer to the driver object controling all of the devices. Return Value: None. --*/ { PAGED_CODE(); SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering DriverUnload\n", PRODUCT_NAME)); // All Device Objects must have been deleted by now. ASSERT (pDriverObject->DeviceObject == NULL); // Free if(SavedRegistryPath.Buffer) { SpxFreeMem(SavedRegistryPath.Buffer); SavedRegistryPath.Buffer = NULL; } return; } // End of SPX_INIT.C