Best practices, tips

Hello all,

I have been learning about Windows Kernel Mode Development for some time now. So far I have not developed anything serious, I just thought up some projects that I use to get a feeling for developing drivers as I think the best way of learning is by doing.
I do not study anything Computer-Science related (although sometimes I wish I had) but recently I came into contact with someone from the Computer-Science department of my university and we talked about my interest in coding; driver development in particular.

I am now working on a kernel driver for one of his projects. My question is if some of you could help me make sure that I am doing thing “how they should be done”. I don’t mean this in the sense that I want people to review my code, but more to point me to references that explain things like the PAGED_CODE() macro.

So to summarize; I feel that I understand the basics of driver development, I have written several working drivers that share events with user mode, use IOCTLs etc.
But recently I looked into PREfast and was amazed by the things I didn’t know yet, but that can be very valuable in a serious project (like driver annotations, I am really glad I found out about that early in the project). So I wonder if there are more things like this, possibly in some ‘best practice guide’.

Thank you all in advance for your time.

Chris

Well, the reference that explains the PAGED_CODE() macro is the WDK
documentation.

An Intellisense endowment such as Source Insight or Visual Assist may be
very helpful
in hacking through unfamiliar code.

Code reviews also are helpful. In the opensource world this is free, in
Windows… it depends :wink:
The rest you already know… Happy learning!
–pa

wrote in message news:xxxxx@ntdev…
> Hello all,
>
> I have been learning about Windows Kernel Mode Development for some time
> now. So far I have not developed anything serious, I just thought up some
> projects that I use to get a feeling for developing drivers as I think the
> best way of learning is by doing.
> I do not study anything Computer-Science related (although sometimes I
> wish I had) but recently I came into contact with someone from the
> Computer-Science department of my university and we talked about my
> interest in coding; driver development in particular.
>
> I am now working on a kernel driver for one of his projects. My question
> is if some of you could help me make sure that I am doing thing “how they
> should be done”. I don’t mean this in the sense that I want people to
> review my code, but more to point me to references that explain things
> like the .
>
> So to summarize; I feel that I understand the basics of driver
> development, I have written several working drivers that share events with
> user mode, use IOCTLs etc.
> But recently I looked into PREfast and was amazed by the things I didn’t
> know yet, but that can be very valuable in a serious project (like driver
> annotations, I am really glad I found out about that early in the
> project). So I wonder if there are more things like this, possibly in some
> ‘best practice guide’.
>
> Thank you all in advance for your time.
>
> Chris
>
>

I was told not having a CS degree doesn’t really hurt one’s career in sw
engineering, although I did have big trouble rebalancing a binary tree after
removing a node at the time RTL generic table is not built in ntoskrnl.
Fortunately don’t need to do that very often.

Besides PREfast, you may also add PREfix, Driver Verifier, Static Driver
Verifier to your checklist. Depending on the type of driver you are writing,
there might be more specific tests for it, ie NDIStest for L2 nic, Sparta
for TOE nic. You should also define your own test plans too. In my
experience, real bugs, bad bugs are rarely (if any) detected by standardize
tests. Run tests as early as possible. Make smaller changes one at a time if
possible. Use a good source control system to keep your source code(Perforce
is my favor). Many nasty regressions are found by looking and diff’ing
changelists.

These by no way constitute “good practices” but work pretty well for me.

Hope that helps,
Calvin Guan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Monday, February 08, 2010 1:40 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Best practices, tips

Hello all,

I have been learning about Windows Kernel Mode Development for some time
now. So far I have not developed anything serious, I just thought up some
projects that I use to get a feeling for developing drivers as I think the
best way of learning is by doing.

I do not study anything Computer-Science related (although sometimes I wish
I had) but recently I came into contact with someone from the
Computer-Science department of my university and we talked about my interest
in coding; driver development in particular.

I am now working on a kernel driver for one of his projects. My question is
if some of you could help me make sure that I am doing thing “how they
should be done”. I don’t mean this in the sense that I want people to review
my code, but more to point me to references that explain things like the
PAGED_CODE() macro.

So to summarize; I feel that I understand the basics of driver development,
I have written several working drivers that share events with user mode, use
IOCTLs etc.
But recently I looked into PREfast and was amazed by the things I didn’t
know yet, but that can be very valuable in a serious project (like driver
annotations, I am really glad I found out about that early in the project).
So I wonder if there are more things like this, possibly in some ‘best
practice guide’.

Thank you all in advance for your time.

Chris


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> Use a good source control system to keep your source code(Perforce

is my favor). Many nasty regressions are found by looking and diff’ing
changelists.

This is incredibly useful. I aim to ‘check in’ almost every ‘complete’
change I make.

A good source control system will be able to semi-automate tracking down
a problem (‘bisect’ I think it’s called under mercurial). The idea is
that for a reproducible bug that has crept in but you don’t know exactly
when, you nominate the most recent changeset where you know the bug
didn’t exist, and the oldest changeset where you know the bug did exist,
and do a binary search until you find the offending changeset. Obviously
it can be done manually but a little automation makes it much easier.

James

My degree is in Psytchology and religion. Of course in 1969 when I
graduated, computers were rare, and computer science degrees even rarer.
With a CS degree, yeah you may indeed know how to write a Fibonacci routine,
or even a bTree, but I have NEVER EVER seen a need for a fibber anything,
and seldom, until recently have I needed a binary tree in the kernel. It’s
not “may”, but will need at one time or another, all of the test and
diagnostic tools mentioned, plus figure out your own and maybe even new
applications and uses of all of those tools.

Oh yeah … don’t get old … I do believe I have encountered genuine age
discrimantion on this job hunt. IK guess “they” are afraid I’ll retire in 2
or 3 years. Rediculous. In my experience, “they” will be laying me off in 2
or 3 years after I’ve finished the driver work.

Gary G. Little
H (952) 223-1349
C (952) 454-4629
xxxxx@comcast.net

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Calvin Guan
Sent: Monday, February 08, 2010 8:12 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Best practices, tips

I was told not having a CS degree doesn’t really hurt one’s career in sw
engineering, although I did have big trouble rebalancing a binary tree after
removing a node at the time RTL generic table is not built in ntoskrnl.
Fortunately don’t need to do that very often.

Besides PREfast, you may also add PREfix, Driver Verifier, Static Driver
Verifier to your checklist. Depending on the type of driver you are writing,
there might be more specific tests for it, ie NDIStest for L2 nic, Sparta
for TOE nic. You should also define your own test plans too. In my
experience, real bugs, bad bugs are rarely (if any) detected by standardize
tests. Run tests as early as possible. Make smaller changes one at a time if
possible. Use a good source control system to keep your source code(Perforce
is my favor). Many nasty regressions are found by looking and diff’ing
changelists.

These by no way constitute “good practices” but work pretty well for me.

Hope that helps,
Calvin Guan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Monday, February 08, 2010 1:40 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Best practices, tips

Hello all,

I have been learning about Windows Kernel Mode Development for some time
now. So far I have not developed anything serious, I just thought up some
projects that I use to get a feeling for developing drivers as I think the
best way of learning is by doing.

I do not study anything Computer-Science related (although sometimes I wish
I had) but recently I came into contact with someone from the
Computer-Science department of my university and we talked about my interest
in coding; driver development in particular.

I am now working on a kernel driver for one of his projects. My question is
if some of you could help me make sure that I am doing thing “how they
should be done”. I don’t mean this in the sense that I want people to review
my code, but more to point me to references that explain things like the
PAGED_CODE() macro.

So to summarize; I feel that I understand the basics of driver development,
I have written several working drivers that share events with user mode, use
IOCTLs etc.
But recently I looked into PREfast and was amazed by the things I didn’t
know yet, but that can be very valuable in a serious project (like driver
annotations, I am really glad I found out about that early in the project).
So I wonder if there are more things like this, possibly in some ‘best
practice guide’.

Thank you all in advance for your time.

Chris


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

__________ Information from ESET Smart Security, version of virus signature
database 4849 (20100208) __________

The message was checked by ESET Smart Security.

http://www.eset.com

__________ Information from ESET Smart Security, version of virus signature
database 4849 (20100208) __________

The message was checked by ESET Smart Security.

http://www.eset.com

>didn’t exist, and the oldest changeset where you know the bug did exist,

and do a binary search until you find the offending changeset.

…and run the repro tests on each build :slight_smile: too time consuming.

Also, not all bugs are newly introduced by the recent updates.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>

>didn’t exist, and the oldest changeset where you know the bug did
exist,
>and do a binary search until you find the offending changeset.

…and run the repro tests on each build :slight_smile: too time consuming.

Yes it is a bit harder to automate such things under windows. It’s logN
time though, so if you had 1024 commits in that time it should be 10-11
builds required.

1000 commits over a short amount of time would probably be unusual for
most windows drivers though, so it may be that some of the advantages
are lost when compared to just sorting through the changes and figuring
it out for yourself :slight_smile:

Also, not all bugs are newly introduced by the recent updates.

Correct. I am speaking of regressions here.

James

Thank you all for your replies.

Pavel A. wrote:

Well, the reference that explains the PAGED_CODE() macro is the WDK
documentation.

True, but my question is: “How do I find out about the existence of PAGED_CODE, or other coding practice like Driver Annotations”. In the case of PAGED_CODE I saw it being used in a driver’s source code and then found the documentation about it. I suppose going through the samples is a good way of discovering these things.

Calvin Guan wrote:

I was told not having a CS degree doesn’t really hurt one’s career in sw
engineering

I am a mechanical engineering student in a phase now where I have to choose a Master ‘direction’, I think I will stay in the field of mechanical engineering but I really don’t want to ‘close’ the door to a career in SW engineering (finding a combination would be ideal, but very hard). The guy who I work for now said the same, that the lack of a CS degree probably won’t hurt. I hope that is especially true for me as I am interested in security-related topics, like binary analysis, reverse engineering malware and besides that driver development. I think doing a project like this, that is connected to a university will help as well, I just hope companies will look at this kind of experience and appreciate the fact that I am learning these things in my own time rather that look at a paper that is suppose to prove your capabilities.

A good source control system will be able to semi-automate tracking down
a problem

That’s a good point, I do use a source control system now but not very effectively… at the end of the day I just commit my changes but I have never used it to look back yet… I should spend some time on this to include source control in my development process.

Oh yeah … don’t get old …

I hope not to have to worry about that for a long time… I’m 21 so there are enough labor years ahead of me :). I would expect this field to be one of the least age-discriminating though… it is not very physically demanding.

> With a CS degree, yeah you may indeed know how to write a Fibonacci routine, or even

a bTree, but I have NEVER EVER seen a need for a fibber anything, and seldom, until recently
have I needed a binary tree in the kernel.

I would say a request to write a function that calculates n’th Fibonacci number is just a test of one’s mental abilities. If one is unable to do something as simple as running { res=val1+val2;val1=val2;val2=res;} N times in a loop it does not really make sense to discuss issues like maintaining locking hierarchy and disabling re-entrancy in order to avoid deadlocks with this person, don’t you think…

Although you DEFINITELY don’t need a degree in CS (in fact, any formal education/training) to do programming you still need to be familiar with the books they study in CS courses just to make sure you understand the domain of a problem you are supposed to solve…

Anton Bassov

On Tuesday 09 February 2010 10:58:22 xxxxx@gmail.com wrote:

True, but my question is: “How do I find out about the existence of
PAGED_CODE, or other coding practice like Driver Annotations”. In the case
of PAGED_CODE I saw it being used in a driver’s source code and then found
the documentation about it. I suppose going through the samples is a good
way of discovering these things.

A good starting point is a book like ‘Programming the Windows Driver Model’
which will explain about the traditional things like PAGED_CODE; however it
was published in 2003 so it doesn’t have any information about driver
annotations: for that you’d need to read the “PREfast Driver Annotations” page
which can be found via http://msdn.microsoft.com/en-us/library/aa469205.aspx .

I’ve found that there are lots of useful articles on Microsoft’s driver
development site, starting at
http://www.microsoft.com/whdc/driver/default.mspx - e.g.
http://www.microsoft.com/whdc/driver/tips/default.mspx and
http://msdn.microsoft.com/en-us/library/ms796245.aspx .


Bruce Cran

Much of the problem here is that what is good practice is still
something people argue about. Take PAGE_CODE that the OP started this
discussion on, I have seen many people claim it is not worth using.
Personally, I completely disagree with that opinion, but I can
understand where they are coming from. I always use RTL_NUMBER_OF but
many developers never do or use something different. I personally
wonder why Microsoft has not deprecated RtlInitString since it is unsafe
(hint it uses strlen) so I never use it, but I am the exception.

On tools this could quickly venture into debates unapproved on this
forum, but for instance I use PC-Lint still and with a more stringent
set of checks than the article from years ago in the NtInsider. I
personally want all the driver code PreFast clean with no filters, but
almost no one else does. I would use /Wall to compile the driver, but
the Microsoft headers fail miserably with that.

So what is best practice? I suspect there is no common opinion.


Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

__________ Information from ESET Smart Security, version of virus
signature database 4851 (20100209) __________

The message was checked by ESET Smart Security.

http://www.eset.com

> I would say a request to write a function that calculates n’th Fibonacci number

Yes, if the person remembers what is Fibonacci number :slight_smile: I only read about them 10 years old in one of the numerous Soviet books for smart children, and then forgot _due to never meet them in practice (uni courses included to “practice”).


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> personally want all the driver code PreFast clean with no filters, but

almost no one else does.

I do :slight_smile: though some very special are suppressed with #pragma

I would use /Wall to compile the driver, but
the Microsoft headers fail miserably with that.

#pragmas help a lot. Note: you do not need portability to non-MS compiler usually.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> Much of the problem here is that what is good practice is still

something people argue about.

With a lot of things in ‘our’ field that is the case I guess, people still argue when void main is acceptable(please don’t continue on this ;)).

I personally wonder why Microsoft has not deprecated RtlInitString since it is unsafe
(hint it uses strlen) so I never use it, but I am the exception.

Those are sort the things I was aiming for in my post as well… until now I could’ve used that function, unknowing that it is unsafe. So how can I as a self-learning developer know about these things?

I personally want all the driver code PreFast clean with no filters, but
almost no one else does.

I have to admit that I ignored it until recently… but I hit myself now for not looking into it before…

You do the best you can and learn what you can along the way. Reflect. Adjust. Lather. Rinse. Try again. Repeat.

That’s (IMO) what everyone does, despite the best laid plans or lack thereof.

I commend your interest, but personally, I think you’re sweating the small stuff for no reason at the moment, because as a beginner, suffice to say that you will find your time occupied by more pressing things, like bsod’s, et. c.

Obviously, you’ve got to do whatever works for you and you’re certainly the only one who knows what that is, but if you happen to be sort of cycling, trying to figure out the BEST way to start, my advice, for what it’s worth is just to pick something and see how it goes. Evaluate. Adjust. Repeat.

Personally, I think that the worst thing that you can do is make decisions up front that you (or anyone new) really don’t know the answers to and then sticking to them as ‘best practices.’ I would suggest that you just get something working first. You’ll find it (I think) a lot more enjoyable, which is important, especially in the beginning, because what you’re going to find yourself struggling with more than anything else (imo) is windbg. That’s what I would see the purpose of ‘getting something working’ is - starting to get familiar with windbg (unless you’re name is Michal, but that’s a different story).

Good luck,

mm

For the most part the samples in the WDK are pretty good practice. The
RtlInitString thing is one that I took a look at noticing that it took a
NULL terminate string with no length constraint so disassembled the
function. On PreFast my preference on false positives is in order:

a. Change the code to avoid the tools problem
b. Annotate to clean up the warning
c. Use #pragma around the specific line that has the problem

I do use /W4 /Wp64 /WX on all my compiles these days.


Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@gmail.com” wrote in message
news:xxxxx@ntdev:

> > Much of the problem here is that what is good practice is still
> > something people argue about.
>
>
> With a lot of things in ‘our’ field that is the case I guess, people still argue when void main is acceptable(please don’t continue on this ;)).
>
>
> > I personally wonder why Microsoft has not deprecated RtlInitString since it is unsafe
> > (hint it uses strlen) so I never use it, but I am the exception.
>
>
> Those are sort the things I was aiming for in my post as well… until now I could’ve used that function, unknowing that it is unsafe. So how can I as a self-learning developer know about these things?
>
>
> > I personally want all the driver code PreFast clean with no filters, but
> > almost no one else does.
>
>
> I have to admit that I ignored it until recently… but I hit myself now for not looking into it before…

Information from ESET Smart Security, version of virus
signature database 4851 (20100209)


The message was checked by ESET Smart Security.

http://www.eset.com

On Tuesday 09 February 2010 17:55:30 Don Burn wrote:

Much of the problem here is that what is good practice is still
something people argue about. Take PAGE_CODE that the OP started this
discussion on, I have seen many people claim it is not worth using.
Personally, I completely disagree with that opinion, but I can
understand where they are coming from. I always use RTL_NUMBER_OF but
many developers never do or use something different. I personally
wonder why Microsoft has not deprecated RtlInitString since it is unsafe
(hint it uses strlen) so I never use it, but I am the exception.

On tools this could quickly venture into debates unapproved on this
forum, but for instance I use PC-Lint still and with a more stringent
set of checks than the article from years ago in the NtInsider. I
personally want all the driver code PreFast clean with no filters, but
almost no one else does. I would use /Wall to compile the driver, but
the Microsoft headers fail miserably with that.

So what is best practice? I suspect there is no common opinion.

I’m not sure it’s so much a case of ‘best practice’ but what experienced
developers might think of as ‘normal practice’ - things like creating checked
builds, running the driver verifier etc. Having spent quite some time recently
working on a driver which didn’t even compile under the checked build
environment and which had numerous bugs which would have been found within
minutes of running verifier.exe I think it’s easy to forget that there are a
lot of standard tools that people should learn to run from the start, before
even getting to SDV, annotations etc. I think the important thing is that
people choose a tool to run that does some validation of their code.


Bruce Cran

Actually, I will disagree on the claim before getting to annotations
etc. Personally, I will not run a driver on a test system until it
compiles with /W4 /Wp64 /WX and is PreFast clean. As general practice I
try to run SDV on it in the evening (I find SDV too slow for normal
use), and I run PC-LINT and at least review the errors if not clean them
up.

It is stupid to me to not run PreFast and clean things up before you
drop the code on a test platform and see it fail with a bug that PreFast
would have found.


Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Bruce Cran” wrote in message news:xxxxx@ntdev:

>
> I’m not sure it’s so much a case of ‘best practice’ but what experienced
> developers might think of as ‘normal practice’ - things like creating checked
> builds, running the driver verifier etc. Having spent quite some time recently
> working on a driver which didn’t even compile under the checked build
> environment and which had numerous bugs which would have been found within
> minutes of running verifier.exe I think it’s easy to forget that there are a
> lot of standard tools that people should learn to run from the start, before
> even getting to SDV, annotations etc. I think the important thing is that
> people choose a tool to run that does some validation of their code.
>
> –
> Bruce Cran

Information from ESET Smart Security, version of virus
signature database 4852 (20100209)


The message was checked by ESET Smart Security.

http://www.eset.com

MM Wrote:

I would suggest that you just get something working first.

That is what I have been doing so far, and it has indeed been really enjoyable ;).
WinDbg is indeed an essential ‘tool’ to get the hang of, I have spent quite some time in getting acquainted with it and I will continue to due so as I am sure it has much more to offer than what I use it for now.

I want to thank you all for your links, advise and restoring my confidence that it wasn’t a mistake to study mechanical engineering after all ;).
From your comments I think that I am on the right track, it’s just that I really start to think a lot now if what I am doing is not only working, but also the right way. But with your comments I know now what I have to do to verify my work :wink:

Thanks again

On Tuesday 09 February 2010 20:14:53 Don Burn wrote:

Actually, I will disagree on the claim before getting to annotations
etc. Personally, I will not run a driver on a test system until it
compiles with /W4 /Wp64 /WX and is PreFast clean. As general practice I
try to run SDV on it in the evening (I find SDV too slow for normal
use), and I run PC-LINT and at least review the errors if not clean them
up.

It is stupid to me to not run PreFast and clean things up before you
drop the code on a test platform and see it fail with a bug that PreFast
would have found.

By “before getting to” I meant that if there’s one tool people should learn to
use even if they don’t run any others (and it’s so useful that it shouldn’t be
controversial) it should be the driver verifier. I agree that people should
also learn to compile with the highest warnings, use driver annotations and
run PREfast right from the start of a new driver project too, since it’ll save
time later on.


Bruce Cran