Hey , whats the actual difference between the two when it comes to :smile:

  1. Handling : IOCTLs are handled by the DeviceObject.DriverObject.Majorfunction[IRP_MJ_DEVICE_CONTROL] you are sending it to, what FSCTLs are handled by ?
  2. IOCTLs are sent to a specific device, can one send FSCTL to a sepcific device or do they always travel the file system device stack?
  3. to send a message from UM to a filter communication port you can use FilterSendMessage - under the hood it sends NtfsControlFile with specific control code and the following
  • handle to the port (which is actually a handle to a file object with DeviceObject fltmsg of the filter manager , as well as FsContext2.CCB that points to the actual port object
  • input / out buffers
    Now usually with how IOCTLs work the handle is used to locate the driver object dispatch routine to be called, and the handle is not needed in the actual dispatch rotuine . in this case tho since the filter manager need to know which port to direct the message to i assume the handle needs to be passed to the dispatch routine of the FSCTL? what is the prototype of a FSCTL handler?
    without the handle to the file object thereโ€™s no wat the filter manager can tell which port the message should be sent to right?

FSCTLs are handled at the IRP_MJ_FILE_SYSTEM_CONTROL entry point. By convention, the file systems will only allow IOCTLs to be submitted against a volume open. For example, from FAT:

//  Decode the file object, the only type of opens we accept are
//  user volume opens.

if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb ) != UserVolumeOpen) {

    FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );

    DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER);


FSCTLs, however, can be sent to any type of open. In addition, the file system will pass unhandled IOCTLs down to the lower levels of the storage branch whereas unhandled FSCTLs are failed without passing down.