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")));
|
||
}
|
||
|
||
|