|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
dispatch.c
Abstract:
This module contains the dispatch routines for SAC.
Author:
Sean Selitrennikoff (v-seans) - Jan 13, 1999 Brian Guarraci (briangu), 2001
Revision History:
--*/
#include <initguid.h>
#include "sac.h"
DEFINE_GUID(SAC_CMD_CHANNEL_APPLICATION_GUID, 0x63d02271, 0x8aa4, 0x11d5, 0xbc, 0xcf, 0x00, 0xb0, 0xd0, 0x14, 0xa2, 0xd0);
NTSTATUS DispatchClose( IN PSAC_DEVICE_CONTEXT DeviceContext, IN PIRP Irp );
NTSTATUS DispatchCreate( IN PSAC_DEVICE_CONTEXT DeviceContext, IN PIRP Irp );
NTSTATUS Dispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
/*++
Routine Description:
This is the dispatch routine for SAC.
Arguments:
DeviceObject - Pointer to device object for target device
Irp - Pointer to I/O request packet
Return Value:
NTSTATUS -- Indicates whether the request was successfully queued.
Security:
interface: external --> internal exposed to anything that can get a handle device object --*/
{ PSAC_DEVICE_CONTEXT DeviceContext = (PSAC_DEVICE_CONTEXT)DeviceObject->DeviceExtension; PIO_STACK_LOCATION IrpSp; NTSTATUS Status;
//
//
//
Status = STATUS_UNSUCCESSFUL;
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC Dispatch: Entering.\n")));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MajorFunction) { case IRP_MJ_CREATE: Status = DispatchCreate(DeviceContext, Irp);
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC Dispatch: Exiting with status 0x%x\n", Status)));
break;
case IRP_MJ_CLEANUP:
#if ENABLE_SERVICE_FILE_OBJECT_CHECKING
//
// Determine if the process that is closing
// their driver handle owns any channels or
// is the process that registered the cmd event info.
// If it is any of these, close the respective
// resource.
//
//
// Compare the FileObject against
//
// the service fileobject
// the existing channel fileobjects
//
//
if (IsCmdEventRegistrationProcess(IrpSp->FileObject)) { Status = UnregisterSacCmdEvent(IrpSp->FileObject);
if (NT_SUCCESS(Status)) {
//
// Notify the Console Manager that the service has unregistered
//
Status = IoMgrHandleEvent( IO_MGR_EVENT_UNREGISTER_SAC_CMD_EVENT, NULL, NULL ); }
}
#endif
else {
//
// Find all channels that have the same File object
// and notify the Io Mgr that they should be closed
//
Status = ChanMgrCloseChannelsWithFileObject(IrpSp->FileObject); }
//
// we return SUCCESS regardless of our attempts to clean up
// the service or channels.
//
Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC Dispatch: Exiting cleanup status 0x%x\n", Status)));
break;
case IRP_MJ_CLOSE:
Status = DispatchClose(DeviceContext, Irp);
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC Dispatch: Exiting close status 0x%x\n", Status)));
break;
case IRP_MJ_DEVICE_CONTROL:
ASSERT(0); Status = DispatchDeviceControl(DeviceObject, Irp);
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC Dispatch: Exiting with status 0x%x\n", Status)));
break;
default: IF_SAC_DEBUG(SAC_DEBUG_FAILS, KdPrint(( "SAC Dispatch: Invalid major function %lx\n", IrpSp->MajorFunction ))); Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; IoCompleteRequest(Irp, DeviceContext->PriorityBoost);
Status = STATUS_NOT_IMPLEMENTED; IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC Dispatch: Exiting with status 0x%x\n", Status)));
break; }
return Status;
} // Dispatch
NTSTATUS DispatchDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
/*++
Routine Description:
This is the dispatch routine for SAC IOCTLs.
Arguments:
DeviceObject - Pointer to device object for target device
Irp - Pointer to I/O request packet
Return Value:
NTSTATUS -- Indicates whether the request was successfully queued.
Security:
interface: external -> internal internal -> external
--*/
{ NTSTATUS Status; PSAC_DEVICE_CONTEXT DeviceContext; PIO_STACK_LOCATION IrpSp; ULONG i; ULONG ResponseLength; ULONG IoControlCode;
ResponseLength = 0;
DeviceContext = (PSAC_DEVICE_CONTEXT)DeviceObject->DeviceExtension; IrpSp = IoGetCurrentIrpStackLocation(Irp);
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchDeviceControl: Entering.\n")));
//
// Get the IOCTL code
//
IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
switch (IoControlCode) { case IOCTL_SAC_OPEN_CHANNEL: { PSAC_CHANNEL Channel; PSAC_CMD_OPEN_CHANNEL OpenChannelCmd; PSAC_RSP_OPEN_CHANNEL OpenChannelRsp; PSAC_CHANNEL_OPEN_ATTRIBUTES Attributes;
//
//
//
Channel = NULL;
//
// Verify the parameters of the IRP
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(SAC_CMD_OPEN_CHANNEL)) { Status = STATUS_INVALID_BUFFER_SIZE; break; } if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength != sizeof(SAC_RSP_OPEN_CHANNEL)) { Status = STATUS_INVALID_BUFFER_SIZE; break; }
//
// Get the IRP buffers
//
OpenChannelCmd = (PSAC_CMD_OPEN_CHANNEL)Irp->AssociatedIrp.SystemBuffer; OpenChannelRsp = (PSAC_RSP_OPEN_CHANNEL)Irp->AssociatedIrp.SystemBuffer; //
// Get the attributes from the command structure
//
Attributes = &OpenChannelCmd->Attributes;
//
// Verify that the Channel Type is valid
//
if (! ChannelIsValidType(Attributes->Type)) { Status = STATUS_INVALID_PARAMETER_1; break; }
//
// Verify that if the user wants to use the CLOSE_EVENT, we received on to use
//
if (Attributes->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT) { #if DEBUG_DISPATCH
ASSERT(Attributes->CloseEvent != NULL); #endif
if (Attributes->CloseEvent == NULL) { Status = STATUS_INVALID_PARAMETER_5; break; } } else { #if DEBUG_DISPATCH
ASSERT(Attributes->CloseEvent == NULL); #endif
if (Attributes->CloseEvent != NULL) { Status = STATUS_INVALID_PARAMETER_5; break; } } //
// Verify that if the user wants to use the HAS_NEW_DATA_EVENT, we received one to use
//
if (Attributes->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) { #if DEBUG_DISPATCH
ASSERT(Attributes->HasNewDataEvent); #endif
if (! Attributes->HasNewDataEvent) { Status = STATUS_INVALID_PARAMETER_6; break; } } else { #if DEBUG_DISPATCH
ASSERT(Attributes->HasNewDataEvent == NULL); #endif
if (Attributes->HasNewDataEvent != NULL) { Status = STATUS_INVALID_PARAMETER_6; break; } } #if ENABLE_CHANNEL_LOCKING
//
// Verify that if the user wants to use the LOCK_EVENT, we received one to use
//
if (Attributes->Flags & SAC_CHANNEL_FLAG_LOCK_EVENT) { #if DEBUG_DISPATCH
ASSERT(Attributes->LockEvent); #endif
if (! Attributes->LockEvent) { Status = STATUS_INVALID_PARAMETER_7; break; } } else { #if DEBUG_DISPATCH
ASSERT(Attributes->LockEvent == NULL); #endif
if (Attributes->LockEvent != NULL) { Status = STATUS_INVALID_PARAMETER_7; break; } } #endif
//
// Verify that if the user wants to use the REDRAW_EVENT, we received one to use
//
if (Attributes->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT) { #if DEBUG_DISPATCH
ASSERT(Attributes->RedrawEvent); #endif
if (! Attributes->RedrawEvent) { Status = STATUS_INVALID_PARAMETER_8; break; } } else { #if DEBUG_DISPATCH
ASSERT(Attributes->RedrawEvent == NULL); #endif
if (Attributes->RedrawEvent != NULL) { Status = STATUS_INVALID_PARAMETER_8; break; } } //
// SECURITY:
//
// at this point we have at least a properly formed set of flags
// and event handles. The events still need to be validated, however.
// this is done via ChanMgrCreateChannel.
//
//
// Create the channel based on type
//
if (Attributes->Type == ChannelTypeCmd) { PSAC_CHANNEL_OPEN_ATTRIBUTES tmpAttributes; PWCHAR Name; PCWSTR Description;
//
//
//
tmpAttributes = NULL; Name = NULL; Description = NULL;
//
// Create a channel for this IRP
//
do {
//
// the cmd channel requires all of the events
// hence, ensure we have them
//
if (!(Attributes->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT) || !(Attributes->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT) || !(Attributes->Flags & SAC_CHANNEL_FLAG_LOCK_EVENT) || !(Attributes->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT)) { Status = STATUS_INVALID_PARAMETER_7; break;
}
//
// Allocate a temporary attributes structure that
// we'll populate with attributes appropriate for
// creating a cmd type channel
//
tmpAttributes = ALLOCATE_POOL(sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES), GENERAL_POOL_TAG); if (! tmpAttributes) { Status = STATUS_NO_MEMORY; break; }
//
// Allocate a buffer for the channel's name
//
Name = ALLOCATE_POOL(SAC_MAX_CHANNEL_NAME_SIZE, GENERAL_POOL_TAG); if (! Name) { Status = STATUS_NO_MEMORY; break; }
//
// Generate a name for the command console channel
//
Status = ChanMgrGenerateUniqueCmdName(Name); if (! NT_SUCCESS(Status)) { break; }
//
// Initialize the Command Console attributes
//
RtlZeroMemory(tmpAttributes, sizeof(SAC_CHANNEL_OPEN_ATTRIBUTES));
tmpAttributes->Type = Attributes->Type; // attempt to copy the name
wcsncpy(tmpAttributes->Name, Name, SAC_MAX_CHANNEL_NAME_LENGTH); tmpAttributes->Name[SAC_MAX_CHANNEL_NAME_LENGTH] = UNICODE_NULL; // attempt to copy the channel description
Description = GetMessage(CMD_CHANNEL_DESCRIPTION); ASSERT(Description); if (!Description) { Status = STATUS_NO_MEMORY; break; } wcsncpy(tmpAttributes->Description, Description, SAC_MAX_CHANNEL_DESCRIPTION_LENGTH); tmpAttributes->Description[SAC_MAX_CHANNEL_DESCRIPTION_LENGTH] = UNICODE_NULL; tmpAttributes->Flags = Attributes->Flags | SAC_CHANNEL_FLAG_APPLICATION_TYPE; tmpAttributes->CloseEvent = Attributes->CloseEvent; tmpAttributes->HasNewDataEvent = Attributes->HasNewDataEvent; #if ENABLE_CHANNEL_LOCKING
tmpAttributes->LockEvent = Attributes->LockEvent; #endif
tmpAttributes->RedrawEvent = Attributes->RedrawEvent; tmpAttributes->ApplicationType = SAC_CMD_CHANNEL_APPLICATION_GUID;
//
// attempt to create the new channel
//
Status = ChanMgrCreateChannel( &Channel, tmpAttributes );
} while (FALSE); //
// Cleanup
//
SAFE_FREE_POOL(&Name); SAFE_FREE_POOL(&tmpAttributes); } else { //
// Validate the Name & Description strings
//
//
// Verify name string is NULL terminated.
//
i = 0; while (i < SAC_MAX_CHANNEL_NAME_LENGTH) { if (Attributes->Name[i] == UNICODE_NULL) { break; }
i++; }
//
// fail if string is not NULL terminated or if string is empty
//
if ((i == SAC_MAX_CHANNEL_NAME_LENGTH) || (i == 0)) { Status = STATUS_INVALID_PARAMETER_2; break; }
//
// Verify description string is NULL terminated.
// Note: the Description is allowed to have zero length, so we don't check it.
//
i = 0; while (i < SAC_MAX_CHANNEL_DESCRIPTION_LENGTH) { if (Attributes->Description[i] == UNICODE_NULL) { break; }
i++; }
if (i == SAC_MAX_CHANNEL_DESCRIPTION_LENGTH) { Status = STATUS_INVALID_PARAMETER_3; break; }
//
// attempt to create the new channel
//
Status = ChanMgrCreateChannel( &Channel, Attributes );
} if (NT_SUCCESS(Status)) {
//
// Keep track of the File Object used to reference the driver
//
ChannelSetFileObject(Channel, IrpSp->FileObject);
//
// Populate the response message with the new channel handle
//
OpenChannelRsp->Handle = ChannelGetHandle(Channel); ResponseLength = sizeof(SAC_RSP_OPEN_CHANNEL);
//
// Notify the Console Manager that a new channel has been created
//
IoMgrHandleEvent( IO_MGR_EVENT_CHANNEL_CREATE, Channel, NULL ); }
break;
} case IOCTL_SAC_CLOSE_CHANNEL: {
PSAC_CMD_CLOSE_CHANNEL ChannelCloseCmd; PSAC_CHANNEL Channel; //
// Verify the parameters of the IRP
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(SAC_CMD_CLOSE_CHANNEL)) { Status = STATUS_INVALID_BUFFER_SIZE; break; }
//
// Close the given channel.
//
ChannelCloseCmd = (PSAC_CMD_CLOSE_CHANNEL)Irp->AssociatedIrp.SystemBuffer;
//
// Get the referred channel by it's handle while making
// sure the driver handle is the same one as the one
// that created the channel - the same process
//
Status = ChanMgrGetByHandleAndFileObject( ChannelCloseCmd->Handle, IrpSp->FileObject, &Channel );
if (NT_SUCCESS(Status)) {
//
// close the channel
//
Status = ChanMgrCloseChannel(Channel);
//
// We are done with the channel
//
ChanMgrReleaseChannel(Channel);
}
break;
}
case IOCTL_SAC_WRITE_CHANNEL: {
PSAC_CMD_WRITE_CHANNEL ChannelWriteCmd; PSAC_CHANNEL Channel;
//
// Verify the parameters of the IRP
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(SAC_CMD_WRITE_CHANNEL)) { Status = STATUS_BUFFER_TOO_SMALL; break; }
//
// Get the Write cmd structure
//
ChannelWriteCmd = (PSAC_CMD_WRITE_CHANNEL)Irp->AssociatedIrp.SystemBuffer;
//
// Verify that the specified write bufferSize is reasonable
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != (sizeof(SAC_CMD_WRITE_CHANNEL) + ChannelWriteCmd->Size)) { //
// if the buffer sizes dont match,
// then the specified the wrong size
//
Status = STATUS_INVALID_PARAMETER_2; break; }
//
// Get the referred channel by it's handle while making
// sure the driver handle is the same one as the one
// that created the channel - the same process
//
Status = ChanMgrGetByHandleAndFileObject( ChannelWriteCmd->Handle, IrpSp->FileObject, &Channel );
if (NT_SUCCESS(Status)) {
//
// Call the I/O Manager's OWrite method
//
Status = IoMgrHandleEvent( IO_MGR_EVENT_CHANNEL_WRITE, Channel, ChannelWriteCmd );
//
// We are done with the channel
//
ChanMgrReleaseChannel(Channel);
} #if DEBUG_DISPATCH
ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND); #endif
break;
} case IOCTL_SAC_READ_CHANNEL: {
PSAC_CHANNEL Channel; PSAC_CMD_READ_CHANNEL ChannelReadCmd; PSAC_RSP_READ_CHANNEL ChannelReadRsp;
//
//
//
Channel = NULL;
//
// Verify the parameters of the IRP
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(SAC_CMD_READ_CHANNEL)) { Status = STATUS_INVALID_BUFFER_SIZE; break; } if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SAC_RSP_READ_CHANNEL)) { Status = STATUS_BUFFER_TOO_SMALL; break; }
//
// Read from the given channel.
//
ChannelReadCmd = (PSAC_CMD_READ_CHANNEL)Irp->AssociatedIrp.SystemBuffer;
//
// Get the referred channel by it's handle while making
// sure the driver handle is the same one as the one
// that created the channel - the same process
//
Status = ChanMgrGetByHandleAndFileObject( ChannelReadCmd->Handle, IrpSp->FileObject, &Channel );
if (NT_SUCCESS(Status)) {
ChannelReadRsp = (PSAC_RSP_READ_CHANNEL)Irp->AssociatedIrp.SystemBuffer;
//
// SECURITY:
//
// it is safe to use the OutputBufferLength since we know the buffer
// is large enough to hold at least one byte.
// the response structure is essentially a byte array of bytes
// read, we read the # of bytes specified by OutputBufferLength
//
Status = ChannelIRead( Channel, &(ChannelReadRsp->Buffer[0]), IrpSp->Parameters.DeviceIoControl.OutputBufferLength, &ResponseLength );
//
// We are done with the channel
//
ChanMgrReleaseChannel(Channel);
} #if DEBUG_DISPATCH
ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND); #endif
break;
} case IOCTL_SAC_POLL_CHANNEL: {
PSAC_CHANNEL Channel; PSAC_CMD_POLL_CHANNEL PollChannelCmd; PSAC_RSP_POLL_CHANNEL PollChannelRsp;
//
//
//
Channel = NULL;
//
// Verify the parameters of the IRP
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(SAC_CMD_POLL_CHANNEL)) { Status = STATUS_INVALID_BUFFER_SIZE; break; } if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength != sizeof(SAC_RSP_POLL_CHANNEL)) { Status = STATUS_INVALID_BUFFER_SIZE; break; }
//
// get the channel specified by the incoming channel handle
//
PollChannelCmd = (PSAC_CMD_POLL_CHANNEL)Irp->AssociatedIrp.SystemBuffer; PollChannelRsp = (PSAC_RSP_POLL_CHANNEL)Irp->AssociatedIrp.SystemBuffer;
//
// Get the referred channel by it's handle while making
// sure the driver handle is the same one as the one
// that created the channel - the same process
//
Status = ChanMgrGetByHandleAndFileObject( PollChannelCmd->Handle, IrpSp->FileObject, &Channel );
if (NT_SUCCESS(Status)) {
//
// see if there is data waiting
//
// SECURITY:
//
// the InputWaiting variable is guaranteed to be safe since
// we validated the OutputBufferLength
//
PollChannelRsp->InputWaiting = ChannelHasNewIBufferData(Channel);
ResponseLength = sizeof(SAC_RSP_POLL_CHANNEL);
//
// We are done with the channel
//
Status = ChanMgrReleaseChannel(Channel);
}
#if DEBUG_DISPATCH
ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND); #endif
break;
}
case IOCTL_SAC_REGISTER_CMD_EVENT: {
PSAC_CMD_SETUP_CMD_EVENT SetupCmdEvent;
//
// Verify the parameters of the IRP
//
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(SAC_CMD_SETUP_CMD_EVENT)) { Status = STATUS_INVALID_BUFFER_SIZE; break; }
//
// get the event info
//
SetupCmdEvent = (PSAC_CMD_SETUP_CMD_EVENT)Irp->AssociatedIrp.SystemBuffer; #if ENABLE_CMD_SESSION_PERMISSION_CHECKING
//
// If we are not able to launch cmd sessions,
// then notify that we cannot peform this action
//
if (! IsCommandConsoleLaunchingEnabled()) { Status = STATUS_UNSUCCESSFUL;
break; } #endif
//
// Attempt to register the callers cmd event info
//
// SECURITY:
//
// the SAC_CMD_SETUP_CMD_EVENT has events handles that must be
// validated as part of the registration process
//
Status = RegisterSacCmdEvent( IrpSp->FileObject, SetupCmdEvent );
if (NT_SUCCESS(Status)) { //
// Notify the Console Manager that the Command Prompt
// service has REGISTERED
//
Status = IoMgrHandleEvent( IO_MGR_EVENT_REGISTER_SAC_CMD_EVENT, NULL, NULL ); }
#if DEBUG_DISPATCH
ASSERT(NT_SUCCESS(Status)); #endif
break; }
case IOCTL_SAC_UNREGISTER_CMD_EVENT: {
Status = STATUS_UNSUCCESSFUL;
#if ENABLE_CMD_SESSION_PERMISSION_CHECKING
//
// If we are not able to launch cmd sessions,
// then notify that we cannot peform this action
//
if (! IsCommandConsoleLaunchingEnabled()) { break; } #endif
#if ENABLE_SERVICE_FILE_OBJECT_CHECKING
//
// If the current process is the one that registered
// the cmd event info,
// then unregister
//
if (! IsCmdEventRegistrationProcess(IrpSp->FileObject)) { break; }
#endif
Status = UnregisterSacCmdEvent(IrpSp->FileObject);
if (NT_SUCCESS(Status)) {
//
// Notify the Console Manager that the Command Prompt
// service has UNREGISTERED
//
Status = IoMgrHandleEvent( IO_MGR_EVENT_UNREGISTER_SAC_CMD_EVENT, NULL, NULL );
}
#if DEBUG_DISPATCH
ASSERT(NT_SUCCESS(Status)); #endif
break; }
default: Status = STATUS_INVALID_DEVICE_REQUEST; break;
}
Irp->IoStatus.Status = Status; Irp->IoStatus.Information = ResponseLength;
if (Status != STATUS_PENDING) { IoCompleteRequest(Irp, DeviceContext->PriorityBoost); }
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchDeviceControl: Exiting with status 0x%x\n", Status)));
return Status;
} // DispatchDeviceControl
NTSTATUS DispatchShutdownControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
/*++
Routine Description:
This is the dispatch routine which receives the shutdown IRP.
Arguments:
DeviceObject - Pointer to device object for target device
Irp - Pointer to I/O request packet
Return Value:
NTSTATUS -- Indicates whether the request was successfully queued.
--*/
{ UNREFERENCED_PARAMETER(DeviceObject); IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchShutdownControl: Entering.\n")));
//
// Notify any user.
//
IoMgrHandleEvent( IO_MGR_EVENT_SHUTDOWN, NULL, NULL ); IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchShutdownControl: Exiting.\n")));
Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
} // DispatchShutdownControl
NTSTATUS DispatchCreate( IN PSAC_DEVICE_CONTEXT DeviceContext, IN PIRP Irp )
/*++
Routine Description:
This is the dispatch routine for SAC IOCTL Create
Arguments:
DeviceContext - Pointer to device context for target device
Irp - Pointer to I/O request packet
Return Value:
NTSTATUS -- Indicates whether the request was successfully queued.
--*/
{ NTSTATUS Status; PIO_STACK_LOCATION IrpSp;
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchCreate: Entering.\n")));
//
// Check to see if we are done initializing.
//
if (!GlobalDataInitialized || !DeviceContext->InitializedAndReady) {
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE; IoCompleteRequest(Irp, DeviceContext->PriorityBoost);
Status = STATUS_INVALID_DEVICE_STATE;
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchCreate: Exiting with status 0x%x\n", Status)));
//
// We need to catch this state
//
ASSERT(0);
return Status; }
//
// Get a pointer to the current stack location in the IRP. This is where
// the function codes and parameters are stored.
//
IrpSp = IoGetCurrentIrpStackLocation(Irp);
//
// Case on the function that is being performed by the requestor. If the
// operation is a valid one for this device, then make it look like it was
// successfully completed, where possible.
//
switch (IrpSp->MajorFunction) { //
// The Create function opens a connection to this device.
//
case IRP_MJ_CREATE:
Status = STATUS_SUCCESS; break;
default: Status = STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, DeviceContext->PriorityBoost);
//
// Return the immediate status code to the caller.
//
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchCreate: Exiting with status 0x%x\n", Status)));
//
// We need to catch this state
//
ASSERT(NT_SUCCESS(Status));
return Status;
}
NTSTATUS DispatchClose( IN PSAC_DEVICE_CONTEXT DeviceContext, IN PIRP Irp )
/*++
Routine Description:
This is the dispatch routine for SAC IOCTL Close
Arguments:
DeviceContext - Pointer to device context for target device
Irp - Pointer to I/O request packet
Return Value:
NTSTATUS -- Indicates whether the request was successfully queued.
--*/
{ NTSTATUS Status;
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchClose: Entering.\n")));
//
// Check to see if we are done initializing.
//
if (!GlobalDataInitialized || !DeviceContext->InitializedAndReady) {
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE; IoCompleteRequest(Irp, DeviceContext->PriorityBoost);
Status = STATUS_INVALID_DEVICE_STATE;
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DispatchClose: Exiting with status 0x%x\n", Status)));
return Status; }
Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, DeviceContext->PriorityBoost);
Status = STATUS_SUCCESS; return Status; }
|