Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

Compiler Error C2981, has any one gotten around it?

AlbertAlbert Member - All Emails Posts: 489

C2981 : the dynamic form of 'keyword' is not supported with /kernel

To give a jist:

  1. Assume there are two C++ interfaces I1 and I2
  2. Assume a class C which implements both of them, class C : public I1, public I2
  3. The consumer of the class object only has view of I1 and has a pointer to it called pI1
  4. Now it wants to also use I2, and tries to do a dynamic cast if(dynamic_cast<I2*>( pI1 ) != NULL)...
  5. the compiler throws this error stating this form of dynamic cast isn't supported with the /Kernel option!

A good and simple example of doing this in user mode is here: https://stackoverflow.com/questions/1023511/multiple-interfaces-inhertience-casting-from-one-to-another/1023517
and a good explanation here : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1105r0.html (search the keyword C2981)

Out of curiosity, I tried reinterpret_cast, which obviously doesn't work, and the subsequent use of the vtable lands in random functions inside the object.

Short of building a COM like QI interface mechanism, is there a workaround?

I do not want to expose the underlying object instead of the interface, as that will require changes in many places inside the driver, neither do I like the visitor pattern described in the stackoverflow page.

If there is another elegant solution to this one, kindly suggest.

Comments

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,909

    All of the port/miniport models that use C++ use a COM-like QueryInterface mechanism. I've always thought dynamic_cast was a huge hack.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • AlbertAlbert Member - All Emails Posts: 489

    @Tim_Roberts said:
    All of the port/miniport models that use C++ use a COM-like QueryInterface mechanism. I've always thought dynamic_cast was a huge hack.

    looks like I have to redesign a lot ground up, implementing the QI for all classes giving them something like IUknown as base and object IDs, going to be a fun weekend :neutral:

  • MBond2MBond2 Member Posts: 304

    Why are you bothering with all of this? Creating interfaces is valid when you are planning for future flexibility - especially by others - which should almost never be the case for KM code for a specific driver. I don't like C++ at all and prefer either C or C#, but I understand why people use it. but don't over use it right? And my biggest problem with C++ is how easy it is to over use the 'features' and how many more things need to be checked when reviewing code (which is what I do almost exclusively)

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,909

    Why are you bothering with all of this?

    We've been through these religious argument for 15 years or more, and frankly I'm tired of it. Whatever your prejudices against C++ are, they are just silly. C++ is a tool, and it is a powerful one at that. It works perfectly well in the kernel, within the well-known limitations. Many of the streaming drivers require it. Bad programmers write bad code in any language. Presumably, you understand that any C# code you write is just calling C++ native routines underneath.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • MBond2MBond2 Member Posts: 304

    I'm just as tired of defending my position over those same years and will not do it again. as you say, all of the arguments have been said and everyone has already made up their minds already. this is a legitimate technical question to the OP and not an attempt to reignite some long settled debate.

    C# code does not in general call out to C++ code. It can, but these days even the C# compiler is written in C#

  • AlbertAlbert Member - All Emails Posts: 489

    @MBond2 said:

    this is a legitimate technical question to the OP and not an attempt to reignite some long settled debate.

    in that case let me attempt to answer it atleast...

    @MBond2 said:
    Why are you bothering with all of this? Creating interfaces is valid when you are planning for future flexibility - especially by others - which should almost never be the case for KM code for a specific driver. I don't like C++ at all and prefer either C or C#, but I understand why people use it. but don't over use it right? And my biggest problem with C++ is how easy it is to over use the 'features' and how many more things need to be checked when reviewing code (which is what I do almost exclusively)

    What if one as an entire kernel echo system to support, with different drivers having different life spans running together, , some updates more frequently than others, and need to communicate with each other via refcounted objects and these objects can have different versions based on when they were built and need to be backward compatible as well. Imagine an entire COM like ecosystem designed for the kernel, where objects are passed with interface pointers and use queryInterface to find other interfaces in run time.

    That is my use case, and it is very hard to get all this done in C, it can be, but I don't think it will be justifiable.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    What if one as an entire kernel echo system to support, with different drivers having different life spans running together, , some updates more frequently than others, and need to communicate with each other via refcounted objects and these objects can have different versions based on when they were built and need to be backward compatible as well. Imagine an entire COM like ecosystem designed for the kernel, where objects are passed with interface pointers and use queryInterface to find other interfaces in run time.

    Hmmm... You have just described the Windows OS kernel-mode architecture.

    Get your last comments in, folks.., I’m going to lock this thread soon.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • AlbertAlbert Member - All Emails Posts: 489

    @Peter_Viscarola_(OSR) said:
    Hmmm... You have just described the Windows OS kernel-mode architecture.

    Well, not as big at that, but with 9 drivers. Also Windows was designed before C++, so a lot of the legacy design is baked into it, even though I speculate, I have no idea whether things have changed internally, while they kept the interfaces c style, but probably not.

    This product was written much later, and has gone considerable rewrites over the years and moved to c++/COM like design.

    As some of you might recall, I had taken a 10+ years hiatus from kernel coding and have recently returned back to it roughly a year ago, When I saw that code, it looked nothing like kernel code to me, and it was a tough and a steep uphill climb for me.

    As with any system, once you get used to it, you tend to understand the philosophy of the original designers, and I have to admit, having those nifty helper objects, and knowing how to use them correctly again, has increased by efficiency and it is much easier to do quality checks as well.

    They also invested a lot on unit tests, and porting the code to be testable in user land with bullseye and other tools, which makes it easier to check what paths haven't been tested. These abstractions also help newer programmers onboard easily, the boiler plate kernel stuff being hidden away deep inside the trenches. This makes hiring easy(it isn't easy to get kernel engineers).

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    Keep in mind: C++ is just a TOOL.

    I literally meant that every concept you listed is part of Windows kernel-mode architecture, even if there were no C++ in the entire Windows system. I admit that the the "where objects are passed with interface pointers and use queryInterface to find other interfaces in run time" is pretty limited in Windows... but we DO exactly have such an interface, don't we.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • AlbertAlbert Member - All Emails Posts: 489

    @Peter_Viscarola_(OSR) said:
    Keep in mind: C++ is just a TOOL.

    but we DO exactly have such an interface, don't we.

    if you are using wdf, but not all drivers are WDF based. BTW, object based design is possible in C as well, and Ctor() Dtor() concepts are very much possible with some glue like code and some scripts.

    I am not denying it, and yes C++ is just a tool, I was merely stating the ease of use of the tool in a programmers life. Yes, the tool is as good as it's handler, agreed, and kernel needs special care, like stack bloat, pool allocation etc.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399
    edited April 2

    you are using wdf, but not all drivers are WDF based

    No... not just in WDF. IoGetDeviceInterfaces.

    object based design is possible in C as well

    Of course! And many other such principles.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • AwbadhhoAwbadhho Member Posts: 134
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Developing Minifilters 24 May 2021 Live, Online
Writing WDF Drivers 14 June 2021 Live, Online
Internals & Software Drivers 2 August 2021 Live, Online
Kernel Debugging 27 Sept 2021 Live, Online