int get_next_line(int const fd, char ** line) { int ret_read; char *buff; static char *rest = NULL; int ifretline; ret_read = 0; ifretline = 0; if ((buff = (char*)malloc(512)) == NULL || (*line = ft_memalloc(1)) == NULL) return (-1); if (!rest) rest = ft_memalloc(1); if (*rest != '\0' && ft_strchr(rest, '\n')) { manager_buffer(&buff, &rest, line, &ifretline); return (1); } while (ifretline == 0 && (ret_read = read(fd, buff, 512))) { buff[ret_read] = '\0'; manager_read(&buff, &rest, line, &ifretline); } if (buff[0] == '\0' && rest[0] != '\0' && ret_read == 0) return (last_tring(&rest, &buff)); return (ret_read = (*line[0] == '\0' ? 0 : 1)); }
static NTSTATUS NTAPI driver_dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION irpStack; PVOID ioBuffer; ULONG inputBufferLength; ULONG outputBufferLength; ULONG ioControlCode; NTSTATUS ntStatus = STATUS_SUCCESS; co_manager_t *manager; co_rc_t rc; co_manager_ioctl_t ioctl; co_manager_open_desc_t opened; DbgPrint("colinux: driver_dispatch...\n"); Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation(Irp); manager = (co_manager_t *)DeviceObject->DeviceExtension; if (!manager) { ntStatus = STATUS_NO_SUCH_DEVICE; goto complete; } opened = (typeof(opened))(irpStack->FileObject->FsContext); if (!opened) { switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: { rc = co_manager_open(manager, &opened); if (!CO_OK(rc)) { ntStatus = STATUS_INVALID_PARAMETER; /* TODO */ goto complete; } irpStack->FileObject->FsContext = opened; break; } case IRP_MJ_CLOSE: case IRP_MJ_CLEANUP: break; default: ntStatus = STATUS_NO_SUCH_DEVICE; goto complete; } } ioBuffer = Irp->AssociatedIrp.SystemBuffer; inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (irpStack->MajorFunction) { case IRP_MJ_CLOSE: case IRP_MJ_CLEANUP: if (opened) { irpStack->FileObject->FsContext = NULL; co_manager_open_desc_deactive_and_close(manager, opened); } break; case IRP_MJ_READ: { Irp->IoStatus.Information = irpStack->Parameters.Read.Length; if (Irp->MdlAddress == NULL) { ntStatus = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; goto complete; } Irp->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (Irp->AssociatedIrp.SystemBuffer == NULL) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; goto complete; } ntStatus = manager_read(manager, opened, Irp); return ntStatus; } case IRP_MJ_WRITE: { Irp->IoStatus.Information = irpStack->Parameters.Write.Length; if (Irp->MdlAddress == NULL) { ntStatus = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; goto complete; } Irp->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (Irp->AssociatedIrp.SystemBuffer == NULL) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; goto complete; } ntStatus = manager_write(manager, opened, Irp); return ntStatus; } case IRP_MJ_DEVICE_CONTROL: { ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; co_rc_t rc; ioctl = (co_manager_ioctl_t)(CO_GET_IOCTL_METHOD(ioControlCode)); DbgPrint("colinux: IRP_MJ_DEVICE_CONTROL %d (%d)...\n", ioctl, ioctl & ~CO_WINNT_IOCTL_64BIT_FLAG); if (CO_WINNT_IOCTL_MASK64(ioControlCode) != CO_WINNT_IOCTL(ioctl)) { co_debug("ioControlCode != CO_WINNT_IOCTL(ioctl 0x%0x) 0x%lx <> 0x%x\n", ioctl, ioControlCode, CO_WINNT_IOCTL(ioctl)); ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } #ifdef WIN64 /* allow 32 bit Wow64 */ ioctl &= ~CO_WINNT_IOCTL_64BIT_FLAG; #endif rc = co_manager_ioctl(manager, ioctl, ioBuffer, inputBufferLength, outputBufferLength, (uintptr_t *)&Irp->IoStatus.Information, /* truncate max size to 32 bit here. */ opened); /* Intrinsic Success / Failure indictation is returned per ioctl. */ /* rc returns general errors in ioctl parameter. */ if (CO_OK(rc)) ntStatus = STATUS_SUCCESS; else ntStatus = STATUS_UNSUCCESSFUL; break; } } complete: Irp->IoStatus.Status = ntStatus; IoCompleteRequest(Irp, IO_NO_INCREMENT); return ntStatus; }
static NTSTATUS manager_dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION irpStack; PVOID ioBuffer; ULONG inputBufferLength; ULONG outputBufferLength; ULONG ioControlCode; NTSTATUS ntStatus = STATUS_SUCCESS; co_manager_t *manager; co_rc_t rc; co_manager_ioctl_t ioctl; co_manager_open_desc_t opened; Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation(Irp); manager = (co_manager_t *)DeviceObject->DeviceExtension; if (!manager) { ntStatus = STATUS_NO_SUCH_DEVICE; goto complete; } opened = (typeof(opened))(irpStack->FileObject->FsContext); if (!opened) { switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: { rc = co_manager_open(manager, &opened); if (!CO_OK(rc)) { ntStatus = STATUS_INVALID_PARAMETER; /* TODO */ goto complete; } irpStack->FileObject->FsContext = opened; break; } case IRP_MJ_CLOSE: case IRP_MJ_CLEANUP: break; default: ntStatus = STATUS_NO_SUCH_DEVICE; goto complete; } } ioBuffer = Irp->AssociatedIrp.SystemBuffer; inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (irpStack->MajorFunction) { case IRP_MJ_CLOSE: case IRP_MJ_CLEANUP: if (opened) { irpStack->FileObject->FsContext = NULL; co_manager_open_desc_deactive_and_close(manager, opened); } break; case IRP_MJ_READ: { Irp->IoStatus.Information = irpStack->Parameters.Read.Length; if (Irp->MdlAddress == NULL) { ntStatus = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; goto complete; } Irp->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (Irp->AssociatedIrp.SystemBuffer == NULL) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; goto complete; } ntStatus = manager_read(manager, opened, Irp); return ntStatus; } case IRP_MJ_WRITE: { Irp->IoStatus.Information = irpStack->Parameters.Write.Length; if (Irp->MdlAddress == NULL) { ntStatus = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; goto complete; } Irp->AssociatedIrp.SystemBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (Irp->AssociatedIrp.SystemBuffer == NULL) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; goto complete; } ntStatus = manager_write(manager, opened, Irp); return ntStatus; } case IRP_MJ_DEVICE_CONTROL: { ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; if (CO_GET_IOCTL_TYPE(ioControlCode) != CO_DRIVER_TYPE) { ntStatus = STATUS_INVALID_PARAMETER; break; } if (CO_GET_IOCTL_MTYPE(ioControlCode) != METHOD_BUFFERED) { ntStatus = STATUS_INVALID_PARAMETER; break; } if (CO_GET_IOCTL_ACCESS(ioControlCode) != FILE_ANY_ACCESS) { ntStatus = STATUS_INVALID_PARAMETER; break; } ioctl = (co_manager_ioctl_t)(CO_GET_IOCTL_METHOD(ioControlCode)); co_manager_ioctl(manager, ioctl, ioBuffer, inputBufferLength, outputBufferLength, &Irp->IoStatus.Information, opened); /* Intrinsic Success / Failure indictation is returned per ioctl. */ ntStatus = STATUS_SUCCESS; break; } } complete: Irp->IoStatus.Status = ntStatus; IoCompleteRequest(Irp, IO_NO_INCREMENT); return ntStatus; }