206 lines
4.8 KiB
C
206 lines
4.8 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
WlWrap.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module wraps library functions, rerouting them to native
|
||
|
implementations as available.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Adrian J. Oney - April 21, 2002
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "WlDef.h"
|
||
|
#include "WlpWrap.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#ifdef ALLOC_PRAGMA
|
||
|
#pragma alloc_text(PAGE, WdmlibInit)
|
||
|
#pragma alloc_text(PAGE, WdmlibIoCreateDeviceSecure)
|
||
|
#endif
|
||
|
|
||
|
BOOLEAN WdmlibInitialized = FALSE;
|
||
|
|
||
|
//
|
||
|
// Here is a list of global variables through which we route our function calls
|
||
|
//
|
||
|
PFN_IO_CREATE_DEVICE_SECURE PfnIoCreateDeviceSecure = NULL;
|
||
|
PFN_IO_VALIDATE_DEVICE_IOCONTROL_ACCESS PfnIoValidateDeviceIoControlAccess = NULL;
|
||
|
|
||
|
|
||
|
VOID
|
||
|
WdmlibInit(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
UNICODE_STRING functionName;
|
||
|
|
||
|
RtlInitUnicodeString(&functionName, L"IoCreateDeviceSecure");
|
||
|
|
||
|
PfnIoCreateDeviceSecure = MmGetSystemRoutineAddress(&functionName);
|
||
|
|
||
|
if (PfnIoCreateDeviceSecure == NULL) {
|
||
|
|
||
|
PfnIoCreateDeviceSecure = IoDevObjCreateDeviceSecure;
|
||
|
}
|
||
|
|
||
|
RtlInitUnicodeString(&functionName, L"IoValidateDeviceIoControlAccess");
|
||
|
|
||
|
PfnIoValidateDeviceIoControlAccess = MmGetSystemRoutineAddress(&functionName);
|
||
|
|
||
|
WdmlibInitialized = TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
WdmlibIoCreateDeviceSecure(
|
||
|
IN PDRIVER_OBJECT DriverObject,
|
||
|
IN ULONG DeviceExtensionSize,
|
||
|
IN PUNICODE_STRING DeviceName OPTIONAL,
|
||
|
IN DEVICE_TYPE DeviceType,
|
||
|
IN ULONG DeviceCharacteristics,
|
||
|
IN BOOLEAN Exclusive,
|
||
|
IN PCUNICODE_STRING DefaultSDDLString,
|
||
|
IN LPCGUID DeviceClassGuid,
|
||
|
OUT PDEVICE_OBJECT *DeviceObject
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is a library wrapper for IoCreateDeviceSecure. It calls either
|
||
|
the internal library version of IoCreateDeviceSecure, or it calls the
|
||
|
native implementation in the Operating System.
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
See IoCreateDeviceSecure documentation.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
See IoCreateDeviceSecure documentation.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
if (WdmlibInitialized == FALSE) {
|
||
|
|
||
|
WdmlibInit();
|
||
|
}
|
||
|
|
||
|
return PfnIoCreateDeviceSecure(
|
||
|
DriverObject,
|
||
|
DeviceExtensionSize,
|
||
|
DeviceName,
|
||
|
DeviceType,
|
||
|
DeviceCharacteristics,
|
||
|
Exclusive,
|
||
|
DefaultSDDLString,
|
||
|
DeviceClassGuid,
|
||
|
DeviceObject
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
WdmlibRtlInitUnicodeStringEx(
|
||
|
OUT PUNICODE_STRING DestinationString,
|
||
|
IN PCWSTR SourceString OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
SIZE_T Length;
|
||
|
|
||
|
if (SourceString != NULL) {
|
||
|
|
||
|
Length = wcslen(SourceString);
|
||
|
|
||
|
//
|
||
|
// We are actually limited to 32765 characters since we want to store a
|
||
|
// meaningful MaximumLength also.
|
||
|
//
|
||
|
if (Length > (UNICODE_STRING_MAX_CHARS - 1)) {
|
||
|
|
||
|
return STATUS_NAME_TOO_LONG;
|
||
|
}
|
||
|
|
||
|
Length *= sizeof(WCHAR);
|
||
|
|
||
|
DestinationString->Length = (USHORT) Length;
|
||
|
DestinationString->MaximumLength = (USHORT) (Length + sizeof(WCHAR));
|
||
|
DestinationString->Buffer = (PWSTR) SourceString;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
DestinationString->Length = 0;
|
||
|
DestinationString->MaximumLength = 0;
|
||
|
DestinationString->Buffer = NULL;
|
||
|
}
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
WdmlibIoValidateDeviceIoControlAccess(
|
||
|
IN PIRP Irp,
|
||
|
IN ULONG RequiredAccess
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
|
||
|
This routine validates ioctl access bits based on granted access
|
||
|
information passed in the IRP. This routine is called by a driver to
|
||
|
validate IOCTL access bits for IOCTLs that were originally defined as
|
||
|
FILE_ANY_ACCESS and cannot be changed for compatibility reasons but really
|
||
|
has to be validated for read/write access.
|
||
|
|
||
|
This routine is actually a wrapper around the kernel function exported in
|
||
|
XPSP1 and .NET server versions of Windows. This wrapper allows a driver to
|
||
|
call this function on all versions of Windows starting with WIN2K. On
|
||
|
Windows platforms which don't support the kernel function
|
||
|
IoValidateDeviceIoControlAccess this wrapper reverts back to the old
|
||
|
behaviour. This wrapper allows a driver to have the same source code and
|
||
|
get the added benefit of the security check on newer operating systems.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
IRP - IRP for the device control
|
||
|
|
||
|
RequiredAccess - Is the expected access required by the driver. Should be
|
||
|
FILE_READ_ACCESS, FILE_WRITE_ACCESS or both.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Returns NTSTATUS
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// In older versions, assume access check succeeds
|
||
|
// to retain old behaviour.
|
||
|
//
|
||
|
|
||
|
if (PfnIoValidateDeviceIoControlAccess == NULL) {
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If the function is present use the appropriate access check.
|
||
|
//
|
||
|
|
||
|
return (PfnIoValidateDeviceIoControlAccess(Irp, RequiredAccess));
|
||
|
|
||
|
}
|