⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eppflex.c

📁 simple MIPS EJTAG u-boot loader
💻 C
📖 第 1 页 / 共 2 页
字号:
                return frob_port(devobj, irp, fs->pnpinfo.EcpController + 2);

        case IOCTL_EPPFLEX_READ_CONFIGA:
                return read_port(devobj, irp, fs->pnpinfo.EcpController);

        case IOCTL_EPPFLEX_WRITE_CONFIGA:
                return write_port(devobj, irp, fs->pnpinfo.EcpController);

        case IOCTL_EPPFLEX_READ_CONFIGB:
                return read_port(devobj, irp, fs->pnpinfo.EcpController + 1);

        case IOCTL_EPPFLEX_WRITE_CONFIGB:
                return write_port(devobj, irp, fs->pnpinfo.EcpController + 1);

        case IOCTL_EPPFLEX_READ_EPPADDR:
                return read_port(devobj, irp, fs->info.Controller + 3);

        case IOCTL_EPPFLEX_WRITE_EPPADDR:
                return write_port(devobj, irp, fs->info.Controller + 3);

        case IOCTL_EPPFLEX_READ_EPPDATA:
                return read_port(devobj, irp, fs->info.Controller + 4);

        case IOCTL_EPPFLEX_WRITE_EPPDATA:
                return write_port(devobj, irp, fs->info.Controller + 4);
        }
        irp->IoStatus.Status = status;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        return status;
}

static NTSTATUS create(PDEVICE_OBJECT devobj, PIRP irp)
{
        NTSTATUS status;
        PIO_STACK_LOCATION irpsp;
        PFILE_OBJECT fileobj;
        WCHAR ppname[22] = L"\\Device\\ParallelPort0";
        UNICODE_STRING uppname;
        struct eppflex *s = devobj->DeviceExtension;
        struct eppflexfile *fs;
        ULONG devnr = 0;
        LARGE_INTEGER timeout;
        unsigned int i;
        
        VLOG(printk("eppflex: create\n"));
        irpsp = IoGetCurrentIrpStackLocation(irp);
        fileobj = irpsp->FileObject;
        status = STATUS_NO_MEMORY;
        fileobj->FsContext = fs = kmalloc(sizeof(struct eppflexfile));
        if (!fs)
                goto out;

        VLOG(printk("eppflex: filename length: %u\n", fileobj->FileName.Length));

        for (i = 0; i < fileobj->FileName.Length; i++) {
                VLOG(printk("eppflex: fn[%2u]: %04x\n", i, fileobj->FileName.Buffer[i]));
                if (fileobj->FileName.Buffer[i] == (WCHAR)'\\')
                        continue;
                if (fileobj->FileName.Buffer[i] < (WCHAR)'0' ||
                    fileobj->FileName.Buffer[i] > (WCHAR)'9')
                        break;
                devnr = 10 * devnr + fileobj->FileName.Buffer[i] - (WCHAR)'0';
        }
        
        VLOG(printk("eppflex: Device number %lu\n", devnr));

        status = STATUS_INVALID_PARAMETER;
        if (devnr > 9)
                goto out;
    

        ppname[20] = ((WCHAR)'0') + (WCHAR)devnr;
        RtlInitUnicodeString(&uppname, ppname);

        status = IoGetDeviceObjectPointer(&uppname, STANDARD_RIGHTS_ALL, &fs->pdfo, &fs->pdo);
        if (!NT_SUCCESS(status)) {
                ELOG(printk("eppflex: cannot open parallel port %u\n", devnr));
                goto out;
        }
    
        timeout.QuadPart = -(LONGLONG)10*1000*500;  /* 500ms, in 100ns units */
        status = callparport(fs, IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,
                             &fs->info, 0, sizeof(fs->info), &timeout);
        if (!NT_SUCCESS(status)) {
                ELOG(printk("eppflex: GET_PARALLEL_PORT_INFO error 0x%lx\n", status));
                goto out;
        }
        status = callparport(fs, IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO,
                             &fs->pnpinfo, 0, sizeof(fs->pnpinfo), &timeout);
        if (!NT_SUCCESS(status)) {
                ELOG(printk("eppflex: warning: GET_PARALLEL_PNP_INFO error 0x%lx\n", status));
                fs->pnpinfo.EcpController = fs->info.Controller + 0x400;
                fs->pnpinfo.SpanOfEcpController = fs->info.SpanOfController;
                fs->pnpinfo.HardwareCapabilities = 0;
                fs->pnpinfo.FifoDepth = 0;
                fs->pnpinfo.FifoWidth = 0;
        }

        VLOG(printk("eppflex: ioaddr: 0x%x(%u)  ecpioaddr: 0x%x(%u)  cap: 0x%x  FIFO: %d,%d\n",
                    fs->info.Controller, fs->info.SpanOfController,
                    fs->pnpinfo.EcpController, fs->pnpinfo.SpanOfEcpController,
                    fs->pnpinfo.HardwareCapabilities, fs->pnpinfo.FifoDepth, fs->pnpinfo.FifoWidth));
        
        timeout.QuadPart = -(LONGLONG)10*1000*50;  /* 50ms, in 100ns units */
        status = callparport(fs, IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE, NULL, 0, 0, &timeout);
        if (!NT_SUCCESS(status)) {
                ELOG(printk("eppflex: PARALLEL_PORT_ALLOCATE error 0x%lx\n", status));
                goto out;
        }

        status = STATUS_SUCCESS;

  out:
        if (!NT_SUCCESS(status) && fs) {
                kfree(fs);
                fileobj->FsContext = NULL;
        }
        irp->IoStatus.Status = status;
        irp->IoStatus.Information = 0L;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        return status;
}

static NTSTATUS close(PDEVICE_OBJECT devobj, PIRP irp)
{
        NTSTATUS status;
        PIO_STACK_LOCATION irpsp;
        PFILE_OBJECT fileobj;
        struct eppflex *s = devobj->DeviceExtension;
        struct eppflexfile *fs;
        LARGE_INTEGER timeout;

        irpsp = IoGetCurrentIrpStackLocation(irp);
        fileobj = irpsp->FileObject;
        fs = fileobj->FsContext;
        VLOG(printk("eppflex: close\n"));
        if (fs) {

                timeout.QuadPart = -(LONGLONG)10*1000*50;  /* 50ms, in 100ns units */
                status = callparport(fs, IOCTL_INTERNAL_RELEASE_PARALLEL_PORT_INFO, NULL, 0, 0, &timeout);
                if (!NT_SUCCESS(status))
                        ELOG(printk("eppflex: RELEASE_PARALLEL_PORT_INFO error 0x%lx\n", status));
                status = callparport(fs, IOCTL_INTERNAL_PARALLEL_PORT_FREE, NULL, 0, 0, &timeout);
                if (!NT_SUCCESS(status))
                        ELOG(printk("eppflex: PARALLEL_PORT_FREE error 0x%lx\n", status));
                ObDereferenceObject(fs->pdfo);
                kfree(fs);
                fileobj->FsContext = NULL;
        }
        status = irp->IoStatus.Status = STATUS_SUCCESS;
        irp->IoStatus.Information = 0L;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        return status;
}

static void unload(PDRIVER_OBJECT drvobj)
{
        struct eppflex *s = drvobj->DeviceObject->DeviceExtension;
        UNICODE_STRING nameString, linkString;

        printk("eppflex: stop\n");

        IoDeleteDevice(drvobj->DeviceObject);
        RtlInitUnicodeString(&linkString, L"\\DosDevices\\EPPFLEX" );
        RtlInitUnicodeString(&nameString, L"\\Device\\eppflex" );
        IoDeleteSymbolicLink(&linkString);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT drvobj, PUNICODE_STRING RegistryPath)
{
        UNICODE_STRING nameString, linkString;
        PDEVICE_OBJECT devobj;
        NTSTATUS status;
        struct eppflex *s;


        /*
         * Create the device object.
         */
        RtlInitUnicodeString(&nameString, L"\\Device\\eppflex" );
        status = IoCreateDevice(drvobj, sizeof(struct eppflex), &nameString, FILE_DEVICE_UNKNOWN, 0, TRUE, &devobj);
        if (!NT_SUCCESS(status))
                return status;

        /*
         * Create the symbolic link so the VDD can find us.
         */
        RtlInitUnicodeString( &linkString, L"\\DosDevices\\EPPFLEX" );
        status = IoCreateSymbolicLink (&linkString, &nameString);
        if (!NT_SUCCESS(status)) {
                IoDeleteDevice(drvobj->DeviceObject);
                return status;
        }

        /*
         * Initialize the driver object with this device driver's entry points.
         */

        drvobj->DriverUnload = unload;
        drvobj->MajorFunction[IRP_MJ_CREATE] = create;
        drvobj->MajorFunction[IRP_MJ_CLOSE] = close;
        drvobj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ioctl;

        s = devobj->DeviceExtension;

        /*
         * Initialize the device extension.
         */

        printk("eppflex: started "__DATE__" "__TIME__"\n");

        return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -