[dochelp to bcc]
[adding case mail and case number]

Hi Gordon,

I can help you with this.  As you suggest, a TTT may be helpful of, perhaps, 
the Explorer process, but that would be huge.  First, I suggest ETW/ETL logs 
from the file system to exclude it first.   I attached it the tool (rename 
t.cmd.txt to just t.cmd).  On the client, do "t clion", repro the issue, do "t 
clioff"" and send me the resulting t.cab output.

Thank you for the hint re: sorting.  This may be something unique to the shell 
(where it is causing the excessive requests).  I have additional tools to 
employ (perfmon and, eventually, TTT) if the T.CAB and my source review doesn't 
yield the answer.

Also, do you have a similar Explorer behavior with SMB2?  If not, do you also 
return listings in the on-the-disk ordering?

Bryan

-----Original Message-----
From: Gordon Ross [mailto:[email protected]] 
Sent: Wednesday, March 28, 2012 1:34 PM
To: Interoperability Documentation Help
Cc: [email protected]
Subject: [MS-CIFS] Trans2FindFirst/FindNext

Hi DocHelp people,

I a questions about windows client behavior involving SMB Transact2 
FindFirst/FindNext, as described in MS-CIFS 2.2.6.3.1.

We have a Windows 7 (x64) client that appears to be repeatedly requesting a 
directory listing when Windows Explorer is asked to show large directory on our 
server.  The directory has about 20,000 folders.

The only obvious difference we see when comparing with a Windows server (2k8r2) 
is that we return the directory contents in the order found on-disk (which is 
in general, not sorted).

I'd appreciate suggestions on how to track down what might be the reason for 
the Windows client repeating the findfirst/findnext
requests as we observe.   Should we provide a TTT from the windows
client?

Thanks,
Gordon

@echo off

@rem parse persistent state to carry across invocations
@rem note this must be done before we go inside setlocal
@rem
@rem t clion core
@rem t clioff           <- recovers persisted "core" arg

@rem figure out "i am"
for %%i in (%*) do (
        if %%i equ clion set __t_persist_iam=cli
        if %%i equ clioff set __t_persist_iam=cli

        if %%i equ srvon set __t_persist_iam=srv
        if %%i equ srvoff set __t_persist_iam=srv
)

@rem persist iam-specific state
for %%i in (%*) do (
        if %%i equ core call :seteval __t_persist_core_%__t_persist_iam% 1
)

@rem commence detection of multiple stream requests.
for %%i in (%*) do (
        @rem pattern to follow for dup detection
        @rem whichever trace claims an element (on) unsets dup flag (at off)

        @rem ... remember on
        if "%__t_persist_dup_sec%" equ "" (

                @rem note that this has to know that "core" disables
                @rem the security trace (gack)
                if "%__t_persist_core%" equ "" (
                        if %%i equ clion set __t_persist_dup_sec=cli
                        if %%i equ srvon set __t_persist_dup_sec=srv
                )
        )
        if "%__t_persist_dup_rpcxdr%" equ "" (
                if %%i equ clion set __t_persist_dup_rpcxdr=cli
                if %%i equ srvon set __t_persist_dup_rpcxdr=srv
        )

        @rem ... detect who gets to unset the persisted state at off time.
        if %%i equ clioff ( 
                if "%__t_persist_dup_sec%" equ "cli" set 
__t_persist_remove_dup_sec=1
                if "%__t_persist_dup_rpcxdr%" equ "cli" set 
__t_persist_remove_dup_rpcxdr=1
        )
        if %%i equ srvoff (
                if "%__t_persist_dup_sec%" equ "srv" set 
__t_persist_remove_dup_sec=1
                if "%__t_persist_dup_rpcxdr%" equ "srv" set 
__t_persist_remove_dup_rpcxdr=1
        )
)

setlocal enabledelayedexpansion

@rem vars
set fail=0
set exe=
set tracelog=
set disp=
set sec=

@rem parsed args
set brief=
set cli=
set core=
set nobin=
set nocab=
set srv=
set circ=

@rem recover persisted state
call :geteval __t_persist_core_!__t_persist_iam!
set core=!ret!

@rem bin groups for the defined streams
set dfsn_bins=dfssvc.exe dfs.sys
set fr_bins=fde.dll fdeploy.dll shell32.dll
set fskm_bins=cscobj.dll cscsvc.dll csc.sys dfsc.sys mup.sys mrxsmb10.sys 
mrxsmb20.sys mrxsmb.sys mrxdav.sys nfsrdr.sys rdbss.sys rpcxdr.sys
set fsum_bins=cscapi.dll cscui.dll webclnt.dll 
set nbt_bins=netbt.sys smb.sys
set nfs_bins=msnfsflt.sys nfssvr.sys portmap.sys rpcxdr.sys 
set sec_bins=kerberos.dll msv1_0.dll negoexts.dll pku2u.dll
set smbhash_bins=hashgen.exe smbgproxy.dll smbhash.exe
set srv_bins=srv.sys srv2.sys srvnet.sys
set tcp_bins=tcpip.sys

for %%i in (%*) do (
        if %%i equ clion set cli=1
        if %%i equ clioff set cli=0
        if %%i equ srvon set srv=1
        if %%i equ srvoff set srv=0

        if %%i equ nocab set nocab=1
        if %%i equ nobin set nobin=1

        if %%i equ brief set brief=1
        
        call :checkcirc %%i
)

@rem recover persisted state for stream ownership at stop time
if "!cli!" equ "0" (
        if "!__t_persist_dup_sec!" equ "cli" ( set sec=1 )
)
if "!srv!" equ "0" (
        if "!__t_persist_dup_sec!" equ "srv" ( set sec=1 )
)

@rem choose one
if defined cli ( if defined srv ( goto :usage ) )

@rem grab the current process list before turning on tracing
@rem and be resilient to the absence of tasklist.exe
set taskfile=%temp%\tasklist-!random!.txt
for %%i in (tasklist.exe) do (set exe=%%~$PATH:i
if "!exe!" equ " " (
        echo tasklist.exe is not present > !taskfile!
) else (
        !exe! /FO csv /svc > !taskfile!
)
set exe=

@rem detect absence of logman (winpe), and map the circular log args
@rem to the appropriate tool.

for %%i in (logman.exe) do ( set exe=%%~$PATH:i )
if "!exe!" equ " " (
        for %%i in (tracelog.exe) do ( set exe=%%~$PATH:i )
        if "!exe!" equ " " ( echo tracelog is required && goto :eof )
        set tracelog=1
        
        if defined circ set circargs=-cir !circbuf!  
        
) else (
        if defined circ set circargs=-f bincirc -max !circbuf!  
)

if "!cli!" equ "1" (
        @rem hack to work around inability to exit within calls.
        @rem primary failure is access denied, which will occur
        @rem on the first try.

        call :fskmon
        if !fail! neq 0 ( goto :eof )

        call :fsumon

        if not defined core (
                call :fron
                call :nbton
                call :tcpon
                call :secon
        )

        goto :on_final
)

if "!srv!" equ "1" (
        call :dfsnon
        if !fail! neq 0 goto :eof

        call :srvon
        call :smbhashon
        call :nfson

        if not defined core (
                call :secon
        )

        goto :on_final
)

if "!cli!" equ "0" (
        call :etloff fskm
        call :etloff fsum

        if not defined core (
                call :etloff fr
                call :etloff nbt
                call :etloff tcp
                if defined sec call :etloff sec
        )

        @rem on off, use finalization
        goto :off
)

if "!srv!" equ "0" (
        call :etloff dfsn
        call :etloff srv
        call :etloff smbhash
        call :etloff nfs

        if not defined core (
                if defined sec call :etloff sec
        )

        @rem on off, use finalization
        goto :off
)

:usage
echo usage: t ^<cli^|srv^>^on  [brief] [core] [circ:N]
echo usage: t ^<cli^|srv^>^off [nocab] [nobin]
echo  used @on:
echo    brief - brief mode tracing flags (defined for fskm/mup)
echo    core - only generate fsf team owned component traces
echo    circ - generate circular logs of size N megabytes. Default circular 
buffer size is 50 MB.
echo  used @off:
echo    nocab - do not compress traces
echo    nobin - do not gather system binaries matching the captured traces
echo            (please do not use if external to FSF/without direction)
goto :eof

@@@@@@@@@
@
@ tracing steps:
@
@ 1. traceon: start a specific session with given stream
@ 2. traceadd: add additional streams to the session
@ 3. disp: dump rendering of what trace* did
@

@rem always goes first - adds access denied check
:fskmon

@rem do brief
if defined brief (
        set flags=0x3333333
        set level=0
) else (
        set flags=0xfffffff
        set level=7
)

call :traceon fskm    20c46239-d059-4214-a11e-7d6769cbe020 
csckm/dav/dfsc/mup/rdbss/smb !level! !flags!
if !fail! neq 0 ( goto :eof )

@rem csc - per molly, useful interleaved with kernelmode
call :traceadd fskm   89D89015-C0DF-414c-BC48-F50E114832BC service
call :traceadd fskm   791cd79c-65b5-48a3-804c-786048994f47 fastsync
call :traceadd fsum   d5418619-c167-44d9-bc36-765beb5d55f3 dcluser
call :traceadd fsum   66418A2A-72AF-4c1a-9C84-42F6865563BD cscui

@rem nfs client
call :traceadd fskm   355C2284-61CB-47bb-8407-4BE72B5577B0 nfsrdr

@rem note: rpcxdr shared with server (below)
@rem detect duplicated capture
call :dup rpcxdr
if !fail! equ 0 ( 
        call :traceadd fskm   94B45058-6F59-4696-B6BC-B23B7768343D rpcxdr
) else (
        set fail=0
)

call :disp
goto :eof

@@@@@@@@@
:secon

@rem detect duplicated capture
call :dup sec
if !fail! neq 0 ( goto :eof )

@rem flags via larry's wiki @ 
http://mswikis/winsecurity/protocols/kerberos/Wiki%20Pages/how%20to%20turn%20on%20tracing.aspx
call :traceon  sec    6B510852-3583-4e2d-AFFE-A67F9F223438 kerberos 7 0x43
call :traceadd sec    5BBB6C18-AA45-49b1-A15F-085F7ED0AA90 ntlm 7 0x15003
call :traceadd sec    5AF52B0D-E633-4ead-828A-4B85B8DAAC2B negoexts 7 0x73
call :traceadd sec    2A6FAF47-5449-4805-89A3-A504F3E221A6 pku2u 7 0x1f3
call :disp
goto :eof

@@@@@@@@@
:fsumon
@rem csc
call :traceon  fsum   361f227c-aa14-4d19-9007-0c8d1a8a541b cscnet
call :traceadd fsum   0999b701-3e5d-4998-bc58-a775590a55d9 cscdll
call :traceadd fsum   19EE4CF9-5322-4843-B0D8-BAB81BE4E81E cscapi
call :traceadd fsum   66418A2A-72AF-4c1a-9C84-42F6865563BD cscui

@rem dav
call :traceadd fsum   91efb5a1-642d-42a4-9821-f15c73064fb5 WebClnt
call :disp
goto :eof

@@@@@@@@@
:srvon
call :traceon  srv    3121cf5d-c5e6-4f37-be86-57083590c333 srvdl
call :traceadd srv    2744F0B7-8455-44f8-9B64-5F589F9D163A srv2
call :traceadd srv    c0183094-fdc6-493f-a3e8-697224f83f6f srvnet
call :traceadd srv    D8E0C67B-7D87-48b6-9290-42126E66FAEE srvsvc
call :disp
goto :eof

@@@@@@@@@
:smbhashon
call :traceon smbhash 48be2803-12c0-4932-aa80-93372d5a9114 smbhash
call :disp
goto:eof

@@@@@@@@@
:nfson
call :traceon  nfs    CC9A5284-CC3E-4567-B3F6-3EB24E7CFEC5 MsNfsFltGuid
call :traceadd nfs    3c33d8b3-66fa-4427-a31b-f7dfa429d78f NfsSvrGuid
call :traceadd nfs    fc33d8b3-66fa-4427-a31b-f7dfa429d78f NfsSvrGuid2
call :traceadd nfs    57294EFD-C387-4e08-9144-2028E8A5CB1A NfsSvrNlmGuid
call :traceadd nfs    E18A05DC-CCE3-4093-B5AD-211E4C798A0D PortmapGuid

@rem note: rpcxdr shared with client (above)
@rem detect duplicated capture
call :dup rpcxdr
if !fail! equ 0 ( 
        call :traceadd fskm   94B45058-6F59-4696-B6BC-B23B7768343D rpcxdr
) else (
        set fail=0
)

call :disp
goto :eof

@@@@@@@@@
:fron
call :traceon fr      2955e23c-4e0b-45ca-a181-6ee442ca1fc0 fr 4 0x1f
call :disp
goto :eof

@@@@@@@@@
:dfsnon
call :traceon dfsn    27246e9d-b4df-4f20-b969-736fa49ff6ff dfsn
call :disp
goto :eof

@@@@@@@@@
:nbton
call :traceon nbt     bca7bd7f-b0bf-4051-99f4-03cfe79664c1 nbtsmb
call :disp
goto :eof

@@@@@@@@@
:tcpon
rem - tcp-only == flags 0x80 from the original script
call :traceon tcp     eb004a05-9b1a-11d4-9123-0050047759bc tcp 7 0x80
call :disp
goto :eof

@@@@@@@@@
:etloff
call :traceoff %1

@rem roll up the binaries associated with this trace, if specified
if defined nobin goto :eof

set bins=!bins! !%1_bins!
goto :eof

@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ duplicate stream detectomatic
:dup
@rem 1 name of stream

@rem if it isn't you ...
if "!__t_persist_dup_%1!" equ "srv" (
        if "!srv!" equ "1" ( goto :eof )
        goto :dupfail
)

if "!__t_persist_dup_%1!" equ "cli" (
        if "!cli!" equ "1" ( goto :eof )
        goto :dupfail
)

goto :eof

:dupfail
echo info: %1 is already being captured (!__t_persist_dup_%1!)
set fail=1
goto :eof


@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ high level trace fns
@@@@@
:traceon
@rem 1 etl name
@rem 2 guid
@rem 3 display name
@rem 4 optional level
@rem 5 optional flags

call :stop %1
call :create %1
if !fail! equ 0 ( set disp=started %1 ^<- )
if !fail! neq 0 goto :eof

call :traceadd %1 %2 %3 %4 %5
goto :eof

:traceadd
@rem 1 etl name
@rem 2 guid
@rem 3 display name
@rem 4 optional level
@rem 5 optional flags

call :update %1 %2 %4 %5
if not errorlevel 1 ( set disp=!disp!%3 )
goto :eof

:traceoff
@rem 1 etl name

call :stop %1
if not errorlevel 1 ( echo %1 -^> %1.etl )
goto :eof

@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ impl level trace fns
@@@@@
:stop
@rem 1 etl name

if defined tracelog (
        call :doit tracelog -stop %1
) else (
        call :doit logman stop -n %1 -ets
)
set etl=!etl! %1.etl

goto :eof

:create
@rem 1 etl name

if defined tracelog (
        call :doit tracelog -start %1 -f %1.etl -gs !circargs!

        @rem tracelog access denied case
        if !errorlevel! equ 5 (
                @rem copy/paste of logman's output when running in normal 
context
                @rem could be better

                echo Access is denied.
                echo You're running with a restricted token, try running 
elevated.
        )
) else (

        call :doit logman create trace -n %1 -o %1.etl -mode globalsequence 
-ets !circargs!

        @rem logman access denied case
        if !errorlevel! equ -2147024891 (
                @rem copy/paste of logman's output when running in normal 
context
                @rem could be better

                echo Access is denied.
                echo You're running with a restricted token, try running 
elevated.
        )
)

if !errorlevel! neq 0 (
        echo %1 failed !errorlevel!

        @rem set resets errorlevel - must come last
        set fail=1
)
goto :eof

:update
@rem 1 etl name
@rem 2 guid
@rem 3 optional level
@rem 4 optional flags

if "%3" equ "" (
        set level=7
) else (
        set level=%3
)

if "%4" equ "" (
        set flags=0xfffffff
) else (
        set flags=%4
)

if defined tracelog (
        call :doit tracelog -enable %1 -guid #%2 -flags !flags! -level !level!
) else (
        call :doit logman update %1 -p {%2} !flags! !level! -ets
)
goto :eof

@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@rem finalization / cab generator
@rem
@rem two phase, second (*_final) is termination
:off

if defined nocab goto :off_final

@rem construct cab directive file
set dirfile=%temp%\tracecab-!random!.ddf
set verfile=%temp%\version-!random!.txt
set cabroot=t
set cabname=!cabroot!

@rem nosmash
:retry
if exist !cabname!.cab (
        set cabname=!cabroot!-!random!
        goto :retry
)

@rem os version data
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /t REG_SZ > 
!verfile!

echo .set CabinetName1=!cabname!.cab    > !dirfile!
echo .set CompressionType=LZX           >> !dirfile!
echo .set DiskDirectory=.               >> !dirfile!
echo .set DiskDirectory1=.              >> !dirfile!
echo .set InfFileName=nul               >> !dirfile!
echo .set RptFileName=nul               >> !dirfile!
echo .set maxdisksize=0                 >> !dirfile!
echo !verfile! version.txt              >> !dirfile!
echo !taskfile! tasklist.txt            >> !dirfile!
for %%i in (!etl!) do echo %%i          >> !dirfile!
for %%i in (!bins!) do (
        if exist %systemroot%\system32\%%i (
                echo %systemroot%\system32\%%i bin\%%i >> !dirfile!
        ) else (
        if exist %systemroot%\system32\drivers\%%i (
                echo %systemroot%\system32\drivers\%%i bin\%%i >> !dirfile!
        )
        )
)

echo ---
makecab /f !dirfile!
if !errorlevel! neq 0 (
        echo failed to compress trace files - not deleting
        goto :off_final
)

echo ---
if defined bins echo compressed: matching system binaries
echo compressed: version info +!etl! -^> !cabname!.cab
echo done

@rem cleanup
call :doit del !dirfile!
call :doit del !verfile!
for %%i in (!etl!) do call :doit del %%i

@rem finalization for off state
:off_final
call :doit del !taskfile!
endlocal

call :seteval __t_persist_core_%__t_persist_iam%
goto :final

@rem finalization for on state
:on_final
endlocal

@rem finalization for on (and off) state
:final
@rem wipe persisted state

if defined __t_persist_remove_dup_rpcxdr set __t_persist_dup_rpcxdr=
set __t_persist_remove_dup_rpcxdr=

if defined __t_persist_remove_dup_sec set __t_persist_dup_sec=
set __t_persist_remove_dup_sec=

set __t_persist_iam=
goto :eof

@@@@@@@@@@@@@@@@@@@@@@@@@@@@
:doit
%* > nul
if errorlevel 1 ( echo failed: %* )
goto :eof

:disp
if !fail! equ 0 ( echo !disp! )
goto :eof

:seteval
set %1=%2
goto :eof

:geteval
set ret=!%1!
goto :eof

@rem Check for circular buffer option and buffer size.
:checkcirc
for /f "tokens=1,2 delims=:" %%i in ("%1") do (
    if %%i equ circ (
    
        set circ=1
        set circbuf=%%j
        if "%%j" equ "" set circbuf=50
        echo Enabling circular buffer of size !circbuf! MB
    )
)
goto :eof

_______________________________________________
cifs-protocol mailing list
[email protected]
https://lists.samba.org/mailman/listinfo/cifs-protocol

Reply via email to