There are a couple of things worth mentioning about this approach:// // this is the name of the ADS that we want to open the file. // UNICODE_STRING ADSName = RTL_CONSTANT_STRING(L":foo:$DATA"); ... // // initialize OBJECT_ATTRIBUTES with the handle we have and the name of the // ADS. // InitializeObjectAttributes( &objectAttributes, &ADSName, OBJ_KERNEL_HANDLE, openFileHandle, NULL ); // // and now issue our open for the stream. // status = FltCreateFile( gFilterHandle, FltObjects->Instance, &ADSHandle, FILE_READ_DATA | FILE_READ_ATTRIBUTES, &objectAttributes, &ioStatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_OPEN_REPARSE_POINT, NULL, 0, 0 );
- Clearly this requires the main stream to be opened. So it can't be called from a preCreate for a file.
- One cool feature is that it works regardless of whether openFileHandle is a handle to the main stream of a file or to another ADS. This is nice because normally building the name of the ADS to open when opening it by name requires special treatment for when the user has opened the ADS compared to when they have the main data stream.
- Finally, please notice the FILE_OPEN_REPARSE_POINT flag. This is added because in case openFileHandle is a handle to a file that is a reparse point then our create will reparse which isn't what we want. So I put the FILE_OPEN_REPARSE_POINT flag just in case openFileHandle was opened with FILE_OPEN_REPARSE_POINT itself. The flag should have no effect otherwise.