news 2026/5/8 18:25:08

ACPI!ACPIDetectPdoDevices函数分析对节点PCI0的处理_STA方法不存在默认存在

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ACPI!ACPIDetectPdoDevices函数分析对节点PCI0的处理_STA方法不存在默认存在

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 22:24:20

Adobe Research:AI从真实设计学习改善海报风格

在平面设计领域,一个让无数非专业人士头疼的问题终于有了解决方案。当你看到一张精美的海报,心想"我的设计要是能做成这种风格就好了"时,是否曾为如何实现这个想法而困扰?现在,来自康奈尔大学和Adobe Resear…

作者头像 李华
网站建设 2026/5/2 20:20:43

美团LongCat团队:词汇库升级提升AI性能

考虑这样一个场景:当你想让一个人变得更聪明时,你会怎么做?传统的做法可能是找更多的专家来帮忙,但美团LongCat团队的研究人员发现了一个更巧妙的方法——让这个人的"词汇库"变得更丰富。这项突破性研究发表于2026年1月…

作者头像 李华
网站建设 2026/5/2 13:08:32

<span class=“js_title_inner“>jQuery 4.0 突发!沉寂十年,这位“前端祖师爷”终于跟 IE 说了再见</span>

2026 年 1 月 17 日,在距离初代版本发布整整 20 年后,jQuery 团队正式发布了 jQuery 4.0.0。这是一次跨越十年的大版本更新。对于许多新生代前端开发者来说,$ 符号可能只是教科书里的历史遗迹;但对于经历过“浏览器兼容性地狱”的…

作者头像 李华
网站建设 2026/5/3 9:19:57

<span class=“js_title_inner“>不负春日不负卿,24年Q1总结</span>

有些事情,经历过才懂难得。有些朋友,遇见了才识真情。有些决定,拍板了才知对错。那么在没有经历时如何了然懂事,在不识真情时如何相知相交,在不辨对错时如何勇于决策?我没有答案。我们总是在教育和被教育中…

作者头像 李华
网站建设 2026/4/18 10:58:17

企业需要这位AI生产力总监而非首席AI官

关于谁应该负责确保企业充分利用生成式AI,存在很多争议。一些专家认为CIO应该监督这一关键角色,而其他人则认为这一责任应该由首席数据官承担。除了这些现有角色之外,其他专家支持首席AI官(CAIO)这一C级高管新成员&…

作者头像 李华