// // This is where it all starts... // NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status; PDEVICE_OBJECT device_object; UNICODE_STRING ctl_device_name; UNICODE_STRING sym_link; AWEAllocDriverObject = DriverObject; MmPageEntireDriver((PVOID)(ULONG_PTR)DriverEntry); // Create the control device. RtlInitUnicodeString(&ctl_device_name, AWEALLOC_DEVICE_NAME); status = IoCreateDevice(DriverObject, 0, &ctl_device_name, FILE_DEVICE_NULL, 0, FALSE, &device_object); if (!NT_SUCCESS(status)) return status; device_object->Flags |= DO_DIRECT_IO; RtlInitUnicodeString(&sym_link, AWEALLOC_SYMLINK_NAME); status = IoCreateUnprotectedSymbolicLink(&sym_link, &ctl_device_name); if (!NT_SUCCESS(status)) { IoDeleteDevice(device_object); return status; } DriverObject->MajorFunction[IRP_MJ_CREATE] = AWEAllocCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = AWEAllocClose; DriverObject->MajorFunction[IRP_MJ_READ] = AWEAllocReadWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = AWEAllocReadWrite; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AWEAllocFlushBuffers; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AWEAllocQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AWEAllocSetInformation; DriverObject->DriverUnload = AWEAllocUnload; KdPrint(("AWEAlloc: Initialization done. Leaving DriverEntry().\n")); return STATUS_SUCCESS; }
VOID ParInitializeDeviceObject( IN PDRIVER_OBJECT DriverObject, IN ULONG ParallelPortNumber ) /*++ Routine Description: This routine is called for every parallel port in the system. It will create a class device upon connecting to the port device corresponding to it. Arguments: DriverObject - Supplies the driver object. ParallelPortNumber - Supplies the number for this port. Return Value: None. --*/ { UNICODE_STRING portName, className, linkName; NTSTATUS status; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION extension; PFILE_OBJECT fileObject; // Cobble together the port and class device names. if (!ParMakeNames(ParallelPortNumber, &portName, &className, &linkName)) { ParLogError(DriverObject, NULL, PhysicalZero, PhysicalZero, 0, 0, 0, 1, STATUS_SUCCESS, PAR_INSUFFICIENT_RESOURCES); return; } // Create the device object. status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &className, FILE_DEVICE_PARALLEL_PORT, 0, FALSE, &deviceObject); if (!NT_SUCCESS(status)) { ParLogError(DriverObject, NULL, PhysicalZero, PhysicalZero, 0, 0, 0, 2, STATUS_SUCCESS, PAR_INSUFFICIENT_RESOURCES); ExFreePool(linkName.Buffer); goto Cleanup; } // Now that the device has been created, // set up the device extension. extension = deviceObject->DeviceExtension; RtlZeroMemory(extension, sizeof(DEVICE_EXTENSION)); extension->DeviceObject = deviceObject; deviceObject->Flags |= DO_BUFFERED_IO; status = IoGetDeviceObjectPointer(&portName, FILE_READ_ATTRIBUTES, &fileObject, &extension->PortDeviceObject); if (!NT_SUCCESS(status)) { ParLogError(DriverObject, deviceObject, PhysicalZero, PhysicalZero, 0, 0, 0, 3, STATUS_SUCCESS, PAR_CANT_FIND_PORT_DRIVER); IoDeleteDevice(deviceObject); ExFreePool(linkName.Buffer); goto Cleanup; } ObDereferenceObject(fileObject); extension->DeviceObject->StackSize = extension->PortDeviceObject->StackSize + 1; // We don't own parallel ports initially extension->PortOwned = FALSE; // Get the port information from the port device object. status = ParGetPortInfoFromPortDevice(extension); if (!NT_SUCCESS(status)) { ParLogError(DriverObject, deviceObject, PhysicalZero, PhysicalZero, 0, 0, 0, 4, STATUS_SUCCESS, PAR_CANT_FIND_PORT_DRIVER); IoDeleteDevice(deviceObject); ExFreePool(linkName.Buffer); goto Cleanup; } // Set up the symbolic link for windows apps. status = IoCreateUnprotectedSymbolicLink(&linkName, &className); if (!NT_SUCCESS(status)) { ParLogError(DriverObject, deviceObject, extension->OriginalController, PhysicalZero, 0, 0, 0, 5, STATUS_SUCCESS, PAR_NO_SYMLINK_CREATED); extension->CreatedSymbolicLink = FALSE; ExFreePool(linkName.Buffer); goto Cleanup; } // We were able to create the symbolic link, so record this // value in the extension for cleanup at unload time. extension->CreatedSymbolicLink = TRUE; extension->SymbolicLinkName = linkName; Cleanup: // release the port info so the port driver can be paged out ParReleasePortInfoToPortDevice(extension); ExFreePool(portName.Buffer); ExFreePool(className.Buffer); }