Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

786 lines
22 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. AgntEvnt.c
  5. Abstract:
  6. This module implements the interface by which the csc driver reports
  7. stuff to the agent.
  8. Author:
  9. Joe Linn [JoeLinn] 5-may-1997
  10. Revision History:
  11. Notes:
  12. Additional synchronization surrounds net_start and net_stop. for netstop, we
  13. have to wait for the agent to signal that he is finished before we can proceed.
  14. we probably we should implement a mechanism by which he can refuse the
  15. netstop. anyway this is done by recording the netstop context that is waiting
  16. before signaling the event. the same sort of thing is true for netstart.
  17. --*/
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #pragma code_seg("PAGE")
  21. extern DEBUG_TRACE_CONTROLPOINT RX_DEBUG_TRACE_MRXSMBCSC;
  22. #define Dbg (DEBUG_TRACE_MRXSMBCSC)
  23. // A global variable which indicates the current status of the net
  24. // TRUE implies available. This is used in controlling the
  25. // transitioning indication to the agent
  26. LONG CscNetPresent = FALSE;
  27. LONG CscAgentNotifiedOfNetStatusChange = CSC_AGENT_NOT_NOTIFIED;
  28. LONG CscAgentNotifiedOfFullCache = CSC_AGENT_NOT_NOTIFIED;
  29. PKEVENT MRxSmbAgentSynchronizationEvent = NULL;
  30. ULONG MRxSmbAgentSynchronizationEventIdx = 0;
  31. PKEVENT MRxSmbAgentFillEvent = NULL;
  32. PRX_CONTEXT MRxSmbContextAwaitingAgent = NULL;
  33. PRX_CONTEXT MRxSmbContextAwaitingFillAgent = NULL;
  34. LONG vcntTransportsForCSC=0;
  35. extern ULONG CscSessionIdCausingTransition;
  36. //CODE.IMPROVEMENT.NTIFS had to just know to do this......
  37. extern POBJECT_TYPE *ExEventObjectType;
  38. //CODE.IMPROVEMENT.NTIFS just stole this from oak\in\zwapi.h
  39. NTSYSAPI
  40. NTSTATUS
  41. NTAPI
  42. ZwOpenEvent (
  43. OUT PHANDLE EventHandle,
  44. IN ACCESS_MASK DesiredAccess,
  45. IN POBJECT_ATTRIBUTES ObjectAttributes
  46. );
  47. typedef struct _MRXSMBCSC_OPENEVENT_POSTCONTEXT {
  48. KEVENT PostEvent;
  49. RX_WORK_QUEUE_ITEM WorkQueueItem;
  50. } MRXSMBCSC_OPENEVENT_POSTCONTEXT, *PMRXSMBCSC_OPENEVENT_POSTCONTEXT;
  51. VOID
  52. MRxSmbCscOpenAgentEvent (
  53. BOOLEAN PostedCall);
  54. VOID
  55. MRxSmbCscOpenAgentFillEvent (
  56. BOOLEAN PostedCall);
  57. NTSTATUS
  58. MRxSmbCscOpenAgentEventPostWrapper(
  59. IN OUT PMRXSMBCSC_OPENEVENT_POSTCONTEXT OpenEventPostContext
  60. )
  61. {
  62. RxDbgTrace( 0, Dbg, ("MRxSmbCscOpenAgentEventPostWrapper entry\n"));
  63. MRxSmbCscOpenAgentEvent(TRUE);
  64. RxDbgTrace( 0, Dbg, ("MRxSmbCscOpenAgentEventPostWrapper exit\n"));
  65. KeSetEvent( &OpenEventPostContext->PostEvent, 0, FALSE );
  66. return(STATUS_SUCCESS);
  67. }
  68. NTSTATUS
  69. MRxSmbCscOpenAgentFillEventPostWrapper(
  70. IN OUT PMRXSMBCSC_OPENEVENT_POSTCONTEXT OpenFillEventPostContext
  71. )
  72. {
  73. RxDbgTrace( 0, Dbg, ("MRxSmbCscOpenAgentFillEventPostWrapper entry\n"));
  74. MRxSmbCscOpenAgentFillEvent(TRUE);
  75. RxDbgTrace( 0, Dbg, ("MRxSmbCscOpenAgentFillEventPostWrapper exit\n"));
  76. KeSetEvent( &OpenFillEventPostContext->PostEvent, 0, FALSE );
  77. return(STATUS_SUCCESS);
  78. }
  79. VOID
  80. MRxSmbCscOpenAgentEvent (
  81. BOOLEAN PostedCall
  82. )
  83. /*++
  84. Routine Description:
  85. This routine gets a pointer to the agent's event.
  86. Arguments:
  87. Return Value:
  88. Notes:
  89. The shadowcrit serialization mutex must have already been acquired before the call.
  90. --*/
  91. {
  92. NTSTATUS Status;
  93. HANDLE EventHandle;
  94. UNICODE_STRING EventName;
  95. OBJECT_ATTRIBUTES ObjectAttributes;
  96. WCHAR SessEventName[100];
  97. WCHAR IdBuffer[16];
  98. UNICODE_STRING IdString;
  99. ASSERT (MRxSmbAgentSynchronizationEvent == NULL);
  100. // DbgPrint("MRxSmbCscOpenAgentEvent(%d) Caused by sess 0x%x\n",
  101. // PostedCall,
  102. // CscSessionIdCausingTransition);
  103. if (PsGetCurrentProcess()!= RxGetRDBSSProcess()) {
  104. //CODE.IMPROVEMENT we should capture the rdbss process
  105. // and avoid this call (RxGetRDBSSProcess)
  106. NTSTATUS PostStatus;
  107. MRXSMBCSC_OPENEVENT_POSTCONTEXT PostContext;
  108. ASSERT(!PostedCall);
  109. KeInitializeEvent(&PostContext.PostEvent,
  110. NotificationEvent,
  111. FALSE );
  112. IF_DEBUG {
  113. //fill the workqueue structure with deadbeef....all the better to diagnose
  114. //a failed post
  115. ULONG i;
  116. for (i=0;i+sizeof(ULONG)-1<sizeof(PostContext.WorkQueueItem);i+=sizeof(ULONG)) {
  117. PBYTE BytePtr = ((PBYTE)&PostContext.WorkQueueItem)+i;
  118. PULONG UlongPtr = (PULONG)BytePtr;
  119. *UlongPtr = 0xdeadbeef;
  120. }
  121. }
  122. PostStatus = RxPostToWorkerThread(
  123. MRxSmbDeviceObject,
  124. CriticalWorkQueue,
  125. &PostContext.WorkQueueItem,
  126. MRxSmbCscOpenAgentEventPostWrapper,
  127. &PostContext);
  128. ASSERT(PostStatus == STATUS_SUCCESS);
  129. KeWaitForSingleObject( &PostContext.PostEvent,
  130. Executive, KernelMode, FALSE, NULL );
  131. return;
  132. }
  133. // Build an event name with the session id at the end
  134. wcscpy(SessEventName, SESSION_EVENT_NAME_NT);
  135. wcscat(SessEventName, L"_");
  136. EventName.Buffer = SessEventName;
  137. EventName.Length = wcslen(SessEventName) * sizeof(WCHAR);
  138. EventName.MaximumLength = sizeof(SessEventName);
  139. IdString.Buffer = IdBuffer;
  140. IdString.Length = 0;
  141. IdString.MaximumLength = sizeof(IdBuffer);
  142. RtlIntegerToUnicodeString(CscSessionIdCausingTransition, 10, &IdString);
  143. RtlAppendUnicodeStringToString(&EventName, &IdString);
  144. // DbgPrint("MRxSmbCscOpenAgentEvent: SessEventName = %wZ\n", &EventName);
  145. InitializeObjectAttributes( &ObjectAttributes,
  146. &EventName,
  147. 0,
  148. (HANDLE) NULL,
  149. (PSECURITY_DESCRIPTOR) NULL );
  150. Status = ZwOpenEvent( &EventHandle,
  151. EVENT_ALL_ACCESS,
  152. &ObjectAttributes
  153. );
  154. if (Status!=STATUS_SUCCESS) {
  155. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent no event %08lx\n",Status));
  156. return;
  157. }
  158. Status = ObReferenceObjectByHandle( EventHandle,
  159. 0,
  160. *ExEventObjectType,
  161. KernelMode,
  162. (PVOID *) &MRxSmbAgentSynchronizationEvent,
  163. NULL );
  164. MRxSmbAgentSynchronizationEventIdx = CscSessionIdCausingTransition;
  165. ZwClose(EventHandle);
  166. if (Status!=STATUS_SUCCESS) {
  167. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent couldn't reference %08lx\n", Status));
  168. MRxSmbAgentSynchronizationEvent = NULL;
  169. MRxSmbAgentSynchronizationEventIdx = 0;
  170. return;
  171. }
  172. return;
  173. }
  174. NTSTATUS
  175. MRxSmbCscSignalAgent (
  176. PRX_CONTEXT RxContext OPTIONAL,
  177. ULONG Controls
  178. )
  179. /*++
  180. Routine Description:
  181. This routine signals the csc usermode agent using the appropriate event.
  182. Arguments:
  183. RxContext - the RDBSS context. if this is provided then the context is
  184. as the guy who is waiting.
  185. Return Value:
  186. NTSTATUS - The return status for the operation
  187. Notes:
  188. The shadowcrit serialization mutex must have already been acquired before the call.
  189. We will drop it here.
  190. --*/
  191. {
  192. NTSTATUS Status = STATUS_SUCCESS;
  193. BOOLEAN ShadowCritEntered = TRUE; //must be in critsect on
  194. BOOLEAN PreventLeaveCrit = BooleanFlagOn(Controls,SIGNALAGENTFLAG_DONT_LEAVE_CRIT_SECT);
  195. RxDbgTrace(+1, Dbg, ("MRxSmbCscSignalAgent entry...%08lx\n",RxContext));
  196. DbgDoit(ASSERT(vfInShadowCrit));
  197. ASSERT(MRxSmbIsCscEnabled);
  198. if (!FlagOn(Controls,SIGNALAGENTFLAG_CONTINUE_FOR_NO_AGENT)) {
  199. if (hthreadReint==0) {
  200. //no agent and no force...just get out
  201. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent no agent/noforce %08lx\n", RxContext));
  202. goto FINALLY;
  203. }
  204. }
  205. if (
  206. MRxSmbAgentSynchronizationEvent != NULL
  207. &&
  208. MRxSmbAgentSynchronizationEventIdx != CscSessionIdCausingTransition
  209. ) {
  210. ObDereferenceObject(MRxSmbAgentSynchronizationEvent);
  211. MRxSmbAgentSynchronizationEvent = NULL;
  212. MRxSmbAgentSynchronizationEventIdx = 0;
  213. }
  214. if (MRxSmbAgentSynchronizationEvent == NULL) {
  215. MRxSmbCscOpenAgentEvent(FALSE); //FALSE==>not a posted call
  216. if (MRxSmbAgentSynchronizationEvent == NULL) {
  217. //still NULL...no agent.........
  218. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent no event %08lx %08lx\n",
  219. RxContext,Status));
  220. Status = STATUS_SUCCESS;
  221. goto FINALLY;
  222. }
  223. }
  224. if (RxContext != NULL) {
  225. MRxSmbContextAwaitingAgent = RxContext;
  226. }
  227. if (!PreventLeaveCrit) {
  228. LeaveShadowCrit();
  229. ShadowCritEntered = FALSE;
  230. } else {
  231. ASSERT(RxContext==NULL); //cant wait with critsect held
  232. }
  233. // reduce the window of MRxSmbAgentSynchronizationEvent getting nulled out
  234. // by explictly checking before pulsing
  235. if (MRxSmbAgentSynchronizationEvent)
  236. {
  237. KeSetEvent(MRxSmbAgentSynchronizationEvent,0,FALSE);
  238. }
  239. if (RxContext != NULL) {
  240. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent waiting %08lx\n", RxContext));
  241. RxWaitSync(RxContext);
  242. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent end of wait %08lx\n", RxContext));
  243. }
  244. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent %08lx\n", RxContext));
  245. FINALLY:
  246. if (ShadowCritEntered && !PreventLeaveCrit) {
  247. LeaveShadowCrit();
  248. }
  249. RxDbgTrace(-1, Dbg, ("MRxSmbCscSignalAgent... exit %08lx %08lx\n",
  250. RxContext, Status));
  251. return(Status);
  252. }
  253. VOID
  254. MRxSmbCscSignalNetStatus(
  255. BOOLEAN NetPresent,
  256. BOOLEAN fFirstLast
  257. )
  258. {
  259. if(!MRxSmbIsCscEnabled) {
  260. return;
  261. }
  262. if (NetPresent)
  263. {
  264. InterlockedIncrement(&vcntTransportsForCSC);
  265. }
  266. else
  267. {
  268. if(vcntTransportsForCSC == 0)
  269. {
  270. DbgPrint("CSC:Mismatched transport departure messages from mini redir \n");
  271. return;
  272. }
  273. InterlockedDecrement(&vcntTransportsForCSC);
  274. }
  275. if (!fFirstLast)
  276. {
  277. return;
  278. }
  279. InterlockedExchange(
  280. &CscNetPresent,
  281. NetPresent);
  282. InterlockedExchange(
  283. &CscAgentNotifiedOfNetStatusChange,
  284. CSC_AGENT_NOT_NOTIFIED);
  285. CscNotifyAgentOfNetStatusChangeIfRequired(FALSE);
  286. }
  287. VOID
  288. CscNotifyAgentOfNetStatusChangeIfRequired(
  289. BOOLEAN fInvokeAutoDial
  290. )
  291. {
  292. LONG AgentNotificationState;
  293. AgentNotificationState = InterlockedExchange(
  294. &CscAgentNotifiedOfNetStatusChange,
  295. CSC_AGENT_NOTIFIED);
  296. if (AgentNotificationState == CSC_AGENT_NOT_NOTIFIED) {
  297. EnterShadowCrit(); //this is dropped in the signalagent routine....
  298. if (CscNetPresent) {
  299. SetFlag(sGS.uFlagsEvents,FLAG_GLOBALSTATUS_GOT_NET);
  300. } else {
  301. SetFlag(sGS.uFlagsEvents,FLAG_GLOBALSTATUS_NO_NET);
  302. if (fInvokeAutoDial)
  303. {
  304. SetFlag(sGS.uFlagsEvents,FLAG_GLOBALSTATUS_INVOKE_AUTODIAL);
  305. }
  306. }
  307. MRxSmbCscSignalAgent(
  308. NULL,
  309. SIGNALAGENTFLAG_CONTINUE_FOR_NO_AGENT);
  310. }
  311. }
  312. VOID
  313. CscNotifyAgentOfFullCacheIfRequired(
  314. VOID)
  315. {
  316. // DbgPrint("CscNotifyAgentOfFullCacheIfRequired()\n");
  317. if (MRxSmbAgentSynchronizationEvent == NULL) {
  318. MRxSmbCscOpenAgentEvent(FALSE); //FALSE==>not a posted call
  319. if (MRxSmbAgentSynchronizationEvent == NULL) {
  320. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalAgent no event %08lx %08lx\n"));
  321. // DbgPrint("CscNotifyAgentOfFullCacheIfRequired exit no event\n");
  322. return;
  323. }
  324. }
  325. SetFlag(sGS.uFlagsEvents, FLAG_GLOBALSTATUS_INVOKE_FREESPACE);
  326. if (MRxSmbAgentSynchronizationEvent)
  327. KeSetEvent(MRxSmbAgentSynchronizationEvent,0,FALSE);
  328. // DbgPrint("CscNotifyAgentOfFullCacheIfRequired exit\n");
  329. }
  330. //CODE.IMPROVEMENT.ASHAMED...the next two routines are virtually identical; also there's
  331. // a lot of very similar codein the third
  332. VOID
  333. MRxSmbCscAgentSynchronizationOnStart (
  334. IN OUT PRX_CONTEXT RxContext
  335. )
  336. /*++
  337. Routine Description:
  338. This routine signals the csc usermode agent that a start is occurring.
  339. By passing the context to the signal routine, we indicate that we want
  340. to wait for an external guy (in this case ioctl_register_start) to signal us
  341. tro proceed
  342. Arguments:
  343. RxContext - the RDBSS context.
  344. Return Value:
  345. Notes:
  346. --*/
  347. {
  348. #if 0
  349. NTSTATUS Status;
  350. if(!MRxSmbIsCscEnabled) {
  351. return;
  352. }
  353. RxDbgTrace(+1, Dbg, ("MRxSmbCscAgentSynchronizationOnStart entry...%08lx\n",RxContext));
  354. EnterShadowCrit(); //this is dropped in the signalagent routine....
  355. // check if an agent is already registered
  356. // if he is then we don't need to do any of this stuff
  357. if (!hthreadReint)
  358. {
  359. SetFlag(sGS.uFlagsEvents,FLAG_GLOBALSTATUS_START);
  360. Status = MRxSmbCscSignalAgent(RxContext,
  361. SIGNALAGENTFLAG_CONTINUE_FOR_NO_AGENT);
  362. }
  363. else
  364. {
  365. LeaveShadowCrit();
  366. }
  367. RxDbgTrace(-1, Dbg, ("MRxSmbCscAgentSynchronizationOnStart...%08lx %08lx\n",
  368. RxContext, Status));
  369. #endif
  370. return;
  371. }
  372. VOID
  373. MRxSmbCscAgentSynchronizationOnStop (
  374. IN OUT PRX_CONTEXT RxContext
  375. )
  376. /*++
  377. Routine Description:
  378. This routine signals the csc usermode agent that a stop is occurring.
  379. By passing the context to the signal routine, we indicate that we want
  380. to wait for an external guy (in this case ioctl_register_stop) to signal us
  381. tro proceed
  382. Arguments:
  383. RxContext - the RDBSS context.
  384. Return Value:
  385. Notes:
  386. --*/
  387. {
  388. #if 0
  389. NTSTATUS Status;
  390. if(!MRxSmbIsCscEnabled) {
  391. return;
  392. }
  393. RxDbgTrace(+1, Dbg, ("MRxSmbCscAgentSynchronizationOnStop entry...%08lx\n",RxContext));
  394. EnterShadowCrit(); //this is dropped in the signalagent routine....
  395. if (hthreadReint)
  396. {
  397. SetFlag(sGS.uFlagsEvents,FLAG_GLOBALSTATUS_STOP);
  398. Status = MRxSmbCscSignalAgent(RxContext,0); //0 means no special operations
  399. }
  400. else
  401. {
  402. LeaveShadowCrit();
  403. }
  404. RxDbgTrace(-1, Dbg, ("MRxSmbCscAgentSynchronizationOnStop...%08lx %08lx\n",
  405. RxContext, Status));
  406. #endif
  407. return;
  408. }
  409. VOID
  410. MRxSmbCscReleaseRxContextFromAgentWait (
  411. void
  412. )
  413. /*++
  414. Routine Description:
  415. This routine checks to see if there is a context waiting for the agent. If so,
  416. it signals the context's syncevent. It also clears the specified flags.
  417. Arguments:
  418. RxContext - the RDBSS context.
  419. Return Value:
  420. Notes:
  421. --*/
  422. {
  423. PRX_CONTEXT WaitingContext;
  424. RxDbgTrace(+1, Dbg, ("MRxSmbCscReleaseRxContextFromAgentWait entry...%08lx\n"));
  425. ASSERT(MRxSmbIsCscEnabled);
  426. EnterShadowCrit();
  427. WaitingContext = MRxSmbContextAwaitingAgent;
  428. MRxSmbContextAwaitingAgent = NULL;
  429. LeaveShadowCrit();
  430. if (WaitingContext != NULL) {
  431. RxSignalSynchronousWaiter(WaitingContext);
  432. }
  433. RxDbgTrace(-1, Dbg, ("MRxSmbCscReleaseRxContextFromAgentWait...%08lx\n"));
  434. return;
  435. }
  436. //CODE.IMPROVEMENT get this in an include file
  437. extern ULONG MRxSmbCscNumberOfShadowOpens;
  438. extern ULONG MRxSmbCscActivityThreshold;
  439. VOID
  440. MRxSmbCscReportFileOpens (
  441. void
  442. )
  443. /*++
  444. Routine Description:
  445. This routine checks to see if there has been enough activity to signal
  446. the agent to recompute reference priorities.
  447. Arguments:
  448. Return Value:
  449. Notes:
  450. --*/
  451. {
  452. NTSTATUS Status;
  453. RxDbgTrace(+1, Dbg, ("MRxSmbCscReportFileOpens entry...%08lx %08lx\n",
  454. MRxSmbCscNumberOfShadowOpens,(ULONG)(sGS.cntFileOpen) ));
  455. EnterShadowCrit(); //this is dropped in the signalagent routine....
  456. MRxSmbCscNumberOfShadowOpens++;
  457. if ((MRxSmbCscNumberOfShadowOpens > (ULONG)(sGS.cntFileOpen) ) // to guard against rollover
  458. && ((MRxSmbCscNumberOfShadowOpens - (ULONG)(sGS.cntFileOpen))
  459. < MRxSmbCscActivityThreshold)) {
  460. RxDbgTrace(-1, Dbg, ("MRxSmbCscReportFileOpens inactive...\n"));
  461. LeaveShadowCrit();
  462. return;
  463. }
  464. //SetFlag(sGS.uFlagsEvents,FLAG_GLOBALSTATUS_START);
  465. sGS.cntFileOpen = MRxSmbCscNumberOfShadowOpens;
  466. Status = MRxSmbCscSignalAgent(NULL,0); //this means don't wait for a repsonse
  467. RxDbgTrace(-1, Dbg, ("MRxSmbCscReportFileOpens...activeexit\n"));
  468. return;
  469. }
  470. NTSTATUS
  471. MRxSmbCscSignalFillAgent(
  472. PRX_CONTEXT RxContext OPTIONAL,
  473. ULONG Controls)
  474. {
  475. NTSTATUS Status = STATUS_SUCCESS;
  476. BOOLEAN ShadowCritEntered = TRUE; //must be in critsect on
  477. BOOLEAN PreventLeaveCrit = BooleanFlagOn(Controls,SIGNALAGENTFLAG_DONT_LEAVE_CRIT_SECT);
  478. RxDbgTrace(+1, Dbg, ("MRxSmbCscSignalFillAgent entry...%08lx\n",RxContext));
  479. // DbgPrint("MRxSmbCscSignalFillAgent entry...%08lx\n",RxContext);
  480. ASSERT(MRxSmbIsCscEnabled);
  481. if (!FlagOn(Controls,SIGNALAGENTFLAG_CONTINUE_FOR_NO_AGENT)) {
  482. if (hthreadReint==0) {
  483. //no agent and no force...just get out
  484. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent no agent/noforce %08lx\n", RxContext));
  485. goto FINALLY;
  486. }
  487. }
  488. if (MRxSmbAgentFillEvent == NULL) {
  489. // DbgPrint("MRxSmbCscSignalFillAgent: gotta open the event...\n");
  490. MRxSmbCscOpenAgentFillEvent(FALSE); //FALSE==>not a posted call
  491. if (MRxSmbAgentFillEvent == NULL) {
  492. //still NULL...no agent.........
  493. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent no event %08lx %08lx\n",
  494. RxContext,Status));
  495. // DbgPrint("MRxSmbCscSignalFillAgent no event %08lx %08lx\n");
  496. Status = STATUS_SUCCESS;
  497. goto FINALLY;
  498. }
  499. }
  500. if (RxContext != NULL) {
  501. MRxSmbContextAwaitingFillAgent = RxContext;
  502. }
  503. // if (!PreventLeaveCrit) {
  504. // LeaveShadowCrit();
  505. // ShadowCritEntered = FALSE;
  506. // } else {
  507. // ASSERT(RxContext==NULL); //cant wait with critsect held
  508. // }
  509. // reduce the window of MRxSmbAgentFillEvent getting nulled out
  510. // by explictly checking before pulsing
  511. if (MRxSmbAgentFillEvent) {
  512. KeSetEvent(MRxSmbAgentFillEvent,0,FALSE);
  513. }
  514. if (RxContext != NULL) {
  515. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent waiting %08lx\n", RxContext));
  516. RxWaitSync(RxContext);
  517. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent end of wait %08lx\n", RxContext));
  518. }
  519. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent %08lx\n", RxContext));
  520. FINALLY:
  521. // if (ShadowCritEntered && !PreventLeaveCrit) {
  522. // LeaveShadowCrit();
  523. // }
  524. RxDbgTrace(-1, Dbg, ("MRxSmbCscSignalFillAgent... exit %08lx %08lx\n",
  525. RxContext, Status));
  526. // DbgPrint("MRxSmbCscSignalFillAgent... exit %08lx %08lx\n", Status);
  527. return(Status);
  528. }
  529. VOID
  530. MRxSmbCscOpenAgentFillEvent (
  531. BOOLEAN PostedCall)
  532. {
  533. NTSTATUS Status;
  534. HANDLE EventHandle;
  535. UNICODE_STRING EventName;
  536. OBJECT_ATTRIBUTES ObjectAttributes;
  537. if (PsGetCurrentProcess()!= RxGetRDBSSProcess()) {
  538. //CODE.IMPROVEMENT we should capture the rdbss process
  539. // and avoid this call (RxGetRDBSSProcess)
  540. NTSTATUS PostStatus;
  541. MRXSMBCSC_OPENEVENT_POSTCONTEXT PostContext;
  542. ASSERT(!PostedCall);
  543. // DbgPrint("MRxSmbCscOpenAgentFillEvent: posting...\n");
  544. KeInitializeEvent(&PostContext.PostEvent,
  545. NotificationEvent,
  546. FALSE );
  547. PostStatus = RxPostToWorkerThread(
  548. MRxSmbDeviceObject,
  549. CriticalWorkQueue,
  550. &PostContext.WorkQueueItem,
  551. MRxSmbCscOpenAgentFillEventPostWrapper,
  552. &PostContext);
  553. ASSERT(PostStatus == STATUS_SUCCESS);
  554. KeWaitForSingleObject( &PostContext.PostEvent,
  555. Executive, KernelMode, FALSE, NULL );
  556. // DbgPrint("MRxSmbCscOpenAgentFillEvent: posting done...\n");
  557. return;
  558. }
  559. RtlInitUnicodeString(&EventName,SHARED_FILL_EVENT_NAME_NT);
  560. InitializeObjectAttributes( &ObjectAttributes,
  561. &EventName,
  562. 0,
  563. (HANDLE) NULL,
  564. (PSECURITY_DESCRIPTOR) NULL );
  565. Status = ZwOpenEvent( &EventHandle,
  566. EVENT_ALL_ACCESS,
  567. &ObjectAttributes);
  568. if (Status!=STATUS_SUCCESS) {
  569. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent no event %08lx\n",Status));
  570. DbgPrint("MRxSmbCscSignalFillAgent no event %08lx\n",Status);
  571. return;
  572. }
  573. Status = ObReferenceObjectByHandle( EventHandle,
  574. 0,
  575. *ExEventObjectType,
  576. KernelMode,
  577. (PVOID *) &MRxSmbAgentFillEvent,
  578. NULL );
  579. ZwClose(EventHandle);
  580. if (Status!=STATUS_SUCCESS) {
  581. RxDbgTrace(0, Dbg, ("MRxSmbCscSignalFillAgent couldn't reference %08lx\n", Status));
  582. DbgPrint("MRxSmbCscSignalFillAgent couldn't reference %08lx\n", Status);
  583. MRxSmbAgentFillEvent = NULL;
  584. return;
  585. }
  586. return;
  587. }