00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
#include <ntsrv.h>
00033
#include <smbtrace.h>
00034
00035 #define _SMBTRSUP_SYS_ 1 // to get correct definitions for exported variables
00036
#include <smbtrsup.h>
00037
00038
#if DBG
00039
ULONG SmbtrsupDebug = 0;
00040
#define TrPrint(x) if (SmbtrsupDebug) KdPrint(x)
00041
#else
00042 #define TrPrint(x)
00043
#endif
00044
00045
00046
00047
00048
00049
#ifndef UNICODE
00050
#error "UNICODE build required"
00051
#endif
00052
00053
00054
#if DBG
00055
#define PAGED_DBG 1
00056
#endif
00057
#ifdef PAGED_DBG
00058
#undef PAGED_CODE
00059
#define PAGED_CODE() \
00060
struct { ULONG bogus; } ThisCodeCantBePaged; \
00061
ThisCodeCantBePaged; \
00062
if (KeGetCurrentIrql() > APC_LEVEL) { \
00063
KdPrint(( "SMBTRSUP: Pageable code called at IRQL %d. File %s, Line %d\n", KeGetCurrentIrql(), __FILE__, __LINE__ )); \
00064
ASSERT(FALSE); \
00065
}
00066
#define PAGED_CODE_CHECK() if (ThisCodeCantBePaged) ;
00067
ULONG ThisCodeCantBePaged;
00068
#else
00069 #define PAGED_CODE_CHECK()
00070
#endif
00071
00072
00073
#if PAGED_DBG
00074
#define ACQUIRE_SPIN_LOCK(a, b) { \
00075
PAGED_CODE_CHECK(); \
00076
KeAcquireSpinLock(a, b); \
00077
}
00078
#define RELEASE_SPIN_LOCK(a, b) { \
00079
PAGED_CODE_CHECK(); \
00080
KeReleaseSpinLock(a, b); \
00081
}
00082
00083
#else
00084 #define ACQUIRE_SPIN_LOCK(a, b) KeAcquireSpinLock(a, b)
00085 #define RELEASE_SPIN_LOCK(a, b) KeReleaseSpinLock(a, b)
00086
#endif
00087
00088
00089
00090
00091 #define LOCK_INC_ID(var) \
00092
ExInterlockedAddUlong( (PULONG)&ID(var), \
00093
1, &ID(var##Interlock) )
00094
00095
00096
00097
00098 #define LOCK_ZERO_ID(var) { \
00099
ID(var) = 0; \
00100
}
00101
00102
00103
00104
00105
00106
00107
00108
00109 typedef enum _SMBTRACE_STATE {
00110
TraceStopped,
00111
TraceStarting,
00112
TraceStartStopFile,
00113
00114
TraceStartStopNull,
00115
00116
TraceAppWaiting,
00117
TraceRunning,
00118
TraceStopping
00119 }
SMBTRACE_STATE;
00120
00121
00122
00123
00124
00125
00126 typedef struct _SMBTRACE_QUEUE_ENTRY {
00127 LIST_ENTRY
ListEntry;
00128 ULONG
SmbLength;
00129 PVOID
Buffer;
00130
00131 PVOID
SmbAddress;
00132
00133 BOOLEAN
BufferNonPaged;
00134
00135
00136 PKEVENT WaitEvent;
00137
00138
00139 }
SMBTRACE_QUEUE_ENTRY, *
PSMBTRACE_QUEUE_ENTRY;
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 #define ID(field) (SmbTraceData[Component].field)
00152
00153
00154
00155
00156
00157 typedef struct _INSTANCE_DATA {
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 PCHAR
ComponentName;
00168 PWSTR
SharedMemoryName;
00169 PWSTR
NewSmbEventName;
00170 PWSTR
DoneSmbEventName;
00171
00172
00173
00174
00175 BOOLEAN
InstanceInitialized;
00176
00177
00178
00179
00180 BOOLEAN
SingleSmbMode;
00181 CLONG
Verbosity;
00182
00183
00184
00185
00186 SMBTRACE_STATE TraceState;
00187
00188
00189
00190
00191 PFILE_OBJECT StartersFileObject;
00192
00193
00194
00195
00196 PEPROCESS FspProcess;
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 KSPIN_LOCK
SmbsLostInterlock;
00210 ULONG
SmbsLost;
00211
00212
00213
00214
00215 KEVENT ActiveEvent;
00216 KEVENT TerminatedEvent;
00217 KEVENT TerminationEvent;
00218 KEVENT AppTerminationEvent;
00219 KEVENT NeedMemoryEvent;
00220
00221
00222
00223
00224 HANDLE
NewSmbEvent;
00225 HANDLE
DoneSmbEvent;
00226
00227
00228
00229
00230
00231 HANDLE
SectionHandle;
00232
00233
00234
00235
00236
00237
00238 PVOID
PortMemoryBase;
00239 ULONG_PTR
PortMemorySize;
00240 ULONG
TableSize;
00241 PVOID
PortMemoryHeap;
00242
00243
00244
00245
00246
00247 KSPIN_LOCK
HeapReferenceCountLock;
00248 PERESOURCE StateInterlock;
00249 PERESOURCE HeapInterlock;
00250 ULONG
HeapReferenceCount;
00251
00252
00253
00254
00255 PSMBTRACE_TABLE_HEADER
TableHeader;
00256 PSMBTRACE_TABLE_ENTRY
Table;
00257
00258
00259
00260
00261
00262
00263
00264 LIST_ENTRY
Queue;
00265 KSPIN_LOCK
QueueInterlock;
00266 KSEMAPHORE QueueSemaphore;
00267
00268 }
INSTANCE_DATA;
00269
00270
00271
#ifdef ALLOC_DATA_PRAGMA
00272
#pragma data_seg("PAGESMBD")
00273
#endif
00274
00275
00276
00277
00278 INSTANCE_DATA SmbTraceData[] = {
00279
00280
00281
00282
00283
00284 {
00285
"Srv",
00286 SMBTRACE_SRV_SHARED_MEMORY_NAME,
00287 SMBTRACE_SRV_NEW_SMB_EVENT_NAME,
00288 SMBTRACE_SRV_DONE_SMB_EVENT_NAME,
00289
00290
FALSE,
00291
00292
FALSE,
00293 SMBTRACE_VERBOSITY_ERROR,
00294
00295
TraceStopped,
00296
00297
NULL,
00298
NULL
00299
00300
00301 },
00302
00303
00304
00305
00306
00307 {
00308
"Rdr",
00309 SMBTRACE_LMR_SHARED_MEMORY_NAME,
00310 SMBTRACE_LMR_NEW_SMB_EVENT_NAME,
00311 SMBTRACE_LMR_DONE_SMB_EVENT_NAME,
00312
00313
FALSE,
00314
00315
FALSE,
00316 SMBTRACE_VERBOSITY_ERROR,
00317
00318
TraceStopped,
00319
00320
NULL,
00321
NULL
00322
00323
00324 }
00325 };
00326
00327
00328
00329
00330
00331
00332
00333 BOOLEAN
SmbTraceActive[] = {
FALSE,
FALSE};
00334 BOOLEAN
SmbTraceTransitioning[] = {
FALSE,
FALSE};
00335
00336 HANDLE
00337 SmbTraceDiscardableCodeHandle = 0;
00338
00339 HANDLE
00340 SmbTraceDiscardableDataHandle = 0;
00341
00342
#ifdef ALLOC_DATA_PRAGMA
00343
#pragma data_seg()
00344
#endif
00345
00346
00347
00348
00349
00350 BOOLEAN
00351
SmbTraceReferenceHeap(
00352 IN SMBTRACE_COMPONENT Component
00353 );
00354
00355
VOID
00356
SmbTraceDereferenceHeap(
00357 IN SMBTRACE_COMPONENT Component
00358 );
00359
00360
VOID
00361
SmbTraceDisconnect(
00362 IN SMBTRACE_COMPONENT Component
00363 );
00364
00365
VOID
00366
SmbTraceEmptyQueue (
00367 IN SMBTRACE_COMPONENT Component
00368 );
00369
00370
VOID
00371
SmbTraceThreadEntry(
00372 IN PVOID Context
00373 );
00374
00375
NTSTATUS
00376
SmbTraceFreeMemory (
00377 IN SMBTRACE_COMPONENT Component
00378 );
00379
00380
VOID
00381
SmbTraceToClient(
00382 IN PVOID Smb,
00383 IN CLONG SmbLength,
00384 IN PVOID SmbAddress,
00385 IN SMBTRACE_COMPONENT Component
00386 );
00387
00388 ULONG
00389
SmbTraceMdlLength(
00390 IN
PMDL Mdl
00391 );
00392
00393
VOID
00394
SmbTraceCopyMdlContiguous(
00395 OUT PVOID Destination,
00396 IN
PMDL Mdl,
00397 IN ULONG Length
00398 );
00399
00400
00401
00402
00403
00404
00405
00406
VOID
00407
SmbTraceDeferredDereferenceHeap(
00408 IN PVOID Context
00409 );
00410
00411
#ifdef ALLOC_PRAGMA
00412
#pragma alloc_text(PAGE, SmbTraceInitialize)
00413
#pragma alloc_text(PAGE, SmbTraceTerminate)
00414
#pragma alloc_text(PAGE, SmbTraceStart)
00415
#pragma alloc_text(PAGE, SmbTraceStop)
00416
#pragma alloc_text(PAGE, SmbTraceCompleteSrv)
00417
#pragma alloc_text(PAGE, SmbTraceDisconnect)
00418
#pragma alloc_text(PAGE, SmbTraceEmptyQueue)
00419
#pragma alloc_text(PAGE, SmbTraceThreadEntry)
00420
#pragma alloc_text(PAGE, SmbTraceFreeMemory)
00421
#pragma alloc_text(PAGE, SmbTraceToClient)
00422
#pragma alloc_text(PAGE, SmbTraceDeferredDereferenceHeap)
00423
#pragma alloc_text(PAGESMBC, SmbTraceCompleteRdr)
00424
#pragma alloc_text(PAGESMBC, SmbTraceReferenceHeap)
00425
#pragma alloc_text(PAGESMBC, SmbTraceDereferenceHeap)
00426
#pragma alloc_text(PAGESMBC, SmbTraceMdlLength)
00427
#pragma alloc_text(PAGESMBC, SmbTraceCopyMdlContiguous)
00428
#endif
00429
00430
00431
00432
00433
00434
00435
00436
00437
NTSTATUS
00438 SmbTraceInitialize (
00439 IN SMBTRACE_COMPONENT Component
00440 )
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 {
00461
PAGED_CODE();
00462
00463
if (
ID(InstanceInitialized) ==
FALSE ) {
00464
00465
00466
00467
00468
KeInitializeEvent( &
ID(ActiveEvent), NotificationEvent,
FALSE);
00469
KeInitializeEvent( &
ID(TerminatedEvent), NotificationEvent,
FALSE);
00470
KeInitializeEvent( &
ID(TerminationEvent), NotificationEvent,
FALSE);
00471
KeInitializeEvent( &
ID(AppTerminationEvent), NotificationEvent,
FALSE);
00472
KeInitializeEvent( &
ID(NeedMemoryEvent), NotificationEvent,
FALSE);
00473
00474
KeInitializeSpinLock( &
ID(SmbsLostInterlock) );
00475
KeInitializeSpinLock( &
ID(HeapReferenceCountLock) );
00476
00477
ID(StateInterlock) =
ExAllocatePoolWithTag(
00478
NonPagedPool,
00479
sizeof(
ERESOURCE),
00480 'tbmS'
00481 );
00482
if (
ID(StateInterlock) ==
NULL ) {
00483
return STATUS_INSUFFICIENT_RESOURCES;
00484 }
00485
ExInitializeResource(
ID(StateInterlock) );
00486
00487
ID(HeapInterlock) =
ExAllocatePoolWithTag(
00488
NonPagedPool,
00489
sizeof(
ERESOURCE),
00490 'tbmS'
00491 );
00492
if (
ID(HeapInterlock) ==
NULL ) {
00493
ExDeleteResource(
ID(StateInterlock) );
00494
ExFreePool(
ID(StateInterlock) );
00495
ID(StateInterlock) =
NULL;
00496
return STATUS_INSUFFICIENT_RESOURCES;
00497 }
00498
ExInitializeResource(
ID(HeapInterlock) );
00499
00500
ID(InstanceInitialized) =
TRUE;
00501 }
00502
00503
return STATUS_SUCCESS;
00504
00505 }
00506
00507
00508
VOID
00509 SmbTraceTerminate (
00510 IN SMBTRACE_COMPONENT Component
00511 )
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 {
00532
PAGED_CODE();
00533
00534
if (
ID(InstanceInitialized) ) {
00535
00536
ExDeleteResource(
ID(StateInterlock) );
00537
ExFreePool(
ID(StateInterlock) );
00538
00539
ExDeleteResource(
ID(HeapInterlock) );
00540
ExFreePool(
ID(HeapInterlock) );
00541
00542
ID(InstanceInitialized) =
FALSE;
00543 }
00544
00545
return;
00546
00547 }
00548
00549
00550
NTSTATUS
00551 SmbTraceStart (
00552 IN ULONG InputBufferLength,
00553 IN ULONG OutputBufferLength,
00554 IN OUT PVOID ConfigInOut,
00555 IN
PFILE_OBJECT FileObject,
00556 IN SMBTRACE_COMPONENT Component
00557 )
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 #define
ACL_LENGTH (ULONG)sizeof(ACL) + \
00591 (ULONG)sizeof(ACCESS_ALLOWED_ACE) + \
00592 sizeof(LUID) + \
00593 8
00594
00595 {
00596
NTSTATUS status;
00597 UNICODE_STRING memoryNameU;
00598
00599 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
00600 UCHAR
Buffer[
ACL_LENGTH];
00601 PACL AdminAcl = (PACL)(&
Buffer[0]);
00602 SECURITY_DESCRIPTOR securityDescriptor;
00603
00604 UNICODE_STRING eventNameU;
00605 OBJECT_ATTRIBUTES objectAttributes;
00606 ULONG i;
00607 LARGE_INTEGER sectionSize;
00608 PSMBTRACE_CONFIG_PACKET_REQ ConfigPacket;
00609 PSMBTRACE_CONFIG_PACKET_RESP ConfigPacketResp;
00610 HANDLE threadHandle;
00611
00612
PAGED_CODE();
00613
00614
ASSERT(
ID(InstanceInitialized) );
00615
00616
00617
00618
00619
00620
if ( ( InputBufferLength !=
sizeof( SMBTRACE_CONFIG_PACKET_REQ ) )
00621 || ( OutputBufferLength !=
sizeof( SMBTRACE_CONFIG_PACKET_RESP ) )
00622 ) {
00623
00624
TrPrint((
"%s!SmbTraceStart: config packet(s) of wrong size!\n",
00625
ID(ComponentName) ));
00626
00627
return STATUS_INFO_LENGTH_MISMATCH;
00628
00629 }
00630
00631
ExAcquireResourceExclusive(
ID(StateInterlock),
TRUE );
00632
00633
if (
ID(TraceState) !=
TraceStopped ) {
00634
ExReleaseResource(
ID(StateInterlock) );
00635
return STATUS_INVALID_DEVICE_STATE;
00636 }
00637
00638
ASSERT(!
SmbTraceActive[Component]);
00639
00640
ASSERT (
SmbTraceDiscardableDataHandle ==
NULL);
00641
00642
ASSERT (
SmbTraceDiscardableCodeHandle ==
NULL);
00643
00644
SmbTraceDiscardableCodeHandle = MmLockPagableCodeSection(
SmbTraceReferenceHeap);
00645
00646
SmbTraceDiscardableDataHandle =
MmLockPagableDataSection(
SmbTraceData);
00647
00648
ID(TraceState) =
TraceStarting;
00649
00650
00651
00652
00653
00654
ID(SectionHandle) =
NULL;
00655
ID(PortMemoryHeap) =
NULL;
00656
ID(NewSmbEvent) =
NULL;
00657
ID(DoneSmbEvent) =
NULL;
00658
00659
00660
00661
00662
00663
00664 ConfigPacket = (PSMBTRACE_CONFIG_PACKET_REQ) ConfigInOut;
00665 ConfigPacketResp = (PSMBTRACE_CONFIG_PACKET_RESP) ConfigInOut;
00666
00667
00668
00669
00670
00671
ID(SingleSmbMode) = ConfigPacket->SingleSmbMode;
00672
ID(Verbosity) = ConfigPacket->Verbosity;
00673
ID(PortMemorySize) = ConfigPacket->BufferSize;
00674
ID(TableSize) = ConfigPacket->TableSize;
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 status =
RtlCreateAcl( AdminAcl,
ACL_LENGTH, ACL_REVISION2 );
00685
if ( !
NT_SUCCESS(status) ) {
00686
TrPrint((
00687
"%s!SmbTraceStart: RtlCreateAcl failed: %X\n",
00688
ID(ComponentName), status ));
00689
goto errexit;
00690 }
00691
00692 status =
RtlAddAccessAllowedAce(
00693 AdminAcl,
00694 ACL_REVISION2,
00695 GENERIC_ALL,
00696
SeExports->
SeAliasAdminsSid
00697 );
00698
if ( !
NT_SUCCESS(status) ) {
00699
TrPrint((
00700
"%s!SmbTraceStart: RtlAddAccessAllowedAce failed: %X\n",
00701
ID(ComponentName), status ));
00702
goto errexit;
00703 }
00704
00705
00706
00707
RtlCreateSecurityDescriptor(
00708 &securityDescriptor,
00709 SECURITY_DESCRIPTOR_REVISION1
00710 );
00711
if ( !
NT_SUCCESS(status) ) {
00712
TrPrint((
00713
"%s!SmbTraceStart: RtlCreateSecurityDescriptor failed: %X\n",
00714
ID(ComponentName), status ));
00715
goto errexit;
00716 }
00717
00718 status =
RtlSetDaclSecurityDescriptor(
00719 &securityDescriptor,
00720
TRUE,
00721 AdminAcl,
00722
FALSE
00723 );
00724
if ( !
NT_SUCCESS(status) ) {
00725
TrPrint((
00726
"%s!SmbTraceStart: "
00727
"RtlSetDAclAllowedSecurityDescriptor failed: %X\n",
00728
ID(ComponentName), status ));
00729
goto errexit;
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
RtlInitUnicodeString( &memoryNameU,
ID(SharedMemoryName) );
00740
00741
00742
00743 InitializeObjectAttributes(
00744 &objectAttributes,
00745 &memoryNameU,
00746 OBJ_CASE_INSENSITIVE,
00747
NULL,
00748 &securityDescriptor
00749 );
00750
00751
00752
00753 sectionSize.QuadPart =
ID(PortMemorySize);
00754
00755
00756
00757 status = ZwCreateSection(
00758 &
ID(SectionHandle),
00759 SECTION_MAP_READ | SECTION_MAP_WRITE,
00760 &objectAttributes,
00761 §ionSize,
00762 PAGE_READWRITE,
00763 SEC_RESERVE,
00764
NULL
00765 );
00766
00767
if ( !
NT_SUCCESS(status) ) {
00768
TrPrint((
"%s!SmbTraceStart: ZwCreateSection failed: %X\n",
00769
ID(ComponentName), status ));
00770
goto errexit;
00771 }
00772
00773
00774
00775
ID(PortMemoryBase) =
NULL;
00776
00777 status = ZwMapViewOfSection(
00778
ID(SectionHandle),
00779 NtCurrentProcess(),
00780 &
ID(PortMemoryBase),
00781 0,
00782 0,
00783
NULL,
00784 &
ID(PortMemorySize),
00785 ViewUnmap,
00786 0
L,
00787 PAGE_READWRITE
00788 );
00789
00790
if ( !
NT_SUCCESS(status) ) {
00791
TrPrint((
"%s!SmbTraceStart: NtMapViewOfSection failed: %X\n",
00792
ID(ComponentName), status ));
00793
goto errexit;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
ID(PortMemoryHeap) =
RtlCreateHeap(
00809 0,
00810
ID(PortMemoryBase),
00811
ID(PortMemorySize),
00812
PAGE_SIZE,
00813
ID(HeapInterlock),
00814 0
00815 );
00816
00817
00818
00819
00820
00821
ID(TableHeader) =
RtlAllocateHeap(
00822
ID(PortMemoryHeap), 0,
00823
sizeof( SMBTRACE_TABLE_HEADER )
00824 );
00825
00826
ID(Table) =
RtlAllocateHeap(
00827
ID(PortMemoryHeap), 0,
00828
sizeof( SMBTRACE_TABLE_ENTRY ) *
ID(TableSize)
00829 );
00830
00831
if ( (
ID(TableHeader) ==
NULL) || (
ID(Table) ==
NULL) ) {
00832
TrPrint((
00833
"%s!SmbTraceStart: Not enough memory!\n",
00834
ID(ComponentName) ));
00835
00836 status = STATUS_NO_MEMORY;
00837
00838
goto errexit;
00839 }
00840
00841
00842
00843
ID(TableHeader)->HighestConsumed = 0;
00844
ID(TableHeader)->NextFree = 1;
00845
ID(TableHeader)->ApplicationStop =
FALSE;
00846
00847
for ( i = 0; i <
ID(TableSize); i++) {
00848
ID(Table)[i].BufferOffset = 0
L;
00849
ID(Table)[i].SmbLength = 0
L;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
RtlInitUnicodeString( &eventNameU,
ID(NewSmbEventName) );
00859
00860 InitializeObjectAttributes(
00861 &objectAttributes,
00862 &eventNameU,
00863 OBJ_CASE_INSENSITIVE,
00864
NULL,
00865 &securityDescriptor
00866 );
00867
00868
00869
00870 status = ZwCreateEvent(
00871 &
ID(NewSmbEvent),
00872 EVENT_ALL_ACCESS,
00873 &objectAttributes,
00874 NotificationEvent,
00875
FALSE
00876 );
00877
00878
if ( !
NT_SUCCESS(status) ) {
00879
TrPrint((
"%s!SmbTraceStart: ZwCreateEvent (1st) failed: %X\n",
00880
ID(ComponentName), status ));
00881
00882
goto errexit;
00883 }
00884
00885
if (
ID(SingleSmbMode) ) {
00886
00887
00888
00889
RtlInitUnicodeString( &eventNameU,
ID(DoneSmbEventName) );
00890
00891 InitializeObjectAttributes(
00892 &objectAttributes,
00893 &eventNameU,
00894 OBJ_CASE_INSENSITIVE,
00895
NULL,
00896 &securityDescriptor
00897 );
00898
00899
00900
00901 status = ZwCreateEvent(
00902 &
ID(DoneSmbEvent),
00903 EVENT_ALL_ACCESS,
00904 &objectAttributes,
00905 NotificationEvent,
00906
FALSE
00907 );
00908
00909
if ( !
NT_SUCCESS(status) ) {
00910
TrPrint((
00911
"%s!SmbTraceStart: NtCreateEvent (2nd) failed: %X\n",
00912
ID(ComponentName), status ));
00913
goto errexit;
00914 }
00915
TrPrint((
"%s!SmbTraceStart: DoneSmbEvent handle %x in process %x\n",
00916
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
00917
00918 }
00919
00920
00921
00922
00923
00924
KeResetEvent(&
ID(TerminationEvent));
00925
KeResetEvent(&
ID(TerminatedEvent));
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 status =
PsCreateSystemThread(
00937 &threadHandle,
00938 THREAD_ALL_ACCESS,
00939
NULL,
00940 NtCurrentProcess(),
00941
NULL,
00942 (
PKSTART_ROUTINE)
SmbTraceThreadEntry,
00943 (PVOID)Component
00944 );
00945
00946
if ( !
NT_SUCCESS(status) ) {
00947
00948
TrPrint((
00949
"%s!SmbTraceStart: PsCreateSystemThread failed: %X\n",
00950
ID(ComponentName), status ));
00951
00952
goto errexit;
00953 }
00954
00955
00956
00957
00958
00959 (
VOID)
KeWaitForSingleObject(
00960 &
ID(ActiveEvent),
00961
UserRequest,
00962
KernelMode,
00963
FALSE,
00964
NULL
00965 );
00966
00967
00968
00969
00970
00971
00972 ZwClose( threadHandle );
00973
00974
00975
00976
00977
00978
00979
00980
ID(StartersFileObject) = FileObject;
00981
00982
00983
00984
00985
00986
00987
ID(FspProcess) =
PsGetCurrentProcess();
00988
00989
00990
00991
00992
00993
00994 ConfigPacketResp->HeaderOffset = (ULONG)
00995 ( (ULONG_PTR)
ID(TableHeader)
00996 - (ULONG_PTR)
ID(PortMemoryBase) );
00997
00998 ConfigPacketResp->TableOffset = (ULONG)
00999 ( (ULONG_PTR)
ID(Table)
01000 - (ULONG_PTR)
ID(PortMemoryBase) );
01001
01002
TrPrint((
"%s!SmbTraceStart: SmbTrace started.\n",
ID(ComponentName) ));
01003
01004
ExReleaseResource(
ID(StateInterlock) );
01005
01006
01007
01008
01009
01010
switch (
ID(TraceState) ) {
01011
01012
case TraceStartStopFile :
01013
SmbTraceStop(
ID(StartersFileObject), Component );
01014
return STATUS_UNSUCCESSFUL;
01015
break;
01016
01017
case TraceStartStopNull :
01018
SmbTraceStop(
NULL, Component );
01019
return STATUS_UNSUCCESSFUL;
01020
break;
01021
01022
default :
01023
ID(TraceState) =
TraceRunning;
01024
SmbTraceActive[Component] =
TRUE;
01025
return STATUS_SUCCESS;
01026 }
01027
01028 errexit:
01029
01030
SmbTraceDisconnect( Component );
01031
01032
ID(TraceState) =
TraceStopped;
01033
01034
ExReleaseResource(
ID(StateInterlock) );
01035
01036
01037
01038
01039
01040
return status;
01041
01042 }
01043
01044
01045
01046
#undef ACL_LENGTH
01047
01048
01049
NTSTATUS
01050 SmbTraceStop(
01051 IN
PFILE_OBJECT FileObject OPTIONAL,
01052 IN SMBTRACE_COMPONENT Component
01053 )
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 {
01082
PAGED_CODE();
01083
01084
01085
01086
01087
01088
01089
if ( !
ID(InstanceInitialized) ) {
01090
return STATUS_UNSUCCESSFUL;
01091 }
01092
01093
01094
01095
01096
01097
01098
if ( ARGUMENT_PRESENT(FileObject) &&
01099 FileObject !=
ID(StartersFileObject)
01100 ) {
01101
return STATUS_UNSUCCESSFUL;
01102 }
01103
01104
ExAcquireResourceExclusive(
ID(StateInterlock),
TRUE );
01105
01106
01107
01108
01109
01110
01111
01112
01113
SmbTraceActive[Component] =
FALSE;
01114
01115
switch (
ID(TraceState) ) {
01116
case TraceStopped :
01117
case TraceStopping :
01118
case TraceStartStopFile :
01119
case TraceStartStopNull :
01120
01121
01122
01123
ExReleaseResource(
ID(StateInterlock) );
01124
return STATUS_UNSUCCESSFUL;
01125
break;
01126
01127
case TraceStarting :
01128
01129
01130
01131
01132
01133
ID(TraceState) = ARGUMENT_PRESENT(FileObject)
01134 ?
TraceStartStopFile
01135 :
TraceStartStopNull;
01136
ExReleaseResource(
ID(StateInterlock) );
01137
return STATUS_SUCCESS;
01138
break;
01139
01140
case TraceAppWaiting :
01141
01142
01143
01144
01145
if ( ARGUMENT_PRESENT(FileObject) ) {
01146
break;
01147 }
else {
01148
ExReleaseResource(
ID(StateInterlock) );
01149
return STATUS_UNSUCCESSFUL;
01150 }
01151
break;
01152
01153
case TraceRunning :
01154
01155
01156
01157
01158
01159
01160
if ( ARGUMENT_PRESENT(FileObject) ) {
01161
break;
01162 }
else {
01163
KeSetEvent( &
ID(AppTerminationEvent), 2,
FALSE );
01164
ID(TraceState) =
TraceAppWaiting;
01165
ExReleaseResource(
ID(StateInterlock) );
01166
return STATUS_SUCCESS;
01167 }
01168
01169
break;
01170
01171
default :
01172
ASSERT(!
"SmbTraceStop: invalid TraceState");
01173
break;
01174 }
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
ID(StartersFileObject) =
NULL;
01185
01186
if (
ID(SingleSmbMode)) {
01187
01188 BOOLEAN ProcessAttached =
FALSE;
01189
01190
if (
PsGetCurrentProcess() !=
ID(FspProcess)) {
01191
KeAttachProcess(
ID(FspProcess));
01192 ProcessAttached =
TRUE;
01193 }
01194
01195
TrPrint((
"%s!SmbTraceStop: Signal DoneSmbEvent, handle %x, process %x.\n",
01196
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
01197 ZwSetEvent(
ID(DoneSmbEvent),
NULL );
01198
01199
if (ProcessAttached) {
01200
KeDetachProcess();
01201 }
01202
01203 }
01204
01205
TrPrint((
"%s!SmbTraceStop: Signal Termination Event.\n",
ID(ComponentName) ));
01206
ID(TraceState) =
TraceStopping;
01207
KeSetEvent( &
ID(TerminationEvent), 2,
FALSE );
01208
01209
ExReleaseResource(
ID(StateInterlock) );
01210
01211
KeWaitForSingleObject(
01212 &
ID(TerminatedEvent),
01213
UserRequest,
01214
KernelMode,
01215
FALSE,
01216
NULL
01217 );
01218
01219
TrPrint((
"%s!SmbTraceStop: Terminated Event is set.\n",
ID(ComponentName) ));
01220
ExAcquireResourceExclusive(
ID(StateInterlock),
TRUE );
01221
01222
ID(TraceState) =
TraceStopped;
01223
01224
ExReleaseResource(
ID(StateInterlock) );
01225
01226
TrPrint((
"%s!SmbTraceStop: SmbTrace stopped.\n",
ID(ComponentName) ));
01227
01228
MmUnlockPagableImageSection(
SmbTraceDiscardableCodeHandle);
01229
01230
SmbTraceDiscardableCodeHandle =
NULL;
01231
01232
MmUnlockPagableImageSection(
SmbTraceDiscardableDataHandle);
01233
01234
SmbTraceDiscardableDataHandle =
NULL;
01235
01236
return STATUS_SUCCESS;
01237
01238 }
01239
01240
01241
VOID
01242 SmbTraceCompleteSrv (
01243 IN
PMDL SmbMdl,
01244 IN PVOID Smb,
01245 IN CLONG SmbLength
01246 )
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 {
01288
PSMBTRACE_QUEUE_ENTRY queueEntry;
01289 PVOID buffer;
01290 SMBTRACE_COMPONENT Component = SMBTRACE_SERVER;
01291
KEVENT WaitEvent;
01292
01293
PAGED_CODE();
01294
01295
01296
01297
01298
01299
ASSERT(
ID(TraceState) ==
TraceRunning );
01300
ASSERT(
SmbTraceActive[SMBTRACE_SERVER] );
01301
01302
01303
01304
01305
01306
01307
ASSERT( ( SmbMdl ==
NULL && Smb !=
NULL && SmbLength != 0 )
01308 || ( SmbMdl !=
NULL && Smb ==
NULL && SmbLength == 0 )
01309 || ( SmbMdl ==
NULL && Smb ==
NULL && SmbLength == 0 ) );
01310
01311
01312
01313
01314
01315
01316
ASSERT( KeGetCurrentIrql() <
DISPATCH_LEVEL);
01317
ASSERT(
PsGetCurrentProcess() ==
ID(FspProcess) );
01318
01319
01320
01321
01322
01323
01324
if (
SmbTraceReferenceHeap( Component ) ==
FALSE ) {
01325
return;
01326 }
01327
01328
01329
01330
01331
01332
01333
if ( SmbMdl !=
NULL ) {
01334 SmbLength =
SmbTraceMdlLength(SmbMdl);
01335 }
01336
01337
01338
01339
01340
01341
01342
01343
if (
ID(SingleSmbMode) ) {
01344
KeInitializeEvent( &WaitEvent, NotificationEvent,
FALSE );
01345 }
01346
01347 queueEntry =
ExAllocatePoolWithTag(
NonPagedPool,
01348
sizeof(
SMBTRACE_QUEUE_ENTRY),
01349 'tbmS'
01350 );
01351
01352
if ( queueEntry ==
NULL ) {
01353
01354
LOCK_INC_ID(SmbsLost);
01355
SmbTraceDereferenceHeap( Component );
01356
return;
01357 }
01358
01359
01360
01361
01362
01363
01364 buffer =
RtlAllocateHeap(
ID(PortMemoryHeap), 0, SmbLength );
01365
01366
if ( buffer ==
NULL ) {
01367
01368
01369
LOCK_INC_ID(SmbsLost);
01370
ExFreePool( queueEntry );
01371
01372
if ( !
ID(SingleSmbMode) ) {
01373
01374
01375
01376
KeSetEvent( &
ID(NeedMemoryEvent), 0,
FALSE );
01377 }
01378
01379
SmbTraceDereferenceHeap( Component );
01380
return;
01381 }
01382
01383
01384
01385
01386
01387
01388
01389
if ( SmbMdl !=
NULL ) {
01390
SmbTraceCopyMdlContiguous( buffer, SmbMdl, SmbLength );
01391 queueEntry->
SmbAddress = SmbMdl;
01392 }
else {
01393 RtlCopyMemory( buffer, Smb, SmbLength );
01394 queueEntry->
SmbAddress = Smb;
01395 }
01396
01397 queueEntry->
SmbLength = SmbLength;
01398 queueEntry->
Buffer = buffer;
01399 queueEntry->
BufferNonPaged =
FALSE;
01400
01401
01402
01403
01404
01405
01406
01407
01408
if (
ID(SingleSmbMode) ) {
01409 queueEntry->
WaitEvent = &WaitEvent;
01410 }
else {
01411 queueEntry->
WaitEvent =
NULL;
01412 queueEntry->
SmbAddress =
NULL;
01413 }
01414
01415
01416
01417
01418
01419
ExInterlockedInsertTailList(
01420 &
ID(Queue),
01421 &queueEntry->
ListEntry,
01422 &
ID(QueueInterlock)
01423 );
01424
01425
KeReleaseSemaphore(
01426 &
ID(QueueSemaphore),
01427
SEMAPHORE_INCREMENT,
01428 1,
01429
FALSE
01430 );
01431
01432
01433
01434
01435
01436
if (
ID(SingleSmbMode) ) {
01437
TrPrint((
"%s!SmbTraceCompleteSrv: Slow mode wait\n",
ID(ComponentName) ));
01438
KeWaitForSingleObject(
01439 &WaitEvent,
01440
UserRequest,
01441
KernelMode,
01442
FALSE,
01443
NULL
01444 );
01445
TrPrint((
"%s!SmbTraceCompleteSrv: Slow mode wait done\n",
ID(ComponentName) ));
01446 }
01447
01448
SmbTraceDereferenceHeap( Component );
01449
01450
return;
01451
01452 }
01453
01454
01455
VOID
01456 SmbTraceCompleteRdr (
01457 IN
PMDL SmbMdl,
01458 IN PVOID Smb,
01459 IN CLONG SmbLength
01460 )
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505 {
01506
PSMBTRACE_QUEUE_ENTRY queueEntry;
01507 PVOID buffer;
01508 BOOLEAN ProcessAttached =
FALSE;
01509 BOOLEAN AtDpcLevel;
01510 SMBTRACE_COMPONENT Component = SMBTRACE_REDIRECTOR;
01511
KEVENT WaitEvent;
01512
01513
01514
01515
01516
01517
ASSERT(
ID(TraceState) ==
TraceRunning );
01518
ASSERT(
SmbTraceActive[SMBTRACE_REDIRECTOR] );
01519
01520
01521
01522
01523
01524
01525
ASSERT( ( SmbMdl ==
NULL && Smb !=
NULL && SmbLength != 0 )
01526 || ( SmbMdl !=
NULL && Smb ==
NULL && SmbLength == 0 )
01527 || ( SmbMdl ==
NULL && Smb ==
NULL && SmbLength == 0 ) );
01528
01529
01530
01531
01532
01533
01534
if (
SmbTraceReferenceHeap( Component ) ==
FALSE ) {
01535
return;
01536 }
01537
01538
01539
01540
01541
01542 AtDpcLevel = (BOOLEAN)(KeGetCurrentIrql() >=
DISPATCH_LEVEL);
01543
01544
01545
01546
01547
01548
01549
if ( SmbMdl !=
NULL ) {
01550 SmbLength =
SmbTraceMdlLength(SmbMdl);
01551 }
01552
01553
01554
01555
01556
01557
01558
01559
01560
if (
ID(SingleSmbMode) ) {
01561
KeInitializeEvent( &WaitEvent, NotificationEvent,
FALSE );
01562 }
01563
01564
01565
01566
01567
01568 queueEntry =
ExAllocatePoolWithTag(
01569
NonPagedPool,
01570
sizeof(
SMBTRACE_QUEUE_ENTRY),
01571 'tbmS'
01572 );
01573
01574
if ( queueEntry ==
NULL ) {
01575
01576
LOCK_INC_ID(SmbsLost);
01577
SmbTraceDereferenceHeap( Component );
01578
return;
01579 }
01580
01581
01582
01583
01584
01585
01586
if ( AtDpcLevel ) {
01587
01588 buffer =
ExAllocatePoolWithTag(
NonPagedPool, SmbLength, 'tbmS' );
01589 queueEntry->
BufferNonPaged =
TRUE;
01590
01591 }
else {
01592
01593
if (
PsGetCurrentProcess() !=
ID(FspProcess) ) {
01594
KeAttachProcess(
ID(FspProcess));
01595 ProcessAttached =
TRUE;
01596 }
01597
01598 buffer =
RtlAllocateHeap(
ID(PortMemoryHeap), 0, SmbLength );
01599 queueEntry->
BufferNonPaged =
FALSE;
01600
01601 }
01602
01603
if ( buffer ==
NULL ) {
01604
01605
if ( ProcessAttached ) {
01606
KeDetachProcess();
01607 }
01608
01609
01610
LOCK_INC_ID(SmbsLost);
01611
01612
if (!
ID(SingleSmbMode)) {
01613
01614
01615
01616
01617
01618
if ( !queueEntry->
BufferNonPaged ) {
01619
KeSetEvent( &
ID(NeedMemoryEvent), 0,
FALSE );
01620 }
01621 }
01622
01623
ExFreePool( queueEntry );
01624
SmbTraceDereferenceHeap( Component );
01625
return;
01626 }
01627
01628
01629
01630
01631
01632
01633
01634
if ( SmbMdl !=
NULL ) {
01635
SmbTraceCopyMdlContiguous( buffer, SmbMdl, SmbLength );
01636 queueEntry->
SmbAddress = SmbMdl;
01637 }
else {
01638 RtlCopyMemory( buffer, Smb, SmbLength );
01639 queueEntry->
SmbAddress = Smb;
01640 }
01641
01642
if ( ProcessAttached ) {
01643
KeDetachProcess();
01644 }
01645
01646 queueEntry->
SmbLength = SmbLength;
01647 queueEntry->
Buffer = buffer;
01648
01649
01650
01651
01652
01653
01654
01655
01656
if (
ID(SingleSmbMode) && !AtDpcLevel ) {
01657 queueEntry->
WaitEvent = &WaitEvent;
01658 }
else {
01659 queueEntry->
WaitEvent =
NULL;
01660 queueEntry->
SmbAddress =
NULL;
01661 }
01662
01663
01664
01665
01666
01667
ExInterlockedInsertTailList(
01668 &
ID(Queue),
01669 &queueEntry->
ListEntry,
01670 &
ID(QueueInterlock)
01671 );
01672
01673
KeReleaseSemaphore(
01674 &
ID(QueueSemaphore),
01675
SEMAPHORE_INCREMENT,
01676 1,
01677
FALSE
01678 );
01679
01680
01681
01682
01683
01684
if (
ID(SingleSmbMode) && !AtDpcLevel ) {
01685
TrPrint((
"%s!SmbTraceCompleteRdr: Slow mode wait\n",
ID(ComponentName) ));
01686
KeWaitForSingleObject(
01687 &WaitEvent,
01688
UserRequest,
01689
KernelMode,
01690
FALSE,
01691
NULL
01692 );
01693
TrPrint((
"%s!SmbTraceCompleteRdr: Slow mode wait done\n",
ID(ComponentName) ));
01694 }
01695
01696
SmbTraceDereferenceHeap( Component );
01697
01698
return;
01699
01700 }
01701
01702
01703
01704
01705
01706
01707
01708 BOOLEAN
01709 SmbTraceReferenceHeap(
01710 IN SMBTRACE_COMPONENT Component
01711 )
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732 {
01733 BOOLEAN retval =
TRUE;
01734 KIRQL OldIrql;
01735
01736
ACQUIRE_SPIN_LOCK( &
ID(HeapReferenceCountLock), &OldIrql );
01737
01738
if (
ID(TraceState) !=
TraceRunning ) {
01739 retval =
FALSE;
01740 }
else {
01741
ASSERT(
ID(HeapReferenceCount) > 0 );
01742
ID(HeapReferenceCount)++;
01743
TrPrint((
"%s!SmbTraceReferenceHeap: Count now %lx\n",
01744
ID(ComponentName),
01745
ID(HeapReferenceCount) ));
01746 }
01747
01748
RELEASE_SPIN_LOCK( &
ID(HeapReferenceCountLock), OldIrql );
01749
01750
return retval;
01751
01752 }
01753
01754 typedef struct _TRACE_DEREFERENCE_ITEM {
01755 WORK_QUEUE_ITEM WorkItem;
01756 SMBTRACE_COMPONENT
Component;
01757 }
TRACE_DEREFERENCE_ITEM, *
PTRACE_DEREFERENCE_ITEM;
01758
01759
VOID
01760 SmbTraceDeferredDereferenceHeap(
01761 IN PVOID Context
01762 )
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780 {
01781
PTRACE_DEREFERENCE_ITEM WorkItem = Context;
01782 SMBTRACE_COMPONENT Component = WorkItem->
Component;
01783
01784
PAGED_CODE();
01785
01786
ExFreePool(WorkItem);
01787
01788
SmbTraceDereferenceHeap(Component);
01789
01790 }
01791
01792
01793
VOID
01794 SmbTraceDereferenceHeap(
01795 IN SMBTRACE_COMPONENT Component
01796 )
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815 {
01816 ULONG oldCount;
01817 KIRQL OldIrql;
01818
01819
ACQUIRE_SPIN_LOCK( &
ID(HeapReferenceCountLock), &OldIrql );
01820
01821
if (
ID(HeapReferenceCount) > 1) {
01822
ID(HeapReferenceCount) --;
01823
01824
TrPrint((
"%s!SmbTraceDereferenceHeap: Count now %lx\n",
01825
ID(ComponentName),
01826
ID(HeapReferenceCount) ));
01827
01828
RELEASE_SPIN_LOCK( &
ID(HeapReferenceCountLock), OldIrql );
01829
01830
return;
01831 }
01832
01833
RELEASE_SPIN_LOCK( &
ID(HeapReferenceCountLock), OldIrql );
01834
01835
01836
01837
01838
01839
01840
if (KeGetCurrentIrql() >=
DISPATCH_LEVEL) {
01841
PTRACE_DEREFERENCE_ITEM WorkItem;
01842
01843 WorkItem =
ExAllocatePoolWithTag(
NonPagedPoolMustSucceed,
sizeof(
TRACE_DEREFERENCE_ITEM), 'tbmS');
01844
01845
ExInitializeWorkItem(&WorkItem->
WorkItem,
SmbTraceDeferredDereferenceHeap, WorkItem);
01846 WorkItem->
Component = Component;
01847
01848
ExQueueWorkItem(&WorkItem->
WorkItem,
DelayedWorkQueue);
01849
01850
return;
01851
01852 }
01853
01854
ACQUIRE_SPIN_LOCK( &
ID(HeapReferenceCountLock), &OldIrql );
01855
01856 oldCount =
ID(HeapReferenceCount)--;
01857
01858
TrPrint((
"%s!SmbTraceDereferenceHeap: Count now %lx\n",
01859
ID(ComponentName),
01860
ID(HeapReferenceCount) ));
01861
01862
RELEASE_SPIN_LOCK( &
ID(HeapReferenceCountLock), OldIrql );
01863
01864
if ( oldCount == 1 ) {
01865
01866
01867
01868
01869
01870
SmbTraceDisconnect( Component );
01871 }
01872
01873
return;
01874
01875 }
01876
01877
01878
VOID
01879 SmbTraceDisconnect (
01880 IN SMBTRACE_COMPONENT Component
01881 )
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900 {
01901 BOOLEAN ProcessAttached =
FALSE;
01902
01903
PAGED_CODE();
01904
01905
if (
PsGetCurrentProcess() !=
ID(FspProcess)) {
01906
KeAttachProcess(
ID(FspProcess));
01907 ProcessAttached =
TRUE;
01908
01909 }
01910
01911
01912
if (
ID(DoneSmbEvent) !=
NULL ) {
01913
01914
TrPrint((
"%s!SmbTraceDisconnect: Signal DoneSmbEvent, handle %x, process %x.\n",
01915
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
01916 ZwSetEvent(
ID(DoneSmbEvent),
NULL );
01917
01918
TrPrint((
"%s!SmbTraceDisconnect: Close DoneSmbEvent, handle %x, process %x.\n",
01919
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
01920 ZwClose(
ID(DoneSmbEvent) );
01921
ID(DoneSmbEvent) =
NULL;
01922 }
01923
01924
if (
ID(NewSmbEvent) !=
NULL ) {
01925 ZwClose(
ID(NewSmbEvent) );
01926
ID(NewSmbEvent) =
NULL;
01927 }
01928
01929
if (
ID(PortMemoryHeap) !=
NULL ) {
01930
RtlDestroyHeap(
ID(PortMemoryHeap) );
01931
ID(PortMemoryHeap) =
NULL;
01932 }
01933
01934
if (
ID(SectionHandle) !=
NULL ) {
01935 ZwClose(
ID(SectionHandle) );
01936
ID(SectionHandle) =
NULL;
01937 }
01938
01939
if (ProcessAttached) {
01940
KeDetachProcess();
01941 }
01942
01943
return;
01944
01945 }
01946
01947
01948
VOID
01949 SmbTraceEmptyQueue (
01950 IN SMBTRACE_COMPONENT Component
01951 )
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969 {
01970 PLIST_ENTRY listEntry;
01971
PSMBTRACE_QUEUE_ENTRY queueEntry;
01972
01973
PAGED_CODE();
01974
01975
while ( ( listEntry =
ExInterlockedRemoveHeadList(
01976 &
ID(Queue),
01977 &
ID(QueueInterlock)
01978 )
01979 ) !=
NULL
01980 ) {
01981 queueEntry = CONTAINING_RECORD(
01982 listEntry,
01983
SMBTRACE_QUEUE_ENTRY,
01984 ListEntry
01985 );
01986
01987
01988
01989
01990
01991
01992
if ( queueEntry->
BufferNonPaged ) {
01993
01994
ASSERT( Component == SMBTRACE_REDIRECTOR );
01995
01996
ExFreePool( queueEntry->
Buffer );
01997 }
01998
01999
02000
02001
02002
02003
02004
if ( queueEntry->
WaitEvent !=
NULL ) {
02005
02006
ASSERT(
ID(SingleSmbMode) ==
TRUE );
02007
02008
KeSetEvent( queueEntry->
WaitEvent, 0,
FALSE );
02009 }
02010
02011
ExFreePool( queueEntry );
02012 }
02013
02014
return;
02015
02016 }
02017
02018
02019
VOID
02020 SmbTraceThreadEntry (
02021 IN PVOID Context
02022 )
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045 #define
NUMBER_OF_BLOCKING_OBJECTS 4
02046
02047
02048
02049
#define INDEX_WAIT_TERMINATIONEVENT 0
02050
#define INDEX_WAIT_APPTERMINATIONEVENT 1
02051
#define INDEX_WAIT_NEEDMEMORYEVENT 2
02052
#define INDEX_WAIT_QUEUESEMAPHORE 3
02053
02054
#define STATUS_WAIT_TERMINATIONEVENT STATUS_WAIT_0
02055
#define STATUS_WAIT_APPTERMINATIONEVENT STATUS_WAIT_1
02056
#define STATUS_WAIT_NEEDMEMORYEVENT STATUS_WAIT_2
02057
#define STATUS_WAIT_QUEUESEMAPHORE STATUS_WAIT_3
02058
02059 {
02060
NTSTATUS status;
02061 PLIST_ENTRY listEntry;
02062
PSMBTRACE_QUEUE_ENTRY queueEntry;
02063 PVOID buffer;
02064 PVOID waitObjects[
NUMBER_OF_BLOCKING_OBJECTS];
02065 SMBTRACE_COMPONENT Component;
02066 BOOLEAN Looping;
02067
02068
#if NUMBER_OF_BLOCKING_OBJECTS > THREAD_WAIT_OBJECTS
02069
02070
02071
02072
02073
02074
KWAIT_BLOCK waitBlocks[
NUMBER_OF_BLOCKING_OBJECTS];
02075
#endif
02076
02077
PAGED_CODE();
02078
02079
02080
02081
02082 Component = (SMBTRACE_COMPONENT)(UINT_PTR)Context;
02083
02084
02085
02086
02087
02088 InitializeListHead( &
ID(Queue) );
02089
KeInitializeSpinLock( &
ID(QueueInterlock) );
02090
KeInitializeSemaphore( &
ID(QueueSemaphore), 0, 0x7FFFFFFF );
02091
02092
02093
02094
02095
02096
02097
02098
02099 waitObjects[
INDEX_WAIT_TERMINATIONEVENT] = &
ID(TerminationEvent);
02100 waitObjects[
INDEX_WAIT_APPTERMINATIONEVENT] = &
ID(AppTerminationEvent);
02101 waitObjects[
INDEX_WAIT_NEEDMEMORYEVENT] = &
ID(NeedMemoryEvent);
02102 waitObjects[
INDEX_WAIT_QUEUESEMAPHORE] = &
ID(QueueSemaphore);
02103
02104
02105
02106
02107
02108
02109
02110
02111
ID(SmbsLost) = 0
L;
02112
ID(HeapReferenceCount) = 1;
02113
02114
02115
02116
02117
02118
KeSetEvent( &
ID(ActiveEvent), 0,
FALSE );
02119
02120
02121
02122
02123
02124
TrPrint((
"%s!SmbTraceThread: Tracing started.\n",
ID(ComponentName) ));
02125
02126 Looping =
TRUE;
02127
while( Looping ) {
02128
02129
TrPrint((
"%s!SmbTraceThread: WaitForMultiple.\n",
ID(ComponentName) ));
02130 status =
KeWaitForMultipleObjects(
02131
NUMBER_OF_BLOCKING_OBJECTS,
02132 &waitObjects[0],
02133 WaitAny,
02134
UserRequest,
02135
KernelMode,
02136
FALSE,
02137
NULL,
02138 #
if NUMBER_OF_BLOCKING_OBJECTS >
THREAD_WAIT_OBJECTS
02139 &waitBlocks[0]
02140 #
else
02141
NULL
02142 #endif
02143 );
02144
02145
if ( !
NT_SUCCESS(status) ) {
02146
TrPrint((
02147
"%s!SmbTraceThreadEntry: KeWaitForMultipleObjectsfailed: %X\n",
02148
ID(ComponentName), status ));
02149 }
else {
02150
TrPrint((
02151
"%s!SmbTraceThreadEntry: %lx\n",
02152
ID(ComponentName), status ));
02153 }
02154
02155
switch( status ) {
02156
02157
case STATUS_WAIT_TERMINATIONEVENT:
02158
02159
02160
02161
02162
02163 Looping =
FALSE;
02164
break;
02165
02166
case STATUS_WAIT_APPTERMINATIONEVENT:
02167
02168
02169
KeResetEvent(&
ID(AppTerminationEvent));
02170
02171
02172
02173
02174
02175
02176
02177
02178
ID(TableHeader)->ApplicationStop =
TRUE;
02179
SmbTraceToClient(
NULL, 0,
NULL, Component );
02180
02181
break;
02182
02183
case STATUS_WAIT_NEEDMEMORYEVENT:
02184
02185
02186
KeResetEvent(&
ID(NeedMemoryEvent));
02187
02188
02189
02190
02191
02192
02193
SmbTraceFreeMemory( Component );
02194
02195
break;
02196
02197
case STATUS_WAIT_QUEUESEMAPHORE:
02198
02199
02200
02201
02202
02203
02204
02205
if (
ID(TraceState) ==
TraceAppWaiting ) {
02206
SmbTraceEmptyQueue( Component );
02207
break;
02208 }
02209
02210
02211
02212
02213
02214
02215
02216
02217 listEntry =
ExInterlockedRemoveHeadList(
02218 &
ID(Queue),
02219 &
ID(QueueInterlock)
02220 );
02221
02222
if ( listEntry !=
NULL ) {
02223
02224
02225
02226
02227
02228 queueEntry = CONTAINING_RECORD(
02229 listEntry,
02230
SMBTRACE_QUEUE_ENTRY,
02231 ListEntry
02232 );
02233
02234
02235
02236
02237
02238
02239
02240
02241
if ( queueEntry->
BufferNonPaged ) {
02242
02243
02244
02245
02246
02247
ASSERT( Component != SMBTRACE_SERVER );
02248
02249 buffer =
RtlAllocateHeap(
ID(PortMemoryHeap), 0,
02250 queueEntry->
SmbLength );
02251
02252
if ( buffer ==
NULL ) {
02253
02254
LOCK_INC_ID(SmbsLost);
02255
02256
ExFreePool( queueEntry->
Buffer );
02257
ExFreePool( queueEntry );
02258
02259
break;
02260
02261 }
02262
02263 RtlCopyMemory( buffer, queueEntry->
Buffer,
02264 queueEntry->
SmbLength );
02265
02266
ExFreePool( queueEntry->
Buffer );
02267
02268
02269
02270
02271
02272
02273
02274
ASSERT( queueEntry->
SmbAddress ==
NULL );
02275
02276
SmbTraceToClient(
02277 buffer,
02278 queueEntry->
SmbLength,
02279
NULL,
02280 Component
02281 );
02282
02283 }
else {
02284
02285
02286
02287
02288
02289
02290
02291
SmbTraceToClient(
02292 queueEntry->
Buffer,
02293 queueEntry->
SmbLength,
02294 queueEntry->
SmbAddress,
02295 Component
02296 );
02297
02298
if ( queueEntry->
WaitEvent !=
NULL ) {
02299
KeSetEvent( queueEntry->
WaitEvent, 0,
FALSE );
02300 }
02301 }
02302
02303
02304
02305
02306
02307
ExFreePool( queueEntry );
02308
02309 }
02310
02311
break;
02312
02313
default:
02314
break;
02315 }
02316
02317 }
02318
02319
02320
02321
02322
TrPrint((
"%s!SmbTraceThread: Tracing clean up.\n",
ID(ComponentName) ));
02323
02324
SmbTraceDereferenceHeap( Component );
02325
02326
SmbTraceEmptyQueue( Component );
02327
02328
02329
02330
02331
02332
TrPrint((
"%s!SmbTraceThread: Tracing terminated.\n",
ID(ComponentName) ));
02333
02334
KeSetEvent( &
ID(TerminatedEvent), 0,
FALSE );
02335
02336
02337
02338
02339
02340 status =
PsTerminateSystemThread( STATUS_SUCCESS );
02341
02342
02343
TrPrint((
02344
"%s!SmbTraceThreadEntry: PsTerminateSystemThread() failed: %X\n",
02345
ID(ComponentName), status ));
02346
02347 }
02348
02349
02350
02351
#undef NUMBER_OF_BLOCKING_OBJECTS
02352
02353
02354
NTSTATUS
02355 SmbTraceFreeMemory (
02356 IN SMBTRACE_COMPONENT Component
02357 )
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379 {
02380 PVOID buffer;
02381 PSMBTRACE_TABLE_ENTRY tableEntry;
02382 ULONG tableIndex;
02383
02384
PAGED_CODE();
02385
02386
TrPrint((
"%s!SmbTraceFreeMemory: Called for garbage collection.\n",
02387
ID(ComponentName) ));
02388
02389
02390
02391
02392
02393
02394 tableIndex =
ID(TableHeader)->NextFree;
02395
02396
while( tableIndex !=
ID(TableHeader)->HighestConsumed ) {
02397
02398 tableEntry =
ID(Table) + tableIndex;
02399
02400
02401
02402
02403
02404
02405
if ( tableEntry->BufferOffset != 0
L ) {
02406
02407 buffer = (PVOID)( (ULONG_PTR)tableEntry->BufferOffset
02408 + (ULONG_PTR)
ID(PortMemoryBase) );
02409
02410
RtlFreeHeap(
ID(PortMemoryHeap), 0, buffer);
02411
02412 tableEntry->BufferOffset = 0
L;
02413 }
02414
02415
02416 tableIndex = (tableIndex + 1) %
ID(TableSize);
02417 }
02418
02419
return( STATUS_SUCCESS );
02420
02421 }
02422
02423
02424
VOID
02425 SmbTraceToClient(
02426 IN PVOID Smb,
02427 IN CLONG SmbLength,
02428 IN PVOID SmbAddress,
02429 IN SMBTRACE_COMPONENT Component
02430 )
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459 {
02460
NTSTATUS status;
02461 PVOID buffer;
02462 PSMBTRACE_TABLE_ENTRY tableEntry;
02463 ULONG tableIndex;
02464
02465
PAGED_CODE();
02466
02467
02468
02469
02470
02471
if (
ID(SingleSmbMode) ) {
02472
PKEVENT DoneEvent;
02473
02474
TrPrint((
"%s!SmbTraceToClient: Reset DoneSmbEvent, handle %x, process %x.\n",
02475
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
02476
02477 status =
ObReferenceObjectByHandle(
ID(DoneSmbEvent),
02478 EVENT_MODIFY_STATE,
02479
NULL,
02480
KernelMode,
02481 (PVOID *)&DoneEvent,
02482
NULL
02483 );
02484
02485
ASSERT (
NT_SUCCESS(status) );
02486
02487
KeResetEvent(DoneEvent);
02488
02489
ObDereferenceObject(DoneEvent);
02490 }
02491
02492
if (Smb !=
NULL) {
02493
02494
02495
02496
02497
02498
if (
ID(TableHeader)->NextFree ==
ID(TableHeader)->HighestConsumed ) {
02499
02500
LOCK_INC_ID( SmbsLost );
02501
RtlFreeHeap(
ID(PortMemoryHeap), 0, Smb );
02502
return;
02503 }
02504
02505 tableIndex =
ID(TableHeader)->NextFree;
02506
02507 tableEntry =
ID(Table) + tableIndex;
02508
02509
02510
02511
02512
02513
02514 tableEntry->NumberMissed =
ID(SmbsLost);
02515
02516
if ( tableEntry->NumberMissed != 0 ) {
02517
LOCK_ZERO_ID(SmbsLost);
02518 }
02519
02520
02521
02522
02523
02524
if ( tableEntry->BufferOffset != 0
L ) {
02525
02526 buffer = (PVOID)( (ULONG_PTR)tableEntry->BufferOffset
02527 + (ULONG_PTR)
ID(PortMemoryBase) );
02528
02529
RtlFreeHeap(
ID(PortMemoryHeap), 0, buffer);
02530 tableEntry->BufferOffset = 0
L;
02531 }
02532
02533
02534
02535
02536
02537 tableEntry->BufferOffset = (ULONG)((ULONG_PTR)Smb - (ULONG_PTR)
ID(PortMemoryBase));
02538 tableEntry->SmbLength = SmbLength;
02539
02540
02541
02542
02543
02544
02545 tableEntry->SmbAddress = SmbAddress;
02546
02547
02548
02549
02550
02551
ID(TableHeader)->NextFree = (tableIndex + 1) %
ID(TableSize);
02552
02553 }
02554
02555
02556
02557
02558
02559
02560
TrPrint((
"%s!SmbTraceToClient: Set NewSmbEvent.\n",
ID(ComponentName) ));
02561 status = ZwSetEvent(
ID(NewSmbEvent),
NULL );
02562
02563
02564
02565
02566
02567
02568
02569
if ((
ID(SingleSmbMode) ) &&
02570 (
ID(TraceState) ==
TraceRunning )) {
02571
02572
02573
02574
02575
02576
02577
TrPrint((
"%s!SmbTraceToClient: Waiting for DoneSmbEvent, handle %x, process %x.\n",
02578
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
02579 status = ZwWaitForSingleObject(
02580
ID(DoneSmbEvent),
02581
FALSE,
02582
NULL
02583 );
02584
02585
TrPrint((
"%s!SmbTraceToClient: DoneSmbEvent is set, handle %x, process %x.\n",
02586
ID(ComponentName),
ID(DoneSmbEvent),
PsGetCurrentProcess()));
02587
ASSERT(
NT_SUCCESS(status) );
02588
02589
if (Smb !=
NULL) {
02590
02591 tableEntry->BufferOffset = 0
L;
02592
RtlFreeHeap(
ID(PortMemoryHeap), 0, Smb);
02593 }
02594
02595 }
02596
02597
return;
02598
02599 }
02600
02601
02602 ULONG
02603 SmbTraceMdlLength(
02604 IN
PMDL Mdl
02605 )
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623 {
02624 ULONG Bytes = 0;
02625
02626
while (Mdl !=
NULL) {
02627 Bytes +=
MmGetMdlByteCount(Mdl);
02628 Mdl = Mdl->Next;
02629 }
02630
02631
return Bytes;
02632 }
02633
02634
02635
VOID
02636 SmbTraceCopyMdlContiguous(
02637 OUT PVOID Destination,
02638 IN
PMDL Mdl,
02639 IN ULONG Length
02640 )
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665 {
02666 PCHAR Dest = Destination;
02667
02668 UNREFERENCED_PARAMETER(Length);
02669
02670
while (Mdl !=
NULL) {
02671
02672 RtlCopyMemory(
02673 Dest,
02674
MmGetSystemAddressForMdl(Mdl),
02675
MmGetMdlByteCount(Mdl)
02676 );
02677
02678 Dest +=
MmGetMdlByteCount(Mdl);
02679 Mdl = Mdl->Next;
02680 }
02681
02682
ASSERT((ULONG)(Dest - (PCHAR)Destination) == Length);
02683
02684
return;
02685
02686 }
02687