I can’t help but think that this is a mind-bogglingly stupid question,
but I’ve been reading documentation for most of the afternoon and
haven’t found an answer. I’ve created a control device object using the
CDO example code as the model.
In my cdo, I open a file, do some i/o on it, untag it, and then close
it. All of this is invoked from userland using IOCTLs.
What’s bugging me is that when I create the file, I’m doing so with
IoCreateFileSpecifyDeviceObjectHint with a DeviceObject of 0, which
should send it to the top of the stack. Therefore, as I understand it,
my minifilter in the stack for the volume with the file on it should see
the i/o. However it’s not. This isn’t a problem per-se (if I were
seeing the i/o, I’d have become screwed up in the recursion). I don’t
want to see the i/o for the file in question, but I feel like I may be
doing something wrong.
Any thoughts? Code follows.
Thanks,
~Eric
// Called from DriverEntry, creates device:
NTSTATUS create_restorer_device_object (PDRIVER_OBJECT driver_object)
{
int i;
UNICODE_STRING device_name = RTL_CONSTANT_STRING
(RESTORER_DEVICE_NAME);
UNICODE_STRING link_name = RTL_CONSTANT_STRING
(RESTORER_USER_NAME);
NTSTATUS status = STATUS_SUCCESS;
DBG_PRINT ((“Creating restorer device object\n”));
if (globals.restorer_device) {
//wraps DbgPrint with some additional info (line #, etc)
DBG_PRINT ((
“Could not create restorer device
object, already exists\n”));
status = STATUS_UNSUCCESSFUL;
goto out;
}
status = IoCreateDevice (driver_object, 0, &device_name,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE, &globals.restorer_device);
// this is a macro that tests the status and DbgPrints an error
and jumps to out
// if it’s not a success code.
TEST_STATUS_AND_ABORT ((“Could not create restorer device\n”));
status = IoCreateSymbolicLink (&link_name, &device_name);
TEST_STATUS_AND_ABORT ((“Could not create symlink to restorer
device\n”));
//Default to invalid request for all IRPs
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
driver_object->MajorFunction[i] = ehr_invalid;
}
//Set up the few functions we’re going to support
driver_object->MajorFunction[IRP_MJ_CREATE] = ehr_create;
driver_object->MajorFunction[IRP_MJ_CLEANUP] = ehr_cleanup;
driver_object->MajorFunction[IRP_MJ_CLOSE] = ehr_close;
driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ehr_ioctl;
DBG_PRINT ((“Done creating\n”));
out:
if (!NT_SUCCESS (status)) {
if (globals.restorer_device) {
IoDeleteDevice (globals.restorer_device);
}
}
return status;
}
// This is the function in the cdo that handles my file_open ioctl
static NTSTATUS ehr_file_open (PIRP irp, PIO_STACK_LOCATION irp_sp)
{
NTSTATUS status = STATUS_SUCCESS;
EHR_OPEN_ARGS *args = (EHR_OPEN_ARGS *)
irp->AssociatedIrp.SystemBuffer;
size_t input_size =
irp_sp->Parameters.DeviceIoControl.InputBufferLength;
UNICODE_STRING file_name;
UNICODE_STRING volume_name;
UNICODE_STRING om_root = RTL_CONSTANT_STRING (L"\??\");
OBJECT_ATTRIBUTES oa;
UNICODE_STRING oa_path;
IO_STATUS_BLOCK iosb;
USHORT total_size;
HANDLE t_handle = INVALID_HANDLE_VALUE;
eh_stream_context *sc = NULL;
BOOLEAN first_open = FALSE;
BOOLEAN do_restore = FALSE;
RtlInitUnicodeString (&file_name, args->wsFileName);
RtlInitUnicodeString (&volume_name, args->wsVolumeName);
//total size in bytes we need to allocate
total_size = file_name.Length + om_root.Length;
kuReserveUnicodeStringCb (&oa_path, total_size, PagedPool,
EHR_TAG);
TEST_STATUS_AND_ABORT ((“Failed to reserve oa_path\n”));
status = RtlUnicodeStringCat (&oa_path, &om_root);
TEST_STATUS_AND_ABORT ((“couldn’t add om_root to oa_path\n”));
status = RtlUnicodeStringCat (&oa_path, &file_name);
TEST_STATUS_AND_ABORT ((“couldn’t add file_name to oa_path\n”));
InitializeObjectAttributes (&oa, &oa_path, 0, 0, 0);
status = IoCreateFileSpecifyDeviceObjectHint (&t_handle,
GENERIC_WRITE, &oa, &iosb, 0,
FILE_ATTRIBUTE_NORMAL, 0,
FILE_OPEN, FILE_OPEN_REPARSE_POINT
| FILE_SYNCHRONOUS_IO_NONALERT, 0, 0,
CreateFileTypeNone,
0, IO_IGNORE_SHARE_ACCESS_CHECK, 0);
/* … more stuff happens */
}
Once I have this handle, I don’t see the i/o on it in my minifilter. It
seems like I should, and that’s what’s bugging me. The i/o is limited
to writes, FltUntagFile, and a close.