UMDF defines all of its interfaces using COM interfaces, rather than the flat C-style DDI that the KMDF team used.  When kernel developers see this their first question is often "why did you do that?" and it's an understandable question. I had a long discussion at WinHEC about this exact topic.

First not everyone is sold on the flat C DDI that we put together for KMDF. In the polls we've done, the sample group (let's be optimistic and call it the "industry") is split about evenly on whether they want C or C++. However for folks that concentrate more on user-mode stuff there's a greater preference for C++. So we wanted a DDI that would work well with C++ but that wouldn't force you to use it.

Using straight C++ objects also wouldn't work. C++ has its nice points, but sharing objects across DLL boundaries isn't one of them. There's no way to publish only your "public" members, there are concerns about whether our compiler will do the same name mangling from release to release with exports (long story), there's the fragile base class problem, there are all sorts of issues with the new & delete operators, and it can't be used from C without a wrapper library.

We could have used C++ abstract classes – describing the interfaces that our objects exposed without any of the pesky internal details. But we'd then have to add reference counting on top of that, and some method of casting one interface type to another, and when you're all done it looks like every object supports IUnknown.

So the bottom line is that we chose COM because we had to expose something that acted an awful lot like COM. Rather than create our own semantic which everyone would have to learn, we decided to borrow from an existing one that's already understood by many developers.

We've worked very hard to keep the COM runtime goop out of UMDF. UMDF drivers don't register as COM DLLs, they don't get to do any of the weird COM synchronization stuff, and they don't have to worry about IDispatch or monikers or whether they're running in-proc/out-of-proc. We try to use the COM programming model but without the weird magic that the COM runtime introduces. We do allow you to use something like ATL though if you're tolerant of a little magic and want to make the COM boilerplate easier. And I have to admit that as much as I dislike magical templated macros, being able to use CComPtr to do my reference counting for me is a helpful thing.