|
|
/*++
Copyright (c) 1999-2001 Microsoft Corporation. All Rights Reserved.
Module Name:
device.c
Abstract:
Author:
Joseph Ballantyne
Environment:
Kernel Mode
Revision History:
--*/
#define IRPMJFUNCDESC
#define WANTVXDWRAPS
#include "common.h"
#include "rtp.h"
#include "log.h"
#ifndef UNDER_NT
ULONG RT_Init_VxD(VOID);
#define STR_DEVICENAME TEXT(L"\\Device\\Rt")
#define STR_REGISTRY TEXT(L"\\REGISTRY\\Machine\\Software\\Microsoft\\RealTime")
#define STR_RTDISABLE TEXT(L"DisableRtExecutive")
#else
//#define OFFBYDEFAULT 1
#define STR_DEVICENAME TEXT("\\Device\\Rt")
#define STR_REGISTRY TEXT("\\REGISTRY\\Machine\\Software\\Microsoft\\RealTime")
#define STR_RTDISABLE TEXT("DisableRtExecutive")
#ifdef OFFBYDEFAULT
#define STR_RTENABLE TEXT("EnableRtExecutive")
#endif
#endif
#define RT_LOG_SIZE 32 // This MUST be a power of 2.
#ifdef OFFBYDEFAULT
DWORD RtEnable=0; #endif
DWORD RtDisable=0;
LONG RtInitialized=0;
PDEVICE_OBJECT pdo=NULL;
PRTLOGHEADER RtLog=NULL;
VOID DriverUnload ( IN PDRIVER_OBJECT DriverObject ) {
Break();
}
NTSTATUS RtpInitialize ( VOID )
{
RTL_QUERY_REGISTRY_TABLE QueryTable[] = { { NULL, // No callback routine
RTL_QUERY_REGISTRY_DIRECT, NULL, &RtDisable, REG_DWORD, &RtDisable, sizeof(RtDisable) },
#ifdef OFFBYDEFAULT
{ NULL, // No callback routine
RTL_QUERY_REGISTRY_DIRECT, NULL, &RtEnable, REG_DWORD, &RtEnable, sizeof(RtEnable) }, #endif
{ NULL, // Null entry
0, NULL, NULL, 0, NULL, 0 } }; UNICODE_STRING usRegistry; UNICODE_STRING usRtDisable; #ifdef OFFBYDEFAULT
UNICODE_STRING usRtEnable; #endif
#ifdef UNDER_NT
PHYSICAL_ADDRESS Physical; #endif
ULONG i;
//Break();
// Prepare to query the registry
RtlInitUnicodeString( &usRegistry, STR_REGISTRY ); RtlInitUnicodeString( &usRtDisable, STR_RTDISABLE ); #ifdef OFFBYDEFAULT
RtlInitUnicodeString( &usRtEnable, STR_RTENABLE ); #endif
QueryTable[0].Name = usRtDisable.Buffer; #ifdef OFFBYDEFAULT
QueryTable[1].Name = usRtEnable.Buffer; #endif
// Query registry to see if we should allow RT to run.
RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, usRegistry.Buffer, &(QueryTable[0]), NULL, NULL );
// Now setup the realtime logging buffer.
#ifdef UNDER_NT
Physical.QuadPart=-1I64; RtLog=(PRTLOGHEADER)MmAllocateContiguousMemory(PAGE_SIZE*(RT_LOG_SIZE+1), Physical); #else
RtLog=(PRTLOGHEADER)ExAllocatePool(NonPagedPool, PAGE_SIZE*(RT_LOG_SIZE+1)); #endif
// Failing to allocate the RtLog is not fatal. If we get it, set it up.
if (RtLog) {
RtLog->Buffer=(PCHAR)RtLog+PAGE_SIZE;
// The output or print buffersize MUST be a power of 2. This is because the read and write
// locations increment constantly and DO NOT WRAP with the buffer size. That is intentional
// because it makes checking whether there is data in the buffer or not very simple and atomic.
// However, the read and write locations will wrap on 32 bit boundaries. This is OK as long as
// our buffersize divides into 2^32 evenly, which it always will if it is a power of 2.
RtLog->BufferSize=PAGE_SIZE*RT_LOG_SIZE;
RtLog->WriteLocation=0;
// Mark every slot in the output buffer empty.
for (i=0; i<RtLog->BufferSize; i+=RT_LOG_ENTRY_SIZE) { ((ULONG *)RtLog->Buffer)[i/sizeof(ULONG)]=NODATA; }
}
#ifdef OFFBYDEFAULT
if (RtEnable) { #endif
// Initialize if RT not disabled and we have not already initialized.
if (!RtDisable && InterlockedIncrement(&RtInitialized)==1) {
#ifndef UNDER_NT
RT_Init_VxD(); #endif
SetupRealTimeThreads();
}
#ifdef OFFBYDEFAULT
} #endif
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING usRegistryPathName ) {
//dprintf(("DriverEntry Enter (DriverObject = %x)", DriverObject));
DriverObject->DriverUnload = DriverUnload;
// For now, keep RT loaded always.
ObReferenceObject(DriverObject);
#if 0
// We will need to create a device in order to be able to pull
// RT statistics down into user mode.
{
UNICODE_STRING usDeviceName;
RtlInitUnicodeString( &usDeviceName, STR_DEVICENAME );
IoCreateDevice(DriverObject,0,&usDeviceName,0,0,FALSE,&pdo);
}
#endif
return RtpInitialize();
}
NTSTATUS DllInitialize ( IN PUNICODE_STRING RegistryPath ) {
#ifdef UNDER_NT
// On NT, we do NOT load until someone linked to us loads. That way
// unless we are needed, we stay out of the way.
return RtpInitialize();
#else
// On Win9x because Rt hooks the IDT, it MUST be loaded at boot time.
// This code is here to catch if we ever get loaded as a DLL which will only
// happen if we did NOT get properly loaded at boot time.
// In debug on Win9x, make SURE our failure to load properly at boot is noticed.
#if DEBUG
KeBugCheckEx(0x1baddeed,0,0,0,0);
#endif // DEBUG
// In retail on Win9x be as nice as possible. None of our API's will succeed,
// but we let people that are linked to us load without failing.
return STATUS_SUCCESS;
#endif // UNDER_NT
}
|