how to ensure atomic code in a kernel mode driver

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David J. Craig
Sent: Wednesday, December 03, 2003 6:21 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Re: how to ensure atomic code in a kernel mode driver

You mean something like the system-wide cancel spinlock? You
can do worse and I have seen it from no spinlocks to grabbing
several for almost the entire duration of processing each request.

More like implementing a lock which busy spins on an interlocked memory
access.

There a very good reasons why the OS abstracts the hardware interfaces. The
primary one is that each ‘hardware interface’ can be implemented by
different physical devices, or perhaps by no physical device at all, and as
a consequence ‘accessing the hardware’ requires the programmer to know about
every quirk of every possible hardware variation, including hardware that
doesn’t even exist yet, and all possible virtualizations of the hardware.
Take a look at the size of the PCI ‘hack table’ exception list in the
registry
(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PCI\Parameters) each
entry there is a deviant hardware device of some sort. So Alberto appears to
want every kernel programmer out there to replicate this sort of effort, and
get it right and get it compatible with everyone else doing the same thing?
Why would I think that is a Really Bad Idea?

Thank all,

The original host of my CAN controller was an 8051. The simplest way of
synchronization I/O writings with other sources of interrupt was
disabling all interrupts (EA=0/EA=1). Now I’m developing a WinNT driver
for the CAN and I have little knowledge of this OS (I’m starting).

Now, I know the only code that can corrupt the IO writings is MY OWN ISR
and then I just have to synchronize the IO with the ISR using
KInterrup::Synchronize (one of the sync ways in DriverWorks).

Thank you all for the help.

-----Mensaje original-----
De: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] En nombre de Arlie Davis
Enviado el: mi?rcoles, 03 de diciembre de 2003 22:45
Para: Windows System Software Devs Interest List
Asunto: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Absolutely agreed. However, it’s important that new driver developers
know that it is no longer appropriate, in general, to roll your own
assembly in NT drivers. I know I’m preaching to the choir here, but
I’ve had to deal with too much crappy, needlessly-inconsistent code to
have much tolerance for it anymore.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Moreira, Alberto
Sent: Wednesday, December 03, 2003 3:54 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Yes, Max, but the guy is a beginner. One can use KeAcquireSpinlock and
still have no clue of what a spinlock is all about. Do it at machine
level, and knowledge will seep in - first time he uses the calls, he
knows what’s going on underneath ! And the insights on computer
architecture by trying to implement a spinlock loop with or without
pause instructions, or the difference between btc/bts and compare
replace or exchange add, again, those cannot be acquired by using the
kernel call. Maybe it’s the professor in me speaking, but I believe that
every one of us kernel devs should do a fair amount of machine code
development, if nothing else as a scratching pole.

Alberto.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@sedecal.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

> to the hardware than to a Byzantine kernel layer, there’s much less

That’s why the best way is to - know exactly what each kernel routine does, and
call them.

It is enough to look at spinlock implementation in debugger’s disassembly to
understand what is going on there.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

And this is exactly where someone would have to dig into the fair amount of
knowledge of assembly. I’ve seen many many kernel programmers, they would
love to code and code and code …, when bugs shows up, they have no clues
what to look at and how to look at. ONLY WAY TO KNOW THIS IS TO TRY USING
IT, BUT THAT DOES NOT MEAN REIMPLEMENT ANYTHING ONE WOULD LIKE TO, WELL THEN
THERE ARE OTHERS WHO ARE ABSOULTELY SURE ABOUT THEIR OWN IMPLEMENTATION, AND
THEY WOULD GO FOR IT… For example, Windows socket direct(Servernet)
initially was targettted for multiplatform, so quite a bit of the lock(s)
primitives and its variant was implemented, but then again people had source
licenses and/or free source and/or proprietary source.

Opinion differs !, but to me kernel programming w/o knowing a fair amount of
assembly is as theoritical as “There is no parallel line in algebric
geometry”

-prokash

.
----- Original Message -----
From: “Maxim S. Shatskih”
To: “Windows System Software Devs Interest List”
Sent: Thursday, December 04, 2003 2:54 AM
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

> > to the hardware than to a Byzantine kernel layer, there’s much less
>
> That’s why the best way is to - know exactly what each kernel routine
does, and
> call them.
>
> It is enough to look at spinlock implementation in debugger’s disassembly
to
> understand what is going on there.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@garlic.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Bullshit is to assume that talking to the hardware automatically messes
things up. If you know what you’re doing, you will know how to handle your
hardware. If that is true, going directly to the hardware is an option, no
less valid than using an API.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Don Burn
Sent: Wednesday, December 03, 2003 6:05 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

BULLSHIT, almost every piece of code as you describe that has been my
misfortune to encounter in the last 30+ years of systems level programming
has violated the operating system principles and in general messed up the
system.

Your arguments about spin locks are a case in point, if you do not know what
you are doing it is easy to mess up a multi-processor with a poor spinlock
implementation.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting

----- Original Message -----
From: “Moreira, Alberto”
To: “Windows System Software Devs Interest List”
Sent: Wednesday, December 03, 2003 4:57 PM
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

> I know a lot of things that people do as a matter of fact that are way
less
> appropriate than talking directly to the hardware. In fact, I’d rather
talk
> to the hardware than to a Byzantine kernel layer, there’s much less
> probability of making mistakes and screwing things up. The best low level
> code isn’t the one that sticks to the OS rules, but the one that works
> independent of what OS is running. And if machine level code was
> automatically crappy or inconsistent, neither SoftICE nor any of our tools
> would be feasible.
>
> Alberto.
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

Having had the joy and pain of architecting some commercial OS’es, I would
love to know how you were granted divine insight into knowing what you are
doing. I tell my Linux friends “Beware of the dark side of the source”
since even seeing the code, does not necessarily mean you know the reasoning
behind it or the future plans you may screw up.
Reimplementing or extending OS functionality without working with the OS
team has been leading to disasters for years. Note: this is not only by
people outside a company, but it regularly happen inside, a few examples
from my past:

  1. An early experimental multiprocessor machine, had a spin lock
    implementation very similar to Windows. A couple developers writing drivers
    kept asking for a TestSpinLock call, we would keep pointing out that by
    coding in a cleaner manner they didn’t need it. Finally, they stopped
    coming to us, instead they determined that by testing for zero they could
    verify the spinlock was available. They wrote a number of drivers using
    this technique. Of course we then changed the spin lock implementation
    (trying something like a queued spin lock) and the value they were testing
    was always non-zero. We ended up shipping a system with suboptimal
    performance for 6 months, since we could not turn on the improved spinlock
    till they rewrote the code, even then we had to give them a TestSpinLock
    which was not something we ever intended in our designs.

  2. A group providing an emulation layer on another OS noticed we have
    fields in data structure parameters that were not being used or tested, so
    they started taking advantage of them. We then came out with a new kernel
    that validated the fields were zero in preparation of adding more features,
    in the end instead of the clean design we had expected, we had a foo and a
    fooEx for almost every system call because the boys didn’t follow the rules.

  3. Another group in the same company found a quick coding hack which
    had been documented not to work. They found it worked for their case and
    started using it, so by the time the multiprocessor system where it didn’t
    work came out of the labs, no code from this group would work on it. In the
    end the system was scrapped, because of bozo’s who “KNEW WHAT THEY WERE
    DOING”

Any time you stray from the documented environment, you have to be
aware that all you can say on your efforts are the work with a given
implementation or revision. Encouraging folks to go there is never a good
idea. Additionally, the knowledge to read the disassembled caode is small
versus what is need to roll your own.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting

----- Original Message -----
From: “Moreira, Alberto”
To: “Windows System Software Devs Interest List”
Sent: Thursday, December 04, 2003 11:11 AM
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

> Bullshit is to assume that talking to the hardware automatically messes
> things up. If you know what you’re doing, you will know how to handle your
> hardware. If that is true, going directly to the hardware is an option, no
> less valid than using an API.
>
> Alberto.
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Don Burn
> Sent: Wednesday, December 03, 2003 6:05 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver
>
>
> BULLSHIT, almost every piece of code as you describe that has been my
> misfortune to encounter in the last 30+ years of systems level programming
> has violated the operating system principles and in general messed up the
> system.
>
> Your arguments about spin locks are a case in point, if you do not know
what
> you are doing it is easy to mess up a multi-processor with a poor spinlock
> implementation.
>
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
>
> ----- Original Message -----
> From: “Moreira, Alberto”
> To: “Windows System Software Devs Interest List”
> Sent: Wednesday, December 03, 2003 4:57 PM
> Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver
>
>
> > I know a lot of things that people do as a matter of fact that are way
> less
> > appropriate than talking directly to the hardware. In fact, I’d rather
> talk
> > to the hardware than to a Byzantine kernel layer, there’s much less
> > probability of making mistakes and screwing things up. The best low
level
> > code isn’t the one that sticks to the OS rules, but the one that works
> > independent of what OS is running. And if machine level code was
> > automatically crappy or inconsistent, neither SoftICE nor any of our
tools
> > would be feasible.
> >
> > Alberto.
> >
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@compuware.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
> The contents of this e-mail are intended for the named addressee only. It
> contains information that may be confidential. Unless you are the named
> addressee or an authorized designee, you may not copy or use it, or
disclose
> it to anyone else. If you received it in error please notify us
immediately
> and then destroy it.
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@acm.org
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

An OS is just an OS. If it helps me, I use it. If it doesn’t, I don’t. Most
horror stories I have seen in my 35 years of kernel and graphics work did
not originate from people accessing the hardware but from ill choices by the
OS designers and implementers, ill choices that force kernel devs to bypass
the OS in search of plugging in those shortcomings.

The problem with spinlocks, as I see it, is very simple: OS theory proposes
that they should be at the lowest possible level. Hence, one key point: A
SPINLOCK SHOULD NOT BE INTERRUPTIBLE, that simple. Much confusion in
handling spinlocks comes from OS’s violating that very simple principle, so
when we’re doing hardware level synchronization, we no longer have to worry
just about other processors, but also about our own - and that’s not what
spinlocks were intended to be. A spinlock is a busy loop that stops a
processor on its tracks waiting for a barrier, and if the semantics of the
OS call doesn’t guarantee that the processor will NOT do something else but
spin, the OS concept is potentially questionable - and if I do need
something that stops the processor cold on its tracks, I’ll roll my own, and
I’ll have to do that to circumvent a limitation of the OS.

Furthermore, I have never seen a system that’s CPU bound because of a
spinlock, so, performance issues are not a factor here - not unless the
design is poor enough that CPU performance becomes an issue, and even then,
my first reaction is, GET A BETTER PROCESSOR rather than go through
involutions inside the OS. Or, get a better design, so that you get rid of
that shared data structure.

Typically we resort to talk to the hardware when the OS leaves something to
be desired. And notice, out of your three examples, two have nothing to do
with talking to the hardware, and the third includes that ill-defined
“suboptimal” criterion that may not mean much. If you want to see what
“optimal” means, take a look at the way video display drivers are
implemented today, that’s definitely one step towards higher performance.
But you know what ? Video drivers talk directly to the hardware and expose
the hardware to the user via surfaces. Not to mention Direct Rendering,
which exposes the hardware at Ring 3 - but it may be a while before Windows
evolves that far !

The best OS, you see, is the one you take for granted: it’s mostly invisible
and very seldom called, yet it’s there and it does its job without asking
you to do everything through its APIs.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Don Burn
Sent: Thursday, December 04, 2003 11:38 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Having had the joy and pain of architecting some commercial OS’es, I would
love to know how you were granted divine insight into knowing what you are
doing. I tell my Linux friends “Beware of the dark side of the source”
since even seeing the code, does not necessarily mean you know the reasoning
behind it or the future plans you may screw up.
Reimplementing or extending OS functionality without working with the OS
team has been leading to disasters for years. Note: this is not only by
people outside a company, but it regularly happen inside, a few examples
from my past:

  1. An early experimental multiprocessor machine, had a spin lock
    implementation very similar to Windows. A couple developers writing drivers
    kept asking for a TestSpinLock call, we would keep pointing out that by
    coding in a cleaner manner they didn’t need it. Finally, they stopped
    coming to us, instead they determined that by testing for zero they could
    verify the spinlock was available. They wrote a number of drivers using
    this technique. Of course we then changed the spin lock implementation
    (trying something like a queued spin lock) and the value they were testing
    was always non-zero. We ended up shipping a system with suboptimal
    performance for 6 months, since we could not turn on the improved spinlock
    till they rewrote the code, even then we had to give them a TestSpinLock
    which was not something we ever intended in our designs.

  2. A group providing an emulation layer on another OS noticed we have
    fields in data structure parameters that were not being used or tested, so
    they started taking advantage of them. We then came out with a new kernel
    that validated the fields were zero in preparation of adding more features,
    in the end instead of the clean design we had expected, we had a foo and a
    fooEx for almost every system call because the boys didn’t follow the rules.

  3. Another group in the same company found a quick coding hack which
    had been documented not to work. They found it worked for their case and
    started using it, so by the time the multiprocessor system where it didn’t
    work came out of the labs, no code from this group would work on it. In the
    end the system was scrapped, because of bozo’s who “KNEW WHAT THEY WERE
    DOING”

Any time you stray from the documented environment, you have to be
aware that all you can say on your efforts are the work with a given
implementation or revision. Encouraging folks to go there is never a good
idea. Additionally, the knowledge to read the disassembled caode is small
versus what is need to roll your own.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting

----- Original Message -----
From: “Moreira, Alberto”
To: “Windows System Software Devs Interest List”
Sent: Thursday, December 04, 2003 11:11 AM
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

> Bullshit is to assume that talking to the hardware automatically messes
> things up. If you know what you’re doing, you will know how to handle your
> hardware. If that is true, going directly to the hardware is an option, no
> less valid than using an API.
>
> Alberto.
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Don Burn
> Sent: Wednesday, December 03, 2003 6:05 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver
>
>
> BULLSHIT, almost every piece of code as you describe that has been my
> misfortune to encounter in the last 30+ years of systems level programming
> has violated the operating system principles and in general messed up the
> system.
>
> Your arguments about spin locks are a case in point, if you do not know
what
> you are doing it is easy to mess up a multi-processor with a poor spinlock
> implementation.
>
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
>
> ----- Original Message -----
> From: “Moreira, Alberto”
> To: “Windows System Software Devs Interest List”
> Sent: Wednesday, December 03, 2003 4:57 PM
> Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver
>
>
> > I know a lot of things that people do as a matter of fact that are way
> less
> > appropriate than talking directly to the hardware. In fact, I’d rather
> talk
> > to the hardware than to a Byzantine kernel layer, there’s much less
> > probability of making mistakes and screwing things up. The best low
level
> > code isn’t the one that sticks to the OS rules, but the one that works
> > independent of what OS is running. And if machine level code was
> > automatically crappy or inconsistent, neither SoftICE nor any of our
tools
> > would be feasible.
> >
> > Alberto.
> >
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@compuware.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
> The contents of this e-mail are intended for the named addressee only. It
> contains information that may be confidential. Unless you are the named
> addressee or an authorized designee, you may not copy or use it, or
disclose
> it to anyone else. If you received it in error please notify us
immediately
> and then destroy it.
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@acm.org
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

> I know a lot of things that people do as a matter of fact that are way
less

appropriate than talking directly to the hardware. In fact, I’d rather
talk
to the hardware than to a Byzantine kernel layer, there’s much less
probability of making mistakes and screwing things up. The best low level
code isn’t the one that sticks to the OS rules, but the one that works
independent of what OS is running.

I hope you never write any commercial code. Or if you do, that I never have
to load on any of my or my customer’s machines.

Hackers and script kiddies that figure they know better than the OS
designers and should flout the interface rules as a matter of course are
responsible for about 99% of the problem code in the world. But they figure
that since it works on THEIR machine that they are right in doing it, and if
it fails on someone else’s machine, why, that is clearly the fault of the
other person for not having a machine configured identically to the hacker’s
machine.

Foo.

Loren

> Bullshit is to assume that talking to the hardware automatically messes

things up. If you know what you’re doing, you will know how to handle your
hardware. If that is true, going directly to the hardware is an option, no
less valid than using an API.

If this is YOUR OWN machine (singlular, not plural) and you have no
intention of ever upgrading the hardware in any way while running this
application/driver, then go for it.

If you have any intention of selling this pig in a poke to a customer, then
they have every right in the world to sue you when your code crashes their
machine and trashes their data.

(Some 10 years ago there was a kid in the Amiga developer’s groups who made
exactly these same arguments, that it was always better to ignore the DDK
instructions and bang the metal rather than using the defined interfaces.
After all, it was FASTER. So it was BETTER. Others argued against this
point.

Finally he was challenged to produce an example app showing how his code
would work everywhere and be better than the OS code. Of the 25 or so
developers that tried the code on various machines, ONLY TWO of the machines
would even boot after installing his driver, and both of those crashed when
excercising it. After he argued for a while that the machines didn’t really
crash and it only looked like they had crashed but were really still working
fine even if they didn’t respond and had a bluescreen-equivalent showing,
people stopped listening to him and he shut up.

The crashes weren’t surprising. There were 5 variations on the hardware he
was poking, and only one would respond to the method he was using, and even
then it was memory timing dependent. There were also about 10 variations on
the rom code, and only one had the instructions he was expecting at the
addresses he was jumping to. Thus, there was about 1 chance in 50 of his
code working, with the chance degrading all the time as new OS code and
hardware was released.)

Loren

Whoah whoah whoah. This discussion is getting rather bitter. This is a
complex topic, and although I disagreed with a lot of what Alberto said
in his first couple of posts, I’m willing to give him the benefit of the
doubt.

I *think* we can all agree that well-defined APIs are a really, really
good thing, such as device driver models, PnP, etc. However, I do agree
that Alberto’s example of DirectX, and the balance it represents between
abstraction (indirection) and direct access (mapping video buffers into
user-mode processes) is a good one. (There are lots of other similar
examples, like zero-copy networking, user-mode networking, etc.)
However, even in this model, there is a lot of abstraction. Apps don’t
party on device registers. They use a well-defined set of COM
interfaces to negotiate direct access to video memory, then they party
on the video memory.

In general, I don’t think any code outside of a k-mode device driver has
any business ever touching a device register, or any kind of device
configuration. I/O pages or mapped memory is a different story.

Now, spin locks and such are a slightly different matter. First,
because the code interacts with only the processors and memory of the
system, and the processors have a very well-defined instruction set.
Second, because a lot of these techniques apply symmetrically in both
user- and kernel-mode. So the main portability concerns are: 1)
different processor architectures (instruction sets), and 2) performance
variations on behavior of different memory architectures, e.g. the many
different SMP implementations.

The OS primitives for spin locks and other synchronization techniques
(lookaside lists, slists, etc.) are meant to be Pretty Good on all
platforms – good enough that most apps don’t have a need to implement
them on their own. And I believe that you ought to use these – EVEN if
you have some clever assembly code! – unless you have done a lot of
performance analysis, and have PROVED that you actually NEED a different
implementation.

The reason is that using a different implementation of a spin lock (or
whatever) does carry other costs – mostly in debugging and maintenance.
You have to spend the time to debug it – and you need to debug it on
lots of different hardware, if you expect to sell the code commercially.
(SMP systems are NOT all built alike.)

And it’s significantly more difficult to debug code that rolls its own
spin locks, because you trade one well-known, well-understood, tested
implementation for one that is usually undocumented, and has new,
unfamiliar function names, structure names, etc. (And that’s if you
have the debug symbols!) If a driver bugchecks my system, and I look at
it under a debugger and I see KeAcquireSpinLock in somebody’s stack,
that gives me useful information. However, if the driver stack is
unavailable (no symbols), or has functions like FooStopTime or
FooFastWait, I have to WASTE a lot of time figuring out what that driver
was trying to do.

So. Again, my main point – use the OS primitives unless you have
PROVED, via rigorous empirical performance analysis, that you need a
different implementation. And even then, you can probably do better
than that – you probably need to rethink your locking protocols, if you
are spending so much time waiting on spin-locks. There may be better
implementations than the one your OS provides, but they aren’t going to
save you if your app is still lock-bound.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Loren Wilton
Sent: Thursday, December 04, 2003 10:56 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

I know a lot of things that people do as a matter of fact that are way
less
appropriate than talking directly to the hardware. In fact, I’d rather
talk
to the hardware than to a Byzantine kernel layer, there’s much less
probability of making mistakes and screwing things up. The best low
level code isn’t the one that sticks to the OS rules, but the one that

works independent of what OS is running.

I hope you never write any commercial code. Or if you do, that I never
have to load on any of my or my customer’s machines.

Hackers and script kiddies that figure they know better than the OS
designers and should flout the interface rules as a matter of course are
responsible for about 99% of the problem code in the world. But they
figure that since it works on THEIR machine that they are right in doing
it, and if it fails on someone else’s machine, why, that is clearly the
fault of the other person for not having a machine configured
identically to the hacker’s machine.

Foo.

Loren


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@sublinear.org To
unsubscribe send a blank email to xxxxx@lists.osr.com

I trust my own code better than I trust someone else’s - including the OS
writers. And I often want to do things that the OS doesn’t. For example, I
rarely want to let my processor be interrupted inside a spinlock-protected
critical section, now if the OS doesn’t give me a no-interrupts critical
section, sorry, I’m going to roll my own. And it’s not going to be any less
robust than the OS, or I wouldn’t respect myself as a programmer.

Furthermore, I don’t trust other people’s designs in rolling their OS-level
queues, lists and what not - they’re rarely structured the way I want them
to, and it takes me more time to learn to handle the vagaries of their
design than to do my own. So, again, it’s not a question of faster or even
better, it’s an issue of feeling comfortable with. My approach is this:
unless I must use an API - and note the word “must” and all its implications

  • I’d rather use my own code. I keep telling everyone around me, I’ll reuse
    any piece of code, provided I wrote it.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Loren Wilton
Sent: Thursday, December 04, 2003 11:19 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Bullshit is to assume that talking to the hardware automatically messes
things up. If you know what you’re doing, you will know how to handle your
hardware. If that is true, going directly to the hardware is an option, no
less valid than using an API.

If this is YOUR OWN machine (singlular, not plural) and you have no
intention of ever upgrading the hardware in any way while running this
application/driver, then go for it.

If you have any intention of selling this pig in a poke to a customer, then
they have every right in the world to sue you when your code crashes their
machine and trashes their data.

(Some 10 years ago there was a kid in the Amiga developer’s groups who made
exactly these same arguments, that it was always better to ignore the DDK
instructions and bang the metal rather than using the defined interfaces.
After all, it was FASTER. So it was BETTER. Others argued against this
point.

Finally he was challenged to produce an example app showing how his code
would work everywhere and be better than the OS code. Of the 25 or so
developers that tried the code on various machines, ONLY TWO of the machines
would even boot after installing his driver, and both of those crashed when
excercising it. After he argued for a while that the machines didn’t really
crash and it only looked like they had crashed but were really still working
fine even if they didn’t respond and had a bluescreen-equivalent showing,
people stopped listening to him and he shut up.

The crashes weren’t surprising. There were 5 variations on the hardware he
was poking, and only one would respond to the method he was using, and even
then it was memory timing dependent. There were also about 10 variations on
the rom code, and only one had the instructions he was expecting at the
addresses he was jumping to. Thus, there was about 1 chance in 50 of his
code working, with the chance degrading all the time as new OS code and
hardware was released.)

Loren


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

I would contend that the cumbersomeness of the OS APIs and the need to
support a brand new OS every couple of years is the responsible for most
problem code out there, including the code you attribute to hackers and
script kiddies. Take for example a simple case such as a list: I can code
precisely how much I need, to the level I need, and it takes less than half
an hour to get it working. It’ll take me more than that just to learn the
API, let alone to figure out how to coax it to do what I need it to do. The
result is this: the code I write is robust and bug free, while using the
API, hohum, I don’t know - just misread one line of the document and shit
happens.

And what do you know, real programmers don’t read manuals. :slight_smile:

Moreover, much of that interface is written in C, which in itself is a
rather unsound proposition. Talk about migrating the API to C++ so that one
can apply those protections inherent in OO languages, or even to something
like C# so that one can take advantage of garbage collection, and what I see
is those same people who whine about safety and bug-free code fight it tooth
and nail - as if writing C code with all those pointers dangling all over
the place was the safest ever way to program !

So, sorry, an OS API is no guarantee against code problems, much the
contrary.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Loren Wilton
Sent: Thursday, December 04, 2003 10:56 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

I know a lot of things that people do as a matter of fact that are way
less
appropriate than talking directly to the hardware. In fact, I’d rather
talk
to the hardware than to a Byzantine kernel layer, there’s much less
probability of making mistakes and screwing things up. The best low level
code isn’t the one that sticks to the OS rules, but the one that works
independent of what OS is running.

I hope you never write any commercial code. Or if you do, that I never have
to load on any of my or my customer’s machines.

Hackers and script kiddies that figure they know better than the OS
designers and should flout the interface rules as a matter of course are
responsible for about 99% of the problem code in the world. But they figure
that since it works on THEIR machine that they are right in doing it, and if
it fails on someone else’s machine, why, that is clearly the fault of the
other person for not having a machine configured identically to the hacker’s
machine.

Foo.

Loren


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

> Moreover, much of that interface is written in C, which in itself is a

rather unsound proposition. Talk about migrating the API to C++ so that one
can apply those protections inherent in OO languages

What protections namely?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Alberto,

May be voice enabled API would be good :).

So that we can at least yell at it !!!

Once I tested and AI program, back in school days. Every one was introducing
their name, and was asking the program’s name, and what you do for living,
and sort of all the normal question we use when we mutually introduces. WHEN
MY TURN CAME, my first word was Hello, got the response hello, then I said
“U know U are my problem”. Answer was (bit delayed) but said “Why U think
I’m Ur problem”. I said , “U are rediculous”, and seriously “U are my
problem”. The program fires back: “Hey, I think U are my problem”, and I’m
not"… test ended, I liked it.

On the practical side, I was once coding ATL ( vc 5.0++), and I was fond of
using any library routine I can, so that I dont need to worry about MAP,
multiMAP, etc from STL, no raw file system API (open, seek, close …),
instead Stream I/O, and of course strings, coming from C background that was
like a real productive steps. Now a bug showed up, as usual, weekend food
was find the bug, and eat. An expert C++ coder was inhouse, offered me to
help, and went to fix the src of the implementation ( just a tweak), AND I
ASKED, PLEASE TELL ME WHERE IS MY MISTAKE. He could not find it, so he
decided to built that library for an adhoc support. That is why I hope we
will have “Voice enabled API”, so that I can yell at it.

Someone suggested that there should a Law for breaking or introducing
bug(s), that would we really ideal for me, all my PDAs( linux, Palm,
PocketPCs), including desktops crashes, I dont really need to work in that
case, just file complain. Hawaii, Bhamas, Amazon forests are no longer going
to be my dream.

-prokash
----- Original Message -----
From: “Moreira, Alberto”
To: “Windows System Software Devs Interest List”
Sent: Friday, December 05, 2003 7:23 AM
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

> I trust my own code better than I trust someone else’s - including the OS
> writers. And I often want to do things that the OS doesn’t. For example, I
> rarely want to let my processor be interrupted inside a spinlock-protected
> critical section, now if the OS doesn’t give me a no-interrupts critical
> section, sorry, I’m going to roll my own. And it’s not going to be any
less
> robust than the OS, or I wouldn’t respect myself as a programmer.
>
> Furthermore, I don’t trust other people’s designs in rolling their
OS-level
> queues, lists and what not - they’re rarely structured the way I want them
> to, and it takes me more time to learn to handle the vagaries of their
> design than to do my own. So, again, it’s not a question of faster or even
> better, it’s an issue of feeling comfortable with. My approach is this:
> unless I must use an API - and note the word “must” and all its
implications
> - I’d rather use my own code. I keep telling everyone around me, I’ll
reuse
> any piece of code, provided I wrote it.
>
>
> Alberto.
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Loren Wilton
> Sent: Thursday, December 04, 2003 11:19 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver
>
>
> > Bullshit is to assume that talking to the hardware automatically messes
> > things up. If you know what you’re doing, you will know how to handle
your
> > hardware. If that is true, going directly to the hardware is an option,
no
> > less valid than using an API.
>
> If this is YOUR OWN machine (singlular, not plural) and you have no
> intention of ever upgrading the hardware in any way while running this
> application/driver, then go for it.
>
> If you have any intention of selling this pig in a poke to a customer,
then
> they have every right in the world to sue you when your code crashes their
> machine and trashes their data.
>
>
> (Some 10 years ago there was a kid in the Amiga developer’s groups who
made
> exactly these same arguments, that it was always better to ignore the DDK
> instructions and bang the metal rather than using the defined interfaces.
> After all, it was FASTER. So it was BETTER. Others argued against this
> point.
>
> Finally he was challenged to produce an example app showing how his code
> would work everywhere and be better than the OS code. Of the 25 or so
> developers that tried the code on various machines, ONLY TWO of the
machines
> would even boot after installing his driver, and both of those crashed
when
> excercising it. After he argued for a while that the machines didn’t
really
> crash and it only looked like they had crashed but were really still
working
> fine even if they didn’t respond and had a bluescreen-equivalent showing,
> people stopped listening to him and he shut up.
>
> The crashes weren’t surprising. There were 5 variations on the hardware
he
> was poking, and only one would respond to the method he was using, and
even
> then it was memory timing dependent. There were also about 10 variations
on
> the rom code, and only one had the instructions he was expecting at the
> addresses he was jumping to. Thus, there was about 1 chance in 50 of his
> code working, with the chance degrading all the time as new OS code and
> hardware was released.)
>
> Loren
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@compuware.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
> The contents of this e-mail are intended for the named addressee only. It
> contains information that may be confidential. Unless you are the named
> addressee or an authorized designee, you may not copy or use it, or
disclose
> it to anyone else. If you received it in error please notify us
immediately
> and then destroy it.
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@garlic.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>

> I would contend that the cumbersomeness of the OS APIs and the need to

support a brand new OS every couple of years is the responsible for most
problem code out there, including the code you attribute to hackers and
script kiddies.

I would add that many problem code is due to careless/incapable programmers
with poor knowledge of the environment. I believe good programmers should be
able to write good code not matter how complex the environment and/or its
API are. Skipping learning the API and rolling his/her own is not the way to
go in many cases (or they just don’t know OS has API to do that). I’ve seen
many bad drivers written by programmers who just don’t bother RTFM. I was
really pissed off when I have to fix those crappies. Well, maybe I shouldn’t
complain about that too much since it pays my mortgage-:wink:

hohum, I don’t know - just misread one line of the document and shit
happens.

Sometimes, misreading even a single WORD screws the whole thing up:)

Calvin Guan, Software Engineer xxxxx@nospam.ati.com
ATI Technologies Inc. Markham ON. Canada
Tel: (905) 882-2600 Ext. 8654

-----Original Message-----
From: Moreira, Alberto [mailto:xxxxx@compuware.com]
Sent: Friday, December 05, 2003 10:30 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Take for example a simple case such as a
list: I can code
precisely how much I need, to the level I need, and it takes
less than half
an hour to get it working. It’ll take me more than that just
to learn the
API, let alone to figure out how to coax it to do what I need
it to do. The
result is this: the code I write is robust and bug free,
while using the
3 happens.

And what do you know, real programmers don’t read manuals. :slight_smile:

Moreover, much of that interface is written in C, which in itself is a
rather unsound proposition. Talk about migrating the API to
C++ so that one
can apply those protections inherent in OO languages, or even
to something
like C# so that one can take advantage of garbage collection,
and what I see
is those same people who whine about safety and bug-free code
fight it tooth
and nail - as if writing C code with all those pointers
dangling all over
the place was the safest ever way to program !

So, sorry, an OS API is no guarantee against code problems, much the
contrary.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Loren Wilton
Sent: Thursday, December 04, 2003 10:56 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

> I know a lot of things that people do as a matter of fact
that are way
less
> appropriate than talking directly to the hardware. In fact,
I’d rather
talk
> to the hardware than to a Byzantine kernel layer, there’s much less
> probability of making mistakes and screwing things up. The
best low level
> code isn’t the one that sticks to the OS rules, but the one
that works
> independent of what OS is running.

I hope you never write any commercial code. Or if you do,
that I never have
to load on any of my or my customer’s machines.

Hackers and script kiddies that figure they know better than the OS
designers and should flout the interface rules as a matter of
course are
responsible for about 99% of the problem code in the world.
But they figure
that since it works on THEIR machine that they are right in
doing it, and if
it fails on someone else’s machine, why, that is clearly the
fault of the
other person for not having a machine configured identically
to the hacker’s
machine.

Foo.

Loren


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named
addressee only. It
contains information that may be confidential. Unless you are
the named
addressee or an authorized designee, you may not copy or use
it, or disclose
it to anyone else. If you received it in error please notify
us immediately
and then destroy it.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@ati.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Objects. Encapsulation. Polymorphism. Inheritance. Call by reference.
Constructors. Destructors. Overloading. Abstract classes. Interfaces.
Namespaces.

I could go on.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Maxim S. Shatskih
Sent: Friday, December 05, 2003 11:41 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Moreover, much of that interface is written in C, which in itself is a
rather unsound proposition. Talk about migrating the API to C++ so that
one
can apply those protections inherent in OO languages

What protections namely?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

C++ has all of this, and it doesn’t magically fix anything. C++ is just
pretty C.

Type safety and GC would go a long way toward fixing a LOT of problems.
That, and maybe analytical verification that methods meets certain
constraints, such as calling other methods/functions at appropriate IRQL
levels, paged/non-paged rules, etc.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Moreira, Alberto
Sent: Friday, December 05, 2003 12:38 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Objects. Encapsulation. Polymorphism. Inheritance. Call by reference.
Constructors. Destructors. Overloading. Abstract classes. Interfaces.
Namespaces.

I could go on.

Alberto.

> multiMAP, etc from STL, no raw file system API (open, seek, close …),

instead Stream I/O,

Tastes differ. I consider good old <stdio.h> to be by far better then C++'s
iostream set of classes.

Lesser visual noise in “::” tokens, and no schizoid redefinition of “<<” as
output, since it is a bitwise shift :slight_smile:

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com</stdio.h>

Arlie, each of those features adds to the safety of your code.

Objects: everything’s an object, there are no dangling functions nor are
there lone pieces of data floating all over the place. The structure of your
driver fits naturally the structure of the i/o environment around it. Data
is either part of a public interface or it is invisible to all third parties
excepting possibly that type’s family. More, with judicious use of
interfaces, you don’t even need to know if a method sits in the same
process, in another process, or in a machine across the network.

Encapsulation: data and functions are only visible to the outside if they’re
part of an interface or of a public section. No chance of calling private
functions or accessing private pieces of data. Great separation between
interface and implementation: adds to the safety of the code.

Polymorphism: objects can implement the same method in different ways. An
object is a namespace and names are only visible inside that object. That
adds to safety and avoids misuse of code and data. Functions can have the
same name and yet differ in parameter signature, allowing automatic
defaulting of parameters not supplied - instead of the mess of NULLs and
zeros in funky places we have today. Two different packets can call the same
function name (such as IrpRead or IrpWrite) and achieve quite different
effects. Another example, you could have two subclasses of a superclass, one
for low IRQL and another for DIRQL: same name, implementing the same
interface (among others - you don’t only have to implement one interface),
only that one issues calls that can be issued at low IRQL, while the other
issues calls that can only be issued a high IRQL. That would concentrate a
lot of IRQL-depending manipulation in one or two classes: adds to locality,
makes it easy to spot errors, and hence increases the quality of your code.
More, functions can return object references and therefore no more calling
APIs with pointers as parameters, pointing to writable areas: by itself a
no-no, even worse if the caller must allocate the memory and state the
length of the object: another piece of nonsense that adds to the insecurity
of the code. Want a new object ? Call the method, which issues a “new” on
the object (lengths are automatically taken into account, no need for the
programmer to bother with them), and get the return value being a reference
to that object. Did it fail ? You get a reference to a null object or to a
void one that has a fail status inside it.

Inheritance: Deriving a class from an existing class keeps the existing code
static and hence minimizes the possibility that your addition breaks
existing code. Objects with different member variables and functions can
derive from the same superclass, allowing each derived class to have its own
handling of program runtime conditions - that avoids big “if” and “case”
statements with a zillion branches that clutter the listing and are hard to
follow. The code gets simpler and hence safer, and we know that the
condition for object A cannot possibly affect object B because they’re
different classes and one cannot see the private members of the other. Are
you dispatching an IRP ? Just write one subclass for each type of IRP, then
just invoke the method: no ifs or cases, each IRP object takes care of its
own handling. Much cleaner and hence safer. Want to write a filter driver ?
Inherit it from a mother driver class. Want to extend the driver stack ?
Derive a class from it. And so on. Clean, efficient, hierarchical,
compartmentalized: safe.

Call by reference: No pointers need apply. Need I say more ? You pass a
reference to the real object, not a pointer to it.

Constructors and Destructors: read “automatic memory management”. No more
mallocs and mfrees sprinkled all over, an object allocates its store at
construction time and releases it at destruction time. More, in a garbage
collected language like C# there’s no need to manage memory at destruction
time. In other words: memory leaks cease to be a problem.

Overloading: If I have two numbers, a+b is sum, but if I have two strings,
a+b can be made to be concatenation. I can construct arbitrary streams of
objects or data structures by overloading the “>>” and “<<” operators. I can
overload those same operators to achieve list operations such as append and
remove, so that I don’t need to memorize Byzantine APIs any longer: the
statements “item << queue” or “item >> queue” are jolly clear and much
easier to manage. In a really nicely put together interface, I could push an
IRP onto the stack by writing “irp >> stack” : clear, obvious, and no need
for yet another cumbersome and hard to remember call with half a zillion
parameters. Want special memory management, say, allocate from the nonpaged
pool ? Override the “new” operator. And so on.

Abstract classes and interfaces: allow you to individualize the interfaces
into objects, so that you achieve interface-centric programming. That alone
is a great improvement, just take a look at the COM spec if you doubt it. An
interface can be represented by an abstract class, and a class can be donned
an interface by using multiple inheritance: no more ad-hoc little functions
all over the place, the interface is cast in stone and exists independent of
your class. Moreover, you can get new classes to support the same interface
just by inheriting from its abstract class, no more compatibility issues due
to errors of transcription or bugs in the interface code: just inherit the
interface and implement it. This allows a separation between interface and
implementation that greatly improves the safety of your code.

Namespaces: No more two-level all-or-nothing global-or-local
everybody-sees-everything programming. Object names are organized in
namespaces, a class is just another namespace that comes and goes as it
creates and deletes objects, and so on. You can precisely control who sees
and who doesn’t see every item in your namespaces. Which, again, adds to the
safety of your code.

Golly, I could go on for a long time.

Alberto.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Arlie Davis
Sent: Friday, December 05, 2003 1:11 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

C++ has all of this, and it doesn’t magically fix anything. C++ is just
pretty C.

Type safety and GC would go a long way toward fixing a LOT of problems.
That, and maybe analytical verification that methods meets certain
constraints, such as calling other methods/functions at appropriate IRQL
levels, paged/non-paged rules, etc.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Moreira, Alberto
Sent: Friday, December 05, 2003 12:38 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] RE: how to ensure atomic code in a kernel mode driver

Objects. Encapsulation. Polymorphism. Inheritance. Call by reference.
Constructors. Destructors. Overloading. Abstract classes. Interfaces.
Namespaces.

I could go on.

Alberto.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

How can the listed below be “protectors”?

Objects. Encapsulation.

Achievable by “static” keyword in C. As about the tiny classes like CString,
which are the C++ish way of encapsulation - it is bug-hiding and debugging
obfuscation, which is IMHO unsuitable in the serious code.

What if “a + b” with strings will fail the memory allocation? The exception? It
is another can of worms, since it provocates the “forget the error handling -
all will be done magically” programming style.

Well, if the accounting app will crash with some pre-mortem message box (from
the top-level exception handler) due to out-of-memory on string addition - then
this is tolerable, anyway plenty of memory is available in user mode, and thus
such a thing is very rare.

Not so with system-level development, and even with things like ISAPI filters
who, though user mode, are exposed to hackers directly - and nearly as hard to
debug as the kernel mode code.

Explicitly coded error handling at least guarantees that the function is
locally correct - all possible cases are coded and handled. Not so with
exceptions, which are just thrown up and nobody knows how the upper layers will
handle them.

Given the amount of labour MS did to the disk stack on XP (NO resources are
allocated in critical IO paths) - I can hardly imagine C++ to be suitable for
such a task.

Polymorphism.

Very good idea.
UNIXen used this for VFS for years, without resorting to compiler-generated
vtables, which are by definition worse then macros given in the header files of
the standard library.

Inheritance.

More often is a plague then a help, makes the code lesser readable.
Multiple inheritance is nearly always evil, and thus not supported in other OO
languages then C++ - Java, C# and Delphi (the “implements” keyword aside, I’m
speaking about inheriting from the class with some “meat” in it).

Call by reference.

Just plain unsafe feature, administratively forbidden in some development teams
I know.
The reason is that the C way:

int f(MyObject*);

requires “&” at calls like:

f(&obj);

The “&” sign tells the reader that the object can be changed during the call.
Now the C++ way:

f(obj);

and the developer will be very much surprised in the end - “why obj have
changed here”?

Please, Alberto, tell me, how int f(MyObject&) is a protector? It is really
useful only in “operator +” routines, and just plain evil in all other places.
Even C# is free of this evil, requiring to write the word “ref” explicitly in
calls.

Constructors. Destructors.

These ones are good (as polymorphism is).
Good, unless somebody will do something which can fail in the constructor -
opening a file or such.

Overloading.

Just plain evil for anything except accounting apps or web forums :slight_smile:

“operator +” is more or less - at least a “+” token is present, so, the reader
can know that something can occur behind his back.

Not so with “operator T”, since it does not require anything to be explicitly
written! Hidden semantics is a can of worms, and the source of bugs.

Abstract classes. Interfaces.

These ones are good for sure, but achievable in C too.

Namespaces.

Namespaces themselves are not this bad, but “using” keyword is.

You see “vector” in the code. Is it “std::vector”? or some other vector? why
not always type “std::” prefix, so the reader will understand that this is
STL?

BTW - you forgotten the really good C++ feature - the templates. This feature,
though has ugly syntax, is very good - unless somebody will write

typedef std::vector IntVector;

due to being lazy. Why not type “std::vector” directly in all places?

Generally speaking, the average C++ code is lesser safe the the average C code
due to lots of hidden semantics in it.

In C, if you have a buffer overrun, it is always clear. In C++, it can be
buried inside some CString-like class which the developer wrote “for
convinience”, and be by far harder to find, especially if it is inlined.

Also I cannot understand. From one side, you suggest the “bare-hardware”
programming style, instead of using the OS routines instead. From another side,
you suggest encapsulation. Sorry, but KeAcquireSpinLock is encapsulation! and
KeSynchronizeExecution is too! Consider KeSynchronizeExecution as “SMP-safe
encapsulation around cli/sti pair”.

The programming styles who go directly to hardware in the presence of the OS
primitives
will surely break encapsulation which you consider to be good.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com