NTSTATUS attach(PUNICODE_STRING tardevname, enum DevType type) { UNREFERENCED_PARAMETER(tardevname); UNREFERENCED_PARAMETER(type); NTSTATUS sta; if (type == DEVTYPE_TCP) { sta = IoCreateDevice(dri, 0, NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &tcptop); DbgPrint("tcp0x%x\n", sta); tcptop->Flags |= DO_DIRECT_IO; sta = IoAttachDevice(tcptop, tardevname, &tcpflt); DbgPrint("0x%x\n", sta); } if (type == DEVTYPE_UDP) { sta = IoCreateDevice(dri, 0, NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &udptop); DbgPrint("udp0x%x\n", sta); udptop->Flags |= DO_DIRECT_IO; sta = IoAttachDevice(udptop, tardevname, &udpflt); DbgPrint("0x%x\n", sta); } if (type == DEVTYPE_IP) { sta = IoCreateDevice(dri, 0, NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &iptop); DbgPrint("ip0x%x\n", sta); iptop->Flags |= DO_DIRECT_IO; sta = IoAttachDevice(iptop, tardevname, &ipflt); DbgPrint("0x%x\n", sta); } return STATUS_SUCCESS; }
/* create & attach device */ NTSTATUS c_n_a_device(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT *fltobj, PDEVICE_OBJECT *oldobj, wchar_t *devname) { NTSTATUS status; UNICODE_STRING str; /* create filter device */ status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, TRUE, fltobj); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] c_n_a_device: IoCreateDevice(%S): 0x%x\n", devname, status)); return status; } (*fltobj)->Flags |= DO_DIRECT_IO; RtlInitUnicodeString(&str, devname); status = IoAttachDevice(*fltobj, &str, oldobj); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] DriverEntry: IoAttachDevice(%S): 0x%x\n", devname, status)); return status; } KdPrint(("[tdi_fw] DriverEntry: %S fileobj: 0x%x\n", devname, *fltobj)); return STATUS_SUCCESS; }
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject = NULL; DbgPrint("Load\n"); driverObject->DriverUnload = my_unload; status = IoCreateDevice(driverObject, sizeof(device_extension_t), NULL, // Filter driver: device has no name FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject); if (status != STATUS_SUCCESS) { DbgPrint("Cannot create device\n"); goto cleanup; } for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { // Filter driver: ignore function instead of unsupported driverObject->MajorFunction[i] = my_ignored_function; } driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = my_ioctl; device_extension_t* device_extension = (device_extension_t*) deviceObject->DeviceExtension; UNICODE_STRING deviceToFilter; RtlInitUnicodeString(&deviceToFilter, DEVICE_PATH); // Attach the filter device in the device stack status = IoAttachDevice(deviceObject, &deviceToFilter, &device_extension->next); if (status != STATUS_SUCCESS) { DbgPrint("Cannot attach device\n"); goto cleanup; } PDEVICE_OBJECT filteredDevice = device_extension->next; // These flags are used only for ReadFile and WriteFile. deviceObject->Flags |= filteredDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO); deviceObject->DeviceType = filteredDevice->DeviceType; deviceObject->Characteristics = filteredDevice->Characteristics; deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; cleanup: if (status != STATUS_SUCCESS) { if (deviceObject) { IoDeleteDevice(deviceObject); } } return status; }
static VOID TestAttachDevice( IN PDEVICE_OBJECT DeviceObject, IN PWCHAR NewDriverRegPath) { NTSTATUS Status; UNICODE_STRING LowerDeviceName; RtlInitUnicodeString(&LowerDeviceName, NewDriverRegPath); Status = IoAttachDevice(DeviceObject, &LowerDeviceName, &AttachDeviceObject); ok_eq_hex(Status, STATUS_SUCCESS); /* TODO: Add more tests */ }
void try_attach_to_other_driver(PDRIVER_OBJECT driverObject) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject = NULL; status = IoCreateDevice(driverObject, sizeof(device_extension_t), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject); if (status != STATUS_SUCCESS) { DbgPrint("Cannot create filter device\n"); goto cleanup; } device_extension_t* device_extension = (device_extension_t*) deviceObject->DeviceExtension; UNICODE_STRING deviceToFilter; RtlInitUnicodeString(&deviceToFilter, FIRST_DEVICE_PATH); // Attach the filter device in the device stack DbgPrint("About to attach device\n"); status = IoAttachDevice(deviceObject, &deviceToFilter, &device_extension->next); DbgPrint("Attached device: 0x%08X\n", deviceObject->AttachedDevice); DbgPrint("device_extension->next=0x%08X\n", device_extension->next); if (status != STATUS_SUCCESS) { DbgPrint("Cannot attach device\n"); goto cleanup; } PDEVICE_OBJECT filteredDevice = device_extension->next; // These flags are used only for ReadFile and WriteFile. deviceObject->Flags |= filteredDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO); deviceObject->DeviceType = filteredDevice->DeviceType; deviceObject->Characteristics = filteredDevice->Characteristics; deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; DbgPrint("Filter device successfully created\n"); cleanup: if (status != STATUS_SUCCESS) { if (deviceObject) { IoDeleteDevice(deviceObject); } } }
/********************************************************************** * * DriverEntry * * This is the default entry point for drivers. The parameters * are a driver object and the registry path. * **********************************************************************/ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) { UNREFERENCED_PARAMETER(pRegistryPath); NTSTATUS NtStatus = STATUS_SUCCESS; UINT uiIndex = 0; PDEVICE_OBJECT pDeviceObject = NULL, pFilteredDevice = NULL; UNICODE_STRING usDeviceToFilter; PEXAMPLE_FILTER_EXTENSION pExampleFilterDeviceContext; UNICODE_STRING usDriverName, usDosDeviceName; RtlInitUnicodeString(&usDriverName, L"\\Device\\ExampleFilter"); RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\ExampleFilter"); DbgPrint("DriverEntry Called \r\n"); NtStatus = IoCreateDevice(pDriverObject, sizeof(EXAMPLE_FILTER_EXTENSION), &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject); //DbgBreakPoint(); if(NtStatus == STATUS_SUCCESS) { /* * The "MajorFunction" is a list of function pointers for entry points into the driver. * You can set them all to point to 1 function, then have a switch statement for all * IRP_MJ_*** functions or you can set specific function pointers for each entry * into the driver. * */ for(uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++) pDriverObject->MajorFunction[uiIndex] = ExampleFilter_UnSupportedFunction; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = ExampleFilter_Close; pDriverObject->MajorFunction[IRP_MJ_CREATE] = ExampleFilter_Create; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ExampleFilter_IoControl; pDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ExampleFilter_IoControlInternal; pDriverObject->MajorFunction[IRP_MJ_READ] = ExampleFilter_Read; pDriverObject->MajorFunction[IRP_MJ_WRITE] = ExampleFilter_Write; /* * Required to unload the driver dynamically. If this function is missing * the driver cannot be dynamically unloaded. */ pDriverObject->DriverUnload = ExampleFilter_Unload; /* * We want to save the device we attached to on the lower end so we can use it in * subsequent calls and be able to send IRP's down properly. */ pExampleFilterDeviceContext = (PEXAMPLE_FILTER_EXTENSION)pDeviceObject->DeviceExtension; /* * We want to attach this device above our other device. So this driver will actually * sit on top of our other driver. We will be able to filter all calls to the device. */ RtlInitUnicodeString(&usDeviceToFilter, L"\\Device\\Example"); NtStatus = IoAttachDevice(pDeviceObject, &usDeviceToFilter, &pExampleFilterDeviceContext->pNextDeviceInChain); /* * WARNING! * * The IoAttachDevice() API opens the DeviceObject for us then calls IoAttachDeviceToStack() then closes * the object. That means we will get the CLEAN UP and CLOSE IRP Major functions before IoAttachDevice * returns! We need to make sure the function pointer we pass in can be accessed by those functions in * some system wide memory space. The DeviceExtension is a great place to put this and it must * be passed into IoAttachDevice!!!!!!!!! */ if(!NT_SUCCESS(NtStatus)) { IoDeleteDevice(pDeviceObject); } else { pFilteredDevice = pExampleFilterDeviceContext->pNextDeviceInChain; /* * Our device driver should ensure that it is using the same type of I/O as the * device it is attempting to filter. For example, buffered, direct or neither should * be the same. */ pDeviceObject->Flags |= pFilteredDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO); pDeviceObject->DeviceType = pFilteredDevice->DeviceType; pDeviceObject->Characteristics = pFilteredDevice->Characteristics; pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; } IoCreateSymbolicLink(&usDosDeviceName, &usDriverName); } return NtStatus; }