📄 ioctl.c
字号:
case IOCTL_SERIAL_GET_TIMEOUTS: {
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_TIMEOUTS)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
*(PSERIAL_TIMEOUTS)irp->AssociatedIrp.SystemBuffer = pdoExt->fakeTimeouts;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_SET_TIMEOUTS: {
if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_TIMEOUTS)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->fakeTimeouts = *(PSERIAL_TIMEOUTS)irp->AssociatedIrp.SystemBuffer;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_SET_DTR: {
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->fakeDTRRTS |= SERIAL_DTR_STATE;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_CLR_DTR: {
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->fakeDTRRTS &= ~SERIAL_DTR_STATE;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_SET_RTS: {
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->fakeDTRRTS |= SERIAL_RTS_STATE;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_CLR_RTS: {
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->fakeDTRRTS &= ~SERIAL_RTS_STATE;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_GET_DTRRTS: {
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
irp->IoStatus.Information = sizeof(ULONG);
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
*(PULONG)irp->AssociatedIrp.SystemBuffer = pdoExt->fakeDTRRTS;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_GET_WAIT_MASK: {
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
irp->IoStatus.Information = sizeof(ULONG);
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
*(PULONG)irp->AssociatedIrp.SystemBuffer = pdoExt->waitMask;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_SET_WAIT_MASK: {
ULONG mask = *(PULONG)irp->AssociatedIrp.SystemBuffer;
if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
if (mask & ~(SERIAL_EV_RXCHAR | SERIAL_EV_RXFLAG | SERIAL_EV_TXEMPTY | SERIAL_EV_CTS
| SERIAL_EV_DSR | SERIAL_EV_RLSD | SERIAL_EV_BREAK | SERIAL_EV_ERR
| SERIAL_EV_RING | SERIAL_EV_PERR | SERIAL_EV_RX80FULL | SERIAL_EV_EVENT1
| SERIAL_EV_EVENT2)) {
status = STATUS_INVALID_PARAMETER;
break;
}
CompletePendingWaitIrps(pdoExt, 0);
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->waitMask = mask;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_WAIT_ON_MASK: {
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
if(pdoExt->currentMask || !pdoExt->waitMask) {
irp->IoStatus.Information = sizeof(ULONG);
irp->IoStatus.Status = STATUS_SUCCESS;
*(PULONG)irp->AssociatedIrp.SystemBuffer = pdoExt->currentMask;
pdoExt->currentMask = 0;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
return status;
}
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
status = EnqueueWaitIrp(pdoExt, irp);
break;
}
case IOCTL_SERIAL_GET_CHARS: {
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_CHARS)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
irp->IoStatus.Information = sizeof(SERIAL_CHARS);
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
*(PSERIAL_CHARS)irp->AssociatedIrp.SystemBuffer = pdoExt->specialChars;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
case IOCTL_SERIAL_SET_CHARS: {
if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_CHARS)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
irp->IoStatus.Status = STATUS_SUCCESS;
KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
pdoExt->specialChars = *(PSERIAL_CHARS)irp->AssociatedIrp.SystemBuffer;
KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
break;
}
default:
DBGVERBOSE(("Ioctl: ??? (%xh)", (ULONG)irpSp->Parameters.DeviceIoControl.IoControlCode));
status = irp->IoStatus.Status;
break;
}
return status;
}
NTSTATUS QueryDeviceName(POSPDOEXT *pdoExt, PIRP irp)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;
HANDLE hRegDevice;
irp->IoStatus.Information = 0;
irpSp = IoGetCurrentIrpStackLocation(irp);
status = IoOpenDeviceRegistryKey(pdoExt->parentFdoExt->physicalDevObj,
PLUGPLAY_REGKEY_DRIVER,
KEY_READ,
&hRegDevice);
if (NT_SUCCESS(status)) {
UNICODE_STRING keyName;
PKEY_VALUE_FULL_INFORMATION keyValueInfo;
ULONG keyValueTotalSize, actualLength;
PWCHAR valueData;
WCHAR deviceKeyName[] = L"DriverDesc";
RtlInitUnicodeString(&keyName, deviceKeyName);
keyValueTotalSize = sizeof(KEY_VALUE_FULL_INFORMATION) + (keyName.Length + MAX_BUFFER)*sizeof(WCHAR);
keyValueInfo = ALLOCPOOL(PagedPool, keyValueTotalSize);
if (keyValueInfo) {
status = ZwQueryValueKey(hRegDevice,
&keyName,
KeyValueFullInformation,
keyValueInfo,
keyValueTotalSize,
&actualLength);
if (NT_SUCCESS(status)) {
ASSERT(keyValueInfo->Type == REG_SZ);
valueData = (PWCHAR)((PCHAR)keyValueInfo + keyValueInfo->DataOffset);
DBGVERBOSE(("Device Name is of Length: %xh.", keyValueInfo->DataLength));
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < keyValueInfo->DataLength)
status = STATUS_BUFFER_TOO_SMALL;
else {
irp->IoStatus.Information = keyValueInfo->DataLength;
wcscpy((PWCHAR)irp->AssociatedIrp.SystemBuffer, valueData);
}
}
else
DBGVERBOSE(("QueryDeviceName: Device Name not found. ZwQueryValueKey failed with %xh.", status));
FREEPOOL(keyValueInfo);
}
else
ASSERT(keyValueInfo);
ZwClose(hRegDevice);
}
else
DBGERR(("QueryDeviceName: IoOpenDeviceRegistryKey failed with %xh.", status));
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -