news 2026/10/12 18:51:37

ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor

ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor

//
// Handle the hints that are given to us
//
if (buffer->GFlag & PNP_ADDRESS_FLAG_MINIMUM_FIXED &&
buffer->GFlag & PNP_ADDRESS_FLAG_MAXIMUM_FIXED) {

if (Descriptor->Type == CmResourceTypeBusNumber) {

oldValue = Descriptor->u.BusNumber.Length;
newValue = Descriptor->u.BusNumber.Length =
Descriptor->u.BusNumber.MaxBusNumber -
Descriptor->u.BusNumber.MinBusNumber + 1;

}


//
// Move to the next descriptor
//
buffer += increment;
tagName = *buffer;

}

switch(tagName) {

case TAG_DOUBLE_ADDRESS: {

status = PnpiBiosAddressDoubleToIoDescriptor(
buffer,
Array,
ArrayIndex,
Flags
);

ACPIPrint( (
ACPI_PRINT_RESOURCES_2,
"PnpBiosResourcesToNtResources: TAG_DOUBLE_ADDRESS = 0x%8lx\n",
status
) );
break;
}

0: kd> kc
#
00 ACPI!PnpiBiosAddressDoubleToIoDescriptor
01 ACPI!PnpBiosResourcesToNtResources
02 ACPI!ACPIBusIrpQueryResourceRequirements
03 ACPI!ACPIDispatchIrp
04 nt!IofCallDriver
05 nt!IopSynchronousCall
06 nt!PpIrpQueryResourceRequirements
07 nt!PiQueryResourceRequirements
08 nt!PiProcessNewDeviceNode
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
Data = 0xe129e381 "???"
Array = 0xe1278800
ArrayIndex = 0
Flags = 1


0: kd> db 0xe129e381
e129e381 87 18 00 00 0c 03 00 00-00 00 00 00 0a 00 ff ff ................
e129e391 0b 00 00 00 00 00 00 00-02 00 00 87 18 00 00 0c ................


0: kd> dt PNP_DWORD_ADDRESS_DESCRIPTOR 0xe129e381
ACPI!PNP_DWORD_ADDRESS_DESCRIPTOR
+0x000 Tag : 0x87 ''
+0x001 Length : 0x18
+0x003 RFlag : 0 '' PNP_ADDRESS_MEMORY_TYPE 0x0
+0x004 GFlag : 0xc ''
+0x005 TFlag : 0x3 ''
+0x006 Granularity : 0
+0x00a MinimumAddress : 0xa0000
+0x00e MaximumAddress : 0xbffff
+0x012 TranslationAddress : 0
+0x016 AddressLength : 0x20000


DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, // Granularity
0x000A0000, // Range Minimum
0x000BFFFF, // Range Maximum
0x00000000, // Translation Offset
0x00020000, // Length
0x00,, , AddressRangeMemory, TypeStatic)


//
// These are the possible values for RFlag Means
//
#define PNP_ADDRESS_MEMORY_TYPE 0x0
#define PNP_ADDRESS_IO_TYPE 0x1
#define PNP_ADDRESS_BUS_NUMBER_TYPE 0x2

//
// The Global flags
//
#define PNP_ADDRESS_FLAG_CONSUMED_ONLY 0x1
#define PNP_ADDRESS_FLAG_SUBTRACTIVE_DECODE 0x2
#define PNP_ADDRESS_FLAG_MINIMUM_FIXED 0x4
#define PNP_ADDRESS_FLAG_MAXIMUM_FIXED 0x8

//
// Ensure that there is enough space within the chosen list to add the
// resource
//
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &rangeDescriptor );
if (!NT_SUCCESS(status)) {

return status;
}


0: kd> t
eax=f789a164 ebx=80ae2bca ecx=80ae0dfa edx=80b18958 esi=e1278800 edi=e129e381
eip=f744a2d2 esp=f789a138 ebp=f789a158 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
ACPI!PnpiUpdateResourceList:
f744a2d2 55 push ebp
0: kd> dv
ResourceList = 0xe1278800
ResourceDesc = 0xf789a164
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_LIST * *)0xe1278800)
((ACPI!_IO_RESOURCE_LIST * *)0xe1278800) : 0xe1278800 [Type: _IO_RESOURCE_LIST * *]
0xe12a7908 [Type: _IO_RESOURCE_LIST *]


//
// Find the next descriptor to use
//
*ResourceDesc = & ( (*ResourceList)->Descriptors[ (*ResourceList)->Count ] );

0: kd> dv ResourceDesc
ResourceDesc = 0xf789a164
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_DESCRIPTOR * *)0xf789a164)
((ACPI!_IO_RESOURCE_DESCRIPTOR * *)0xf789a164) : 0xf789a164 [Type: _IO_RESOURCE_DESCRIPTOR * *]
0xe12a7930 : No Resource [Type: _IO_RESOURCE_DESCRIPTOR *]

0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 1
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR


0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910
+0x000 Option : 0 ''
+0x001 Type : 0x6 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR -v
struct _IO_RESOURCE_DESCRIPTOR, 7 elements, 0x20 bytes
+0x000 Option : UChar
+0x001 Type : UChar
+0x002 ShareDisposition : UChar
+0x003 Spare1 : UChar
+0x004 Flags : Uint2B
+0x006 Spare2 : Uint2B
+0x008 u : union __unnamed, 8 elements, 0x18 bytes
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*3
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*4
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*5
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*6
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*7
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*8
+0x000 Option : 0x22 '"'
+0x001 Type : 0x8 ''
+0x002 ShareDisposition : 0x2c ','
+0x003 Spare1 : 0x4 ''
+0x004 Flags : 0x624f
+0x006 Spare2 : 0x7153
+0x008 u : __unnamed

//
// Update the count of in-use descriptors
//
(*ResourceList)->Count += 1;


0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 2
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR


//
// Ensure that there is enough space within the chosen list to add the
// resource
//
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &rangeDescriptor );
if (!NT_SUCCESS(status)) {

return status;
}

0: kd> dv rangeDescriptor
rangeDescriptor = 0xe12a7930 No Resource


//
// If this is I/O or Memory, then we will need to make enough space for
// a device private resource too.
//
if ((buffer->RFlag == PNP_ADDRESS_MEMORY_TYPE) ||
(buffer->RFlag == PNP_ADDRESS_IO_TYPE)) {

status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &privateDescriptor );

if (!NT_SUCCESS(status)) {
return status;
}


0: kd> kc
#
00 ACPI!PnpiUpdateResourceList
01 ACPI!PnpiBiosAddressDoubleToIoDescriptor
02 ACPI!PnpBiosResourcesToNtResources
03 ACPI!ACPIBusIrpQueryResourceRequirements
04 ACPI!ACPIDispatchIrp
05 nt!IofCallDriver
06 nt!IopSynchronousCall
07 nt!PpIrpQueryResourceRequirements
08 nt!PiQueryResourceRequirements
09 nt!PiProcessNewDeviceNode
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
ResourceList = 0xe1278800
ResourceDesc = 0xf789a160
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_LIST * *)0xe1278800)
((ACPI!_IO_RESOURCE_LIST * *)0xe1278800) : 0xe1278800 [Type: _IO_RESOURCE_LIST * *]
0xe12a7908 [Type: _IO_RESOURCE_LIST *]


0: kd> gu
eax=00000000 ebx=80ae2bca ecx=f789a160 edx=80b18958 esi=e1278800 edi=e129e381
eip=f744ac0c esp=f789a144 ebp=f789a158 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
ACPI!PnpiBiosAddressDoubleToIoDescriptor+0xa8:
f744ac0c 85c0 test eax,eax
0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 3
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR


0: kd> dv privateDescriptor
privateDescriptor = 0xe12a7950 No Resource
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed

privateDescriptor->Type = CmResourceTypeDevicePrivate;

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed


#define CmResourceTypeNonArbitrated 128 // Not arbitrated if 0x80 bit set
#define CmResourceTypeConfigData 128 // ResType_Reserved (0x8000)
#define CmResourceTypeDevicePrivate 129 // ResType_DevicePrivate (0x8001)
#define CmResourceTypePcCardConfig 130 // ResType_PcCardConfig (0x8002)
#define CmResourceTypeMfCardConfig 131 // ResType_MfCardConfig (0x8003)


privateDescriptor->Flags = TRANSLATION_DATA_PARENT_ADDRESS;

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed


#define TRANSLATION_RANGE_SPARSE 0x0001
#define TRANSLATION_DATA_PARENT_ADDRESS 0x6000


//
// Fill in the top 32 bits of the start address.
//
privateDescriptor->u.DevicePrivate.Data[2] = 0;

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950 -r
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Memory : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 0
+0x004 MaximumVector : 0
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 0
+0x004 MaximumChannel : 0
+0x000 Generic : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 0
+0x000 BusNumber : __unnamed
+0x000 Length : 0
+0x004 MinBusNumber : 0
+0x008 MaxBusNumber : 0
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 0
+0x004 Reserved1 : 0
+0x008 Reserved2 : 0


length = buffer->AddressLength;
alignment = buffer->Granularity + 1;

//
// Calculate the bounds of both the parent and child sides of
// the bridge.
//
// The translation field applies to the parent address i.e.
// the child address is the address in the buffer and the
// parent address is the addition of the child address and
// the translation field.
//

parentMin = buffer->MinimumAddress + buffer->TranslationAddress;
childMin = buffer->MinimumAddress;
childMax = buffer->MaximumAddress;


switch (buffer->RFlag) {
case PNP_ADDRESS_MEMORY_TYPE:

//
// Set the proper ranges
//

rangeDescriptor->u.Memory.Alignment = alignment;
rangeDescriptor->u.Memory.Length = length;
rangeDescriptor->u.Memory.MinimumAddress.LowPart = childMin;
rangeDescriptor->u.Memory.MaximumAddress.LowPart = childMax;
rangeDescriptor->u.Memory.MinimumAddress.HighPart =
rangeDescriptor->u.Memory.MaximumAddress.HighPart = 0;
rangeDescriptor->Type = CmResourceTypeMemory;

typedef enum _CM_RESOURCE_TYPE {
CmResourceTypeNull = 0, // Reserved
CmResourceTypePort, 1
CmResourceTypeInterrupt, 2
CmResourceTypeMemory, 3
CmResourceTypeDma, 4
CmResourceTypeDeviceSpecific
} CM_RESOURCE_TYPE;


0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20 -r
+0x000 Option : 0 ''
+0x001 Type : 0x3 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 Memory : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 0x20000
+0x004 MaximumVector : 1
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 0x20000
+0x004 MaximumChannel : 1
+0x000 Generic : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 0x20000
+0x000 BusNumber : __unnamed
+0x000 Length : 0x20000
+0x004 MinBusNumber : 1
+0x008 MaxBusNumber : 0xa0000
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 0x20000
+0x004 Reserved1 : 1
+0x008 Reserved2 : 0xa0000

if (buffer->TFlag & TRANSLATION_MEM_TO_IO) {

//
// The device private describes the parent. With this
// flag set, the descriptor type of the parent will
// changed from Memory to IO.
//

privateDescriptor->u.DevicePrivate.Data[0] =
CmResourceTypePort;

} else {

//
// The parent descriptor type will not change.
//

privateDescriptor->u.DevicePrivate.Data[0] =
CmResourceTypeMemory;

}
0: kd> dd 0xe12a7910+20*2
e12a7950 00008100 00006000 00000003 000a0000
e12a7960 00000000 00000000 00000000 00000000


0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2 -r
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Memory : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 3
+0x004 MaximumVector : 0xa0000
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 3
+0x004 MaximumChannel : 0xa0000
+0x000 Generic : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 3
+0x000 BusNumber : __unnamed
+0x000 Length : 3
+0x004 MinBusNumber : 0xa0000
+0x008 MaxBusNumber : 0
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 3
+0x004 Reserved1 : 0xa0000
+0x008 Reserved2 : 0
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!unsigned long (*)[3])0xe12a7958))
(*((ACPI!unsigned long (*)[3])0xe12a7958)) [Type: unsigned long [3]]
[0] : 0x3 [Type: unsigned long]
[1] : 0xa0000 [Type: unsigned long]
[2] : 0x0 [Type: unsigned long]


回顾:parentMin
parentMin = buffer->MinimumAddress + buffer->TranslationAddress;
childMin = buffer->MinimumAddress;
childMax = buffer->MaximumAddress;
回顾结束:

//
// Handle global flags
//
PnpiBiosAddressHandleGlobalFlags( buffer, rangeDescriptor );
return STATUS_SUCCESS;
}

VOID
PnpiBiosAddressHandleGlobalFlags(
IN PVOID Buffer,
IN PIO_RESOURCE_DESCRIPTOR Descriptor
)
{
} else {

Descriptor->ShareDisposition = CmResourceShareShared;

}

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20
+0x000 Option : 0 ''
+0x001 Type : 0x3 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x20
+0x006 Spare2 : 0
+0x008 u : __unnamed

0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!unsigned long (*)[3])0xe12a7958))
(*((ACPI!unsigned long (*)[3])0xe12a7958)) [Type: unsigned long [3]]
[0] : 0x3 [Type: unsigned long]
[1] : 0xa0000 [Type: unsigned long]
[2] : 0x0 [Type: unsigned long]

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

2026必备!千笔,专科生降AI率神器

在AI技术迅速渗透学术写作领域的当下,越来越多的专科生开始借助AI工具提升论文写作效率。然而,随着查重系统对AI生成内容的识别能力不断提升,AI率超标问题日益严峻,成为影响论文通过率的关键障碍。面对市场上五花八门的降AI率和降…

作者头像 李华
网站建设 2026/10/11 2:16:00

猫眼电影数据可视化与智能分析平台 | Python Flask框架 Echarts 预测/推荐算法 爬虫 大数据 deepseek 毕业设计源码(建议收藏)✅

博主介绍:✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌ > 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与…

作者头像 李华
网站建设 2026/10/5 5:28:37

【通信设备】电视会议系统架构与技术解析

目录 1. 引言:电视会议系统的价值与市场趋势 1.1 核心需求驱动 1.2 市场竞争格局 2. 电视会议系统基础架构解析 2.1 系统组成构成 2.2 网络传输层协议 2.3 带宽需求计算 2.4 核心技术指标与QoS保障 3. 核心技术与实现原理 3.1 音视频处理与编码压缩 3.2 网…

作者头像 李华
网站建设 2026/10/12 3:21:00

赶deadline必备!顶流之选的降AI率软件 —— 千笔·降AI率助手

在AI技术日益渗透学术写作的当下,越来越多的学生、研究人员和职场人士开始借助AI工具提升写作效率。然而,随之而来的AI率超标问题却让许多人在论文提交前陷入焦虑——无论是知网、维普还是Turnitin等查重系统,都在不断升级算法,对…

作者头像 李华
网站建设 2026/10/10 19:44:28

手写mybatis

手写mybatis https://gitee.com/laomaodu/handwritten-mybatis 内容回顾 sqlsession线程不安全 public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType,PersistenceExceptionTranslator exceptionTranslator) { ​notNull(s…

作者头像 李华