📄 init.c
字号:
DebugPrintMsg("Stop Device!");
// 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.
default:
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
}
//Ave2kIoDecrement (deviceInfo);
return status;
}
NTSTATUS
Ave2kStartDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
DEVICE_DESCRIPTION DeviceDescription;
ULONG NumberOfMapRegisters=0;
NTSTATUS status = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
PCM_PARTIAL_RESOURCE_LIST partialResourceList;//translated resource
PIO_STACK_LOCATION stack;
ULONG i;
PDEVICE_EXTENSION pDevExt;
DebugPrintMsg("IN Start Device!");
pDevExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
stack = IoGetCurrentIrpStackLocation (Irp);
PAGED_CODE();
//
// We need to check that we haven't received a surprise removal
//
if (pDevExt->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.AllocatedResourcesTranslated) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
partialResourceList =
&stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
resource = &partialResourceList->PartialDescriptors[0];
for (i = 0; i < partialResourceList->Count; i++, resource++) {
switch (resource->Type) {
case CmResourceTypePort:
DebugPrint("Resource Translated Port: (%x) Length: (%d)\n",
resource->u.Port.Start.LowPart,
resource->u.Port.Length);
break;
case CmResourceTypeMemory:
pDevExt->PortBase = (PVOID)
MmMapIoSpace (resource->u.Memory.Start,
resource->u.Memory.Length,
MmNonCached);
pDevExt->PhyPortBase=resource->u.Memory.Start.LowPart;
pDevExt->PortSpan = resource->u.Memory.Length;
pDevExt->PortWasMapped = TRUE;
DebugPrint("Resource Translated Memory: (%x) Length: (%d)\n",
resource->u.Memory.Start.LowPart,
resource->u.Memory.Length);
break;
case CmResourceTypeInterrupt:
DebugPrint("Interrupt Vector %x IRQL %d Affinity %d Mode %d",
resource->u.Interrupt.Vector,resource->u.Interrupt.Level,
resource->u.Interrupt.Affinity,resource->Flags);
//
// Make sure device interrupts are OFF
//
Ave2kDisableInterrupts( pDevExt );
status =
IoConnectInterrupt(
&pDevExt->pInterrupt,
Ave2kIsr,
pDevExt,
&IsrSpinLock,//NULL,
resource->u.Interrupt.Vector,
(KIRQL)resource->u.Interrupt.Level,
(KIRQL)resource->u.Interrupt.Level,//IsrSynchronizeIrql,//DeviceBlock->Dirql,
resource->Flags,
TRUE, //ShareVector,
resource->u.Interrupt.Affinity,
FALSE );
if( !NT_SUCCESS( status ))
{
DebugPrintMsg("connect Interrupt Error!");
return status;
}
else
{
DebugPrintMsg("connect Interrupt OK!");
}
break;
default:
DebugPrint("Unhandled resource type (0x%x)\n", resource->Type);
status = STATUS_UNSUCCESSFUL;
break;
} // end of switch
} // end of for
if(!NT_SUCCESS(status))return status;
InitializeHardware(pDevExt);
//Give default to variables in device extension
if(InitializeData(pDevExt)==FALSE)
return STATUS_UNSUCCESSFUL;
//
// Initialize the hardware and enable interrupts
//
//KeSynchronizeExecution(
// pDevExt->pInterrupt,
// Ave2kInitDevice,
// pDevExt ); deleted 02/08/22.
//Actually the function don't enable any interrupt, and here interrupt shoud be disabled by
//preceding Ave2kDisableInterrupts.
DebugPrintMsg("Start Device OK!");
return STATUS_SUCCESS;
}
NTSTATUS
Ave2kDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for power irps.
Does nothing except forwarding the IRP to the next device
in the stack.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT Status code
--*/
{
PDEVICE_EXTENSION deviceInfo;
deviceInfo = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// If the device has been removed, the driver should not pass
// the IRP down to the next lower driver.
//
if (deviceInfo->Removed) {
PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return STATUS_DELETE_PENDING;
}
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(deviceInfo->NextLowerDriver, Irp);
}
NTSTATUS
Ave2kDispatchSystemControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceInfo;
PAGED_CODE();
deviceInfo = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(deviceInfo->NextLowerDriver, Irp);
}
void GetDeviceInfo(PDEVICE_OBJECT DeviceObject)
{
NTSTATUS status;
int i;
ULONG ResultLength;
ULONG SubVendorID;
ULONG SubSystemID;
CHAR *buffer;
CHAR *buffer1;
buffer=(CHAR*)ExAllocatePool(PagedPool,400);
buffer1=(CHAR*)ExAllocatePool(PagedPool,5);
status=IoGetDeviceProperty(DeviceObject,
DevicePropertyHardwareID,
400,
&buffer[0],
&ResultLength
);
if(!NT_SUCCESS(status))
{
DebugPrintMsg("get HID error");
if(status==STATUS_BUFFER_TOO_SMALL)DebugPrintMsg("Buffer too small");
if(status==STATUS_INVALID_PARAMETER_2)DebugPrintMsg("error properties");
if(status==STATUS_INVALID_DEVICE_REQUEST)DebugPrintMsg("error pdo");
DebugPrint("HID:%u",ResultLength);
}
for(i=0;i<4;i++)
{
buffer1[i]=buffer[2*i+58];
}
buffer1[4]=0;
SubSystemID=HexCharToInt(buffer1);
DebugPrint("SubsystemID:%x",SubSystemID);
for(i=0;i<4;i++)
{
buffer1[i]=buffer[2*i+66];
}
buffer1[4]=0;
SubVendorID=HexCharToInt(buffer1);
DebugPrint("SubVendorID:%x",SubVendorID);
//used to indicate the borad with same pci_venderid and pci_deviceid but unexpected
//subvendorid and subsystemid
BoardVersion=0xffff;
/*if(0xffff == SubVendorID)
{
DebugPrintMsg("Reva0");
BoardVersion = REVA0;
}*/
if(SUBVENDOR_THAKRAL == SubVendorID)
{
switch(SubSystemID)
{
#if(TARGET_DEVICE==TD_AVE2K || TARGET_DEVICE==TD_TEST)
case SUBSYS_AVE2KREVA1:
DebugPrintMsg("Reva1");
BoardVersion = REVA1;
break;
case SUBSYS_AVE2KREVA2:
#endif
#if(TARGET_DEVICE==TD_AVEIII || TARGET_DEVICE==TD_TEST)
case SUBSYS_AVE2KREVA21:
#endif
DebugPrintMsg("Reva2");
BoardVersion = REVA2;
break;
#if(TARGET_DEVICE==TD_AVE2K || TARGET_DEVICE==TD_TEST)
case SUBSYS_AVE2KDREVB2:
DebugPrintMsg("hahahaha!");
DebugPrintMsg("Revb2");
BoardVersion = REVB2;
break;
case SUBSYS_AVE2KMREVC2:
DebugPrintMsg("Revc2");
BoardVersion = REVC2;
break;
case SUBSYS_AVE2KREVD1Q:
case SUBSYS_AVE2KREVD1D:
case SUBSYS_AVE2KREVD1S:
BoardVersion = REVD1;
break;
#if(TARGET_DEVICE==TD_TEST)
default:
BoardVersion = REVA1;
break;
#endif
#endif
}
}
#if(TARGET_DEVICE==TD_TEST)
else
BoardVersion = REVA1;
#endif
ExFreePool(buffer);
ExFreePool(buffer1);
}
LONG
Ave2kIoIncrement(
IN OUT PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
This routine increments the number of requests the device receives
Arguments:
DeviceExtension - pointer to the device extension.
Return Value:
The value of OutstandingIO field in the device extension.
--*/
{
LONG result;
result = InterlockedIncrement(&DeviceExtension->UsageCount);
ASSERT(result > 0);
return result;
}
LONG Ave2kIoDecrement(
IN OUT PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
This routine decrements the number of requests the device receives
Arguments:
DeviceObject - pointer to the device object.
Return Value:
The value of OutstandingIO field in the device extension.
--*/
{
LONG result;
result = InterlockedDecrement(&DeviceExtension->UsageCount);
ASSERT(result >= 0);
if (result == 0) {
ASSERT(DeviceExtension->Removed == TRUE);
//
// Set the remove event, so the device object can be deleted
//
KeSetEvent (&DeviceExtension->RemoveEvent,
IO_NO_INCREMENT,
FALSE);
}
return result;
}
PCHAR
PnPMinorFunctionString (
UCHAR MinorFunction
)
{
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
return "IRP_MN_START_DEVICE";
case IRP_MN_QUERY_REMOVE_DEVICE:
return "IRP_MN_QUERY_REMOVE_DEVICE";
case IRP_MN_REMOVE_DEVICE:
return "IRP_MN_REMOVE_DEVICE";
case IRP_MN_CANCEL_REMOVE_DEVICE:
return "IRP_MN_CANCEL_REMOVE_DEVICE";
case IRP_MN_STOP_DEVICE:
return "IRP_MN_STOP_DEVICE";
case IRP_MN_QUERY_STOP_DEVICE:
return "IRP_MN_QUERY_STOP_DEVICE";
case IRP_MN_CANCEL_STOP_DEVICE:
return "IRP_MN_CANCEL_STOP_DEVICE";
case IRP_MN_QUERY_DEVICE_RELATIONS:
return "IRP_MN_QUERY_DEVICE_RELATIONS";
case IRP_MN_QUERY_INTERFACE:
return "IRP_MN_QUERY_INTERFACE";
case IRP_MN_QUERY_CAPABILITIES:
return "IRP_MN_QUERY_CAPABILITIES";
case IRP_MN_QUERY_RESOURCES:
return "IRP_MN_QUERY_RESOURCES";
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
case IRP_MN_QUERY_DEVICE_TEXT:
return "IRP_MN_QUERY_DEVICE_TEXT";
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
case IRP_MN_READ_CONFIG:
return "IRP_MN_READ_CONFIG";
case IRP_MN_WRITE_CONFIG:
return "IRP_MN_WRITE_CONFIG";
case IRP_MN_EJECT:
return "IRP_MN_EJECT";
case IRP_MN_SET_LOCK:
return "IRP_MN_SET_LOCK";
case IRP_MN_QUERY_ID:
return "IRP_MN_QUERY_ID";
case IRP_MN_QUERY_PNP_DEVICE_STATE:
return "IRP_MN_QUERY_PNP_DEVICE_STATE";
case IRP_MN_QUERY_BUS_INFORMATION:
return "IRP_MN_QUERY_BUS_INFORMATION";
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
case IRP_MN_SURPRISE_REMOVAL:
return "IRP_MN_SURPRISE_REMOVAL";
default:
return "IRP_MN_?????";
}
}
//++
// Function:
// Ave2kReleaseHardware
//
// Description:
// This function releases any resources
// allocated during driver initialization.
//
// Arguments:
// A pointer to the Device extension
//
// Return Value:
// (None)
//--
VOID
Ave2kPnPReleaseHardware(
IN PDEVICE_EXTENSION pDevExt
)
{
UNICODE_STRING linkName;
WCHAR linkNameBuffer[ AVE2K_MAX_NAME_LENGTH ];
UNICODE_STRING number;
WCHAR numberBuffer[10];
CM_RESOURCE_LIST ResList;
BOOLEAN bConflict;
linkName.Buffer = linkNameBuffer;
linkName.MaximumLength = AVE2K_MAX_NAME_LENGTH;
number.Buffer = numberBuffer;
number.MaximumLength = 10;
DebugPrintMsg("Release Hardware Resource!");
//
// Add code here to save the state of
// the hardware in the Registry and/or
// to set the hardware into a known condition.
//
//
// Stop handling interrupts from device
//
Ave2kDisableInterrupts( pDevExt );
IoDisconnectInterrupt( pDevExt->pInterrupt );
MmUnmapIoSpace(pDevExt->PortBase, pDevExt->PortSpan);
//
// Form the Win32 symbolic link name.
//
linkName.Length = 0;
RtlAppendUnicodeToString(
&linkName,
AVE2K_WIN32_DEVICE_NAME );
//
// Attach Win32 device number to the
// end of the name; DOS device numbers
// are one greater than NT numbers...
//
number.Length = 0;
RtlIntegerToUnicodeString(
pDevExt->NtDeviceNumber + 1,
10,
&number );
RtlAppendUnicodeStringToString(
&linkName,
&number );
//
// Remove symbolic link from Object
// namespace...
//
IoDeleteSymbolicLink( &linkName );
//Free allocated buffer1 address
if(NULL != pDevExt->DataCommonBuffer1.BaseAddress)
HalFreeCommonBuffer(
(PADAPTER_OBJECT)pDevExt->pAdapter,
pDevExt->DataCommonBuffer1.Length,
pDevExt->DataCommonBuffer1.LogicalAddress,
(PVOID)pDevExt->DataCommonBuffer1.BaseAddress,
FALSE);
//Free allocated buffer2 address
if(NULL != pDevExt->DataCommonBuffer2.BaseAddress)
HalFreeCommonBuffer(
(PADAPTER_OBJECT)pDevExt->pAdapter,
pDevExt->DataCommonBuffer2.Length,
pDevExt->DataCommonBuffer2.LogicalAddress,
(PVOID)pDevExt->DataCommonBuffer2.BaseAddress,
FALSE);
if(pDevExt->pAdapter != NULL)
(((pDevExt->pAdapter)->DmaOperations)->PutDmaAdapter)(pDevExt->pAdapter);
}
ULONG HexCharToInt(char *buf)
{
ULONG i,j,retVal=0;
for(i=0;i<4;i++)
{
switch(buf[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
j=buf[i]-'0';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
j=buf[i]-'A'+10;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
j=buf[i]-'a'+10;
break;
default: j=0;
}
retVal=retVal*16+j;
}
return retVal;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -