📄 driverentry.cpp
字号:
// Main program for LoadEz function driver: EZ-USB auto-loader program, Version 2.0
// Copyright (C) 2000 by John Hyde, USB Design By Example
// All rights reserved
//
// Derived using Walter Oney's WDM Wizard
// Copyright (C) 1999, 2000 by Walter Oney
// All rights reserved. Used with permission
//
// Also uses Walter Oney's Portable FileIO Subsystem
// Copyright (C) 1999, 2000 by Walter Oney
// All rights reserved. Used with permission
//
// Please send all comments, suggestions and error reports to John@USB-By-Example.com
/* Permission is hereby granted to:
(1) to merge this program code with other program material to create a derivative work and
(2) to republish this program, or any work derived, in whole or in part, therefrom, in compiled
object form only. Any other publication of this program, in any form, without the explicit
permission of the copyright holders is prohibited.
*/
#include "stddcls.h"
#include "driver.h"
#include <initguid.h>
#include "guids.h"
#include "usbdi.h"
#include "fileIO.h"
NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo);
VOID DriverUnload(PDRIVER_OBJECT fdo);
struct INIT_STRUCT : public _GENERIC_INIT_STRUCT {};
// Need a few global variables
const WCHAR HexCharacter[] = L"0123456789ABCDEF";
BOOLEAN win98 = FALSE;
///////////////////////////////////////////////////////////////////////////////
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
KdPrint((DRIVERNAME "Version 2.1. (John@USB-By-Example.com)\n"));
// We require GENERIC.SYS 1.3 or later.
if (GenericGetVersion() < 0x00010003) {
KdPrint((DRIVERNAME "Required version (=>1.3) of GENERIC.SYS not installed\n"));
return STATUS_UNSUCCESSFUL;
}
// See if we're running under Win98 or NT:
win98 = IsWin98();
KdPrint((DRIVERNAME "Running under Windows(R) "));
if (win98) KdPrint (("98\n")); else KdPrint(("NT\n"));
// Initialize function pointers. LoadEz only needs four
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
PAGED_CODE();
KdPrint((DRIVERNAME "Unloading Driver\n"));
}
///////////////////////////////////////////////////////////////////////////////
NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo) {
PAGED_CODE();
KdPrint((DRIVERNAME "Adding Device\n"));
NTSTATUS status;
// Create a functional device object to represent the hardware we're managing.
PDEVICE_OBJECT fdo;
ULONG dxsize = (sizeof(DEVICE_EXTENSION) + 7) & ~7;
ULONG xsize = dxsize + GetSizeofGenericExtension();
status = IoCreateDevice(DriverObject, xsize, NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &fdo);
if (!NT_SUCCESS(status)) {
KdPrint((DRIVERNAME "IoCreateDevice failed with status %X\n", status));
return status;
}
KdPrint((DRIVERNAME "Device Object (%8.8x) created\n", fdo));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
BOOLEAN ginit = FALSE;
// From this point forward, any error will have side effects that need to be cleaned up.
// Using a try-finally block allows easy modification without losing track of the side effects.
__try
{ // finish initialization
pdx->DeviceObject = fdo;
pdx->Pdo = pdo;
// Link our device object into the stack leading to the PDO
pdx->LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
if (!pdx->LowerDeviceObject) {
KdPrint((DRIVERNAME "IoAttachDeviceToDeviceStack failed\n"));
status = STATUS_DEVICE_REMOVED;
__leave;
} // can't attach device
// Set power management flags in the device object
fdo->Flags |= DO_POWER_PAGABLE;
// Initialize to use the GENERIC.SYS library
pdx->pgx = (PGENERIC_EXTENSION) ((PUCHAR) pdx + dxsize);
INIT_STRUCT gis;
RtlZeroMemory(&gis, sizeof(gis));
gis.Size = sizeof(gis);
gis.DeviceObject = fdo;
gis.Pdo = pdo;
gis.Ldo = pdx->LowerDeviceObject;
gis.RemoveLock = &pdx->RemoveLock;
gis.StartDevice = StartDevice;
gis.StopDevice = StopDevice;
gis.RemoveDevice = RemoveDevice;
RtlInitUnicodeString(&gis.DebugName, LDRIVERNAME);
status = InitializeGenericExtension(pdx->pgx, &gis);
if (!NT_SUCCESS(status)) {
KdPrint((DRIVERNAME "InitializeGenericExtension failed with status %X\n", status));
__leave;
}
ginit = TRUE;
GenericRegisterInterface(pdx->pgx, &GUID_INTERFACE_LOADEZ);
// Clear the "initializing" flag so that we can get IRPs
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
} // finish initialization
__finally
{ // cleanup side effects
if (!NT_SUCCESS(status)) { // need to cleanup
if (ginit) CleanupGenericExtension(pdx->pgx);
if (pdx->LowerDeviceObject) IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fdo);
}
}
return status;
}
VOID RemoveDevice(IN PDEVICE_OBJECT fdo) {
PAGED_CODE();
KdPrint((DRIVERNAME "Removing Device (%8.8x)\n", fdo));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS status;
if (pdx->LowerDeviceObject) IoDetachDevice(pdx->LowerDeviceObject);
if (pdx->HexFileBuffer) ExFreePool(pdx->HexFileBuffer);
IoDeleteDevice(fdo);
}
///////////////////////////////////////////////////////////////////////////////
// Plug-and-Play and Power Management is handled, for the most part, by GENERIC.SYS
NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp) {
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
return GenericDispatchPnp(pdx->pgx, Irp);
}
NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp) {
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
return GenericDispatchPower(pdx->pgx, Irp);
}
///////////////////////////////////////////////////////////////////////////////
// Declare the support functions
NTSTATUS SendUrbAndWait(PDEVICE_OBJECT fdo, PURB Urb) {
PAGED_CODE();
KEVENT Event;
IO_STATUS_BLOCK ioStatus;
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
pdx->LowerDeviceObject, NULL, 0, NULL, 0, TRUE, &Event, &ioStatus);
PIO_STACK_LOCATION Stack = IoGetNextIrpStackLocation(Irp);
Stack->Parameters.Others.Argument1 = (PVOID) Urb;
Status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = ioStatus.Status;
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -