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

📄 tiamobus.cpp

📁 基于SCSI协议的虚拟磁盘源代码
💻 CPP
字号:

//**************************************************************************************
//	日期:	23:2:2004   
//	创建:	tiamo	
//	描述:   exbus
//**************************************************************************************

#include "stdafx.h"
#include "..\public.h"

#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,DriverUnload)
#pragma alloc_text(PAGE,DispatchCreateClose)
#pragma alloc_text(PAGE,AddDevice)

// driver entry
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING pRegPath)
{
	pDriver->DriverUnload = DriverUnload;
	pDriver->DriverExtension->AddDevice = AddDevice;
	pDriver->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
	pDriver->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
	pDriver->MajorFunction[IRP_MJ_PNP] = DispatchPnP;
	pDriver->MajorFunction[IRP_MJ_POWER] = DispatchPower;
	pDriver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoControl;
	devDebugPrint(DRIVER_NAME"*******DriverEntry called\n");
	return STATUS_SUCCESS;
}

// driver unload
void DriverUnload(PDRIVER_OBJECT pDriver)
{
	devDebugPrint(DRIVER_NAME"*******DriverUnload called\n");
	return;
}

// create close for device control
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

	PCommonExt pCommonExt = static_cast<PCommonExt>(pDevice->DeviceExtension);
	if(pCommonExt->m_bFdo)
	{
		PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);
		switch(pIoStack->MajorFunction)
		{
		case IRP_MJ_CREATE:
			devDebugPrint(DRIVER_NAME"*******IRP_MJ_CREATE for bus fdo device \n");
			break;
		case IRP_MJ_CLOSE:
			devDebugPrint(DRIVER_NAME"*******IRP_MJ_CLOSE for bus fdo device \n");
			break;
		}
		status = STATUS_SUCCESS;
	}

	pIrp->IoStatus.Information = 0;
	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp,IO_NO_INCREMENT);

	return status;
}

// device io control for bus fdo
NTSTATUS DispatchIoControl(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

	PFdoExt pFdoExt = static_cast<PFdoExt>(pDevice->DeviceExtension);

	if(pFdoExt->m_bFdo)
	{
		BOOLEAN bCallNext = TRUE;
		IncIoCount(pFdoExt);
		
		PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);
		switch(pIoStack->Parameters.DeviceIoControl.IoControlCode)
		{
			// add a scsi device,input is a miniport config struct
		case IOCTL_TIAMO_BUS_PLUGIN:
			status = STATUS_INVALID_PARAMETER;

			bCallNext = FALSE;

			if(pIoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(MiniportConfig))
			{
				PMiniportConfig pMiniportConfig = static_cast<PMiniportConfig>(pIrp->AssociatedIrp.SystemBuffer);

				if(pMiniportConfig && pMiniportConfig->m_ulDevices > 0 && pMiniportConfig->m_ulDevices < 5)
				{
					ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);

					// create the only one pdo
					if(!pFdoExt->m_pEnumPdo)
					{
						PDEVICE_OBJECT pdo;
						status = IoCreateDevice(pDevice->DriverObject,sizeof(PdoExt),NULL,FILE_DEVICE_BUS_EXTENDER,
												FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,FALSE,&pdo);

						if(NT_SUCCESS(status))
						{
							// set the pdo ext
							PPdoExt pPdoExt = static_cast<PPdoExt>(pdo->DeviceExtension);

							RtlZeroMemory(pPdoExt,sizeof(PdoExt));

							pPdoExt->m_bFdo = FALSE;
							// save the fdo here
							pPdoExt->m_pParentFdo = pDevice;
							pPdoExt->m_ulCurrentPnpState = pPdoExt->m_ulPrevPnpState = -1;

							pPdoExt->m_sysPowerState = PowerSystemWorking;
							pPdoExt->m_devPowerState = PowerDeviceD3;
							pPdoExt->m_bPresent = TRUE;

							//pdo->Flags |= DO_POWER_PAGABLE;
							
							pFdoExt->m_pEnumPdo = pdo;

							RtlMoveMemory(pPdoExt->m_szImageFileName,pMiniportConfig->m_szImageFileName,1024 * sizeof(WCHAR));

							pPdoExt->m_ulDevices = pMiniportConfig->m_ulDevices;

							pdo->Flags &= ~DO_DEVICE_INITIALIZING;

							devDebugPrint(DRIVER_NAME"*******IOCTL_TIAMO_BUS_PLUGIN detected new device and created a pdo.\n");
						}
					}
					else
					{
						status = STATUS_DEVICE_ALREADY_ATTACHED;
					}

					ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);

					if(NT_SUCCESS(status))
						IoInvalidateDeviceRelations(pFdoExt->m_pPhysicalDevice,BusRelations);
				}
			}
			break;

			// miniport get config
		case IOCTL_TIAMO_BUS_MINIPORT_GET_CONFIG:
			status = STATUS_INVALID_PARAMETER;

			bCallNext = FALSE;

			if(pIoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(MiniportConfig))
			{
				ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo);
				if(pFdoExt->m_pEnumPdo)
				{
					PPdoExt pPdoExt = static_cast<PPdoExt>(pFdoExt->m_pEnumPdo->DeviceExtension);
					if(pPdoExt)
					{
						RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,&pPdoExt->m_ulDevices,sizeof(MiniportConfig));
						pIrp->IoStatus.Information = sizeof(MiniportConfig);
						status = STATUS_SUCCESS;
						devDebugPrint(DRIVER_NAME"*******IOCTL_TIAMO_BUS_MINIPORT_GET_CONFIG upper miniport fdo get it's pdo configuration\n");
					}
				}
				else
				{
					status = STATUS_NO_SUCH_DEVICE;
				}

				ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo);
			}
			
			break;
		}

		DecIoCount(pFdoExt);

		if(bCallNext)
			return IoCallDriver(pFdoExt->m_pLowerDevice,pIrp);
	}
		
	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp,IO_NO_INCREMENT);
	
	return status;
}

// add device
NTSTATUS AddDevice(PDRIVER_OBJECT pDriver,PDEVICE_OBJECT pPhysicalDeviceObject)
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevice = NULL;
	PFdoExt pFdoExt = NULL;
	__try
	{
		UNICODE_STRING busFdoName;
		RtlInitUnicodeString(&busFdoName,BUS_FDO_NAME);
		status = IoCreateDevice(pDriver,sizeof(FdoExt),&busFdoName,FILE_DEVICE_BUS_EXTENDER,FILE_DEVICE_SECURE_OPEN,
								FALSE,&pDevice);

		if(!NT_SUCCESS(status))
			ExRaiseStatus(status);

		pFdoExt = static_cast<PFdoExt>(pDevice->DeviceExtension);
		RtlZeroMemory(pFdoExt,sizeof(FdoExt));

		status = IoRegisterDeviceInterface(pPhysicalDeviceObject,&GUID_TIAMO_BUS,NULL,&pFdoExt->m_symbolicName);
		if(!NT_SUCCESS(status))
			ExRaiseStatus(status);

		KeInitializeEvent(&pFdoExt->m_evRemove,SynchronizationEvent,FALSE);

		KeInitializeEvent(&pFdoExt->m_evStop,SynchronizationEvent,TRUE);

		ExInitializeFastMutex (&pFdoExt->m_mutexEnumPdo);

		pFdoExt->m_sysPowerState = PowerSystemWorking;
		pFdoExt->m_devPowerState = PowerDeviceD3;

		pFdoExt->m_bFdo = TRUE;
		pFdoExt->m_pPhysicalDevice = pPhysicalDeviceObject;

		pFdoExt->m_pLowerDevice = IoAttachDeviceToDeviceStack(pDevice,pPhysicalDeviceObject);

		pFdoExt->m_ulCurrentPnpState = -1;
		pFdoExt->m_ulPrevPnpState = -1;

		pFdoExt->m_ulOutstandingIO = 1;

		//pDevice->Flags |= DO_POWER_PAGABLE;

		POWER_STATE state;
		state.DeviceState = PowerDeviceD0;
		PoSetPowerState(pDevice,DevicePowerState,state);

		pDevice->Flags &= ~DO_DEVICE_INITIALIZING;

		devDebugPrint(DRIVER_NAME"*******AddDevice called,fdo createed.\n");
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		if(pFdoExt && pFdoExt->m_pLowerDevice)
		{
			IoDetachDevice(pFdoExt->m_pLowerDevice);
			RtlFreeUnicodeString(&pFdoExt->m_symbolicName);
		}

		if(pDevice)
		{
			IoDeleteDevice(pDevice);
		}
	}

	return status;
}

// here outstandingio indicates that how many irps are outstanding.1 is the base
//
// 2 means only one irp is outstanding,when you want to stop the device,you process the xx_STOP IRP
// then if outstandingio is 2 means that,the irp that you are currently processing is the only one,
// so you can safely stop it(first Dec by 1,then the stopEvent will become signaled,wait for that object,you can get it,
// then do not forget inc it,because of the fact that when the dispatch function return ,it will dec it again)
//
// 1 means no irp is outstanding,so you can safely remove it(first dec it by 2,then the value become 0,so the removeEvent
// become signaled,wait for that object,you can get it,but now no need to inc it,because the device will disappear soon)
void IncIoCount(PFdoExt pExt)
{
	LONG ulRet;
	ulRet = InterlockedIncrement(reinterpret_cast<volatile LONG *>(&pExt->m_ulOutstandingIO));

	if(ulRet == 2) 
	{
		KeClearEvent(&pExt->m_evStop);
	}

	return;
}

void DecIoCount(PFdoExt pExt)   
{

	LONG ulRet = InterlockedDecrement(reinterpret_cast<volatile LONG *>(&pExt->m_ulOutstandingIO));

	if(ulRet == 1) 
	{
		KeSetEvent(&pExt->m_evStop,IO_NO_INCREMENT,FALSE);        
	}

	if(ulRet == 0) 
	{
		KeSetEvent(&pExt->m_evRemove,IO_NO_INCREMENT,FALSE);
	}

	return;
}

⌨️ 快捷键说明

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