═══ 1. How to Use the SMP Programming Addendum ═══ The SMP Programming Addendum is a detailed technical guide and reference for application programmers who which to exploit the symmetric multiprocessor support in the OS/2 operating system. It gives reference information and code examples to enable you to write source code using OS/2 functions and tools. Before you begin to use this information, it would be helpful to understand how you can:  Expand the Contents to see all available topics  Obtain additional information for a highlighted word or phrase  Use action bar choices  Use the programming information. How to Use the Contents When the Contents window first appears, some topics have a plus (+) sign beside them. The plus sign indicates that additional topics are available. To expand the Contents if you are using a mouse, click on the plus sign. If you are using the keyboard, use the Up or Down Arrow key to highlight the topic, and press the plus (+) key. For example, File System has a plus sign beside it. To see additional topics for that heading, click on the plus sign or highlight that topic and press the plus (+) key. To view a topic, double-click on the topic (or press the Up or Down Arrow key to highlight the topic, and then press the Enter key). How to Obtain Additional Information After you select a topic, the information for that topic appears in a window. Highlighted words or phrases indicate that additional information is available. You will notice that certain words and phrases are highlighted in green letters, or in white letters on a black background. These are called hypertext terms. If you are using a mouse, double-click on the highlighted word. If you are using a keyboard, press the Tab key to move to the highlighted word, and then press the Enter key. Additional information then appears in a window. How to Use Action Bar Choices Several choices are available for managing information presented in the OS/2 operating system SMP Programming Addendum. There are three pull-down menus on the action bar: the Services menu, the Options menu, and the Help menu. The actions that are selectable from the Services menu operate on the active window currently displayed on the screen. These actions include the following: Bookmark Allows you to set a placeholder so you can retrieve information of interest to you. When you place a bookmark on a topic, it is added to a list of bookmarks you have previously set. You can view the list, and you can remove one or all bookmarks from the list. If you have not set any bookmarks, the list is empty. To set a bookmark, do the following: 1. Select a topic from the Contents. 2. When that topic appears, choose the Bookmark option from the Services pull-down. 3. If you want to change the name used for the bookmark, type the new name in the field. 4. Click on the Place radio button (or press the Up or Down Arrow key to select it). 5. Click on OK (or select it and press Enter). The bookmark is then added to the bookmark list. Search Allows you to find occurrences of a word or phrase in the current topic, selected topics, or all topics. You can specify a word or phrase to be searched. You can also limit the search to a set of topics by first marking the topics in the Contents list. To search for a word or phrase in all topics, do the following: 1. Choose the Search option from the Services pull-down. 2. Type the word or words to be searched for. 3. Click on All sections (or press the Up or Down Arrow keys to select it). 4. Click on Search (or select it and press Enter) to begin the search. 5. The list of topics where the word or phrase appears is displayed. Print Allows you to print one or more topics. You can also print a set of topics by first marking the topics in the Contents list. To print the document Contents list, do the following: 1. Choose Print from the Services pull-down. 2. Click on Contents (or press the Up or Down Arrow key to select it). 3. Click on Print (or select it and press Enter). 4. The Contents list is printed on your printer. Copy Allows you to copy a topic that you are viewing to the System Clipboard or to a file that you can edit. You will find this particularly useful for copying syntax definitions and program samples into the application that you are developing. You can copy a topic that you are viewing in two ways:  Copy copies the topic that you are viewing into the System Clipboard. If you are using a Presentation Manager (PM) editor (for example, the System Editor) that copies or cuts (or both) to the System Clipboard, and pastes to the System Clipboard, you can easily add the copied information to your program source module.  Copy to file copies the topic that you are viewing into a temporary file named TEXT.TMP. You can later edit that file by using any editor. You will find TEXT.TMP in the directory where your viewable document resides. To copy a topic, do the following: 1. Expand the Contents list and select a topic. 2. When the topic appears, choose Copy to file from the Services pull-down. 3. The system puts the text pertaining to that topic into the temporary file named TEXT.TMP. For information on one of the other choices in the Services pull-down, highlight the choice and press the F1 key. The actions that are selectable from the Options menu allow you to change the way your Contents list is displayed. To expand the Contents and show all levels for all topics, choose Expand all from the Options pull-down. You can also press the Ctrl and * keys together. For information on one of the other choices in the Options pull-down, highlight the choice and press the F1 key. The actions that are selectable from the Help menu allow you to select different types of help information. You can also press the F1 key for help information about the Information Presentation Facility (IPF). How to Use the Programming Information The SMP Programming Addendum consists of guide and reference information that provides a detailed description of each system function that has been added or changed to support the symmetric multiprocessing capabilities of OS/2. Programming information is presented by component, such as Error Management, Exception Management, and File System, for example: ┌─────────────────────────────────────────┐ │ Contents │ ├─────────────────────────────────────────┤ │ │ │ + Error Management │ │ + Exception Management │ │ + File System │ │ │ └─────────────────────────────────────────┘ By clicking on the plus sign beside "File System", you see an alphabetic list of the functions for the file system. Selecting a function takes you directly into the reference information for that function. Units of reference information are presented in selectable multiple windows or viewports. A viewport is a Presentation Manager window that can be sized, moved, minimized, maximized, or closed. By selecting a unit (in this case, an entry on the Contents list), you will see two windows displayed: ┌────────────────────┬──────────────────────────┐ │ Unit Title │ Selection Title │ ├────────────────────┼──────────────────────────┤ │ Select an item │ │ │ │ │ │ Function Syntax │ │ │ Parameters │ │ │ Return Values │ │ │ Notes │ │ │ Example │ │ │ Related Functions │ │ │ Glossary │ │ │ │ │ └────────────────────┴──────────────────────────┘ The window on the left is the primary window. It contains a list of items that are always available to you. The window on the right is the secondary window. It contains a 'snapshot' of the unit information. For reference units (that is, function descriptions), this window contains the Function Syntax. All of the information needed to understand a reference unit (or topic) is readily available to you through the primary window. The information is divided into discrete information groups, and only the appropriate information group appears for the topic that you are viewing. The information groups for a reference unit (that is, a function description) can include the following:  Function Syntax  Parameters  Return Values  Notes  Example  Related Functions  Glossary This list may vary. Some topics may be omitted when they do not apply. Information groups are displayed in separate viewports that are stacked in a third window location that overlaps the secondary window. By selecting an item (information group) in the primary window, the item is displayed in the third window location, as follows: ┌────────────────┬─────────────┬──────────────────┐ │ Unit Title │ Selection │ Glossary │ ├────────────────┼─────────────┼──────────────────┤ │ Select an item │ │ Select a starting│ │ │ │ letter of │ │ . │ │ glossary terms │ │ . │ │ │ │ . │ │ A N │ │ . │ │ B O │ │ . │ │ C P │ │ Glossary │ │ . . │ │ │ │ . . │ │ │ │ . . │ │ │ │ M Z │ └────────────────┴─────────────┴──────────────────┘ By selecting successive items from the primary window, additional windows are displayed on top of the previous windows displayed in the third window location. For example, in a function description, Parameters and Return Values are items listed in the primary window. When selected, they appear one on top of the other in the third window location. Because of this, you may move the first selected (topmost) window to the left before selecting the next item. This allows simultaneous display of two related pieces of information from the "stack" of windows in the third window location, as follows: ┌────────────────┬──────────────┬─────────────────┐ │ Unit Title │ Parameters │ Return Values │ ├────────────────┼──────────────┼─────────────────┤ │ Select an item │ │ │ │ . │ │ │ │ . │ │ │ │ . │ │ │ │ Parameters │ │ │ │ Return Values │ │ │ │ . │ │ │ │ . │ │ │ │ . │ │ │ │ │ │ │ └────────────────┴──────────────┴─────────────────┘ Each window can be individually closed from its system menu. All windows are closed when you close the primary window. Some secondary windows may have the appearance of a split screen. For example, an illustration may appear in the left half of the window, and scrollable, explanatory information may appear in the right half of the window. Because illustrations may not necessarily fit into the small window size on your screen, you may maximize the secondary window for better readability. ═══ 2. Introduction to OS/2 Warp Server Version 4 Advanced ═══ This document provides a guide for developers writing applications and device drivers exploiting the symmetrical multiprocessing capabilities of OS/2 Warp Server Version 4 Advanced. The purpose of this reference is to give information about functions, constants, and data structures. It provides information about the functions which enable the user to call functions in the C programming language. OS/2 Warp Server for SMP was developed to satisfy the need to run OS/2 on multiprocessor based CISC processors, namely the Intel x86 compatible family. The requirements for OS/2 Warp Server for SMP were that it run all existing applications, device drivers and subsystems, as well as take advantage of new multiprocessor (MP) exploitive applications and device drivers. The emergence of low-cost MP hardware based on the 486, Pentium, and Pentium Pro processors makes OS/2 Warp Server for SMP an attractive desktop operating environment. Server and workstation environments using the x86 architecture are moving toward the more powerful emerging RISC based chip sets. These new RISC processors lack the full range of programming tools available for the x86 chip set. OS/2 Warp Server for SMP attempts to solve the problems of insufficient processor bandwidth by supporting multiple x86 processors in a single computer. To provide increased performance, OS/2 Warp Server for SMP allows applications, file system, mass storage and network drivers to execute on any processor at any time. A number of databases and applications have been modified to take advantage of the additional features provided by OS/2 Warp Server for SMP. DB2/2 and CICS are two databases that IBM has modified to run better under OS/2 Warp Server for SMP. These application can benefit greatly from OS/2 Warp Server for SMP because they are CPU-intensive. Other applications which can also benefit from OS/2 Warp Server for SMP are:  Lotus Notes & cc-Mail  NetView Series  Novell Netware  Scientific Applications  Multimedia Applications ═══ 2.1. What's New Since OS/2 for SMP 2.11 ═══ OS/2 Warp Server Version 4 Advanced provides: High Memory Support Memory management has been enhanced to allow 32-bit applications to allocate and address linear memory objects above the 512MB boundary. This effectively breaks the 512MB memory limit in previous versions of OS/2. Raw File System The Raw File System provides the ability to access physical or logical drives using a UNC name. Since drive access is no longer limited to available drive letters, more than 26 physical and logical drives are now available to 32-bit applications. This allows access to up to 128 drives without incurring the serialization overhead of the OS/2 file system. In addition, the raw file system supports physical disks up to 1 TB (terabyte) in size. Enhanced File I/O Support With the addition of the DosListIO function, multiple locking, unlocking, seeking, and I/O operations may now be initiated at once. These can be synchronous (ordered) requests or, in the case of the Raw File System, unordered requests. MPS 1.4 Compliant Intel I/O APIC Support OS/2 Warp Server for SMP now recognizes multiple MPS 1.4 compliant Intel I/O Advanced Programmable Interrupt Controllers (APICs) in a system. Multiple I/O APICs increases the number of adapters allowed on the system. Software Trace Facility (STRACE) STRACE is a tracing tool available on Pentium-class machines which provides a software-based timing and tracing mechanism. With the addition of the DosPerfSysCall function, software running in ring 3 may now record events in the software trace buffer. Performance Monitoring OS/2 Warp Server for SMP provides a set of functions which allow application developers an efficient and uniform way to access system performance information and to monitor and change processor status. The ICAT Debugger The ICAT debugger is a source-level debugger used for remotely debugging OS/2 device drivers, kernel code, Installable File Systems (IFS), and applications running on an OS/2 Warp Server for SMP machine from another OS/2 system. Kernel Debugger The protocols necessary for communicating with the kernel debugger over a serial communications link have been made available for application developers. ═══ 2.2. Exploiting SMP-Specific Features ═══ If your program or device driver will be using SMP-specific features of OS/2, such as the new DosListIO and DosPerfSysCall functions, you will need to dual-path your code so that your program can run on versions of OS/2 that do not support the new functions. It is the intent of IBM to provide these functions in non-SMP versions of OS/2 in the future. The recommended way to determine from your program if you are running on an version of OS/2 that supports the new DosListIO and DosPerfSysCall From a program: Query the exported entry point for the function using DosQueryProcAddr. From a device driver: Use the GetDOSVar device helper specifying first an ordinal value of 18, SMP_ACTIVE. If SMP is indicated, ordinal value 17, _cProcessors can be used to determine the number of processors available. In addition, ordinal 19, PSDInfo.psd_flags, returns usual informational about a PSD. Refer to PSDInfo in PSD.H for details. ═══ 2.3. Notation Conventions ═══ The following notation conventions are used in this reference: NULL The term NULL applied to a parameter is used to indicate the presence of the pointer parameter, but with no value. NULLHANDLE The term NULLHANDLE applied to a parameter is used to indicate the presence of the handle parameter, but with no value. Implicit Pointer If no entry for a data type "Pxxxxxxx" is found in Data Types, then it is implicitly a pointer to the data type "xxxxxxx". See Implicit Pointer Data Types for more information about implicit pointers. Constant Names All constants are written in uppercase to match the header files. Where applicable, constant names have a prefix derived from the name of a function, message, or idea associated with the constant. For example: WM_CREATE Window message SV_CXICON System value CF_TEXT Clipboard format. In this book, references to a complete set of constants with a given prefix is written as shown in the following examples: Window message WM_* System value SV_* Parameters and Fields Function parameters and data structure fields are shown in italics. ═══ 2.4. Conventions Used in Function Descriptions ═══ This section provides information about the notation conventions and function descriptions used in this reference. The documentation for each function contains the following sections: Syntax The function syntax describes the C-language calling syntax of the function and gives a brief description. Programming Note The functions in this book are spelled in mixed-case for readability but are known to the system as uppercase character strings. If you are using a compiler that generates a mixed-case external name, you should code the functions in uppercase. Parameters Each parameter is listed with its C-language data type, parameter type, and a brief description.  All data types are written in uppercase to match the header files. A data type of "Pxxxxxxx" implicitly defines a pointer to the data type "xxxxxxx". The term NULL applied to a parameter indicates the presence of the parameter, with no value. Refer to Data Types for a complete list of all data types and their descriptions.  There are three parameter types: Input Specified by the programmer. Output Returned by the function. Input/Output Specified by the programmer and modified by the function.  A brief description is provided with each parameter. Where appropriate, restrictions are also included. In some cases, the parameter points to a structure. Returns A list of possible return codes or errors (when appropriate) is included in this section. Some functions do not have return codes. Refer to Errors for a complete list of all return codes and their descriptions. Remarks This section contains additional information about the function, when required. Related Functions This list shows the functions (if any) that are related to the function being described. Example Code An example for each function is shown in the C programming language. ═══ 2.5. Error Severities ═══ Each of the error conditions given in the list of errors for each function falls into one of these areas: Warning The function detected a problem, but took some remedial action that enabled the function to complete successfully. The return code in this case indicates that the function completed successfully. Error The function detected a problem for which it could not take any sensible remedial action. The system has recovered from the problem, and the state of the system, with respect to the application, remains the same as at the time when the function was requested. The system has not even partially executed the function (other than reporting the error). Severe Error The function detected a problem from which the system could not reestablish its state, with respect to the application, at the time when that function was requested; that is, the system partially executed the function. This necessitates the application performing some corrective activity to restore the system to some known state. Unrecoverable Error The function detected some problem from which the system could not re-establish its state, with respect to the application, at the time when that call was issued. It is possible that the application cannot perform some corrective action to restore the system to some known state. ═══ 2.6. Header Files ═══ All functions require an "#include" statement for the system header file OS2.H: #include Most functions also require a "#define" statement to select an appropriate (conditional) section of the header file, and hence, the required prototype. Where this is necessary, it is shown at the head of the function definition in the form: #define INCL_name Note: These "#define" statements must precede the "#include " statement. ═══ 2.7. Addressing Elements in Arrays ═══ Constants defining array elements are given values that are zero-based in C; that is, the numbering of the array elements starts at zero, not one. For example, in the DevQueryCaps function, the sixth element of the ulArray parameter is CAPS_HEIGHT, which is equated to 5. Count parameters related to such arrays always mean the actual number of elements available; therefore, again using the DevQueryCaps function as an example, if all elements up to and including CAPS_HEIGHT are provided for, lCount could be set to (CAPS_HEIGHT+1). In functions for which the starting array element can be specified, this is always zero-based, and so the C element number constants can be used directly. For example, to start with the CAPS_HEIGHT element, the lStart parameter can be set to CAPS_HEIGHT. ═══ 2.8. Implicit Pointer Data Types ═══ A data type name beginning with "P" (for example, PERRORCODE) is likely to be a pointer to another data type (in this instance, ERRORCODE). In the data type summary, Data Types, no explicit "typedefs" are shown for pointers; therefore, if no data type definition can be found in the summary for a data type name "Pxxxxxx", it represents a pointer to the data type "xxxxxx", for which a definition should be found in the reference. The implicit type definition needed for such a pointer "Pxxxxxx" is: typedef xxxxxx *Pxxxxxx; Such definitions are provided in the header files. ═══ 2.9. Storage Mapping of Data Types ═══ The storage mapping of the data types is dependent on the machine architecture. To be portable, applications must access the data types using the definitions supplied for the environment in which they will execute. ═══ 2.10. Double-Byte Character Set (DBCS) ═══ Throughout this publication, you will see references to specific value for character strings. The values are for single-byte character set (SBCS). If you use the double-byte character set (DBCS), note that one DBCS character equals two SBCS characters. ═══ 2.10.1. C++ Considerations ═══ This section contains several topics you should take into consideration if you are using C++. ═══ 2.10.1.1. C++ Header Files ═══ OS/2 functions that used to take a PSZ as a parameter, and that do not modify the contents of the passed string, have been updated in the C++ header files to take a PCSZ data type parameter. The use of PCSZ allows for better optimization by the compiler and is more semantically compatible with C++. Existing code that calls functions that use PSZ will continue to work correctly. Several of the typedefs have been changed in the C++ header files. For example, many items that are unsigned char in the C header files are char in the C++ header files. For instance, typedef unsigned char BYTE; has changed to typedef char BYTE; The existing samples that are included in the IBM Developer's Toolkit for OS/2 Warp Version 3 can be used with either set of the header files. ═══ 2.10.1.2. LINK386 ═══ The C++ compiler will provide a dynamic link library which is used by LINK386 when generating error messages. This DLL will convert a compiler generated mangled name into the function prototype. If the DLL is not present, an error message will be displayed and LINK386 will display the compiler-generated, mangled name in the error message. ═══ 3. Platform Specific Drivers (PSDs) ═══ In OS/2 Warp Server for SMP, all of the platform specific code has been removed from the operating system, and placed into a Platform Specific Driver. These drivers provide an abstraction layer for the underlying hardware by allowing the operating system to call generic functions to perform platform-specific operations without worrying about the actual hardware implementation. This allows OS/2 Warp Server for SMP to support new MP hardware platforms without modifying the operating system. PSDs are 32-bit flat DLLs specified in CONFIG.SYS by using the PSD= keyword, and must conform to the 8.3 file naming convention (e.g. PSD=BELIZE.PSD). They cannot contain either drive or path information because OS/2 cannot process such information at the stage of the startup sequence when the PSD statements are processed. The root directory of the startup partition is first searched for the specified file name, followed by the \OS2 directory of the startup partition. If drive or path information is included in a PSD statement, an error is generated. PSD parameters may be specified after the PSD's name, and may be a maximum of 1024 characters long. The parameter string is not interpreted or parsed by OS/2, but is passed verbatim as an ASCIIZ string when the PSD's Install function is invoked. If multiple PSD statements are encountered, OS/2 will load each PSD in the order listed in CONFIG.SYS, and call the PSD's install function. The first PSD which successfully installs will be the one OS/2 uses. PSD statements are processed before BASEDEV, IFS, and DEVICE statements. ═══ 3.1. Platform Specific Driver Architecture and Structure ═══ The PSD operates in three contexts (modes): Kernel, Interrupt, and Init.  Kernel Mode The OS/2 kernel calls the PSD for task-time operations, that is, it will execute as a thread within a process. Kernel mode is also referred to as the task context.  Interrupt Mode The OS/2 kernel calls the PSD for interrupt-time operations. Interrupt time is a generic term that refers to executing code as a result of a hardware interrupt. The code does not execute as a thread belonging to a process.  Init Mode The PSD is currently being used for system initialization. A limited set of PSD helps are available for use. PSDs may contain multiple code and data objects. All objects will be fixed (not-swappable or movable) in low physical memory, with virtual addresses in the system arena. Objects are loaded in low physical memory to facilitate the use of real mode or bi-modal code. All objects default to permanent, which means that they remain in the system after initialization is completed. The SEGMENTS directive and the IOPL option in the linker DEF file should be used to mark those objects that are not to be kept after initialization. The multitasking/multiprocessing environment of OS/2 Warp Server for SMP dictates that the PSD must be capable of handling multiple requests simultaneously. This means that global variables should be used sparingly. Upon PSD installation, the kernel passes a pointer to a small area of processor local memory (PLMA) which the PSD developer can use to store variables. This PLMA area is currently 256 bytes in size. IBM reserves the right to increase the size of this area in future releases of OS/2, though the minimum available will always be 256 bytes. The size of the PLMA is passed in the same structure as the pointer to the PLMA from the PSDINSTALL export. PSD developers must be aware of the effects of the calls they make, because there is no guarantee that if an operation is started on a processor, and execution blocks, that the operation will continue on the same processor. OS/2 does not preempt a thread in the PSD, but it may block as a result of using a PSD help, or it may be interrupted by a hardware interrupt. PSDs can register an interrupt handler for any given IRQ level using the SET_IRQ PSD help. These interrupt handlers are guaranteed to be called before any device driver's interrupt handler. If the PSD's interrupt handler returns NO_ERROR, the interrupt manager will assume the interrupt has been handled, it will end the interrupt. If a -1 is returned, the interrupt manager will assume that the interrupt has not been handled, and will call each device driver which has a registered interrupt handler for that particular level until one claims the interrupt. If the interrupt is unclaimed, the IRQ level will be masked off. All PSDs must use the SET_IRQ PSD help to indicate which IRQ level they will be using for inter-processor interrupts (IPI). If the PSD's IPI IRQ level is shared, it must register a handler which detects if the IRQ is an IPI or another interrupt. The handler must return NO_ERROR if the interrupt was caused by an IPI, otherwise it returns a -1. If the IPI IRQ level is unique, an interrupt handler need not be installed but SET_IRQ must still be used to indicate which is the IPI IRQ level. The kernel will save the state of all the registers (except EAX) around calls to the PSD functions. All the functions will run at Ring 0. Upon invocation, SS, DS, and ES will be flat. The PSD functions must conform to the C calling convention. They receive parameters on the stack (4 bytes per parameter), and must return a return code in EAX. The PSD functions have been split into three categories:  Functions that the PSD must have for OS/2 to operate (required functions)  Functions that the PSD does not need to have (optional functions)  Functions that the PSD must have for OS/2 to use multiple processors (MP functions). The kernel provides default handling for some of the PSD functions. PSD functions can also chain to a kernel default handler by returning a -1 return code. If a return code other than -1 is returned by a PSD function, the default handler will not get called. The PSD function glossary later in this chapter details the categories of all the functions, as well as any default handlers they may have. The PSD developer makes functions available to OS/2 by using the EXPORTS statement in the module definition (DEF) file. All functions should be exported using upper case with no leading underscores (_). An example is shown below. LIBRARY TESTPSD EXPORTS PSD_INSTALL = _Install PSD_DEINSTALL = _DeInstall The initial CS and EIP in the PSD's executable image is ignored. The image should also not contain a stack object. OS/2 allocates a per-processor PSD stack and sets SS and ESP correctly before invoking any of the PSD functions. PSDs should be written in flat 32-bit code, using C, and must be linked as a LIBRARY. OS/2 invokes all PSD functions in protect mode, but there is also a PSD help which allows the PSD developer to call a PSD function in real mode. OS/2 services are provided through the PSD help interface. Access to these services are obtained upon PSD installation. PSD helpers preserve all registers except EAX. All the definitions (e.g. defines, structures, etc.) that are required for building a PSD are in the header file PSD.H. ═══ 3.2. OS/2 Initialization ═══ OS/2 requires a PSD for system initialization. The system will display an error message if a valid PSD for the current platform cannot be installed. The following is a list of steps, in the order in which they occur, that are executed after a PSD is installed. If any step does not complete successfully, the system initialization process will stop, and a fatal error message will be displayed. 1. After a PSD is successfully installed, its Init function is invoked. This function is used to allocate and initialize any resources that the PSD may require, as well as initializing the state of the hardware. 2. The kernel determines the number of usable processors on the current platform by using the PSD_GET_NUM_OF_PROCS function. 3. The kernel allocates all resources required to support the additional processors. This step determines what to allocate based on the results of the previous step. 4. The PSD's processor initialization function is invoked on the current processor (CPU0). 5. An MP daemon is created for CPU0. An MP daemon is a thread that never goes away, which is used for MP operations by a specific processor. 6. An MP daemon is created for the next logical processor. 7. The PSD's start processor call is invoked to start the next logical processor. The PSD should only start the specified processor, and then return (see the PSD_START_PROC function for more detail). The started processor will spin in a tight loop waiting for a variable to be cleared. This variable is referred to as the processor initialization real mode spinlock. 8. Upon return from the PSD's start processor call, the processor initialization real mode spinlock is cleared. 9. CPU0 will spin in a tight loop waiting for a variable to be cleared. This variable is referred to as the CPU0 spinlock. 10. The started processor continues execution of the kernel's real mode processor initialization code now that processor's initialization real mode spinlock has been cleared. 11. The started processor sets up all protect mode and paging information, and switches into protect mode with paging enabled. 12. Up to this point, the started processor has been running on a small processor initialization stack (It has not been running as an OS/2 thread). The current context is switched to that of this processors MP daemon. 13. OS/2 calls the PSD's processor initialization function for the current processor. 14. The PSD indicates that the processor has been initialized. 15. The started processor will spin in a tight loop waiting for a variable to be cleared. This variable is referred to as the processor initialization protect mode spinlock. 16. The CPU0 spinlock is cleared. 17. System initialization continues on CPU0 now that its spinlock has been cleared. 18. Steps 6, through 17 are repeated until all processors have been started. 19. The rest of system initialization continues normally, on CPU0. 20. After the system is fully initialized, the processor initialization protect mode spinlock is cleared. This allows CPU1 through CPU-N to start executing code. ═══ 3.3. PSD Function Glossary ═══ In the functions listed below all pointers must be flat 32-bit linear addresses. The following keywords indicate: Required Indicates that the function is required for OS/2 to operate properly, so the function can not be omitted. Optional Indicates that the function is not required. MP Indicates that the function is not required for OS/2 to execute with one processor, but it is required for OS/2 to use multiple processors. Default Indicates that the OS/2 kernel provides default handling for that specific function. Can Block Indicates that the function can call a PSD help that may block. Can't Block Indicates that the function can not call a PSD help that may block. Input Indicates that the kernel fills the field with input values before calling the function. Output Indicates that the PSD should return values in the specified field. 0-based Indicates that a zero denotes the first value. 1-based Indicates that a one denotes the first value. ═══ 3.4. PSD Functions ═══ Following are the PSD functions. ═══ 3.4.1. PSD_INSTALL ═══ PSD_INSTALL keywords Required, Can Block Description Determine if the PSD supports the current platform. This function probes the hardware to see if the PSD supports the current platform. No other operations should be executed in this function. It is merely a presence check. This function is the first function called upon loading a PSD. It must store away all the information passed to it in the install structure. Mode Called in Init Mode; may be called in Kernel Mode. Entry Pointer to an INSTALL structure. Exit NO_ERROR if the PSD installed successfully. -1 if the PSD does not support the current platform. Structures typedef struct install_s { P_F_2 pPSDHlpRouter; (Input) char *pParmString; (Input) void *pPSDPLMA; (Input) ulong_t sizePLMA; (Input) } INSTALL; pPSDHlpRouter points to the PSD help router. Use the PSDHelp macro in PSD.H to access the PSD helps. pParmString points to any parameters specified in CONFIG.SYS after the PSD's name. If no parameters were specified this field is NULL. pPSDPLMA points to the PSD's processor local memory area. This area contains different physical memory at the same linear address across all processors. You can use the area to store variables such that each processor accesses unique values, but all the code references the same variables. sizePLMA is the total size of the PSD's PLMA in bytes. Notes This function may be called after OS/2 is finished with initialization by the DosTestPSD API; therefore, the PSD developer must be careful not to use any Init mode only PSD help's in this function. ═══ 3.4.2. PSD_DEINSTALL ═══ PSD_DEINSTALL keywords Required, Can Block Description DeInstall the PSD. This function is called to release any resources that may have been allocated by the PSD_INSTALL function. A PSD is never de-installed after its Init routine is called. Mode Called in Init Mode; may be called in Kernel Mode. Entry None. Exit NO_ERROR if the PSD DeInstalled succesfully. -1 if the PSD didn't DeInstall. Notes This function may be called after OS/2 is finished with initialization by the DosTestPSD API; therefore, the PSD developer must be careful not to use any init mode only PSDHelp's in this function. ═══ 3.4.3. PSD_INIT ═══ PSD_INIT keywords Required, Can Block Description Initialize the PSD. This function is called to initialize the PSD. It is used to allocate and initialize any resources that the PSD may require, as well as initializing the state of the hardware. This function should only initialize the state of the hardware in general. Initialization of CPUs should be done in ProcInit. It must fill in the INIT structure passed to it by OS/2. This function is only called once on CPU0. Mode Called in Init Mode only. Entry Pointer to INIT structure Exit NO_ERROR if the PSD initialized successfully. -1 if the PSD didn't initialize. Structures typedef struct init_s { ulong_t flags; (Output) ulong_t version; (Output) } INIT; flags in the INIT structure indicate any special features or requirement that the PSD may have. INIT_GLOBAL_IRQ_ACCESS indicates that the platform can perform IRQ operations (e.g. PIC masking) on any processor. If this flag is omitted, the IRQ functions are guaranteed to only get called on CPU0, otherwise they may get called on any processor. If the flag is omitted and an IRQ operation is initiated on a processor other then CPU0, the OS/2 kernel will route the request to CPU0. INIT_USE_FPERR_TRAP indicates that Trap 16 will be used to report floating point errors, instead of IRQ 13. If this flag is set, the kernel sets the NE flag in CR0 for all processors. The PSD is responsible for doing any additional work for making the transition. INIT_EOI_IRQ13_ON_CPU0 indicates that an EOI for a floating point error using IRQ13 should only be performed from CPU0. On CPU1-N, the hardware is responsible for clearing the interrupt. version indicates the version number of this PSD. It should be updated appropriately as this will help with service. Notes None. ═══ 3.4.4. PSD_PROC_INIT ═══ PSD_PROC_INIT keywords MP, Can Block Description Initialize the current processor. This function is called to initialize the current processor. It is called in protect mode, once on a per-processor basis. It should initialize variables in the PSD's PLMA, along with initialization of the hardware state for that specific processor. Mode Called in Init Mode only. Entry None. Exit NO_ERROR if the processor initialized successfully. -1 if the processor didn't initialize. Structures None Notes None ═══ 3.4.5. PSD_START_PROC ═══ PSD_START_PROC keywords MP, Can Block Description Start a processor. This function is used to start a specified processor. The PSD may only start the processor that was specified. OS/2 fills in the address of a started processors initial real mode CS:IP in the warm reboot vector of the BIOS data area (0x40:0x67). OS/2 provides serialization such that another processor will not be started until the previous processor has finished its real mode initialization, gone into protect mode, and finished calling the ProcInit function. The processor which is started will be held in real mode until the StartProc function has been completed, and will then be allowed to initialize. All processors are started before the first device driver is loaded. Mode Called in Init Mode only. Entry Processor number (0-based). Exit NO_ERROR if the processor started successfully. -1 if the processor didn't start. Structures None. Notes If the hardware implementation uses some other mechanism to indicate a started processors initial CS:IP the value specified in the warm reboot vector should be used. If the hardware implementation requires some other real mode operation to be completed before the processor can continue to execute, the PSD developer must be certain to chain to the address specified in the warm reboot vector. ═══ 3.4.6. PSD_GET_NUM_OF_PROCS ═══ PSD_GET_NUM_OF_PROCS keywords Required, Can Block Description Return number of processors. This function must detect and return the number of usable x86 based processors that exist on the current platform. If the PSD detects that any of the processors are defective or non x86-based, it is the PSD's responsibility to setup the state of the PSD and hardware, such that all usable processors are logically ordered. For example, if there are 4 processors and CPU2 is defective, the CPU's should be ordered as follows: CPU0 = 0, CPU1 = 1, CPU2 (Defective), CPU3 = 2). Mode Called in Init Mode only. Entry None. Exit Number of processors (1-based). Structures None. Notes OS/2 Warp Server for SMP only supports processors that are compatible with the architecture of the Intel 386 and above. ═══ 3.4.7. PSD_GEN_IPI ═══ PSD_GEN_IPI keywords MP, Can't Block Description Generate an inter-processor interrupt. This function is used to generate an inter-processor interrupt. All inter-processor hardware dependencies should be fully initialized before the first GenIPI is called. Mode Called in Kernel, and Interrupt Mode. Entry Processor number to interrupt (0-based). Exit NO_ERROR if the IPI was generated. -1 if the IPI was not generated. Structures None. Notes OS/2 guarantees that the GenIPI function will not be called to interrupt a processor that has not finished processing any previous IPIs. ═══ 3.4.8. PSD_END_IPI ═══ PSD_END_IPI keywords MP, Can't Block Description End an inter-processor interrupt. This function is used to end an inter-processor interrupt, that was generated by GenIPI. Mode Called in Kernel, and Interrupt Mode. Entry Processor number to end interrupt on (0-based). Exit NO_ERROR if the IPI was ended successfully. -1 if the IPI didn't end successfully. Structures None. Notes The processor number specified and the current processor number should be identical. ═══ 3.4.9. PSD_PORT_IO ═══ PSD_PORT_IO keywords Optional, Default, Can't Block Description Perform local port I/O. Some platforms have some non MP specific system ports localized on a per-processor basis. If a local I/O operation may block before completion, I/O can be routed to a specific CPU for processing. This should be done, because an operation which started on one processor is not guaranteed to complete on that processor if execution is blocked. This function gets invoked as the result of a device driver calling DevHelp_Port_IO. Mode Called in Kernel, and Interrupt Mode. Entry Pointer to a PORT_IO structure. Exit NO_ERROR if the I/O was successful. -1 if the I/O wasn't successful. Structures typedef struct port_io_s { ulong_t port; (Input) ulong_t data; (Input/Output) ulong_t flags; (Input) } PORT_IO; port indicates which port to read to, or write from. data contains the data read from a read request, or the data to write if a write request. If the request uses less the 4 bytes the least significant portion of the data variable is used. flags indicate what operation to perform. IO_READ_BYTE Read a byte from the port IO_READ_WORD Read a word from the port IO_READ_DWORD Read a dword from the port IO_WRITE_BYTE Write a byte to the port IO_WRITE_WORD Write a word to the port IO_WRITE_DWORD Write a dword to the port Notes If the I/O performed is to a non-local port, the I/O should be handled as a regular I/O request. If device drivers or applications access the local ports directly, instead of using the documented interfaces problems may occur. ═══ 3.4.10. PSD_IRQ_MASK ═══ PSD_IRQ_MASK keywords Optional, Default, Can't Block Description Mask/Unmask IRQ levels This function allows masking (disabling), or un-masking (enabling) of IRQ levels. When this function is invoked it should save the state of the interrupt flag, and disable interrupts before performing the mask operation. It should then restore the state of the interrupt flag. Mode Called in Kernel, and Interrupt Mode. Entry Pointer to PSD_IRQ structure. Exit NO_ERROR operation completed successfully. -1 operation failed. Structures typedef struct psd_irq_s { ulong_t flags; (Input) ulong_t data; (Input/Output) ulong_t procnum; (Input) } PSD_IRQ; data is the logical IRQ levels to mask, or un-mask. flags indicate which type of operation is to be performed. IRQ_MASK mask (disable) IRQ levels IRQ_UNMASK unmask (enable) IRQ levels IRQ_GETMASK retrieves the masks for all IRQ levels IRQ_NEWMASK indicates that all the IRQ levels should reflect the state of the specified mask. procnum is the processor number of where the operation should take place. Notes If this function is omitted, OS/2 will perform all mask operations for an 8259 Master/Slave based PIC system. The requests will be sent to CPU0 depending on the state of the INIT_GLOBAL_IRQ_ACCESS flag. ═══ 3.4.11. PSD_IRQ_REG ═══ PSD_IRQ_REG keywords Optional, Default, Can't Block Description Access IRQ related registers. This function permits access to the IRQ related registers. Mode Called in Kernel, and Interrupt Mode. Entry Pointer to PSD_IRQ structure. Exit NO_ERROR operation completed successfully. -1 operation failed. Structures typedef struct psd_irq_s { ulong_t flags; (Input) ulong_t data; (Input/Output) ulong_t procnum; (Input) } PSD_IRQ; flags indicate which type of operation is to be performed. IRQ_READ_IRR read the interrupt request register. IRQ_READ_ISR read the in service register. data contains the data read from a read request, or the data to write if a write request. procnum is the processor number of where the operation should take place. Notes If this function is omitted, OS/2 will perform all register operations for an 8259 Master/Slave based PIC system. The requests will be sent to CPU0 depending on the state of the INIT_GLOBAL_IRQ_ACCESS flag. ═══ 3.4.12. PSD_IRQ_EOI ═══ PSD_IRQ_EOI keywords Optional, Default, Can't Block Description Issue an EOI. This function is used to issue an End-Of-Interrupt. Mode Called in Kernel, and Interrupt mode. Entry Pointer to PSD_IRQ structure. Exit NO_ERROR operation completed successfully. -1 operation failed. Structures typedef struct psd_irq_s { ulong_t flags; (Input) ulong_t data; (Input/Output) ulong_t procnum; (Input) } PSD_IRQ; data is the interrupt level to end. flags is not used in this operation. procnum is the processor number of where the operation should take place. Notes If this function is omitted, OS/2 will perform all EOI operations for an 8259 Master/Slave based PIC system. The requests will be sent to CPU0 depending on the state of the INIT_GLOBAL_IRQ_ACCESS flag. ═══ 3.4.13. PSD_APP_COMM ═══ PSD_APP_COMM keywords Optional, Can Block Description Perform generic APP/PSD communication. This function performs generic application/PSD communication. The entry arguments, and return codes are not interpreted by OS/2, it is passed verbatim to and from the PSD. Mode Called in Kernel mode. Entry Function number, Argument. Exit Return code. Structures None. Notes None. ═══ 3.4.14. PSD_SET_ADV_INT_MODE ═══ PSD_SET_ADV_INT_MODE keywords Optional, Can't Block Description TBD Mode Called in Init Mode only. Entry None. Exit Return code. Structures None. Notes The kernel initially provides default handling/detection for spurious interrupts. This is done for the last IRQ line of every PIC. It does this by checking the PIC's ISR register, and if the IRQ is not in service, it does not pass the interrupt request to the interrupt manager (i.e. a spurious interrupt). If a PSD switches into advanced interrupt mode; the kernel will no longer provide default handling/detection of spurious interrupts. It becomes the PSD's responsibility. One way a PSD could provide handling/detection of a spurious interrupt is to register a PSD handler for an IRQ level which may be spurious. As soon as the interrupt is detected the handler should insure that it is valid. If it is not (i.e. a spurious interrupt), it should dismiss the interrupt, and return NO_ERROR to the interrupt manager. The NO_ERROR return code informs the interrupt manager that the interrupt has been handled by the PSD. If the interrupt is valid the PSD should return a -1, as this informs the interrupt manager that the interrupt should be passed on to any device drivers registered to receive that interrupt. ═══ 3.5. PSD Helps ═══ OS/2 provides system services to the PSD developer via PSD helps. The address of the PSD help router is passed in the INSTALL structure when a PSD's install function is called. All PSD helps destroy the contents of the EAX register (used for a return code). All other registers, including the flags, are preserved. To invoke a PSD help, set up the appropriate parameters and call the PSD help router. For an example, refer to Sample Source Code for a PSD. Some prototypes and macros are defined in PSD.H to simplify their usage. The following keywords indicate: May Block Indicates that the help may block. Won't Block Indicates that the help won't block. ═══ 3.5.1. PSDHLP_VMALLOC ═══ PSDHLP_VMALLOC keywords May Block Description Allocate memory. This function is used to allocate virtual memory, or map virtual memory to physical memory, depending on the value of the flags. All virtual addresses are allocated from the system arena (i.e. global address space). Mode Callable in Init and Kernel mode. Parameters Pointer to a VMALLOC structure. Exit Return code. Structures typedef struct vmalloc_s { ulong_t addr; (Input/Output) ulong_t cbsize; (Input) ulong_t flags; (Input) } VMALLOC; addr is filled with the linear address of the allocated or mapped memory on return from the help. If VMALLOC_LOCSPECIFIC is specified, this field must contain the virtual address to map before calling the help. If VMALLOC_PHYS is specified, this field must contain the physical address to map before calling the help. cbsize is the size of the allocation, or mapping in bytes. flags indicate which type of operation is to be performed. VMALLOC_FIXED indicates that the allocated memory is to be fixed in memory (not-swappable or movable). If this flag is omitted, the allocated memory will be swappable by default. VMALLOC_CONTIG indicates that the allocation must use contigous physical memory. If this flag is specified VMALLOC_FIXED must also be used. VMALLOC_LOCSPECIFIC indicates a request for a memory allocation at a specific virtual address. If this flag is specified, the addr field must contain the virtual address to map. Note: This flag can be used with the VMALLOC_PHYS flag to allocate memory where linear = physical. VMALLOC_PHYS indicates a request for a virtual mapping of physical memory. If this flag is specified, the addr field must contain the physical address to map. Note: This flag can be used with the VMALLOC_LOCSPECIFIC flag to allocate memory where linear = physical. VMALLOC_1M indicates a request for a memory allocation below the 1MB boundary. Notes None. ═══ 3.5.2. PSDHLP_VMFREE ═══ PSDHLP_VMFREE keywords May Block Description Free allocation created by PSDHLP_VMALLOC. This function frees memory or destroys a physical mapping created by the PSDHLP_VMALLOC help. Mode Callable in Init and Kernel Mode. Parameters Linear address to free. Exit Return code. Structures None. Notes All memory or mappings allocated by a PSD must be released if the PSD is DeInstalled. ═══ 3.5.3. PSDHLP_SET_IRQ ═══ PSDHLP_SET_IRQ keywords Won't Block Description Setup IRQ information. This function is used to setup IRQ information. The PSD can use this help to register an interrupt handler at any given IRQ level between IRQ 0-IRQ 1F. These interrupt handler's are guaranteed to be called before any device driver's interrupt handler. If the PSD's interrupt handler returns NO_ERROR, the interrupt manager will assume the interrupt has been handled, and it will end the interrupt. If a -1 is returned, the interrupt manager will assume that the interrupt has not been handled, and will call each device driver which has a registered interrupt handler for that particular level, until one claims the interrupt. If the interrupt is unclaimed, the IRQ level will be masked off. All PSDs must use the SET_IRQ PSD help to indicate which IRQ level it will be using for its inter-processor interrupts (IPI). If the PSD's IPI IRQ level is shared, it must register a handler which detects if the IRQ is an IPI or another interrupt. The handler must return NO_ERROR if the interrupt was caused by an IPI, otherwise, it returns a -1. If the IPI IRQ level is unique, an interrupt handler need not be installed, but SET_IRQ must still be used to indicate the IPI IRQ level. This function can also be used to set, or remap what interrupt vector a particular IRQ level will use. Mode Callable in Init mode only. Parameters Pointer to a SET_IRQ structure. Exit Return code. Structures typedef struct set_irq_s { ushort_t irq; ushort_t flags; ulong_t vector; P_F_2 handler; } SET_IRQ; irq specifies which IRQ level this operation is to be performed on. flags indicate what is the type of the specified IRQ. If no flag is used, a regular IRQ level is assumed. IRQf_IPI indicates that the specified IRQ level is to be used for inter-processor interrupts. IRQf_LSI indicates that the specified IRQ level is to be used as a local software interrupt. IRQf_SPI indicates that the specfied IRQ level is to be used as a system priority interrupt. vector is used to specify what interrupt vector the IRQ level will use. handler contains the address of an interrupt handler. If the PSD is just specifying that a specific IRQ level is of a special type (e.g. IPI IRQ), it does not need a handler (the handler variable must be NULL). Notes IRQf_LSI, and IRQf_SPI, are currently not being used. ═══ 3.5.4. PSDHLP_CALL_REAL_MODE ═══ PSDHLP_CALL_REAL_MODE keywords Won't Block Description Call a PSD function in real mode. This function is used by the PSD developer to call one of his PSD functions in real mode. Mode Callable in Init mode only. Parameters Pointer to a CALL_REAL_MODE structure. Exit Called functions return code. Structures typedef struct call_real_mode_s { ulong_t function; ulong_t pdata; } CALL_REAL_MODE; function contains the linear address of the function to be called in real mode. pdata contains the linear address of a parameter to be passed to the real mode function. The parameter is pointed to by DS:SI on entry to the called function. A return code may be returned by the real mode function in EAX. Notes No PSD helps may be used in real mode. ═══ 3.5.5. PSDHLP_VMLINTOPHYS ═══ PSDHLP_VMLINTOPHYS keywords Won't Block Description Convert linear address to physical This function converts the specified linear address to physical. Mode Callable in Init, Kernel, and Interrupt Mode. Parameters Linear address to convert. Exit Physical address if successful, -1 otherwise. Structures None. Notes None. ═══ 3.6. Application Programming Interface ═══ The OS/2 kernel will provide new support APIs for PSDs. ═══ 3.6.1. DosTestPSD ═══ Description Determine if the PSD is valid for the current platform. This function will load the specified PSD, call its Install, and DeInstall routine, and unload the PSD. It returns the return code from the PSD's Install routine, or any error code it might have received while attempting to do the above operation. Parameters Pointer to a fully qualified PSD path and name. Exit Return Code. Notes This function will mainly be used by OS/2's install, to test the validity of a PSD that will be installed. ═══ 4. High Memory Support ═══ The High Memory Support in OS/2 Warp Server for SMP removes the 512 MB virtual memory limit present in previous versions of OS/2, thus allowing 32-bit applications to allocate shared or private memory objects above the 512 MB boundary. ═══ 4.1. VIRTUALADDRESSLIMIT Parameter in CONFIG.SYS ═══ A new CONFIG.SYS parameter, VIRTUALADDRESSLIMIT. has been added to specify the highest virtual memory address that may be accessed. The default value for OS/2 Warp Server for SMP is 2 GB, which is specified in MB in the command: VIRTUALADDRESSLIMIT=2048 The smallest value allowed is 512, which provides compatability with previous versions of OS/2 which only allowed access to 512 MB. The largest value supported is 3072 (3 GB). The VIRTUALADDRESSLIMIT parameter may be specified as part of selective install. Values in excess of 512 will reduce the number of processes that can concurrently run on the system. When memory has been exhausted, OS/2 control program functions will fail with ERROR_NOT_ENOUGH_MEMORY and PM functions will fail with PMERR_INSUFFICIENT_MEMORY. Future versions of OS/2 may allow larger values and, for any given value, support more concurrent processes. Values outside the valid range (below 512 or over 3072) will result in an error message during CONFIG.SYS processing and the system will use the default value of 2048. The highest virtual memory address and the maximum number of concurrent processes allowed can be determined from a program by using the DosQuerySysInfo function. ═══ 4.2. New OBJ_ANY Memory Attribute ═══ A new allocation attribute of OBJ_ANY is available to 32-bit programs when allocating memory using DosAllocMem and DosAllocSharedMem. OBJ_ANY indicates that the memory may be allocated anywhere in the available virtual address space. An application must be able to handle pointer values above the 512 MB tiled memory compatibility region when using OBJ_ANY. In OS/2 Warp Server for SMP, OBJ_ANY memory allocations will first be attempted in the high memory area, which is the area of the virtual address space above 512 MB. If there is insufficient memory to satisfy the request from the high memory area, the memory will be allocated in the first 512 MB of the address space. IBM reserves the right to change this allocation strategy in future releases of OS/2. Memory objects allocated below the 512 MB line will start on a 64 KB boundary, the size will be rounded up to a multiple of 64 KB, and the memory will be tileable. Objects allocated above the 512 MB line will start on a 4 KB boundary, the size will be rounded up to a multiple of 4 KB, and the memory will not be tileable. 16-bit programs will not be able to address or access the object. Memory should be allocated with the OBJ_ANY attribute wherever possible, since it provides the most efficient use of both the per-process address space as well as the system-wide virtual memory resources. It is intended that an application would make infrequent requests for large blocks of memory using DosAllocMem and then use DosSubSetMem along with DosSubAllocMem and DosSubFreeMem to manage the memory. If OBJ_ANY is not specified, the behavior of DosAllocMem and DosAllocSharedMem is the same as in OS/2 Warp. ═══ 4.3. Implementation Details ═══ Note: IBM reserves the right to change these implementation details in future releases of OS/2. Any number specified in VIRTUALADDRESSLIMIT is rounded up to a 64 MB boundary. The user's address space above the 512 MB line has the same properties as the user's address space below the 512 MB line, namely:  A high private arena at the low end and a high shared arena at the high end.  1/8 of the user's address space is guaranteed to be in the high private arena  1/8 of the user's address s[ace is guaranteed to be in the high shared arena  The two arenas grow toward each other: the high private arena grows up and the high shared arena grows down. No memory objects can span the 512 MB line. The current allocation strategy for OBJ_ANY allocations is: Allocate from the appropriate high memory arena. If there is not enough virtual memory in the specified arena to support the request, then the allocation will come from the appropriate low memory arena below the 512 MB line, if possible. Otherwise, the function will fail with a return code of ERROR_NOT_ENOUGH_MEMORY. ═══ 4.4. High Memory Support Functions ═══ The following OS/2 functions have been tested with the High Memory Support:  DosFlatToSel  DosGetNamedSharedMem  DosGetSharedMem  DosGiveSharedMem  DosSetMem  DosFreeMem  DosRead  DosWrite  DosQueryMem  DosQueryState  DosQueryPageUsage  DosSubSetMem  DosSubAllocMem  DosSubFreeMem  DosSubUnsetMem  All 32-bit semaphore functions  All 32-bit exception handling functions The maximum amount of free space in the high memory area can be determined from a program by using the DosQuerySysInfo function. If a virtual address above the 512 MB line is passed to DosFlatToSel, a 0 is returned. The following functions have been enhanced for High Memory Support: ═══ 4.5. DosAllocMem ═══ ═══ DosAllocMem - Syntax ═══ Allocates a private memory object within the virtual-address space. #define INCL_DOSMEMMGR #include PPVOID ppb; /* A pointer to a variable that will receive the base address of the allocated private memory object. */ ULONG cb; /* Size, in bytes, of the private memory object to allocate. */ ULONG flag; /* Allocate attribute and desired access protection flags. */ APIRET ulrc; /* Return Code. */ ulrc = DosAllocMem(ppb, cb, flag); ═══ DosAllocMem Parameter - ppb ═══ ppb (PPVOID) - output A pointer to a variable that will receive the base address of the allocated private memory object. ═══ DosAllocMem Parameter - cb ═══ cb (ULONG) - input Size, in bytes, of the private memory object to allocate. The size is rounded up to the next page-size boundary. The size of a page is 4KB. ═══ DosAllocMem Parameter - flag ═══ flag (ULONG) - input Allocate attribute and desired access protection flags. A set of flags describing the allocation attributes and desired access protection for the private memory object. Possible values are shown in the lists below: Allocation Attributes PAG_COMMIT (0x00000010) All pages in the private memory object are initially committed. OBJ_TILE (0x00000040) The private memory object must be allocated in the first 512MB of virtual-address space, with 16-bit selectors mapping the memory object. OBJ_ANY (0x01000000) The private memory object may reside anywhere in the available virtual-address space. 16-bit programs will not be able to access this object. OBJ_TILE and OBJ_ANY are incompatible options. Specifying both for the same memory object will result in an error. OBJ_ANY indicates that the memory may be allocated anywhere in the available virtual address space. In OS/2 Warp Server for SMP, OBJ_ANY memory allocations will first be attempted in the high memory area, which is the area of the virtual address space above 512 MB. If there is insufficient memory to satisfy the request from the high memory area, the memory will be allocated in the first 512 MB of the address space. IBM reserves the right to change this allocation strategy in future releases of OS/2. If a memory object is allocated in the high memory area above 512 MB, 16-bit programs will not be able to address or access the object. Memory should be allocated with the OBJ_ANY attribute wherever possible, since it provides the most efficient use of both the per-process address space as well as the system-wide virtual memory resources. It is intended that an application would make infrequent requests for large blocks of memory using DosAllocMem and then use DosSubSetMem along with DosSubAllocMem and DosSubFreeMem to manage the memory. The maximum amount of free space in the high memory area can be determined from a program by using the DosQuerySysInfo function. For OBJ_TILE memory objects, the 16-bit selectors are allocated to map the 32-bit object at 64KB boundaries. The figure below shows how the 16-bit alias selectors map the 32-bit object. 32-bit 32-bit 16-bit alias Offset Object Selectors BaseAddress+000KB┌──────────────┐ ───── Sel │ │ BaseAddress+064KB├──────────────┤ ───── Sel+HugeInc │ │ BaseAddress+128KB├──────────────┤ ───── Sel+HugeInc*2 │ │ BaseAddress+192KB├──────────────┤ ───── Sel+HugeInc*3 │ │ HugeInc is the huge increment used for DosAllocHuge. Desired Access Protection PAG_EXECUTE (0x00000004) Execute access to the committed pages in the private memory object PAG_READ (0x00000001) Read access PAG_WRITE (0x00000002) Write access PAG_GUARD (0x00000008) Access to the committed pages in the private memory object causes a "guard page entered" condition to be raised in the subject process. At least one of the bits PAG_READ, PAG_WRITE, or PAG_EXECUTE must be set. ═══ DosAllocMem Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosAllocMem returns one of the following values: 0 NO_ERROR 8 ERROR_NOT_ENOUGH_MEMORY 87 ERROR_INVALID_PARAMETER 95 ERROR_INTERRUPT For a full list of error codes, see Errors. ═══ DosAllocMem - Parameters ═══ ppb (PPVOID) - output A pointer to a variable that will receive the base address of the allocated private memory object. cb (ULONG) - input Size, in bytes, of the private memory object to allocate. The size is rounded up to the next page-size boundary. The size of a page is 4KB. flag (ULONG) - input Allocate attribute and desired access protection flags. A set of flags describing the allocation attributes and desired access protection for the private memory object. Possible values are shown in the lists below: Allocation Attributes PAG_COMMIT (0x00000010) All pages in the private memory object are initially committed. OBJ_TILE (0x00000040) The private memory object must be allocated in the first 512MB of virtual-address space, with 16-bit selectors mapping the memory object. OBJ_ANY (0x01000000) The private memory object may reside anywhere in the available virtual-address space. 16-bit programs will not be able to access this object. OBJ_TILE and OBJ_ANY are incompatible options. Specifying both for the same memory object will result in an error. OBJ_ANY indicates that the memory may be allocated anywhere in the available virtual address space. In OS/2 Warp Server for SMP, OBJ_ANY memory allocations will first be attempted in the high memory area, which is the area of the virtual address space above 512 MB. If there is insufficient memory to satisfy the request from the high memory area, the memory will be allocated in the first 512 MB of the address space. IBM reserves the right to change this allocation strategy in future releases of OS/2. If a memory object is allocated in the high memory area above 512 MB, 16-bit programs will not be able to address or access the object. Memory should be allocated with the OBJ_ANY attribute wherever possible, since it provides the most efficient use of both the per-process address space as well as the system-wide virtual memory resources. It is intended that an application would make infrequent requests for large blocks of memory using DosAllocMem and then use DosSubSetMem along with DosSubAllocMem and DosSubFreeMem to manage the memory. The maximum amount of free space in the high memory area can be determined from a program by using the DosQuerySysInfo function. For OBJ_TILE memory objects, the 16-bit selectors are allocated to map the 32-bit object at 64KB boundaries. The figure below shows how the 16-bit alias selectors map the 32-bit object. 32-bit 32-bit 16-bit alias Offset Object Selectors BaseAddress+000KB┌──────────────┐ ───── Sel │ │ BaseAddress+064KB├──────────────┤ ───── Sel+HugeInc │ │ BaseAddress+128KB├──────────────┤ ───── Sel+HugeInc*2 │ │ BaseAddress+192KB├──────────────┤ ───── Sel+HugeInc*3 │ │ HugeInc is the huge increment used for DosAllocHuge. Desired Access Protection PAG_EXECUTE (0x00000004) Execute access to the committed pages in the private memory object PAG_READ (0x00000001) Read access PAG_WRITE (0x00000002) Write access PAG_GUARD (0x00000008) Access to the committed pages in the private memory object causes a "guard page entered" condition to be raised in the subject process. At least one of the bits PAG_READ, PAG_WRITE, or PAG_EXECUTE must be set. ulrc (APIRET) - returns Return Code. DosAllocMem returns one of the following values: 0 NO_ERROR 8 ERROR_NOT_ENOUGH_MEMORY 87 ERROR_INVALID_PARAMETER 95 ERROR_INTERRUPT For a full list of error codes, see Errors. ═══ DosAllocMem - Remarks ═══ DosAllocMem can be used to reserve, or reserve and commit, linear address space for a private memory object. The operating system allocates a range of private pages large enough to fulfill the specified allocation request from the private virtual-address space of the subject process. The base address of the object is returned in the ppb parameter. The allocated memory object is rounded up to a multiple of 4KB in size. The committed memory allocated by DosAllocMem can be swapped. Any access protection can be applied to committed pages within a private memory object. Committed pages are initially allocated and backed by demand pages. The first attempt to read or write the page causes a page of zeros to be created. If a failure occurs during the allocation, no pages are allocated, and an appropriate error code is returned. With the Intel 80386 processor, execute and read access are equivalent. Also, write access implies both read and execute access. The guard-page attribute is intended to provide automatic stack-growth and stack-limit checking. An application may also use it in other data structures. Reserved pages that are not committed are given an access protection of "no access". ═══ DosAllocMem - Related Functions ═══ Related Functions  DosAllocSharedMem  DosFreeMem ═══ DosAllocMem - Example Code ═══ This example allocates memory as Read/Write, queries it, commits it, uses it, and then releases it. #define INCL_DOSMEMMGR /* Include DOS Memory Management APIs */ #define INCL_DOSERRORS /* DOS error values */ #include #include #include int main (VOID) { PVOID MyObject = NULL; /* Pointer to memory object */ ULONG ulObjSize = 0; /* Size of memory object (in bytes) */ ULONG ulMemFlags = 0; /* Attribute flags for the object */ ULONG ulMemSize = 0; /* Size of memory region for DosSetMem */ APIRET rc = NO_ERROR; /* Return code */ ulObjSize = 40960L; /* A big object */ rc = DosAllocMem(&MyObject, /* Pointer to memory object pointer */ ulObjSize, /* Size of object to be allocated */ OBJ_ANY | /* Allocate memory anywhere */ PAG_WRITE ); /* Allocate memory as read/writeable */ if (rc != NO_ERROR) { printf("DosAllocMem error: return code = %u\n",rc); return 1; } /* Object can't be used until it is COMMITTED. Since this was not done at DosAllocMem time, do it now. */ rc = DosSetMem(MyObject, /* Pointer to object */ ulObjSize, /* Size of area to change */ PAG_DEFAULT | PAG_COMMIT ); /* Commit the object */ if (rc != NO_ERROR) { printf("DosSetMem error: return code = %u\n",rc); rc = DosFreeMem(MyObject); /* If omitted, OS/2 frees it at termination */ return 1; } else { printf("DosSetMem: complete\n"); } strcpy(MyObject, "The memory object has just been used."); /* Check COMMIT status of the memory object. */ ulMemSize = ulObjSize; rc = DosQueryMem(MyObject, &ulMemSize, &ulMemFlags); if (rc == NO_ERROR) { if (ulMemFlags & PAG_COMMIT) { printf(" Page containing MyObject is now committed.\n"); } else { printf("Error: Page containing MyObject has not been committed.\n"); } /* endif */ } else { printf("DosQueryMem error: return code = %u\n",rc); } /* endif */ rc = DosFreeMem(MyObject); if (rc != NO_ERROR) { printf("DosFreeMem error: return code = %u\n",rc); return 1; } return NO_ERROR; } ═══ DosAllocMem - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 4.6. DosAllocSharedMem ═══ ═══ DosAllocSharedMem - Syntax ═══ Allocates a shared memory object within the virtual-address space. #define INCL_DOSMEMMGR #include PPVOID ppb; /* A pointer to a variable that will receive the base address of the allocated range of pages. */ PSZ pszName; /* An optional address of the name string associated with the shared memory object to be allocated. */ ULONG cb; /* Size, in bytes, of the shared memory object to allocate. */ ULONG flag; /* Allocation attribute and desired access protection flags. */ APIRET ulrc; /* Return Code. */ ulrc = DosAllocSharedMem(ppb, pszName, cb, flag); ═══ DosAllocSharedMem Parameter - ppb ═══ ppb (PPVOID) - output A pointer to a variable that will receive the base address of the allocated range of pages. OS/2 determines where to allocate the virtual address for the shared memory object. ═══ DosAllocSharedMem Parameter - pszName ═══ pszName (PSZ) - input An optional address of the name string associated with the shared memory object to be allocated. The name is an ASCIIZ string in the format of an OS/2 file name, and is in the subdirectory, \SHAREMEM\; for example, \SHAREMEM\PUBLIC.DAT. To allocate unnamed shared memory, set this parameter to NULL. If you want to use unnamed shared memory, the flag parameter must include either OBJ_GETTABLE or OBJ_GIVEABLE. ═══ DosAllocSharedMem Parameter - cb ═══ cb (ULONG) - input Size, in bytes, of the shared memory object to allocate. The size is rounded up to the next page-size boundary. The size of a page is 4KB. ═══ DosAllocSharedMem Parameter - flag ═══ flag (ULONG) - input Allocation attribute and desired access protection flags. A set of flags describing the allocation attributes and desired access protection for the shared memory object. Possible values are shown in the following lists: Allocation Attributes PAG_COMMIT (0x00000010) All pages in the shared memory object are initially committed. OBJ_GIVEABLE (0x00000200) The access to the memory object can be given to another process using the DosGiveSharedMem function. OBJ_GETTABLE (0x00000100) The memory object can be accessed by another process that knows the address of the memory and calls the DosGetSharedMem function. OBJ_TILE (0x00000040) The shared memory object must be allocated in the first 512MB of virtual-address space, with 16-bit selectors mapping the memory object. OBJ_ANY (0x01000000) The shared memory object may be allocated anywhere in the virtual-address space. 16-bit programs will not be able to access the memory object. OBJ_TILE and OBJ_ANY are incompatable attributes and may not be specified together. OBJ_ANY indicates that the memory may be allocated anywhere in the available virtual address space. In OS/2 Warp Server for SMP, OBJ_ANY memory allocations will first be attempted in the high memory area, which is the area of the virtual address space above 512 MB. If there is insufficient memory to satisfy the request from the high memory area, the memory will be allocated in the first 512 MB of the address space. IBM reserves the right to change this allocation strategy in future releases of OS/2. If a memory object is allocated in the high memory area above 512 MB, 16-bit programs will not be able to address or access the object. Memory should be allocated with the OBJ_ANY attribute wherever possible, since it provides the most efficient use of both the per-process address space as well as the system-wide virtual memory resources. It is intended that an application would make infrequent requests for large blocks of memory using DosAllocMem and then use DosSubSetMem along with DosSubAllocMem and DosSubFreeMem to manage the memory. The maximum amount of free space in the high memory area can be determined from a program by using the DosQuerySysInfo function. For OBJ_TILE memory objects, the 16-bit selectors are allocated to map the 32-bit object at 64KB boundaries. The figure in the description of the Parameters for DosAllocMem shows how the 16-bit alias selectors map the 32-bit object. Desired Access Protection PAG_EXECUTE (0x00000004) Execute access to the committed pages in the private memory object is desired. PAG_READ (0x00000001) Read access is desired. PAG_WRITE (0x00000002) Write access is desired. PAG_GUARD (0x00000008), Access to the committed pages in the private memory object causes a "guard page entered" condition to be raised in the subject process. At least one of the bits of PAG_READ, PAG_WRITE, or PAG_EXECUTE must be set. ═══ DosAllocSharedMem Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosAllocSharedMem returns one of the following values: 0 NO_ERROR 8 ERROR_NOT_ENOUGH_MEMORY 87 ERROR_INVALID_PARAMETER 95 ERROR_INTERRUPT 123 ERROR_INVALID_NAME 183 ERROR_ALREADY_EXISTS For a full list of error codes, see Errors. ═══ DosAllocSharedMem - Parameters ═══ ppb (PPVOID) - output A pointer to a variable that will receive the base address of the allocated range of pages. OS/2 determines where to allocate the virtual address for the shared memory object. pszName (PSZ) - input An optional address of the name string associated with the shared memory object to be allocated. The name is an ASCIIZ string in the format of an OS/2 file name, and is in the subdirectory, \SHAREMEM\; for example, \SHAREMEM\PUBLIC.DAT. To allocate unnamed shared memory, set this parameter to NULL. If you want to use unnamed shared memory, the flag parameter must include either OBJ_GETTABLE or OBJ_GIVEABLE. cb (ULONG) - input Size, in bytes, of the shared memory object to allocate. The size is rounded up to the next page-size boundary. The size of a page is 4KB. flag (ULONG) - input Allocation attribute and desired access protection flags. A set of flags describing the allocation attributes and desired access protection for the shared memory object. Possible values are shown in the following lists: Allocation Attributes PAG_COMMIT (0x00000010) All pages in the shared memory object are initially committed. OBJ_GIVEABLE (0x00000200) The access to the memory object can be given to another process using the DosGiveSharedMem function. OBJ_GETTABLE (0x00000100) The memory object can be accessed by another process that knows the address of the memory and calls the DosGetSharedMem function. OBJ_TILE (0x00000040) The shared memory object must be allocated in the first 512MB of virtual-address space, with 16-bit selectors mapping the memory object. OBJ_ANY (0x01000000) The shared memory object may be allocated anywhere in the virtual-address space. 16-bit programs will not be able to access the memory object. OBJ_TILE and OBJ_ANY are incompatable attributes and may not be specified together. OBJ_ANY indicates that the memory may be allocated anywhere in the available virtual address space. In OS/2 Warp Server for SMP, OBJ_ANY memory allocations will first be attempted in the high memory area, which is the area of the virtual address space above 512 MB. If there is insufficient memory to satisfy the request from the high memory area, the memory will be allocated in the first 512 MB of the address space. IBM reserves the right to change this allocation strategy in future releases of OS/2. If a memory object is allocated in the high memory area above 512 MB, 16-bit programs will not be able to address or access the object. Memory should be allocated with the OBJ_ANY attribute wherever possible, since it provides the most efficient use of both the per-process address space as well as the system-wide virtual memory resources. It is intended that an application would make infrequent requests for large blocks of memory using DosAllocMem and then use DosSubSetMem along with DosSubAllocMem and DosSubFreeMem to manage the memory. The maximum amount of free space in the high memory area can be determined from a program by using the DosQuerySysInfo function. For OBJ_TILE memory objects, the 16-bit selectors are allocated to map the 32-bit object at 64KB boundaries. The figure in the description of the Parameters for DosAllocMem shows how the 16-bit alias selectors map the 32-bit object. Desired Access Protection PAG_EXECUTE (0x00000004) Execute access to the committed pages in the private memory object is desired. PAG_READ (0x00000001) Read access is desired. PAG_WRITE (0x00000002) Write access is desired. PAG_GUARD (0x00000008), Access to the committed pages in the private memory object causes a "guard page entered" condition to be raised in the subject process. At least one of the bits of PAG_READ, PAG_WRITE, or PAG_EXECUTE must be set. ulrc (APIRET) - returns Return Code. DosAllocSharedMem returns one of the following values: 0 NO_ERROR 8 ERROR_NOT_ENOUGH_MEMORY 87 ERROR_INVALID_PARAMETER 95 ERROR_INTERRUPT 123 ERROR_INVALID_NAME 183 ERROR_ALREADY_EXISTS For a full list of error codes, see Errors. ═══ DosAllocSharedMem - Remarks ═══ DosAllocSharedMem allocates a shared memory object within the virtual-address space. Allocating a shared memory object causes the creation of an object that describes a region of memory that can be shared. The virtual-address space in the calling process is allocated and mapped to the shared memory object. The virtual-address space for a shared memory object is reserved at the same location in the virtual address space of every process. This allows any process to gain access to the shared object at the same virtual address where it was originally allocated. When the shared memory object is given a name, the shared memory object can be shared by other processes that gain access through the shared memory name (see DosGetNamedSharedMem). To specify the name for the shared memory object, the name string provided must include the prefix "\SHAREMEM\". It is an error to request giveable or gettable named shared memory. To allocate unnamed shared memory, set the pszName parameter to NULL. If the shared memory object is unnamed, it may be specified as giveable (OBJ_GIVEABLE) or gettable (OBJ_GETTABLE). Unnamed shared memory may be shared by all processes that get access to the shared memory object (see DosGetSharedMem), or are given access to the shared memory object (see DosGiveSharedMem). It is an error to request non-giveable or non-gettable unnamed shared memory. The allocated memory object is rounded up to a multiple of 4KB in size. The committed memory allocated by DosAllocSharedMem is movable and can be swapped. With the Intel 80386 processor, execute and read access are equivalent. Also, write access implies both read and execute access. The tiled allocation attribute is provided for compatibility with the existing 16-bit implementation of the operating system. If the shared memory object is tiled, the virtual address for the shared memory object will be within the first 512MB of the virtual address space, with 16-bit selectors mapping the memory object. ═══ DosAllocSharedMem - Related Functions ═══ Related Functions  DosAllocMem  DosFreeMem  DosGetNamedSharedMem  DosGetSharedMem  DosGiveSharedMem ═══ DosAllocSharedMem - Example Code ═══ This example allocates named shared memory as Read/Write, and commits it during allocation. It also writes to it, and show how other processes can access it. #define INCL_DOSMEMMGR /* Include DOS Memory Management APIs */ #define INCL_DOSERRORS /* DOS error values */ #include #include #include int main (VOID) { PVOID pvShrObject = NULL; /* Pointer to shared memory object */ PSZ pszMemName = "\\SHAREMEM\\MYTOOL\\APPLICAT.DAT"; /* Object name */ PVOID pvAltObject = NULL; /* Alternate pointer to shared memory */ APIRET rc = NO_ERROR; /* Return code */ ULONG ulObjSize = 1024; /* Size (system rounds to 4096 - page bdy) */ rc = DosAllocSharedMem(&pvShrObject, /* Pointer to object pointer */ pszMemName, /* Name for shared memory */ ulObjSize, /* Desired size of object */ PAG_COMMIT | /* Commit memory */ PAG_WRITE ); /* Allocate memory as read/write */ if (rc != NO_ERROR) { printf("DosAllocSharedMem error: return code = %u\n",rc); return 1; } strcpy(pvShrObject, "Write your shared application data here."); /* Get the address of the shared memory and reference it that way. (Done for illustrative purposes only, this is how another process would go about accessing the named shared memory.) */ rc = DosGetNamedSharedMem(&pvAltObject, /* Pointer to pointer of object */ pszMemName, /* Name of shared memory */ PAG_READ); /* Want read-only access */ if (rc != NO_ERROR) { printf("DosGetNamedSharedMem error: return code = %u\n",rc); return 1; } printf("Shared data read was \"%s\"\n",pvAltObject); rc = DosFreeMem(pvShrObject); if (rc != NO_ERROR) { printf("DosFreeMem error: return code = %u\n",rc); return 1; } return NO_ERROR; } ═══ DosAllocSharedMem - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 4.7. DosQuerySysInfo ═══ ═══ DosQuerySysInfo - Syntax ═══ Returns values of static system variables. #define INCL_DOSMISC #include ULONG iStart; /* Ordinal of the first system variable to return. */ ULONG iLast; /* Ordinal of the last system variable to return. */ PVOID pBuf; /* Address of the data buffer where the system returns the variable values. */ ULONG cbBuf; /* Length, in bytes, of the data buffer. */ APIRET ulrc; /* Return Code. */ ulrc = DosQuerySysInfo(iStart, iLast, pBuf, cbBuf); ═══ DosQuerySysInfo Parameter - iStart ═══ iStart (ULONG) - input Ordinal of the first system variable to return. ═══ DosQuerySysInfo Parameter - iLast ═══ iLast (ULONG) - input Ordinal of the last system variable to return. ═══ DosQuerySysInfo Parameter - pBuf ═══ pBuf (PVOID) - output Address of the data buffer where the system returns the variable values. ═══ DosQuerySysInfo Parameter - cbBuf ═══ cbBuf (ULONG) - input Length, in bytes, of the data buffer. ═══ DosQuerySysInfo Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosQuerySysInfo returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW For a full list of error codes, see Errors. ═══ DosQuerySysInfo - Parameters ═══ iStart (ULONG) - input Ordinal of the first system variable to return. iLast (ULONG) - input Ordinal of the last system variable to return. pBuf (PVOID) - output Address of the data buffer where the system returns the variable values. cbBuf (ULONG) - input Length, in bytes, of the data buffer. ulrc (APIRET) - returns Return Code. DosQuerySysInfo returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW For a full list of error codes, see Errors. ═══ DosQuerySysInfo - Remarks ═══ DosQuerySysInfo returns a single system variable or a range of system variables to a user-allocated buffer. To request a single system variable, set iStart equal to iLast. To request a range of system variables, set iStart less than iLast. Each system variable is a ULONG value. The following list gives the ordinal index, name, and description of the system variables. 1 QSV_MAX_PATH_LENGTH Maximum length, in bytes, of a path name. 2 QSV_MAX_TEXT_SESSIONS Maximum number of text sessions. 3 QSV_MAX_PM_SESSIONS Maximum number of PM sessions. 4 QSV_MAX_VDM_SESSIONS Maximum number of DOS sessions. 5 QSV_BOOT_DRIVE Drive from which the system was started (1 means drive A, 2 means drive B, and so on). 6 QSV_DYN_PRI_VARIATION Dynamic priority variation flag (0 means absolute priority, 1 means dynamic priority). 7 QSV_MAX_WAIT Maximum wait in seconds. 8 QSV_MIN_SLICE Minimum time slice in milliseconds. 9 QSV_MAX_SLICE Maximum time slice in milliseconds. 10 QSV_PAGE_SIZE Memory page size in bytes. This value is 4096 for the 80386 processor. 11 QSV_VERSION_MAJOR Major version number (see note below). 12 QSV_VERSION_MINOR Minor version number (see note below). 13 QSV_VERSION_REVISION Revision number (see note below). 14 QSV_MS_COUNT Value of a 32-bit, free-running millisecond counter. This value is zero when the system is started. 15 QSV_TIME_LOW Low-order 32 bits of the time in seconds since January 1, 1970 at 0:00:00. 16 QSV_TIME_HIGH High-order 32 bits of the time in seconds since January 1, 1970 at 0:00:00. 17 QSV_TOTPHYSMEM Total number of bytes of physical memory in the system. 18 QSV_TOTRESMEM Total number of bytes of resident memory in the system. 19 QSV_TOTAVAILMEM Maximum number of bytes of memory that can be allocated by all processes in the system. This number is advisory and is not guaranteed, since system conditions change constantly. 20 QSV_MAXPRMEM Maximum number of bytes of memory that this process can allocate in its private arena. This number is advisory and is not guaranteed, since system conditions change constantly. 21 QSV_MAXSHMEM Maximum number of bytes of memory that a process can allocate in the shared arena. This number is advisory and is not guaranteed, since system conditions change constantly. 22 QSV_TIMER_INTERVAL Timer interval in tenths of a millisecond. 23 QSV_MAX_COMP_LENGTH Maximum length, in bytes, of one component in a path name. 24 QSV_FOREGROUND_FS_SESSION Session ID of the current foreground full-screen session. Note that this only applies to full-screen sessions. The Presentation Manager session (which displays Vio-windowed, PM, and windowed DOS Sessions) is full-screen session ID 1. 25 QSV_FOREGROUND_PROCESS Process ID of the current foreground process. 26 QSV_NUMPROCESSORS Number of processors in the machine. 27 QSV_MAXHPRMEM Maximum amount of free space in the high private arena for this process. This number does not indicate the largest single memory object that can be allocated, since the arena is probably fragmented. 28 QSV_MAXHSHMEM Maximum amount of free space in the high shared arena for this process. This number does not indicate the largest single memory object that can be allocated, since the arena is probably fragmented. 29 QSV_MAXPROCESSES Maximum number of concurrent processes supported. 30 QSV_VIRTUALADDRESSLIMIT Size of the user's address space in MB. Note: Major, minor and revision numbers for versions of OS/2 operating system are described below: ┌──────────┬──────────┬──────────┬──────────┐ │ │Major │Minor │Revision │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 2.0 │20 │00 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 2.1 │20 │10 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 2.11 │20 │11 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 3.0 │20 │30 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 4.0 │20 │40 │0 │ └──────────┴──────────┴──────────┴──────────┘ An application can specify file objects managed by an installable file system that supports long file names. Because some installable file systems support longer names than others, the application should issue DosQuerySysInfo upon initialization. DosQuerySysInfo returns the maximum path length (QSV_MAX_PATH_LENGTH) supported by the installed file system. The path length includes the drive specifier (d:), the leading backslash ( \ ), and the trailing null character. The value returned by DosQuerySysInfo can be used to allocate buffers for path names returned by other functions. Since memory usage in the system changes constantly, the values returned by QSV_MAXHPRMEM and QSV_MAXHSMMEM should only be used as an indication of current memory usage. ═══ DosQuerySysInfo - Related Functions ═══ Related Functions  DosOpen  DosSetFSInfo ═══ DosQuerySysInfo - Example Code ═══ This example queries and displays the maximum length for a path name and the total amount of physical memory in bytes. #define INCL_DOSMISC /* DOS Miscellaneous values */ #define INCL_DOSERRORS /* DOS Error values */ #include #include int main(VOID) { ULONG aulSysInfo[QSV_MAX] = {0}; /* System Information Data Buffer */ APIRET rc = NO_ERROR; /* Return code */ rc = DosQuerySysInfo(1L, /* Request all available system */ QSV_MAX, /* information */ (PVOID)aulSysInfo, sizeof(ULONG)*QSV_MAX); if (rc != NO_ERROR) { printf("DosQuerySysInfo error: return code = %u\n", rc); return 1; } else { printf("Maximum length for a path name is %u characters.\n", aulSysInfo[QSV_MAX_PATH_LENGTH-1]); /* Max length of path name */ printf("Total physical memory is %u bytes.\n", aulSysInfo[QSV_TOTPHYSMEM-1]); /* Total physical memory */ } /* endif */ return NO_ERROR; } ═══ DosQuerySysInfo - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5. Raw File System ═══ The OS/2 Raw File System provides an interface for applications to efficiently manage data on the logical partitions or physical hard drives installed in a system. Some of the Raw File System function is available by using a combination of the DosPhysicalDisk and DosDevIOCtl functions. However, the Raw File System provides a significant step forward in usability and performance. The Raw File System provides a programming abstraction that treats each logical partition or physical disk as one large file that can be opened, locked, seeked, read from, written to, and closed. Logical partitions are identified using the Universal Naming Convention (UNC) in the form of \\.\X: where X can be substituted with the letter corresponding the logical partition desired on any hard drive, floppy disk or CD-ROM drive. Physical disks are identified using a UNC name in the form of \\.\Physical_Disk# where # is replaced with the physical disk number corresponding to the number found in the FDISK utility. The Raw File System recognizes up to 128 physical disks, thus eliminating the limit of 26 drives in previous versions of OS/2. The use of the universal naming convention coupled with the ability to access any physical or logical drive using the common file system functions in OS/2, provides a greatly simplified migration path for applications. Traditionally, raw file systems have been utilized by applications that manage large amounts of data under heavy workloads. Typically, this has been commercial database servers performing on-line transaction processing. Disk I/O can become a bottleneck under these conditions and the use of an efficient raw file system can be very useful in improving system performance, through reduced path length and serialization. The chapter describes the Raw File System functions in detail. ═══ 5.1. Programming Recommendations ═══ As an aid to those who wish to develop using the Raw File System, here are a few recommendations based on the implementation that will help make the most of your efforts. Note: Be careful when using the Raw File System! While it can be very useful and powerful, it will not stop you from destroying the data on your disks if you are not careful. Physical vs. Logical Disks Physical disk refers to the actual hard disk drives installed in the system. The Raw File System supports up to 128 installed physical disks. Logical disks refers to partitions located on the physical disks, including floppy and CD-ROM drives, that have been formatted for a specific file system, such as FAT or HPFS. OS/2 is limited to 26 such partitions, the first two of which are reserved for floppy drives. Physical Disk Numbering Physical disk numbers directly correspond with the number assigned using the FDISK utility program. Physical Disk Formatting When using the Raw File System to manage data on a physical disk, the disk should not be formatted for use by another file system. The FDISK utility will show the disk as unformatted. Drive Locking To make a physical disk accessible only by the current process, use the OPEN_SHARE_DENYREADWRITE flag on the DosOpen call. The lock will automatically be released when DosClose is called. In order to lock a logical partition, a call to DosDevIOCtl with category 8, function DSK_LOCKDRIVE must called. This must be done before any reads or writes can succeed. Upon completion, DosDevIOCtl with category 8, function DSK_UNLOCKDRIVE must be called before DosClose in order to unlock the disk. Memory Buffer Sizes The Raw File System supports large memory buffers for reading and writing. For best performance, keep your memory buffers less than 64KB in size. Buffers larger than this are broken up into multiple requests in order not to overload the system buffers. Aligned Memory Buffers The Raw File System is implemented with performance critical applications in mind. Implementation details dictate that memory buffers used for I/O should begin on page boundaries in order to achieve maximum performance. Unaligned memory buffers will result in poorer performance. See the example code in the DosListIO function to see how to align a buffer. DosListIO Function The DosListIO function should be used when multiple reads and writes are necessary. This will greatly reduce the number of instructions needed to perform the I/O operations and as a result help minimize utilization of system resources. This is most beneficial under heavy workloads. Disks Larger than 2 GB The Raw File System supports physical disks up to 1 TB (terabyte) in size. To allow easier addressing of such large disks, a new mode bit, FILE_SECTOR, has been added to DosSetFilePtr and DosListIO which allows offsets to be specified in sectors rather than bytes. For Maximum Performance... To achieve maximum performance using the Raw File System, the application should use the DosListIO function with page aligned memory buffers less than 64 KB in size directed to data on physical drives. ═══ 5.2. DosClose ═══ ═══ DosClose - Syntax ═══ Closes a handle to a file, pipe, or device. #define INCL_DOSFILEMGR #include HFILE hFile; /* The handle returned by a previous call to DosCreateNPipe, DosCreatePipe, DosDupHandle, or DosOpen. */ APIRET ulrc; /* Return Code. */ ulrc = DosClose(hFile); ═══ DosClose Parameter - hFile ═══ hFile (HFILE) - input The handle returned by a previous call to DosCreateNPipe, DosCreatePipe, DosDupHandle, or DosOpen. ═══ DosClose Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosClose returns one of the following values: 0 NO_ERROR 2 ERROR_FILE_NOT_FOUND 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE For a full list of error codes, see Errors. ═══ DosClose - Parameters ═══ hFile (HFILE) - input The handle returned by a previous call to DosCreateNPipe, DosCreatePipe, DosDupHandle, or DosOpen. ulrc (APIRET) - returns Return Code. DosClose returns one of the following values: 0 NO_ERROR 2 ERROR_FILE_NOT_FOUND 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE For a full list of error codes, see Errors. ═══ DosClose - Remarks ═══ Issuing DosClose with the handle to a file closes a handle to a file, pipe, or device. If additional handles to a file were created with DosDupHandle, DosClose must be issued for the duplicate handles before the directory is updated, and information in internal buffers is written to the medium. Closing a device handle causes the device to be notified of the close, if appropriate. Named-Pipe Considerations DosClose closes a named pipe by handle. When all handles that refer to one end of a pipe are closed, the pipe is considered broken. If the client end closes, no other process can reopen the pipe until the serving end issues DosDisConnectNPipe, followed by DosConnectNPipe. If the server end closes when the pipe is already broken, the pipe is immediately deallocated; otherwise, it is not deallocated until the last client handle is closed. ═══ DosClose - Related Functions ═══ Related Functions  DosConnectNPipe  DosCreateNPipe  DosDisConnectNPipe  DosDupHandle  DosOpen  DosResetBuffer ═══ DosClose - Example Code ═══ This example opens, or creates and opens, a file named "DOSTEST.DAT", writes to it, reads from it, and finally closes it. #define INCL_DOSFILEMGR /* File Manager values */ #define INCL_DOSERRORS /* DOS Error values */ #include #include #include int main(void) { HFILE hfFileHandle = 0L; /* Handle for file being manipulated */ ULONG ulAction = 0; /* Action taken by DosOpen */ ULONG ulBytesRead = 0; /* Number of bytes read by DosRead */ ULONG ulWrote = 0; /* Number of bytes written by DosWrite */ ULONG ulLocal = 0; /* File pointer position after DosSetFilePtr */ UCHAR uchFileName[20] = "dostest.dat", /* Name of file */ uchFileData[100] = " "; /* Data to write to file */ APIRET rc = NO_ERROR; /* Return code */ /* Open the file dostest.dat. Use an existing file or create a new */ /* one if it doesn't exist. */ rc = DosOpen(uchFileName, /* File path name */ &hfFileHandle, /* File handle */ &ulAction, /* Action taken */ 100L, /* File primary allocation */ FILE_ARCHIVED | FILE_NORMAL, /* File attribute */ OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */ OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, /* Open mode of the file */ 0L); /* No extended attribute */ if (rc != NO_ERROR) { printf("DosOpen error: return code = %u\n", rc); return 1; } else { printf ("DosOpen: Action taken = %ld\n", ulAction); } /* endif */ /* Write a string to the file */ strcpy (uchFileData, "testing...\n1...\n2...\n3\n"); rc = DosWrite (hfFileHandle, /* File handle */ (PVOID) uchFileData, /* String to be written */ sizeof (uchFileData), /* Size of string to be written */ &ulWrote); /* Bytes actually written */ if (rc != NO_ERROR) { printf("DosWrite error: return code = %u\n", rc); return 1; } else { printf ("DosWrite: Bytes written = %u\n", ulWrote); } /* endif */ /* Move the file pointer back to the beginning of the file */ rc = DosSetFilePtr (hfFileHandle, /* File Handle */ 0L, /* Offset */ FILE_BEGIN, /* Move from BOF */ &ulLocal); /* New location address */ if (rc != NO_ERROR) { printf("DosSetFilePtr error: return code = %u\n", rc); return 1; } /* Read the first 100 bytes of the file */ rc = DosRead (hfFileHandle, /* File Handle */ uchFileData, /* String to be read */ 100L, /* Length of string to be read */ &ulBytesRead); /* Bytes actually read */ if (rc != NO_ERROR) { printf("DosRead error: return code = %u\n", rc); return 1; } else { printf ("DosRead: Bytes read = %u\n%s\n", ulBytesRead, uchFileData); } /* endif */ rc = DosClose(hfFileHandle); /* Close the file */ if (rc != NO_ERROR) { printf("DosClose error: return code = %u\n", rc); return 1; } return NO_ERROR; } ═══ DosClose - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.3. DosDevIOCtl ═══ ═══ DosDevIOCtl - Syntax ═══ Performs control functions on a device specified by an opened device handle. #define INCL_DOSDEVICES #define INCL_DOSDEVIOCTL #include HFILE hDevice; /* Device handle returned by DosOpen, or a standard (open) device handle. */ ULONG category; /* Device category. */ ULONG function; /* Device-specific function code. */ PVOID pParams; /* Address of the command-specific argument list. */ ULONG cbParmLenMax; /* Length, in bytes, of pParams. */ PULONG pcbParmLen; /* Pointer to the length of parameters. */ PVOID pData; /* Address of the data area. */ ULONG cbDataLenMax; /* Length, in bytes, of pData. */ PULONG pcbDataLen; /* Pointer to the length of data. */ APIRET ulrc; /* Return Code. */ ulrc = DosDevIOCtl(hDevice, category, function, pParams, cbParmLenMax, pcbParmLen, pData, cbDataLenMax, pcbDataLen); ═══ DosDevIOCtl Parameter - hDevice ═══ hDevice (HFILE) - input Device handle returned by DosOpen, or a standard (open) device handle. ═══ DosDevIOCtl Parameter - category ═══ category (ULONG) - input Device category. The valid range is 0 to 255. ═══ DosDevIOCtl Parameter - function ═══ function (ULONG) - input Device-specific function code. The valid range is 0 to 255. ═══ DosDevIOCtl Parameter - pParams ═══ pParams (PVOID) - input Address of the command-specific argument list. ═══ DosDevIOCtl Parameter - cbParmLenMax ═══ cbParmLenMax (ULONG) - input Length, in bytes, of pParams. This is the maximum length of the data to be returned in pParams. pcbParmLen may be larger than this on input, but not on output. ═══ DosDevIOCtl Parameter - pcbParmLen ═══ pcbParmLen (PULONG) - in/out Pointer to the length of parameters. Input Pointer to the length, in bytes, of the parameters passed in pParams. by the application. Output Pointer to the length, in bytes, of the parameters returned. If this function returns ERROR_BUFFER_OVERFLOW, then pcbParmLen points to the size of the buffer required to hold the parameters returned. No other data is returned in this case. ═══ DosDevIOCtl Parameter - pData ═══ pData (PVOID) - input Address of the data area. ═══ DosDevIOCtl Parameter - cbDataLenMax ═══ cbDataLenMax (ULONG) - input Length, in bytes, of pData. This is the maximum length of the data to be returned in pData. pcbDataLen may be larger than this on input, but not on output. ═══ DosDevIOCtl Parameter - pcbDataLen ═══ pcbDataLen (PULONG) - in/out Pointer to the length of data. Input Pointer to the length, in bytes, of the data passed by the application in pData. Output Pointer to the length, in bytes, of the data returned. If this function returns ERROR_BUFFER_OVERFLOW, then pcbDataLen points to the size of the buffer required to hold the data returned. ═══ DosDevIOCtl Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosDevIOCtl returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED For a full list of error codes, see Errors. ═══ DosDevIOCtl - Parameters ═══ hDevice (HFILE) - input Device handle returned by DosOpen, or a standard (open) device handle. category (ULONG) - input Device category. The valid range is 0 to 255. function (ULONG) - input Device-specific function code. The valid range is 0 to 255. pParams (PVOID) - input Address of the command-specific argument list. cbParmLenMax (ULONG) - input Length, in bytes, of pParams. This is the maximum length of the data to be returned in pParams. pcbParmLen may be larger than this on input, but not on output. pcbParmLen (PULONG) - in/out Pointer to the length of parameters. Input Pointer to the length, in bytes, of the parameters passed in pParams. by the application. Output Pointer to the length, in bytes, of the parameters returned. If this function returns ERROR_BUFFER_OVERFLOW, then pcbParmLen points to the size of the buffer required to hold the parameters returned. No other data is returned in this case. pData (PVOID) - input Address of the data area. cbDataLenMax (ULONG) - input Length, in bytes, of pData. This is the maximum length of the data to be returned in pData. pcbDataLen may be larger than this on input, but not on output. pcbDataLen (PULONG) - in/out Pointer to the length of data. Input Pointer to the length, in bytes, of the data passed by the application in pData. Output Pointer to the length, in bytes, of the data returned. If this function returns ERROR_BUFFER_OVERFLOW, then pcbDataLen points to the size of the buffer required to hold the data returned. ulrc (APIRET) - returns Return Code. DosDevIOCtl returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED For a full list of error codes, see Errors. ═══ DosDevIOCtl - Remarks ═══ Values returned in the range 0xFF00 through 0xFFFF are user-dependent error codes. Values returned in the range 0xFE00 through 0xFEFF are device-driver-dependent error codes. This function provides a generic, expandable IOCtl facility. A null (zero) value for pData specifies that this parameter is not defined for the generic IOCtl function being specified. A null value for pData causes the values passed in cbDataLenMax and pcbDataLen to be ignored. A null (zero) value for pParams specifies that this parameter is not defined for the generic IOCtl function being specified. A null value for pParams causes the values passed in cbParmLenMax and pcbParmLen to be ignored. The kernel formats a generic IOCtl packet and calls the device driver. Because OS/2 Version 1.0 and Version 1.1 device drivers do not understand generic IOCtl packets with cbDataLenMax, pcbDataLen, cbParmLenMax, and pcbParmLen, the kernel does not pass these fields to the device driver. Device drivers that are marked as level 2 or higher must support receipt of the generic IOCtl packets with associated length fields. Do not pass a non-null pointer with a zero length. See Generic IOCtl Commands for a partial listing of IOCtl control functions. For the complete listing of the generic IOCtl control functions (the IOCtl interface), see the OS/2 Warp Control Program Programming Guide and Reference. For debugging considerations, see DosDebug. ═══ DosDevIOCtl - Related Functions ═══ Related Functions  DosBeep  DosDevConfig  DosPhysicalDisk ═══ DosDevIOCtl - Example Code ═══ The following is NOT a complete C program. It is simply intended to provide an idea of how to issue control functions to a device. This example assumes that DevHandle contains the handle to the device, and that the device recognizes category code hex 83, function code hex 1D and the input parameters and input data area. #define INCL_DOSDEVICES /* Device values */ #define INCL_DOSERRORS /* Error values */ #include #include #include HFILE DevHandle = NULLHANDLE; /* Handle for device */ ULONG ulCategory = 0x83; /* Device category */ ULONG ulFunction = 0x1D; /* Device-specific function */ UCHAR uchParms[120] = {0}; /* Input and output for function */ ULONG ulParmLen = 0; /* Input and output parameter size */ UCHAR uchDataArea[200] = {0}; /* Input and output data area */ ULONG ulDataLen = 0; /* Input and output data size */ APIRET rc = NO_ERROR; /* Return code */ strcpy(uchParms,"/X /Y /Z"); /* Input parameters */ ulParmLen = strlen(uchParms); /* Length of input parameters */ strcpy(uchDataArea,"DF=123;NP=BCR;UN=1993;MAX=328"); /* Input data */ ulDataLen = strlen(uchDataArea); /* Length of data */ rc = DosDevIOCtl(DevHandle, /* Handle to device */ ulCategory, /* Category of request */ ulFunction, /* Function being requested */ uchParms, /* Input/Output parameter list */ sizeof(uchParms), /* Maximum output parameter size */ &ulParmLen, /* Input: size of parameter list */ /* Output: size of parameters returned */ uchDataArea, /* Input/Output data area */ sizeof(uchDataArea), /* Maximum output data size */ &ulDataLen); /* Input: size of input data area */ /* Output: size of data returned */ if (rc != NO_ERROR) { printf("DosDevIOCtl error: return code = %u\n", rc); return 1; } ═══ DosDevIOCtl - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.4. DosListIO ═══ ═══ DosListIO - Syntax ═══ Performs multiple locking, unlocking, seeking, and I/O operations against one or more files. #define INCL_DOSFILEMGR #include ULONG ulCmdMode; /* Command mode */ ULONG ulNumEntries; /* Number of LISTIO entries to process */ PLISTIO pListIO; /* Pointer to array of LISTIO structures */ APIRET ulrc; /* Return Code. */ ulrc = DosListIO(ulCmdMode, ulNumEntries, pListIO); ═══ DosListIO Parameter - ulCmdMode ═══ ulCmdMode (ULONG) - input Command mode The mode in which operations should be performed. Valid modes are: LISTIO_ORDERED Operations are performed synchronously in the order specified. LISTIO_UNORDERED Operations are performed independently without an implied ordering. (This mode is only available in the Raw File System.) ═══ DosListIO Parameter - ulNumEntries ═══ ulNumEntries (ULONG) - input Number of LISTIO entries to process The number of seek/read or seek/write operations in the list. Each operation is represented by a LISTIO array entry. ═══ DosListIO Parameter - pListIO ═══ pListIO (PLISTIO) - in/out Pointer to array of LISTIO structures Pointer to an array of ulNumEntries LISTIO data structures which contain the information necessary to perform the I/O operations. ═══ DosListIO Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosListIO returns one of the following values: 0 NO_ERROR 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE 19 ERROR_WRITE_PROTECT 26 ERROR_NOT_DOS_DISK 29 ERROR_WRITE_FAULT 33 ERROR_LOCK_VIOLATION 87 ERROR_INVALID_PARAMETER 109 ERROR_BROKEN_PIPE 234 ERROR_MORE_DATA For a full list of error codes, see Errors. ═══ DosListIO - Parameters ═══ ulCmdMode (ULONG) - input Command mode The mode in which operations should be performed. Valid modes are: LISTIO_ORDERED Operations are performed synchronously in the order specified. LISTIO_UNORDERED Operations are performed independently without an implied ordering. (This mode is only available in the Raw File System.) ulNumEntries (ULONG) - input Number of LISTIO entries to process The number of seek/read or seek/write operations in the list. Each operation is represented by a LISTIO array entry. pListIO (PLISTIO) - in/out Pointer to array of LISTIO structures Pointer to an array of ulNumEntries LISTIO data structures which contain the information necessary to perform the I/O operations. ulrc (APIRET) - returns Return Code. DosListIO returns one of the following values: 0 NO_ERROR 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE 19 ERROR_WRITE_PROTECT 26 ERROR_NOT_DOS_DISK 29 ERROR_WRITE_FAULT 33 ERROR_LOCK_VIOLATION 87 ERROR_INVALID_PARAMETER 109 ERROR_BROKEN_PIPE 234 ERROR_MORE_DATA For a full list of error codes, see Errors. ═══ DosListIO - Remarks ═══ DosListIO applies the same restrictions for each seek/read and seek/write operations as would be applied if the requests were issued separately with DosSetFilePtr, DosRead, and DosWrite. The actual number of bytes read or written, along with the operation return code are returned in the LISTIO structure upon completion of the request, therefore care must be taken that the memory containing the LISTIO control blocks is not deallocated or manipulated by another thread before the DosListIO request returns. There are two valid modes for the list of I/O operations to be processed. ORDERED This mode guarantees that the operations are performed in the order specified. DosFileIO will return with an error code corresponding to the first failed request and will not attempt to process the remaining requests. This provides a synchronous sequence of atomic I/O requests. This is the only mode that is compatible with file systems other than the Raw File System. UNORDERED This mode does not guarantee the order that the operations are performed or the order that the operations complete. DosFileIO will return with an error code if any request fails. Additionally, each request in the list will be issued, even those following a failed operation. This mode is valid for the Raw File System only. ═══ DosListIO - Related Functions ═══ Related Functions  DosOpen  DosSetFilePtr  DosRead  DosWrite  DosClose ═══ DosListIO - Example Code ═══ This example reads from a physical disk using the Raw File System and DosListIO. #define INCL_ERRORS #define INCL_DOS #define INCL_NOPMAPI #include #include #include #include #include #include "listio.h" #define EightK 8*1024 #define FourK 4*1024 #define LISTIO_NUM 1000 #define PAGE_RAND_MAX 100 CHAR Buf[EightK]; LISTIO ListIO[LISTIO_NUM]; ULONG seed = 1; ULONG page_rand(void); int main (VOID) { CHAR *BufAligned; ULONG rc; ULONG Loop = LISTIO_NUM, i, j; ULONG Action, Actual; HFILE hFile; /* Make sure buffer is page aligned */ BufAligned = (UCHAR *)(((LONG)Buf + FourK) & 0xFFFFF000); /* Open a raw file system disk */ rc = DosOpen((PSZ)"\\\\.\\Physical_Disk2", &hFile, &Action, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, 0L); if (rc != NO_ERROR) { printf("ERROR:DosOpen rc = %d\n", rc); return(1); } /* if */ /*************************************/ /* Perform Random READ using DosRead */ /*************************************/ for(i = 0; i < Loop ; i++) { /* Loop for Random Read */ rc = DosSetFilePtr(hFile, /* file's handle */ page_rand()*FourK, /* offset */ FILE_BEGIN, /* from beginning of file */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosSetFilePtr rc = %d\n", rc); return(1); } /* if */ rc = DosRead( hFile, /* file's handle */ BufAligned, /* buffer pointer */ FourK, /* size to read */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosRead rc = %d\n", rc); return(1); } /* if */ } /* for i */ /****************************************/ /* Perform Random Read using DosListIO */ /****************************************/ for (i = 0; i < Loop; i++) { ListIO[i].hFile = hFile; ListIO[i].CmdFlag = LISTIO_READ | FILE_BEGIN; ListIO[i].Offset = page_rand()*FourK; ListIO[i].pBuffer = BufAligned; ListIO[i].NumBytes = FourK; } /* for i */ rc = DosListIO( LISTIO_UNORDERED, /* unordered mode */ Loop, /* number of reads */ ListIO); /* array of control blocks */ if (rc != NO_ERROR) { printf("ERROR:DosListIO rc = %d\n", rc); for (i = 0; i < Loop; i++) { if ((ListIO[i].Actual != FourK) || (ListIO[i].RetCode != NO_ERROR)) { printf("ERROR:DosListIO i = %d, Actual = %d, RetCode = %d\n", I, ListIO[i].Actual, ListIO[i].RetCode); } /* if */ } /* for i */ return(1); } /* if */ /* Close file */ rc = DosClose(hFile); if (rc != NO_ERROR) { printf("ERROR:DosClose rc = %d\n", rc); return(1); } return(NO_ERROR); } /********************************************************/ /* */ /* FUNCTION: page_rand */ /* */ /* DESCRIPTION: Generate random number in range */ /* [0,PAGE_RAND_MAX-1] */ /* */ /********************************************************/ ULONG page_rand() { seed = seed * 1103515245 + 12345; return(((ULONG)(seed/(2*PAGE_RAND_MAX)) % PAGE_RAND_MAX)); } ═══ DosListIO - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.5. DosOpen ═══ ═══ DosOpen - Syntax ═══ Opens a new file, an existing file or device, or a replacement for an existing file. An open file can have extended attributes. #define INCL_DOSFILEMGR #include PSZ pszFileName; /* Address of the ASCIIZ path name of the file or device to be opened. */ PHFILE pHf; /* Address of the handle for the file or device. */ PULONG pulAction; /* Address of the variable that receives the value that specifies the action taken by the DosOpen function. */ ULONG cbFile; /* New logical size of the file (end of data, EOD), in bytes. */ ULONG ulAttribute; /* File attribute information. */ ULONG fsOpenFlags; /* The action to be taken depending on whether the file exists or does not exist. */ ULONG fsOpenMode; /* The mode of the open function. Possible values are shown in the following list: */ PEAOP2 peaop2; /* Extended attributes. */ APIRET ulrc; /* Return Code. */ ulrc = DosOpen(pszFileName, pHf, pulAction, cbFile, ulAttribute, fsOpenFlags, fsOpenMode, peaop2); ═══ DosOpen Parameter - pszFileName ═══ pszFileName (PSZ) - input Address of the ASCIIZ path name of the file or device to be opened. In the Raw File System, this is the universal naming convention (UNC) name for either a logical partition or physical disk. Logical partitions are identified using a UNC name in the form of: \\.\X:, where X is replaced with the letter corresponding to the drive. Physical disks are identified with a UNC name in the form of: \\.\Physical_Disk#, where # is replaced with the physical disk number as reported by the FDISK utility. ═══ DosOpen Parameter - pHf ═══ pHf (PHFILE) - output Address of the handle for the file or device. ═══ DosOpen Parameter - pulAction ═══ pulAction (PULONG) - output Address of the variable that receives the value that specifies the action taken by the DosOpen function. If DosOpen fails, this value has no meaning. Otherwise, it is one of the following values: 1 FILE_EXISTED File already existed. This is always returned on the successful open of a device. 2 FILE_CREATED File was created. 3 FILE_TRUNCATED File existed and was changed to a given size (file was replaced). ═══ DosOpen Parameter - cbFile ═══ cbFile (ULONG) - input New logical size of the file (end of data, EOD), in bytes. This parameter is significant only when creating a new file or replacing an existing one. Otherwise, it is ignored. It is an error to create or replace a file with a nonzero length if the fsOpenMode Access-Mode flag is set to read-only. ═══ DosOpen Parameter - ulAttribute ═══ ulAttribute (ULONG) - input File attribute information. This parameter is significant only when manipulating a file, it is ignored on raw file system devices. Possible values are shown in the following list.: Bit Description 31-6 Reserved, must be 0. 5 FILE_ARCHIVED (0x00000020) File has been archived. 4 FILE_DIRECTORY (0x00000010) File is a subdirectory. 3 Reserved, must be 0. 2 FILE_SYSTEM (0x00000004) File is a system file. 1 FILE_HIDDEN (0x00000002) File is hidden and does not appear in a directory listing. 0 FILE_READONLY (0x00000001) File can be read from, but not written to. 0 FILE_NORMAL (0x00000000) File can be read from or written to. File attributes apply only if the file is created. These bits may be set individually or in combination. For example, an attribute value of 0x00000021 (bits 5 and 0 set to 1) indicates a read-only file that has been archived. ═══ DosOpen Parameter - fsOpenFlags ═══ fsOpenFlags (ULONG) - input The action to be taken depending on whether the file exists or does not exist. This parameter is not used in the raw file system. Possible values are shown in the following list: Bits Description 31-8 Reserved, must be 0. 7-4 The following flags apply if the file does not exist: 0000 OPEN_ACTION_FAIL_IF_NEW Open an existing file; fail if the file does not exist. 0001 OPEN_ACTION_CREATE_IF_NEW Create the file if the file does not exist. 3-0 The following flags apply if the file already exists: 0000 OPEN_ACTION_FAIL_IF_EXISTS Open the file; fail if the file already exists. 0001 OPEN_ACTION_OPEN_IF_EXISTS Open the file if it already exists. 0010 OPEN_ACTION_REPLACE_IF_EXISTS Replace the file if it already exists. ═══ DosOpen Parameter - fsOpenMode ═══ fsOpenMode (ULONG) - input The mode of the open function. Possible values are shown in the following list: Bit Description 31-16 Reserved, must be zero. 15 OPEN_FLAGS_DASD (0x00008000) Direct Open flag: 0 pszFileName represents a file to be opened normally. 1 pszFileName is "drive:" (such as C: or A:), and represents a mounted disk or diskette volume to be opened for direct access. 14 OPEN_FLAGS_WRITE_THROUGH (0x00004000) Write-Through flag: 0 Writes to the file may go through the file-system driver's cache. The file-system driver writes the sectors when the cache is full or the file is closed. 1 Writes to the file may go through the file-system driver's cache, but the sectors are written (the actual file I/O operation is completed) before a synchronous write call returns. This state of the file defines it as a synchronous file. For synchronous files, this bit must be set, because the data must be written to the medium for synchronous write operations. This bit flag is not inherited by child processes. 13 OPEN_FLAGS_FAIL_ON_ERROR (0x00002000) Fail-Errors flag. Media I/O errors are handled as follows: 0 Reported through the system critical-error handler. 1 Reported directly to the caller by way of a return code. Media I/O errors generated through Category 08h Logical Disk Control IOCtl Commands always get reported directly to the caller by way of return code. The Fail-Errors function applies only to non-IOCtl handle-based file I/O calls. This flag bit is not inherited by child processes. 12 OPEN_FLAGS_NO_CACHE (0x00001000) No-Cache/Cache flag: 0 The file-system driver should place data from I/O operations into its cache. 1 I/O operations to the file need not be done through the file-system driver's cache. The setting of this bit determines whether file-system drivers should place data into the cache. Like the write-through bit, this is a per-handle bit, and is not inherited by child processes. 11 Reserved; must be 0. 10-8 The locality of reference flags contain information about how the application is to get access to the file. The values are as follows: 000 OPEN_FLAGS_NO_LOCALITY (0x00000000) No locality known. 001 OPEN_FLAGS_SEQUENTIAL (0x00000100) Mainly sequential access. 010 OPEN_FLAGS_RANDOM (0x00000200) Mainly random access. 011 OPEN_FLAGS_RANDOMSEQUENTIAL (0x00000300) Random with some locality. 7 OPEN_FLAGS_NOINHERIT (0x00000080) Inheritance flag: 0 File handle is inherited by a process created from a call to DosExecPgm. 1 File handle is private to the current process. This bit is not inherited by child processes. 6-4 Sharing Mode flags. This field defines any restrictions to file access placed by the caller on other processes. The values are as follows: 001 OPEN_SHARE_DENYREADWRITE (0x00000010) Deny read/write access. 010 OPEN_SHARE_DENYWRITE (0x00000020) Deny write access. 011 OPEN_SHARE_DENYREAD (0x00000030) Deny read access. 100 OPEN_SHARE_DENYNONE (0x00000040) Deny neither read nor write access (deny none). Any other value is invalid. 3 Reserved; must be 0. 2-0 Access-Mode flags. This field defines the file access required by the caller. The values are as follows: 000 OPEN_ACCESS_READONLY (0x00000000) Read-only access 001 OPEN_ACCESS_WRITEONLY (0x00000001) Write-only access 010 OPEN_ACCESS_READWRITE (0x00000002) Read/write access. Any other value is invalid, as are any other combinations. File Sharing File sharing requires the cooperation of sharing processes. This cooperation is communicated through sharing and access modes. Any sharing restrictions placed on a file opened by a process are removed when the process closes the file with a DosClose request. Sharing Mode Specifies the type of file access that other processes may have. For example, if other processes can continue to read the file while your process is operating on it, specify Deny Write. The sharing mode prevents other processes from writing to the file but still allows them to read it. Access Mode Specifies the type of file access (access mode) needed by your process. For example, if your process requires read/write access, and another process has already opened the file with a sharing mode of Deny None, your DosOpen request succeeds. However, if the file is open with a sharing mode of Deny Write, the process is denied access. If the file is inherited by a child process, all sharing and access restrictions also are inherited. If an open file handle is duplicated by a call to DosDupHandle, all sharing and access restrictions also are duplicated. Raw File System When a device is opened in the raw file system, the only valid access mode is OPEN_ACCESS_READWRITE. The valid sharing modes are: Mode Function OPEN_SHARE_DENYNONE Allows other processes to perform read and write operations to the device. OPEN_SHARE_DENYREADWRITE Locks device and prohibits access to device by other processes or file systems. All other flags are either invalid or not implemented in this release of OS/2. ═══ DosOpen Parameter - peaop2 ═══ peaop2 (PEAOP2) - in/out Extended attributes. This parameter is only used to specify extended attributes (EAs) when creating a new file, replacing an existing file, or truncating an existing file. It is ignored when used on a device. When opening existing files, it should be set to null. Input The address of the extended-attribute buffer, which contains an EAOP2 structure. fpFEA2List points to a data area where the relevant FEA2 list is to be found. fpGEA2List and oError are ignored. Output fpGEA2List and fpFEA2List are unchanged. The area that fpFEA2List points to is unchanged. If an error occurred during the set, oError is the offset of the FEA2 entry where the error occurred. The return code from DosOpen is the error code for that error condition. If no error occurred, oError is undefined. If peaop2 is zero, then no extended attributes are defined for the file. If extended attributes are not to be defined or modified, the pointer peaop2 must be set to zero. ═══ DosOpen Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosOpen returns one of the following values: 0 NO_ERROR 2 ERROR_FILE_NOT_FOUND 3 ERROR_PATH_NOT_FOUND 4 ERROR_TOO_MANY_OPEN_FILES 5 ERROR_ACCESS_DENIED 12 ERROR_INVALID_ACCESS 26 ERROR_NOT_DOS_DISK 32 ERROR_SHARING_VIOLATION 36 ERROR_SHARING_BUFFER_EXCEEDED 82 ERROR_CANNOT_MAKE 87 ERROR_INVALID_PARAMETER 99 ERROR_DEVICE_IN_USE 108 ERROR_DRIVE_LOCKED 110 ERROR_OPEN_FAILED 112 ERROR_DISK_FULL 206 ERROR_FILENAME_EXCED_RANGE 231 ERROR_PIPE_BUSY For a full list of error codes, see Errors. ═══ DosOpen - Parameters ═══ pszFileName (PSZ) - input Address of the ASCIIZ path name of the file or device to be opened. In the Raw File System, this is the universal naming convention (UNC) name for either a logical partition or physical disk. Logical partitions are identified using a UNC name in the form of: \\.\X:, where X is replaced with the letter corresponding to the drive. Physical disks are identified with a UNC name in the form of: \\.\Physical_Disk#, where # is replaced with the physical disk number as reported by the FDISK utility. pHf (PHFILE) - output Address of the handle for the file or device. pulAction (PULONG) - output Address of the variable that receives the value that specifies the action taken by the DosOpen function. If DosOpen fails, this value has no meaning. Otherwise, it is one of the following values: 1 FILE_EXISTED File already existed. This is always returned on the successful open of a device. 2 FILE_CREATED File was created. 3 FILE_TRUNCATED File existed and was changed to a given size (file was replaced). cbFile (ULONG) - input New logical size of the file (end of data, EOD), in bytes. This parameter is significant only when creating a new file or replacing an existing one. Otherwise, it is ignored. It is an error to create or replace a file with a nonzero length if the fsOpenMode Access-Mode flag is set to read-only. ulAttribute (ULONG) - input File attribute information. This parameter is significant only when manipulating a file, it is ignored on raw file system devices. Possible values are shown in the following list.: Bit Description 31-6 Reserved, must be 0. 5 FILE_ARCHIVED (0x00000020) File has been archived. 4 FILE_DIRECTORY (0x00000010) File is a subdirectory. 3 Reserved, must be 0. 2 FILE_SYSTEM (0x00000004) File is a system file. 1 FILE_HIDDEN (0x00000002) File is hidden and does not appear in a directory listing. 0 FILE_READONLY (0x00000001) File can be read from, but not written to. 0 FILE_NORMAL (0x00000000) File can be read from or written to. File attributes apply only if the file is created. These bits may be set individually or in combination. For example, an attribute value of 0x00000021 (bits 5 and 0 set to 1) indicates a read-only file that has been archived. fsOpenFlags (ULONG) - input The action to be taken depending on whether the file exists or does not exist. This parameter is not used in the raw file system. Possible values are shown in the following list: Bits Description 31-8 Reserved, must be 0. 7-4 The following flags apply if the file does not exist: 0000 OPEN_ACTION_FAIL_IF_NEW Open an existing file; fail if the file does not exist. 0001 OPEN_ACTION_CREATE_IF_NEW Create the file if the file does not exist. 3-0 The following flags apply if the file already exists: 0000 OPEN_ACTION_FAIL_IF_EXISTS Open the file; fail if the file already exists. 0001 OPEN_ACTION_OPEN_IF_EXISTS Open the file if it already exists. 0010 OPEN_ACTION_REPLACE_IF_EXISTS Replace the file if it already exists. fsOpenMode (ULONG) - input The mode of the open function. Possible values are shown in the following list: Bit Description 31-16 Reserved, must be zero. 15 OPEN_FLAGS_DASD (0x00008000) Direct Open flag: 0 pszFileName represents a file to be opened normally. 1 pszFileName is "drive:" (such as C: or A:), and represents a mounted disk or diskette volume to be opened for direct access. 14 OPEN_FLAGS_WRITE_THROUGH (0x00004000) Write-Through flag: 0 Writes to the file may go through the file-system driver's cache. The file-system driver writes the sectors when the cache is full or the file is closed. 1 Writes to the file may go through the file-system driver's cache, but the sectors are written (the actual file I/O operation is completed) before a synchronous write call returns. This state of the file defines it as a synchronous file. For synchronous files, this bit must be set, because the data must be written to the medium for synchronous write operations. This bit flag is not inherited by child processes. 13 OPEN_FLAGS_FAIL_ON_ERROR (0x00002000) Fail-Errors flag. Media I/O errors are handled as follows: 0 Reported through the system critical-error handler. 1 Reported directly to the caller by way of a return code. Media I/O errors generated through Category 08h Logical Disk Control IOCtl Commands always get reported directly to the caller by way of return code. The Fail-Errors function applies only to non-IOCtl handle-based file I/O calls. This flag bit is not inherited by child processes. 12 OPEN_FLAGS_NO_CACHE (0x00001000) No-Cache/Cache flag: 0 The file-system driver should place data from I/O operations into its cache. 1 I/O operations to the file need not be done through the file-system driver's cache. The setting of this bit determines whether file-system drivers should place data into the cache. Like the write-through bit, this is a per-handle bit, and is not inherited by child processes. 11 Reserved; must be 0. 10-8 The locality of reference flags contain information about how the application is to get access to the file. The values are as follows: 000 OPEN_FLAGS_NO_LOCALITY (0x00000000) No locality known. 001 OPEN_FLAGS_SEQUENTIAL (0x00000100) Mainly sequential access. 010 OPEN_FLAGS_RANDOM (0x00000200) Mainly random access. 011 OPEN_FLAGS_RANDOMSEQUENTIAL (0x00000300) Random with some locality. 7 OPEN_FLAGS_NOINHERIT (0x00000080) Inheritance flag: 0 File handle is inherited by a process created from a call to DosExecPgm. 1 File handle is private to the current process. This bit is not inherited by child processes. 6-4 Sharing Mode flags. This field defines any restrictions to file access placed by the caller on other processes. The values are as follows: 001 OPEN_SHARE_DENYREADWRITE (0x00000010) Deny read/write access. 010 OPEN_SHARE_DENYWRITE (0x00000020) Deny write access. 011 OPEN_SHARE_DENYREAD (0x00000030) Deny read access. 100 OPEN_SHARE_DENYNONE (0x00000040) Deny neither read nor write access (deny none). Any other value is invalid. 3 Reserved; must be 0. 2-0 Access-Mode flags. This field defines the file access required by the caller. The values are as follows: 000 OPEN_ACCESS_READONLY (0x00000000) Read-only access 001 OPEN_ACCESS_WRITEONLY (0x00000001) Write-only access 010 OPEN_ACCESS_READWRITE (0x00000002) Read/write access. Any other value is invalid, as are any other combinations. File Sharing File sharing requires the cooperation of sharing processes. This cooperation is communicated through sharing and access modes. Any sharing restrictions placed on a file opened by a process are removed when the process closes the file with a DosClose request. Sharing Mode Specifies the type of file access that other processes may have. For example, if other processes can continue to read the file while your process is operating on it, specify Deny Write. The sharing mode prevents other processes from writing to the file but still allows them to read it. Access Mode Specifies the type of file access (access mode) needed by your process. For example, if your process requires read/write access, and another process has already opened the file with a sharing mode of Deny None, your DosOpen request succeeds. However, if the file is open with a sharing mode of Deny Write, the process is denied access. If the file is inherited by a child process, all sharing and access restrictions also are inherited. If an open file handle is duplicated by a call to DosDupHandle, all sharing and access restrictions also are duplicated. Raw File System When a device is opened in the raw file system, the only valid access mode is OPEN_ACCESS_READWRITE. The valid sharing modes are: Mode Function OPEN_SHARE_DENYNONE Allows other processes to perform read and write operations to the device. OPEN_SHARE_DENYREADWRITE Locks device and prohibits access to device by other processes or file systems. All other flags are either invalid or not implemented in this release of OS/2. peaop2 (PEAOP2) - in/out Extended attributes. This parameter is only used to specify extended attributes (EAs) when creating a new file, replacing an existing file, or truncating an existing file. It is ignored when used on a device. When opening existing files, it should be set to null. Input The address of the extended-attribute buffer, which contains an EAOP2 structure. fpFEA2List points to a data area where the relevant FEA2 list is to be found. fpGEA2List and oError are ignored. Output fpGEA2List and fpFEA2List are unchanged. The area that fpFEA2List points to is unchanged. If an error occurred during the set, oError is the offset of the FEA2 entry where the error occurred. The return code from DosOpen is the error code for that error condition. If no error occurred, oError is undefined. If peaop2 is zero, then no extended attributes are defined for the file. If extended attributes are not to be defined or modified, the pointer peaop2 must be set to zero. ulrc (APIRET) - returns Return Code. DosOpen returns one of the following values: 0 NO_ERROR 2 ERROR_FILE_NOT_FOUND 3 ERROR_PATH_NOT_FOUND 4 ERROR_TOO_MANY_OPEN_FILES 5 ERROR_ACCESS_DENIED 12 ERROR_INVALID_ACCESS 26 ERROR_NOT_DOS_DISK 32 ERROR_SHARING_VIOLATION 36 ERROR_SHARING_BUFFER_EXCEEDED 82 ERROR_CANNOT_MAKE 87 ERROR_INVALID_PARAMETER 99 ERROR_DEVICE_IN_USE 108 ERROR_DRIVE_LOCKED 110 ERROR_OPEN_FAILED 112 ERROR_DISK_FULL 206 ERROR_FILENAME_EXCED_RANGE 231 ERROR_PIPE_BUSY For a full list of error codes, see Errors. ═══ DosOpen - Remarks ═══ A successful DosOpen request returns a handle for accessing the file or device. The read/write pointer is set at the first byte of the file. The position of the pointer can be changed with DosSetFilePtr or by read and write operations on the file or device. A file's date and time can be queried with DosQueryFileInfo. They are set with DosSetFileInfo. The read-only attribute of a file can be set with the ATTRIB command. ulAttribute cannot be set to Volume Label. To set volume-label information, issue DosSetFSInfo with a logical drive number. Volume labels cannot be opened. cbFile affects the size of the file only when the file is new or a is replacement. If an existing file is opened, cbFile is ignored. To change the size of the existing file, issue DosSetFileSize. The value in cbFile is a recommended size. If the full size cannot be allocated, the open request may still succeed. The file system makes a reasonable attempt to allocate the new size in an area that is as nearly contiguous as possible on the medium. When the file size is extended, the values of the new bytes are undefined. The Direct Open bit provides direct access to an entire disk or diskette volume. It is not used with the raw file system. This mode of opening the volume that is currently on the drive returns a handle to the calling function; the handle represents the logical volume as a single file. The calling function specifies this handle with a DosDevIOCtl Category 8, DSK_LOCKDRIVE request to prevent other processes from accessing the logical volume. When you are finished using the logical volume, issue a DosDevIOCtl Category 8, DSK_UNLOCKDRIVE request to allow other processes to access the logical volume. The file-handle state bits can be set by DosOpen and DosSetFHState. An application can query the file-handle state bits, as well as the rest of the Open Mode field, by issuing DosQueryFHState. You can use an EAOP2 structure to set extended attributes in peaop2 when creating a file, replacing an existing file, or truncating an existing file. No extended attributes are set when an existing file is just opened. A replacement operation is logically equivalent to atomically deleting and re-creating the file. This means that any extended attributes associated with the file also are deleted before the file is re-created. When using the raw file system to access logical partitions and disk locking is required, use the following logic: 1. Lock the disk by passing the drive handle to DosDevIOCtl Category 8, DSK_LOCKDRIVE. 2. Perform designed I/O operations to the disk. 3. Unlock the disk using DosDevIOCtl Category 8, DSK_UNLOCKDRIVE. When using the raw file system to access a physical disk and disk locking is required, the OPEN_SHARE_DENYREADWRITE flag should be used. The disk will be automatically unlocked when a DosClose is done. ═══ DosOpen - Related Functions ═══ Related Functions  DosClose  DosDevIOCtl  DosDupHandle  DosQueryHType  DosSetFileInfo  DosSetFilePtr  DosSetFileSize  DosSetMaxFH  DosSetRelMaxFH ═══ DosOpen - Example Code ═══ This example reads to a physical disk using the raw file system and DosListIO. #define INCL_ERRORS #define INCL_DOS #define INCL_NOPMAPI #include #include #include #include #include #include "listio.h" #define EightK 8*1024 #define FourK 4*1024 #define LISTIO_NUM 1000 #define PAGE_RAND_MAX 100 CHAR Buf[EightK]; LISTIO ListIO[LISTIO_NUM]; ULONG seed = 1; ULONG page_rand(void); int main (VOID) { CHAR *BufAligned; ULONG rc; ULONG Loop = LISTIO_NUM, i, j; ULONG Action, Actual; HFILE hFile; /* Make sure buffer is page aligned */ BufAligned = (UCHAR *)(((LONG)Buf + FourK) & 0xFFFFF000); /* Open a raw file system disk */ rc = DosOpen((PSZ)"\\\\.\\Physical_Disk2", &hFile, &Action, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, 0L); if (rc != NO_ERROR) { printf("DosOpen error: rc = %u\n", rc); return(1); } /* if */ /*************************************/ /* Perform Random READ using DosRead */ /*************************************/ for(i = 0; i < Loop ; i++) { /* Loop for Random Read */ rc = DosSetFilePtr(hFile, /* file's handle */ page_rand()*FourK, /* offset */ FILE_BEGIN, /* from beginning of file */ &Actual); if (rc != NO_ERROR) { printf("DosSetFilePtr error: rc = %u\n", rc); return(1); } /* if */ rc = DosRead( hFile, /* file's handle */ BufAligned, /* buffer pointer */ FourK, /* size to read */ &Actual); if (rc != NO_ERROR) { printf("DosRead error: rc = %u\n", rc); return(1); } /* if */ } /* for i */ /****************************************/ /* Perform Random Read using DosListIO */ /****************************************/ for (i = 0; i < Loop; i++) { ListIO[i].hFile = hFile; ListIO[i].CmdFlag = LISTIO_READ | FILE_BEGIN; ListIO[i].Offset = page_rand()*FourK; ListIO[i].pBuffer = BufAligned; ListIO[i].NumBytes = FourK; } /* for i */ rc = DosListIO( LISTIO_UNORDERED, /* unordered mode */ Loop, /* number of reads */ ListIO); /* array of control blocks */ if (rc != NO_ERROR) { printf("DosListIO error: rc = %u\n", rc); for (i = 0; i < Loop; i++) { if ((ListIO[i].Actual != FourK) || (ListIO[i].RetCode != NO_ERROR)) { printf("DosListIO error: i = %d, Actual = %d, RetCode = %u\n", I, ListIO[i].Actual, ListIO[i].RetCode); } /* if */ } /* for i */ return(1); } /* if */ /* Close file */ rc = DosClose(hFile); if (rc != NO_ERROR) { printf("DosClose error: rc = %u\n", rc); return(1); } return(NO_ERROR); } /********************************************************/ /* */ /* FUNCTION: page_rand */ /* */ /* DESCRIPTION: Generate random number in range */ /* [0,PAGE_RAND_MAX-1] */ /* */ /********************************************************/ ULONG page_rand() { seed = seed * 1103515245 + 12345; return(((ULONG)(seed/(2*PAGE_RAND_MAX)) % PAGE_RAND_MAX)); } ═══ DosOpen - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.6. DosPhysicalDisk ═══ ═══ DosPhysicalDisk - Syntax ═══ Obtains information about partitionable disks. #define INCL_DOSPROCESS #include ULONG function; /* The type of information to obtain about the partitionable disks. */ PVOID pBuf; /* The address of the buffer where the returned information is placed. */ ULONG cbBuf; /* The length, in bytes, of the data buffer. */ PVOID pParams; /* The address of the buffer used for input parameters. */ ULONG cbParams; /* The length, in bytes, of the parameter buffer. */ APIRET ulrc; /* Return Code. */ ulrc = DosPhysicalDisk(function, pBuf, cbBuf, pParams, cbParams); ═══ DosPhysicalDisk Parameter - function ═══ function (ULONG) - input The type of information to obtain about the partitionable disks. Possible values are shown in the following list: 1 INFO_COUNT_PARTITIONABLE_DISKS Obtain the total number of partitionable disks. 2 INFO_GETIOCTLHANDLE Obtain a handle to use with Category 09h Physical Disk Control IOCtl Commands. 3 INFO_FREEIOCTLHANDLE Release a handle for a partitionable disk. ═══ DosPhysicalDisk Parameter - pBuf ═══ pBuf (PVOID) - input The address of the buffer where the returned information is placed. The output data for each function is shown in the following list (all lengths are in bytes): ┌──────────┬──────────┬────────────────────────────────────────┐ │Function │DataLen │Returned Information │ ├──────────┼──────────┼────────────────────────────────────────┤ │ 1 │ 2 │Total number of partitionable disks in │ │ │ │the system (1-based). │ ├──────────┼──────────┼────────────────────────────────────────┤ │ 2 │ 2 │Handle for the specified partitionable │ │ │ │disk for the Category 09h Physical Disk │ │ │ │Control IOCtl Commands. │ ├──────────┼──────────┼────────────────────────────────────────┤ │ 3 │ 0 │None - pointer must be zero. │ └──────────┴──────────┴────────────────────────────────────────┘ ═══ DosPhysicalDisk Parameter - cbBuf ═══ cbBuf (ULONG) - input The length, in bytes, of the data buffer. ═══ DosPhysicalDisk Parameter - pParams ═══ pParams (PVOID) - input The address of the buffer used for input parameters. The input parameters required for each function are as follows (all lengths are in bytes): ┌──────────┬─────────────┬─────────────────────────────────────┐ │Function │ParmLen │Input Parameters │ ├──────────┼─────────────┼─────────────────────────────────────┤ │ 1 │ 0 │None - must be set to zero. │ ├──────────┼─────────────┼─────────────────────────────────────┤ │ 2 │string length│ASCIIZ string that specifies the │ │ │ │partitionable disk. │ ├──────────┼─────────────┼─────────────────────────────────────┤ │ 3 │ 2 │Handle obtained from Function 2. │ └──────────┴─────────────┴─────────────────────────────────────┘ The ASCIIZ string used to specify the partitionable disk must be of the following format: number : Where: number specifies the partitionable disk number (1-based) in ASCII. colon ( : ) must be present. is the byte of zero for the ASCIIZ string. ═══ DosPhysicalDisk Parameter - cbParams ═══ cbParams (ULONG) - input The length, in bytes, of the parameter buffer. ═══ DosPhysicalDisk Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosPhysicalDisk returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 87 ERROR_INVALID_PARAMETER For a full list of error codes, see Errors. ═══ DosPhysicalDisk - Parameters ═══ function (ULONG) - input The type of information to obtain about the partitionable disks. Possible values are shown in the following list: 1 INFO_COUNT_PARTITIONABLE_DISKS Obtain the total number of partitionable disks. 2 INFO_GETIOCTLHANDLE Obtain a handle to use with Category 09h Physical Disk Control IOCtl Commands. 3 INFO_FREEIOCTLHANDLE Release a handle for a partitionable disk. pBuf (PVOID) - input The address of the buffer where the returned information is placed. The output data for each function is shown in the following list (all lengths are in bytes): ┌──────────┬──────────┬────────────────────────────────────────┐ │Function │DataLen │Returned Information │ ├──────────┼──────────┼────────────────────────────────────────┤ │ 1 │ 2 │Total number of partitionable disks in │ │ │ │the system (1-based). │ ├──────────┼──────────┼────────────────────────────────────────┤ │ 2 │ 2 │Handle for the specified partitionable │ │ │ │disk for the Category 09h Physical Disk │ │ │ │Control IOCtl Commands. │ ├──────────┼──────────┼────────────────────────────────────────┤ │ 3 │ 0 │None - pointer must be zero. │ └──────────┴──────────┴────────────────────────────────────────┘ cbBuf (ULONG) - input The length, in bytes, of the data buffer. pParams (PVOID) - input The address of the buffer used for input parameters. The input parameters required for each function are as follows (all lengths are in bytes): ┌──────────┬─────────────┬─────────────────────────────────────┐ │Function │ParmLen │Input Parameters │ ├──────────┼─────────────┼─────────────────────────────────────┤ │ 1 │ 0 │None - must be set to zero. │ ├──────────┼─────────────┼─────────────────────────────────────┤ │ 2 │string length│ASCIIZ string that specifies the │ │ │ │partitionable disk. │ ├──────────┼─────────────┼─────────────────────────────────────┤ │ 3 │ 2 │Handle obtained from Function 2. │ └──────────┴─────────────┴─────────────────────────────────────┘ The ASCIIZ string used to specify the partitionable disk must be of the following format: number : Where: number specifies the partitionable disk number (1-based) in ASCII. colon ( : ) must be present. is the byte of zero for the ASCIIZ string. cbParams (ULONG) - input The length, in bytes, of the parameter buffer. ulrc (APIRET) - returns Return Code. DosPhysicalDisk returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 87 ERROR_INVALID_PARAMETER For a full list of error codes, see Errors. ═══ DosPhysicalDisk - Remarks ═══ DosPhysicalDisk obtains information about partitionable disks. The handle returned for the specified partitionable disk can only be used with the DosDevIOCtl function for the Category 09h Physical Disk Control IOCtl Commands. Use of the handle for a physical partitionable disk is not permitted for handle-based file system functions, such as DosRead or DosClose. ═══ DosPhysicalDisk - Related Functions ═══ Related Functions  DosBeep  DosDevConfig  DosDevIOCtl ═══ DosPhysicalDisk - Example Code ═══ This example obtains the total number of partitionable disks in the system. A partitionable disk is a physical disk drive that can be formatted into partitions. #define INCL_DOSDEVICES /* Device values */ #define INCL_DOSERRORS /* DOS error values */ #include #include int main (VOID) { USHORT usNumDrives = 0; /* Data return buffer */ ULONG ulDataLen = sizeof(USHORT); /* Data return buffer length */ APIRET rc = NO_ERROR; /* Return code */ /* Request a count of the number of partitionable disks in the system */ rc = DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &usNumDrives, ulDataLen, NULL, /* No parameter for this function */ 0L); if (rc != NO_ERROR) { printf("DosPhysicalDisk error: return code = %u\n", rc); return 1; } else { printf("DosPhysicalDisk: %u partitionable disk(s)\n",usNumDrives); } return NO_ERROR; } ═══ DosPhysicalDisk - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.7. DosRead ═══ ═══ DosRead - Syntax ═══ Reads the specified number of bytes from a file, pipe, or device to a buffer location. #define INCL_DOSFILEMGR #include HFILE hFile; /* File handle obtained from DosOpen. */ PVOID pBuffer; /* Address of the buffer to receive the bytes read. */ ULONG cbRead; /* The length, in bytes, of pBuffer. */ PULONG pcbActual; /* Address of the variable to receive the number of bytes actually read. */ APIRET ulrc; /* Return Code. */ ulrc = DosRead(hFile, pBuffer, cbRead, pcbActual); ═══ DosRead Parameter - hFile ═══ hFile (HFILE) - input File handle obtained from DosOpen. ═══ DosRead Parameter - pBuffer ═══ pBuffer (PVOID) - output Address of the buffer to receive the bytes read. ═══ DosRead Parameter - cbRead ═══ cbRead (ULONG) - input The length, in bytes, of pBuffer. This is the number of bytes to be read. A value of zero is treated as a null operation as is not considered an error. In the raw file system, this must be a multiple of the sector size (512). ═══ DosRead Parameter - pcbActual ═══ pcbActual (PULONG) - output Address of the variable to receive the number of bytes actually read. ═══ DosRead Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosRead returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE 26 ERROR_NOT_DOS_DISK 33 ERROR_LOCK_VIOLATION 87 ERROR_INVALID_PARAMETER 232 ERROR_NO_DATA 234 ERROR_MORE_DATA For a full list of error codes, see Errors. ═══ DosRead - Parameters ═══ hFile (HFILE) - input File handle obtained from DosOpen. pBuffer (PVOID) - output Address of the buffer to receive the bytes read. cbRead (ULONG) - input The length, in bytes, of pBuffer. This is the number of bytes to be read. A value of zero is treated as a null operation as is not considered an error. In the raw file system, this must be a multiple of the sector size (512). pcbActual (PULONG) - output Address of the variable to receive the number of bytes actually read. ulrc (APIRET) - returns Return Code. DosRead returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE 26 ERROR_NOT_DOS_DISK 33 ERROR_LOCK_VIOLATION 87 ERROR_INVALID_PARAMETER 232 ERROR_NO_DATA 234 ERROR_MORE_DATA For a full list of error codes, see Errors. ═══ DosRead - Remarks ═══ Note: When writing message pipes the application is limited to 64K messages. As well, these messages cannot span 64k boundaries due to the current design of the thunk layer in read or write routines. If the message is not written in an aligned manner, the subsequent read will not be able to handle the messages properly. If a 64k or less message is written to a pipe from an aligned buffer, the read will handle this properly. The requested number of bytes might not be read. If the value returned in pcbActual is zero, the process tried to read from the end of the file. The file pointer is moved to the desired position by reading data, writing data, or issuing DosSetFilePtr. If you issue DosOpen with the Direct Open flag set to 1 in the fsOpenFlags parameter, you have direct access to an entire disk or diskette volume, independent of the file system. You must lock the logical volume before accessing it, and you must unlock the logical volume when you are finished accessing it. Issue DosDevIOCtl for Category 8, DSK_LOCKDRIVE to lock the logical volume, and for Category 8, DSK_UNLOCKDRIVE to unlock the logical volume. While the logical volume is locked, no other process can access it. Raw File System Considerations Using the Raw File System on logical partitions requires you to lock and unlock the volume using the DosDevIOCtl Category 8, DSK_LOCKDRIVE and DSK_UNLOCKDRIVE. Reads and writes will not complete successfully until the logical drive is locked. The Raw File System requires that the number of bytes being read is a multiple of the sector size (512). Named Pipe Considerations A named pipe is read as one of the following:  A byte pipe in byte-read mode  A message pipe in message-read mode  A message pipe in byte-read mode. A byte pipe must be in byte-read mode to be read; an error is returned if it is in message-read mode. All currently available data, up to the size requested, is returned. A message pipe can be read in either message-read mode or byte-read mode. When the message pipe is in message-read mode, a read operation that is larger than the next available message returns only that message. pcbActual is set to indicate the size of the message returned. A read operation that is smaller than the next available message returns with the number of bytes requested and an ERROR_MORE_DATA return code. When the reading of a message is resumed after ERROR_MORE_DATA is returned, a read operation always blocks until the next piece (or the rest) of the message can be transferred. DosPeekNPipe can be issued to determine how many bytes are left in the message. A message pipe in byte-read mode is read as if it were a byte stream, and DosRead skips over message headers. This is like reading a byte pipe in byte-read mode. When blocking mode is set for a named pipe, a read operation blocks until data is available. In this case, the read operation never returns with pcbActual equal to zero, except when the pipe is closed. When the mode is set to message-read, messages are always read in their entirety, except when the message is bigger than the size of the read operation. pcbActual can equal zero in nonblocking mode, but only when no data is available at the time of the read operation. If you attempt a read of a named pipe when the other end of the pipe is closed while the read is pending, DosRead returns:  pcbActual equal to 0  ulrc equal to either 0 or ERROR_NO_DATA Unnamed Pipe Considerations Threads writing to and reading from the same unnamed pipe are not synchronized. It is possible for the pipe reader to obtain partial contents of a write request if the pipe becomes full during the write request. ═══ DosRead - Related Functions ═══ Related Functions  DosOpen  DosSetFilePtr  DosWrite ═══ DosRead - Example Code ═══ This example reads to a physical disk using the raw file system and DosListIO. #define INCL_ERRORS #define INCL_DOS #define INCL_NOPMAPI #include #include #include #include #include #include "listio.h" #define EightK 8*1024 #define FourK 4*1024 #define LISTIO_NUM 1000 #define PAGE_RAND_MAX 100 CHAR Buf[EightK]; LISTIO ListIO[LISTIO_NUM]; ULONG seed = 1; ULONG page_rand(void); int main (VOID) { CHAR *BufAligned; ULONG rc; ULONG Loop = LISTIO_NUM, i, j; ULONG Action, Actual; HFILE hFile; /* Make sure buffer is page aligned */ BufAligned = (UCHAR *)(((LONG)Buf + FourK) & 0xFFFFF000); /* Open a raw file system disk */ rc = DosOpen((PSZ)"\\\\.\\Physical_Disk2", &hFile, &Action, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, 0L); if (rc != NO_ERROR) { printf("ERROR:DosOpen rc = %d\n", rc); return(1); } /* if */ /*************************************/ /* Perform Random READ using DosRead */ /*************************************/ for(i = 0; i < Loop ; i++) { /* Loop for Random Read */ rc = DosSetFilePtr(hFile, /* file's handle */ page_rand()*FourK, /* offset */ FILE_BEGIN, /* from beginning of file */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosSetFilePtr rc = %d\n", rc); return(1); } /* if */ rc = DosRead( hFile, /* file's handle */ BufAligned, /* buffer pointer */ FourK, /* size to read */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosRead rc = %d\n", rc); return(1); } /* if */ } /* for i */ /****************************************/ /* Perform Random Read using DosListIO */ /****************************************/ for (i = 0; i < Loop; i++) { ListIO[i].hFile = hFile; ListIO[i].CmdFlag = LISTIO_READ | FILE_BEGIN; ListIO[i].Offset = page_rand()*FourK; ListIO[i].pBuffer = BufAligned; ListIO[i].NumBytes = FourK; } /* for i */ rc = DosListIO( LISTIO_UNORDERED, /* unordered mode */ Loop, /* number of reads */ ListIO); /* array of control blocks */ if (rc != NO_ERROR) { printf("ERROR:DosListIO rc = %d\n", rc); for (i = 0; i < Loop; i++) { if ((ListIO[i].Actual != FourK) || (ListIO[i].RetCode != NO_ERROR)) { printf("ERROR:DosListIO i = %d, Actual = %d, RetCode = %d\n", I, ListIO[i].Actual, ListIO[i].RetCode); } /* if */ } /* for i */ return(1); } /* if */ /* Close file */ rc = DosClose(hFile); if (rc != NO_ERROR) { printf("ERROR:DosClose rc = %d\n", rc); return(1); } return(NO_ERROR); } /********************************************************/ /* */ /* FUNCTION: page_rand */ /* */ /* DESCRIPTION: Generate random number in range */ /* [0,PAGE_RAND_MAX-1] */ /* */ /********************************************************/ ULONG page_rand() { seed = seed * 1103515245 + 12345; return(((ULONG)(seed/(2*PAGE_RAND_MAX)) % PAGE_RAND_MAX)); } ═══ DosRead - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.8. DosSetFilePtr ═══ ═══ DosSetFilePtr - Syntax ═══ Moves the read/write pointer according to the type of move specified. #define INCL_DOSFILEMGR #include HFILE hFile; /* The handle returned by a previous DosOpen function. */ LONG ib; /* The signed distance (offset) to move, in bytes. */ ULONG method; /* The method of moving. */ PULONG ibActual; /* Address of the new pointer location. */ APIRET ulrc; /* Return Code. */ ulrc = DosSetFilePtr(hFile, ib, method, ibActual); ═══ DosSetFilePtr Parameter - hFile ═══ hFile (HFILE) - input The handle returned by a previous DosOpen function. ═══ DosSetFilePtr Parameter - ib ═══ ib (LONG) - input The signed distance (offset) to move, in bytes. In the Raw File System, this offset must be a multiple of the sector size, which is 512. ═══ DosSetFilePtr Parameter - method ═══ method (ULONG) - input The method of moving. Specifies a location in the file from where the ib to move the read/write pointer starts. The values and their meanings are described in the following list: 0 FILE_BEGIN Move the pointer from the beginning of the file. 1 FILE_CURRENT Move the pointer from the current location of the read/write pointer. 2 FILE_END Move the pointer from the end of the file. Use this method to determine a file's size. 2 FILE_SECTOR Indicates that the value specified for ib is in sectors rather than bytes. This permits access to disks up to 1 TB (terabyte) in size. This flag must be ORed with either FILE_BEGIN, FILE_CURRENT, or FILE_END and is only valid when using the raw file system. ═══ DosSetFilePtr Parameter - ibActual ═══ ibActual (PULONG) - output Address of the new pointer location. ═══ DosSetFilePtr Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosSetFilePtr returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 25 ERROR_SEEK 130 ERROR_DIRECT_ACCESS_HANDLE 131 ERROR_NEGATIVE_SEEK 132 ERROR_SEEK_ON_DEVICE For a full list of error codes, see Errors. ═══ DosSetFilePtr - Parameters ═══ hFile (HFILE) - input The handle returned by a previous DosOpen function. ib (LONG) - input The signed distance (offset) to move, in bytes. In the Raw File System, this offset must be a multiple of the sector size, which is 512. method (ULONG) - input The method of moving. Specifies a location in the file from where the ib to move the read/write pointer starts. The values and their meanings are described in the following list: 0 FILE_BEGIN Move the pointer from the beginning of the file. 1 FILE_CURRENT Move the pointer from the current location of the read/write pointer. 2 FILE_END Move the pointer from the end of the file. Use this method to determine a file's size. 2 FILE_SECTOR Indicates that the value specified for ib is in sectors rather than bytes. This permits access to disks up to 1 TB (terabyte) in size. This flag must be ORed with either FILE_BEGIN, FILE_CURRENT, or FILE_END and is only valid when using the raw file system. ibActual (PULONG) - output Address of the new pointer location. ulrc (APIRET) - returns Return Code. DosSetFilePtr returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 25 ERROR_SEEK 130 ERROR_DIRECT_ACCESS_HANDLE 131 ERROR_NEGATIVE_SEEK 132 ERROR_SEEK_ON_DEVICE For a full list of error codes, see Errors. ═══ DosSetFilePtr - Remarks ═══ The read/write pointer in a file is a signed 32-bit number. A negative value for ib moves the pointer backward in the file; a positive value moves it forward. DosSetFilePtr cannot be used to move to a negative position in the file. The signed 32-bit value of the read/write pointer limits raw file system access to the first 2GB of a disk unless the FILE_SECTOR option is specified. FILE_SECTOR indicates that the 32-bit value is in sectors rather than bytes, which allows access to up to 1TB. DosSetFilePtr cannot be used for a character device or pipe. ═══ DosSetFilePtr - Related Functions ═══ Related Functions  DosOpen  DosRead  DosSetFileSize  DosWrite ═══ DosSetFilePtr - Example Code ═══ This example reads to a physical disk using the raw file system and DosListIO. #define INCL_ERRORS #define INCL_DOS #define INCL_NOPMAPI #include #include #include #include #include #include "listio.h" #define EightK 8*1024 #define FourK 4*1024 #define LISTIO_NUM 1000 #define PAGE_RAND_MAX 100 CHAR Buf[EightK]; LISTIO ListIO[LISTIO_NUM]; ULONG seed = 1; ULONG page_rand(void); int main (VOID) { CHAR *BufAligned; ULONG rc; ULONG Loop = LISTIO_NUM, i, j; ULONG Action, Actual; HFILE hFile; /* Make sure buffer is page aligned */ BufAligned = (UCHAR *)(((LONG)Buf + FourK) & 0xFFFFF000); /* Open a raw file system disk */ rc = DosOpen((PSZ)"\\\\.\\Physical_Disk2", &hFile, &Action, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, 0L); if (rc != NO_ERROR) { printf("ERROR:DosOpen rc = %d\n", rc); return(1); } /* if */ /*************************************/ /* Perform Random READ using DosRead */ /*************************************/ for(i = 0; i < Loop ; i++) { /* Loop for Random Read */ rc = DosSetFilePtr(hFile, /* file's handle */ page_rand()*FourK, /* offset */ FILE_BEGIN, /* from beginning of file */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosSetFilePtr rc = %d\n", rc); return(1); } /* if */ rc = DosRead( hFile, /* file's handle */ BufAligned, /* buffer pointer */ FourK, /* size to read */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosRead rc = %d\n", rc); return(1); } /* if */ } /* for i */ /****************************************/ /* Perform Random Read using DosListIO */ /****************************************/ for (i = 0; i < Loop; i++) { ListIO[i].hFile = hFile; ListIO[i].CmdFlag = LISTIO_READ | FILE_BEGIN; ListIO[i].Offset = page_rand()*FourK; ListIO[i].pBuffer = BufAligned; ListIO[i].NumBytes = FourK; } /* for i */ rc = DosListIO( LISTIO_UNORDERED, /* unordered mode */ Loop, /* number of reads */ ListIO); /* array of control blocks */ if (rc != NO_ERROR) { printf("ERROR:DosListIO rc = %d\n", rc); for (i = 0; i < Loop; i++) { if ((ListIO[i].Actual != FourK) || (ListIO[i].RetCode != NO_ERROR)) { printf("ERROR:DosListIO i = %d, Actual = %d, RetCode = %d\n", I, ListIO[i].Actual, ListIO[i].RetCode); } /* if */ } /* for i */ return(1); } /* if */ /* Close file */ rc = DosClose(hFile); if (rc != NO_ERROR) { printf("ERROR:DosClose rc = %d\n", rc); return(1); } return(NO_ERROR); } /********************************************************/ /* */ /* FUNCTION: page_rand */ /* */ /* DESCRIPTION: Generate random number in range */ /* [0,PAGE_RAND_MAX-1] */ /* */ /********************************************************/ ULONG page_rand() { seed = seed * 1103515245 + 12345; return(((ULONG)(seed/(2*PAGE_RAND_MAX)) % PAGE_RAND_MAX)); } ═══ DosSetFilePtr - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 5.9. DosWrite ═══ ═══ DosWrite - Syntax ═══ Writes a specified number of bytes from a buffer to the specified file. #define INCL_DOSFILEMGR #include HFILE hFile; /* File handle from DosOpen. */ PVOID pBuffer; /* Address of the buffer that contains the data to write. */ ULONG cbWrite; /* Number of bytes to write. */ PULONG pcbActual; /* Address of the variable to receive the number of bytes actually written. */ APIRET ulrc; /* Return Code. */ ulrc = DosWrite(hFile, pBuffer, cbWrite, pcbActual); ═══ DosWrite Parameter - hFile ═══ hFile (HFILE) - input File handle from DosOpen. ═══ DosWrite Parameter - pBuffer ═══ pBuffer (PVOID) - input Address of the buffer that contains the data to write. ═══ DosWrite Parameter - cbWrite ═══ cbWrite (ULONG) - input Number of bytes to write. If data is being written using the Raw File System, the number of bytes specified must be a multiple of the sector size (512). ═══ DosWrite Parameter - pcbActual ═══ pcbActual (PULONG) - output Address of the variable to receive the number of bytes actually written. ═══ DosWrite Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosWrite returns one of the following values: 0 NO_ERROR 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE 19 ERROR_WRITE_PROTECT 26 ERROR_NOT_DOS_DISK 29 ERROR_WRITE_FAULT 33 ERROR_LOCK_VIOLATION 109 ERROR_BROKEN_PIPE 112 ERROR_DISK_FULL 157 ERROR_DISCARDED For a full list of error codes, see Errors. ═══ DosWrite - Parameters ═══ hFile (HFILE) - input File handle from DosOpen. pBuffer (PVOID) - input Address of the buffer that contains the data to write. cbWrite (ULONG) - input Number of bytes to write. If data is being written using the Raw File System, the number of bytes specified must be a multiple of the sector size (512). pcbActual (PULONG) - output Address of the variable to receive the number of bytes actually written. ulrc (APIRET) - returns Return Code. DosWrite returns one of the following values: 0 NO_ERROR 5 ERROR_ACCESS_DENIED 6 ERROR_INVALID_HANDLE 19 ERROR_WRITE_PROTECT 26 ERROR_NOT_DOS_DISK 29 ERROR_WRITE_FAULT 33 ERROR_LOCK_VIOLATION 109 ERROR_BROKEN_PIPE 112 ERROR_DISK_FULL 157 ERROR_DISCARDED For a full list of error codes, see Errors. ═══ DosWrite - Remarks ═══ Note: When writing message pipes the application is limited to 64K messages. As well, these messages cannot span 64k boundaries due to the current design of the thunk layer in read or write routines. If the message is not written in an aligned manner, the subsequent read will not be able to handle the messages properly. If a 64k or less message is written to a pipe from an aligned buffer, the read will handle this properly. DosWrite begins to write at the current file-pointer position. The file pointer is automatically moved by read and write operations. It can be moved to a desired position by issuing DosSetFilePtr. If the specified file has been opened using the write-through flag, DosWrite writes the data to the disk before returning. Upon return to the caller, pcbActual contains the number of bytes actually written. If there is not enough space on the disk or diskette to write all of the bytes specified by cbWrite then DosWrite does not write any bytes. Upon return to the caller, pcbActual contains zero. A value of zero for cbWrite is not considered an error. No data transfer occurs, and there is no effect on the file or the file pointer. If the file is read-only, the write operation to the file is not performed. If you issue DosOpen with the Direct Open flag set to 1 in the fsOpenMode parameter, you have direct access to an entire disk or diskette volume, independent of the file system. You must lock the logical volume before accessing it, and you must unlock the logical volume when you are finished accessing it. Issue DosDevIOCtl for Category 8, DSK_LOCKDRIVE to lock the logical volume, and for Category 8, DSK_UNLOCKDRIVE to unlock the logical volume. While the logical volume is locked, no other process can access it. Raw File System Considerations Using the raw file system on logical partitions requires you to lock and unlock the volume using DosDevIOCtl Category 8, DSK_LOCKDRIVE and DSK_UNLOCKDRIVE. Unless the logical drive is locked, write requests will fail. The raw file system requires that the number of bytes written be a multiple of the sector size (512). Named-Pipe Considerations DosWrite also is used to write bytes or messages to a named pipe. Each write operation to a message pipe writes a message whose size is the length of the write operation. DosWrite automatically encodes message lengths in the pipe, so applications need not encode this information in the buffer being written. Write operations in blocking mode always write all requested bytes before returning. In nonblocking mode, DosWrite returns either with all bytes written or none written. DosWrite returns with no bytes written when it would have to divide the message into blocks in order to complete the request. This can occur when there is not enough space left in the pipe, or when the pipe is currently being written to by another client. If this occurs, DosWrite returns immediately with a value of zero for pcbActual, indicating that no bytes were written. For a byte pipe, if the number of bytes to be written exceeds the space available in the pipe, DosWrite writes as many bytes as it can, and returns with the number of bytes actually written in pcbActual. An attempt to write to a pipe whose other end has been closed returns ERROR_BROKEN_PIPE or, if the other end was closed without reading all pending data, ERROR_DISCARDED. Clients of named pipes created with the NP_ACCESS_OUTBOUND access mode cannot use the DosWrite function. If the named pipe's client uses the DosWrite function, the function returns error code ERROR_ACCESS_DENIED. ═══ DosWrite - Related Functions ═══ Related Functions  DosOpen  DosRead  DosSetFilePtr ═══ DosWrite - Example Code ═══ This example reads to a physical disk using the raw file system and DosListIO. #define INCL_ERRORS #define INCL_DOS #define INCL_NOPMAPI #include #include #include #include #include #include "listio.h" #define EightK 8*1024 #define FourK 4*1024 #define LISTIO_NUM 1000 #define PAGE_RAND_MAX 100 CHAR Buf[EightK]; LISTIO ListIO[LISTIO_NUM]; ULONG seed = 1; ULONG page_rand(void); int main (VOID) { CHAR *BufAligned; ULONG rc; ULONG Loop = LISTIO_NUM, i, j; ULONG Action, Actual; HFILE hFile; /* Make sure buffer is page aligned */ BufAligned = (UCHAR *)(((LONG)Buf + FourK) & 0xFFFFF000); /* Open a raw file system disk */ rc = DosOpen((PSZ)"\\\\.\\Physical_Disk2", &hFile, &Action, 0L, FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, 0L); if (rc != NO_ERROR) { printf("ERROR:DosOpen rc = %d\n", rc); return(1); } /* if */ /*************************************/ /* Perform Random READ using DosRead */ /*************************************/ for(i = 0; i < Loop ; i++) { /* Loop for Random Read */ rc = DosSetFilePtr(hFile, /* file's handle */ page_rand()*FourK, /* offset */ FILE_BEGIN, /* from beginning of file */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosSetFilePtr rc = %d\n", rc); return(1); } /* if */ rc = DosRead( hFile, /* file's handle */ BufAligned, /* buffer pointer */ FourK, /* size to read */ &Actual); if (rc != NO_ERROR) { printf("ERROR:DosRead rc = %d\n", rc); return(1); } /* if */ } /* for i */ /****************************************/ /* Perform Random Read using DosListIO */ /****************************************/ for (i = 0; i < Loop; i++) { ListIO[i].hFile = hFile; ListIO[i].CmdFlag = LISTIO_READ | FILE_BEGIN; ListIO[i].Offset = page_rand()*FourK; ListIO[i].pBuffer = BufAligned; ListIO[i].NumBytes = FourK; } /* for i */ rc = DosListIO( LISTIO_UNORDERED, /* unordered mode */ Loop, /* number of reads */ ListIO); /* array of control blocks */ if (rc != NO_ERROR) { printf("ERROR:DosListIO rc = %d\n", rc); for (i = 0; i < Loop; i++) { if ((ListIO[i].Actual != FourK) || (ListIO[i].RetCode != NO_ERROR)) { printf("ERROR:DosListIO i = %d, Actual = %d, RetCode = %d\n", I, ListIO[i].Actual, ListIO[i].RetCode); } /* if */ } /* for i */ return(1); } /* if */ /* Close file */ rc = DosClose(hFile); if (rc != NO_ERROR) { printf("ERROR:DosClose rc = %d\n", rc); return(1); } return(NO_ERROR); } /********************************************************/ /* */ /* FUNCTION: page_rand */ /* */ /* DESCRIPTION: Generate random number in range */ /* [0,PAGE_RAND_MAX-1] */ /* */ /********************************************************/ ULONG page_rand() { seed = seed * 1103515245 + 12345; return(((ULONG)(seed/(2*PAGE_RAND_MAX)) % PAGE_RAND_MAX)); } ═══ DosWrite - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 6. Processor Management and Performance Functions ═══ OS/2 Warp Server for SMP provides a set of functions which allow application developers an efficient and uniform way to access system performance information and to monitor and change processor status. Some of these functions have a dependency on Intel Pentium or Pentium-Pro support. If a function cannot be provided because OS/2 is not running on an processor with the required features, a return code will indicate an attempt to use an unsupported function. The functions available for obtaining processor information are provided on the following screens. ═══ 6.1. DosGetProcessorStatus ═══ ═══ DosGetProcessorStatus - Syntax ═══ Get the status for a specific processor. #define INCL_DOSSPINLOCK #include ULONG ProcNum; /* Processor number. */ PULONG pStatus; /* Pointer to the status returned for the specified processor. */ APIRET ulrc; /* Return Code. */ ulrc = DosGetProcessorStatus(ProcNum, pStatus); ═══ DosGetProcessorStatus Parameter - ProcNum ═══ ProcNum (ULONG) - input Processor number. ═══ DosGetProcessorStatus Parameter - pStatus ═══ pStatus (PULONG) - output Pointer to the status returned for the specified processor. Pointer to the status returned for the specified processor. Valid values are: 0 Processor offline. 1 Processor online. ═══ DosGetProcessorStatus Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosGetProcessorStatus returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER For a full list of error codes, see Errors. ═══ DosGetProcessorStatus - Parameters ═══ ProcNum (ULONG) - input Processor number. pStatus (PULONG) - output Pointer to the status returned for the specified processor. Pointer to the status returned for the specified processor. Valid values are: 0 Processor offline. 1 Processor online. ulrc (APIRET) - returns Return Code. DosGetProcessorStatus returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER For a full list of error codes, see Errors. ═══ DosGetProcessorStatus - Remarks ═══ DosGetProcessorStatus returns the status for the processor specified. Processors are numbered from 1 to n. ═══ DosGetProcessorStatus - Related Functions ═══ Related Functions  DosPerfSysCall  DosSetProcessorStatus ═══ DosGetProcessorStatus - Example Code ═══ The following code example shows the use of DosGetProcessorStatus: #define INCL_BASE #define INCL_DOSSPINLOCK #define INCL_DOSERRORS #include #include #include int main(VOID) { ULONG ulProcNum = 0L; /* Processor number */ ULONG ulStatus = 0L; /* Processor status */ APIRET rc = NO_ERROR; /* Return code */ /* Determine status of processor 0 */ ulProcNum = 1L; /* Processors are numbered from 1 to n */ rc = DosGetProcessorStatus(ulProcNum, &ulStatus); if (rc != NO_ERROR) { printf("DosGetProcessorStatus failed: rc = %u\n", rc); return 1; } else { printf("Processor %u is %s.\n", ulProcNum, (ulStatus ? "OFFLINE" : "ONLINE")); } /* endif */ return NO_ERROR; } ═══ DosGetProcessorStatus - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 6.2. DosPerfSysCall ═══ ═══ DosPerfSysCall - Syntax ═══ Retrieve system performance information and perform software tracing. #define INCL_BASE #include ULONG ulCommand; /* Command */ ULONG ulParm1; /* Command specific parameter 1 */ ULONG ulParm2; /* Command specific parameter 2 */ ULONG ulParm3; /* Command specific parameter 3 */ APIRET ulrc; /* Return Code. */ ulrc = DosPerfSysCall(ulCommand, ulParm1, ulParm2, ulParm3); ═══ DosPerfSysCall Parameter - ulCommand ═══ ulCommand (ULONG) - input Command DosPerfSysCall accepts the following commands: CMD_KI_RDCNT (0x63) Read CPU utilization information in both uniprocessor and symmetric multi-processor (SMP) environments by taking a snapshot of the time stamp counters. To determine CPU utilization, the application must compute the difference between two time stamp snapshots using 64-bit arithmetic. See the example code for details. CMD_SOFTTRACE_LOG (0x14) Record software trace information. ═══ DosPerfSysCall Parameter - ulParm1 ═══ ulParm1 (ULONG) - in/out Command specific parameter 1 Parameter usage depends on the command specified: CMD_KI_RDCNT Pointer to an array of CPUUTIL structures, with one entry for each processor. On a 4-way SMP machine, the array definition would be: CPUUTIL CPUUtil[4]; /* For processor IDs 0, 1, 2, and 3 */ since processor numbers and arrays are both 0-based. ulParm1 would be set to the address of CPUUtil[0]. ulParm2 and ulParm3 are not used and should be set to zero. CMD_SOFTTRACE_LOG Major code for the trace entry in the range of 0 to 255. Major codes 184 (0x00b8) and 185 (0x00b9) have been reserved for customer use. Major code 1 is reserved for exclusive use by IBM. ═══ DosPerfSysCall Parameter - ulParm2 ═══ ulParm2 (ULONG) - in/out Command specific parameter 2 Parameter usage depends on the command specified: CMD_KI_RDCNT 0 (reserved) CMD_SOFTTRACE_LOG Minor code for the trace entry in the range of 0 to 255. ═══ DosPerfSysCall Parameter - ulParm3 ═══ ulParm3 (ULONG) - in/out Command specific parameter 3 Parameter usage depends on the command specified: CMD_KI_RDCNT 0 (reserved) CMD_SOFTTRACE_LOG Pointer to a HOOKDATA data structure. ═══ DosPerfSysCall Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosPerfSysCall returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION For a full list of error codes, see Errors. ═══ DosPerfSysCall - Parameters ═══ ulCommand (ULONG) - input Command DosPerfSysCall accepts the following commands: CMD_KI_RDCNT (0x63) Read CPU utilization information in both uniprocessor and symmetric multi-processor (SMP) environments by taking a snapshot of the time stamp counters. To determine CPU utilization, the application must compute the difference between two time stamp snapshots using 64-bit arithmetic. See the example code for details. CMD_SOFTTRACE_LOG (0x14) Record software trace information. ulParm1 (ULONG) - in/out Command specific parameter 1 Parameter usage depends on the command specified: CMD_KI_RDCNT Pointer to an array of CPUUTIL structures, with one entry for each processor. On a 4-way SMP machine, the array definition would be: CPUUTIL CPUUtil[4]; /* For processor IDs 0, 1, 2, and 3 */ since processor numbers and arrays are both 0-based. ulParm1 would be set to the address of CPUUtil[0]. ulParm2 and ulParm3 are not used and should be set to zero. CMD_SOFTTRACE_LOG Major code for the trace entry in the range of 0 to 255. Major codes 184 (0x00b8) and 185 (0x00b9) have been reserved for customer use. Major code 1 is reserved for exclusive use by IBM. ulParm2 (ULONG) - in/out Command specific parameter 2 Parameter usage depends on the command specified: CMD_KI_RDCNT 0 (reserved) CMD_SOFTTRACE_LOG Minor code for the trace entry in the range of 0 to 255. ulParm3 (ULONG) - in/out Command specific parameter 3 Parameter usage depends on the command specified: CMD_KI_RDCNT 0 (reserved) CMD_SOFTTRACE_LOG Pointer to a HOOKDATA data structure. ulrc (APIRET) - returns Return Code. DosPerfSysCall returns one of the following values: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION For a full list of error codes, see Errors. ═══ DosPerfSysCall - Remarks ═══ DosPerfSysCall is a general purpose performance function. This function accepts four parameters. The first parameter is the command requested. The other three parameters are command specific. DosPerfSysCall is intended to be extended by IBM in the future for other performance related functions. Some functions of DosPerfSysCall may have a dependency on Intel Pentium or Pentium-Pro support. If a function cannot be provided because OS/2 is not running on an processor with the required features, a return code will indicate an attempt to use an unsupported function. The perfutil.h file referenced in the example code may or may not be shipped as part of the Toolkit. In the event that it is not, its contents are: #ifdef __cplusplus extern "C" { #endif #ifndef PERFCALL_INCLUDED #define PERFCALL_INCLUDED /* DosPerfSysCall Function Prototype */ /* The ordinal for DosPerfSysCall (in BSEORD.H) */ /* is defined as ORD_DOS32PERFSYSCALL */ APIRET APIENTRY DosPerfSysCall(ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3); /*** * * Software Tracing * ---------------- * **/ #define CMD_SOFTTRACE_LOG (0x14) typedef struct _HookData { ULONG ulLength; PBYTE pData; } HOOKDATA; typedef HOOKDATA * PHOOKDATA; /*** * * CPU Utilization * --------------- * **/ #define CMD_KI_RDCNT (0x63) typedef struct _CPUUTIL { ULONG ulTimeLow; /* Low 32 bits of time stamp */ ULONG ulTimeHigh; /* High 32 bits of time stamp */ ULONG ulIdleLow; /* Low 32 bits of idle time */ ULONG ulIdleHigh; /* High 32 bits of idle time */ ULONG ulBusyLow; /* Low 32 bits of busy time */ ULONG ulBusyHigh; /* High 32 bits of busy time */ ULONG ulIntrLow; /* Low 32 bits of interrupt time */ ULONG ulIntrHigh; /* High 32 bits of interrupt time */ } CPUUTIL; typedef CPUUTIL *PCPUUTIL; #ifdef __cplusplus } #endif It may also be necessary to define the ordinal for this function: #define ORD_DOS32PERFSYSCALL 976 ═══ DosPerfSysCall - Related Functions ═══ Related Functions  DosGetProcessorStatus  DosSetProcessorStatus ═══ DosPerfSysCall - Example Code ═══ This example uses DosPerfSysCall to obtain CPU Utilization information on a uniprocessor. #define INCL_BASE #include #include #include #include #include /* Convert 8-byte (low, high) time value to double */ #define LL2F(high, low) (4294967296.0*(high)+(low)) /* This is a 1 processor example */ void main (int argc, char *argv[]) { APIRET rc; int i, iter, sleep_sec; double ts_val, ts_val_prev; double idle_val, idle_val_prev; double busy_val, busy_val_prev; double intr_val, intr_val_prev; CPUUTIL CPUUtil; if ((argc < 2) || (*argv[1] < '1') || (*argv[1] > '9')) { fprintf(stderr, "usage: %s [1-9]\n", argv[0]); exit(0); } sleep_sec = *argv[1] - '0'; iter = 0; do { rc = DosPerfSysCall(CMD_KI_RDCNT,(ULONG) &CPUUtil,0,0); if (rc) { fprintf(stderr, "CMD_KI_RDCNT failed rc = %d\n",rc); exit(1); } ts_val = LL2F(CPUUtil.ulTimeHigh, CPUUtil.ulTimeLow); idle_val = LL2F(CPUUtil.ulIdleHigh, CPUUtil.ulIdleLow); busy_val = LL2F(CPUUtil.ulBusyHigh, CPUUtil.ulBusyLow); intr_val = LL2F(CPUUtil.ulIntrHigh, CPUUtil.ulIntrLow); if (iter > 0) { double ts_delta = ts_val - ts_val_prev; printf("idle: %4.2f%% busy: %4.2f%% intr: %4.2f%%\n", (idle_val - idle_val_prev)/ts_delta*100.0, (busy_val - busy_val_prev)/ts_delta*100.0, (intr_val - intr_val_prev)/ts_delta*100.0); } ts_val_prev = ts_val; idle_val_prev = idle_val; busy_val_prev = busy_val; intr_val_prev = intr_val; iter++; DosSleep(1000*sleep_sec); } while (1); } This example performs software tracing from a program in ring 3. #define INCL_BASE #include #include #include #include #include int main ( int argc, char *argv[] ) { APIRET rc; BYTE HookBuffer[256]; HOOKDATA HookData = {0,HookBuffer}; ULONG ulMajor, ulMinor; /* Log 3 ULONG values (1, 2, and 3) and a string. */ *((PULONG)&HookBuffer[0]) = 1; *((PULONG)&HookBuffer[4]) = 2; *((PULONG)&HookBuffer[8]) = 3; strcpy((PSZ)&HookBuffer[12], "Test of 3 ULONG values and a string.") HookData.ulLength = 12 + strlen((PSZ)&HookBuffer[12]) + 1; ulMajor = 0x00b8; /* Hook major code */ ulMinor = 0x0001; /* Hook minor code */ rc = DosPerfSysCall( CMD_SOFTTRACE_LOG, ulMajor, ulMinor, (ULONG) &HookData); if (rc != NO_ERROR) { fprintf(stderr, "CMD_SOFTTRACE_LOG failed: rc = %u\n", rc); return 1; } return NO_ERROR; } ═══ DosPerfSysCall - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 6.3. DosQuerySysInfo ═══ ═══ DosQuerySysInfo - Syntax ═══ Returns values of static system variables. #define INCL_DOSMISC #include ULONG iStart; /* Ordinal of the first system variable to return. */ ULONG iLast; /* Ordinal of the last system variable to return. */ PVOID pBuf; /* Address of the data buffer where the system returns the variable values. */ ULONG cbBuf; /* Length, in bytes, of the data buffer. */ APIRET ulrc; /* Return Code. */ ulrc = DosQuerySysInfo(iStart, iLast, pBuf, cbBuf); ═══ DosQuerySysInfo Parameter - iStart ═══ iStart (ULONG) - input Ordinal of the first system variable to return. ═══ DosQuerySysInfo Parameter - iLast ═══ iLast (ULONG) - input Ordinal of the last system variable to return. ═══ DosQuerySysInfo Parameter - pBuf ═══ pBuf (PVOID) - output Address of the data buffer where the system returns the variable values. ═══ DosQuerySysInfo Parameter - cbBuf ═══ cbBuf (ULONG) - input Length, in bytes, of the data buffer. ═══ DosQuerySysInfo Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosQuerySysInfo returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW For a full list of error codes, see Errors. ═══ DosQuerySysInfo - Parameters ═══ iStart (ULONG) - input Ordinal of the first system variable to return. iLast (ULONG) - input Ordinal of the last system variable to return. pBuf (PVOID) - output Address of the data buffer where the system returns the variable values. cbBuf (ULONG) - input Length, in bytes, of the data buffer. ulrc (APIRET) - returns Return Code. DosQuerySysInfo returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW For a full list of error codes, see Errors. ═══ DosQuerySysInfo - Remarks ═══ DosQuerySysInfo returns a single system variable or a range of system variables to a user-allocated buffer. To request a single system variable, set iStart equal to iLast. To request a range of system variables, set iStart less than iLast. Each system variable is a ULONG value. The following list gives the ordinal index, name, and description of the system variables. 1 QSV_MAX_PATH_LENGTH Maximum length, in bytes, of a path name. 2 QSV_MAX_TEXT_SESSIONS Maximum number of text sessions. 3 QSV_MAX_PM_SESSIONS Maximum number of PM sessions. 4 QSV_MAX_VDM_SESSIONS Maximum number of DOS sessions. 5 QSV_BOOT_DRIVE Drive from which the system was started (1 means drive A, 2 means drive B, and so on). 6 QSV_DYN_PRI_VARIATION Dynamic priority variation flag (0 means absolute priority, 1 means dynamic priority). 7 QSV_MAX_WAIT Maximum wait in seconds. 8 QSV_MIN_SLICE Minimum time slice in milliseconds. 9 QSV_MAX_SLICE Maximum time slice in milliseconds. 10 QSV_PAGE_SIZE Memory page size in bytes. This value is 4096 for the 80386 processor. 11 QSV_VERSION_MAJOR Major version number (see note below). 12 QSV_VERSION_MINOR Minor version number (see note below). 13 QSV_VERSION_REVISION Revision number (see note below). 14 QSV_MS_COUNT Value of a 32-bit, free-running millisecond counter. This value is zero when the system is started. 15 QSV_TIME_LOW Low-order 32 bits of the time in seconds since January 1, 1970 at 0:00:00. 16 QSV_TIME_HIGH High-order 32 bits of the time in seconds since January 1, 1970 at 0:00:00. 17 QSV_TOTPHYSMEM Total number of bytes of physical memory in the system. 18 QSV_TOTRESMEM Total number of bytes of resident memory in the system. 19 QSV_TOTAVAILMEM Maximum number of bytes of memory that can be allocated by all processes in the system. This number is advisory and is not guaranteed, since system conditions change constantly. 20 QSV_MAXPRMEM Maximum number of bytes of memory that this process can allocate in its private arena. This number is advisory and is not guaranteed, since system conditions change constantly. 21 QSV_MAXSHMEM Maximum number of bytes of memory that a process can allocate in the shared arena. This number is advisory and is not guaranteed, since system conditions change constantly. 22 QSV_TIMER_INTERVAL Timer interval in tenths of a millisecond. 23 QSV_MAX_COMP_LENGTH Maximum length, in bytes, of one component in a path name. 24 QSV_FOREGROUND_FS_SESSION Session ID of the current foreground full-screen session. Note that this only applies to full-screen sessions. The Presentation Manager session (which displays Vio-windowed, PM, and windowed DOS Sessions) is full-screen session ID 1. 25 QSV_FOREGROUND_PROCESS Process ID of the current foreground process. 26 QSV_NUMPROCESSORS Number of processors in the machine. 27 QSV_MAXHPRMEM Maximum amount of free space in the high private arena for this process. This number does not indicate the largest single memory object that can be allocated, since the arena is probably fragmented. 28 QSV_MAXHSHMEM Maximum amount of free space in the high shared arena for this process. This number does not indicate the largest single memory object that can be allocated, since the arena is probably fragmented. 29 QSV_MAXPROCESSES Maximum number of concurrent processes supported. 30 QSV_VIRTUALADDRESSLIMIT Size of the user's address space in MB. Note: Major, minor and revision numbers for versions of OS/2 operating system are described below: ┌──────────┬──────────┬──────────┬──────────┐ │ │Major │Minor │Revision │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 2.0 │20 │00 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 2.1 │20 │10 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 2.11 │20 │11 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 3.0 │20 │30 │0 │ ├──────────┼──────────┼──────────┼──────────┤ │OS/2 4.0 │20 │40 │0 │ └──────────┴──────────┴──────────┴──────────┘ An application can specify file objects managed by an installable file system that supports long file names. Because some installable file systems support longer names than others, the application should issue DosQuerySysInfo upon initialization. DosQuerySysInfo returns the maximum path length (QSV_MAX_PATH_LENGTH) supported by the installed file system. The path length includes the drive specifier (d:), the leading backslash ( \ ), and the trailing null character. The value returned by DosQuerySysInfo can be used to allocate buffers for path names returned by other functions. Since memory usage in the system changes constantly, the values returned by QSV_MAXHPRMEM and QSV_MAXHSMMEM should only be used as an indication of current memory usage. ═══ DosQuerySysInfo - Related Functions ═══ Related Functions  DosOpen  DosSetFSInfo ═══ DosQuerySysInfo - Example Code ═══ This example queries and displays the maximum length for a path name and the total amount of physical memory in bytes. #define INCL_DOSMISC /* DOS Miscellaneous values */ #define INCL_DOSERRORS /* DOS Error values */ #include #include int main(VOID) { ULONG aulSysInfo[QSV_MAX] = {0}; /* System Information Data Buffer */ APIRET rc = NO_ERROR; /* Return code */ rc = DosQuerySysInfo(1L, /* Request all available system */ QSV_MAX, /* information */ (PVOID)aulSysInfo, sizeof(ULONG)*QSV_MAX); if (rc != NO_ERROR) { printf("DosQuerySysInfo error: return code = %u\n", rc); return 1; } else { printf("Maximum length for a path name is %u characters.\n", aulSysInfo[QSV_MAX_PATH_LENGTH-1]); /* Max length of path name */ printf("Total physical memory is %u bytes.\n", aulSysInfo[QSV_TOTPHYSMEM-1]); /* Total physical memory */ } /* endif */ return NO_ERROR; } ═══ DosQuerySysInfo - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 6.4. DosSetProcessorStatus ═══ ═══ DosSetProcessorStatus - Syntax ═══ Set the status for a specific processor. #define INCL_DOSSPINLOCK #include ULONG ProcNum; /* Processor number. */ PULONG pStatus; /* Pointer to the status for the specified processor. */ APIRET ulrc; /* Return Code. */ ulrc = DosSetProcessorStatus(ProcNum, pStatus); ═══ DosSetProcessorStatus Parameter - ProcNum ═══ ProcNum (ULONG) - input Processor number. ═══ DosSetProcessorStatus Parameter - pStatus ═══ pStatus (PULONG) - input Pointer to the status for the specified processor. Pointer to the status to be set for the specified processor. The valid values are: 0 Take processor offline. 1 Bring processor online. ═══ DosSetProcessorStatus Return Value - ulrc ═══ ulrc (APIRET) - returns Return Code. DosSetProcessorStatus returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER For a full list of error codes, see Errors. ═══ DosSetProcessorStatus - Parameters ═══ ProcNum (ULONG) - input Processor number. pStatus (PULONG) - input Pointer to the status for the specified processor. Pointer to the status to be set for the specified processor. The valid values are: 0 Take processor offline. 1 Bring processor online. ulrc (APIRET) - returns Return Code. DosSetProcessorStatus returns one of the following values: 0 NO_ERROR 87 ERROR_INVALID_PARAMETER For a full list of error codes, see Errors. ═══ DosSetProcessorStatus - Remarks ═══ DosSetProcessorStatus sets the status for the processor specified. Processors are numbered from 1 to n. ═══ DosSetProcessorStatus - Related Functions ═══ Related Functions  DosGetProcessorStatus  DosPerfSysCall ═══ DosSetProcessorStatus - Example Code ═══ The following code example shows the use of DosSetProcessorStatus: #define INCL_BASE #define INCL_DOSSPINLOCK #define INCL_DOSERRORS #include #include #include int main(VOID) { ULONG ulProcNum = 0L; /* Processor number */ ULONG ulStatus = 0L; /* Processor status */ APIRET rc = NO_ERROR; /* Return code */ /* Take processor 1 offline */ ulProcNum = 2L; /* Processors are numbered 1 to n */ ulStatus = 0L; rc = DosSetProcessorStatus(ulProcNum, &ulStatus); if (rc != NO_ERROR) { printf("DosSetProcessorStatus failed: rc = %u\n", rc); return 1; } else { printf("Processor %u offline.\n", ulProcNum); } /* endif */ return NO_ERROR; } ═══ DosSetProcessorStatus - Topics ═══ Select an item: Syntax Parameters Returns Remarks Example Code Related Functions ═══ 7. Application Considerations ═══ The following sections discuss application considerations of OS/2 Warp Server for SMP. ═══ 7.1. Application Compatibility Requirements ═══ These compatibility requirements apply only to multithreaded applications, and therefore do not apply to DOS and WINOS2 applications. However, you are strongly encouraged to write 32-bit multithreaded applications for better performance and portability on OS/2 Warp Server for SMP.  An application or associated subsystem must not use the INC instruction as a semaphore without prepending a LOCK prefix. On a uniprocessor (UP) system this instruction can be used as high performance semaphore without calling any other operating system service if the semaphore is free and when the semaphore is clear and there are no waiters for the semaphore. Because the INC instruction can not be interrupted once started and because the results would be stored in the flags register which are per thread then it could be used safely as semaphore. In an OS/2 Warp Server for SMP environment this technique will not work because it is possible that two or more threads could be executing the same INC instruction receiving the same results in each processor's/thread's flag register thinking that they each have the semaphore.  Similarly a 486 or greater instruction such as the CMPXCHG has the same problem above if a LOCK prefix is not prepended before the instruction.  An application or associated subsystem which relies on priorities to guarantee execution of its threads within a process will not work in OS/2 Warp Server for SMP. For example an application may have a time-critical and an idle thread and may assume that while the time-critical thread is executing that the idle thread will not get any execution time unless the time-critical thread explicitly yields the CPU. In an OS/2 Warp Server for SMP environment it is possible that both the time-critical and idle threads are executing simultaneously on different processors. The above compatibility requirements apply only to multithreaded applications, and therefore do not apply to DOS and WINOS2 applications. However, you are strongly encouraged to write 32-bit multithreaded applications for better performance and portability on OS/2 Warp Server for SMP. Given that there is the possibility of some set of applications which may use one of these techniques, OS/2 Warp Server for SMP provides a mechanism whereby these multithreaded applications can execute in UP mode. Only one thread of that process would be allowed to execute at any given time. That thread could execute on any one of the processors. A utility is used to mark the EXE file as uniprocessor only. OS/2 forces the process to run in the uniprocessor mode when the loader detects that the EXE file has been marked as uniprocessor only. See View and Set Program Type For Executable File (MARKEXE). ═══ 8. Device Drivers In OS/2 Warp Server for SMP ═══ Existing device drivers run on OS/2 Warp Server for SMP without modification provided that they use the device helper (DevHlp) routines to access the interrupt controller. Device drivers which access the interrupt controller directly, or which mask and unmask interrupts directly through the controller, will need to be changed. ═══ 9. New Device Helper (DevHlp) Routines ═══ This chapter provides information on the new physical and virtual Device Helper (DevHlp) routines in OS/2 Warp Server for SMP. The OS/2 kernel provides the following new DevHlps: DevHlp_PerfSysTrace EQU 69 ; 45 Record data in STRACE buffer. DevHlp_SetIRQMask EQU 119 ; 77 Set/Unset an IRQ mask DevHlp_GetIRQMask EQU 120 ; 78 Get an IRQ mask ═══ 9.1. DevHlp_PerfSysTrace ═══ Description Record data to STRACE buffer. This function writes software trace information to the STRACE buffer. Parameters Major code Data length in bytes Minor code Data to be traced Exit Return code. Assembly language ; dh_PerfSysTrace - Record data to STRACE buffer. ; ; This routine records data in the STRACE buffer. ; ; ENTRY: AX = major code (0-255) ; BX = data length, in bytes (0-255) ; CX = minor code (0-255) ; DS:SI = pointer to data ; ; EXIT-NORMAL: AX = 0 SOFTWARE TRACE DATA AREA MODIFIED ; ; EXIT-ERROR: AX = ERROR CODE ; ; Uses C calling convention. See DevHlp_SysTrace for example. ; ; MOV AX,MajorCode ; major code for trace hook MOV BX,TraceSize ; size of data MOV CX,MinorCode ; minor code LDS SI,TraceData ; MOV DL,DevHlp_PerfSysTrace CALL DevHlp ═══ 9.2. DevHlp_SetIRQMask ═══ Description Enable/disable interrupt. This function enables and/or disables interrupts for a specific IRQ. Parameters Specified IRQ level. Enable/disable flag. Exit Return code. Assembly language ; dh_SetIRQMask - Masks/Unmasks a specified IRQ masks ; ; This function enables/disables interrupts for a specific IRQ. ; ; ENTRY AL = IRQ to be enabled/disabled ; AH = 0 enable IRQ (disable mask) ; 1 disable IRQ (enable mask) ; ; EXIT-SUCCESS ; none ; ; EXIT-FAILURE ; NONE ; MOV AL,IRQ to enable/disabled MOV AH,mask operation (0=enabled,1=disabled) MOV DL,DevHlp_SetIRQMask CALL DevHlp JC Error ═══ 9.3. DevHlp_GetIRQMask ═══ Description Retrieve the mask state of an IRQ level. This function reads the current IRQ mask state for the specified IRQ. Parameters Specified IRQ level. Exit EAX=0, mask disabled (IRQ enabled). EAX=1, mask enabled (IRQ disabled) Assembly language ; dh_GetIRQMask - Retrieve a specified IRQ mask state ; ; This function reads the current IRQ mask state for the specified IRQ. ; ; ENTRY AL = IRQ ; ; EXIT-SUCCESS ; EAX - 0 = mask disabled (IRQ enabled) ; - 1 = mask enabled (IRQ disabled) ; ; EXIT-FAILURE ; NONE ; MOV AL,IRQ whose mask state is to be retrieved MOV DL,DevHlp_GetIRQMask CALL DevHlp JC Error ═══ 9.4. Virtual Device Driver Helps ═══ The OS/2 kernel provides a new VDH service for VDDs to communicate with PSDs. ═══ 9.4.1. VDHPortIO ═══ Description Perform I/O to a specified port. This function is used to perform input/output operations to a specified local port. Parameters Pointer to a PORT_IO structure. Exit Return code. Structures typedef struct port_io_s { ulong_t port; (Input) ulong_t data; (Input/Output) ulong_t flags; (Input) } PORT_IO; port indicates which port to read to, or write from. data contains the data read from a read request, or the data to write if a write request. flags indicate what operation to perform. IO_READ_BYTE Read a byte from the port IO_READ_WORD Read a word from the port IO_READ_DWORD Read a dword from the port IO_WRITE_BYTE Write a byte to the port IO_WRITE_WORD Write a word to the port IO_WRITE_DWORD Write a dword to the port Notes None. ═══ 10. Kernel Debugger ═══ The Kernel Debugger is essentially a replacement OS/2 Kernel module that contains a built-in debugger component. The kernel debugger can be used to halt system execution, inspect and alter memory and registers, and display system control blocks. The kernel debugger is described in detail in The OS/2 Debugging Handbook - Volume II, IBM publication number SG24-4641. The kernel debugger architecture is such that only one thread can be in the debugger at any given time. The kernel debugger in OS/2 Warp Server for SMP serializes its access using a spinlock. When entered, the debugger informs the user of the state of all the processors, even though the other processors are still executing code. This is accomplished by sending a spin command via an interprocessor interrupt, or IPI, to all the other processors. When a processor receives the spin command, it saves its current state information, acknowledges receiving the command, and then spins. This allows the debugger to switch to a slot which is currently executing on another processor and determine what it is doing. ═══ 10.1. New and Changed Commands ═══ All kernel debugger commands work as before, but a few have been modified to display or use multiprocessor-specific information. New commands have also been added. The new and changed commands are: .DP (processor status) The .DP command has been added to dump out a processor control block verbosely, that is, to display a processor's status. The command takes as an argument: * Displays status based on the real current slot # Displays status based on the currently selected slot 0-based processor number Displays status for a specific processor. .DP 3 would display the status of processor 3. blank Displays the status of all processors. .DL (display processor spinlocks) The .DL command has been added to display the spinlocks owned by a particular processor. Valid arguments are: * Displays spinlocks based on the real current slot # Displays spinlocks based on the currently selected slot 0-based processor number Displays spinlocks for a specific processor. .DL 1 would display the spinlocks held on processor 1. Address of a spinlock Displays a specific spinlock. blank Displays all spinlocks. .DS Dumps the Inter-Processor Interrupt (IPI) statistics for each processor, including the IPI type and IPI delivery method. .DSH Dumps the IPI history, which is the last 256 IPIs generated in the system. The source, destination, and type of the IPI are displayed as well as the IPI delivery method and the address and symbol name where the IPI was generated. .PQ Dumps the scheduler's priority queues based on the debugger's slot number. .R and R (register commands) The register commands have been enhanced to indicate which processor the currently selected slot is running on. This information is displayed at the end of the third register line in the form p=xxyy where xx is the 1-based processor number, and yy are the flags. A processor number of 00 means that the currently selected slot is not running on any processor, or is blocked. The flags are: s processor is currently spinning. r processor is attempting to grab the ring 0 suspend lock. .SS (change current slot) The .SS command has been modified to reference the proper PSA (processor save area) when displaying a variable on a different processor. value of that variable on that particular processor). .S The .S command is now identical to the .SS command. The PLMA is displayed properly for each processor. ═══ 10.2. KDB Communications Protocol ═══ Generally the kernel debugger communicates over a serial communications link with a terminal emulator program running on another machine. This allows a user to debug a problem by issuing kernel debugger commands in the emulator program and seeing the results displayed on the debug console. To automate the debugging process, or to provide a high-level language debugging environment, this interaction with the kernel debugger could instead be handled by a program running on the other machine. This debug engine would interact with the user, convert the user's debugging request to a series of kernel debugger commands, issue them, and then present the response from the kernel debugger back to the user in a user-friendly format. Communications between the debug engine and the kernel debugger can proceed in one of two modes: raw (dumb TTY) mode ASCII characters are sent to the kernel debugger one at a time. The kernel debugger echoes each character. A carriage return (^M or 0x0d) ends a line. The kernel debugger returns data to the debug engine one ASCII character at a time. packet mode Packets are sent to the kernel debugger. A packet consists of a fixed sized header followed by zero or more bytes of data. The kernel debugger returns data to the debug engine in packets. ═══ 10.2.1. Raw Mode ═══ Any kernel debugger command may be sent in raw mode. Debug engines that communicate in packet mode may wish to use raw mode to issue a .B command to set the communication rate for the serial connection. To enter raw mode from packet mode, or to get the kernel debugger's attention while the system is running and enter raw mode, the debug engine should send a break character (^C or 0x03) and wait for the kernel debugger to issue a prompt. ═══ 10.2.2. Packet Mode ═══ To enter packet mode from raw mode, or to get the kernel debugger's attention while the system is running and enter packet mode, the debug engine should send the KDP break character (0x1f). If the system was running, the kernel debugger will respond with an event packet containing a CVK_RET_ASYNC event. If the system was quiesced, the kernel debugger will not respond at all. ═══ 10.2.2.1. Packet Format ═══ The format of a packet is as follows: ┌──────┬───────────────────────┬─────────...────────────┬──────┐ │ 0x1d │ 10-byte packet header │ packet body (optional) │ 0x1e │ └──────┴───────────────────────┴─────────...────────────┴──────┘ The packet header and the packet body, if present, are bitstuffed. The data is treated as a stream of bits and is broken into seven-bit chunks. Each chunk is put into the seven low-order bits of a byte and the high order bit of the byte is set. The bitstuffed data is padded at the end with zero bits to the next byte boundary. For example, the header 00009540 0000ac57 when bitstuffed becomes 808092d4 808081ac abc0. ═══ 10.2.2.2. Packet Header Format ═══ The header, prior to bitstuffing, contains a 4-byte logical ID field, a 2-byte length field, and a 2-byte checksum. The checksum of n bytes of data is computed as follows: unsigned char data[ ]; unsigned short checksum = 0xa1e8; for (i = 0; i < n; i++) { checksum += data[i]; checksum = (checksum << 3) + (checksum >> 13); } ═══ 10.2.2.3. Packet Data Format ═══ All multibyte items are presumed to appear in little-endian order. Thus, the checksum computed for the header 00009540 0000 is 0x57ac; when stored in the header the low order byte (0xac) appears first. The header length field contains the number of bytes of data in the packet body before the packet body is bitstuffed. If the header length field is zero, there is no packet body. If a packet body is present, it includes a 2-byte checksum that is not accounted for in the header length field. For example, if the header length field is 0x12, there are actually 20 bytes in the unbitstuffed packet body. The logical ID field takes one of the following forms (sequence numbers are one byte long): CVK_HDR_DATA - 0x8000 | 0x4000 if "flast" flag is set | ((index number & 0x3f) << 8) | sequence number CVK_HDR_ACK - (0x4000 | ((index number & 0x3f) << 8) | sequence number) << 16 CVK_HDR_NACK- (0xc000 | ((index number & 0x3f) << 8) | sequence number) << 16 ═══ 10.2.2.4. Maximum Packet Size ═══ The maximum packet size for a bitstuffed packet is defined by CVK_PACKET_MAXSIZE as 623. This is derived by: Start byte 1 Header 10 Data 611 End Byte 1 ═══ 10.2.3. General Considerations ═══ The debug engine initiates all transactions with the kernel debugger, normally by sending a command while the kernel debugger is waiting to receive one. In this case, the kernel debugger expects to receive a CVK_HDR_DATA packet and will discard any CVK_HDR_ACK or CVK_HDR_NACK packets it receives. (The kernel debugger also discards a packet if its header cannot be unbitstuffed or has a bad checksum. The kernel issues a CVK_HDR_NACK packet containing the sequence number and index number from the original CVK_HDR_DATA packet if the packet's body cannot be unbitstuffed or has a bad checksum.) Once the kernel receives a valid CVK_HDR_DATA packet, it extracts the sequence number and index number and uses them to construct a CVK_HDR_ACK packet, which it returns to the debug engine. (The flast flag in the CVK_HDR_DATA packet is ignored.) The kernel debugger then performs the action requested by the command and returns the result. In general, the result is returned in a single CVK_HDR_DATA packet whose sequence number matches the sequence number contained in the debug engine's original command packet, whose index number is zero, and whose flast flag is FALSE. After the result is transmitted, the kernel debugger waits for a response from the debug engine. The kernel is expecting either a CVK_HDR_ACK packet whose sequence number and index number match those sent in the result _or_ a CVK_HDR_DATA packet (containing the next command). If the kernel debugger receives any other response, it resends the CVK_HDR_DATA packet containing the result. If the debug engine sends a KDP break character while the victim machine is running, either to initiate a transaction or to regain control after the victim machine has resumed execution, the kernel debugger responds with a CVK_HDR_DATA packet whose sequence number matches the sequence number from the CVK_HDR_DATA packet that caused the system to resume. There is no such packet when the kernel debugger responds to the first KDP break sent by the debug engine. The sequence number in that case contains garbage. The kernel debugger does not generate replies for some commands, such as reboot, and the replies to commands that cause the victim machine to resume execution, such as resume or step, are not sent until an event such as a breakpoint, module load, or break signal from the debug engine, has caused the victim machine to quiesce. The kernel debugger responds somewhat differently to the CVK_CMD_RAW command, which is used to issue arbitrary kernel debugger commands while in packet mode. Each line in the response is returned in a separate CVK_HDR_DATA packet whose sequence number matches the sequence number in the CVK_CMD_RAW command's header. The index number in the first reply packet is 0; the index number increases by 1 in each successive reply packet (and wraps from 63 to 0). The debug engine should return a CVK_HDR_ACK packet with the appropriate sqeuence number and index number after each reply packet is received. The kernel debugger does not manipulate or increment sequence numbers and uses them only to generate ACKs and NACKs and to match ACKs with replies. A debug engine could use the same sequence number for every request, but this is not recommended. ═══ 10.2.4. Kernel Debugger Packet Responses ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_SUC │0x0000 │Success │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_BAD_COMMAND │0x0002 │Unrecognized command │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_PAGEIN │0xffef │Discarded page reloaded │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_TEND │0xfff0 │Task died │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_TNEW │0xfff1 │Task created │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_ASYNC │0xfff5 │Asynchronous halt (break) │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_LIB │0xfff8 │Module loaded │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_GPF │0xfff9 │General protection fault │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_KIL │0xfffa │Module unloaded │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_NMI │0xfffb │Non-maskable interrupt │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_BPT │0xfffc │Software breakpoint (INT3) │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_TBT │0xfffd │Single step │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │CVK_RET_ERR │0xffff │Failure │ └──────────────────────────────┴──────────┴──────────────────────────────┘ ═══ 10.2.5. Events Reported by the Kernel Debugger ═══ The following is a summary of the data reported when the kernel debugger sends an event in packet mode: ═══ 10.2.5.1. CVK_RET_GPF Events ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_DIVIDE │ 0 │Divide by zero exception │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_INTO │ 4 │Overflow Interrupt (INTO │ │ │ │instruction) │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_BOUND │ 5 │Bounds check (BOUND │ │ │ │instruction) │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_INVALID_OPCODE │ 6 │Invalid operation │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_EXTENSION │ 7 │Coprocessor not available │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_DOUBLE_EXCEPTION │ 8 │Double exception │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_EXTENSION_SEG_OVERRUN │ 9 │Coprocessor segment overrun │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_INVALID_TSS │ 10 │Invalid TSS │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_SEG_NOT_PRESENT │ 11 │Segment not present │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_STACK_SEG │ 12 │Stack exception │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_GP_FAULT │ 13 │General protection fault │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_PAGE_FAULT │ 14 │Page fault │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_GPF Value Event code from the table above. OffV Linear address in CS:(E)IP at time of event. SegV Slot number of thread. MTE MTE entry of executable running in process. PID PID of process that generated the event. TID TID of thread that generated the event. DBit Flags from CS selector. Reg Registers at time of event. MemCache Not used. ═══ 10.2.5.2. CVK_RET_TBT Event ═══ A CVK_RET_TBT event is generated when a single step occurs or when a debug trap, such as an event triggered by one of the hardware debug registers, occurs. ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_SSTEP │ 1 │Single step or debug trap │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_TBT Value Not used. OffV Linear address in CS:(E)IP at time of event. SegV Slot number of thread. MTE MTE entry of executable running in process. PID PID of process that generated the event. TID TID of thread that generated the event. DBit Flags from CS selector. Reg Registers at time of event. MemCache Not used. ═══ 10.2.5.3. CVK_RET_BPT Event ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_BREAKPOINT │ 3 │Software breakpoint │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_BPT Value Not used. OffV Linear address in CS:(E)IP at time of event. SegV Slot number of thread. MTE MTE entry of executable running in process. PID PID of process that generated the event. TID TID of thread that generated the event. DBit Flags from CS selector. Reg Registers at time of event. MemCache Not used. ═══ 10.2.5.4. CVK_RET_NMI Event ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_NMI │ 2 │Non-maskable interrupt │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_NMI Value Not used. OffV Linear address in CS:(E)IP at time of event. SegV Slot number of thread. MTE MTE entry of executable running in process. PID PID of process that generated the event. TID TID of thread that generated the event. DBit Flags from CS selector. Reg Registers at time of event. MemCache Not used. ═══ 10.2.5.5. CVK_RET_SUC Event ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_SUCCESS │100 │When last CVK_CMD_RAW response│ │ │ │is sent. │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Cmd CVK_RET_SUC ═══ 10.2.5.6. CVK_RET_ASYNC Event ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_ASYNC_TRAP │101 │KDP break received. │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_ASYNC Value Not used. OffV Linear address in CS:(E)IP at time of event. SegV Slot number of thread. MTE MTE entry of executable running in process. PID PID of process that generated the event. TID TID of thread that generated the event. DBit Flags from CS selector. Reg Registers at time of event. MemCache Not used. ═══ 10.2.5.7. CVK_RET_LIB and CVK_RET_KIL Events ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_LINK │102 │Module loaded │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_UNLINK │103 │Module unloaded │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_LIB or CVK_RET_KIL Value MTE handle of module in question. OffV Not used. SegV Slot number of thread. MTE MTE entry of executable running in process. PID PID of process that generated the event. TID TID of thread that generated the event. DBit Not used. UCHAR NAME[ ] Null-terminated full pathname of module in question (immediately follows DBit and overlays Reg and MemCache) ═══ 10.2.5.8. CVK_RET_TNEW and CVK_RET_TEND Events ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_TASK_CREATE │104 │Task create │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_TASK_END │105 │Task died │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_TNEW or CVK_RET_TEND Value Not used. OffV Not used. SegV Not used. MTE Not used. PID PID of process that was created or died. TID 1 (Primary TID in process) DBit Not used. Reg Not used. MemCache Not used. ═══ 10.2.5.9. CVK_RET_PAGEIN Events ═══ ┌──────────────────────────────┬──────────┬──────────────────────────────┐ │Event │Code │Description │ ├──────────────────────────────┼──────────┼──────────────────────────────┤ │KDP_T_PAGEIN │106 │Discarded page reloaded │ └──────────────────────────────┴──────────┴──────────────────────────────┘ Fields returned in cvkcmd_s are as follows: Cmd CVK_RET_PAGEIN Value Not used. OffV Address of the page in question. SegV Not used. MTE MTE handle of the module that contains the page in question. PID Not used. TID Not used. DBit Not used. Reg Not used. MemCache Not used. ═══ 10.2.6. Kernel Debugger Packet Commands ═══ The following table lists the kernel debugger packet commands: ┌────────────────────┬────────┬──────────────────────────────┬────────┬────────┐ │Command │Code │Description │CVK_ │CVK_ │ │ │ │ │CMDSIZE_│RETSIZE_│ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_RMEM │ 1 │Read memory │18 │20 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_RREG │ 3 │Read registers │18 │24 + │ │ │ │ │ │sizeof( │ │ │ │ │ │RegSa_ │ │ │ │ │ │struc) │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_WMEM │ 4 │Write memory │20 │6 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_WREG │ 6 │Write registers │20 + │2 │ │ │ │ │sizeof( │ │ │ │ │ │RegSa_ │ │ │ │ │ │struc) │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_RUN │ 7 │Resume execution │6 │0 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_KILL │ 8 │Reboot victim machine │2 │0 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_STEP │ 9 │Single step │2 │0 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_NUMTOBASE │13 │Get object/segment information│14 │14 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_LIBNAME │16 │Get module information │6 │6 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_RAW │20 │Perform kernel debugger │6 │ │ │ │ │command │ │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_DBIT │22 │Get selector information │20 │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_RSTEP │23 │Range step │10 │0 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_SCANMTE │24 │Scan module table │2 │6 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_SCANTCB │25 │Scan thread control blocks │6 │10 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_SEL2LIN │26 │Convert selector:offset to │18 │6 │ │ │ │linear address. │ │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_LIN2SEL │27 │Convert linear address to │18 │12 │ │ │ │selector:offset. │ │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_OBJCOUNT │28 │Get number of objects/segments│6 │6 │ │ │ │in module │ │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_SCANOBJ │29 │Scan object/segment table │14 │10 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_SELINFO │30 │Get selector information │18 │20 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_RNPX │31 │Read NPX state │18 │128 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_WNPX │32 │Write NPX state │128 │60 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_ENA │33 │Enable optional features │6 │2 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_DIS │34 │Disable optional features │6 │2 │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_PIREG │35 │Register for PAGEIN │14 │2 │ │ │ │notification │ │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_PIDRG │36 │Deregister for PAGEIN │14 │2 │ │ │ │notification │ │ │ ├────────────────────┼────────┼──────────────────────────────┼────────┼────────┤ │CVK_CMD_SCANPCB │37 │Scan processor control blocks │6 │10 │ └────────────────────┴────────┴──────────────────────────────┴────────┴────────┘ Each command is described below, along with the input parameters and the output values. Parameters are usually passed in a cvkcmd_s If a given field in the cvkcmd_s structure is not listed, its value is not used. There are constants called CVK_CMDSIZE_xxx and CVK_RETSIZE_xxx which provide the size of the command and the size of the response from each command, where xxx is substituted with the last part of the command name. For CVK_CMD_PIDRG, the constants would be called CVK_CMDSIZE_PIDRG and CVK_RETSIZE_PIDRG. The values for these constants are provided in the last two rows of the table above. ═══ 10.2.6.1. Read Memory (CVK_CMD_RMEM) ═══ Parameters: Cmd CVK_CMD_RMEM Value Number of bytes to read. (<= CVK_MEMCACHE_SIZE) OffV Offset of data to read. SegV Selector or segment index for data to read. 0 if OffV is a linear address, otherwise setting of PE in CR0 and VM in EFLAGS of interrupted thread determine whether SegV is selector or selector index. TID Slot of thread in whose context address is to be used. 0 is used for regions in globally shared areas. Returns: Value Number of bytes actually read. MemCache[Value] Data read. ═══ 10.2.6.2. Read Registers (CVK_CMD_RREG) ═══ Parameters: Cmd CVK_CMD_RREG TID Slot of thread in whose registers are desired. Returns: Reg Registers for thread. ULONG PC (immediately following Reg) Linear address corresponding to CS:(E)IP. ═══ 10.2.6.3. Write Memory (CVK_CMD_WMEM) ═══ Parameters: Cmd CVK_CMD_WMEM Value Number of bytes to write. (<= CVK_MEMCACHE_SIZE) OffV Offset of data to write. SegV Selector or segment index for data to write. 0 if OffV is a linear address, otherwise setting of PE in CR0 and VM in EFLAGS of interrupted thread determine whether SegV is selector or selector index. TID Slot of thread in whose context address is to be used. 0 is used for regions in globally shared areas. MemCache[Value] Data to write. Returns: Value Number of bytes actually written. ═══ 10.2.6.4. Write Registers (CVK_CMD_WREG) ═══ Parameters: Cmd CVK_CMD_WREG TID Slot of thread in whose registers are to be changed. Reg Registers for thread. Only the following registers are affected: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, EIP, CS, DS, ES, FS, GS, SS, and EFLAGS. Returns: Cmd Return code ═══ 10.2.6.5. Resume Execution (CVK_CMD_RUN) ═══ Parameters: Cmd CVK_CMD_RUN Value Indicates action kernel debugger should take after resuming execution. -CVK_CMD_RUN Kernel debugger is not to expect further commands or generate further events. All optional features enabled with the CVK_CMD_ENA command are disabled. In other words, this command detaches the debug engine from the kernel debugger. Anything else Kernel debugger sends notification when an event occurs. Returns: None. See description above in Value for action taken by system under debug. ═══ 10.2.6.6. Reboot Victim (CVK_CMD_KILL) ═══ Parameters: None. Returns: None. ═══ 10.2.6.7. Single Step (CVK_CMD_STEP) ═══ Parameters: None. Returns: None. System under debug sends event notification when an event occurs. ═══ 10.2.6.8. Get Object/Segment Information (CVK_CMD_NUMTOBASE) ═══ Parameters: Cmd CVK_CMD_NUMTOBASE Value Object/segment index for segment about which information is desired. MTE MTE handle for module about which information is desired. Returns: Value Flags from object/segment table entry for segment. (ote_flags or ste_flags) OffV Base address for object. (0 for segments.) SegV Selector for object/segment. ═══ 10.2.6.9. Get Module Information (CVK_CMD_LIBNAME) ═══ Parameters: Cmd CVK_CMD_LIBNAME Value MTE handle for module about which information is desired. Returns: Value Length of full pathname of module, including trailing null character. Returns 0 if SMTE or name is not resident. UCHAR NAME[Value] Null-terminated full pathname of module (immediately follows Value) ═══ 10.2.6.10. Perform Kernel Debugger Command (CVK_CMD_RAW) ═══ Parameters: Cmd CVK_CMD_RAW OffV Null-terminated text of command to perform (overlays OffV) Returns: Cmd Indicates whether this is the last response. CVK_CMD_RAW More response packets coming. CVK_RET_SUC Last response packet. Value Length of command response. OffV Null-terminated response to command (overlays OffV) Note: This command may return multiple responses. The last event packet response will have Cmd set to CVK_RET_SUC instead of CVK_CMD_RAW. ═══ 10.2.6.11. Get Selector Information (CVK_CMD_DBIT) ═══ Parameters: Cmd CVK_CMD_DBIT SegV Selector for which information is desired. Returns: DBit Flags from selector's descriptor. ═══ 10.2.6.12. Range Step (CVK_CMD_RSTEP) ═══ Parameters: Cmd CVK_CMD_RSTEP OffV Offset at which to stop. Returns: None. System under debug steps until CS selector changes or until (E)IP becomes >= OffV value, then issues a single step event. ═══ 10.2.6.13. Scan Module Table (CVK_CMD_SCANMTE) ═══ Parameters: Cmd CVK_CMD_SCANMTE Returns: Cmd CVK_RET_LIB if information was returned, otherwise returns CVK_RET_SUC if end of module table reached. Value MTE handle of module if Cmd = CVK_RET_LIB. UCHAR NAME[Value] Null-terminated full pathname of module (immediately follows Value) Not present if SMTE or name is not paged in. Packet length is CVK_RETSIZE_SCANMTE in this case. The module table scan ignores resource modules, which contain only resource objects and segments, and forwarder modules, which contain no objects or segments. ═══ 10.2.6.14. Scan Thread Control Blocks (CVK_CMD_SCANTCB) ═══ Parameters: Cmd CVK_CMD_SCANTCB Value Slot number of thread control block to start with. Specify 0 to start at first occupied slot. Specify -1 to start at currently scheduled slot. Returns: Value Slot number of next occupied thread control block. 0 if no more TCBs. OffV Number of information blocks returned in current response. struct { USHORT slot; /* Slot index for thread */ USHORT PID; /* PID that contains thread */ USHORT TID; /* Thread ordinal */ USHORT MTE; /* MTE handle for module running in process that contains thread */ USHORT flags; /* Flags for thread Bit 0 (low-order bit) If ON, indicates thread was running when system stopped. Bits 1-15 are unused */ } TIBInfo Information returned immediately following OffV. ═══ 10.2.6.15. Convert Selector:Offset to Linear Address (CVK_CMD_SEL2LIN) ═══ Parameters: Cmd CVK_CMD_SEL2LIN OffV Offset SegV Selector TID Thread that linear address should be in context of. Returns: Value Linear address ═══ 10.2.6.16. Convert Linear Address to Selector:Offset (CVK_CMD_LIN2SEL) ═══ Parameters: Cmd CVK_CMD_LIN2SEL Value Linear address TID Slot of thread that desired linear address is to be in context of. (Currently ignored. Linear address must be in global region and mapped by interrupted thread's CS, DS, ES, or SS.) Returns: OffV Offset SegV Selector ═══ 10.2.6.17. Get Number of Objects/Segments in Module (CVK_CMD_OBJCOUNT) ═══ Parameters: Cmd CVK_CMD_OBJCOUNT Value MTE handle for module about which information is desired. Returns: Value Number of objects/segments in module. 0 returned if the module is a forwarder module, which contains no objects or segments, or a resource module, which contains only resource objects and segments. ═══ 10.2.6.18. Scan Object/Segment Table (CVK_CMD_SCANOBJ) ═══ Parameters: Cmd CVK_CMD_SCANOBJ Value Object/segment table tindex of entry to start with. Specify 0 to start at the beginning. MTE MTE handle for module about which information is desired. Returns: Value Object/segment table index of next entry. 0 is returned if no more entries. OffV Number of information blocks returned in current response. struct { ULONG base; /* Base address of object/segment */ ULONG size; /* Size in bytes of object/segment in memory */ ULONG flags; /* Flags for object/segment: bit 0 (low-order bit) ON - 16-bit segment OFF - 32-bit segment bit 1 ON - data OFF - code bits 2-31 are unused */ } ObjInfo; Information block returned immediately follows OffV ═══ 10.2.6.19. Get Selector Information (CVK_CMD_SELINFO) ═══ Parameters: Cmd CVK_CMD_SELINFO SegV Selector TID Slot of thread desired selector is to be in context of. Returns: Value Limit of segment in bytes. OffV Base address of segment. DBit Flags from descriptor. ═══ 10.2.6.20. Read NPX Information (CVK_CMD_RNPX) ═══ Parameters: Cmd CVK_CMD_RNPX TID Slot of thread whose NPX state is desired. Returns: Cmd Return code. 0 NPX state read and returned 1 NPX is being emulated. 2 Invalid slot. 3 Thread has no NPX state. 4 State swapped out. Reg Image of NPX state as saved by FSAVE instruction. ═══ 10.2.6.21. Write NPX Information (CVK_CMD_WNPX) ═══ Parameters: Cmd CVK_CMD_WNPX TID Slot of thread whose NPX state is to be set. Reg Image of NPX state (restored by FRESTOR instruction) Returns: Cmd Return code. 0 NPX state written successfully. 1 NPX is being emulated. 2 Invalid slot. 3 Thread has no NPX state. 4 State swapped out. ═══ 10.2.6.22. Enable Optional Features (CVK_CMD_ENA) ═══ Parameters: Cmd CVK_CMD_ENA Value Index of feature to enable. 0 CVK_RET_TNEW and CVK_RET_TEND notifications. Returns: Cmd Return code. Note: All optional features are disabled when a CVK_CMD_RUN command is issued with a Value of -CVK_CMD_RUN. ═══ 10.2.6.23. Disable Optional Features (CVK_CMD_DIS) ═══ Parameters: Cmd CVK_CMD_DIS Value Index of feature to disable. 0 CVK_RET_TNEW and CVK_RET_TEND notifications. Returns: Cmd Return code. Note: All optional features are disabled when a CVK_CMD_RUN command is issued with a Value of -CVK_CMD_RUN. ═══ 10.2.6.24. Register for PAGEIN Notification (CVK_CMD_PIREG) ═══ Parameters: Cmd CVK_CMD_PIREG OffV Address of page. MTE MTE handle of module that contains page. Returns: Cmd Return code. ═══ 10.2.6.25. Deregister for PAGEIN Notification (CVK_CMD_PIDRG) ═══ Parameters: Cmd CVK_CMD_PIDRG OffV Address of page. MTE MTE handle of module that contains page. Returns: Cmd Return code. ═══ 10.2.6.26. Scan Processor Control Blocks (CVK_CMD_SCANPCB) ═══ Parameters: Cmd CVK_CMD_SCANPCB Value Processor number to start with. Specify 0 for processor 1. Returns: Value Processor number of next processor control block. 0 if no more PCBs. OffV Number of information blocks returned in current response. struct { ULONG pNum; /* Processor Number */ USHORT slot; /* Slot index of thread running on processor. (0 means processor idle) */ USHORT flags; /* Flags (currently unused) */ } PCBInfo[OffV] Information returned immediately following OffV. ═══ 11. The ICAT Debugger ═══ The IBM Interactive Code Analysis Tool (ICAT) Debugger is used for debugging OS/2 device drivers, kernel code, Installable File Systems (IFS), and applications that are running on an OS/2 Warp Server for SMP remote machine. The debugger helps you detect and diagnose errors in code written in C, C++, and assembler languages at the source level. ═══ 11.1. What is the ICAT Debugger ═══ The ICAT Debugger (hereafter referred to in this chapter as the debugger) is a source-level debugger which uses OS/2 Warp 3.0, OS/2 Warp Connect, or OS/2 Warp Version 4 to assist in detecting and diagnosing errors in an OS/2 Warp Server for SMP system. It provides a graphical user interface and debugs PM and non-PM (single- or multi-threaded) applications as well as device drivers and other system-level binaries. This debugger has been designed to debug remotely an OS/2 Warp Server for SMP system. The Kernel Debugger (KDB) runs on a victim OS/2 Warp Server for SMP machine and replies to debug service requests that are sent from the debugger while running on an Intel-based OS/2 Warp 3.0, OS/2 Warp Connect, or OS/2 Warp Version 4 machine. The supported communication mode between machines is serial. Supported debug file formats include HLL (which is IBM VisualAge C++ (VACPP)) and CodeView (CV). ═══ 11.2. Before You Begin ═══ This section lists the hardware and software requirements, considerations you need to be aware of, compiling and linking options, environment variables, limitations, helpful tips, and a demo to help get you started. ═══ 11.2.1. Hardware Requirements ═══ The debugger must be run on an Intel-based system capable of running OS/2 Warp 3.0, OS/2 Warp Connect, or OS/2 Warp Version 4. Slightly less than 11 megabytes of disk space is required to install the debugger. We recommend that you run with at least a 486SX processor for performance reasons. ═══ 11.2.2. Software Requirements ═══ There are software requirements for both the victim machine where the programs are debugged and run and the host machine where the debugger runs. To set up the victim OS/2 machine: 1. Obtain or build an OS2KRNLD that has the debugger packet-handling code. This code is now part of the regular KDB builds. 2. OS2KRNL is in the root directory of the victim system's boot drive but is hidden. Use the following command to make it visible: attrib -r -s -h os2krnl Use the following commands to back up the file and replace it with its debug equivalent: copy os2krnl os2krnl.bak copy os2krnld os2krnl To set up the host OS/2 machine: 1. Unzip the ICATMERL.ZIP file into the directory where you want to run the debugger. This file contains the debugger, the victim sample binaries, and the original source files. 2. Set the environment variables. Refer to Setting Environment Variables for more information. ═══ 11.2.3. Compiling and Linking Your Program ═══ Before using the debugger, you need to compile and link your program. For VACPP programs, use the following options: /Ti+ Compiles your program to produce an object file that includes line number information and a symbol table in addition to the source code. /O- Compiles your program with optimization off. This is the default. /Oi- Compiles your program with inlining off. This is the default. /DEbug Links your program to produce an executable file that includes line number information and a symbol table in addition to the executable code. Note: When you specify the /Ti+ option with the /DEbug option, icc passes this option to the linker automatically, so you only need to use it if you link separately from the compile. For more information about compiling and linking your program, refer to IBM C++ Tools Programming Guide. For Microsoft CL, CL386, MASM, and MASM386 programs, use the following options: /Zi Compiles your program to produce an object file that includes line number information and a symbol table, in addition to the source code. /Od Compiles your program with optimization off. /CO Links your program to produce an executable file that includes line number information and a symbol table in addition to the executable code. For Watcom wpp386 programs, use the following options: -d2 Compiles your program with full debugging information. -hc Compiles your program emitting CodeView debug format (currently, the debugger only supports Watcom's CodeView debug format). -od Compiles your program with optimization off. For the Watcom linker, wlink, use this option: d codeview Links your program with CodeView debug format. The debugger supports a separate debug file (from your created application) for the Watcom compiler. For the Watcom linker, wlink, use this option to create a separate debug file if desired: op symf This will create a .sym file. Be careful not to confuse this file with a KDB .sym file. The debugger looks for debug information first in the application file. If it doesn't find it, it looks for the debug information in a .dbg file and then in a .sym file as a last resort. Most users rename the separate Watcom .sym file to a .dbg file. ═══ 11.2.4. Setting Environment Variables ═══ The debugger uses environment variables to manage debugging sessions and remote communications. To set the environmental variables, you will need to edit the SETICAT.CMD file. The environment variables should be set in the OS/2 session where the debugger is to be run. The environment variables are as follows: CAT_MACHINE Specifies which host com port the debugger uses to communicate with KDB and the baud rate for communications. This variable has the following form: COMx:nnnn where x identifies the port (for example, 1 for COM1) and nnnn specifies the baud rate. The following rates are supported:  9600 (the default)  19200  38400  57600  115200 For speeds above 19200, you need buffered UARTs on both the host and victim machines. For speeds above 57600, you need customized serial drivers such as SIO.SYS or the COM.SYS that ships with Warp Version 4 (which can also be used with earlier versions of Warp). For example, type the following at the command prompt: set CAT_MACHINE=COM2:57600 Note: Ensure that your communication port is enabled if you use a ThinkPad. CAT_SETUP_RATE When the debugger first attempts to communicate with KDB, it does so at the baud rate specified by this environment variable or at 9600 baud if this variable is not defined. If the communication succeeds, the debugger changes the baud rate to the rate specified by the CAT_MACHINE environment variable and proceeds. Otherwise, the debugger tries to initiate contact at the rate specified by the CAT_MACHINE environment variable. If neither attempt succeeds, the debugger issues an error message. In most cases, you do not need to set CAT_SETUP_RATE. It is primarily useful if you have been communicating with the victim system directly (for example, using ZOC or T) and have left the serial line running at a rate other than 9600 baud that does not match the rate specified by the CAT_MACHINE environment variable. Additionally, if this environment variable is set, the debugger will reset KDB to this rate when the debugger is closed. For example, type the following at the command prompt: set CAT_SETUP_RATE=9600 CAT_HOST_BIN_PATH Tells the debugger where to find your debug binaries (the .SYS and .EXE files with debug information) on your host system. For example, type the following at the command prompt: set CAT_HOST_BIN_PATH=I:\SDE\SAMDETW CAT_COMMUNICATION_TYPE Allows asynchronous communications. Currently, this must be set to ASYNC_SIGBRK in subsequent releases it is planned to support other forms of communication. For example, type the following at the command prompt: set CAT_COMMUNICATION_TYPE=ASYNC_SIGBRK CAT_HOST_SOURCE_PATH Tells the debugger where to find the source files that were used to build your debug binaries. See Finding Source Files for more details. For example, type the following at the command prompt: set CAT_HOST_SOURCE_PATH=I:\SDE\SAMDETW;E:\icat\testcases\src CAT_PATH_RECURSE Causes a recursive search of the subdirectories below the subdirectories listed in CAT_HOST_BIN_PATH and CAT_HOST_SOURCE_PATH. For example, with the CAT_HOST_SOURCE_PATH=i\sde\samdetw variable, the debugger will search the samdetw subdirectory and all subdirectories below samdetw as well as their subdirectories. The default is NULL, which means the debugger will not perform a recursive search. When the variable is set to any non-null value, the recursive search is performed. For example, type the following at the command prompt: set CAT_PATH_RECURSE=ON CAT_MODULE_LIST By default, the debugger obtains information about every executable module (DLL, EXE, device driver, and so on) running on the victim system. As a result, it can take several minutes to attach to the victim system. If the CAT_MODULE_LIST environment variable is defined, the debugger only obtains information about a module if its name appears in the environment variable string. (The debugger always obtains information about the kernel itself.) This can dramatically reduce the amount of time it takes for the debugger to come up. For example, type the following at the command prompt: set CAT_MODULE_LIST=SAMPLEDD.SYS SAMPLE.EXE The debugger will only obtain information on the kernel and the two modules listed in CAT_MODULE_LIST. (If a program named LE.EXE were running, the debugger would also obtain information on it since LE.EXE is a substring of SAMPLE.EXE.) CAT_RESUME During debugger initialization, the debugger stops the victim system in order to establish the desired baud rate. The debugger then continues its initialization and eventually allows the user to attach to the victim system. By default, the debugger does not allow the victim system to resume execution during this interval. This behavior is necessary to debug a system that has already reached a failure or that contains a hardcoded INT3 instruction (as device drivers often do). There could be situations where you want to initialize the debugger, but somehow time your attach to the victim system using the Attach push button. In this case, define CAT_RESUME, and then the debugger will resume the victim system waiting for your attach command to stop it again. For example, type the following at the command prompt: set CAT_RESUME=ON CAT_DIAL and CAT_MODEM_INIT The host and victim machines can be connected directly (with a null modem serial cable) or by way of modem. If either of these variables is defined, the debugger sets up the COM port specified by the CAT_MACHINE environment variable so that the debugger can talk to a modem. The debugger then issues the modem attention string (+++) followed by the string specified by the CAT_MODEM_INIT variable (if any) to initialize the modem. The debugger then issues the string specified by the CAT_DIAL variable (if any) and waits 500 seconds for the remote modem to answer. The CAT_MODEM_INIT environment variable should be based on the string your terminal emulator uses to initialize the modem. This string presumably doesn't change very often. Once you have determined the correct AT commands, you can keep the CAT_MODEM_INIT environment variable constant and change CAT_DIAL when you need to place calls to different numbers. For example, type the following at the command prompt: set CAT_MODEM_INIT=ATZ set CAT_DIAL=ATDT4840 CAT_OVERRIDE Specifies a path that the debugger searches first to find the source files that were used to build your debug binaries. See "Finding Source Files" below for a complete description of the process. For example, type the following at the command prompt: set CAT_OVERRIDE=e:\temp\updates CATTAB Specifies the number of spaces between tab stops when source code containing tabs is displayed in a debugger window. For example, type the following at the command prompt: set CATTAB=5 The debugger will convert each tab in the source to 5 spaces when the source is displayed. CATTABGRID Specifies the column positions for the tab stops when source code containing tabs is displayed in a debugger window. For example, typing the following command at the command prompt sets tab stops at the 6th position: set CATTABGRID=6 DEBUG_NUMBEROFELEMENTS DEBUG_NUMBEROFELEMENTS is an environment variable that is set to an integer, n. This integer represents the default number of elements displayed for a variable or structure that has a substantial number of elements. The last element displayed for such a structure is labeled "more elements." Clicking on this entry will display the next n elements of the variable or structure. For example, type the following at the command prompt: set DEBUG_NUMBEROFELEMENTS=100 The next 100 elements are displayed. ═══ 11.2.5. Finding Source Files ═══ The search path tells the debugger where to find the source file used in the source windows. The debugger searches for the source files in the following order: 1. The path defined by the CAT_OVERRIDE environment variable, if specified. 2. The directory where the object file was compiled. 3. The path defined by the CAT_HOST_BIN_PATH environment variable, if specified. 4. The directory where the executable file is located. 5. The path defined by the CAT_HOST_SOURCE_PATH environment variable, if specified. 6. The current directory. 7. The path defined in the INCLUDE environment variable. 8. The directory of the last source file found in this debug session. Note: The CAT_PATH_RECURSE environment variable, if specified, will cause the debugger to search recursively all subdirectories of the CAT_HOST_BIN_PATH and CAT_HOST_SOURCE_PATH environment variables. ═══ 11.2.6. Limitations ═══ The debugger has the following restriction:  You can not launch an application with the debugger. You can only attach to the OS/2 Warp Server for SMP system. The victim system communicates over COM2 if COM2 exists and over COM1 otherwise. The COM port the victim system uses must not be usurped by an application. For example, if the victim system is using COM2 and you issue the following command: mode com2 you may disrupt communications. The device driver and executables associated with the IBM LAN Management Utilities (for example, LMUIPL.SYS) can also prevent the victim system from communicating. Similarly, the COM port the host system uses must be dedicated to the debugger. If the debugger fails to attach, make sure you're not running a terminal emulator (for example, T or ZOC) in the background that has the COM port tied up. Currently, there are limitations with C++ support for the Watcom compiler. The debugger does not support mangled names from the Watcom compiler. This can show up when the debugger can not find certain functions (external functions and overloaded member functions) or sets function breakpoints. ═══ 11.2.7. Helpful Tips and Hints ═══ The following are tips and hints that may be helpful:  You must have OS/2 WARP 3.0, OS/2 Warp Connect, or OS/2 Warp Server for SMP on your host machine.  If CAT_HOST_BIN_PATH points to a remote-mounted drive, the drive must be mounted in binary mode.  Put any environment variables that you want set in a command file. For example, you could put them in the SETICAT.CMD file or create your own command file.  The DBGSTRIP utility can be used to strip debug information from binaries placed on the victim machine but should not be used on binaries placed in CAT_HOST_BIN_PATH (if you want to do source-level debugging).  Using C and C++, you can write your program code with stylistic features that are not supported by the debugger. For example, multiple statements on the same line are difficult to debug. None of the individual statements can be accessed separately when you set breakpoints or when you use step commands. ICAT allows you to manipulate any thread running on the victim machine. Because certain portions of the address space are not shared by all threads, you must be sure that you are in the proper context when you set breakpoints, display storage, etc. The title of a thread-specific window includes the thread's identifier as shown in the Debug Session Control window (see Using the Debug Session Control Window). To ensure you are in the context of the proper thread, select the thread from the Debug Session Control window's Threads pane. For example, suppose you attach to the victim system and wish to set a breakpoint. If the breakpoint is in a shared region (for example, in a device driver, a DLL, or the kernel), it does not matter which context you are in when you set the breakpoint. But if the breakpoint is not in a shared region such as in an EXE file, you must ensure that you are in the context of a thread that belongs to the process that owns the region before you set the breakpoint. Because the debugger does not necessarily have information about every EXE file in the system, a window may show source for a module even though the thread listed in the title of the window is not part of the process that is running the EXE file. If you set the breakpoint without first verifying you are in the proper context, you will actually set a breakpoint in a different module entirely. ═══ 11.2.8. When Things Go Wrong ═══ Here are some things to check when the debugger is not doing what you think it should:  If the debugger can't attach to the victim system: - Ensure your serial cable is a "null modem" cable (one that connects the transmit data pin of one machine to the receive data pin of the other). - Ensure that your serial cable is securely attached to both the host and victim machines. - Ensure that you have the serial cable connected to the correct COMx port that KDB will use on the victim machine and to the COMx port that you specified with the CAT_MACHINE environment variable on the host machine. - Ensure that KDB is installed on the victim machine, and if necessary, check this by using a terminal emulator from the host machine before running the debugger. If the terminal emulator is successful, don't forget to shut it down before invoking the debugger. - Ensure that your CAT_HOST_BIN_PATH is set correctly. - Ensure that your CAT_COMMUNICATION_TYPE environment variable is set to ASYNC_SIGBRK. - Ensure that you have buffered UARTs on both host and victim machines if you want to run at baud rates > 19200. - Ensure that your communication port is enabled if you use a ThinkPad.  If the debugger only displays the disassembly listing of your program and not the source listing: - Ensure that the program was compiled with the proper flags to enable source-level debugging. See Compiling and Linking Your Program. - Ensure that the executable in the CAT_HOST_BIN_PATH was not processed by the DBGSTRIP utility. DBGSTRIP makes the executable smaller by removing the debug information. - Ensure that your CAT_HOST_SOURCE_PATH is set to reference your source files. - Ensure that the modules you want to debug are specified by the CAT_MODULE_LIST environment variable. ═══ 11.2.9. Using the Demo ═══ This demo shows a very simple set of DevIOCtl calls being made from a sample application to a device driver. It explains some of the actions you could take to debug this scenario at the source level. To run the demo, follow these steps: 1. Copy SAMPLEDD.SYS to the root directory of the C drive on your victim system. 2. On the victim system, edit CONFIG.SYS so that it contains the following line: DEVICE=C:\SAMPLEDD.SYS This loads the sample device driver when you reboot the victim system. 3. Copy SAMPLE.EXE to your victim system. 4. Reboot your victim machine so that the SAMPLEDD.SYS binary and the debug OS2KRNL and OS2LDR binaries are instantiated. You can perform a quick check to see if the victim machine is OK by running your normal terminal emulator (T, ZOC, and so on). This will show if KDB is communicating at 9600 baud. 5. Shut down the terminal emulator before you run the debugger. 6. Run the SETICAT.CMD file to set the environment variables on your host system. 7. Type icatgam. The Initialization window displays. 8. From the Initialization window, select the Attach push button. 9. In the Debug Session Control, make sure you see SAMPLEDD.SYS. Click on the plus sign (+) next to it and notice that one part is displayed. Click on that plus sign (+) and notice eight entries are now displayed. 10. Click on STRATEGY. The STRATEGY routine of the sampledd device driver should display in a source window. Note: This is MASM source, so you will see assembler directives, but it is source. We support both CodeView (CL and CL386) and HLL (IBM VACPP) debug formats for C. 11. Set a breakpoint on line 209 inside the STRATEGY routine by double-clicking on the line number. Run the debugger by selecting the Run button. 12. On the victim machine, type sample. SAMPLE.EXE will emit a DevIOCtl to open the SAMPLEDD device driver. 13. When the debugger notifies you that the breakpoint has been encountered, open the Registers window and then open the Storage window. Edit one of the addresses in this storage window by double-clicking on the address and change the address value to that of the PC register, which is located at the top of the list of status flags registers in the Registers window. You will see memory that corresponds to the code space. 14. From the Source window, select Passthru from the Monitors menu. 15. In the Passthru window, type dg cs in the Command entry field and select the Send push button or press the Enter key. This sends the command to KDB and the output is displayed in the response area. Notice that it provides information about SAMPLEDD's code descriptor. You can emit most KDB commands from the Passthru window. Commands that cause the victim machine to resume execution (for example, g and t) should be avoided. Note: If you change the state of the victim machine with KDB commands in the Passthru window, you must select the Resync push button to allow the debugger to reflect the changes. 16. Set another breakpoint on line 275 inside the Open subroutine. Run the debugger until the breakpoint is encountered. 17. Select the step into choice or button to do a step into on the Ccall macro to SubrWFrame. You are in the SubrWFrame subroutine. Click on the Call Stack icon. 18. From the Call Stack window, select the Display style choice from the Options menu. 19. From the Display style window, enable the Return Address choice, which is located under the Select items group heading. Select the OK push button. 20. Select the step over choice or button and notice the change in the Call Stack window. 21. Look at the Debug Session Control window and find SAMPLE.EXE. Click on the plus sign (+) and notice that one part is displayed. Click on that plus sign (+) and you will see MAIN. 22. Click on MAIN and set a breakpoint at line 44. Run the debugger by selecting the Run button. The breakpoint will be encountered in the STRATEGY routine again. 23. Run one more time and the breakpoint will be encountered in SAMPLE.EXE in MAIN. After you have completed these steps, close the debugger. At this point, you can use your terminal emulator to communicate with KDB. If you did not use the CAT_SETUP_RATE environment variable, KDB will be set at the baud rate you used to communicate with the debugger. ═══ 11.3. Getting Started ═══ This section describes how to start a debugging session from the OS/2 command prompt, attach to a process you want to debug, and how to end a debugging session. ═══ 11.3.1. Starting the Debugger from OS/2 ═══ To start the debugger from the OS/2 command prompt, enter the command icatgam. For example, type the following: icatgam /x where /x represents a debugger parameter. The debugger parameters are: /p+ Use program profile information. /p- Do not use any program profile information. If you type icatgam and press Enter, the Initialization Window displays. See Using the Initialization Window for more information. ═══ 11.3.2. Using the Initialization Window ═══ Use the Initialization window to attach to the OS2KRNL. To use this window:  Select the Use program profile check box if you want to restore the windows and breakpoints when debugging a program more than once.  Select the Attach push button to attach to the OS2KRNL.  Select the Settings push button to display the Debugger Properties window, which allows you to select how threads and source files initially display and set environment variables. See Debugger properties... for more information. ═══ 11.3.3. Ending the Debugging Session ═══ To end the debugging session, select Close debugger from the File menu in a debugger window. The Close Debugger window displays. Select one of the following choices:  Select Yes to end your debugging session.  Select No to return to the previous screen without exiting the debugger. You can also end the debugging session by pressing F3 in any of the debugger windows. ═══ 11.4. Frequently Used Features of the Debugger ═══ This section introduces the tool buttons, ways to execute your program, and describes how to set breakpoints.  Refer to Using the Tool Buttons for a list of the tool buttons items.  Refer to Executing a Program for information on step commands.  Refer to Setting Breakpoints for information on breakpoints. ═══ 11.4.1. Using the Tool Buttons ═══ A tool bar has been provided for easier access to frequently used features. Not all buttons are displayed in the windows. To display buttons in a window, enable the Tool buttons choice that is listed under the Options menu. The following is a list of features that are provided: Step over executes the current line in the program. If the current line is a call, execution is halted when the call is completed. Step into executes the current line in the program. If the current line is a call, execution is halted at the first statement in the called function. Step debug executes the current line in the program. The debugger steps over any function for which debugging information is not available (for example, library and system routines) and steps into any function for which debugging information is available. Step return automatically executes the lines of code up to and including the return statement of the current function. Run allows you to start and stop the program. When the debugger is running, the Run button is disabled and the Halt button is enabled. You can click on the Halt button to halt the program execution. You can also interrupt the program you are debugging by selecting the Halt choice from the Run menu. View changes the current source window to one of the other source windows. For example, you can change from the Disassembly window to the Mixed window. Monitor Expression displays the Monitor Expression window, which allows you to type in the name of the expression you want to monitor. Call Stack displays the Call Stack window, which allows you to view all of the active functions for a particular thread including the system calls. The functions are displayed in the order that they were called. Registers displays the Registers window, which allows you to view all the processor and coprocessor registers for a particular thread. Storage displays the Storage window, which shows the storage contents and the address of the storage. Breakpoints displays the Breakpoints List window, which allows you to view all the breakpoints that have been set. Passthru displays the Passthru window, which allows you to send commands and receive responses from KDB directly. Debug Session Control displays the Debug Session Control window. Growth direction allows you to change the direction that items are displayed on the stack. Delete allows you to delete the highlighted item. Delete all allows you to delete all the items in the window. 32-float displays the storage contents as a 32-bit floating point. 64-float displays the storage contents as a 64-bit floating point. 32-bit unsigned displays the storage contents as a 32-bit unsigned integer. 32-bit signed displays the storage contents as a 32-bit signed integer. ASCII displays the storage contents in ASCII. Hex and ASCII displays the storage contents in Hex and ASCII. Change representation allows you the change the data representation.  Refer to Executing a Program for information on step commands.  Refer to Setting Breakpoints for information on breakpoints. ═══ 11.4.2. Executing a Program ═══ You can execute your program by using step commands or the Run command. Step commands Step commands control the execution of the program. The step commands are located in the tool bar of the source windows and under the Run menu of the source windows. Run command The Run command runs the program until a breakpoint is encountered, the program is halted, or the program ends. You can start the RUN command from the Run button in the tool bar or the Run menu of the source windows. When you execute your program, a clock icon displays to indicate that the program is running and might require input to continue to the next breakpoint or termination of the program.  Refer to Setting Breakpoints for information on breakpoints. ═══ 11.4.3. Setting Breakpoints ═══ You can control how your program executes by setting breakpoints. A breakpoint stops the execution of your program at a specific location or when a specific event occurs. To set breakpoints, select the Breakpoints menu from the Debug Session Control window or from any of the source windows and select the appropriate choice for the type of breakpoint you want to set. You can also set a simple line breakpoint by double-clicking in the prefix area of an executable statement in any of the source windows. The prefix area is the area to the left of the source code where line numbers or addresses are displayed. The prefix area turns red indicating that the breakpoint has been set. You can also use the arrow keys to move the cursor to the prefix area and then use the space bar to toggle the breakpoints. This allows you to set or delete a breakpoint. Refer to Breakpoints Menu Choices for more information on breakpoints. ═══ 11.5. Introducing the Main Debugging Windows ═══ This section introduces the Debug Session Control window and the three source windows which offer different views of your source code. It describes the menu items and choices that are located in each of these windows.  Refer to Using the Debug Session Control Window for information on the Debug Session Control window.  Refer to Using the Source Windows for information on the source windows. ═══ 11.5.1. Using the Debug Session Control Window ═══ The Debug Session Control window is the control window of the debugger and displays during the entire debugging session. This window is divided into two panes. One pane shows the threads for the program you are debugging and the corresponding process IDs, process names, kernel thread IDs, and processor number (when applicable). The other pane shows the components for the program that you are debugging.  For a description of the choices that are available from the File menu, refer to File Menu Choices.  For a description of the choices that are available from the Breakpoints menu, refer to Breakpoints Menu Choices.  For a description of the choices that are available from the Monitors menu, refer to Monitors Menu Choices.  For a description of the choices that are available from the Run menu, refer to Run Menu Choices.  For a description of the choices that are available from the Options menu, refer to Options Menu Choices  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. The Threads pane contains the threads and the state of the threads started by your program. These values can be used in conjunction with the KDB .p command to match an ICAT thread to a corresponding KDB slot. To display the state of a thread, select the plus icon to the left of the thread. The Thread Popup Menu contains choices to take you to different debugger windows. The popup menu is shown when you place the mouse pointer on a highlighted thread name and click mouse button 2. The following are the popup choices: Execution point Opens a source window containing the next line to be run. Registers Displays the Registers window. Call stack Displays the Call Stack window. Local variables Displays the Local Variables window. The Components pane shows the path name of the executable files that are associated with the OS2KRNL. To display a list of object files contained within an executable file, select the plus icon to the left of the executable file name. To open a source window of an object file, double-click on the object file name. To display a list of functions for a specific object file, select the plus icon to the left of the object file name. To open a source window of a specific function, double-click on the function name. You can display any object or function in a source window by double-clicking on the name in the Components pane or by highlighting the component name and selecting the View popup choice. To specify which components are shown in the Components list, select Options -> Window Settings -> Display style. The Display Style window displays. Disable the Show all components choice if you want only components compiled and linked with debugging data to be listed. If the choice is enabled, all components are listed. The Object or Function Popup Menu contains choices that allow you to display the object or function in a source window or set a function breakpoint. The popup menu is shown when you place the mouse pointer on a object or function name and click mouse button 2. The choices in the popup menu are: View Shows the object or function in a source window. Set function breakpoint Sets a function breakpoint to stop the execution of your program after calling a specific function in the current selected thread. Set breakpoint (every) Sets a breakpoint to stop the execution of your program on a function in all the threads. ═══ 11.5.1.1. File Menu Choices ═══ Select choices from the File menu of the Debug Session Control window to open a new source file, locate a particular function, open a source window that contains the next line to be executed, start a new debugging session, or end a debugging session. For a description of the File menu, refer to the following:  Open new source...  Find function...  Where is execution point  Initialization...  Close debugger. ═══ 11.5.1.1.1. Open new source... ═══ Displays the Open New Source window, which allows you to open a new source file. If you have multiple source files in your program, only one source file is initially displayed. Use the Open New Source window to open additional source files. To use the Open New Source window:  Type the name of the object file you want to open the source for in the Source entry field. For example, to look for the source used to compile A123.OBJ, type the following: A123 If you are unsure of the file name, select the File list... push button to view a list of the files that you can select.  Type the name of the executable file in the Executable entry field. The source files for the executable file display in the Source entry field.  Enable the All Executables check box if you want to search all the executable files. Disable the All Executables check box to search for a particular executable file.  Enable the Debugging Information Only check box if you want to search only the source files that contain debugging information.  Select the OK push button. ═══ 11.5.1.1.2. Find function... ═══ Displays the Find Function window, which allows you to open a source window to a particular function. To use the Find Function window:  Type the name of the function you want to search for in the Function entry field. If the function that you specify is not found, the following message displays: NO MATCHING FUNCTION FOUND This means it may be a static function or the function you specified does not exist. The debugger searches each object file for global functions that match the function name specified. If an object file contains the global function that was specified, then it will also search that file for any static function with the same name.  Enable the Debugging information only check box if you want to search only the object files that contain debugging information.  Enable the Case sensitive check box if you want to search for the string exactly as typed. Disable this check box if you want to search for both uppercase and lowercase characters.  Select the OK push button. ═══ 11.5.1.1.3. Where is execution point ═══ Opens a source window containing the next line to be executed. ═══ 11.5.1.1.4. Save thread list in file ═══ Saves the contents of the Threads pane into a file. The default file name is threads.out. To change the default file name, select Options -> Window settings -> Display style... from the Debug Session Control window. ═══ 11.5.1.1.5. Save component list in file ═══ Saves the contents of the Components pane into a file. The default file name is comps.out. To change the default file name, select Options -> Window settings -> Display style... from the Debug Session Control window. ═══ 11.5.1.1.6. Initialization... ═══ Displays the Initialization window, which allows you to start a debugging session by attaching to the OS2KRNL. Refer to Using the Initialization Window for more information. ═══ 11.5.1.1.7. Close debugger ═══ Ends the debugging session. When you select the Close debugger choice, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.5.1.2. Breakpoints Menu Choices ═══ Select choices from the Breakpoints menu to set breakpoints and to stop the execution of your program at any point. You can set as many breakpoints as you want. Breakpoints can be set from the Debug Session Control window or from the source windows. When you set a breakpoint in one source window, it is reflected in the other source windows. For a description of the Breakpoints menu, refer to the following:  Set line...  Set function...  Set address...  Set watchpoint...  Set load occurrence...  List  Delete All. ═══ 11.5.1.2.1. Set line... ═══ Displays the Line Breakpoint window, which allows you to set a line breakpoint to stop the execution of your program at a specific line number. The Line Breakpoint window is divided into two group headings: Required Parameters and Optional Parameters. The Required Parameters group heading contains the following:  Executable Entry Field To select a component from the Executable list: 1. Type the executable name in the entry field or open the Executable list by selecting the list button. This displays a drop-down combination box. 2. Highlight the executable where you want to set the breakpoint  Source Entry Field To select a component from the Source list: 1. Type the source name in the entry field or open the Source list by selecting the list button. This displays a drop-down combination box. 2. Highlight the source where you want to set the breakpoint.  Include File Entry Field If the source you selected has include files with executable statements, then the File list displays all the file names that contain executable lines. 1. Type the name of the file in the entry field or open the File list by selecting the list button. This displays a drop-down combination box. 2. Highlight the file where you want to set the breakpoint.  Line Entry Field To set a line breakpoint, type the line number in the Line entry field. The breakpoint is set on the line number. The Optional Parameters group heading contains the following:  Thread Entry Field To select a thread ID from the Thread list: 1. Open the Thread list by selecting the list button. This displays a drop-down combination box. 2. Highlight the thread where you want to set the breakpoint. Select Every, the default, to set a breakpoint in all of the active threads in your program. The Every choice is thread independent. Select one of the individual threads to set a breakpoint in one thread only. Threads are added to the Thread list as new threads are activated.  From Entry Field This field is used for location breakpoints, address breakpoints and load occurrence breakpoints. Type in a number to start activating the breakpoint the nth time the location is encountered.  To Entry Field This field is used for location breakpoints, address breakpoints and load occurrence breakpoints. Type in a number to stop activating the breakpoint after the nth time the location is encountered.  Every Entry Field This field is used for location breakpoints, address breakpoints and load occurrence breakpoints. Type in a number to indicate how often the breakpoint should be activated within the From and To range.  Expression Entry Field If you are setting an address, function, or line breakpoint, you can also type in an expression. The execution of the program stops only if this condition tests true. For example, you could type the following: (i==1) || (j==k) && (k!=5) Note: Variables in a conditional expression associated with a function breakpoint are limited to any static or global variables that are known to the called function when the function is called. Local variables and automatic variables will not evaluate correctly. The maximum length of the condition is 256 characters.  Defer breakpoint Check Box Enable the Defer breakpoint check box if you want to set a breakpoint in a module that is not currently loaded. If you set a deferred line breakpoint and the line is located in a template, the debugger sets the line breakpoint in all of the templates when the module is loaded. When a module is loaded and a deferred breakpoint has been set in the module, the state of the breakpoint changes from deferred to active. When a module is freed, any breakpoints that were set in the module change from the active state to deferred state. If you enter an invalid source, file or line number, the debugger will be unable to activate the breakpoint when the module is loaded. Therefore, the invalid breakpoint will remain in the deferred state even after the module is loaded. ═══ 11.5.1.2.2. Set function... ═══ Displays the Function Breakpoint window, which allows you to set a function breakpoint to stop the execution of your program when the first instruction of the function is encountered where the breakpoint has been set. The entry fields in this window are the same as in the Line Breakpoint window except for the following:  Function Entry Field Type the name of the function where you want to set the breakpoint or select a function from the Function list. To select a function, do the following: 1. Open the Function list by selecting the list button. This displays a drop-down combination box. 2. Highlight the function where you want to set the breakpoint. If a function is overloaded, then a window displays with a list of all the overloaded function names. Select the appropriate function from the list.  Debugging information only Check Box Enable this check box if you want to search only the object files that contain debugging information.  Case sensitive Check Box Enable this check box if you want to search for the string exactly as typed. Disable this check box if you want to search for both uppercase and lowercase characters. For a description of the types of data you can enter in the entry fields under the Optional Parameters group heading, refer to Set line.... ═══ 11.5.1.2.3. Set address... ═══ Displays the Address Breakpoint window, which allows you to set an address breakpoint to stop the execution of your program at a specific address. The entry fields in this window are the same as in the Line Breakpoint window except for the following:  Address or Expression Entry Field Type the name of the address or expression in the Address or Expression entry field. For example, to set an address breakpoint for the address 0x000A1FCC, you would type one of the following in the Address entry field: 0x000A1FCC or A1FCC The 0x is optional. For a description of the types of data you can enter in the entry fields under the Optional Parameters group heading, refer to Set line.... ═══ 11.5.1.2.4. Set watchpoint... ═══ Displays the Watchpoint window, which allows you to set a watchpoint to stop the execution of your program when contents of memory at a given address are referenced, when an instruction is fetched from a particular address, or when an I/O port at a particular address is referenced. Use the Watchpoint window to set a watchpoint.  Address (or Expression) or Port # Entry Field Type a hexadecimal address or port or an expression that can be evaluated to a hexadecimal address. Note: If you type ABC in the Address (or Expression) or Port # entry field, and there is a variable named ABC, the value of the variable is used instead of the hex value ABC. Also, you can type &a in the Address (or Expression) or Port # entry field to set the watchpoint on the address of a variable a. For example, type the following in the Address (or Expression) or Port # entry field to set a watchpoint for the address A1FCC. A1FCC Type the following in the Address (or Expression) or Port # entry field to set a watchpoint for the expression &variable. &variable  Bytes to Monitor Radio Buttons The debugger will monitor 1, 2, or 4 bytes for the type of watchpoint operation that you select. This choice is made for you on the Instruction fetch and I/O Port types.  Watchpoint Radio Buttons The debugger supports four types of watchpoints. They are as follows: I/O Port Causes a break when the port address is read from or written to. Write Causes a break when the address is written to. Read or write Causes a break when the address is read from or written to. Instruction fetch Causes a break when the instruction at that address is fetched. Warning: If you set a watchpoint that is on the call stack, you should remove the watchpoint before leaving the routine associated with the watchpoint. Otherwise, when you return from the routine, the routine's stack frame will be removed from the stack leaving the watchpoint intact. Any other routine that gets loaded on the stack will then contain the watchpoint. You can set up to four watchpoints. For a description of the types of data you can enter in the entry fields under the Optional Parameters group heading, refer to Set line.... ═══ 11.5.1.2.5. Set load occurrence... ═══ Displays the Load Occurrence Breakpoint window, which allows you to set a load occurrence breakpoint to stop the execution of your program when a specific module is loaded. To use the Load Occurrence Breakpoint window, type the name of the module in the Module Name entry field. Execution stops when the module is loaded.  Module Name Entry Field To set a load occurrence breakpoint when MY.DLL is loaded, you would type one of the following in the Module Name entry field: MY or MY.DLL Note: If the CAT_MODULE_LIST environment variable has been defined, and the module's name is not contained in the CAT_MODULE_LIST, the module will not be reported. If the module can not be found in the module search path, the module name will not be accepted. See Debugger properties... for information on identifying modules. For a description of the types of data you can enter in the entry fields under the Optional Parameters group heading, refer to Set line.... ═══ 11.5.1.2.6. List ═══ Displays the Breakpoints List window, which lists all the breakpoints that have been set. It also shows the state of each breakpoint. Use the Breakpoints List window to display a list of the breakpoints that have been set. The following information is also provided for each breakpoint.  The enablement state  The type of breakpoint  The position of the breakpoint  The conditions under which the breakpoint is activated. For more information on the Breakpoints List window, refer to Using the Breakpoints List Window. ═══ 11.5.1.2.7. Delete All ═══ Deletes all the breakpoints that have been set. ═══ 11.5.1.3. Monitors Menu Choices ═══ Select choices from the Monitors menu of the Debug Session Control window to open other debugging windows such as monitors, call stack, registers, and storage. The choices listed under the Monitors menu are also accessible from the tool bar of the source windows. Call stack Displays the Call Stack window, which allows you to monitor the call stack for a particular thread. This window is described in Using the Call Stack Window. Registers Displays the Registers window, which allows you to monitor registers and flags for a particular component or thread. This window is described in Using the Registers Window. Storage Displays the Storage window, which allows you to monitor the storage in your program. This window is described in Using the Storage Window. Local variables Displays the Local Variables window, which allows you to display the local variables for the program's current function. This window is described in Using the Local Variables Window. Passthru Allows you to send commands to KDB and displays the formatted KDB response. ═══ 11.5.1.4. Run Menu Choices ═══ Select choices from the Run menu to execute your program or stop execution. For a description of the Run menu, refer to the following:  Run  Halt  Hide Debugger on Run. ═══ 11.5.1.4.1. Run ═══ Executes the program from the current line until a breakpoint is encountered or the program ends. ═══ 11.5.1.4.2. Halt ═══ Interrupts the program you are debugging. ═══ 11.5.1.4.3. Hide Debugger on Run ═══ Minimizes the debugger windows while your application is running. ═══ 11.5.1.5. Options Menu Choices ═══ Select choices from the Options menu to control how the debugger windows display. For a description of the Options menu, refer to the following:  Window settings->  Debugger settings->. ═══ 11.5.1.5.1. Window settings-> ═══ Use the Window settings cascading choices to modify the characteristics of the Debug Session Control window. Fonts Displays the Fonts window, which allows you to select the font you want to use for the text displayed in the Debug Session Control window. Display style... Displays the Display Style window, which allows you to select the settings you want to use. Restore defaults Resets all of the window settings to their original settings. Tool buttons Enables or disables tool buttons. Hover help Enables or disables the hover help. Infoarea Enables or disables the information area. . ═══ 11.5.1.5.2. Debugger settings-> ═══ Use the Debugger settings cascading choice to set various debugger options that control how the debugger windows display. These settings affect the behavior of the debugger and remain in effect for the duration of the debugging session. ═══ 11.5.1.5.3. Debugger properties... ═══ Displays the Debugger Properties window, which allows you to select how the threads and source files initially display. This window contains the following three tabs:  Source  Remote  Modules. The Remote page displays by default if you open the window using the Initialization window. If not, the Source page displays. When you select the Remote tab, the following page displays: Use this window to do the following tasks:  Set the communication baud rate for the debugger.  Set the communication port.  Set the communication baud rate for KDB on initialization and after exiting.  Set the path where the debugger finds source.  Set the path where the debugger finds the debug binary modules.  View the communication mode (ASYNC_SIGBRK is all that is currently available).  Set modem communication information, if used.  Set a string to initialize KDB.  Set the option for recursive subdirectory searching of the source and binary paths. This window's values are dithered and cannot be changed after communication has been established with the victim machine. ICAT Baud Rate Group Heading This group of radio buttons allows you to select communication baud rates from 9600 to 115200. Ensure that your machine can handle rates greater than 19200 if you choose them. You must have buffered UARTs on both machines in this case. If you choose a rate of 115200, your host machine must have a COM.SYS different than the default supplied with OS/2. KDB Baud Rate Group Heading This group of radio buttons allows you to select the initial (setup) communication rate that the debugger uses to communicate with KDB. If any rate other than default is selected, that same rate will be used to reset the victim machine's communication port when the debugger is exited. Communications Port Spin Button This spin button allows you to select the communication port number for the debugger on the host machine. Environment Variables Group Heading These entry fields correspond respectively to the following environment variables:  CAT_HOST_SOURCE_PATH  CAT_HOST_BIN_PATH  CAT_COMMUNICATION_TYPE  CAT_DIAL  CAT_MODEM_INIT  CAT_KDB_INIT By adjusting these fields, you can alter your communication and serial paths dynamically before communication is established with the victim machine. See Setting Environment Variables for detailed information on environment variables. Path Recursion Check Box This check box, when selected, forces the debugger to search all source and binary path subdirectories recursively. When you select the Source tab, the following page displays: Use this window to determine:  when a source window first displays during a debugging session.  how to process a source window from which execution has just left. The window can remain displayed, be turned into an icon, or be discarded. Old source disposition Group Heading In the course of debugging, these selections allow you to control the behavior of source windows from which execution has just left. The Old Source Disposition radio buttons control the behavior of source windows within a thread. The dispositions that the views can take are: Keep Leaves open the source windows that contain the components and threads that you select with Display at stop. Minimize Changes into icons the views that contain the components and threads that you select with Display at stop. Discard Disposes of the views that contain the components and threads that you select with Display at stop. Settings Group Heading You can choose to display more than one source window for a particular source file. Enable the Multiple views check box if you want to have multiple source windows open at the same time. Mouse button 2 behavior Group Heading Select the radio button that represents the action that you want mouse button 2 to perform. When you select the Modules tab, the following page displays: Use this window to add a module name to or delete a module name from the CAT_MODULE_LIST environment variable. See Setting Environment Variables for detailed information on this environment variable. Modules List Box This contains a list of modules which the debugger obtains information about if or when they are loaded. If a module is loaded and it is not in the list, the debugger ignores the module. New Module Entry Field Type the name of the module that you want to add or delete. Select the appropriate push button to perform this task. ═══ 11.5.1.5.4. Monitor properties... ═══ Displays the Monitor Properties window, which allows you to select the settings for monitoring variables or expressions. Use the Monitor Properties window to set the following:  The window into which the variable or expression being monitored is placed.  For popup expression windows, how long the monitor windows display. Monitor Location Group Heading Choose one of the following radio buttons to select the monitor window that opens when you select a variable or expression to monitor. The selections you can make, and the corresponding windows, are: Popup Display the variable or expression in a popup expression window. Private monitor Display the variable or expression in the Private Monitor window. Program monitor Display the variable or expression in the Program Monitor window. Storage monitor Display the variable or expression in the Storage window. Save File Entry Field Use this field to identify the file where all monitor windows will write their contents when the Save to file choice is selected. Number of elements to show entry field Use this field to identify the maximum number of structure or class elements that will be displayed at one time for a given variable in the monitors. Enable bubble variables check box Select this option if you want a bubble value for the contents of a variable to appear as you place the mouse or the variable in the Source, Disassembly, and Mixed view windows. Popup Duration Group Heading If you select Popup from the Monitor Location group heading, select one of the following radio buttons to specify how long the popup expression window displays: Step/run The monitor window closes when the next step command or Run is executed. New source The monitor window closes when execution stops in a new source file. Permanent This monitor window is associated with a specific source window and closes when the associated source window closes. ═══ 11.5.1.5.5. Default data representation-> ═══ Use the Default data representation cascading choices to change the representation for a data type in a specific language. Select a language to change the default representation of the selected data type. For example, you can change the default representation for an integer in the C language from decimal to hexadecimal. Select the System choice to change the default representation of the math coprocessor registers. This choice is language independent. ═══ 11.5.1.5.6. Program profiles-> ═══ Use the Program profiles cascading choices to enable program profiles, delete program profiles, or change the location where the program profiles are stored, Program profiles are used to restore the debugger windows and breakpoints when debugging a program more than once. They are stored separately for each program debugged. The file extension for the files that contain this information is @DR. Select information Select what information you want saved in the program profiles. Delete program profiles Delete program profiles for a program that you have debugged. Change location Change the location of the file that holds the program profiles. This also moves any existing profiles to the new directory. ═══ 11.5.1.5.7. Save debugger window positions ═══ When you select this choice, the window positions and sizes are saved for each type of debugger window currently open. ═══ 11.5.1.5.8. Global font change ═══ Select the Global font change choice to change the font in all the debugger windows. When you select Global font change, the Font Selection window displays. ═══ 11.5.1.5.9. Enable window cascading ═══ Select the Enable window cascading choice to have the debugging windows overlap each other. When you enable this choice, successive windows that are opened overlap each other on the screen. However, they are cascaded so that you can see the underlying windows. When this choice is disabled, successive windows cover previously displayed windows so that you do not see the underlying windows. ═══ 11.5.1.5.10. Display tool buttons ═══ Select the Display tool buttons choice if you want tool buttons to be shown in all the debugger windows. ═══ 11.5.1.5.11. Display hover help ═══ Select the Display hover help choice if you want hover help to be shown in all the debugger windows. ═══ 11.5.1.5.12. Display infoarea ═══ Select the Display infoarea choice if you want the information area to be shown in all the debugger windows. ═══ 11.5.1.5.13. Display tool buttons on title bar ═══ Select the Display tool buttons on title bar choice if you want the tool buttons to be shown on the title bar of each window. ═══ 11.5.1.6. Windows Menu Choices ═══ Select the Windows menu from the Debug Session Control window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.5.1.7. Help Menu Choices ═══ Select choices from the Help menu of the Debug Session Control window to display the various types of help information. Help index Displays an alphabetical index of all available debugger help topics. General help Displays help information for the active window. Using help Describes how to use the help facility. Product information Displays product information. ═══ 11.5.2. Using the Source Windows ═══ A source window allows you to view the program you are debugging. You can look at your source in one of the following windows:  Source  Disassembly  Mixed A source window is thread specific. Executable lines initially display in blue, and non-executable lines initially display in black. Lines with breakpoints have a red prefix, and lines with disabled breakpoints have a green prefix. The Source window displays the source code for the current function of the program being debugged. If source is available, the Source window displays with the Debug Session Control window when the debugging session starts. Otherwise, the Disassembly window displays. The Disassembly window displays the assembler instructions for your program without symbolic information. The Mixed window displays your program as follows:  Each line of source code is prefixed by its line number as in the Source window.  Each disassembled line is prefixed by an address as in the Disassembly window.  Source comment lines also display.  The lines of source code are treated as comments within the lines of disassembly code. You can only set breakpoints or run your program on lines of disassembly code. Note: The Mixed window cannot be opened if the source code is not available.  Refer to File Menu Choices for a description of the File menu items in the Source window.  Refer to View Menu Choices for a description of the View menu items in the Source window. ═══ 11.5.2.1. File Menu Choices ═══ The choices in the File menu are a subset of those listed under the File menu of the Debug Session Control window. Refer to File Menu Choices for a description of the choices. ═══ 11.5.2.2. View Menu Choices ═══ Select choices from the View menu to locate strings of text, scroll to a particular line, view include files, change the text file, or select a different view of your program. For a description of the View menu, refer to the following:  Find Window  Find next  Scroll to line number...  Select include file  Change text file  Source  Disassembly  Mixed. ═══ 11.5.2.2.1. Find Window ═══ Displays the Find window which allows you to search for a text string. To use the Find window to search for a text string: 1. Type the text string you want to search for in the Text entry field. 2. Enable the Case sensitive check box if you want to search for the string exactly as typed. Disable this check box to search for uppercase and lowercase characters. 3. Select the OK push button. The search string can have alphabetic and numeric characters, a maximum of 256 characters, and uppercase and lowercase characters. ═══ 11.5.2.2.2. Find next ═══ Allows you to search for the next occurrence of the text string that you typed in the Find window. ═══ 11.5.2.2.3. Scroll to line number... ═══ Displays the Scroll to Line Number window, which allows you to go to a particular line in your program or set a line breakpoint. To use the Scroll to Line Number window to scroll to a specific line: 1. Type the line number you want to scroll to in the Line entry field. 2. Select the OK push button to scroll to that line. Note: If the Source window is active, just type a number and the Scroll to Line Number window automatically displays. To use the Scroll to Line Number window to set a breakpoint: 1. Type the line number you want to set the breakpoint on in the Line entry field. 2. Select the Breakpoint push button to set the breakpoint on the specified line number. ═══ 11.5.2.2.4. Select include file ═══ Displays the Select Include window that allows you to view the files that are included in your program. To use the Select Include window: 1. Select the include file. The include file name is highlighted. 2. Select the OK push button. The selected include file view displays. ═══ 11.5.2.2.5. Change text file ═══ Displays the Change Text File window, which allows you to specify a file name to be used as the source in the current view. This is useful if the debugger found the incorrect source file for your program so that you can specify the use of a different source file from a different directory. Use the Change Text File window to replace the path name or file name of the program you are debugging with a new path name or file name. To replace the file name: 1. Type the new path name and file name in the File entry field. 2. Select the appropriate push button. ═══ 11.5.2.2.6. Source ═══ Displays the Source window, which displays the source code for the current function of the program being debugged. Refer to Using the Source Windows for more information. ═══ 11.5.2.2.7. Disassembly ═══ Displays the Disassembly window, which displays the assembler instructions for your program without symbolic information. Refer to Using the Source Windows for more information. ═══ 11.5.2.2.8. Mixed ═══ Displays the Mixed window, which is a combination of the Source and Disassembly windows. Refer to Using the Source Windows for more information. ═══ 11.5.2.3. Breakpoints Menu Choices ═══ The choices listed under the Breakpoints menu are the same as those listed for the Debug Session Control window with the addition of the Toggle at current line choice. The Toggle at current line choice sets a breakpoint on the current line or deletes an existing breakpoint from the current line. For a description of the other menu choices, refer to Breakpoints Menu Choices. ═══ 11.5.2.4. Monitors Menu Choices ═══ Select choices from the Monitors menu of the source windows to monitor expressions or variables and view the other debugger windows such as call stack, registers, and so on. The next four choices listed under the Monitors menu are also accessible from the tool bar in the Debug Session Control Window. ═══ 11.5.2.4.1. Monitor expression... ═══ Displays the Monitor Expression window, which allows you to monitor expressions or variables and add them to various monitor windows. Use the Monitor Expression window to type the name of the expression you want to monitor. This window lists the following contextual information:  The component you are in.  The active line of the source code, which is highlighted.  The view of the module that is active.  The thread you are in. To specify an expression to be monitored: 1. Type the name of the variable or expression you want to monitor in the Expression entry field. 2. Select the appropriate radio button for the location from where you want to monitor your expression. Note: The expression displays as specified in the Monitor Properties window. To change the default location, select Monitor properties from the Debugger settings choice from the Options menu in the source windows or the Debug Session Control window. ═══ 11.5.2.4.2. Call stack ═══ Displays the Call Stack window, which allows you to monitor the call stack for a particular thread. This window is described in Using the Call Stack Window. ═══ 11.5.2.4.3. Registers ═══ Displays the Registers window, which allows you to monitor registers and flags for a particular component or thread. This window is described in Using the Registers Window. ═══ 11.5.2.4.4. Storage ═══ Displays the Storage window, which allows you to monitor the storage in your program. This window is described in Using the Storage Window. ═══ 11.5.2.4.5. Local variables ═══ Displays the Local Variables window, which allows you to display the local variables for the program's current function. This window is described in Using the Local Variables Window. ═══ 11.5.2.4.6. Passthru ═══ Displays the Passthru window, which allows you to send commands to KDB and displays the formatted KDB response. This window is described in Using the Passthru Window. ═══ 11.5.2.5. Run Menu Choices ═══ Select choices from the Run menu to perform step commands, run your program or hide debugger windows. For a description of the Run menu, refer to the following:  Step over  Step into  Step debug  Step return  Run  Halt  Run to location  Jump to location  Hide Debugger on Run. ═══ 11.5.2.5.1. Step over ═══ Executes the current, highlighted line in the program. If the line includes a function call, the debugger does not regain control until the function has returned. ═══ 11.5.2.5.2. Step into ═══ Executes the current, highlighted line in the program. If the line includes a function call, the debugger regains control before the first statement in the function has been performed. ═══ 11.5.2.5.3. Step debug ═══ Executes the current, highlighted line in the program. The debugger steps over any function for which debugging information is not available (for example, library and system routines) and steps into any function for which debugging information is available. ═══ 11.5.2.5.4. Step return ═══ Automatically executes the lines of code up to, and including, the return statement of the current function. ═══ 11.5.2.5.5. Run ═══ Runs the program. Control returns to the debugger when the program ends or execution stops at an enabled breakpoint. ═══ 11.5.2.5.6. Halt ═══ Interrupts the program you are debugging. ═══ 11.5.2.5.7. Run to location ═══ Executes your program from the current line up to the line that is highlighted or black in the prefix area. To use the Run to location choice: 1. Single-click in the prefix area of the line you want to become the current line. The prefix area turns black. 2. Select the Run to location choice. The program runs up to the line that you marked. The Run to location choice stops only on executable lines. If a highlighted line is not executable, the run is not performed. ═══ 11.5.2.5.8. Jump to location ═══ Select the Jump to location choice to change the current line in your program without executing the lines between the present current line and the new current line. To use the Jump to location choice: 1. Single-click in the prefix area of the line you want to become the current line. The prefix area turns gray. 2. Select the Jump to location choice. The current line is changed, and the lines between are not executed. The Jump to location choice stops only on executable lines. If a highlighted line is not executable, the jump is not performed. Warning: Jumping out of the current function may corrupt the call stack and cause unpredictable results. ═══ 11.5.2.5.9. Hide Debugger on Run ═══ For a description of this choice, refer to Hide Debugger on Run. ═══ 11.5.2.6. Options Menu Choices ═══ Select choices from the Options menu to control how the debugger windows display. For a description of the Options menu, refer to the following:  Window settings->  Debugger settings->. ═══ 11.5.2.6.1. Window settings-> ═══ Use the Window settings cascading choices to modify the characteristics of the source windows. Colors... Displays the Source Window Controls window, which allows you to change the color in the windows. Fonts... Displays the Font window, which allows you to change the font in the windows. Restore defaults Resets all of the window settings to their original settings. Notebook Displays the source windows in a notebook format. Tool buttons Enables or disables tool buttons. Hover help Enables or disables hover help. Infoarea Enables or disables the information area. ═══ 11.5.2.6.2. Debugger settings-> ═══ Use the Debugger settings cascaded choices to set various debugger options that control how the debugger windows display. These settings affect the behavior of the debugger and remain in effect for the duration of the debugging session. Refer to Debugger settings-> for a description of the choices. ═══ 11.5.2.7. Windows Menu Choices ═══ Select the Windows menu of the source windows to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.5.2.8. Help Menu Choices ═══ Select choices from the Help menu of the source windows to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.6. Introducing the Other Debugging Windows ═══ This section introduces the basic debugging windows. These are the windows that are normally located in the Monitors menu of the Debug Session Control and the source windows. The windows include call stack, registers, storage, local variables, and passthru.  Using the Call Stack Window  Using the Registers Window  Using the Storage Window  Using the Monitor Windows  Using the Breakpoints List Window ═══ 11.6.1. Using the Call Stack Window ═══ The Call Stack window lists all of the active functions for a particular thread including system calls. Each Call Stack window displays call stack information for one thread only. When the state of the program changes, such as when you execute the program or you update displayed data, the Call Stack window changes to reflect the current state. You can double-click on any call stack entry to display the source code for that entry. The line that calls the next stack entry is highlighted. The remaining stack size shows the bytes left in the stack for the thread. Note: The stack may not display correctly if the code does not follow standard calling conventions or if you step into optimized code. To display the Call Stack window, select Call Stack from the Monitors menu or select the Call Stack button from the tool bar.  For a description of the choices that are available from the File menu, refer to File Menu Choice.  For a description of the choices that are available from the Options menu, refer to Options Menu Choices.  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. ═══ 11.6.1.1. File Menu Choice ═══ Use the choice from the File menu to end the debugging session. The Close debugger choice allows you to end the current debugging session. When you select Close debugger, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.6.1.2. Options Menu Choices ═══ Use choices from the Options menu to select the font you want for the Call Stack window and control how the items on the call stack display. ═══ 11.6.1.2.1. Fonts... ═══ Displays the Font window, which allows you to select the type of font you want to use for the Call Stack window. ═══ 11.6.1.2.2. Display style... ═══ Displays the Display Style window, which allows you to select the type of information you want displayed in the call stack and choose how the items are to be displayed. To use the Display Style window:  Select one or more of the items under Select Items to display for each call stack entry. Each item causes a new column to be added to the Call Stack window. The following items are available: Entry No Represents the position of the call stack item in the list. Entry level 1 is the first function started. Function Lists program name or the address of the function call that created the new call stack entry. Source Lists the component name that contains the function. The name displayed corresponds with a name listed in the Components list box in the Debug Session Control window. Ring Tells the ring level (0, 2, or 3) at which this frame is established. Return Address Indicates where execution will return in that function. Recursion Lists the recursion level. 0 is the first invocation. Frame Address Indicates the start of the call stack frame for that function. Variable Base Indicates the end of the call stack frame for that function. Size Indicates the size of the call stack frame for that function.  Select one of the following Growth Direction radio buttons to determine how new items are displayed on the call stack. Up Displays new items at the top of the Call Stack window. Down Displays new items at the bottom of the Call Stack window. Enable the Unwind rings check box to have the debugger unwind the call stack across ring (privilege) transitions. This allows you to view the call sequence from user applications into the kernel. ═══ 11.6.1.2.3. Restore defaults ═══ Select the Restore defaults choice to reset all of the window settings to their original settings. ═══ 11.6.1.2.4. Tool buttons ═══ Select the Tool buttons choice to enable or disable tool buttons. If enabled, the tool buttons are displayed in the window. If disabled, the tool buttons are not displayed. ═══ 11.6.1.2.5. Hover help ═══ Select the Hover help choice if you want hover help to be shown. ═══ 11.6.1.2.6. Infoarea ═══ Select the Infoarea choice if you want the information area to be shown in the window. ═══ 11.6.1.3. Windows Menu Choices ═══ Select the Windows menu of the Call Stack window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.6.1.4. Help Menu Choices ═══ Select choices from the Help menu of the Call Stack window to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.6.2. Using the Registers Window ═══ The Registers window lists all the processor registers for a particular thread. The contents of all of the registers except floating-point registers are displayed in hexadecimal. To update a register, double-click on the register and a multiple-line entry field displays. Type over the contents and press Enter. In the Registers window, floating-point registers display as floating-point decimal numbers. They can be updated with a floating-point decimal number or with a hexadecimal string that represents a floating-point number. To display the processor registers and flags, select Registers from the Monitors menu or select the Registers button from the tool bar.  For a description of the choices that are available from the File menu, refer to File Menu Choices.  For a description of the choices that are available from the Options menu, refer to Options Menu Choice.  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. ═══ 11.6.2.1. File Menu Choices ═══ Use the choice from the File menu to end the debugging session. The Close debugger choice allows you to end the current debugging session. When you select Close debugger, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.6.2.2. Options Menu Choice ═══ Use the choices from the Options menu to select the font you want for the Registers window, select the items you want shown in the window, restore the defaults, and enable or disable the tool buttons. ═══ 11.6.2.2.1. Fonts... ═══ When you select Fonts..., the Font window displays. From this window, select the font you want shown in the Registers window. ═══ 11.6.2.2.2. Display style... ═══ When you select the Display style... choice, the Display Style window is displayed, which allows you to select the type of information you want displayed in the Registers window. Groups Group Heading This specifies the five types of registers that the debugger displays. General registers are as follows:  EIP  EAX  EBX  ECX  EDX  EBP  ESP  ESI  EDI Status Flags registers include the PC and the EFLAGS registers. Segment registers are as follows:  CS  DS  ES  FS  GS  SS The PC register is the linear address of the current instruction. The FP stack registers are those defined by the math coprocessor. The Debug registers include miscellaneous processor registers such as CR0 and DR0. Orientation Heading The registers groups are separated with either vertical or horizontal split bars. Select the radio button which represents how you want the groups separated. Enable the Column titles check box if you want the registers group to have a title. For example, General. Enable the Save split bars check box if you want to save the adjustment of the split bars for the next time you open the Registers window. ═══ 11.6.2.2.3. Restore defaults ═══ Select the Restore defaults choice to reset all of the window settings to their original settings. ═══ 11.6.2.2.4. Tool buttons ═══ Select the Tool buttons choice to enable or disable tool buttons. If enabled, the tool buttons are displayed in the window. If disabled, the tool buttons are not displayed. ═══ 11.6.2.2.5. Hover help ═══ Select the Hover help choice to enable or disable hover help. If enabled, hover help is displayed in the window. If disabled, hover help is not displayed. ═══ 11.6.2.2.6. Infoarea ═══ Select the Infoarea choice to enable or disable the information area. If enabled, the infoarea is displayed in the window. If disabled, the infoarea is not displayed. ═══ 11.6.2.3. Windows Menu Choices ═══ Select the Windows menu from the Registers window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.6.2.4. Help Menu Choices ═══ Select choices from the Help menu of the Registers window to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.6.3. Using the Storage Window ═══ The Storage window shows the storage contents and the address of the storage. Multiple storage windows can display the same storage. When you run a program or update displayed data, the Storage window is updated to reflect the change. To update the storage contents and all affected windows, double-click in the multiple-line entry field that displays. Type over the contents of the field. To specify a new address location, type over the address field in the Storage window. The window scrolls to the appropriate storage location. To display the Storage window, select Storage from the Monitors menu or select the Storage button from the tool buttons.  For a description of the choices that are available from the File menu, refer to File Menu Choice.  For a description of the choices that are available from the Options menu, refer to Options Menu Choices.  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. ═══ 11.6.3.1. File Menu Choice ═══ Use the choice from the File menu to end the debugging session. The Close debugger choice allows you to end the current debugging session. When you select Close debugger, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.6.3.2. Options Menu Choices ═══ Use choices from the Options menu to monitor expressions, control how the items in the storage window display, and select the font you want for the Storage window. ═══ 11.6.3.2.1. Fonts... ═══ Displays the Font window, which allows you to select the type of font you want to use for the Storage window. ═══ 11.6.3.2.2. Display style... ═══ Displays the Display Style window, which allows you to select the format for the storage contents and storage addresses and change the columns per line that display. Use the Storage Display Style window to select the parameters that control how the storage contents display and set how the storage addresses display. Content Style Group Heading Select how you want the storage contents displayed. You can select from several storage display styles. To select the storage content style: 1. Scroll to the content style you want. 2. Select the content style. 3. The style becomes highlighted. Address Style Group Heading Select the available address style. To select the address style: 1. Select the address style. 2. The address style becomes highlighted. Columns per line Entry Field Select the number of columns per line you want displayed in the Storage window. Use the Up or Down arrow keys to select the number of columns you want displayed in the Storage window. The available number of columns per line are 1-16. Enable the Column titles check box if you want to display the titles of the columns in the Storage window. ═══ 11.6.3.2.3. Fill Storage... ═══ Displays the Storage Fill Dialog window, which allows you to fill memory with a specific character or hexadecimal pattern. To fill memory with a specific character or hexadecimal pattern: 1. Type the starting address of the memory area to fill in the Starting Address entry field. 2. Type the ending address of the area or the length of the area to fill in the corresponding entry field. 3. Select either Character or Hexadecimal as the string type. 4. Type the fill string in the Repeated String, Character or Byte(s) field. This string is repeated as necessary to fill the specified area. ═══ 11.6.3.2.4. Monitor expression... ═══ Displays the Monitor Expression in Storage window, which allows you to type in the name of the expression you want to monitor. To specify an expression, type the name or address of the variable or expression you want to monitor in the Expression entry field. The expression evaluator used is based on the context. For example if you display the Storage window by selecting the Monitor expression... choice from the Monitors menu, the evaluator used is based on the context in the Monitor Expression window. However, if you display the Storage window first and then select the Monitor expression... choice from the Options menu of the Storage window, the evaluator used is based on the context of the stopping thread. Note: You cannot look at variables that have been defined using the #DEFINE preprocessor directive. If the variable is not in scope when the monitor is opened, the default address is displayed. If the variable goes out of scope, the address is changed to a hex constant. If you enable the Enabled monitor check box, the monitor updates the stop value of the program to the actual value in storage. However, a disabled monitor suspends this updating and reflects the stop value or the value held when the monitor was disabled. ═══ 11.6.3.2.5. Restore defaults ═══ Select the Restore defaults choice to reset all of the window settings to their original settings. ═══ 11.6.3.2.6. Tool buttons ═══ Select the Tool buttons choice if you want tool buttons. ═══ 11.6.3.2.7. Hover help ═══ Select the Hover help choice if you want hover help. ═══ 11.6.3.2.8. Infoarea ═══ Select the Infoarea choice if you want the information area to be shown in the window. ═══ 11.6.3.3. Windows Menu Choices ═══ Select the Windows menu from the Storage window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.6.3.4. Help Menu Choices ═══ Select choices from the Help menu of the Storage window to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.6.4. Using the Local Variables Window ═══ The Local Variables window monitors the local variables (static, automatic, and parameters) for the current execution point in the program. The contents of the Local Variables window change each time your program enters or leaves a function.  For a description of the choices that are available from the File menu, refer to File Menu Choice.  For a description of the choices that are available from the Edit menu, refer to Edit Menu Choices.  For a description of the choices that are available from the Options menu, refer to Options Menu Choices.  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. ═══ 11.6.4.1. File Menu Choice ═══ Use the choice from the File menu to end the debugging session. The Close debugger choice allows you to end the current debugging session. When you select Close debugger, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.6.4.2. Edit Menu Choices ═══ Select the choices from the Edit menu of the Local Variables window to delete, select, deselect, show other elements, or change representation of the variables. ═══ 11.6.4.2.1. Delete ═══ Select the Delete choice to delete variables or expressions that are being monitored from a monitor window. To delete a variable or expression from a monitor window: 1. Select the variable or expression using your mouse pointer. The variable or expression becomes highlighted. 2. Select the Delete choice from the Edit menu. ═══ 11.6.4.2.2. Select all ═══ Select the Select all choice to select all the expressions in the window. ═══ 11.6.4.2.3. Deselect all ═══ Select the Deselect all choice to cancel the selection of all the expressions in the window, ═══ 11.6.4.2.4. Other elements... ═══ Select the Other elements choice to view the next n items (classes, arrays, or structures) that are related to the variable or expression that you are monitoring. Currently, n defaults to 50. You can override this number by setting the environment variable DEBUG_NUMBEROFELEMENTS. For example, you would type the following to change it to 100: set DEBUG_NUMBEROFELEMENTS=100 You can also change this number dynamically in the Number of elements to show field by selecting Options -> Debugger settings -> Monitor properties from the Debug Session Control window or any of the source windows. ═══ 11.6.4.2.5. Representation-> ═══ Use the Representation cascading choices to display the contents of the variable in a new representation. The types of representation that display on the menu depend on the data type of the variable you are monitoring. The following are possible representations: Hexadecimal Displays the contents of the monitored variable in hexadecimal notation. Decimal Displays the contents of the monitored variable in decimal notation. String Displays the contents of the monitored variable as a character string. Hexadecimal pointer Displays the contents of the monitored variable as a hexadecimal pointer. Decimal pointer Displays the contents of the monitored variable as a decimal pointer. Array Displays the contents of the monitored variable as an array. Floating/point Displays the contents of the monitored variable in floating-point notation. Character Displays the contents of the monitored variable in character form. Note: Floating-point registers or variables display as either a floating-point decimal number or as a hexadecimal string. However, they cannot be updated with a hexadecimal string that represents a floating-point number. If you need to update a floating-point variable with a hexadecimal representation of a floating-point number, you must step through the Disassembly window to see when the variable loads into a register and then change the value in the Registers window. ═══ 11.6.4.2.6. Copy to clipboard ═══ Select the Copy to clipboard choice to copy the selected (highlighted) local variable data to the clipboard. ═══ 11.6.4.2.7. Save window in file ═══ Select the Save window in file choice to save the Local Variables window contents in a file. You can choose the file name by selecting Options -> Debugger settings -> Monitor properties from the Debug Session Control window or any of the source windows and filling in the Save File entry field. ═══ 11.6.4.3. Options Menu Choices ═══ Select choices from the Options menu to control how the contents of variables display and set debugger options. ═══ 11.6.4.3.1. Fonts... ═══ Displays the Font window, which allows you to select the type of font you want to use for the Local Variables window. ═══ 11.6.4.3.2. Restore defaults ═══ Select the Restore defaults choice to reset all of the window settings to their original settings. ═══ 11.6.4.3.3. Show context ═══ Select the Show context choice to display the contextual information for the variable you are monitoring. The following information displays:  Source  File  Line  Thread. ═══ 11.6.4.3.4. Tool buttons ═══ Select the Tool buttons choice if you want tool buttons. ═══ 11.6.4.3.5. Hover help ═══ Select the Hover help choice if you want hover help. ═══ 11.6.4.3.6. Infoarea ═══ Select the Infoarea choice if you want the information area to be shown in the window. ═══ 11.6.4.4. Windows Menu Choices ═══ Select the Windows menu from the Local Variables window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.6.4.5. Help Menu Choices ═══ Select choices from the Help menu of the Local Variables window to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.6.5. Using the Passthru Window ═══ The Passthru window allows you to send commands to KDB and view its responses. The window is divided into two areas. The Command entry field area is where you enter the KDB commands, and the response area is used to display the KDB output. The KDB response area is scrollable, which allows you to review previous KDB responses from prior commands. This output area also appends a status icon for each line to indicate your input, the debugger's acceptance of that input, and text from KDB. Note: When you send KDB commands using the Passthru window, the debugger does not update its state. Thus, you should use this window for obtaining information instead of altering registers or data. To send a command to KDB, do the following: 1. Type the command you want to send in the Command entry field. 2. Select the Send push button. You can also press the Enter key if the Enter key performs send function check box is enabled in the Display Style window. 3. Select the Resync button to force the debugger to refresh all of its internal caches of the victim machine state. Use this button if you used the Passthru window to alter the state on the victim machine. Note: Commands that cause the victim machine to resume execution (for example, g and t) should be avoided. They can cause the debugger to lock up. The debugger tries to filter out the KDB commands that can cause a lockup, but you should always exercise caution. ═══ 11.6.5.1. REXX Command Files ═══ The debugger supports the execution of DEBUGO REXX command files. To start a DEBUGO REXX command file, specify an * before the command filename in the Command entry field. For example: * memcount.cmd would trigger the execution of the DEBUGO REXX command file memcount.cmd.  For a description of the choices that are available from the File menu, refer to File Menu Choice.  For a description of the choices that are available from the Edit menu, refer to Edit Menu Choices.  For a description of the choices that are available from the Options menu, refer to Options Menu Choices.  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. ═══ 11.6.5.2. File Menu Choice ═══ Use the choice from the File menu to end the debugging session. The Close debugger choice allows you to end the current debugging session. When you select Close debugger, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.6.5.3. Edit Menu Choices ═══ Select the choices from the Edit menu to edit lines in the response area, delete a line in the response area, or delete all the lines in the response area of the Passthru window. ═══ 11.6.5.3.1. Edit ═══ Select the Edit choice to edit a line in the response area of the Passthru window. To edit a line: 1. Highlight the line you want to edit. 2. Select the Edit choice. ═══ 11.6.5.3.2. Delete ═══ Select the Delete choice to delete a line in the response area of the Passthru window. To delete a line: 1. Highlight the line you want to delete. 2. Select the Delete choice. ═══ 11.6.5.3.3. Delete all ═══ Select the Delete all choice to delete all the lines in the response area of the Passthru window. To delete all the lines in the response area: 1. Select the Delete all choice. When you select the Delete all choice, a message box prompts you to confirm that you want to delete all the lines. 2. Select Yes. ═══ 11.6.5.3.4. Find ═══ Select the Find choice to search for a text string in the active window. To find a text string: 1. Type in the string of text you want to find in the Text entry field. 2. Enable the Case sensitive check box if you want to search for the string exactly as typed. Disable this check box to search for uppercase and lowercase characters. 3. Select the OK push button. ═══ 11.6.5.3.5. Find Next ═══ Select Find Next to search for the next occurrence of the text string that you typed in the Find window. ═══ 11.6.5.4. Options Menu Choices ═══ Select choices from the Options menu to change the font and control what items are shown in the Passthru window. ═══ 11.6.5.4.1. Fonts... ═══ Displays the Font window, which allows you to select the type of font you want to use for the Passthru window. ═══ 11.6.5.4.2. Display style... ═══ Displays the Display Style window, which allows you to select the items you want displayed in the window, select the number of items you want displayed, change the function of the Enter key, and save the output in a file. To use the Display Style window:  Select the items you want under the Select Items group heading. Each item you select causes a new column to be added to the response area of the Passthru window.  In the Number Items entry field, type the number of lines you want to be displayed in the response area. The maximum number of lines is 10,000.  The Output File entry field allows you to specify the name of the file where Passthru responses are optionally saved.  The Save output in file also check box allows you to copy the Passthru response items into a file (logging function). If the check box is enabled, the responses are copied into the file that you specified in the Output File entry field.  The Enter key performs send function check box allows you to enable or disable the Enter key from performing a send function. If the check box is enabled, the Enter key will perform the same function as the Send push button. If it is disabled, the Enter key will perform a carriage return. ═══ 11.6.5.4.3. Restore defaults ═══ Select the Restore defaults choice to reset all of the window settings to their original settings. ═══ 11.6.5.4.4. Add custom tool buttons ═══ Select the Add custom tool buttons choice to associate a Passthru command with a tool button icon. To do this: 1. Select one of the 10 icons to associate with a command. 2. Enter a Passthru command in the Commands entry field. For example, dg cs. 3. Select the Add push button to place the icon on the toolbar. When you select the icon from the toolbar, the associated command is executed. You can add, delete, or change icons and their associated text. Note: If the tool buttons choice has not been selected or if the tool buttons are on the title bar, you can not select the Add custom tool buttons choice ═══ 11.6.5.4.5. Tool buttons ═══ Select the Tool buttons choice to enable or disable tool buttons. If enabled, the tool buttons are displayed in the window. If disabled, the tool buttons are not displayed. ═══ 11.6.5.4.6. Hover help ═══ Select the Hover help choice if you want hover help. ═══ 11.6.5.4.7. Infoarea ═══ Select the Infoarea choice if you want the information area to be shown in the window. ═══ 11.6.5.5. Windows Menu Choices ═══ Select the Windows menu from the Passthru window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.6.5.6. Help Menu Choices ═══ Select choices from the Help menu of the Passthru window to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.6.6. Using the Monitor Windows ═══ The debugger has four other windows that allow you to monitor variables and expressions. These windows are as follows:  Popup Monitor  Program Monitor  Private Monitor  Storage Monitor. A Popup Monitor window monitors single variables or expressions. This window is associated with a specific source window and closes when the associated window closes. The Program Monitor, Private Monitor, and Storage Monitor windows are used as collectors for individual variables or expressions in which you might be interested. The difference between the Private Monitor window and the Program Monitor window is the length of time that each remains open. The Program Monitor window remains open for the entire debugging session. The Private Monitor window is associated with the source window from which it was opened and closes when its associated view is closed. ═══ 11.6.7. Using the Breakpoints List Window ═══ Use the Breakpoints List window to display a list of the breakpoints that have been set. The following information is provided for each breakpoint that has been set:  The type of breakpoint  The position of the breakpoint  The enablement state  The conditions under which the breakpoint is activated. To display the Breakpoints List window, select List from the Breakpoints menu or select the Breakpoints button in the tool bar.  For a description of the choices that are available from the File menu, refer to File Menu Choice.  For a description of the choices that are available from the Edit menu, refer to Edit Menu Choices.  For a description of the choices that are available from the Options menu, refer to Options Menu Choices.  For a description of the choices that are available from the Windows menu, refer to Windows Menu Choices.  For a description of the choices that are available from the Help menu, refer to Help Menu Choices. ═══ 11.6.7.1. File Menu Choice ═══ Use the choice from the File menu to end the debugging session. The Close debugger choice allows you to end the current debugging session. When you select Close debugger, the Close Debugger message box prompts you to confirm that you want to end the debugging session. ═══ 11.6.7.2. Edit Menu Choices ═══ Select the choices from the Edit menu of the Breakpoints List window to delete, disable, modify, or enable breakpoints. ═══ 11.6.7.2.1. Delete ═══ Deletes any breakpoints that are highlighted in the Breakpoints List window. To delete a breakpoint: 1. Highlight the breakpoint you want to delete. 2. Select the Delete choice. ═══ 11.6.7.2.2. Disable ═══ Disables any highlighted breakpoints. The breakpoint remains set but is not activated. This allows you to run your program and not stop when the breakpoint is encountered. To disable a breakpoint: 1. Highlight the breakpoint you want to disable. 2. Select the Disable choice. ═══ 11.6.7.2.3. Modify ═══ Use the Modify choice to change the breakpoints that have been set in your program. To modify a breakpoint: 1. Highlight the breakpoint you want to change. 2. Select the Modify choice. The breakpoint window that represents the type of breakpoint displays. 3. Make the appropriate changes to the entry fields. 4. Select the OK push button to accept your changes and close the window. If you want to make other changes, select the Set push button to accept the changes and keep the window open. ═══ 11.6.7.2.4. Delete all ═══ Deletes all the breakpoints that have been set. To delete all the breakpoints: 1. Select the Delete all choice. The Delete All Breakpoints window displays. 2. Select Yes from the Delete All Breakpoints window. ═══ 11.6.7.2.5. Disable all ═══ Disables all the breakpoints that have been set. To disable all the breakpoints: Select the Disable all choice. The prefix area in the source window changes from red to green to show that the breakpoints are disabled. ═══ 11.6.7.2.6. Enable all ═══ Enables all the breakpoints that have been disabled. To enable the breakpoints: Select the Enable all choice. The prefix area in the source window changes from green to red to show that the breakpoints are enabled. ═══ 11.6.7.3. Set Menu Choices ═══ Refer to Breakpoints Menu Choices for a description of the Set menu choices. ═══ 11.6.7.4. Options Menu Choices ═══ Select choices from the Options menu of the Breakpoints List window to sort the breakpoints, change the style, and change the font for the window. ═══ 11.6.7.4.1. Fonts... ═══ Displays the Font window that allows you to select the font you want to use for the text in the Breakpoints List window. ═══ 11.6.7.4.2. Display style... ═══ Displays the Display Style window, which allows you to control how the items appear in the Breakpoints List window. To change the columns which are displayed in the Breakpoint List window: 1. Select one or more of the items under the Select Items group heading. Each item you select causes a new column to be added to the Breakpoint List window. 2. Select the OK push button. The Show Watchpoint Types check box allows you to see more type information for watchpoints when they are enabled. For example, a type field of Watch - Instruction fetch would be displayed. ═══ 11.6.7.4.3. Sort ═══ Displays the Sort window, which allows you to sort the breakpoints by the characteristics of the breakpoint. Use the Sort window to sort the breakpoints that have been set in your program. Breakpoints can be sorted according to the following categories:  Type  Executable  Source  File  Function  Line  Address  State  Status  Thread  Expression  From  To  Every. Select the category you want and select the OK push button. ═══ 11.6.7.4.4. Restore defaults ═══ Select the Restore defaults choice to reset all of the window settings to their original settings. ═══ 11.6.7.4.5. Tool buttons ═══ Select the Tool buttons choice if you want tool buttons. ═══ 11.6.7.4.6. Hover help ═══ Select the Hover help choice if you want hover help. ═══ 11.6.7.4.7. Infoarea ═══ Select the Infoarea choice if you want the information area to be shown in the window. ═══ 11.6.7.5. Windows Menu Choices ═══ Select the Windows menu from the Breakpoints List window to view a list of all the open debugger windows. By selecting a window from the Windows menu, it is brought into focus and made the active window. Also, if the window is minimized, it is restored. ═══ 11.6.7.6. Help Menu Choices ═══ Select choices from the Help menu of the Breakpoints List window to display the various types of help information. Refer to Help Menu Choices for a description of the help choices. ═══ 11.7. Expressions Supported ═══ This section describes the expression language supported by the debugger, which is a subset of C/C++. This includes the operands, operators, and data types. Note: You can display and update bit fields for C/C++ code only. You cannot look at variables that have been defined using the #DEFINE preprocessor directive.  Supported Expression Operands  Supported Expression Operators  Supported Data Types ═══ 11.7.1. Supported Expression Operands ═══ You can monitor an expression that uses the following types of operands only: Operand Definition Variable A variable used in your program. Constant The constant can be one of the following types:  Fixed or floating-point constant. Note: The largest floating-point constant is 1.8E308. The smallest floating-point is 2.23E-308.  A string constant, enclosed in quotation marks (" ")  A character constant, enclosed in single quote marks (' ') Registers In the case of conflicting names, the program variable names take precedence over the register names. For conversions that are done automatically when the registers display in mixed-mode expressions, general purpose registers are treated as unsigned arithmetic items with a length appropriate to the register. If you monitor an enumerated variable, a comment displays to the right of the value. If the value of the variable matches one of the enumerated types, the comment contains the name of the first enumerated type that matches the value of the variable. If the length of the enumerated name does not fit in the monitor, the contents display as an empty entry field. The comment (empty or not) lets you distinguish between a valid enumerated value and an invalid value. An invalid value does not have a comment to the right of the value. You can not update an enumerated variable by entering an enumerated type. You must enter a value or expression. If the value is a valid enumerated value, the comment to the right of the value updates. Bit fields are supported for C/C++ compiled code only. You can display and update bit fields, but you cannot use them in expressions. You cannot look at variables that have been defined using the #DEFINE preprocessor directive.  Supported Expression Operators  Supported Data Types ═══ 11.7.2. Supported Expression Operators ═══ You can monitor an expression that uses the following operators only: ┌──────────────────────────────┬──────────────────────────────┐ │Operator │Coded as │ ├──────────────────────────────┼──────────────────────────────┤ │Global scope resolution │::a │ ├──────────────────────────────┼──────────────────────────────┤ │Class scope resolution │a::b │ ├──────────────────────────────┼──────────────────────────────┤ │Subscripting │a[b] │ ├──────────────────────────────┼──────────────────────────────┤ │Member selection │a.b or a->b │ ├──────────────────────────────┼──────────────────────────────┤ │Size │sizeof a or sizeof (type) │ ├──────────────────────────────┼──────────────────────────────┤ │Logical not │!a │ ├──────────────────────────────┼──────────────────────────────┤ │One's complement │~a │ ├──────────────────────────────┼──────────────────────────────┤ │Unary minus │-a │ ├──────────────────────────────┼──────────────────────────────┤ │Unary plus │+a │ ├──────────────────────────────┼──────────────────────────────┤ │Dereference │*a │ ├──────────────────────────────┼──────────────────────────────┤ │Type cast │(type) a │ ├──────────────────────────────┼──────────────────────────────┤ │Multiply │a * b │ ├──────────────────────────────┼──────────────────────────────┤ │Divide │a / b │ ├──────────────────────────────┼──────────────────────────────┤ │Modulo │a % b │ ├──────────────────────────────┼──────────────────────────────┤ │Add │a + b │ ├──────────────────────────────┼──────────────────────────────┤ │Subtract │a - b │ ├──────────────────────────────┼──────────────────────────────┤ │Left shift │a << b │ ├──────────────────────────────┼──────────────────────────────┤ │Right shift │a >> b │ ├──────────────────────────────┼──────────────────────────────┤ │Less than │a < b │ ├──────────────────────────────┼──────────────────────────────┤ │Greater than │a > b │ ├──────────────────────────────┼──────────────────────────────┤ │Less than or equal to │a <= b │ ├──────────────────────────────┼──────────────────────────────┤ │Greater than or equal to │a >= b │ ├──────────────────────────────┼──────────────────────────────┤ │Equal │a == b │ ├──────────────────────────────┼──────────────────────────────┤ │Not equal │a != b │ ├──────────────────────────────┼──────────────────────────────┤ │Bitwise AND │a & b │ ├──────────────────────────────┼──────────────────────────────┤ │Bitwise OR │a | b │ ├──────────────────────────────┼──────────────────────────────┤ │Bitwise exclusive OR │a ^ b │ ├──────────────────────────────┼──────────────────────────────┤ │Logical AND │a && b │ ├──────────────────────────────┼──────────────────────────────┤ │Logical OR │a || b │ ├──────────────────────────────┼──────────────────────────────┤ └──────────────────────────────┴──────────────────────────────┘  Supported Data Types ═══ 11.7.3. Supported Data Types ═══ You can monitor an expression that uses the following typecasting operations:  8-bit signed byte  8-bit unsigned byte  16-bit signed integer  16-bit unsigned integer  32-bit signed integer  32-bit unsigned integer  32-bit floating-point  64-bit floating-point  128-bit floating-point  Pointers  User-defined types. ═══ 12. Software Trace Facility (STRACE) ═══ STRACE is a software tracing mechanism that runs on OS/2 Warp Server for SMP. The following conditions must be met in order to enable software tracing:  TRACE=OFF must be specified in the CONFIG.SYS file. This is a requirement of the existing TRACE command in OS/2.  OS/2 Warp Server for SMP must be running on a Pentium, Pentium Pro, or better processor, since the 64-bit Time Stamp Counter is used as the timing mechanism. Once data has been collected using STRACE, it may be copied to another OS/2 Warp or later system (along with the STRACE.EXE file from the OS2 directory on the boot drive) and processed using STRACE. ═══ 12.1. STRACE Overview ═══ STRACE uses software trace hooks to collect data. Trace hooks are identified by both a major code and a minor code. Major code 1 is reserved for exclusive use by IBM. Major codes 0x00b8 (184) and 0x00b9 (185) have been reserved for customer use. A listing of major and minor codes associated with OS/2 Warp Server for SMP can be found in System Trace Hook Definitions. For major codes other than 0x00b8 and 0x00b9 mentioned above, the user identifies the major codes to be traced with the TRACE command. To turn tracing on for events with major codes of 0x0002, 0x0013, and 0x0042: TRACE ON 2 19 66 Note: The TRACE command requires decimal arguments. If TRACE ON is specified without one or more major codes, tracing for all major codes, except 1, is enabled. STRACE.EXE uses the general purpose performance function DosPerfSysCall to access the software trace buffer. When STRACE is turned on, it allocates the required buffers (one per processor) in the kernel space and starts tracing immediately. A user may turn off STRACE (to stop collecting trace data), copy the buffers to the user's buffer, flush the buffer to restart tracing, or reset STRACE (turn off and free the allocated buffers). ═══ 12.2. STRACE Syntax ═══ ON OFF INIT RESET FLUSH INFO GET STRACE POST /S=ssss /R=rrrrrrrr /M=mmmmmmm /O=oooooooo /N=nnnnnnnn /A=a MAJOR VERSION MTE INSERT REMOVE NRM ═══ 12.2.1. STRACE Arguments ═══ One of the following arguments is required. The first valid command is used. All others will be ignored and a warning is issued to the user. ON Turns STRACE ON. If STRACE is off, this command causes the buffers to be allocated if needed and turns tracing on. If STRACE is currently on, this command has no effect. The default buffer size per processor is 3 MB which can be changed by using the /S option described below. Note that if buffers exist at the time of this command, no new buffers will be allocated. Tracing is simply turned on using the existing buffers, whatever size they may be. Tracing will be automatically turned off when any buffer on any processor is full. OFF Turns STRACE OFF. If STRACE is on, this command turns tracing off. The buffers are not freed. If STRACE is currently off, this command has no effect. INIT Initializes STRACE. This command causes the buffers to be allocated if necessary, but does not turn tracing on. If STRACE is currently on, this command has no effect. The default buffer size per processor is 3 MB, which can be changed using the /S option. Note that if buffers exist at the time of this command, no new buffers will be allocated. RESET Resets STRACE. If STRACE is on, this command turns tracing off. Whether STRACE was on or off, any allocated trace buffers will be freed and the contents discarded. FLUSH Flushes STRACE buffers. This command causes all data in the trace buffers to be discarded. The buffers remain allocated if they exist. This command does not alter the state of tracing. If STRACE is on, it will remain on and tracing continues into an empty buffer. If STRACE is off, it remains off. INFO Returns the status of STRACE. Indicates whether STRACE is active or not, the current buffer allocation, and data collection statistics, such as number of bytes collected. This command does not alter the state of tracing. GET Returns a copy of the trace buffers. This command returns all trace data to the user in a binary file in the current directory called STRACE.RAW. Use the /R option to direct the output to a different file and path. This file is processed using the POST option of STRACE, to convert it to a readable format. This command does not alter the state of tracing. Trace major codes should be disabled prior to issuing STRACE GET. POST Processes the binary file returned from the GET option and produces two files: an integrated ASCII dump of the trace and an MTE (module table entry) loader dump output file. The default input file is STRACE.RAW, the default ASCII dump output file is STRACE.OUT, and the default MTE dump output file is STRACE.MTE Use the /R, /O, and /M options respectively to specify a different file name, or fully-qualified path and file name, for each. This command does not alter the state of tracing. MAJOR Displays the active STRACE major codes being traced. This command does not alter the state of tracing. VERSION Displays the current version of STRACE. This command does not alter the state of tracing. MTE Captures Module Table Entry data and writes it to the MTE loader dump file. Use the /M option to direct the output to a file other than STRACE.MTE. Module Table entry data provides information about loaded memory objects, their sizes, addresses and process affiliations. INSERT Dynamically inserts trace hooks into the kernel. The user can insert a major code group. For example for major code 19, strace insert 19. The user can insert a particular major/minor code. For example, 19/1, strace insert 19 1. Very few software trace hooks are dynamic; most are already inserted, and the strace insert and strace remove commands have no affect. At present, only hooks associated with major code 0x0013 (19) can be inserted with this capability. REMOVE Dynamically remove trace hooks from the kernel. The user can remove a major code group. For example for major code 19, strace remove 19. The user can remove a particular major/minor code. For example, 19/1, strace remove 19 1. At present, only hooks associated with major code 0x0013 (19) can be removed with this capability. NRM For IBM Use Only. ═══ 12.2.2. STRACE Options ═══ The following options can be used to alter the default behavior of the STRACE command: /S=ssss Specifies the buffer size for each processor in megabytes (MB). The default is /S=3, which results in a trace buffer of 3 MB for each processor. /R=rrrrrrrr Specifies the drive, path, and name for the file containing the data returned by the GET and POST arguments, and is ignored otherwise. The default is /R=STRACE.RAW. /M=mmmmmmmm Specifies the drive, path, and name for the MTE loader dump file produced by the POST and MTE arguments, and is ignored otherwise. The default is /M=STRACE.MTE. /O=oooooooo Specifies the drive, path, and name of the ASCII output file created with the POST option, and is ignored otherwise. The default is /O=STRACE.OUT. /A=a Controls whether the adjustment of time stamps for processors with different initial Time Stamp Counter values should be performed during STRACE POST processing. The default is /A=1 which performs the adjustment. Specify /A=0 to suppress this adjustment. ═══ 12.2.3. STRACE Command Examples ═══ TRACE ON This activates all trace major codes (except major code 1, which is for IBM use only). STRACE ON /S=4 This will allocate a trace buffer of 4 MB per processor and turn software tracing on. STRACE OFF This will turn tracing off. Once tracing is off, the user may then process the trace data contained in the trace buffer without having additional data written to the buffer. STRACE GET /R=MYTRACE.RAW This will extract the trace buffer into the file MYTRACE.RAW. STRACE POST /R=MYTRACE.RAW /O=E:\TRACE\MYTRACE.OUT This will process the RAW file MYTRACE.RAW and generate an ASCII version in E:\TRACE\MYTRACE.OUT. STRACE RESET This will turn tracing off and free any STRACE buffers. TRACE OFF This will deactivate all trace major codes. ═══ 12.2.4. Sample Use of STRACE ═══ Let's say you are running a program called COLLIE.EXE which uses queues to fetch data from another program. You could use STRACE to gather performance data on how the semaphore operations associated with the queuing activities are handled, or you could use it to monitor what semaphore operations are done to help diagnose a hang in the program. The control program semaphore functions use major code 0x0018 (see Dos Functions - 2 of 12), therefore the following sequence of commands could be used: 1. Turn trace on for the desired major code, TRACE ON 24 0x0018 in this case. 2. Turn on STRACE STRACE ON 3. Run the desired program. START COLLIE 4. When program completes, or at the appropriate STRACE OFF time, turn off STRACE. TRACE OFF 5. Get a copy of the trace information from all processors. STRACE GET /R=RUN1.RAW 6. Clear the trace buffers in preparation for running the program again. STRACE FLUSH 7. Turn on STRACE again. TRACE ON 24 STRACE ON 8. Run the program again. START COLLIE 9. Turn off STRACE at the appropriate time. STRACE OFF TRACE OFF 10. Copy the trace buffers to another file. STRACE GET /R=RUN2.RAW 11. If all tracing is complete, you could now STRACE RESET delete the trace buffers. 12. Generate readable trace data and explicitly STRACE POST /R=RUN1.RAW name all output files. /M=RUN1.MTE /O=RUN1.OUT ═══ 12.3. STRACE POST Processing ═══ The STRACE POST option processes the binary file returned from the GET option and produces two files:  ASCII dump output file, described in STRACE ASCII Dump Format  MTE loader dump output file, described in STRACE MTE Dump Format Sample output from running an STRACE POST is shown here: RAW file = strace.raw Output file = strace.out MTE file = strace.mte Adjust time = TRUE CPU 0 Rating 89.997898 Mhz CPU 1 Rating 89.995955 Mhz CPU 2 Rating 89.996197 Mhz CPU 3 Rating 90.005302 Mhz Working ... hooks processed. 575779 CPU 0 Start time stamp :(531:fa721cba) End time stamp :(535:5b3f6e10) Drift ratio :0.000000e+000 Number of hooks :159367 CPU 1 Start time stamp :(8:45ea9f53) End time stamp :(b:a6b8945c) Drift ratio :2.888343e-006 Number of hooks :128142 CPU 2 Start time stamp :(8:45de419e) End time stamp :(b:a6abcb34) Drift ratio :9.924885e-007 Number of hooks :145038 CPU 3 Start time stamp :(8:45d4207a) End time stamp :(b:a6a2318d) Drift ratio :3.383068e-006 Number of hooks :143232 On rare occasions, a start or end time stamp may be shown as ffffffff:ffffffff. This occurs when STRACE processing was unable to gain synchronous access to one or more processors to get their time stamps. When this occurs, you will need to recollect the STRACE data by turning off STRACE, flushing the STRACE buffers, and then restarting STRACE. ═══ 12.4. STRACE ASCII Dump Format ═══ The format of the ASCII dump file produced by the STRACE POST command is described below. Each hook is listed on a single line containing information about the hook type, major code, minor code, time stamp, processor ID, and hook-specific data. A sample STRACE.OUT file is shown here: 102 13 29 9450:1545341324 0 fff37182 fff05c9c 102 13 2b 9450:1545341598 0 fff37198 fff05c9c 102 13 29 9450:1545342287 0 fff371a3 fff05c9c 102 13 2b 9450:1545342546 0 fff371ae fff05c9c 104 13 4b 9450:1545343593 0 00000001 00000004 fff05d1c fff405a3 100 4 89 9450:1545343975 0 3401 a8 3 9450:1546123683 2 -- strace.mte -- 104 13 9 9450:1546180366 2 00000000 00000001 fff05f58 fff47a71 101 15 1 9450:1546183708 0 fff48224 100 15 81 9450:1546184199 0 101 15 1 9450:1546184525 1 fff48224 100 15 81 9450:1546184847 1 101 15 1 9450:1546185450 3 fff48224 104 13 4b 9450:1546185848 2 00000001 00000004 fff05f58 fff47f38 100 15 81 9450:1546185851 3 100 13 3b 9450:1546189361 2 100 13 39 9450:1546189762 0 104 13 9 9450:1546191925 2 00000000 00000001 fff05ed8 fff6e0d5 104 13 4b 9450:1546193003 2 00000001 00000004 fff05ed8 fff6e136 100 13 3b 9450:1546193765 0 100 13 39 9450:1546194102 1 100 13 3b 9450:1546194683 1 100 13 3a 9450:1546194745 2 104 13 9 9450:1546194789 0 00000000 00000040 fff05d40 fff42840 100 13 39 9450:1546195040 2 104 13 9 9450:1546197102 2 00000000 00000001 fff05ed8 fff6e467 The general format for trace output is: tttt MM mm TTTTTTTT:tttttttt p dddddddd...ddd | | | | | | | | | | | | | +--- Data in hex, described below, and hook type specific | | | | | | | | | | | +----- Processor ID in decimal (0,1,2,3,...,63) | | | | | | | | | +-------------- Low-order 32 bits of Time Stamp (Pentium cycle counter) | | | | (in decimal) | | | | | | | +----------------------- High-order 32 bits of Pentium cycle counter (in decimal) | | | | | +-------------------------- Minor Code (in hex) | +----------------------------- Major Code (in hex) | +---------------------------------- Hook Type (in hex) ═══ 12.4.1. Hook Types ═══ The different hook types are: SFT_HOOK_32BIT (0x0100) Each data item is a ULONG. The low 8 bits of the hook type indicate the total number of data items. The maximum number of data items is 255. SFT_HOOK_DATA (0x0200) Data is a buffer of 0 to 255 bytes. The low 8 bits of the hook type indicate the length of the buffer. SFT_HOOK_VARDATA (0x0400) Data consists of variable length items. Low 8 bits of the hook type indicate the number of data items. Each data item is preceded by a ULONG length indicator. The maximum number of data items is 255. Length indicators are removed as part of STRACE POST processing. SFT_HOOK_VARDATA2 (0x0800) Data consists of variable length items. Low 8 bits of the hook type indicate the number of data items. Each data item is preceded by a USHORT length indicator. The maximum number of data items is 255. Length indicators are removed as part of STRACE POST processing. SFT_HOOK_TIMEHI (0x1100) Occurs when the high 32-bits of the time stamp changes. SFT_HOOK_STARTUP (0x2200) Occurs when STRACE is started. SFT_HOOK_MTE (0x3400) Occurs when STRACE is started. Used by trace post-processors to get information about loaded memory objects. Hook examples are provided below. Entries from an STRACE.OUT file, or other ASCII dump of the trace data generated by the STRACE POST command is as follows: ═══ 12.4.1.1. Timer high order 32 bits change hook (SFT_HOOK_TIMEHI) ═══ This hook is produced whenever the high order 32 bits of the time stamp changes. The STRACE POST command normalizes the time stamps and accounts for potential clock drift across the processors in the system. The time stamp shown in each hook reflects this normalization. 1101 a8 1 254:3417264209 0 000000fe | | | | | | | | | | | +---- High 32 bits of timer (unnormalized) | | | | +------ Processor ID (0,1,2,3,...,63) | | | +-------------- Normalized Time Stamp (high32bits:low32bits) | | +------------------- Minor Code = 0x01 | +------------------------ Major code = 0xa8 +----------------------------- Type Indicator (SFT_HOOK_TIMEHI | 1) ═══ 12.4.1.2. Startup Hook (SFT_HOOK_STARTUP) ═══ This hook is produced on STRACE startup. It contains information about the system on which trace is operating, initial time of day information, and number of processors in the system. The data returned is mapped by SFTSTARTUP. 2218 a8 2 254:3417264209 0 141e000708000000cc0715390703000001000000598d9303 | | | | | | | | | | | +---Data as follows: | | | | | UCHAR VerMajor | | | | | UCHAR VerMinor | | | | | UCHAR RevLettr | | | | | UCHAR DayDate | | | | | UCHAR MonDate | | | | | UCHAR pad1[3] | | | | | USHORT YrsDate | | | | | UCHAR HrsTime | | | | | UCHAR MinTime | | | | | UCHAR SecTime | | | | | UCHAR HunTime | | | | | UCHAR pad2[2] | | | | | ULONG ulNumCPUs | | | | | ULONG ulCPURate[] | | | | | | | | | +----- Processor ID (0,1,2,3,...,63) | | | +-------------- Normalized Time Stamp (high32bits:low32bits) | | +---------------------------- Minor Code = 0x02 | +--------------------------------- Major Code = 0xa8 +-------------------------------------- Type Indicator/Length (SFT_HOOK_STARTUP | 0x18 bytes) ═══ 12.4.1.3. Module Table Entry Hook (SFT_HOOK_MTE) ═══ This hook is also produced at STRACE startup. The data is used by trace post-processors for information about loaded memory objects. 3401 a8 3 254:3418461893 0 -- see strace.mte -- | | | | | | | | | | | +---- MTE data (not directly reported; | | | | | but see the STRACE.MTE file for an example) | | | | | | | | | +--- Processor ID (0,1,2,3,...,63) | | | +-------------- Normalized Time Stamp (high32bits:low32bits) | | +---------------------------- Minor Code = 0x03 | +--------------------------------- Major Code = 0xa8 +-------------------------------------- Type Indicator/# of buffers (SFT_HOOK_MTE | 1) ═══ 12.4.1.4. Hook logging 1 32-bit value ═══ 101 14 9 254:3419280448 1 0000000c | | | | | | | | | | | | | +-------------------- 32-bit value | | | | | +------------------------ Processor ID (0,1,2,3...,63) | | | | +-------------- Normalized Time Stamp (high32bits:low32bits) | | | +---------------------------- Minor code = 0x09 | | +---------------------------------- Major code = 0x14 | +-------------------------------------- Total Number of 32-bit values = 1 +---------------------------------------- Type Indicator - (SFT_HOOK_32BIT | 1) ═══ 12.4.1.5. Hook logging 4 32-bit values ═══ 104 13 12 254:3419275789 0 00c10000 00000001 fff04248 fff3f5c7 | | | | | | | | | | | | | | | | | | | +-- 4th 32-bit value | | | | | | | | +------- 3rd 32-bit value | | | | | | | +---------------- 2nd 32-bit value | | | | | | +------------------------ 1st 32-bit value | | | | | +---------------------------- Processor ID | | | | +------------- Normalized Time Stamp (high32bits:low32bits) | | | +---------------------------- Minor Code = 0x12 | | +--------------------------------- Major Code = 0x13 | +------------------------------------- Total number of 32-bit values = 4 +--------------------------------------- Type indicator - (SFT_HOOK_32BIT | 4) ═══ 12.4.1.6. Hook logging 3 2-byte buffers ═══ Note that STRACE POST processing removes the data item length information and simply lists each entry in little-endian (reverse byte) order. 803 12 1 254:3419280201 2 2600 0100 0002 | | | | | | | | | | | | | | | | | +------- Data item 3 | | | | | | | +------------ Data item 2 | | | | | | +----------------- Data item 1 | | | | | +------ Processor ID (0,1,2,3,...,63) | | | | +-------------- Normalized Time Stamp (high32bits:low32bits) | | | +--------------------------- Minor Code = 0x01 | | +-------------------------------- Major Code = 0x12 | +----------------------------------- Total number of buffers = 3 +------------------------------------- Type indicator - (SFT_HOOK_VARDATA2 | 3 ) ═══ 12.5. STRACE MTE Dump Format ═══ The STRACE POST and STRACE MTE commands produce an MTE dump output file. The format of each line in the file is shown here: 0002 00020000 00004000 0000000d fb1e0828 E:\OS2\EPWMP.EXE | | | | | | | | | | | +--- Module name | | | | | | | | | +- PTDA Address | | | | | | | +---------- PID (process identifier) | | | | | +------------------- Size in bytes | | | +--------------------------- Linear Load Address | +--------------------------------- Segment number A portion of an STRACE.MTE file is shown below. 0001 00010000 00003190 00000008 fb1de424 E:\OS2\SYSTEM\LOGDAEM.EXE 0002 00020000 000007f0 00000008 fb1de424 E:\OS2\SYSTEM\LOGDAEM.EXE 0003 00030000 000072d0 00000008 fb1de424 E:\OS2\SYSTEM\LOGDAEM.EXE 0001 00010000 000000c8 00000007 fb1ddcf0 E:\IBMLAN\NETPROG\LSDAEMON.EXE 0002 00020000 00002010 00000007 fb1ddcf0 E:\IBMLAN\NETPROG\LSDAEMON.EXE 0003 00030000 00000030 00000007 fb1ddcf0 E:\IBMLAN\NETPROG\LSDAEMON.EXE 0001 00010000 000000e2 00000006 fb1dd5bc E:\IBMCOM\PROTOCOL\LANDLL.EXE 0002 00020000 00000436 00000006 fb1dd5bc E:\IBMCOM\PROTOCOL\LANDLL.EXE 0001 00010000 00001d82 00000005 fb1dce88 E:\MPTN\BIN\CNTRL.EXE 0002 00020000 0000020a 00000005 fb1dce88 E:\MPTN\BIN\CNTRL.EXE 0003 00030000 00007260 00000005 fb1dce88 E:\MPTN\BIN\CNTRL.EXE 0001 00010000 000010c4 00000004 fb1dc754 E:\IBMCOM\LANMSGEX.EXE 0002 00020000 00000291 00000004 fb1dc754 E:\IBMCOM\LANMSGEX.EXE 0001 00010000 00000a40 0000000a fb1df28c E:\OS2\PMSHELL.EXE 0002 00020000 00000070 0000000a fb1df28c E:\OS2\PMSHELL.EXE 0003 00030000 0000fa50 0000000a fb1df28c E:\OS2\PMSHELL.EXE 0001 00010000 0000cbbb 00000086 fb1e48fc E:\OS2\APPS\KLONDIKE.EXE 0002 00020000 0000e710 00000086 fb1e48fc E:\OS2\APPS\KLONDIKE.EXE 0003 00030000 00000a32 00000086 fb1e48fc E:\OS2\APPS\KLONDIKE.EXE 0004 00040000 0000eec0 00000086 fb1e48fc E:\OS2\APPS\KLONDIKE.EXE 0005 00000000 0000d808 00000086 fb1e48fc E:\OS2\APPS\KLONDIKE.EXE 0006 00000000 0000ff44 00000086 fb1e48fc E:\OS2\APPS\KLONDIKE.EXE 0001 00010000 0000cbbb 00000085 fb1e41c8 E:\OS2\APPS\KLONDIKE.EXE ═══ 12.6. Differences Between TRACE and STRACE ═══ There may be some confusion between the existing OS/2 Trace facility and the new software tracing provided by STRACE, especially since STRACE uses the OS/2 Trace facility control utility. First the OS/2 Trace facility will be described, then the differences between it and software tracing will be outlined. ═══ 12.6.1. OS/2 Trace Facility ═══ The OS/2 Trace facility is an important RAS mechanism in the OS/2 product. It allows specific events within the operating system, in system extensions, and in applications to be recorded in a circular System Trace buffer. Software developers can create tracepoints that are used to monitor the execution of software modules. The OS/2 Trace facility includes two important utility programs. The OS/2 Trace control utility, TRACE.EXE, is used to enable and disable the tracing of events. Entries within the System Trace buffer can be formatted for viewing by using the OS/2 Trace Formatter utility, TRACEFMT.EXE. The Trace Formatter can also be used to copy the contents of the System Trace buffer to disk for processing on another system. The general categories of events that are traced in OS/2 are:  External application program interfaces (APIs)  Internal interfaces  Other internal events. For an interface or event, there are generally two tracepoints. A pre-invocation trace and a post-invocation trace. One can determine the action taken by the system for a particular event by matching the two corresponding trace events in the trace output. For more information on the OS/2 Trace facility, refer to the OS/2 Command Reference and the OS/2 Warp System Trace Facility online books. (The latter book is shipped as part of OS/2 Warp Version 4. It may or may not be part of the OS/2 Warp Server for SMP online documentation.) ═══ 12.6.2. How STRACE is Different ═══ Software Tracing uses the OS/2 Trace facility control utility, TRACE.EXE, to enable and disable the tracing of events. Software Tracing is performed to special trace buffers which are allocated, one per processor, when STRACE is initialized or turned on. Thus, the information recorded by Software Trace does not go into the OS/2 Trace facility's System Trace buffer and the recording can be efficiently done in a multiprocessing environment. The user can alter the size of the buffers with the STRACE command to collect much more data than TRACE can. The trace hooks placed in the kernel for software tracing are there for performance use, as opposed to the ones for TRACE which are positioned primarily as debugging aids. Software Tracing utilizes the 64-bit Pentium Time Stamp Counter to provide precise time stamping of events. Software trace information is formatted by using the POST option of STRACE. STRACE also permits the transfer of trace data to disk for processing on other systems, provided, of course, that STRACE.EXE has been copied to the other system. ═══ 12.7. System Trace Hook Definitions ═══ The following sections outline the trace hook major and minor codes for various functions in OS/2. The information in these tables is subject to change as new hooks are added and obsolete ones are removed. The mention of a hook for a specific function does not necessarily mean that the hook actually records data in the current version of OS/2. Major codes of 0xb8 and 0xb9 have been reserved for use by customers for trace hooks. It is the intent of IBM to document the format of the trace data associated with each implemented trace hook in OS/2 in the future. ═══ 12.7.1. Exceptions and Interrupts ═══ ┌────────────────────┬────────────────────┬────────────────────┐ │Hook ID │Event Name │Description │ │Major/Minor Code │ │ │ ├────────────────────┼────────────────────┼────────────────────┤ │03/01 │Exception 0 │Divide By Zero │ ├────────────────────┼────────────────────┼────────────────────┤ │03/02 │Exception 1 │Debug Exception │ ├────────────────────┼────────────────────┼────────────────────┤ │03/03 │Exception 2 │NMI │ ├────────────────────┼────────────────────┼────────────────────┤ │03/04 │Exception 3 │Breakpoint │ ├────────────────────┼────────────────────┼────────────────────┤ │03/05 │Exception 4 │Overflow │ ├────────────────────┼────────────────────┼────────────────────┤ │03/06 │Exception 5 │Bounds Check │ ├────────────────────┼────────────────────┼────────────────────┤ │03/07 │Exception 6 │Invalid Opcode │ ├────────────────────┼────────────────────┼────────────────────┤ │03/08 │Exception 7 │NPX Not Available │ ├────────────────────┼────────────────────┼────────────────────┤ │03/09 │Exception 8 │Double Fault │ ├────────────────────┼────────────────────┼────────────────────┤ │03/0A │Exception 9 │NPX Segment Overrun │ ├────────────────────┼────────────────────┼────────────────────┤ │03/0B │Exception A │Invalid TSS │ ├────────────────────┼────────────────────┼────────────────────┤ │03/0C │Exception B │Segment Not Preset │ ├────────────────────┼────────────────────┼────────────────────┤ │03/0D │Exception C │Stack Fault │ ├────────────────────┼────────────────────┼────────────────────┤ │03/0E │Exception D │General Protection │ │ │ │Fault │ ├────────────────────┼────────────────────┼────────────────────┤ │03/0F │Exception E │Page Fault │ ├────────────────────┼────────────────────┼────────────────────┤ │04/01 │Interrupt IRQ 0 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/02 │Interrupt IRQ 1 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/03 │Interrupt IRQ 2 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/04 │Interrupt IRQ 3 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/05 │Interrupt IRQ 4 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/06 │Interrupt IRQ 5 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/07 │Interrupt IRQ 6 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/08 │Interrupt IRQ 7 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/09 │Interrupt IRQ 8 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/0A │Interrupt IRQ 9 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/0B │Interrupt IRQ A │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/0C │Interrupt IRQ B │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/0D │Interrupt IRQ C │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/0E │Interrupt IRQ D │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/0F │Interrupt IRQ E │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/10 │Interrupt IRQ F │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/11 │Interrupt IRQ 10 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/12 │Interrupt IRQ 11 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/13 │Interrupt IRQ 12 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/14 │Interrupt IRQ 13 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/15 │Interrupt IRQ 14 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/16 │Interrupt IRQ 15 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/17 │Interrupt IRQ 16 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/18 │Interrupt IRQ 17 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/19 │Interrupt IRQ 18 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/1A │Interrupt IRQ 19 │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/1B │Interrupt IRQ 1A │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/1C │Interrupt IRQ 1B │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/1D │Interrupt IRQ 1C │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/1E │Interrupt IRQ 1D │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/1F │Interrupt IRQ 1E │ │ ├────────────────────┼────────────────────┼────────────────────┤ │04/20 │Interrupt IRQ 1F │ │ └────────────────────┴────────────────────┴────────────────────┘ ═══ 12.7.2. Dos Functions - 1 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/01 │DosCreateThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/02 │DosWaitChild │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/03 │DosEnterCritSec │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/04 │DosExecPgm │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/05 │DosExit │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/06 │DosExitCritSec │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/07 │DosExitList │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/08 │DosSetPriority │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/09 │DosKillProcess │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/0B │DosResumeThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/0C │DosSuspendThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/0D │DosSetCp │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/0E │DosDebug │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/0F │Dos32ExitList │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/10 │DosGetInfoSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/11 │DosGetPID │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/12 │DosGetPPID │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/13 │DosGetPrty │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/14 │DosGetInfoBlocks │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/15 │DosR2StackRealloc │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/16 │DosWaitThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/17 │DosCallBack │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/18 │Dos32CreateThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/19 │DosRetForward │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/1A │TickHandler │ ├────────────────────┼──────────────────────────────────────────────────┤ │10/1B │DosCreateVDM │ ├────────────────────┼──────────────────────────────────────────────────┤ │12/01 │Thread Dispatch │ ├────────────────────┼──────────────────────────────────────────────────┤ │12/02 │ExitList Call │ ├────────────────────┼──────────────────────────────────────────────────┤ │12/03 │IdleTask │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/01 │SpinLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/02 │SpinLockRing0 │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/03 │SpinLockSpin │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/04 │SpinLockHold │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/05 │SpinLockRing0Hold │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/06 │SpinLockIPI │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/07 │SpinLockIPISpin │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/09 │SpinLock09Get spin lock │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/0A │SpinLock0AStart to spin on spin lock │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/29 │SpinLock29Release spin lock │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/2A │SpinLock2AStart to spin on spin lock (type II) │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/2B │SpinLock2BGet spin lock (type II) │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/4B │SpinLock4BRelease spin lock (type II) │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/39 │SpinLock39Get spin lock (type III) │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/3B │SpinLock3BRelease spin lock (type III) │ ├────────────────────┼──────────────────────────────────────────────────┤ │13/4B │SpinLock4BStart to spin on spin lock (type III) │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.3. Dos Functions - 2 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/01 │DosLoadModule │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/02 │DosFreeModule │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/04 │DosQueryModuleHandle │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/05 │DosQueryModuleName │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/06 │DosGetEnv │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/07 │DosGetMachineMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/08 │DosGetVersion │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/09 │DosQueryAppType │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/0A │DosScanEnv │ ├────────────────────┼──────────────────────────────────────────────────┤ │14/0B │DosQueryProcAddr │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/01 │DosHoldSignal │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/02 │DosSendSignal │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/03 │DosSetSigHandler │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/04 │DosCreatePipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/05 │DosSemClear │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/06 │DosSemRequest │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/07 │DosSemSet │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/08 │DosSemSetWait │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/09 │DosSemWait │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/0A │DosMuxSemWait │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/0B │DosCloseSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/0C │DosCreateSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/0D │DosOpenSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/0F │DosAddMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/10 │DosCallNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/12 │DosCloseEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/13 │DosCloseMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/14 │DosCloseMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/15 │DosConnectNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/16 │DosCreateEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/17 │DosCreateMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/18 │DosCreateMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/19 │DosDisconnectNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/1A │DosCreateNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/1B │DosOpenEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/1C │DosOpenMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/1D │DosOpenMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/1E │DosPeekNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/1F │DosQueryNPHState │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/20 │DosQueryNPipeInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/21 │DosQueryNPipeSemState │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/23 │DosQueryEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/24 │DosQueryMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/25 │DosQueryMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/27 │DosReleaseMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/29 │DosRequestMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/2B │DosSetNPHState │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/2C │DosSetNPipeSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/2D │DosTransactNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/2E │DosWaitEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/2F │DosWaitMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/30 │DosWaitNPipe │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.4. Dos Functions - 3 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/31 │DosFSRamSemClear │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/32 │DosFSRamSemRequest │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/33 │DosDeleteMuxWaitSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/34 │DosPostEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/35 │DosRawReadNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/36 │DosRawWriteNPipe │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/37 │DosResetEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/39 │DosSetKBDSigFocus │ ├────────────────────┼──────────────────────────────────────────────────┤ │18/40 │SemWaitEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/01 │DosError │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/02 │DosSetVec │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/05 │DosSysTrace │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/06 │DosErrClass │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/07 │DosLogRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/08 │DosLogRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/09 │DosDynamicTrace │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/0A │DosRaiseException │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/0B │DosSetExceptionHandler │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/0C │DosUnsetExceptionHandler │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/0D │DosUnwindExceptionHandler │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/0E │DosSetTraceInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │1C/0F │DosSystemService │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/11 │VMAllocMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/12 │VMFreeMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/13 │VMLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/14 │VMUnlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/15 │VMInitTask │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/16 │VMFreeTask │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/17 │VMAttach │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/18 │VM32ApiAliasMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/19 │VM32ApiAllocMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/1A │VM32ApiAllocSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/1B │VM32ApiGetNamedShared │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/1C │VM32ApiGetSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/1D │VM32ApiGiveSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/1E │VM32ApiFreeMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/1F │VM32ApiSetMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/21 │VM32ApiQueryMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/22 │PGPageFault │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/24 │PGReloadFrame │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/25 │PGGetPF │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/26 │PGIdle │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/27 │SELInitLDT │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/28 │SELAllocLDT │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/29 │SELFreeLDT │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/2A │SMSwapIn │ ├────────────────────┼──────────────────────────────────────────────────┤ │20/2B │SMSwapOut │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.5. Dos Functions - 4 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/01 │DosAllocSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/02 │DosAllocShrSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/03 │DosGetShrSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/04 │DosReallocSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/05 │DosFreeSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/06 │DosAllocHuge │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/07 │DosReallocHuge │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/08 │DosCreateCSAlias │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/09 │DosGiveSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/0A │DosAllocMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/0B │DosAllocSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/0C │DosFreeMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/0D │DosGetHugeShift │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/0E │DosGetNamedSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/0F │Dos32GetResource │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/10 │DosGetSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/11 │DosGetSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/12 │DosGiveSharedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/13 │DosLockSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/16 │DosMemAvail │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/17 │DosQueryMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/18 │DosSetMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/19 │DosSizeSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/1A │DosUnlockSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/1B │DosSubAlloc │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/1C │Dos32SubAlloc │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/1D │DosSubFree │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/1E │Dos32SubFree │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/1F │DosSubSet │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/20 │Dos32SubSet │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/21 │DosAliasMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/22 │DosAllocProtectedMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/23 │DosAllocProtHuge │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/24 │DosAllocProtSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/25 │DosAllocShrProtSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/26 │DosQueryMemState │ ├────────────────────┼──────────────────────────────────────────────────┤ │24/27 │DosSubUnSet │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.6. Dos Functions - 5 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/01 │DosResetBuffer │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/02 │DosSetFilePtr │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/03 │DosClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/04 │DosDelete │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/05 │DosDupHandle │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/06 │DosSetFileLocks │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/07 │DosCreateDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/08 │DosMove │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/09 │DosSetFileSize │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/0A │DosOpen │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/0B │DosRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/0C │DosReadAsync │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/0D │DosDeleteDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/0E │DosSetDefaultDisk │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/0F │DosSetFHState │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/10 │DosSetFileMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/11 │DosSetVerify │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/12 │DosWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/13 │DosWriteAsync │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/14 │DosSetCurrentDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/15 │DosFindClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/16 │DosFindFirst │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/17 │DosFindNext │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/18 │DosFindFirst2 │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/19 │DosCreateDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/1A │DosOpen2 │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/1B │DosQueryCurrentDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/1C │DosQueryCurrentDisk │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/1D │DosQueryFHState │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/1E │DosQueryFileInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/1F │DosQueryFileMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/20 │DosQueryFSInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/21 │DosQueryHType │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/22 │DosQueryVerify │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/23 │DosSetFileInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/24 │DosSetFSInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/25 │DosSetMaxFH │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/26 │DosCopy │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/27 │DosSearchPath │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/28 │DosEditName │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/29 │DosFileIO │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.7. Dos Functions - 6 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/2A │DosFindFromName │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/2B │DosFindNotifyClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/2C │DosFindNotifyFirst │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/2D │DosFindNotifyNext │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/2E │DosFSAttach │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/2F │DosFSCtl │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/30 │DosOpLockRelease │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/31 │DosOpLockWait │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/32 │DosQueryFSAttach │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/33 │DosQueryPathInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/34 │DosQuerySysInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/35 │DosSetPathInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/36 │DosForceDelete │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/40 │Dos32Read │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/41 │Dos32Write │ ├────────────────────┼──────────────────────────────────────────────────┤ │30/42 │fscMPStub │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/01 │Cluster Allocate │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/02 │Cluster Deallocate │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/03 │Unlock/Lock File Range │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/04 │AddHash │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/05 │AddLW │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/06 │CCH │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/07 │LazyWriter │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/08 │LazyRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/0A │SDW │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/0B │FLW │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/0C │LWWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │32/13 │SDR │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.8. Dos Functions - 7 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/01 │AddHash │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/02 │AddLW │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/03 │CCH │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/04 │FindDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/05 │LazyWriter │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/06 │LDE │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/07 │RDBufOrGetInBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/08 │ReadDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/09 │SDL │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/0A │SDW │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/0B │FLW │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/0D │FSOpen │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/0E │FSRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/0F │FSWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/11 │SplitDir │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/12 │Adjust │ ├────────────────────┼──────────────────────────────────────────────────┤ │33/13 │SDR │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/01 │DosGetDateTime │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/02 │DosSetDateTime │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/03 │DosSleep │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/04 │DosTimerAsync │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/05 │DosTimerStart │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/06 │DosStopTimer │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/07 │DosAsyncTimer │ ├────────────────────┼──────────────────────────────────────────────────┤ │38/08 │DosStartTimer │ ├────────────────────┼──────────────────────────────────────────────────┤ │39/01 │DosQueryCp │ ├────────────────────┼──────────────────────────────────────────────────┤ │39/08 │DosMapCase │ ├────────────────────┼──────────────────────────────────────────────────┤ │39/09 │DosQueryCollate │ ├────────────────────┼──────────────────────────────────────────────────┤ │39/0A │DosQueryCtryInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │39/0B │DosQueryDBCSEv │ ├────────────────────┼──────────────────────────────────────────────────┤ │4F/01 │DOSIntEnter │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/01 │KeyboardInput │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/02 │DisplayOutput │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/05 │PrinterOutput │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/06 │DirectConsoleI/O │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/07 │DirectConsoleInput │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/08 │ConsoleInput │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/09 │DisplayString │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/0A │BufferedKeyboardInput │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/0B │CheckStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/0D │DiskReset │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/0E │SelectDisk │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.9. Dos Functions - 8 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/0F │FCBOPEN │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/10 │FCBClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/11 │FCBFindFirst │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/12 │FCBNextEntry │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/14 │FCBSeqRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/15 │FCBSeqWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/16 │FCBCreateFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/17 │FCBRenameFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/19 │CurrentDisk │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/1A │SetDiskXferAddress │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/1B │AllocTableInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/1C │AllocTableInfoForSpecificDevice │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/21 │FCBRandomRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/22 │FCBRandomWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/23 │FCBFileSize │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/24 │FCBLSEEK │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/25 │SetInterruptVector │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/26 │CreateNewProgSegPrefix │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/27 │FCBRandomBlockRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/28 │FCBRandomBlockWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/29 │ParseFilename │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/2A │GetDate │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/2B │SetDate │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/2C │GetTime │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/2D │SetTime │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/2F │GetDiskXferAddress │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/35 │GetInterruptVector │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/36 │GetDiskFreeSpace │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/39 │CreateSubdirectory │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/3A │RemoveSubdirectory │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/3B │ChangeCurrentDirectory │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/3C │CREATE │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/3D │OPEN │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/3E │CLOSE │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/3F │READ │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/40 │WRITE │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/41 │DeleteFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/42 │LSEEK │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/43 │ChangeFileMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/44 │IOCTL │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.10. Dos Functions - 9 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/45 │DupFileHandle │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/46 │ForceDupFileHandle │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/47 │GetCurrentDirectory │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/48 │AllocateMemorySegment │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/49 │FreeMemorySegment │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/4A │ResizeMemorySegment │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/4B │EXEC │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/4C │ProgTerminate │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/4E │FINDFIRST │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/4F │FINDNEXT │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/56 │RENAMEFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/57 │Get/SetFileDate/Time │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/5A │CreateUniqueFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/5B │CREATENEW │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/5C │Lock/UnlockFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │50/68 │CommitFile │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/01 │SetSystemTimerTimeCounter │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/02 │ReadRealTimeClockTime │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/03 │SetRealTimeClockTime │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/04 │ReadRealTimeClockDate │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/05 │SetRealTimeClockDate │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/06 │SetRealTimeClockAlarm │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/07 │ResetRealTimeClockAlarm │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/08 │SetRealTimeClock │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/09 │ReadRealTimeClockAlarm │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/0A │ReadSystemTimerDayCounter │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/0B │SetSystemTimerDayCounter │ ├────────────────────┼──────────────────────────────────────────────────┤ │52/7E │ReadSystemTimerTimeCounter │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/01 │SetCursorType │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/02 │SetCursorPosition │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/03 │ReadCursorPosition │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/04 │ReadLightPenPosition │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/05 │SelectActiveDisplayPage │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/06 │ScrollActivePageUp │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/07 │ScrollActivePageDown │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/08 │ReadAttribute/CharacterAtCurrentCursorPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/09 │WriteAttribute/CharacterAtCurrentCursorPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/0A │WriteCharacterAtCurrentCursorPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/0B │SetColorPalette │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.11. Dos Functions - 10 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/0C │WriteDot │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/0D │ReadDot │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/0E │WriteTeletypetoActivePage │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/0F │ReadCurrentVideoState │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/10 │SetPaletteRegisters │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/11 │CharacterGenerator │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/12 │AlternateSelect │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/13 │WriteString │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/14 │LoadLCDCharacterFont/Set │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/15 │ReturnPhysicalDisplayParameters │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/1A │Read/WriteDisplayCombinationCode │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/1B │ReturnFunctionality/StateInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/1C │Save/RestoreVideoState │ ├────────────────────┼──────────────────────────────────────────────────┤ │54/7E │SetMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/01 │KeyboardRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/02 │KeyboardStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/03 │ShiftStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/04 │SetTypematicRate │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/05 │KeyboardWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/10 │ExtendedKeyboardRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/11 │ExtendedKeyboardStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/12 │ExtendedShiftStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/13 │KeyboardIntercept │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/20 │Extended122KeyboardRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/21 │Extended122KeyboardStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │56/22 │Extended122ShiftStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │57/01 │InitializeThePrinterPort │ ├────────────────────┼──────────────────────────────────────────────────┤ │57/02 │ReadStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │57/7E │PrintCharacter │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/01 │ReadStatusOfLastOp │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/02 │ReadDesiredSectors │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/03 │WriteDesiredSectors │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/04 │VerifyDesiredSectors │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/05 │FormatDesiredCylinder │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/06 │FormatDesiredCylinderSetBadSectorFlags │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/07 │FormatDriveStarting │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/08 │ReadDriveParameters │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/09 │InitializeDrivePairChar │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/0C │Seek │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/0D │AlternateDiskReset │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/10 │TestDriveReady │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/11 │Recalibrate │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/15 │ReadDASDType │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/19 │ParkHeads │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/1A │FormatUnit │ ├────────────────────┼──────────────────────────────────────────────────┤ │58/7E │ResetDiskSystem │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.12. Dos Functions - 11 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │59/01 │SendAChar │ ├────────────────────┼──────────────────────────────────────────────────┤ │59/02 │ReceiveAChar │ ├────────────────────┼──────────────────────────────────────────────────┤ │59/03 │ReadStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │59/04 │ExtendedInitialize │ ├────────────────────┼──────────────────────────────────────────────────┤ │59/05 │ExtendedCommPortControl │ ├────────────────────┼──────────────────────────────────────────────────┤ │59/7E │InitTheCommPort │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/01 │ShowCursor │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/02 │HideCursor │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/03 │GetButtonStatusAndMousePos │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/04 │SetMouseCursorPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/05 │GetButtonPressInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/06 │GetButtonReleaseInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/07 │SetMin/MaxHorizontalCursor │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/08 │SetMin/MaxVerticalCursor │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/09 │SetGraphicsCursorBlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/0A │SetTextCursor │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/0B │ReadMouseMotionCounters │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/0C │SetIntSubrCallMask │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/0D │LightPenEmulModeOn │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/0E │LightPenEmulModeOff │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/0F │SetMickey/PixelRatio │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/10 │ConditionalOff │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/11 │SetDoubleSpeedThreshold │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/12 │SwapInterruptSubroutines │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/13 │GetMouseDriverState │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/14 │SaveMouseDriverState │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/15 │RestoreMouseDriverState │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/16 │SetAltSubrCallMask │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/17 │GetUserAltIntAddr │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/18 │SetMouseSensitivity │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/19 │GetMouseSensitivity │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/1A │SetMouseInterruptRate │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/1B │SetCRTPageNumber │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/1C │GetCRTPageNumber │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/1D │DisableMouseDriver │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/1E │EnableMouseDriver │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/1F │SoftwareReset │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/20 │SetLanguageForMsg │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/21 │GetLanguageNumber │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/22 │GetDriverVersion │ ├────────────────────┼──────────────────────────────────────────────────┤ │5A/7E │MouseResetAndStatus │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.13. Dos Functions - 12 of 12 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/01 │ReadStatusOfLastOp │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/02 │ReadDesiredSectors │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/03 │WriteDesiredSectors │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/04 │VerifyDesiredSectors │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/05 │FormatDesiredTrack │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/08 │ReadDriveParameters │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/15 │ReadDASDType │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/16 │SetDisketteChgLineStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/17 │SetDASDTypeForFormat │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/18 │SetMediaTypeForFormat │ ├────────────────────┼──────────────────────────────────────────────────┤ │5C/7E │ResetDisketteSystem │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/01 │DosDevConfig │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/02 │DosDevIOCtl │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/04 │DosMonOpen │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/05 │DosMonClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/06 │DosMonReg │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/07 │DosMonRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/08 │DosMonWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/09 │DosPhysicalDisk │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/0A │DosDevIOCtl2 │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/0B │DosCLIAccess │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/0C │DosPortAccess │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/81 │DosDevConfig │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/82 │DosDevIOCtl │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/84 │DosMonOpen │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/85 │DosMonClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/86 │DosMonReg │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/87 │DosMonRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/88 │DosMonWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/89 │DosPhysicalDisk │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/8A │DosDevIOCtl2 │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/8B │DosCLIAccess │ ├────────────────────┼──────────────────────────────────────────────────┤ │60/8C │DosPortAccess │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.14. DevHlp Functions - 1 of 2 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/01 │DevHlp_SchedClock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/02 │DevHlp_DevDone │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/03 │DevHlp_Yield │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/04 │DevHlp_TCYield │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/05 │DevHlp_Block │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/06 │DevHlp_Run │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/07 │DevHlp_SemRequest │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/08 │DevHlp_SemClear │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/09 │DevHlp_SemHandle │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/0A │DevHlp_PushReqPacket │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/0B │DevHlp_PullReqPacket │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/0C │DevHlp_PullParticular │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/0D │DevHlp_SortReqPacket │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/0E │DevHlp_AllocReqPacket │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/0F │DevHlp_FreeReqPacket │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/10 │DevHlp_QueueInit │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/11 │DevHlp_QueueFlush │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/12 │DevHlp_QueueWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/13 │DevHlp_QueueRead │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/14 │DevHlp_Lock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/15 │DevHlp_Unlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/17 │DevHlp_VirtToPhys │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/18 │DevHlp_PhysToUVirt │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/19 │DevHlp_AllocPhys │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/1A │DevHlp_FreePhys │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/1B │DevHlp_SetROMVector │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/1C │DevHlp_SetIRQ │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/1D │DevHlp_UnSetIRQ │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/1E │DevHlp_SetTimer │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/1F │DevHlp_ResetTimer │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/20 │DevHlp_MonCreate │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/21 │DevHlp_Register │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/22 │DevHlp_DeRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/23 │DevHlp_MonWrite │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/24 │DevHlp_MonFlush │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/25 │DevHlp_GetDOSVar │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/26 │DevHlp_SendEvent │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/27 │DevHlp_ROMCritSection │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/28 │DevHlp_EOI │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/29 │DevHlp_GetLIDEntry │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/2A │DevHlp_FreeLIDEntry │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/2B │DevHlp_ABIOSCall │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/2C │DevHlp_ABIOSCommonEnt │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/2E │DevHlp_TickCount │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/2F │DevHlp_AllocGDTSel │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.15. DevHlp Functions - 2 of 2 ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/30 │DevHlp_PhysToGDTSel │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/31 │DevHlp_RealToProt │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/32 │DevHlp_ProtToReal │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/33 │DevHlp_VerifyAccess │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/34 │DevHlp_AddTraceEvent │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/35 │DevHlp_GetDeviceBlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/36 │DevHlp_ABIOSGetParms │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/37 │DevHlp_AttachDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/38 │DevHlp_InternalError │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/3A │DevHlp_Profiling Kernel │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/3B │DevHlp_RegStackUsage │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/3C │DevHlp_LogEntry │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/3D │DevHlp_VideoPause │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/3E │DevHlp_SaveMessage │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/3F │DevHlp_ReallocSeg │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/40 │DevHlp_PutWaitingQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/41 │DevHlp_GetWaitingQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/42 │DevHlp_VMAlloc │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/43 │DevHlp_VMFree │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/44 │DevHlp_VMGlobalToProcess │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/45 │DevHlp_VMLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/46 │DevHlp_VMProcessToGlobal │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/47 │DevHlp_VMUnlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/48 │DevHlp_FreeGDTSelector │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/49 │DevHlp_GetDescInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/4A │DevHlp_LinToGDTSelector │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/4B │DevHlp_LinToPageList │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/4C │DevHlp_PageListToGDTSelector │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/4D │DevHlp_PageListToLin │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/4E │DevHlp_VirtToLin │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/70 │DevHlp_CreateSpinLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/71 │DevHlp_FreeSpinLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/72 │DevHlp_AcquireSpinLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │61/73 │DevHlp_ReleaseSpinLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │62/01 │DevHlp_PhysToVirt │ ├────────────────────┼──────────────────────────────────────────────────┤ │62/02 │DevHlp_UnPhysToVirt │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.16. Kbd Functions ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/01 │DosBeep │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/02 │KbdRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/03 │KbdCharIn │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/04 │KbdFlushBuffer │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/05 │KbdPeek │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/06 │KbdSetStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/07 │KbdGetStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/08 │KbdStringIn │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/09 │KbdDeRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/0A │KbdOpen │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/0B │KbdClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/0C │KbdGetFocus │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/0D │KbdFreeFocus │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/0E │KbdGetCp │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/0F │KbdSetCp │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/10 │KbdXlate │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/11 │KbdSetCustXt │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/12 │KbdGetHWID │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/13 │KbdSetFgnd │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/14 │KbdShellInit │ ├────────────────────┼──────────────────────────────────────────────────┤ │64/15 │KbdSynch │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/01 │Read │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/02 │Write │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/03 │Write with verify │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/04 │Request Enqueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/05 │Request List Entry │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/06 │SCB Entry Ready For Transfer │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/07 │SCB Chain Complete │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/08 │Strategy-1 Request │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/09 │IOCTL Request │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/0A │Strategy-2 RL Header │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/0B │Strategy-2 RL Entry │ ├────────────────────┼──────────────────────────────────────────────────┤ │68/0C │IORB Request │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.17. Mouse Functions ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/01 │MouRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/02 │MouGetNumButtons │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/03 │MouGetNumMickeys │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/04 │MouGetDevStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/05 │MouReadEventQue │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/06 │MouGetNumQueEl │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/07 │MouGetEventMask │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/08 │MouGetScaleFact │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/09 │MouSetScaleFact │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/0A │MouSetEventMask │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/0B │MouOpen │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/0C │MouClose │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/0D │MouSetPtrShape │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/0E │MouRemovePtr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/0F │MouDrawPtr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/11 │MouDeregister │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/13 │MouGetPtrShape │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/14 │MouGetPtrPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/15 │MouSetPtrPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/17 │MouFlushQue │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/18 │MouSetDevStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/19 │MouGetThreshold │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/1A │MouSetThreshold │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/1B │MouShellInit │ ├────────────────────┼──────────────────────────────────────────────────┤ │6A/1C │MouSynch │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.18. VIO Functions ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/01 │VioRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/02 │VioGetBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/03 │VioGetCurPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/04 │VioGetCurType │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/05 │VioGetMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/06 │VioGetPhysBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/07 │VioReadCellStr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/08 │VioReadCharStr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/09 │VioScrollDn │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/0A │VioScrollUp │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/0B │VioScrollLf │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/0C │VioScrollRt │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/0D │VioSetCurPos │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/0E │VioSetCurType │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/0F │VioSetMode │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/10 │VioShowBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/11 │VioWrtCellStr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/12 │VioWrtCharStr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/13 │VioWrtCharStrAtt │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/14 │VioWrtNAttr │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/15 │VioWrtNCell │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/16 │VioWrtNChar │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/17 │VioWrtTTY │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/18 │VioSetAnsi │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/19 │VioGetAnsi │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/1A │VioModeWait │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/1B │VioSavRedrawWait │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/1C │VioSavRedrawUndo │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/1D │VioScrLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/1E │VioScrUnLock │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/1F │VioModeUndo │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/20 │VioGetFont │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/21 │VioGetConfig │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/22 │VioPopUp │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/23 │VioEndPopUp │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/24 │VioDeRegister │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/25 │VioPrtSc │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/26 │VioPrtScToggle │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/27 │VioSetCp │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/28 │VioGetCp │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/29 │VioSetFont │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/2A │VioGetState │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/2B │VioSetState │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/2C │VioAssociate │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/2D │VioCreateLogFont │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/2E │VioCreatePS │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/2F │VioDeleteSetID │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/30 │VioGetDeviceCellSize │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/31 │VioGetOrg │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/32 │VioGetPSAddress │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/33 │VioGlobalReg │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/34 │VioQueryConsole │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/35 │VioQueryFonts │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/36 │VioQuerySetIDs │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/37 │VioSetDeviceCellSize │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/38 │VioSetOrg │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/39 │VioShieldInit │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/3A │VioShieldTerm │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/3B │VioShowPS │ ├────────────────────┼──────────────────────────────────────────────────┤ │6C/3C │VioDestroyPS │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.19. Miscellaneous Kernel Functions ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/01 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/02 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/03 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/04 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/05 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/06 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/07 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │7F/08 │CpuSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/02 │DosSMSGStart │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/03 │DosSMSGSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/04 │DosSMSGTerminate │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/09 │DosSMSGDoPopup │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/0A │DosSMSGEndPopup │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/0B │DosSMSGSet │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/0C │DosSelectSession │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/0D │DosSetSession │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/0E │DosStartSession │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/0F │DosStopSession │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/11 │DosSMDoAppReq │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/13 │DosSMAppNotify │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/14 │DosSMNotifyDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/15 │DosSMNotifyDD2 │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/16 │DosSMParentSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/17 │DosSMGetStatus │ ├────────────────────┼──────────────────────────────────────────────────┤ │80/18 │DosSMRegisterDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/03 │DosSMGetSGId │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/04 │DosSMFreeSGId │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/05 │DosSMAddSGQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/06 │DosSMGetSGQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/07 │DosSMDelSGQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/09 │DosSMChildExit │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/0A │ParentNotify │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/0B │ParentSwitch │ ├────────────────────┼──────────────────────────────────────────────────┤ │81/0C │WriteTermQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │83/01 │DosGetMessage │ ├────────────────────┼──────────────────────────────────────────────────┤ │83/02 │DosInsertMessage │ ├────────────────────┼──────────────────────────────────────────────────┤ │83/03 │DosPutMessage │ ├────────────────────┼──────────────────────────────────────────────────┤ │83/04 │DosQueryMessageCP │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/01 │DosCloseQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/02 │DosCreateQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/03 │DosOpenQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/04 │DosPeekQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/05 │DosPurgeQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/06 │DosQueryQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/07 │DosReadQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │88/08 │DosWriteQueue │ ├────────────────────┼──────────────────────────────────────────────────┤ │89/01 │Write Internal │ ├────────────────────┼──────────────────────────────────────────────────┤ │89/02 │Read Internal │ ├────────────────────┼──────────────────────────────────────────────────┤ │89/03 │Peek Internal │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.20. VDH Functions ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/01 │VDHCreateSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/02 │VDHDestroySem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/03 │VDHWaitEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/04 │VDHRequestMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/05 │VDHReleaseMutexSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/06 │VDHResetEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/07 │VDHPostEventSem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/08 │VDHQuerySem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/09 │VDHArmTimerHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/0A │VDHDisArmTimerHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/0B │VDHAllocMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/0C │VDHFreeMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/0D │VDHAllocDosMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/0E │VDHCreateBlockPool │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/0F │VDHAllocBlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/10 │VDHFreeBlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/11 │VDHDestroyBlockPool │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/12 │VDHCopyMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/13 │VDHExchangeMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/14 │VDHAllocPages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/15 │VDHReallocPages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/16 │VDHFreePages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/17 │VDHFindFreePages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/18 │VDHGetDirtyPageInfo │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/19 │VDHQueryFreePages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/1A │VDHReservePages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/1B │VDHUnreservePages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/1C │VDHMapPages │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/1D │VDHAllocDMABuffer │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/1E │VDHFreeDMABuffer │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/1F │VDHYield │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/20 │VDHSetPriority │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/21 │VDHCreateSel │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/22 │VDHDestroySel │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/23 │VDHLockMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/24 │VDHUnlockMem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/25 │VDHQueryHookData │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/26 │VDHArmContextHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/27 │VDHArmSTIHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/28 │VDHArmReturnHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/29 │VDHPushFarCall │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/2F │VDHPushRegs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/30 │VDHPopRegs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/31 │VDHPushStack │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/32 │VDHPopStack │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/33 │VDHSwitchToVPM │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/34 │VDHSwitchToV86 │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/35 │VDHSetFlags │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/36 │VDHPushInt │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/37 │VDHPopInt │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/39 │VDHSetDosDevice │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/3A │VDHInstallIOHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/3B │VDHRemoveIOHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/3C │VDHSetIOHookState │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/3D │VDHInstallIntHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/3E │VDHAllocHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/3F │VDHFreeHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/40 │VDHArmBPHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/41 │VDHRegisterDPMI │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/42 │VDHGetSelBase │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/43 │VDHChangeVPMIF │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/44 │VDHReadUBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/45 │VDHWriteUBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/46 │VDHStartHWInt │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/47 │VDHCheckPagePerm │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/48 │VDHRaiseException │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/49 │VDHCheckVPMExcept │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/4A │VDHGetVPMExcept │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/4B │VDHSetVPMExcept │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/4C │VDHCheckVPMIntVector │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/4D │VDHGetVPMIntVector │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/4E │VDHSetVPMIntVector │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/4F │VDHArmVPMBPHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/50 │VDHBeginUseVPMStack │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/51 │VDHEndUseVPMStack │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/52 │VDHProbeUBuf │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/53 │VDHPopVPMFarRet │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/54 │VDHPrepVPMIret │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/55 │VDHKillVDM │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/56 │VDHHaltSystem │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/57 │VDHFreezeVDM │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/58 │VDHThawVDM │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/59 │VDHIsVDMFrozen │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/5A │VDHOpenPDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/5B │VDHRegisterVDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/5C │VDHInstallUserHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/5D │VDHValidatePID │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/5E │VDHVMGetHandle │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/5F │VDHVMAttach │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/60 │VDHOpenVDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/61 │VDHCloseVDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/62 │VDHHandleFromPID │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/63 │VDHQuerySel │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/64 │VDHPutSysValue │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/65 │VDHRequestVDD │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/66 │VDHRegisterPerfCtrs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/67 │VDHDecodeProperty │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/68 │VDHCreateThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/69 │VDHExitThread │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/6A │VDHGetError │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/6B │VDHSetError │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/6C │VDHHandleFromSGID │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/6D │VDHEnumerateVDMs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/6E │VDHQueryLin │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/6F │VDHQuerySysValue │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/70 │VDHDevBeep │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/71 │VDHProcessToGlobal │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/72 │VDHInstallFaultHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/73 │VDHRemoveFaultHook │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/74 │VDHMapMemBlock │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/75 │VDHRegisterProperty │ ├────────────────────┼──────────────────────────────────────────────────┤ │8D/76 │VDHQueryProperty │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/2A │VDHSetVIRR │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/2B │VDHClearVIRR │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/2C │VDHQueryVIRQ │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/2D │VDHWaitVIRRs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/2E │VDHWakeVIRRs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/38 │VDHSendVEOI │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/AA │VDHSetVIRR │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/AB │VDHClearVIRR │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/AC │VDHQueryVIRQ │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/AD │VDHWaitVIRRs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/AE │VDHWakeVIRRs │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/B8 │VDHSendVEOI │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.21. Vpic, WinOS2 and STRACE Functions ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event Name │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/77 │vpicIntHdlr │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/78 │vpicSetVIRR │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/79 │vpicChangeVIRRState │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/7A │vpicCheckVIRR │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/7B │vpicSimulateInt │ ├────────────────────┼──────────────────────────────────────────────────┤ │8E/7C │vpicSimulateIRQ0 │ ├────────────────────┼──────────────────────────────────────────────────┤ │90/01 │WinOS2CreateTask │ ├────────────────────┼──────────────────────────────────────────────────┤ │90/02 │WinOS2LoadModule │ ├────────────────────┼──────────────────────────────────────────────────┤ │90/03 │WinOS2LoadSegment │ ├────────────────────┼──────────────────────────────────────────────────┤ │90/04 │WinOS2Schedule │ ├────────────────────┼──────────────────────────────────────────────────┤ │90/83 │WinOS2LoadSegment │ ├────────────────────┼──────────────────────────────────────────────────┤ │A7/01 │Display Disk Directory │ ├────────────────────┼──────────────────────────────────────────────────┤ │A7/02 │ShowMem Thread Dispatching │ ├────────────────────┼──────────────────────────────────────────────────┤ │A7/03 │Display Disk Directory │ ├────────────────────┼──────────────────────────────────────────────────┤ │A7/04 │Specify Physical Drive │ ├────────────────────┼──────────────────────────────────────────────────┤ │A8/01 │STRACE High32 Timer │ ├────────────────────┼──────────────────────────────────────────────────┤ │A8/02 │STRACE Startup Hook │ ├────────────────────┼──────────────────────────────────────────────────┤ │A8/03 │STRACE MTE Hook │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 12.7.22. Hooks Reserved for Customer Use ═══ ┌────────────────────┬──────────────────────────────────────────────────┐ │Hook ID │Event │ │Major/Minor Code │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │B8/00-FF │Reserved for customer use │ ├────────────────────┼──────────────────────────────────────────────────┤ │B9/00-FF │Reserved for customer use │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 13. View and Set Program Type For Executable File (MARKEXE) ═══ The MARKEXE program enables you to view and set the program type for an executable file. The program type identifies the OS/2 sessions in which a program can run. For applications running on OS/2 Warp Server for SMP, MARKEXE enables you to set the MPUNSAFE bit, which forces the application to always run in uniprocessor mode. See Requirements for Multi-Processing for information on when to set the MPUNSAFE bit. Use MARKEXE with the OS/2 Linear Executable Linker (LINK386) or the OS/2 Segmented Executable Linker (LINK) to change or set the program type of programs you have created and to set or unset the MPUNSAFE bit. You can set DLL initialization and termination and also enable long file name support. When using LINK386, you can set DLL initialization and termination; long file name support is already set. When using LINK, you can set DLL initialization and long file name support. ═══ 13.1. Command-Line Syntax ═══ MARKEXE uses the following syntax: MARKEXE [/?] [FORCE] [NO] [option] filename... Filename is a file name or a list of file names. Global file-name characters (*.EXE) also can be used. For descriptions of the above terms, see Syntax Definitions. If no option is given, DISPLAY is assumed. Typing MARKEXE /? at the command line displays the appropriate copyright statement along with a list of options. DISPLAY - display status of flags DLLINIT - per-process initialization DLLTERM - per-process termination WINDOWAPI - window api (PM application) WINDOWCOMPAT - window compatible application NOTWINDOWCOMPAT - not window compatible application UNSPECIFIED - unspecified application type LFNS - long file name support MPUNSAFE - multi-processor unsafe application ═══ 13.1.1. Syntax Definitions ═══ MARKEXE has the following keywords, options, and program types. You can also specify any number of files to be viewed or marked. KEYWORDS FORCE Marks the executable file with OS/2 as the target operating system even though the file was marked for another operating system. Using FORCE might produce internally inconsistent executable files. NO Sets the command to the opposite condition. This keyword does not apply to the DISPLAY option or any of the Program Type options. OPTIONS DISPLAY Displays the application type in a message; does not make any changes. (This is the default option.) DLLINIT Sets per process initialization for the dynamic link library. DLLTERM Sets per process termination for the dynamic link library. (Use with LINK386 only.) LFNS Enables support of long file names. (Use with LINK only.) MPUNSAFE Marks the application as unsafe for running in a multi-processor environment. Note: Only one option may be entered on the command line. PROGRAM TYPES MARKEXE does not modify the file if the executable file's program type is the same as the requested type. It displays a message instead. WINDOWAPI The application is a Presentation Manager application and can run in the Presentation Manager session only. WINDOWCOMPAT The application can run in a Presentation Manager window or in an full-screen session. NOTWINDOWCOMPAT The application must run in an OS/2 full-screen session. UNSPECIFIED The application type is not known. By default, the OS/2 operating system will force the program to run in a full-screen session. Note: Specifying an incorrect program type might cause undesirable results when you try to run that program. For example, do not change a WINDOWCOMPAT program to WINDOWAPI. Only one program type may be entered on the command line. ═══ 13.1.2. Viewing Program Type ═══ To display the program type of an executable file without changing the file, specify only a file name, omitting an option. MARKEXE filename.exe Example To view the program type of MYPROG.EXE, type the following: MARKEXE myprog.exe MARKEXE displays the type in a message that looks like this: myprog.exe: OS/2 1.x, WINDOWCOMPAT, LFNS ═══ 13.1.3. Setting Program Type ═══ To set the program type of an executable file, specify one of the program types. More than one executable file can be set to the same program type on a single command line. MARKEXE type filename.exe another.exe Examples To set WINDOWCOMPAT as the program type of MYPROG.EXE, type: MARKEXE WINDOWCOMPAT myprog.exe To set WINDOWAPI as the program type of several executable files, type: MARKEXE WINDOWAPI marion.exe alex.exe ═══ 13.1.4. Requirements for Multi-Processing ═══ The following should be considered before running an application in multi-processor mode:  An application or associated subsystem must not use the 'INC' instruction as a semaphore without prepending a 'LOCK' prefix. On a UniProcessor (UP) system this instruction can be used as a high-performance semaphore without calling any other operating system service if the semaphore is free and when the semaphore is clear and there are no waiters for the semaphore. Because the INC instruction cannot be interrupted once started, and because the results would be stored in the flags register which are per thread, then it could be used safely as a semaphore. In an OS/2 Warp Server for SMP environment, this technique will not work because it is possible that two or more threads could be executing the same INC instruction, receiving the same results in each processor's or thread's flag register and thinking that they have the semaphore.  A 486 or greater instruction such as CMPXCHG has the same problem as above if a 'LOCK' prefix is not prepended before the instruction.  An application or associated subsystem which relies on priorities to guarantee execution of its threads within a process will not work in OS/2 Warp Server for SMP. For example, an application may have a time-critical and an idle thread, and may assume that while the time-critical thread is executing the idle thread will not get any execution time unless the time-critical thread explicitly yields the CPU. In an OS/2 Warp Server for SMP environment it is possible that both the time-critical and the idle threads are executing simultaneously on different processors. The above compatibility requirements apply only to multi-threaded applications, and therefore do no apply to DOS and WINOS2 applications. However, you are strongly encouraged to write 32-bit multi-threaded applications for better performance and portability on OS/2 Warp Server for SMP. Given the possibility that some set of applications may use one of these techniques, OS/2 Warp Server for SMP provides a mechanism that allows these multi-threaded applications to execute in UP mode. UP mode permits only one thread of that process to execute at a time. That thread could execute on any one of the available processors. MARKEXE, described in View and Set Program Type For Executable File (MARKEXE), is used to mark an executable file as uniprocessor only. When an executable file that has the uniprocessor mode flag set is loaded, OS/2 ensures that only one thread of that process will ever execute at a time. Multiple uniprocessor only processes may be active in the system at the same time, but only one thread from each process may be active at a time. ═══ 14. Data Types ═══ The following are the data types referenced in this book. They are listed in alphabetical order. ═══ 14.1. AddrS ═══ Data associated with the kernel debugger communications protocol. typedef struct _AddrS { DWORD AddrOff; /* Address offset. */ DWORD AddrSeg; /* Address segment or selector. */ BYTE AddrType; /* Type of address specified. */ BYTE AddrSize; /* AddrSize */ WORD AddrTask; /* AddrTask */ } AddrS; typedef AddrS *AddrS; ═══ AddrS Field - AddrOff ═══ AddrOff (DWORD) Address offset. ═══ AddrS Field - AddrSeg ═══ AddrSeg (DWORD) Address segment or selector. ═══ AddrS Field - AddrType ═══ AddrType (BYTE) Type of address specified. Type of address specified. Valid types are: EXPR_TYPE_SEG (0x01) Address is of form segment:offset. EXPR_TYPE_LIN (0x02) Address type is linear. EXPR_TYPE_SEL (0x09) Address is of form selector:offset. EXPR_TYPE_PHY (0x0A) Address type is physical. ═══ AddrS Field - AddrSize ═══ AddrSize (BYTE) AddrSize ═══ AddrS Field - AddrTask ═══ AddrTask (WORD) AddrTask ═══ 14.2. APIRET ═══ Unsigned integer in the range 0 through 4 294 967 295. typedef unsigned long APIRET; ═══ 14.3. BIOSPARAMETERBLOCK ═══ BIOS Parameter Block (BPB). typedef struct _BIOSPARAMETERBLOCK { USHORT usBytesPerSector; /* Number of bytes per sector. */ BYTE bSectorsPerCluster; /* Number of sectors per cluster. */ USHORT usReservedSectors; /* Number of reserved sectors. */ BYTE cFATs; /* Number of FATs. */ USHORT cRootEntries; /* Number of root directory entries. */ USHORT cSectors; /* Number of sectors. */ BYTE bMedia; /* Media descriptor. */ USHORT usSectorsPerFAT; /* Number of secctors per FAT. */ USHORT usSectorsPerTrack; /* Number of sectors per track. */ USHORT cHeads; /* Number of heads. */ ULONG cHiddenSectors; /* Number of hidden sectors. */ ULONG cLargeSectors; /* Number of large sectors. */ BYTE abReserved[6]; /* Reserved. */ USHORT cCylinders; /* Number of cylinders defined for the physical device. */ BYTE bDeviceType; /* Physical layout of the specified device. */ USHORT fsDeviceAttr; /* A bit field that returns flag information about the specified drive. */ } BIOSPARAMETERBLOCK; typedef BIOSPARAMETERBLOCK *PBIOSPARAMETERBLOCK; ═══ BIOSPARAMETERBLOCK Field - usBytesPerSector ═══ usBytesPerSector (USHORT) Number of bytes per sector. ═══ BIOSPARAMETERBLOCK Field - bSectorsPerCluster ═══ bSectorsPerCluster (BYTE) Number of sectors per cluster. ═══ BIOSPARAMETERBLOCK Field - usReservedSectors ═══ usReservedSectors (USHORT) Number of reserved sectors. ═══ BIOSPARAMETERBLOCK Field - cFATs ═══ cFATs (BYTE) Number of FATs. ═══ BIOSPARAMETERBLOCK Field - cRootEntries ═══ cRootEntries (USHORT) Number of root directory entries. ═══ BIOSPARAMETERBLOCK Field - cSectors ═══ cSectors (USHORT) Number of sectors. ═══ BIOSPARAMETERBLOCK Field - bMedia ═══ bMedia (BYTE) Media descriptor. ═══ BIOSPARAMETERBLOCK Field - usSectorsPerFAT ═══ usSectorsPerFAT (USHORT) Number of secctors per FAT. ═══ BIOSPARAMETERBLOCK Field - usSectorsPerTrack ═══ usSectorsPerTrack (USHORT) Number of sectors per track. ═══ BIOSPARAMETERBLOCK Field - cHeads ═══ cHeads (USHORT) Number of heads. ═══ BIOSPARAMETERBLOCK Field - cHiddenSectors ═══ cHiddenSectors (ULONG) Number of hidden sectors. ═══ BIOSPARAMETERBLOCK Field - cLargeSectors ═══ cLargeSectors (ULONG) Number of large sectors. ═══ BIOSPARAMETERBLOCK Field - abReserved[6] ═══ abReserved[6] (BYTE) Reserved. ═══ BIOSPARAMETERBLOCK Field - cCylinders ═══ cCylinders (USHORT) Number of cylinders defined for the physical device. ═══ BIOSPARAMETERBLOCK Field - bDeviceType ═══ bDeviceType (BYTE) Physical layout of the specified device. 0 48 TPI low-density diskette drive 1 96 TPI high-density diskette drive 2 Small (3.5-inch) 720KB drive 3 8-inch single-density diskette drive 4 8-inch double-density diskette drive 5 Fixed disk 6 Tape drive 7 Other (includes 1.44MB 3.5-inch diskette drive) 8 R/W optical disk 9 3.5-inch 4.0MB diskette drive (2.88MB formatted) ═══ BIOSPARAMETERBLOCK Field - fsDeviceAttr ═══ fsDeviceAttr (USHORT) A bit field that returns flag information about the specified drive. Bit 0 Removable Media flag. 0 Media is removable. 1 Media cannot be removed. Bit 1 Changeline flag. 0 The physical device driver returns the value 0, Unsure if media has changed, from the Media Check function. 1 Device support determines that the media was removed since the last I/O operation. ═══ 14.4. BOOL ═══ Boolean. Valid values are:  FALSE, which is 0  TRUE, which is 1 typedef unsigned long BOOL; ═══ 14.5. BOOL32 ═══ Boolean. Valid values are:  FALSE, which is 0  TRUE, which is 1 typedef unsigned long BOOL32; ═══ 14.6. BYTE ═══ A byte. typedef unsigned char BYTE; ═══ 14.7. CHAR ═══ Single-byte character. #define CHAR char ═══ 14.8. CPUUTIL ═══ Performance data returned by DosPerfSysCall. typedef struct _CPUUTIL { ULONG ulTimeLow; /* Low 32 bits of time stamp */ ULONG ulTimeHigh; /* High 32 bits of time stamp */ ULONG ulIdleLow; /* Low 32 bits of idle time */ ULONG ulIdleHigh; /* High 32 bits of idle time */ ULONG ulBusyLow; /* Low 32 bits of busy time */ ULONG ulBusyHigh; /* High 32 bits of busy time */ ULONG ulIntrLow; /* Low 32 bits of interrupt time */ ULONG ulIntrHigh; /* High 32 bits of interrupt time */ } CPUUTIL; typedef CPUUTIL *PCPUUTIL; ═══ CPUUTIL Field - ulTimeLow ═══ ulTimeLow (ULONG) Low 32 bits of time stamp ═══ CPUUTIL Field - ulTimeHigh ═══ ulTimeHigh (ULONG) High 32 bits of time stamp ═══ CPUUTIL Field - ulIdleLow ═══ ulIdleLow (ULONG) Low 32 bits of idle time ═══ CPUUTIL Field - ulIdleHigh ═══ ulIdleHigh (ULONG) High 32 bits of idle time ═══ CPUUTIL Field - ulBusyLow ═══ ulBusyLow (ULONG) Low 32 bits of busy time ═══ CPUUTIL Field - ulBusyHigh ═══ ulBusyHigh (ULONG) High 32 bits of busy time ═══ CPUUTIL Field - ulIntrLow ═══ ulIntrLow (ULONG) Low 32 bits of interrupt time ═══ CPUUTIL Field - ulIntrHigh ═══ ulIntrHigh (ULONG) High 32 bits of interrupt time ═══ 14.9. cvkcmd_s ═══ Data associated with the kernel debugger communications protocol. typedef struct _cvkcmd_s { USHORT Cmd; /* Command */ ULONG Value; /* Value, command dependent. */ ULONG OffV; /* Command dependent, usually a linear address. */ USHORT SegV; /* Command dependent. Usually slot number of thread. */ USHORT MTE; /* Module Table Entry */ USHORT PID; /* Process Identifier */ USHORT TID; /* Thread Identifier */ USHORT DBit; /* Flags from the CS selector. */ RegSA_struc Reg; /* Register save area */ UCHAR MemCache; /* Data area */ } cvkcmd_s; typedef cvkcmd_s *cvkcmd_s; ═══ cvkcmd_s Field - Cmd ═══ Cmd (USHORT) Command One of the following: ┌────────────────────┬─────┬────────────────────┬────────┬────────┐ │Command │Code │Description │CVK_ │CVK_ │ │ │ │ │CMDSIZE_│RETSIZE_│ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_RMEM │ 1 │Read memory │18 │20 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_RREG │ 3 │Read registers │18 │24 + │ │ │ │ │ │sizeof( │ │ │ │ │ │RegSa_ │ │ │ │ │ │struc) │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_WMEM │ 4 │Write memory │20 │6 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_WREG │ 6 │Write registers │20 + │2 │ │ │ │ │sizeof( │ │ │ │ │ │RegSa_ │ │ │ │ │ │struc) │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_RUN │ 7 │Resume execution │6 │0 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_KILL │ 8 │Reboot victim │2 │0 │ │ │ │machine │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_STEP │ 9 │Single step │2 │0 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_NUMTOBASE │13 │Get object/segment │14 │14 │ │ │ │information │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_LIBNAME │16 │Get module │6 │6 │ │ │ │information │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_RAW │20 │Perform kernel │6 │ │ │ │ │debugger command │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_DBIT │22 │Get selector │20 │ │ │ │ │information │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_RSTEP │23 │Range step │10 │0 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_SCANMTE │24 │Scan module table │2 │6 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_SCANTCB │25 │Scan thread control │6 │10 │ │ │ │blocks │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_SEL2LIN │26 │Convert │18 │6 │ │ │ │selector:offset to │ │ │ │ │ │linear address. │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_LIN2SEL │27 │Convert linear │18 │12 │ │ │ │address to │ │ │ │ │ │selector:offset. │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_OBJCOUNT │28 │Get number of │6 │6 │ │ │ │objects/segments in │ │ │ │ │ │module │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_SCANOBJ │29 │Scan object/segment │14 │10 │ │ │ │table │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_SELINFO │30 │Get selector │18 │20 │ │ │ │information │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_RNPX │31 │Read NPX state │18 │128 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_WNPX │32 │Write NPX state │128 │60 │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_ENA │33 │Enable optional │6 │2 │ │ │ │features │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_DIS │34 │Disable optional │6 │2 │ │ │ │features │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_PIREG │35 │Register for PAGEIN │14 │2 │ │ │ │notification │ │ │ ├────────────────────┼─────┼────────────────────┼────────┼────────┤ │CVK_CMD_PIDRG │36 │Deregister for │14 │2 │ │ │ │PAGEIN notification │ │ │ └────────────────────┴─────┴────────────────────┴────────┴────────┘ ═══ cvkcmd_s Field - Value ═══ Value (ULONG) Value, command dependent. ═══ cvkcmd_s Field - OffV ═══ OffV (ULONG) Command dependent, usually a linear address. ═══ cvkcmd_s Field - SegV ═══ SegV (USHORT) Command dependent. Usually slot number of thread. ═══ cvkcmd_s Field - MTE ═══ MTE (USHORT) Module Table Entry ═══ cvkcmd_s Field - PID ═══ PID (USHORT) Process Identifier ═══ cvkcmd_s Field - TID ═══ TID (USHORT) Thread Identifier ═══ cvkcmd_s Field - DBit ═══ DBit (USHORT) Flags from the CS selector. ═══ cvkcmd_s Field - Reg ═══ Reg (RegSA_struc) Register save area ═══ cvkcmd_s Field - MemCache ═══ MemCache (UCHAR) Data area Data area used for variable length data in a command or response. Maximum size of the data is CVK_MEMCACHE_SIZE (512). ═══ 14.10. DosDebug Buffer ═══ DosDebug buffer structure. typedef struct _DosDebug Buffer { ULONG Pid; /* Debuggee Process ID */ ULONG Tid; /* Debuggee Thread ID */ LONG Cmd; /* Command or Notification */ LONG Value; /* Generic Data Value */ ULONG Addr; /* Debuggee Address */ ULONG Buffer; /* Debugger Buffer Address */ ULONG Len; /* Length of Range */ ULONG Index; /* Generic Identifier Index */ ULONG MTE; /* Module Table Entry Handle */ ULONG EAX; /* Register Set */ ULONG ECX; ULONG EDX; ULONG EBX; ULONG ESP; ULONG EBP; ULONG ESI; ULONG EDI; ULONG EFlags; ULONG EIP; ULONG CSLim; /* Byte Granular Limits */ ULONG CSBase; /* Byte Granular Base */ UCHAR CSAcc; /* Access Bytes */ UCHAR CSAtr; /* Attribute Bytes */ USHORT CS; ULONG DSLim; ULONG DSBase; UCHAR DSAcc; UCHAR DSAtr; USHORT DS; ULONG ESLim; ULONG ESBase; UCHAR ESAcc; UCHAR ESAtr; USHORT ES; ULONG FSLim; ULONG FSBase; UCHAR FSAcc; UCHAR FSAtr; USHORT FS; ULONG GSLim; ULONG GSBase; UCHAR GSAcc; UCHAR GSAtr; USHORT GS; ULONG SSLim; ULONG SSBase; UCHAR SSAcc; UCHAR SSAtr; USHORT SS; } DosDebug Buffer; typedef DosDebug Buffer *DBUGBUF; ═══ DosDebug Buffer Field - Pid ═══ Pid (ULONG) Debuggee Process ID ═══ DosDebug Buffer Field - Tid ═══ Tid (ULONG) Debuggee Thread ID ═══ DosDebug Buffer Field - Cmd ═══ Cmd (LONG) Command or Notification ═══ DosDebug Buffer Field - Value ═══ Value (LONG) Generic Data Value ═══ DosDebug Buffer Field - Addr ═══ Addr (ULONG) Debuggee Address ═══ DosDebug Buffer Field - Buffer ═══ Buffer (ULONG) Debugger Buffer Address ═══ DosDebug Buffer Field - Len ═══ Len (ULONG) Length of Range ═══ DosDebug Buffer Field - Index ═══ Index (ULONG) Generic Identifier Index ═══ DosDebug Buffer Field - MTE ═══ MTE (ULONG) Module Table Entry Handle ═══ DosDebug Buffer Field - EAX ═══ EAX (ULONG) Register Set ═══ DosDebug Buffer Field - ECX ═══ ECX (ULONG) ═══ DosDebug Buffer Field - EDX ═══ EDX (ULONG) ═══ DosDebug Buffer Field - EBX ═══ EBX (ULONG) ═══ DosDebug Buffer Field - ESP ═══ ESP (ULONG) ═══ DosDebug Buffer Field - EBP ═══ EBP (ULONG) ═══ DosDebug Buffer Field - ESI ═══ ESI (ULONG) ═══ DosDebug Buffer Field - EDI ═══ EDI (ULONG) ═══ DosDebug Buffer Field - EFlags ═══ EFlags (ULONG) ═══ DosDebug Buffer Field - EIP ═══ EIP (ULONG) ═══ DosDebug Buffer Field - CSLim ═══ CSLim (ULONG) Byte Granular Limits ═══ DosDebug Buffer Field - CSBase ═══ CSBase (ULONG) Byte Granular Base ═══ DosDebug Buffer Field - CSAcc ═══ CSAcc (UCHAR) Access Bytes ═══ DosDebug Buffer Field - CSAtr ═══ CSAtr (UCHAR) Attribute Bytes ═══ DosDebug Buffer Field - CS ═══ CS (USHORT) ═══ DosDebug Buffer Field - DSLim ═══ DSLim (ULONG) ═══ DosDebug Buffer Field - DSBase ═══ DSBase (ULONG) ═══ DosDebug Buffer Field - DSAcc ═══ DSAcc (UCHAR) ═══ DosDebug Buffer Field - DSAtr ═══ DSAtr (UCHAR) ═══ DosDebug Buffer Field - DS ═══ DS (USHORT) ═══ DosDebug Buffer Field - ESLim ═══ ESLim (ULONG) ═══ DosDebug Buffer Field - ESBase ═══ ESBase (ULONG) ═══ DosDebug Buffer Field - ESAcc ═══ ESAcc (UCHAR) ═══ DosDebug Buffer Field - ESAtr ═══ ESAtr (UCHAR) ═══ DosDebug Buffer Field - ES ═══ ES (USHORT) ═══ DosDebug Buffer Field - FSLim ═══ FSLim (ULONG) ═══ DosDebug Buffer Field - FSBase ═══ FSBase (ULONG) ═══ DosDebug Buffer Field - FSAcc ═══ FSAcc (UCHAR) ═══ DosDebug Buffer Field - FSAtr ═══ FSAtr (UCHAR) ═══ DosDebug Buffer Field - FS ═══ FS (USHORT) ═══ DosDebug Buffer Field - GSLim ═══ GSLim (ULONG) ═══ DosDebug Buffer Field - GSBase ═══ GSBase (ULONG) ═══ DosDebug Buffer Field - GSAcc ═══ GSAcc (UCHAR) ═══ DosDebug Buffer Field - GSAtr ═══ GSAtr (UCHAR) ═══ DosDebug Buffer Field - GS ═══ GS (USHORT) ═══ DosDebug Buffer Field - SSLim ═══ SSLim (ULONG) ═══ DosDebug Buffer Field - SSBase ═══ SSBase (ULONG) ═══ DosDebug Buffer Field - SSAcc ═══ SSAcc (UCHAR) ═══ DosDebug Buffer Field - SSAtr ═══ SSAtr (UCHAR) ═══ DosDebug Buffer Field - SS ═══ SS (USHORT) ═══ 14.11. DTR ═══ Data associated with the kernel debugger communications protocol. typedef struct _DTR { WORD DTRLimit; /* Limit of GDT/IDT register */ WORD DTRBaseLow; /* Bits 0-15 of base address. */ WORD DTRBaseHigh; /* Bits 16-23 of base address. */ WORD DTRBaseExt; /* Bits 24-31 of base address. */ } DTR; typedef DTR *DTR; ═══ DTR Field - DTRLimit ═══ DTRLimit (WORD) Limit of GDT/IDT register ═══ DTR Field - DTRBaseLow ═══ DTRBaseLow (WORD) Bits 0-15 of base address. ═══ DTR Field - DTRBaseHigh ═══ DTRBaseHigh (WORD) Bits 16-23 of base address. ═══ DTR Field - DTRBaseExt ═══ DTRBaseExt (WORD) Bits 24-31 of base address. ═══ 14.12. DWORD ═══ 32-bit unsigned integer in the range 0 through 4 294 967 295. typedef unsigned long DWORD; ═══ 14.13. EAOP2 ═══ EAOP2 data structure. typedef struct _EAOP2 { PGEA2LIST fpGEA2List; /* GEA set. */ PFEA2LIST fpFEA2List; /* FEA set. */ ULONG oError; /* Offset of FEA error. */ } EAOP2; typedef EAOP2 *PEAOP2; ═══ EAOP2 Field - fpGEA2List ═══ fpGEA2List (PGEA2LIST) GEA set. ═══ EAOP2 Field - fpFEA2List ═══ fpFEA2List (PFEA2LIST) FEA set. ═══ EAOP2 Field - oError ═══ oError (ULONG) Offset of FEA error. ═══ 14.14. EASIZEBUF ═══ Maximum size of extended attributes (EAs). typedef struct _EASIZEBUF { USHORT cbMaxEASize; /* Maximum size of an EA. */ ULONG cbMaxEAListSize; /* Maximum size of the full EA list. */ } EASIZEBUF; typedef EASIZEBUF *PEASIZEBUF; ═══ EASIZEBUF Field - cbMaxEASize ═══ cbMaxEASize (USHORT) Maximum size of an EA. ═══ EASIZEBUF Field - cbMaxEAListSize ═══ cbMaxEAListSize (ULONG) Maximum size of the full EA list. ═══ 14.15. ERRORID ═══ Error identity. typedef ULONG ERRORID; ═══ 14.16. EXCEPTIONREGISTRATIONRECORD ═══ These structures are linked together to form a chain of exception handlers that are dispatched upon receipt of an exception. Exception handlers should not be registered directly from a high level language such as "C". This is the responsibility of the language runtime routine. typedef struct _EXCEPTIONREGISTRATIONRECORD { STRUCT _EXCEPTIONREGISTRATIONRECORD *prev_structure; /* Nested exception registration record structure. */ _ERR *ExceptionHandler; /* Pointer to the ERR function. */ } EXCEPTIONREGISTRATIONRECORD; typedef EXCEPTIONREGISTRATIONRECORD *PEXCEPTIONREGISTRATIONRECORD; ═══ EXCEPTIONREGISTRATIONRECORD Field - prev_structure ═══ prev_structure (STRUCT _EXCEPTIONREGISTRATIONRECORD *) Nested exception registration record structure. This field should be treated as a C-language volatile field. That is, even though this field may be changed in ways unknown to your program, the intent of the original expression will be maintained. ═══ EXCEPTIONREGISTRATIONRECORD Field - ExceptionHandler ═══ ExceptionHandler (_ERR *) Pointer to the ERR function. This field must be treated as a C-language volatile field. That is, even though this field may be changed in ways unknown to your program, the intent of the original expression will be maintained. The ERR function is defined below: typedef ULONG APIENTRY _ERR (PEXECPTIONREPORTRECORD, struct _EXCEPTIONREGISTRATIONRECORD *, PCONTEXTRECORD, PVOID); typedef _ERR *ERR; ═══ 14.17. EXCEPTIONREPORTRECORD ═══ This structure contains machine-independent information about an exception or unwind. No system exception will ever have more parameters than the value of EXCEPTION_MAXIMUM_PARAMETERS. User exceptions are not bound to this limit. typedef STRUCT _EXCEPTIONREPORTRECORD { ULONG ExceptionNum; /* Exception number. */ ULONG fHandlerFlags; /* Handler flags. */ STRUCT _EXCEPTIONREPORTRECORD *NestedExceptionReportRecord; /* Nested exception report record structure. */ PVOID ExceptionAddress; /* Address of the exception. */ ULONG cParameters; /* Size of exception specific information. */ ULONG ExceptionInfo[EXCEPTION_MAXIMUM_PARAMETERS]; /* Exception specific information. */ } EXCEPTIONREPORTRECORD; typedef EXCEPTIONREPORTRECORD *PEXCEPTIONREPORTRECORD; ═══ EXCEPTIONREPORTRECORD Field - ExceptionNum ═══ ExceptionNum (ULONG) Exception number. ═══ EXCEPTIONREPORTRECORD Field - fHandlerFlags ═══ fHandlerFlags (ULONG) Handler flags. ═══ EXCEPTIONREPORTRECORD Field - NestedExceptionReportRecord ═══ NestedExceptionReportRecord (STRUCT _EXCEPTIONREPORTRECORD *) Nested exception report record structure. ═══ EXCEPTIONREPORTRECORD Field - ExceptionAddress ═══ ExceptionAddress (PVOID) Address of the exception. ═══ EXCEPTIONREPORTRECORD Field - cParameters ═══ cParameters (ULONG) Size of exception specific information. ═══ EXCEPTIONREPORTRECORD Field - ExceptionInfo[EXCEPTION_MAXIMUM_PARAMETERS] ═══ ExceptionInfo[EXCEPTION_MAXIMUM_PARAMETERS] (ULONG) Exception specific information. ═══ 14.18. FATTRS ═══ Font-attributes structure. typedef struct _FATTRS { USHORT usRecordLength; /* Length of record. */ USHORT fsSelection; /* Selection indicators. */ LONG lMatch; /* Matched-font identity. */ CHAR szFacename[FACESIZE]; /* Typeface name. */ USHORT idRegistry; /* Registry identifier. */ USHORT usCodePage; /* Code page. */ LONG lMaxBaselineExt; /* Maximum baseline extension. */ LONG lAveCharWidth; /* Average character width. */ USHORT fsType; /* Type indicators. */ USHORT fsFontUse; /* Font-use indicators. */ } FATTRS; typedef FATTRS *PFATTRS; ═══ FATTRS Field - usRecordLength ═══ usRecordLength (USHORT) Length of record. ═══ FATTRS Field - fsSelection ═══ fsSelection (USHORT) Selection indicators. Flags causing the following features to be simulated by the system. Note: If an italic flag is applied to a font that is itself defined as italic, the font is slanted further by italic simulation. Underscore or strikeout lines are drawn using the appropriate attributes (for example, color) from the character bundle (see the CHARBUNDLE datatype), not the line bundle (see LINEBUNDLE). The width of the line, and the vertical position of the line in font space, are determined by the font. Horizontally, the line starts from a point in font space directly above or below the start point of each character, and extends to a point directly above or below the escapement point for that character. For this purpose, the start and escapement points are those applicable to left-to-right or right-to-left character directions (see GpiSetCharDirection in Graphics Programming Interface Programming Reference), even if the string is currently being drawn in a top-to-bottom or bottom-to-top direction. For left-to-right or right-to-left directions, any white space generated by the character extra and character break extra attributes (see GpiSetCharExtra and GpiSetCharBreakExtra in Graphics Programming Interface Programming Reference), as well as increments provided by the vector of increments on GpiCharStringPos and GpiCharStringPosAt, are also underlined/overstruck, so that in these cases the line is continuous for the string. FATTR_SEL_ITALIC Generate italic font. FATTR_SEL_UNDERSCORE Generate underscored font. FATTR_SEL_BOLD Generate bold font. (Note that the resulting characters are wider than those in the original font.) FATTR_SEL_STRIKEOUT Generate font with overstruck characters. FATTR_SEL_OUTLINE Use an outline font with hollow characters. If this flag is not set, outline font characters are filled. Setting this flag normally gives better performance, and for sufficiently small characters (depending on device resolution) there may be little visual difference. ═══ FATTRS Field - lMatch ═══ lMatch (LONG) Matched-font identity. ═══ FATTRS Field - szFacename[FACESIZE] ═══ szFacename[FACESIZE] (CHAR) Typeface name. The typeface name of the font, for example, Tms Rmn. ═══ FATTRS Field - idRegistry ═══ idRegistry (USHORT) Registry identifier. Font registry identifier (zero if unknown). ═══ FATTRS Field - usCodePage ═══ usCodePage (USHORT) Code page. If zero, the current Gpi code page (see GpiSetCp in Graphics Programming Interface Programming Reference) is used. A subsequent GpiSetCp function changes the code page used for this logical font. ═══ FATTRS Field - lMaxBaselineExt ═══ lMaxBaselineExt (LONG) Maximum baseline extension. For raster fonts, this should be the height of the required font, in world coordinates. For outline fonts, this should be zero. ═══ FATTRS Field - lAveCharWidth ═══ lAveCharWidth (LONG) Average character width. For raster fonts, this should be the width of the required font, in world coordinates. For outline fonts, this should be zero. ═══ FATTRS Field - fsType ═══ fsType (USHORT) Type indicators. FATTR_TYPE_KERNING Enable kerning (PostScript only). FATTR_TYPE_MBCS Font for mixed single- and double-byte code pages. FATTR_TYPE_DBCS Font for double-byte code pages. FATTR_TYPE_ANTIALIASED Antialiased font required. Only valid if supported by the device driver. ═══ FATTRS Field - fsFontUse ═══ fsFontUse (USHORT) Font-use indicators. These flags indicate how the font is to be used. They affect presentation speed and font quality. FATTR_FONTUSE_NOMIX Text is not mixed with graphics and can be written without regard to any interaction with graphics objects. FATTR_FONTUSE_OUTLINE Select an outline (vector) font. The font characters can be used as part of a path definition. If this flag is not set, an outline font might or might not be selected. If an outline font is selected, however, character widths are rounded to an integral number of pels. FATTR_FONTUSE_TRANSFORMABLE Characters can be transformed (for example, scaled, rotated, or sheared). ═══ 14.19. FDATE ═══ Date data structure for file-system functions. typedef struct _FDATE { USHORT day:5; /* Binary day for directory entry. */ USHORT month:4; /* Binary month for directory entry. */ USHORT year:7; /* The number of years since 1980 for this directory entry. */ } FDATE; typedef FDATE *PFDATE; ═══ FDATE Field - day:5 ═══ day:5 (USHORT) Binary day for directory entry. ═══ FDATE Field - month:4 ═══ month:4 (USHORT) Binary month for directory entry. ═══ FDATE Field - year:7 ═══ year:7 (USHORT) The number of years since 1980 for this directory entry. ═══ 14.20. FEA2 ═══ FEA2 defines the format for setting the full extended attributes in the file. typedef struct _FEA2 { ULONG oNextEntryOffset; /* Offset to next entry. */ BYTE fEA; /* Extended attributes flag. */ BYTE cbName; /* Length of szName, not including NULL. */ USHORT cbValue; /* Value length. */ CHAR szName[1]; /* Extended attribute name. */ } FEA2; typedef FEA2 *PFEA2; Extended attributes (EAs) are non-critical by default. A non-critical EA is one that is not necessary to the functionality of the application. If a non-critical EA is lost, the system continues to operate correctly. For example, losing the icons associated with data files does not generally cause any ill effect other than the inability to show the icon. A critical extended attribute is one which is necessary for the correct operation of the operating system or of a particular operation. EAs should be marked as critical if their loss would cause the system or program to perform incorrectly. For example, a mail program might store mail headers in EAs. The loss of the header from a message would normally render the mail program unable to further use that message. This would be unacceptable, so the mail program should mark this EA as critical. ═══ FEA2 Field - oNextEntryOffset ═══ oNextEntryOffset (ULONG) Offset to next entry. ═══ FEA2 Field - fEA ═══ fEA (BYTE) Extended attributes flag. FEA_NEEDEA Extended attributes are critical. If this flag is set, this file cannot be copied to a file system that does not support extended attributes. This flag should only be set if extended attributes are critical to the processing of this file. 0 Extended attributes are not critical. ═══ FEA2 Field - cbName ═══ cbName (BYTE) Length of szName, not including NULL. This value must be greater than 0. ═══ FEA2 Field - cbValue ═══ cbValue (USHORT) Value length. Sending an EA with cbValue set to 0 in the FEA2 data structure causes that attribute to be deleted, if possible. Receiving an EA with cbValue set to 0 in the FEA2 data structure indicates that the attribute is not present. ═══ FEA2 Field - szName[1] ═══ szName[1] (CHAR) Extended attribute name. ═══ 14.21. FEA2LIST ═══ FEA2 data structure. typedef struct _FEA2LIST { ULONG cbList; /* Total bytes of structure including full list. */ FEA2 list[1]; /* Variable-length FEA2 structures. */ } FEA2LIST; typedef FEA2LIST *PFEA2LIST; ═══ FEA2LIST Field - cbList ═══ cbList (ULONG) Total bytes of structure including full list. ═══ FEA2LIST Field - list[1] ═══ list[1] (FEA2) Variable-length FEA2 structures. ═══ 14.22. FHLOCK ═══ Unsigned integer in the range 0 through 4 294 967 295. typedef ULONG FHLOCK; ═══ 14.23. FILEFINDBUF ═══ Find file buffer data structure. typedef struct _FILEFINDBUF { FDATE fdateCreation; /* Date of file creation. */ FTIME ftimeCreation; /* Time of file creation. */ FDATE fdateLastAccess; /* Date of last access. */ FTIME ftimeLastAccess; /* Time of last access. */ FDATE fdateLastWrite; /* Date of last write. */ FTIME ftimeLastWrite; /* Time of last write. */ ULONG cbFile; /* Size of file. */ ULONG cbFileAlloc; /* Allocated size. */ USHORT attrFile; /* File attributes. */ UCHAR cchName; /* Length of file name. */ CHAR achName[CCHMAXPATHCOMP]; /* File name including null terminator. */ } FILEFINDBUF; typedef FILEFINDBUF *PFILEFINDBUF; ═══ FILEFINDBUF Field - fdateCreation ═══ fdateCreation (FDATE) Date of file creation. ═══ FILEFINDBUF Field - ftimeCreation ═══ ftimeCreation (FTIME) Time of file creation. ═══ FILEFINDBUF Field - fdateLastAccess ═══ fdateLastAccess (FDATE) Date of last access. ═══ FILEFINDBUF Field - ftimeLastAccess ═══ ftimeLastAccess (FTIME) Time of last access. ═══ FILEFINDBUF Field - fdateLastWrite ═══ fdateLastWrite (FDATE) Date of last write. ═══ FILEFINDBUF Field - ftimeLastWrite ═══ ftimeLastWrite (FTIME) Time of last write. ═══ FILEFINDBUF Field - cbFile ═══ cbFile (ULONG) Size of file. ═══ FILEFINDBUF Field - cbFileAlloc ═══ cbFileAlloc (ULONG) Allocated size. ═══ FILEFINDBUF Field - attrFile ═══ attrFile (USHORT) File attributes. ═══ FILEFINDBUF Field - cchName ═══ cchName (UCHAR) Length of file name. ═══ FILEFINDBUF Field - achName[CCHMAXPATHCOMP] ═══ achName[CCHMAXPATHCOMP] (CHAR) File name including null terminator. ═══ 14.24. FILEFINDBUF3 ═══ Level 1 (32-bit) information (used without EAs). typedef struct _FILEFINDBUF3 { ULONG oNextEntryOffset; /* Offset of next entry. */ FDATE fdateCreation; /* Date of file creation. */ FTIME ftimeCreation; /* Time of file creation. */ FDATE fdateLastAccess; /* Date of last access. */ FTIME ftimeLastAccess; /* Time of last access. */ FDATE fdateLastWrite; /* Date of last write. */ FTIME ftimeLastWrite; /* Time of last write. */ ULONG cbFile; /* Size of file. */ ULONG cbFileAlloc; /* Allocation size. */ ULONG attrFile; /* File attributes. */ UCHAR cchName; CHAR achName[CCHMAXPATHCOMP]; /* File name including null terminator. */ } FILEFINDBUF3; typedef FILEFINDBUF3 *PFILEFINDBUF3; ═══ FILEFINDBUF3 Field - oNextEntryOffset ═══ oNextEntryOffset (ULONG) Offset of next entry. ═══ FILEFINDBUF3 Field - fdateCreation ═══ fdateCreation (FDATE) Date of file creation. ═══ FILEFINDBUF3 Field - ftimeCreation ═══ ftimeCreation (FTIME) Time of file creation. ═══ FILEFINDBUF3 Field - fdateLastAccess ═══ fdateLastAccess (FDATE) Date of last access. ═══ FILEFINDBUF3 Field - ftimeLastAccess ═══ ftimeLastAccess (FTIME) Time of last access. ═══ FILEFINDBUF3 Field - fdateLastWrite ═══ fdateLastWrite (FDATE) Date of last write. ═══ FILEFINDBUF3 Field - ftimeLastWrite ═══ ftimeLastWrite (FTIME) Time of last write. ═══ FILEFINDBUF3 Field - cbFile ═══ cbFile (ULONG) Size of file. ═══ FILEFINDBUF3 Field - cbFileAlloc ═══ cbFileAlloc (ULONG) Allocation size. ═══ FILEFINDBUF3 Field - attrFile ═══ attrFile (ULONG) File attributes. ═══ FILEFINDBUF3 Field - cchName ═══ cchName (UCHAR) ═══ FILEFINDBUF3 Field - achName[CCHMAXPATHCOMP] ═══ achName[CCHMAXPATHCOMP] (CHAR) File name including null terminator. ═══ 14.25. FILEFINDBUF4 ═══ Level 2 (32-bit) information (used with EAs). typedef struct _FILEFINDBUF4 { ULONG oNextEntryOffset; /* Offset of next entry. */ FDATE fdateCreation; /* Date of file creation. */ FTIME ftimeCreation; /* Time of file creation. */ FDATE fdateLastAccess; /* Date of last access. */ FTIME ftimeLastAccess; /* Time of last access. */ FDATE fdateLastWrite; /* Date of last write. */ FTIME ftimeLastWrite; /* Time of last write. */ ULONG cbFile; /* Size of file. */ ULONG cbFileAlloc; /* Allocated size. */ ULONG attrFile; /* File attributes. */ ULONG cbList; /* Size of the file's extended attributes. */ UCHAR cchName; /* Length of file name. */ CHAR achName[CCHMAXPATHCOMP]; /* File name including null terminator. */ } FILEFINDBUF4; typedef FILEFINDBUF4 *PFILEFINDBUF4; ═══ FILEFINDBUF4 Field - oNextEntryOffset ═══ oNextEntryOffset (ULONG) Offset of next entry. ═══ FILEFINDBUF4 Field - fdateCreation ═══ fdateCreation (FDATE) Date of file creation. ═══ FILEFINDBUF4 Field - ftimeCreation ═══ ftimeCreation (FTIME) Time of file creation. ═══ FILEFINDBUF4 Field - fdateLastAccess ═══ fdateLastAccess (FDATE) Date of last access. ═══ FILEFINDBUF4 Field - ftimeLastAccess ═══ ftimeLastAccess (FTIME) Time of last access. ═══ FILEFINDBUF4 Field - fdateLastWrite ═══ fdateLastWrite (FDATE) Date of last write. ═══ FILEFINDBUF4 Field - ftimeLastWrite ═══ ftimeLastWrite (FTIME) Time of last write. ═══ FILEFINDBUF4 Field - cbFile ═══ cbFile (ULONG) Size of file. ═══ FILEFINDBUF4 Field - cbFileAlloc ═══ cbFileAlloc (ULONG) Allocated size. ═══ FILEFINDBUF4 Field - attrFile ═══ attrFile (ULONG) File attributes. ═══ FILEFINDBUF4 Field - cbList ═══ cbList (ULONG) Size of the file's extended attributes. The size is measured in bytes and is the size of the file's entire extended attribute set on the disk. ═══ FILEFINDBUF4 Field - cchName ═══ cchName (UCHAR) Length of file name. ═══ FILEFINDBUF4 Field - achName[CCHMAXPATHCOMP] ═══ achName[CCHMAXPATHCOMP] (CHAR) File name including null terminator. ═══ 14.26. FILELOCK ═══ FILELOCK data structure. typedef struct _FILELOCK { LONG lOffset; /* Offset to the beginning of the lock (or unlock) range. */ LONG lRange; /* Length, in bytes, of the lock (or unlock) range. */ } FILELOCK; typedef FILELOCK *PFILELOCK; ═══ FILELOCK Field - lOffset ═══ lOffset (LONG) Offset to the beginning of the lock (or unlock) range. ═══ FILELOCK Field - lRange ═══ lRange (LONG) Length, in bytes, of the lock (or unlock) range. A value of 0 indicates that locking (or unlocking) is not required. ═══ 14.27. FILESTATUS ═══ Use for Level 1 (FIL_STANDARD) file information for:  DosQueryFileInfo  DosQueryPathInfo  DosSetFileInfo  DosSetPathInfo typedef struct _FILESTATUS { FDATE fdateCreation; /* Date of file creation. */ FTIME ftimeCreation; /* Time of file creation. */ FDATE fdateLastAccess; /* Date of last access. */ FTIME ftimeLastAccess; /* Time of last access. */ FDATE fdateLastWrite; /* Date of last write. */ FTIME ftimeLastWrite; /* Time of last write. */ ULONG cbFile; /* File size (end of data). */ ULONG cbFileAlloc; /* File allocated size. */ USHORT attrFile; /* Attributes of the file. */ } FILESTATUS; typedef FILESTATUS *PFILESTATUS; ═══ FILESTATUS Field - fdateCreation ═══ fdateCreation (FDATE) Date of file creation. ═══ FILESTATUS Field - ftimeCreation ═══ ftimeCreation (FTIME) Time of file creation. ═══ FILESTATUS Field - fdateLastAccess ═══ fdateLastAccess (FDATE) Date of last access. ═══ FILESTATUS Field - ftimeLastAccess ═══ ftimeLastAccess (FTIME) Time of last access. ═══ FILESTATUS Field - fdateLastWrite ═══ fdateLastWrite (FDATE) Date of last write. ═══ FILESTATUS Field - ftimeLastWrite ═══ ftimeLastWrite (FTIME) Time of last write. ═══ FILESTATUS Field - cbFile ═══ cbFile (ULONG) File size (end of data). ═══ FILESTATUS Field - cbFileAlloc ═══ cbFileAlloc (ULONG) File allocated size. ═══ FILESTATUS Field - attrFile ═══ attrFile (USHORT) Attributes of the file. ═══ 14.28. FILESTATUS3 ═══ Level 1 (32-bit) (FIL_STANDARD) information. typedef struct _FILESTATUS3 { FDATE fdateCreation; /* Date of file creation. */ FTIME ftimeCreation; /* Time of file creation. */ FDATE fdateLastAccess; /* Date of last access. */ FTIME ftimeLastAccess; /* Time of last access. */ FDATE fdateLastWrite; /* Date of last write. */ FTIME ftimeLastWrite; /* Time of last write. */ ULONG cbFile; /* File size (end of data). */ ULONG cbFileAlloc; /* File allocated size. */ ULONG attrFile; /* Attributes of the file. */ } FILESTATUS3; typedef FILESTATUS3 *PFILESTATUS3; ═══ FILESTATUS3 Field - fdateCreation ═══ fdateCreation (FDATE) Date of file creation. ═══ FILESTATUS3 Field - ftimeCreation ═══ ftimeCreation (FTIME) Time of file creation. ═══ FILESTATUS3 Field - fdateLastAccess ═══ fdateLastAccess (FDATE) Date of last access. ═══ FILESTATUS3 Field - ftimeLastAccess ═══ ftimeLastAccess (FTIME) Time of last access. ═══ FILESTATUS3 Field - fdateLastWrite ═══ fdateLastWrite (FDATE) Date of last write. ═══ FILESTATUS3 Field - ftimeLastWrite ═══ ftimeLastWrite (FTIME) Time of last write. ═══ FILESTATUS3 Field - cbFile ═══ cbFile (ULONG) File size (end of data). ═══ FILESTATUS3 Field - cbFileAlloc ═══ cbFileAlloc (ULONG) File allocated size. ═══ FILESTATUS3 Field - attrFile ═══ attrFile (ULONG) Attributes of the file. ═══ 14.29. FILESTATUS4 ═══ Level 2 (32-bit) (FIL_QUERYEASIZE) information. typedef struct _FILESTATUS4 { FDATE fdateCreation; /* Date of file creation. */ FTIME ftimeCreation; /* Time of file creation. */ FDATE fdateLastAccess; /* Date of last access. */ FTIME ftimeLastAccess; /* Time of last access. */ FDATE fdateLastWrite; /* Date of last write. */ FTIME ftimeLastWrite; /* Time of last write. */ ULONG cbFile; /* File size (end of data). */ ULONG cbFileAlloc; /* File allocated size. */ ULONG attrFile; /* Attributes of the file. */ ULONG cbList; /* Length of entire EA set. */ } FILESTATUS4; typedef FILESTATUS4 *PFILESTATUS4; ═══ FILESTATUS4 Field - fdateCreation ═══ fdateCreation (FDATE) Date of file creation. ═══ FILESTATUS4 Field - ftimeCreation ═══ ftimeCreation (FTIME) Time of file creation. ═══ FILESTATUS4 Field - fdateLastAccess ═══ fdateLastAccess (FDATE) Date of last access. ═══ FILESTATUS4 Field - ftimeLastAccess ═══ ftimeLastAccess (FTIME) Time of last access. ═══ FILESTATUS4 Field - fdateLastWrite ═══ fdateLastWrite (FDATE) Date of last write. ═══ FILESTATUS4 Field - ftimeLastWrite ═══ ftimeLastWrite (FTIME) Time of last write. ═══ FILESTATUS4 Field - cbFile ═══ cbFile (ULONG) File size (end of data). ═══ FILESTATUS4 Field - cbFileAlloc ═══ cbFileAlloc (ULONG) File allocated size. ═══ FILESTATUS4 Field - attrFile ═══ attrFile (ULONG) Attributes of the file. ═══ FILESTATUS4 Field - cbList ═══ cbList (ULONG) Length of entire EA set. ═══ 14.30. FPREG ═══ Coprocessor stack register element. typedef struct _FPREG { ULONG losig; /* Low 32-bits of the significand. */ ULONG hisig; /* High 32-bits of the significand. */ USHORT signexp; /* Sign and exponent. */ } FPREG; typedef FPREG *PFPREG; A floating point register is 80 bits wide and consists of three fields. The following graphic shows the layout of the floating point register: 79 78 64 63 0 ┌───┬────────────┬───────────────────────────────────────┐ │ │ │ Significand │ └─┬─┴──────┬─────┴───────────────────────────────────────┘ │ │ │ Exponent Sign ═══ FPREG Field - losig ═══ losig (ULONG) Low 32-bits of the significand. The low 32-bits of the number's significant digits are held in the lower part of the significand field. ═══ FPREG Field - hisig ═══ hisig (ULONG) High 32-bits of the significand. The high 32-bits of the number's significant digits are held in the higher part of the significand field. ═══ FPREG Field - signexp ═══ signexp (USHORT) Sign and exponent. The exponent field (bits 64-78) locates the binary point within the significand field (bits 0-63). The 1-bit sign field (bit 79) indicates whether the number is positive or negative ═══ 14.31. FRAME ═══ Frame control data structure. typedef struct _FRAME { BYTE bCharsPerLine; /* Characters per line. */ BYTE bLinesPerInch; /* Lines per inch. */ } FRAME; typedef FRAME *PFRAME; ═══ FRAME Field - bCharsPerLine ═══ bCharsPerLine (BYTE) Characters per line. Valid values are 80 and 132. ═══ FRAME Field - bLinesPerInch ═══ bLinesPerInch (BYTE) Lines per inch. Valid values are 6 and 8. ═══ 14.32. FSALLOCATE ═══ File-system device allocation. typedef struct _FSALLOCATE { ULONG idFileSystem; /* File system identification. */ ULONG cSectorUnit; /* Number of sectors per allocation unit. */ ULONG cUnit; /* Number of allocation units. */ ULONG cUnitAvail; /* Number of allocation units available. */ USHORT cbSector; /* Number of bytes per sector. */ } FSALLOCATE; typedef FSALLOCATE *PFSALLOCATE; ═══ FSALLOCATE Field - idFileSystem ═══ idFileSystem (ULONG) File system identification. ═══ FSALLOCATE Field - cSectorUnit ═══ cSectorUnit (ULONG) Number of sectors per allocation unit. ═══ FSALLOCATE Field - cUnit ═══ cUnit (ULONG) Number of allocation units. ═══ FSALLOCATE Field - cUnitAvail ═══ cUnitAvail (ULONG) Number of allocation units available. ═══ FSALLOCATE Field - cbSector ═══ cbSector (USHORT) Number of bytes per sector. ═══ 14.33. FSINFO ═══ File-system information data structure. typedef struct _FSINFO { ULONG ulVSN; /* Volume Serial Number. */ VOLUMELABEL vol; /* Volume label. */ } FSINFO; typedef FSINFO *PFSINFO; ═══ FSINFO Field - ulVSN ═══ ulVSN (ULONG) Volume Serial Number. Volume Serial Number is a unique 32-bit number that the operating system uses to identify its disk or diskette volumes. The hard error prompts the user for an unmounted removable volume by displaying both the Volume Serial Number (an 8-digit hexadecimal number) and the Volume Label. ═══ FSINFO Field - vol ═══ vol (VOLUMELABEL) Volume label. Trailing blanks in the time the volume label are not considered part of the label, and are not returned as valid label data. The volume label is limited to a length of 11 bytes. ═══ 14.34. FSQBUFFER2 ═══ Data structure for information about an attached file system (local or remote), or about a character device or pseudocharacter device attached to the file system. typedef struct _FSQBUFFER2 { USHORT iType; /* Type of item. */ USHORT cbName; /* Length, in bytes, of the item name, not including null. */ USHORT cbFSDName; /* Length, in bytes, of the file-system driver name, not including null. */ USHORT cbFSAData; /* Length, in bytes, of the file-system driver Attach data returned by the file-system driver. */ UCHAR szName[1]; /* Item name. */ UCHAR szFSDName[1]; /* Name of the file-system driver that the item is attached to. */ UCHAR rgFSAData[1]; /* File-system driver Attach data returned by the file-system driver. */ } FSQBUFFER2; typedef FSQBUFFER2 *PFSQBUFFER2; ═══ FSQBUFFER2 Field - iType ═══ iType (USHORT) Type of item. Possible values are described in the following list: 1 FSAT_CHARDEV Resident character device 2 FSAT_PSEUDODEV Pseudocharacter device 3 FSAT_LOCALDRV Local drive 4 FSAT_REMOTEDRV Remote drive attached to the file-system driver. ═══ FSQBUFFER2 Field - cbName ═══ cbName (USHORT) Length, in bytes, of the item name, not including null. ═══ FSQBUFFER2 Field - cbFSDName ═══ cbFSDName (USHORT) Length, in bytes, of the file-system driver name, not including null. ═══ FSQBUFFER2 Field - cbFSAData ═══ cbFSAData (USHORT) Length, in bytes, of the file-system driver Attach data returned by the file-system driver. ═══ FSQBUFFER2 Field - szName[1] ═══ szName[1] (UCHAR) Item name. The name is an ASCIIZ string. ═══ FSQBUFFER2 Field - szFSDName[1] ═══ szFSDName[1] (UCHAR) Name of the file-system driver that the item is attached to. The name is an ASCIIZ string. ═══ FSQBUFFER2 Field - rgFSAData[1] ═══ rgFSAData[1] (UCHAR) File-system driver Attach data returned by the file-system driver. ═══ 14.35. FTIME ═══ Time data structure for file-system functions. typedef struct _FTIME { USHORT twosecs:5; /* Binary number of two-second increments. */ USHORT minutes:6; /* Binary number of minutes. */ USHORT hours:5; /* Binary number of hours. */ } FTIME; typedef FTIME *PFTIME; ═══ FTIME Field - twosecs:5 ═══ twosecs:5 (USHORT) Binary number of two-second increments. ═══ FTIME Field - minutes:6 ═══ minutes:6 (USHORT) Binary number of minutes. ═══ FTIME Field - hours:5 ═══ hours:5 (USHORT) Binary number of hours. ═══ 14.36. GEA2 ═══ Level 3 (32-bit) (FIL_QUERYEASFROMLIST) file information - get extended attributes. typedef struct _GEA2 { ULONG oNextEntryOffset; /* Offset to next entry. */ BYTE cbName; /* Name length not including NULL. */ CHAR szName[1]; /* Attribute name. */ } GEA2; typedef GEA2 *PGEA2; ═══ GEA2 Field - oNextEntryOffset ═══ oNextEntryOffset (ULONG) Offset to next entry. ═══ GEA2 Field - cbName ═══ cbName (BYTE) Name length not including NULL. ═══ GEA2 Field - szName[1] ═══ szName[1] (CHAR) Attribute name. ═══ 14.37. GEA2LIST ═══ Get extended attributes list. typedef struct _GEA2LIST { ULONG cbList; /* Total bytes of structure including full list. */ GEA2 list[1]; /* Variable-length GEA2 structures. */ } GEA2LIST; typedef GEA2LIST *PGEA2LIST; ═══ GEA2LIST Field - cbList ═══ cbList (ULONG) Total bytes of structure including full list. ═══ GEA2LIST Field - list[1] ═══ list[1] (GEA2) Variable-length GEA2 structures. ═══ 14.38. HDC ═══ Device-context handle. typedef LHANDLE HDC; ═══ 14.39. HDIR ═══ Value (32-bit) used as a directory handle. typedef LHANDLE HDIR; ═══ 14.40. HEV ═══ Value (32-bit) used as an event semaphore handle. typedef ULONG HEV; ═══ 14.41. HFILE ═══ File handle. typedef LHANDLE HFILE; ═══ 14.42. HKBD ═══ Keyboard handle. typedef unsigned short HKBD; ═══ 14.43. HMODULE ═══ Module handle. typedef LHANDLE HMODULE; ═══ 14.44. HMTX ═══ Value (32-bit) used as a mutex semaphore handle. typedef ULONG HMTX; ═══ 14.45. HMUX ═══ Value (32-bit) used as a muxwait semaphore handle. typedef ULONG HMUX; ═══ 14.46. HOOKDATA ═══ Data used by DosPerfSysCall for software tracing. typedef struct _HOOKDATA { ULONG ulLength; /* Length */ PBYTE pData; /* Data */ } HOOKDATA; typedef HOOKDATA *PHOOKDATA; ═══ HOOKDATA Field - ulLength ═══ ulLength (ULONG) Length ═══ HOOKDATA Field - pData ═══ pData (PBYTE) Data ═══ 14.47. HOTKEY ═══ Session Manager Hot Key data structure. typedef struct _HOTKEY { USHORT fsHotKey; /* State Key Flag. */ UCHAR uchScancodeMake; /* The Scan Code of the hot key, Make. */ UCHAR uchScancodeBreak; /* The Scan Code of the hot key, Break. */ USHORT idHotKey; /* Hot Key Id. */ } HOTKEY; typedef HOTKEY *PHOTKEY; ═══ HOTKEY Field - fsHotKey ═══ fsHotKey (USHORT) State Key Flag. Has the following settings: High Byte Bit settings are as follows: Bit 15 Reserved = 0 Bit 14 Reserved = 0 Bit 13 Reserved = 0 Bit 12 Reserved = 0 Bit 11 Right Alt key down Bit 10 Right Ctrl key down Bit 9 Left Alt key down Bit 8 Left Ctrl key down Low Byte Bit settings are as follows: Bit 7 Reserved = 0 Bit 6 Reserved = 0 Bit 5 Reserved = 0 Bit 4 Reserved = 0 Bit 3 Reserved = 0 Bit 2 Reserved = 0 Bit 1 Left Shift key down Bit 0 Right Shift key down ═══ HOTKEY Field - uchScancodeMake ═══ uchScancodeMake (UCHAR) The Scan Code of the hot key, Make. ═══ HOTKEY Field - uchScancodeBreak ═══ uchScancodeBreak (UCHAR) The Scan Code of the hot key, Break. ═══ HOTKEY Field - idHotKey ═══ idHotKey (USHORT) Hot Key Id. The Hot Key Id value is set by the caller. Notice that ID value FFFFh is reserved and must not be used as a Hot Key ID. See Remarks in KBD_SETSESMGRHOTKEY. A maximum of two of the above bit selections can be selected for a given hot key definition. If more than two bits are selected or if a reserved bit is selected, the result is an INVALID_PARAMETER error code returned to the caller. ═══ 14.48. HPIPE ═══ Value (32-bit) used as a pipe handle. typedef LHANDLE HPIPE; ═══ 14.49. HQUEUE ═══ Value (32-bit) used as a system queue handle. typedef LHANDLE HQUEUE; ═══ 14.50. HRGN ═══ Region handle. typedef LHANDLE HRGN; ═══ 14.51. HSEM ═══ Semaphore handle. typedef VOID *HSEM; ═══ 14.52. HSPINLOCK ═══ A value (32-bit) used as a handle to a spin lock. #define HSPINLOCK ULONG ═══ 14.53. HTIMER ═══ Value (32-bit) used as a timer handle. typedef LHANDLE HTIMER; ═══ 14.54. HVDD ═══ 32-bit value used as a virtual device driver handle. typedef LHANDLE HVDD; ═══ 14.55. LISTIO ═══ List of I/O requests for DosListIO. typedef struct _LISTIO { HFILE hFile; /* File handle. */ ULONG CmdFlag; /* Command flag. */ LONG Offset; /* Offset into file or disk. */ PVOID pBuffer; /* Pointer to read/write buffer. */ ULONG NumBytes; /* Number of bytes to read or write. */ ULONG Actual; /* Actual number of bytes read or written. */ ULONG RetCode; /* Return code from operation. */ ULONG Reserved; /* Reserved. */ ULONG Reserved2[3]; /* Reserved. */ ULONG Reserved3[2]; /* Reserved. */ } LISTIO; typedef LISTIO *PLISTIO; ═══ LISTIO Field - hFile ═══ hFile (HFILE) File handle. ═══ LISTIO Field - CmdFlag ═══ CmdFlag (ULONG) Command flag. Indicates the type of operation to perform. Valid values are: 0 FILE_BEGIN Seek from beginning of file. 1 FILE_CURRENT Seek from current file pointer, 2 FILE_END Seek from end of file. 2 FILE_SECTOR Indicates the value in Offset is in sectors rather than bytes. This permits access to disks up to 1 TB (terabyte) in size. This flag is only valid in the raw file system and must be ORed with either FILE_BEGIN, FILE_CURRENT, or FILE_END. 4 LISTIO_READ Read operation is requested. 8 LISTIO_WRITE Write operation is requested. Either LISTIO_READ or LISTIO_WRITE must be specified. ═══ LISTIO Field - Offset ═══ Offset (LONG) Offset into file or disk. ═══ LISTIO Field - pBuffer ═══ pBuffer (PVOID) Pointer to read/write buffer. ═══ LISTIO Field - NumBytes ═══ NumBytes (ULONG) Number of bytes to read or write. ═══ LISTIO Field - Actual ═══ Actual (ULONG) Actual number of bytes read or written. ═══ LISTIO Field - RetCode ═══ RetCode (ULONG) Return code from operation. Return code from the operation. (This might need to be cast to an APIRET.) ═══ LISTIO Field - Reserved ═══ Reserved (ULONG) Reserved. ═══ LISTIO Field - Reserved2[3] ═══ Reserved2[3] (ULONG) Reserved. ═══ LISTIO Field - Reserved3[2] ═══ Reserved3[2] (ULONG) Reserved. ═══ 14.56. LONG ═══ Signed integer in the range -2 147 483 648 through 2 147 483 647. #define LONG long Note: Where this data type represents a graphic coordinate in world or model space, its value is restricted to -134 217 728 through 134 217 727. A graphic coordinate in device or screen coordinates is restricted to -32 768 through 32 767. The value of a graphic coordinate may be further restricted by any transforms currently in force, including the positioning of the origin of the window on the screen. In particular, coordinates in world or model space must not generate coordinate values after transformation (that is, in device or screen space) outside the range -32 768 through 32 767. ═══ 14.57. PCH ═══ Pointer to a character string. typedef unsigned char *PCH; ═══ 14.58. PCSZ ═══ Pointer to a constant null-terminated string. typedef const char *PCSZ; ═══ 14.59. PFHLOCK ═══ Pointer to an unsigned integer in the range 0 through 4 294 967 295. typedef PULONG PFHLOCK; ═══ 14.60. PFN ═══ Pointer to a procedure. typedef _PFN *PFN; In the header file, this is a two-part definition as shown below: typedef int (APIENTRY _PFN) (); typedef _PFN *PFN; ═══ 14.61. PFNEXITLIST ═══ Address of a routine to be executed. typedef FNEXITLIST *PFNEXITLIST; In the header files, the FNEXITLIST structure is defined as shown below: typedef VOID APIENTRY FNEXITLIST (ULONG); ═══ 14.62. PFNSIGHANDLER ═══ Pointer (32-bit) to a function with pascal calling type. typedef CHAR *PFNSIGHANDLER; ═══ 14.63. PFNTHREAD ═══ Address of the code to be executed when the thread begins execution. typedef FNTHREAD *PFNTHREAD; In the header files, the FNTHREAD structure is defined as shown below: typedef VOID APIENTRY FNTHREAD (ULONG); ═══ 14.64. PIB ═══ Process Information Block structure. typedef struct _PIB { ULONG pib_ulpid; /* Process identifier. */ ULONG pib_ulppid; /* Parent process identifier. */ ULONG pib_hmte; /* Module handle of executable program. */ PCHAR pib_pchcmd; /* Command line pointer. */ PCHAR pib_pchenv; /* Environment pointer. */ ULONG pib_flstatus; /* Process' status bits. */ ULONG pib_ultype; /* Process' type code. */ } PIB; typedef PIB *PPIB; An OS/2 application that has been loaded into memory and prepared for execution is called a process. A process is the code, data, and other resources of an application, such as file handles, semaphores, pipes, queues, and so on. The OS/2 operating system considers every application it loads to be a process. Information about a process is kept in a read/write area of the process address space, called the Process Information Block (PIB). The operating system creates and maintains a PIB for every process in the system. An application can access the PIB of a specific process using DosGetThreadInfo. ═══ PIB Field - pib_ulpid ═══ pib_ulpid (ULONG) Process identifier. ═══ PIB Field - pib_ulppid ═══ pib_ulppid (ULONG) Parent process identifier. ═══ PIB Field - pib_hmte ═══ pib_hmte (ULONG) Module handle of executable program. ═══ PIB Field - pib_pchcmd ═══ pib_pchcmd (PCHAR) Command line pointer. This is the address of the ASCIIZ argument strings passed to the program. This string represents command parameters. The convention used by CMD.EXE is that the first of these strings is the program name (as entered from the command prompt or found in a batch file), and the second string consists of the parameters for the program. The second ASCIIZ string is followed by an additional byte of zeros. A value of zero for the address of pib_pchcmd means that no arguments are to be passed to the program. ═══ PIB Field - pib_pchenv ═══ pib_pchenv (PCHAR) Environment pointer. These strings represent environment variables and their current values. An environment string has the following form: variable=value The last ASCIIZ environment string must be followed by an additional byte of zeros. ═══ PIB Field - pib_flstatus ═══ pib_flstatus (ULONG) Process' status bits. A value of 1 in this bit flag indicates that the current process is in exit list processing. ═══ PIB Field - pib_ultype ═══ pib_ultype (ULONG) Process' type code. The following process' type codes are available: 0 Full screen protect-mode session 1 Requires real mode. Dos emulation. 2 VIO windowable protect-mode session 3 Presentation Manager protect-mode session 4 Detached protect-mode process. ═══ 14.65. PID ═══ Process identity. typedef LHANDLE PID; ═══ 14.66. PIPEINFO ═══ DosQueryNPipeInfo uses this data structure for level-1 information. typedef struct _PIPEINFO { USHORT cbOut; /* Actual size of the buffer for outbound data. */ USHORT cbIn; /* Actual size of the buffer for inbound data. */ BYTE cbMaxInst; /* Maximum number of pipe instances. */ BYTE cbCurInst; /* Current number of pipe instances. */ BYTE cbName; /* Length of szName. */ CHAR szName[1]; /* Name of the pipe. */ } PIPEINFO; typedef PIPEINFO *PIPEINFO; ═══ PIPEINFO Field - cbOut ═══ cbOut (USHORT) Actual size of the buffer for outbound data. ═══ PIPEINFO Field - cbIn ═══ cbIn (USHORT) Actual size of the buffer for inbound data. ═══ PIPEINFO Field - cbMaxInst ═══ cbMaxInst (BYTE) Maximum number of pipe instances. ═══ PIPEINFO Field - cbCurInst ═══ cbCurInst (BYTE) Current number of pipe instances. ═══ PIPEINFO Field - cbName ═══ cbName (BYTE) Length of szName. ═══ PIPEINFO Field - szName[1] ═══ szName[1] (CHAR) Name of the pipe. The name of the pipe (including \\ComputerName if the pipe is on a remote system). ═══ 14.67. PSZ ═══ Pointer to a null-terminated string. If you are using C++ **, you may need to use PCSZ. typedef unsigned char *PSZ; ═══ 14.68. PVOID ═══ Pointer to a data type of undefined format. typedef VOID *PVOID; ═══ 14.69. QWORD ═══ Quad word structure. typedef struct _QWORD { ULONG qw_ulLo; /* Low word. */ ULONG qw_ulHi; /* High word. */ } QWORD; typedef QWORD *PQWORD; ═══ QWORD Field - qw_ulLo ═══ qw_ulLo (ULONG) Low word. ═══ QWORD Field - qw_ulHi ═══ qw_ulHi (ULONG) High word. ═══ 14.70. RegSA_struc ═══ Register data associated with the kernel debugger communications protocol. typedef struct _RegSA_struc { DWORD EAXSav; /* EAX register */ DWORD EBXSav; /* EBX register */ DWORD ECXSav; /* ECX register */ DWORD EDXSav; /* EDX register */ DWORD ESPSav; /* ESP register */ DWORD EBPSav; /* EBP register */ DWORD ESISav; /* ESI register */ DWORD EDISav; /* EDI register */ WORD ESSav; /* ES register */ WORD SSSav; /* SS register */ WORD DSSav; /* DS register */ WORD FSSav; /* FS register */ WORD GSSav; /* GS register */ AddrS CSIPsav; /* Instruction address save area */ DWORD EFsav; /* EF save area */ DWORD CR0sav; /* CR0 save area */ DTR GDTsav; /* GDT save area */ WORD RS_Pad1; /* RS_Pad1 save area */ DTR IDTsav; /* IDT save area */ WORD RS_Pad2; /* RS_Pad2 save area */ WORD LDTsav; /* LDTsav area */ WORD TRsav; /* TRsav area */ DWORD CR2Sav; /* CR2 register */ DWORD CR3Sav; /* CR3 register */ DWORD CR4Sav; /* CR4 register */ DWORD DR0Sav; /* DR0 register */ DWORD DR1Sav; /* DR1 register */ DWORD DR2Sav; /* DR2 register */ DWORD DR3Sav; /* DR3 register */ DWORD DR6Sav; /* DR6 register */ DWORD DR7Sav; /* DR7 register */ DWORD DR7Sav2; /* DR7 register 2 */ DWORD TR6Sav; /* TR6 register */ DWORD TR7Sav; /* TR7 register */ } RegSA_struc; typedef RegSA_struc *RegSA_struc; ═══ RegSA_struc Field - EAXSav ═══ EAXSav (DWORD) EAX register ═══ RegSA_struc Field - EBXSav ═══ EBXSav (DWORD) EBX register ═══ RegSA_struc Field - ECXSav ═══ ECXSav (DWORD) ECX register ═══ RegSA_struc Field - EDXSav ═══ EDXSav (DWORD) EDX register ═══ RegSA_struc Field - ESPSav ═══ ESPSav (DWORD) ESP register ═══ RegSA_struc Field - EBPSav ═══ EBPSav (DWORD) EBP register ═══ RegSA_struc Field - ESISav ═══ ESISav (DWORD) ESI register ═══ RegSA_struc Field - EDISav ═══ EDISav (DWORD) EDI register ═══ RegSA_struc Field - ESSav ═══ ESSav (WORD) ES register ═══ RegSA_struc Field - SSSav ═══ SSSav (WORD) SS register ═══ RegSA_struc Field - DSSav ═══ DSSav (WORD) DS register ═══ RegSA_struc Field - FSSav ═══ FSSav (WORD) FS register ═══ RegSA_struc Field - GSSav ═══ GSSav (WORD) GS register ═══ RegSA_struc Field - CSIPsav ═══ CSIPsav (AddrS) Instruction address save area ═══ RegSA_struc Field - EFsav ═══ EFsav (DWORD) EF save area ═══ RegSA_struc Field - CR0sav ═══ CR0sav (DWORD) CR0 save area ═══ RegSA_struc Field - GDTsav ═══ GDTsav (DTR) GDT save area ═══ RegSA_struc Field - RS_Pad1 ═══ RS_Pad1 (WORD) RS_Pad1 save area ═══ RegSA_struc Field - IDTsav ═══ IDTsav (DTR) IDT save area ═══ RegSA_struc Field - RS_Pad2 ═══ RS_Pad2 (WORD) RS_Pad2 save area ═══ RegSA_struc Field - LDTsav ═══ LDTsav (WORD) LDTsav area ═══ RegSA_struc Field - TRsav ═══ TRsav (WORD) TRsav area ═══ RegSA_struc Field - CR2Sav ═══ CR2Sav (DWORD) CR2 register ═══ RegSA_struc Field - CR3Sav ═══ CR3Sav (DWORD) CR3 register ═══ RegSA_struc Field - CR4Sav ═══ CR4Sav (DWORD) CR4 register ═══ RegSA_struc Field - DR0Sav ═══ DR0Sav (DWORD) DR0 register ═══ RegSA_struc Field - DR1Sav ═══ DR1Sav (DWORD) DR1 register ═══ RegSA_struc Field - DR2Sav ═══ DR2Sav (DWORD) DR2 register ═══ RegSA_struc Field - DR3Sav ═══ DR3Sav (DWORD) DR3 register ═══ RegSA_struc Field - DR6Sav ═══ DR6Sav (DWORD) DR6 register ═══ RegSA_struc Field - DR7Sav ═══ DR7Sav (DWORD) DR7 register ═══ RegSA_struc Field - DR7Sav2 ═══ DR7Sav2 (DWORD) DR7 register 2 ═══ RegSA_struc Field - TR6Sav ═══ TR6Sav (DWORD) TR6 register ═══ RegSA_struc Field - TR7Sav ═══ TR7Sav (DWORD) TR7 register ═══ 14.71. REQUESTDATA ═══ REQUESTDATA data structure. typedef struct _REQUESTDATA { PID pid; /* Process identifier of the process that placed the element into the queue. */ ULONG ulData; /* An event code that is specified by the application. */ } REQUESTDATA; typedef REQUESTDATA *PREQUESTDATA; ═══ REQUESTDATA Field - pid ═══ pid (PID) Process identifier of the process that placed the element into the queue. ═══ REQUESTDATA Field - ulData ═══ ulData (ULONG) An event code that is specified by the application. This data is understood by both the thread that is adding the element to the queue (the client thread) and the thread that receives the queue element (server thread). It has no special meaning, and is not altered by the operating system. ═══ 14.72. RESULTCODES ═══ RESULTCODES data structure. typedef struct _RESULTCODES { ULONG codeTerminate; /* Termination code or process identifier. */ ULONG codeResult; /* Exit code. */ } RESULTCODES; typedef RESULTCODES *PRESULTCODES; ═══ RESULTCODES Field - codeTerminate ═══ codeTerminate (ULONG) Termination code or process identifier. For asynchronous requests, this field contains the process identifier of the child process. For synchronous requests, this field contains the termination code furnished by the system describing why the child process ended. The values of the termination code are shown in the following list: 0 TC_EXIT Normal exit. 1 TC_HARDERROR Hard-error halt 2 TC_TRAP Trap operation for a 16-bit child process 3 TC_KILLPROCESS Unintercepted DosKillProcess 4 TC_EXCEPTION Exception operation for a 32-bit child process ═══ RESULTCODES Field - codeResult ═══ codeResult (ULONG) Exit code. Result code specified by the terminating synchronous process on its last call to DosExit. ═══ 14.73. SEL ═══ Selector. typedef USHORT SEL; ═══ 14.74. SEMRECORD ═══ Muxwait semaphore data structure. typedef struct _SEMRECORD { HSEM hsemCur; /* Handle of the semaphore. */ ULONG ulUser; /* User-defined value. */ } SEMRECORD; typedef SEMRECORD *PSEMRECORD; ═══ SEMRECORD Field - hsemCur ═══ hsemCur (HSEM) Handle of the semaphore. ═══ SEMRECORD Field - ulUser ═══ ulUser (ULONG) User-defined value. ═══ 14.75. SFTSTARTUP ═══ Performance data. typedef struct _SFTSTARTUP { UCHAR VerMajor; /* Major version number */ UCHAR VerMinor; /* Minor version number */ UCHAR RevKettr; /* Revision letter */ UCHAR DayDate; /* Day of month (1 - 31) */ UCHAR MonDate; /* Month (1 - 12) */ UCHAR pad1[3]; /* Pad to 4 bytes */ USHORT YrsDate; /* Years since 1980 */ UCHAR HrsTime; /* Hours */ UCHAR MinTime; /* Minutes */ UCHAR SecTime; /* Seconds */ UCHAR HunTime; /* Hundredths of seconds */ UCHAR pad2[2]; /* Pad 2 */ UCHAR ulNumCPUs; /* Number of processors */ UCHAR ulCPURate[SFT_MAX_PROCESSORS]; /* Processor rate. One entry per processor. */ } SFTSTARTUP; typedef SFTSTARTUP *PSFTSTARTUP; ═══ SFTSTARTUP Field - VerMajor ═══ VerMajor (UCHAR) Major version number ═══ SFTSTARTUP Field - VerMinor ═══ VerMinor (UCHAR) Minor version number ═══ SFTSTARTUP Field - RevKettr ═══ RevKettr (UCHAR) Revision letter ═══ SFTSTARTUP Field - DayDate ═══ DayDate (UCHAR) Day of month (1 - 31) ═══ SFTSTARTUP Field - MonDate ═══ MonDate (UCHAR) Month (1 - 12) ═══ SFTSTARTUP Field - pad1[3] ═══ pad1[3] (UCHAR) Pad to 4 bytes ═══ SFTSTARTUP Field - YrsDate ═══ YrsDate (USHORT) Years since 1980 ═══ SFTSTARTUP Field - HrsTime ═══ HrsTime (UCHAR) Hours ═══ SFTSTARTUP Field - MinTime ═══ MinTime (UCHAR) Minutes ═══ SFTSTARTUP Field - SecTime ═══ SecTime (UCHAR) Seconds ═══ SFTSTARTUP Field - HunTime ═══ HunTime (UCHAR) Hundredths of seconds ═══ SFTSTARTUP Field - pad2[2] ═══ pad2[2] (UCHAR) Pad 2 ═══ SFTSTARTUP Field - ulNumCPUs ═══ ulNumCPUs (UCHAR) Number of processors ═══ SFTSTARTUP Field - ulCPURate[SFT_MAX_PROCESSORS] ═══ ulCPURate[SFT_MAX_PROCESSORS] (UCHAR) Processor rate. One entry per processor. ═══ 14.76. SHORT ═══ Signed integer in the range -32 768 through 32 767. #define SHORT short ═══ 14.77. STATUSDATA ═══ Status data structure. typedef struct _STATUSDATA { USHORT Length; /* The length of the data structure, in bytes, including Length itself. */ USHORT SelectInd; /* An indicator that specifies whether the target session should be flagged as selectable or non-selectable. */ USHORT BondInd; /* An indicator that specifies which session to bring to the foreground the next time the parent session is selected. */ } STATUSDATA; typedef STATUSDATA *PSTATUSDATA; ═══ STATUSDATA Field - Length ═══ Length (USHORT) The length of the data structure, in bytes, including Length itself. ═══ STATUSDATA Field - SelectInd ═══ SelectInd (USHORT) An indicator that specifies whether the target session should be flagged as selectable or non-selectable. Possible values are shown in the following list: 0 SET_SESSION_UNCHANGED Leaves the current setting unchanged. 1 SET_SESSION_SELECTABLE Makes the target session selectable. 2 SET_SESSION_NON_SELECTABLE Makes the target session non-selectable. A non-selectable session is not selectable from the Shell switch list, nor can the user jump to it via the system hot key. The operator may continue to select a non-selectable windowed session by pressing a mouse button within a visible part of the window. ═══ STATUSDATA Field - BondInd ═══ BondInd (USHORT) An indicator that specifies which session to bring to the foreground the next time the parent session is selected. Possible values are shown in the following list: 0 SET_SESSION_UNCHANGED Leaves the current setting unchanged. 1 SET_SESSION_BOND Establishes a bond between the parent session and the child session. The child session is brought to the foreground the next time the parent session is selected. If the child session is selected, the child session is brought to the foreground. 2 SET_SESSION_NO_BOND Specifies bringing the parent session to the foreground the next time the parent session is selected, and bringing the child session to the foreground if the child is selected. Any bond previously established with the child session specified is broken. ═══ 14.78. STRINGINBUF ═══ The buffer length data structure. typedef struct _STRINGINBUF { ULONG cb; /* Length, of the input buffer, in bytes. */ ULONG cchIn; /* Number of bytes returned. */ } STRINGINBUF; typedef STRINGINBUF *PSTRINGINBUF; ═══ STRINGINBUF Field - cb ═══ cb (ULONG) Length, of the input buffer, in bytes. ═══ STRINGINBUF Field - cchIn ═══ cchIn (ULONG) Number of bytes returned. ═══ 14.79. TIB ═══ Thread Information Block structure. typedef struct _TIB { PVOID tib_pexchain; /* Head of exception handler chain. */ PVOID tib_pstack; /* Pointer to the base of the stack. */ PVOID tib_pstacklimit; /* Pointer to the end of the stack. */ PTIB2 tib_ptib2; /* Pointer to a system-specific thread information block. */ ULONG tib_version; /* Version number for this Thread Information Block. */ ULONG tib_ordinal; /* Thread ordinal number. */ } TIB; typedef TIB *PTIB; A thread is a dispatchable unit of executable code that consists of set of instructions, related CPU register values, and a stack. Every process has at least one thread and can have many threads running at the same time. The application runs when the operating system gives control to a thread in a process. A thread is the basic unit of execution. Information about a thread is kept in a read/write area of the process address space, called the Thread Information Block (TIB). The operating system creates and maintains a TIB for every thread in the system. An application can access the TIB of a specific thread using DosGetThreadInfo. Note: The fields of this data structure should not be modified unless you are switching stacks, in which case only the tib_pstack and tib_pstacklimit should changed. ═══ TIB Field - tib_pexchain ═══ tib_pexchain (PVOID) Head of exception handler chain. ═══ TIB Field - tib_pstack ═══ tib_pstack (PVOID) Pointer to the base of the stack. ═══ TIB Field - tib_pstacklimit ═══ tib_pstacklimit (PVOID) Pointer to the end of the stack. ═══ TIB Field - tib_ptib2 ═══ tib_ptib2 (PTIB2) Pointer to a system-specific thread information block. ═══ TIB Field - tib_version ═══ tib_version (ULONG) Version number for this Thread Information Block. ═══ TIB Field - tib_ordinal ═══ tib_ordinal (ULONG) Thread ordinal number. ═══ 14.80. TIB2 ═══ System-specific Thread Information Block structure. typedef struct _TIB2 { ULONG tib2_ultid; /* Current thread identifier. */ ULONG tib2_ulpri; /* Current thread priority. */ ULONG tib2_version; /* Version number for this system-specific Thread Information Block. */ USHORT tib2_usMCCount; /* Must-complete count. */ USHORT tib2_fMCForceFlag; /* Must-complete force flag. */ } TIB2; typedef TIB2 *PTIB2; ═══ TIB2 Field - tib2_ultid ═══ tib2_ultid (ULONG) Current thread identifier. ═══ TIB2 Field - tib2_ulpri ═══ tib2_ulpri (ULONG) Current thread priority. The low byte of the low word is a hexadecimal value representing a rank (value 0 to 31) within a priority class. Class values, found in the high byte of the low word, are as follows: 0x01 Idle. 0x02 Regular. 0x03 Time critical. 0x04 Server. ═══ TIB2 Field - tib2_version ═══ tib2_version (ULONG) Version number for this system-specific Thread Information Block. ═══ TIB2 Field - tib2_usMCCount ═══ tib2_usMCCount (USHORT) Must-complete count. ═══ TIB2 Field - tib2_fMCForceFlag ═══ tib2_fMCForceFlag (USHORT) Must-complete force flag. ═══ 14.81. TID ═══ Thread identity. typedef LHANDLE TID; ═══ 14.82. TRACKLAYOUT ═══ Track layout. typedef struct _TRACKLAYOUT { BYTE bCommand; /* Command information. */ USHORT usHead; /* Physical head on the device that performs the operation. */ USHORT usCylinder; /* Cylinder to be written, read, or verified. */ USHORT usFirstSector; /* Logical sector number within the Track Layout Table that starts the I/O operation. */ USHORT cSectors; /* Number of sectors to read, write, or verify. */ struct { USHORT usSectorNumber; /* Sector number. */ USHORT usSectorSize; /* Sector size. */ } TrackTable[1]; } TRACKLAYOUT; typedef TRACKLAYOUT *PTRACKLAYOUT; ═══ TRACKLAYOUT Field - bCommand ═══ bCommand (BYTE) Command information. Bit 0 If clear (0), the track layout contains nonconsecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ TRACKLAYOUT Field - usHead ═══ usHead (USHORT) Physical head on the device that performs the operation. ═══ TRACKLAYOUT Field - usCylinder ═══ usCylinder (USHORT) Cylinder to be written, read, or verified. ═══ TRACKLAYOUT Field - usFirstSector ═══ usFirstSector (USHORT) Logical sector number within the Track Layout Table that starts the I/O operation. Note that all the sector numbers start with 0. For example the third sector is number 2. ═══ TRACKLAYOUT Field - cSectors ═══ cSectors (USHORT) Number of sectors to read, write, or verify. This value must be less than or equal to the maximum number number of sectors specified in the track table. The IOCtl subfunctions do not step heads or tracks. ═══ TRACKLAYOUT Field - usSectorNumber ═══ usSectorNumber (USHORT) Sector number. There must be one usSectorNumber and usSectorSize in the track layout table for every sector, up to cSectors sectors. ═══ TRACKLAYOUT Field - usSectorSize ═══ usSectorSize (USHORT) Sector size. There must be one usSectorNumber and usSectorSize in the track layout table for every sector, up to cSectors sectors. ═══ 14.83. UCHAR ═══ Single-byte unsigned character or unsigned integer in the range 0 through 255. typedef unsigned char UCHAR; ═══ 14.84. ULONG ═══ 32-bit unsigned integer in the range 0 through 4 294 967 295. typedef unsigned long ULONG; ═══ 14.85. USHORT ═══ Unsigned integer in the range 0 through 65 535. typedef unsigned short USHORT; ═══ 14.86. VOID ═══ A data area of undefined format. #define VOID void ═══ 14.87. VOLUMELABEL ═══ Volume label structure. typedef struct _VOLUMELABEL { BYTE cch; /* Length of the volume label, not including the null. */ CHAR szVolLabel[12]; /* Volume label. */ } VOLUMELABEL; typedef VOLUMELABEL *PVOLUMELABEL; ═══ VOLUMELABEL Field - cch ═══ cch (BYTE) Length of the volume label, not including the null. ═══ VOLUMELABEL Field - szVolLabel[12] ═══ szVolLabel[12] (CHAR) Volume label. This is an ASCIIZ string. ═══ 14.88. WORD ═══ Unsigned integer in the range 0 through 65 535. typedef unsigned short WORD; ═══ 15. Errors ═══ For errors 0 through 499, the following shows the numerical value of an error, its symbolic name, and a brief description of the error. For errors 500 and above, the following shows the numerical value of an error and its symbolic name. Select a range of Control Program error return codes: 0 to 99 100 to 199 200 to 299 300 to 399 400 to 499 500 to 599 600 to 1999 2000 to 59999 60000 to 65079 ═══ Errors 0 to 99 ═══ The following shows the numerical value of an error, its symbolic name, and a brief description of the error. 0 NO_ERROR No error occurred. 1 ERROR_INVALID_FUNCTION Function number is not valid. 2 ERROR_FILE_NOT_FOUND File not found. 3 ERROR_PATH_NOT_FOUND Path not found. 4 ERROR_TOO_MANY_OPEN_FILES Too many open files (no handles left). 5 ERROR_ACCESS_DENIED Access denied. 6 ERROR_INVALID_HANDLE Handle is not valid. 7 ERROR_ARENA_TRASHED Memory control blocks destroyed. 8 ERROR_NOT_ENOUGH_MEMORY Insufficient memory. 9 ERROR_INVALID_BLOCK Memory-block address is not valid. 10 ERROR_BAD_ENVIRONMENT Environment is not valid. 11 ERROR_BAD_FORMAT Format is not valid. 12 ERROR_INVALID_ACCESS Access code is not valid. 13 ERROR_INVALID_DATA Data is not valid. 14 Reserved. 15 ERROR_INVALID_DRIVE Drive is not valid. 16 ERROR_CURRENT_DIRECTORY Attempting to remove current directory. 17 ERROR_NOT_SAME_DEVICE Not same device. 18 ERROR_NO_MORE_FILES No more files. 19 ERROR_WRITE_PROTECT Attempt to write on write-protected diskette. 20 ERROR_BAD_UNIT Unknown unit. 21 ERROR_NOT_READY Drive not ready. 22 ERROR_BAD_COMMAND Unknown command. 23 ERROR_CRC Data error - cyclic redundancy check. 24 ERROR_BAD_LENGTH Request structure length is not valid. 25 ERROR_SEEK Seek error. 26 ERROR_NOT_DOS_DISK Unknown media type. 27 ERROR_SECTOR_NOT_FOUND Sector not found. 28 ERROR_OUT_OF_PAPER Printer is out of paper. 29 ERROR_WRITE FAULT Write fault. 30 ERROR_READ_FAULT Read fault. 31 ERROR_GEN_FAILURE General failure. For DosGetShrSeg and DosGetNamedSharedMem, indicates that a segment's maximum reference count of 65535 has been exceeded. 32 ERROR_SHARING_VIOLATION Sharing violation. 33 ERROR_LOCK_VIOLATION Lock violation. 34 ERROR_WRONG_DISK Disk change is not valid. 35 ERROR_FCB_UNAVAILABLE FCB unavailable. 36 ERROR_SHARING_BUFFER_EXCEEDED Sharing buffer overflow. 37 ERROR_CODE_PAGE_MISMATCHED Code page does not match. 38 ERROR_HANDLE_EOF End of file reached. 39 ERROR_HANDLE_DISK_FULL Disk is full. 40-49 Reserved. 50 ERROR_NOT_SUPPORTED Network request not supported. 51 ERROR_REM_NOT_LIST Remote network node is not online. 52 ERROR_DUP_NAME Duplicate file name in network. 53 ERROR_BAD_NETPATH Network path not found. 54 ERROR_NETWORK_BUSY Network is busy. 55 ERROR_DEV_NOT_EXIST Device is not installed in network. 56 ERROR_TOO_MANY_CMDS Network command limit reached. 57 ERROR_ADAP_HDW_ERR Network adapter hardware error. 58 ERROR_BAD_NET_RESP Incorrect response in network. 59 ERROR_UNEXP_NET_ERR Unexpected error in network. 60 ERROR_BAD_REM_ADAP Remote network adapter error. 61 ERROR_PRINTQ_FULL Network printer queue is full. 62 ERROR_NO_SPOOL_SPACE No space in print spool file. 63 ERROR_PRINT_CANCELLED Print spool file deleted. 64 ERROR_NETNAME_DELETED Network name deleted. 65 ERROR_NETWORK_ACCESS_DENIED Access to network denied. 66 ERROR_BAD_DEV_TYPE Device type for network is not valid. 67 ERROR_BAD_NET_NAME Network name not found. 68 ERROR_TOO_MANY_NAMES Network name limit exceeded. 69 ERROR_TOO_MANY_SESS Network session limit exceeded. 70 ERROR_SHARING_PAUSED Temporary pause in network. 71 ERROR_REQ_NOT_ACCEP Network request denied. 72 ERROR_REDIR_PAUSED Pause in network print disk redirection. 73 ERROR_SBCS_ATT_WRITE_PROT Attempted write on protected disk. 74 ERROR_SBCS_GENERAL_FAILURE General failure, single-byte character set. 75 ERROR_XGA_OUT_MEMORY XGA is out of memory. 76-79 Reserved. 80 ERROR_FILE_EXISTS File exists. 81 ERROR_DUP_FCB Reserved. 82 ERROR_CANNOT_MAKE Cannot make directory entry. 83 ERROR_FAIL_I24 Failure on INT 24. 84 ERROR_OUT_OF_STRUCTURES Too many redirections. 85 ERROR_ALREADY_ASSIGNED Duplicate redirection. 86 ERROR_INVALID_PASSWORD Password is not valid. 87 ERROR_INVALID_PARAMETER Parameter is not valid. 88 ERROR_NET_WRITE_FAULT Network device fault. 89 ERROR_NO_PROC_SLOTS No process slots available. 90 ERROR_NOT_FROZEN System error. 90 ERROR_SYS_COMP_NOT_LOADED System error. 91 ERR_TSTOVFL Timer service table overflow. 92 ERR_TSTDUP Timer service table duplicate. 93 ERROR_NO_ITEMS No items to work on. 95 ERROR_INTERRUPT Interrupted system call. 99 ERROR_DEVICE_IN_USE Device in use. ═══ Errors 100 to 199 ═══ The following shows the numerical value of an error, its symbolic name, and a brief description of the error. 100 ERROR_TOO_MANY_SEMAPHORES User/system open semaphore limit reached. 101 ERROR_EXCL_SEM_ALREADY_OWNED Exclusive semaphore already owned. 102 ERROR_SEM_IS_SET DosCloseSem found semaphore set. 103 ERROR_TOO_MANY_SEM_REQUESTS Too many exclusive semaphore requests. 104 ERROR_INVALID_AT_INTERRUPT_TIME Operation at interrupt time is not valid. 105 ERROR_SEM_OWNER_DIED Previous semaphore owner ended without freeing semaphore. 106 ERROR_SEM_USER_LIMIT Semaphore limit exceeded. 107 ERROR_DISK_CHANGE Insert drive B disk into drive A. 108 ERROR_DRIVE_LOCKED Drive locked by another process. 109 ERROR_BROKEN_PIPE Write on pipe with no reader. 110 ERROR_OPEN_FAILED Open/create failed due to explicit fail command. 111 ERROR_BUFFER_OVERFLOW Buffer passed to system call too small to hold return data. 112 ERROR_DISK_FULL Not enough space on the disk. 113 ERROR_NO_MORE_SEARCH_HANDLES Cannot allocate another search structure and handle. 114 ERROR_INVALID_TARGET_HANDLE Target handle in DosDupHandle is not valid. 115 ERROR_PROTECTION_VIOLATION User virtual address is not valid. 116 ERROR_VIOKBD_REQUEST Error on display write or keyboard read. 117 ERROR_INVALID_CATEGORY Category for DevIOCtl not defined. 118 ERROR_INVALID_VERIFY_SWITCH Value passed for verify flag is not valid. 119 ERROR_BAD_DRIVER_LEVEL Level four driver not found. 120 ERROR_CALL_NOT_IMPLEMENTED Function called is not valid. 121 ERROR_SEM_TIMEOUT Time-out occurred from semaphore API function. 122 ERROR_INSUFFICIENT_BUFFER Data buffer too small. 123 ERROR_INVALID_NAME Illegal character or file-system name is not valid. 124 ERROR_INVALID_LEVEL Level for information retrieval or setting is not valid. 125 ERROR_NO_VOLUME_LABEL No volume label found with DosQueryFSInfo function. 126 ERROR_MOD_NOT_FOUND Module handle not found with DosQueryProcAddr(), DosQueryModAddr(). 127 ERROR_PROC_NOT_FOUND Procedure address not found with DosQueryProcAddr(). 128 ERROR_WAIT_NO_CHILDREN DosWaitChild finds no children. 129 ERROR_CHILD_NOT_COMPLETE DosWaitChild children not ended. 130 ERROR_DIRECT_ACCESS_HANDLE Handle operation is not valid for direct disk-access handles. 131 ERROR_NEGATIVE_SEEK Attempting seek to negative offset. 132 ERROR_SEEK_ON_DEVICE Application trying to seek on device or pipe. 133 ERROR_IS_JOIN_TARGET Drive has previously joined drives. 134 ERROR_IS_JOINED Drive is already joined. 135 ERROR_IS_SUBSTED Drive is already substituted. 136 ERROR_NOT_JOINED Cannot delete drive that is not joined. 137 ERROR_NOT_SUBSTED Cannot delete drive that is not substituted. 138 ERROR_JOIN_TO_JOIN Cannot join to a joined drive. 139 ERROR_SUBST_TO_SUBST Cannot substitute to a substituted drive. 140 ERROR_JOIN_TO_SUBST Cannot join to a substituted drive. 141 ERROR_SUBST_TO_JOIN Cannot substitute to a joined drive. 142 ERROR_BUSY_DRIVE Specified drive is busy. 143 ERROR_SAME_DRIVE Cannot join or substitute a drive to a directory on the same drive. 144 ERROR_DIR_NOT_ROOT Directory must be a subdirectory of the root. 145 ERROR_DIR_NOT_EMPTY Directory must be empty to use join command. 146 ERROR_IS_SUBST_PATH Path specified is being used in a substitute. 147 ERROR_IS_JOIN_PATH Path specified is being used in a join. 148 ERROR_PATH_BUSY Path specified is being used by another process. 149 ERROR_IS_SUBST_TARGET Cannot join or substitute a drive that has a directory that is the target of a previous substitute. 150 ERROR_SYSTEM_TRACE System trace error. 151 ERROR_INVALID_EVENT_COUNT DosWaitMuxWaitSem errors. 152 ERROR_TOO_MANY_MUXWAITERS System limit of 100 entries reached. 153 ERROR_INVALID_LIST_FORMAT List format is not valid. 154 ERROR_LABEL_TOO_LONG Volume label too big. 155 ERROR_TOO_MANY_TCBS Cannot create another TCB. 156 ERROR_SIGNAL_REFUSED Signal refused. 157 ERROR_DISCARDED Segment is discarded. 158 ERROR_NOT_LOCKED Segment is not locked. 159 ERROR_BAD_THREADID_ADDR Thread-identity address is not valid. 160 ERROR_BAD_ARGUMENTS Environment pointer is not valid. 161 ERROR_BAD_PATHNAME Path name is not valid. 162 ERROR_SIGNAL_PENDING Signal already pending. 163 ERROR_UNCERTAIN_MEDIA Error with INT 24 mapping. 164 ERROR_MAX_THRDS_REACHED No more process slots. 165 ERROR_MONITORS_NOT_SUPPORTED Error with INT 24 mapping. 166 ERROR_UNC_DRIVER_NOT_INSTALLED Default redirection return code. 167 ERROR_LOCK_FAILED Locking failed. 168 ERROR_SWAPIO_FAILED Swap I/O failed. 169 ERROR_SWAPIN_FAILED Swap in failed. 170 ERROR_BUSY Segment is busy. 171-172 Reserved. 173 ERROR_CANCEL_VIOLATION A lock request is not outstanding for the specified file range, or the range length is zero. 174 ERROR_ATOMIC_LOCK_NOT_SUPPORTED The file-system driver (FSD) does not support atomic lock operations. Versions of OS/2 prior to version 2.00 do not support atomic lock operations. 175 ERROR_READ_LOCKS_NOT_SUPPORTED The file system driver (FSD) does not support shared read locks. 176-179 Reserved. 180 ERROR_INVALID_SEGMENT_NUMBER Segment number is not valid. 181 ERROR_INVALID_CALLGATE Call gate is not valid. 182 ERROR_INVALID_ORDINAL Ordinal is not valid. 183 ERROR_ALREADY_EXISTS Shared segment already exists. 184 ERROR_NO_CHILD_PROCESS No child process to wait for. 185 ERROR_CHILD_ALIVE_NOWAIT NoWait specified and child alive. 186 ERROR_INVALID_FLAG_NUMBER Flag number is not valid. 187 ERROR_SEM_NOT_FOUND Semaphore does not exist. 188 ERROR_INVALID_STARTING_CODESEG Starting code segment is not valid, incorrect END (label) directive. 189 ERROR_INVALID_STACKSEG Stack segment is not valid. 190 ERROR_INVALID_MODULETYPE Module type is not valid - dynamic-link library file cannot be used as an application. Application cannot be used as a dynamic-link library. 191 ERROR_INVALID_EXE_SIGNATURE EXE signature is not valid - file is a DOS mode program or an improper program. 192 ERROR_EXE_MARKED_INVALID EXE marked is not valid - link detected errors when the application was created. 193 ERROR_BAD_EXE_FORMAT EXE format not valid - file is a DOS mode program or an improper program. 194 ERROR_ITERATED_DATA_EXCEEDS_64k Iterated data exceeds 64KB - there is more than 64KB of data in one of the segments of the file. 195 ERROR_INVALID_MINALLOCSIZE Minimum allocation size is not valid - the size is specified to be less than the size of the segment data in the file. 196 ERROR_DYNLINK_FROM_INVALID_RING Dynamic link from privilege level is not valid - privilege level 2 routine cannot link to dynamic-link libraries. 197 ERROR_IOPL_NOT_ENABLED IOPL not enabled - IOPL set to NO in CONFIG.SYS. 198 ERROR_INVALID_SEGDPL Segment descriptor privilege level is not valid - can only have privilege levels of 2 and 3. 199 ERROR_AUTODATASEG_EXCEEDS_64k Automatic data segment exceeds 64KB. ═══ Errors 200 to 299 ═══ The following shows the numerical value of an error, its symbolic name, and a brief description of the error. 200 ERROR_RING2SEG_MUST_BE_MOVABLE Privilege level 2 segment must be movable. 201 ERROR_RELOC_CHAIN_XEEDS_SEGLIM Relocation chain exceeds segment limit. 202 ERROR_INFLOOP_IN_RELOC_CHAIN Infinite loop in relocation chain segment. 203 ERROR_ENVVAR_NOT_FOUND Environment variable not found. 204 ERROR_NOT_CURRENT_CTRY Not current country. 205 ERROR_NO_SIGNAL_SENT No signal sent - no process in the command subtree has a signal handler. 206 ERROR_FILENAME_EXCED_RANGE File name or extension is greater than 8.3 characters. 207 ERROR_RING2_STACK_IN_USE Privilege level 2 stack is in use. 208 ERROR_META_EXPANSION_TOO_LONG Meta (global) expansion is too long. 209 ERROR_INVALID_SIGNAL_NUMBER Signal number is not valid. 210 ERROR_THREAD_1_INACTIVE Inactive thread. 211 ERROR_INFO_NOT_AVAIL File system information is not available for this file. 212 ERROR_LOCKED Locked error. 213 ERROR_BAD_DYNALINK Attempted to execute a non-family API in DOS mode. 214 ERROR_TOO_MANY_MODULES Too many modules. 215 ERROR_NESTING_NOT_ALLOWED Nesting is not allowed. 216 ERROR_CANNOT_SHRINK System error. 217 ERROR_ZOMBIE_PROCESS Zombie process. 218 ERROR_STACK_IN_HIGH_MEMORY Stack is in high memory. 219 ERROR_INVALID_EXITROUTINE_RING Exit routine ring is not valid. 220 ERROR_GETBUF_FAILED Get buffer failed. 221 ERROR_FLUSHBUF_FAILED Flush buffer failed. 222 ERROR_TRANSFER_TOO_LONG Transfer is too long. 223 ERROR_FORCENOSWAP_FAILED System error. 224 ERROR_SMG_NO_TARGET_WINDOW The application window was created without the FCF_TASKLIST style, or the application window not yet been created or has already been destroyed. 228 ERROR_NO_CHILDREN No child process. 229 ERROR_INVALID_SCREEN_GROUP Session is not valid. 230 ERROR_BAD_PIPE The pipe is non-existent pipe or the operation is not valid. 231 ERROR_PIPE_BUSY Pipe is busy. 232 ERROR_NO_DATA No data available on non-blocking read. 233 ERROR_PIPE_NOT_CONNECTED Pipe was disconnected by server. 234 ERROR_MORE_DATA More data is available. 240 ERROR_VC_DISCONNECTED Session was dropped due to errors. 250 ERROR_CIRCULARITY_REQUESTED Renaming a directory that would cause a circularity problem. 251 ERROR_DIRECTORY_IN_CDS Renaming a directory that is in use. 252 ERROR_INVALID_FSD_NAME Trying to access an FSD that is not valid. 253 ERROR_INVALID_PATH Pseudo device is not valid. 254 ERROR_INVALID_EA_NAME Character in name or cbName is not valid. 255 ERROR_EA_LIST_INCONSISTENT List does not match its size, or there are EAs that are not valid in the list. 256 ERROR_EA_LIST_TOO_LONG FEAList is longer than 64K-1 bytes. 257 ERROR_NO_META_MATCH String does not match expression. 258 ERROR_FINDNOTIFY_TIMEOUT System error. 259 ERROR_NO_MORE_ITEMS DosQueryFSAttach ordinal query. 260 ERROR_SEARCH_STRUC_REUSED DOS mode findfirst/next search structure reused. 261 ERROR_CHAR_NOT_FOUND Character not found. 262 ERROR_TOO_MUCH_STACK Stack request exceeds system limit. 263 ERROR_INVALID_ATTR Attribute is not valid. 264 ERROR_INVALID_STARTING_RING Starting ring is not valid. 265 ERROR_INVALID_DLL_INIT_RING DLL INIT ring is not valid. 266 ERROR_CANNOT_COPY Cannot copy. 267 ERROR_DIRECTORY Used by DOSCOPY in doscall1. 268 ERROR_OPLOCKED_FILE Oplocked file. 269 ERROR_OPLOCK_THREAD_EXISTS Oplock thread exists. 270 ERROR_VOLUME_CHANGED Volume changed. 271 ERROR_FINDNOTIFY_HANDLE_IN_USE Handle in use. 272 ERROR_FINDNOTIFY_HANDLE_CLOSED Handle closed. 273 ERROR_NOTIFY_OBJECT_REMOVED Object removed. 274 ERROR_ALREADY_SHUTDOWN System is already shut down. 275 ERROR_EAS_DIDNT_FIT Buffer is not big enough to hold the EAs. 276 ERROR_EA_FILE_CORRUPT EA file has been damaged. 277 ERROR_EA_TABLE_FULL EA table is full. 278 ERROR_INVALID_EA_HANDLE EA handle is not valid. 279 ERROR_NO_CLUSTER No cluster. 280 ERROR_CREATE_EA_FILE Cannot create the EA file. 281 ERROR_CANNOT_OPEN_EA_FILE Cannot open the EA file. 282 ERROR_EAS_NOT_SUPPORTED Destination file system does not support EAs. 283 ERROR_NEED_EAS_FOUND Destination file system does not support EAs, and the source file's EAs contain a need EA. 284 ERROR_DUPLICATE_HANDLE The handle already exists. 285 ERROR_DUPLICATE_NAME The name already exists. 286 ERROR_EMPTY_MUXWAIT The list of semaphores in a muxwait semaphore is empty. 287 ERROR_MUTEX_OWNED The calling thread owns one or more of the mutex semaphores in the list. 288 ERROR_NOT_OWNER Caller does not own the semaphore. 289 ERROR_PARAM_TOO_SMALL Parameter is not large enough to contain all of the semaphore records in the muxwait semaphore. 290 ERROR_TOO_MANY_HANDLES Limit reached for number of handles. 291 ERROR_TOO_MANY_OPENS There are too many files or semaphores open. 292 ERROR_WRONG_TYPE Attempted to create wrong type of semaphore. 293 ERROR_UNUSED_CODE Code is not used. 294 ERROR_THREAD_NOT_TERMINATED Thread has not ended. 295 ERROR_INIT_ROUTINE_FAILED Initialization routine failed. 296 ERROR_MODULE_IN_USE Module is in use. 297 ERROR_NOT_ENOUGH_WATCHPOINTS There are not enough watchpoints. 298 ERROR_TOO_MANY_POSTS Post count limit was reached for an event semaphore. 299 ERROR_ALREADY_POSTED Event semaphore is already posted. ═══ Errors 300 to 399 ═══ The following shows the numerical value of an error, its symbolic name, and a brief description of the error. 300 ERROR_ALREADY_RESET Event semaphore is already reset. 301 ERROR_SEM_BUSY Semaphore is busy. 302 Reserved 303 ERROR_INVALID_PROCID Process identity is not valid. 304 ERROR_INVALID_PDELTA Priority delta is not valid. 305 ERROR_NOT_DESCENDANT Not descendant. 306 ERROR_NOT_SESSION_MANAGER Requestor not session manager. 307 ERROR_INVALID_PCLASS P class is not valid. 308 ERROR_INVALID_SCOPE Scope is not valid. 309 ERROR_INVALID_THREADID Thread identity is not valid. 310 ERROR_DOSSUB_SHRINK Cannot shrink segment - DosSubSetMem. 311 ERROR_DOSSUB_NOMEM No memory to satisfy request - DosSubAllocMem. 312 ERROR_DOSSUB_OVERLAP Overlap of the specified block with a block of allocated memory - DosSubFreeMem. 313 ERROR_DOSSUB_BADSIZE Size parameter is not valid - DosSubAllocMem or DosSubFreeMem. 314 ERROR_DOSSUB_BADFLAG Flag parameter is not valid - DosSubSetMem. 315 ERROR_DOSSUB_BADSELECTOR Segment selector is not valid. 316 ERROR_MR_MSG_TOO_LONG Message too long for buffer. 317 ERROR_MR_MID_NOT_FOUND Message identity number not found. 318 ERROR_MR_UN_ACC_MSGF Unable to access message file. 319 ERROR_MR_INV_MSGF_FORMAT Message file format is not valid. 320 ERROR_MR_INV_IVCOUNT Insertion variable count is not valid. 321 ERROR_MR_UN_PERFORM Unable to perform function. 322 ERROR_TS_WAKEUP Unable to wake up. 323 ERROR_TS_SEMHANDLE System semaphore is not valid. 324 ERROR_TS_NOTIMER No timers available. 326 ERROR_TS_HANDLE Timer handle is not valid. 327 ERROR_TS_DATETIME Date or time is not valid. 328 ERROR_SYS_INTERNAL Internal system error. 329 ERROR_QUE_CURRENT_NAME Current queue name does not exist. 330 ERROR_QUE_PROC_NOT_OWNED Current process does not own queue. 331 ERROR_QUE_PROC_OWNED Current process owns queue. 332 ERROR_QUE_DUPLICATE Duplicate queue name. 333 ERROR_QUE_ELEMENT_NOT_EXIST Queue element does not exist. 334 ERROR_QUE_NO_MEMORY Inadequate queue memory. For DosOpenQueue, DosCreateQueue, and DosWriteQueue, the following applies: These calls use a system-wide pool of memory. Every DosOpenQueue and DosCreateQueue uses up 34 bytes of memory, which is freed on close. Every DosWriteQueue uses 24 bytes of memory, which is freed on read. If too many elements are written to queues, further opens, creates, reads, or writes fail with this error code. 335 ERROR_QUE_INVALID_NAME Queue name is not valid. 336 ERROR_QUE_INVALID_PRIORITY Queue priority parameter is not valid. 337 ERROR_QUE_INVALID_HANDLE Queue handle is not valid. 338 ERROR_QUE_LINK_NOT_FOUND Queue link not found. 339 ERROR_QUE_MEMORY_ERROR Queue memory error. 340 ERROR_QUE_PREV_AT_END Previous queue element was at end of queue. 341 ERROR_QUE_PROC_NO_ACCESS Process does not have access to queues. 342 ERROR_QUE_EMPTY Queue is empty. 343 ERROR_QUE_NAME_NOT_EXIST Queue name does not exist. 344 ERROR_QUE_NOT_INITIALIZED Queues not initialized. 345 ERROR_QUE_UNABLE_TO_ACCESS Unable to access queues. 346 ERROR_QUE_UNABLE_TO_ADD Unable to add new queue. 347 ERROR_QUE_UNABLE_TO_INIT Unable to initialize queues. 349 ERROR_VIO_INVALID_MASK Function replaced is not valid. 350 ERROR_VIO_PTR Pointer to parameter is not valid. 351 ERROR_VIO_APTR Pointer to attribute is not valid. 352 ERROR_VIO_RPTR Pointer to row is not valid. 353 ERROR_VIO_CPTR Pointer to column is not valid. 354 ERROR_VIO_LPTR Pointer to length is not valid. 355 ERROR_VIO_MODE Unsupported screen mode. 356 ERROR_VIO_WIDTH Cursor width value is not valid. 357 ERROR_VIO_ATTR Cursor attribute value is not valid. 358 ERROR_VIO_ROW Row value is not valid. 359 ERROR_VIO_COL Column value is not valid. 360 ERROR_VIO_TOPROW TopRow value is not valid. 361 ERROR_VIO_BOTROW BotRow value is not valid. 362 ERROR_VIO_RIGHTCOL Right column value is not valid. 363 ERROR_VIO_LEFTCOL Left column value is not valid. 364 ERROR_SCS_CALL Call issued by other than session manager. 365 ERROR_SCS_VALUE Value is not for save or restore. 366 ERROR_VIO_WAIT_FLAG Wait flag setting is not valid. 367 ERROR_VIO_UNLOCK Screen not previously locked. 368 ERROR_SGS_NOT_SESSION_MGR Caller not session manager. 369 ERROR_SMG_INVALID_SGID Session identity is not valid. 369 ERROR_SMG_INVALID_SESSION_ID Session ID is not valid. 370 ERROR_SMG_NOSG No sessions available. 370 ERROR_SMG_NO_SESSIONS No sessions available. 371 ERROR_SMG_GRP_NOT_FOUND Session not found. 371 ERROR_SMG_SESSION_NOT_FOUND Session not found. 372 ERROR_SMG_SET_TITLE Title sent by shell or parent cannot be changed. 373 ERROR_KBD_PARAMETER Parameter to keyboard is not valid. 374 ERROR_KBD_NO_DEVICE No device. 375 ERROR_KBD_INVALID_IOWAIT I/O wait specified is not valid. 376 ERROR_KBD_INVALID_LENGTH Length for keyboard is not valid. 377 ERROR_KBD_INVALID_ECHO_MASK Echo mode mask is not valid. 378 ERROR_KBD_INVALID_INPUT_MASK Input mode mask is not valid. 379 ERROR_MON_INVALID_PARMS One or more parameters to DosMon is not valid. 380 ERROR_MON_INVALID_DEVNAME Device name string is not valid. 381 ERROR_MON_INVALID_HANDLE Device handle is not valid. 382 ERROR_MON_BUFFER_TOO_SMALL Buffer too small. 383 ERROR_MON_BUFFER_EMPTY Buffer is empty. 384 ERROR_MON_DATA_TOO_LARGE Data record is too large. 385 ERROR_MOUSE_NO_DEVICE Mouse device closed; the device handle is not valid. 386 ERROR_MOUSE_INV_HANDLE Mouse device closed; the device handle is not valid. 387 ERROR_MOUSE_INV_PARMS Parameters for display mode are not valid. 388 ERROR_MOUSE_CANT_RESET Function assigned and cannot be reset. 389 ERROR_MOUSE_DISPLAY_PARMS Parameters for display mode are not valid. 390 ERROR_MOUSE_INV_MODULE Module not valid. 391 ERROR_MOUSE_INV_ENTRY_PT Entry point not valid. 392 ERROR_MOUSE_INV_MASK Function mask is not valid. 393 NO_ERROR_MOUSE_NO_DATA No valid data. 394 NO_ERROR_MOUSE_PTR_DRAWN Pointer drawn. 395 ERROR_INVALID_FREQUENCY Frequency for beep is not valid. 396 ERROR_NLS_NO_COUNTRY_FILE Cannot find COUNTRY.SYS file. 397 ERROR_NLS_OPEN_FAILED Cannot open COUNTRY.SYS file. 398 ERROR_NLS_NO_CTRY_CODE Country code not found. 398 ERROR_NO_COUNTRY_OR_CODEPAGE Country code not found. 399 ERROR_NLS_TABLE_TRUNCATED Table returned information truncated, buffer is too small. ═══ Errors 400 to 499 ═══ The following shows the numerical value of an error, its symbolic name, and a brief description of the error. 400 ERROR_NLS_BAD_TYPE Selected type does not exist. 401 ERROR_NLS_TYPE_NOT_FOUND Selected type is not in file. 402 ERROR_VIO_SMG_ONLY Valid from session manager only. 403 ERROR_VIO_INVALID_ASCIIZ ASCIIZ length is not valid. 404 ERROR_VIO_DEREGISTER VioDeRegister not allowed. 405 ERROR_VIO_NO_POPUP Pop-up window not allocated. 406 ERROR_VIO_EXISTING_POPUP Pop-up window on screen (NoWait). 407 ERROR_KBD_SMG_ONLY Valid from session manager only. 408 ERROR_KBD_INVALID_ASCIIZ ASCIIZ length is not valid. 409 ERROR_KBD_INVALID_MASK Replacement mask is not valid. 410 ERROR_KBD_REGISTER KbdRegister not allowed. 411 ERROR_KBD_DEREGISTER KbdDeRegister not allowed. 412 ERROR_MOUSE_SMG_ONLY Valid from session manager only. 413 ERROR_MOUSE_INVALID_ASCIIZ ASCIIZ length is not valid. 414 ERROR_MOUSE_INVALID_MASK Replacement mask is not valid. 415 ERROR_MOUSE_REGISTER Mouse register not allowed. 416 ERROR_MOUSE_DEREGISTER Mouse deregister not allowed. 417 ERROR_SMG_BAD_ACTION Action specified is not valid. 418 ERROR_SMG_INVALID_CALL INIT called more than once, or the session identity is not valid. 419 ERROR_SCS_SG_NOTFOUND New session number. 420 ERROR_SCS_NOT_SHELL Caller is not shell. 421 ERROR_VIO_INVALID_PARMS Parameters passed are not valid. 422 ERROR_VIO_FUNCTION_OWNED Save/restore already owned. 423 ERROR_VIO_RETURN Non-destruct return (undo). 424 ERROR_SCS_INVALID_FUNCTION Caller function is not valid. 425 ERROR_SCS_NOT_SESSION_MGR Caller not session manager. 426 ERROR_VIO_REGISTER Vio register not allowed. 427 ERROR_VIO_NO_MODE_THREAD No mode restore thread in SG. 428 ERROR_VIO_NO_SAVE_RESTORE_THD No save/restore thread in SG. 429 ERROR_VIO_IN_BG Function in background is not valid. 430 ERROR_VIO_ILLEGAL_DURING_POPUP Function not allowed during pop-up window. 431 ERROR_SMG_NOT_BASESHELL Caller is not the base shell. 432 ERROR_SMG_BAD_STATUSREQ Status requested is not valid. 433 ERROR_QUE_INVALID_WAIT NoWait parameter out of bounds. 434 ERROR_VIO_LOCK Error returned from Scroll Lock. 435 ERROR_MOUSE_INVALID_IOWAIT Parameters for IOWait are not valid. 436 ERROR_VIO_INVALID_HANDLE VIO handle is not valid. 437 ERROR_VIO_ILLEGAL_DURING_LOCK Function not allowed during screen lock. 438 ERROR_VIO_INVALID_LENGTH VIO length is not valid. 439 ERROR_KBD_INVALID_HANDLE KBD handle is not valid. 440 ERROR_KBD_NO_MORE_HANDLE Ran out of handles. 441 ERROR_KBD_CANNOT_CREATE_KCB Unable to create kcb. 442 ERROR_KBD_CODEPAGE_LOAD_INCOMPL Unsuccessful code-page load. 443 ERROR_KBD_INVALID_CODEPAGE_ID Code page identity is not valid. 444 ERROR_KBD_NO_CODEPAGE_SUPPORT No code page support. 445 ERROR_KBD_FOCUS_REQUIRED Keyboard focus required. 446 ERROR_KBD_FOCUS_ALREADY_ACTIVE Calling thread has an outstanding focus. 447 ERROR_KBD_KEYBOARD_BUSY Keyboard is busy. 448 ERROR_KBD_INVALID_CODEPAGE Code page is not valid. 449 ERROR_KBD_UNABLE_TO_FOCUS Focus attempt failed. 450 ERROR_SMG_SESSION_NON_SELECT Session is not selectable. 451 ERROR_SMG_SESSION_NOT_FOREGRND Parent/child session is not foreground. 452 ERROR_SMG_SESSION_NOT_PARENT Not parent of requested child. 453 ERROR_SMG_INVALID_START_MODE Session start mode is not valid. 454 ERROR_SMG_INVALID_RELATED_OPT Session start related option is not valid. 455 ERROR_SMG_INVALID_BOND_OPTION Session bond option is not valid. 456 ERROR_SMG_INVALID_SELECT_OPT Session select option is not valid. 457 ERROR_SMG_START_IN_BACKGROUND Session started in background. 458 ERROR_SMG_INVALID_STOP_OPTION Session stop option is not valid. 459 ERROR_SMG_BAD_RESERVE Reserved parameters are not zero. 460 ERROR_SMG_PROCESS_NOT_PARENT Session parent process already exists. 461 ERROR_SMG_INVALID_DATA_LENGTH Data length is not valid. 462 ERROR_SMG_NOT_BOUND Parent is not bound. 463 ERROR_SMG_RETRY_SUB_ALLOC Retry request block allocation. 464 ERROR_KBD_DETACHED This call is not allowed for a detached PID. 465 ERROR_VIO_DETACHED This call is not allowed for a detached PID. 466 ERROR_MOU_DETACHED This call is not allowed for a detached PID. 467 ERROR_VIO_FONT No font is available to support the mode. 468 ERROR_VIO_USER_FONT User font is active. 469 ERROR_VIO_BAD_CP Code page specified is not valid. 470 ERROR_VIO_NO_CP System displays do not support code page. 471 ERROR_VIO_NA_CP Current display does not support code page. 472 ERROR_INVALID_CODE_PAGE Code page is not valid. 473 ERROR_CPLIST_TOO_SMALL Code page list is too small. 474 ERROR_CP_NOT_MOVED Code page was not moved. 475 ERROR_MODE_SWITCH_INIT Mode switch initialization error. 476 ERROR_CODE_PAGE_NOT_FOUND Code page was not found. 477 ERROR_UNEXPECTED_SLOT_RETURNED Internal error. 478 ERROR_SMG_INVALID_TRACE_OPTION Start session trace indicator is not valid. 479 ERROR_VIO_INTERNAL_RESOURCE VIO internal resource error. 480 ERROR_VIO_SHELL_INIT VIO shell initialization error. 481 ERROR_SMG_NO_HARD_ERRORS No session manager hard errors. 482 ERROR_CP_SWITCH_INCOMPLETE DosSetProcessCp is unable to set a KBD or VIO code page. 483 ERROR_VIO_TRANSPARENT_POPUP Error during VIO pop-up window. 484 ERROR_CRITSEC_OVERFLOW Critical section overflow. 485 ERROR_CRITSEC_UNDERFLOW Critical section underflow. 486 ERROR_VIO_BAD_RESERVE Reserved parameter is not zero. 487 ERROR_INVALID_ADDRESS Physical address is not valid. 488 ERROR_ZERO_SELECTORS_REQUESTED At least one selector must be requested. 489 ERROR_NOT_ENOUGH_SELECTORS_AVA Not enough GDT selectors to satisfy request. 490 ERROR_INVALID_SELECTOR GDT selector is not valid. 491 ERROR_SMG_INVALID_PROGRAM_TYPE Program type is not valid. 492 ERROR_SMG_INVALID_PGM_CONTROL Program control is not valid. 493 ERROR_SMG_INVALID_INHERIT_OPT Inherit option is not valid. 494 ERROR_VIO_EXTENDED_SG 495 ERROR_VIO_NOT_PRES_MGR_SG 496 ERROR_VIO_SHIELD_OWNED 497 ERROR_VIO_NO_MORE_HANDLES 498 ERROR_VIO_SEE_ERROR_LOG 499 ERROR_VIO_ASSOCIATED_DC ═══ Errors 500 to 599 ═══ The following shows the numerical value of an error, and its symbolic name. 500 ERROR_KBD_NO_CONSOLE 501 ERROR_MOUSE_NO_CONSOLE 502 ERROR_MOUSE_INVALID_HANDLE 503 ERROR_SMG_INVALID_DEBUG_PARMS 504 ERROR_KBD_EXTENDED_SG 505 ERROR_MOU_EXTENDED_SG 506 ERROR_SMG_INVALID_ICON_FILE 507 ERROR_TRC_PID_NON_EXISTENT 508 ERROR_TRC_COUNT_ACTIVE 509 ERROR_TRC_SUSPENDED_BY_COUNT 510 ERROR_TRC_COUNT_INACTIVE 511 ERROR_TRC_COUNT_REACHED 512 ERROR_NO_MC_TRACE 513 ERROR_MC_TRACE 514 ERROR_TRC_COUNT_ZERO 515 ERROR_SMG_TOO_MANY_DDS 516 ERROR_SMG_INVALID_NOTIFICATION 517 ERROR_LF_INVALID_FUNCTION 518 ERROR_LF_NOT_AVAIL 519 ERROR_LF_SUSPENDED 520 ERROR_LF_BUF_TOO_SMALL 521 ERROR_LF_BUFFER_CORRUPTED 521 ERROR_LF_BUFFER_FULL 522 ERROR_LF_INVALID_DAEMON 522 ERROR_LF_INVALID_RECORD 523 ERROR_LF_INVALID_TEMPL 523 ERROR_LF_INVALID_SERVICE 524 ERROR_LF_GENERAL_FAILURE 525 ERROR_LF_INVALID_ID 526 ERROR_LF_INVALID_HANDLE 527 ERROR_LF_NO_ID_AVAIL 528 ERROR_LF_TEMPLATE_AREA_FULL 529 ERROR_LF_ID_IN_USE 530 ERROR_MOU_NOT_INITIALIZED 531 ERROR_MOUINITREAL_DONE 532 ERROR_DOSSUB_CORRUPTED 533 ERROR_MOUSE_CALLER_NOT_SUBSYS 534 ERROR_ARITHMETIC_OVERFLOW 535 ERROR_TMR_NO_DEVICE 536 ERROR_TMR_INVALID_TIME 537 ERROR_PVW_INVALID_ENTITY 538 ERROR_PVW_INVALID_ENTITY_TYPE 539 ERROR_PVW_INVALID_SPEC 540 ERROR_PVW_INVALID_RANGE_TYPE 541 ERROR_PVW_INVALID_COUNTER_BLK 542 ERROR_PVW_INVALID_TEXT_BLK 543 ERROR_PRF_NOT_INITIALIZED 544 ERROR_PRF_ALREADY_INITIALIZED 545 ERROR_PRF_NOT_STARTED 546 ERROR_PRF_ALREADY_STARTED 547 ERROR_PRF_TIMER_OUT_OF_RANGE 548 ERROR_PRF_TIMER_RESET 549-599 Reserved. ═══ Errors 600 to 1999 ═══ The following shows the numerical value of an error, and its symbolic name. 600-638 Reserved. 639 ERROR_VDD_LOCK_USEAGE_DENIED 640 ERROR_TIMEOUT 641 ERROR_VDM_DOWN 642 ERROR_VDM_LIMIT 643 ERROR_VDD_NOT_FOUND 644 ERROR_INVALID_CALLER 645 ERROR_PID_MISMATCH 646 ERROR_INVALID_VDD_HANDLE 647 ERROR_VLPT_NO_SPOOLER 648 ERROR_VCOM_DEVICE_BUSY 649 ERROR_VLPT_DEVICE_BUSY 650 ERROR_NESTING_TOO_DEEP 651 ERROR_VDD_MISSING 691 ERROR_IMP_INVALID_PARM 692 ERROR_IMP_INVALID_LENGTH 693 MSG_HPFS_DISK_ERROR_WARN 730 ERROR_MON_BAD_BUFFER 731 ERROR_MODULE_CORRUPTED 732-1476 Reserved. 1477 ERROR_SM_OUTOF_SWAPFILE 1478-1999 Reserved. ═══ Errors 2000 to 59999 ═══ The following shows the numerical value of an error, and its symbolic name. 2000-2054 Reserved. 2055 ERROR_LF_TIMEOUT 2057 ERROR_LF_SUSPEND_SUCCESS 2058 ERROR_LF_RESUME_SUCCESS 2059 ERROR_LF_REDIRECT_SUCCESS 2060 ERROR_LF_REDIRECT_FAILURE 32768 ERROR_SWAPPER_NOT_ACTIVE 32769 ERROR_INVALID_SWAPID 32770 ERROR_IOERR_SWAP_FILE 32771 ERROR_SWAP_TABLE_FULL 32772 ERROR_SWAP_FILE_FULL 32773 ERROR_CANT_INIT_SWAPPER 32774 ERROR_SWAPPER_ALREADY_INIT 32775 ERROR_PMM_INSUFFICIENT_MEMORY 32776 ERROR_PMM_INVALID_FLAGS 32777 ERROR_PMM_INVALID_ADDRESS 32778 ERROR_PMM_LOCK_FAILED 32779 ERROR_PMM_UNLOCK_FAILED 32780 ERROR_PMM_MOVE_INCOMPLETE 32781 ERROR_UCOM_DRIVE_RENAMED 32782 ERROR_UCOM_FILENAME_TRUNCATED 32783 ERROR_UCOM_BUFFER_LENGTH 32784 ERROR_MON_CHAIN_HANDLE 32785 ERROR_MON_NOT_REGISTERED 32786 ERROR_SMG_ALREADY_TOP 32787 ERROR_PMM_ARENA_MODIFIED 32788 ERROR_SMG_PRINTER_OPEN 32789 ERROR_PMM_SET_FLAGS_FAILED 32790 ERROR_INVALID_DOS_DD 32791 ERROR_BLOCKED 32792 ERROR_NOBLOCK 32793 ERROR_INSTANCE_SHARED 32794 ERROR_NO_OBJECT 32795 ERROR_PARTIAL_ATTACH 32796 ERROR_INCACHE 32797 ERROR_SWAP_IO_PROBLEMS 32798 ERROR_CROSSES_OBJECT_BOUNDARY 32799 ERROR_LONGLOCK 32800 ERROR_SHORTLOCK 32801 ERROR_UVIRTLOCK 32802 ERROR_ALIASLOCK 32803 ERROR_ALIAS 32804 ERROR_NO_MORE_HANDLES 32805 ERROR_SCAN_TERMINATED 32806 ERROR_TERMINATOR_NOT_FOUND 32807 ERROR_NOT_DIRECT_CHILD 32808 ERROR_DELAY_FREE 32809 ERROR_GUARDPAGE 32900 ERROR_SWAPERROR 32901 ERROR_LDRERROR 32902 ERROR_NOMEMORY 32903 ERROR_NOACCESS 32904 ERROR_NO_DLL_TERM 32905-59999 Reserved. ═══ Errors 60000 to 65079 ═══ The following shows the numerical value of an error, and its symbolic name. 60000-65025 Reserved. 65026 ERROR_CPSIO_CODE_PAGE_INVALID 65027 ERROR_CPSIO_NO_SPOOLER 65028 ERROR_CPSIO_FONT_ID_INVALID 65029-65032 Reserved. 65033 ERROR_CPSIO_INTERNAL_ERROR 65034 ERROR_CPSIO_INVALID_PTR_NAME 65035-65036 Reserved. 65037 ERROR_CPSIO_NOT_ACTIVE 65038 Reserved. 65039 ERROR_CPSIO_PID_FULL 65040 ERROR_CPSIO_PID_NOT_FOUND 65041-65042 Reserved. 65043 ERROR_CPSIO_READ_CTL_SEQ 65044 Reserved. 65045 ERROR_CPSIO_READ_FNT_DEF 65046 Reserved. 65047 ERROR_CPSIO_WRITE_ERROR 65048 ERROR_CPSIO_WRITE_FULL_ERROR 65049 ERROR_CPSIO_WRITE_HANDLE_BAD 65050-65073 Reserved. 65074 ERROR_CPSIO_SWIT_LOAD 65075-65076 Reserved. 65077 ERROR_CPSIO_INV_COMMAND 65078 ERROR_CPSIO_NO_FONT_SWIT 65079 ERROR_ENTRY_IS_CALLGATE ═══ 16. Generic IOCtl Commands ═══ OS/2 device drivers are used to access the I/O hardware. The IOCtl functions provide a method for an application, or subsystem, to send device-specific control commands to a physical device driver. These IOCtls are subfunctions that are issued through the DosDevIOCtl API function request. The DosDevIOCtl function request can be used only by OS/2 applications; the INT 21h IOCtl request can be used only by DOS applications. The category and function fields are as follows. Each code is contained in a byte: Category Code 0xxx xxxx OS/2-defined 1xxx xxxx User-defined _xxx xxxx Code. Function Code 0xxx xxxx Return error, if unsupported 1xxx xxxx Ignore, if unsupported x0xx xxxx Intercepted by the OS/2 operating system x1xx xxxx Passed to driver xx0x xxxx Sends data and commands to device xx1x xxxx Queries data and information from device ___x xxxx Subfunction. Notice that the send/query data bit is intended only to standardize the function set; it plays no critical role. Some functions can contain both command and query elements. Such commands are defined as sends data. ═══ 16.1. Category 08h Logical Disk Control IOCtl Commands ═══ The following is a summary of Category 08h IOCtl Commands: ┌────────────────────┬────────────────────────────────────────┐ │Function │Description │ ├────────────────────┼────────────────────────────────────────┤ │ 00h │Lock Drive │ ├────────────────────┼────────────────────────────────────────┤ │ 01h │Unlock Drive │ ├────────────────────┼────────────────────────────────────────┤ │ 02h │Redetermine Media │ ├────────────────────┼────────────────────────────────────────┤ │ 03h │Set Logical Map │ ├────────────────────┼────────────────────────────────────────┤ │ 04h │Begin Format │ ├────────────────────┼────────────────────────────────────────┤ │ 20h │Block Removable │ ├────────────────────┼────────────────────────────────────────┤ │ 21h │Query Logical Map │ ├────────────────────┼────────────────────────────────────────┤ │ 22h │Reserved │ ├────────────────────┼────────────────────────────────────────┤ │ 40h │Removable Media Control │ ├────────────────────┼────────────────────────────────────────┤ │ 43h │Set Device Parameters │ ├────────────────────┼────────────────────────────────────────┤ │ 44h │Write Logical Track │ ├────────────────────┼────────────────────────────────────────┤ │ 45h │Format and Verify Track │ ├────────────────────┼────────────────────────────────────────┤ │ 5Dh │Diskette Control │ ├────────────────────┼────────────────────────────────────────┤ │ 5Eh │Reserved │ ├────────────────────┼────────────────────────────────────────┤ │ 5Fh │Reserved │ ├────────────────────┼────────────────────────────────────────┤ │ 60h │Query Media Sense │ ├────────────────────┼────────────────────────────────────────┤ │ 63h │Query Device Parameters │ ├────────────────────┼────────────────────────────────────────┤ │ 64h │Read Logical Track │ ├────────────────────┼────────────────────────────────────────┤ │ 65h │Verify Logical Track │ ├────────────────────┼────────────────────────────────────────┤ │ 66h │Status │ └────────────────────┴────────────────────────────────────────┘ ═══ 16.1.1. DSK_LOCKDRIVE (00h) - Lock Drive ═══ ═══ DSK_LOCKDRIVE (00h) - Description ═══ This function locks a drive and is used to exclude I/O by another process on the volume in the drive. The Lock Drive function succeeds only if there is one file handle open on the volume in the drive (that is, the file handle on which this function is issued). This is necessary because the desired result is to exclude all other I/O to this volume until "Function 01h - Unlock Drive" is issued. ═══ DSK_LOCKDRIVE (00h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_LOCKDRIVE (00h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_LOCKDRIVE (00h) - Data Packet Format ═══ ┌────────────────────────────────────────────────┐ │Field Length C Datatype │ ├────────────────────────────────────────────────┤ │Reserved. Set to 0. BYTE UCHAR │ └────────────────────────────────────────────────┘ ═══ DSK_LOCKDRIVE (00h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_LOCKDRIVE (00h) - Remarks ═══ This function should be called after obtaining a handle from DosOpen but before actually accessing the drive. Notice that it is necessary to call DSK_UNLOCKDRIVE before closing the drive. ═══ DSK_LOCKDRIVE (00h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_LOCKDRIVE (00h) Description: Lock Drive Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.2. DSK_UNLOCKDRIVE (01h) - Unlock Drive ═══ ═══ DSK_UNLOCKDRIVE (01h) - Description ═══ This function locks the drive. ═══ DSK_UNLOCKDRIVE (01h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_UNLOCKDRIVE (01h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_UNLOCKDRIVE (01h) - Data Packet Format ═══ ┌────────────────────────────────────────────────┐ │Field Length C Datatype │ ├────────────────────────────────────────────────┤ │Reserved. Set to 0. BYTE UCHAR │ └────────────────────────────────────────────────┘ ═══ DSK_UNLOCKDRIVE (01h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_UNLOCKDRIVE (01h) - Remarks ═══ This function releases a lock on a volume in a drive, thereby allowing I/O from other processes to that volume again. The locked volume represented by the file handle on which this function is issued, must be in the drive. Notice that this function must be called after accessing a drive that was locked with DSK_LOCKDRIVE before closing the drive with DosClose. ═══ DSK_UNLOCKDRIVE (01h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_UNLOCKDRIVE (01h) Description: Unlock Drive Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.3. DSK_REDETERMINEMEDIA (02h) - Redetermine Media ═══ ═══ DSK_REDETERMINEMEDIA (02h) - Description ═══ This function redetermines media (ends format). ═══ DSK_REDETERMINEMEDIA (02h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_REDETERMINEMEDIA (02h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_REDETERMINEMEDIA (02h) - Data Packet Format ═══ ┌────────────────────────────────────────────────┐ │Field Length C Datatype │ ├────────────────────────────────────────────────┤ │Reserved. Set to 0. BYTE UCHAR │ └────────────────────────────────────────────────┘ ═══ DSK_REDETERMINEMEDIA (02h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_REDETERMINEMEDIA (02h) - Remarks ═══ This function rebuilds the device parameters (including the Volume Parameter Block (VPB) used by the operating system to identify the volume), simulates a close on the current device handle, and forces a mount on the volume. Function 02h dismounts the volume from the current file system drive (FSD), attaches the new FSD, and reattaches the current handle to the volume's new FSD. It is typically called after a new boot sector has been written to a volume (after a format has been done). The caller must have the disk or diskette locked when calling this function; otherwise, the function fails with the error ERROR_LOCK_VIOLATION. The caller can have only one file open to refer to the disk or diskette. If other processes have the volume open or the calling process has opened the volume multiple times, the call fails and ERROR_DRIVE_BUSY is returned. ═══ DSK_REDETERMINEMEDIA (02h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_REDETERMINEMEDIA (02h) Description: Redetermine Media Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.4. DSK_SETLOGICALMAP (03h) - Set Logical Map ═══ ═══ DSK_SETLOGICALMAP (03h) - Description ═══ This function sets the next logical drive letter than is used to reference the drive. ═══ DSK_SETLOGICALMAP (03h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_SETLOGICALMAP (03h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_SETLOGICALMAP (03h) - Logical Drive Number ═══ Logical Drive Number On entry, a logical drive number (1=A, 2=B, and so forth) is specified. On return, this byte specifies the logical drive currently mapped to the drive that the specified file handle is opened on. A zero is returned if there is only one logical drive mapped onto this physical drive. ═══ DSK_SETLOGICALMAP (03h) - Data Packet Format ═══ ┌────────────────────────────────────────────────┐ │Field Length C Datatype │ ├────────────────────────────────────────────────┤ │Logical Drive Number BYTE UCHAR │ └────────────────────────────────────────────────┘ ═══ DSK_SETLOGICALMAP (03h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_SETLOGICALMAP (03h) - Remarks ═══ When copying diskettes on a drive whose physical drive number has more than one logical drive letter assigned to it, the operating system issues diskette swap prompts to tell the user which logical drive letter is currently referencing the physical drive number. Function 03h is typically used to avoid this prompt by setting a drive number (corresponding to the drive letter) that is referenced in the next I/O request. The last logical drive letter assigned to the physical drive is determined by calling DSK_GETLOGICALMAP. ═══ DSK_SETLOGICALMAP (03h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_SETLOGICALMAP (03h) Description: Set Logical Map Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.5. DSK_BEGINFORMAT (04h) - Begin Format ═══ ═══ DSK_BEGINFORMAT (04h) - Description ═══ This function begins the format. ═══ DSK_BEGINFORMAT (04h) - FSD Name ═══ FSD Name The file system driver name (that is, the name the FSD exports). A zero length string is used to indicate the FAT file system. ═══ DSK_BEGINFORMAT (04h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────┤ │FSD Name ASCIIZ string PSZ │ └───────────────────────────────────────────┘ ═══ DSK_BEGINFORMAT (04h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_BEGINFORMAT (04h) - Data Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_BEGINFORMAT (04h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_BEGINFORMAT (04h) - Remarks ═══ This function attaches (mounts) a specified File System Driver (FSD) to a logical disk volume. Function 04h is typically used to force mount the FSD that is formatting a volume. It is called before starting a format operation on a volume. This function also unmounts a current FSD (if any), and forces a mount to the specified FSD. A flag is set in the OS/2 kernel to indicate that a Begin Format (unmount/mount) was done. DSK_REDETERMINEMEDIA clears this flag. Therefore, Function 02h must be performed before the disk is closed with DosClosed. The volume is then ready for normal I/O service from the newly mounted FSD. ═══ DSK_BEGINFORMAT (04h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_BEGINFORMAT (04h) Description: Begin Format Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.6. DSK_BLOCKREMOVABLE (20h) - Block Removable ═══ ═══ DSK_BLOCKREMOVABLE (20h) - Description ═══ This function is used to determine if the media is removable or fixed. ═══ DSK_BLOCKREMOVABLE (20h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_BLOCKREMOVABLE (20h) - Drive Unit ═══ Drive Unit This field is used only when this IOCtl is issued without using a previously allocated file handle. A file handle of -1 must be used. Note that that media in the drive is not required. Drive Unit values are 0 = A, 1 = B, 2 = C, and so forth. ═══ DSK_BLOCKREMOVABLE (20h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ ├───────────────────────────────────────────────┤ │Drive Unit BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_BLOCKREMOVABLE (20h) - Data ═══ Data On return, the data byte is set accordingly: 0 Removable media 1 Nonremovable media ═══ DSK_BLOCKREMOVABLE (20h) - Data Packet Format ═══ ┌─────────────────────────────────┐ │Field Length C Datatype │ ├─────────────────────────────────┤ │Data BYTE UCHAR │ └─────────────────────────────────┘ ═══ DSK_BLOCKREMOVABLE (20h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_BLOCKREMOVABLE (20h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_BLOCKREMOVABLE (20h) Description: Block Removable Select an item: Description Parameter Packet Format Data Packet Format Returns ═══ 16.1.7. DSK_GETLOGICALMAP (21h) - Query Logical Map ═══ ═══ DSK_GETLOGICALMAP (21h) - Description ═══ This function returns the logical drive letter that was last used to reference (open) the drive. ═══ DSK_GETLOGICALMAP (21h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_GETLOGICALMAP (21h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_GETLOGICALMAP (21h) - Logical Drive Number ═══ Logical Drive Number On entry, a logical drive number (1=A, 2=B, and so forth) is specified. On return, if the device has more than one logical drive letter assigned to it, a drive number corresponding to the last drive letter that was used to reference the device is returned. For example, if the entry drive number was 1 (where 1=A) and the returned drive number was 2 (where 2=B), this drive was last referenced as the B: drive. If only one drive letter (logical drive) is assigned to the device, a zero is returned. Note: This function works as long as the file handle is valid. The file handle can be set to anything other than zero. ═══ DSK_GETLOGICALMAP (21h) - Data Packet Format ═══ ┌────────────────────────────────────────────────┐ │Field Length C Datatype │ ├────────────────────────────────────────────────┤ │Logical Drive Number BYTE UCHAR │ └────────────────────────────────────────────────┘ ═══ DSK_GETLOGICALMAP (21h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_GETLOGICALMAP (21h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_GETLOGICALMAP (21h) Description: Query Logical Map Select an item: Description Parameter Packet Format Data Packet Format Returns ═══ 16.1.8. DSK_UNLOCKEJECTMEDIA (40h) - Removable Media Control ═══ ═══ DSK_UNLOCKEJECTMEDIA (40h) - Description ═══ This function physically locks/unlocks the media in the drive. It also ejects the media for drives that support these functions. ═══ DSK_UNLOCKEJECTMEDIA (40h) - Length Command Information ═══ Length Command Information Bits 0-1 Description 00 Unlock. 01 Lock - drive can be locked with or without media in it. If the drive is locked without media in it, the media will be ejected when it is inserted until an UnlockIOCtl is issued. 10 Eject Media - media will be ejected if the drive is not locked. 11 Loads Media. ═══ DSK_UNLOCKEJECTMEDIA (40h) - Drive Unit ═══ Drive Unit This field is used only when the IOCtl is issued without using a previously allocated file handle. A file handle of -1 must be used. Notice that media in the drive is not required. Drive Unit values are 0=A, 1=B, 2=C, and so forth. ═══ DSK_UNLOCKEJECTMEDIA (40h) - Parameter Packet Format ═══ ┌──────────────────────────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────────────────────────┤ │Length Command Information BYTE UCHAR │ ├──────────────────────────────────────────────────────┤ │Drive Unit BYTE UCHAR │ └──────────────────────────────────────────────────────┘ ═══ DSK_UNLOCKEJECTMEDIA (40h) - Data Packet Format ═══ None. ═══ DSK_UNLOCKEJECTMEDIA (40h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_UNLOCKEJECTMEDIA (40h) - Remarks ═══ Not all floppy drives support these functions. ═══ DSK_UNLOCKEJECTMEDIA (40h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_UNLOCKEJECTMEDIA (40h) Description: Removable Media Control Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.9. DSK_SETDEVICEPARAMS (43h) - Set Device Parameters ═══ ═══ DSK_SETDEVICEPARAMS (43h) - Description ═══ This function sets the parameters for a specified device. ═══ DSK_SETDEVICEPARAMS (43h) - Command Information ═══ Command Information The two low bits of the command byte are used to indicate one of three possible actions: Bits Description 00 Revert to building the BIOS Parameter Block (BPB) off the medium for all subsequent Build BPB functions. This is used after a format operation to reset the device parameters to their original state. 01 Change the default BPB for the physical device. This changes the physical parameters for the drive as opposed to parameters for the media in the drive. 10 Change the BPB for the medium to the specified BPB, and return the new BPB for the medium for all subsequent Build BPB calls. This is used to prepare the device for a format media operation according to the device parameters specified. All other bits are reserved, and must be set to 0. ═══ DSK_SETDEVICEPARAMS (43h) - Drive Unit ═══ Drive Unit The field is used only when this IOCtl is issued without using a previously allocated file handle and when Command Information is set to 01. A file handle of -1 must be used. Note that media in the drive is not required. Drive Unit values are 0=A, 1=B, 2=C, and so forth. ═══ DSK_SETDEVICEPARAMS (43h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ ├───────────────────────────────────────────────┤ │Drive Unit BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_SETDEVICEPARAMS (43h) - Extended BPB for Devices ═══ Extended BPB for Devices The term Extended BPB refers to the BIOS Parameter Block. It is a table that describes the structure of the media and the physical layout of the drive (heads, tracks, sectors). The Extended BPB has the following format: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Bytes per Sector │WORD │ ├─────────────────────────┼───────┤ │Sectors per Cluster │BYTE │ ├─────────────────────────┼───────┤ │Reserved Sectors │WORD │ ├─────────────────────────┼───────┤ │Number of FATs │BYTE │ ├─────────────────────────┼───────┤ │Root Directory Entries │WORD │ ├─────────────────────────┼───────┤ │Total Sectors │WORD │ ├─────────────────────────┼───────┤ │Media Descriptor │BYTE │ ├─────────────────────────┼───────┤ │Sectors per FAT │WORD │ ├─────────────────────────┼───────┤ │Sectors per Track │WORD │ ├─────────────────────────┼───────┤ │Number of Heads │WORD │ ├─────────────────────────┼───────┤ │Hidden Sectors │DWORD │ ├─────────────────────────┼───────┤ │Large Total Sectors │DWORD │ ├─────────────────────────┼───────┤ │Reserved │6 BYTES│ └─────────────────────────┴───────┘ ═══ DSK_SETDEVICEPARAMS (43h) - Number of Cylinders ═══ Number of Cylinders Indicates the number of cylinders defined for the physical device. ═══ DSK_SETDEVICEPARAMS (43h) - Device Type ═══ Device Type Describes the physical layout of the device specified, and has one of the following values: 0 48 TPI low-density diskette drive 1 96 TPI high-density diskette drive 2 Small (3.5-inch) 720KB drive 3 8-inch single-density diskette drive 4 8-inch double-density diskette drive 5 Fixed disk 6 Tape drive 7 Other (includes 1.44MB 3.5-inch diskette drive) 8 R/W optical disk 9 3.5-inch 4.0MB diskette drive (2.88MB formatted) ═══ DSK_SETDEVICEPARAMS (43h) - Device Attributes ═══ Device Attributes A bit field that returns flag information about the specified drive: Bit 0 Removable Media flag. This bit is set to 1 if the media cannot be removed. It is set to 0 if the media is removable. Bit 1 Changeline flag. This bit is set to 1 if the device support determines that the media was removed since the last I/O operation. To query whether the media has changed, call the device driver Strategy Command "1h - MEDIA CHECK". (See "Physical Device Driver Strategy Commands" in the Physical Device Driver Reference for more information.) If this bit is set to 0, then the physical device driver can return the value 0, Unsure if media has changed, from the Media Check function. ═══ DSK_SETDEVICEPARAMS (43h) - Data Packet Format ═══ ┌──────────────────────────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────────────────────────┤ │Extended BPB for Devices 31 BYTES BYTE[31] │ ├──────────────────────────────────────────────────────┤ │Number of Cylinders WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Device Type BYTE BYTE │ ├──────────────────────────────────────────────────────┤ │Device Attributes WORD USHORT │ └──────────────────────────────────────────────────────┘ Related C Data Structure The BIOSPARAMETERBLOCK data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ DSK_SETDEVICEPARAMS (43h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_SETDEVICEPARAMS (43h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_SETDEVICEPARAMS (43h) Description: Set Device Parameters Select an item: Description Parameter Packet Format Data Packet Format Returns ═══ 16.1.10. DSK_WRITETRACK (44h) - Write Logical Track ═══ ═══ DSK_WRITETRACK (44h) - Description ═══ This function writes a logical track. ═══ DSK_WRITETRACK (44h) - Command Information ═══ Command Information A byte with bit 0 defined as follows: Bit 0 If clear (0), the track layout contains non-consecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ DSK_WRITETRACK (44h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ DSK_WRITETRACK (44h) - Cylinder ═══ Cylinder The cylinder for the write. ═══ DSK_WRITETRACK (44h) - First Sector ═══ First Sector The logical sector number within the Track Layout Table that starts the I/O operation. Note that the sector numbers start with 0. For example, the third sector is number 2. ═══ DSK_WRITETRACK (44h) - Number of Sectors ═══ Number of Sectors The number of sectors to write (up to the maximum specified in the track table; the IOCtl subfunctions do not step heads/tracks). ═══ DSK_WRITETRACK (44h) - Track Layout Table ═══ Track Layout Table Has the following: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │1 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 1 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │2 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 2 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │3 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 3 │WORD │ │ . │ . │ │ . │ . │ │ . │ . │ ├─────────────────────────┼───────┤ │Sector number for Sector │WORD │ │n │ │ ├─────────────────────────┼───────┤ │Sector size for Sector n │WORD │ └─────────────────────────┴───────┘ The sector table that is specified provides information that is used during the WRITE track operation. ═══ DSK_WRITETRACK (44h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │First Sector WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Track Layout Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ DSK_WRITETRACK (44h) - Data Packet Format ═══ The Data Packet is a buffer. It contains the data to be written. ┌──────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────┤ │Buffer BYTES UCHAR[] │ └──────────────────────────────────┘ ═══ DSK_WRITETRACK (44h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_WRITETRACK (44h) - Remarks ═══ This function is used to perform a write of sectors on the media and to perform the operations on the device that is specified in this request. The track table passed in on the call is used to determine the sector number, which is passed to the disk controller for the operation. In cases where the sectors are oddly numbered or are non-consecutive, this request breaks into n single sector operations and writes one sector at a time. This DosDevIOCtls is typically used when performing I/O outside of the normal file system data area on the media. ═══ DSK_WRITETRACK (44h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_WRITETRACK (44h) Description: Write Logical Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.11. DSK_FORMATVERIFY (45h) - Format and Verify Track ═══ ═══ DSK_FORMATVERIFY (45h) - Description ═══ This function formats and verifies a track. ═══ DSK_FORMATVERIFY (45h) - Command Information ═══ Command Information A byte with bit 0 defined as follows: Bit 0 If clear (0), the track layout contains nonconsecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. Bit 1 Indicates that this is a multi-track request. For multi-track requests, the track table should contain a single entry. All other bits are reserved and must be set to 0. ═══ DSK_FORMATVERIFY (45h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ DSK_FORMATVERIFY (45h) - Cylinder ═══ Cylinder The cylinder for the operation. Upon return from a multitrack format request, if a defective spot is encountered on the media, the returned head and cylinder contain the defective area. ═══ DSK_FORMATVERIFY (45h) - Number of Tracks ═══ Number of Tracks The number of tracks to format/verify on a multitrack request. This is set to zero for single track requests. On return from a multitrack request, Number of Tracks is set to one of the following values: Value Description 8000H Multitrack successful 4000H Multitrack not supported 2000H Multitrack failed on FORMAT operation 1000H Multitrack failed on VERIFY operation ═══ DSK_FORMATVERIFY (45h) - Number of Sectors ═══ Number of Sectors The number of sectors on the track being formatted. On return from a multitrack request, if a defective spot is found on the media before the multitrack format operation can complete, this field indicates the number of tracks remaining (to be formatted) on this multitrack format request. ═══ DSK_FORMATVERIFY (45h) - Format Track Table ═══ Format Track Table Contains four-byte tuples. Each tuple is in the form (c, h, r, n) where c=cylinder number, h=head number, r=Sector ID, and n=save bytes per sector: n Bytes/Sector 0 128 1 256 2 512 3 1024 There is a 4-tuple for each sector in the track to be formatted. Both the head and cylinder numbers must be consistent within the tuple and the corresponding Parameter Packet field. ═══ DSK_FORMATVERIFY (45h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Tracks WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Format Track Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ DSK_FORMATVERIFY (45h) - Starting Sector ═══ Starting Sector On input, this is the starting sector on a multitrack request. This is set to zero for a single track request. On return from a multitrack format request, if a defective spot is found on the media, Starting Sector is the first logical sector number within the head and cylinder of the defective area. ═══ DSK_FORMATVERIFY (45h) - Data Packet Format ═══ ┌───────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────┤ │Starting Sector BYTE BYTE │ └───────────────────────────────────────────┘ ═══ DSK_FORMATVERIFY (45h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_FORMATVERIFY (45h) - Remarks ═══ The following describes a format track table for a track layout starting with sector 1 and containing only consecutive sectors (command information Bit 0 set to 1). This table also describes only a single track request (number of tracks set to 0) for a track with 12 sectors (number of sectors) formatted to 512 bytes-per-sector. ┌───────────────┬───────────────┬───────────────┬───────────────┐ │C │H │S │N │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │1 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │2 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │3 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │4 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │5 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │6 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │7 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │8 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │9 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │10 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │11 │2 │ ├───────────────┼───────────────┼───────────────┼───────────────┤ │10 │0 │12 │2 │ └───────────────┴───────────────┴───────────────┴───────────────┘ This routine formats and verifies the track specified according to the information passed in the Format Track Table. The track is passed to the controller, which performs the formatting. Note that some controllers do not support formatting tracks with varying sector sizes; therefore, applications must ensure that the sector sizes specified in the Track Layout Table are all the same. ┌───────────────┬───────────────┬───────────────┬───────────────┐ │0 │0 │1 │2 │ └───────────────┴───────────────┴───────────────┴───────────────┘ ═══ DSK_FORMATVERIFY (45h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_FORMATVERIFY (45h) Description: Format and Verify Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.12. DSK_DISKETTECONTROL (5Dh) - Diskette Control ═══ ═══ DSK_DISKETTECONTROL (5Dh) - Description ═══ This function allows cooperative sharing of the diskette controller hardware by a separate device driver. ═══ DSK_DISKETTECONTROL (5Dh) - Command Information ═══ Command Information Indicates whether the application is requesting or returning exclusive ownership of the diskette controller, or querying the diskette device driver. Bits 0-1 Description 00 Resume - This IOCtl resumes processing of diskette requests by the diskette driver. 01 Suspend - When this IOCtl returns without error, the diskette driver will have relinquished control of the diskette hardware, including the IRQ level. Further requests to the diskette device from the operating system will be queued. 10 Query - This IOCtl indicates whether the diskette driver is idle (no pending requests in the device driver queue). A return code of 0 (NO_ERROR) indicates the device driver is idle. ═══ DSK_DISKETTECONTROL (5Dh) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_DISKETTECONTROL (5Dh) - Reserved ═══ Reserved Reserved. Set to 0. ═══ DSK_DISKETTECONTROL (5Dh) - Data Packet Format ═══ ┌────────────────────────────────────┐ │Field Length C Datatype │ ├────────────────────────────────────┤ │Reserved BYTE UCHAR │ └────────────────────────────────────┘ ═══ DSK_DISKETTECONTROL (5Dh) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_DISKETTECONTROL (5Dh) - Remarks ═══ If pending requests are detected, then the handling is up to the tape application. It is recommended that the tape application do an orderly clean-up of its activities and then issue a RESUME IOCTL to allow diskette requests to proceed and subsequently issue another SUSPEND IOCTL to reclaim the diskette hardware. ═══ DSK_DISKETTECONTROL (5Dh) - ═══ Category: IOCTL_DISK (08h) Function: DSK_DISKETTECONTROL (5Dh) Description: Diskette Control Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.13. DSK_QUERYMEDIASENSE (60h) - Query Media Sense ═══ ═══ DSK_QUERYMEDIASENSE (60h) - Description ═══ This function returns the media sense information. ═══ DSK_QUERYMEDIASENSE (60h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_QUERYMEDIASENSE (60h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_QUERYMEDIASENSE (60h) - Media Sense Information ═══ Media Sense Information On return, this field can be interpreted as follows: 0 Unable to determine media type 1 720KB diskette is present in 3.5-inch drive 2 1.44MB diskette is present in 3.5-inch drive 3 2.88MB diskette is present in 3.5-inch drive ═══ DSK_QUERYMEDIASENSE (60h) - Data Packet Format ═══ ┌───────────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────────┤ │Media Sense Information BYTE UCHAR │ └───────────────────────────────────────────────────┘ ═══ DSK_QUERYMEDIASENSE (60h) - Returns ═══ The error return codes for this function are as follows: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 22 ERROR_BAD_COMMAND 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_QUERYMEDIASENSE (60h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_QUERYMEDIASENSE (60h) Description: Query Media Sense Select an item: Description Parameter Packet Format Data Packet Format Returns ═══ 16.1.14. DSK_GETDEVICEPARAMS (63h) - Query Device Parameters ═══ ═══ DSK_GETDEVICEPARAMS (63h) - Description ═══ Returns the device parameters. ═══ DSK_GETDEVICEPARAMS (63h) - Command Information ═══ Command Information A byte with bit 0 defined as follows: 0 Return the recommended BPB for the drive, which is the BPB for the physical device, unless it is a formatted fixed media. Then, it is the BPB that was on the media when the system was booted. 1 Return the BPB for the media currently in the drive. This always reads the BPB off the current media in the drive. An error is returned if the media is unformatted. All other bits are reserved, and must be set to 0. ═══ DSK_GETDEVICEPARAMS (63h) - Drive Unit ═══ Drive Unit Used only when this IOCtl is issued without using a previously allocated file handle and when Command Information is set to 0. A file handle of -1 must be used. Notice that media in the drive is not required. Drive Unit values are 0=A, 1=B, 2=C, and so forth. ═══ DSK_GETDEVICEPARAMS (63h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ ├───────────────────────────────────────────────┤ │Drive Unit BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ DSK_GETDEVICEPARAMS (63h) - Extended BPB for Device ═══ Extended BPB for Device The physical device driver maintains two BPBs for each drive. One is the current BPB that corresponds to the media in the drive. The other is a recommended BPB based on the type of media that corresponds to the physical device. (For example, for a high-density drive, the BPB is for a 96 tracks-per-inch (TPI); for a low-density drive, the BPB is for a 48 TPI). The low bit of the Command Information field indicates which BPB the application needs to see. ═══ DSK_GETDEVICEPARAMS (63h) - Number of Cylinders ═══ Number of Cylinders Indicates the number of cylinders defined for the physical device. ═══ DSK_GETDEVICEPARAMS (63h) - Device Type ═══ Device Type Describes the physical layout of the device specified, and has one of the following values: 0 48 TPI low-density diskette drive 1 96 TPI high-density diskette drive 2 3.5-inch 720KB diskette drive 3 8-Inch single-density diskette drive 4 8-Inch double-density diskette drive 5 Fixed disk 6 Tape drive 7 Other (includes 1.44MB 3.5-inch diskette drive) 8 R/W optical disk 9 3.5-inch 4.0MB diskette drive (2.88MB formatted) ═══ DSK_GETDEVICEPARAMS (63h) - Device Attributes ═══ Device Attributes A bit field that returns flag information about the specified drive: Bit 0 Removable Media flag. This bit is set to 1 if the media cannot be removed. It is set to 0 if the media is removable. Bit 1 Changeline flag. This bit is set to 1, if the device support determines that the media was removed since the last I/O operation. To query whether the media has changed, call the physical device driver Strategy Command "1h - MEDIA CHECK". (Refer to "Physical Device Driver Strategy Commands" in the Physical Device Driver Reference for more information.) If this bit is set to 0, then the physical device driver can return the value 0, Unsure if media has changed, from the Media Check function. Bit 2 Greater than 16MB Support flag. If this bit is set to 1, the physical device driver supports physical addresses greater than 16MB. ═══ DSK_GETDEVICEPARAMS (63h) - Data Packet Format ═══ ┌─────────────────────────────────────────────────────┐ │Field Length C Datatype │ ├─────────────────────────────────────────────────────┤ │Extended BPB for Device 31 BYTES UCHAR[31] │ ├─────────────────────────────────────────────────────┤ │Number of Cylinders WORD USHORT │ ├─────────────────────────────────────────────────────┤ │Device Type BYTE UCHAR │ ├─────────────────────────────────────────────────────┤ │Device Attributes WORD USHORT │ └─────────────────────────────────────────────────────┘ ═══ DSK_GETDEVICEPARAMS (63h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_GETDEVICEPARAMS (63h) - Remarks ═══ This function gets the parameters for a specified device. ═══ DSK_GETDEVICEPARAMS (63h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_GETDEVICEPARAMS (63h) Description: Query Device Parameters Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.15. DSK_READTRACK (64h) - Read Logical Track ═══ ═══ DSK_READTRACK (64h) - Description ═══ Reads a logical track. ═══ DSK_READTRACK (64h) - Command Information ═══ Command Information A byte with bit 0 defined as follows: Bit 0 If clear (0), the track layout contains non-consecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ DSK_READTRACK (64h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ DSK_READTRACK (64h) - Cylinder ═══ Cylinder The cylinder for the read. ═══ DSK_READTRACK (64h) - First Sector ═══ First Sector The logical sector number within the Track Layout Table that starts the I/O operation. Note that the sector numbers start with 0. For example, the third sector is number 2. ═══ DSK_READTRACK (64h) - Number of Sectors ═══ Number of Sectors The number of sectors to read (up to the maximum specified in the track table; the IOCtl subfunctions do not step heads/tracks). ═══ DSK_READTRACK (64h) - Track Layout Table ═══ Track Layout Table Has the following: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │1 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 1 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │2 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 2 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │3 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 3 │WORD │ │ . │ . │ │ . │ . │ │ . │ . │ ├─────────────────────────┼───────┤ │Sector number for Sector │WORD │ │n │ │ ├─────────────────────────┼───────┤ │Sector size for Sector n │WORD │ └─────────────────────────┴───────┘ The sector table that is specified provides information that is used during the READ track operation. ═══ DSK_READTRACK (64h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE BYTE │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │First Sector WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Track Layout Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ DSK_READTRACK (64h) - Data Packet Format ═══ The Data Packet is a buffer. The buffer must be large enough to hold requested data. ┌──────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────┤ │Buffer BYTES UCHAR[] │ └──────────────────────────────────┘ ═══ DSK_READTRACK (64h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_READTRACK (64h) - Remarks ═══ This function is used to perform a read of sectors on the media and to perform the operations on the device that is specified in this request. The track table passed in on the call is used to determine the sector number, which is passed to the disk controller for the operation. In cases where the sectors are oddly numbered or are non-consecutive, this request breaks into n single sector operations and reads one sector at a time. This DosDevIOCtls is typically used when performing I/O outside of the normal file system data area on the media. ═══ DSK_READTRACK (64h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_READTRACK (64h) Description: Read Logical Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.16. DSK_VERIFYTRACK (65h) - Verify Logical Track ═══ ═══ DSK_VERIFYTRACK (65h) - Description ═══ Verifies a logical track. ═══ DSK_VERIFYTRACK (65h) - Command Information ═══ Command Information A byte with bit 0 defined as follows: Bit 0 If clear (0), the track layout contains non-consecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ DSK_VERIFYTRACK (65h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ DSK_VERIFYTRACK (65h) - Cylinder ═══ Cylinder The cylinder for the verify. ═══ DSK_VERIFYTRACK (65h) - First Sector ═══ First Sector The logical sector number within the Track Layout Table that starts the I/O operation. Note that the sector numbers start with 0. For example, the third sector is number 2. ═══ DSK_VERIFYTRACK (65h) - Number of Sectors ═══ Number of Sectors The number of sectors to verify (up to the maximum specified in the track table; the IOCtl subfunctions do not step heads/tracks). ═══ DSK_VERIFYTRACK (65h) - Track Layout Table ═══ Track Layout Table Has the following: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │1 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 1 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │2 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 2 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │3 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 3 │WORD │ │ . │ . │ │ . │ . │ │ . │ . │ ├─────────────────────────┼───────┤ │Sector number for Sector │WORD │ │n │ │ ├─────────────────────────┼───────┤ │Sector size for Sector n │WORD │ └─────────────────────────┴───────┘ The sector table that is specified provides information that is used during the VERIFY track operation. ═══ DSK_VERIFYTRACK (65h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE BYTE │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │First Sector WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Track Layout Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ DSK_VERIFYTRACK (65h) - Data Packet Format ═══ None. ═══ DSK_VERIFYTRACK (65h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_VERIFYTRACK (65h) - Remarks ═══ This function is used to perform a verify of sectors on the media and to perform the operations on the device that is specified in this request. The track table passed in on the call is used to determine the sector number, which is passed to the disk controller for the operation. In cases where the sectors are oddly numbered or are non-consecutive, this request breaks into n single sector operations and verifies one sector at a time. This DosDevIOCtls is typically used when performing I/O outside of the normal file system data area on the media. ═══ DSK_VERIFYTRACK (65h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_VERIFYTRACK (65h) Description: Verify Logical Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.1.17. DSK_GETLOCKSTATUS (66h) - Status ═══ ═══ DSK_GETLOCKSTATUS (66h) - Description ═══ The output of this function indicates if the drive is locked with or without media in it. ═══ DSK_GETLOCKSTATUS (66h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ DSK_GETLOCKSTATUS (66h) - Drive Unit ═══ Drive Unit This field is used only when the IOCtl is issued without using a previously allocated file handle. A file handle of -1 must be used. Notice that media in the drive is not required. Drive Unit values are 0=A, 1=B, 2=C, and so forth. ═══ DSK_GETLOCKSTATUS (66h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ ├───────────────────────────────────────────────┤ │Drive Unit WORD USHORT │ └───────────────────────────────────────────────┘ ═══ DSK_GETLOCKSTATUS (66h) - Status ═══ Status Bits 0-1 Value 00 Lock/Unlock/Eject/Status functions not supported. 01 Drive locked. Lock/Unlock/Eject functions supported. 10 Drive unlocked. Lock/Unlock/Eject functions supported. 11 Lock Status not supported. Lock/Unlock/Eject functions supported. Bit 2 Value 0 No media in drive 1 Media in drive Bit 3-31 Reserved ═══ DSK_GETLOCKSTATUS (66h) - Data Packet Format ═══ ┌──────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────┤ │Status WORD USHORT │ └──────────────────────────────────┘ ═══ DSK_GETLOCKSTATUS (66h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ DSK_GETLOCKSTATUS (66h) - Remarks ═══ None. ═══ DSK_GETLOCKSTATUS (66h) - ═══ Category: IOCTL_DISK (08h) Function: DSK_GETLOCKSTATUS (66h) Description: Status Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.2. Category 09h Physical Disk Control IOCtl Commands ═══ Category 09h is used to access physical partitionable hard disks. The handle used for Category 09h command is returned by the DosPhysicalDisk (Function 2) API function. (See the OS/2 Control Program Programming Reference for more information). This handle is used to tell the system which physical disk is accessed by the IOCtl command. The Physical Disk Control commands relate to the entire partitionable hard disk. Direct track and sector I/O start at the beginning of the physical drive. PDSK_GETPHYSDEVICEPARAMS, describes the entire physical device. The following is a summary of Category 09h IOCtl Commands: ┌───────────────┬─────────────────────────────────────────────┐ │Function │Description │ ├───────────────┼─────────────────────────────────────────────┤ │ 00h │Lock Physical Drive │ ├───────────────┼─────────────────────────────────────────────┤ │ 01h │Unlock Physical Drive │ ├───────────────┼─────────────────────────────────────────────┤ │ 44h │Write Physical Track │ ├───────────────┼─────────────────────────────────────────────┤ │ 63h │Query Physical Device Parameters │ ├───────────────┼─────────────────────────────────────────────┤ │ 64h │Read Physical Track │ ├───────────────┼─────────────────────────────────────────────┤ │ 65h │Verify Physical Track │ └───────────────┴─────────────────────────────────────────────┘ ═══ 16.2.1. PDSK_LOCKPHYSDRIVE (00h) - Lock Physical Drive ═══ ═══ PDSK_LOCKPHYSDRIVE (00h) - Description ═══ This function locks the physical drive. ═══ PDSK_LOCKPHYSDRIVE (00h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ PDSK_LOCKPHYSDRIVE (00h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ PDSK_LOCKPHYSDRIVE (00h) - Data Packet Format ═══ ┌──────────────────────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────────────────────┤ │Reserved. Set to 0. 31 BYTES UCHAR[31] │ └──────────────────────────────────────────────────┘ ═══ PDSK_LOCKPHYSDRIVE (00h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ PDSK_LOCKPHYSDRIVE (00h) - Remarks ═══ All the logical units on the physical drive are affected as well. ═══ PDSK_LOCKPHYSDRIVE (00h) - ═══ Category: IOCTL_PHYSICALDISK (09h) Function: PDSK_LOCKPHYSDRIVE (00h) Description: Lock Physical Drive Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.2.2. PDSK_UNLOCKPHYSDRIVE (01h) - Unlock Physical Drive ═══ ═══ PDSK_UNLOCKPHYSDRIVE (01h) - Description ═══ This function unlocks the physical drive. ═══ PDSK_UNLOCKPHYSDRIVE (01h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ PDSK_UNLOCKPHYSDRIVE (01h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ PDSK_UNLOCKPHYSDRIVE (01h) - Data Packet Format ═══ ┌──────────────────────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────────────────────┤ │Reserved. Set to 0. 31 BYTES UCHAR[31] │ └──────────────────────────────────────────────────┘ ═══ PDSK_UNLOCKPHYSDRIVE (01h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ PDSK_UNLOCKPHYSDRIVE (01h) - Remarks ═══ All the logical units on the physical drive are affected as well. ═══ PDSK_UNLOCKPHYSDRIVE (01h) - ═══ Category: IOCTL_PHYSICALDISK (09h) Function: PDSK_UNLOCKPHYSDRIVE (01h) Description: Unlock Physical Drive Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.2.3. PDSK_WRITEPHYSTRACK (44h) - Write Physical Track ═══ ═══ PDSK_WRITEPHYSTRACK (44h) - Description ═══ This function performs a physical write track. ═══ PDSK_WRITEPHYSTRACK (44h) - Command Information ═══ Command Information A bit field as follows: Bit 0 If clear (0), the track layout contains non-consecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ PDSK_WRITEPHYSTRACK (44h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ PDSK_WRITEPHYSTRACK (44h) - Cylinder ═══ Cylinder The cylinder for the write. ═══ PDSK_WRITEPHYSTRACK (44h) - First Sector ═══ First Sector The logical sector number within the Track Layout Table that starts the I/O operation. Note that the sector numbers start with 0. For example, the third sector is number 2. ═══ PDSK_WRITEPHYSTRACK (44h) - Number of Sectors ═══ Number of Sectors The number of sectors to write (up to the maximum specified in the track table; the IOCtl subfunctions do not step heads/tracks). ═══ PDSK_WRITEPHYSTRACK (44h) - Track Layout Table ═══ Track Layout Table The Track Layout Table is as follows: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │1 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 1 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │2 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 2 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │3 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 3 │WORD │ │ . │ . │ │ . │ . │ │ . │ . │ ├─────────────────────────┼───────┤ │Sector number for Sector │WORD │ │n │ │ ├─────────────────────────┼───────┤ │Sector size for Sector n │WORD │ └─────────────────────────┴───────┘ ═══ PDSK_WRITEPHYSTRACK (44h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE BYTE │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │First Sector WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Track Layout Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ PDSK_WRITEPHYSTRACK (44h) - Data Packet Format ═══ The Data Packet is a buffer. It contains the data to be written. ┌──────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────┤ │Buffer BYTES UCHAR[] │ └──────────────────────────────────┘ ═══ PDSK_WRITEPHYSTRACK (44h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ PDSK_WRITEPHYSTRACK (44h) - Remarks ═══ This function is used to perform the operations specified on the physical drive in this request. This is similar to the Category 08h commands, except that the I/O is done offset from the beginning of the physical drive instead of from the beginning of the extended volume associated with the unit number (Category 08h). The Track Layout Table passed in the Parameter Packet is used to determine the sector number, which is passed on to the disk controller for the operation. In cases where the sectors are oddly numbered or are non-consecutive, this request breaks into n single sector operations and writes one sector at a time. The sector table that is specified provides information that is used during the WRITE track operation. ═══ PDSK_WRITEPHYSTRACK (44h) - ═══ Category: IOCTL_PHYSICALDISK (09h) Function: PDSK_WRITEPHYSTRACK (44h) Description: Write Physical Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.2.4. PDSK_GETPHYSDEVICEPARAMS (63h) - Query Physical Device Parameters ═══ ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Description ═══ This function returns the physical device parameters. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Command Information ═══ Command Information Reserved. Must be set to 0. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE UCHAR │ └───────────────────────────────────────────────┘ ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Number of Cylinders ═══ Number of Cylinders The number of cylinders on the physical drive. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Number of Heads ═══ Number of Heads The number of heads on the physical drive. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Number of Sectors per Track ═══ Number of Sectors per Track The number of sectors per track on the physical drive. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Data Packet Format ═══ ┌──────────────────────────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────────────────────────┤ │Reserved WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Number of Cylinders WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Number of Heads WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Number of Sectors per Track WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Reserved WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Reserved WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Reserved WORD USHORT │ ├──────────────────────────────────────────────────────┤ │Reserved WORD USHORT │ └──────────────────────────────────────────────────────┘ Related C Data Structure The DEVICEPARAMETERBLOCK data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - Remarks ═══ The data values returned apply to the entire physical disk. ═══ PDSK_GETPHYSDEVICEPARAMS (63h) - ═══ Category: IOCTL_PHYSICALDISK (09h) Function: PDSK_GETPHYSDEVICEPARAMS (63h) Description: Query Physical Device Parameters Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.2.5. PDSK_READPHYSTRACK (64h) - Read Physical Track ═══ ═══ PDSK_READPHYSTRACK (64h) - Description ═══ Performs a physical read track. ═══ PDSK_READPHYSTRACK (64h) - Command Information ═══ Command Information A bit field as follows: Bit 0 If clear (0), the track layout contains nonconsecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ PDSK_READPHYSTRACK (64h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ PDSK_READPHYSTRACK (64h) - Cylinder ═══ Cylinder The cylinder for the read. ═══ PDSK_READPHYSTRACK (64h) - First Sector ═══ First Sector The logical sector number within the Track Layout Table that starts the I/O operation. Note that the sector numbers start with 0. For example, the third sector is number 2. ═══ PDSK_READPHYSTRACK (64h) - Number of Sectors ═══ Number of Sectors The number of sectors to read (up to the maximum specified in the track table; the IOCtl subfunctions do not step heads/tracks). ═══ PDSK_READPHYSTRACK (64h) - Track Layout Table ═══ Track Layout Table The Track Layout Table is as follows: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │1 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 1 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │2 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 2 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │3 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 3 │WORD │ │ . │ . │ │ . │ . │ │ . │ . │ ├─────────────────────────┼───────┤ │Sector number for Sector │WORD │ │n │ │ ├─────────────────────────┼───────┤ │Sector size for Sector n │WORD │ └─────────────────────────┴───────┘ ═══ PDSK_READPHYSTRACK (64h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE BYTE │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │First Sector WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Track Layout Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ PDSK_READPHYSTRACK (64h) - Data Packet Format ═══ The Data Packet is a buffer. The buffer must be large enough to hold requested data. ┌──────────────────────────────────┐ │Field Length C Datatype │ ├──────────────────────────────────┤ │Buffer BYTES UCHAR[] │ └──────────────────────────────────┘ ═══ PDSK_READPHYSTRACK (64h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ PDSK_READPHYSTRACK (64h) - Remarks ═══ This function is used to perform the operations specified on the physical drive in this request. This is similar to the Category 08h commands, except that the I/O is done offset from the beginning of the physical drive instead of from the beginning of the extended volume associated with the unit number (Category 08h). The Track Layout Table passed in the Parameter Packet is used to determine the sector number, which is passed on to the disk controller for the operation. In cases where the sectors are oddly numbered or are nonconsecutive, this request breaks into n single sector operations and reads one sector at a time. Note also that the device driver does not correctly read a non-512 byte sector if the READ operation would generate a DMA violation error. Applications should be written so that this error does not occur. The sector table that is specified provides information that is used during the READ track operation. ═══ PDSK_READPHYSTRACK (64h) - ═══ Category: IOCTL_PHYSICALDISK (09h) Function: PDSK_READPHYSTRACK (64h) Description: Read Physical Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 16.2.6. PDSK_VERIFYPHYSTRACK (65h) - Verify Physical Track ═══ ═══ PDSK_VERIFYPHYSTRACK (65h) - Description ═══ Performs a physical verify track. ═══ PDSK_VERIFYPHYSTRACK (65h) - Command Information ═══ Command Information A bit field as follows: Bit 0 If clear (0), the track layout contains non-consecutive sectors or does not start with Sector 1. If set (1), the track layout starts with Sector 1 and contains only consecutive sectors. All other bits are reserved and must be set to 0. ═══ PDSK_VERIFYPHYSTRACK (65h) - Head ═══ Head The physical head on the drive that performs the operation. ═══ PDSK_VERIFYPHYSTRACK (65h) - Cylinder ═══ Cylinder The cylinder for the verify. ═══ PDSK_VERIFYPHYSTRACK (65h) - First Sector ═══ First Sector The logical sector number within the Track Layout Table that starts the I/O operation. Note that the sector numbers start with 0. For example, the third sector is number 2. ═══ PDSK_VERIFYPHYSTRACK (65h) - Number of Sectors ═══ Number of Sectors The number of sectors to verify (up to the maximum specified in the track table; the IOCtl subfunctions do not step heads/tracks). ═══ PDSK_VERIFYPHYSTRACK (65h) - Track Layout Table ═══ Track Layout Table The Track Layout Table is as follows: ┌─────────────────────────┬───────┐ │Field │Length │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │1 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 1 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │2 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 2 │WORD │ ├─────────────────────────┼───────┤ │Sector Number for Sector │WORD │ │3 │ │ ├─────────────────────────┼───────┤ │Sector Size for Sector 3 │WORD │ │ . │ . │ │ . │ . │ │ . │ . │ ├─────────────────────────┼───────┤ │Sector number for Sector │WORD │ │n │ │ ├─────────────────────────┼───────┤ │Sector size for Sector n │WORD │ └─────────────────────────┴───────┘ ═══ PDSK_VERIFYPHYSTRACK (65h) - Parameter Packet Format ═══ ┌───────────────────────────────────────────────┐ │Field Length C Datatype │ ├───────────────────────────────────────────────┤ │Command Information BYTE BYTE │ ├───────────────────────────────────────────────┤ │Head WORD USHORT │ ├───────────────────────────────────────────────┤ │Cylinder WORD USHORT │ ├───────────────────────────────────────────────┤ │First Sector WORD USHORT │ ├───────────────────────────────────────────────┤ │Number of Sectors WORD USHORT │ ├───────────────────────────────────────────────┤ │Track Layout Table BYTES BYTE[] │ └───────────────────────────────────────────────┘ Related C Data Structure The TRACKLAYOUT data structure can be used by C programmers. To include this data structure in your file, make sure INCL_DOSDEVIOCTL is defined before you include OS2.H. ═══ PDSK_VERIFYPHYSTRACK (65h) - Data Packet Format ═══ None. ═══ PDSK_VERIFYPHYSTRACK (65h) - Returns ═══ Possible values are shown in the following list: 0 NO_ERROR 1 ERROR_INVALID_FUNCTION 6 ERROR_INVALID_HANDLE 15 ERROR_INVALID_DRIVE 31 ERROR_GEN_FAILURE 87 ERROR_INVALID_PARAMETER 111 ERROR_BUFFER_OVERFLOW 115 ERROR_PROTECTION_VIOLATION 117 ERROR_INVALID_CATEGORY 119 ERROR_BAD_DRIVER_LEVEL 163 ERROR_UNCERTAIN_MEDIA 165 ERROR_MONITORS_NOT_SUPPORTED ═══ PDSK_VERIFYPHYSTRACK (65h) - Remarks ═══ This function is used to perform the operations specified on the physical drive in this request. This is similar to the Category 08h commands, except that the I/O is done offset from the beginning of the physical drive instead of from the beginning of the extended volume associated with the unit number (Category 08h). The Track Layout Table passed in the Parameter Packet is used to determine the sector number, which is passed on to the disk controller for the operation. In cases where the sectors are oddly numbered or are non-consecutive, this request breaks into n single sector operations and verifies one sector at a time. The sector table that is specified provides information that is used during the VERIFY track operation. ═══ PDSK_VERIFYPHYSTRACK (65h) - ═══ Category: IOCTL_PHYSICALDISK (09h) Function: PDSK_VERIFYPHYSTRACK (65h) Description: Verify Physical Track Select an item: Description Parameter Packet Format Data Packet Format Returns Remarks ═══ 17. Sample Source Code for a PSD ═══ The following is the source code for an actual PSD. ═══ 17.1. Main program ═══ #define INCL_ERROR_H #include #include #include extern ulong_t RMP2Available(void); /* * Global Variables */ P_F_2 router = 0; char *pParmString = 0; int IODelayCount = 30; PLMA *pPSDPLMA = 0; ulong_t sizePLMA = 0; /*** Disable - Disable interrupts * * This function disables interrupts, and returns * the original state of eflags * * ENTRY None * * EXIT EFLAGS * */ ulong_t Disable(void) { ulong_t eflags; _asm { pushfd pop eax mov eflags,eax cli }; return (eflags); } /*** Enable - Restore the state of eflags * * This function restores the state of eflags * * ENTRY eflags - state of eflags to restore * * EXIT None * */ void Enable(ulong_t eflags) { _asm { push eflags popfd }; return; } /*** InByte - Read a byte from a port * * This function reads a byte from a specified port * * ENTRY port - port number to read from * * EXIT data read * */ ulong_t InByte(ulong_t port) { ulong_t data; _asm { mov dx,port in al,dx movzx eax,al mov data,eax }; return (data); } /*** OutByte - Writes a byte to a port * * This function writes a byte to a specified port * * ENTRY port - port number to read from * data - data to write * * EXIT None * */ void OutByte(ulong_t port, ulong_t data) { _asm { mov dx,port mov al,byte ptr data out dx,al }; return; } /*** SendEOI - Send an end of interrupt * * This function sends an end of interrupt. * * ENTRY irq - irq level to end * * EXIT None * */ ulong_t SendEOI(ulong_t irq) { ulong_t flags; flags = Disable(); if (irq < NUM_IRQ_PER_PIC) OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI); else { OutByte(PIC2_PORT0, OCW2_NON_SPECIFIC_EOI); IODelay; OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI); } Enable(flags); } /*** WHO_AM_I - Returns the current processor number * * This function returns the current processor number * * ENTRY NONE * * EXIT Current processor number (P1 or P2) * */ ulong_t WHO_AM_I (void) { return(InByte(WHO_AM_I_PORT)); } /*** IPIPresent - Detects the presence of an IPI * * This function detects the presence of an IPI on the current * processor * * ENTRY None * * EXIT NO_ERROR - IPI present * -1 - IPI not present * */ ulong_t IPIPresent (void) { ulong_t rc = 0; struct control_s ctrl; ulong_t port; port = pPSDPLMA->controlport; ctrl.b_all = InByte(port); if (ctrl.b_387err) { OutByte (0xf0, 0); // The busy latch for NPX must be cleared. // When we call the interrupt handler // (w/ Call16bitDD int.asm), ints. are 1st enabled. // If the busy latch is not cleared, then we // will take this interrupt in again and will // eventually nest until the interrupt stack is // overrun. rc = -1; } return (rc); } /*** Install - Install PSD * * This function checks to see if this PSD is installable on the * current platform. * * ENTRY pinstall - pointer to an INSTALL structure * * EXIT NO_ERROR - PSD Installed * -1 - PSD not valid for this platform * */ ulong_t Install(INSTALL *pinstall) { VMALLOC vmac; int i; char *p; ulong_t rc = 0; char ALR_String = "PROVEISA"; // _asm int 3; /* Setup Global variables */ router = pinstall->pPSDHlpRouter; pParmString = pinstall->pParmString; pPSDPLMA = (void *)pinstall->pPSDPLMA; sizePLMA = pinstall->sizePLMA; vmac.addr = BIOS_SEG << 4; vmac.cbsize = _64K; vmac.flags = VMALLOC_PHYS; /* Map BIOS area */ if ((rc = PSDHelp(router, PSDHLP_VMALLOC, &vmac)) == NO_ERROR) { /* Check for ALR string */ p = (char *)vmac.addr + ALR_STRING_OFFSET; for (i = 0; ALR_String i != '\0'; i++) if (p i != ALR_String i) { rc = -1; break; } /* Free BIOS mapping */ PSDHelp(router, PSDHLP_VMFREE, vmac.addr); } return (rc); } /*** DeInstall - DeInstall PSD * * This function deinstalls the PSD. * * ENTRY None * * EXIT NO_ERROR * */ ulong_t DeInstall(void) { return (NO_ERROR); } /*** Init - Initialize the PSD * * This function initializes the PSD. * * ENTRY None * * EXIT NO_ERROR - PSD initialized * -1 - PSD not initialized * */ ulong_t Init(INIT *pinit) { struct control_s ctrl; SET_IRQ set_irq; /* Initialize P1 control port */ ctrl.b_all = 0; ctrl.b_cacheon = 1; OutByte(P1_PROCESSOR_CONTROL_PORT, ctrl.b_all); /* Setup P2 interrupt vector */ OutByte(P2_INTERRUPT_VECTOR_CONTROL_PORT, IPI_VECTOR); /* Setup IPI info */ set_irq.irq = 13; set_irq.flags = IRQf_IPI; set_irq.vector = 0; set_irq.handler = (P_F_2)IPIPresent; PSDHelp(router, PSDHLP_SET_IRQ, &set_irq); /* Fill init structure */ pinit->flags = INIT_EOI_IRQ13_ON_CPU0; //76422 pinit->version = VERSION; return (NO_ERROR); } /*** ProcInit - Processor initialization * * This function initializes per processor items. * * NOTE: This function is called once on each processor * in the system. * * ENTRY None * * EXIT NO_ERROR - Processor initialized * -1 - Processor not initialized * */ ulong_t ProcInit(void) { if (WHO_AM_I() == P1) { pPSDPLMA->procnum = 0; pPSDPLMA->controlport = P1_PROCESSOR_CONTROL_PORT; } else { pPSDPLMA->procnum = 1; pPSDPLMA->controlport = P2_PROCESSOR_CONTROL_PORT; } return (NO_ERROR); } /*** StartProcessor - Start a processor * * This function starts a processor. * * ENTRY procnum - processor number to start (0-based) * * EXIT Return Code * */ ulong_t StartProcessor(ulong_t procnum) { CALL_REAL_MODE rm; struct control_s ctrl; ulong_t rc = -1; if (procnum == 1) { rm.function = (ulong_t)&RMP2Available; rm.pdata = 0; rc = PSDHelp(router, PSDHLP_CALL_REAL_MODE, &rm); if (rc & P2_AVAILABLE) { /* Dispatch P2 */ ctrl.b_all = 0; ctrl.b_cacheon = 1; OutByte(P2_PROCESSOR_CONTROL_PORT, ctrl.b_all); rc = NO_ERROR; } else rc = -1; } return (rc); } /*** GetNumOfProcs - Get number of processors * * This function gets the number of processors which exist on this * platform. * * ENTRY None * * EXIT Number of processors * */ ulong_t GetNumOfProcs(void) { ulong_t cprocs = 2; return (cprocs); } /*** GenIPI - Generate an inter-processor interrupt * * This function generates an IPI. * * ENTRY procnum - processor number to interrupt (0-based) * * EXIT NO_ERROR * */ ulong_t GenIPI(ulong_t procnum) { struct control_s ctrl; ulong_t port; if (procnum == 0) port = P1_PROCESSOR_CONTROL_PORT; else port = P2_PROCESSOR_CONTROL_PORT; ctrl.b_all = InByte(port); ctrl.b_pint = 1; OutByte(port, ctrl.b_all); return (NO_ERROR); } /*** EndIPI - End an inter-processor interrupt * * This function ends an IPI. * * ENTRY procnum - processor number to end interrupt on (0-based) * * EXIT NO_ERROR * */ ulong_t EndIPI(ulong_t procnum) { struct control_s ctrl; ulong_t port; if (procnum == 0) port = P1_PROCESSOR_CONTROL_PORT; else port = P2_PROCESSOR_CONTROL_PORT; ctrl.b_all = InByte(port); ctrl.b_pint = 0; OutByte(port, ctrl.b_all); if (procnum == 0) SendEOI(IPI_IRQ); return (NO_ERROR); } ═══ 17.2. Entry stub ═══ .386 _TEXT SEGMENT ASSUME CS:_TEXT,DS:NOTHING PUBLIC _RMP2Available _RMP2Available PROC mov ah,0E2h mov al,0 int 15h movzx eax,ax retf _RMP2Available ENDP _TEXT ENDS END ═══ 17.3. PSD.H ═══ /*static char *SCCSID = "@(#)psd.h 1.0 93/18/08";*/ // XLATOFF #ifndef ulong_t typedef unsigned long ulong_t; typedef unsigned short ushort_t; typedef unsigned char uchar_t; #endif typedef int (*P_F_1)(ulong_t arg); typedef int (*P_F_2)(ulong_t arg1, ulong_t arg2); #define PSDHelp(router, function, arg) \ ((*router)((function), (ulong_t)(arg))) // XLATON /* ASM P_F_1 struc dd ? P_F_1 ends P_F_2 struc dd ? P_F_2 ends */ #define WARM_REBOOT_VECTOR_SEG 0x40 #define WARM_REBOOT_VECTOR_OFF 0x67 /* PSD Info structure */ typedef struct info_s { /* psd */ ulong_t flags; /* PSD flags */ ulong_t version; /* PSD version */ ulong_t hmte; /* MTE handle of PSD */ uchar_t *pParmString; /* Pointer to ASCIIZ PSD parameter*/ ulong_t IRQ_IPI; /* IRQ for IPI */ ulong_t IRQ_LSI; /* IRQ for LSI */ ulong_t IRQ_SPI; /* IRQ for SPI */ } PSDINFO; /* PSD flags definition */ #define PSD_ADV_INT_MODE 0x20000000 /* PSD is in adv int mode #81531 */ #define PSD_INSTALLED 0x40000000 /* PSD has been installed */ #define PSD_INITIALIZED 0x80000000 /* PSD has been initialized */ /* PSD function numbers-structures */ #define PSD_INSTALL 0x00000000 /* Install PSD */ typedef struct install_s { /* install */ P_F_2 pPSDHlpRouter; /* Address of PSDHlpRouter */ char *pParmString; /* Pointer to parameter string */ void *pPSDPLMA; /* Pointer to PSD's PLMA */ ulong_t sizePLMA; /* Size of PLMA in bytes */ } INSTALL; #define PSD_DEINSTALL 0x00000001 /* DeInstall PSD */ #define PSD_INIT 0x00000002 /* Initialize PSD */ typedef struct init_s { /* init */ ulong_t flags; /* Init flags */ ulong_t version; /* PSD Version number */ } INIT; #define INIT_GLOBAL_IRQ_ACCESS 0x00000001 /* Platform has global IRQ access */ #define INIT_USE_FPERR_TRAP 0x00000002 /* Use Trap 16 to report FP err's */ #define INIT_EOI_IRQ13_ON_CPU0 0x00000004 /* eoi IRQ 13 only if on cpu 0 */ #define INIT_TIMER_CPU0 0x00000008 /* system timer is on CPU 0 */ #define PSD_PROC_INIT 0x00000003 /* Initialize processor */ #define PSD_START_PROC 0x00000004 /* Start processor */ #define PSD_GET_NUM_OF_PROCS 0x00000005 /* Get number of processors */ #define PSD_GEN_IPI 0x00000006 /* Generate an IPI */ #define PSD_END_IPI 0x00000007 /* End an IPI */ #define PSD_PORT_IO 0x00000008 /* Port I/O */ typedef struct port_io_s { /* port_io */ ulong_t port; /* Port number to access */ ulong_t data; /* Data read, or data to write */ ulong_t flags; /* IO Flags */ } PORT_IO; #define IO_READ_BYTE 0x0000 /* Read a byte from the port */ #define IO_READ_WORD 0x0001 /* Read a word from the port */ #define IO_READ_DWORD 0x0002 /* Read a dword from the port */ #define IO_WRITE_BYTE 0x0003 /* Write a byte to the port */ #define IO_WRITE_WORD 0x0004 /* Write a word to the port */ #define IO_WRITE_DWORD 0x0005 /* Write a dword to the port */ #define IO_FLAGMASK 0x0007 /* Flag mask */ #define PSD_IRQ_MASK 0x00000009 /* Mask/Unmask IRQ levels */ typedef struct psd_irq_s { /* psd_irq */ ulong_t flags; /* IRQ flags */ ulong_t data; /* IRQ data */ /* depending on type of irq */ /* operation, the data field */ /* can contain any of the */ /* following info: */ /* 1) Mask or UNMasking data */ /* 2) IRR or ISR reg values */ /* 3) IRQ # for EOI operations */ ulong_t procnum; /* Processor number */ } PSD_IRQ; #define PSD_IRQ_REG 0x0000000A /* Access IRQ related regs */ #define PSD_IRQ_EOI 0x0000000B /* Issue an EOI */ #define IRQ_MASK 0x00000001 /* Turn on IRQ mask bits */ #define IRQ_UNMASK 0x00000002 /* Turn off IRQ mask bits */ #define IRQ_GETMASK 0x00000004 /* Get IRQ mask bits */ #define IRQ_NEWMASK 0x00000010 /* Set and/or Reset all masks */ #define IRQ_READ_IRR 0x00000100 /* Read the IRR reg */ #define IRQ_READ_ISR 0x00000200 /* Read the ISR reg */ #define PSD_APP_COMM 0x0000000C /* PSD/APP Communication */ #define PSD_SET_ADV_INT_MODE 0x0000000D /* Set advanced int mode */ #define PSD_SET_PROC_STATE 0x0000000E /* Set proc state; idle, or busy */ #define PROC_STATE_IDLE 0x00000000 /* Processor is idle */ #define PROC_STATE_BUSY 0x00000001 /* Processor is busy */ #define PSD_QUERY_SYSTEM_TIMER 0x0000000F /* Query Value of System Timer 0 */ typedef struct psd_qrytmr_s { /* psd_qrytmr */ ulong_t qw_ulLo_psd; /* Timer count */ ulong_t qw_ulHi_psd; /* Timer count */ ulong_t pqwTmr; /* 16:16 ptr to qwTmr */ } PSD_QRYTMR; #define PSD_SET_SYSTEM_TIMER 0x00000010 /* Set System Timer 0 counter */ typedef struct psd_settmr_s { /* psd_settmr */ ulong_t NewRollOver; /* NewRollover*/ ulong_t pqwTmrRollover; /* 16:16 ptr to qwTmrRollover */ } PSD_SETTMR; /* PSD helper function numbers-structures */ #define PSDHLP_VMALLOC 0x00000000 /* Allocate memory */ typedef struct vmalloc_s { /* vmalloc */ ulong_t addr; /* Physical address to map */ /* if VMALLOC_PHYS */ /* Lin addr to alloc at */ /* if VMALLOC_LOCSPECIFIC */ /* on return, addr of allocation */ ulong_t cbsize; /* Size of mapping in bytes */ ulong_t flags; /* Allocation flags */ } VMALLOC; #define VMALLOC_FIXED 0x00000001 /* Allocate resident memory */ #define VMALLOC_CONTIG 0x00000002 /* Allocate contiguous memory */ #define VMALLOC_LOCSPECIFIC 0x00000004 /* Alloc at a specific lin address */ #define VMALLOC_PHYS 0x00000008 /* Map physical address */ #define VMALLOC_1M 0x00000010 /* Allocate below 1M */ #define VMALLOC_FLAGMASK 0x0000001f /* Valid flag mask */ #define PSDHLP_VMFREE 0x00000001 /* Free memory */ #define PSDHLP_SET_IRQ 0x00000002 /* Set up an IRQ */ typedef struct set_irq_s { /* set_irq */ ushort_t irq; /* IRQ level */ ushort_t flags; /* Set IRQ flags */ ulong_t vector; /* IRQ interrupt vector */ P_F_2 handler; /* IRQ handler */ } SET_IRQ; #define IRQf_IPI 0x0020 /* IRQ for IPI */ #define IRQf_LSI 0x0040 /* IRQ for LSI */ #define IRQf_SPI 0x0080 /* IRQ for SPI */ #define PSDHLP_CALL_REAL_MODE 0x00000003 /* Call a function in real mode */ typedef struct call_real_mode_s { /* call_real_mode */ ulong_t function; /* Function address */ ulong_t pdata; /* Pointer to data area */ } CALL_REAL_MODE; #define PSDHLP_VMLINTOPHYS 0x00000004 /* Convert linear addr to phys */ #define PSDHLP_ADJ_PG_RANGES 0x00000005 /* Adjust page ranges */ typedef struct _pagerange_s { /* pagerange */ ulong_t lastframe; /* Last valid page in range */ ulong_t firstframe; /* First valid page in range */ }; typedef struct adj_pg_ranges_s{ /* adj_pg_ranges */ struct _pagerange_s *pprt; /* Pointer to page range table */ ulong_t nranges; /* Num of ranges in range table */ } ADJ_PG_RANGES; /* PSD function prototypes */ extern void PSDEnter (ulong_t function, ulong_t arg, P_F_2 altEntry); ═══ 17.4. Specific header ═══ /* * Miscellaneous */ #define VERSION 0x00000010 #define _64K (64 * 1024) #define BIOS_SEG 0xF000 #define ALR_STRING_OFFSET 0xEC47 #define P2_AVAILABLE 0x00008000 /* * PLMA structure */ typedef struct plma_s { ulong_t procnum; /* Current processor number (0-based) */ ulong_t controlport; /* Control port for current processor */ } PLMA; /* * Generate delay between I/O instructions */ #define IODelay {int i; for(i = 0; i < IODelayCount; i++); } /* * IPI info */ #define IPI_IRQ 0x0d /* IRQ level for IPI */ #define IPI_VECTOR 0x75 /* Vector number for IPI */ /* * PIC Info */ #define NUM_IRQ_PER_PIC 0x08 #define OCW2_NON_SPECIFIC_EOI 0x20 #define PIC1_PORT0 0x20 #define PIC1_PORT1 0x21 #define PIC2_PORT0 0xA0 #define PIC2_PORT1 0xA1 /* * The contents of the WHO_AM_I port (read-only) can be used * by code to determine which processor we are currently on */ #define WHO_AM_I_PORT 0xC70 #define P1 0x00 #define P2 0xF0 /* * The processor control port contains the bits used to control * various functions of the associated processor */ #define P1_PROCESSOR_CONTROL_PORT 0x0C6A #define P2_PROCESSOR_CONTROL_PORT 0xFC6A struct _b_control_s { ulong_t _reset:1, /* RESET - (Not implemented for P1) */ /* 1 = Resets processor */ _387pres:1, /* 387PRES - (Read only) */ /* 0 = 80387 is not installed */ /* 1 = 80387 is installed */ _cacheon:1, /* CACHEON - (Not implemented for P1) */ /* 0 = Disables cache */ /* 1 = Enables cache */ _mbusaccess:1, /* M Bus Access (Not implemented for P1) */ /* 0 = Allows the processor to gain */ /* control of the memory bus */ /* 1 = Prohibits the processor from gaining */ /* access to the memory bus. The */ /* processor can execute instructions */ /* from its cache; however, cache read */ /* misses, I/O, and writes cause the */ /* processor to cease executing */ /* instructions until the bit becomes */ /* a "0" */ _flush:1, /* FLUSH */ /* Writing a "1" to this bit followed by a "0" */ /* causes invalidation of all cache address */ /* information */ _387err:1, /* 387ERR */ /* 0 = No 80387 error */ /* 0 = An 80387 error has occurred. This bit */ /* must be cleared by software */ _pint:1, /* PINT */ /* A low-to-high transition of this bit causes */ /* an interrupt. This bit must be cleared by */ /* software, preferably by the interrupt service */ /* routine. On P2, the value stored in FC68h */ /* contains the interrupt number. P1 is always */ /* interrupted with IRQ13 */ _intdis:1, /* INTDIS */ /* When set to "1", this bit disables interrupts */ /* sent to the processor by way of the PINT bit. */ /* The PINT bit can still be changed when */ /* interrupts are disabled; however, the */ /* low-to-high transition is not seen by the */ /* processor until the INTDIS bit is made inactive */ _pad:24; }; struct _l_control_s { /* to treat control as an unsigned long */ unsigned long _long; }; union _control_u { struct _b_control_s b_control_s; struct _l_control_s l_control_s; }; struct control_s { union _control_u control_u; }; #define b_reset control_u.b_control_s._reset #define b_387pres control_u.b_control_s._387pres #define b_cacheon control_u.b_control_s._cacheon #define b_mbusaccess control_u.b_control_s._mbusaccess #define b_flush control_u.b_control_s._flush #define b_387err control_u.b_control_s._387err #define b_pint control_u.b_control_s._pint #define b_intdis control_u.b_control_s._intdis #define b_all control_u.l_control_s._long /* * The interrupt vector control port contains the 8-bit interrupt * number that is executed when the PINT bit transitions from "0" * to "1". This vector is only used for P2. P1 is always interrupted * with IRQ 13. */ #define P2_INTERRUPT_VECTOR_CONTROL_PORT 0xFC68 /* * The following ports contain the EISA identification of the * system processor boards */ #define COMPAQ_ID1 0x0000000E #define COMPAQ_ID2 0x00000011 #define P1_EISA_PRODUCT_ID_PORT1 0x0C80 /* Compressed COMPAQ ID - OEh */ #define P1_EISA_PRODUCT_ID_PORT2 0x0C81 /* 11h */ #define P1_EISA_PRODUCT_ID_PORT3 0x0C82 /* Product code for the proc board */ #define P1_EISA_PRODUCT_ID_PORT4 0x0C83 /* Revision number */ #define P2_EISA_PRODUCT_ID_PORT1 0xFC80 /* Compressed COMPAQ ID - OEh */ #define P2_EISA_PRODUCT_ID_PORT2 0xFC81 /* 11h */ #define P2_EISA_PRODUCT_ID_PORT3 0xFC82 /* Product code for the proc board */ #define P2_EISA_PRODUCT_ID_PORT4 0xFC83 /* Revision number */ /* * Any write to The RAM Relocation Register (memory mapped) * will flush the caches of both P1 and P2 */ #define RAM_RELOCATION_REGISTER 0x80C00000 /* * The P1 Cache Control Register (memory mapped) */ #define P1_CACHE_CONTROL_REGISTER 0x80C00002 struct p1cache_s { ulong_t _reserved1:6, _p1cc:1, /* P1 Cache Control */ /* 0 = Disables P1 cache */ /* 1 = Enables P1 cache */ _reserved2:9; }; /* * Expanision board control ports */ #define P1_EISA_EXPANSION_BOARD_CONTROL 0x0C84 #define P2_EISA_EXPANSION_BOARD_CONTROL 0xFC84 ═══ 17.5. Makefile ═══ # SCCSID = @(#)makefile 6.7 92/06/03 #/***********************************************************************/ #/* */ #/* PSD Name: ALR.PSD - ALR PSD */ #/* ----------------------------------- */ #/* */ #/* Source File Name: MAKEFILE */ #/* */ #/* Descriptive Name: MAKEFILE for the ALR PSD */ #/* */ #/* Function: */ #/* */ #/* */ #/*---------------------------------------------------------------------*/ #/* */ #/* Copyright (C) 1992 IBM Corporation */ #/* */ #/* DISCLAIMER OF WARRANTIES. The following enclosed code is */ #/* provided to you solely for the purpose of assisting you in */ #/* the development of your applications. The code is provided */ #/* "AS IS", without warranty of any kind. IBM shall not be liable */ #/* for any damages arising out of your use of this code, even if */ #/* they have been advised of the possibility of such damages. */ #/* */ #/*---------------------------------------------------------------------*/ #/* */ #/* Change Log */ #/* */ #/* Mark Date Programmer Comment */ #/* ---- ---- ---------- ------- */ #/* @nnnn mm/dd/yy NNN */ #/* */ #/* */ #/***********************************************************************/ # ****** NOTE ****** # # If you are using a SED command with TAB characters, many editors # will expand tabs causing unpredictable results in other programs. # # Documentation: # # Using SED command with TABS. Besure to invoke set tab save option # on your editor. If you don't, the program 'xyz' will not work # correctly. # #**************************************************************************** # Dot directive definition area (usually just suffixes) #**************************************************************************** .SUFFIXES: .SUFFIXES: .com .sys .exe .obj .mbj .asm .inc .def .lnk .lrf .crf .ref .SUFFIXES: .lst .sym .map .c .h .lib #**************************************************************************** # Environment Setup for the component(s). #**************************************************************************** # # Conditional Setup Area and User Defined Macros # # # Compiler Location w/ includes, libs and tools # INC = ..\..\..\inc H = ..\..\..\h LIB = ..\..\..\lib386;..\..\..\lib TOOLSPATH = ..\..\..\tools # # Because the compiler/linker and other tools use environment # variables ( INCLUDE, LIB, etc ) in order to get the location of files, # the following line will check the environment for the LIFE of the # makefile and will be specific to this set of instructions. All MAKEFILES # are requested to use this format to insure that they are using the correct # level of files and tools. # !if set INCLUDE=$(INC) || \ set LIB=$(LIB) || set PATH=$(TOOLSPATH);$(DK_TOOLS) !endif # # Compiler/tools Macros # AS=masm CC=cl386 IMPLIB=implib IPF=ipfc LIBUTIL=lib LINK=link386 MAPSYM=mapsym RC=rc # # Compiler and Linker Options # AFLAGS = -MX -T -Z $(ENV) AINC = -I. -I$(INC) CINC = -I$(H) -I$(MAKEDIR) CFLAGS = /c /Zp /Gs /AS $(ENV) LFLAGS = /map /nod /exepack LIBS = os2386.lib DEF = ALR.def #**************************************************************************** # Set up Macros that will contain all the different dependencies for the # executables and dlls etc. that are generated. #**************************************************************************** # # # OBJ1 = entry.obj main.obj # # LIST Files # LIST = OBJS = $(OBJ1) #**************************************************************************** # Setup the inference rules for compiling and assembling source code to # object code. #**************************************************************************** .asm.obj: $(AS) $(AFLAGS) $(AINC) $*.asm; .asm.mbj: $(AS) $(AFLAGS) -DMMIOPH $(AINC) $*.asm $*.mbj; .asm.lst: $(AS) -l -n $(AFLAGS) $(AINC) $*.asm; .c.obj: $(CC) $(CFLAGS) $(CINC) $*.c .c.lst: $(CC) $(CFLAGS) /Fc $(CINC) $*.c copy $*.cod $*.lst del $*.cod #**************************************************************************** # Target Information #**************************************************************************** # # This is a very important step. The following small amount of code MUST # NOT be removed from the program. The following directive will do # dependency checking every time this component is built UNLESS the # following is performed: # A specific tag is used -- ie. all # # This allows the developer as well as the B & I group to perform incremental # build with a degree of accuracy that has not been used before. # There are some instances where certain types of INCLUDE files must be # created first. This type of format will allow the developer to require # that file to be created first. In order to achieve that, all that has to # be done is to make the DEPEND.MAK tag have your required target. Below is # an example: # # depend.mak: { your file(s) } dephold # # Please DON'T remove the following line # !include "$(H)\common.mak" !include "$(H)\version.mak" # # Should be the default tag for all general processing # all: ALR.psd list: $(LIST) clean: if exist *.lnk del *.lnk if exist *.obj del *.obj if exist *.mbj del *.mbj if exist *.map del *.map if exist *.old del *.old if exist *.lst del *.lst if exist *.lsd del *.lsd if exist *.sym del *.sym if exist *.sys del *.sys #***************************************************************************** # Specific Description Block Information #***************************************************************************** # This section would only be for specific direction as to how to create # unique elements that are necessary to the build process. This could # be compiling or assembling, creation of DEF files and other unique # files. # If all compiler and assembly rules are the same, use an inference rule to # perform the compilation. # alr.psd: $(OBJS) makefile Rem Create DEF file <<$(DEF) LIBRARY ALR EXPORTS PSD_INSTALL = _Install PSD_DEINSTALL = _DeInstall PSD_INIT = _Init PSD_PROC_INIT = _ProcInit PSD_START_PROC = _StartProcessor PSD_GET_NUM_OF_PROCS = _GetNumOfProcs PSD_GEN_IPI = _GenIPI PSD_END_IPI = _EndIPI <$@ -del depchk dephold: touch $@ !include depend.mak ═══ 18. Comments, Please! ═══ We're interested in your feedback. If there is something you like or dislike about the SMP Programming Addendum, or any of the OS/2 Toolkit books, please let us know! You can use one of the methods listed below to send your comments to IBM. Include the book title and the name of the topic you are commenting on. The comments you send should pertain only to the information in the book and its presentation. To request additional publications, ask questions, or make comments about the functions of IBM products or systems, talk to your IBM reseller or IBM marketing representative. When you send comments to IBM, you grant IBM a nonexclusive right to use or distribute your comments in any way it believes appropriate without incurring any obligation to you. ┌────────────────────┬──────────────────────────────┐ │CompuServe │[72410,624] │ ├────────────────────┼──────────────────────────────┤ │Internet │devcon@vnet.ibm.com │ │ │os2books@vnet.ibm.com │ ├────────────────────┼──────────────────────────────┤ │IBMMAIL │USIB66YK at IBMMAIL │ └────────────────────┴──────────────────────────────┘ In addition to sending us electronic mail, you can also participate in these forums monitored by IBM: ┌────────────────────┬──────────────────────────────────────────────────┐ │Provider │Forum name │ ├────────────────────┼──────────────────────────────────────────────────┤ │CompuServe │OS/2 Developer Forum 1 - Developer Documentation │ │ │(GO OS2DF1) │ ├────────────────────┼──────────────────────────────────────────────────┤ │OS/2 BBS │DEVCON CFORUM │ │TalkLink │ │ ├────────────────────┼──────────────────────────────────────────────────┤ │IBM Internal │OS2PUBS FORUM │ │ │(IBMPC Conferencing Facility) │ └────────────────────┴──────────────────────────────────────────────────┘ ═══ 19. Glossary ═══ MP-unsafe Does not provide the necessary serialization to run on more than one CPU at a time. For example, a driver will be MP unsafe if it relies upon priorities between threads for accessing shared resources, or uses the CLI/STI method for protecting resources like semaphores or memory. MP-safe Provides the necessary serialization to run properly in a system with greater than one processor. Does not use invalid UP serialization techniques. For example, a driver will be MP safe if it does not rely upon priorities between threads for accessing shared resources, or use the CLI/STI method for protecting resources like semaphores or memory. MP-exploitive Provides proper MP serialization techniques which allow multiple threads to run concurrently on more than one CPU. ═══ 20. Notices ═══ November 1996 The following paragraph does not apply to the United Kingdom or any country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This publication could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time. It is possible that this publication may contain reference to, or information about, IBM products (machines and programs), programming, or services that are not announced in your country. Such references or information must not be construed to mean that IBM intends to announce such IBM products, programming, or services in your country. Requests for technical information about IBM products should be made to your IBM reseller or IBM marketing representative. ═══ 20.1. Copyright Notices ═══ COPYRIGHT LICENSE: This publication contains printed sample application programs in source language, which illustrate OS/2 programming techniques. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the OS/2 application programming interface. Each copy of any portion of these sample programs or any derivative work, which is distributed to others, must include a copyright notice as follows: "(C) (your company name) (year). All rights reserved." (C) Copyright International Business Machines Corporation 1994,1996. All rights reserved. Note to U.S. Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. ═══ 20.2. Disclaimers ═══ References in this publication to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Subject to IBM's valid intellectual property or other legally protectable rights, any functionally equivalent product, program, or service may be used instead of the IBM product, program, or service. The evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, are the responsibility of the user. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to: IBM Director of Licensing IBM Corporation 500 Columbus Avenue Thornwood, NY 10594 U.S.A. ═══ 20.3. Trademarks ═══ The following terms are trademarks of the IBM Corporation in the United States or other countries or both: Common User Access CICS CUA DB2/2 NetView OS/2 Presentation Manager Systems Application Architecture SAA SP XGA The following terms are trademarks of other companies: ADD Applications Design and Development, Inc. C++ American Telephone and Telegraph Company Compaq Compaq Computer Corporation DDS Sony Corporation Focus Information Builders, Inc. Frame Frame Technology, Inc. Intel Intel Corporation Lotus Notes Lotus Development Corporation Novell Novell, Inc. NET NCR Corporation Pentium Intel Corporation Pentium Pro Intel Corporation PostScript Adobe Systems Incorporated SPEC Standard Performance Evaluation Corporation VDM Geographics Systems, Ltd. Windows NT Microsoft Corporation Microsoft, Windows, and the Windows 95 logo are trademarks or registered trademarks of Microsoft Corporation.