Friday, August 28, 2009

livekd: error finding i386kd.exe

Problem: after running livekd.exe in the console window, it says: error finding i386kd.exe
Reason: livekd cannot find the path of "Debuging tools for Windows" .
Solution: edit "path" environment variable, add the path to "Debuging tools for Windows" .

Wednesday, August 26, 2009

NICKLE (rootkit detection , prevention)

http://friends.cs.purdue.edu/dokuwiki/doku.php?id=nickle

Page Table Entry format

http://www.cs.nmsu.edu/~pfeiffer/classes/473/notes/intelvm.php?currentsem=f09

Intel Secrets and SMM

http://www.rcollins.org/ddj/ddj.html

Monday, August 17, 2009

Trailing a Growing File in Perl

http://oreilly.com/catalog/cookbook/chapter/ch08.html
Trailing a Growing File

Problem
You want to read from a continually growing file, but the read fails when you reach the (current) end of file.
Solution
Read until the end of file. Sleep, clear the EOF flag, and read some more. Repeat until interrupted. To clear the EOF flag, either use seek: for (;;) {
while () { .... }
sleep $SOMETIME;
seek(FH, 0, 1);
}
or the IO::Handle module's clearerr method: use IO::Seekable;

for (;;) {
while () { .... }
sleep $SOMETIME;
FH->clearerr();
}
Discussion
When you read to the end of a file, an internal flag is set that prevents further reading. The most direct way to clear this flag is the clearerr method, if supported: it's in the IO::Handle and FileHandle modules. $naptime = 1;

use IO::Handle;
open (LOGFILE, "/tmp/logfile") or die "can't open /tmp/logfile: $!";
for (;;) {
while () { print } # or appropriate processing
sleep $naptime;
LOGFILE->clearerr(); # clear stdio error flag
}
If that simple approach doesn't work on your system, you may need to use seek . The seek code given above tries to move zero bytes from the current position, which nearly always works. It doesn't change the current position, but it should clear the end-of-file condition on the handle so that the next picks up new data.
If that still doesn't work (e.g., it relies on features of your C library's (so-called) standard I/O implementation), then you may need to use the following seek code, which remembers the old file position explicitly and returns there directly. for (;;) {
for ($curpos = tell(LOGFILE); ; $curpos = tell(LOGFILE)) {
# process $_ here
}
sleep $naptime;
seek(LOGFILE, $curpos, 0); # seek to where we had been
}
On some kinds of filesystems, the file could be removed while you are reading it. If so, there's probably little reason to continue checking whether it grows. To make the program exit in that case, stat the handle and make sure its link count (the third field in the return list) hasn't gone to 0: exit if (stat(LOGFILE))[3] == 0
If you're using the File::stat module, you could write that more readably as: use File::stat;
exit if stat(*LOGFILE)->nlink == 0;

See Also
The seek function in perlfunc (1) and in Chapter 3 of Programming Perl ; your system's tail (1) and stdio (3) manpages

Friday, August 14, 2009

ABOUT TCPDUMP DROP PACKET

http://blog.tianya.cn/blogger/post_show.asp?BlogID=227219&PostID=16646525&idWriter=0&Key=0

tcpdump丢包分析
作者:waitquiet 提交日期:2009-3-3 18:29:00 | 分类: | 访问量:213 

  通过tcpdump抓包时,结束后tcpdump会给出如下统计信息:
  1552 packets captured
  1586 packets received by filter
  34 packets dropped by kernel
  
  其中“captured”的计数指的是应用层捕获到的数据,“received by filter”和“dropped by kernel”的计数由内核维护,应用层通过getsockopt来获取。收到一个包,“received by filter”会加1,如果sock的接收buffer被填满时,则把这个数据包丢弃,将“dropped by kernel”加1。
  if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf){
   spin_lock(&sk->sk_receive_queue.lock);
   po->stats.tp_drops++;
   spin_unlock(&sk->sk_receive_queue.lock);
  }
  通过调节/proc/sys/net/core/rmem_default和/proc/sys/net/core/rmem_max能够改变sk_rcvbuf的大小。
  
  正常“captured”加上“dropped by kernel”应该等于“received by filter”的大小,有的时候出现不等的情况应该是还有一些数据包在sk_rcvbuf中,还没有被应用层收到的原因。

Sunday, August 9, 2009

cell phone anti-theft software

General phones:
http://techzoogle.com/antitheft-technologies-for-cell-phones/
http://www.ghacks.net/2008/05/17/anti-theft-software-for-mobile-phones/
http://www.wimp-software.co.uk/

iPhones:
http://www.gadgettrak.com/products/iphone/
http://theory.isthereason.com/?p=2302
http://thinkabdul.com/2008/02/23/iphone-findme-free-anti-theft-software-for-apple-iphone-to-retrieve-gsm-cell-id-location-via-twitter/

Monday, August 3, 2009

Develop windows drivers: resources and tips

http://students.cs.byu.edu/~nbushman/drivers.htm


Author: Nate
Bushman
     Last Modified: 18

August 2003

People keep on asking me, "Hey, how can I learn how to write
drivers?"  Well, I

wrote up this document to help answer that question (at
least partially).  The first

part of this document lists various driver dev
resources, and the second part

contains a bunch of tips and tricks.


WinNT/2K/XP Kernel Mode Device Driver Development Resources




THE MICROSOFT WINDOWS DRIVER DEVELOPMENT KIT (DDK):



The DDK and its associated documentation and samples is an essential

resource for learning about device driver development. Once you're

familiar with the basics (read one of the books below) you should

definately go through the sample drivers that come with the DDK.

The "toaster" sample code contains generic code for several types of


drivers. You can order the DDK at: http://www.microsoft.com/ddk

The Windows Driver Development Kit also ships with the MSDN.



BOOKS:



"Windows NT Device Driver Development" by Peter Viscarola and Tony Mason.

This is the first NT driver book I read, and still the first one that I

recommend. It's got all of the essentials and is clearly written. 95%


of the stuff in this book still applies to W2K/XP drivers too.



"Programming the Microsoft Windows Driver Model, 2nd ed." by Walter Oney et al.

Read this book as soon as you can. It's filled with guidelines that will help you to

avoid the common mistakes. I couldn't believe how many things I'd learned

the hard way that I could have avoided if I'd read this book first.



"Inside Windows 2000, 3rd Ed." by David Solomon and Mark Russinovich.


This isn't a driver dev book, but you'll soon see drivers don't run in their

own sandbox. They're an integral part of the OS, and in order for them

to work properly you need to have a good understand of how the OS works.

This book is an absolute goldmine of OS internals. Highly recommended.



"The Windows 2000 Device Driver Book, 2nd Ed." Be sure to get the second

edition which was recently published. The first edition has many errors.

I like this book. It's only around 400 pages, so it's not overkill, and


it has a lot of really useful insights. It's helpled me to solve some

pretty tricky problems that I didn't find solutions to anywhere else. I'd

still recommend that you read Viscarola and Mason's book first.



"Windows NT/2000 Native API Reference" by Gary Nebbett. NT provides tons of

useful functionality through the native NT API. Most of this API is

undocumented and may change at any time. However, sometimes using these

undocumented functions is the only way you can accomplish certain tasks.


This book documents this API for the first time.



"Developing Windows NT Device Drivers" by Ed Dekker and Joseph Newcomer.

I've only been using this one as reference, so I can't say how good the

content is. I love the useful tables in the back of this book, and what

I have read is well written and clear.



"Windows NT File System Internals" by Rajeev Nagar. This is the only


file system driver book available for the NT platform, and it doesn't

cover any of the new stuff found in W2K or XP. However, it's got a lot

of useful info that you can't find anywhere else.



"Windows 2000 Kernel Debugging" by Steven McDowell. For me, this book

was mostly a waste of time. But if you've have zilch exposure to kernel

debugging then this book may help you to get up to speed a bit faster.

It's a very fast read as it only has a little over 200 pages of useful


text. When you really want to get to know the kernel debugger, read

the debugger documentation that comes with WinDbg. You can download

WinDbg at http://www.microsoft.com/ddk/debugging/ The WinDbg
documentation

is fantastic. When you start writing drivers you'll be crashing your

machine all the time, so getting to know the debugger is very important.



"Writing Windows WDM Device Drivers" by Chris Cant. I've only read parts


of this book, and what I read was useful. I've heard several people complain

that it has a lot of errors.



"Undocumented Windows 2000 Secrets" by Sven Schreiber. Not really an essential

book, but it may help you if you have to do some tricky stuff like patching

the system service descriptor table (this would allow you to filter native

API calls), or if you need to understand the until-now undocumented format of

Microsoft's .PDB symbol files.




Microsoft has also published the DDK documentation as a three-volume set.



WEB SITES:



http://www.microsoft.com/whdc/ - Windows Hardware and Driver Central
Home

http://www.microsoft.com/ddk - The home of
the DDK


http://www.microsoft.com/ddk/debugging/
- Get your kernel debugger here


http://www.microsoft.com/hwdev - More
driver dev resources from Microsoft

http://www.osr.com - Home of "The NT Insider," the
online DDK docs, & more

http://www.osronline.com - OSR's new online presence


http://www.sysinternals.com - Tons of
useful
apps and docs for systems programmers

http://www.hollistech.com - Home of
ddkbuild.bat - build your driver from the GUI

http://www.oneysoft.com - Home of "Programming
the Windows Driver Model" book

http://www.pcausa.com - Useful if you're writing
any kind of network driver


http://www.cmkrnl.com/faq.html - Jamie Hanrahan's (of Kernel Mode Systems) useful
faq

http://www.compuware.com - Makers of the SoftICE debugger and other driver dev
tools

http://www.wd-3.com - The Windows Driver Developer's Digest.



PERIODICALS:



"The NT Insider" - Sign up for the free distribution of this bimonthly


publication at http://www.osr.com It's packed with useful tips.



Matt Pietrek's "Under the Hood" column articles found in the Microsoft Systems

Journal (available in the MSDN Library) - Tons of useful systems programming

tips over several years. Microsoft stopped printing the MSJ and most of the

articles from MSJ (including Matt's) can now be found in MSDN Magazine.




Jim Finnegan's "Nerditorium" column articles found in the Microsoft Systems

Journal (available in the MSDN Library) - Even more driver oriented than

Pietrek's stuff. Read his March 1998 article for a quick intro to NT drivers.

href="http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0398/driver.htm">http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0398/driver.htm



Mark Russinovich's column articles found in Windows 2000 Magazine. Mark's

articles are clear and detailed, and provide very useful information on


how various parts of the OS are implemented and work. If you don't have

a subscription to Windows 2000 Magazine you can still get access to all but

his latest articles at www.windows2000mag.com He's also provided a ton

of systems programming resources at his website: href="http://www.sysinternals.com">http://www.sysinternals.com



EMAIL LISTS:



OSR hosts two fantastic email lists that are very active and an excellent

resource to driver developers. They are NTDEV and NTFSD. Post general driver


dev questions to NTDEV and post file-system driver specific questions to

NTFSD. You can sign up for these email lists at http://www.osr.com

and archives of these lists are found at http://www.ntdev.org.


NEWSGROUPS:



comp.os.ms-windows.programmer.nt.kernel-mode
(Very Good)

microsoft.public.development.device.drivers

(Very Good)

microsoft.public.win32.programmer.kernel(Very
Good)

microsoft.public.windbg (For help with the kernel debugger)

microsoft.public.ddk.* (There are several of these)



SEMINARS:




http://www.osr.com/seminars_main.shtml



http://www.azius.com


http://www.oneysoft.com/wdmclass.htm




OTHER RESOURCES:



The Microsoft Installable File System Development kit (IFS kit). This is a

$1000 CD that comes with the complete source for FastFAT and CDFS. If you're

writing file system or file system filter drivers then you'll want to buy the

IFS kit. I don't know about the XP IFS kit, but the W2K IFS kit comes with the


NT IFS kit. You can find more info at:

http://www.microsoft.com/ddk/IFSkit/




 


WinNT/2K/XP Device Driver Development Tips'n'Tricks


PERFORM BASIC TESTING



1) Turn the Driver Verifier on when you’re testing your driver. On your test
machine just run “verifier” from the Start | Run dialog. Driver Verifier will
let you perform a number of tests on the driver(s) of your choice. Click on the
Settings tab and select the driver(s) that you want Verifier to test, then in
the same tab select which tests you want Verifier to perform. You should at a
minimum select the Special Pool, Force IRQL Checking, Pool Tracking and I/O
Verification Level 1 tests.

2) Test your driver on both the free and checked builds of the OS. The checked
OS is full of assertions that will help you to find bugs. To quote Peter
Viscarola of OSR, “To me, there is very little that is sloppier or more
unprofessional looking than to have your released driver cause ASSERTS in the
Checked build. I mean, the Checked build contains very basic tests for
correctness. If you can’t pass those, it implies that you haven’t even done the
basics in terms of testing.” If you’re testing with a hybrid OS (a free OS with
checked versions of the HAL and kernel), you should also add checked versions of
the other drivers that your driver interacts with. For example, if you’re
testing a storage filter driver on a hybrid system, then in addition to the
checked HAL and kernel, you should also install the checked versions of ntfs.sys,
fastfat.sys, diskperf.sys, ftdisk.sys, classpnp.sys, scsiport.sys, etc.

3) Enable pool tagging on your test system, and be sure to use the “WithTag”
variations of any function calls that allocate memory. Pool tagging will help
you to discover memory leaks because it will associate a tag (which you provide
in the allocation call) with each memory allocation. Download PoolTag from OSR.
It’s a nice GUI app that will both enable pool tagging and display the current
memory allocated to each tag.


4) Use WinDbg - Have a kernel debugger attached to the test machine(s) on which
you’re running your driver. If Driver Verifier finds a problem, or when the
checked build of the OS asserts, you’ll end up with a blue screen. It’ll save
you quite a bit of time if you have WinDbg attached to your test systems so that
these bug checks will simply trap in the debugger, allowing you to analyze the
problem immediately. Usually, this is simply a matter of dumping the stack of
the offending code to find out who caused the problem. Be sure to generate
symbol files for your driver so that kernel debuggers can analyze stacks/etc.
You do this in your SOURCES file, which I’ll discuss later.

5) Test your driver on multiprocessor systems. The more processors the better.
Basically you’ll be testing your code to make sure that it properly synchronizes
access to shared resources. Multiprocessor systems are more likely to reveal
synchronization bugs in your code like deadlocks.





USE GOOD DRIVER IMPLEMENTATION PRACTICES



1) Use ASSERT() for all assumptions in your code. Every function should have an
ASSERT() which checks the current IRQL to see if it is within the assumed range.
Every function that’s internal to the driver (that can’t be called by code
outside of the driver) should have ASSERTs that validate parameter values. If a
function assumes that it’s running in the system context, it should perform an
ASSERT to see if it’s process is the system process. By using ASSERTs to check
IRQL and process context, you’ll self-document these requirements for every
function.

2) Functions that can be called by code that is external to the driver must
validate their parameters. This check should always occur, regardless of whether
your driver is built in the free or checked environment. It should NOT be
checked using ASSERT(). Such functions include your driver’s dispatch, AddDevice,
DriverEntry, and Unload routines.

3) Beware of macros. Many of the APIs in the DDK are actually implemented as
macros. Never use arguments that are expressions with side effects. These
arguments could be passed to a macro instead of a function and the macro can
evaluate the expression multiple times. Use block notation for conditional
expressions to avoid problems with multi-statement macros. For example: if
(flag) DoSomething(); If the function DoSomething() is a actually a
multi-statement macro, then only the first statement in the macro would be
conditionally executed. Be safe and use block notation for your conditional
expressions, like: if (flag) { DoSomething(); }

4) Synchronize access to any resources that can be touched by more than one
thread at the same time. It’s far better to experience a performance hit due to
synchronization code and to have your code properly synchronized than to have
code that’s a little faster but full of bugs.


5) Use structured exception handling. More on this below.

6) Don’t touch paged memory at IRQL >= DISPATCH_LEVEL. Also, keep in mind that
the UNICODE character tables are in paged memory, so if you attempt to use a
DbgPrint() statement to print out a WCHAR/UNICODE string, the system will
attempt to access paged memory in order to convert that string to text that can
be sent to the attached kernel debugger. At DISPATCH_LEVEL, the statement
DbgPrint(“%S”, unicodeString.Buffer); will cause a 0x0A bug check.

7) Some entry points to your driver (such as AddDevice()) are documented to be
called at PASSIVE_LEVEL. For this reason these functions are often placed in a
pageable code section. Be aware that if you use a spinlock in such a function
that you must not place the code for the function in a pageable code section.
The reason for this is that the uniprocessor kernel will raise IRQL to
DISPATCH_LEVEL for the duration of ownership of the spinlock.

8) Avoid stack overflows. Every NT thread has two stacks, a user-mode and a
kernel-mode stack. The user-mode stack is quite large, but the kernel-mode stack
is limited to 12K. To avoid overflowing the kernel stack, avoid deeply nested
function calls, large local variables, and recursive calls. Also, some system
calls (especially the registry I/O calls) consume quite a bit of stack. You may
find it necessary to farm off some of your API calls to worker threads whose
stacks are empty. You can use ASSERTs with IoGetRemainingStackSize() to quickly
locate areas in your code where you might overflow the stack.

9) Avoid undocumented system calls. The behavior of these calls can change from
one implementation to the next, and even between service packs. If you do use
undocumented calls, document exactly which ones you used and the reasons you
were forced to use them.

10) Be very careful to avoid deadlocks if your driver initiates new I/O that
will pass through the stack in which your driver participates. This is
especially true if your driver blocks on that new I/O.

11) Keep in mind that the data that an IRP points to through its MDL can be
changing while your driver owns the IRP. An IRP MDL’s data is not static.

12) All completion routines (except routines which set events that dispatch
routines are waiting on – see IoMarkIrpPending documentation) must include this
code: if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } This is necessary in
order to propagate the PendingReturned flag up to the top of the stack so that
the IRP can be properly freed.


13) Zero-out (or use some other non-random value) structs that you are about to
free. This will help you to identify when you are referencing memory that has
already been freed. If you leave data in the struct, it’s likely that your code
will not complain about the data that it finds in the memory when it uses a
pointer that points to memory that’s already been freed. This technique is
easily accomplished by #defining a new version of the free-memory function that,
if DBG is defined, will zero-out the memory before freeing it.

14) Build in unit tests that fully test the features of your driver. Make it
possible for these test to be ran by a script. This will enable you to run a
daily batter of tests (a daily “smoke screen”) to see if any of the code you’ve
added that day has broken pre-existing code.



PERFORMANCE ENHANCING TIPS



1) Use lookaside lists (zones in NT 3.x) when you’re repeatedly allocating blocks
of memory that are the same size. Lookaside lists will hold onto previously
deallocated blocks instead of returning them to the Memory Manager. The next
time you need a block of memory the list can return one to you immediately
without all of the memory management overhead.

2) Use dispatcher synchronization objects (such as a mutex) instead of spinlocks
to synchronize access to resources where all of the code that accesses the
resource is guaranteed to run at IRQL PASSIVE_LEVEL.





USE WINDBG




1) Step through your code in WinDbg. WinDbg is a symbolic debugger capable of
source-level debugging. Stepping through your code and watching your variables
is one of the best ways to see if you actually implemented what you thought you
implemented.

2) WinDbg needs the symbol files (.PDB files) for your OS and for the driver
that you’re testing in order for it to analyze data in memory. I’ll discuss how
you can generate these files when I discuss tips on building your drivers.

3) Use cookies in your structs so that you can identify them when you’re poking
around in memory or in a crash dump file.

4) There’s so much to be said about taking advantage of the kernel debuggers
that it’s beyond the scope of this document. There is a book on using the kernel
debuggers, but it’s very basic. I’d recommend you read the documentation for
WinDbg. It’s been updated and is very clear and complete. WinDbg has undergone a
major transformation during the last year, and is significantly more powerful
and stable.

5) If you’re using WinDbg to analyze a crash dump file, use dumpchk.exe first to
check the file to see if it’s corrupt or not. If a driver has trampled over
critical data structures in memory, the crash dump file may not be usable.
Dumpchk.exe will tell you if a crash dump file is usable or not.



HAVE A SUPPORT PLAN



1) In order to support customers who experience system crashes, you’ll find that
it’s incredibly useful to be able to use WinDbg to symbolically debug their
crash dump files. In order to do this, you must provide WinDbg with the
necessary symbolic information. This symbolic information is found in the .PDB
file (the symbol file) that’s generated at build time. Unfortunately this file
is not generated by default. You must include instructions in your SOURCES file,
which I’ll describe in the next section. Occasionally you may run up against a
crash dump file that WinDbg has trouble analyzing. In this case you’ll end up
doing a lot of manual debugging. For this you will need to know which addresses
the linker mapped your symbols to. This is found in the .MAP file. You will also
need to view the mixed source/assembler for your driver. WinDbg isn’t capable of
doing this, but the compiler can generate .COD files for each of your .C files.
In the next section I’ll discuss how you can build your driver so that you
generate .PDB, .MAP and .COD files.

2) You may find it useful to create a debugger extension dll that will give you
extra commands in WinDbg specifically tailored to debugging your driver. WinDbg
comes with sample code for a simple debugger extension dll. They’re very easy to
write.


3) Do not release your .PDB files to the public. These files can be used to
obtain the entire original source of your driver.





BUILDING YOUR DRIVER



1) When you build your driver, you’ll want the compiler/linker to generate the
following files: A symbol file (.PDB), a linker map file (.MAP), mixed
source/assembler files for each .C file (.COD) and a browse file that will let
you browse symbols when you’re editing your driver’s source code (.BSC).

2) You’ll want to set a suitable warning level for the compiler.

3) You’ll want to enable/disable the correct optimizations.

4) Here is a sample SOURCES file for a Windows 2000 driver that contains all of
the commands needed to accomplish items 1-3:


NOTE: This SOURCES file will only work, as is, with the Windows 2000 DDK. If you
are using a newer version of the DDK (such as the XP DDK) then you may run into build issues, especially
with the switch that specifies that mixed source/assembly .cod output files are
desired. Tommy Tam (VISTA Controls) says that he's used this SOURCES file with
a more-recent DDK by removing the /Fc*$.cod switch from MSC_OPTIMIZATIONS and by adding
either one of the the following lines:


USER_C_FLAGS=$(USER_C_FLAGS) -fc$(O)/

USER_C_FLAGS=$(USER_C_FLAGS) /FAcs /Fa$O\$B

You may also need to modify the free/checked paths for the linker .MAP file.





# START OF SAMPLE SOURCES FILE


# Specify the target file/type of the build

TARGETNAME=MyDriver

TARGETPATH=obj

TARGETTYPE=DRIVER




# Produce the same symbolic information for both free and checked builds.

# This will allow us to perform full source level debugging on both

# builds without affecting the free build's performance

!IF "$(DDKBUILDENV)" != "checked"

NTDEBUG=ntsdnodbg

NTDEBUGTYPE=both


USE_PDB=1

!ELSE

NTDEBUG=ntsd

NTDEBUGTYPE=both

USE_PDB=1

!ENDIF



# Set compiler optimizations:

# /Ox - Full optimization enabled


# /Os - favor speed over size when optimizing

# /Od - Disable all optimizations

# /Oi - Enable optimization for intrinsic functions

# /Fc$*.cod - Generate mixed assembler/source code files

#

# For both checked and free builds, make sure that any intrinsic

# functions are compiled correctly. To do this, ensure that /Oi

# is selected for both free and checked builds. There is a bug in

# VC++ 6.0 (at least through SP4) where, if you specify any


# intrinsic functions in your code with "#pragma intrinsic" but

# you don't have the /Oi optimization enabled, neither a call

# to the function, nor the intrinsic inline version of the function

# will end up in your object code. This bug only applies to free

# builds, but just to be safe we'll make sure that the flag is

# enabled for all builds.

!IF "$(DDKBUILDENV)" != "checked"


MSC_OPTIMIZATION=/Ox /Os /Oi /Fc$*.cod

!ELSE

MSC_OPTIMIZATION=/Od /Oi /Fc$*.cod

!ENDIF



# Generate a linker map file just in case we need one for debugging

!IF "$(DDKBUILDENV)" != "checked"


LINKER_FLAGS=$(LINKER_FLAGS) -MAP:.\objfre\i386\$(TARGETNAME).map \

-MAPINFO:EXPORTS -MAPINFO:LINES -MAPINFO:FIXUPS

!ELSE

LINKER_FLAGS=$(LINKER_FLAGS) -MAP:.\objchk\i386\$(TARGETNAME).map \

-MAPINFO:EXPORTS -MAPINFO:LINES -MAPINFO:FIXUPS

!ENDIF



# Generate a browser information file for use in IDE development

BROWSER_INFO=1


BROWSERFILE=$(TARGETNAME).BSC -n



# Set the compiler's warning level

MSC_WARNING_LEVEL=-W3 -WX



# Specify the files to be used in the build

INCLUDES=$(BASEDIR)\inc;.



SOURCES=MyDriver.c



# END OF SAMPLE SOURCES FILE



USE THE IDE



1) Visit http://www.hollistech.com or href="http://www.osr.com">http://www.osr.com and download DDKBUILD.BAT. This batch file
can be used to build drivers from the IDE. You’ll be able to edit, compile and
browse symbols (assuming your SOURCES file instructs the compiler to build a .BSC
file) all within the Visual Studio IDE. DDKBUILD.BAT does not interfere with the
default build mechanism. You’ll still be able to “build –cZ” your driver from
the command line build environment.



DEALING WITH COMMON BUG CHECKS (BLUE SCREENS)



Here are some of the more common bug checks, and methods for avoiding them:




0x0A (IRQL_NOT_LESS_OR_EQUAL)

0xD1 (DRIVER_IRQL_NOT_LESS_OR_EQUAL )

0x1E (KMODE_EXCEPTION_NOT_HANDLED)

0x7F (UNEXPECTED_KERNEL_MODE_TRAP)



IRQL_NOT_LESS_OR_EQUAL or DRIVER_IRQL_NOT_LESS_OR_EQUAL



These bug checks occur when your driver has touched paged memory when the
processor’s IRQL was >= DISPATCH_LEVEL. It’s pretty easy to avoid this bug
check. Only make API calls at IRQLs that those APIs are documented to support.
If it’s reasonable, use NonPaged pool whenever you allocate memory. Don’t place
your code in pageable sections unless that code is guaranteed to run at IRQL <
DISPATCH_LEVEL and never uses spinlocks. Don’t use DbgPrint or KdPrint to print
out unicode strings if IRQL >= DISPATCH_LEVEL. Don’t assume that your dispatch
functions will be called at PASSIVE_LEVEL. Usually they will, but IoCallDriver()
can be called at IRQL <= DISPATCH_LEVEL, so it’s legal for the driver above you
to pass an IRP down to you at DISPATCH_LEVEL.




KMODE_EXCEPTION_NOT_HANDLED



You should use structured exception handling in your driver so that it
can gracefully detect these exceptions and recover from them. Walter Oney has an
excellent section on structured exception handling in his book Programming the
Windows Driver Model.



UNEXPECTED_KERNEL_MODE_TRAP



The most common cause of this bug check is a kernel-stack overflow. The
documentation doesn’t mention this. Use WinDbg to print out the stack to find
out which one of your functions is eating up all of the 12K of kernel stack. To
avoid this bug check, don’t use recursive calls, deeply nested calls, or
functions with large local variables. Use assertions on the current stack size
to determine which areas of your code are potential stack eaters.

 









IRP HANDLING RULES

by Maxim S. Shatskih



- IoMarkIrpPending must be called before the IRP will arrive to a context (queue or such), from where it can be completed in
an async way by other code paths (DPCs or such).

- IoMarkIrpPending requires STATUS_PENDING to be returned, and vice versa. No exceptions from this.

- if you want to complete the IRP just in the dispatch routine, return the same status as you put to Irp->IoStatus.Status.
This cannot be STATUS_PENDING. Do not call IoMarkIrpPending.

- Irp->IoStatus.Status must be filled only just before IoCompleteRequest. You can use Irp->IoStatus as a temporary storage
before this :-) (at least if you do not pass the IRP down). Also note that Irp->IoStatus.Information can hold a pointer (it
really holds it for some PnP IRPs).

- drivers which are not bottom-most, including all filters, can also pass the IRP down by "return IoCallDriver". In this case,
IoMarkIrpPending must not be called (regardless of NT4's CLASS2 code which had such a bug, it was not hit only because
SCSIPORT always returned STATUS_PENDING, and my full SCSI port code hit it more or less soon).

- this sequence is also valid, though slower. It is necessary as a workaround for filtering some buggy drivers like NT4's
CDFS:




IoMarkIrpPending(Irp);

(VOID)IoCallDriver(BottomDeviceObject, Irp);

return STATUS_PENDING;



- now the completion routines. Only 2 return values are valid. STATUS_MORE_PROCESSING_REQUIRED and STATUS_SUCCESS.

- STATUS_MORE_PROCESSING_REQUIRED means that IoCompleteRequest exits immediately. Next completion routines are not called, and
IRP is not passed to IO manager for destruction.

- if and only if the completion routine returns STATUS_SUCCESS, then it must do the following:




if( Irp->PendingReturned )

IoMarkIrpPending(Irp);



Just copy-paste it. It is necessary. Too bad IoCompleteRequest does not this itself.



- now the kinds of IRPs. "Full-blown" and "not-full-blown".

- first are created by IoBuildDeviceIoControlRequest and IoBuildSynchronousFsdRequest, including the IO syscalls called from
user mode or by Zwxxx (NtxxxFile functions use the Ioxxx functions are mentioned). These IRPs are associated with the thread,
and IoGetRequestorProcess works for them. These IRPs must be passed to IO manager for destruction by returning STATUS_SUCCESS
from the completion routine. IoFreeIrp cannot be called for them.

- "not-full-blown" IRPs are created by IoBuildAsynchronousFsdRequest and IoAllocateIrp. They are not associated with any
thread. They cannot be passed to IO manager for destruction, the completion routine must return
STATUS_MORE_PROCESSING_REQUIRED. They must be freed by IoFreeIrp, possibly in the completion routine.


- if you send the IRP down to some driver, you can use any way of the above ones. The driver will not be interested in how the
IRP coming from above was built.

- for first way, create an event, pass it to IoBuildDeviceIoControlRequest, then call IoCallDriver, then wait for event. IRP's
result will be in IO_STATUS_BLOCK passed to IoBuildDeviceIoControlRequest.

- for second way, create an event, write a completion routine of:



KeSetEvent((PKEVENT)Context, IO_xxx_INCREMENT, FALSE);

return STATUS_MORE_PROCESSING_REQUIRED;



then call IoAllocateIrp, then IoSetCompletionRoutine with event as a context, then call IoCallDriver, then wait for event.
After this, IRP's result is in Irp->IoStatus. You can either free the IRP by IoFreeIrp now, or call IoReuseIrp and then reuse
the IRP for next calls, calling IoFreeIrp later.

- now Irp->RequestorMode. It governs how the buffer pointer checks are made in the drivers which use Irp->UserBuffer - like
FSDs. If mode is KernelMode, then no checks are made. If mode is UserMode, then Irp->UserBuffer is probed to be user mode
pointer. So, for your own IRPs which fill Irp->UserBuffer, set Irp->RequestorMode to KernelMode.


- note that some stacks like 1394 require Irp->RequestorMode to be KernelMode.








Marking an IRP as pending in a file system filter driver

by Ravisankar Pudipeddi

extracted from the OSR NTFSD email list



Ah, confusion reigns again regarding what pending, cancel, synchronous i/o etc. mean. Time for a refresh yet again: let my
try to explain succintly as a set of rules (hopefully this will be more clearer). You have to read all the rules to
understand, and this is specifically targeted towards FSD/filter developers.




1.) You can return STATUS_PENDING by default for any IRP, including IRP_MJ_CREATE - except for a few special IRPs for which
STATUS_PENDING indicates something more. Currently these are the FSCTL_REQUEST*OPLOCK* IRPs. If you return pending for them,
the caller assumes the oplock is granted. For every other IRP, all STATUS_PENDING means is that if it's synchronous i/o (such
as a create), I/O manager will wait for the IRP to complete.



2.) When you return STATUS_PENDING, if it's a synchronous i/o, NT i/o manager automatically waits for the i/o to complete. You
needn't worry that you are making an inherently synchronous IRP asynchronous by returning pending. You are not.



3.) You HAVE to do IoMarkIrpPending() if you return STATUS_PENDING from your dispatch. You HAVE to return STATUS_PENDING if
you are doing IoMarkIrpPending() in your dispatch.



4.) If you are going to return STATUS_MORE_PROCESSING_REQUIRED from your *completion routine* for an IRP, then in your
*dispatch* (not in the completion): you have to mark the irp pending & return pending. This means you need to know in you
dispatch if you are going to abort processing in your completion. That's the way it works.



5.) If you are going to return STATUS_PENDING from your dispatch routine, and you have a completion routine, then you HAVE to
propagate the pending flag in your completion and vice versa. Propagating the pending flag up the stack in your completion
routine is as follows:

    if (Irp->PendingReturned) IoMarkIrpPending( Irp );


    Note the Irp->PendingReturned variable is NOT valid on the way down of an IRP. It comes into existence
only when an IRP is completing.



6.) As the converse of rule 5.) if you ARE going to wait for the IRP to complete in your dispatch - i.e. your completion
routine sets an event and returns STATUS_MORE_PROCESSING_REQUIRED, and then you pick up in your dispatch and return a
non-pending status, you must NOT propagate the pending flag in your completion routine. This is because you are not going to
return pending from your dispatch, you are synchronizing the i/o essentially in your dispatch. The rules can be probably be
further simplified as:

    If returning pending from dispatch, mark irp pending.

    If you marked an IRP pending in dispatch, return STATUS_PENDING from dispatch.

    If you are NOT returning STATUS_PENDING from dispatch, then do not propagate the pending flag in your
completion



7.) You do not necessarily have to have a cancel routine even if you return pending. You do need a cancel routine if you are
going to hold on to the IRP for a long time in your driver - if you are queueing it up in your driver, then please, do
implement a cancel routine. If you are sending it off to a work queue, unfortunately since work items cannot be cancelled,
there is no point in implementing one.



8.) You have to clear the cancel routine before you do an IoCompleteRequest() on it, or before you forward it via an
IoCallDriver().




By the way - the i/o verifier catches almost every violation of the above rules & more. Turn it on for your driver. Ravi



This posting is provided "AS IS" with no warranties, and confers no rights.



windows command line

http://commandwindows.com/runline.htm