windows-nt/Source/XPSP1/NT/drivers/wdm/rt/exec/device.c
2020-09-26 16:20:57 +08:00

310 lines
5.5 KiB
C

/*++
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
}