Sunday, January 09, 2011
Monday, September 07, 2009
Wednesday, July 08, 2009
Friday, June 26, 2009
Wednesday, June 24, 2009
ONE STOP INFO FOR... : WINDOWS KERNEL PROGRAMMERS
BOOKS : DEVICE DRIVER
1)Windows NT Device Driver Book, A Guide for Programmers
- Art Baker
Addison Wesley Longman Publication
2)Developing Win NT Device Drivers:
A Progarammer's Handbook
- Edward N. Dekker, Joseph M. Newcomer
Addison Wesley Publication
3)Windows NT Device Driver Development
- Peter Viscarole, Tony Mason
Techmedia Publication
4)Programming the Microsoft Windows Driver Model
-Walter Oney
Microsoft Series
5)Windows NT
File System Internals
A Developer's Guide
- Rajeev Nagar
O'reilly Publication
6)Win32 System Programming
- Johnson Hart
BOOKS : WINDOWS INTERNALS
1)Inside Windows NT
- Custer Helen
2)Inside Windows NT
- David Solomon
PERIODICALS/JOURNALS
"The NT Insider" - http://www.osr.com
"Windows NT Magazine" - http://www.winntmag.com
"Dr.Dobb's Journal" - http://www.ddj.com
PERIODICALS/JOURNALS
DDK - http://www.microsoft.com/ddk
Platform SDK - http://www.msdn.microsoft.com/library/psdk/portals/mainport.htm
IFT KIT - http://www.microsoft.com/ddk/IFSKit
(http://www.microsoft.com/ddk/IFSkit/testing.asp)
WEBSITES
http://www.microsoft.com
http://www.osr.com
http://www.sysinternals.com
http://www.numega.com
IMPORTANT LINKS
http://www.osr.com/book
http://comp.os.microsoft.mswindows.programmers.nt.kernel-mode
http://www.microsoft.public.win32.programmer.kernel
FAQs : Drivers
http://www.cmkrnl.com/faq.html
http://www.chsw.com/ddk/
http://www.asktheoracle.com/driver/
http://faqs.org/faqs/windows/programming/vxd/
http://win32asm.rxsp.com/vxd-tut3.html
Windows 2000 Symbols
http://www.microsoft.com/Windows2000/downloads/tools/symbols/download.asp
Note:-
The order doesn't signify anything. It's the order in which I recollected & typed the information.
Bit Twiddling Hacks
http://graphics.stanford.edu/~seander/bithacks.html
How to create a project in MS Visual Studio 2005?
Background:
When Visual Studio is clicked for 1st time, click on Run Program(if it is Vista) and click on "Visual C++" so that Visual C++ Settings are made.
Attached documents:
1. Project file created. Just click on " HelloWorld.vcproj" file - it opens the project
2. Image shows how the IDE looks when the "Hello World.c" file is added.
When Visual Studio opens:
1. File - > New Project -> Choose Visual C++ on left pane -> Click on "Win32 Console Application" on the right pane.
2. Enter the location:
ex: C:\SourceCodeProjects
and name of the project under Name field:
ex: HelloWorld
3. Click "OK"
4. Press "Next" in the wizard dialog.
5. Click on "Empty Project" under "Additional options". Press Finish
6. Go to the following location where the project is created.
ex:
C:\SourceCodeProjects\HelloWorld2\HelloWorld2
7. Create "HelloWorld.c" file with Hello-World program.
(i) Right click on "Source Files" (hich is shown under the project in Visual Studio 2005). Click on "Existing Item" under context menu. Click Add.
OR
(ii) Drag and drop this program on the left pane where "Source Files" is shown under the project in Visual Studio 2005.
8. Click on Build Solution
(You can remove the following 2 lines.
int global_int;
#define GLOBALS 1
It just shows how the left pane helps in navigating and seeing the code at exact location.
How to debug?
1. Press breakpoint by pressing F9.
2. You can now click away at F10 (Step Over), F11 (Step Into) and F5 (Continue)
Happy Programming!!
When Visual Studio is clicked for 1st time, click on Run Program(if it is Vista) and click on "Visual C++" so that Visual C++ Settings are made.
Attached documents:
1. Project file created. Just click on " HelloWorld.vcproj" file - it opens the project
2. Image shows how the IDE looks when the "Hello World.c" file is added.
When Visual Studio opens:
1. File - > New Project -> Choose Visual C++ on left pane -> Click on "Win32 Console Application" on the right pane.
2. Enter the location:
ex: C:\SourceCodeProjects
and name of the project under Name field:
ex: HelloWorld
3. Click "OK"
4. Press "Next" in the wizard dialog.
5. Click on "Empty Project" under "Additional options". Press Finish
6. Go to the following location where the project is created.
ex:
C:\SourceCodeProjects\
7. Create "HelloWorld.c" file with Hello-World program.
(i) Right click on "Source Files" (hich is shown under the project in Visual Studio 2005). Click on "Existing Item" under context menu. Click Add.
OR
(ii) Drag and drop this program on the left pane where "Source Files" is shown under the project in Visual Studio 2005.
8. Click on Build Solution
(You can remove the following 2 lines.
int global_int;
#define GLOBALS 1
It just shows how the left pane helps in navigating and seeing the code at exact location.
How to debug?
1. Press breakpoint by pressing F9.
2.
How to compile and debug on LINUX machine (or on CYGWIN env in Windows)?
1. How to compile?
gcc hello.c
(On Linux, it creates a.out
On CYGWIN, it creates a.exe)
Note:-
This program cannot be debugged
2. How to compile & debug?
gcc -g hello.c -o hello.exe
(-g option is used to include global symbols. Without global symbols, debugging information will not be in the binary)
Debug:
gdb
>file
ex:
file ./hello.exe
> b main
(keep a breakpoint at main)
> run
( to execute the program. it hits the breakpoint at main)
> p
ex: p a
p b
p c
(displays the variable)
> set language c
> set variable = value>
ex:
set variable a=1000
gcc hello.c
(On Linux, it creates a.out
On CYGWIN, it creates a.exe)
Note:-
This program cannot be debugged
2. How to compile & debug?
gcc -g hello.c -o hello.exe
(-g option is used to include global symbols. Without global symbols, debugging information will not be in the binary)
Debug:
gdb
>file
ex:
file ./hello.exe
> b main
(keep a breakpoint at main)
> run
( to execute the program. it hits the breakpoint at main)
> p
ex: p a
p b
p c
(displays the variable)
> set language c
> set variable
ex:
set variable a=1000
ECLIPSE ON CYGWIN
- Project Name : MyProject (Only .h, .hh and .cc files from MyProject are in this folder. Note: Makefile is created by Eclipse)
- Click Finish.
Tips for Windows NT Driver Developers -- Things to Avoid
| 1. | Never return STATUS_PENDING from a dispatch routine without marking the I/O request packet (IRP) pending (IoMarkIrpPending). |
| 2. | Never call KeSynchronizeExecution from an interrupt service routine (ISR). It will deadlock your system. |
| 3. | Never set DeviceObject->Flags to both DO_BUFFERED_IO and DO_DIRECT_IO. It can confuse the system and eventually lead to fatal error. Also, never set METHOD_BUFFERED, METHOD_NEITHER, METHOD_IN_DIRECT or METHOD_OUT_DIRECT in DeviceObject->Flags, because these values are only used in defining IOCTLs. |
| 4. | Never allocate dispatcher objects from a paged pool. If you do, it will cause occasional system bugchecks. |
| 5. | Never allocate memory from paged pool, or access memory in paged pool, while running at IRQL >= DISPATCH_LEVEL. It is a fatal error. |
| 6. | Never wait on a kernel dispatcher object for a nonzero interval at IRQL >= DISPATCH_LEVEL. It is a fatal error. |
| 7. | Never call any function that causes the calling thread to wait directly or indirectly while executing at IRQL >= DISPATCH_LEVEL. It is a fatal error. |
| 8. | Never lower the interrupt request level (IRQL) below the level at which your top-level routine has been invoked. |
| 9. | Never call KeLowerIrql() if you haven't called KeRaiseIrql(). |
| 10. | Never stall a processor (KeStallExecutionProcessor) longer than 50 microseconds. |
| 11. | Never hold any spin locks longer than necessary. For better overall system performance, do not hold any system-wide spin locks longer than 25 microseconds. |
| 12. | Never call KeAcquireSpinLock and KeReleaseSpinLock, or KeAcquireSpinLockAtDpcLevel and KeReleaseSpinLockFromDpcLevel, while running at IRQL greater than DISPATCH_LEVEL. |
| 13. | Never release a spin lock that was acquired with KeAcquireSpinLock by calling KeReleaseSpinLockFromDpcLevel, because the original IRQL will not be restored. |
| 14. | Never call KeAcquireSpinLock and KeReleaseSpinLock or any other routine that uses an executive spin lock from an ISR or SynchCritSection routine(s). |
| 15. | Never forget to clear DO_DEVICE_INITIALIZING flag when you create a device object in a routine other than DriverEntry. |
| 16. | Never queue a deferred procedure call (DPC) object (using KeInsertQueueDpc) with multiple threads on different processors simultaneously. It can lead to fatal error. |
| 17. | Never deallocate a periodic timer from a CutomerTimerDPC routine. You can deallocate nonperiodic timers from a DPC routine. |
| 18. | Never pass the same DPC pointer to KeSetTimer, or KeSetTimerEx (CustomTimerDpc) and KeInsertQueueDpc (CustomDpc), because it causes race conditions. |
| 19. | Never call IoStartNextPacket while holding a spin lock. It can deadlock your system. |
| 20. | Never call IoCompleteRequest while holding a spin lock. It can deadlock your system. |
| 21. | Never call IoCompleteRequest without setting the completion routine to NULL if your driver sets the completion routine. |
| 22. | Never forget to set the I/O status block in the IRP before calling IoCompleteRequest. |
| 23. | Never call IoMarkPending after queuing an IRP or sending it to another driver (IoCallDriver). The IRP may be completed before the driver calls IoMarkPending and a bugcheck might occur. For drivers with completion routines, the completion routines must call IoMarkPending if Irp->PendingReturned is set. |
| 24. | Never touch an IRP after you have called IoCompleteRequest on it. |
| 25. | Never call IoCancelIrp on an IRP that is not owned by your driver unless you know that the IRP has not been completed yet. |
| 26. | Never call IoCancelIrp for the IRP that your dispatch routine is working on until your dispatch routine returns to caller. |
| 27. | Never call IoMakeAssociatedIrp to create IRPs for lower drivers from an intermediate driver. The IRP you get in your intermediate driver could be an associated IRP, and you cannot associate other IRPs to an already associated IRP. |
| 28. | Never call IoMakeAssociatedIrp on an IRP that is set up to perform buffered I/O. |
| 29. | Never simply dereference virtual pointers to device I/O registers and access them. Always use correct hardware abstraction layer (HAL) functions to access a device. |
| 30. | Never access IRP or device object fields from an ISR that may be modified from DISPATCH_LEVEL. On a symmetric multiprocessor system this can cause data corruption. |
| 31. | Never modify data while running at high-IRQL if that data may be written by low-IRQL code. Use the KeSynchronizeExecution routine. |
| 32. | Never acquire one of the driver's own spin locks (if you have any) in your DispatchCleanup routine, before acquiring the system-wide cancel spin lock (IoAcquireCancelSpinLock). Following a consistent lock acquisition hierarchy throughout your driver is essential to avoiding potential deadlocks. |
| 33. | Never call IoAcquireCancelSpinLock in your cancel routine because it is always called with the system cancel spin lock held on its behalf. |
| 34. | Never forget to call IoReleaseCancelSpinLock before returning from a cancel routine. |
| 35. | Never use IRQL-based synchronization because this works only on single processor systems. Raising IRQL on one processor does not mask interrupts on other processors. |
| 36. | Never use RtlCopyMemory for overlapped memory address ranges. Use RtlMoveMemory. |
| 37. | Never assume page sizes are constant, even for a given CPU. Use PAGE_SIZE and other page related constants defined in header files to maintain portability. |
| 38. | Never access any registry keys other than Registry\Machine\Hardware and Registry\Machine\System from DriverEntry routine of a driver loaded in Boot\System Initialization phase. |
| 39. | Never create an Enum key for loading a driver under a driver's registry key (Registry\Machine\System\ |
| 40. | Never attempt to initialize a physical device without claiming the necessary bus-relative I/O ports, memory ranges, interrupt, or direct memory access (DMA) channel/port hardware resources in the registry first. |
| 41. | Never call IoRegisterDriverReinitializati |
| 42. | Never call KeSetEvent with the Wait parameter set to TRUE from a pageable thread or pageable driver routine that runs at IRQL PASSIVE_LEVEL. This type of call causes a fatal page fault if your routine happens to be paged out between the calls to KeSetEvent and KeWait..Object(s). |
| 43. | Never call KeReleaseSemaphore with the Wait parameter set to TRUE from a pageable thread or pageable driver routine that runs at IRQL PASSIVE_LEVEL. If your routine happens to be paged out between the calls to KeReleaseSemaphore and KeWait..Object(s), this type of a call causes a fatal page fault. |
| 44. | Never call KeReleaseMutex with the Wait parameter set to TRUE from a pageable thread or pageable driver routine that runs at IRQL PASSIVE_LEVEL. If your routine happens to be paged out between the calls to KeReleaseMutex and KeWait..Object(s), this type of a call causes a fatal page fault. |
| 45. | Never call KeBugCheckEx or KeBugCheck from a retail Windows NT driver to bring down the system, unless the error encountered is a critical error which would corrupt system memory or eventually cause the system to bugcheck. Always try to handle error conditions gracefully. |
| 46. | Never assume that an IoTimer routine will be called precisely on a one- second boundary because the intervals at which any particular IoTimer routine is called ultimately depends on resolution of the system clock. |
| 47. | Never call Win32s application programming interfaces (API) from a kernel-mode device driver. |
| 48. | Never use recursive functions that can cause the stack to overflow because the calling thread's kernel-mode stack does not grow dynamically while it is running in kernel-mode. |
| 49. | Never use interrupt object pointers (PKINTERRUPT) to identify interrupts in an ISR that handles more than one interrupt, because the address of the interrupt object you get in the ISR will not always be the same as the one you got from IoConnectInterrupt. You should only use the ServiceContext value that you specify in IoConnectInterrupt to identify the current interrupting device. |
| 50. | Never unload a driver without clearing CustomTimerDpc (KeCancelTimer). If the DPC is fired after the driver is unloaded, it could hit non existent-code and cause the system to bugcheck. |
| 51. | Never unload a driver until all the IRPs that have the I/O CompletionRoutine of the driver set in it are completed. If the IRP gets completed by the lower driver after your driver is unloaded, the system could try to execute the non-existent code and cause the system to crash. |
| 52. | Never enable device interrupt until your driver is ready to handle it. You should enable only after your driver is completely initialized, and it is safe for the system to touch the driver's internal structures in ISR and DPC. |
| 53. | Never call outside of your driver while holding a spinlock because it can cause deadlock. |
| 54. | Never return any status other than STATUS_MORE_PROCESSING_ |
| 55. | Never allocate an IRP with IoBuildSynchronousFsdRequest/ |
| 56. | Never call IoInitializeIrp on an IRP that has been allocated with IoAllocateIrp with ChargeQuota parameter set to TRUE. When you allocate an IRP with ChargeQuota set to TRUE, the I/O manager keeps the information about the pool from which it allocated the memory for the IRP in the IRP's internal flag. When you call IoInitializeIrp on such an IRP, the allocation pool information is lost as this function blindly zeros the entire IRP. This leads to memory corruption when you free the IRP. Also, never reuse an IRP that comes from the IO manager. If you want to reuse an IRP, you should allocate your own by using IoAllocateIrp. |
| 57. | Never specify WaitMode as UserMode in KeWaitForSingleObject/ |
| 58. | Never acquire resources such as ERESOURCES and FastMutex(Unsafe) in the context of a user-mode thread without protecting the code in a critical section. Because the acquisition of these resources does not raise the IRQL to APC_LEVEL, if the thread is suspended (done by queuing an APC) after it has acquired the resource, it could cause deadlock and compromise system security. Therefore, you should acquire such resources either by explicitly raising the IRQL to APC_LEVEL or in a critical section by calling KeEnterCriticalRegion. |
http://support.microsoft.com/