Holy cow, I wrote a book!
Sadly, I get to add another entry to
The ways people mess up IUnknown::QueryInterface:
Some people are just too eager to please.
HRESULT CSomething::QueryInterface(REFIID riid, void **ppvObj)
*ppvObj = this;
No matter what the interface is, they say,
"Sure, we do that!"
no matter what you ask for, they always return the same interface.
Even if it's not what you asked for.
Some people say that
"these problems wouldn't be there if Microsoft Windows
had enforced correct behavior to begin with."
My exercise to you, commenter "foo", is to come up with
a list of all bugs in IUnknown::QueryInterface
which Windows should enforce and describe how to enforce it.
(If your response is "You should have designed it differently
so these bugs are impossible to write", please outline that
alternate bug-resistant design.
Remember that your design must be language-independent,
while still supporting things like tear-offs,
aggregation, and remote objects.
and it needs to work on typical PC-class computers of the early 1990's,
which ran at 25MHz with 4MB of memory.)