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.
1165 lines
28 KiB
1165 lines
28 KiB
/*++
|
|
|
|
Copyright (c) 1991 - 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
##### ## ## ##### ##### ##### ###### ### #### ##### #####
|
|
## ## ## ## ## ## ## ## ## ## ## # ## # ## ## ## ##
|
|
## #### ## ## ## ## ## ## ## ### ## ## ## ## ##
|
|
##### ## ## ## ## ## ##### ## ### ## ## ## ## ##
|
|
## #### ##### ## ## #### ## ### ## ##### #####
|
|
## ## ## ## ## ## ## ## ## # ## ## ## # ## ##
|
|
##### ## ## ## ##### ## ## ## ### ## #### ## ##
|
|
|
|
Abstract:
|
|
|
|
This module contains the code for all fundtions that
|
|
are exported by the Server Appliance port driver for
|
|
use by the mini-port drivers.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 1-Oct-2001
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Notes:
|
|
|
|
|
|
--*/
|
|
|
|
#include "internal.h"
|
|
#include <ntimage.h>
|
|
|
|
|
|
|
|
PVOID
|
|
SaPortAllocatePool(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN SIZE_T NumberOfBytes
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is a wrapper for ExAllocatePool, but enforces
|
|
pool tagging by using the associated miniport's driver name
|
|
for the pool tag.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
NumberOfBytes - Number of bytes to allocate
|
|
|
|
Return Value:
|
|
|
|
Pointer to the allocated pool or NULL for failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension;
|
|
ULONG DeviceType;
|
|
ULONG PoolTag;
|
|
|
|
|
|
if (MiniPortDeviceExtension) {
|
|
DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
DeviceType = DeviceExtension->InitData->DeviceType;
|
|
} else {
|
|
DeviceType = 0;
|
|
}
|
|
|
|
switch (DeviceType) {
|
|
case SA_DEVICE_DISPLAY:
|
|
PoolTag = 'sDaS';
|
|
break;
|
|
|
|
case SA_DEVICE_KEYPAD:
|
|
PoolTag = 'pKaS';
|
|
break;
|
|
|
|
case SA_DEVICE_NVRAM:
|
|
PoolTag = 'vNaS';
|
|
break;
|
|
|
|
case SA_DEVICE_WATCHDOG:
|
|
PoolTag = 'dWaS';
|
|
break;
|
|
|
|
default:
|
|
PoolTag = 'tPaS';
|
|
break;
|
|
}
|
|
|
|
return ExAllocatePoolWithTag( NonPagedPool, NumberOfBytes, PoolTag );
|
|
}
|
|
|
|
|
|
VOID
|
|
SaPortFreePool(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PVOID PoolMemory
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is a wrapper for ExFreePool, but enforces
|
|
pool tagging by using the associated miniport's driver name
|
|
for the pool tag.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
PoolMemory - Pointer to the previously allocated pool
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
ULONG PoolTag;
|
|
|
|
|
|
switch (DeviceExtension->InitData->DeviceType) {
|
|
case SA_DEVICE_DISPLAY:
|
|
PoolTag = 'sDaS';
|
|
break;
|
|
|
|
case SA_DEVICE_KEYPAD:
|
|
PoolTag = 'pKaS';
|
|
break;
|
|
|
|
case SA_DEVICE_NVRAM:
|
|
PoolTag = 'vNaS';
|
|
break;
|
|
|
|
case SA_DEVICE_WATCHDOG:
|
|
PoolTag = 'dWaS';
|
|
break;
|
|
}
|
|
|
|
ExFreePoolWithTag( PoolMemory, PoolTag );
|
|
}
|
|
|
|
|
|
PVOID
|
|
SaPortGetVirtualAddress(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PHYSICAL_ADDRESS PhysicalAddress,
|
|
IN ULONG Length
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is a wrapper for MmMapIoSpace and simply provides a
|
|
virtual memory address to access a physical resource.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
PhysicalAddress - Physical memory address
|
|
Length - Length of the memory space
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
return MmMapIoSpace( PhysicalAddress, Length, MmNonCached );
|
|
}
|
|
|
|
|
|
VOID
|
|
SaPortRequestDpc(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PVOID Context
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is a wrapper for IoRequestDpc.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
Context - Miniport supplied context pointer
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
IoRequestDpc( DeviceExtension->DeviceObject, MiniPortDeviceExtension, Context );
|
|
}
|
|
|
|
|
|
VOID
|
|
SaPortCompleteRequest(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PIRP Irp,
|
|
IN ULONG Information,
|
|
IN NTSTATUS Status,
|
|
IN BOOLEAN CompleteAll
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is use by all miniports to complete the currently processed IRP.
|
|
The caller can optionally request that all oustanding I/Os be completed. This is
|
|
accomplished by removing all IRPs from the device queue and processing the I/O.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
Information - Informational, request specific data
|
|
Status - NT status value
|
|
CompleteAll - TRUE for completion of all outstanding I/O requests, otherwise FALSE
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
PKDEVICE_QUEUE_ENTRY Packet;
|
|
KIRQL CancelIrql;
|
|
PIRP ThisIrp;
|
|
|
|
|
|
|
|
if (Irp) {
|
|
CompleteRequest( Irp, Status, Information );
|
|
return;
|
|
}
|
|
|
|
if (DeviceExtension->DeviceObject->CurrentIrp == NULL) {
|
|
return;
|
|
}
|
|
|
|
CompleteRequest( DeviceExtension->DeviceObject->CurrentIrp, Status, Information );
|
|
|
|
if (CompleteAll) {
|
|
while (1) {
|
|
IoAcquireCancelSpinLock( &CancelIrql );
|
|
Packet = KeRemoveDeviceQueue( &DeviceExtension->DeviceObject->DeviceQueue );
|
|
if (Packet == NULL) {
|
|
IoReleaseCancelSpinLock( CancelIrql );
|
|
break;
|
|
}
|
|
ThisIrp = CONTAINING_RECORD( Packet, IRP, Tail.Overlay.DeviceQueueEntry );
|
|
IoReleaseCancelSpinLock( CancelIrql );
|
|
SaPortStartIo( DeviceExtension->DeviceObject, ThisIrp );
|
|
}
|
|
} else {
|
|
IoStartNextPacket( DeviceExtension->DeviceObject, TRUE );
|
|
}
|
|
|
|
IoReleaseRemoveLock( &DeviceExtension->RemoveLock, DeviceExtension->DeviceObject->CurrentIrp );
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
SaPortSynchronizeExecution (
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
|
|
IN PVOID SynchronizeContext
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is a wrapper for KeSynchronizeExecution.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
SynchronizeRoutine - Is the entry point for a caller-supplied SynchCritSection routine whose execution is to be
|
|
synchronized with the execution of the ISR associated with the interrupt objects.
|
|
SynchronizeContext - Pointer to a caller-supplied context area to be passed to the SynchronizeRoutine when it is called.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
if (DeviceExtension->InterruptObject == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
return KeSynchronizeExecution(
|
|
DeviceExtension->InterruptObject,
|
|
SynchronizeRoutine,
|
|
SynchronizeContext
|
|
);
|
|
}
|
|
|
|
|
|
ULONG
|
|
SaPortGetOsVersion(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the OS version on which the minport is running.
|
|
The OS version value is obtained at DriverEntry time.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
OS Version data.
|
|
|
|
--*/
|
|
|
|
{
|
|
return (ULONG)((OsMajorVersion << 16) | (OsMinorVersion & 0xffff));
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortGetRegistryValueInformation(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
IN OUT PULONG RegistryType,
|
|
IN OUT PULONG RegistryDataLength
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
status = ReadRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
&KeyInformation
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
__leave;
|
|
}
|
|
|
|
*RegistryType = KeyInformation->Type;
|
|
*RegistryDataLength = KeyInformation->DataLength;
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
if (KeyInformation) {
|
|
ExFreePool( KeyInformation );
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortDeleteRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
UNICODE_STRING unicodeString;
|
|
HANDLE parametersKey = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
status = OpenParametersRegistryKey(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
KEY_ALL_ACCESS,
|
|
¶metersKey
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "OpenParametersRegistryKey failed", status );
|
|
}
|
|
|
|
RtlInitUnicodeString( &unicodeString, ValueName );
|
|
|
|
status = ZwDeleteValueKey(
|
|
parametersKey,
|
|
&unicodeString
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "ZwDeleteValueKey failed", status );
|
|
}
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
if (parametersKey) {
|
|
ZwClose( parametersKey );
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortReadNumericRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
OUT PULONG RegistryValue
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the miniport driver's registry parameters.
|
|
This function returns a numeric (REG_DWORD) data value.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
ValueName - Name of the registry value to read
|
|
RegistryValue - Pointer to a ULONG that holds the registry data
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
status = ReadRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
&KeyInformation
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
__leave;
|
|
}
|
|
|
|
if (KeyInformation->Type != REG_DWORD) {
|
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
|
__leave;
|
|
}
|
|
|
|
RtlCopyMemory( RegistryValue, (PUCHAR)KeyInformation + KeyInformation->DataOffset, sizeof(ULONG) );
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
if (KeyInformation) {
|
|
ExFreePool( KeyInformation );
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortWriteNumericRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
IN ULONG RegistryValue
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the miniport driver's registry parameters.
|
|
This function returns a numeric (REG_DWORD) data value.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
ValueName - Name of the registry value to read
|
|
RegistryValue - Pointer to a ULONG that holds the registry data
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
__try {
|
|
|
|
Status = WriteRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
REG_DWORD,
|
|
&RegistryValue,
|
|
sizeof(ULONG)
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
__leave;
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortReadBinaryRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
OUT PVOID RegistryValue,
|
|
IN OUT PULONG RegistryValueLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the miniport driver's registry parameters.
|
|
This function returns a numeric (REG_DWORD) data value.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
ValueName - Name of the registry value to read
|
|
RegistryValue - Pointer to a ULONG that holds the registry data
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
status = ReadRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
&KeyInformation
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
__leave;
|
|
}
|
|
|
|
if (KeyInformation->Type != REG_BINARY) {
|
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
|
__leave;
|
|
}
|
|
|
|
if (*RegistryValueLength < KeyInformation->DataLength) {
|
|
*RegistryValueLength = KeyInformation->DataLength;
|
|
status = STATUS_BUFFER_TOO_SMALL;
|
|
__leave;
|
|
}
|
|
|
|
RtlCopyMemory( RegistryValue, (PUCHAR)KeyInformation + KeyInformation->DataOffset, KeyInformation->DataLength );
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
if (KeyInformation) {
|
|
ExFreePool( KeyInformation );
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortWriteBinaryRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
IN PVOID RegistryValue,
|
|
IN ULONG RegistryValueLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the miniport driver's registry parameters.
|
|
This function returns a numeric (REG_DWORD) data value.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
ValueName - Name of the registry value to read
|
|
RegistryValue - Pointer to a ULONG that holds the registry data
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
__try {
|
|
|
|
Status = WriteRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
REG_BINARY,
|
|
RegistryValue,
|
|
RegistryValueLength
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
__leave;
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortReadUnicodeStringRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
OUT PUNICODE_STRING RegistryValue
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the miniport driver's registry parameters.
|
|
This function returns a UNICODE_STRING representation of REG_SZ registry data.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
ValueName - Name of the registry value to read
|
|
RegistryValue - Pointer to a UNICODE_STRING that holds the registry data
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
|
|
|
|
|
|
__try {
|
|
|
|
status = ReadRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
&KeyInformation
|
|
);
|
|
if (!NT_SUCCESS(status)) {
|
|
__leave;
|
|
}
|
|
|
|
if (KeyInformation->Type != REG_SZ) {
|
|
status = STATUS_OBJECT_TYPE_MISMATCH;
|
|
__leave;
|
|
}
|
|
|
|
RegistryValue->Buffer = (PWSTR) ExAllocatePool( NonPagedPool, KeyInformation->DataLength );
|
|
if (RegistryValue->Buffer == NULL) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
__leave;
|
|
}
|
|
|
|
RtlCopyMemory( RegistryValue->Buffer, (PUCHAR)KeyInformation + KeyInformation->DataOffset, KeyInformation->DataLength );
|
|
|
|
RegistryValue->Length = (USHORT) KeyInformation->DataLength;
|
|
RegistryValue->MaximumLength = RegistryValue->Length;
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
if (KeyInformation) {
|
|
ExFreePool( KeyInformation );
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
if (RegistryValue->Buffer) {
|
|
ExFreePool( RegistryValue->Buffer );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortWriteUnicodeStringRegistryValue(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR ValueName,
|
|
IN PUNICODE_STRING RegistryValue
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine provides access to the miniport driver's registry parameters.
|
|
This function returns a UNICODE_STRING representation of REG_SZ registry data.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
ValueName - Name of the registry value to read
|
|
RegistryValue - Pointer to a UNICODE_STRING that holds the registry data
|
|
|
|
Return Value:
|
|
|
|
NT status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
__try {
|
|
|
|
Status = WriteRegistryValue(
|
|
DeviceExtension->DriverExtension,
|
|
&DeviceExtension->DriverExtension->RegistryPath,
|
|
ValueName,
|
|
REG_SZ,
|
|
RegistryValue->Buffer,
|
|
RegistryValue->Length
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
__leave;
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
} __finally {
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
PVOID
|
|
SaPortLockPagesForSystem(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PVOID UserBuffer,
|
|
IN ULONG UserBufferLength,
|
|
IN OUT PMDL *Mdl
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine obtains a virtual address that is locked down
|
|
and usable by the miniport driver at all times.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
UserBuffer - User buffer that is passed to the miniport
|
|
UserBufferLength - Length in bytes of the UserBuffer
|
|
Mdl - MDL that is created by this routine
|
|
|
|
Return Value:
|
|
|
|
Virtual system address for the UserBuffer
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
if (Mdl == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
*Mdl = NULL;
|
|
|
|
__try {
|
|
*Mdl = IoAllocateMdl( UserBuffer, UserBufferLength, FALSE, TRUE, NULL );
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
*Mdl = NULL;
|
|
}
|
|
|
|
if (*Mdl == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
__try {
|
|
MmProbeAndLockPages( *Mdl, KernelMode , IoWriteAccess );
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
IoFreeMdl( *Mdl );
|
|
}
|
|
|
|
return MmGetSystemAddressForMdlSafe( *Mdl, NormalPagePriority );
|
|
}
|
|
|
|
|
|
VOID
|
|
SaPortReleaseLockedPagesForSystem(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PMDL Mdl
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine releases the resources with a previously allocated MDL.
|
|
|
|
Arguments:
|
|
|
|
MiniPortDeviceExtension - Pointer to the miniport's device extension
|
|
Mdl - MDL that is created by SaPortLockPagesForSystem
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
MmUnlockPages( Mdl );
|
|
IoFreeMdl( Mdl );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortCopyUnicodeString(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PUNICODE_STRING DestinationString,
|
|
IN OUT PUNICODE_STRING SourceString
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine copies a UNICODE_STRING from a source to a
|
|
destination, but allocates a new buffer from pool first.
|
|
|
|
Arguments:
|
|
|
|
DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
|
|
SourceString - Source UNICODE_STRING for the copy
|
|
|
|
Return Value:
|
|
|
|
NT status code
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
|
|
DestinationString->Buffer = (PWSTR) SaPortAllocatePool( MiniPortDeviceExtension, SourceString->MaximumLength );
|
|
if (DestinationString->Buffer == NULL) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlCopyMemory( DestinationString->Buffer, SourceString->Buffer, SourceString->Length );
|
|
|
|
DestinationString->Length = SourceString->Length;
|
|
DestinationString->MaximumLength = SourceString->MaximumLength;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortCreateUnicodeString(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PUNICODE_STRING DestinationString,
|
|
IN PWSTR SourceString
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new UNICODE_STRING from pool
|
|
and initializes it with the source string.
|
|
|
|
Arguments:
|
|
|
|
DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
|
|
SourceString - Source character string
|
|
|
|
Return Value:
|
|
|
|
NT status code
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
DestinationString->Length = wcslen(SourceString) * sizeof(WCHAR);
|
|
DestinationString->MaximumLength = DestinationString->Length;
|
|
|
|
DestinationString->Buffer = (PWSTR) SaPortAllocatePool( MiniPortDeviceExtension, DestinationString->Length+2 );
|
|
if (DestinationString->Buffer == NULL) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory( DestinationString->Buffer, DestinationString->Length+2 );
|
|
RtlCopyMemory( DestinationString->Buffer, SourceString, DestinationString->Length );
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SaPortCreateUnicodeStringCat(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PUNICODE_STRING DestinationString,
|
|
IN PWSTR SourceString1,
|
|
IN PWSTR SourceString2
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new UNICODE_STRING from pool
|
|
and initializes it with the two source strings by
|
|
concatinating them together.
|
|
|
|
Arguments:
|
|
|
|
DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
|
|
SourceString1 - Source character string
|
|
SourceString2 - Source character string
|
|
|
|
Return Value:
|
|
|
|
NT status code
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
|
|
DestinationString->Length = STRING_SZ(SourceString1) + STRING_SZ(SourceString2);
|
|
DestinationString->MaximumLength = DestinationString->Length;
|
|
|
|
DestinationString->Buffer = (PWSTR) SaPortAllocatePool( MiniPortDeviceExtension, DestinationString->Length+2 );
|
|
if (DestinationString->Buffer == NULL) {
|
|
REPORT_ERROR( DeviceExtension->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
RtlZeroMemory( DestinationString->Buffer, DestinationString->Length+2 );
|
|
RtlCopyMemory( DestinationString->Buffer, SourceString1, STRING_SZ(SourceString1) );
|
|
RtlCopyMemory( ((PUCHAR)DestinationString->Buffer)+STRING_SZ(SourceString1), SourceString2, STRING_SZ(SourceString2) );
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
VOID
|
|
SaPortFreeUnicodeString(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PUNICODE_STRING SourceString
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a new UNICODE_STRING from pool
|
|
and initializes it with the two source strings by
|
|
concatinating them together.
|
|
|
|
Arguments:
|
|
|
|
DestinationString - Pointer to an empty UNICODE_STRING structure to be filled out
|
|
SourceString1 - Source character string
|
|
SourceString2 - Source character string
|
|
|
|
Return Value:
|
|
|
|
NT status code
|
|
|
|
--*/
|
|
|
|
{
|
|
SaPortFreePool( MiniPortDeviceExtension, SourceString->Buffer );
|
|
SourceString->Buffer = NULL;
|
|
SourceString->MaximumLength = 0;
|
|
SourceString->MaximumLength = 0;
|
|
}
|
|
|
|
|
|
extern "C" PACL SePublicDefaultDacl;
|
|
|
|
NTSTATUS
|
|
SaPortCreateBasenamedEvent(
|
|
IN PVOID MiniPortDeviceExtension,
|
|
IN PWSTR EventNameString,
|
|
IN OUT PKEVENT *Event,
|
|
IN OUT PHANDLE EventHandle
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PDEVICE_EXTENSION DeviceExtension = DeviceExtentionFromMiniPort( MiniPortDeviceExtension );
|
|
UNICODE_STRING EventName;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
|
|
|
|
__try {
|
|
|
|
SecurityDescriptor = (PSECURITY_DESCRIPTOR) SaPortAllocatePool( DeviceExtension, 4096 );
|
|
if (SecurityDescriptor == NULL) {
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "Could not allocate pool for security descriptor", Status );
|
|
}
|
|
|
|
Status = RtlCreateSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "RtlCreateSecurityDescriptor failed", Status );
|
|
}
|
|
|
|
Status = RtlSetDaclSecurityDescriptor( SecurityDescriptor, TRUE, *(PACL*)SePublicDefaultDacl, FALSE );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "RtlSetDaclSecurityDescriptor failed", Status );
|
|
}
|
|
|
|
Status = SaPortCreateUnicodeStringCat( MiniPortDeviceExtension, &EventName, L"\\BaseNamedObjects\\", EventNameString );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "SaPortCreateUnicodeStringCat failed", Status );
|
|
}
|
|
|
|
InitializeObjectAttributes( &objectAttributes, &EventName, OBJ_OPENIF, NULL, SecurityDescriptor );
|
|
|
|
Status = ZwCreateEvent( EventHandle, EVENT_ALL_ACCESS, &objectAttributes, SynchronizationEvent, TRUE );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "ZwCreateEvent failed", Status );
|
|
}
|
|
|
|
Status = ObReferenceObjectByHandle( *EventHandle, 0, NULL, KernelMode, (PVOID*)Event, NULL );
|
|
if (!NT_SUCCESS(Status)) {
|
|
ERROR_RETURN( DeviceExtension->DeviceType, "ObReferenceObjectByHandle failed", Status );
|
|
}
|
|
|
|
ObDereferenceObject( *Event );
|
|
|
|
} __finally {
|
|
|
|
if (EventName.Buffer) {
|
|
SaPortFreeUnicodeString( MiniPortDeviceExtension, &EventName );
|
|
}
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
if (SecurityDescriptor) {
|
|
SaPortFreePool( MiniPortDeviceExtension, SecurityDescriptor );
|
|
}
|
|
if (EventHandle) {
|
|
ZwClose( *EventHandle );
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
SaPortShutdownSystem(
|
|
IN BOOLEAN PowerOff
|
|
)
|
|
{
|
|
return NtShutdownSystem( PowerOff ? ShutdownPowerOff : ShutdownReboot );
|
|
}
|