diff --git a/build/VStudio/winfsp.vcxproj b/build/VStudio/winfsp.vcxproj
index c78a834a..4a4418c9 100644
--- a/build/VStudio/winfsp.vcxproj
+++ b/build/VStudio/winfsp.vcxproj
@@ -143,6 +143,7 @@
+
diff --git a/build/VStudio/winfsp.vcxproj.filters b/build/VStudio/winfsp.vcxproj.filters
index a144f466..f49c593f 100644
--- a/build/VStudio/winfsp.vcxproj.filters
+++ b/build/VStudio/winfsp.vcxproj.filters
@@ -71,6 +71,9 @@
Source
+
+ Source
+
diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h
index 6ff2a3b3..347f39f9 100644
--- a/inc/winfsp/fsctl.h
+++ b/inc/winfsp/fsctl.h
@@ -19,11 +19,13 @@ extern const __declspec(selectany) GUID FspDeviceClassGuid =
/* fsctl device codes */
#define FSP_FSCTL_CREATE \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'C', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
-#define FSP_FSCTL_DELETE \
- CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'D', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
/* fsvrt device codes */
+#define FSP_FSCTL_DELETE \
+ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'D', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define FSP_FSCTL_TRANSACT \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
+#define FSP_FSCTL_CREATE_BUFFER_SIZEMAX 64
+
#endif
diff --git a/src/sys/debug.c b/src/sys/debug.c
index 6827eb90..aae2ace2 100644
--- a/src/sys/debug.c
+++ b/src/sys/debug.c
@@ -86,7 +86,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_COMPLETE_MDL)
SYMBRC(IRP_MN_COMPLETE_MDL_DPC)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
case IRP_MJ_DIRECTORY_CONTROL:
switch (MinorFunction)
@@ -94,7 +94,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_QUERY_DIRECTORY)
SYMBRC(IRP_MN_NOTIFY_CHANGE_DIRECTORY)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
case IRP_MJ_FILE_SYSTEM_CONTROL:
switch (MinorFunction)
@@ -105,7 +105,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_LOAD_FILE_SYSTEM)
SYMBRC(IRP_MN_KERNEL_CALL)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
case IRP_MJ_LOCK_CONTROL:
switch (MinorFunction)
@@ -115,7 +115,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_UNLOCK_ALL)
SYMBRC(IRP_MN_UNLOCK_ALL_BY_KEY)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
case IRP_MJ_POWER:
switch (MinorFunction)
@@ -125,7 +125,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_SET_POWER)
SYMBRC(IRP_MN_QUERY_POWER)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
case IRP_MJ_SYSTEM_CONTROL:
switch (MinorFunction)
@@ -142,7 +142,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_EXECUTE_METHOD)
SYMBRC(IRP_MN_REGINFO_EX)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
case IRP_MJ_PNP:
switch (MinorFunction)
@@ -153,10 +153,22 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction)
SYMBRC(IRP_MN_CANCEL_REMOVE_DEVICE)
SYMBRC(IRP_MN_SURPRISE_REMOVAL)
default:
- return "[Unknown]";
+ return "[IRP_MN:Unknown]";
}
default:
return "";
}
}
+
+const char *IoctlCodeSym(ULONG ControlCode)
+{
+ switch (ControlCode)
+ {
+ SYM(FSP_FSCTL_CREATE)
+ SYM(FSP_FSCTL_DELETE)
+ SYM(FSP_FSCTL_TRANSACT)
+ default:
+ return "IOCTL:Unknown";
+ }
+}
#endif
diff --git a/src/sys/driver.h b/src/sys/driver.h
index 3349e7c6..652e4925 100644
--- a/src/sys/driver.h
+++ b/src/sys/driver.h
@@ -8,6 +8,7 @@
#define WINFSP_SYS_DRIVER_H_INCLUDED
#include
+#include
#include
#include
@@ -176,12 +177,16 @@ FAST_IO_RELEASE_FOR_MOD_WRITE FspReleaseForModWrite;
FAST_IO_ACQUIRE_FOR_CCFLUSH FspAcquireForCcFlush;
FAST_IO_RELEASE_FOR_CCFLUSH FspReleaseForCcFlush;
+/* misc */
+NTSTATUS CreateGuid(GUID *Guid);
+
/* debug */
#if DBG
BOOLEAN HasDbgBreakPoint(const char *Function);
const char *NtStatusSym(NTSTATUS Status);
const char *IrpMajorFunctionSym(UCHAR MajorFunction);
const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction);
+const char *IoctlCodeSym(ULONG ControlCode);
#endif
/* extern */
diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c
index 0c1aafc8..60bca7e0 100644
--- a/src/sys/fsctl.c
+++ b/src/sys/fsctl.c
@@ -6,23 +6,23 @@
#include
-static
-NTSTATUS
-FspFsctlCreateVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp);
-static
-NTSTATUS
-FspFsctlDeleteVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp);
-static
-NTSTATUS
-FspFsvolTransact(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp);
-static DRIVER_DISPATCH FspFsctlFileSystemControl;
-static DRIVER_DISPATCH FspFsvrtFileSystemControl;
-static DRIVER_DISPATCH FspFsvolFileSystemControl;
+static NTSTATUS FspFsctlCreateVolume(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
+static NTSTATUS FspFsvolDeleteVolume(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
+static NTSTATUS FspFsvolTransact(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
+static NTSTATUS FspFsctlFileSystemControl(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
+static NTSTATUS FspFsvrtFileSystemControl(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
+static NTSTATUS FspFsvolFileSystemControl(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
DRIVER_DISPATCH FspFileSystemControl;
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsctlCreateVolume)
-#pragma alloc_text(PAGE, FspFsctlDeleteVolume)
+#pragma alloc_text(PAGE, FspFsvolDeleteVolume)
#pragma alloc_text(PAGE, FspFsvolTransact)
#pragma alloc_text(PAGE, FspFsctlFileSystemControl)
#pragma alloc_text(PAGE, FspFsvrtFileSystemControl)
@@ -30,66 +30,85 @@ DRIVER_DISPATCH FspFileSystemControl;
#pragma alloc_text(PAGE, FspFileSystemControl)
#endif
-static
-NTSTATUS
-FspFsctlCreateVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp)
+static NTSTATUS FspFsctlCreateVolume(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
+{
+ if (FSP_FSCTL_CREATE_BUFFER_SIZEMAX > IrpSp->Parameters.FileSystemControl.OutputBufferLength)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ NTSTATUS Result;
+
+ GUID Guid;
+ Result = CreateGuid(&Guid);
+ if (!NT_SUCCESS(Result))
+ return Result;
+
+ PDEVICE_OBJECT FsvrtDeviceObject;
+ UNICODE_STRING DeviceSddl;
+ UNICODE_STRING DeviceName;
+ RtlInitUnicodeString(&DeviceSddl, L"" DEVICE_SDDL);
+ RtlInitEmptyUnicodeString(&DeviceName, Irp->AssociatedIrp.SystemBuffer, FSP_FSCTL_CREATE_BUFFER_SIZEMAX);
+ Result = RtlUnicodeStringPrintf(&DeviceName,
+ L"\\Device\\Volume{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ Guid.Data1, Guid.Data2, Guid.Data3,
+ Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
+ Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
+ ASSERT(NT_SUCCESS(Result));
+ Result = IoCreateDeviceSecure(DeviceObject->DriverObject,
+ sizeof(FSP_FSVRT_DEVICE_EXTENSION), &DeviceName, DeviceObject->DeviceType, 0, FALSE,
+ &DeviceSddl, 0,
+ &FsvrtDeviceObject);
+ if (!NT_SUCCESS(Result))
+ return Result;
+ FspDeviceExtension(FsvrtDeviceObject)->Kind = FspFsvrtDeviceExtensionKind;
+ Irp->IoStatus.Information = DeviceName.Length + 1;
+
+ return Result;
+}
+
+static NTSTATUS FspFsvolDeleteVolume(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
return STATUS_INVALID_DEVICE_REQUEST;
}
-static
-NTSTATUS
-FspFsctlDeleteVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp)
+static NTSTATUS FspFsvolTransact(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
return STATUS_INVALID_DEVICE_REQUEST;
}
-static
-NTSTATUS
-FspFsvolTransact(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp)
-{
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-static
-NTSTATUS
-FspFsctlFileSystemControl(
- _In_ PDEVICE_OBJECT DeviceObject,
- _In_ PIRP Irp)
+static NTSTATUS FspFsctlFileSystemControl(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
switch (IrpSp->Parameters.FileSystemControl.FsControlCode)
{
case FSP_FSCTL_CREATE:
- Result = FspFsctlCreateVolume(DeviceObject, IrpSp);
- break;
- case FSP_FSCTL_DELETE:
- Result = FspFsctlDeleteVolume(DeviceObject, IrpSp);
+ Result = FspFsctlCreateVolume(DeviceObject, Irp, IrpSp);
break;
}
}
return Result;
}
-static
-NTSTATUS
-FspFsvrtFileSystemControl(
- _In_ PDEVICE_OBJECT DeviceObject,
- _In_ PIRP Irp)
+static NTSTATUS FspFsvrtFileSystemControl(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
switch (IrpSp->Parameters.FileSystemControl.FsControlCode)
{
+ case FSP_FSCTL_DELETE:
+ Result = FspFsvolDeleteVolume(DeviceObject, Irp, IrpSp);
+ break;
case FSP_FSCTL_TRANSACT:
- Result = FspFsvolTransact(DeviceObject, IrpSp);
+ Result = FspFsvolTransact(DeviceObject, Irp, IrpSp);
break;
}
break;
@@ -97,14 +116,10 @@ FspFsvrtFileSystemControl(
return Result;
}
-static
-NTSTATUS
-FspFsvolFileSystemControl(
- _In_ PDEVICE_OBJECT DeviceObject,
- _In_ PIRP Irp)
+static NTSTATUS FspFsvolFileSystemControl(
+ PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
@@ -129,14 +144,19 @@ FspFileSystemControl(
switch (FspDeviceExtension(DeviceObject)->Kind)
{
case FspFsvolDeviceExtensionKind:
- FSP_RETURN(Result = FspFsctlFileSystemControl(DeviceObject, Irp));
+ FSP_RETURN(Result = FspFsctlFileSystemControl(DeviceObject, Irp, IrpSp));
case FspFsvrtDeviceExtensionKind:
- FSP_RETURN(Result = FspFsvrtFileSystemControl(DeviceObject, Irp));
+ FSP_RETURN(Result = FspFsvrtFileSystemControl(DeviceObject, Irp, IrpSp));
case FspFsctlDeviceExtensionKind:
- FSP_RETURN(Result = FspFsvolFileSystemControl(DeviceObject, Irp));
+ FSP_RETURN(Result = FspFsvolFileSystemControl(DeviceObject, Irp, IrpSp));
default:
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
}
- FSP_LEAVE_MJ("", 0);
+ FSP_LEAVE_MJ(
+ "FileObject=%p%s%s",
+ IrpSp->FileObject,
+ IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction ? ", " : "",
+ IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction ?
+ IoctlCodeSym(IrpSp->Parameters.FileSystemControl.FsControlCode) : "");
}
diff --git a/src/sys/misc.c b/src/sys/misc.c
new file mode 100644
index 00000000..14a71d91
--- /dev/null
+++ b/src/sys/misc.c
@@ -0,0 +1,24 @@
+/**
+ * @file sys/misc.c
+ *
+ * @copyright 2015 Bill Zissimopoulos
+ */
+
+#include
+
+NTSTATUS CreateGuid(GUID *Guid);
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, CreateGuid)
+#endif
+
+NTSTATUS CreateGuid(GUID *Guid)
+{
+ NTSTATUS Result;
+ int Retries = 3;
+ do
+ {
+ Result = ExUuidCreate(Guid);
+ } while (!NT_SUCCESS(Result) && 0 < --Retries);
+ return Result;
+}