⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driverentry.cpp

📁 USB开发固件程序详细.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
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 + -