mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
5.5 KiB
309 lines
5.5 KiB
|
|
/*++
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|