My driver is written in C++ and all dispatch routines are defined as
static member functions of the class KnDriverObject, for example:
class KnDriverObject
{
public:
static
NTSTATUS
DispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
…
};
In DriverEntry I initialize the dispatch table as usual:
extern “C”
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
…
DriverObject->MajorFunction[IRP_MJ_CREATE] =
KnDriverObject::DispatchCreate;
…
}
When I run PFD on this then for the assignment above I get:
warning 28155: The function being assigned or passed should be a
DRIVER_DISPATCH function: Add the declaration ‘DRIVER_DISPATCH
;’ before the current first declaration of .
Obviously, if DispatchCreate is declared as a static member function
then PFD does not deduce that it is a DRIVER_DISPATCH function and
issues that warning. The warning message (and the docs) suggest to add
an explicit declaration like
DRIVER_DISPATCH DispatchCreate;
I tried that without success. How can I do that for a static member
function?
Are there any other suggestions that may help to make PFD believe that
KnDriverObject::DispatchCreate is a DRIVER_DISPATCH function?
Thanks in advance.
Udo
Maybe this is one of the reasons why C++ is not supported for writing drivers.
Automatic tools do not fully understand every c++ quirk.
–PA
“Udo Eberhardt” wrote in message news:xxxxx@ntdev…
> My driver is written in C++ and all dispatch routines are defined as static member functions of the class KnDriverObject, for
> example:
>
> class KnDriverObject
> {
> public:
>
> static
> NTSTATUS
> DispatchCreate(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> );
>
> …
>
> };
>
> In DriverEntry I initialize the dispatch table as usual:
>
> extern “C”
> NTSTATUS
> DriverEntry(
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> …
>
> DriverObject->MajorFunction[IRP_MJ_CREATE] =
> KnDriverObject::DispatchCreate;
>
> …
>
> }
>
>
> When I run PFD on this then for the assignment above I get:
> warning 28155: The function being assigned or passed should be a DRIVER_DISPATCH function: Add the declaration
> ‘DRIVER_DISPATCH ;’ before the current first declaration of .
>
> Obviously, if DispatchCreate is declared as a static member function then PFD does not deduce that it is a DRIVER_DISPATCH
> function and issues that warning. The warning message (and the docs) suggest to add an explicit declaration like
>
> DRIVER_DISPATCH DispatchCreate;
>
> I tried that without success. How can I do that for a static member function?
>
> Are there any other suggestions that may help to make PFD believe that KnDriverObject::DispatchCreate is a DRIVER_DISPATCH
> function?
>
> Thanks in advance.
> Udo
>
I use C++ in drivers for years now. I know what I’m doing and I know the
potential pitfalls. I use a well-defined subset of C++ only. I
successfully created many drivers with this approach, many of them are
WHQL-signed. Apart from that, with the WDK MS ships many samples written
in C++ and they are using C++ internally to create drivers. But, I
really don’t want to restart this C++ vs. C debate…
The doc states that PFD supports C++. So I would expect that there is a
way to make the concept of a static member function understandable to PFD.
Udo
Pavel A. wrote:
Maybe this is one of the reasons why C++ is not supported for writing drivers.
Automatic tools do not fully understand every c++ quirk.
–PA
“Udo Eberhardt” wrote in message news:xxxxx@ntdev…
>> My driver is written in C++ and all dispatch routines are defined as static member functions of the class KnDriverObject, for
>> example:
>>
>> class KnDriverObject
>> {
>> public:
>>
>> static
>> NTSTATUS
>> DispatchCreate(
>> IN PDEVICE_OBJECT DeviceObject,
>> IN PIRP Irp
>> );
>>
>> …
>>
>> };
>>
>> In DriverEntry I initialize the dispatch table as usual:
>>
>> extern “C”
>> NTSTATUS
>> DriverEntry(
>> IN PDRIVER_OBJECT DriverObject,
>> IN PUNICODE_STRING RegistryPath
>> )
>> {
>> …
>>
>> DriverObject->MajorFunction[IRP_MJ_CREATE] =
>> KnDriverObject::DispatchCreate;
>>
>> …
>>
>> }
>>
>>
>> When I run PFD on this then for the assignment above I get:
>> warning 28155: The function being assigned or passed should be a DRIVER_DISPATCH function: Add the declaration
>> ‘DRIVER_DISPATCH ;’ before the current first declaration of .
>>
>> Obviously, if DispatchCreate is declared as a static member function then PFD does not deduce that it is a DRIVER_DISPATCH
>> function and issues that warning. The warning message (and the docs) suggest to add an explicit declaration like
>>
>> DRIVER_DISPATCH DispatchCreate;
>>
>> I tried that without success. How can I do that for a static member function?
>>
>> Are there any other suggestions that may help to make PFD believe that KnDriverObject::DispatchCreate is a DRIVER_DISPATCH
>> function?
>>
>> Thanks in advance.
>> Udo
>>
>
>
>
Did you try
class …
public:
static DRIVER_DISPATCH DispatchCreate;
also, you try to cast the pointer when assigning
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)
KnDriverObject::DispatchCreate;
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Udo Eberhardt
Sent: Friday, December 15, 2006 5:31 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Prefast warning on driver dispatch functions
My driver is written in C++ and all dispatch routines are defined as
static member functions of the class KnDriverObject, for example:
class KnDriverObject
{
public:
static
NTSTATUS
DispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
…
};
In DriverEntry I initialize the dispatch table as usual:
extern “C”
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
…
DriverObject->MajorFunction[IRP_MJ_CREATE] =
KnDriverObject::DispatchCreate;
…
}
When I run PFD on this then for the assignment above I get:
warning 28155: The function being assigned or passed should be a
DRIVER_DISPATCH function: Add the declaration ‘DRIVER_DISPATCH
;’ before the current first declaration of .
Obviously, if DispatchCreate is declared as a static member function
then PFD does not deduce that it is a DRIVER_DISPATCH function and
issues that warning. The warning message (and the docs) suggest to add
an explicit declaration like
DRIVER_DISPATCH DispatchCreate;
I tried that without success. How can I do that for a static member
function?
Are there any other suggestions that may help to make PFD believe that
KnDriverObject::DispatchCreate is a DRIVER_DISPATCH function?
Thanks in advance.
Udo
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
Doron Holan wrote:
Did you try
class …
public:
static DRIVER_DISPATCH DispatchCreate;
This has no effect. PFD still issues the warning.
also, you try to cast the pointer when assigning
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)
KnDriverObject::DispatchCreate;
I tried
DriverObject->MajorFunction[IRP_MJ_CREATE] =
(DRIVER_DISPATCH*)KnDriverObject::DispatchCreate;
Also has no effect. PFD still issues the warning.
Udo
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Udo Eberhardt
Sent: Friday, December 15, 2006 5:31 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Prefast warning on driver dispatch functions
My driver is written in C++ and all dispatch routines are defined as
static member functions of the class KnDriverObject, for example:
class KnDriverObject
{
public:
static
NTSTATUS
DispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
…
};
In DriverEntry I initialize the dispatch table as usual:
extern “C”
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
…
DriverObject->MajorFunction[IRP_MJ_CREATE] =
KnDriverObject::DispatchCreate;
…
}
When I run PFD on this then for the assignment above I get:
warning 28155: The function being assigned or passed should be a
DRIVER_DISPATCH function: Add the declaration ‘DRIVER_DISPATCH
;’ before the current first declaration of .
>
> Obviously, if DispatchCreate is declared as a static member function
> then PFD does not deduce that it is a DRIVER_DISPATCH function and
> issues that warning. The warning message (and the docs) suggest to add
> an explicit declaration like
>
> DRIVER_DISPATCH DispatchCreate;
>
> I tried that without success. How can I do that for a static member
> function?
>
> Are there any other suggestions that may help to make PFD believe that
> KnDriverObject::DispatchCreate is a DRIVER_DISPATCH function?
>
> Thanks in advance.
> Udo
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
Prefast has no such language restriction. The tool is part of visual studio
2005 and claims to fully support c++.
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-273091-
xxxxx@lists.osr.com] On Behalf Of Pavel A.
Sent: Friday, December 15, 2006 9:56 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Prefast warning on driver dispatch functions
Maybe this is one of the reasons why C++ is not supported for writing
drivers.
Automatic tools do not fully understand every c++ quirk.
–PA
“Udo Eberhardt” wrote in message
> news:xxxxx@ntdev…
> > My driver is written in C++ and all dispatch routines are defined as
> static member functions of the class KnDriverObject, for
> > example:
> >
> > class KnDriverObject
> > {
> > public:
> >
> > static
> > NTSTATUS
> > DispatchCreate(
> > IN PDEVICE_OBJECT DeviceObject,
> > IN PIRP Irp
> > );
> >
> > …
> >
> > };
> >
> > In DriverEntry I initialize the dispatch table as usual:
> >
> > extern “C”
> > NTSTATUS
> > DriverEntry(
> > IN PDRIVER_OBJECT DriverObject,
> > IN PUNICODE_STRING RegistryPath
> > )
> > {
> > …
> >
> > DriverObject->MajorFunction[IRP_MJ_CREATE] =
> > KnDriverObject::DispatchCreate;
> >
> > …
> >
> > }
> >
> >
> > When I run PFD on this then for the assignment above I get:
> > warning 28155: The function being assigned or passed should be a
> DRIVER_DISPATCH function: Add the declaration
> > ‘DRIVER_DISPATCH ;’ before the current first
> declaration of .
> >
> > Obviously, if DispatchCreate is declared as a static member function
> then PFD does not deduce that it is a DRIVER_DISPATCH
> > function and issues that warning. The warning message (and the docs)
> suggest to add an explicit declaration like
> >
> > DRIVER_DISPATCH DispatchCreate;
> >
> > I tried that without success. How can I do that for a static member
> function?
> >
> > Are there any other suggestions that may help to make PFD believe
> that KnDriverObject::DispatchCreate is a DRIVER_DISPATCH
> > function?
> >
> > Thanks in advance.
> > Udo
> >
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
When I run into obvious perfast idiocy I simply pragma my way out of it. It
seems much simpler and far less painful than banging my head against this
particular wall. Lint or prefast is useful when it catches problems, when it
catches non-problems it needs to be avoided. Re-arranging good code to
handle prefast misfires seems the wrong way to go - the pragmas document the
problem and leave your code as it was.
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-273098-
xxxxx@lists.osr.com] On Behalf Of Udo Eberhardt
Sent: Friday, December 15, 2006 10:33 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Prefast warning on driver dispatch functions
I use C++ in drivers for years now. I know what I’m doing and I know
the
potential pitfalls. I use a well-defined subset of C++ only. I
successfully created many drivers with this approach, many of them are
WHQL-signed. Apart from that, with the WDK MS ships many samples
written
in C++ and they are using C++ internally to create drivers. But, I
really don’t want to restart this C++ vs. C debate…
The doc states that PFD supports C++. So I would expect that there is a
way to make the concept of a static member function understandable to
PFD.
Udo
Pavel A. wrote:
> Maybe this is one of the reasons why C++ is not supported for writing
drivers.
> Automatic tools do not fully understand every c++ quirk.
>
> --PA
>
>
>
> “Udo Eberhardt” wrote in message
> news:xxxxx@ntdev…
> >> My driver is written in C++ and all dispatch routines are defined as
> static member functions of the class KnDriverObject, for
> >> example:
> >>
> >> class KnDriverObject
> >> {
> >> public:
> >>
> >> static
> >> NTSTATUS
> >> DispatchCreate(
> >> IN PDEVICE_OBJECT DeviceObject,
> >> IN PIRP Irp
> >> );
> >>
> >> …
> >>
> >> };
> >>
> >> In DriverEntry I initialize the dispatch table as usual:
> >>
> >> extern “C”
> >> NTSTATUS
> >> DriverEntry(
> >> IN PDRIVER_OBJECT DriverObject,
> >> IN PUNICODE_STRING RegistryPath
> >> )
> >> {
> >> …
> >>
> >> DriverObject->MajorFunction[IRP_MJ_CREATE] =
> >> KnDriverObject::DispatchCreate;
> >>
> >> …
> >>
> >> }
> >>
> >>
> >> When I run PFD on this then for the assignment above I get:
> >> warning 28155: The function being assigned or passed should be a
> DRIVER_DISPATCH function: Add the declaration
> >> ‘DRIVER_DISPATCH ;’ before the current first
> declaration of .
> >>
> >> Obviously, if DispatchCreate is declared as a static member function
> then PFD does not deduce that it is a DRIVER_DISPATCH
> >> function and issues that warning. The warning message (and the docs)
> suggest to add an explicit declaration like
> >>
> >> DRIVER_DISPATCH DispatchCreate;
> >>
> >> I tried that without success. How can I do that for a static member
> function?
> >>
> >> Are there any other suggestions that may help to make PFD believe
> that KnDriverObject::DispatchCreate is a DRIVER_DISPATCH
> >> function?
> >>
> >> Thanks in advance.
> >> Udo
> >>
> >
> >
> >
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
> ----------
From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Mark Roddy[SMTP:xxxxx@hollistech.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, December 15, 2006 6:05 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Prefast warning on driver dispatch functions
When I run into obvious perfast idiocy I simply pragma my way out of it. It
seems much simpler and far less painful than banging my head against this
particular wall. Lint or prefast is useful when it catches problems, when it
catches non-problems it needs to be avoided. Re-arranging good code to
handle prefast misfires seems the wrong way to go - the pragmas document the
problem and leave your code as it was.
You’re right but the problem is to distinuish idiocy from real problem. In my experience PC-lint is right in most cases (when correctly pre-configured) although it may not be obvious. It is tempting to pragma/comment out the “no-problem” but it can be wrong. However, it can be different for prefast. In my experience it generates much more nonsense.
Best regards,
Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]
This is good advice. I also don’t like to re-arrange anything to quieten
prefast if it’s obvious that the tool is wrong. I will leave the code as
it is and look up the appropriate pragmas from the docs.
Udo
Mark Roddy wrote:
When I run into obvious perfast idiocy I simply pragma my way out of it. It
seems much simpler and far less painful than banging my head against this
particular wall. Lint or prefast is useful when it catches problems, when it
catches non-problems it needs to be avoided. Re-arranging good code to
handle prefast misfires seems the wrong way to go - the pragmas document the
problem and leave your code as it was.
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:bounce-273098-
> xxxxx@lists.osr.com] On Behalf Of Udo Eberhardt
> Sent: Friday, December 15, 2006 10:33 AM
> To: Windows System Software Devs Interest List
> Subject: Re:[ntdev] Prefast warning on driver dispatch functions
>
> I use C++ in drivers for years now. I know what I’m doing and I know
> the
> potential pitfalls. I use a well-defined subset of C++ only. I
> successfully created many drivers with this approach, many of them are
> WHQL-signed. Apart from that, with the WDK MS ships many samples
> written
> in C++ and they are using C++ internally to create drivers. But, I
> really don’t want to restart this C++ vs. C debate…
>
> The doc states that PFD supports C++. So I would expect that there is a
> way to make the concept of a static member function understandable to
> PFD.
>
> Udo
>
>
> Pavel A. wrote:
>> Maybe this is one of the reasons why C++ is not supported for writing
> drivers.
>> Automatic tools do not fully understand every c++ quirk.
>>
>> --PA
>>
>>
>>
>> “Udo Eberhardt” wrote in message
>> news:xxxxx@ntdev…
>>>> My driver is written in C++ and all dispatch routines are defined as
>> static member functions of the class KnDriverObject, for
>>>> example:
>>>>
>>>> class KnDriverObject
>>>> {
>>>> public:
>>>>
>>>> static
>>>> NTSTATUS
>>>> DispatchCreate(
>>>> IN PDEVICE_OBJECT DeviceObject,
>>>> IN PIRP Irp
>>>> );
>>>>
>>>> …
>>>>
>>>> };
>>>>
>>>> In DriverEntry I initialize the dispatch table as usual:
>>>>
>>>> extern “C”
>>>> NTSTATUS
>>>> DriverEntry(
>>>> IN PDRIVER_OBJECT DriverObject,
>>>> IN PUNICODE_STRING RegistryPath
>>>> )
>>>> {
>>>> …
>>>>
>>>> DriverObject->MajorFunction[IRP_MJ_CREATE] =
>>>> KnDriverObject::DispatchCreate;
>>>>
>>>> …
>>>>
>>>> }
>>>>
>>>>
>>>> When I run PFD on this then for the assignment above I get:
>>>> warning 28155: The function being assigned or passed should be a
>> DRIVER_DISPATCH function: Add the declaration
>>>> ‘DRIVER_DISPATCH ;’ before the current first
>> declaration of .
>>>> Obviously, if DispatchCreate is declared as a static member function
>> then PFD does not deduce that it is a DRIVER_DISPATCH
>>>> function and issues that warning. The warning message (and the docs)
>> suggest to add an explicit declaration like
>>>> DRIVER_DISPATCH DispatchCreate;
>>>>
>>>> I tried that without success. How can I do that for a static member
>> function?
>>>> Are there any other suggestions that may help to make PFD believe
>> that KnDriverObject::DispatchCreate is a DRIVER_DISPATCH
>>>> function?
>>>>
>>>> Thanks in advance.
>>>> Udo
>>>>
>>>
>>>
>> —
>> Questions? First check the Kernel Driver FAQ at
>> http://www.osronline.com/article.cfm?id=256
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
Although meanwhile I gave up and use #pragmas to suppress prefast
messages I want to post my latest findings from running PFD on a driver
implemented in C++. All statements apply to PFD shipped with WDK 6000.
PFD’s feature to infer the purpose of a function based on its signature
and return value (as documented in the WDK) seems generally not to work
if the function is declared as a static class member function.
Consequently PFD issues warning 28155 when the function is assigned or
passed as an argument, e.g. to IoQueueWorkItem. I had this problem for
various function types, particularly:
DRIVER_DISPATCH
DRIVER_UNLOAD
DRIVER_CANCEL
IO_COMPLETION_ROUTINE
IO_WORKITEM_ROUTINE
All of them are handled in a special way by PFD.
The only way to make PFD happy I found is:
- Declare the “offending” function outside of the class.
- Add a friend declaration to the class to allow access to protected and
private members.
- Additionally, add an explicit function type declaration before the
class declaration, e.g.:
static DRIVER_CANCEL KnIrpQueue_IrpCancelRoutine;
for a routine that was previously declared as
static KnIrpQueue::IrpCancelRoutine
I do not consider this as an acceptable solution because it contradicts
good C++ design. On the other hand, I think it can be very valuable if
PFD understands which of my functions is an IRP cancel routine. I found
that PFD performs some helpful checks in cancel routines, for example it
verifies whether the cancel spinlock is handled properly.
I hope anyone can suggest a better work-around for those problems with
static member functions.
Udo
Udo Eberhardt wrote:
Doron Holan wrote:
> Did you try
>
> class …
>
> public:
> static DRIVER_DISPATCH DispatchCreate;
>
This has no effect. PFD still issues the warning.
>
> also, you try to cast the pointer when assigning
>
> DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)
> KnDriverObject::DispatchCreate;
>
I tried
DriverObject->MajorFunction[IRP_MJ_CREATE] =
(DRIVER_DISPATCH*)KnDriverObject::DispatchCreate;
Also has no effect. PFD still issues the warning.
Udo
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Udo Eberhardt
> Sent: Friday, December 15, 2006 5:31 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] Prefast warning on driver dispatch functions
>
> My driver is written in C++ and all dispatch routines are defined as
> static member functions of the class KnDriverObject, for example:
>
> class KnDriverObject
> {
> public:
>
> static
> NTSTATUS
> DispatchCreate(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp
> );
>
> …
>
> };
>
> In DriverEntry I initialize the dispatch table as usual:
>
> extern “C”
> NTSTATUS
> DriverEntry(
> IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath
> )
> {
> …
>
> DriverObject->MajorFunction[IRP_MJ_CREATE] =
> KnDriverObject::DispatchCreate;
>
> …
>
> }
>
>
> When I run PFD on this then for the assignment above I get:
> warning 28155: The function being assigned or passed should be a
> DRIVER_DISPATCH function: Add the declaration ‘DRIVER_DISPATCH
> ;’ before the current first declaration of .
>>
>> Obviously, if DispatchCreate is declared as a static member function
>> then PFD does not deduce that it is a DRIVER_DISPATCH function and
>> issues that warning. The warning message (and the docs) suggest to add
>> an explicit declaration like
>>
>> DRIVER_DISPATCH DispatchCreate;
>>
>> I tried that without success. How can I do that for a static member
>> function?
>>
>> Are there any other suggestions that may help to make PFD believe that
>> KnDriverObject::DispatchCreate is a DRIVER_DISPATCH function?
>>
>> Thanks in advance.
>> Udo
>>
>> —
>> Questions? First check the Kernel Driver FAQ at
>> http://www.osronline.com/article.cfm?id=256
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
“Mark Roddy” wrote in message news:xxxxx@ntdev…
> Prefast has no such language restriction. The tool is part of visual studio
> 2005 and claims to fully support c++.
Ok, so this claim is not completely grounded, as we’ve seen.
PFD isn’t yet quite like the Deep Fritz; a human armed with c++ still has
a fat chance against it.
More likely, it currently can handle a certain subset of c++ features,
or needs more hints, that are not described in the documentation that we have.
–PA
>> -----Original Message-----
>> From: xxxxx@lists.osr.com [mailto:bounce-273091-
>> xxxxx@lists.osr.com] On Behalf Of Pavel A.
>> Sent: Friday, December 15, 2006 9:56 AM
>> To: Windows System Software Devs Interest List
>> Subject: Re:[ntdev] Prefast warning on driver dispatch functions
>>
>> Maybe this is one of the reasons why C++ is not supported for writing
>> drivers.
>> Automatic tools do not fully understand every c++ quirk.
>>
>> --PA
>>
>>
>>
>> “Udo Eberhardt” wrote in message
>> news:xxxxx@ntdev…
>> > My driver is written in C++ and all dispatch routines are defined as
>> static member functions of the class KnDriverObject, for
>> > example:
>> >
>> > class KnDriverObject
>> > {
>> > public:
>> >
>> > static
>> > NTSTATUS
>> > DispatchCreate(
>> > IN PDEVICE_OBJECT DeviceObject,
>> > IN PIRP Irp
>> > );
>> >
>> > …
>> >
>> > };
>> >
>> > In DriverEntry I initialize the dispatch table as usual:
>> >
>> > extern “C”
>> > NTSTATUS
>> > DriverEntry(
>> > IN PDRIVER_OBJECT DriverObject,
>> > IN PUNICODE_STRING RegistryPath
>> > )
>> > {
>> > …
>> >
>> > DriverObject->MajorFunction[IRP_MJ_CREATE] =
>> > KnDriverObject::DispatchCreate;
>> >
>> > …
>> >
>> > }
>> >
>> >
>> > When I run PFD on this then for the assignment above I get:
>> > warning 28155: The function being assigned or passed should be a
>> DRIVER_DISPATCH function: Add the declaration
>> > ‘DRIVER_DISPATCH ;’ before the current first
>> declaration of .
>> >
>> > Obviously, if DispatchCreate is declared as a static member function
>> then PFD does not deduce that it is a DRIVER_DISPATCH
>> > function and issues that warning. The warning message (and the docs)
>> suggest to add an explicit declaration like
>> >
>> > DRIVER_DISPATCH DispatchCreate;
>> >
>> > I tried that without success. How can I do that for a static member
>> function?
>> >
>> > Are there any other suggestions that may help to make PFD believe
>> that KnDriverObject::DispatchCreate is a DRIVER_DISPATCH
>> > function?
>> >
>> > Thanks in advance.
>> > Udo
>> >
>>
>
“Pavel A.” wrote in message news:xxxxx@ntdev…
> “Mark Roddy” wrote in message news:xxxxx@ntdev…
>> Prefast has no such language restriction. The tool is part of visual
>> studio
>> 2005 and claims to fully support c++.
>
> Ok, so this claim is not completely grounded, as we’ve seen.
> PFD isn’t yet quite like the Deep Fritz; a human armed with c++ still has
> a fat chance against it.
> More likely, it currently can handle a certain subset of c++ features,
> or needs more hints, that are not described in the documentation that we
> have.
>
Actually, PREfast does completely support C++, but there is a set of
rules/tests for drivers with the version you get with the DDK. Now the
OP’s problem is that the PREfast rules for drivers assume the dispatch
routines follow a C function prototype, and the OP is using a C++ class
member function. It turns out this works with the Microsoft compiler, but
IIRC there is no requirement in the C++ standard that such a member
function has to use the same convention as the C function, for instance the
compiler could have added an argument for the class. So PREfast is
rightfully complaining because the OP is not following the rules for a
dispatch function, even though his code works (and is likely to keep
working).
Personally, I take the tack that I will modify my code to clear up many of
PREfast’s complaints. Yes the code is legal and does not require the
change, but adding the checks PREfast is complaining are missing documents
assumptions in the code. And a good optimizer such as Microsoft’s will
remove most of the superfulous checks in the binary.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply
Note that all complains were about static class member functions.
AFAIK a C++ compiler will never add implicit parameters to static member
functions. Therefore, static member functions are commonly used to
implement C-style call-back functions. Very often this is used in
user-mode code to implement thread routines, IO completion routines,
window procs, etc. So why not use this pattern in kernel mode?
As I wrote in another post, the only way to re-arrange the code I found
is to declare the offending functions outside of the class. However,
this will force me to either make all members accessed by these
functions public, or to add a friend declaration to the class. Both seem
not to be an elegant solution because encapsulation concepts are
violated and complexity is increased.
Udo
Don Burn wrote:
“Pavel A.” wrote in message news:xxxxx@ntdev…
>> “Mark Roddy” wrote in message news:xxxxx@ntdev…
>>> Prefast has no such language restriction. The tool is part of visual
>>> studio
>>> 2005 and claims to fully support c++.
>> Ok, so this claim is not completely grounded, as we’ve seen.
>> PFD isn’t yet quite like the Deep Fritz; a human armed with c++ still has
>> a fat chance against it.
>> More likely, it currently can handle a certain subset of c++ features,
>> or needs more hints, that are not described in the documentation that we
>> have.
>>
>
> Actually, PREfast does completely support C++, but there is a set of
> rules/tests for drivers with the version you get with the DDK. Now the
> OP’s problem is that the PREfast rules for drivers assume the dispatch
> routines follow a C function prototype, and the OP is using a C++ class
> member function. It turns out this works with the Microsoft compiler, but
> IIRC there is no requirement in the C++ standard that such a member
> function has to use the same convention as the C function, for instance the
> compiler could have added an argument for the class. So PREfast is
> rightfully complaining because the OP is not following the rules for a
> dispatch function, even though his code works (and is likely to keep
> working).
>
> Personally, I take the tack that I will modify my code to clear up many of
> PREfast’s complaints. Yes the code is legal and does not require the
> change, but adding the checks PREfast is complaining are missing documents
> assumptions in the code. And a good optimizer such as Microsoft’s will
> remove most of the superfulous checks in the binary.
>
>
As I said in my previous post, IIRC the standard does not require a class
member function (including static ones) to have no implicit parameters, so
the warning is valid.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply
“Udo Eberhardt” wrote in message
news:xxxxx@ntdev…
> Note that all complains were about static class member functions. AFAIK
> a C++ compiler will never add implicit parameters to static member
> functions. Therefore, static member functions are commonly used to
> implement C-style call-back functions. Very often this is used in
> user-mode code to implement thread routines, IO completion routines,
> window procs, etc. So why not use this pattern in kernel mode?
>
> As I wrote in another post, the only way to re-arrange the code I found
> is to declare the offending functions outside of the class. However, this
> will force me to either make all members accessed by these functions
> public, or to add a friend declaration to the class. Both seem not to be
> an elegant solution because encapsulation concepts are violated and
> complexity is increased.
>
> Udo
>
>
> Don Burn wrote:
>> “Pavel A.” wrote in message news:xxxxx@ntdev…
>>> “Mark Roddy” wrote in message
>>> news:xxxxx@ntdev…
>>>> Prefast has no such language restriction. The tool is part of visual
>>>> studio
>>>> 2005 and claims to fully support c++.
>>> Ok, so this claim is not completely grounded, as we’ve seen.
>>> PFD isn’t yet quite like the Deep Fritz; a human armed with c++ still
>>> has
>>> a fat chance against it.
>>> More likely, it currently can handle a certain subset of c++ features,
>>> or needs more hints, that are not described in the documentation that
>>> we have.
>>>
>>
>> Actually, PREfast does completely support C++, but there is a set of
>> rules/tests for drivers with the version you get with the DDK. Now the
>> OP’s problem is that the PREfast rules for drivers assume the dispatch
>> routines follow a C function prototype, and the OP is using a C++ class
>> member function. It turns out this works with the Microsoft compiler,
>> but IIRC there is no requirement in the C++ standard that such a member
>> function has to use the same convention as the C function, for instance
>> the compiler could have added an argument for the class. So PREfast is
>> rightfully complaining because the OP is not following the rules for a
>> dispatch function, even though his code works (and is likely to keep
>> working).
>>
>> Personally, I take the tack that I will modify my code to clear up many
>> of PREfast’s complaints. Yes the code is legal and does not require the
>> change, but adding the checks PREfast is complaining are missing
>> documents assumptions in the code. And a good optimizer such as
>> Microsoft’s will remove most of the superfulous checks in the binary.
>>
>>
>
Hmm, that’s interesting. I’m not familiar with those details of the
standard, but I’m sure you are right. However, this would mean that for
any code that implements C-style callbacks (e.g. called by OS) as static
member functions there is no guarantee that this will work with every
compiler. This would make C++ less useful to create applications that
are based on a C style operating system API. Sounds strange to me
because every application developer in the world is doing exactly this.
Probably, this is the discrepancy between theory and practice.
Udo
Don Burn wrote:
As I said in my previous post, IIRC the standard does not require a class
member function (including static ones) to have no implicit parameters, so
the warning is valid.
I suspect that any competant implementation will not change the aguments
for this reason, and yes then PREfast should consider either a different
warning (that you just disable), or not issuing a warning. This is one of
the reasons that a lot of us who are conservative avoid C++, because the
standard allows things that will surprise you, even though most
implementations try to eliminate those surprises.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply
“Udo Eberhardt” wrote in message
news:xxxxx@ntdev…
> Hmm, that’s interesting. I’m not familiar with those details of the
> standard, but I’m sure you are right. However, this would mean that for
> any code that implements C-style callbacks (e.g. called by OS) as static
> member functions there is no guarantee that this will work with every
> compiler. This would make C++ less useful to create applications that are
> based on a C style operating system API. Sounds strange to me because
> every application developer in the world is doing exactly this. Probably,
> this is the discrepancy between theory and practice.
>
> Udo
>
>
> Don Burn wrote:
>> As I said in my previous post, IIRC the standard does not require a
>> class member function (including static ones) to have no implicit
>> parameters, so the warning is valid.
>>
>
My philosophy is to use C++ up to a certain level which means there is a
set of things I don’t use because they could cause trouble. However,
static member functions do not (yet) belong to that set…
Udo
Don Burn wrote:
I suspect that any competant implementation will not change the aguments
for this reason, and yes then PREfast should consider either a different
warning (that you just disable), or not issuing a warning. This is one of
the reasons that a lot of us who are conservative avoid C++, because the
standard allows things that will surprise you, even though most
implementations try to eliminate those surprises.