当前位置: 首页 > news >正文

Ntfs!NtfsCheckpointVolume函数中的Ntfs!LfsFlushLfcb函数对Lfcb->LogHeadBuffer进行了赋值--重要


第一部分:


//
//
//  If we can do the Io, call down to flush the Lfcb.
//

        if (Flush) {
LfsFlushLfcb( Lfcb, Lsn, RestartLsn );
break;
}

第二部分:

          if (LfsRestart) {

                PLFS_RESTART_PAGE_HEADER RestartPage;

                ASSERT( !UseTailCopy && IoBlocks == 1);

                //
//  Build the partial mdl to describe this lfs restart page from the permanently
//  mapped piece of the log
//

                RestartPage = Add2Ptr( Lfcb->LogHeadBuffer, FileOffset, PLFS_RESTART_PAGE_HEADER );
IoBuildPartialMdl( Lfcb->LogHeadMdl, Lfcb->LogHeadPartialMdl, RestartPage, (ULONG)Lfcb->LogPageSize );


第三部分:


0: kd> t
Ntfs!LfsFlushToLsnPriv+0x1c4:
f71fe6b6 e817d2f5ff      call    Ntfs!LfsFlushLfcb (f715b8d2)
0: kd> t
Ntfs!LfsFlushLfcb:
f715b8d2 689c000000      push    9Ch
0: kd> kc
#
00 Ntfs!LfsFlushLfcb
01 Ntfs!LfsFlushToLsnPriv
02 Ntfs!LfsWriteLfsRestart
03 Ntfs!LfsWriteRestartArea
04 Ntfs!NtfsCheckpointVolume
05 Ntfs!NtfsMountVolume
06 Ntfs!NtfsCommonFileSystemControl
07 Ntfs!NtfsFspDispatch
08 nt!ExpWorkerThread
09 nt!PspSystemThreadStartup
0a nt!KiThreadStartup
0: kd> dv
Lfcb = 0xe13417d8
TargetLsn = {135414905}
RestartLsn = 0x01 ''
FirstLbcb = 0x8999d020


if (TargetLsn.QuadPart > Lfcb->RestartArea->CurrentLsn.QuadPart) {

            ThisLbcb = CONTAINING_RECORD( Lfcb->LbcbWorkque.Blink,
LBCB,
WorkqueLinks );

            TargetLsn.QuadPart = ThisLbcb->LastLsn.QuadPart;
RestartLsn = (BOOLEAN) LfsLbcbIsRestart( ThisLbcb );
}

第四部分:


0: kd> dx -r1 ((Ntfs!_LFCB *)0xe13417d8)
((Ntfs!_LFCB *)0xe13417d8)                 : 0xe13417d8 [Type: _LFCB *]
[+0x000] NodeTypeCode     : 2051 [Type: short]
[+0x002] NodeByteSize     : 352 [Type: short]

[+0x070] SeqNumber        : 8 [Type: __int64]
[+0x078] SeqNumberForWrap : 9 [Type: __int64]
[+0x080] SeqNumberBits    : 0x28 [Type: unsigned long]
[+0x084] FileDataBits     : 0x18 [Type: unsigned long]
[+0x088] LbcbWorkque      [Type: _LIST_ENTRY]

0: kd> dx -r1 (*((Ntfs!_LIST_ENTRY *)0xe1341860))
(*((Ntfs!_LIST_ENTRY *)0xe1341860))                 [Type: _LIST_ENTRY]
[+0x000] Flink            : 0xe135ed2c [Type: _LIST_ENTRY *]
[+0x004] Blink            : 0xe127bc34 [Type: _LIST_ENTRY *]


//
//  Remember the first Lbcb in the list.
//

        FirstLbcb = CONTAINING_RECORD( Lfcb->LbcbWorkque.Flink,
LBCB,
WorkqueLinks );


0: kd> dt _lbcb 0xe127bc34-4
Ntfs!_LBCB
+0x000 NodeTypeCode     : 0n2050
+0x002 NodeByteSize     : 0n96
+0x004 WorkqueLinks     : _LIST_ENTRY [ 0xe1341860 - 0xe1350cec ]
+0x00c ActiveLinks      : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 FileOffset       : 0n4096
+0x020 Length           : 0n224
+0x028 SeqNumber        : 0n0
+0x030 BufferOffset     : 0n0
+0x038 PageHeader       : 0xe139d008 Void
+0x03c LogPageBcb       : (null)
+0x040 LastLsn          : _LARGE_INTEGER 0x8124479
+0x048 LastEndLsn       : _LARGE_INTEGER 0x8124479
+0x050 Flags            : 0
+0x054 LbcbFlags        : 0x20
+0x058 ResourceThread   : 0

第五部分:

#define LfsLbcbIsRestart(LBCB)                                  \
(FlagOn( (LBCB)->LbcbFlags, LBCB_RESTART_LBCB ))


#define LBCB_LOG_WRAPPED                        (0x00000001)
#define LBCB_ON_ACTIVE_QUEUE                    (0x00000002)
#define LBCB_NOT_EMPTY                          (0x00000004)
#define LBCB_FLUSH_COPY                         (0x00000008)
#define LBCB_RESTART_LBCB                       (0x00000020)

         RestartLsn = (BOOLEAN) LfsLbcbIsRestart( ThisLbcb );        TRUE

0: kd> p
Ntfs!LfsFlushLfcb+0xaa:
f715b97c 83e020          and     eax,20h
0: kd> r
eax=00000020


0: kd> dv FirstLbcb
FirstLbcb = 0xe135ed28


0: kd> dx -r1 (*((Ntfs!_LIST_ENTRY *)0xe1341860))
(*((Ntfs!_LIST_ENTRY *)0xe1341860))                 [Type: _LIST_ENTRY]
[+0x000] Flink            : 0xe135ed2c [Type: _LIST_ENTRY *]
[+0x004] Blink            : 0xe127bc34 [Type: _LIST_ENTRY *]

0: kd> dt lbcb 0xe135ed2c-4
Ntfs!LBCB
+0x000 NodeTypeCode     : 0n2050
+0x002 NodeByteSize     : 0n96
+0x004 WorkqueLinks     : _LIST_ENTRY [ 0xe1277b54 - 0xe1341860 ]
+0x00c ActiveLinks      : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 FileOffset       : 0n4096
+0x020 Length           : 0n4048
+0x028 SeqNumber        : 0n0
+0x030 BufferOffset     : 0n0
+0x038 PageHeader       : 0xe1363008 Void
+0x03c LogPageBcb       : (null)
+0x040 LastLsn          : _LARGE_INTEGER 0x8124466
+0x048 LastEndLsn       : _LARGE_INTEGER 0x8124466
+0x050 Flags            : 0
+0x054 LbcbFlags        : 0x20
+0x058 ResourceThread   : 0


第六部分:


LfsFindFirstIo( Lfcb,
TargetLsn,
RestartLsn,
FirstLbcb,
&NextLbcb,
&FileOffset,
&ContainsLastEntry,
&LfsRestart,
&UseTailCopy,
&IoBlocks );

0: kd> p
Ntfs!LfsFlushLfcb+0x11a:
f715b9ec e883380a00      call    Ntfs!LfsFindFirstIo (f71ff274)
0: kd> t
Ntfs!LfsFindFirstIo:
f71ff274 55              push    ebp
0: kd> kc
#
00 Ntfs!LfsFindFirstIo
01 Ntfs!LfsFlushLfcb
02 Ntfs!LfsFlushToLsnPriv
03 Ntfs!LfsWriteLfsRestart
04 Ntfs!LfsWriteRestartArea
05 Ntfs!NtfsCheckpointVolume
06 Ntfs!NtfsMountVolume
07 Ntfs!NtfsCommonFileSystemControl
08 Ntfs!NtfsFspDispatch
09 nt!ExpWorkerThread
0a nt!PspSystemThreadStartup
0b nt!KiThreadStartup
0: kd> dv
Lfcb = 0xe13417d8
TargetLsn = {135414905}
RestartLsn = 0x20 ' '
FirstLbcb = 0xe135ed28
NextLbcb = 0xf78d66cc
FileOffset = 0xf78d6724
ContainsLastEntry = 0xf78d672c ""


//
//  Local support routine.
//

VOID
LfsFindFirstIo (
IN PLFCB Lfcb,
IN LSN TargetLsn,
IN BOOLEAN RestartLsn,
IN PLBCB FirstLbcb,
OUT PLBCB *NextLbcb,
OUT PLONGLONG FileOffset,
OUT PBOOLEAN ContainsLastEntry,
OUT PBOOLEAN LfsRestart,
OUT PBOOLEAN UseTailCopy,
OUT PULONG IoBlocks
)


} else {

        *ContainsLastEntry = FALSE;
}


0: kd> dv ContainsLastEntry
ContainsLastEntry = 0xf78d672c ""
0: kd> dx -r1 ((Ntfs!unsigned char *)0xf78d672c)
((Ntfs!unsigned char *)0xf78d672c)                 : 0xf78d672c : 0x0 [Type: unsigned char *]
0x0 [Type: unsigned char]


第七部分:

    if (LfsLbcbIsRestart( FirstLbcb )) {

        *LfsRestart = TRUE;            //关键代码


0: kd> dv LfsRestart
LfsRestart = 0xf78d672e "???"
0: kd> dx -r1 ((Ntfs!unsigned char *)0xf78d672e)
((Ntfs!unsigned char *)0xf78d672e)                 : 0xf78d672e : 0x1 [Type: unsigned char *]
0x1 [Type: unsigned char]

第八部分:

    //
//  If we haven't found the Lbcb to restart from we will just use the
//  next Lbcb after the last one found.
//

    if ((*NextLbcb == NULL) && (FirstLbcb->WorkqueLinks.Flink != &Lfcb->LbcbWorkque)) {

        *NextLbcb = CONTAINING_RECORD( FirstLbcb->WorkqueLinks.Flink,
LBCB,
WorkqueLinks );
}

0: kd> dx -r1 ((Ntfs!_LBCB *)0xe135ed28)
((Ntfs!_LBCB *)0xe135ed28)                 : 0xe135ed28 [Type: _LBCB *]
[+0x000] NodeTypeCode     : 2050 [Type: short]
[+0x002] NodeByteSize     : 96 [Type: short]
[+0x004] WorkqueLinks     [Type: _LIST_ENTRY]
[+0x00c] ActiveLinks      [Type: _LIST_ENTRY]
[+0x018] FileOffset       : 4096 [Type: __int64]
[+0x020] Length           : 4048 [Type: __int64]
[+0x028] SeqNumber        : 0 [Type: __int64]
[+0x030] BufferOffset     : 0 [Type: __int64]
[+0x038] PageHeader       : 0xe1363008 [Type: void *]
[+0x03c] LogPageBcb       : 0x0 [Type: void *]
[+0x040] LastLsn          : {135414886} [Type: _LARGE_INTEGER]
[+0x048] LastEndLsn       : {135414886} [Type: _LARGE_INTEGER]
[+0x050] Flags            : 0x0 [Type: unsigned long]
[+0x054] LbcbFlags        : 0x20 [Type: unsigned long]
[+0x058] ResourceThread   : 0x0 [Type: unsigned long]
0: kd> dx -r1 (*((Ntfs!_LIST_ENTRY *)0xe135ed2c))
(*((Ntfs!_LIST_ENTRY *)0xe135ed2c))                 [Type: _LIST_ENTRY]
[+0x000] Flink            : 0xe1277b54 [Type: _LIST_ENTRY *]
[+0x004] Blink            : 0xe1341860 [Type: _LIST_ENTRY *]
0: kd> dt _lbcb 0xe1277b54-4
Ntfs!_LBCB
+0x000 NodeTypeCode     : 0n2050
+0x002 NodeByteSize     : 0n96
+0x004 WorkqueLinks     : _LIST_ENTRY [ 0xe1350cec - 0xe135ed2c ]
+0x00c ActiveLinks      : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x018 FileOffset       : 0n0
+0x020 Length           : 0n4048
+0x028 SeqNumber        : 0n0
+0x030 BufferOffset     : 0n0
+0x038 PageHeader       : 0xe138c008 Void
+0x03c LogPageBcb       : (null)
+0x040 LastLsn          : _LARGE_INTEGER 0x8124467
+0x048 LastEndLsn       : _LARGE_INTEGER 0x8124467
+0x050 Flags            : 0
+0x054 LbcbFlags        : 0x20
+0x058 ResourceThread   : 0


第九部分:

VOID
LfsFindFirstIo (
IN PLFCB Lfcb,
IN LSN TargetLsn,
IN BOOLEAN RestartLsn,
IN PLBCB FirstLbcb,
OUT PLBCB *NextLbcb,
OUT PLONGLONG FileOffset,
OUT PBOOLEAN ContainsLastEntry,
OUT PBOOLEAN LfsRestart,
OUT PBOOLEAN UseTailCopy,
OUT PULONG IoBlocks
)

dv
IoBlocks = 1

            Length = IoBlocks * (ULONG) Lfcb->LogPageSize;

0: kd> dv Length
Length = 0x1000

            } else {

                TargetLbcb = FirstLbcb;
}


0: kd> dv TargetLbcb
TargetLbcb = 0xe135ed28


第十部分:

            if (LfsRestart) {

                PLFS_RESTART_PAGE_HEADER RestartPage;

                ASSERT( !UseTailCopy && IoBlocks == 1);

                //
//  Build the partial mdl to describe this lfs restart page from the permanently
//  mapped piece of the log
//

                RestartPage = Add2Ptr( Lfcb->LogHeadBuffer, FileOffset, PLFS_RESTART_PAGE_HEADER );
IoBuildPartialMdl( Lfcb->LogHeadMdl, Lfcb->LogHeadPartialMdl, RestartPage, (ULONG)Lfcb->LogPageSize );


RestartPage->ChkDskLsn = LfsLi0;

                RestartPage->MultiSectorHeader.UpdateSequenceArrayOffset
= Lfcb->RestartUsaOffset;

                RestartPage->MultiSectorHeader.UpdateSequenceArraySize
= Lfcb->UsaArraySize;

                //
//  Maintain the illusion that all systems have log page == system page
//  on disk so we can migrate disks between different platforms
//

                RestartPage->SystemPageSize = (ULONG)Lfcb->LogPageSize;
RestartPage->LogPageSize = (ULONG)Lfcb->LogPageSize;

                RestartPage->RestartOffset = (USHORT) Lfcb->RestartDataOffset;
RestartPage->MajorVersion = Lfcb->MajorVersion;
RestartPage->MinorVersion = Lfcb->MinorVersion;


0: kd> dv FileOffset
FileOffset = 0n4096


0: kd> dd 0x89897000
89897000  00000000 00000000 00000000 50554f4c
89897010  89862000 00000000 00000000 00000000
89897020  00000000 00000000 00000000 00000000
89897030  00000000 00000000 00000000 00000000
89897040  00000000 00000000 00000000 00000000
89897050  00000000 00000000 00000000 00000000
89897060  00000000 00000000 00000000 00000000
89897070  00000000 00000000 00000000 00000000
0: kd> dd 0x89896000
89896000  898d9000 8955c000 0000001a 50554f4c
89896010  89862000 898d9010 00000000 00000000
89896020  00000120 89934c40 89934c40 00000000
89896030  00000000 00000000 00000000 89934c9e
89896040  00000000 00000000 00000000 00000000
89896050  00000000 f7407364 8963c834 8963c808
89896060  000a0008 00000000 89896068 89896068
89896070  00000000 00000000 00000000 00000000


0: kd> dd 0x89897000
89897000  52545352 0009001e 00000000 00000000
89897010  00001000 00001000 00010030 00000001
89897020  00000000 00000000 00000000 00000000
89897030  00000000 00000000 00000000 00000000
89897040  00000000 00000000 00000000 00000000
89897050  00000000 00000000 00000000 00000000
89897060  00000000 00000000 00000000 00000000
89897070  00000000 00000000 00000000 00000000


0: kd> dt LFS_RESTART_PAGE_HEADER 0x89897000
Ntfs!LFS_RESTART_PAGE_HEADER
+0x000 MultiSectorHeader : _MULTI_SECTOR_HEADER
+0x008 ChkDskLsn        : _LARGE_INTEGER 0x0
+0x010 SystemPageSize   : 0x1000
+0x014 LogPageSize      : 0x1000
+0x018 RestartOffset    : 0x30
+0x01a MinorVersion     : 0n1
+0x01c MajorVersion     : 0n1
+0x01e UpdateSequenceArray : [1] 0

0: kd> dt LFS_RESTART_PAGE_HEADER 0x89897000 -r
Ntfs!LFS_RESTART_PAGE_HEADER
+0x000 MultiSectorHeader : _MULTI_SECTOR_HEADER
+0x000 Signature        : [4]  "RSTR"
+0x004 UpdateSequenceArrayOffset : 0x1e
+0x006 UpdateSequenceArraySize : 9
+0x008 ChkDskLsn        : _LARGE_INTEGER 0x0
+0x000 LowPart          : 0
+0x004 HighPart         : 0n0
+0x000 u                : __unnamed
+0x000 LowPart          : 0
+0x004 HighPart         : 0n0
+0x000 QuadPart         : 0n0
+0x010 SystemPageSize   : 0x1000
+0x014 LogPageSize      : 0x1000
+0x018 RestartOffset    : 0x30
+0x01a MinorVersion     : 0n1
+0x01c MajorVersion     : 0n1
+0x01e UpdateSequenceArray : [1] 0

    [+0x04c] RestartDataOffset : 0x30 [Type: unsigned long]


#define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I)))


0: kd> dt LFS_RESTART_PAGE_HEADER -v
Ntfs!LFS_RESTART_PAGE_HEADER
struct _LFS_RESTART_PAGE_HEADER, 8 elements, 0x20 bytes
+0x000 MultiSectorHeader : struct _MULTI_SECTOR_HEADER, 3 elements, 0x8 bytes
+0x008 ChkDskLsn        : union _LARGE_INTEGER, 4 elements, 0x8 bytes
+0x010 SystemPageSize   : Uint4B
+0x014 LogPageSize      : Uint4B
+0x018 RestartOffset    : Uint2B
+0x01a MinorVersion     : Int2B
+0x01c MajorVersion     : Int2B
+0x01e UpdateSequenceArray : [1] Uint2B

0: kd> dd 0xe1363008
e1363008  08124465 00000000 ffff0001 00000000
e1363018  00000028 004000e0 04000000 00000000
e1363028  00000068 00400030 85e12261 00000000
e1363038  00000000 00000000 00000000 00000000
e1363048  08124452 00000000 08124465 00000000
e1363058  ffffffff 00000000 00000000 00000008
e1363068  0054004e 00530046 00000000 00000000
e1363078  00000000 00000000 00000000 00000000

0: kd> dd 89897000
89897000  52545352 0009001e 00000000 00000000
89897010  00001000 00001000 00010030 00000001
89897020  00000000 00000000 00000000 00000000
89897030  00000000 00000000 00000000 00000000
89897040  00000000 00000000 00000000 00000000
89897050  00000000 00000000 00000000 00000000
89897060  00000000 00000000 00000000 00000000
89897070  00000000 00000000 00000000 00000000


0: kd> p
Ntfs!LfsFlushLfcb+0x23f:
f715bb11 c1e902          shr     ecx,2
0: kd> p
Ntfs!LfsFlushLfcb+0x242:
f715bb14 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
0: kd> r
eax=e135ed28 ebx=e13417d8 ecx=000003f4 edx=00000fd0 esi=e1363008 edi=89897030


0: kd> ?4*3f4
Evaluate expression: 4048 = 00000fd0


0: kd> dd 89897000
89897000  52545352 0009001e 00000000 00000000
89897010  00001000 00001000 00010030 00000001
89897020  00000000 00000000 00000000 00000000
89897030  08124465 00000000 ffff0001 00000000
89897040  00000028 004000e0 04000000 00000000
89897050  00000068 00400030 85e12261 00000000
89897060  00000000 00000000 00000000 00000000
89897070  08124452 00000000 08124465 00000000


0: kd> dd 89897000
89897000  52545352 0009001e 00000000 00000000
89897010  00001000 00001000 00010030 00000001
89897020  00000000 00000000 00000000 00000000
89897030  08124465 00000000 ffff0001 00000000
89897040  00000028 004000e0 04000000 00000000
89897050  00000068 00400030 85e12261 00000000
89897060  00000000 00000000 00000000 00000000
89897070  08124452 00000000 08124465 00000000
0: kd> dd 89897000+80*1
89897080  ffffffff 00000000 00000000 00000008
89897090  0054004e 00530046 00000000 00000000
898970a0  00000000 00000000 00000000 00000000
898970b0  00000000 00000000 00000000 00000000
898970c0  00000000 00000000 00000000 00000000
898970d0  00000000 00000000 00000000 00000000
898970e0  00000000 00000000 00000000 00000000
898970f0  00000000 00000000 00000000 00000000

0: kd> dt lfs_restart_area 89897030
Ntfs!LFS_RESTART_AREA
+0x000 CurrentLsn       : _LARGE_INTEGER 0x8124465
+0x008 LogClients       : 1
+0x00a ClientFreeList   : 0xffff
+0x00c ClientInUseList  : 0
+0x00e Flags            : 0
+0x010 SeqNumberBits    : 0x28
+0x014 RestartAreaLength : 0xe0
+0x016 ClientArrayOffset : 0x40
+0x018 FileSize         : 0n67108864
+0x020 LastLsnDataLength : 0x68
+0x024 RecordHeaderLength : 0x30
+0x026 LogPageDataOffset : 0x40
+0x028 RestartOpenLogCount : 0x85e12261
+0x02c LastFailedFlushStatus : 0
+0x030 LastFailedFlushOffset : 0n0
+0x038 LastFailedFlushLsn : _LARGE_INTEGER 0x0
+0x040 LogClientArray   : [1] _LFS_CLIENT_RECORD
0: kd> dx -id 0,0,899a2278 -r1 (*((Ntfs!_LFS_CLIENT_RECORD (*)[1])0x89897070))
(*((Ntfs!_LFS_CLIENT_RECORD (*)[1])0x89897070))                 [Type: _LFS_CLIENT_RECORD [1]]
[0]              [Type: _LFS_CLIENT_RECORD]
0: kd> dx -id 0,0,899a2278 -r1 (*((Ntfs!_LFS_CLIENT_RECORD *)0x89897070))
(*((Ntfs!_LFS_CLIENT_RECORD *)0x89897070))                 [Type: _LFS_CLIENT_RECORD]
[+0x000] OldestLsn        : {135414866} [Type: _LARGE_INTEGER]
[+0x008] ClientRestartLsn : {135414885} [Type: _LARGE_INTEGER]
[+0x010] PrevClient       : 0xffff [Type: unsigned short]
[+0x012] NextClient       : 0xffff [Type: unsigned short]
[+0x014] SeqNumber        : 0x0 [Type: unsigned short]
[+0x016] AlignWord        : 0x0 [Type: unsigned short]
[+0x018] AlignDWord       : 0x0 [Type: unsigned long]
[+0x01c] ClientNameLength : 0x8 [Type: unsigned long]
[+0x020] ClientName       [Type: unsigned short [64]]
0: kd> dx -id 0,0,899a2278 -r1 (*((Ntfs!unsigned short (*)[64])0x89897090))
(*((Ntfs!unsigned short (*)[64])0x89897090))                 [Type: unsigned short [64]]
[0]              : 0x4e [Type: unsigned short]
[1]              : 0x54 [Type: unsigned short]
[2]              : 0x46 [Type: unsigned short]
[3]              : 0x53 [Type: unsigned short]

http://www.dtcms.com/a/273916.html

相关文章:

  • 冒泡、选择、插入排序:三大基础排序算法深度解析(C语言实现)
  • 模型训练的常用方法及llama-factory支持的数据训练格式
  • [论文阅读] 人工智能 + 软件工程 | LLM辅助软件开发:需求如何转化为代码?
  • GPT和MBR分区
  • SLICEGPT: COMPRESS LARGE LANGUAGE MODELSBY DELETING ROWS AND COLUMNS
  • 匿名函数作递归函数引用
  • Immutable
  • MetaMask 连接其他网络,连接本地的 Anvil 区块链节点
  • 在Windows非Docker环境安装Redis的几种方法
  • pytest+yaml+allure接口自动化测试框架
  • 在 Postman 中高效生成随机环境变量的完整指南
  • 鸿蒙app 开发中的Record<string,string>的用法和含义
  • 深入探索Kafka Streams:企业级实时数据处理实践指南
  • 关闭 GitLab 升级提示的详细方法
  • AI产品经理面试宝典第8天:核心算法面试题-下
  • 蓝光三维扫描技术在汽车钣金件复杂型面测量中的应用案例
  • 重振索尼复古微型电脑——计划以OrangePi CM5 作为主板升级
  • php 如何通过mysqli操作数据库?
  • springboot生成pdf方案之dot/html/图片转pdf三种方式
  • 【实用IP查询工具】IP数据云-IP地址查询离线库使用方案
  • 【AI大模型】RAG系统组件:向量数据库(ChromaDB)
  • 《数据库》MySQL备份回复
  • 【数据库基础 1】MySQL环境部署及基本操作
  • Ntfs!NtfsCheckpointVolume函数分析之Lfcb->RestartArea的变更和什么时候RestartArea写回文件的关系
  • 两台电脑通过网线直连形成局域网,共享一台wifi网络实现上网
  • Cesium实战:交互式多边形绘制与编辑功能完全指南(最终修复版)
  • Unity3d程序运行显示debugger信息
  • c/c++拷贝函数
  • 【Qt 学习之路】Qt Android开发环境搭建:Ubuntu的Vmware虚拟机中的踩坑实录
  • Arcgis连接HGDB报错