You are previewing Windows® via C/C++, Fifth Edition.
O'Reilly logo
Windows® via C/C++, Fifth Edition

Book Description

Master the intricacies of application development with unmanaged C++ code—straight from the experts. Jeffrey Richter’s classic book is now fully revised for Windows XP, Windows Vista, and Windows Server 2008. You get in-depth, comprehensive guidance, advanced techniques, and extensive code samples to help you program Windows–based applications.

Discover how to:

  • Architect and implement your applications for both 32-bit and 64-bit Windows

  • Create and manipulate processes and jobs

  • Schedule, manage, synchronize and destroy threads

  • Perform asynchronous and synchronous device I/O operations with the I/O completion port

  • Allocate memory using various techniques including virtual memory, memory-mapped files, and heaps

  • Manipulate the default committed physical storage of thread stacks

  • Build DLLs for delay-loading, API hooking, and process injection

  • Using structured exception handling, Windows Error Recovery, and Application Restart services

  • Table of Contents

    1. Windows® via C/C++, Fifth Edition
      1. Acknowledgments
        1. Jeffrey’s Family
        2. Christophe’s Family
        3. Technical Assistance
        4. Microsoft Press Editorial Team
        5. Mutual Admiration
      2. Introduction
        1. 64-Bit Windows
        2. What’s New in the Fifth Edition
        3. Code Samples and System Requirements
        4. Support for This Book
          1. Questions and Comments
      3. I. Required Reading
        1. 1. Error Handling
          1. Defining Your Own Error Codes
          2. The ErrorShow Sample Application
        2. 2. Working with Characters and Strings
          1. Character Encodings
          2. ANSI and Unicode Character and String Data Types
          3. Unicode and ANSI Functions in Windows
          4. Unicode and ANSI Functions in the C Run-Time Library
          5. Secure String Functions in the C Run-Time Library
            1. Introducing the New Secure String Functions
            2. How to Get More Control When Performing String Operations
            3. Windows String Functions
          6. Why You Should Use Unicode
          7. How We Recommend Working with Characters and Strings
          8. Translating Strings Between Unicode and ANSI
            1. Exporting ANSI and Unicode DLL Functions
            2. Determining If Text Is ANSI or Unicode
        3. 3. Kernel Objects
          1. What Is a Kernel Object?
            1. Usage Counting
            2. Security
          2. A Process’ Kernel Object Handle Table
            1. Creating a Kernel Object
            2. Closing a Kernel Object
          3. Sharing Kernel Objects Across Process Boundaries
            1. Using Object Handle Inheritance
              1. Changing a Handle’s Flags
            2. Naming Objects
              1. Terminal Services Namespaces
              2. Private Namespaces
            3. Duplicating Object Handles
      4. II. Getting Work Done
        1. 4. Processes
          1. Writing Your First Windows Application
            1. A Process Instance Handle
              1. A Process’ Previous Instance Handle
              2. A Process’ Command Line
              3. A Process’ Environment Variables
              4. A Process’ Affinity
              5. A Process’ Error Mode
              6. A Process’ Current Drive and Directory
              7. A Process’ Current Directories
              8. The System Version
          2. The CreateProcess Function
            1. pszApplicationName and pszCommandLine
              1. psaProcess, psaThread, and bInheritHandles
              2. fdwCreate
              3. pvEnvironment
              4. pszCurDir
              5. psiStartInfo
              6. ppiProcInfo
          3. Terminating a Process
            1. The Primary Thread’s Entry-Point Function Returns
            2. The ExitProcess Function
            3. The TerminateProcess Function
            4. When All the Threads in the Process Die
            5. When a Process Terminates
          4. Child Processes
            1. Running Detached Child Processes
          5. When Administrator Runs as a Standard User
            1. Elevating a Process Automatically
            2. Elevating a Process by Hand
            3. What Is the Current Privileges Context?
            4. Enumerating the Processes Running in the System
              1. The Process Information Sample Application
        2. 5. Jobs
          1. Placing Restrictions on a Job’s Processes
          2. Placing a Process in a Job
          3. Terminating All Processes in a Job
            1. Querying Job Statistics
          4. Job Notifications
          5. The Job Lab Sample Application
        3. 6. Thread Basics
          1. When to Create a Thread
          2. When Not to Create a Thread
          3. Writing Your First Thread Function
          4. The CreateThread Function
            1. psa
            2. cbStackSize
            3. pfnStartAddr and pvParam
            4. dwCreateFlags
            5. pdwThreadID
          5. Terminating a Thread
            1. The Thread Function Returns
            2. The ExitThread Function
            3. The TerminateThread Function
            4. When a Process Terminates
            5. When a Thread Terminates
          6. Some Thread Internals
          7. C/C++ Run-Time Library Considerations
            1. Oops—I Called CreateThread Instead of _beginthreadex by Mistake
            2. C/C++ Run-Time Library Functions That You Should Never Call
          8. Gaining a Sense of One’s Own Identity
            1. Converting a Pseudohandle to a Real Handle
        4. 7. Thread Scheduling, Priorities, and Affinities
          1. Suspending and Resuming a Thread
          2. Suspending and Resuming a Process
          3. Sleeping
          4. Switching to Another Thread
          5. Switching to Another Thread on a Hyper-Threaded CPU
          6. A Thread’s Execution Times
          7. Putting the CONTEXT in Context
          8. Thread Priorities
          9. An Abstract View of Priorities
          10. Programming Priorities
            1. Dynamically Boosting Thread Priority Levels
            2. Tweaking the Scheduler for the Foreground Process
            3. Scheduling I/O Request Priorities
            4. The Scheduling Lab Sample Application
          11. Affinities
        5. 8. Thread Synchronization in User Mode
          1. Atomic Access: The Interlocked Family of Functions
          2. Cache Lines
          3. Advanced Thread Synchronization
            1. A Technique to Avoid
          4. Critical Sections
            1. Critical Sections: The Fine Print
            2. Critical Sections and Spinlocks
            3. Critical Sections and Error Handling
          5. Slim Reader-Writer Locks
          6. Condition Variables
            1. The Queue Sample Application
              1. The Queue Implementation Details
              2. The Client Thread Is the WriterThread
              3. Consuming Requests by the Server Threads
              4. Deadlock Issues When Stopping Threads
            2. Useful Tips and Techniques
              1. Use One Lock per Atomically-Manipulated Object Set
              2. Accessing Multiple Logical Resources Simultaneously
              3. Don’t Hold a Lock for a Long Time
        6. 9. Thread Synchronization with Kernel Objects
          1. Wait Functions
          2. Successful Wait Side Effects
          3. Event Kernel Objects
            1. The Handshake Sample Application
          4. Waitable Timer Kernel Objects
            1. Having Waitable Timers Queue APC Entries
            2. Timer Loose Ends
          5. Semaphore Kernel Objects
          6. Mutex Kernel Objects
            1. Abandonment Issues
            2. Mutexes vs. Critical Sections
            3. The Queue Sample Application
          7. A Handy Thread Synchronization Object Chart
          8. Other Thread Synchronization Functions
            1. Asynchronous Device I/O
              1. WaitForInputIdle
              2. MsgWaitForMultipleObjects(Ex)
              3. WaitForDebugEvent
              4. SignalObjectAndWait
            2. Detecting Deadlocks with the Wait Chain Traversal API
              1. The LockCop Sample Application
        7. 10. Synchronous and Asynchronous Device I/O
          1. Opening and Closing Devices
            1. A Detailed Look at CreateFile
              1. CreateFile Cache Flags
                1. FILE_FLAG_NO_BUFFERING
                3. FILE_FLAG_WRITE_THROUGH
              2. Miscellaneous CreateFile Flags
                1. FILE_FLAG_DELETE_ON_CLOSE
                3. FILE_FLAG_POSIX_SEMANTICS
                5. FILE_FLAG_OPEN_NO_RECALL
                6. FILE_FLAG_OVERLAPPED
              3. File Attribute Flags
          2. Working with File Devices
            1. Getting a File’s Size
            2. Positioning a File Pointer
            3. Setting the End of a File
          3. Performing Synchronous Device I/O
            1. Flushing Data to the Device
            2. Synchronous I/O Cancellation
          4. Basics of Asynchronous Device I/O
            1. The OVERLAPPED Structure
            2. Asynchronous Device I/O Caveats
            3. Canceling Queued Device I/O Requests
          5. Receiving Completed I/O Request Notifications
            1. Signaling a Device Kernel Object
            2. Signaling an Event Kernel Object
              1. GetOverlappedResult
            3. Alertable I/O
              1. The Bad and the Good of Alertable I/O
            4. I/O Completion Ports
              1. Creating an I/O Completion Port
              2. Associating a Device with an I/O Completion Port
              3. Architecting Around an I/O Completion Port
              4. How the I/O Completion Port Manages the Thread Pool
              5. How Many Threads in the Pool?
              6. Simulating Completed I/O Requests
              7. The FileCopy Sample Application
        8. 11. The Windows Thread Pool
          1. Scenario 1: Call a Function Asynchronously
            1. Explicitly Controlling a Work Item
            2. The Batch Sample Application
          2. Scenario 2: Call a Function at a Timed Interval
            1. The Timed Message Box Sample Application
          3. Scenario 3: Call a Function When a Single Kernel Object Becomes Signaled
          4. Scenario 4: Call a Function When Asynchronous I/O Requests Complete
          5. Callback Termination Actions
            1. Customized Thread Pools
            2. Gracefully Destroying a Thread Pool: Cleanup Groups
        9. 12. Fibers
          1. Working with Fibers
            1. The Counter Sample Application
      5. III. Memory Management
        1. 13. Windows Memory Architecture
          1. A Process’ Virtual Address Space
          2. How a Virtual Address Space Is Partitioned
            1. Null-Pointer Assignment Partition
            2. User-Mode Partition
              1. Getting a Larger User-Mode Partition in x86 Windows
              2. Getting a 2-GB User-Mode Partition in 64-Bit Windows
            3. Kernel-Mode Partition
          3. Regions in an Address Space
          4. Committing Physical Storage Within a Region
          5. Physical Storage and the Paging File
            1. Physical Storage Not Maintained in the Paging File
          6. Protection Attributes
            1. Copy-on-Write Access
            2. Special Access Protection Attribute Flags
          7. Bringing It All Home
            1. Inside the Regions
          8. The Importance of Data Alignment
        2. 14. Exploring Virtual Memory
          1. System Information
            1. The System Information Sample Application
          2. Virtual Memory Status
          3. Memory Management on NUMA Machines
            1. The Virtual Memory Status Sample Application
          4. Determining the State of an Address Space
            1. The VMQuery Function
            2. The Virtual Memory Map Sample Application
        3. 15. Using Virtual Memory in Your Own Applications
          1. Reserving a Region in an Address Space
          2. Committing Storage in a Reserved Region
          3. Reserving a Region and Committing Storage Simultaneously
          4. When to Commit Physical Storage
          5. Decommitting Physical Storage and Releasing a Region
            1. When to Decommit Physical Storage
            2. The Virtual Memory Allocation Sample Application
          6. Changing Protection Attributes
          7. Resetting the Contents of Physical Storage
            1. The MemReset Sample Application
          8. Address Windowing Extensions
            1. The AWE Sample Application
        4. 16. A Thread’s Stack
          1. The C/C++ Run-Time Library’s Stack-Checking Function
          2. The Summation Sample Application
        5. 17. Memory-Mapped Files
          1. Memory-Mapped Executables and DLLs
            1. Static Data Is Not Shared by Multiple Instances of an Executable or a DLL
              1. Sharing Static Data Across Multiple Instances of an Executable or a DLL
              2. The Application Instances Sample Application
          2. Memory-Mapped Data Files
            1. Method 1: One File, One Buffer
            2. Method 2: Two Files, One Buffer
            3. Method 3: One File, Two Buffers
            4. Method 4: One File, Zero Buffers
          3. Using Memory-Mapped Files
            1. Step 1: Creating or Opening a File Kernel Object
            2. Step 2: Creating a File-Mapping Kernel Object
            3. Step 3: Mapping the File’s Data into the Process’ Address Space
            4. Step 4: Unmapping the File’s Data from the Process’ Address Space
            5. Steps 5 and 6: Closing the File-Mapping Object and the File Object
            6. The File Reverse Sample Application
          4. Processing a Big File Using Memory-Mapped Files
          5. Memory-Mapped Files and Coherence
          6. Specifying the Base Address of a Memory-Mapped File
          7. Implementation Details of Memory-Mapped Files
          8. Using Memory-Mapped Files to Share Data Among Processes
          9. Memory-Mapped Files Backed by the Paging File
            1. The Memory-Mapped File Sharing Sample Application
          10. Sparsely Committed Memory-Mapped Files
            1. The Sparse Memory-Mapped File Sample Application
        6. 18. Heaps
          1. A Process’ Default Heap
          2. Reasons to Create Additional Heaps
            1. Component Protection
            2. More Efficient Memory Management
            3. Local Access
            4. Avoiding Thread Synchronization Overhead
            5. Quick Free
          3. How to Create an Additional Heap
            1. Allocating a Block of Memory from a Heap
            2. Changing the Size of a Block
            3. Obtaining the Size of a Block
            4. Freeing a Block
            5. Destroying a Heap
            6. Using Heaps with C++
          4. Miscellaneous Heap Functions
      6. IV. Dynamic-Link Libraries
        1. 19. DLL Basics
          1. DLLs and a Process’ Address Space
          2. The Overall Picture
            1. Building the DLL Module
              1. What Exporting Really Means
              2. Creating DLLs for Use with Non–Visual C++ Tools
            2. Building the Executable Module
              1. What Importing Really Means
            3. Running the Executable Module
        2. 20. DLL Advanced Techniques
          1. Explicit DLL Module Loading and Symbol Linking
            1. Explicitly Loading the DLL Module
            2. Explicitly Unloading the DLL Module
            3. Explicitly Linking to an Exported Symbol
          2. The DLL’s Entry-Point Function
            1. The DLL_PROCESS_ATTACH Notification
            2. The DLL_PROCESS_DETACH Notification
            3. The DLL_THREAD_ATTACH Notification
            4. The DLL_THREAD_DETACH Notification
            5. Serialized Calls to DllMain
            6. DllMain and the C/C++ Run-Time Library
          3. Delay-Loading a DLL
            1. The DelayLoadApp Sample Application
          4. Function Forwarders
          5. Known DLLs
          6. DLL Redirection
          7. Rebasing Modules
          8. Binding Modules
        3. 21. Thread-Local Storage
          1. Dynamic TLS
            1. Using Dynamic TLS
          2. Static TLS
        4. 22. DLL Injection and API Hooking
          1. DLL Injection: An Example
          2. Injecting a DLL Using the Registry
          3. Injecting a DLL Using Windows Hooks
            1. The Desktop Item Position Saver (DIPS) Utility
          4. Injecting a DLL Using Remote Threads
            1. The Inject Library Sample Application
            2. The Image Walk DLL
          5. Injecting a DLL with a Trojan DLL
          6. Injecting a DLL as a Debugger
          7. Injecting Code with CreateProcess
          8. API Hooking: An Example
            1. API Hooking by Overwriting Code
            2. API Hooking by Manipulating a Module’s Import Section
            3. The Last MessageBox Info Sample Application
      7. V. Structured Exception Handling
        1. 23. Termination Handlers
          1. Understanding Termination Handlers by Example
            1. Funcenstein1
            2. Funcenstein2
            3. Funcenstein3
            4. Funcfurter1
            5. Pop Quiz Time: FuncaDoodleDoo
            6. Funcenstein4
            7. Funcarama1
            8. Funcarama2
            9. Funcarama3
            10. Funcarama4: The Final Frontier
            11. Notes About the finally Block
            12. Funcfurter2
            13. The SEH Termination Sample Application
        2. 24. Exception Handlers and Software Exceptions
          1. Understanding Exception Filters and Exception Handlers by Example
            1. Funcmeister1
            2. Funcmeister2
            1. Some Useful Examples
            2. Global Unwinds
            3. Halting Global Unwinds
            1. Use EXCEPTION_CONTINUE_EXECUTION with Caution
          5. GetExceptionCode
            1. Memory-Related Exceptions
            2. Exception-Related Exceptions
            3. Debugging-Related Exceptions
            4. Integer-Related Exceptions
            5. Floating Point–Related Exceptions
          6. GetExceptionInformation
          7. Software Exceptions
        3. 25. Unhandled Exceptions, Vectored Exception Handling, and C++ Exceptions
          1. Inside the UnhandledExceptionFilter Function
            1. Action #1: Allowing Write Access to a Resource and Continuing Execution
            2. Action #2: Notifying a Debugger of the Unhandled Exception
            3. Action #3: Notifying Your Globally Set Filter Function
            4. Action #4: Notifying a Debugger of the Unhandled Exception (Again)
            5. Action #5: Silently Terminating the Process
            6. UnhandledExceptionFilter and WER Interactions
          2. Just-in-Time Debugging
          3. The Spreadsheet Sample Application
          4. Vectored Exception and Continue Handlers
          5. C++ Exceptions vs. Structured Exceptions
          6. Exceptions and the Debugger
        4. 26. Error Reporting and Application Recovery
          1. The Windows Error Reporting Console
          2. Programmatic Windows Error Reporting
            1. Disabling Report Generation and Sending
          3. Customizing All Problem Reports Within a Process
          4. Creating and Customizing a Problem Report
            1. Creating a Custom Problem Report: WerReportCreate
            2. Setting Report Parameters: WerReportSetParameter
            3. Adding a Minidump File to the Report: WerReportAddDump
            4. Adding Arbitrary Files to the Report: WerReportAddFile
            5. Modifying Dialog Box Strings: WerReportSetUIOption
            6. Submitting a Problem Report: WerReportSubmit
            7. Closing a Problem Report: WerReportCloseHandle
            8. The Customized WER Sample Application
          5. Automatic Application Restart and Recovery
            1. Automatic Application Restart
            2. Support for Application Recovery
      8. VI. Appendixes
        1. A. The Build Environment
          1. The CmnHdr.h Header File
            1. Microsoft Windows Version Build Option
            2. Unicode Build Option
            3. Windows Definitions and Warning Level 4
            4. The pragma message Helper Macro
            5. The chINRANGE Macro
            6. The chBEGINTHREADEX Macro
            7. DebugBreak Improvement for x86 Platforms
            8. Creating Software Exception Codes
            9. The chMB Macro
            10. The chASSERT and chVERIFY Macros
            11. The chHANDLE_DLGMSG Macro
            12. The chSETDLGICONS Macro
            13. Forcing the Linker to Look for a (w)WinMain Entry-Point Function
            14. Support XP-Theming of the User Interface with pragma
        2. B. Message Crackers, Child Control Macros, and API Macros
          1. Message Crackers
          2. Child Control Macros
          3. API Macros
      9. C. About the Authors
        1. Jeffrey Richter
        2. Christophe Nasarre
      10. Index