NTSTATUS PdoPortQueryDevText( IN PC0C_PDOPORT_EXTENSION pDevExt, IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack) { NTSTATUS status; status = STATUS_SUCCESS; switch (pIrpStack->Parameters.QueryDeviceText.DeviceTextType) { case DeviceTextDescription: if (!pIrp->IoStatus.Information) { UNICODE_STRING portText; RtlInitUnicodeString(&portText, NULL); StrAppendStr0(&status, &portText, L"com0com - serial port emulator"); if (NT_SUCCESS(status)) pIrp->IoStatus.Information = (ULONG_PTR)portText.Buffer; } break; case DeviceTextLocationInformation: if (!pIrp->IoStatus.Information) { UNICODE_STRING portText; RtlInitUnicodeString(&portText, NULL); StrAppendStr0(&status, &portText, pDevExt->portName); if (NT_SUCCESS(status)) pIrp->IoStatus.Information = (ULONG_PTR)portText.Buffer; } break; default: status = pIrp->IoStatus.Status; } return status; }
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; }