📄 genport.c
字号:
deviceInfo,
NULL,
deviceInfo->InterruptVector,
deviceInfo->InterruptLevel,
deviceInfo->InterruptLevel,
deviceInfo->InterruptMode,
TRUE,
deviceInfo->InterruptAffinity,
FALSE);
if (!NT_SUCCESS(status))
{
DebugPrint((">>> IoConnectInterrupt Failed!\n"));
}
else
{
DebugPrint((">>> IoConnectInterrupt Succeeded!\n"));
deviceInfo->TestIsr = 0;
}
}
deviceInfo->Started = TRUE;//原来的代码
deviceInfo->Removed = FALSE;//原来的代码
//初始化缓存
df = (PLOCAL_DEVICE_INFO) deviceInfo->DeviceObject->DeviceExtension;
DebugPrint((">>>Init Begin! deviceInfo = %X df = %X\n",deviceInfo,df));
DebugPrint((">>>Init Begin! deviceInfo->DeviceObject = %X DeviceObject = %X\n",deviceInfo->DeviceObject,DeviceObject));
for(j = 0;j < COM_NUM;j++)
{
deviceInfo->Inited[j] = FALSE;
DebugPrint((">>>deviceInfo->Inited[%d] = %d\n",j,deviceInfo->Inited[j]));
for(i = 0;i < 2;i++)
{
KeInitializeSemaphore(&deviceInfo->BufSemaphore[i][j], 1, 1);
status = BufInit(&deviceInfo->Buf[i][j] );
if (!NT_SUCCESS(status))
{
DebugPrint((">>>i=%d j=%d BufInit Failed!\n",i,j));
}
else
{
DebugPrint((">>>i=%d j=%d BufInit Succeeded! Size = %d\n",i,j,deviceInfo->Buf[i][j].MaxSize));
}
}
}
//启动定时器
KeInitializeTimer(&deviceInfo->RecTimer);
DebugPrint((">>>KeInitializeTimer Succeeded!\n"));
KeInitializeDpc(&deviceInfo->RecDPC, DpcForRec, DeviceObject);
DebugPrint((">>>KeInitializeDpc Succeeded!\n"));
//其它定义
deviceInfo->CallDpcForRecCount = 0;
//增加结束
}
else
{
DebugPrint((">>> GpdStartDevice Failed!\n"));
}
}
//
// We must now complete the IRP, since we stopped it in the
// completion routine with STATUS_MORE_PROCESSING_REQUIRED.
//
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_QUERY_STOP_DEVICE:
//
// Fail the query stop to prevent the system from taking away hardware
// resources. If you do support this you must have a queue to hold
// incoming requests between stop and subsequent start with new set of
// resources.
//
Irp->IoStatus.Status = status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
//
// The device can be removed without disrupting the machine.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
case IRP_MN_SURPRISE_REMOVAL:
//
// The device has been unexpectedly removed from the machine
// and is no longer available for I/O. Stop all access to the device.
// Release any resources associated with the device, but leave the
// device object attached to the device stack until the PnP Manager
// sends a subsequent IRP_MN_REMOVE_DEVICE request.
// You should fail any outstanding I/O to the device. You will
// not get a remove until all the handles open to the device
// have been closed.
//
deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;
if (deviceInfo->PortWasMapped)
{
MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
deviceInfo->PortWasMapped = FALSE;
}
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&win32DeviceName);
IoSkipCurrentIrpStackLocation(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
case IRP_MN_REMOVE_DEVICE:
//
// Relinquish all resources here.
// Detach and delete the device object so that
// your driver can be unloaded. You get remove
// either after query_remove or surprise_remove.
//
if(!deviceInfo->Removed)
{
deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;
//我增加的代码
//IoDisconnectInterrupt(,,,);
if(deviceInfo->FoundInterrupt )
{
IoDisconnectInterrupt(deviceInfo->InterruptObject);
DebugPrint((">>> IoDisconnectInterrupt Finished!\n"));
}
// KeCancelTimer(&deviceInfo->RecTimer);
DebugPrint((">>> KeCancelTimer Finished!\n"));
for(j = 0;j < COM_NUM;j++)
{
deviceInfo->Inited[j] = FALSE;
}
//增加结束
if (deviceInfo->PortWasMapped)
{
MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
deviceInfo->PortWasMapped = FALSE;
}
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&win32DeviceName);
}
//
// Wait for all outstanding requests to complete
//
DebugPrint(("Waiting for outstanding requests\n"));
IoReleaseRemoveLockAndWait(&deviceInfo->RemoveLock, Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
IoDetachDevice(deviceInfo->NextLowerDriver);
IoDeleteDevice(DeviceObject);
return status;
case IRP_MN_STOP_DEVICE:
DebugPrint((">>> IRP_MN_STOP_DEVICE\n"));
// Since you failed query stop, you will not get this request.
case IRP_MN_CANCEL_REMOVE_DEVICE:
// No action required in this case. Just pass it down.
case IRP_MN_CANCEL_STOP_DEVICE:
//No action required in this case.
Irp->IoStatus.Status = STATUS_SUCCESS;
default:
//
// Please see PnP documentation for use of these IRPs.
//
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
}
IoReleaseRemoveLock(&deviceInfo->RemoveLock, Irp);
return status;
}
NTSTATUS
GpdStartDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Get the resources, map the resources if required
and initialize the device.
Arguments:
DeviceObject - pointer to a device object.
Irp - pointer to an I/O Request Packet.
Return Value:
NT status code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resourceTrans;
PCM_PARTIAL_RESOURCE_LIST partialResourceList;
PCM_PARTIAL_RESOURCE_LIST partialResourceListTranslated;
PIO_STACK_LOCATION stack;
ULONG i,k;
PLOCAL_DEVICE_INFO deviceInfo;
DebugPrint (("-- Entered GpdStartDevice\n"));
deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
stack = IoGetCurrentIrpStackLocation (Irp);
PAGED_CODE();//确保Irp操作所在的级别
//
// We need to check that we haven't received a surprise removal
//
if (deviceInfo->Removed) {
//
// Some kind of surprise removal arrived. We will fail the IRP
// The dispatch routine that called us will take care of
// completing the IRP.
//
return STATUS_DELETE_PENDING;
}
//
// Do whatever initialization needed when starting the device:
// gather information about it, update the registry, etc.
//
if ((NULL == stack->Parameters.StartDevice.AllocatedResources) &&
(NULL == stack->Parameters.StartDevice.AllocatedResourcesTranslated)) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Parameters.StartDevice.AllocatedResources points to a
// CM_RESOURCE_LIST describing the hardware resources that
// the PnP Manager assigned to the device. This list contains
// the resources in raw form. Use the raw resources to program
// the device.
//
partialResourceList =
&stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
DebugPrint((">>> partialResourceList->count = %d\n",partialResourceList->Count));
resource = &partialResourceList->PartialDescriptors[0];
DebugPrint((">>> resource->Type = %d\n",
resource->Type));
DebugPrint((">>> Resource Port: (%x) Length: (%d)\n",
resource->u.Port.Start.LowPart,
resource->u.Port.Length));
//
// Parameters.StartDevice.AllocatedResourcesTranslated points
// to a CM_RESOURCE_LIST describing the hardware resources that
// the PnP Manager assigned to the device. This list contains
// the resources in translated form. Use the translated resources
// to connect the interrupt vector, map I/O space, and map memory.
//
partialResourceListTranslated =
&stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
resourceTrans = &partialResourceListTranslated->PartialDescriptors[0];
for (i = 0;
i < partialResourceList->Count; i++, resource++, resourceTrans++) {
switch (resource->Type) {
case CmResourceTypePort:
switch (resourceTrans->Type) {
case CmResourceTypePort:
deviceInfo->PortWasMapped = FALSE;
deviceInfo->PortBase = (PVOID)(resourceTrans->u.Port.Start.LowPart);
deviceInfo->PortCount = resourceTrans->u.Port.Length;
for(k = 0;k < COM_NUM;k++)
{
deviceInfo->ComBase[k] = (PVOID)((ULONG)deviceInfo->PortBase + (ULONG)0x08*k);
DebugPrint(("deviceInfo->ComBase[%d]: (%x)\n", k,deviceInfo->ComBase[k]));
}
DebugPrint((">>> resourceTrans->Type = %d\n",
CmResourceTypePort));
DebugPrint(("Resource Translated Port: (%x) Length: (%d)\n",
resourceTrans->u.Port.Start.LowPart,
resourceTrans->u.Port.Length));
DebugPrint(("deviceInfo->PortBase: (%x) Length: (%d)\n",
deviceInfo->PortBase,
deviceInfo->PortCount));
break;
case CmResourceTypeMemory:
//
// We need to map the memory
//
deviceInfo->PortBase = (PVOID)
MmMapIoSpace (resourceTrans->u.Memory.Start,
resourceTrans->u.Memory.Length,
MmNonCached);
deviceInfo->PortCount = resourceTrans->u.Memory.Length;
deviceInfo->PortWasMapped = TRUE;
DebugPrint(("Resource Translated Memory: (%x) Length: (%d)\n",
resourceTrans->u.Memory.Start.LowPart,
resourceTrans->u.Memory.Length));
break;
default:
DebugPrint(("Unhandled resource_type (0x%x)\n", resourceTrans->Type));
status = STATUS_UNSUCCESSFUL;
TRAP ();
}
break;
case CmResourceTypeMemory:
deviceInfo->PortBase = (PVOID)
MmMapIoSpace (resourceTrans->u.Memory.Start,
resourceTrans->u.Memory.Length,
MmNonCached);
deviceInfo->PortCount = resourceTrans->u.Memory.Length;
deviceInfo->PortWasMapped = TRUE;
DebugPrint(("Resource Translated Memory: (%x) Length: (%d)\n",
resourceTrans->u.Memory.Start.LowPart,
resourceTrans->u.Memory.Length));
break;
case CmResourceTypeInterrupt:
//我自己增加的代码
deviceInfo->FoundInterrupt = TRUE;
deviceInfo->InterruptLevel = (KIRQL)resourceTrans->u.Interrupt.Level;
deviceInfo->InterruptVector = resourceTrans->u.Interrupt.Vector;
deviceInfo->InterruptAffinity = resourceTrans->u.Interrupt.Affinity;
DebugPrint((">>> InterruptLevel = %d \n",deviceInfo->InterruptLevel));
DebugPrint((">>> InterruptVector = %d \n",deviceInfo->InterruptVector));
if (resourceTrans->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
deviceInfo->InterruptMode = Latched;
DebugPrint((">>> InterruptMode = Latched \n"));
} else {
deviceInfo->InterruptMode = LevelSensitive;
DebugPrint((">>> InterruptMode = LevelSensitive \n"));
}
break;
//增加结束
default:
DebugPrint(("Unhandled resource type (0x%x)\n", resource->Type));
status = STATUS_UNSUCCESSFUL;
break;
} // end of switch
} // end of for
return status;
}
NTSTATUS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -