📄 driverentry.cpp
字号:
NTSTATUS GetIdentity(PDEVICE_OBJECT fdo) {
PAGED_CODE();
// Need to discover the VID and PID currently in use
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
USB_DEVICE_DESCRIPTOR Descriptor;
NTSTATUS Status;
URB LocalUrb;
PURB Urb = &LocalUrb;
RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
Urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
Urb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(Descriptor);
Urb->UrbControlDescriptorRequest.TransferBuffer = &Descriptor;
Urb->UrbControlDescriptorRequest.TransferBufferMDL = NULL;
Urb->UrbControlDescriptorRequest.DescriptorType = 1;
Status = SendUrbAndWait(fdo, Urb);
pdx->VID = Descriptor.idVendor;
pdx->PID = Descriptor.idProduct;
KdPrint((DRIVERNAME "Current VID = %4.4x and PID = %4.4x\n", pdx->VID, pdx->PID));
return Status;
}
NTSTATUS SetEZUSBMemory(PDEVICE_OBJECT fdo, USHORT StartLocation, USHORT Length, PVOID DataBytes) {
PAGED_CODE();
// Need to build a Vendor Request and send it to the development board
URB LocalUrb;
PURB Urb = &LocalUrb;
RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
Urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
Urb->UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
Urb->UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_OUT;
Urb->UrbControlVendorClassRequest.TransferBufferLength = Length;
Urb->UrbControlVendorClassRequest.TransferBuffer = DataBytes;
Urb->UrbControlVendorClassRequest.TransferBufferMDL = NULL;
Urb->UrbControlVendorClassRequest.Request = 0x0A0; // "Anchor Load"
Urb->UrbControlVendorClassRequest.Value = StartLocation;
return SendUrbAndWait(fdo, Urb);
}
NTSTATUS EZUSB_Reset(PDEVICE_OBJECT fdo, UCHAR ResetBit) {
PAGED_CODE();
// EZUSB_Reset is a special case of SetEZUSBMemory
return SetEZUSBMemory(fdo, 0x07F92, 1, &ResetBit);
}
NTSTATUS GetFirmware(PDEVICE_OBJECT fdo) {
PAGED_CODE();
// Open the Firmware file and load it into a local buffer
// First create the name of the file that we need to open
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS Status;
Status = GetIdentity(fdo);
if (Status != STATUS_SUCCESS) {
KdPrint((DRIVERNAME "Could not get VID and PID from IO device\n"));
return Status;
}
// Create a filename from the current VID and PID
WCHAR Filename[] = L"\\SystemRoot\\system32\\drivers\\vvvvpppp.hex";
Filename[29] = HexCharacter[(pdx->VID >> 12) & 0x0F];
Filename[30] = HexCharacter[(pdx->VID >> 8) & 0x0F];
Filename[31] = HexCharacter[(pdx->VID >> 4) & 0x0F];
Filename[32] = HexCharacter[pdx->VID & 0x0F];
Filename[33] = HexCharacter[(pdx->PID >> 12) & 0x0F];
Filename[34] = HexCharacter[(pdx->PID >> 8) & 0x0F];
Filename[35] = HexCharacter[(pdx->PID >> 4) & 0x0F];
Filename[36] = HexCharacter[pdx->PID & 0x0F];
// Need to use Walter Oney's portable file subsystem here since this driver may be running before
// the file system is running
HANDLE FileHandle;
Status = OpenFile(Filename, TRUE, &FileHandle);
KdPrint((DRIVERNAME "OpenFile returned with status = %8.8x\n", Status));
if (!NT_SUCCESS(Status)) return Status;
pdx->HexFileLength = (ULONG) GetFileSize(FileHandle);
pdx->HexFileBuffer = (PCHAR) ExAllocatePool(NonPagedPool, pdx->HexFileLength);
if (!pdx->HexFileBuffer) return STATUS_NO_MEMORY;
ULONG BytesReturned;
Status = ReadFile(FileHandle, pdx->HexFileBuffer, pdx->HexFileLength, &BytesReturned);
if (!NT_SUCCESS(Status)) KdPrint((DRIVERNAME "ReadFile failed with status = %8.8x\n", Status));
else KdPrint((DRIVERNAME "ReadFile returned %d bytes\n", BytesReturned));
CloseFile(FileHandle);
return Status;
}
bool GetNextCharacter(PDEVICE_OBJECT fdo, PCHAR BufferPtr) {
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
*BufferPtr = pdx->HexFileBuffer[pdx->ByteOffset];
if (pdx->ByteOffset++ < pdx->HexFileLength) return true;
return false;
}
bool GetNextLine(PDEVICE_OBJECT fdo, PCHAR BufferPtr) {
PAGED_CODE();
// Get the next line from the input file, return FALSE if EOF
// First find the ':'
do { if (!GetNextCharacter(fdo, BufferPtr)) return false; } while (*BufferPtr != ':');
// Then read until the end of the line
do { if (!GetNextCharacter(fdo, ++BufferPtr)) return false; } while (*BufferPtr != 10); // EOL
return true;
}
SHORT value(char Entry) {
PAGED_CODE();
for (SHORT i = 0; i<sizeof(HexCharacter); i++) {if (Entry == HexCharacter[i]) return i;}
KdPrint((DRIVERNAME "Invalid Hex character '%2.2x' in file\n", Entry)); return 0;
}
///////////////////////////////////////////////////////////////////////////////
// This is where the work is done in this device driver
NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated) {
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
KdPrint((DRIVERNAME "Starting IO device\n"));
// Starting the device involves downloading firmware into the EZ-USB component
// Open the HEX file and read it into a local buffer
NTSTATUS Status = GetFirmware(fdo);
if (Status != STATUS_SUCCESS) {
KdPrint((DRIVERNAME "Could not get device firmware (%8.8x)\n", Status));
return Status;
}
// Loading is done in two passes since AnchorLoad only operates on internal memory addresses
// Load external memory first using a helper "mover" program
// First ensure that the EZ-USB 8051 is RESET before downloading
Status = EZUSB_Reset(fdo, 1);
if (Status != STATUS_SUCCESS) return Status;
// Since we are still here (previous line did not return) no need to check this Status further
UCHAR MoverCode[] = // 8051 Object code for the Mover program
{0x90, 0x7F, 0x9E, 0x74, 0x0C0, 0x0F0, 0x90, 0x7F, 0x95, 0x0F0, 0x75, 0x92, 0,
0x78, 0x24, 0x0E2, 0x60, 0x10, 0x0FF, 8, 0x0E2, 0xF5, 0x83, 8, 0x0E2, 0x0F5, 0x82,
8, 8, 0x0E2, 0x0F0, 0x0A3, 0x0DF, 0x0FA, 0x80, 0x0FE, 0x0F, 0x0FF, 0x0F0, 0, 0x4D,
0x6F, 0x76, 0x65, 0x72, 0x20, 0x49, 0x6E, 0x73, 0x74, 0x61, 0x6C, 0x6C, 0x65, 0x64};
SetEZUSBMemory(fdo, 0, sizeof(MoverCode), MoverCode);
EZUSB_Reset(fdo, 0); // unRESET the EZUSB CPU so that it executes this code
UCHAR Record[40];
char Buffer[80];
int Pass, i;
for (Pass = 1; Pass<3; Pass++) {
pdx->ByteOffset = 0; // Start at the beginning of the Hex data file
EZUSB_Reset(fdo, 1); // Stop the EZUSB CPU
USHORT ByteCount, LoadAddress, RecordType;
// Read the HEX records one at a time and load them onto the development board
while (GetNextLine(fdo, Buffer)) {
ByteCount = Record[0] = (value(Buffer[1]) << 4) + value(Buffer[2]);
for (i = 1; i<ByteCount+4; i++) Record[i] = (value(Buffer[1+i+i]) << 4) + value(Buffer[2+i+i]);;
LoadAddress = (Record[1] << 8) + Record[2];
RecordType = Record[3];
if (RecordType == 0) {
// A content record (=0) has been located
if ((Pass == 1) && (LoadAddress > 0x1FFF)) {
// KdPrint((DRIVERNAME "Loading %2.2xH bytes at upper address %4.4xH\n", ByteCount, LoadAddress));
SetEZUSBMemory(fdo, 0x24, ByteCount+4, Record);
EZUSB_Reset(fdo, 0); // unRESET EZUSB CPU so that it will move the data
EZUSB_Reset(fdo, 1); // Stop the EZUSB CPU again
}
if ((Pass == 2) && (LoadAddress + ByteCount) < 0x1B3F) {
// KdPrint((DRIVERNAME "Loading %2.2xH bytes at lower address %4.4xH\n", ByteCount, LoadAddress));
SetEZUSBMemory(fdo, LoadAddress, ByteCount, &Record[4]);
}
}
}
}
// All done, allow the EZ-USB CPU to 'renumerate'
KdPrint((DRIVERNAME "Firmware downloaded!\n"));
EZUSB_Reset(fdo, 0);
// Interesting philosophical point - the original device that caused this driver to run no longer
// exists, since the driver has downloaded it with a new identity.
// It would be preferrable to return UNSUCCESSFUL so the OS will mark us STOPPED. (this also prevents "Surprize Removal" messages on Win2K)
// However, the USDB.SYS driver will Suspend our I/O device if we do. So return SUCCESS
return STATUS_SUCCESS;
}
VOID StopDevice(IN PDEVICE_OBJECT fdo, BOOLEAN oktouch /* = FALSE */) {
PAGED_CODE();
KdPrint((DRIVERNAME "Device Stopped\n"));
}
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
extern "C" void __declspec(naked) __cdecl _chkesp() {
_asm je okay
ASSERT(!DRIVERNAME "Stack pointer mismatch!");
okay:
_asm ret
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -