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

nt!CcFlushCache函数分析之nt!CcFindBcb

nt!CcFindBcb函数分析

第一部分:

1: kd> p
nt!CcAcquireByteRangeForWrite+0x377:
80a13c49 e866e4ffff      call    nt!CcFindBcb (80a120b4)
1: kd> t
nt!CcFindBcb:
80a120b4 55              push    ebp
1: kd> kc
 #
00 nt!CcFindBcb
01 nt!CcAcquireByteRangeForWrite
02 nt!CcFlushCache
03 Ntfs!LfsFlushLfcb
04 Ntfs!LfsFlushToLsnPriv
05 Ntfs!LfsWriteLfsRestart
06 Ntfs!LfsWriteRestartArea
07 Ntfs!NtfsCheckpointVolume
08 Ntfs!NtfsCheckpointAllVolumes
09 nt!ExpWorkerThread
0a nt!PspSystemThreadStartup
0b nt!KiThreadStartup
1: kd> dv
 SharedCacheMap = 0x89469530
     FileOffset = 0xf78d2768 {7884800}
 BeyondLastByte = 0xf78d26c8 {7888896}
            Bcb = 0xf78d26fc
          Found = 0x00 ''

1: kd> ?0n7884800
Evaluate expression: 7884800 = 00785000

第二部分:

   //
    //  Get address of Bcb listhead that is *after* the Bcb we are looking for,
    //  for backwards scan.  It is important that we fail in the forward
    //  direction so that we are looking in the right segment of the Bcb list.
    //

    BcbList = GetBcbListHead( SharedCacheMap, FileOffset->QuadPart + SIZE_PER_BCB_LIST, TRUE );

    [+0x018] SectionSize      : {67108864} [Type: _LARGE_INTEGER]
1: kd> ?0n67108864
Evaluate expression: 67108864 = 04000000


#define BEGIN_BCB_LIST_ARRAY             (0x200000)
#define SIZE_PER_BCB_LIST                (VACB_MAPPING_GRANULARITY * 2)
#define BCB_LIST_SHIFT                   (VACB_OFFSET_SHIFT + 1)

#define VACB_OFFSET_SHIFT                (18)
#define VACB_LEVEL_SHIFT                  (7)

#define VACB_SIZE_OF_FIRST_LEVEL         (1 << (VACB_OFFSET_SHIFT + VACB_LEVEL_SHIFT))

#define GetBcbListHead(SCM,OFF,FAILSUCC) (                                                         \
  (((SCM)->SectionSize.QuadPart > BEGIN_BCB_LIST_ARRAY) &&                                         \
   FlagOn((SCM)->Flags, MODIFIED_WRITE_DISABLED)) ?                                                \
   (((SCM)->SectionSize.QuadPart > VACB_SIZE_OF_FIRST_LEVEL) ?                                     \
    CcGetBcbListHeadLargeOffset((SCM),(OFF),(FAILSUCC)) :                                          \
    (((OFF) >= (SCM)->SectionSize.QuadPart) ? &(SCM)->BcbList :                                    \
     ((PLIST_ENTRY)((SCM)->Vacbs) + (((SCM)->SectionSize.QuadPart + (OFF)) >> BCB_LIST_SHIFT)))) : \
   &(SCM)->BcbList                                                                                 \
)


10  0000 0000 0000 0000 0000 0000

2000000

CcGetBcbListHeadLargeOffset((SCM),(OFF),(FAILSUCC))


1: kd> p
nt!CcFindBcb+0x1d:
80a120d1 3d00002000      cmp     eax,200000h
1: kd> p
nt!CcFindBcb+0x22:
80a120d6 7665            jbe     nt!CcFindBcb+0x89 (80a1213d)
1: kd> r
eax=04000000


1: kd> p
nt!CcFindBcb+0x30:
80a120e4 3d00000002      cmp     eax,2000000h
1: kd> p
nt!CcFindBcb+0x35:
80a120e9 7619            jbe     nt!CcFindBcb+0x50 (80a12104)
1: kd> r
eax=04000000


第三部分:nt!CcGetBcbListHeadLargeOffset

1: kd> kc
 #
00 nt!CcGetBcbListHeadLargeOffset
01 nt!CcFindBcb
02 nt!CcAcquireByteRangeForWrite
03 nt!CcFlushCache
04 Ntfs!LfsFlushLfcb
05 Ntfs!LfsFlushToLsnPriv
06 Ntfs!LfsWriteLfsRestart
07 Ntfs!LfsWriteRestartArea
08 Ntfs!NtfsCheckpointVolume
09 Ntfs!NtfsCheckpointAllVolumes
0a nt!ExpWorkerThread
0b nt!PspSystemThreadStartup
0c nt!KiThreadStartup
1: kd> dv
 SharedCacheMap = 0x89469530
     FileOffset = 0n8409088
FailToSuccessor = 0x01 ''
    SavedLevels = 0x80a189aa
SavedVacbArrays = struct _VACB **[7]
          Shift = 8
   SavedIndexes = unsigned long [7]
          Level = 0

1: kd> ?0n8409088
Evaluate expression: 8409088 = 00805000


#define SIZE_PER_BCB_LIST                (VACB_MAPPING_GRANULARITY * 2)
#define VACB_MAPPING_GRANULARITY         (0x40000)

80000+00785000=00805000

1: kd> dx -r1 ((ntkrnlmp!_VACB * *)0x89469320)
((ntkrnlmp!_VACB * *)0x89469320)                 : 0x89469320 [Type: _VACB * *]
    0x894d1008 [Type: _VACB *]
1: kd> dx -r1 ((ntkrnlmp!_VACB *)0x894d1008)
((ntkrnlmp!_VACB *)0x894d1008)                 : 0x894d1008 [Type: _VACB *]
    [+0x000] BaseAddress      : 0x89988018 [Type: void *]
    [+0x004] SharedCacheMap   : 0x0 [Type: _SHARED_CACHE_MAP *]
    [+0x008] Overlay          [Type: __unnamed]
    [+0x010] LruList          [Type: _LIST_ENTRY]


第四部分:

    Shift = VACB_OFFSET_SHIFT + VACB_LEVEL_SHIFT;    25

#define VACB_OFFSET_SHIFT                (18)
#define VACB_LEVEL_SHIFT                  (7)


    do {

        Level += 1;
        Shift += VACB_LEVEL_SHIFT;

    } while (SharedCacheMap->SectionSize.QuadPart > ((LONGLONG)1 << Shift));

1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x46:
80a189f0 8345fc07        add     dword ptr [ebp-4],7
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x4a:
80a189f4 8b4dfc          mov     ecx,dword ptr [ebp-4]
1: kd> r
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=89469530 edi=89469320
eip=80a189f4 esp=f78d2610 ebp=f78d2660 iopl=0         nv up ei pl nz ac po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000212
nt!CcGetBcbListHeadLargeOffset+0x4a:
80a189f4 8b4dfc          mov     ecx,dword ptr [ebp-4] ss:0010:f78d265c=00000020
1: kd> dd f78d2660-4
f78d265c  00000020

dv
          Shift = 0x20
          Level = 1

    if (FileOffset >= ((LONGLONG)1 << Shift)) {
        return &SharedCacheMap->BcbList;
    }


    //
    //  Now descend the tree to the bottom level to get the caller's Bcb ListHead.
    //

    Shift -= VACB_LEVEL_SHIFT;    25    0x2000000
    do {

        //
        //  Calculate the index into the Vacb block for this level.
        //

        Index = (ULONG)(FileOffset >> Shift);    =0
        ASSERT(Index <= VACB_LAST_INDEX_FOR_LEVEL);


1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x9d:
80a18a47 83fe7f          cmp     esi,7Fh
1: kd> r
eax=00000000 ebx=00000000 ecx=00000019 edx=00000000 esi=00000000 edi=89469320

第五部分:

        //
        //  Get block address for next level.
        //

        NextVacbArray = (PVACB *)VacbArray[Index];    894d1008


1: kd> p
nt!CcGetBcbListHeadLargeOffset+0xb8:
80a18a62 8b1cb7          mov     ebx,dword ptr [edi+esi*4]
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0xbb:
80a18a65 33c9            xor     ecx,ecx
1: kd> r
eax=00000000 ebx=894d1008 ecx=00000019 edx=00000000 esi=00000000 edi=89469320


1: kd> dd 89469320
89469320  894d1008 00000000 00000000 00000000
89469330  00000000 00000000 00000000 00000000
89469340  00000000 00000000 00000000 00000000

1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x13c:
80a18ae6 e825b10d00      call    nt!_allshl (80af3c10)
1: kd> r
eax=00000001 ebx=894d1008 ecx=00000019 edx=00000000 esi=00000000 edi=894d1008


1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x141:
80a18aeb 83e801          sub     eax,1
1: kd> r
eax=02000000


1: kd> r
eax=01ffffff ebx=894d1008 ecx=00000019 edx=00000000 esi=00000000 edi=894d1008
eip=80a18af1 esp=f78d2610 ebp=f78d2660 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
nt!CcGetBcbListHeadLargeOffset+0x147:
80a18af1 21450c          and     dword ptr [ebp+0Ch],eax ss:0010:f78d266c=00805000
1: kd> dd f78d2660+c
f78d266c  00805000

1ff    ffff    0080    5000

1: kd> dv
 SharedCacheMap = 0x89469530
     FileOffset = 0n8409088


1: kd> dv
 SharedCacheMap = 0x89469530
     FileOffset = 0n8409088
FailToSuccessor = 0x01 ''
    SavedLevels = 1
SavedVacbArrays = struct _VACB **[7]
          Shift = 0x12


    Index = (ULONG)(FileOffset >> Shift);
    return (PLIST_ENTRY)((PCHAR)&VacbArray[Index & ~1] + VACB_LEVEL_BLOCK_SIZE);
}

80    5000

1000 0000 1001 0000 0000 0000  

1000 0000 1001 0000 0000 0000  

10 00 00

0x20


1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x161:
80a18b0b 8b4dfc          mov     ecx,dword ptr [ebp-4]
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x164:
80a18b0e e81db10d00      call    nt!_allshr (80af3c30)
1: kd> r
eax=00805000 ebx=894d1008 ecx=00000012 edx=00000000 esi=00000000 edi=894d1008
eip=80a18b0e esp=f78d2610 ebp=f78d2660 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
nt!CcGetBcbListHeadLargeOffset+0x164:
80a18b0e e81db10d00      call    nt!_allshr (80af3c30)
1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x169:
80a18b13 83e0fe          and     eax,0FFFFFFFEh
1: kd> r
eax=00000020


#define VACB_LEVEL_BLOCK_SIZE             ((1 << VACB_LEVEL_SHIFT) * sizeof(PVOID))

#define VACB_LEVEL_SHIFT                  (7)

1000 0000 00
10    00 00    00 00

200


1: kd> p
nt!CcGetBcbListHeadLargeOffset+0x16c:
80a18b16 8d848300020000  lea     eax,[ebx+eax*4+200h]
1: kd> r
eax=00000020 ebx=894d1008

1: kd> r
eax=894d1288


1: kd> dd 894d1008+80+200
894d1288  898f1298 894d1290 894d1288 894d1298
894d1298  894d1290 894d12a0 894d1298 894d12a8

第六部分:


1: kd> p
nt!CcFindBcb+0x4e:
80a12102 eb3c            jmp     nt!CcFindBcb+0x8c (80a12140)
1: kd> r
eax=894d1288


1: kd> dt _bcb  0x898f1298-10
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n765
   +0x002 Dirty            : 0x1 ''
   +0x003 Reserved         : 0 ''
   +0x004 ByteLength       : 0x1000
   +0x008 FileOffset       : _LARGE_INTEGER 0x787000
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x8962bcf8 - 0x894d1288 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x788000
   +0x020 OldestLsn        : _LARGE_INTEGER 0x0
   +0x028 NewestLsn        : _LARGE_INTEGER 0x0
   +0x030 Vacb             : 0x89988498 _VACB
   +0x034 PinCount         : 1
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x89469530 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : 0xc2c47000 Void


1: kd> dt LIST_ENTRY 894d1288
ntdll!LIST_ENTRY
 [ 0x898f1298 - 0x894d1290 ]
   +0x000 Flink            : 0x898f1298 _LIST_ENTRY [ 0x8962bcf8 - 0x894d1288 ]
   +0x004 Blink            : 0x894d1290 _LIST_ENTRY [ 0x894d1288 - 0x894d1298 ]

1: kd> p
nt!CcFindBcb+0x91:
80a12145 837e0400        cmp     dword ptr [esi+4],0
1: kd> r
eax=898f1288 ebx=89469530 ecx=00000012 edx=00000000 esi=f78d2768 edi=89469530


1: kd> ?0n7884800
Evaluate expression: 7884800 = 00785000

1: kd> dt _bcb  0x898f1298-10
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n765
   +0x002 Dirty            : 0x1 ''
   +0x003 Reserved         : 0 ''
   +0x004 ByteLength       : 0x1000
   +0x008 FileOffset       : _LARGE_INTEGER 0x787000
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x8962bcf8 - 0x894d1288 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x788000
   +0x020 OldestLsn        : _LARGE_INTEGER 0x0
   +0x028 NewestLsn        : _LARGE_INTEGER 0x0
   +0x030 Vacb             : 0x89988498 _VACB
   +0x034 PinCount         : 1
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x89469530 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : 0xc2c47000 Void

1: kd> dt _bcb  0x8962bcf8-10
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n765
   +0x002 Dirty            : 0x1 ''
   +0x003 Reserved         : 0 ''
   +0x004 ByteLength       : 0x1000
   +0x008 FileOffset       : _LARGE_INTEGER 0x786000
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x894c6668 - 0x898f1298 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x787000
   +0x020 OldestLsn        : _LARGE_INTEGER 0x0
   +0x028 NewestLsn        : _LARGE_INTEGER 0x0
   +0x030 Vacb             : (null)
   +0x034 PinCount         : 0
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x89469530 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : (null)


1: kd> dt _bcb 0x894c6668-10
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n765
   +0x002 Dirty            : 0x1 ''
   +0x003 Reserved         : 0 ''
   +0x004 ByteLength       : 0x1000
   +0x008 FileOffset       : _LARGE_INTEGER 0x785000
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x894d1280 - 0x8962bcf8 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x786000
   +0x020 OldestLsn        : _LARGE_INTEGER 0x0
   +0x028 NewestLsn        : _LARGE_INTEGER 0x0
   +0x030 Vacb             : (null)
   +0x034 PinCount         : 0
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x89469530 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : (null)


1: kd> dt _bcb 0x894d1280-10
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n4712        //错误
   +0x002 Dirty            : 0x4d 'M'
   +0x003 Reserved         : 0x89 ''
   +0x004 ByteLength       : 0x894d1278
   +0x008 FileOffset       : _LARGE_INTEGER 0x894d1280`894d1270
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x894d1278 - 0x894c6668 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x894d1290`898f1298
   +0x020 OldestLsn        : _LARGE_INTEGER 0x894d1298`894d1288
   +0x028 NewestLsn        : _LARGE_INTEGER 0x894d12a0`894d1290
   +0x030 Vacb             : 0x894d1298 _VACB
   +0x034 PinCount         : 0x894d12a8
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x894d12d8 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : 0x894d12e8 Void

1: kd> p
nt!CcFindBcb+0xb1:
80a12165 3bd1            cmp     edx,ecx
1: kd> r
eax=8962bce8 ebx=89469530 ecx=00786000 edx=00785000


1: kd> p
nt!CcFindBcb+0xbe:
80a12172 83e810          sub     eax,10h
1: kd> p
nt!CcFindBcb+0xc1:
80a12175 668138fd02      cmp     word ptr [eax],2FDh
1: kd> r
eax=894c6658


            if (FileOffset->QuadPart >= Bcbt->FileOffset.QuadPart) {
                Found = TRUE;
                break;
            }

第七部分:


1: kd> dt _bcb 894c6658
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n765
   +0x002 Dirty            : 0x1 ''
   +0x003 Reserved         : 0 ''
   +0x004 ByteLength       : 0x1000
   +0x008 FileOffset       : _LARGE_INTEGER 0x785000
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x894d1280 - 0x8962bcf8 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x786000
   +0x020 OldestLsn        : _LARGE_INTEGER 0x0
   +0x028 NewestLsn        : _LARGE_INTEGER 0x0
   +0x030 Vacb             : (null)
   +0x034 PinCount         : 0
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x89469530 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : (null)

1: kd> dv
 SharedCacheMap = 0x89469530
     FileOffset = 0xf78d2768 {7884800}
 BeyondLastByte = 0xf78d26c8 {7888896}
            Bcb = 0xf78d26fc
          Found = 0x01 ''
1: kd> dx -r1 ((ntkrnlmp!_BCB * *)0xf78d26fc)
((ntkrnlmp!_BCB * *)0xf78d26fc)                 : 0xf78d26fc [Type: _BCB * *]
    0x894c6658 [Type: _BCB *]

    return Found;
}


第八部分:

                //
                //  Position ourselves.  If we did not find a Bcb for the page, then
                //  a lower FileOffset was returned, so we want to move forward one.
                //

                if (!CcFindBcb( SharedCacheMap,
                                StartingOffset,
                                &StartingOffsetBias,
                                &Bcb )) {                //返回到这里:
                    Bcb = CONTAINING_RECORD( Bcb->BcbLinks.Blink, BCB, BcbLinks );
                }

dv
                   Bcb = 0x894c6658

                    Bcb = CONTAINING_RECORD( Bcb->BcbLinks.Blink, BCB, BcbLinks );    =0x8962bcf8-10

1: kd> dx -r1 ((ntkrnlmp!_BCB *)0x894c6658)
((ntkrnlmp!_BCB *)0x894c6658)                 : 0x894c6658 [Type: _BCB *]
    [+0x000] Dummy            [Type: _MBCB]
    [+0x000] NodeTypeCode     : 765 [Type: short]
    [+0x002] Dirty            : 0x1 [Type: unsigned char]
    [+0x003] Reserved         : 0x0 [Type: unsigned char]
    [+0x004] ByteLength       : 0x1000 [Type: unsigned long]
    [+0x008] FileOffset       : {7884800} [Type: _LARGE_INTEGER]
    [+0x010] BcbLinks         [Type: _LIST_ENTRY]
    [+0x018] BeyondLastByte   : {7888896} [Type: _LARGE_INTEGER]
    [+0x020] OldestLsn        : {0} [Type: _LARGE_INTEGER]
    [+0x028] NewestLsn        : {0} [Type: _LARGE_INTEGER]
    [+0x030] Vacb             : 0x0 [Type: _VACB *]
    [+0x034] PinCount         : 0x0 [Type: unsigned long]
    [+0x038] Resource         [Type: _ERESOURCE]
    [+0x070] SharedCacheMap   : 0x89469530 [Type: _SHARED_CACHE_MAP *]
    [+0x074] BaseAddress      : 0x0 [Type: void *]
1: kd> dx -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x894c6668))
(*((ntkrnlmp!_LIST_ENTRY *)0x894c6668))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x894d1280 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x8962bcf8 [Type: _LIST_ENTRY *]        Blink            : 0x8962bcf8


1: kd> dt _bcb 0x8962bcf8-10
nt!_BCB
   +0x000 Dummy            : _MBCB
   +0x000 NodeTypeCode     : 0n765
   +0x002 Dirty            : 0x1 ''
   +0x003 Reserved         : 0 ''
   +0x004 ByteLength       : 0x1000
   +0x008 FileOffset       : _LARGE_INTEGER 0x786000
   +0x010 BcbLinks         : _LIST_ENTRY [ 0x894c6668 - 0x898f1298 ]
   +0x018 BeyondLastByte   : _LARGE_INTEGER 0x787000
   +0x020 OldestLsn        : _LARGE_INTEGER 0x0
   +0x028 NewestLsn        : _LARGE_INTEGER 0x0
   +0x030 Vacb             : (null)
   +0x034 PinCount         : 0
   +0x038 Resource         : _ERESOURCE
   +0x070 SharedCacheMap   : 0x89469530 _SHARED_CACHE_MAP
   +0x074 BaseAddress      : (null)

相关文章:

  • 武汉招聘网站制作充电宝seo关键词优化
  • 一起合伙做项目的网站广州品牌seo推广
  • 菏泽住房和城乡建设委员会网站搜索引擎排名优化包括哪些方面
  • 视频分享网站怎么做的seo课程总结
  • 外贸网站模板 免费网店代运营骗局流程
  • 怎么用ps做网站首页图片竞价sem培训
  • 【自己动手写AI Agent】 对于企业构建AI应用的几点思考3
  • C++(智能指针)
  • Redis—持久化
  • 设计模式 | 抽象工厂模式
  • 鸿蒙分布式能力深度解析:构建跨设备无缝体验的技术基石
  • Fisco Bcos学习 - 控制台搭建和基本使用
  • NVads V710 v5 系列虚拟机已发布
  • 【iOS】iOS崩溃总结
  • 我手动从go官网下载了go1.16.15linux安装包,我该如何做,才能使得vscode仍能通过右下角来管理这个go版本
  • python学习笔记(深度学习)
  • 新能源汽车电池类型差异分析
  • 英飞凌高性能BMS解决方案助力汽车电动化
  • 亚远景-ASPICE与ISO 26262:汽车安全与软件质量的协同
  • 【世纪龙科技】新能源汽车VR虚拟体验展示馆-解锁认知新维度
  • 打造属于你的AI智能体,从数据开始 —— 使用 Bright Data MCP+Trae快速构建垂直智能体
  • React Native【实战范例】账号管理(含转换分组列表数据的封装,分组折叠的实现,账号的增删改查,表单校验等)
  • React + Umi(Umijs/Max) 搭建项目及配置
  • 大塘至浦北高速分布式光伏项目,让‘交通走廊’变身‘绿色能源带’
  • TensorFlow Lite (TFLite) 和 PyTorch Mobile介绍2
  • P7915 [CSP-S 2021] 回文