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

📄 pnp.cpp

📁 虚拟磁盘源码,完整的虚拟磁盘源码,支持大硬盘数据
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				{
					KeWaitForSingleObject(&pnpEvent,Executive,KernelMode,FALSE,NULL);
					status = ioStatus.Status;
				}
			}

			// dec the ref of the fdo's stack upper device
			ObDereferenceObject(pTargetObject);

			// copy the device state
			RtlCopyMemory(pCaps->DeviceState,parentCaps.DeviceState,(PowerSystemShutdown + 1) * sizeof(DEVICE_POWER_STATE));

			// set our own supported device state
			pCaps->DeviceState[PowerSystemWorking] = PowerDeviceD0;

			if(pCaps->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
				pCaps->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;

			if(pCaps->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
				pCaps->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;

			if(pCaps->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
				pCaps->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;

			// donot support d1 and d2
			pCaps->DeviceD1 = pCaps->DeviceD2 = FALSE;

			// no wake
			pCaps->DeviceWake = PowerDeviceUnspecified;
			pCaps->SystemWake = PowerSystemUnspecified;

			pCaps->WakeFromD0 = FALSE;
			pCaps->WakeFromD1 = FALSE;
			pCaps->WakeFromD2 = FALSE;
			pCaps->WakeFromD3 = FALSE;

			// no latency
			pCaps->D1Latency = 0;
			pCaps->D2Latency = 0;
			pCaps->D3Latency = 0;

			// can eject
			pCaps->EjectSupported = TRUE;

			// don't disable
			pCaps->HardwareDisabled = FALSE;

			// can be removed
			pCaps->Removable = TRUE;

			// don't display surprise remove warning dlg
			pCaps->SurpriseRemovalOK = TRUE;

			// no unique id
			pCaps->UniqueID = FALSE;

			// nead user action for install
			pCaps->SilentInstall = FALSE;

			// bus address
			pCaps->Address = 0;

			// ui display number
			pCaps->UINumber = 0;
		}
		break;

		// query pdo id
	case IRP_MN_QUERY_ID:
		{
			switch(pIoStack->Parameters.QueryId.IdType)
			{
			case BusQueryInstanceID:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,10,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}

					RtlStringCchPrintfW(static_cast<PWCHAR>(buffer),10,L"%04d",0);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryInstanceID\n");
				}
				break;

			case BusQueryDeviceID:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_DEVICE_ID_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}
					RtlCopyMemory(buffer,PDO_DEVICE_ID,PDO_DEVICE_ID_LENGTH);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryDeviceID\n");
				}
				break;

			case BusQueryHardwareIDs:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_HARDWARE_IDS_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}
					RtlCopyMemory(buffer,PDO_HARDWARE_IDS,PDO_HARDWARE_IDS_LENGTH);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryHardwareIDs\n");
				}
				break;

			case BusQueryCompatibleIDs:
				{
					PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_COMPATIBLE_IDS_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}
					RtlCopyMemory(buffer,PDO_COMPATIBLE_IDS,PDO_COMPATIBLE_IDS_LENGTH);
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tBusQueryCompatibleIDs\n");
				}
				break;
			}
		}
		break;

		// query text
	case IRP_MN_QUERY_DEVICE_TEXT:
		{
			switch (pIoStack->Parameters.QueryDeviceText.DeviceTextType) 
			{
			case DeviceTextDescription:
				if(!pIrp->IoStatus.Information) 
				{
					PVOID buffer = ExAllocatePoolWithTag (PagedPool,PDO_TEXT_LENGTH,'suBT');
					if(!buffer) 
					{
						status = STATUS_INSUFFICIENT_RESOURCES;
						break;
					}

					RtlStringCchPrintfW(static_cast<PWCHAR>(buffer),PDO_TEXT_LENGTH,L"%ws",PDO_TEXT);
					
					pIrp->IoStatus.Information = PtrToUlong(buffer);
					devDebugPrint("\tDeviceTextDescription\n");
				}
				break;

			default:
				status = pIrp->IoStatus.Status;
				break;
			}
		}
		break;

		// boot resource
	case IRP_MN_QUERY_RESOURCES:
		{
			PCM_RESOURCE_LIST pResList = static_cast<PCM_RESOURCE_LIST>(ExAllocatePoolWithTag(PagedPool,
																			sizeof(CM_RESOURCE_LIST),'suBT'));

			if(pResList)
			{
				// shareed busnumber resource 
				RtlZeroMemory(pResList,sizeof(CM_RESOURCE_LIST));

				pResList->Count = 1;
				pResList->List[0].BusNumber = 0;
				pResList->List[0].InterfaceType = Internal;
				pResList->List[0].PartialResourceList.Count = 1;
				pResList->List[0].PartialResourceList.Revision = 1;
				pResList->List[0].PartialResourceList.Version = 1;
				pResList->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareShared;
				pResList->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber;
				pResList->List[0].PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1;

				pIrp->IoStatus.Information = PtrToUlong(pResList);
			}
			else
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
			}
		}
		break;

		// resource requirements
	case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
		{
			PIO_RESOURCE_REQUIREMENTS_LIST pList = static_cast<PIO_RESOURCE_REQUIREMENTS_LIST>(
										ExAllocatePoolWithTag(PagedPool,sizeof(IO_RESOURCE_REQUIREMENTS_LIST),'suBT'));

			if(pList)
			{
				RtlZeroMemory(pList,sizeof(IO_RESOURCE_REQUIREMENTS_LIST));

				pList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
				pList->AlternativeLists = 1;
				pList->InterfaceType = InterfaceTypeUndefined;
				pList->BusNumber = 0;
				pList->List[0].Version = 1;
				pList->List[0].Revision = 1;
				pList->List[0].Count = 1;
				pList->List[0].Descriptors[0].Option = IO_RESOURCE_PREFERRED;
				pList->List[0].Descriptors[0].ShareDisposition = CmResourceShareShared;

				pList->List[0].Descriptors[0].Type = CmResourceTypeBusNumber;
				pList->List[0].Descriptors[0].u.BusNumber.MaxBusNumber = 0x10;
				pList->List[0].Descriptors[0].u.BusNumber.Length = 1;

				pIrp->IoStatus.Information = PtrToUlong(pList);
			}
			else
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
			}
		}
		break;

		// bus info
	case IRP_MN_QUERY_BUS_INFORMATION:
		{
			PPNP_BUS_INFORMATION busInfo;

			busInfo = static_cast<PPNP_BUS_INFORMATION>(ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION),'suBT'));

			if (busInfo == NULL) 
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
				break;
			}

			busInfo->BusTypeGuid = GUID_TIAMO_BUS;

			busInfo->LegacyBusType = Internal;

			busInfo->BusNumber = 0;

			pIrp->IoStatus.Information = PtrToUlong(busInfo);
		}
		break;

		// usage
	case IRP_MN_DEVICE_USAGE_NOTIFICATION:
		status = STATUS_UNSUCCESSFUL;
		break;

	case IRP_MN_EJECT:
		{
			// device physical removed
			pPdoExt->m_bPresent = FALSE;
		}
		break;

	//case IRP_MN_QUERY_INTERFACE:
	//	break;

		// target relations
	case IRP_MN_QUERY_DEVICE_RELATIONS:
		{
			if(pIoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
			{
				/*switch(pIoStack->Parameters.QueryDeviceRelations.Type)
				{
				case EjectionRelations:
				devDebugPrint("\tquery EjectionRelations\n");
				break;
				case PowerRelations:
				devDebugPrint("\tquery PowerRelations\n");
				break;
				case RemovalRelations:
				devDebugPrint("\tquery RemovalRelations\n");
				break;
				case BusDeviceRelation:
				devDebugPrint("\tquery BusDeviceRelation\n");
				break;
				case SingleBusRelations:
				devDebugPrint("\tquery SingleBusRelations\n");
				break;
				}*/
				break;
			}

			PDEVICE_RELATIONS pRel = static_cast<PDEVICE_RELATIONS>(ExAllocatePoolWithTag(PagedPool,sizeof(DEVICE_RELATIONS),'suBT'));
			if(!pRel) 
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
				break;
			}

			pRel->Count = 1;
			pRel->Objects[0] = pDevice;
			ObReferenceObject(pDevice);

			status = STATUS_SUCCESS;
			pIrp->IoStatus.Information = PtrToUlong(pRel);
		}
		break;

	default:
		status = pIrp->IoStatus.Status;
		break;
	}

	// pdo should complete the irp
	pIrp->IoStatus.Status = status;
	IoCompleteRequest (pIrp, IO_NO_INCREMENT);

	return status;
}

// dispatch pnp
NTSTATUS DispatchPnP(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	NTSTATUS status;
	PCommonExt pCommonExt = static_cast<PCommonExt>(pDevice->DeviceExtension);

	PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);

	// delete pendind
	if( pCommonExt->m_ulCurrentPnpState == IRP_MN_REMOVE_DEVICE)
	{
		pIrp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE ;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
		return status;
	}

#ifdef DBG
	PrintPnpCall(pDevice,pIrp);
#endif

	if(pCommonExt->m_bFdo)
		status = DoFdoPnP(pDevice,pIrp);
	else
		status = DoPdoPnP(pDevice,pIrp);

	return status;
}

// completion routine
NTSTATUS CompletionRoutine(PDEVICE_OBJECT pDevice,PIRP pIrp,PVOID pContext)
{
	if(pIrp->PendingReturned == TRUE) 
	{
		KeSetEvent(static_cast<PKEVENT>(pContext),IO_NO_INCREMENT,FALSE);
	}

	// irp will complete later
	return STATUS_MORE_PROCESSING_REQUIRED;
}

// send irp down synchronously
NTSTATUS SendIrpToLowerDeviceSyn(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	KEVENT   event;
	NTSTATUS status;

	KeInitializeEvent(&event,NotificationEvent,FALSE);

	IoCopyCurrentIrpStackLocationToNext(pIrp);

	IoSetCompletionRoutine(pIrp,CompletionRoutine,&event,TRUE,TRUE,TRUE);

	status = IoCallDriver(pDevice,pIrp);

	if (status == STATUS_PENDING) 
	{
		KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
		status = pIrp->IoStatus.Status;
	}

	return status;
}

#ifdef DBG
void PrintPnpCall(PDEVICE_OBJECT pDevice,PIRP pIrp)
{
	static PCHAR szDevice[] = {"pdo","fdo"};
	static PCHAR szMinor[] = 
	{
		"Start",
		"QueryRemove",
		"Remove",
		"CancelRemove",
		"Stop",
		"QueryStop",
		"CancelStop",
		"QueryRelations",
		"QueryInterface",
		"QueryCaps",
		"QueryResource",
		"QueryResourceRequirements",
		"QueryText",
		"FilterResourceRequirements",
		"0x0E",
		"ReadConfig",
		"WriteConfig",
		"Eject",
		"SetLock",
		"QueryID",
		"QueryPnpState",
		"QueryBusInfo",
		"DeviceUsageNotification",
		"SurpriseRemove",
		"QueryLegacyBusInfo",
	};

	PCommonExt pCommonExt = static_cast<PCommonExt>(pDevice->DeviceExtension);
	PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);

	devDebugPrint(DRIVER_NAME"*******IRP_MJ_PNP - %s - %s \n",szMinor[pIoStack->MinorFunction],szDevice[pCommonExt->m_bFdo]);
}
#endif

⌨️ 快捷键说明

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