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

📄 phantomeppsrlapi.c

📁 用Ardence RTX SDK开发的EPP并口驱动程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
	ucb.m_SoftwareTimerEnabled = TRUE;
	
	// Fix Me:
	// The following hardcoded values miraculously work, even without
	// setting ExSetTimerResolution. These values are based on a 1024 Hz clock.

	if (SoftwareTimerPeriodMs == 1)
	{
		ucb.m_SoftwareTimerDueTime.QuadPart = 9765;
	}
	else if (SoftwareTimerPeriodMs == 2)
	{
		ucb.m_SoftwareTimerDueTime.QuadPart = 19530;
	}
	else
	{
		status = STATUS_UNSUCCESSFUL;
		goto FINISH;
	}

	//RtPrintf("Setting software timer: %d\n", ucb.m_SoftwareTimerDueTime.QuadPart);
	RtSetTimerRelative(ucb.m_SoftwareTimer, &ucb.m_SoftwareTimerDueTime,NULL);

FINISH:

	//KeReleaseSpinLock(&pDeviceExtension->m_SpinLock, restoreIrql);

	return status;
}


DWORD EnableTimerEvent(HANDLE hEvent)
{
	HANDLE   pEventObject = NULL;
	DWORD    status = STATUS_SUCCESS;

	// Don't proceed if the previous timer event has not been disabled
	if (ucb.m_SignalEventObject != NULL)
	{
		//RtPrintf("PHANTOMEPP:utilityEnableTimerEvent: Need to disable previous event first\n");
		return STATUS_UNSUCCESSFUL;
	}

	// First attempt to grab a reference to the requisite object handle
	//ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );        

	//status = ObReferenceObjectByHandle(
	//	hEvent,
	//	OBJECT_TYPE_ALL_ACCESS,
	//	NULL,
	//	KernelMode,
	//	&pEventObject, 
	//	NULL);

	//if (!status)
	//{
	//	//RtPrintf("PHANTOMEPP:utilityEnableTimerEvent: Failed to reference event by handle\n");
	//	return status;
	//}

	//if (pEventObject == NULL)
	//{
	//	//RtPrintf("PHANTOMEPP:utilityEnableTimerEvent: Null event object\n");
	//	return STATUS_UNSUCCESSFUL;  
	//}

	// Now we can raise IRQL and manage the assignment
	//KeAcquireSpinLock(&pDeviceExtension->m_SpinLock, &restoreIrql);

	// Now assign the new event handle and event object
	ucb.m_SignalEventHandle = hEvent;
	ucb.m_SignalEventObject = hEvent;
	ucb.m_SignalEventCount = 0;

	//RtPrintf("Signal event object set\n");

	//KeReleaseSpinLock(&pDeviceExtension->m_SpinLock, restoreIrql);

	return status;
}


int RTFCNDCL DriverSoftwareTimerDPCRoutine(PVOID unused)
{

	//KeAcquireSpinLockAtDpcLevel(&pDeviceExtension->m_SpinLock);

	if (ucb.m_SignalEventObject != NULL)
	{
		////RtPrintf("PHANTOMEPP: set timer event signaled.\n");
		RtSetEvent(ucb.m_SignalEventObject);
	}	

	// Increment a running counter of the number of times the event has been signalled
	ucb.m_SignalEventCount++;

	if (ucb.m_SoftwareTimerEnabled)
	{
		////RtPrintf("PHANTOMEPP: set next timer event relative.\n");
		RtSetTimerRelative(ucb.m_SoftwareTimer,&ucb.m_SoftwareTimerDueTime,NULL);
	}

	//KeReleaseSpinLockFromDpcLevel(&pDeviceExtension->m_SpinLock);

	return STATUS_SUCCESS;
}



DWORD DisableTimerEvent()
{
	//KIRQL       restoreIrql;

	// Now we can raise IRQL and manage the assignment
	//KeAcquireSpinLock(&pDeviceExtension->m_SpinLock, &restoreIrql);

	// First deference any previous event object
	if (ucb.m_SignalEventObject != NULL)
	{
		//ObDereferenceObject(pDeviceExtension->m_SignalEventObject);
		
	}

	// Now clear the event handle and event object
	ucb.m_SignalEventHandle = NULL;
	ucb.m_SignalEventObject = NULL;

	//KeReleaseSpinLock(&pDeviceExtension->m_SpinLock, restoreIrql);

	return STATUS_SUCCESS;
}

DWORD DisableSoftwareTimerEvent()
{
	//KIRQL         restoreIrql;
	DWORD		    Timeout;
	LARGE_INTEGER	TimeRemaining;

	// Now we can raise IRQL and manage the assignment
	//KeAcquireSpinLock(&pDeviceExtension->m_SpinLock, &restoreIrql);

	if (ucb.m_SoftwareTimerEnabled)
	{       
		ucb.m_SoftwareTimerEnabled = FALSE;

		//RtPrintf("PHANTOMEPP: cancel timer.\n");
		RtCancelTimer(ucb.m_SoftwareTimer,&TimeRemaining);

		// Wait for the timer DPC to finish executing
		Timeout = 10000; // 1 ms
		RtWaitForSingleObject(ucb.m_SignalEventObject,Timeout);
	}

	//KeReleaseSpinLock(&pDeviceExtension->m_SpinLock, restoreIrql);

	// Complete the disabling process by dereferencing the timer event
	return DisableTimerEvent();
}


DWORD EnableInterrupts()
{
	DWORD status = STATUS_SUCCESS;
	PUCHAR nPortBase = ucb.baseAddress;

	if (ucb.m_ParPortInterruptAllocated == TRUE)
	{
		//RtPrintf("PHANTOMEPP:utilityEnableInterrupts interrupt already allocated\n");
		return STATUS_SUCCESS;
	}       

	//RtPrintf("PHANTOMEPP:Connecting interrupt to ParPort\n");

	// Make sure that interrupts are allowed by the port. Microsoft disables
	// this by default.
	status = RegistryEnableInterrupts(&ucb.m_RegistryEnableInterruptsChanged);

	if (!status)
	{
		//RtPrintf("PHANTOMEPP:RegistryEnableInterrupts Failed\n");

		goto FINISH;
	}

	// Connect to the ParPort interrupt line
	//.....

	// Enable parallel port IRQ via ACK line
	WriteControl(nPortBase, ReadControl(nPortBase) | 0x10);

	ucb.m_ParPortInterruptAllocated = TRUE;

FINISH:

	return status;
}

DWORD DisableInterrupts()
{
	DWORD  status = STATUS_SUCCESS;
	PUCHAR nPortBase = ucb.baseAddress;

	if(ucb.m_ParPortInterruptAllocated == TRUE)
	{
		//RtPrintf("PHANTOMEPP:Disconnect interrupt from ParPort\n");

		// Disable parallel port IRQ via ACK line
		WriteControl(nPortBase, ReadControl(nPortBase) & ~0x10);

		//status = utilityBusIoControl(pDeviceExtension->m_ParPortDeviceObject,
		//	IOCTL_INTERNAL_PARALLEL_DISCONNECT_INTERRUPT,
		//	&pDeviceExtension->m_ParPortInterruptServiceRoutine,
		//	sizeof(pDeviceExtension->m_ParPortInterruptServiceRoutine),
		//	NULL,
		//	0);

		if (status == STATUS_SUCCESS)
		{
			ucb.m_ParPortInterruptAllocated = FALSE;
		}
		else
		{
			//RtPrintf("PHANTOMEPP:Unexpected failure in Disconnect Interrupt\n");
		}
	}

	return status;
}

DWORD RegistryEnableInterrupts(BOOLEAN* pWasChanged)
{
	DWORD status = STATUS_SUCCESS;
	return status;
}



BOOLEAN DriverInterruptServiceRoutine()
{
	BOOLEAN interruptHandled = TRUE;
	return(interruptHandled);
}


#define COUNTER_TIMEOUT     (100)

// Wait for ACK line to go low in the status byte
BOOLEAN HandleInterrupt()
{
	int			i;
	UCHAR       status;
	PUCHAR      nPortBase = ucb.baseAddress;
	BOOLEAN     bInterruptHandled;	

	for (i = 0; i < COUNTER_TIMEOUT; i++)
	{
		status = ReadStatus(nPortBase);
		bInterruptHandled = (status & 0x40) == 0;
		if (bInterruptHandled)
			break;

		// Write to the address register to suppress the interrupt line
		WriteAddress(nPortBase, 0x0);
	}

	// If the ACK line failed to be pulled low, set a flag to acknowledge that
	// the device was disconnected
	if (!bInterruptHandled)
	{
		//RtPrintf("PHANTOMEPP:Interrupt line not suppressed.\n");
	}

	// Interrupt was handled by us if the line was taken low (will fail if
	// device is not physically connected)
	return bInterruptHandled;
}


int RTFCNDCL  DriverTimeoutDPCRoutine(PVOID unused)
{
	DWORD status;

	//RtPrintf("PHANTOMEPP:Software watchdog invoked. Refreshing device(s).\n");

	// Update the Phantom using the most recent read/write buffers
	status = ReadWritePhantom();

	if (status == STATUS_SUCCESS)
	{
		// Set the timeout callback used for the software watchdog
		if (ucb.m_EnableSoftwareWatchdog &&
			ucb.m_TimeoutCount < 100)
		{
			SetWatchdogTimeout();
		}
	}
	else
	{
		// Failed to update the device, so bail on future attempts
		ucb.m_EnableSoftwareWatchdog = FALSE;
	}

	// Provides notification that the DPC is done executing
	RtSetEvent(ucb.m_TimeoutEvent);

	return 0;
}


int RTFCNDCL DriverInterruptDPCRoutine(PVOID unused)
{
	// Increment a running counter of the number of times the event has been signaled
	ucb.m_SignalEventCount++;

	if(ucb.m_SignalEventObject != NULL)
	{
		RtSetEvent(ucb.m_SignalEventObject);
	}

	return 0;
}


DWORD DriverCloseDispatch()
{
	HANDLE hAppEvent;
	DWORD status = STATUS_SUCCESS;

	//RtPrintf("PHANTOMEPP:CloseHandle()  call\n");

	// Perform a cleanup pass when the last file handle is closed
	if (--ucb.m_nFileCount == 0)
	{
		// Disable the software watchdog timer, clear the pending watchdog timeout
		// and wait for the DPC to be flushed out
		ucb.m_EnableSoftwareWatchdog = FALSE;
		ClearWatchdogTimeout(TRUE);

		// Make sure that timer events are disabled
		if (ucb.m_SoftwareTimerEnabled)
		{
			status = DisableSoftwareTimerEvent();
		}
		else
		{
			status = DisableTimerEvent();

			if (status == STATUS_SUCCESS)
			{
				status = DisableInterrupts();
			}
		}

		// Make sure the ParPort is freed
		if (status == STATUS_SUCCESS)
		{
			status = FreeParPort();
		}
	}

	// Delete the timer and event
	RtResetEvent(ucb.m_TimeoutEvent);

	// Reset the app event
	hAppEvent = RtdDriverGetEvent(hDriver);
	RtResetEvent(hAppEvent);

	//IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return(status);
}


DWORD FreeParPort()
{
	DWORD status = STATUS_SUCCESS;

	// Finally release the ParPort
	if (ucb.m_ParPortAllocated == TRUE)
	{
		//RtPrintf("PHANTOMEPP:Freeing ParPort\n");

		//status = utilityBusIoControl(pDeviceExtension->m_ParPortDeviceObject,
		//	IOCTL_INTERNAL_PARALLEL_PORT_FREE,
		//	NULL,
		//	0,
		//	NULL,
		//	0);

		//if (!NT_SUCCESS (status))
		//{
		//	utilityLogError(pDeviceExtension->m_DeviceObject, 
		//		PHANTOMEPP_PARALLEL_PORT_FREE_FAILED, 
		//		PHANTOMEPP_ERROR_VALUE_BASE + 130,
		//		status, 
		//		NULL, 0);

		//	KdPrint("PHANTOMEPP:Unexpected failure in Free Parallel Port\n"));
		//}

		ucb.m_ParPortAllocated = FALSE;
	}

	return status;
}


VOID DriverUnload()
{
	//DWORD             status;
	//WCHAR             IndexBuffer[8];
	//WCHAR             Win32DeviceBuffer[DEVICE_NAME_BUFFER_SIZE];	
	//UNICODE_STRING    uniIndex = {0, sizeof(IndexBuffer)/sizeof(WCHAR), IndexBuffer};
	//UNICODE_STRING    uniWin32Device = {0, sizeof(Win32DeviceBuffer)/sizeof(WCHAR), Win32DeviceBuffer};

	//CurrentDevice = pDriverObject->DeviceObject;

	//while( CurrentDevice )
	{
		//pDeviceExtension = CurrentDevice->DeviceExtension;

		//RtPrintf("PHANTOMEPP:Unloading Device %d, DeviceObject %x.\n",ucb.m_DeviceIndex);

		// Disable the event timer if it's still being used
		if (ucb.m_SoftwareTimerEnabled)
		{
			DisableSoftwareTimerEvent();
		}
		else
		{
			DisableTimerEvent();
			DisableInterrupts();
		}

		// Disable the software watchdog timer, clear the pending watchdog timeout
		// and wait for the DPC to be flushed out
		ucb.m_EnableSoftwareWatchdog = FALSE;
		ClearWatchdogTimeout(TRUE);       

		// Make sure the ParPort is freed
		FreeParPort();

		// Convert Device Index to Unicode String
		//uniIndex.Length = 0;
		//uniWin32Device.Length = 0;
		//RtlIntegerToUnicodeString(pDeviceExtension->m_DeviceIndex, 10, &uniIndex);
		//RtlAppendUnicodeToString(&uniWin32Device, WIN32_DEVICE_NAME);
		//RtlAppendUnicodeStringToString(&uniWin32Device, &uniIndex);
		//RtPrintf("PHANTOMEPP:Delete symbolic link.\n");

		//IoDeleteSymbolicLink (&uniWin32Device);

		//IoDeleteDevice(CurrentDevice);

		//CurrentDevice = pDriverObject->DeviceObject;
	}

}


DWORD DriverShutdown(PTRP Irp)
{
	// Delete the timer and event
	RtDeleteTimer(ucb.m_SoftwareTimer);
	RtDeleteTimer(ucb.m_TimeoutTimer);
	RtCloseHandle(ucb.m_TimeoutEvent);

	ucb.m_SoftwareTimer = NULL;
	ucb.m_TimeoutTimer = NULL;
	ucb.m_TimeoutEvent = NULL;

	//IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}

⌨️ 快捷键说明

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