Problem when starting my mini filter driver

hi,

i am learning how to write a mini filter driver. below is my simple code.
the problem is: on Win7, i can load the driver in (i can verify its
existence in the output of “driverquery” command), but when i start it
with command:

net start mymini

it reports error like: “System error 2 has occurred. The system cannot
find the file specified.”

meanwhile, DbgView reports “ERROR FltRegisterFilter - c0000034”

perhaps my code gets wrong somewhere. please would anybody help me to
fix this problem?

many thanks,
J


#include <ntifs.h>
#include <wdm.h>

#include <fltkernel.h>
#include <ntstrsafe.h>

static NTSTATUS FilterUnload (IN FLT_FILTER_UNLOAD_FLAGS Flags);

static NTSTATUS SetupCallback (IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_SETUP_FLAGS Flags,
IN DEVICE_TYPE VolumeDeviceType,
IN FLT_FILESYSTEM_TYPE VolumeFilesystemType);

static NTSTATUS MessageCallback (
in PVOID ConnectionCookie,
in_bcount_opt(InputBufferSize) PVOID InputBuffer,
in ULONG InputBufferSize,
out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength)
PVOID OutputBuffer,
in ULONG OutputBufferSize,
out PULONG ReturnOutputBufferLength);

static CONST FLT_OPERATION_REGISTRATION Callbacks = {
{ IRP_MJ_OPERATION_END }
};

const FLT_CONTEXT_REGISTRATION Contexts = {
{ FLT_CONTEXT_END }
};

static CONST FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION),
FLT_REGISTRATION_VERSION,
0,
Contexts,
Callbacks,
FilterUnload,
SetupCallback,
NULL, NULL, NULL, NULL, NULL, NULL
};

static PFLT_FILTER retfilter;

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
status = FltRegisterFilter(DriverObject, &FilterRegistration, &retfilter);
if (!NT_SUCCESS(status)) {
DbgPrint(“ERROR FltRegisterFilter - %08x\n”, status);
return status;
}

DbgPrint(“Successfully Loaded\n”);

return STATUS_SUCCESS;
}

static NTSTATUS FilterUnload (IN FLT_FILTER_UNLOAD_FLAGS Flags)
{
FltUnregisterFilter(retfilter);

return STATUS_SUCCESS;
}

static NTSTATUS SetupCallback (IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_SETUP_FLAGS Flags,
IN DEVICE_TYPE VolumeDeviceType,
IN FLT_FILESYSTEM_TYPE VolumeFilesystemType)
{
return STATUS_SUCCESS;
}

static NTSTATUS MessageCallback (
in PVOID ConnectionCookie,
in_bcount_opt(InputBufferSize) PVOID InputBuffer,
in ULONG InputBufferSize,
out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength)
PVOID OutputBuffer,
in ULONG OutputBufferSize,
out PULONG ReturnOutputBufferLength)
{
return STATUS_SUCCESS;
}</ntstrsafe.h></fltkernel.h></wdm.h></ntifs.h>

This kind of error occurs when the driver file it is trying to load is missing.Say for this case I suppose you have named the driver file as “mymini.sys” which is not in the directory it is searching the file for in the loader routine,just check it.So the FltRegisterFilter service you have registered is showing errors.

Well, he said he can see his output from DriverEntry so it can not be driver file not found. Isn’t it?

@OP

I don’t really know the answer but can you try specifying something in Callbacks, its a guess but may be its not able to register if there is nothing to filter.

The error 0xc0000034 is STATUS_OBJECT_NAME_NOT_FOUND.
You return this from DriverEntry, so this will be result of StartService (translated to win32 error code).

@OP: So do you net start the driver while it is already loaded? Why?

To avoid confusion, return from DriverEntry only certain statuses,
for example STATUS_UNSUCCESSFUL, rather than just propagate whatever error you get in the process.
– pa

>>So do you net start the driver while it is already loaded?

If so, I must say the API should return something more sensible, (already in use or something similar). Lets see if it really is what OP is doing.

Aditya

On Wed, Oct 27, 2010 at 8:45 PM, wrote:
> The error 0xc0000034 is STATUS_OBJECT_NAME_NOT_FOUND.
> You return this from DriverEntry, so this will be result of StartService (translated to win32 error code).
>
> @OP: So do you net start the driver while it is already loaded? Why?

Because otherwise the DriverEntry() is not executed, no?

My experience is like this: I have a small utility to load my driver
in, like the code below. I run that to load my driver in, then to
really make it run, I need to start it with “net start …”

Is that not what we are supposed to do??

I am still a newbie to driver programming, so please tell me if I am wrong?

Thanks,
J

------

#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
SC_HANDLE sh1, sh2;

sh1 = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!sh1) {
printf(“Failed on OpenSCManager!\n”);
return -1;
}

sh2 = CreateService(sh1,
“mymini”,
“mymini”,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
“c:\windows\system32\drivers\mymini.sys”,
NULL, NULL, NULL, NULL, NULL);
if (!sh2) {
if (GetLastError() == ERROR_SERVICE_EXISTS)
printf(“mymini already loaded!\n”);
else {
printf(“Failed to load mymini!\n”);
return -1;
}
} else {
printf(“\nmymini loaded!\n”);
}

return 0;
}</stdio.h></windows.h>

On Wed, Oct 27, 2010 at 4:32 PM, wrote:
> This kind of error occurs when the driver file it is trying to load is missing.Say for this case I suppose you have named the driver file as “mymini.sys” which is not in the directory it is searching the file for in the loader routine,just check it.So the FltRegisterFilter service you have registered is showing errors.
>

i put the driver file (mymini.sys) into c:\windows\system32\drivers,
but it doesnt help

i am on Windows 64bit, if that matters.

thanks,
J

So Mr. Pavel was correct.

>My experience is like this: I have a small utility to load my driver in, like the code below. I run that to load my driver in, then to really make it run, I need to start it with “net start …”

No you are not suppose to do it. Either do a net start or NtLoadDriver.

Once your driver entry called, its DriverEntry responsibility to do things as per your architecture. For example if it is a software only driver, it will create a device object and initialize certain major functions. If it is a FS mini filter driver it will register it with FltMgr etc.

Now I assume though it gets loaded, you are not getting any IRPs? That is because you have not asked for a single callback (create, read , write)?

I suggest you first do some reading and play with normal drivers (software only), than jump to mini filter.

Aditya

That will depend on what type of driver is being loaded. If it is a driver
associated with a device then that driver will be loaded during bus
enumeration when drivers are loaded for devices found on the bus. However,
there are drivers, such as non-Pnp drivers that can be installed using SC
and SCM commands from an application such as you are using. How the driver
starts, and DriverEntry called, can be determined by how you set the “Start”
value field in the service registry key for the driver. If it is set to a 3,
then you either use “net start ”, start-service , or the
ServiceManager function StartService passing the name of the service to
start.

Gary G. Little
H (952) 223-1349
C (952) 454-4629
xxxxx@comcast.net

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Jun Koi
Sent: Wednesday, October 27, 2010 10:29 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Problem when starting my mini filter driver

On Wed, Oct 27, 2010 at 8:45 PM, wrote:
> The error 0xc0000034 is STATUS_OBJECT_NAME_NOT_FOUND.
> You return this from DriverEntry, so this will be result of StartService
(translated to win32 error code).
>
> @OP: So do you net start the driver while it is already loaded? Why?

Because otherwise the DriverEntry() is not executed, no?

My experience is like this: I have a small utility to load my driver in,
like the code below. I run that to load my driver in, then to really make it
run, I need to start it with “net start …”

Is that not what we are supposed to do??

I am still a newbie to driver programming, so please tell me if I am wrong?

Thanks,
J

------

#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
SC_HANDLE sh1, sh2;

sh1 = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!sh1) {
printf(“Failed on OpenSCManager!\n”);
return -1;
}

sh2 = CreateService(sh1,
“mymini”,
“mymini”,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
“c:\windows\system32\drivers\mymini.sys”,
NULL, NULL, NULL, NULL, NULL);
if (!sh2) {
if (GetLastError() == ERROR_SERVICE_EXISTS)
printf(“mymini already loaded!\n”);
else {
printf(“Failed to load mymini!\n”);
return -1;
}
} else {
printf(“\nmymini loaded!\n”);
}

return 0;
}


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Information from ESET Smart Security, version of virus signature
database 5569 (20101027)


The message was checked by ESET Smart Security.

http://www.eset.com</stdio.h></windows.h>

@OP: You are correct, after having created the service (what you called “loaded”),
net start will actually start the driver.
Since the debug message is displayed, the CreateService part worked well;
now find out why FltRegisterFilter failed.

Still, I’d suggest to use a constant return value of DriverEntry, to avoid possible
confusion with “file not found” situations.

Also, instead of the little program to create the service,
a simple “sc create” or INF installer would go, but that is matter of taste.

Regards,
– pa

hmm, Now I realized that though technically OK my last post did not really made *any* point. I thought you are first loading the driver with NtLoadDriver and than using this service method as well. My BAD.

So here is your problem,

your call to CreateService does not create all registry entries required by a minifilter, for example “Instance”, which specify the altitude for the driver. Now when you call FltRegisterFilter it calls Registry APIs to find the value of defaultInstance as it needs it to place the driver, It does not found those and hence returns the error.

You are better with an inf taken from WDK samples. modify it and it should work. I also checked that empty callback is fine.

Additionally to correct the nomenclature,

printf(“mymini already loaded!\n”); should be mymini already exist &
printf(“Failed to load mymini!\n”); failed to create mymini

CreateService is not loading them here, its just creating the registry key for you. It is getting loaded on your call to net start.

Thanks
Aditya

Your code does not “load” the driver. It installs it (i.e., creates a system service which is your kernel driver). “Net start” is what is “loading” it. To start it programmatically, you’d have to use the StartService API. Net start will FAIL if the driver is already loaded (as will startService- both will indicate the service is already started).


#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
SC_HANDLE sh1, sh2;

sh1 = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!sh1) {
printf(“Failed on OpenSCManager!\n”);
return -1;
}

sh2 = CreateService(sh1,
“mymini”,
“mymini”,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
“c:\windows\system32\drivers\mymini.sys”,
NULL, NULL, NULL, NULL, NULL);
if (!sh2) {
if (GetLastError() == ERROR_SERVICE_EXISTS)
printf(“mymini already loaded!\n”);
else {
printf(“Failed to load mymini!\n”);
return -1;
}
} else {
printf(“\nmymini loaded!\n”);
}

return 0;
}</stdio.h></windows.h>

Jun Koi wrote:

On Wed, Oct 27, 2010 at 8:45 PM, wrote:
>> The error 0xc0000034 is STATUS_OBJECT_NAME_NOT_FOUND.
>> You return this from DriverEntry, so this will be result of StartService (translated to win32 error code).
>>
>> @OP: So do you net start the driver while it is already loaded? Why?
> Because otherwise the DriverEntry() is not executed, no?
>
> My experience is like this: I have a small utility to load my driver
> in, like the code below. I run that to load my driver in, then to
> really make it run, I need to start it with “net start …”
>
> Is that not what we are supposed to do??

This is fine IF you are a legacy driver – meaning a non-plug-and-play
driver. If you are PnP, then you cannot use “net start”.

By the way, you don’t need to write a program to do what you’re doing.
That ability is built-in to the “sc” command;

sc create mymini type= kernel start= demand binpath=
system32\drivers\mymini.sys

Note the odd syntax. The = is part of the keyword.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Jun Koi wrote:

i put the driver file (mymini.sys) into c:\windows\system32\drivers,
but it doesnt help

i am on Windows 64bit, if that matters.

Did you build a 64-bit driver?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

>>Did you build a 64-bit driver?

His driver is loaded so his binary is OK. I believe all he has to do is create minifilter specific entries manually as CreateService does not create them.

On Fri, Oct 29, 2010 at 2:02 AM, wrote:
> hmm, Now I realized that though technically OK my last post did not really made any point. I thought you are first loading the driver with NtLoadDriver and than using this service method as well. My BAD.
>
> So here is your problem,
>
> your call to CreateService does not create all registry entries required by a minifilter, for example “Instance”, which specify the altitude for the driver. Now when you call FltRegisterFilter it calls Registry APIs to find the value of defaultInstance as it needs it to place the driver, It does not found those and hence returns the error.
>

now it is more clear to see for me that what is really wrong if my code.

i think it is possible to properly create a service for minifilter
driver without using an INF. a question: any sample code to do so? or
if not, what are the programming steps to do that?

> You are better with an inf taken from WDK samples. modify it and it should work. I also checked that empty callback is fine.
>
> Additionally to correct the nomenclature,
>
> printf(“mymini already loaded!\n”); should be mymini already exist &
> printf(“Failed to load mymini!\n”); failed to create mymini
>
> CreateService is not loading them here, its just creating the registry key for you. It is getting loaded on your call to net start.

this is really helpful, thanks!!

Jun

On Fri, Oct 29, 2010 at 3:18 AM, Tim Roberts wrote:
> Jun Koi wrote:
>>
>> i put the driver file (mymini.sys) into c:\windows\system32\drivers,
>> but it doesnt help
>>
>> i am on Windows 64bit, if that matters.
>
> Did you build a 64-bit driver?
>

yes, that is what i want to do.

thanks,
J

On Fri, Oct 29, 2010 at 3:17 AM, Tim Roberts wrote:
> Jun Koi wrote:
>> On Wed, Oct 27, 2010 at 8:45 PM, ? wrote:
>>> The error 0xc0000034 is STATUS_OBJECT_NAME_NOT_FOUND.
>>> You return this from DriverEntry, so this will be result of StartService (translated to win32 error code).
>>>
>>> @OP: So do you net start the driver while it is already loaded? Why?
>> Because otherwise the DriverEntry() is not executed, no?
>>
>> My experience is like this: I have a small utility to load my driver
>> in, like the code below. I run that to load my driver in, then to
>> really make it run, I need to start it with “net start …”
>>
>> Is that not what we are supposed to do??
>
> This is fine IF you are a legacy driver – meaning a non-plug-and-play
> driver. ?If you are PnP, then you cannot use “net start”.
>
> By the way, you don’t need to write a program to do what you’re doing.
> That ability is built-in to the “sc” command;
>
> ? ?sc ?create ?mymini ?type= ?kernel ?start= ?demand ?binpath=
> system32\drivers\mymini.sys

so if we run with “start=auto”, my driver will be loaded in, and
initialized immediately, without any additional step?

i looked at the help of sc (sc /?), but its instruction is pretty compact.

many thanks!
J

No.

If your driver is a non pnp driver, it means that it will be loaded by the
system automatically at the next reboot. If you want it to run ASAP, you
will still need to NET START it the first time.

If your driver IS a pnp driver, it means that the system will start your
driver when it determines that it needs to do so, based on the
insertion/removal of devices.

Also, as I think Tim already mentioned, the syntax of SC is deranged - that
needs to be ‘start= auto’ (not ‘start=auto’).

Good luck,

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Jun Koi
Sent: Sunday, October 31, 2010 11:08 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Problem when starting my mini filter driver

On Fri, Oct 29, 2010 at 3:17 AM, Tim Roberts wrote:
> Jun Koi wrote:
>> On Wed, Oct 27, 2010 at 8:45 PM, ? wrote:
>>> The error 0xc0000034 is STATUS_OBJECT_NAME_NOT_FOUND.
>>> You return this from DriverEntry, so this will be result of StartService
(translated to win32 error code).
>>>
>>> @OP: So do you net start the driver while it is already loaded? Why?
>> Because otherwise the DriverEntry() is not executed, no?
>>
>> My experience is like this: I have a small utility to load my driver
>> in, like the code below. I run that to load my driver in, then to
>> really make it run, I need to start it with “net start …”
>>
>> Is that not what we are supposed to do??
>
> This is fine IF you are a legacy driver – meaning a non-plug-and-play
> driver. ?If you are PnP, then you cannot use “net start”.
>
> By the way, you don’t need to write a program to do what you’re doing.
> That ability is built-in to the “sc” command;
>
> ? ?sc ?create ?mymini ?type= ?kernel ?start= ?demand ?binpath=
> system32\drivers\mymini.sys

so if we run with “start=auto”, my driver will be loaded in, and
initialized immediately, without any additional step?

i looked at the help of sc (sc /?), but its instruction is pretty compact.

many thanks!
J


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer