news 2026/3/3 20:54:10

ACPI!ACPIBuildDeviceRequest函数分析和ACPI!ACPIBuildDeviceDpc函数的关系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ACPI!ACPIBuildDeviceRequest函数分析和ACPI!ACPIBuildDeviceDpc函数的关系

ACPI!ACPIBuildDeviceRequest函数分析和ACPI!ACPIBuildDeviceDpc函数的关系


NTSTATUS
ACPIBuildDeviceRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN PACPI_BUILD_CALLBACK CallBack,
IN PVOID CallBackContext,
IN BOOLEAN RunDPC
)
/*++

Routine Description:

This routine is called when a device extension is ready to be filled in.
This routine creates a request which is enqueued. When the DPC is fired,
the request will be processed

Note: AcpiDeviceTreeLock must be held to call this function

Arguments:

DeviceExtension - The device which wants to be filled in
CallBack - The function to call when done
CallBackContext - The argument to pass to that function
RunDPC - Should we enqueue the DPC immediately (if it is not
running?)

Return Value:

NTSTATUS

--*/
{
PACPI_BUILD_REQUEST buildRequest;

ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );

//
// Allocate a buildRequest structure
//
buildRequest = ExAllocateFromNPagedLookasideList(
&BuildRequestLookAsideList
);
if (buildRequest == NULL) {

return STATUS_INSUFFICIENT_RESOURCES;

}

//
// If the current reference is 0, that means that someone else beat
// use to the device extension that that we *CANNOT* touch it
//
if (DeviceExtension->ReferenceCount == 0) {

ExFreeToNPagedLookasideList(
&BuildRequestLookAsideList,
buildRequest
);
return STATUS_DEVICE_REMOVED;

} else {

InterlockedIncrement( &(DeviceExtension->ReferenceCount) );

}

//
// Fill in the structure
//
RtlZeroMemory( buildRequest, sizeof(ACPI_BUILD_REQUEST) );
buildRequest->Signature = ACPI_SIGNATURE;
buildRequest->TargetListEntry = &AcpiBuildDeviceList;
buildRequest->WorkDone = WORK_DONE_STEP_0;
buildRequest->Status = STATUS_SUCCESS;
buildRequest->CallBack = CallBack;
buildRequest->CallBackContext = CallBackContext;
buildRequest->BuildContext = DeviceExtension;
buildRequest->Flags = BUILD_REQUEST_VALID_TARGET |
BUILD_REQUEST_DEVICE;

//
// At this point, we need the spinlock
//
KeAcquireSpinLockAtDpcLevel( &AcpiBuildQueueLock );

//
// Add this to the list
//
InsertTailList(
&AcpiBuildQueueList,
&(buildRequest->ListEntry)
);

//
// Do we need to queue up the DPC?
//
if (RunDPC && !AcpiBuildDpcRunning) {

KeInsertQueueDpc( &AcpiBuildDpc, 0, 0 );

}

//
// Done with the lock
//
KeReleaseSpinLockFromDpcLevel( &AcpiBuildQueueLock );

//
// Done
//
return STATUS_PENDING;
}


0: kd> t
Breakpoint 4 hit
eax=0000000a ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=80ae2bca
eip=f73fcc7c esp=f789a0b4 ebp=f789a0d8 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!ACPIBuildDeviceRequest:
f73fcc7c 55 push ebp
0: kd> kc
#
00 ACPI!ACPIBuildDeviceRequest
01 ACPI!OSNotifyCreateDevice
02 ACPI!OSNotifyCreate
03 ACPI!Device
04 ACPI!ParseTerm
05 ACPI!RunContext
06 ACPI!InsertReadyQueue
07 ACPI!RestartContext
08 ACPI!SyncLoadDDB
09 ACPI!AMLILoadDDB
0a ACPI!ACPIInitializeDDB
0b ACPI!ACPIInitializeDDBs
0c ACPI!ACPIInitialize
0d ACPI!ACPIInitStartACPI
0e ACPI!ACPIRootIrpStartDevice
0f ACPI!ACPIDispatchIrp
10 nt!IofCallDriver
11 nt!IopSynchronousCall
12 nt!IopStartDevice
13 nt!PipProcessStartPhase1
14 nt!PipProcessDevNodeTree
15 nt!PipDeviceActionWorker
16 nt!PipRequestDeviceAction
17 nt!IopInitializeBootDrivers
18 nt!IoInitSystem
19 nt!Phase1Initialization
1a nt!PspSystemThreadStartup
1b nt!KiThreadStartup


0: kd> x acpi!AcpiBuildDpc
f743b840 ACPI!AcpiBuildDpc = struct _KDPC
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!_KDPC *)0xf743b840))
(*((ACPI!_KDPC *)0xf743b840)) [Type: _KDPC]
[+0x000] Type : 19 [Type: short]
[+0x002] Number : 0x0 [Type: unsigned char]
[+0x003] Importance : 0x1 [Type: unsigned char]
[+0x004] DpcListEntry [Type: _LIST_ENTRY]
[+0x00c] DeferredRoutine : 0xf73fc5b2 [Type: void (*)(_KDPC *,void *,void *,void *)]
[+0x010] DeferredContext : 0x0 [Type: void *]
[+0x014] SystemArgument1 : 0x0 [Type: void *]
[+0x018] SystemArgument2 : 0x0 [Type: void *]
[+0x01c] DpcData : 0x0 [Type: void *]
0: kd> u f73fc5b2
ACPI!ACPIBuildDeviceDpc [d:\srv03rtm\base\busdrv\acpi\driver\nt\buildsrc.c @ 478]:
f73fc5b2 53 push ebx
f73fc5b3 8b1d70b042f7 mov ebx,dword ptr [ACPI!_imp_KefAcquireSpinLockAtDpcLevel (f742b070)]
f73fc5b9 56 push esi
f73fc5ba be98b843f7 mov esi,offset ACPI!AcpiBuildQueueLock (f743b898)
f73fc5bf 8bce mov ecx,esi
f73fc5c1 ffd3 call ebx
f73fc5c3 803d9eb843f700 cmp byte ptr [ACPI!AcpiBuildDpcRunning (f743b89e)],0
f73fc5ca 740d je ACPI!ACPIBuildDeviceDpc+0x27 (f73fc5d9)


0: kd> dv
DeviceExtension = 0x899c0d58
CallBack = 0x00000000
CallBackContext = 0x00000000
RunDPC = 0x00 ''

0: kd> dx -id 0,0,899a2278 -r1 ((ACPI!_DEVICE_EXTENSION *)0x899c0d58)
((ACPI!_DEVICE_EXTENSION *)0x899c0d58) : 0x899c0d58 [Type: _DEVICE_EXTENSION *]
[+0x000] Flags : 0xa [Type: unsigned __int64]
[+0x000] UFlags [Type: __unnamed]
[+0x008] Signature : 0x5f534750 [Type: unsigned long]
[+0x00c] DebugFlags : 0x0 [Type: unsigned long]
[+0x010] DispatchTable : 0x0 [Type: IRP_DISPATCH_TABLE *]
[+0x014] WorkContext [Type: WORK_QUEUE_CONTEXT]
[+0x014] Fdo [Type: _FDO_DEVICE_EXTENSION]
[+0x014] Filter [Type: _FILTER_DEVICE_EXTENSION]
[+0x014] Pdo [Type: _PDO_DEVICE_EXTENSION]
[+0x058] WorkQueue [Type: EXTENSION_WORKER]
[+0x058] Button [Type: BUTTON_EXTENSION]
[+0x058] Thermal [Type: THERMAL_EXTENSION]
[+0x058] LinkNode [Type: LINK_NODE_EXTENSION]
[+0x058] Dock [Type: DOCK_EXTENSION]
[+0x058] Processor [Type: _PROCESSOR_DEVICE_EXTENSION]
[+0x088] DeviceState : Stopped (0) [Type: _ACPI_DEVICE_STATE]
[+0x08c] PreviousState : Stopped (0) [Type: _ACPI_DEVICE_STATE]
[+0x090] PowerInfo [Type: _ACPI_POWER_INFO]
[+0x10c] DeviceID : 0x0 [Type: unsigned char *]
[+0x10c] Address : 0x0 [Type: unsigned long]
[+0x110] InstanceID : 0x0 [Type: unsigned char *]
[+0x114] ResourceList : 0x0 [Type: _CM_RESOURCE_LIST *]
[+0x118] PnpResourceList : 0x0 [Type: _ObjData *]
[+0x11c] OutstandingIrpCount : 1 [Type: long]
[+0x120] ReferenceCount : 2 [Type: long]
[+0x124] HibernatePathCount : 0 [Type: long]
[+0x128] RemoveEvent : 0x0 [Type: _KEVENT *]
[+0x12c] AcpiObject : 0x899affac [Type: _NSObj *]
[+0x130] DeviceObject : 0x0 [Type: _DEVICE_OBJECT *]
[+0x134] TargetDeviceObject : 0x0 [Type: _DEVICE_OBJECT *]
[+0x138] PhysicalDeviceObject : 0x0 [Type: _DEVICE_OBJECT *]
[+0x13c] ParentExtension : 0x89981a18 [Type: _DEVICE_EXTENSION *]
[+0x140] ChildDeviceList [Type: _LIST_ENTRY]
[+0x148] SiblingDeviceList [Type: _LIST_ENTRY]
[+0x150] EjectDeviceHead [Type: _LIST_ENTRY]
[+0x158] EjectDeviceList [Type: _LIST_ENTRY]

0: kd> x acpi!*rootdevice*
f743b710 ACPI!RootDeviceExtension = 0x89981a18

bp nt!IoCreateDevice


//
// Allocate a buildRequest structure
//
buildRequest = ExAllocateFromNPagedLookasideList(
&BuildRequestLookAsideList
);
if (buildRequest == NULL) {

return STATUS_INSUFFICIENT_RESOURCES;

}


0: kd> p
eax=899860d0 ebx=00000000 ecx=00000001 edx=0000000a esi=899860d0 edi=f743b7e0
eip=f73fccaf esp=f789a0a8 ebp=f789a0b0 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!ACPIBuildDeviceRequest+0x33:
f73fccaf 85f6 test esi,esi


0: kd> dt _ACPI_BUILD_REQUEST 899860d0
ACPI!_ACPI_BUILD_REQUEST
+0x000 ListEntry : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x008 Signature : 0
+0x00c Flags : 3
+0x00c UFlags : __unnamed
+0x010 WorkDone : 0x10101
+0x014 CurrentWorkDone : 0x3f8
+0x018 NextWorkDone : 0
+0x01c BuildContext : 0x00000007 Void
+0x020 Status : 0n65538
+0x024 CurrentObject : 0x00000004 _NSObj
+0x028 CallBack : 0x00000004 void +4
+0x02c CallBackContext : 0xffffffff Void
+0x030 DeviceRequest : __unnamed
+0x030 RunRequest : __unnamed
+0x030 SynchronizeRequest : __unnamed
+0x044 Integer : 0x1c2000
+0x044 String : 0x001c2000 "--- memory read error at address 0x001c2000 ---"
+0x044 TargetListEntry : 0x001c2000 _LIST_ENTRY


0: kd> x acpi!AcpiBuildDeviceList
f743b888 ACPI!AcpiBuildDeviceList = struct _LIST_ENTRY [ 0xf743b888 - 0xf743b888 ]
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!_LIST_ENTRY *)0xf743b888))
(*((ACPI!_LIST_ENTRY *)0xf743b888)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0xf743b888 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xf743b888 [Type: _LIST_ENTRY *]

//
// Fill in the structure
//
RtlZeroMemory( buildRequest, sizeof(ACPI_BUILD_REQUEST) );
buildRequest->Signature = ACPI_SIGNATURE;
buildRequest->TargetListEntry = &AcpiBuildDeviceList; 关键地方1:
buildRequest->WorkDone = WORK_DONE_STEP_0;
buildRequest->Status = STATUS_SUCCESS;
buildRequest->CallBack = CallBack;
buildRequest->CallBackContext = CallBackContext;
buildRequest->BuildContext = DeviceExtension; 关键地方2:
buildRequest->Flags = BUILD_REQUEST_VALID_TARGET |
BUILD_REQUEST_DEVICE;


0: kd> dt _ACPI_BUILD_REQUEST 899860d0
ACPI!_ACPI_BUILD_REQUEST
+0x000 ListEntry : _LIST_ENTRY [ 0xf743b890 - 0x899c6d08 ]
+0x008 Signature : 0x5f534750
+0x00c Flags : 0x1001
+0x00c UFlags : __unnamed
+0x010 WorkDone : 3
+0x014 CurrentWorkDone : 0
+0x018 NextWorkDone : 0
+0x01c BuildContext : 0x899c0d58 Void
+0x020 Status : 0n0
+0x024 CurrentObject : (null)
+0x028 CallBack : (null)
+0x02c CallBackContext : (null)
+0x030 DeviceRequest : __unnamed
+0x030 RunRequest : __unnamed
+0x030 SynchronizeRequest : __unnamed
+0x044 Integer : 0xf743b888
+0x044 String : 0xf743b888 "???"
+0x044 TargetListEntry : 0xf743b888 _LIST_ENTRY [ 0xf743b888 - 0xf743b888 ]

//
// Add this to the list
//
InsertTailList(
&AcpiBuildQueueList,
&(buildRequest->ListEntry)
);


0: kd> x acpi!AcpiBuildQueueList
f743b890 ACPI!AcpiBuildQueueList = struct _LIST_ENTRY [ 0x899c6d08 - 0x899860d0 ]
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!_LIST_ENTRY *)0xf743b890))
(*((ACPI!_LIST_ENTRY *)0xf743b890)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x899c6d08 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x899860d0 [Type: _LIST_ENTRY *]
0: kd> dx -id 0,0,899a2278 -r1 ((ACPI!_LIST_ENTRY *)0x899c6d08)
((ACPI!_LIST_ENTRY *)0x899c6d08) : 0x899c6d08 [Type: _LIST_ENTRY *]
[+0x000] Flink : 0x899860d0 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0xf743b890 [Type: _LIST_ENTRY *]

参考:第一个是什么情况:
0: kd> dt _ACPI_BUILD_REQUEST 0x899c6d08
ACPI!_ACPI_BUILD_REQUEST
+0x000 ListEntry : _LIST_ENTRY [ 0x899860d0 - 0xf743b890 ]
+0x008 Signature : 0x5f534750
+0x00c Flags : 0x100a
+0x00c UFlags : __unnamed
+0x010 WorkDone : 3
+0x014 CurrentWorkDone : 0
+0x018 NextWorkDone : 0
+0x01c BuildContext : 0x89981a18 Void
+0x020 Status : 0n0
+0x024 CurrentObject : (null)
+0x028 CallBack : 0xf7400be2 void ACPI!ACPIDevicePowerNotifyEvent+0
+0x02c CallBackContext : 0xf789a260 Void
+0x030 DeviceRequest : __unnamed
+0x030 RunRequest : __unnamed
+0x030 SynchronizeRequest : __unnamed
+0x044 Integer : 0xf743b868
+0x044 String : 0xf743b868 "h???"
+0x044 TargetListEntry : 0xf743b868 _LIST_ENTRY [ 0xf743b868 - 0xf743b868 ]


0: kd> u 0xf743b868
ACPI!AcpiBuildSynchronizationList:
f743b868 68b843f768 push 68F743B8h
f743b86d b843f770b8 mov eax,0B870F743h
f743b872 43 inc ebx
f743b873 f770b8 div eax,dword ptr [eax-48h]
f743b876 43 inc ebx
f743b877 f778b8 idiv eax,dword ptr [eax-48h]
f743b87a 43 inc ebx
f743b87b f778b8 idiv eax,dword ptr [eax-48h]

F:\srv03rtm>grep "AcpiBuildSynchronizationList" -nr F:\srv03rtm\base\busdrv\acpi |grep -v "inary"
F:\srv03rtm\base\busdrv\acpi/driver/nt/acpiosnt.c:182: InitializeListHead( &AcpiBuildSynchronizationList );
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:124:LIST_ENTRY AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:717: if (!IsListEmpty( &AcpiBuildSynchronizationList) ) {
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:725: &AcpiBuildSynchronizationList
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:6725: syncRequest->TargetListEntry = &AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.c:7037: buildRequest->TargetListEntry = &AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/buildsrc.h:256: extern LIST_ENTRY AcpiBuildSynchronizationList;
F:\srv03rtm\base\busdrv\acpi/driver/nt/obj/i386/acpi.map:3021: 0003:00003868 _AcpiBuildSynchronizationList 00052868 <common>
F:\srv03rtm\base\busdrv\acpi/tools/kdext/build.c:229: dumpAcpiBuildList( "ACPI!AcpiBuildSynchronizationList" );


NTSTATUS
ACPIBuildSynchronizationRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN PACPI_BUILD_CALLBACK CallBack,
IN PVOID CallBackContext,
IN PLIST_ENTRY SynchronizeListEntry,
IN BOOLEAN RunDPC
)
{

//
// Fill in the structure
//
RtlZeroMemory( buildRequest, sizeof(ACPI_BUILD_REQUEST) );
buildRequest->Signature = ACPI_SIGNATURE;
buildRequest->TargetListEntry = &AcpiBuildSynchronizationList;


0: kd> dt ACPI!_DEVICE_EXTENSION 0x89981a18
+0x000 Flags : 0x0001e000`00200010
+0x000 UFlags : __unnamed
+0x008 Signature : 0x5f534750
+0x00c DebugFlags : 0
+0x010 DispatchTable : 0xf743826c IRP_DISPATCH_TABLE
+0x014 WorkContext : WORK_QUEUE_CONTEXT
+0x014 Fdo : _FDO_DEVICE_EXTENSION
+0x014 Filter : _FILTER_DEVICE_EXTENSION
+0x014 Pdo : _PDO_DEVICE_EXTENSION
+0x058 WorkQueue : EXTENSION_WORKER
+0x058 Button : BUTTON_EXTENSION
+0x058 Thermal : THERMAL_EXTENSION
+0x058 LinkNode : LINK_NODE_EXTENSION
+0x058 Dock : DOCK_EXTENSION
+0x058 Processor : _PROCESSOR_DEVICE_EXTENSION
+0x088 DeviceState : 0 ( Stopped )
+0x08c PreviousState : 0 ( Stopped )
+0x090 PowerInfo : _ACPI_POWER_INFO
+0x10c DeviceID : 0x899bfea0 "ACPI\PNP0C08"
+0x10c Address : 0x899bfea0
+0x110 InstanceID : 0x899c53e8 "0x5F534750"
+0x114 ResourceList : 0x899bfeb8 _CM_RESOURCE_LIST
+0x118 PnpResourceList : (null)
+0x11c OutstandingIrpCount : 0n2
+0x120 ReferenceCount : 0n3
+0x124 HibernatePathCount : 0n0
+0x128 RemoveEvent : (null)
+0x12c AcpiObject : (null)
+0x130 DeviceObject : 0x89981b98 _DEVICE_OBJECT
+0x134 TargetDeviceObject : 0x899c1de0 _DEVICE_OBJECT
+0x138 PhysicalDeviceObject : 0x899c1de0 _DEVICE_OBJECT
+0x13c ParentExtension : (null)
+0x140 ChildDeviceList : _LIST_ENTRY [ 0x899c0ea0 - 0x899c0ea0 ]
+0x148 SiblingDeviceList : _LIST_ENTRY [ 0x89981b60 - 0x89981b60 ]
+0x150 EjectDeviceHead : _LIST_ENTRY [ 0x89981b68 - 0x89981b68 ]
+0x158 EjectDeviceList : _LIST_ENTRY [ 0x89981b70 - 0x89981b70 ]

参考:第一个是什么情况:


0: kd> x acpi!AcpiBuildDpcRunning
f743b89e ACPI!AcpiBuildDpcRunning = 0x00 ''
0: kd> x acpi!RunDPC
0: kd> dv RunDPC
RunDPC = 0x00 ''

//
// Do we need to queue up the DPC?
//
if (RunDPC && !AcpiBuildDpcRunning) {

KeInsertQueueDpc( &AcpiBuildDpc, 0, 0 );

}

//
// Done with the lock
//
KeReleaseSpinLockFromDpcLevel( &AcpiBuildQueueLock );

//
// Done
//
return STATUS_PENDING;
}

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

ozon、美客多测评必杀技:黑科技测评环境

在跨境电商领域&#xff0c;各大平台的风控体系都在不断迭代升级。与之相应的是&#xff0c;测评补单技术也必须与时俱进&#xff0c;持续优化&#xff0c;才能在新的风控环境下保障测评补单操作的稳定与安全。对于卖家而言&#xff0c;若选择自己养号测评补单&#xff0c;需要…

作者头像 李华
网站建设 2026/3/3 18:17:54

OCR伦理问题思考:HunyuanOCR应如何平衡便利与安全

OCR伦理问题思考&#xff1a;HunyuanOCR应如何平衡便利与安全 在智能办公、跨境支付、远程身份核验日益普及的今天&#xff0c;一张照片就能提取身份证信息、自动翻译菜单、识别医疗单据——这曾是科幻电影中的场景&#xff0c;如今正通过像 HunyuanOCR 这样的端到端多模态模型…

作者头像 李华
网站建设 2026/2/28 23:55:21

引言:技术趋势预测的背景与意义

技术趋势预测的背景与意义2023年技术领域的关键突破为2024年趋势奠定基础&#xff0c;分析年度技术趋势有助于开发者把握方向&#xff0c;提前布局学习与职业规划。CSDN作为开发者社区&#xff0c;其数据与专家观点具有行业参考价值。核心趋势领域预测人工智能与生成式AI 大模型…

作者头像 李华
网站建设 2026/3/2 22:38:40

INT8量化部署教程:降低GPU显存占用的实践步骤

INT8量化部署实践&#xff1a;如何在单卡4090D上高效运行百亿级OCR模型 在当今AI系统部署的现实挑战中&#xff0c;显存瓶颈始终是悬在开发者头顶的一把利剑。尤其是面对多模态大模型时&#xff0c;哪怕是一个“轻量级”的1B参数OCR系统&#xff0c;若以FP32格式加载&#xff…

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

Prometheus监控接入:跟踪HunyuanOCR GPU利用率指标

Prometheus监控接入&#xff1a;跟踪HunyuanOCR GPU利用率指标 在AI模型日益深入生产系统的今天&#xff0c;一个常见的尴尬场景是&#xff1a;服务明明“跑起来了”&#xff0c;却没人说得清它到底“跑得怎么样”。尤其是在部署像HunyuanOCR这样的多模态大模型时&#xff0c;…

作者头像 李华
网站建设 2026/3/3 1:10:57

二维码内容提取尝试:HunyuanOCR能否解析条形码区域

二维码内容提取尝试&#xff1a;HunyuanOCR能否解析条形码区域 在企业级文档自动化处理的日常中&#xff0c;一个看似简单却频繁出现的需求是——从一张发票、一张快递单或一张电子票券中&#xff0c;快速准确地提取出条形码和二维码所包含的信息。传统做法是部署两套系统&…

作者头像 李华