MiniFilter Driver - modify a file bytes on IRP_MJ_CLOSE and IRP_MJ_CREATE - windows-7

I'd like to change a file when it is closed and reverse the change when it is opened.
It's kind of like encryption driver except I don't want to encrypt the file.
I've created a new "Filter Driver: Filesystem Mini-Filter" project with WDK8 in Visual Studio 2012 and registered PreCreate, PostCreate, PreClose and PostClose as callback functions.
For example, on IRP_MJ_CLOSE of file which it's byte are {72,101,108,108,111} ("Hello"), I want that after the PostClose function the file would look like this on the hard disk:
{10,11,12,72,101,108,108,111}.
I suspect it is not as easy as just:
FLT_PREOP_CALLBACK_STATUS
PreClose (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Flt_CompletionContext_Outptr_ PVOID *CompletionContext
)
{
//...
//some if statment...
{
Data->Iopb->Parameters.Write.WriteBuffer = newBfr;
Data->Iopb->Parameters.Write.Length = newLen;
}
//...
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
I'd like some guidance on the subject.
Also what is the best way to debug this? I Haven't found a way to print to the windows 7 debug.
Thanks!
gfgqtmakia.
EDIT: I've read http://code.msdn.microsoft.com/windowshardware/swapBuffer-File-System-6b7e6e2d but I don't think it'll help me because it is for read/write, which I don't want to deal with.
EDIT2: Or maybe I should do my changes in the PreCreate and PostClose, when the file is on the hard drive and not in the middle of an IRP, and then I won't need to deal with buffers "on the fly" but on the disk?

You will have to write something like swap buffers. Modifying file data in PostCreate/PreClose would not be good idea.
Few reasons:
Firstly in PostCreate/PreClose you shouldn't be accessing Data->Iopb->Parameters.Write.WriteBuffer. That is valid only in IRP_MJ_WRITE. You can do FltWriteFile to write data to file.
Windows kernel may not write file data immediately to the disk in/after IRP_MJ_CLOSE. Think about page cache.
There are may complexities like paging i/o, direct i/o etc. that need to be taken care properly.
Another major thing I notice it that you will also change the file size (as said in your question actual data length is 5 bytes while you will update data to 8 bytes). Now this is very difficult to manage. It never recommended to change the file size in minifilter/file system driver.

Related

Read a chunk of a file using WINAPI's ReadFile or something similar?

Well, I'm working on a project, in which I'm handling potentially big files, that I can't load into ram all at once, so I'm going to treat them like a CHS hard drive, and grab the data one 0x800 byte chunk at a time.
My problem is, I cannot find any functions in the WINAPI that allow me to read the data from a file I've opened with CreateFile, starting at an offset.
And yes, it must be a WINAPI function, and no, I do not want to map the whole file into memory.
Thanks much, Bradley.
Use ReadFile with SetFilePointer

Why does DeviceIoControl prepend 12 bytes of information to the user-provided input buffer?

I hope this does not turn out to be a totally braindead question.
I am editing a template WDF Windows USB device driver to send formatted data to one of the device's bulk out pipes; the data has to be set up in a certain way to tell the device to read an internal register.
The problem is that I cannot get the data to go across the bus in the exact format necessary. I wrote a small test app to enumerate the device and call DeviceIoControl with the input buffer set to a struct I set up according to spec.
I have a copy of a USB bus trace for a working case (performed by a driver whose source I have no access to), and I captured a bus trace for what happens when I call the custom IOCTL in my driver. What I see go across the bus is the data structure I set up prefixed with twelve bytes of data; the data structure is correct, but I want to know what the initial twelve bytes of data are, and stop the driver from sending them.
The driver, I believe, has been written properly; I put some debug traces in the driver and it looks like the buffer retrieved by WdfRequestRetrieveInputMemory already has the 12 bytes prepended, so this seems like this is happening pre-driver.
If it is useful information, the IOCTL is set up as METHOD_BUFFERED with FILE_ANY_ACCESS.
The relevant portion of the test code that sets this up is very simple:
const ULONG ulBufferSize = sizeof( CONTROL_READ_DATA );
unsigned char pBuffer[sizeof(CONTROL_READ_DATA)];
DWORD dwBytesReturned;
CONTROL_READ_DATA* readData = (CONTROL_READ_DATA*)pBuffer;
readData->field1 = data;
readData->field2 = moreData;
// ... all fields filled in...
// Send IOCTLs into camera
if( !::DeviceIoControl( hDevice,
IOCTL_CUSTOM_000,
&readData,
ulBufferSize,
&readData,
ulBufferSize,
&dwBytesReturned,
NULL ) )
{
dwError = ::GetLastError();
// Clean up here
return dwError;
}
The data I see go across the bus is: 80FD1200 CCCCCCCC CCCCCCCC + (My data).
Does anyone have any insights?
Wow, really ridiculous error. Notice I'm passing the address of readData to DeviceIoControl, which itself is already a pointer. I can't believe I wasted so much time on this.
Thanks all!
Alignment of the data is the culprit. Check out http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.80).aspx to set it to one.

Is it possible to save some data parmanently in AVR Microcontroller?

Well, the question says it all.
What I would like to do is that, every time I power up the micro-controller, it should take some data from the saved data and use it. It should not use any external flash chip.
If possible, please give some code-snippet so that I can use them in AVR studio 4. for example if I save 8 uint16_t data it should load those data into an array of uint16_t.
You have to burn the data to the program memory of the chip if you don't need to update them programmatically, or if you want read-write support, you should use the built-in EPROM.
Pgmem example:
#include <avr/pgmspace.h>
PROGMEM uint16_t data[] = { 0, 1, 2, 3 };
int main()
{
uint16_t x = pgm_read_word_near(data + 1); // access 2nd element
}
You need to get the datasheet for the part you are using. Microcontrollers like these typically contain at least a flash and sometimes multiple banks of flash to allow for different bootloaders while making it easy to erase one whole flash without affecting another. Likewise some have eeprom. This is all internal, not external. Esp since you say you need to save programatically this should work (remember how easy it is to wear out a flash do dont save unless you need to). Either eeprom or flash will meet the requirement of having that information there when you power up, non-volatile. As well as being able to save it programmatically. Googling will find a number of examples on how to do this, in addition to the datasheet you apparently have not read, as well as the app notes that also contain this information (that you should have read). If you are looking for some sort of one time programmable fuse blowing thing, there may be OTP versions of the avr, and you will have to read the datasheets, programmers references and app notes on how to program that memory, and should tell you if OTP parts can be written programmatically or if they are treated differently.
The reading of the data is in the memory map in the datasheet, write code to read those adresses. Writing is described in the datasheet (programmers reference manual, users guide, whatever atmel calls it) as well and there are many examples on the net.

Programmatically registering a performance counter in the registry

I'm trying to register a performance counter and part of this process includes adding some textual descriptions to a specific registry key. For English this key is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 which apparently is also known as HKEY_PERFORMANCE_TEXT. There are a pair of values under there (Counter, Help) that have REG_MULTI_SZ data, and I need to modify them to accomplish my goal.
The official way of doing this is by using a tool called lodctr along with a .h and .ini file. There is also a function for doing this programmatically, but my understanding is that it is just a simple wrapper around calling the lodctr program. I found the prospect of maintaining, distributing, and keeping synchronized 3 separate files a bit cumbersome, so I previously wrote code to do this and it worked fine under Windows XP (and possibly Vista, though I don't remember for sure).
Now I'm trying to use the same code on Windows 7 and it doesn't work. The problem is that whenever I try to set the registry values it fails with ERROR_BADKEY; even regedit fails to modify the values, so it's not a problem with my code. I ran Process Monitor against it and noticed that there was no activity at the driver level, so it seems this access must be getting blocked in user-mode code (e.g. advapi32.dll or wherever). I understand why Microsoft would try to prevent people from doing this as it is very easy to screw up, and doing so will screw up the entire performance counter collection on the machine.
I'm going to debug lodctr and see what the magic is purely out of curiosity, but I'm wondering if anybody has run into this before? Are there any alternatives other than the lodctr utility? Perhaps calling the NT registry API directly? I would really prefer to avoid the hassle of the lodctr method if possible.
A minimal example to reproduce the issue:
HKEY hKey = NULL;
LONG nResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009"), 0, KEY_ALL_ACCESS, &hKey);
if(ERROR_SUCCESS == nResult)
{
LPCTSTR lpData = _T("bar");
DWORD cbData = (_tcsclen(lpData) + 1) * sizeof(TCHAR);
nResult = RegSetValueEx(hKey, _T("foo"), 0, REG_SZ, (const BYTE*)lpData, cbData);
// here nResult == ERROR_BADKEY
RegCloseKey(hKey);
hKey = NULL;
}
EDIT 1:
I spent about an hour or so trying to debug the official APIs and couldn't figure it out so I tried some more Google. After a while I came across this KB article which explains the RegSetValueEx behavior. Since it mentioned modifying system files that got me to thinking that perhaps this particular registry data is backed by a mapped file. Then I came across another KB article that mentions Perfc009.dat and Perfh009.dat in the system32 folder. Opened these up in a hex editor and sure enough it is the raw REG_MULTI_SZ data I am trying to modify. Now that I know that maybe I can take another look and figure it out, though I am bored with it for now.
Never mind, I give up. It's easier to just go with the flow. Instead of trying to modify the registry directly, I will create the .h and .ini files programmatically and invoke the relevant functions.

Equivalent to pread/pwrite in MSVC?

What calls best emulate pread/pwrite in MSVC 10?
At the C runtime library level, look at fread, fwrite and fseek.
At the Win32 API level, have a look at ReadFile, WriteFile, and SetFilePointer. MSDN has extensive coverage of file I/O API's.
Note that both ReadFile and WriteFile take an OVERLAPPED struct argument, which lets you specify a file offset. The offset is respected for all files that support byte offsets, even when opened for synchronous (i.e. non 'overlapped') I/O.
Depending on the problem you are trying to solve, file mapping may be a better design choice.
It looks like you just use the lpOverlapped parameter to ReadFile/WriteFile to pass a pointer to an OVERLAPPED structure with the offset specified in Offset and OffsetHigh.
(Note: You don't actually get overlapping IO unless the handle was opened with FILE_FLAG_OVERLAPPED.)
The answer provided by Oren seems correct but doesn't seem to meet the needs. Actually, I too was here for searching the answer but couldn't find it. So, I will update a bit here.
As said,
At the C runtime library level, there are fread, fwrite and fseek.
At the Win32 API level, we can have two level of abstractions. One at the lower level which works with file descriptors and other at higher level which works with Windows' defined data structures such as File and Handle.
If you wish to work with Files and Handles, you have ReadFile, WriteFile, and SetFilePointer. But most the time, C++ developers prefer working with File Descriptors. For that, you have _read, _write and _lseek.

Resources