Beispiel #1
0
NTSTATUS PdoPortBusInfo(
    IN PC0C_PDOPORT_EXTENSION pDevExt,
    IN PIRP                   pIrp)
{
  PPNP_BUS_INFORMATION pBusInfo;

  pBusInfo = (PPNP_BUS_INFORMATION)C0C_ALLOCATE_POOL(PagedPool, sizeof(PNP_BUS_INFORMATION));

  if (!pBusInfo)
    return STATUS_INSUFFICIENT_RESOURCES;

  pBusInfo->BusTypeGuid = GUID_C0C_BUS_TYPE;
  pBusInfo->LegacyBusType = PNPBus;
  pBusInfo->BusNumber = pDevExt->pBusExt->portNum;

  pIrp->IoStatus.Information = (ULONG_PTR)pBusInfo;

  return STATUS_SUCCESS;
}
Beispiel #2
0
NTSTATUS FdoPortOpen(IN PC0C_FDOPORT_EXTENSION pDevExt)
{
  LIST_ENTRY queueToComplete;
  PUCHAR pBase;
  ULONG size;
  KIRQL oldIrql;
  PC0C_IO_PORT pIoPort;

  if (InterlockedIncrement(&pDevExt->openCount) != 1) {
    InterlockedDecrement(&pDevExt->openCount);
    return STATUS_ACCESS_DENIED;
  }

  pIoPort = pDevExt->pIoPortLocal;

  if (pIoPort->plugInMode && !pIoPort->pIoPortRemote->isOpen) {
    InterlockedDecrement(&pDevExt->openCount);
    return STATUS_ACCESS_DENIED;
  }

  if (pIoPort->exclusiveMode)
    IoInvalidateDeviceRelations(pIoPort->pPhDevObj, BusRelations);

  switch (MmQuerySystemSize()) {
  case MmLargeSystem:
    size = 4096;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  case MmMediumSystem:
    size = 1024;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  case MmSmallSystem:
    size = 128;
    pBase = (PUCHAR)C0C_ALLOCATE_POOL(NonPagedPool, size);
    if (pBase)
      break;
  default:
    size = 0;
    pBase = NULL;
  }

  InitializeListHead(&queueToComplete);

#if ENABLE_TRACING
  if (pIoPort->amountInWriteQueue) {
    NTSTATUS status;
    UNICODE_STRING msg;

    status = STATUS_SUCCESS;
    RtlInitUnicodeString(&msg, NULL);
    StrAppendStr0(&status, &msg, L"!!!WARNING!!! amountInWriteQueue = ");
    StrAppendNum(&status, &msg, pIoPort->amountInWriteQueue, 10);

    Trace0((PC0C_COMMON_EXTENSION)pDevExt, msg.Buffer);

    StrFree(&msg);
  }
#endif /* ENABLE_TRACING */

  KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql);

  InitBuffer(&pIoPort->readBuf, pBase, size);

  pIoPort->amountInWriteQueue = 0;
  pIoPort->tryWrite = FALSE;
  pIoPort->errors = 0;
  pIoPort->waitMask = 0;
  pIoPort->eventMask = 0;
  RtlZeroMemory(&pIoPort->perfStats, sizeof(pIoPort->perfStats));
  pIoPort->handFlow.XoffLimit = size >> 3;
  pIoPort->handFlow.XonLimit = size >> 1;
  pIoPort->pIoPortRemote->brokeIdleChars = 0;

  SetHandFlow(pIoPort, NULL, &queueToComplete);
  SetModemControl(pIoPort, C0C_MCR_OPEN, C0C_MCR_OPEN, &queueToComplete);

  if (pIoPort->pIoPortRemote->pWriteDelay && pIoPort->pIoPortRemote->brokeCharsProbability > 0)
    StartWriteDelayTimer(pIoPort->pIoPortRemote->pWriteDelay);

  KeReleaseSpinLock(pIoPort->pIoLock, oldIrql);

  pIoPort->isOpen = TRUE;

  if (pIoPort->pIoPortRemote->plugInMode)
    IoInvalidateDeviceRelations(pIoPort->pIoPortRemote->pPhDevObj, BusRelations);

  FdoPortCompleteQueue(&queueToComplete);

  return STATUS_SUCCESS;
}
Beispiel #3
0
NTSTATUS FdoBusPnp(
    IN PC0C_FDOBUS_EXTENSION pDevExt,
    IN PIRP                  pIrp)
{
  NTSTATUS status;
  PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  ULONG minorFunction = pIrpStack->MinorFunction;
  PDEVICE_OBJECT pLowDevObj = pDevExt->pLowDevObj; // IRP_MN_REMOVE_DEVICE deletes *pDevExt!

  status = STATUS_SUCCESS;

  switch (minorFunction) {
  case IRP_MN_QUERY_DEVICE_RELATIONS:
    if (pIrpStack->Parameters.QueryDeviceRelations.Type == BusRelations) {
      ULONG countPdos, countRelations;
      PDEVICE_RELATIONS pRelationsPrev, pRelations;
      int i;

      countPdos = 0;
      for (i = 0 ; i < 2 ; i++) {
        if (pDevExt->childs[i].pDevExt)
          countPdos++;
      }

      if (!countPdos)
        break;

      pRelationsPrev = (PDEVICE_RELATIONS)pIrp->IoStatus.Information;
      countRelations = pRelationsPrev ? pRelationsPrev->Count : 0;

      pRelations = (PDEVICE_RELATIONS)C0C_ALLOCATE_POOL(PagedPool,
        sizeof(DEVICE_RELATIONS) + ((countPdos + countRelations - 1) * sizeof (PDEVICE_OBJECT)));

      if (!pRelations) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        break;
      }

      if (countRelations)
        RtlCopyMemory(pRelations->Objects, pRelationsPrev->Objects,
                                      countRelations * sizeof (PDEVICE_OBJECT));

      for (i = 0 ; i < 2 ; i++) {
        PC0C_PDOPORT_EXTENSION  pPhDevExt;

        pPhDevExt = pDevExt->childs[i].pDevExt;

        if (pPhDevExt) {
          if (!pDevExt->childs[i].ioPort.pDevExt) {
            UNICODE_STRING portName;
            UNICODE_STRING portRegistryPath;

            RtlInitUnicodeString(&portRegistryPath, NULL);
            StrAppendPortParametersRegistryPath(&status, &portRegistryPath, pPhDevExt->portName);

            RtlInitUnicodeString(&portName, NULL);
            StrAppendParameterPortName(&status, &portName, portRegistryPath.Buffer);

            StrFree(&portRegistryPath);

            if (NT_SUCCESS(status) && portName.Length &&
                _wcsicmp(C0C_PORT_NAME_COMCLASS, portName.Buffer) == 0)
            {
              pDevExt->childs[i].ioPort.isComClass = TRUE;
              Trace0((PC0C_COMMON_EXTENSION)pPhDevExt, L"Port class set to COM");
            } else {
              pDevExt->childs[i].ioPort.isComClass = FALSE;
              Trace0((PC0C_COMMON_EXTENSION)pPhDevExt, L"Port class set to CNC");
            }

            StrFree(&portName);

            status = STATUS_SUCCESS;
          }

          pRelations->Objects[countRelations++] = pPhDevExt->pDevObj;
          ObReferenceObject(pPhDevExt->pDevObj);
        }
      }

      pRelations->Count = countRelations;

      if (pRelationsPrev)
        ExFreePool(pRelationsPrev);

      pIrp->IoStatus.Information = (ULONG_PTR)pRelations;
      pIrp->IoStatus.Status = STATUS_SUCCESS;
    }
    break;
  case IRP_MN_REMOVE_DEVICE:
    RemoveFdoBus(pDevExt);
    pDevExt = NULL;
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    break;
  case IRP_MN_START_DEVICE:
  case IRP_MN_STOP_DEVICE:
  case IRP_MN_QUERY_STOP_DEVICE:
  case IRP_MN_CANCEL_STOP_DEVICE:
  case IRP_MN_QUERY_REMOVE_DEVICE:
  case IRP_MN_CANCEL_REMOVE_DEVICE:
  case IRP_MN_SURPRISE_REMOVAL:
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    break;
  }

  if (status == STATUS_SUCCESS) {
    TraceIrp("FdoBusPnp", pIrp, NULL, TRACE_FLAG_RESULTS);

    IoSkipCurrentIrpStackLocation(pIrp);
    status = IoCallDriver(pLowDevObj, pIrp);

    TraceCode((PC0C_COMMON_EXTENSION)pDevExt, "PNP ", codeNameTablePnp, minorFunction, &status);
  } else {
    TraceIrp("PNP", pIrp, &status, TRACE_FLAG_RESULTS);

    pIrp->IoStatus.Status = status;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  }

  return status;
}
Beispiel #4
0
NTSTATUS PdoPortPnp(
    IN PC0C_PDOPORT_EXTENSION pDevExt,
    IN PIRP                   pIrp)
{
  NTSTATUS status = pIrp->IoStatus.Status;
  PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

  switch (pIrpStack->MinorFunction) {
  case IRP_MN_QUERY_ID:
    status = PdoPortQueryId(pDevExt, pIrp, pIrpStack);
    break;
  case IRP_MN_QUERY_CAPABILITIES:
    status = PdoPortQueryCaps(pDevExt, pIrp, pIrpStack);
    break;
  case IRP_MN_QUERY_DEVICE_TEXT:
    status = PdoPortQueryDevText(pDevExt, pIrp, pIrpStack);
    break;
  case IRP_MN_QUERY_BUS_INFORMATION:
    status = PdoPortBusInfo(pDevExt, pIrp);
    break;
  case IRP_MN_QUERY_DEVICE_RELATIONS:
    switch (pIrpStack->Parameters.QueryDeviceRelations.Type) {
    case TargetDeviceRelation: {
      PDEVICE_RELATIONS pRelations;

      HALT_UNLESS(pIrp->IoStatus.Information == 0);

      if (pIrp->IoStatus.Information != 0)
        break;

      pRelations = (PDEVICE_RELATIONS)C0C_ALLOCATE_POOL(PagedPool, sizeof(DEVICE_RELATIONS));

      if (!pRelations) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        break;
      }

      pRelations->Count = 1;
      pRelations->Objects[0] = pDevExt->pDevObj;
      ObReferenceObject(pDevExt->pDevObj);
      pIrp->IoStatus.Information = (ULONG_PTR)pRelations;
      status = STATUS_SUCCESS;
      break;
    }
    case RemovalRelations:
    case BusRelations:
    case EjectionRelations:
    case PowerRelations:
    default:
      break;
    }
    break;
  case IRP_MN_DEVICE_USAGE_NOTIFICATION:
    status = STATUS_UNSUCCESSFUL;
    break;
  case IRP_MN_REMOVE_DEVICE:
  case IRP_MN_START_DEVICE:
  case IRP_MN_STOP_DEVICE:
  case IRP_MN_QUERY_STOP_DEVICE:
  case IRP_MN_CANCEL_STOP_DEVICE:
  case IRP_MN_QUERY_REMOVE_DEVICE:
  case IRP_MN_CANCEL_REMOVE_DEVICE:
  case IRP_MN_SURPRISE_REMOVAL:
  case IRP_MN_EJECT:
    status = STATUS_SUCCESS;
    break;
  default:
    break;
  }

  TraceIrp("PNP", pIrp, &status, TRACE_FLAG_RESULTS);

  pIrp->IoStatus.Status = status;
  IoCompleteRequest(pIrp, IO_NO_INCREMENT);

  return status;
}