亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? io.c

?? 這個是一個開源項目, 有能力的人可以一起來寫
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*
 * $Id: io.c,v 1.29 2006/11/27 11:58:27 vfrolov Exp $
 *
 * Copyright (c) 2004-2006 Vyacheslav Frolov
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 * $Log: io.c,v $
 * Revision 1.29  2006/11/27 11:58:27  vfrolov
 * Fixed unexpected completing all queued read requests when
 * completing the first one
 *
 * Revision 1.28  2006/06/21 16:23:57  vfrolov
 * Fixed possible BSOD after one port of pair removal
 *
 * Revision 1.27  2006/05/17 15:31:14  vfrolov
 * Implemented SERIAL_TRANSMIT_TOGGLE
 *
 * Revision 1.26  2006/02/26 08:39:19  vfrolov
 * Added check for start/stop queue matching
 * Fixed delayed BREAK losts
 *
 * Revision 1.25  2006/02/21 13:42:11  vfrolov
 * Implemented SERIAL_BREAK_CHAR
 *
 * Revision 1.24  2006/02/17 07:55:13  vfrolov
 * Implemented IOCTL_SERIAL_SET_BREAK_ON and IOCTL_SERIAL_SET_BREAK_OFF
 *
 * Revision 1.23  2006/01/10 10:17:23  vfrolov
 * Implemented flow control and handshaking
 * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF
 * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue
 *   fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS
 *
 * Revision 1.22  2005/12/06 13:04:32  vfrolov
 * Fixed data types
 *
 * Revision 1.21  2005/12/05 10:54:55  vfrolov
 * Implemented IOCTL_SERIAL_IMMEDIATE_CHAR
 *
 * Revision 1.20  2005/11/30 16:04:11  vfrolov
 * Implemented IOCTL_SERIAL_GET_STATS and IOCTL_SERIAL_CLEAR_STATS
 *
 * Revision 1.19  2005/11/29 12:33:21  vfrolov
 * Changed SetModemStatus() to ability set and clear bits simultaneously
 *
 * Revision 1.18  2005/11/29 08:35:13  vfrolov
 * Implemented SERIAL_EV_RX80FULL
 *
 * Revision 1.17  2005/11/25 08:59:39  vfrolov
 * Implemented SERIAL_EV_RXFLAG
 *
 * Revision 1.16  2005/09/14 13:14:47  vfrolov
 * Fixed possible tick loss
 *
 * Revision 1.15  2005/09/14 10:42:38  vfrolov
 * Implemented SERIAL_EV_TXEMPTY
 *
 * Revision 1.14  2005/09/13 14:56:16  vfrolov
 * Implemented IRP_MJ_FLUSH_BUFFERS
 *
 * Revision 1.13  2005/09/13 08:55:41  vfrolov
 * Disabled modem status tracing by default
 *
 * Revision 1.12  2005/09/06 07:23:44  vfrolov
 * Implemented overrun emulation
 *
 * Revision 1.11  2005/08/26 08:35:05  vfrolov
 * Fixed unwanted interference to baudrate emulation by read operations
 *
 * Revision 1.10  2005/08/25 15:38:17  vfrolov
 * Some code moved from io.c to bufutils.c
 *
 * Revision 1.9  2005/08/25 08:25:40  vfrolov
 * Fixed data types
 *
 * Revision 1.8  2005/08/23 15:49:21  vfrolov
 * Implemented baudrate emulation
 *
 * Revision 1.7  2005/07/14 12:24:31  vfrolov
 * Replaced ASSERT by HALT_UNLESS
 *
 * Revision 1.6  2005/05/19 08:23:41  vfrolov
 * Fixed data types
 *
 * Revision 1.5  2005/05/14 17:07:02  vfrolov
 * Implemented SERIAL_LSRMST_MST insertion
 *
 * Revision 1.4  2005/05/13 16:58:03  vfrolov
 * Implemented IOCTL_SERIAL_LSRMST_INSERT
 *
 * Revision 1.3  2005/05/13 06:32:16  vfrolov
 * Implemented SERIAL_EV_RXCHAR
 *
 * Revision 1.2  2005/02/01 08:36:27  vfrolov
 * Changed SetModemStatus() to set multiple bits and set CD to DSR
 *
 * Revision 1.1  2005/01/26 12:18:54  vfrolov
 * Initial revision
 *
 */

#include "precomp.h"
#include "timeout.h"
#include "delay.h"
#include "bufutils.h"
#include "handflow.h"

/*
 * FILE_ID used by HALT_UNLESS to put it on BSOD
 */
#define FILE_ID 1

#define GET_REST_BUFFER(pIrp, done) \
    (((PUCHAR)(pIrp)->AssociatedIrp.SystemBuffer) + done)

typedef struct _RW_DATA {

  #define RW_DATA_TYPE_IRP   1
  #define RW_DATA_TYPE_CHR   2

  short type;

  union {
    struct {
      PIRP pIrp;
      NTSTATUS status;
    } irp;
    struct {
      UCHAR chr;

      #define RW_DATA_TYPE_CHR_NONE   0
      #define RW_DATA_TYPE_CHR_XCHR   1
      #define RW_DATA_TYPE_CHR_BREAK  2

      short type;

      BOOLEAN isChr;
    } chr;
  } data;
} RW_DATA, *PRW_DATA;

#define CAN_WRITE_RW_DATA_CHR(pIoPort, dataChar) \
  ( \
    ((dataChar).data.chr.type == RW_DATA_TYPE_CHR_XCHR && \
          ((pIoPort)->writeHolding & ~SERIAL_TX_WAITING_FOR_XON) == 0) || \
    ((dataChar).data.chr.type == RW_DATA_TYPE_CHR_BREAK) \
  ) \

ULONG GetWriteLength(IN PIRP pIrp)
{
  PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

  switch(pIrpStack->MajorFunction) {
  case IRP_MJ_WRITE:
    return pIrpStack->Parameters.Write.Length;
  case IRP_MJ_DEVICE_CONTROL:
    if (pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR)
      return sizeof(UCHAR);
    break;
  }
  return 0;
}

NTSTATUS ReadBuffer(PIRP pIrp, PC0C_BUFFER pBuf, PSIZE_T pReadDone)
{
  NTSTATUS status;
  SIZE_T readLength, information;
  SIZE_T readDone;

  readLength = IoGetCurrentIrpStackLocation(pIrp)->Parameters.Read.Length;
  information = pIrp->IoStatus.Information;

  readDone =  ReadFromBuffer(pBuf, GET_REST_BUFFER(pIrp, information), readLength - information);

  if (readDone) {
    *pReadDone += readDone;
    information += readDone;
    pIrp->IoStatus.Information = information;
  }


  if (information == readLength)
    status = STATUS_SUCCESS;
  else
    status = STATUS_PENDING;

  return status;
}

VOID OnRxBreak(
    PC0C_IO_PORT pReadIoPort,
    PLIST_ENTRY pQueueToComplete)
{
  pReadIoPort->errors |= SERIAL_ERROR_BREAK;
  pReadIoPort->eventMask |= pReadIoPort->waitMask & (SERIAL_EV_BREAK | SERIAL_EV_ERR);

  if (pReadIoPort->eventMask)
    WaitComplete(pReadIoPort, pQueueToComplete);
}

VOID OnRxChars(
    PC0C_IO_PORT pReadIoPort,
    SIZE_T size,
    PC0C_FLOW_FILTER pFlowFilter,
    PLIST_ENTRY pQueueToComplete)
{
  SetXonXoffHolding(pReadIoPort, pFlowFilter->lastXonXoff);

  if (pFlowFilter->events & (C0C_FLOW_FILTER_EV_RXCHAR | C0C_FLOW_FILTER_EV_RXFLAG)) {
    if (pFlowFilter->events & C0C_FLOW_FILTER_EV_RXCHAR)
      pReadIoPort->eventMask |= SERIAL_EV_RXCHAR;

    if (pFlowFilter->events & C0C_FLOW_FILTER_EV_RXFLAG)
      pReadIoPort->eventMask |= SERIAL_EV_RXFLAG;

    if (pReadIoPort->eventMask)
      WaitComplete(pReadIoPort, pQueueToComplete);
  }

  pReadIoPort->perfStats.ReceivedCount += (ULONG)size;
}

VOID WriteBuffer(
    PRW_DATA pDataWrite,
    PC0C_IO_PORT pReadIoPort,
    PLIST_ENTRY pQueueToComplete,
    PSIZE_T pWriteLimit,
    PSIZE_T pWriteDone)
{
  SIZE_T writeLength, information;
  SIZE_T writeDone;
  C0C_FLOW_FILTER flowFilter;
  PVOID pWriteBuf;
  PC0C_BUFFER pBuf;
  SIZE_T length;
  BOOLEAN isBreak;

  isBreak = FALSE;

  if (pDataWrite->type == RW_DATA_TYPE_IRP) {
    PIRP pIrp = pDataWrite->data.irp.pIrp;

    information = pIrp->IoStatus.Information;
    pWriteBuf = GET_REST_BUFFER(pIrp, information);
    writeLength = GetWriteLength(pIrp);
  } else {
    HALT_UNLESS1(pDataWrite->type == RW_DATA_TYPE_CHR, pDataWrite->type);

    information = 0;
    pWriteBuf = &pDataWrite->data.chr.chr;
    writeLength = pDataWrite->data.chr.isChr ? 1 : 0;
    if (pDataWrite->data.chr.type == RW_DATA_TYPE_CHR_BREAK)
      isBreak = TRUE;
  }

  pBuf = &pReadIoPort->readBuf;
  length = writeLength - information;

  if (pWriteLimit && length > *pWriteLimit)
    length = *pWriteLimit;

  FlowFilterInit(pReadIoPort, &flowFilter);

  writeDone = WriteToBuffer(pBuf, pWriteBuf, length, &flowFilter);

  if (writeDone) {
    *pWriteDone += writeDone;
    information += writeDone;

    if (pDataWrite->type == RW_DATA_TYPE_IRP) {
      pDataWrite->data.irp.pIrp->IoStatus.Information = information;
      pReadIoPort->pIoPortRemote->amountInWriteQueue -= (ULONG)writeDone;
    }

    if (pWriteLimit)
      *pWriteLimit -= writeDone;

    OnRxChars(pReadIoPort, writeDone, &flowFilter, pQueueToComplete);
    if (isBreak)
      OnRxBreak(pReadIoPort, pQueueToComplete);
    else
      pReadIoPort->pIoPortRemote->perfStats.TransmittedCount += (ULONG)writeDone;
  }

  if (information == writeLength) {
    if (pDataWrite->type == RW_DATA_TYPE_IRP) {
      pDataWrite->data.irp.status = STATUS_SUCCESS;
    } else {
      HALT_UNLESS1(pDataWrite->type == RW_DATA_TYPE_CHR, pDataWrite->type);

      pDataWrite->data.chr.isChr = FALSE;
    }
  }
}

VOID AlertOverrun(PC0C_IO_PORT pReadIoPort, PLIST_ENTRY pQueueToComplete)
{
  pReadIoPort->errors |= SERIAL_ERROR_QUEUEOVERRUN;

  if (pReadIoPort->handFlow.FlowReplace & SERIAL_ERROR_CHAR)
    WriteMandatoryToBuffer(&pReadIoPort->readBuf, pReadIoPort->specialChars.ErrorChar);

  if (pReadIoPort->handFlow.ControlHandShake & SERIAL_ERROR_ABORT) {
    CancelQueue(&pReadIoPort->irpQueues[C0C_QUEUE_READ], pQueueToComplete);
    CancelQueue(&pReadIoPort->irpQueues[C0C_QUEUE_WRITE], pQueueToComplete);
  }
}

VOID WriteOverrun(
    PRW_DATA pDataWrite,
    PC0C_IO_PORT pReadIoPort,
    PLIST_ENTRY pQueueToComplete,
    PSIZE_T pWriteLimit,
    PSIZE_T pWriteDone)
{
  SIZE_T writeLength, information;
  SIZE_T writeDone, readDone;
  C0C_FLOW_FILTER flowFilter;
  PVOID pWriteBuf;
  SIZE_T length;
  BOOLEAN isBreak;

  isBreak = FALSE;

  if (pDataWrite->type == RW_DATA_TYPE_IRP) {
    PIRP pIrp = pDataWrite->data.irp.pIrp;

    information = pIrp->IoStatus.Information;
    pWriteBuf = GET_REST_BUFFER(pIrp, information);
    writeLength = GetWriteLength(pIrp);
  } else {
    HALT_UNLESS1(pDataWrite->type == RW_DATA_TYPE_CHR, pDataWrite->type);

    information = 0;
    pWriteBuf = &pDataWrite->data.chr.chr;
    writeLength = pDataWrite->data.chr.isChr ? 1 : 0;
    if (pDataWrite->data.chr.type == RW_DATA_TYPE_CHR_BREAK)
      isBreak = TRUE;
  }

  length = writeLength - information;

  if (pWriteLimit && length > *pWriteLimit)
    length = *pWriteLimit;

  FlowFilterInit(pReadIoPort, &flowFilter);

  CopyCharsWithEscape(
      &pReadIoPort->readBuf, &flowFilter,
      NULL, 0,
      pWriteBuf, length,
      &readDone, &writeDone);

  if (writeDone) {
    *pWriteDone += writeDone;
    information += writeDone;

    if (pDataWrite->type == RW_DATA_TYPE_IRP) {
      pDataWrite->data.irp.pIrp->IoStatus.Information = information;
      pReadIoPort->pIoPortRemote->amountInWriteQueue -= (ULONG)writeDone;
    }

    if (pWriteLimit)
      *pWriteLimit -= writeDone;

    if (readDone) {
      AlertOverrun(pReadIoPort, pQueueToComplete);
      pReadIoPort->perfStats.BufferOverrunErrorCount += (ULONG)readDone;
    }

    OnRxChars(pReadIoPort, writeDone, &flowFilter, pQueueToComplete);
    if (isBreak)
      OnRxBreak(pReadIoPort, pQueueToComplete);
    else
      pReadIoPort->pIoPortRemote->perfStats.TransmittedCount += (ULONG)writeDone;
  }

  if (information == writeLength) {
    if (pDataWrite->type == RW_DATA_TYPE_IRP) {
      pDataWrite->data.irp.status = STATUS_SUCCESS;
    } else {
      HALT_UNLESS1(pDataWrite->type == RW_DATA_TYPE_CHR, pDataWrite->type);

      pDataWrite->data.chr.isChr = FALSE;
    }
  }
}

VOID ReadWriteDirect(
    PIRP pIrpRead,
    PRW_DATA pDataWrite,

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
不卡高清视频专区| 午夜不卡av免费| 欧美区一区二区三区| 亚洲国产成人tv| 日韩欧美一区中文| 欧美自拍偷拍一区| 99久久精品国产一区二区三区 | 欧美激情一区二区三区不卡| www久久精品| 欧日韩精品视频| 成人app软件下载大全免费| 久久99国产精品麻豆| 日日夜夜免费精品视频| 性做久久久久久久久| 亚洲精品免费看| 亚洲激情五月婷婷| 一区二区三区国产精华| 亚洲欧美在线视频观看| 2021中文字幕一区亚洲| 日韩视频一区二区在线观看| 欧美精品18+| 91.成人天堂一区| 欧美少妇bbb| 欧美日韩国产另类一区| 欧美三级电影网站| 欧美色综合天天久久综合精品| 国产成人日日夜夜| 国产91清纯白嫩初高中在线观看| 国产精品一区二区在线播放 | 91精品国产综合久久精品| 欧美性大战久久久久久久蜜臀| 91久久精品一区二区| 欧美色网站导航| 91精品国产美女浴室洗澡无遮挡| 91精品国产91久久综合桃花| 日韩亚洲国产中文字幕欧美| 欧美大尺度电影在线| 欧美精品一区视频| 日本一区二区三区视频视频| 国产精品国产三级国产普通话三级 | 欧美亚洲国产怡红院影院| 欧美专区在线观看一区| 91精品免费在线观看| 精品欧美一区二区三区精品久久| 久久久不卡影院| 国产精品国产自产拍高清av| 亚洲午夜精品一区二区三区他趣| 视频一区二区三区在线| 国产一区二区看久久| 91麻豆国产在线观看| 91精品啪在线观看国产60岁| 欧美激情一区二区在线| 亚洲成人av免费| 国模一区二区三区白浆| 色婷婷亚洲婷婷| 欧美成人a在线| 亚洲欧美视频在线观看| 美女诱惑一区二区| 欧美情侣在线播放| 中文字幕欧美区| 亚洲影视在线观看| 日本美女一区二区| 92国产精品观看| 亚洲精品在线观看视频| 亚洲欧美视频一区| 国产精品亚洲人在线观看| 欧美亚洲一区二区在线观看| 中文字幕不卡的av| 蜜臀精品久久久久久蜜臀 | 久久综合精品国产一区二区三区 | 国产曰批免费观看久久久| 色综合久久中文综合久久牛| 日韩一区二区在线看| 亚洲午夜私人影院| 99久久夜色精品国产网站| 欧美刺激脚交jootjob| 亚洲一区成人在线| 一本一道久久a久久精品| 日韩一区二区三区四区| 亚洲最快最全在线视频| 不卡一二三区首页| 久久久久久电影| 狠狠狠色丁香婷婷综合激情| 欧美日韩性生活| 美洲天堂一区二卡三卡四卡视频 | 美腿丝袜一区二区三区| 欧美日韩精品福利| 一区二区三区波多野结衣在线观看 | 精品国产成人系列| 久久av中文字幕片| 日韩精品中文字幕一区| 男女激情视频一区| 欧美久久久久久蜜桃| 一区二区三国产精华液| 97精品国产露脸对白| 亚洲欧美日韩一区| 成人性色生活片免费看爆迷你毛片| 日韩欧美美女一区二区三区| 裸体在线国模精品偷拍| 26uuu另类欧美亚洲曰本| 黄色日韩网站视频| www精品美女久久久tv| 麻豆国产欧美日韩综合精品二区| 91精品国产免费| 国产在线播放一区二区三区 | 国产成人综合自拍| 国产亚洲欧美中文| 不卡欧美aaaaa| 亚洲免费在线观看| 欧美日韩一区二区三区不卡| 青青草精品视频| 亚洲国产成人私人影院tom| www.av亚洲| 亚洲男人天堂一区| 这里是久久伊人| 韩国理伦片一区二区三区在线播放 | 欧美一区二区不卡视频| 日日摸夜夜添夜夜添亚洲女人| 成人午夜激情在线| 亚洲图片自拍偷拍| 日韩久久免费av| 成人三级伦理片| 曰韩精品一区二区| 欧美综合一区二区三区| 裸体歌舞表演一区二区| 国产日韩欧美精品一区| 91麻豆精品秘密| 久久精品国产亚洲一区二区三区| 亚洲成人777| 国产视频在线观看一区二区三区| 欧美日韩精品三区| 欧美主播一区二区三区美女| 国产·精品毛片| 国产原创一区二区| 免费久久99精品国产| 亚洲一区二区在线视频| 亚洲欧美另类久久久精品| 久久久久久99精品| 欧美精品一区二区三区在线播放| 欧美日本在线看| 在线视频你懂得一区| 97se亚洲国产综合在线| bt欧美亚洲午夜电影天堂| 国产成人亚洲综合a∨婷婷| 日韩**一区毛片| 免费精品视频在线| 麻豆精品精品国产自在97香蕉| 日本不卡的三区四区五区| 三级成人在线视频| 日本不卡中文字幕| 男人的j进女人的j一区| 另类小说视频一区二区| 老司机精品视频在线| 久久99这里只有精品| 麻豆91精品视频| 国产福利一区在线观看| 国产 日韩 欧美大片| 成人黄页在线观看| 日本高清成人免费播放| 欧美性xxxxx极品少妇| 欧美久久婷婷综合色| 日韩欧美国产一区二区三区| 精品第一国产综合精品aⅴ| 精品国产人成亚洲区| 欧美精彩视频一区二区三区| 欧美国产综合一区二区| 亚洲黄色性网站| 男女男精品网站| 成人午夜免费电影| 欧美色偷偷大香| 精品伦理精品一区| 国产精品日韩精品欧美在线| 亚洲精品一二三| 青青草成人在线观看| 国产精品91一区二区| 一本久久a久久精品亚洲| 欧美日韩中文另类| 日韩精品中文字幕一区| 亚洲欧洲韩国日本视频| 亚洲成人av一区| 国v精品久久久网| 欧美日韩电影在线| 国产午夜精品一区二区三区视频| 中文字幕一区二区三区视频| 亚洲无人区一区| 国产成人久久精品77777最新版本| k8久久久一区二区三区| 欧美一区二区三区免费视频| 国产精品久久久久久一区二区三区 | 国产欧美日韩在线| 亚洲国产精品久久久男人的天堂 | 蜜桃精品视频在线| av一区二区三区| 日韩免费一区二区| 亚洲精品视频观看| 国产高清视频一区| 欧美一卡2卡3卡4卡| 亚洲精品免费一二三区| 国产精品亚洲人在线观看| 欧美一区二区免费视频|