📄 pnp.cpp
字号:
{
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 + -