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.

194 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. chkcomm.c
  5. Abstract:
  6. Author:
  7. Thomas J. Dimitri (TommyD) 08-May-1992
  8. Environment:
  9. Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
  10. Revision History:
  11. --*/
  12. #if DBG
  13. #define __FILE_SIG__ 'ckhC'
  14. #endif
  15. #include "asyncall.h"
  16. NTSTATUS
  17. AsyncCheckCommStatusCompletionRoutine(
  18. IN PDEVICE_OBJECT DeviceObject,
  19. IN PIRP Irp,
  20. IN PVOID Context)
  21. /*++
  22. --*/
  23. {
  24. NTSTATUS status;
  25. PSERIAL_STATUS pSerialStatus;
  26. PASYNC_IO_CTX AsyncIoCtx = (PASYNC_IO_CTX)Context;
  27. PASYNC_INFO pInfo=AsyncIoCtx->Context;
  28. DeviceObject; // prevent compiler warnings
  29. status = Irp->IoStatus.Status;
  30. pSerialStatus=(PSERIAL_STATUS)(Irp->AssociatedIrp.SystemBuffer);
  31. DbgTracef(0,("ACCSCR: s=$%x\n",status));
  32. switch (status) {
  33. case STATUS_SUCCESS:
  34. if (pSerialStatus->Errors & SERIAL_ERROR_FRAMING) {
  35. DbgTracef(-1,("ACCSCR: Framing error\n"));
  36. pInfo->SerialStats.FramingErrors++;
  37. }
  38. if (pSerialStatus->Errors & SERIAL_ERROR_OVERRUN) {
  39. DbgTracef(-1,("ACCSCR: Overrun error \n"));
  40. pInfo->SerialStats.SerialOverrunErrors++;
  41. }
  42. if (pSerialStatus->Errors & SERIAL_ERROR_QUEUEOVERRUN) {
  43. DbgTracef(-1,("ACCSCR: Q-Overrun error\n"));
  44. pInfo->SerialStats.BufferOverrunErrors++;
  45. }
  46. //
  47. // Keep proper count of errors
  48. //
  49. AsyncIndicateFragment(
  50. pInfo,
  51. pSerialStatus->Errors);
  52. // Fall through...
  53. default:
  54. //
  55. // Free up memory we used to make this call
  56. //
  57. IoFreeIrp(Irp);
  58. AsyncFreeIoCtx(AsyncIoCtx);
  59. }
  60. //
  61. // Deref the ref applied in AsyncCheckCommStatus
  62. //
  63. pInfo->Flags &= ~(ASYNC_FLAG_CHECK_COMM_STATUS);
  64. DEREF_ASYNCINFO(pInfo, Irp);
  65. //
  66. // We return STATUS_MORE_PROCESSING_REQUIRED so that the
  67. // IoCompletionRoutine will stop working on the IRP.
  68. //
  69. return(STATUS_MORE_PROCESSING_REQUIRED);
  70. }
  71. VOID
  72. AsyncCheckCommStatus(
  73. IN PASYNC_INFO pInfo)
  74. /*++
  75. This is the Worker Thread entry for reading comm status errors
  76. --*/
  77. {
  78. PIRP irp;
  79. PIO_STACK_LOCATION irpSp;
  80. PDEVICE_OBJECT deviceObject=pInfo->DeviceObject;
  81. PFILE_OBJECT fileObject=pInfo->FileObject;
  82. PASYNC_IO_CTX AsyncIoCtx;
  83. NTSTATUS status;
  84. irp=IoAllocateIrp(deviceObject->StackSize, (BOOLEAN)FALSE);
  85. //
  86. // Are we out of irps? Oh no!
  87. //
  88. if (irp==NULL) {
  89. return;
  90. }
  91. AsyncIoCtx = AsyncAllocateIoCtx(FALSE, pInfo);
  92. if (AsyncIoCtx == NULL) {
  93. IoFreeIrp(irp);
  94. return;
  95. }
  96. //
  97. // Set the file object to the Not-Signaled state.
  98. //
  99. irp->Tail.Overlay.OriginalFileObject = fileObject;
  100. irp->RequestorMode = KernelMode;
  101. irp->PendingReturned = FALSE;
  102. //
  103. // Fill in the service independent parameters in the IRP.
  104. //
  105. irp->UserEvent = NULL;
  106. irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
  107. irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
  108. irp->Flags = IRP_BUFFERED_IO;
  109. irp->AssociatedIrp.SystemBuffer=&AsyncIoCtx->SerialStatus;
  110. irpSp = IoGetNextIrpStackLocation(irp);
  111. irpSp->FileObject = fileObject;
  112. if (fileObject->Flags & FO_WRITE_THROUGH) {
  113. irpSp->Flags = SL_WRITE_THROUGH;
  114. }
  115. irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  116. irpSp->Parameters.DeviceIoControl.IoControlCode=IOCTL_SERIAL_GET_COMMSTATUS;
  117. irpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
  118. irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(SERIAL_STATUS);
  119. IoSetCompletionRoutine(
  120. irp, // irp to use
  121. AsyncCheckCommStatusCompletionRoutine, // routine to call when irp is done
  122. AsyncIoCtx, // context to pass routine
  123. TRUE, // call on success
  124. TRUE, // call on error
  125. TRUE); // call on cancel
  126. pInfo->Flags |= ASYNC_FLAG_CHECK_COMM_STATUS;
  127. //
  128. // Reference the asyncinfo block so that its still around when
  129. // the completion routine is called
  130. //
  131. REF_ASYNCINFO(pInfo, irp);
  132. //
  133. // Now simply invoke the driver at its dispatch entry with the IRP.
  134. //
  135. status = IoCallDriver(deviceObject, irp);
  136. DbgTracef(0,("ACCS: IoctlGetCommStatus returned with 0x%.8x\n", status));
  137. }