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

📄 driver.cpp

📁 windows2000驱动编程源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//--

NTSTATUS DispatchCreate (
		IN PDEVICE_OBJECT	pDevObj,
		IN PIRP				pIrp			) {
#if DBG>=1
	DbgPrint("EVENTLOGEX: DispatchCreate\n");
#endif
	// Put an open handle message in the Event Log
	ReportEvent(
		LOG_LEVEL_DEBUG,
		MSG_OPENING_HANDLE,
		ERRORLOG_DISPATCH,
		(PVOID)pDevObj,
		pIrp,					// IRP
		NULL, 0,				// No dump data
		NULL, 0 );				// No strings

	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;
	NTSTATUS status = STATUS_SUCCESS;
	if (pDevExt->state != Started)
		status = STATUS_DEVICE_REMOVED;
	
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;	// no bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	return status;
}

//++
// Function:	DispatchClose
//
// Description:
//		Handles call from Win32 CreateHandle request
//		For this driver, frees any buffer
//		and logs an event
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failure code
//--

NTSTATUS DispatchClose (
		IN PDEVICE_OBJECT	pDevObj,
		IN PIRP				pIrp			) {
#if DBG>=1
	DbgPrint("EVENTLOGEX: DispatchClose\n");
#endif
	// Put a close handle message in the Event Log
	ReportEvent(
		LOG_LEVEL_DEBUG,
		MSG_CLOSING_HANDLE,
		ERRORLOG_DISPATCH,
		(PVOID)pDevObj,
		pIrp,					// IRP
		NULL, 0,				// No dump data
		NULL, 0 );				// No strings
	
	// Dig out the Device Extension from the Device object
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;
	if (pDevExt->deviceBuffer != NULL) {
		ExFreePool(pDevExt->deviceBuffer);
		pDevExt->deviceBuffer = NULL;
		pDevExt->deviceBufferSize = 0;
	}
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;	// no bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	return STATUS_SUCCESS;
}

//++
// Function:	DispatchCancel
//
// Description:
//		Handles canceled IRP
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failuer code
//--

VOID DispatchCancel (
		IN PDEVICE_OBJECT	pDevObj,
		IN PIRP				pIrp			) {

#if DBG>=1
	DbgPrint("EVENTLOGEX: IRP Canceled\n");
#endif
	
	// Just complete the IRP
	pIrp->IoStatus.Status = STATUS_CANCELLED;
	pIrp->IoStatus.Information = 0;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	IoStartNextPacket( pDevObj, TRUE );
}


//++
// Function:	DispatchWrite
//
// Description:
//		Handles call from Win32 WriteFile request
//		For this driver, starts the device by
//			indirectly invoking StartIo.
//			Also logs an event.
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failuer code
//--

NTSTATUS DispatchWrite (
		IN PDEVICE_OBJECT	pDevObj,
		IN PIRP				pIrp			) {
#if DBG>=1
	DbgPrint("EVENTLOGEX: Write Operation requested (DispatchWrite)\n");
#endif

	// The stack location contains the user buffer info
	PIO_STACK_LOCATION pIrpStack =
		IoGetCurrentIrpStackLocation( pIrp );
	// Determine the length of the request
	ULONG xferSize = pIrpStack->Parameters.Write.Length;
	// Obtain user buffer pointer
	PVOID userBuffer = pIrp->AssociatedIrp.SystemBuffer;
	// Put a write request message in the Event Log
	ReportEvent(
		LOG_LEVEL_DEBUG,
		MSG_WRITING_DATA,
		ERRORLOG_DISPATCH,
		(PVOID)pDevObj,
		pIrp,					// IRP
		// Dump data is the data written
		(ULONG*)userBuffer, xferSize/sizeof(ULONG),
		NULL, 0 );				// No strings
	
	// Start the I/O
	IoMarkIrpPending( pIrp );
	IoStartPacket( pDevObj, pIrp, 0, DispatchCancel);
	return STATUS_PENDING;
}

//++
// Function:	DispatchRead
//
// Description:
//		Handles call from Win32 ReadFile request
//		For this driver, xfers pool buffer to user
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failuer code
//--

NTSTATUS DispatchRead (
		IN PDEVICE_OBJECT	pDevObj,
		IN PIRP				pIrp			) {
	
#if DBG>=1
	DbgPrint("EVENTLOGEX: Read Operation requested (DispatchRead)\n");
#endif
	
	NTSTATUS status = STATUS_SUCCESS;
	PVOID userBuffer;
	ULONG xferSize;
	// The stack location contains the user buffer info
	PIO_STACK_LOCATION pIrpStack =
		IoGetCurrentIrpStackLocation( pIrp );
	// Dig out the Device Extension from the Device object
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;
	// Determine the length of the request
	xferSize = pIrpStack->Parameters.Read.Length;
	// Obtain user buffer pointer
	userBuffer = pIrp->AssociatedIrp.SystemBuffer;

	// Put a read request message in the Event Log
	ReportEvent(
		LOG_LEVEL_DEBUG,
		MSG_READING_DATA,
		ERRORLOG_DISPATCH,
		(PVOID)pDevObj,
		pIrp,					// IRP
		// Dump data is the data read
		(ULONG*)pDevExt->deviceBuffer, 
		pDevExt->deviceBufferSize/sizeof(ULONG),
		NULL, 0 );				// No strings

	// Don't transfer more than the user's request
	xferSize = (xferSize < pDevExt->deviceBufferSize) ?
				xferSize : pDevExt->deviceBufferSize;
	// Now copy the pool buffer into user space
	RtlCopyMemory( userBuffer, pDevExt->deviceBuffer,
							xferSize );
	// Free the temporary pool buffer
	ExFreePool( pDevExt->deviceBuffer );
	pDevExt->deviceBuffer = NULL;
	pDevExt->deviceBufferSize = 0;

	// Now complete the IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = xferSize;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	return status;
}

//++
// Function:
//		TransmitByte
//
// Description:
//		This function sends one character to the device
//		The polling timer is then started which will
//		eventually invoke the PollingTimerDpc.
//		If no characters remain to be transmitted, return FALSE.
//
// Arguments:
//		Pointer to the Device Extension
//
// Return Value:
//		TRUE - one more byte transmitted
//		FALSE - no more bytes remain to be transmitted
//--
 BOOLEAN TransmitByte( 
		IN PVOID pArg ) {
	
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pArg;
	 // If all the bytes have been sent, just quit
	if( pDevExt->xferCount >= pDevExt->maxXferCount)
		return FALSE;

	// A transfer is happening.
	PDEVICE_OBJECT pDevObj =
		pDevExt->pDevice;
	PIRP pIrp = pDevObj->CurrentIrp;
	// Obtain user buffer pointer
	PUCHAR userBuffer = (PUCHAR)
		pIrp->AssociatedIrp.SystemBuffer;
	UCHAR nextByte =
		userBuffer[pDevExt->xferCount];

	// Now send it...
#if DBG>=2
	DbgPrint("EVENTLOGEX: TransmitByte: Sending 0x%02X to port %X\n",
				nextByte, pDevExt->portBase);
#endif
	// The loopback connector requires us to do
	// some bizzare work.
	// Bit 0 of the data is sent as bit 0 of Port data.
	WriteData( pDevExt, nextByte & 1);
	// It will be read in Status bit 3
	// Bits 1-3 of the data are sent as bits 0,1, & 3
	// of the Control register.
	// Control bits 0 & 1 are inverted.
	UCHAR bits = (nextByte & 0x8) +
				 ((nextByte & 0x6)>>1);
	bits ^= 0x3;	// Invert the 2 control bits (0 & 1)
	// These bits will be read in Status bits 4,5, & 7
	WriteControl( pDevExt, bits | CTL_DEFAULT);

	// Now read the data from the loopback
	UCHAR status =
		ReadStatus( pDevExt );

	// Format the nibble into the upper half of the byte
	UCHAR readByte =
		((status & 0x8)<< 1) |
		((status & 0x30)<<1) |
		(status & 0x80);
	pDevExt->deviceBuffer[pDevExt->xferCount++] =
		readByte;
#if DBG>=2
	DbgPrint("EVENTLOGEX: TransmitByte read character: 0x%03X\n",
				readByte);
#endif

	// Start the polling timer
#if DBG>=2
	DbgPrint("EVENTLOGEX: TransmitByte starting timer\n");
#endif
	KeSetTimer(
		&pDevExt->pollingTimer,
		pDevExt->pollingInterval,
		&pDevExt->pollingDPC );


	return TRUE;
}

//++
// Function:
//		StartIo
//
// Description:
//		This function is responsible initiating the
//		actual data transfer. The ultimate result
//		should be a started Timer object.
//
// Arguments:
//		Pointer to the Device object
//		Pointer to the IRP for this request
//
// Return Value:
//		(None)
//--
VOID
StartIo(
	IN PDEVICE_OBJECT pDevObj,
	IN PIRP pIrp
	) {
#if DBG>=1
	DbgPrint("EVENTLOGEX: Start I/O Operation\n");
#endif
	
	PIO_STACK_LOCATION	pIrpStack = 
		IoGetCurrentIrpStackLocation( pIrp );
		
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;
	PUCHAR userBuffer;
	ULONG xferSize;
		
	switch( pIrpStack->MajorFunction ) {
		
		// Use a SynchCritSection routine to
		// start the write operation...
		case IRP_MJ_WRITE:
			// Set up counts and byte pointer
			pDevExt->maxXferCount = 
				pIrpStack->Parameters.Write.Length;
			pDevExt->xferCount = 0;

			// Since we processing a new Write request,
			// free up any old buffer
			if (pDevExt->deviceBuffer != NULL) {
				ExFreePool(pDevExt->deviceBuffer);
				pDevExt->deviceBuffer = NULL;
				pDevExt->deviceBufferSize = 0;
			}

			// Determine the length of the request
			xferSize = 
				pIrpStack->Parameters.Write.Length;
			// Obtain user buffer pointer
			userBuffer = (PUCHAR)
				pIrp->AssociatedIrp.SystemBuffer;

			// Allocate the new buffer
			pDevExt->deviceBuffer = (PUCHAR)
				ExAllocatePool( PagedPool, xferSize );
			if (pDevExt->deviceBuffer == NULL) {
				// buffer didn't allocate???
				// fail the IRP
				pIrp->IoStatus.Status = 
					STATUS_INSUFFICIENT_RESOURCES;
				pIrp->IoStatus.Information = 0;
				IoCompleteRequest( pIrp, IO_NO_INCREMENT );
				IoStartNextPacket( pDevObj, FALSE );
			}
			pDevExt->deviceBufferSize = xferSize;

			// Try to send the first byte of data.
#if DBG>=1
	DbgPrint("EVENTLOGEX: StartIO: Transmitting first byte of %d\n", pDevExt->deviceBufferSize);
#endif
			TransmitByte( pDevExt );
			break;
		//
		// Should never get here -- just get rid
		// of the packet...
		//	
		default:
			pIrp->IoStatus.Status =
						STATUS_NOT_SUPPORTED;
			pIrp->IoStatus.Information = 0;
			IoCompleteRequest(
				pIrp,
				IO_NO_INCREMENT );
			IoStartNextPacket( pDevObj, FALSE );
			break;
	}
}

//++
// Function:
//		PollingTimerDpc
//
// Description:
//		This function is the DPC routine called
//		each time the timer "ticks".
//		The routine checks on the device - 
//		if room available, more data is sent
//
// Arguments:
//		Pointer to the Device object
//		Pointer to the IRP for this request
//
// Return Value:
//		(None)
//--
VOID PollingTimerDpc( IN PKDPC pDpc,
					  IN PVOID pContext,
					  IN PVOID SysArg1,
					  IN PVOID SysArg2 ) {

#if DBG>=1
	DbgPrint("EVENTLOGEX: PollingTimerDpc Fired\n");
#endif
	PDEVICE_OBJECT pDevObj = (PDEVICE_OBJECT)
		pContext;
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;

	// Try to send more data
	if (!TransmitByte( pDevExt ) ) {
		// Transfer complete (normal or error)
		// Complete the IRP appropriately
#if DBG>=1
	DbgPrint("EVENTLOGEX: PollingTimerDpc Completing IRP\n");
#endif
		PIRP pIrp = pDevObj->CurrentIrp;
		pIrp->IoStatus.Information =
			pDevExt->xferCount;

		// Figure out what the final status should be
		pIrp->IoStatus.Status = STATUS_SUCCESS;
		// If an error occurred, Status would change

		// Now Complete the IRP
		IoCompleteRequest( pIrp, IO_PARALLEL_INCREMENT );

		// And request another IRP
		IoStartNextPacket( pDevObj, FALSE);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -