Tuesday, July 17, 2007
Unicode
Because many applications deal with 8-bit (single-byte) ANSI character strings, Windows functions that accept string parameters have two entry points: a Unicode (wide, 16-bit) and an ANSI (narrow, 8-bit) version.
Registry
In addition, the registry is a window into in-memory volatile data, such as the current hardware state of the system (what device drivers are loaded, the resources they are using, and so on) as well as the Windows performance counters.
Security
Windows has two forms of access control over objects. The first form—discretionary access control—is the protection mechanism that most people think of when they think of operating system security. It's the method by which owners of objects (such as files or printers) grant or deny access to others. When users log in, they are given a set of security credentials, or a security context. When they attempt to access objects, their security context is compared to the access control list on the object they are trying to access to determine whether they have permission to perform the requested operation.
Privileged access control is necessary for those times when discretionary access control isn't enough. It's a method of ensuring that someone can get to protected objects if the owner isn't available.
Security pervades the interface of the Windows API. The Windows subsystem implements object-based security in the same way the operating system does; the Windows subsystem protects shared Windows objects from unauthorized access by placing Windows security descriptors on them. The first time an application tries to access a shared object, the Windows subsystem verifies the application's right to do so. If the security check succeeds, the Windows subsystem allows the application to proceed.
Objects and Handles
An object attribute is a field of data in an object that partially defines the object's state.
Object methods, the means for manipulating objects, usually read or change the object attributes.
The most fundamental difference between an object and an ordinary data structure is that the internal structure of an object is hidden.
Objects provide a convenient means for accomplishing the following four important operating system tasks:
-
Providing human-readable names for system resources
-
Sharing resources and data among processes
-
Protecting resources from unauthorized access
-
Reference tracking, which allows the system to know when an object is no longer in use so that it can be automatically deallocated
Terminal Services and Multiple Sessionsw
The first login session at the physical console of the machine is considered the console session, or session zero. Additional sessions can be created through the use of the remote desktop connection program (Mstsc.exe) or on Windows XP systems through the use of fast user switching (described later).
Windows XP Professional permits a single remote user to connect to the machine, but if someone is logged in at the console, the workstation is locked (that is, someone can be using the system either locally or remotely, but not at the same time).
Kernel Mode vs. User Mode
User application code runs in user mode, whereas operating system code (such as system services and device drivers) runs in kernel mode. Kernel mode refers to a mode of execution in a processor that grants access to all system memory and all CPU instructions. By providing the operating system software with a higher privilege level than the application software has, the processor provides a necessary foundation for operating system designers to ensure that a misbehaving application can't disrupt the stability of the system as a whole.
Although each Windows process has its own private memory space, the kernel-mode operating system and device driver code share a single virtual address space. Each page in virtual memory is tagged as to what access mode the processor must be in to read and/or write the page.
Windows doesn't provide any protection to private read/write system memory being used by components running in kernel mode. In other words, once in kernel mode, operating system and device driver code has complete access to system space memory and can bypass Windows security to access objects.
User applications switch from user mode to kernel mode when they make a system service call.
A transition from user mode to kernel mode (and back) does not affect thread scheduling per se—a mode transition is not a context switch.
Thus, it's normal for a user thread to spend part of its time executing in user mode and part in kernel mode. In fact, because the bulk of the graphics and windowing system also runs in kernel mode, graphics-intensive applications spend more of their time in kernel mode than in user mode.
Virtual Memory
Because most systems have much less physical memory than the total virtual memory in use by the running processes, the memory manager transfers, or pages, some of the memory contents to disk. Paging data to disk frees physical memory so that it can be used for other processes or for the operating system itself. When a thread accesses a virtual address that has been paged to disk, the virtual memory manager loads the information back into memory from disk. Applications don't have to be altered in any way to take advantage of paging because hardware support enables the memory manager to page without the knowledge or assistance of processes or threads.
The size of the virtual address space varies for each hardware platform.
Windows allocates half this address space (the lower half of the 4 GB virtual address space, from x00000000 through x7FFFFFFF) to processes for their unique private storage and uses the other half (the upper half, addresses x80000000 through xFFFFFFFF) for its own protected operating system memory utilization. The mappings of the lower half change to reflect the virtual address space of the currently executing process, but the mappings of the upper half always consist of the operating system's virtual memory.
Processes, Threads, and Jobs
Although programs and processes appear similar on the surface, they are fundamentally different. A program is a static sequence of instructions, whereas a process is a container for a set of resources used when executing the instance of the program. At the highest level of abstraction, a Windows process comprises the following:
-
A private virtual address space, which is a set of virtual memory addresses that the process can use
-
An executable program, which defines initial code and data and is mapped into the process's virtual address space
-
A list of open handles to various system resources, such as semaphores, communication ports, and files, that are accessible to all threads in the process
-
A security context called an access token that identifies the user, security groups, and privileges associated with the process
-
A unique identifier called a process ID (internally called a client ID)
-
At least one thread of execution
Each process also points to its parent or creator process. However, if the parent exits, this information is not updated. Therefore, it is possible for a process to point to a nonexistent parent. This is not a problem, as nothing relies on this information being present.
A thread is the entity within a process that Windows schedules for execution. Without it, the process's program can't run. A thread includes the following essential components:
-
The contents of a set of CPU registers representing the state of the processor.
-
Two stacks, one for the thread to use while executing in kernel mode and one for executing in user mode.
-
A private storage area called thread-local storage (TLS) for use by subsystems, run-time libraries, and DLLs.
-
A unique identifier called a thread ID (also internally called a client ID—process IDs and thread IDs are generated out of the same namespace, so they never overlap).
-
Threads sometimes have their own security context that is often used by multithreaded server applications that impersonate the security context of the clients that they serve.
The volatile registers, stacks, and private storage area are called the thread's context. Because this information is different for each machine architecture that Windows runs on, this structure, by necessity, is architecture-specific. The Windows GetThreadContext function provides access to this architecture-specific information (called the CONTEXT block).
Although threads have their own execution context, every thread within a process shares the process's virtual address space (in addition to the rest of the resources belonging to the process), meaning that all the threads in a process can write to and read from each other's memory. Threads cannot accidentally reference the address space of another process, however, unless the other process makes available part of its private address space as a shared memory section (called a file mapping object in the Windows API) or unless one process has the right to open another process to use cross-process memory functions such as ReadProcessMemory and WriteProcessMemory.
In addition to a private address space and one or more threads, each process has a security identification and a list of open handles to objects such as files, shared memory sections, or one of the synchronization objects such as mutexes, events, or semaphores.
Every process has a security context that is stored in an object called an access token. The process access token contains the security identification and credentials for the process. By default, threads don't have their own access token, but they can obtain one, thus allowing individual threads to impersonate the security context of another process—including processes running on a remote Windows system—without affecting other threads in the process.
The virtual address descriptors (VADs) are data structures that the memory manager uses to keep track of the virtual addresses the process is using.
Windows provides an extension to the process model called a job. A job object's main function is to allow groups of processes to be managed and manipulated as a unit. A job object allows control of certain attributes and provides limits for the process or processes associated with the job. It also records basic accounting information for all processes associated with the job and for all processes that were associated with the job but have since terminated. In some ways, the job object compensates for the lack of a structured process tree in Windows—yet in many ways it is more powerful than a UNIX-style process tree.
Services, Functions, and Routines
-
Windows API functions Documented, callable subroutines in the Windows API. Examples include CreateProcess, CreateFile, and GetMessage.
-
Native system services (or executive system services) The undocumented, underlying services in the operating system that are callable from user mode. For example, NtCreateProcess is the internal system service the Windows CreateProcess function calls to create a new process.
-
Kernel support functions (or routines) Subroutines inside the Windows operating system that can be called only from kernel mode (defined later in this chapter). For example, ExAllocatePool is the routine that device drivers call to allocate memory from the Windows system heaps.
-
Windows services Processes started by the Windows service control manager. For example, the Task Scheduler service runs in a usermode process that supports the at command (which is similar to the UNIX commands at or cron).
-
DLL (dynamic-link library) A set of callable subroutines linked together as a binary file that can be dynamically loaded by applications that use the subroutines. Examples include Msvcrt.dll (the C run-time library) and Kernel32.dll (one of the Windows API subsystem libraries). Windows user-mode components and applications use DLLs extensively. The advantage DLLs provide over static libraries is that applications can share DLLs, and Windows ensures that there is only one in-memory copy of a DLL's code among the applications that are referencing it.
What About .NET and WinFX?
The .NET Framework consists of a library of classes called the Framework Class Library (FCL) and a Common Language Runtime (CLR) that provides a managed code execution environment with features such as just-in-time compilation, type verification, garbage collection, and code access security. By offering these features, the CLR provides a development environment that improves programmer productivity and reduces common programming errors. (For an excellent description of the .NET Framework and its core architecture, see Applied Microsoft .NET Framework Programming by Jeffrey Richter.)
The CLR is implemented as a classic COM server whose code resides in a standard usermode Windows DLL. In fact, all components of the .NET Framework are implemented as standard user-mode Windows DLLs layered over unmanaged Windows API functions. (None of the .NET Framework runs in kernel mode.)
WinFX is "the new Windows API." It is the evolution of the .NET Framework that ships with Windows "Longhorn," the next major release of Windows. It will also be installable on Windows XP and Windows Server 2003. WinFX provides the foundation for the next generation of applications built for the Windows operating system.
Windows API
Prior to the introduction of 64-bit versions of Windows XP and Windows Server 2003, the programming interface to the 32-bit version of the Windows operating systems was called the Win32 API, to distinguish it from the original 16-bit Windows API, which was the programming interface to the original 16-bit versions of Windows.
The Windows API consists of thousands of callable functions, which are divided into the following major categories:
-
Base Services
-
Component Services
-
User Interface Services
-
Graphics and Multimedia Services
-
Messaging and Collaboration
-
Networking
-
Web Services