ACPI!ACPIDetectPdoDevices函数分析对节点PCI0的处理_STA方法不存在默认存在
//
// Grab the first child
//
deviceExtension = (PDEVICE_EXTENSION) CONTAINING_RECORD(
parentExtension->ChildDeviceList.Flink,
DEVICE_EXTENSION,
SiblingDeviceList
);
0: kd> p
eax=89981b58 ebx=f743b620 ecx=f743b620 edx=00000000 esi=899c0ea0 edi=804ee090
eip=f74002cb esp=f789a220 ebp=f789a250 iopl=0 nv up ei pl nz ac pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000216
ACPI!ACPIDetectPdoDevices+0xed:
f74002cb 81c6b8feffff add esi,0FFFFFEB8h
//
// Update the current device status
//
status = ACPIGetDevicePresenceSync(
deviceExtension,
(PVOID *) &deviceStatus,
NULL
//
// This macro is used to get the device status synchronously
//
#define ACPIGetDevicePresenceSync( \
DeviceExtension, \
Buffer, \
BufferSize \
) \
ACPIGetDevicePresence( \
DeviceExtension, \
GET_PROP_SKIP_CALLBACK, \
NULL, \
NULL, \
Buffer, \
BufferSize \
)
//
// This macro is used to get the device presence
//
#define ACPIGetDevicePresence( \
DeviceExtension, \
Flags, \
CallBack, \
Context, \
Buffer, \
BufferSize \
) \
ACPIGet( \
DeviceExtension, \
PACKED_STA, \
(GET_REQUEST_INTEGER | \
GET_TYPE_INTEGER | \
GET_CONVERT_TO_DEVICE_PRESENCE | \
Flags ), \
NULL, \
0, \
CallBack, \
Context, \
(PVOID *) Buffer, \
(PULONG) BufferSize \
)
对比:ACPIGetDevicePresenceAsync第二个参数是:GET_PROP_ASYNCHRONOUS
//
// This macro is used to get the device status asynchronously
//
#define ACPIGetDevicePresenceAsync( \
DeviceExtension, \
CallBack, \
Context, \
Buffer, \
BufferSize \
) \
ACPIGetDevicePresence( \
DeviceExtension, \
GET_PROP_ASYNCHRONOUS, \
CallBack, \
Context, \
Buffer, \
BufferSize \
)
ACPIGetDevicePresenceSync第二个参数是:GET_PROP_SKIP_CALLBACK
//
// This macro is used to get the device status synchronously
//
#define ACPIGetDevicePresenceSync( \
DeviceExtension, \
Buffer, \
BufferSize \
) \
ACPIGetDevicePresence( \
DeviceExtension, \
GET_PROP_SKIP_CALLBACK, \
NULL, \
NULL, \
Buffer, \
BufferSize \
)
对比结束:
0: kd> kc
00 ACPI!ACPIGet
01 ACPI!ACPIDetectPdoDevices
02 ACPI!ACPIRootIrpQueryBusRelations
03 ACPI!ACPIRootIrpQueryDeviceRelations
04 ACPI!ACPIDispatchIrp
05 nt!IofCallDriver
06 nt!IopSynchronousCall
07 nt!IopQueryDeviceRelations
08 nt!PipEnumerateDevice
09 nt!PipProcessDevNodeTree
0a nt!PipDeviceActionWorker
0b nt!PipRequestDeviceAction
0c nt!IopInitializeBootDrivers
0d nt!IoInitSystem
0e nt!Phase1Initialization
0f nt!PspSystemThreadStartup
10 nt!KiThreadStartup
0: kd> dv
Target = 0x899c0d58
ObjectID = 0x4154535f
Flags = 0x20040802
SimpleArgument = 0x00000000
SimpleArgumentSize = 0
CallBackRoutine = 0x00000000
CallBackContext = 0x00000000
Buffer = 0xf789a22c
BufferSize = 0x00000000
case GET_REQUEST_INTEGER:
completionRoutine = ACPIGetWorkerForInteger;
//
// Go out and see if the requested object is present
//
acpiObject = ACPIAmliGetNamedChild(
acpiObject,
ObjectID
);
if (!acpiObject) {
status = STATUS_OBJECT_NAME_NOT_FOUND;
goto ACPIGetExit;
}
0: kd> gu
eax=00000000 ebx=f743b938 ecx=899affac edx=00000000 esi=89968640 edi=89968648
eip=f74078dd esp=f789a1b8 ebp=f789a1f4 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
ACPI!ACPIGet+0x225:
f74078dd 85c0 test eax,eax
ACPIGetExit:
//
// Remember to not execute the callback routine
//
request->Flags |= GET_PROP_SKIP_CALLBACK;
//
// Call the completion routine to actually do the post-processing
//
(completionRoutine)(
acpiObject,
status,
&(request->ResultData),
request
);
0: kd> kc
00 ACPI!ACPIGetWorkerForInteger
01 ACPI!ACPIGet
02 ACPI!ACPIDetectPdoDevices
03 ACPI!ACPIRootIrpQueryBusRelations
04 ACPI!ACPIRootIrpQueryDeviceRelations
05 ACPI!ACPIDispatchIrp
06 nt!IofCallDriver
07 nt!IopSynchronousCall
08 nt!IopQueryDeviceRelations
09 nt!PipEnumerateDevice
0a nt!PipProcessDevNodeTree
0b nt!PipDeviceActionWorker
0c nt!PipRequestDeviceAction
0d nt!IopInitializeBootDrivers
0e nt!IoInitSystem
0f nt!Phase1Initialization
10 nt!PspSystemThreadStartup
11 nt!KiThreadStartup
0: kd> dv
AcpiObject = 0x00000000
Status = 0n-1073741772
Result = 0x8996866c
Context = 0x89968640
freeData = 0x00 ''
0: kd> dt ACPI_GET_REQUEST 0x89968640
+0x000 Flags : 0x20040802
+0x000 UFlags : __unnamed
+0x004 ObjectID : 0x4154535f
+0x008 ListEntry : _LIST_ENTRY [ 0xf743b940 - 0xf743b940 ]
+0x010 DeviceExtension : 0x899c0d58 _DEVICE_EXTENSION
+0x014 AcpiObject : 0x899affac _NSObj
+0x018 CallBackRoutine : (null)
+0x01c CallBackContext : (null)
+0x020 Buffer : 0xf789a22c -> 0x00000030 Void
+0x024 BufferSize : (null)
+0x028 Status : 0n0
+0x02c ResultData : _ObjData
0: kd> db 0x899affac
899affac 4c ff 9a 89 ac 40 9b 89-f0 f0 9a 89 24 00 9b 89 L....@......$...
899affbc 50 43 49 30 30 f3 9a 89-4c ff 9a 89 00 00 06 00 PCI00...L.......
} else if (request->Flags & GET_CONVERT_TO_DEVICE_PRESENCE) {
status = ACPIGetConvertToDevicePresence(
request->DeviceExtension,
Status,
Result,
request->Flags,
request->Buffer,
request->BufferSize
);
0: kd> kc
00 ACPI!ACPIGetConvertToDevicePresence
01 ACPI!ACPIGetWorkerForInteger
02 ACPI!ACPIGet
03 ACPI!ACPIDetectPdoDevices
04 ACPI!ACPIRootIrpQueryBusRelations
05 ACPI!ACPIRootIrpQueryDeviceRelations
06 ACPI!ACPIDispatchIrp
07 nt!IofCallDriver
08 nt!IopSynchronousCall
09 nt!IopQueryDeviceRelations
0a nt!PipEnumerateDevice
0b nt!PipProcessDevNodeTree
0c nt!PipDeviceActionWorker
0d nt!PipRequestDeviceAction
0e nt!IopInitializeBootDrivers
0f nt!IoInitSystem
10 nt!Phase1Initialization
11 nt!PspSystemThreadStartup
12 nt!KiThreadStartup
0: kd> dv
DeviceExtension = 0x899c0d58
Status = 0n-1073741772
Result = 0x8996866c
Flags = 0x20040802
Buffer = 0xf789a22c
BufferSize = 0x00000000
deviceStatus = 8
0: kd> ? 0n-1073741772
Evaluate expression: -1073741772 = c0000034
ULONG deviceStatus = STA_STATUS_DEFAULT;
#define GET_PROP_NSOBJ_INTERFACE 0x08000000
#define DEV_CAP_UNATTACHED_DOCK 0x00000004 00000000
#define DEV_PROP_NO_OBJECT 0x00080000 00000000
if (Status == STATUS_OBJECT_NAME_NOT_FOUND) {
//
// We do make exceptions in the case that this is a processor object
// and we didn't find a control method. In this case, we check the
// processor affinity mask to see if this processor exists. The reason
// that we do this is that older multi-proc capable systems with only
// a single processor will errorneously report both processors.
//
此时,我们可以查看控制方法返回的内容。
如果控制方法返回了STATUS_OBJECT_NAME_NOT_FOUND,那么我们就知道该控制方法不存在。
在这种情况下,我们就必须为设备使用默认状态
//
// Update the device status
//
ACPIInternalUpdateDeviceStatus( DeviceExtension, deviceStatus );
0: kd> kc
00 ACPI!ACPIInternalUpdateDeviceStatus
01 ACPI!ACPIGetConvertToDevicePresence
02 ACPI!ACPIGetWorkerForInteger
03 ACPI!ACPIGet
04 ACPI!ACPIDetectPdoDevices
05 ACPI!ACPIRootIrpQueryBusRelations
06 ACPI!ACPIRootIrpQueryDeviceRelations
07 ACPI!ACPIDispatchIrp
08 nt!IofCallDriver
09 nt!IopSynchronousCall
0a nt!IopQueryDeviceRelations
0b nt!PipEnumerateDevice
0c nt!PipProcessDevNodeTree
0d nt!PipDeviceActionWorker
0e nt!PipRequestDeviceAction
0f nt!IopInitializeBootDrivers
10 nt!IoInitSystem
11 nt!Phase1Initialization
12 nt!PspSystemThreadStartup
13 nt!KiThreadStartup
0: kd> dv
DeviceExtension = 0x899c0d58
DeviceStatus = 0xf
oldIrql = 0x00 ''
0: kd> dx -r1 ((ACPI!_DEVICE_EXTENSION *)0x899c0d58)
((ACPI!_DEVICE_EXTENSION *)0x899c0d58) : 0x899c0d58 [Type: _DEVICE_EXTENSION *]
+0x000\] Flags : 0x40200002010108 \[Type: unsigned __int64
0: kd> gu
eax=00000000 ebx=c0000034 ecx=00402000 edx=00000000 esi=899c0d58 edi=0000000f
eip=f7406da5 esp=f789a15c ebp=f789a170 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000202
ACPI!ACPIGetConvertToDevicePresence+0xcf:
f7406da5 5e pop esi
0: kd> dx -r1 ((ACPI!_DEVICE_EXTENSION *)0x899c0d58)
((ACPI!_DEVICE_EXTENSION *)0x899c0d58) : 0x899c0d58 [Type: _DEVICE_EXTENSION *]
+0x000\] Flags : 0x40200002010108 \[Type: unsigned __int64
VOID
EXPORT
ACPIGetWorkerForInteger(
IN PNSOBJ AcpiObject,
IN NTSTATUS Status,
IN POBJDATA Result,
IN PVOID Context
)
{
//
// We are done, but we must check to see if we are the async or the
// sync case. If we are the sync case, then we have much less cleanup
// to perform
//
if ( !(request->Flags & GET_PROP_SKIP_CALLBACK) ) {
//
// Is there a callback routine to call?
//
if (request->CallBackRoutine != NULL) {
(request->CallBackRoutine)(
AcpiObject,
status,
NULL,
request->CallBackContext
);
}
#define GET_PROP_SKIP_CALLBACK 0x20000000
NTSTATUS
ACPIGet(
IN PVOID Target,
IN ULONG ObjectID,
IN ULONG Flags,
IN PVOID SimpleArgument,
IN ULONG SimpleArgumentSize,
IN PFNACB CallBackRoutine OPTIONAL,
IN PVOID CallBackContext OPTIONAL,
OUT PVOID *Buffer,
OUT ULONG *BufferSize OPTIONAL
)
{
//
// Done with the request
//
if (request != NULL) {
//
// Remove the request from the queue
//
KeAcquireSpinLock( &AcpiGetLock, &oldIrql );
RemoveEntryList( &(request->ListEntry) );
KeReleaseSpinLock( &AcpiGetLock, oldIrql );
//
// Free the storage
//
ExFreePool( request );
}
//
// Done
//
return status;
}
0: kd> p
eax=00000000 ebx=f743b620 ecx=04c90001 edx=04c80000 esi=899c0d58 edi=899c0e78
eip=f7407969 esp=f789a1c4 ebp=f789a1f4 iopl=0 nv up ei pl zr na pe cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000247
ACPI!ACPIGet+0x2b1:
f7407969 c9 leave
0: kd> dv status
status = 0n0
//
// If the device exists
//
if ( NT_SUCCESS(status) &&
!(deviceExtension->Flags & DEV_MASK_NOT_PRESENT) ) {
0: kd> p
eax=00000000 ebx=f743b620 ecx=04c90001 edx=04c80000 esi=899c0d58 edi=899c0e78
eip=f7400300 esp=f789a220 ebp=f789a250 iopl=0 nv up ei pl zr na pe cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000247
ACPI!ACPIDetectPdoDevices+0x122:
f7400300 85c0 test eax,eax
0: kd> bp f7400300