220 lines
4.9 KiB
C
220 lines
4.9 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
init.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module performs initialization for the SAC device driver.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Sean Selitrennikoff (v-seans) - Jan 11, 1999
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "sac.h"
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
DriverEntry(
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN PUNICODE_STRING RegistryPath
|
|||
|
);
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text( INIT, DriverEntry )
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
DriverEntry (
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN PUNICODE_STRING RegistryPath
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the initialization routine for the SAC device driver.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DriverObject - Pointer to driver object created by the system.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The function value is the final status from the initialization operation.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
UNICODE_STRING DeviceName;
|
|||
|
CLONG i;
|
|||
|
BOOLEAN Success;
|
|||
|
PDEVICE_OBJECT DeviceObject;
|
|||
|
PSAC_DEVICE_CONTEXT DeviceContext;
|
|||
|
HEADLESS_RSP_QUERY_INFO Response;
|
|||
|
SIZE_T Length;
|
|||
|
|
|||
|
PAGED_CODE( );
|
|||
|
|
|||
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DriverEntry: Entering.\n")));
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If the system is not setup to use a terminal, then just exit now.
|
|||
|
//
|
|||
|
Length = sizeof(HEADLESS_RSP_QUERY_INFO);
|
|||
|
HeadlessDispatch(HeadlessCmdQueryInformation,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
&Response,
|
|||
|
&Length
|
|||
|
);
|
|||
|
|
|||
|
if ((Response.PortType == HeadlessUndefinedPortType) ||
|
|||
|
((Response.PortType == HeadlessSerialPort) && !Response.Serial.TerminalAttached)) {
|
|||
|
return STATUS_PORT_DISCONNECTED;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the device object. (IoCreateDevice zeroes the memory
|
|||
|
// occupied by the object.)
|
|||
|
//
|
|||
|
// An ACL to the device object in InitializeDeviceData().
|
|||
|
//
|
|||
|
|
|||
|
RtlInitUnicodeString(&DeviceName, SAC_DEVICE_NAME);
|
|||
|
|
|||
|
Status = IoCreateDevice(DriverObject, // DriverObject
|
|||
|
sizeof(SAC_DEVICE_CONTEXT), // DeviceExtension
|
|||
|
&DeviceName, // DeviceName
|
|||
|
FILE_DEVICE_NAMED_PIPE, // DeviceType
|
|||
|
0, // DeviceCharacteristics
|
|||
|
FALSE, // Exclusive
|
|||
|
&DeviceObject // DeviceObject
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|||
|
KdPrint(( "SAC DriverEntry: unable to create device object: %X\n", Status )));
|
|||
|
goto ErrorExit;
|
|||
|
}
|
|||
|
|
|||
|
DeviceContext = (PSAC_DEVICE_CONTEXT)DeviceObject->DeviceExtension;
|
|||
|
DeviceContext->InitializedAndReady = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the driver object for this file system driver.
|
|||
|
//
|
|||
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
|
|||
|
DriverObject->MajorFunction[i] = Dispatch;
|
|||
|
}
|
|||
|
//
|
|||
|
// Special case for IRP_MJ_DEVICE_CONTROL since it is
|
|||
|
// the most often used function in SAC.
|
|||
|
//
|
|||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
|
|||
|
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl;
|
|||
|
DriverObject->FastIoDispatch = NULL;
|
|||
|
DriverObject->DriverUnload = UnloadHandler;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize global data.
|
|||
|
//
|
|||
|
Success = InitializeGlobalData(RegistryPath, DriverObject);
|
|||
|
if (!Success) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto ErrorExit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize our device object.
|
|||
|
//
|
|||
|
Success = InitializeDeviceData(DeviceObject);
|
|||
|
if (!Success) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto ErrorExit;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Register that we want shutdown notification. If this fails, no big deal, as
|
|||
|
// we only lose telling the user of this development.
|
|||
|
//
|
|||
|
IoRegisterShutdownNotification(DeviceObject);
|
|||
|
|
|||
|
return (Status);
|
|||
|
|
|||
|
ErrorExit:
|
|||
|
|
|||
|
FreeGlobalData();
|
|||
|
|
|||
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DriverEntry: Exiting with status 0x%x\n", Status)));
|
|||
|
|
|||
|
return Status;
|
|||
|
|
|||
|
} // DriverEntry
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
UnloadHandler(
|
|||
|
IN PDRIVER_OBJECT DriverObject
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the routine for handling unloading of the driver.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DriverObject - Pointer to driver object created by the system.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PDEVICE_OBJECT DeviceContext;
|
|||
|
PDEVICE_OBJECT NextDeviceContext;
|
|||
|
|
|||
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC UnloadHandler: Entering.\n")));
|
|||
|
|
|||
|
//
|
|||
|
// Walk down each device, disconnecting it and freeing it.
|
|||
|
//
|
|||
|
DeviceContext = DriverObject->DeviceObject;
|
|||
|
|
|||
|
while (DeviceContext != NULL) {
|
|||
|
|
|||
|
NextDeviceContext = (PDEVICE_OBJECT)DeviceContext->NextDevice;
|
|||
|
|
|||
|
FreeDeviceData(DeviceContext);
|
|||
|
|
|||
|
IoDeleteDevice(DeviceContext);
|
|||
|
|
|||
|
DeviceContext = NextDeviceContext;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Free global data
|
|||
|
//
|
|||
|
FreeGlobalData();
|
|||
|
|
|||
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC UnloadHandler: Exiting.\n")));
|
|||
|
}
|
|||
|
|
|||
|
|