📄 init.c
字号:
/*++
Module Name:
Init.c
Abstract:
Main module
Environment:
kernel mode only
Notes:
Copyright (c) 1997-2000 Maverick Corporation. All Rights Reserved.
Revision History:
04/26/00: created
--*/
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "usbcom.h"
#include "GUID829.h"
static ULONG UsbCom_CallUSBD_Counter = 0;
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
DriverObject - pointer to the driver object
RegistryPath - pointer to a unicode string representing the path
to driver-specific key in the registry
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
//NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
BOOLEAN fRes;
DbgPrint ("-----------------------------------------------------------\n");
DbgPrint ("Maintained by CodeMachine Incorporated (www.codemachine.com)\n");
DbgPrint ("Module %s built on %s at %s\n", "plpu-s2k" , __DATE__, __TIME__ );
DbgPrint ("-----------------------------------------------------------\n");
DbgPrint("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer );
//
// Create dispatch points for create, close, unload
DriverObject->MajorFunction[IRP_MJ_CREATE] = UsbCom_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = UsbCom_Close;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UsbCom_Cleanup;
DriverObject->DriverUnload = UsbCom_Unload;
// User mode DeviceIoControl() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UsbCom_ProcessIOCTL;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]
= SerialInternalIoControl; // Added by Henry
// User mode ReadFile()/WriteFile() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_WRITE] = SerialWrite; // Modified by Henry
DriverObject->MajorFunction[IRP_MJ_READ] = SerialRead; // Modified by Henry
// routines for handling system PNP and power management requests
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = UsbCom_ProcessSysControlIrp;
DriverObject->MajorFunction[IRP_MJ_PNP] = UsbCom_ProcessPnPIrp;
DriverObject->MajorFunction[IRP_MJ_POWER] = UsbCom_ProcessPowerIrp;
// The Functional Device Object (FDO) will not be created for PNP devices until
// this routine is called upon device plug-in.
DriverObject->DriverExtension->AddDevice = UsbCom_PnPAddDevice;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]
= SerialQueryInformationFile;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]
= SerialSetInformationFile;
DbgPrint("exiting DriverEntry \n");
return STATUS_SUCCESS;
}
NTSTATUS
UsbCom_ProcessSysControlIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Main dispatch table routine for IRP_MJ_SYSTEM_CONTROL
We basically just pass these down to the PDO
Arguments:
DeviceObject - pointer to FDO device object
Irp - pointer to an I/O Request Packet
Return Value:
Status returned from lower driver
--*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
NTSTATUS waitStatus;
PDEVICE_OBJECT stackDeviceObject;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
stackDeviceObject = deviceExtension->TopOfStackDeviceObject;
DbgPrint("enter UsbCom_ProcessSysControlIrp()\n");
UsbCom_IncrementIoCount(DeviceObject);
UsbCom_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction );
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
UsbCom_DecrementIoCount(DeviceObject);
DbgPrint("UsbCom_ProcessSysControlIrp() Exit UsbCom_ProcessSysControlIrp %x\n", ntStatus);
return ntStatus;
}
VOID
UsbCom_Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object
Return Value:
--*/
{
DbgPrint("enter UsbCom_Unload\n");
//
// Free any global resources allocated
// in DriverEntry.
// We have few or none because for a PNP device, almost all
// allocation is done in PnpAddDevice() and all freeing
// while handling IRP_MN_REMOVE_DEVICE:
//UsbCom_ASSERT( gExAllocCount == 0 );
DbgPrint("exit UsbCom_Unload\n");
}
NTSTATUS
UsbCom_SymbolicLink(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PUNICODE_STRING deviceLinkUnicodeString
)
/*++
Routine Description:
This routine is called to create and initialize
a GUID-based symbolic link to our device to be used to open/create
instances of us from user mode.
Called from UsbCom_CreateDeviceObject() to create the link.
Arguments:
DeviceObject - pointer to our Physical Device Object ( PDO )
deviceLinkUnicodeString - Points to a unicode string structure allocated by the caller.
If this routine is successful, it initializes the unicode string and allocates
the string buffer containing the kernel-mode path to the symbolic link for this
device interface.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// Create the symbolic link
// IoRegisterDeviceInterface registers device functionality (a device interface)
// that a driver will enable for use by applications or other system components.
ntStatus = IoRegisterDeviceInterface(
DeviceObject,
(LPGUID)&GUID_CLASS_COMPORT,
NULL,
deviceLinkUnicodeString);
if (NT_SUCCESS(ntStatus)) {
// IoSetDeviceInterfaceState enables or disables a previously
// registered device interface. Applications and other system components
// can open only interfaces that are enabled.
ntStatus = IoSetDeviceInterfaceState(deviceLinkUnicodeString, TRUE);
if(NT_SUCCESS(ntStatus))
DbgPrint("SUCCEEDED IoSetDeviceInterfaceState()\n");
else
DbgPrint("FAILED to IoSetDeviceInterfaceState()\n");
}
else
DbgPrint("FAILED to IoRegisterDeviceInterface()\n");
return ntStatus;
}
NTSTATUS
UsbCom_CreateDeviceObject(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject,
IN PDEVICE_OBJECT *DeviceObject
)
/*++
Routine Description:
Creates a Functional DeviceObject
Arguments:
DriverObject - pointer to the driver object for device
DeviceObject - pointer to DeviceObject pointer to return
created device object.
Instance - instance of the device create.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus;
UNICODE_STRING deviceLinkUnicodeString, deviceObjName, linkName;
PDEVICE_EXTENSION deviceExtension;
PWCHAR PhysicalDeviceName, pRegName;
ULONG nameLength, regLength;
HANDLE keyHandle;
USHORT i;
DbgPrint("enter UsbCom_CreateDeviceObject() \n");
*DeviceObject = NULL;
pRegName = NULL;
ntStatus = IoOpenDeviceRegistryKey(PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_READ, &keyHandle);
//
// Check to see if we are allowed to do external naming; if not,
// then we just return success
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("Couldn't open registry!\n");
goto ErrorFreeBuffer;
}
pRegName = ExAllocatePool(PagedPool, SYMBOLIC_NAME_LENGTH * sizeof(WCHAR)
+ sizeof(WCHAR));
if (pRegName == NULL) {
DbgPrint("Couldn't allocate memory for pRegName\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
ZwClose(keyHandle);
goto ErrorFreeBuffer;
}
//
// Fetch PortName which contains the suggested REG_SZ symbolic name.
//
regLength = SYMBOLIC_NAME_LENGTH * sizeof(WCHAR);
ntStatus = SerialGetRegistryKeyValue(keyHandle, L"PortName",
sizeof(L"PortName"), pRegName,
®Length);
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("Getting PortName failed - %x\n", ntStatus);
ZwClose (keyHandle);
goto ErrorFreeBuffer;
}
ZwClose (keyHandle);
//
// Zero out allocated memory pointers so we know if they must be freed
//
RtlZeroMemory(&deviceObjName, sizeof(UNICODE_STRING));
RtlZeroMemory(&deviceLinkUnicodeString, sizeof(UNICODE_STRING));
RtlZeroMemory(&linkName, sizeof(UNICODE_STRING));
// BEGIN CODEMACHINE
// change the way device names are allocated and used
/*
deviceObjName.MaximumLength = DEVICE_OBJECT_NAME_LENGTH * sizeof(WCHAR);
deviceObjName.Buffer = ExAllocatePool(PagedPool, deviceObjName.MaximumLength
+ sizeof(WCHAR));
if (deviceObjName.Buffer == NULL) {
DbgPrint("Couldn't allocate memory for device object name\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorFreeBuffer;
}
RtlZeroMemory(deviceObjName.Buffer, deviceObjName.MaximumLength
+ sizeof(WCHAR));
RtlAppendUnicodeToString(&deviceObjName, L"\\Device\\SOPE1USB0");
//
// Create the device object
//
ntStatus = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION),
&deviceObjName, FILE_DEVICE_SERIAL_PORT,
FILE_DEVICE_SECURE_OPEN, TRUE, DeviceObject);
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("UsbCom_CreateDeviceObject() IoCreateDevice() FAILED\n");
goto ErrorFreeBuffer;
}
*/
{
ANSI_STRING DeviceNameAnsi;
ULONG DeviceNumber;
CHAR DeviceNameAscii[32];
for (DeviceNumber = 1; ; DeviceNumber++) {
sprintf ( DeviceNameAscii, "\\Device\\SOPE1USB%d", DeviceNumber );
RtlInitAnsiString ( &DeviceNameAnsi, DeviceNameAscii );
if ( ( ntStatus = RtlAnsiStringToUnicodeString ( &deviceObjName, &DeviceNameAnsi, TRUE ) ) != STATUS_SUCCESS ) {
DbgPrint("UsbCom_CreateDeviceObject():RtlAnsiStringToUnicodeString() PDO=%08x %s : FAIL=%08x\n",
PhysicalDeviceObject, DeviceNameAscii, ntStatus );
goto ErrorFreeBuffer;
}
ntStatus = IoCreateDevice (
DriverObject,
sizeof(DEVICE_EXTENSION),
&deviceObjName,
FILE_DEVICE_SERIAL_PORT,
0,
FALSE,
DeviceObject );
if ( NT_SUCCESS ( ntStatus ) ) {
break;
}
RtlFreeUnicodeString ( &deviceObjName );
if ( ntStatus != STATUS_OBJECT_NAME_COLLISION ) {
DbgPrint("UsbCom_CreateDeviceObject() IoCreateDevice() PDO=%08x (%wZ) FAIL=%08x\n",
PhysicalDeviceObject, &deviceObjName, ntStatus );
goto ErrorFreeBuffer;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -