Source code of Windows XP (NT5)
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.

91 lines
2.2 KiB

  1. #include "pch.h"
  2. NTSTATUS
  3. PptPdoClose(
  4. IN PDEVICE_OBJECT Pdo,
  5. IN PIRP Irp
  6. )
  7. /*++
  8. Routine Description:
  9. This routine is the dispatch for a close requests.
  10. Arguments:
  11. DeviceObject - Supplies the device object.
  12. Irp - Supplies the I/O request packet.
  13. Return Value:
  14. STATUS_SUCCESS - Success.
  15. --*/
  16. {
  17. PPDO_EXTENSION pdx = Pdo->DeviceExtension;
  18. BOOLEAN haveShadowBuffer;
  19. PVOID threadObject;
  20. DD((PCE)pdx,DDT,"PptPdoClose\n");
  21. // immediately stop signalling any dot4 event
  22. pdx->P12843DL.bEventActive = FALSE;
  23. //
  24. // Protect against two threads calling us concurrently
  25. //
  26. ExAcquireFastMutex( &pdx->OpenCloseMutex );
  27. haveShadowBuffer = pdx->bShadowBuffer;
  28. pdx->bShadowBuffer = FALSE;
  29. threadObject = pdx->ThreadObjectPointer;
  30. pdx->ThreadObjectPointer = NULL;
  31. ExReleaseFastMutex( &pdx->OpenCloseMutex );
  32. //
  33. // clean up Bounded ECP shadow buffer
  34. //
  35. if( haveShadowBuffer ) {
  36. Queue_Delete( &(pdx->ShadowBuffer) );
  37. }
  38. //
  39. // if we still have a worker thread, kill it
  40. //
  41. if( threadObject ) {
  42. // set the flag for the worker thread to kill itself
  43. pdx->TimeToTerminateThread = TRUE;
  44. // wake up the thread so it can kill itself
  45. KeReleaseSemaphore( &pdx->RequestSemaphore, 0, 1, FALSE );
  46. // allow thread to get past PauseEvent so it can kill self
  47. KeSetEvent( &pdx->PauseEvent, 0, TRUE );
  48. // wait for the thread to die
  49. KeWaitForSingleObject( threadObject, UserRequest, KernelMode, FALSE, NULL );
  50. // allow the system to release the thread object
  51. ObDereferenceObject( threadObject );
  52. }
  53. //
  54. // update open handle count
  55. //
  56. {
  57. ExAcquireFastMutex( &pdx->OpenCloseMutex );
  58. InterlockedDecrement( &pdx->OpenCloseRefCount );
  59. if( pdx->OpenCloseRefCount < 0) {
  60. // catch possible underflow
  61. pdx->OpenCloseRefCount = 0;
  62. }
  63. ExReleaseFastMutex(&pdx->OpenCloseMutex);
  64. }
  65. return P4CompleteRequest( Irp, STATUS_SUCCESS, 0 );
  66. }