?? class.c
字號:
/*++
Copyright (C) Microsoft Corporation, 1991 - 1999
Module Name:
class.c
Abstract:
SCSI class driver routines
Environment:
kernel mode only
Notes:
Revision History:
--*/
#define CLASS_INIT_GUID 1
#include "classp.h"
#include "debug.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, ClassAddDevice)
#pragma alloc_text(PAGE, ClassClaimDevice)
#pragma alloc_text(PAGE, ClassCreateDeviceObject)
#pragma alloc_text(PAGE, ClassDispatchPnp)
#pragma alloc_text(PAGE, ClassGetDescriptor)
#pragma alloc_text(PAGE, ClassGetPdoId)
#pragma alloc_text(PAGE, ClassInitialize)
#pragma alloc_text(PAGE, ClassInitializeEx)
#pragma alloc_text(PAGE, ClassInvalidateBusRelations)
#pragma alloc_text(PAGE, ClassMarkChildMissing)
#pragma alloc_text(PAGE, ClassMarkChildrenMissing)
#pragma alloc_text(PAGE, ClassModeSense)
#pragma alloc_text(PAGE, ClassPnpQueryFdoRelations)
#pragma alloc_text(PAGE, ClassPnpStartDevice)
#pragma alloc_text(PAGE, ClassQueryPnpCapabilities)
#pragma alloc_text(PAGE, ClassQueryTimeOutRegistryValue)
#pragma alloc_text(PAGE, ClassRemoveDevice)
#pragma alloc_text(PAGE, ClassRetrieveDeviceRelations)
#pragma alloc_text(PAGE, ClassUpdateInformationInRegistry)
#pragma alloc_text(PAGE, ClassSendDeviceIoControlSynchronous)
#pragma alloc_text(PAGE, ClassUnload)
#pragma alloc_text(PAGE, ClasspAllocateReleaseRequest)
#pragma alloc_text(PAGE, ClasspFreeReleaseRequest)
#pragma alloc_text(PAGE, ClasspInitializeHotplugInfo)
#pragma alloc_text(PAGE, ClasspRegisterMountedDeviceInterface)
#pragma alloc_text(PAGE, ClasspScanForClassHacks)
#pragma alloc_text(PAGE, ClasspScanForSpecialInRegistry)
#endif
ULONG ClassPnpAllowUnload = TRUE;
ULONG ClassMaxInterleavePerCriticalIo = CLASS_MAX_INTERLEAVE_PER_CRITICAL_IO;
CONST LARGE_INTEGER Magic10000 = {0xe219652c, 0xd1b71758};
#define FirstDriveLetter 'C'
#define LastDriveLetter 'Z'
/*++////////////////////////////////////////////////////////////////////////////
DriverEntry()
Routine Description:
Temporary entry point needed to initialize the class system dll.
It doesn't do anything.
Arguments:
DriverObject - Pointer to the driver object created by the system.
Return Value:
STATUS_SUCCESS
--*/
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
return STATUS_SUCCESS;
}
/*++////////////////////////////////////////////////////////////////////////////
ClassInitialize()
Routine Description:
This routine is called by a class driver during its
DriverEntry routine to initialize the driver.
Arguments:
Argument1 - Driver Object.
Argument2 - Registry Path.
InitializationData - Device-specific driver's initialization data.
Return Value:
A valid return code for a DriverEntry routine.
--*/
ULONG
ClassInitialize(
IN PVOID Argument1,
IN PVOID Argument2,
IN PCLASS_INIT_DATA InitializationData
)
{
PDRIVER_OBJECT DriverObject = Argument1;
PUNICODE_STRING RegistryPath = Argument2;
PCLASS_DRIVER_EXTENSION driverExtension;
NTSTATUS status;
PAGED_CODE();
DebugPrint((3,"\n\nSCSI Class Driver\n"));
ClasspInitializeDebugGlobals();
//
// Validate the length of this structure. This is effectively a
// version check.
//
if (InitializationData->InitializationDataSize != sizeof(CLASS_INIT_DATA)) {
//
// This DebugPrint is to help third-party driver writers
//
DebugPrint((0,"ClassInitialize: Class driver wrong version\n"));
return (ULONG) STATUS_REVISION_MISMATCH;
}
//
// Check that each required entry is not NULL. Note that Shutdown, Flush and Error
// are not required entry points.
//
if ((!InitializationData->FdoData.ClassDeviceControl) ||
(!((InitializationData->FdoData.ClassReadWriteVerification) ||
(InitializationData->ClassStartIo))) ||
(!InitializationData->ClassAddDevice) ||
(!InitializationData->FdoData.ClassStartDevice)) {
//
// This DebugPrint is to help third-party driver writers
//
DebugPrint((0,
"ClassInitialize: Class device-specific driver missing required "
"FDO entry\n"));
return (ULONG) STATUS_REVISION_MISMATCH;
}
if ((InitializationData->ClassEnumerateDevice) &&
((!InitializationData->PdoData.ClassDeviceControl) ||
(!InitializationData->PdoData.ClassStartDevice) ||
(!((InitializationData->PdoData.ClassReadWriteVerification) ||
(InitializationData->ClassStartIo))))) {
//
// This DebugPrint is to help third-party driver writers
//
DebugPrint((0, "ClassInitialize: Class device-specific missing "
"required PDO entry\n"));
return (ULONG) STATUS_REVISION_MISMATCH;
}
if((InitializationData->FdoData.ClassStopDevice == NULL) ||
((InitializationData->ClassEnumerateDevice != NULL) &&
(InitializationData->PdoData.ClassStopDevice == NULL))) {
//
// This DebugPrint is to help third-party driver writers
//
DebugPrint((0, "ClassInitialize: Class device-specific missing "
"required PDO entry\n"));
ASSERT(FALSE);
return (ULONG) STATUS_REVISION_MISMATCH;
}
//
// Setup the default power handlers if the class driver didn't provide
// any.
//
if(InitializationData->FdoData.ClassPowerDevice == NULL) {
InitializationData->FdoData.ClassPowerDevice = ClassMinimalPowerHandler;
}
if((InitializationData->ClassEnumerateDevice != NULL) &&
(InitializationData->PdoData.ClassPowerDevice == NULL)) {
InitializationData->PdoData.ClassPowerDevice = ClassMinimalPowerHandler;
}
//
// warn that unload is not supported
//
// ISSUE-2000/02/03-peterwie
// We should think about making this a fatal error.
//
if(InitializationData->ClassUnload == NULL) {
//
// This DebugPrint is to help third-party driver writers
//
DebugPrint((0, "ClassInitialize: driver does not support unload %wZ\n",
RegistryPath));
}
//
// Create an extension for the driver object
//
status = IoAllocateDriverObjectExtension(DriverObject,
CLASS_DRIVER_EXTENSION_KEY,
sizeof(CLASS_DRIVER_EXTENSION),
&driverExtension);
if(NT_SUCCESS(status)) {
//
// Copy the registry path into the driver extension so we can use it later
//
driverExtension->RegistryPath.Length = RegistryPath->Length;
driverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
driverExtension->RegistryPath.Buffer =
ExAllocatePoolWithTag(PagedPool,
RegistryPath->MaximumLength,
'1CcS');
if(driverExtension->RegistryPath.Buffer == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
RtlCopyUnicodeString(
&(driverExtension->RegistryPath),
RegistryPath);
//
// Copy the initialization data into the driver extension so we can reuse
// it during our add device routine
//
RtlCopyMemory(
&(driverExtension->InitData),
InitializationData,
sizeof(CLASS_INIT_DATA));
driverExtension->DeviceCount = 0;
} else if (status == STATUS_OBJECT_NAME_COLLISION) {
//
// The extension already exists - get a pointer to it
//
driverExtension = IoGetDriverObjectExtension(DriverObject,
CLASS_DRIVER_EXTENSION_KEY);
ASSERT(driverExtension != NULL);
} else {
DebugPrint((1, "ClassInitialize: Class driver extension could not be "
"allocated %lx\n", status));
return status;
}
//
// Update driver object with entry points.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = ClassCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ClassCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = ClassReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = ClassReadWrite;
DriverObject->MajorFunction[IRP_MJ_SCSI] = ClassInternalIoControl;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ClassDeviceControlDispatch;
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ClassShutdownFlush;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ClassShutdownFlush;
DriverObject->MajorFunction[IRP_MJ_PNP] = ClassDispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = ClassDispatchPower;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = ClassSystemControl;
if (InitializationData->ClassStartIo) {
DriverObject->DriverStartIo = ClasspStartIo;
}
if ((InitializationData->ClassUnload) && (ClassPnpAllowUnload == TRUE)) {
DriverObject->DriverUnload = ClassUnload;
} else {
DriverObject->DriverUnload = NULL;
}
DriverObject->DriverExtension->AddDevice = ClassAddDevice;
status = STATUS_SUCCESS;
return status;
} // end ClassInitialize()
/*++////////////////////////////////////////////////////////////////////////////
ClassInitializeEx()
Routine Description:
This routine is allows the caller to do any extra initialization or
setup that is not done in ClassInitialize. The operation is
controlled by the GUID that is passed and the contents of the Data
parameter is dependent upon the GUID.
This is the list of supported operations:
Guid - GUID_CLASSPNP_QUERY_REGINFOEX
Data - A PCLASS_QUERY_WMI_REGINFO_EX callback function pointer
Initialized classpnp to callback a PCLASS_QUERY_WMI_REGINFO_EX
callback instead of a PCLASS_QUERY_WMI_REGINFO callback. The
former callback allows the driver to specify the name of the
mof resource.
Arguments:
DriverObject
Guid
Data
Return Value:
Status Code
--*/
ULONG
ClassInitializeEx(
IN PDRIVER_OBJECT DriverObject,
IN LPGUID Guid,
IN PVOID Data
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -