Leaked source code of windows server 2003
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.
 
 
 
 
 
 

313 lines
8.9 KiB

/*++
Copyright (c) 1991 - 2002 Microsoft Corporation
Module Name:
## ## ### ## # ## ##### #### ##### #####
### ### ## # ## ### ## ## ## ## # ## ## ## ##
######## ### ## ### ## ## ## ## ## ## ## ##
# ### ## ### ## # # ## ## ## ## ## ## ## ##
# # ## ### ### ### ## ## ## ##### #####
# ## # ## ### ### ## ## ## ## # ## ##
# ## ### ## ## ##### ## #### ## ##
Abstract:
This module contains the entire implementation of
the virtual watchdog miniport driver.
@@BEGIN_DDKSPLIT
Author:
Wesley Witt (wesw) 1-Oct-2001
@@END_DDKSPLIT
Environment:
Kernel mode only.
Notes:
--*/
#include "mswd.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#endif
VOID
MsWdTimerReset(
IN PDEVICE_EXTENSION DeviceExtension
)
{
LARGE_INTEGER DueTime;
KeQuerySystemTime( &DeviceExtension->StartTime );
DueTime.QuadPart = DeviceExtension->TimeoutValue.QuadPart;
KeSetTimer( &DeviceExtension->Timer, DueTime, &DeviceExtension->TimerDpc );
}
VOID
MsWdShutdownWorker(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
)
{
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) Context;
ULONG ExpireBehavior;
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
ExpireBehavior = DeviceExtension->ExpireBehavior;
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
SaPortShutdownSystem( ExpireBehavior == 1 );
}
VOID
MsWdTimerDpc(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
)
{
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeferredContext;
PIO_WORKITEM WorkItem;
WorkItem = IoAllocateWorkItem( DeviceExtension->DeviceObject );
if (WorkItem) {
IoQueueWorkItem( WorkItem, MsWdShutdownWorker, DelayedWorkQueue, DeviceExtension );
}
}
NTSTATUS
MsWdDeviceIoctl(
IN PVOID DeviceExtensionIn,
IN PIRP Irp,
IN PVOID FsContext,
IN ULONG FunctionCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength
)
/*++
Routine Description:
This function is called by the SAPORT driver so that
the mini-port driver can service an IOCTL call.
Arguments:
DeviceExtension - A pointer to the mini-port's device extension
FunctionCode - The IOCTL function code
InputBuffer - Pointer to the input buffer, contains the data sent down by the I/O
InputBufferLength - Length in bytes of the InputBuffer
OutputBuffer - Pointer to the output buffer, contains the data generated by this call
OutputBufferLength - Length in bytes of the OutputBuffer
Context:
IRQL: IRQL PASSIVE_LEVEL, arbitrary thread context
Return Value:
If the function succeeds, it must return STATUS_SUCCESS.
Otherwise, it must return one of the error status values defined in ntstatus.h.
--*/
{
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtensionIn;
NTSTATUS Status = STATUS_SUCCESS;
PSA_WD_CAPS WdCaps = NULL;
LARGE_INTEGER CurrentTime;
switch (FunctionCode) {
case FUNC_SA_GET_VERSION:
*((PULONG)OutputBuffer) = SA_INTERFACE_VERSION;
break;
case FUNC_SA_GET_CAPABILITIES:
WdCaps = (PSA_WD_CAPS)OutputBuffer;
WdCaps->SizeOfStruct = sizeof(SA_WD_CAPS);
WdCaps->Minimum = 1;
WdCaps->Maximum = 512;
break;
case FUNC_SAWD_DISABLE:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
if (*((PULONG)InputBuffer) == 1) {
DeviceExtension->Enabled = 1;
MsWdTimerReset( DeviceExtension );
} else if (*((PULONG)InputBuffer) == 0) {
DeviceExtension->Enabled = 0;
KeCancelTimer( &DeviceExtension->Timer );
} else {
Status = STATUS_INVALID_PARAMETER_1;
}
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_QUERY_EXPIRE_BEHAVIOR:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
*((PULONG)OutputBuffer) = DeviceExtension->ExpireBehavior;
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_SET_EXPIRE_BEHAVIOR:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
if (*((PULONG)InputBuffer) == 1) {
DeviceExtension->ExpireBehavior = 1;
} else {
DeviceExtension->ExpireBehavior = 0;
}
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_PING:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
MsWdTimerReset( DeviceExtension );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_QUERY_TIMER:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
KeQuerySystemTime( &CurrentTime );
CurrentTime.QuadPart = DeviceExtension->TimeoutValue.QuadPart - (CurrentTime.QuadPart - DeviceExtension->StartTime.QuadPart);
*((PULONG)OutputBuffer) = (ULONG)NanoToSec( CurrentTime.QuadPart );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
case FUNC_SAWD_SET_TIMER:
ExAcquireFastMutex( &DeviceExtension->WdIoLock );
DeviceExtension->TimeoutValue.QuadPart = (ULONGLONG)-SecToNano( *((PLONG)InputBuffer) );
MsWdTimerReset( DeviceExtension );
ExReleaseFastMutex( &DeviceExtension->WdIoLock );
break;
default:
Status = STATUS_NOT_SUPPORTED;
REPORT_ERROR( SA_DEVICE_WATCHDOG, "Unsupported device control", Status );
break;
}
return Status;
}
NTSTATUS
MsWdHwInitialize(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID DeviceExtensionIn,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResources,
IN ULONG PartialResourceCount
)
/*++
Routine Description:
This function is called by the SAPORT driver so that
the mini-port driver can initialize it's hardware
resources.
Arguments:
DeviceObject - Pointer to the target device object.
Irp - Pointer to an IRP structure that describes the requested I/O operation.
DeviceExtension - A pointer to the mini-port's device extension.
PartialResources - Pointer to the translated resources alloacted by the system.
PartialResourceCount - The number of resources in the PartialResources array.
Context:
IRQL: IRQL PASSIVE_LEVEL, system thread context
Return Value:
If the function succeeds, it must return STATUS_SUCCESS.
Otherwise, it must return one of the error status values defined in ntstatus.h.
--*/
{
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceExtensionIn;
DeviceExtension->DeviceObject = DeviceObject;
ExInitializeFastMutex( &DeviceExtension->WdIoLock );
KeInitializeTimer( &DeviceExtension->Timer );
KeInitializeDpc( &DeviceExtension->TimerDpc, MsWdTimerDpc, DeviceExtension );
DeviceExtension->TimeoutValue.QuadPart = -SecToNano(DEFAULT_WD_TIMEOUT_SECS);
DeviceExtension->Enabled = 1;
DeviceExtension->ExpireBehavior = 0;
MsWdTimerReset( DeviceExtension );
return STATUS_SUCCESS;
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine is the driver's entry point, called by the I/O system
to load the driver. The driver's entry points are initialized and
a mutex to control paging is initialized.
In DBG mode, this routine also examines the registry for special
debug parameters.
Arguments:
DriverObject - a pointer to the object that represents this device driver.
RegistryPath - a pointer to this driver's key in the Services tree.
Return Value:
STATUS_SUCCESS
--*/
{
NTSTATUS Status;
SAPORT_INITIALIZATION_DATA SaPortInitData;
RtlZeroMemory( &SaPortInitData, sizeof(SAPORT_INITIALIZATION_DATA) );
SaPortInitData.StructSize = sizeof(SAPORT_INITIALIZATION_DATA);
SaPortInitData.DeviceType = SA_DEVICE_WATCHDOG;
SaPortInitData.HwInitialize = MsWdHwInitialize;
SaPortInitData.DeviceIoctl = MsWdDeviceIoctl;
SaPortInitData.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
Status = SaPortInitialize( DriverObject, RegistryPath, &SaPortInitData );
if (!NT_SUCCESS(Status)) {
REPORT_ERROR( SA_DEVICE_WATCHDOG, "SaPortInitialize failed\n", Status );
return Status;
}
return STATUS_SUCCESS;
}