📄 driverentry.cpp
字号:
// Main program for LoadEz function driver: EZ-USB auto-loader program, Version 2.0
//
// Copyright (C) 2001, Intel Corporation
// All rights reserved.
// Permission is hereby granted to merge this program code with other program
// material to create a derivative work. This derivative work may be distributed
// in compiled object form only. Any other publication of this program, in any form,
// without the explicit permission of the copyright holders is prohibited.
//
// Send questions and comments to John.Hyde@intel.com
//
// 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
//
#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.Hyde@intel.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 2000:
win98 = IsWin98();
KdPrint((DRIVERNAME "Running under Windows(R) "));
if (win98) KdPrint (("98\n")); else KdPrint(("2000\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;
}
NTSTATUS GetIdentity(PDEVICE_OBJECT fdo) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -