home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft_Programmers_Library.7z / MPL / os2 / os2kno.txt < prev    next >
Encoding:
Text File  |  2013-11-08  |  1.1 MB  |  28,576 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1.  Microsoft OS/2 Software Development Kit
  2.  =============================================================================
  3.  
  4.  
  5.  1. Executing OS/2 Applications under MS-DOS
  6.  
  7.  Problem:
  8.  
  9.  I am unable to execute an OS/2 application under MS-DOS. The program
  10.  executes correctly under OS/2.
  11.  
  12.  Response:
  13.  
  14.  To prepare an application to execute under OS/2 and MS-DOS, do the
  15.  following:
  16.  
  17.  1. Check the code against compatibility rules (see "Programming Hints"
  18.     4.2.3).
  19.  
  20.  2. Use a subset of API calls (see "Programming Hints" 4.3).
  21.  
  22.  3. Link with -Lp option, when using C, as in the following example:
  23.  
  24.     cl -G0 -Lp <filename.ext>.
  25.  
  26.  4. Use cpbind to create compatible application, as in the following
  27.     example:
  28.  
  29.     cpbind <filename.ext>  \lib5\api.lib  \lib5\doscalls.lib.
  30.  
  31.  
  32.  2. Opening Files under Both OS/2 and MS-DOS
  33.  
  34.  Problem:
  35.  
  36.  My application runs correctly under OS/2, but is unable to open a file
  37.  under MS-DOS.
  38.  
  39.  Response:
  40.  
  41.  The following is an example function that will open a file under
  42.  OS/2 and MS-DOS. Note the settings of modeflag(struct flags).
  43.  
  44.  /***  openfile - opens file to be read
  45.   *
  46.   *    openfile uses DOSOPEN to open or create a file and
  47.   *      return a handle to it.
  48.   *
  49.   *    openfile (fname, fhandle)
  50.   *
  51.   *    ENTRY    fname   - name of the file
  52.   *
  53.   *    EXIT     fhandle - file handle
  54.   *
  55.   *    openfile will exit the program if there is an error
  56.   *      opening the file or if the file was created by
  57.   *      DOSOPEN.
  58.   *
  59.   *    EFFECTS  fhandle - by returning a handle to the file
  60.   *             memory  - by opening a file
  61.   */
  62.  
  63.  void openfile(fname, fhandle)
  64.  char           *fname;
  65.  unsigned short *fhandle;
  66.  {
  67.      unsigned short actiontaken = 0;    /* value return by DOS */
  68.      unsigned long  fsize = 0l;         /* set to not change file size (0) */
  69.      unsigned short fattrib  = 0;       /* set to not change file attrib (0) *
  70.      unsigned short openflag = 0x0011;  /* set to open or create file */
  71.      struct flags {
  72.        unsigned access     :3 ;   /* set to read & write access (2) */
  73.        unsigned reserved1  :1 ;   /* must be zero */
  74.        unsigned sharing    :3 ;   /* set to deny read & write access (1) */
  75.        unsigned inheritance:1 ;   /* set to private (1) */
  76.        unsigned reserved5  :5 ;   /* must be zero */
  77.        unsigned failerrors :1 ;   /* needs to be zero for API */
  78.        unsigned write      :1 ;   /* needs to be zero for API */
  79.        unsigned dasdopen   :1 ;   /* needs to be zero for API */
  80.      };
  81.      static union {
  82.        struct flags   modeflags;
  83.        unsigned short mode;
  84.      } openmode = { { 2,0,1,1,0,0,0,0 } };
  85.      short          rc;         /* return code from DOS call */
  86.  
  87.  /*  Open the file */
  88.      rc = DOSOPEN( (char far *)fname, (unsigned far *)fhandle,
  89.                    (unsigned far *)&actiontaken,
  90.                     fsize, fattrib, openflag,
  91.                     openmode.mode, 0l);
  92.      if ((rc != 0) || (actiontaken != 1)) {
  93.        printf("error opening file %d \n", rc);
  94.        exit(3);
  95.      }
  96.  }
  97.  
  98.  
  99.  3. Swapping under OS/2 and Booting from a Floppy Disk
  100.  
  101.  Problem:
  102.  
  103.  My OS/2 application will not swap. The system is booted from a floppy
  104.  in Drive A, and the application is executed from the hard drive. Since
  105.  the application will not swap, it is limited by the amount of memory
  106.  in the machine.
  107.  
  108.  Response:
  109.  
  110.  In this case, the problem is the result of not using the OS/2
  111.  CONFIG.SYS command SWAPPATH. Since the swap path is not set, it
  112.  defaults to the boot drive--the floppy drive. The floppy in Drive A
  113.  has very little free space left, so no swap file can be created. To
  114.  correct the problem, set SWAPPATH in CONFIG.SYS to the hard drive.
  115.  
  116.  
  117.  4. Exiting a Thread with DOSEXIT
  118.  
  119.  Question:
  120.  
  121.  I have a program that prints a message using the C run-time printf()
  122.  routine, then exits using DOSEXIT. None of my output appears on the
  123.  screen. What is wrong?
  124.  
  125.  Response:
  126.  
  127.  OS/2 provides a standard method of exiting a thread, DOSEXIT. This
  128.  call is defined in the include file DOSCALLS.H as follows:
  129.  
  130.     extern void far pascal DOSEXIT (
  131.       unsigned,
  132.       unsigned );
  133.  
  134.  The two parameters are as follows:
  135.  
  136.     ActionCode  -   0 -> only the current thread is terminated
  137.                     1 -> all threads in the process are terminated
  138.  
  139.     ResultCode  -   Program's completion code (specifiable), to be
  140.                     passed to any thread that issues a DOSCWAIT
  141.                     for this process.
  142.  
  143.  When programming in C, it is possible that data written with printf()
  144.  will be lost if you use DOSEXIT. This is due to the C run time's
  145.  printf() routine buffering its output. DOSEXIT will kill the thread or
  146.  process without flushing these buffers.
  147.  
  148.  While exit() is not as flexible as DOSEXIT, in that you cannot control
  149.  the termination of other threads--exit() will always kill all threads
  150.  in a process--it should always be used to terminate the main thread of
  151.  a program. DOSEXIT can be used to terminate child threads, specifying
  152.  0 in the first parameter.
  153.  
  154.  
  155.  5. Data Available from KBDCHARIN
  156.  
  157.  Problem:
  158.  
  159.  I would like to see a program illustrating the data available from
  160.  KBDCHARIN, the standard system call for getting keyboard input under
  161.  OS/2.
  162.  
  163.  Response:
  164.  
  165.  The KBDCHARIN call fills the fields in a data structure whose address
  166.  has been passed to it by the program. KBDCHARIN is defined in
  167.  SUBCALLS.H as follows:
  168.  
  169.             extern unsigned far pascal KBDCHARIN (
  170.                     struct KeyData far *,
  171.                     unsigned,
  172.                     unsigned );
  173.  
  174.  Fields are defined as the following:
  175.  
  176.  CharData    -  far address of structure to receive data
  177.  
  178.  IOWait      -  indicates if should wait when no character is
  179.                    available -  0 = yes, 1 = no
  180.  
  181.  KbdHandle   -  reserved word of zeros
  182.  
  183.  The data structure for KeyData is also defined in SUBCALLS.H:
  184.  
  185.             struct KeyData {
  186.                     unsigned char char_code;
  187.                     unsigned char scan_code;
  188.                     unsigned char status;
  189.                     unsigned char nls_shift;
  190.                     unsigned shift_state;
  191.                     unsigned long time;
  192.                     };
  193.  
  194.  These fields have the following meanings:
  195.  
  196.  char_code   -  ASCII character code derived from translation of the
  197.                 scan code received
  198.  
  199.  scan_code   -  code received from the keyboard identifying the key
  200.                 pressed. This may have been modified during the
  201.                 translation process.
  202.  
  203.  status      -  indicates the state of the character through bit
  204.                 fields--see manual for exact definitions
  205.  
  206.  nls_shift   -  reserved = 0
  207.  
  208.  shift_state -  defines state of the various shift keys including
  209.                 CTRL-, ALT-, NUM LOCK, etc.--see manual for exact
  210.                 definitions
  211.  
  212.  time        -  time stamp of the keystroke in milliseconds since
  213.                 IPL (system initialization). This field is not valid
  214.                 in real mode.
  215.  
  216.  This demonstration program makes calls to KBDCHARIN and displays the
  217.  data passed to KeyData on the screen. Pressing the space bar
  218.  terminates the demonstration. Compile with the -Lp option.
  219.  
  220.  Before we can use KBDCHARIN, we set the keyboard. This is done by
  221.  making a call to KBDGETSTATUS, masking the status bits to the right
  222.  state, and calling KBDSETSTATUS to set the mode. These calls, and the
  223.  data structures used, are also in SUBCALLS.H.
  224.  
  225.             extern unsigned far pascal KBDGETSTATUS (
  226.                     struct KbdStatus far *,
  227.                     unsigned );
  228.  
  229.             extern unsigned far pascal KBDSETSTATUS (
  230.                     struct KbdStatus far *,
  231.                     unsigned );
  232.  
  233.  In each call, the first parameter is the far address of a keyboard
  234.  status data structure, and the second is the keyboard handle, a
  235.  reserved word of zeros. The data structure used is defined as the
  236.  following:
  237.  
  238.             struct KbdStatus {
  239.                     unsigned length;
  240.                     unsigned bit_mask;
  241.                     unsigned turn_around_char;
  242.                     unsigned interim_char_flags;
  243.                     unsigned shift_state;
  244.                     };
  245.  
  246.  Field definitions are as follows:
  247.  
  248.  length             -  length in bytes of the data structure,
  249.                        including this word
  250.  
  251.  bit_mask           -  full word bit mask representing functions to
  252.                        be altered. For full definitions see manual;
  253.                        we are interested in bit 3 to set ASCII mode.
  254.  
  255.  turn_around_char   -  defines the turnaround (carriage return)
  256.                        character
  257.  
  258.  interim_char_flags -  see manual
  259.  
  260.  shift_state        -  similar to shift_state in KBDCHARIN
  261.  
  262.  #include <doscalls.h>
  263.  #include <subcalls.h>
  264.  
  265.  main ()
  266.      {
  267.          struct  KeyData keydata;
  268.          struct  KbdStatus kbdstatus;
  269.  
  270.          kbdstatus.length = sizeof( kbdstatus );
  271.          KBDGETSTATUS( &kbdstatus, 0 );
  272.          kbdstatus.bit_mask |= 4;       /* turn on bit 3 for binary mode */
  273.          KBDSETSTATUS( &kbdstatus, 0 );
  274.  
  275.          do {
  276.                  KBDCHARIN( &keydata, 0, 0 );
  277.  
  278.                  printf( "char: %02X  scan: %02X  status: %02X  ",
  279.                          keydata.char_code,
  280.                          keydata.scan_code,
  281.                          keydata.status);
  282.  
  283.                  printf( "nls_shift: %02X  shift: %04X  ",
  284.                          keydata.nls_shift,
  285.                          keydata.shift_state);
  286.  
  287.                  printf( "time: %02d:%02d:%02d.%02d\r\n",
  288.                          (int) (0xFF & keydata.time),
  289.                          (int) (0xFF & (keydata.time >> 8)),
  290.                          (int) (0xFF & (keydata.time >> 16)),
  291.                          (int) (0xFF & (keydata.time >> 24)));
  292.  
  293.          } while( keydata.char_code != ' ' );
  294.  
  295.          exit(0);
  296.  
  297.      }
  298.  
  299.  
  300.  6. OS/2 SDK: Family API Library
  301.  
  302.  Question:
  303.  
  304.  As I understand it, there is a Family API Library that allows you to
  305.  write a MS-DOS application that runs under MS-DOS Versions 3.x and in
  306.  protected mode under OS/2. Also, current Windows applications are not
  307.  binary compatible with the OS/2 Presentation Manager (PM). Is it
  308.  possible to write a Windows application that is binary compatible with
  309.  Windows Version 2.00 and the OS/2 Presentation Manager, or will the
  310.  ISV have to sell and maintain two sets of source code and binaries?
  311.  
  312.  Response:
  313.  
  314.  Windows Version 2.00 and the OS/2 Presentation Manager look identical;
  315.  however, the API (application programming interface) for each is
  316.  different. An ISV will have to sell and maintain two sets of binaries.
  317.  
  318.  The family API is much slower than the OS/2 API calling interface. We
  319.  expect competitive pressure to lessen the importance of the family
  320.  API.
  321.  
  322.  It is an IBM marketing decision whether to migrate the OS/2 API back
  323.  to MS-DOS Versions 3.x. If that does happen, one would hope there will
  324.  be source code compatibility and possible binary compatibility.
  325.  
  326.  
  327.  7. OS/2 SDK Version 1.10 Final Release
  328.  
  329.  Microsoft will deliver final releases of OS/2 Version 1.00 and OS/2
  330.  Version 1.10 along with the associated development tools. Software
  331.  Development Kit (SDK) purchasers will receive the final release of the
  332.  following products:
  333.  
  334.     Microsoft OS/2 Version 1.00
  335.     Microsoft OS/2 Version 1.10
  336.  
  337.     Microsoft OS/2 Version 1.00 Programmer's Tool Kit
  338.     Microsoft OS/2 Version 1.10 Programmer's Tool Kit
  339.  
  340.     Microsoft OS/2 Version 1.00 LAN Manager
  341.  
  342.     Microsoft C Compiler Version 5.10
  343.     Microsoft Macro Assembler Version 5.10
  344.  
  345.     Microsoft Windows Version 2.00
  346.     Microsoft Windows SDK Version 2.00
  347.  
  348.  After final releases of the products listed above have been delivered,
  349.  you will not receive any further upgrades for these products. As of
  350.  10/01/88, OS/2 SDK purchasers have received the final releases of the
  351.  following products:
  352.  
  353.     Microsoft OS/2 Version 1.00
  354.     Microsoft OS/2 Version 1.00 Programmer's Tool Kit
  355.  
  356.     Microsoft C Compiler Version 5.10
  357.     Microsoft Macro Assembler Version 5.10
  358.  
  359.     Microsoft Windows Version 2.00
  360.     Microsoft Windows SDK Version 2.00
  361.  
  362.  
  363.  8. How to Tell if You Are in the Background
  364.  
  365.  Question:
  366.     Is it necessary for an application running under OS/2 to determine
  367.  whether it is running in the background?
  368.  
  369.  Response:
  370.     Yes; it may be necessary. For instance, any KBD or VIO calls will
  371.  not work from the background. If a program that waits for keyboard
  372.  input is run in the background by using DETACH, it will continue to
  373.  consume resources in the background while being inaccessible and
  374.  invisible to the user.
  375.     Also, a program may wish to know whether its input is coming from
  376.  the console or from an input file. The following sample program
  377.  illustrates a method for determining this information using the
  378.  DOSQHANDTYPE call. This call reports whether a handle refers to a file
  379.  or device, and if it is a device, if it returns the device's driver
  380.  attribute word. Bit 0 of this word is set if the device is standard
  381.  input and bit 1 is set for standard output. If we make this call
  382.  within handle 0 and get back return values indicating a device, and
  383.  these two bits in the attribute word are both set, then we can safely
  384.  assume that we are running in the foreground and that the keyboard and
  385.  screen are our standard input and output devices.
  386.     DOSQHANDTYPE is defined in DOSCALLS.H as follows:
  387.  
  388.     extern unsigned far pascal DOSQHANDTYPE (
  389.             unsigned,
  390.             unsigned far *,
  391.             unsigned far * );
  392.  
  393.     These fields are defined as follows:
  394.  
  395.     FileHandle  -  the file handle we are requesting information for
  396.     HandType    -  far address where the handle type will be returned
  397.                     0 -> file handle,  1 -> device handle
  398.     FlagWord    -  far address where the device's attribute word will
  399.                    be returned if HandType = 1
  400.  
  401.     Compile this program with the -Lp option and try running it under
  402.  OS/2 with these variations:
  403.  
  404.     C> backgrnd
  405.     C> detach backgrnd > backgrnd.out
  406.  
  407.     Note that in the second case we must direct our output to a file,
  408.  since we cannot write to the screen when DETACHed.
  409.     Only in the first case are we running in the foreground; the
  410.  program allows us to detect this. This technique could be used at the
  411.  entry point of a program to terminate execution if not in the
  412.  foreground, disallowing the possibility of the program being DETACHed.
  413.  
  414.     #include <doscalls.h>
  415.  
  416.     main()
  417.         {
  418.  
  419.         unsigned short     handtype;
  420.         unsigned short     flagword;
  421.  
  422.         DOSQHANDTYPE( 0, (unsigned far *)&handtype,
  423.                      (unsigned far*)&flagword );
  424.  
  425.         if( handtype == 0 )
  426.             printf( "File system handle\n\n" );
  427.         else if( handtype == 1 ) {
  428.                 printf( "Device handle\n\n" );
  429.                 if( flagword & 1 )
  430.                     printf( "    Screen is standard output\n\n" );
  431.                 if( flagword & 2 )
  432.                     printf( "    Keyboard is standard input\n\n" );
  433.                 }
  434.  
  435.         exit(0);
  436.  
  437.         }
  438.  
  439.  
  440.  9. Clearing the Screen under OS/2
  441.  
  442.  Question:
  443.  
  444.  What is the recommended method for clearing the screen under OS/2?
  445.  
  446.  Response:
  447.  
  448.  The following program demonstrates the recommended method for clearing
  449.  the screen. A "cell" (a 2-byte field containing a character and an
  450.  attribute) is copied over the entire screen using VIOSCROLLUP with a
  451.  special set of parameters. SUBCALLS.H must be included to use the
  452.  VIOSCROLLUP call; it contains the following definition:
  453.  
  454.  extern unsigned far pascal VIOSCROLLUP (
  455.                     unsigned,
  456.                     unsigned,
  457.                     unsigned,
  458.                     unsigned,
  459.                     unsigned,
  460.                     char far *,
  461.                     unsigned );
  462.  
  463.  The fields in VIOSCROLLUP are defined as follows:
  464.  
  465.  Field           Definition
  466.  
  467.  TopRow          Rop row of the area to scroll.
  468.  
  469.  LeftCol         Left-most column of the area to scroll.
  470.  
  471.  BotRow          Bottom row of the area to scroll.
  472.  
  473.  RightCol        Right-most column of the area to scroll.
  474.  
  475.  Lines           Number of blank lines to be inserted at the bottom
  476.                  of the screen area being scrolled. If zero is
  477.                  specified, no lines are scrolled.
  478.  
  479.  @Cell           Far address of the cell to be used as the fill
  480.                  character in the new blank lines.
  481.  
  482.  VioHandle       A reserved word of zeros.
  483.  
  484.  Row and column numbers are zero based.
  485.  
  486.  If TopRow and LeftCol are specified as 0, and BotRow, RightCol, and
  487.  Lines are all specified as -1, the entire screen will be filled with
  488.  the character defined by Cell.
  489.  
  490.  This sample program also uses the call VIOSETCURPOS to set the cursor
  491.  to the upper left-hand corner of the screen. This call is defined in
  492.  SUBCALLS.H as the following:
  493.  
  494.  extern unsigned far pascal VIOSETCURPOS (
  495.                     unsigned,
  496.                     unsigned,
  497.                     unsigned );
  498.  
  499.  Fields are defined as follows:
  500.  
  501.  Field           Definition
  502.  
  503.  Row             New cursor row position where 0 is top row.
  504.  
  505.  Col             New cursor column position where 0 is the left-most
  506.                  column.
  507.  
  508.  VioHandle       A reserved word of zeros.
  509.  
  510.  #include <doscalls.h>
  511.  #include <subcalls.h>
  512.  
  513.  main()
  514.      {
  515.  
  516.          char buffer[2];            /* Local buffer for cell value.          *
  517.  
  518.          buffer[0] = 0x20;          /* Cell to replicate is a blank (space)  *
  519.          buffer[1] = 0x07;          /* with normal attributes.               *
  520.  
  521.          VIOSCROLLUP( 0, 0, -1, -1, -1, (char far *)buffer, 0 );
  522.  
  523.                                     /* When the first 5 parameters are set   *
  524.                                     /* as above, the entire screen is        *
  525.                                     /* filled with the cell in buffer[].     *
  526.  
  527.          VIOSETCURPOS( 0, 0, 0 );
  528.                                     /* Call to set the cursor to the upper   *
  529.                                     /* left-hand corner of the screen, so    *
  530.                                     /* we duplicate all the functionality    *
  531.                                     /* of the DOS 3.xx "CLS" command.        *
  532.  
  533.          exit(0);
  534.  
  535.      }
  536.  
  537.  
  538.  10. Equivalent DOS 3.x and Microsoft OS/2 Function Calls
  539.  
  540.  Question:
  541.  
  542.  Which DOS Version 3.x file I/O calls map to which Microsoft OS/2 file
  543.  I/O calls?
  544.  
  545.  Response:
  546.  
  547.  Below is a list of DOS Version 3.x file-related function calls and
  548.  their Microsoft OS/2 equivalent function calls. The following list
  549.  does not represent a one to one correspondence, but rather a best
  550.  approximation:
  551.  
  552.  DOS 3.x Calls (Under Int 21H)           Microsoft OS/2 Calls
  553.  
  554.      Disk Control
  555.          0E (14)                         DOSSELECTDISK
  556.          19 (25)                         DOSQCURDISK
  557.          1C (28)                         DOSQFSINFO
  558.          2E (46)                         DOSSETVERIFY
  559.          36 (54)                         DOSQFSINFO
  560.          54 (84)                         DOSQVERIFY
  561.  
  562.      File Operations
  563.          23 (35)                         DOSQFILEINFO
  564.          3C (60)                         DOSOPEN
  565.          3D (61)                         DOSOPEN
  566.          3E (62)                         DOSCLOSE
  567.          41 (65)                         DOSDELETE
  568.          43 (67)                         DOSQFILEMODE, DOSSETFILEMODE
  569.          45 (69)                         DOSDUPHANDLE
  570.          4E (78)                         DOSFINDFIRST
  571.          4F (79)                         DOSFINDNEXT
  572.          56 (86)                         DOSMOVE
  573.          57 (87)                         DOSQFILEINFO, DOSSETFILEINFO
  574.          5B (91)                         DOSOPEN
  575.  
  576.      Record Operations
  577.          3F (63)                         DOSREAD
  578.          40 (64)                         DOSWRITE
  579.          42 (66)                         DOSCHGFILEPTR
  580.          5C (92)                         DOSFILELOCKS
  581.  
  582.      Directory Operations
  583.          39 (57)                         DOSMKDIR
  584.          3A (58)                         DOSRMDIR
  585.          3B (59)                         DOSCHDIR
  586.          47 (47)                         DOSQCURDISK
  587.  
  588.  
  589.  11. OS/2 SDK: Queue System
  590.  
  591.  Question:
  592.  
  593.  I'm interested in the multiple-in and multiple-out queue structure;
  594.  can the current queue structure do multiple out? Also, what about
  595.  priority queues? Is the queue system resident and used by OS/2, or is
  596.  the queue system only brought in when an application needs it?
  597.  
  598.  Response:
  599.  
  600.  The queue package is used by the shell but is a swappable/discardable
  601.  module; it doesn't have to be resident when it is not being executed.
  602.  Queues support multiple writers but only one reader. An application
  603.  developer can either structure the application using multiple queues
  604.  or construct his or her own queues using shared memory and semaphores.
  605.  
  606.  
  607.  12. OS/2 SDK: Dynamic Link Library Initialization Routine
  608.  
  609.  Question:
  610.  
  611.  I have a question regarding the dynamic link library (DLL)
  612.  initialization routine mentioned in Gordon Letwin's book "Inside
  613.  OS/2." Is this routine part of OS/2, or is it a user-defined or
  614.  application-defined routine that will be automatically called by OS/2
  615.  when the DLL is first loaded? The dynlink example that comes with the
  616.  OS/2 Software Development Kit (SDK) has a DYNINIT.ASM module whose
  617.  entry point is "initroutine," yet the main executable that calls the
  618.  DLL never calls "initroutine." Would you please elaborate on what an
  619.  "initroutine" is, or what it means in the context of DLLs and how you
  620.  can implement such a routine if this facility exists?
  621.  
  622.  Response:
  623.  
  624.  The init routine in a DLL is an optional routine that is executed when
  625.  the DLL is first accessed. Based on whether the init routine is
  626.  specified to be INITGLOBAL or INITINSTANCE, the init routine will
  627.  either be executed the first time that the DLL is accessed by any
  628.  process, or the first time that the DLL is accessed by each process.
  629.  The type can be specified in the DLL's .DEF file when it is linked.
  630.  
  631.  Adding an init routine can be done by declaring a far procedure in an
  632.  assembler module, using the END MASM directive to specify that it is
  633.  the entry point, and then linking it with your DLL. This is the same
  634.  way that an assembly program specifies the entry point for a regular
  635.  .EXE file. Note that a DLL typically does not have an entry point
  636.  defined (and does not need one). It can be thought of as simply a body
  637.  of code, brought into memory by the OS/2 loader, and with different
  638.  entry points within it called from OS/2 processes.
  639.  
  640.  If you are used to programming in C and not MASM, you might not be
  641.  used to the use of the END directive, but it is actually being done
  642.  for you by the C start-up code. Although it is necessary to define an
  643.  init routine for a DLL in assembler because the entry point must be
  644.  defined, what is typically done is that the assembler init routine
  645.  simply calls the real init routine, which can then be written in C, or
  646.  another high-level language. An example of this is shown in the
  647.  OS/2 Version 1.00 Programmer's Toolkit sample program "DYNLINK." At
  648.  the end of the module DYNINIT.ASM, you will see the following:
  649.  
  650.     END    START
  651.  
  652.  This defines the entry point to be the START procedure defined just
  653.  above it in the .ASM file.
  654.  
  655.  
  656.  13. Monitors
  657.  
  658.  Question:
  659.     I was wondering if monitors are intended to solve some
  660.  of the problems of putting existing memory resident
  661.  functions into OS/2. It seems similar to the progression of
  662.  DOS in general, in that the enhancements are very useful
  663.  in fixing many previous problems but perhaps not as good at
  664.  solving current or upcoming ones. The terminate-and-stay
  665.  resident function seems to be one such case. You could fool
  666.  DOS into doing this and even installing device
  667.  drivers after boot time, but this is not really allowed. I
  668.  think that the monitor approach, using specialized and
  669.  restricted modes, could cause you the same set of problems
  670.  in the future. It will still be possible to crash the
  671.  system or really mess things up if you aren't careful.
  672.  
  673.  Response:
  674.     Monitors are intended to provide a general means of
  675.  peeking and modifying the data stream in a character device
  676.  driver, primarily the keyboard. They are not intended to
  677.  provide "terminate and stay resident"--the ExecPgm system
  678.  call is what you use to do that. I think monitors nicely
  679.  solve the problem of multiple packages trying to manage the
  680.  device and hardware interrupts at too low a level in the
  681.  current DOS. They do not solve the problem of two
  682.  programs both needing to be the first to see the F1 key.
  683.  That is a problem I don't think the DOS can solve.
  684.  Application writers need to make their programs
  685.  configurable so end users can avoid conflicts for function
  686.  keys.
  687.     You are right that monitors are a means to mess up the
  688.  system somewhat. You could write a monitor application that
  689.  takes all keys in all screen groups, and does nothing with
  690.  them. I don't know of any way to solve this problem
  691.  without reducing the functionality. This problem is not
  692.  specific to our design of monitors.
  693.  
  694.  
  695.  14. Exit List Functions
  696.  
  697.  Problem:
  698.     The abort function list is set up for a list of
  699.  functions to be called with no arguments. I would like to
  700.  see each function associated with at least a far pointer,
  701.  if not an additional short and long integer. I assume that
  702.  removal of open files is done another way, but it could be
  703.  done with a common function and an entry in the list with a
  704.  file handle as a parameter. It is also a way that a process
  705.  list could be terminated as necessary. This function is
  706.  actually more generic and may be brought out like the file
  707.  name parsing was for the old FCBs.
  708.  
  709.  Response:
  710.     We agree your suggestion is more general--it is also
  711.  something that the application can simulate by storing the
  712.  required arguments in some data segment for use in the exit
  713.  lists. In general, a given package will only need one
  714.  exit list. The multiple exit list facility is intended for
  715.  the case where an application attaches to black box dynlink
  716.  libraries that need their own exit routines. But within a
  717.  given program or dynlink library, the recommended structure
  718.  is to have one exit handler that does several things,
  719.  rather than register a separate exit handler for every
  720.  piece of cleanup needed.
  721.  
  722.  
  723.  15. Least Recently Used (LRU) Algorithm
  724.  
  725.  Question:
  726.     How is the LRU (least recently used) algorithm used in
  727.  swapping segments?
  728.  
  729.  Response:
  730.     The kernel examines the LDT/GDT during each time slice,
  731.  at which time the access bit in each segment is examined.
  732.  The access bit indicates whether that segment has been
  733.  accessed during that particular time slice. If it has
  734.  been accessed, the segment is moved to the top of a queue
  735.  in the memory manager; then, the access bit is cleared.
  736.  Segments are discarded and swapped from the bottom of the
  737.  queue, and the result is an LRU scheme.
  738.  
  739.  
  740.  16. Systems Services and Dynamic Linking
  741.  
  742.  OS/2
  743.  ISVONLY |
  744.  
  745.  Question:
  746.     This question is really addressing how things can be
  747.  made into resources that can be made available to
  748.  applications other than the dynamic linking facility. This
  749.  would be more along the lines of the Windows DDE protocol.
  750.  For example, dynamic linking does not necessarily address
  751.  access to a resident process that may want its services to
  752.  be used by a number of applications where the resident
  753.  process needs to know who it is talking to. It may also
  754.  adjust its services based upon the requests being made upon
  755.  it. This implies a method of finding the resource and
  756.  communicating with it. The dynamic link feature may supply
  757.  all this in a fashion.
  758.  
  759.  Response:
  760.     There are really two issues here. One is how an
  761.  application can find out about available system services
  762.  from other processes. We don't have any specific function
  763.  for that in OS/2, although you could easily come up with
  764.  some convention based around shared memory. I think this is
  765.  more an issue for an environment manager such as Windows.
  766.     The second issue is how a dynamic link library knows who
  767.  it is talking to and tracks clients. Again, I think this is
  768.  more a convention for the library to specify than the OS/2.
  769.  It was not a goal of OS/2 to provide loads of high
  770.  level abstractions and conflict with Windows. OS/2 was
  771.  designed as a base for Windows-like packages. It does not
  772.  pretend to have all the high level services that Windows
  773.  has.
  774.  
  775.  
  776.  17. Running Windows in 3.x Box
  777.  
  778.  OS/2
  779.  ISVONLY |
  780.  
  781.  Problem:
  782.     I can't get Windows 1.x to run in real mode. It tries very hard to run, bu
  783.  it just can't make it.
  784.  
  785.  Response:
  786.     It won't work. Windows has a very close relationship with the internals
  787.  of the DOS 2/3 kernel, and relies on things that just aren't there in the OS/
  788.  real mode box. This applies only to the currently released version of Windows
  789.  
  790.  
  791.  18. Is the System Crash Proof?
  792.  
  793.  OS/2
  794.  ISVONLY |
  795.  
  796.  Question:
  797.     Is this a crash-proof operating system?
  798.  
  799.  Response:
  800.     No, it is not crash-proof until we get to the 386. On the 286, we have the
  801.  real mode box unprotected, and we have protected mode applications with I/O
  802.  privilege. The 386 lets us put the real mode box in virtual mode, and restric
  803.  the ports I/O priv applications can touch. Also, the FAT file system lacks
  804.  protection.
  805.     The system is a lot less likely to crash from a bad application, or two
  806.  applications colliding over something, but it is not 100 percent crash-proof.
  807.  
  808.  
  809.  19. Error in MORE Utility
  810.  
  811.  Problem:
  812.  
  813.  The MORE utility has a minor error when executed from an OS/2 ".CMD"
  814.  file: it displays a zero before the "<". (It still works correctly.)
  815.  
  816.  The following is an example (from a .BAT or .CMD file with echoing
  817.  on):
  818.  
  819.     MORE <AUTOEXEC.BAT   - is displayed when in DOS
  820.  
  821.     MORE  0<AUTOEXEC.BAT - is displayed when in OS/2
  822.  
  823.  Response:
  824.  
  825.  This behavior is a feature of CMD.EXE. CMD.EXE echoes the complete
  826.  redirection specifications when it parses the command string from a
  827.  batch file.
  828.  
  829.  
  830.  20. Redirecting INT 0 Using DosSetVec
  831.  
  832.  Question:
  833.     I have been trying to write an exception handler for OS/2
  834.  protect mode. The exception is trap 0, the "divide by 0"
  835.  condition. I use DosSetVec to point OS/2 to my handler. If I then
  836.  execute an actual divide by 0 operation, my handler gets called
  837.  correctly. But if I try to code an INT 0 to simulate the same
  838.  condition, I get a GP fault. What is wrong?
  839.  
  840.  Response:
  841.     By design, an INT 0 can only be issued from ring 0 code. An attempt
  842.  to issue it from user code will result in a GP fault. In general, OS/2
  843.  will not allow software interrupts in protect mode applications.
  844.  
  845.  
  846.  21. Interim Character Flag in KbdCharIn Call
  847.  
  848.  Question:
  849.     Function KbdCharIn mentions an interim flag without explaining its
  850.  meaning or purpose. I also have looked at the device driver manual,
  851.  Page 187. It also only mentions the term. Could you please explain the
  852.  purpose and meaning of the keyboard interim flag?
  853.  
  854.  Response:
  855.     The interim character flag is used mainly to support double byte
  856.  character sets where the current key's meaning depends on what key
  857.  follows it. The interim character flag is then set so that you will
  858.  know that the character has not been determined yet and you should
  859.  wait for the following key before determining what to do.
  860.  
  861.  
  862.  22. Memory Allocation Limits under OS/2
  863.  
  864.  Problem:
  865.  
  866.  While experimenting with virtual-memory management, we encountered
  867.  the following problem:
  868.  
  869.  A program using DOSALLOCSEG to allocate 1K segments only allocated
  870.  about 2000 nonsharable segments and then returned error# 8 (not
  871.  enough memory). We have 5 megabytes of memory in the machine and 20
  872.  megabytes free on the swap Drive C. The following is our CONFIG.SYS:
  873.  
  874.     protshell=shell cmd.exe
  875.     shell=a:\command.com
  876.     rmsize=640
  877.     buffers=32
  878.     memman=swap,move
  879.     swappath=c:\tmp
  880.  
  881.  Response:
  882.  
  883.  The problem is not with the amount of memory in the machine or free
  884.  space left on the swap drive. The limitation you have encountered is
  885.  the number of descriptors available in the local descriptor table for
  886.  nonsharable segments. Therefore, the way to allocate more nonsharable
  887.  memory for the task is to increase the segment size. The size of the
  888.  segment should be chosen to minimize the amount of swapping that may
  889.  occur.
  890.  
  891.  If the application deals with several small data objects, but only a
  892.  few at any given time, then small segments would reduce the amount of
  893.  memory and the amount of disk I/O when swapping occurs. In the case of
  894.  large data objects, segments at least the size of the data object will
  895.  probably work best. Also, note that segments are swapped in their
  896.  entirety; no partial swapping of segments is performed, and each
  897.  segment allocated is a small amount of additional overhead for the
  898.  system to manage.
  899.  
  900.  
  901.  23. Restoring Video Attributes
  902.  
  903.  Question:
  904.     Returning to a real mode program using EGA graphics
  905.  gives me a white screen. If the display can't be restored,
  906.  can you prohibit switching out?
  907.  
  908.  Response:
  909.     The reason we can't restore it is due to the write-only
  910.  registers. We can't prohibit switching out; there are
  911.  things such as pop-up screens for hard errors, and the
  912.  shell, which we cannot reasonably delay. There will be a
  913.  documented interface for real mode applications to notify
  914.  the operating system of mode changes. This does not,
  915.  however, help existing applications, except Chart and Word,
  916.  which already use this interface under DOS 2/3.
  917.  
  918.  
  919.  24. Dynamic Loading of Device Drivers
  920.  
  921.  Question:
  922.     Why isn't there dynamic loading and unloading of device
  923.  drivers, or at least the loading of them?
  924.  
  925.  Response:
  926.     One reason you can't dynamically load device drivers is
  927.  that the interrupt part of a device driver has to reside in
  928.  low memory so we can get at it if the interrupt happens to
  929.  occur while the CPU is in real mode (mode switching per
  930.  interrupt is too slow). Low memory is not dynamically
  931.  allocatable--there is not much of it, and it is probably
  932.  all assigned to the real mode box.
  933.  
  934.  
  935.  25. Mode Switching on an EGA under OS/2
  936.  
  937.  Question:
  938.  
  939.  Would you demonstrate how to switch EGA between 25- and 43-line modes?
  940.  
  941.  Response:
  942.  
  943.  SETEGA accepts one parameter, which must be either "25" or "43." Too
  944.  few or too many parameters, or a parameter other than the two
  945.  specified above, will result in an error message and termination with
  946.  no action taken.
  947.  
  948.  This program will work only on machines equipped with a standard EGA.
  949.  SETEGA functions as follows:
  950.  
  951.  1. Checks parameters
  952.  
  953.  2. Clears the screen using the VIOSCROLLUP function
  954.  
  955.  3. Gets current mode information using VIOGETMODE, as follows:
  956.  
  957.     extern unsigned far pascal VIOGETMODE (
  958.     struct ModeData far *,
  959.     unsigned );
  960.  
  961.  This call fills a data structure of the following type, whose address
  962.  we pass in the first parameter (the second parameter is the VIO
  963.  handle, a reserved word of zeros):
  964.  
  965.     struct ModeData {
  966.     unsigned length;
  967.     unsigned char type;
  968.     unsigned char color;
  969.     unsigned col;
  970.     unsigned row;
  971.     unsigned hres;
  972.     unsigned vres;
  973.     };
  974.  
  975.  We leave all these fields as they are except "row," the number of
  976.  alphanumeric rows for this mode. This is changed to the value
  977.  specified in our parameter.
  978.  
  979.  VIOSETMODE is now used to set the mode, as follows:
  980.  
  981.     extern unsigned far pascal VIOSETMODE (
  982.     struct ModeData far *,
  983.     unsigned );
  984.  
  985.  This call has the same parameters as VIOGETMODE. We are now set to the
  986.  desired mode. We then set the cursor to an appropriate size and shape.
  987.  This is done by filling in a structure of the following type:
  988.  
  989.     struct CursorData {
  990.     unsigned cur_start;
  991.     unsigned cur_end;
  992.     unsigned cur_width;
  993.     unsigned cur_attribute;
  994.     };
  995.  
  996.  Then VIOSETCURTYPE is called, where the second parameter is again the
  997.  VIO handle:
  998.  
  999.     extern unsigned far pascal VIOSETCURTYPE (
  1000.     struct CursorData far *,
  1001.     unsigned );
  1002.  
  1003.  Last, we set the cursor to the upper left-hand corner of the screen
  1004.  using VIOSETCURPOS. Compile using the -Lp option; the following
  1005.  program may be bound for use under real mode:
  1006.  
  1007.  #include <subcalls.h>
  1008.  #include <doscalls.h>
  1009.  #include <stdio.h>
  1010.  
  1011.  void usage();
  1012.  
  1013.  void main( argc, argv )
  1014.  int  argc;
  1015.  char *argv[];
  1016.  {
  1017.  
  1018.      struct  ModeData    modedata;
  1019.  
  1020.      struct  CursorData  cursordata;
  1021.  
  1022.      static char  buffer[2] = { 0x20, 0x07 };   /* scrolling fill character */
  1023.                                                 /* for clearing the screen  */
  1024.      if( argc != 2 )
  1025.          usage(argv[0]);
  1026.  
  1027.      switch(atoi(argv[1])) {
  1028.          case 43:
  1029.              VIOSCROLLUP( 0, 0, -1, -1, -1, (char far *)buffer, 0 );
  1030.              modedata.length = sizeof( modedata );
  1031.              VIOGETMODE( &modedata, 0 );
  1032.              modedata.row = 43;
  1033.              VIOSETMODE( &modedata, 0 );
  1034.              cursordata.cur_start = 7;
  1035.              cursordata.cur_end = 7;
  1036.              cursordata.cur_width = 1;
  1037.              cursordata.cur_attribute = 0;
  1038.              VIOSETCURTYPE( &cursordata, 0 );
  1039.              VIOSETCURPOS( 0, 0, 0 );
  1040.          break;
  1041.  
  1042.          case 25:
  1043.              VIOSCROLLUP( 0, 0, -1, -1, -1, (char far *)buffer, 0 );
  1044.              modedata.length = sizeof( modedata );
  1045.              VIOGETMODE( &modedata, 0 );
  1046.              modedata.row = 25;
  1047.              VIOSETMODE( &modedata, 0 );
  1048.              cursordata.cur_start = 12;
  1049.              cursordata.cur_end = 13;
  1050.              cursordata.cur_width = 1;
  1051.              cursordata.cur_attribute = 0;
  1052.              VIOSETCURTYPE( &cursordata, 0 );
  1053.              VIOSETCURPOS( 0, 0, 0 );
  1054.          break;
  1055.  
  1056.          default:
  1057.              usage(argv[0]);
  1058.          }
  1059.          exit(0);
  1060.  }
  1061.  
  1062.  void
  1063.  usage(p)
  1064.  char *p;
  1065.  {
  1066.      printf( "usage: %s 25|43\n", p);
  1067.      exit(1);
  1068.  }
  1069.  
  1070.  
  1071.  26. Thread Creation and Scheduling Demonstration
  1072.  
  1073.  Question:
  1074.  
  1075.  Would you give an OS/2 thread creation and scheduling demonstration?
  1076.  
  1077.  Response:
  1078.  
  1079.  THREADS.C creates 23 child threads and counts loops within each thread
  1080.  until you stop the program or until one of the threads has counted
  1081.  10,000 loops.
  1082.  
  1083.  The program below provides an example of creating threads under OS/2
  1084.  as well as demonstrating the "fairness" of the OS/2 scheduler.
  1085.  
  1086.  Each thread contains a DOSSLEEP() call in its counting loop. This will
  1087.  cause the thread to give up its time slice, so that at most one loop
  1088.  will be counted each time the thread is scheduled. Tests indicate that
  1089.  without DOSSLEEP(), the counting loop would be executed about 200 to
  1090.  300 times for each time the thread was scheduled. Thus it is safe to
  1091.  assume that each time a thread is scheduled, it is adding exactly one
  1092.  to its count. A sleep period of 0 is used, allowing each thread to be
  1093.  rescheduled immediately; increasing the value of SLEEPTIME tends to
  1094.  even out scheduling.
  1095.  
  1096.  Each child thread is passed an ID number when it is created. In this
  1097.  example, an arbitrary sequential index is used for convenience. We
  1098.  discard the threadID returned by OS/2 when the thread is created, as
  1099.  it is not needed in this program. The threadID could be saved and used
  1100.  for purposes such as changing the thread's priority or temporarily
  1101.  suspending its execution; because threadID numbers are issued
  1102.  sequentially, they could be used as an index into an array containing
  1103.  information about the threads.
  1104.  
  1105.  A global flag ("Ready") is used to block entry to the counting loops
  1106.  of the child threads until all threads have been created. This
  1107.  prevents the threads created first from getting a "head start."
  1108.  
  1109.  Note that VIO calls are used for all output except when aborting with
  1110.  an error condition. This avoids reentrancy problems, since the VIO
  1111.  calls are internally semaphored. The C run-time itoa() function is
  1112.  reentrant under Microsoft C Version 5.00.
  1113.  
  1114.  Compile THREADS.C with cl -G2 -Lp -Gs threads.c. -G2 enables the 80286
  1115.  instruction set. -Lp tells the linker to use protected-mode libraries.
  1116.  -Gs disables C stack checking; this switch must be used when compiling
  1117.  programs that create threads. The program is as follows:
  1118.  
  1119.   #include <malloc.h>
  1120.   #include <stdio.h>
  1121.   #include <dos.h>
  1122.   #include <doscalls.h>
  1123.   #include <subcalls.h>
  1124.  
  1125.   #define  STACKSIZE   128
  1126.  
  1127.   #define  THREADS     23
  1128.  
  1129.   #define  SLEEPTIME   0L
  1130.  
  1131.   #define  MAXCOUNT    10000
  1132.  
  1133.   unsigned short   ID;           /* global for passing ID number to threads */
  1134.  
  1135.   unsigned short   Ready = 0; /* global to signal threads to start counting */
  1136.  
  1137.   main()
  1138.   {
  1139.  
  1140.      void far   thread();                          /* child thread function */
  1141.  
  1142.      char far   *threadstack;           /* pointer to stack area for thread */
  1143.  
  1144.      unsigned short   threadID;    /* thread ID returned by DOSCREATETHREAD */
  1145.  
  1146.      unsigned short   rc;               /* return code from DOSCREATETHREAD */
  1147.  
  1148.      unsigned short   count = 0;            /* count of times loop executed */
  1149.  
  1150.      unsigned char    buffer[6];        /* general purpose character buffer */
  1151.  
  1152.      unsigned short   i;               /* general purpose indexing variable */
  1153.  
  1154.  Clear the screen and position cursor out of the way, as follows:
  1155.  
  1156.     buffer[0] = 0x20;                                     /* 0x20 = blank  */
  1157.     buffer[1] = 0x07;                                     /* 0x07 = normal */
  1158.     VIOSCROLLUP( 0, 0, -1, -1, -1, buffer, 0 );
  1159.     VIOSETCURPOS( 17, 0, 0 );
  1160.  
  1161.  Print banner and count header for main thread, as follows:
  1162.  
  1163.     VIOWRTCHARSTR( (char far *)"THREADS DEMO", 12, 1, 8, 0 );
  1164.     VIOWRTCHARSTR( (char far *)"Press Ctrl-C to stop", 20, 4, 8, 0 );
  1165.     VIOWRTCHARSTR( (char far *)"main()     ", 11, 0, 51, 0 );
  1166.  
  1167.  Start each of our threads. For each thread we do the following:
  1168.  
  1169.  1. Allocate space for a stack.
  1170.  
  1171.  2. Check to see if this allocation worked. If yes, continue. If no,
  1172.     print message and exit.
  1173.  
  1174.  3. Move the stack pointer to the top of the stack, since stacks grow
  1175.     down.
  1176.  
  1177.  4. Start the thread. The threadID that is returned is not used in this
  1178.     example.
  1179.  
  1180.  5. Check to see if thread create succeeded. If yes, continue. If no,
  1181.     print message and exit.
  1182.  
  1183.  6. Pass the new thread a sequential (arbitrary) ID number in global
  1184.     storage and block until the thread has picked it up, as signaled
  1185.     by the ID number being set back to 0.
  1186.  
  1187.      for( i = 1; i <= THREADS; i++ ) {
  1188.  
  1189.          threadstack = malloc(STACKSIZE);
  1190.  
  1191.          if( threadstack == 0 ) {
  1192.              printf( "Thread %d stack malloc error\n", i );
  1193.              DOSEXIT(1,1);
  1194.          }
  1195.  
  1196.          threadstack += STACKSIZE;
  1197.  
  1198.          rc = DOSCREATETHREAD( thread,
  1199.                                (unsigned far *)&threadID, threadstack );
  1200.  
  1201.          if( rc != 0 ) {
  1202.              printf( "create of thread %d failed, error: %d\n", i, rc );
  1203.              DOSEXIT(1,1);
  1204.          }
  1205.  
  1206.          ID = i;
  1207.          while( ID ) DOSSLEEP( 0L );    /* give up time slice while waiting */
  1208.  
  1209.      }
  1210.  
  1211.  When all of our threads have been started, signal them all to begin
  1212.  counting at the same time by setting the Ready flag as follows:
  1213.  
  1214.     Ready = 1;
  1215.  
  1216.  Enter counting loop; identical to the counting loop in each thread.
  1217.  Each time we are scheduled, we do the following:
  1218.  
  1219.  1. Increment our count.
  1220.  
  1221.  2. Check to see if count has reached 10,000. If yes, terminate all
  1222.     threads. If no, continue.
  1223.  
  1224.  3. Zero out our buffer.
  1225.  
  1226.  4. Use C run-time itoa() function to convert our count to an ASCII
  1227.     value.
  1228.  
  1229.  5. Print the count with VIOWRTCHARSTR().
  1230.  
  1231.  6. Give up our time slice.
  1232.  
  1233.      while( 1 ) {
  1234.  
  1235.          count++;
  1236.  
  1237.          if( count > MAXCOUNT )
  1238.              DOSEXIT( 1, 0 );
  1239.  
  1240.           for( i = 0; i < 6; buffer[i] = 0, i++ );
  1241.           itoa( count, buffer, 10 );
  1242.           VIOWRTCHARSTR( buffer, 5, 0, 63, 0 );
  1243.  
  1244.          DOSSLEEP( SLEEPTIME );
  1245.      }
  1246.  
  1247.   }
  1248.  
  1249.   /*** Child thread function ************************************************/
  1250.  
  1251.   void far thread()
  1252.   {
  1253.  
  1254.      unsigned short  threadnumber;          /* ID number passed from main() */
  1255.  
  1256.      unsigned short  count = 0;             /* count of times loop executed */
  1257.  
  1258.      unsigned char   buffer[6];         /* general purpose character buffer */
  1259.  
  1260.      unsigned short  i;                /* general purpose indexing variable */
  1261.  
  1262.  The child thread's first task upon waking up is to get its
  1263.  threadnumber. The ID is then set back to 0, signaling main() to start
  1264.  the next thread, as follows:
  1265.  
  1266.     threadnumber = ID;
  1267.     ID = 0;
  1268.  
  1269.  Next, print a count header for this thread, as follows:
  1270.  
  1271.     VIOWRTCHARSTR( (char far *)"thread  ", 8, threadnumber, 51, 0 );
  1272.     for( i = 0; i < 6; buffer[i] = 0, i++ );
  1273.     itoa( threadnumber, buffer, 10 );
  1274.     VIOWRTCHARSTR( buffer, 5, threadnumber, 59, 0 );
  1275.  
  1276.  Now we wait, giving up our time slice, until the Ready flag is set,
  1277.  as follows:
  1278.  
  1279.     while( !Ready ) DOSSLEEP( 0L );
  1280.  
  1281.  Enter counting loop; identical to counting loop in main(), as follows:
  1282.  
  1283.      while( 1 ) {
  1284.  
  1285.          count++;
  1286.  
  1287.          if( count > MAXCOUNT )
  1288.              DOSEXIT( 1, 0 );
  1289.  
  1290.          for( i = 0; i < 5; buffer[i] = 0, i++ );
  1291.          itoa( count, buffer, 10 );
  1292.          VIOWRTCHARSTR( buffer, 5, threadnumber, 63, 0 );
  1293.  
  1294.          DOSSLEEP( SLEEPTIME );
  1295.      }
  1296.  
  1297.   }
  1298.  
  1299.  
  1300.  27. Passing Pipes
  1301.  
  1302.  Question:
  1303.     Can pipes be passed to anyone besides local threads or child processes?
  1304.  
  1305.  Response:
  1306.     No. You need to be able to attach to the file handle. This limits it to th
  1307.  local process or any child process that can inherit a handle from the parent.
  1308.  
  1309.  
  1310.  28. Performance with Swapping Is Slow under OS/2
  1311.  
  1312.  Problem:
  1313.  
  1314.  I left BUFFERS=50 in CONFIG.SYS (as it was on the disks). The only
  1315.  problem I have had with OS/2's performance is when I halloced a
  1316.  3-megabyte huge pointer and read a 3-megabyte file into it. (I only
  1317.  have 1 megabyte of extended memory.) This didn't work at all until I
  1318.  put a SWAPPATH in CONFIG.SYS to point to a a second hard disk that had
  1319.  enough room for this data. My first hard disk did not have enough free
  1320.  space, and the program seemed to hang or run very slow.
  1321.  
  1322.  Response:
  1323.  
  1324.  Swapping isn't fast. It is important to set SWAPPATH to a drive that
  1325.  has enough free space to run your application. For example, booting
  1326.  from a floppy disk and not setting the SWAPPATH will default it to the
  1327.  floppy disk (the boot drive) which will be very slow and may quickly
  1328.  run out of disk space.
  1329.  
  1330.  
  1331.  29. Nine Open File Handles
  1332.  
  1333.  Question:
  1334.     I find nine open file handles on program entry. I know
  1335.  about the first five. What are the others?
  1336.  
  1337.  Response:
  1338.     There is no AUX in protected mode, so you actually
  1339.  probably only know about four. The others are used by
  1340.  various dynlink libraries you are attached to, probably by
  1341.  virtue of having stdin/stdout open. VIO, for example, uses
  1342.  at least one handle.
  1343.  
  1344.  
  1345.  30. Getting Device Driver's Buffer Size
  1346.  
  1347.  Question:
  1348.  
  1349.  How do I get a device driver's internal buffer size using DOSMONREG?
  1350.  
  1351.  Response:
  1352.  
  1353.  DOSMONREG requires that an input and output buffer be registered for
  1354.  each instance of a device monitor. These buffers are to be sized 20
  1355.  bytes larger than the device driver's internal buffer size.
  1356.  
  1357.  By making a call to DOSMONREG that fails, the second word of the input
  1358.  and output buffers will contain the device driver's buffer size, in
  1359.  bytes. The following program calls DOSMONREG with input and output
  1360.  buffer sizes specified to be zero. This call to DOSMONREG fails, and
  1361.  returns the device driver's buffer size in the second word of the
  1362.  input and output buffers. The example program then makes a second
  1363.  successful call to DOSMONREG, thus registering the input and output
  1364.  buffers.
  1365.  
  1366.  MONREG.C is an example of using DOSMONREG to get a device driver's
  1367.  buffer size.
  1368.  
  1369.  Compile using the following command:
  1370.  
  1371.     cl -c monreg.c
  1372.  
  1373.  Link using the following command:
  1374.  
  1375.     link4 monreg,monreg,,doscalls+slibc286;
  1376.  
  1377.  #include <doscalls.h>
  1378.  #include <stdio.h>
  1379.  #include <malloc.h>
  1380.  
  1381.  #define  FRONT       1      /* front of the monitor chain */
  1382.  #define  CUR_SG     -1      /* current screen group */
  1383.  
  1384.  #define  OVER       20      /* monitor overhead */
  1385.  
  1386.  typedef struct monitor_buffer {
  1387.      unsigned mon_buff_len;          /* monitor buffer length */
  1388.      unsigned dd_buff_len;           /* device driver length */
  1389.  } MonitorBuffer;
  1390.  
  1391.  void main()
  1392.  {
  1393.      /*
  1394.       *  allocate buffer space to make the first DOSMONREG call
  1395.       */
  1396.      MonitorBuffer  *in = (MonitorBuffer *)malloc(sizeof(MonitorBuffer));
  1397.      MonitorBuffer  *out = (MonitorBuffer *)malloc(sizeof(MonitorBuffer));
  1398.  
  1399.      unsigned int handle;         /* monitor handle */
  1400.      int result;                  /* return values from system calls */
  1401.      int size;                    /* device driver buffer size */
  1402.  
  1403.      /*
  1404.       *  open a keyboard monitor
  1405.       */
  1406.      result = DOSMONOPEN("KBD$",(unsigned far *)&handle);
  1407.  
  1408.     /*
  1409.      *  Set the monitor buffer size to zero so the DOSMONREG call will fail.
  1410.      */
  1411.      in->mon_buff_len = 0 ;
  1412.      out->mon_buff_len = 0 ;
  1413.  
  1414.      result = DOSMONREG(handle,                /* monitor handle */
  1415.                        (char far *) in,        /* address of input buffer */
  1416.                        (char far *) out,       /* address of output buffer */
  1417.                        (unsigned int) FRONT,   /* front of monitor list */
  1418.                        (unsigned int) CUR_SG); /* calling screen group */
  1419.  
  1420.      /*
  1421.       *  The device driver buffer size is returned in the second word
  1422.       *  of the input and output buffers.
  1423.       */
  1424.      size = in->dd_buff_len;  /* save the device driver buffer size */
  1425.  
  1426.      printf("DOSMONREG returns:\t\t%d\t(8 == not enough memory)\n", result);
  1427.      printf("Device driver buffer size:\t%d\t(bytes)\n", size);
  1428.  
  1429.      /*
  1430.       *  Allocate the minimum correct amount of buffer space for
  1431.       *  the input and output buffers.
  1432.       */
  1433.      in = (MonitorBuffer *)realloc(in, size + OVER);
  1434.      out = (MonitorBuffer *)realloc(out, size + OVER);
  1435.  
  1436.      in->mon_buff_len = size + OVER;
  1437.      out->mon_buff_len = size + OVER;
  1438.  
  1439.      result = DOSMONREG(handle,            /* monitor handle */
  1440.                        (char far *) in,    /* address of input buffer */
  1441.                        (char far *) out,   /* address of output buffer */
  1442.                        (unsigned int) 1,   /* front of monitor list */
  1443.                        (unsigned int) -1); /* calling screen group */
  1444.  
  1445.      printf("\nDOSMONREG returns:\t\t%d\t(0 == O.K.)\n", result);
  1446.  }
  1447.  
  1448.  
  1449.  31. Good FORMATS.TBL File on the Program Disk
  1450.  
  1451.  Question:
  1452.  
  1453.  Why is there a FORMATS.TBL file on both the Supplemental disk and the
  1454.  Program disk?
  1455.  
  1456.  Response:
  1457.  
  1458.  The FORMATS.TBL file on the Supplemental disk is bad and shouldn't be
  1459.  used. FORMATS.TBL on the Program disk is the correct one.
  1460.  
  1461.  
  1462.  32. KbdGetStatus() NUMLOCK Problem in VIO Window
  1463.  
  1464.  Microsoft has confirmed that KbdGetStatus() does not correctly report
  1465.  the shift status when run in a VIO window in the Version 1.06 OS/2 SDK
  1466.  (Software Development Kit). Examples of this problem are the status of
  1467.  the NUM LOCK, SCROLL LOCK, and CAPS LOCK lights.
  1468.  
  1469.  Microsoft is researching this problem and will post new information as
  1470.  it becomes available.
  1471.  
  1472.  
  1473.  
  1474.  33. Calculating the OS/2 Huge Shift Count
  1475.  
  1476.  This article describes how to calculate the OS/2 huge shift count.
  1477.  
  1478.  The OS/2 API DosGetHugeShift() will return the value that must be
  1479.  added to the first selector that is returned from DosAllocHuge(). By
  1480.  adding this value to the second and subsequent "huge" selectors
  1481.  returned by DosAllocHuge(), you can obtain addressability to them.
  1482.  
  1483.  For example, if DosGetHugeShift() returns a value of 8, and if the
  1484.  selector value returned by DosAllocHuge() is 120, then the second
  1485.  selector will be 128 (first_selector + huge_shift = 120 + 8 = 128).
  1486.  The third selector will be 136, the fourth will be 144, etc. The
  1487.  shift count is operating-system specific, and may change from one
  1488.  release of OS/2 to another. In addition, the shift count will be
  1489.  different when used in a bound application, which uses huge segments
  1490.  when it is run under MS-DOS.
  1491.  
  1492.  On Page 606 of Volume 1 of the "Microsoft Operating System/2
  1493.  Programmer's Reference" for Version 1.10, the following reference is
  1494.  made to two constants named DOSHUGEINC and DOSHUGESHIFT:
  1495.  
  1496.     If you write MS OS/2 programs in assembly language, the global
  1497.     symbols DOSHUGESHIFT and DOSHUGEINC are available for computing
  1498.     huge memory addresses. DOSHUGESHIFT is equal to the shift count
  1499.     retrieved by DosGetHugeShift, and DOSHUGEINCR is equal to the
  1500.     selector offset.
  1501.  
  1502.  These two values are contained in OS2.LIB and DOSCALLS.LIB. The
  1503.  problem is that by either explicitly linking or dynamically linking
  1504.  via DosGetProcAddr(), once you obtain the far pointers to these two
  1505.  values, the application doesn't have a valid selector to those values.
  1506.  This causes general protection faults when you attempt to obtain the
  1507.  values of these symbols.
  1508.  
  1509.  In addition to the DosGetHugeShift() API, there is another way to
  1510.  obtain this information. The DosGetInfoSeg() API can be used to obtain
  1511.  this current huge shift count, since it is stored in the cHugeShift
  1512.  field of the GINFOSEG (global information segment) structure. However,
  1513.  please note that DosGetHugeShift() is a family API function, whereas
  1514.  DosGetInfoSeg() is a protected-mode only API, so that if you are
  1515.  writing a family API that requires the huge shift count, you should
  1516.  use DosGetHugeShift() rather than DosGetInfoSeg().
  1517.  
  1518.  Most applications don't need to obtain this low-level information and
  1519.  can instead leave this work to the high-level-language compiler that
  1520.  the application is being developed with.
  1521.  
  1522.  When using the Microsoft C Compiler Version 5.10 or later, if you use
  1523.  the "huge" keyword (or default to the huge memory model with /AH), the
  1524.  huge segment calculations are added to your code in a way that is
  1525.  transparent to the application programmer. If the "huge" keyword is
  1526.  not used, you need to explicitly get the huge shift value and
  1527.  calculate all the other selector values for all but the first
  1528.  selector, which is done for you by DosAllocHuge(). Please refer to the
  1529.  Microsoft C Compiler documentation for more details.
  1530.  
  1531.  Related to this article is the sample application HUGE.C. This example
  1532.  will use the C huge keyword if you #define the macro
  1533.  C_HUGE_KEYWORD_ENABLED. If the macro is not #defined, it will manually
  1534.  calculate the huge jumps. The files included are as follows:
  1535.  
  1536.     Binary version - HUGE.EXE
  1537.     C source file  - HUGE.C
  1538.     Make file      - MAKEFILE
  1539.  
  1540.  The file HUGE can be found in the Software/Data Library by searching
  1541.  for the keyword HUGE, the Q number of this article, or S12405. HUGE
  1542.  was archived using the PKware file-compression utility.
  1543.  
  1544.  
  1545.  34. OS/2 SDK: Device Driver for IBM Mouse on the PS/2
  1546.  
  1547.  Question:
  1548.  
  1549.  Where can I obtain a functional mouse driver for the IBM PS/2 Model
  1550.  80?
  1551.  
  1552.  Response:
  1553.  
  1554.  Support for a mouse in the mouse port of the IBM PS/2 was added in the
  1555.  OS/2 Software Development Kit (SDK) Version 1.06. In all previous
  1556.  versions of the OS/2 SDK, the only mouse you could use on an IBM PS/2
  1557.  with OS/2 was a Microsoft (or compatible) Mouse in the serial port.
  1558.  
  1559.  
  1560.  35. Garbage Is Printed when Initializing Non-IBM Printer
  1561.  
  1562.  Problem:
  1563.     When I initialize the printer using DosDevIOCTL category 5,
  1564.  function 0x46, and have the spooler installed, garbage is printed on
  1565.  my non-IBM printer.
  1566.     I discovered that my problem occurs because after I open a parallel
  1567.  port, I call DosDevIOCTL to initialize the printer (category 5,
  1568.  function 0x46). It appears that when a port is not spooled, this call
  1569.  has no effect; when the port is spooled, 40 bytes of initialization
  1570.  data are put into the spool file (and then sent to the
  1571.  printer)--presumably by spool. The data are escape sequences
  1572.  appropriate to the IBM Graphics printer, and do things such as set the
  1573.  form length, character pitch, etc.
  1574.  
  1575.  Response:
  1576.     It is not necessary for you to call that IOCTL (5,0x46) to
  1577.  initialize the printer. You can initialize the printer on your own in
  1578.  any way that you wish and it should not cause problems.
  1579.     Microsoft is researching this problem and will post new information
  1580.  when available.
  1581.  
  1582.  
  1583.  36. Machines OS/2 Runs On
  1584.  
  1585.  Currently, Microsoft's Operating System/2 Software Development Kit
  1586.  (SDK) kernel will run on the following personal computers:
  1587.  
  1588.     IBM PC-AT
  1589.     Compaq Deskpro 286
  1590.     Compaq Deskpro 386
  1591.     Compaq Portable III
  1592.     Compaq Portable 286
  1593.     Zenith Z-241 (ROM Version 1.9 or later)
  1594.     Zenith Z-248 (ROM Version 1.9 or later)
  1595.     Zenith Z-386
  1596.  
  1597.  Note: Many of the OS/2 SDK Development Tools will also run under
  1598.  MS-DOS Versions 3.x.
  1599.  
  1600.  
  1601.  37. KbdCharIn(NoWait) Blocks Even if Not the Foreground Process
  1602.  
  1603.  Question:
  1604.  
  1605.  If a program is sitting in a while(1) loop polling keyboard and mouse
  1606.  with the following
  1607.  
  1608.     KBDCHARIN(NO_WAIT)
  1609.     MOUREADEVENTQUE(NO_WAIT);
  1610.  
  1611.  and is switched out of the foreground session, is it still getting
  1612.  time-slices, or is it blocked until it gets back the keyboard-mouse
  1613.  focus?
  1614.  
  1615.  Response:
  1616.  
  1617.  The process still gets CPU time when it is doing KbdCharin or
  1618.  MouReadEventQueue calls, even though it is not the foreground process.
  1619.  
  1620.  
  1621.  38. DIAL Will Not Run in the Compatibility Box
  1622.  
  1623.  Problem:
  1624.     DIAL works correctly on my system in PC-DOS Version 3.10, but hangs
  1625.  on entry when I run it in the compatibility box.
  1626.     The problem occurs before the first screen comes up, so it probably
  1627.  has nothing to do with the modem.
  1628.  
  1629.  Response:
  1630.     If you have installed the COM01.SYS driver, run SETCOM40 with an
  1631.  argument of COMx=ON, where x represents which com port to set.
  1632.     If you have not installed the driver, this process will not be
  1633.  necessary.
  1634.  
  1635.  
  1636.  39. Interrupt 24H Issued in Compatibility Mode
  1637.  
  1638.  Question:
  1639.  
  1640.  Will Interrupt 24H (Critical Error Handler Address) ever be issued by
  1641.  OS/2 in compatibility mode?  Also, can protected mode applications
  1642.  trap hard errors?
  1643.  
  1644.  Response:
  1645.  
  1646.  Yes, OS/2 will issue Interrupt 24Hs when appropriate in the
  1647.  compatibility mode. In answer to your second question, there is only
  1648.  one hard error daemon, which handles errors for all processes in the
  1649.  system and is not replaceable. There is no way to substitute your own
  1650.  error handler, as was possible under MS-DOS Versions 3.x.
  1651.  
  1652.  You can use the DosError() call to allow your process to receive
  1653.  hard-error notification without generating a hard error signal. In
  1654.  this case, all hard errors generated by OS/2 system calls under your
  1655.  process will be FAILed and the appropriate error code returned. Note
  1656.  that DosError() works on a per-process basis; suspending system
  1657.  handling of hard errors for your process will not affect error
  1658.  handling for other processes.
  1659.  
  1660.  However, even if you use DosError() to turn hard errors into error
  1661.  codes, there is still a class of error that you will not see: fatal
  1662.  errors not associated with a system call, such as memory faults. This
  1663.  class of error will still cause a hard error pop-up and the only
  1664.  "option" is to terminate the program. There is no way to return an
  1665.  error code to the application because there is no system call
  1666.  associated with a typical memory fault.
  1667.  
  1668.  
  1669.  40. DevHelp_MonWrite Call Returns Before Monitor Chain Completes
  1670.  
  1671.  Question:
  1672.  
  1673.  Why does the DevHelp_MonWrite call return before the monitor chain
  1674.  completes, even when the wait flag is set?
  1675.  
  1676.  Response:
  1677.  
  1678.  The DevHelp_MonWrite call returns as soon as the data is placed in the
  1679.  first buffer of the monitor chain. To be able to access the data after
  1680.  it goes through the monitor chain, the device driver thread must block
  1681.  itself until it is restarted in the notify routine.
  1682.  
  1683.  If the device driver chain happens to be empty when DevHelp_MonWrite
  1684.  is called, then when the call returns the notify routine will already
  1685.  have been called, and if you block waiting for it to return you will
  1686.  not get restarted. To avoid this problem you need to check the status
  1687.  of the request packet before DevHelp_Block is called.
  1688.  
  1689.  To block the process after calling DevHelp_MonWrite, use the
  1690.  DevHelp_Block call. When this call returns, you need to check whether
  1691.  the device driver was restarted by a spurious DevHelp_Run or an
  1692.  interrupt. This can be done by setting the status of the request
  1693.  packet to a constant in the notify routine and by checking the status
  1694.  after the device driver is restarted. If the status is not correct,
  1695.  the driver should stay blocked until it is restarted with the proper
  1696.  status.
  1697.  
  1698.  To restart the device driver at the end of the notify routine, you
  1699.  need to set the status word to some constant and then call
  1700.  DevHelp_Run.
  1701.  
  1702.  
  1703.  41. OS/2 SDK: New EXE File Header ne_flags Information
  1704.  
  1705.  Question:
  1706.  
  1707.  What are the characteristics of an EXE module? In theory, I can look
  1708.  at the structure "new_exe" (the new EXE header) and examine the field
  1709.  "ne_flags". The following bits should be defined:
  1710.  
  1711.  #define NENOTWINCOMPAT 0x0100 /* Not compatible with PM windowing */
  1712.  #define NEWINCOMPAT    0x0200 /* Compatible with PM windowing     */
  1713.  #define NEWINAPI       0x0300 /* Uses PM windowing API            */
  1714.  
  1715.  This information seems to be inconsistent. In the programs that I
  1716.  generate, the field is never set. Why is this happening?
  1717.  
  1718.  Response:
  1719.  
  1720.  By default, this field is not set. The current version of OS/2 will
  1721.  start these types of executables up in a full screen group, treating
  1722.  them like full-screen-only applications. There are a couple of
  1723.  different methods you can use to set this field. You can either use
  1724.  the MARKEXE utility to set this field after the program has been
  1725.  linked, or you can specify to the linker explicitly what type of
  1726.  program it is. This is done by using a .DEF file. The first line in
  1727.  the .DEF file should be the following:
  1728.  
  1729.     NAME   myapp   WINDOWCOMPAT
  1730.  
  1731.  "NAME" is a .DEF file keyword for naming the module; "myapp" is the
  1732.  module name, usually the base part of the executable's filename; and
  1733.  "WINDOWCOMPAT" means that the program can be compatibly run in a VIO
  1734.  window. Other values for this field are "WINDOWAPI" and
  1735.  "NOTWINDOWCOMPAT".
  1736.  
  1737.  
  1738.  42. OS/2 Will Not Boot with a Paradise VGA Card Installed
  1739.  
  1740.  Problem:
  1741.  
  1742.  I am trying to bring up Version 1.05 of the OS/2 SDK on my computer,
  1743.  which has a Paradise VGA graphics card installed in it. While the
  1744.  system is booting, I receive the following error message:
  1745.  
  1746.  Trap 0D
  1747.  
  1748.  AX=AA55 BX=0000 CX=0000 DX=0003 BP=0C42
  1749.  SI=6800 DI=0040 DS=0107 ES=0537 FLG=2246
  1750.  CS=0417 IP=4361 SS=0067 SP=0C14 MSW=FFFB
  1751.  CSLIM=4400 SSLIM=001F DSLIM=FFFF ESLIM=01BF
  1752.  CSACC=  FB SSACC=  F3 DSACC=  FB ESACC=F3
  1753.  ERRCD=0000 ERLIM=**** ERACC=  **
  1754.  
  1755.  Response:
  1756.  
  1757.  The above problem is known to occur with a particular Paradise VGA
  1758.  graphics card or an Everex EV-659A EGA card. The Install disk
  1759.  generates a trap 0D error, and the CS value returned after the trap 0D
  1760.  error typically equals 0417. There is an updated version of
  1761.  BVSCALLS.DLL that corrects this problem. You can download the
  1762.  corrected version of BVSCALLS.DLL from the Software Library. This file
  1763.  can be found in the Software Library by searching on the filename
  1764.  BVSCALLS.ARC, the Q number of this article, or S12065.
  1765.  
  1766.  You will need to use the PKXARC utility to unarc the file
  1767.  BVSCALLS.ARC. BVSCALLS.ARC contains BVSCALLS.DLL and a README file.
  1768.  Please read the README file for further instructions on how to install
  1769.  the revised BVSCALLS.DLL file.
  1770.  
  1771.  
  1772.  43. VERIFY.ARC: Use of DosSetVerify() and DosQVerify()
  1773.  
  1774.  When an application calls the OS/2 API DosSetVerify(), the verify
  1775.  setting specified is good only for the context of the current process.
  1776.  However, it does take effect for any child processes you create using
  1777.  DosExecPgm(). This is different than the OS/2 VERIFY command, which
  1778.  sets the verify status for the entire screen group.
  1779.  
  1780.  A file named VERIFY.ARC in the Software Library demonstrates how to
  1781.  use the OS/2 APIs DosQVerify() and DosSetVerify(). VERIFY.ARC contains
  1782.  PVERIFY.C, which is a mini-version of the OS/2 VERIFY command that
  1783.  works in the context of the current process. With this sample program,
  1784.  you can use "PVERIFY ON to turn on verify, and "PVERIFY OFF" to turn
  1785.  off verify, or just "PVERIFY" to display the verify status.
  1786.  
  1787.  If the source code is modified and "CHILD_PROCESS_TEST" is #defined,
  1788.  a child program (invoking CMD.EXE and its internal VERIFY command with
  1789.  no parameters) will be executed to display the status of verify within
  1790.  the child process. Thus, when the code inside the areas delimited by
  1791.  "CHILD_PROCESS_TEST" is enabled, PVERIFY will show scope of the verify
  1792.  state in a child process.
  1793.  
  1794.  VERIFY.ARC can be found in the Software Library by searching for the
  1795.  filename VERIFY.ARC, the Q number of this article, or S12207.
  1796.  VERIFY.ARC has been archived with the PKARC utility. You will need to
  1797.  unarchive it with PKXARC. A copy of PKXARC can be found on the
  1798.  Microsoft OnLine Utilities Disk 2.
  1799.  
  1800.  
  1801.  
  1802.  44. Killing Detached Processes
  1803.  
  1804.  Question:
  1805.  
  1806.  How can I kill a detached process from the command line?
  1807.  
  1808.  Response:
  1809.  
  1810.  DosKillProcess() will send a kill signal to any process. The process
  1811.  will be killed if it does not have a kill signal handler. If the
  1812.  process has registered a kill signal handler, that code will be
  1813.  executed. To use DosKillProcess(), you must know the PID of the process
  1814.  you wish to kill.
  1815.  
  1816.  A sample program that demonstrates a method of killing processes from
  1817.  the command line is located in the Software Library. This file can be
  1818.  found by searching on the filename, KILLPROC.ARC, the Q number of this
  1819.  article, or S12205.
  1820.  
  1821.  You will need to use the PKXARC utility to unarc the file
  1822.  KILLPROC.ARC. KILLPROC.ARC contains KILL.C. KILL.C demonstrates the
  1823.  use of DosKillProcess() to kill a process that was reference by its PID.
  1824.  
  1825.  
  1826.  
  1827.  45. Drawing over Mouse Pointer
  1828.  
  1829.  Question:
  1830.  
  1831.  There are some problems when I run the following:
  1832.  
  1833.     chaser 43 s
  1834.  
  1835.  Sometimes I kill a ship, but it stays on the screen.
  1836.  
  1837.  Response:
  1838.  
  1839.  You can get phantoms in any mode. This is an example of a race
  1840.  condition between separate processes. To correct this problem, the
  1841.  program should hide the mouse pointer and draw its own, under
  1842.  controlled circumstances. Since this is a demo program only, we will
  1843.  leave it for students of OS/2 to correct.
  1844.  
  1845.  The problem is that the mouse pointer device driver doesn't "know"
  1846.  about changes to the screen (in particular, under the pointer) that
  1847.  occur after the pointer has been drawn. When the mouse pointer is
  1848.  moved to a new position, whatever used to be in the old position
  1849.  before the mouse was moved there is restored. If the pointer is moved
  1850.  to cover a "ship," and the ship then moves away, when the mouse is
  1851.  again moved, the image of the ship will be restored, leaving a phantom.
  1852.  
  1853.  Semaphores are used to control access to the global data and screen
  1854.  updates for the attackers and mouse threads. However, the mouse
  1855.  pointer is controlled directly by the mouse device driver. Hence it is
  1856.  asynchronous to the attackers, and may indeed write the pointer over
  1857.  the attacker sometime between when the last mouse event was registered
  1858.  and just prior to the attacker thread moving the character.
  1859.  
  1860.  To really exaggerate the problem, put a DOSSLEEP of 10 to 50
  1861.  milliseconds in the loop that is waiting for a mouse event. Now try
  1862.  NOT to get phantoms!
  1863.  
  1864.  The demo programs in the SDK are meant to illustrate various OS/2
  1865.  features, and to provide some example code to hack on. They are not
  1866.  necessarily complete, correct programs--we are interested in problems
  1867.  when they relate to an informative topic, but in general it will be up
  1868.  to you to provide any necessary corrections. See the header at the
  1869.  start of the game program for some "enhancements" suggested by the
  1870.  author.
  1871.  
  1872.  
  1873.  46. DISKCACHE Option of CONFIG.SYS Unreliable with OS/2 SDK 1.02
  1874.  
  1875.  Question:
  1876.  
  1877.  Should I use the DISKCACHE option of CONFIG.SYS with the OS/2 SDK
  1878.  (Software Development Kit) Version 1.02?
  1879.  
  1880.  Response:
  1881.  
  1882.  The disk caching in the Version 1.06 OS/2 SDK is not 100 percent
  1883.  reliable and may corrupt files on your hard disk. This problem has
  1884.  been corrected in subsequent versions of the OS/2 SDK.
  1885.  
  1886.  
  1887.  47. OS/2 SDK: Using SIGINTR and SIGBREAK
  1888.  
  1889.  Question:
  1890.  
  1891.  How are the SIGINTR and SIGBREAK signals handled?
  1892.  
  1893.  Response:
  1894.  
  1895.  The SIGINTR and SIGBREAK signals are handled differently than other
  1896.  signals. Also, in the COOKED mode, CTRL+C is converted into a SIGINTR
  1897.  before being passed to the parent process of the current screen group.
  1898.  
  1899.  SIGINTR and SIGBREAK use what is called the FOCUS mechanism.
  1900.  Basically, what that amounts to is that the LAST process to do a
  1901.  DOSSETSIGHANDLER() receives the signal (in the current screen group,
  1902.  of course). It is up to that process to determine what to do with the
  1903.  signal. Under normal conditions, the SIGINT is caught by the CMD.EXE
  1904.  process. CMD then issues a DOSKILL() on any child processes.
  1905.  
  1906.  All other signals are applied to the indicated process and/or its tree
  1907.  of children. The USER flags (SIGFLA,B,C) have null default action.
  1908.  SIGTERM, of course, kills the process.
  1909.  
  1910.  Most simple applications will die if they get an interrupt. Some
  1911.  different scenarios for catching signals include daemons wanting to
  1912.  catch and deal with ALL signals that can cause termination. More
  1913.  complex foreground applications (editor, DOS shell, games) may want to
  1914.  catch certain flags only to abort the current command. Processes that
  1915.  have complex cleanup requirements (database engines) may want to
  1916.  catch ALL signals so that they can terminate gracefully.
  1917.  
  1918.  
  1919.  48. Detecting Metakeys with KbdCharIn
  1920.  
  1921.  Question:
  1922.  
  1923.  How can I use KbdCharIn to detect special keys (such as SHIFT, ALT,
  1924.  CTRL, etc.)?
  1925.  
  1926.  Response:
  1927.  
  1928.  To get the status of the SHIFT, ALT, CTRL, etc. keys, you need to set
  1929.  bit 8 in the mask field of the KbdSetStatus Call as well as bit 2 to
  1930.  turn on raw mode. Then use the KbdCharIn call to get the status of the
  1931.  shift-state keys.
  1932.  
  1933.  The following is a sample program to demonstrate setting the status
  1934.  and then detecting shift-state keys:
  1935.  
  1936.  Compile this program using cl -Lp filename.c.
  1937.  
  1938.  #include <subcalls.h>
  1939.  #include <doscalls.h>
  1940.  #include <dos.h>
  1941.  #include <stdio.h>
  1942.  
  1943.  #define NOWAIT 1
  1944.  #define WAIT 0
  1945.  #define HANDLE 0   /* for KBD */
  1946.  
  1947.  main()
  1948.  {
  1949.      struct KeyData CharData;
  1950.      struct KbdStatus kstat;
  1951.      int result;
  1952.  
  1953.      kstat.length = 10;
  1954.      KBDGETSTATUS((struct KbdStatus far *)&kstat, 0);
  1955.      kstat.bit_mask &= ~8;       /* turn off ascii mode */
  1956.      kstat.bit_mask |= 0x104;    /* turn on shift reporting and raw mode */
  1957.      KBDSETSTATUS((struct KbdStatus far *)&kstat, 0);
  1958.  
  1959.    do {
  1960.      CharData.char_code=0;
  1961.      CharData.status=0;
  1962.      CharData.scan_code=0;
  1963.      CharData.shift_state=0;
  1964.      result= KBDCHARIN( (struct KeyData far *) &CharData,
  1965.                 (unsigned) WAIT, (unsigned) HANDLE);
  1966.  
  1967.     if (CharData.shift_state ||
  1968.         CharData.scan_code ||
  1969.         CharData.status ||
  1970.         CharData.char_code) {
  1971.             if(result) {
  1972.                 printf("Result = %d ",result);
  1973.             } else {
  1974.                 printf("Char Code=%x ",CharData.char_code);
  1975.                 printf("Scan Code=%x ",CharData.scan_code);
  1976.                 printf("NLS Status=%x ",CharData.status);
  1977.                 printf("NLS Shift Status=%x ",CharData.nls_shift);
  1978.                 printf("Shift state=%x\n",CharData.shift_state);
  1979.             }
  1980.     }
  1981.   } while(CharData.char_code != 'q');
  1982.  }
  1983.  
  1984.  
  1985.  49. OS/2 Kernel on IBM AT Supports Multiple Displays; PM Does Not
  1986.  
  1987.  Question:
  1988.  
  1989.  Is it possible to have multiple displays in OS/2? If so, how?
  1990.  
  1991.  Response:
  1992.  
  1993.  The OS/2 kernel on an IBM AT supports the same multiple-display
  1994.  configurations as MS-DOS Versions 3.x (i.e., EGA and Monochrome, CGA
  1995.  and Monochrome, etc.). The display that receives VIO output depends on
  1996.  the current mode, so VioSetMode() effectively controls display
  1997.  switching.
  1998.  
  1999.  The Presentation Manager (PM) does NOT support multiple displays.
  2000.  
  2001.  
  2002.  50. Hiding the Mouse Cursor in Protected Mode
  2003.  
  2004.  Question:
  2005.     How do I hide the mouse pointer when in protected mode? There is no
  2006.  direct equivalent to the old INT 33 function 2 Hide Cursor call.
  2007.  
  2008.  Response:
  2009.     The following is an example of how to hide the mouse cursor in
  2010.  protected mode:
  2011.  
  2012.     1. This example uses the concept of "collision areas" to hide the
  2013.  mouse cursor. A collision area is a section of the screen in which the
  2014.  device driver will not draw the mouse pointer image. It still is
  2015.  possible to move the mouse cursor into a collision area, but the
  2016.  cursor will be invisible while it is there, i.e., the pointer will not
  2017.  be drawn.
  2018.     You can hide the mouse cursor by specifying the entire screen as
  2019.  the collision area, and then indicating the position of the mouse by
  2020.  drawing your own cursor character.
  2021.     The OS/2 system call used to set a collision area is MOUREMOVEPTR.
  2022.  Declarations and data structures for this call are in SUBCALLS.H.
  2023.     Use MOUDRAWPTR to cancel the collision area, or make a second call
  2024.  to MOUREMOVEPTR to set a new collision area. Each new call to
  2025.  MOUREMOVEPTR will reset the boundaries of the collision area.
  2026.     Only one collision area (the one most recently set) is active at
  2027.  any time. MOUDRAWPTR cancels the MOUREMOVEPTR call, allowing the mouse
  2028.  pointer to be drawn anywhere on the screen.
  2029.     The documentation for MOUREMOVEPTR in the SDK is unclear as to the
  2030.  meanings of the parameters being passed. Following are the listed
  2031.  parameters:
  2032.  
  2033.     a. Row coordinates
  2034.     b. Coordinates
  2035.     c. Row height
  2036.     d. Column width
  2037.  
  2038.     A better description might be as follows:
  2039.  
  2040.     a. Upper-left row
  2041.     b. Upper-left column
  2042.     c. Lower-right row
  2043.     d. Lower-right column
  2044.  
  2045.     Notice that you must subtract 1 from the screen width and height
  2046.  supplied by VIOGETMODE. The coordinates for VIOGETMODE are 1-based,
  2047.  while the coordinates for MOUREMOVEPTR are 0-based. Specifying
  2048.  coordinates outside the range of the screen will cause the call to
  2049.  fail and no collision area will be set.
  2050.     This program should be built with the following command:
  2051.  
  2052.     cl -Ox -G2 -Lp -Zp mouse.c
  2053.  
  2054.     2. Press the left mouse button to end the demonstration.
  2055.  
  2056.   #include <stdio.h>
  2057.   #include <doscalls.h>
  2058.   #include <subcalls.h>
  2059.  
  2060.   main()
  2061.   {
  2062.    unsigned short  MouseRow,             (where it is at)
  2063.                    MouseCol;
  2064.    unsigned short  ScreenHeight,         (screen attributes)
  2065.                    ScreenWidth;
  2066.    unsigned short  Mouse;                (storage for mouse handle)
  2067.    unsigned short  ReadType = 0;         (0 => wait for an event)
  2068.    unsigned char   MouseCursor[2],       (our palette)
  2069.                    Background[2];
  2070.    struct  CursorData      NewCur;       (struct to get/set cursor type)
  2071.    struct  CursorData      OldCur;
  2072.    struct  EventInfo       MouInfo;      (struct to get mouse event info)
  2073.    struct  PtrLoc          InitMouPos;   (struct to set mouse ptr location)
  2074.    struct  ModeData        ModeInfo;     (struct to get/set video mode)
  2075.    struct  NoPointer       Collision;    (struct to set collision area)
  2076.  
  2077.    3. Initialize as follows:
  2078.  
  2079.    MouseCursor[0] = 0x09;                         (to initialize the cells we)
  2080.    MouseCursor[1] = 0x2F;                          (will be using to draw)
  2081.                                                  (our own mouse cursor and)
  2082.    Background[0] = 0x20;                     (fill in the background color)
  2083.    Background[1] = 0x27;                   (- these attributes are for EGA)
  2084.                                                              (clear screen)
  2085.    VIOSCROLLUP( 0, 0, -1, -1, -1, (char far *)Background, 0 );
  2086.    VIOGETCURTYPE( &OldCur, 0 );              (save info on old cursor type)
  2087.    NewCur.cur_start = 0;
  2088.    NewCur.cur_end = 0;                           (set cursor attributes to)
  2089.    NewCur.cur_width = 1;                         (what we want - invisible)
  2090.    NewCur.cur_attribute = -1;
  2091.    VIOSETCURTYPE( &NewCur, 0 );                         (reset cursor type)
  2092.  
  2093.    ModeInfo.length = sizeof( ModeInfo );                  (get screen mode)
  2094.    VIOGETMODE( ( struct ModeData far * )&ModeInfo, 0);      (so we can set)
  2095.    ScreenHeight = ModeInfo.row;                          (screen size info)
  2096.    ScreenWidth = ModeInfo.col;
  2097.  
  2098.     4. Open the mouse pointer device and set its location, as follows:
  2099.  
  2100.    MOUOPEN( 0L, ( unsigned far * )&Mouse );      (0 => default mouse image)
  2101.    if( ScreenHeight == 25 )                       (put it where we want it)
  2102.        InitMouPos.RowPos = 12;
  2103.    else
  2104.        InitMouPos.RowPos = 21;
  2105.    InitMouPos.ColPos = 40;
  2106.    MOUSETPTRPOS( ( struct PtrLoc far * )&InitMouPos, Mouse );
  2107.  
  2108.     5. Hide the mouse cursor by setting a collision area consisting of
  2109.  the entire screen, as follows:
  2110.  
  2111.    Collision.Row = 0;
  2112.    Collision.Col = 0;
  2113.    Collision.Height = ScreenHeight - 1;
  2114.    Collision.Width = ScreenWidth - 1;
  2115.    MOUREMOVEPTR( ( struct NoPointer far * )&Collision, Mouse );
  2116.  
  2117.     6. Loop to read mouse position and draw cursor, as follows:
  2118.  
  2119.    while( 1 ) {
  2120.        MOUREADEVENTQUE( ( struct EventInfo far * )&MouInfo,     (wait for)
  2121.                         ( unsigned far * )&ReadType,           (something)
  2122.                         Mouse );                               (to happen)
  2123.        if( MouInfo.Mask & 1) {                    (if the mouse has moved)
  2124.           VIOWRTCELLSTR( ( char far * )Background, 2, MouseRow, MouseCol, 0 );
  2125.           MouseRow = MouInfo.Row;
  2126.           MouseCol = MouInfo.Col;
  2127.           VIOWRTCELLSTR( ( char far * )MouseCursor, 2, MouseRow, MouseCol, 0 )
  2128.        }
  2129.  
  2130.        if( MouInfo.Mask & 4 ) {                   (left button pressed)
  2131.           VIOSETCURTYPE( &OldCur, 0 );
  2132.           DOSEXIT( 1, 0 );
  2133.        }
  2134.     }
  2135.   }
  2136.  
  2137.  
  2138.  51. Setting Signal Handlers in C
  2139.  
  2140.  Question:
  2141.  
  2142.  How do I set a signal handler in C?
  2143.  
  2144.  Response:
  2145.  
  2146.  Within OS/2, a signal mechanism notifies processes of external events.
  2147.  These signals are as follows:
  2148.  
  2149.  Signal Name     Description             Signal Number
  2150.  
  2151.  SIGINTR          CTRL+C                       1
  2152.  SIGTERM          Program termination          3
  2153.  SIGBREAK         CTRL+BREAK                   4
  2154.  Process flag A   User-defined flag A          5
  2155.  Process flag B   User-defined flag B          6
  2156.  Process flag C   User-defined flag C          7
  2157.  
  2158.  Upon receipt of a signal, the default action for a process is to
  2159.  ignore the signal, or terminate the process. For most applications,
  2160.  these defaults are unacceptable. OS/2 provides a mechanism to allow a
  2161.  process to associate a different action for each signal, if necessary.
  2162.  The specific API call used is DOSSETSIGHANDLER.
  2163.  
  2164.  The following program is an example of a SIGINTR signal handler. The
  2165.  program installs a signal handler for SIGINTR signals. The signal
  2166.  handler merely prints out the value of the arguments that OS/2 pushes
  2167.  on to the stack. The arguments are signal number and signal argument.
  2168.  
  2169.  In this example, the signal number is 1, which is SIGINTR's signal
  2170.  number. Signal argument is a flag argument used in conjunction with
  2171.  process flags via the DOSFLAGPROCESS API call; hence, its value is
  2172.  undefined.
  2173.  
  2174.  To run sigdemo, get into a protected-mode shell, run "sigdemo", then
  2175.  press CTRL+C.
  2176.  
  2177.  Compile with the following: cl -AL -G2 -Lp sigdemo.c.
  2178.  
  2179.  #include <doscalls.h>
  2180.  #include <subcalls.h>
  2181.  #include <stdio.h>
  2182.  #include <stdlib.h>
  2183.  #include <dos.h>
  2184.  #include <signal.h>
  2185.  
  2186.  extern void pascal far sig_handler();
  2187.  extern far sig_handler2();
  2188.  
  2189.  #define USE_SIGHANDLER 2     /* on signal trap, jump to sig_handler */
  2190.  #define SIGINTR        1     /* trap SIGINTR's, otherwise known as CTL-C */
  2191.  
  2192.  void main() {
  2193.  
  2194.      void (pascal far *address)(); /* address of previous signal handler */
  2195.      unsigned    oldaction;        /* previously set action */
  2196.      /*
  2197.       *  signal action jump to sig_handler
  2198.       */
  2199.      unsigned    action          =  USE_SIGHANDLER;
  2200.      /*
  2201.       *  signal to trap, SIGINTR's, (ctl-c)
  2202.       */
  2203.      unsigned    signum          =  SIGINTR;
  2204.      unsigned    result;           /* return code from API call */
  2205.  
  2206.      /*
  2207.       *  set up new action associated with SIGINTR's, jump to sig_handler
  2208.       */
  2209.      if (result = DOSSETSIGHANDLER((void(far *)())sig_handler,
  2210.                                    (unsigned long far *) &address,
  2211.                                    (unsigned far *) &oldaction,
  2212.                                    action,
  2213.                                    signum))
  2214.          fprintf(stderr,"dossetsighandler failed %d\n", result);
  2215.  
  2216.      DOSSLEEP(10000L);  /* hang around for 10 seconds */
  2217.  
  2218.      fprintf(stderr,"main exiting\n");
  2219.  
  2220.      exit(0);
  2221.  }
  2222.  
  2223.  /*
  2224.   *  sig_handler - the SIGINTR signal handler prints out the arguments
  2225.   *                on the stack, and sends an acknowledgement of signal
  2226.   *                receipt.
  2227.   *
  2228.   *      at sig_handler invocation, the stack looks like the following:
  2229.   *
  2230.   *              (SS:SP)   far return address
  2231.   *              (SS:SP+4) signal number being handled
  2232.   *              (SS:SP+6) signal argument
  2233.   *
  2234.   *      OS/2 cleans up the stack for us by restoring all register states
  2235.   *      to the value prior to the receipt of the signal. Since C normally
  2236.   *      cleans up the stack AFTER returning from a call, this function
  2237.   *      is declared as "pascal", which has the effect of not cleaning the
  2238.   *      stack, and reversing the ordering of the arguments.
  2239.   */
  2240.  void pascal far sig_handler(sig_arg, sig_num)
  2241.  unsigned sig_arg, sig_num;
  2242.  {
  2243.      unsigned prevact; /* previous action */
  2244.      long address;   /* previous address, since we're acking, this is ok */
  2245.      int  result;    /* return code */
  2246.  
  2247.      /*
  2248.       *  print out the argument values OS/2 pushed on the stack
  2249.       */
  2250.      fprintf(stderr,
  2251.              "signum\t%u\t(should be 1)\nsigarg\t%u\t(should be null)\n",
  2252.              sig_num,
  2253.              sig_arg);
  2254.  
  2255.      /*
  2256.       *  acknowledge the receipt of the signal, enabling this particular
  2257.       *  signal once again.
  2258.       */
  2259.      if (result = DOSSETSIGHANDLER((void (pascal far *)()) 0,
  2260.                                    (long far *) &address,
  2261.                                    (unsigned far *) &prevact,
  2262.                                    (unsigned) SIG_ACK,
  2263.                                    sig_num))
  2264.          fprintf(stderr,"dossetsighandler failed %d\n", result);
  2265.  }
  2266.  
  2267.  
  2268.  52. Running Files for Protected-Mode Screen Groups
  2269.  
  2270.  Question:
  2271.  
  2272.  How can I have a file executed for each protected-mode screen group
  2273.  start-up (e.g. in the same way AUTOEXEC.BAT is executed for MS-DOS
  2274.  shells)?
  2275.  
  2276.  Response:
  2277.  
  2278.  The file specified will be executed for each screen group started if
  2279.  the line ""protshell=shell.exe cmd.exe" in your CONFIG.SYS file is
  2280.  changed to "protshell=shell.exe cmd.exe /k [drive:][pathname]".
  2281.  However, the file is not executed for the first screen group; only
  2282.  STARTUP.CMD is executed.
  2283.  
  2284.  The most convenient file to place there would be some sort of command
  2285.  file (like INITENV.CMD of the SDK) to initialize the environment
  2286.  variables. However, any file (e.g. a command processor, an
  2287.  application) may be specified.
  2288.  
  2289.  To execute INITENV.CMD in the first screen group, call it from the
  2290.  STARTUP.CMD command file. (It is advisable to call INITENV.CMD before
  2291.  executing any other commands in STARTUP.CMD, as INITENV.CMD sets up
  2292.  the environment.)
  2293.  
  2294.  The call syntax is as follows:
  2295.  
  2296.     CALL INITENV
  2297.  
  2298.  
  2299.  53. Disk I/O Unreliable if 3.x Box in Foreground
  2300.  
  2301.  Question:
  2302.  
  2303.  Is floppy disk input/output reliable?
  2304.  
  2305.  Response:
  2306.  
  2307.  Floppy drive input/output is not reliable from the 3.x box, or from a
  2308.  background protected mode screen group while the 3.x box is in the
  2309.  foreground.
  2310.  
  2311.  
  2312.  54. OS/2 SDK: Sending Information between Processes
  2313.  
  2314.  Question:
  2315.  
  2316.  What is the best way to send data between two processes?
  2317.  
  2318.  Response:
  2319.  
  2320.  There are several methods that can be used to send data to and from a
  2321.  server process. They are pipes, named pipes, shared memory, and queues.
  2322.  
  2323.  Pipes allow distributed processing and are transparent to either of
  2324.  the processes using them. This allows the data to be sent over
  2325.  the network. Pipes also do not require extra work on your part to keep
  2326.  track of the data being transferred and can be either synchronous or
  2327.  asynchronous. (See the examples on the SDK Toolkit disk \example\pipes
  2328.  on how pipes are implemented.) Pipes have a limitation in that they
  2329.  are of a fixed length (not more than 64K) because they have to fit
  2330.  within one segment.
  2331.  
  2332.  Named pipes also could be used to send data between processes, even
  2333.  over a network. The difference between pipes and named pipes is that
  2334.  named pipes act like full duplex virtual circuits; regular pipes are
  2335.  only one direction. (See the LAN Manager documentation for a detailed
  2336.  description of named pipes.)
  2337.  
  2338.  Shared memory is the fastest method for transferring data, but it
  2339.  requires more work on your part. You have to manage the memory to keep
  2340.  the reading and writing processes synchronized with each other.
  2341.  
  2342.  Queues also can be used to transfer the data between the processes.
  2343.  The advantage of using queues is that only a pointer to the data is
  2344.  passed, making them somewhat more efficient than pipes. A disadvantage
  2345.  is that queues cannot be extended across a network (named pipes can be
  2346.  extended across a network).
  2347.  
  2348.  
  2349.  55. What Descriptor Table Is Active in a Registered Function Call
  2350.  
  2351.  Question:
  2352.     Whose descriptor table is in effect when a video registered
  2353.  function is called?
  2354.  
  2355.  Response:
  2356.     The descriptor table of the process that did the video call is in
  2357.  effect.
  2358.  
  2359.  
  2360.  56. OS/2 SDK: Creating Process to Poll External Devices
  2361.  
  2362.  Question:
  2363.  
  2364.  I would like to know if it is possible to create a process that will
  2365.  poll an external device at least once during a given time interval
  2366.  without taking up a lot of CPU time. The time interval would need to
  2367.  be on the scale of 1-2 milliseconds.
  2368.  
  2369.  Response:
  2370.  
  2371.  You can poll devices in the manner you describe, except that the
  2372.  smallest interval (slice) is 32 milliseconds. Under OS/2 you could
  2373.  implement this in either of the following ways:
  2374.  
  2375.   1. Write the routine as a stand-alone application that sleeps and
  2376.      periodically wakes up to poll the device.
  2377.  
  2378.   2. Write the routine as a device driver that takes advantage of
  2379.      the timing interface available to device drivers.
  2380.  
  2381.  Either way, because of the slicing algorithms, your routine is going
  2382.  to be the only application using the CPU. There will be little
  2383.  opportunity for the other tasks to run.
  2384.  
  2385.  
  2386.  57. OS/2 SDK: Brief Will Not Run in the Compatibility Box
  2387.  
  2388.  Problem:
  2389.  
  2390.  While running Brief Version 1.33 in the 3.x box, I am having problems
  2391.  with the system locking up. There does not appear to be any pattern to
  2392.  it; the system just stops. The system has to be turned off;
  2393.  CTRL+ALT+DEL does not work.
  2394.  
  2395.  Response:
  2396.  
  2397.  Microsoft is aware of these problems with Brief and the compatibility
  2398.  box. We have contacted the author of Brief, and he suggests that you
  2399.  acquire an update from Solution Systems, the marketers of Brief. The
  2400.  version he suggests to update to has a build date later than 5/5/87
  2401.  (ideally, the 5/6/87 build). These builds contain the necessary
  2402.  corrections to the Brief keyboard handler that will allow it to work
  2403.  with the OS/2 compatibility box. The author further suggests that when
  2404.  you invoke this version of Brief from the command line, you specify
  2405.  the "-k" option.
  2406.  
  2407.  
  2408.  58. Access and Create Date/Times in FileFindBuf
  2409.  
  2410.  Problem:
  2411.     The FileFindBuf used in DosFindFirst and DosFindNext has entries
  2412.  for the following:
  2413.  
  2414.     1. Create Date
  2415.     2. Create Time
  2416.     3. Access Date
  2417.     4. Access Time
  2418.     5. Write Date
  2419.     6. Write Time
  2420.  
  2421.     The Write Date and Write Time is filled in correctly, but the
  2422.  Create and Access Date and Times always appear as 0.
  2423.  
  2424.  Response:
  2425.     Information on Create Date and Time and Access Date and Time is not
  2426.  kept in the directory entries for files under the DOS file system used
  2427.  by Versions 1.00 and 1.10 of OS/2.
  2428.     Therefore, this information cannot be returned. These fields were
  2429.  included for use by Installable File Systems under future versions of
  2430.  OS/2.
  2431.  
  2432.  
  2433.  59. BPB Returned by DosDevIOCtl Category 8 Function 63h
  2434.  
  2435.     The DosDevIOCtl category 8 function 63h is used to obtain
  2436.  information about disk devices. The following are its return values:
  2437.  
  2438.     Bytes per sector      WORD
  2439.     Sectors per cluster   BYTE
  2440.     Reserved sectors      WORD
  2441.     Number of FATs        BYTE
  2442.     Root dir.entries      WORD
  2443.     Total sectors         WORD
  2444.     Media descriptor      BYTE
  2445.     Sectors per FAT       WORD
  2446.     Sectors per track     WORD
  2447.     Number of heads       WORD
  2448.     Hidden sectors        DWORD
  2449.     Large total sectors   DWORD
  2450.     Reserved              6 BYTES
  2451.  
  2452.  
  2453.  60. State of Processor in Device Driver After a ProcBlock
  2454.  
  2455.  Response:
  2456.     The processor will be in the same mode when it returns from a block
  2457.  as it was when it issued the block command.
  2458.  
  2459.  
  2460.  61. NOWAIT Option of the KbdCharIn
  2461.  
  2462.  Question:
  2463.     How can I determine if a character was returned from KbdCharIn
  2464.  set to NOWAIT?
  2465.  
  2466.  Response:
  2467.     Use the status byte. Bit six set to one indicates a character
  2468.  was returned. If this bit is set to zero, no character was
  2469.  returned.
  2470.  
  2471.  
  2472.  62. DOSDEVIOCTL, Category 5 - Function "Get Printer Status"
  2473.  
  2474.  Question:
  2475.     What IOCTL is used for getting the printer status?
  2476.  
  2477.  Response:
  2478.     The "Get Printer Status" (Category 5) IOCTL is 66H.
  2479.  
  2480.  
  2481.  63. Process and Thread Status
  2482.  
  2483.  Question:
  2484.     How can I access the following information?
  2485.  
  2486.     1. Process and thread status
  2487.     2. DLL usage and linkage
  2488.     3. A listing of system resources currently in use, such as the
  2489.  following:
  2490.  
  2491.        a. Queues
  2492.        b. Shared memory
  2493.        c. System semaphores
  2494.  
  2495.     4. Other system information
  2496.  
  2497.  Response:
  2498.     There is a new utility called PS (Process Status). This displays
  2499.  information about the state of the MS OS/2 environment. It displays a
  2500.  list of all running threads, DLL usage and linkage, shared memory
  2501.  allocation, and system semaphore states. It is a protected-mode-only
  2502.  program.
  2503.     A special version of the kernel must be installed. Please refer to
  2504.  Section 2.2.2 of the "Microsoft OS/2 SDK Installation" manual for
  2505.  instructions (OS/2 SDK Version 1.02) on how to install it.
  2506.  
  2507.  
  2508.  64. SUBST Command in the Protected Mode
  2509.  
  2510.  Question:
  2511.     Will SUBST work in protected mode?
  2512.  
  2513.  Response:
  2514.     The SUBST command does not work in the protected mode.
  2515.  
  2516.  
  2517.  65. Cursor Not Supported in MouSetPtrShape Call
  2518.  
  2519.  The current documentation of the MouSetPtrShape call implies that a
  2520.  mouse cursor is supported in video modes 0-7 as well as in some
  2521.  graphics modes.
  2522.  
  2523.  This is an error on Page 431 of the "Microsoft Operating System/2
  2524.  Programmer's Reference Guide." We currently do not support the drawing
  2525.  of a mouse cursor in any graphics mode.
  2526.  
  2527.  
  2528.  66. OS/2 SDK: Profiler Not Enough Memory Error
  2529.  
  2530.  Question:
  2531.  
  2532.  When I try to profile a large executable, profInit returns error 8
  2533.  (ERROR_NOT_ENOUGH_MEMORY). Is there a maximum limit on the size of a
  2534.  program that can be profiled?
  2535.  
  2536.  Also, is there any way that I can get profile information of time
  2537.  spent in system DLLs on a system-call by system-call basis rather than
  2538.  on a segment by segment basis (i.e., can we get the map files for the
  2539.  GPI, WIN, and DOS APIs)?
  2540.  
  2541.  Response:
  2542.  
  2543.  Yes, there is a limit on the size of the program that the profiler can
  2544.  profile. The profiler works as follows. For every code segment that
  2545.  your application has, a corresponding and equal sized data segment is
  2546.  allocated. The clock interrupt is then hooked. For every clock tick
  2547.  that comes in, the DS value is examined. If it belongs to the
  2548.  application being profiled, a dword value in the data segment
  2549.  corresponding to the code segment is incremented, based at an offset
  2550.  into the data segment corresponding to the offset into the code
  2551.  segment. This is why the resolution of the profiler is a dword. After
  2552.  incrementing the value, the clock interrupt handler returns control
  2553.  back to the system.
  2554.  
  2555.  Note that because the data segment is updated at interrupt time, it
  2556.  MUST be present in memory at all times. This means that it cannot be
  2557.  swapped out. That is why the memory requirements for profiling an
  2558.  application are so much larger than just running the application
  2559.  without profiling. For every code segment, there is also going to be
  2560.  one LDT slot used to allocate the corresponding data segment. You
  2561.  could potentially run out of selectors and cause the out-of-memory
  2562.  error for this reason.
  2563.  
  2564.  Unfortunately, we cannot release the map files for portions of the
  2565.  system like DOSCALL1.DLL or PMWIN.DLL. You can create functions that
  2566.  simply do the call that you are interested in and then create a macro
  2567.  that replaces all the occurrences of the Dos or Win call with a call
  2568.  to your routine. This will allow you to know how much time your
  2569.  application is spending doing the specified call (with the overhead of
  2570.  an additional call). Whether you want to go to this trouble will
  2571.  depend on how many system calls you are most interested in and how
  2572.  critical it is to know the time spent within them compared to the time
  2573.  spent within your application's routines.
  2574.  
  2575.  
  2576.  67. Documentation Error: Incorrect Definition for Status Field
  2577.  
  2578.  On Page 81 of the "Microsoft Operating System/2 Software Development
  2579.  Kit Device Drivers Guide" the definition of the status field is
  2580.  incorrect. This also affects the Open/Close request packet definitions
  2581.  on their associated pages.
  2582.  
  2583.  Bit 3 of the status field is set on open/close requests to indicate
  2584.  that this request originated from a DosMonOpen/DosMonClose call. If
  2585.  the request originated from a DosMonClose, you need to Deregister the
  2586.  monitor chain so that the monitor threads will die when the device is
  2587.  closed.
  2588.  
  2589.  
  2590.  68. OS/2 SDK: Launching Threads
  2591.  
  2592.  Problem:
  2593.  
  2594.  I have an application in which I need to launch and destroy threads.
  2595.  However, I cannot find any kernel function that allows me to destroy a
  2596.  thread and recover the resources associated with it.
  2597.  
  2598.  Response:
  2599.  
  2600.  If your application needs to destroy threads, they should be using
  2601.  processes. When processes are used, the OS/2 calls DosExecPgm() and
  2602.  DosKillProcess() can be used for launching and destroying. Resources
  2603.  can be shared between processes by using the Inter Process
  2604.  Communications (IPC) facilities and/or shared memory.
  2605.  
  2606.  Although processes are somewhat more expensive to create than threads,
  2607.  once they are running they require no more overhead than threads.
  2608.  
  2609.  An alternative is to design your threads so that they periodically
  2610.  check a flag or a semaphore and DosExit(0,0) when it is set. If your
  2611.  application cannot be guaranteed to check the flag, the method above
  2612.  is the best approach.
  2613.  
  2614.  If you choose the alternative method, think carefully about how the
  2615.  master thread will know that the dying thread died. The best approach
  2616.  is to do a DosEnterCritSec(), then clear the flag/semaphore and
  2617.  DosExit(). This will guarantee that the daughter thread will die
  2618.  before the master thread tries to launch another thread.
  2619.  
  2620.  
  2621.  69. DosSetFHandState() fsState Parameter Information
  2622.  
  2623.  Question:
  2624.  
  2625.  I have a question about the documentation for the DosSetFHandState()
  2626.  function. On Page 138 of the "Microsoft Operating System/2
  2627.  Programmer's Reference Volume 3" for Version 1.10 it states that
  2628.  fsState flag can be set to three different values. However, the
  2629.  include file BSEDOS.H shows a list of many more values that apply to
  2630.  both DosOpen() and DosSetFHandState(). Which is correct, the
  2631.  documentation or the include file?
  2632.  
  2633.  Also, is the fsOpenMode parameter of the DosOpen() function the same
  2634.  as the fsState parameter of the DosSetFHandState() function?
  2635.  
  2636.  Response:
  2637.  
  2638.  The values of the fsState parameter of DosSetFHandState() can be set
  2639.  to the following:
  2640.  
  2641.     OPEN_FLAGS_NOINHERIT
  2642.     OPEN_FLAGS_FAIL_ON_ERROR
  2643.     OPEN_FLAGS_WRITE_THROUGH
  2644.  
  2645.  The other OPEN_FLAGS_* value listed in BSEDOS.H, which CANNOT be used
  2646.  in the fsState parameter of DosSetFHandState() is the following:
  2647.  
  2648.     OPEN_FLAGS_DASD
  2649.  
  2650.  All four of these OPEN_FLAGS_* flags listed above can be used in the
  2651.  fsOpenMode parameter of DosOpen(). Thus, DosSetFHState() can only set
  2652.  some (three of the four) file handle state flags. Because of the way
  2653.  OPEN_FLAGS_DASD is implemented inside the OS/2 kernel, it is not
  2654.  possible to set the OPEN_FLAGS_DASD flag after the file has been
  2655.  opened; it can only be done when the file is opened via the DosOpen()
  2656.  function.
  2657.  
  2658.  There is another relationship between these flags and the functions
  2659.  DosOpen(), DosSetFHandState(), and DosQFHandState(): the
  2660.  DosQFHandState() function returns the equivalent of the entire
  2661.  fsOpenMode [of DosOpen()] parameter of the file handle.
  2662.  
  2663.  Therefore, when the file is opened, you can set all these flags and
  2664.  other file handle states with DosOpen(), and you can query the values
  2665.  of all of the flags of a handle at any time with DosQFHandState().
  2666.  However, you can only modify SOME of the file handle flags with
  2667.  DosSetFHandState() after the file has been opened.
  2668.  
  2669.  The other bitfields of the WORD in the fsOpenMode parameter of
  2670.  DosOpen() are as follows:
  2671.  
  2672.     5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  2673.     D W F R R R R R I S S S R A A A
  2674.  
  2675.  where:
  2676.  
  2677.     AAA  the OPEN_ACCESS_* flags [3 bits]
  2678.     SSS  the OPEN_SHARE_* flags [3 bits]
  2679.     I    the OPEN_FLAGS_NOINHERIT flag [1 bit]
  2680.     F    the OPEN_FLAGS_FAIL_ON_ERROR flag [1 bit]
  2681.     W    the OPEN_FLAGS_WRITE_THROUGH flag [1 bit]
  2682.     D    the OPEN_FLAGS_DASD flag [1 bit]
  2683.     R    the reserved flags [many bits]
  2684.  
  2685.  
  2686.  70. Awake Codes for the DevHlp_Block Function
  2687.  
  2688.  Question:
  2689.  
  2690.  What are the "awake" codes for the DevHlp_Block function? The manual
  2691.  states that an awake code is returned in AL, but doesn't list the
  2692.  values.
  2693.  
  2694.  Response:
  2695.  
  2696.  The awake codes are not important. All the information is given in the
  2697.  carry and zero flags.
  2698.  
  2699.  The current values are as follows:
  2700.  
  2701.     normal      - carry unset
  2702.     timeout     - carry set, zero set
  2703.     interrupted - carry set, zero unset
  2704.  
  2705.  
  2706.  71. Minimum System OS/2 Boot Disk
  2707.  
  2708.  Question:
  2709.  
  2710.  What files are required to be on the boot disk for OS/2?
  2711.  
  2712.  Response:
  2713.  
  2714.  The following is the minimum number of files that must be present on
  2715.  your boot disk:
  2716.  
  2717.  OS2DOS.COM       OS2BIOS.COM      OSO001.MSG       OSO001H.MSG
  2718.  STARTUP.CMD      INITENV.CMD      AUTOEXEC.BAT     CONFIG.SYS
  2719.  
  2720.  CLOCK01.SYS      KBD01.SYS        SCREEN01.SYS
  2721.  DISK01.SYS       OEMHLP.SYS
  2722.  
  2723.  BKSCALLS.DLL     BMSCALLS.DLL     BVSCALLS.DLL
  2724.  KBDCALLS.DLL     MOUCALLS.DLL     VIOCALLS.DLL
  2725.  DOSCALL1.DLL     ANSICALL.DLL     MONCALLS.DLL
  2726.  MSG.DLL          NLS.DLL          QUECALLS.DLL     SESMGR.DLL
  2727.  
  2728.  You can remove the dynalink libraries from the boot floppy if you set
  2729.  the LIBPATH variable in your CONFIG.SYS file to point to the location
  2730.  of the dynalink libraries on your hard disk.
  2731.  
  2732.  You will also need any other device drivers (*.SYS files) for other
  2733.  devices you may have on your system such as a mouse, serial port, etc.
  2734.  
  2735.  
  2736.  72. Setting Unsupported Video Modes (Debugging)
  2737.  
  2738.  Question:
  2739.     How can I set my video card into 35x80 mode?  When the system
  2740.  starts up, my video card behaves like a CGA card. I can change its
  2741.  mode by outputting to a port that can set the card into the mode I
  2742.  desire. When I use VioSetmode to set the mode, I get error returns.
  2743.  
  2744.  Response:
  2745.     The VioSetMode will only change the video into modes that are
  2746.  documented. To change the display into another mode, you must use the
  2747.  VioModeWait API, as follows:
  2748.  
  2749.       1. Create a thread that calls VioModeWait.
  2750.       2. Put the video display into the desired mode, through out
  2751.          instructions. This will require an IOPL code segment (to use
  2752.          in or out instructions).
  2753.       3. When the VioModeWait thread returns, reset the video mode.
  2754.          (This includes the cursor mode).
  2755.  
  2756.     For some video operations, you may need to use the VioSavRedrawWait
  2757.  API. You should look up both of these API calls in the "Microsoft
  2758.  Operating System/2 Programmer's Reference" manual.
  2759.     Please note the following about debugging:
  2760.  
  2761.     When you have a thread for ModeWait or SavRedrawWait, debugging
  2762.  with CodeView may not perform as expected. When a screen switch
  2763.  occurs, the system waits for your application to finish its ModeWait
  2764.  or SavRedrawWait operation before the actual screen switch completes.
  2765.  OS/2 is depending on the cooperation of the application program. When
  2766.  you are debugging an application with CodeView, CodeView tends to
  2767.  "freeze" the application's threads. If a screen switch is attempted
  2768.  (by you or the debugger, i.e., the debugger is attempting to make
  2769.  itself the foreground process) when the application's threads are
  2770.  frozen, the Vio subsystem will deadlock.
  2771.  
  2772.  
  2773.  73. PhysToUVirt Call in Device Drivers
  2774.  
  2775.  Question:
  2776.     The documentation in the device driver guide is not clear.
  2777.     When using the PhysToUVirt call to release memory (DH = 2), should
  2778.  AX:BX still have the physical address, or is it the inverse so that it
  2779.  should have the virtual?
  2780.  
  2781.  Response:
  2782.     For request type 2, AX contains a selector on entry to PhysToUVirt.
  2783.  BX and CX are ignored.
  2784.  
  2785.  
  2786.  74. VioGetMode(), VioSetMode() hvio Parameter Documentation Error
  2787.  
  2788.  Microsoft has confirmed that Pages 213 and 242 of the "Microsoft
  2789.  Operating System/2 Programmer's Reference Volume 3" for Version 1.10
  2790.  incorrectly document the hvio parameter of the functions VioGetMode()
  2791.  and VioSetMode(). Furthermore, this documentation error also occurs in
  2792.  the version of QuickHelp that is included with Version 1.10 of the
  2793.  OS/2 Software Development Kit (SDK).
  2794.  
  2795.  Both the functions VioGetMode() and VioSetMode() take as their second
  2796.  parameter a 16-bit word, "HVIO hvio". In the references sited above,
  2797.  this parameter is documented as capable of being used as a handle to
  2798.  an advanced video input and output (AVIO) presentation space. The
  2799.  documentation further states that this handle must have been created
  2800.  previously with the function VioCreatePS(). These statements are not
  2801.  correct. The functions VioGetMode() and VioSetMode() are only valid
  2802.  for VIO-windowable applications; they are not supported by
  2803.  Presentation Manager (PM) and they must not be used by PM or AVIO
  2804.  applications. The parameter "HVIO hvio" is a reserved word that must
  2805.  always be zero. An error will be returned if VioGetMode() or
  2806.  VioSetMode() is called with a nonzero handle.
  2807.  
  2808.  Also note that when VioSetMode() is called from a VIO-windowed
  2809.  application (as opposed to an application that is running in its own
  2810.  screen group), it will not change the size of a character cell.
  2811.  
  2812.  
  2813.  75. Device Driver Timer Interrupt and Devhlp SETTIMER Problem
  2814.  
  2815.  OS/2 will crash if two device drivers both register "timer interrupt"
  2816.  service routines with the Devhlp SETTIMER function, and if the timer
  2817.  handlers start at the same offset, but in different code segments.
  2818.  
  2819.  Microsoft has confirmed this to be a problem with the Software
  2820.  Development Kit Version 1.05.  We are researching this problem and
  2821.  will post new information as it becomes available.
  2822.  
  2823.  The workaround is to have different offsets for the timer handlers.
  2824.  
  2825.  
  2826.  76. Default QSIZE Parameter for a Mouse
  2827.  
  2828.  The default value for the QSIZE parameter listed on Page 69 of the
  2829.  "Microsoft Operating System/2 Setup Guide" is 10. This information can
  2830.  be found on Page 91 of the "Microsoft Operating System/2 Desktop
  2831.  Reference."
  2832.  
  2833.  
  2834.  77. SHELL11F.AII, SHELL11F.AIF, and SHELL.LIB Descriptions
  2835.  
  2836.  Question:
  2837.     What are the files SHELL11F.AII, SHELL11F.AIF, and SHELL.LIB in the
  2838.  SYS directory of OS/2 used for?
  2839.  
  2840.  Response:
  2841.     These files relate to the Program Selector, the screen you see when
  2842.  you press CTRL-ESC.
  2843.     SHELL11F.AII and SHELL11F.AIF contain information on the entries
  2844.  you see in each of the columns on the Program Selector screen.
  2845.     SHELL.LIB contains screen-drawing information to create the Program
  2846.  Selector screen. The .LIB format was used for this file because it was
  2847.  efficient to do so; it is not a true library.
  2848.     These three files must be in the same place as SHELL.EXE, as
  2849.  pointed to by the "protshell" parameter in CONFIG.SYS.
  2850.  
  2851.  
  2852.  78. Overhead on DosRead() and DosWrite() Calls
  2853.  
  2854.  Question:
  2855.  
  2856.  When communicating to a character device through a device driver, such
  2857.  as a COM device or a user-written device driver, it is unclear what
  2858.  the overhead is in using the DosRead() and DosWrite() functions.
  2859.  
  2860.  In an environment where there are no monitors, is there any processing
  2861.  that OS/2 does to the data in a DosRead() or DosWrite() request to
  2862.  such a device driver? This question applies to anything from a simple
  2863.  copy to any other data processing. Would there be less overhead if I
  2864.  were to accomplish device I/O with DosDevIOCtl()?
  2865.  
  2866.  Response:
  2867.  
  2868.  OS/2 Version 1.10 does no processing to the data in a DosRead() or
  2869.  DosWrite() call. These functions operate in binary (raw) mode.
  2870.  
  2871.  The OS/2 overhead involved in these functions essentially consists
  2872.  of the following:
  2873.  
  2874.  1. Handling I/O redirection
  2875.  
  2876.  2. Locking the user data buffer
  2877.  
  2878.  3. Switching to Ring 0
  2879.  
  2880.  4. Calling the device driver
  2881.  
  2882.  5. Doing some standard error handling procedures
  2883.  
  2884.  Doing the read or write with a DosDevIOCtl() involves basically the
  2885.  same OS/2 overhead described above, except for locking the user data
  2886.  buffer. This is left as an option for the device driver to implement
  2887.  if necessary for that particular device.
  2888.  
  2889.  
  2890.  79. Information on How to Write a Device Driver
  2891.  
  2892.  Problem:
  2893.     I am unable to find a description of the steps necessary to
  2894.  construct a driver for OS/2 and install it. The driver documentation
  2895.  covers the functions available (DevHlps, etc.), but it does not
  2896.  indicate how to build the driver .EXE file and what must be done to
  2897.  convert that file to a .SYS file (if anything).
  2898.     A sample driver of any kind would be a great help. An explanation
  2899.  of how to provide an alternate base driver and what must be provided
  2900.  to completely override a base driver would also help.
  2901.  
  2902.  Response:
  2903.     The design and writing of device drivers was not covered in detail
  2904.  in the SDK release of OS/2. Microsoft provides a Device Driver
  2905.  Developers Kit (DDDK) that does provide this added information. You
  2906.  can request it through your account manager or a Microsoft Service
  2907.  Request.
  2908.  
  2909.  
  2910.  80. Guidelines for Interrupt Handler
  2911.  
  2912.     Device driver interrupt handlers must be carefully written in order
  2913.  to prevent uncontrolled stack growth of the interrupt stack. An
  2914.  interrupt handler should consume as little stack space as possible
  2915.  and should limit the depth of "interrupt nesting."
  2916.     Device drivers that do processing after sending an end-of-interrupt
  2917.  (EOI) to the interrupt controller (8259) and enabling interrupts (STI)
  2918.  can receive "nested interrupts." To prevent using excessive interrupt
  2919.  stack space, the device driver should keep internal flags to limit the
  2920.  amount of interrupt nesting.
  2921.     The amount of interrupt nesting is limited by performing all
  2922.  post-EOI processing at the first-level interrupt. Nested interrupts
  2923.  should avoid and, if possible, eliminate post-EOI processing. In all
  2924.  cases, the device driver should bound the number of nesting levels
  2925.  to as few as possible (preferably two) and should never permit the
  2926.  levels of nesting to be unbounded.
  2927.  
  2928.     A technique for limiting the amount of interrupt nesting to two
  2929.  levels can be implemented as follows:
  2930.  
  2931.     1. When the nested interrupt is encountered, a flag (or count) is set
  2932.  so that the post-EOI processing can be done again by the first-level
  2933.  interrupt if necessary.
  2934.     On a nested interrupt, the interrupts must be disabled (and remain
  2935.  disabled) before doing the EOI and returning to the Interrupt Manager.
  2936.     2. On a first-level interrupt, interrupts may be enabled before doing
  2937.  the EOI and may remain enabled during the post-EOI processing.
  2938.  Interrupts must be disabled (and remain disabled) before clearing the
  2939.  "interrupt in progress" flag and returning to the Interrupt Manager.
  2940.  
  2941.     As stated previously, if a device driver needs to support more than
  2942.  one level of nested interrupts, it still must limit the number of
  2943.  nested interrupts that it handles. A device driver should avoid this
  2944.  if at all possible.
  2945.     As device drivers allow more levels of nesting for their interrupt
  2946.  handlers, the potential exists for the entire interrupt stack to be
  2947.  consumed. This applies to all device drivers, regardless of the
  2948.  interrupt rate of the device being supported.
  2949.     It may seem that a device driver for a slow device need not follow
  2950.  this convention. However, if the system contains another device that
  2951.  has a high interrupt rate, or many devices with more moderate
  2952.  interrupt rates, the interrupt latency (time between occurrence of
  2953.  hardware interrupt and dispatch to interrupt handler) may become
  2954.  greater than the interrupt rate of the "slow" device, and excessive
  2955.  nesting can occur.
  2956.     The following are pseudo-code examples of the proper algorithms:
  2957.  
  2958.  PSEUDO-CODE EXAMPLE (using a flag for nested interrupts)
  2959.  
  2960.     fDoingPostEOI = FALSE;     /* TRUE => doing Post-EOI processing */
  2961.     fNestedInts = FALSE;       /* TRUE => nested interrupt(s) occurred     */
  2962.  
  2963.     InterruptHandler ();
  2964.       /* pre-EOI processing */  /* CANNOT get a nested interrupt before EOI */
  2965.  
  2966.      if (fDoingPostEOI == TRUE) {    /* This is a nested interrupt */
  2967.          fNestedInts = TRUE;         /* Indicate nested interrupt occurred */
  2968.          cli;                        /* Prevent further interrupt nesting */
  2969.          EOI;
  2970.      }
  2971.      else {                          /* first-level interrupt */
  2972.          fDoingPostEOI = TRUE;       /* flag interrupt in progress */
  2973.          fNestedInts = TRUE;         /* force one EOI processing loop */
  2974.          sti;                        /* allow NESTED interrupts after EOI */
  2975.          EOI;                        /* issue EOI to interrupt controller */
  2976.  
  2977.          cli;                        /* Protect fNestedInts */
  2978.          while (fNestedInts == TRUE) { /* Do Post-EOI processing */
  2979.              fNestedInts = FALSE;    /* Reset nesting flag */
  2980.              sti;                    /* allow NESTED interrupts */
  2981.              /* post-EOI processing */
  2982.              cli;                    /* Protect fNestedInts */
  2983.          }
  2984.          fDoingPostEOI = FALSE;      /* interrupt no longer in progress */
  2985.      }
  2986.      return                          /* interrupts ALWAYS disabled here */
  2987.     }
  2988.  
  2989.     PSEUDO-CODE EXAMPLE (using a count for nested
  2990.  interrupts)
  2991.  
  2992.     fDoingPostEOI = FALSE;              /* TRUE => doing Post-EOI processing *
  2993.     cNestedInts = 0;                    /* count of nested interrupts */
  2994.  
  2995.     InterruptHandler ();
  2996.      /* pre-EOI processing */    /* CANNOT get a nested interrupt before EOI *
  2997.  
  2998.      if (fDoingPostEOI == TRUE) {    /* This is a nested interrupt */
  2999.          cNestedInts = cNestedInts+1;/* Increment nested interrupt count */
  3000.          cli;                        /* Prevent further interrupt nesting */
  3001.          EOI;
  3002.      }
  3003.      else {                          /* first-level interrupt */
  3004.          fDoingPostEOI = TRUE;       /* flag interrupt in progress */
  3005.          cNestedInts = 1;            /* force one EOI processing loop */
  3006.          sti;                        /* allow NESTED interrupts after EOI */
  3007.          EOI;                        /* issue EOI to interrupt controller */
  3008.  
  3009.          cli;                        /* Protect cNestedInts */
  3010.          while (cNestedInts > 0) {   /* Do Post-EOI processing */
  3011.              cNestedInts = cNestedInts - 1; /* Decrement nested ints count */
  3012.              sti;                    /* allow NESTED interrupts */
  3013.              /* post-EOI processing */
  3014.              cli;                    /* Protect cNestedInts */
  3015.          }
  3016.          fDoingPostEOI = FALSE;      /* interrupt no longer in progress */
  3017.      }
  3018.      return                          /* interrupts ALWAYS disabled here */
  3019.     }
  3020.  
  3021.  
  3022.  81. File Names Longer Than 8+3 Characters
  3023.  
  3024.  Question:
  3025.     What happens if a file is opened with a name longer than
  3026.  8+3 characters?
  3027.  
  3028.  Response:
  3029.     If you use file names that are greater than 8+3
  3030.  characters the names will be truncated to 8+3 characters,
  3031.  but it will not cause any errors. However, this will be
  3032.  changed in the future to return an error because future
  3033.  file systems will allow longer names. This will not affect
  3034.  the 3x box because it will continue to truncate names
  3035.  greater than 8+3 characters.
  3036.  
  3037.  
  3038.  82. Error in Attribute Word in Device Drivers Guide for OS/2 SDK
  3039.  
  3040.  There is an error in attribute word on Page 79 of the "Microsoft
  3041.  Operating System/2 Software Development Kit Device Drivers Guide." The
  3042.  function level is incorrect for an MS OS/2 Device driver. It should be
  3043.  001, not 010.
  3044.  
  3045.  
  3046.  83. OS/2 SDK: Problem Using Mouse in Compatibility Box
  3047.  
  3048.  Problem:
  3049.  
  3050.  I am trying to run Windows in the DOS compatibility box, and
  3051.  Presentation Manager (PM) in protected mode. I have no problems with
  3052.  the mouse and PM, but when Windows starts up there is no response from
  3053.  the mouse.
  3054.  
  3055.  Response:
  3056.  
  3057.  There is a known problem with using a mouse with Windows Versions 2.1a
  3058.  through 2.1d running in the DOS compatibility box. The problem stems
  3059.  from a compatibility problem that occurs with the OS/2 mouse driver
  3060.  running in the DOS compatibility box.
  3061.  
  3062.  The patch below is intended to correct problems that might be
  3063.  encountered when running Windows Versions 2.1a-2.1d in the DOS
  3064.  compatibility box of OS/2. The patch is implemented on one of the
  3065.  files in Windows (KERNEL.EXE) on the Setup/Build disk.
  3066.  
  3067.  To run this patch, you need PATCH.EXE, which is supplied with OS/2.
  3068.  Refer to the OS/2 documentation regarding information on PATCH.
  3069.  
  3070.  To implement the patch, follow these instructions:
  3071.  
  3072.  1. If Windows is already set up in a directory on your hard disk, do
  3073.     the following:
  3074.  
  3075.     a. Place the file PATCHWIN.21X (see below) in the Windows directory.
  3076.  
  3077.     b. Place the Windows Setup/Build disk (disk 1) in Drive A.
  3078.  
  3079.     c. Go to the Windows directory and type the following at the DOS
  3080.        prompt:
  3081.  
  3082.           PATCH PATCHWIN.21X /A
  3083.  
  3084.  2. If Windows is NOT set up on the hard disk, do the following:
  3085.  
  3086.     a. Place the file PATCHWIN.21X (see below) anywhere on the hard
  3087.        disk.
  3088.  
  3089.     b. Place the Windows Setup/Build disk (disk 1) in Drive A.
  3090.  
  3091.     c. Go to the Windows directory and type the following at the DOS
  3092.        prompt:
  3093.  
  3094.           PATCH PATCHWIN.21X /A
  3095.  
  3096.        You will notice a series of messages appearing on the screen. Be
  3097.        sure that you see one of the following messages; do not be
  3098.        alarmed by any other messages:
  3099.  
  3100.        1) SYS1595: The Verification Failed for <filename>
  3101.  
  3102.        2) Patches applied to <filename>
  3103.  
  3104.  The following are the contents of PATCHWIN.21X:
  3105.  
  3106.  FILE a:kernel.exe               ;Windows 286/2.1C-2.1D (Slow-Boot)
  3107.       VER 000047F5 80-3E-A2-00-05-72-0B-2E-F6-06-0F-01-10-74-03
  3108.       CHA 000047F5 F6-06-0F-01-10-75-08-2E-80-3E-A2-00-05-72-03
  3109.  
  3110.  FILE a:kernel.exe               ;Windows 286/2.1A (Slow-Boot)
  3111.       VER 000047F5 80-3E-A0-00-05-72-0B-2E-F6-06-0D-01-10-74-03
  3112.       CHA 000047F5 F6-06-0D-01-10-75-08-2E-80-3E-A0-00-05-72-03
  3113.  
  3114.  FILE win200.bin                 ;Windows 286/2.1C-2.1D (Fast-Boot)
  3115.       VER 00003FC5 80-3E-A2-00-05-72-0B-2E-F6-06-0F-01-10-74-03
  3116.       CHA 00003FC5 F6-06-0F-01-10-75-08-2E-80-3E-A2-00-05-72-03
  3117.  
  3118.  FILE win200.bin                 ;Windows 286/2.1A (Fast-Boot)
  3119.       VER 00003FC5 80-3E-A0-00-05-72-0B-2E-F6-06-0D-01-10-74-03
  3120.       CHA 00003FC5 F6-06-0D-01-10-75-08-2E-80-3E-A0-00-05-72-03
  3121.  
  3122.  
  3123.  84. Determining What Type of Application Is Calling a DLL
  3124.  
  3125.  Question:
  3126.  
  3127.  I have a dynamic linked library (DLL) that provides functions to
  3128.  various applications. I would like to put up an error message in a
  3129.  VioPopup() if the calling application is text based, or put the error
  3130.  message in a message box if the calling application is Presentation
  3131.  Manager (PM) based. Is there any way for a DLL to determine the
  3132.  executable type of the calling application?
  3133.  
  3134.  Response:
  3135.  
  3136.  Because any DLL-provided code executes in the context of the process
  3137.  that calls it, that DLL code can call DosGetInfoSeg() and look in the
  3138.  process's local infoseg (LINFOSEG) to determine the type of the
  3139.  process. For example, the following code demonstrates how to do this:
  3140.  
  3141.      USHORT      usError;        /* API return code         */
  3142.      SEL         selGlobalInfo;  /* Selector to GINFOSEG    */
  3143.      SEL         selLocalInfo;   /* Selector to LINFOSEG    */
  3144.      PLINFOSEG   plis;           /* Far pointer to LINFOSEG */
  3145.      .
  3146.      .
  3147.      usError = DosGetInfoSeg( &selGlobalInfo, &selLocalInfo );
  3148.      if ( usError )
  3149.          {
  3150.          /* process the error */
  3151.          }
  3152.      plis = MAKELINFOSEG( selLocalInfo );
  3153.      switch ( plis->typeProcess )
  3154.          {
  3155.          case 0:         /* Full-screen process ...  */
  3156.                                          break;
  3157.  
  3158.          case 1:         /* DOS process ...           */
  3159.                           break;
  3160.  
  3161.          case 2:          /* VIO-windowed process ... */
  3162.                           break;
  3163.  
  3164.          case 3:          /* PM process ...           */
  3165.                           break;
  3166.  
  3167.          case 4:          /* Detached process ...     */
  3168.                           break;
  3169.  
  3170.          default:         /* This line should never be reached */
  3171.          }
  3172.      /*
  3173.      .
  3174.      .
  3175.      .
  3176.      */
  3177.  
  3178.  
  3179.  85. Missing Documentation on START Command
  3180.  
  3181.  Question:
  3182.  
  3183.  The "Microsoft Operating System/2 Software Development Kit User's
  3184.  Guide" lacks documentation for the START command. Could you provide
  3185.  this?
  3186.  
  3187.  Response:
  3188.  
  3189.  The Start Command is used to start another process in a different
  3190.  session. The parameter list for the command (in which "program title"
  3191.  is the title that will be displayed by the session manager, and /C
  3192.  specifies the /C option of CMD.EXE because Start goes indirectly
  3193.  through CMD.EXE.) is as follows:
  3194.  
  3195.     Start ["program title"] [/C] command [command inputs]
  3196.  
  3197.  
  3198.  86. Installation Documentation Errors
  3199.  
  3200.  Question:
  3201.  
  3202.  The installation program (instaid.exe) for OS/2 does not match the
  3203.  documentation on Page 2 in the "Microsoft OS/2 Setup Guide" manual.
  3204.  For instance, the documentation says that option 3 is dual-boot and
  3205.  option 4 is to update a system with a previous version of OS/2. The
  3206.  install program has these reversed. Also, option 3 (no dual boot)
  3207.  installs dual boot on the system. How do I install OS/2 without
  3208.  dual-boot?
  3209.  
  3210.  Response:
  3211.  
  3212.  The documentation is incorrect concerning options 3 and 4, as you
  3213.  described. Option 3 does not work correctly; however, option 2 will
  3214.  install OS/2 on your machine without dual-boot and without formatting
  3215.  your hard disk.
  3216.  
  3217.  You will need to reformat your hard disk if it was not partitioned
  3218.  with a version of DOS that used a partitioning scheme similar to
  3219.  MS-DOS Version 3.30.
  3220.  
  3221.  
  3222.  87. DosBufReset() Works Differently In 3.x Box vs. MS-DOS 3.30
  3223.  
  3224.  In the case of a bound family application, the DosBufReset() call
  3225.  gives different results depending on whether or not the application is
  3226.  running in the DOS compatibility box under OS/2, or under a real
  3227.  MS-DOS system (e.g. MS-DOS Version 3.30). If a specific file handle
  3228.  (not "-1") is specified in the DOS compatibility box, the function
  3229.  returns a NO_ERROR status. Under MS-DOS Version 3.30, the function
  3230.  returns an ERROR_INVALID_HANDLE status.
  3231.  
  3232.  Microsoft has confirmed that this is a problem in the Version 1.06
  3233.  OS/2 SDK (Software Development Kit). We are researching this problem
  3234.  and will post new information as it becomes available.
  3235.  
  3236.  
  3237.  88. OS/2 Will Not Boot on PS/2 with a 8514 Adapter
  3238.  
  3239.  Problem:
  3240.  
  3241.  I am trying to bring up the Version 1.05 of the OS/2 SDK on my PS/2,
  3242.  which has a 8514 adapter installed in it. While the system is booting,
  3243.  I receive a Trap 0D error. The CS value returned equals 0417.
  3244.  
  3245.  Response:
  3246.  
  3247.  The above problem is known to occur on PS/2 systems with an 8514
  3248.  adapter installed. The Install disk generates a trap 0D error, and the
  3249.  CS value returned after the trap 0D error typically equals 0417. There
  3250.  is an updated version of BVSCALLS.DLL that corrects this problem. You
  3251.  can download the corrected version of BVSCALLS.DLL from the software
  3252.  library. This file can be found in the Software Library by searching
  3253.  on the filename BVSCALLS.ARC, the Q number of this article, or S12065.
  3254.  
  3255.  You will need to use the PKXARC utility to unarc the file
  3256.  BVSCALLS.ARC. BVSCALLS.ARC contains BVSCALLS.DLL and a README file.
  3257.  Please read the README file for further instructions on how to install
  3258.  the revised BVSCALLS.DLL file.
  3259.  
  3260.  
  3261.  89. Scheduling Priority of Background Threads
  3262.  
  3263.  Question:
  3264.  
  3265.  Does OS/2 give special preference to threads belonging to foreground
  3266.  processes in CPU dispatching priority?
  3267.  
  3268.  Response:
  3269.  
  3270.  Threads are scheduled independently depending on their class and
  3271.  priority. However, a thread may be boosted in priority for one of the
  3272.  following reasons:
  3273.  
  3274.  1. If the thread is in the foreground screen group
  3275.  
  3276.  2. If the thread has a keyboard focus
  3277.  
  3278.  
  3279.  90. Function Calls in Programmer's Reference No Longer Present
  3280.  
  3281.  On Page 48 of the "Microsoft Operating System/2 Software Development
  3282.  Kit Programmer's Reference, the following function calls are listed:
  3283.  
  3284.    VioSetMnLockTime
  3285.    VioSetMxSavetime
  3286.    VioGetTimes
  3287.  
  3288.  However, these functions are no longer present in OS/2.
  3289.  
  3290.  
  3291.  91. OS/2 SDK: Piping Information to an I/O Port
  3292.  
  3293.  Question:
  3294.  
  3295.  I would like to know how difficult it would be to pipe information to
  3296.  an arbitrary I/O port. I would like to be able to pipe an information
  3297.  file to an I/O port. This information would be received by another
  3298.  computer.
  3299.  
  3300.  Response:
  3301.  
  3302.  This could be accomplished with either of the following methods:
  3303.  
  3304.   1. Your application(s) would need two parts. One part would be the
  3305.      normal application that provides the I/O and creates the pipe.
  3306.      The other part would be a detached process that receives the I/O
  3307.      and transfers/outputs the data to the port. This second part
  3308.      would have to contain an IOPL segment so that it could
  3309.      communicate with the hardware.
  3310.  
  3311.   2. Your application again would have two parts. The first and second
  3312.      parts are the same as above except that the detached process no
  3313.      longer needs IOPL privilege because it communicates with a device
  3314.      driver, which in turn feeds data to the ports.
  3315.  
  3316.  Neither method is trivial, but the first method is probably less
  3317.  difficult to implement. The second method has at least one advantage
  3318.  in that interrupts are available when using a device driver, where
  3319.  they are not available when using IOPL.
  3320.  
  3321.  
  3322.  92. Definitions of Tasking Terms (Task vs. Thread)
  3323.  
  3324.  Question
  3325.     Is "task" a synonym for "thread"? Is "multitasking" the
  3326.  same thing as "multi-threading"?
  3327.  
  3328.  Response:
  3329.     Task is not a synonym for thread. There are two terms
  3330.  used in OS/2 to describe programs in execution. The first,
  3331.  threads, can be thought of as an unit of execution. They
  3332.  own their own stack and registers. They do not own any
  3333.  other resources. Threads can access any resources owned by
  3334.  the process that created the thread. However, they cannot
  3335.  access resources owned by other processes in the system
  3336.  other than through Interprocess communication system calls
  3337.  (unless those resources were set up to be shared among
  3338.  processes, e.g. shared memory). Threads are the unit of
  3339.  scheduling within OS/2; therefore, processes with more
  3340.  threads get more CPU time.
  3341.     The second program in execution, processes, owns
  3342.  resources such as memory, semaphores, devices, and files.
  3343.  Each process also owns at least one thread of execution
  3344.  containing its current state in the system. A process also
  3345.  can create other processes, as as well as creating multiple
  3346.  threads of execution within itself.
  3347.     Yes, multitasking and multithreading mean the same
  3348.  thing.
  3349.  
  3350.  
  3351.  93. Device Driver Data Segment Header Fields
  3352.  
  3353.  Question:
  3354.     On Page 78 of the device driver guide, the device driver
  3355.  header structure is defined. The fourth field in the header
  3356.  is labeled "reserved". This field was the offset to the
  3357.  interrupt routine in DOS 3.x. The OS/2 documentation
  3358.  describes no such equivalent. Is this field the interrupt
  3359.  routine offset?
  3360.  
  3361.  Response:
  3362.     The reserved field is not used for the interrupt handler
  3363.  in OS/2. This is because more than one interrupt can be
  3364.  hooked to a particular device in OS/2. Because interrupts
  3365.  can be shared (or not shared), it may be possible that OS/2
  3366.  will refuse to allow a process to hook an interrupt.
  3367.     To register a hardware interrupt handler, use the
  3368.  DevHlp_SETIRQ call (see Page 358 of the device driver
  3369.  guide).
  3370.  
  3371.  
  3372.  94. Definitions of the Terms Program, Application, and Process
  3373.  
  3374.  Question:
  3375.     Are "program" and "application" synonyms for "process"?
  3376.  
  3377.  Response:
  3378.     No. Program, application and process are terms that have
  3379.  unique meanings within OS/2.
  3380.     An application is something you buy from a software
  3381.  company. Applications can contain more that one .EXE file
  3382.  and, therefore, more than one program.
  3383.     A program is an .EXE file that can be run either from
  3384.  the command shell or from another program using the
  3385.  DOSEXECPGM system call. A program contains at least one
  3386.  process, and each process owns at least one thread.
  3387.     Processes own resources such as memory, semaphores,
  3388.  devices, and files. Each process also owns at least one
  3389.  thread of execution that contains its current state in the
  3390.  system. A process also can create other processes, as well
  3391.  as creating multiple threads of execution within itself.
  3392.  
  3393.  
  3394.  95. OS/2 SDK: Floating Point 80387 Coprocessor Run-Time Problems
  3395.  
  3396.  Problem:
  3397.  
  3398.  After installing the OS/2 Software Development Kit (SDK) Version 1.05,
  3399.  my program, which previously worked correctly under SDK Version 1.03,
  3400.  now returns the following error:
  3401.  
  3402.     run-time error M6101:  MATH
  3403.     - floating point error: invalid
  3404.  
  3405.  Response:
  3406.  
  3407.  The above problem will occur with any machine that attempts to use the
  3408.  80387 coprocessor with OS/2 SDK Version 1.05. Microsoft has confirmed
  3409.  this to be a problem in Version 1.05. This problem was corrected in
  3410.  OS/2 SDK Version 1.06.
  3411.  
  3412.  There is a patch available in the Software Library to correct this
  3413.  problem with the OS/2 SDK Version 1.05. This file can be found by
  3414.  searching on the filename 386387.ARC, the Q number of this article, or
  3415.  S12063.
  3416.  
  3417.  386387.ARC has been archived with PKARC, so you will need to unarchive
  3418.  it with PKXARC. The 386387.ARC file contains the file 386_387.PAT. To
  3419.  install the patch, run the PATCH.EXE utility that comes with OS/2 on
  3420.  the file 386_387.PAT.
  3421.  
  3422.  Specifically, with PATCH.EXE on your path, enter the following command
  3423.  at the command prompt and then reboot your machine:
  3424.  
  3425.     patch 386_387.pat /a
  3426.  
  3427.  The SDK demos\apps\mandel\mandel.exe file also returns this error, and
  3428.  a simple C program (compiled with /AL /Lp /Od /Zi) such as the
  3429.  following also causes the machine to hang, forcing a power down to
  3430.  restart:
  3431.  
  3432.       #include <stdio.h>
  3433.       main()
  3434.       {   double x;
  3435.        x = 3.4;
  3436.        x += 7.2;
  3437.        printf("X = %f\n",x);
  3438.       }
  3439.  
  3440.  
  3441.  96. Interrupt Handling
  3442.  
  3443.  OS/2
  3444.  ISVONLY |
  3445.  
  3446.  Question:
  3447.     Does OS/2 provide a capability to handle interrupts at
  3448.  the application (not device driver) level? If so, does it
  3449.  also provide a capability to guarantee that an application
  3450.  buffer will remain permanently in memory for DMA
  3451.  operations?
  3452.  
  3453.  Response:
  3454.     To access interrupts, you must write a device driver and
  3455.  use the SetIRQ DevHelp call to set up the interrupt handler
  3456.  routine. To lock a segment while doing DMA, use the Lock
  3457.  and Unlock DevHelp routines within the device driver. (This
  3458.  method must be used because the device drivers are kept
  3459.  resident in the kernel and, therefore, are not swapped out
  3460.  as ring 3 code can be. If they were swapped out, it would
  3461.  increase the interrupt latency time greatly if the code to
  3462.  service the interrupt had to be swapped in at interrupt
  3463.  time. Also, code that handles interrupt has to have IOPL
  3464.  privilege level that ring 3 code does not have.)
  3465.     The tools supplied with the OS/2 SDK currently do not
  3466.  enable debugging at kernel level, the level at which device
  3467.  drivers operate. Tools will be supplied in a future update
  3468.  to the SDK to enable debugging of device drivers.
  3469.  
  3470.  
  3471.  97. Keystroke Monitor Example
  3472.  
  3473.  Question:
  3474.     Could you show us an example of DOSMONOPEN, DOSGETINFOSEG,
  3475.  DOSMONREG, DOSMONREAD, DOSMONWRITE, and DOSMONCLOSE usage?
  3476.  
  3477.  Response:
  3478.     See the MONITORS example program that came with the OS/2 Software
  3479.  Development kit for example of a keyboard device monitor.
  3480.  
  3481.  
  3482.  98. B1 and B2 Stepping Regarding 286 and 386
  3483.  
  3484.  Question:
  3485.     What are "B1 and B2 stepping" with regard to the 286 and 386?
  3486.  
  3487.  Response:
  3488.     They refer to different versions of the chip. MS OS/2 works with all known
  3489.  production levels of the 286 and 386, so these terms aren't important in this
  3490.  case.
  3491.  
  3492.  
  3493.  99. Hercules Display Adapter Support
  3494.  
  3495.  Question:
  3496.     Is graphics mode on the Hercules display adapter supported by MS OS/2,
  3497.  including the Presentation Manager?
  3498.  
  3499.  Response:
  3500.     The SDK does not currently support Hercules specific modes. Any OEM who
  3501.  licenses MS OS/2 can add support for additional peripherals.
  3502.  
  3503.  
  3504.  100. Using Named Pipes with DosBufReset() and DosWriteAsync()
  3505.  
  3506.  Question:
  3507.  
  3508.  I have a message-named pipe. When I write to it, I use DosWrite(). Is
  3509.  it necessary to do a DosBufReset() before doing a
  3510.  DosDisconnectNmPipe()? So far the client has already closed the pipe,
  3511.  breaking the connection; therefore, DosBufReset() is always returning
  3512.  a broken-pipe error code. This seems to be an unnecessary call. Is
  3513.  DosBufReset() necessary only with DosWriteAsync()?
  3514.  
  3515.  Response:
  3516.  
  3517.  Yes, you still may need to do a DosBufReset() before doing a
  3518.  DosDisconnectNmPipe(). If the server application has written the last
  3519.  piece of data to the pipe and the client reads this data and realizes
  3520.  that it has to close the pipe, you still need the flush. It would be
  3521.  possible for the server application to write the last piece of data,
  3522.  then disconnect the pipe before the client actually reads the "EOF"
  3523.  information that was just written (pipes can have write-behind
  3524.  capabilities; see below for more information).
  3525.  
  3526.  DosWriteAsync() is very different. The DosBufReset() wouldn't be
  3527.  useful until after the DosWriteAsync() semaphore has been cleared.
  3528.  DosWriteAsync() simply postpones the call to DosWrite(). In other
  3529.  words, when you call DosWriteAsync(), a thread is created that will in
  3530.  turn call DosWrite(). So, you don't have to wait for the DosWrite() to
  3531.  complete, but this also means that the data may not get written until
  3532.  the semaphore gets cleared. DosBufReset() has no effect on data that
  3533.  hasn't actually been written.
  3534.  
  3535.  You could get DosWriteAsync() functionality simply by queuing up all
  3536.  write requests (e.g. in a linked list) and having a thread dedicated
  3537.  to "DosWrite-ing" all the requests (in any order that you choose). If
  3538.  you coded this properly, it would be better than DosWriteAsync(),
  3539.  because DosWriteAsync() creates threads (and stacks) and destroys them
  3540.  all the time. There are other limitations of the call that could also
  3541.  be improved upon, i.e., FIFO type of writing, etc.
  3542.  
  3543.  
  3544.  101. High-Density Disks Required for OS/2
  3545.  
  3546.  Question:
  3547.  
  3548.  Why is a high-density floppy disk required for MS OS/2?
  3549.  
  3550.  Response:
  3551.  
  3552.  The disk is required because all the files needed to boot the
  3553.  installation disk will not fit on a low-density disk. Once MS OS/2 is
  3554.  installed on the hard disk, the high-density disk drive is no longer
  3555.  needed.
  3556.  
  3557.  
  3558.  102. OS/2 SDK: MouOpen() Handle Value Information
  3559.  
  3560.  Problem:
  3561.  
  3562.  When issuing a MouOpen() call multiple times in the same screen group,
  3563.  the handle that is returned from the first MouOpen() call is different
  3564.  than the handle returned by the second MouOpen() call. I thought that
  3565.  the same handle would be returned by each of the MouOpen() calls if
  3566.  they were issued in the same screen group.
  3567.  
  3568.  Response:
  3569.  
  3570.  Each process is required to do a MouOpen() call. It is not possible to
  3571.  pass this handle on to any other process. Each process within a screen
  3572.  group will be getting a handle to the same logical mouse, but the
  3573.  handle value itself may be different. No process should rely on a
  3574.  specific value of the mouse handle. Each process should just call
  3575.  MouOpen(), verify that the call did not return an error, then use the
  3576.  mouse handle that is returned on all later calls to MOU routines that
  3577.  require a mouse handle, without caring what the specific value of the
  3578.  handle is.
  3579.  
  3580.  
  3581.  103. Managing Instance Data
  3582.  
  3583.  Question:
  3584.     Please provide detailed documentation AND a sample
  3585.  program (in C or assembler) that demonstrates how to create
  3586.  and manage instance data in a user created dynalink
  3587.  module.
  3588.  
  3589.  Response:
  3590.     Unfortunately, creating and managing instance data in
  3591.  dynalink libraries is not well described in the current
  3592.  documentation. This will be fixed in the next update to the
  3593.  SDK. The next update will also provide sample programs to
  3594.  demonstrate dynalink libraries as well as managing instance
  3595.  data.
  3596.  
  3597.  
  3598.  104. Writing a Keyboard Monitor, DosMonReg Call
  3599.  
  3600.  OS/2
  3601.  ISVONLY |
  3602.  
  3603.  Question:
  3604.     I am trying to write a keyboard monitor, but am having
  3605.  trouble with the DosMonReg call. On Page 175 of the SDK
  3606.  programmer's reference, it describes the "Index" parameter
  3607.  of this call as "a word that specifies a device-specific
  3608.  value." What does this mean? What value should I be giving
  3609.  to this parameter?
  3610.  
  3611.  Response:
  3612.     The meaning of "Index" depends on what device the
  3613.  monitor is for. For the keyboard, it is the ID for the
  3614.  screen group to be monitored. This information can be found
  3615.  on Page 42 of the SDK device driver guide. Since a keyboard
  3616.  monitor will probably be run by being DETACHed, it will
  3617.  have no screen group associated with it--hence your
  3618.  application will want to know the ID of the current
  3619.  foreground screen group. This can be found by using the
  3620.  DosGetInfoSeg call. This call will return addresses for
  3621.  local and global information segments; the "Current
  3622.  Foreground Screen Group" field in the global infoseg
  3623.  contains the value that should be used for the "Index"
  3624.  parameter of DosMonReg.
  3625.  
  3626.  
  3627.  105. Running MS OS/2 on IBM PC-XTs
  3628.  
  3629.  Question:
  3630.     We are upgrading our IBM PC-XTs with accelerator cards
  3631.  containing an 80286. Will we be able to run MS OS/2 on
  3632.  these machines?
  3633.  
  3634.  Response:
  3635.     If the accelerator board manufacturer provides a version
  3636.  of MS OS/2 for the card it could work, depending on the
  3637.  hardware. The standard SDK version probably will not work,
  3638.  because the XT has a different hard disk controller and
  3639.  interrupts.
  3640.  
  3641.  
  3642.  106. Hardware That Supports MS OS/2
  3643.  
  3644.  Question:
  3645.     What hardware technology best exploits the capabilities
  3646.  of MS OS/2? For example, is a 12 MHz Compaq Deskpro 286
  3647.  faster than a 10 MHz PS/2 model 60?
  3648.  
  3649.  Response:
  3650.     This is a very complex question and depends on your
  3651.  application. Obviously if your application is largely CPU
  3652.  bound then a 12 MHz CPU is better than 10. If your
  3653.  application is disk bound then look at disk seek and
  3654.  transfer rates. If you expect to use the Presentation
  3655.  Manager heavily look at the quality of the graphics
  3656.  displays available.
  3657.  
  3658.  
  3659.  107. Running MS OS/2 on a 386
  3660.  
  3661.  Question:
  3662.     Will MS OS/2 run on a 386-based machine? It was stated
  3663.  MS OS/2 does not save the extended register set when
  3664.  performing a context switch. Although MS OS/2 does not
  3665.  necessarily have to "take advantage" of 386-specific
  3666.  instructions, shouldn't it be "aware" of the fact that it
  3667.  is running on a 386 and adjust accordingly?
  3668.  
  3669.  Response:
  3670.     MS OS/2 runs on a 386 and can take advantage of the mode
  3671.  switch capabilities of the 386. Other than that, the
  3672.  current version of OS/2 does not exploit 386 specific
  3673.  features, but runs as a fast 286. There is no 32 bit
  3674.  support at the application level.
  3675.  
  3676.  
  3677.  108. Mode Switching Using 286 Pin Compatible 386
  3678.  
  3679.  Question:
  3680.     In light of the way mode switching has been implemented on a 80286,
  3681.  how much of a performance improvement might there be if an IBM-AT
  3682.  (8 MHz) had an 80286 pin-compatible 80386 installed?
  3683.  
  3684.  Response:
  3685.     The mode switching technique is an OEM specific item; OEMs will
  3686.  choose the fastest way appropriate to their hardware. There is nothing
  3687.  in MS OS/2 that assumes a particular technique. In most cases the
  3688.  overhead of mode switching is negligible and not detectable, so even
  3689.  if you have a much faster mode switch method you may not detect any
  3690.  overall improvement in system performance for your particular
  3691.  environment.
  3692.  
  3693.  
  3694.  109. Disk Space Needed for OS/2 SDK and Swap File
  3695.  
  3696.  Question:
  3697.     How much disk space will be needed for the full MS OS/2 SDK and a
  3698.  swap file?
  3699.  
  3700.  Response:
  3701.     The first release contains 8 1.2 megabyte floppies, not all of which are
  3702.  filled to capacity. Subsequent releases, especially those with the
  3703.  Presentation Manager, will need more. The swap file is usually less than 1
  3704.  megabyte unless you are swapping heavily (not recommended). So, generally,
  3705.  if you have 10 megabytes available you should be safe.
  3706.  
  3707.  
  3708.  110. Error When Running Two Programs with the Same Name
  3709.  
  3710.  OS/2
  3711.  ISVONLY |
  3712.  
  3713.  Question:
  3714.     Does running two programs with the same name cause an error?
  3715.  
  3716.  Response:
  3717.     In the SDK release, if a program is loaded and running in the system, an
  3718.  invocation of a different program with the same name as that contained in the
  3719.  program module will run a second copy of the existing program module without
  3720.  searching the disk. The result is that the second process may end up running
  3721.  the wrong program.
  3722.     The name in the program module is defined by the "NAME" statement in the
  3723.  linker definition file. This prevents renaming a program after it has been
  3724.  linked. The temporary solution is to not rename a module after it has been
  3725.  linked. This problem will be corrected in an update to the OS/2 SDK.
  3726.  
  3727.  
  3728.  111. Summary of the Functions in Each Dynamic Link Library
  3729.  
  3730.  Question:
  3731.  
  3732.  On the OS/2 setup disk there are a number of dynamic link libraries
  3733.  (DLLs). Could you describe the function of each library?
  3734.  
  3735.  Response:
  3736.  
  3737.  The dynamic link libraries are used by the system to perform the
  3738.  system functions of OS/2. The following is a summary of the functions
  3739.  in each library.
  3740.  
  3741.  The following libraries contain the base subsystem calls for each
  3742.  device. These libraries are used by the associated API libraries:
  3743.  
  3744.  Library              Device
  3745.  
  3746.  BKSCALLS.DLL         Keyboard
  3747.  BMSCALLS.DLL         Mouse
  3748.  BVSCALLS.DLL         Video
  3749.  
  3750.  The following contain the API functions for the various sections of
  3751.  the system:
  3752.  
  3753.  Library               Function
  3754.  
  3755.  DOSCALL1.DLL          Ring 3 DOS functions (DOSXxx)
  3756.  ANSICALL.DLL          ANSI screen control (used by BVSCALLS
  3757.                                             and BKSCALLS)
  3758.  
  3759.  VIOCALLS.DLL          Video Input / Output (VioXxx)
  3760.  KBDCALLS.DLL          Keyboard functions (KbdXxx)
  3761.  MONCALLS.DLL          Monitor (MonXxx)
  3762.  MOUCALLS.DLL          Mouse calls (MouXxx)
  3763.  QUECALLS.DLL          Queue calls (QueXxx)
  3764.  IPCCALLS.DLL          LAN Manager calls (on LAN Manager disk)
  3765.  
  3766.  MSG.DLL               Message Retriever (MsgXxx)
  3767.  NLS.DLL               National Language Support (NlsXxx)
  3768.  SESMGR.DLL            Session Manager (screen-switching support
  3769.                                         for shell)
  3770.  
  3771.  SPOOLCP.DLL           Used for the calls that are shared between
  3772.                        the spooler routines and the print routines
  3773.  
  3774.  
  3775.  112. Value Returned Is FEOOH ORed with Error Code
  3776.  
  3777.  Page 81 of the "Microsoft Operating System/2 Software Development Kit
  3778.  Device Drivers Guide" is incorrect. The middle of the page incorrectly
  3779.  states that the error code that is returned is FEOOH ANDed with the
  3780.  error code. It should state that the value returned is FEOOH ORed with
  3781.  the error code.
  3782.  
  3783.  
  3784.  113. Running Programs in Protected Mode
  3785.  
  3786.  Question:
  3787.     When running in the protected mode, how does the system know to run
  3788.  programs in the DOS compatibility environment?
  3789.  
  3790.  Response:
  3791.     It doesn't; the user has to switch to the DOS compatibility environment
  3792.  in order to run real mode applications.
  3793.  
  3794.  
  3795.  114. List of Programs Not Running
  3796.  
  3797.  Question:
  3798.     Will you publish a list of programs that do not run in compatibility
  3799.  environment?
  3800.  
  3801.  Response:
  3802.     This will depend in part on the characteristics of the underlying
  3803.  hardware. We expect OEM hardware manufacturers will adapt MS OS/2 to
  3804.  their hardware and provide information on compatibility, just as they
  3805.  do today with DOS 3.x.
  3806.  
  3807.  
  3808.  115. Installing a Mouse
  3809.  
  3810.  Problem:
  3811.  
  3812.  We have been unable to get any OS/2 or real-mode application to
  3813.  recognize a Microsoft serial mouse on the COM1: port. We have an entry
  3814.  in our CONFIG.SYS that looks like the following:
  3815.  
  3816.     device=c:\os2sys\mousea02.sys mode=b
  3817.  
  3818.  The driver loads correctly (per messages at OS/2 startup), but any
  3819.  applications that use the mouse (CodeView for example) do not
  3820.  recognize it as being installed.
  3821.  
  3822.  Response:
  3823.  
  3824.  You need to also install the POINTDD.SYS device driver in your
  3825.  CONFIG.SYS file. The CONFIG.SYS file should contain the following two
  3826.  lines:
  3827.  
  3828.     device=pointdd.sys
  3829.     device=mouseaXX.sys   where XX is either 02,03,04 depending on
  3830.                           the type of mouse you have on your machine
  3831.                           (see the supplement to the installation guide
  3832.                           for information on which driver to use with
  3833.                           your mouse)
  3834.  
  3835.  
  3836.  116. Mode Switch Time Penalty on 386
  3837.  
  3838.  Question:
  3839.     What is the mode switch time penalty on a 386?
  3840.  
  3841.  Response:
  3842.     See the Intel 80386 Programmer's Reference Manual, Section 14.5, for a
  3843.  description of the general method used to mode switch a 386. We use something
  3844.  similar to this. You could estimate the time from this description and a
  3845.  knowledge of your machine's CPU and memory performance. Mode switching is not
  3846.  an atomic item you can observe in MS OS/2 since it is normally part of a task
  3847.  switch that involves many other things in addition to switching the CPU.
  3848.  
  3849.  
  3850.  117. OS/2 Needs Device Larger Than Disk
  3851.  
  3852.  Question:
  3853.  
  3854.  Is there any reason why an MS OS/2 workstation practically requires a
  3855.  hard disk? Can MS OS/2 swap over the network?
  3856.  
  3857.  Response:
  3858.  
  3859.  MS OS/2, with all the utility programs, is bigger than one disk, so
  3860.  you need some larger device to put the software on. This could be a
  3861.  network device. Likewise the swapper uses a file specified in
  3862.  CONFIG.SYS. This file could reside over the network if your network
  3863.  has sufficient performance to be used as a swap device.
  3864.  
  3865.  
  3866.  118. Using DosLoadModule() with a File Extension to Load DLL
  3867.  
  3868.  Question:
  3869.  
  3870.  Is it true that DosLoadModule() will not load a DLL (Dynamic Linked
  3871.  Library) if a file extension is provided for the module name (even if
  3872.  the extension is .DLL)?
  3873.  
  3874.  Response:
  3875.  
  3876.  Normally, DosLoadModule() will not accept a filename with an
  3877.  extension, even a .DLL extension. The exception to this rule is when a
  3878.  path is specified. Starting with OS/2 Version 1.10 (OS/2 SDK Version
  3879.  1.06), a pathname can be specified to a module loaded by the
  3880.  DosLoadModule() call. In this case, the extension, if one exists on
  3881.  the filename, is REQUIRED. For instance, assuming that
  3882.  LIBPATH=c:\os2\dll;c:\dll, the following module names are valid with
  3883.  DosLoadModule():
  3884.  
  3885.  Filename                               Module Name Parameter
  3886.  ---------------------------------------------------------------------
  3887.  c:\dll\module.dll                      "module"
  3888.  c:\dll\module.dll                      "c:\\dll\\module.dll"
  3889.  c:\app1\xxx.dll                        "c:\\app1\\xxx.dll"
  3890.  c:\app1\yyy                            "c:\\app1\\yyy"
  3891.  c:\app1\courier.fon                    "c:\\app1\\courier.fon"
  3892.  
  3893.  The following would NOT be valid:
  3894.  
  3895.  Filename                               Module Name Parameter
  3896.  ---------------------------------------------------------------------
  3897.  c:\dll\module.dll                      "module.dll"
  3898.  c:\dll\module.dll                      "c:\\dll\\module"
  3899.  c:\app1\xxx.dll                        "xxx.dll"
  3900.  
  3901.  Note: When the module either is not on the LIBPATH or does not have a
  3902.  .DLL extension, you must specify the full path, including the file
  3903.  extension, to DosLoadModule(). Also note the use of the double
  3904.  backslashes when using strings in the C language.
  3905.  
  3906.  
  3907.  119. BIOS Dependencies
  3908.  
  3909.  Question:
  3910.     Microsoft has stated several times that MS OS/2 does not
  3911.  depend upon the ROM BIOS. The compatibility environment
  3912.  does depend on the BIOS, however. Is this IBM's CBIOS or
  3913.  ABIOS?
  3914.  
  3915.  Response:
  3916.     Whether to implement device driver code in ROM or RAM is
  3917.  an OEM decision. On the PC/AT version (i.e., the SDK
  3918.  version) certainly we do utilize some of the ROM routines
  3919.  when running in the compatibility environment. Other OEM
  3920.  manufacturers could decide not to do this. MS OS/2 has no
  3921.  inherent dependency on driver code being in ROM.
  3922.  
  3923.  
  3924.  120. Applications That Use the EGA
  3925.  
  3926.  Question:
  3927.     Are there any known problems running DOS 2.x/3.x applications that use the
  3928.  EGA in the DOS compatibility environment?
  3929.  
  3930.  Response:
  3931.     Yes, some of the EGA registers are write-only and if the application uses
  3932.  those registers the state of the screen may not be fully restorable after a
  3933.  screen switch. Some newer EGA implementations are correcting this problem and
  3934.  we expect OEM manufacturers will take advantage of the enhanced hardware.
  3935.  
  3936.  
  3937.  121. Monitor Applying to a Screen Group
  3938.  
  3939.  Question:
  3940.     Does a monitor apply only to a screen group, or is it system-wide?
  3941.  
  3942.  Response:
  3943.     For the screen group virtualized devices (e.g. KBD, mouse) there is a
  3944.  monitor chain per screen group. For the global devices (e.g. printer) there i
  3945.  one chain per device. You can register on any chain(s).
  3946.  
  3947.  
  3948.  122. Detecting Other Device Monitors
  3949.  
  3950.  Question:
  3951.     Is it possible to determine if other device monitors are installed?
  3952.  
  3953.  Response:
  3954.     No, it is not possible at this time.
  3955.  
  3956.  
  3957.  123. Installable File System (IFS)
  3958.  
  3959.  Question:
  3960.     When is a replacement file system anticipated? Will it have features beyon
  3961.  just breaking the 32 megabyte barrier such as longer file names, mixed case
  3962.  file names, and links?
  3963.  
  3964.  Response:
  3965.     A later version of MS OS/2 will have an installable file system (IFS) that
  3966.  may have some or all of the features mentioned. The 32 megabyte limitation ma
  3967.  be eliminated sooner.
  3968.  
  3969.  
  3970.  124. MS OS/2 Interrupting Applications
  3971.  
  3972.  Question:
  3973.     How does MS OS/2 determine how often real mode applications will be
  3974.  interrupted?
  3975.  
  3976.  Response:
  3977.     They are scheduled similar to foreground protected mode tasks. The
  3978.  scheduler is driven off a periodic clock tick.
  3979.  
  3980.  
  3981.  125. OS/2 SDK: QuickHelp DosExecPgm() Documentation Error
  3982.  
  3983.  The example in the QuickHelp database included with the Version 1.06
  3984.  OS/2 Software Development Kit (SDK) for the OS/2 API DosExecPgm() has
  3985.  a typographical error in it. In this example, the third parameter, the
  3986.  synchronous/trace flags parameter, uses "EXEC_ASYNCH". It should
  3987.  instead use "EXEC_ASYNC". This error will be corrected in a future
  3988.  release of the QuickHelp database.
  3989.  
  3990.  Thus, the correct example for the DosExecPgm() API should be as
  3991.  follows:
  3992.  
  3993.  CHAR achFailName[128];
  3994.  RESULTCODES rescResults;
  3995.  DosExecPgm(achFailName,                 /* object-name buffer */
  3996.      sizeof(achFailName),                /* length of buffer   */
  3997.      EXEC_ASYNC,                         /* async flag         */
  3998.      "abc = 0\0",                        /* argument string    */
  3999.      0,                                  /* environment string */
  4000.      &rescResults,                       /* address of result  */
  4001.      "abc.exe");                         /* name of program    */
  4002.  
  4003.  
  4004.  126. FLAGS Is Not Preserved in OS/2 Calls
  4005.  
  4006.  Question:
  4007.  
  4008.  Is it the programmer's responsibility to save and restore the FLAGS
  4009.  register on all calls?
  4010.  
  4011.  Response:
  4012.  
  4013.  All of the OS/2 calls are specified as returning a value in AX, and
  4014.  they will preserve the state of all of the registers EXCEPT for the
  4015.  FLAGS register. On return from a system call the state of the FLAGS
  4016.  register is undefined. However, one exception is made for the
  4017.  DIRECTION flag. If the DIRECTION flag is cleared when the call is
  4018.  made, it is guaranteed to be cleared when the call returns. It is not
  4019.  guaranteed to be returned set if it was set when the call was made.
  4020.  
  4021.  
  4022.  127. Keystroke Monitor Data Packet MonFlagWord Documentation Error
  4023.  
  4024.  Microsoft has confirmed that there is a documentation error on Pages
  4025.  35-36 of the "Microsoft Operating System/2 Device Drivers Guide." On
  4026.  Pages 35-36, the guide states the following:
  4027.  
  4028.     The low byte of the MonFlagWord contains the original scan code
  4029.     as read from the hardware. The high byte of the MonFlagWord
  4030.     contains the monitor dispatcher flags.
  4031.  
  4032.  The correct description is that the MonFlagWord() lower byte contains
  4033.  the monitor dispatcher flags and the high byte contains the original
  4034.  scan code.
  4035.  
  4036.  
  4037.  128. OS/2 SDK: Mixing the Use of Numbers and Names in .DEF File
  4038.  
  4039.  Question:
  4040.  
  4041.  I would like to keep some of the functions that must be exported from
  4042.  a DLL (dynamic linked library) semiprivate (i.e., use numbered rather
  4043.  than named functions). However, I would like other functions to be
  4044.  named so that they can be easily called from other applications. Is it
  4045.  possible to mix both named and numbered EXPORT statements in the same
  4046.  .DEF file? If so, what restrictions are there?
  4047.  
  4048.  Response:
  4049.  
  4050.  To make a DLL function visible to an application, you must include the
  4051.  name in the EXPORTS list in the .DEF file.
  4052.  
  4053.  To make a DLL function available, but not visible, use the @ ordinal
  4054.  directive, which tells OS/2 to make the function loadable by ordinal
  4055.  only and removes the internal name of the function from OS/2's list of
  4056.  names for the entry points to the DLL. The ordinal number is specified
  4057.  by the programmer. OS/2 does not have defaults for the ordinal
  4058.  numbers.
  4059.  
  4060.  When an ordinal directive is given for a function, the name of the
  4061.  function is not visible to an application. However, if you include the
  4062.  directive RESIDENTNAME on the same line as the function export
  4063.  declaration, OS/2 will retain the name of the function so that an
  4064.  application can call the function either by ordinal or by name.
  4065.  
  4066.  As long as the proper syntax is used, there is no restriction on the
  4067.  combinations of attributes given to any one function, except that the
  4068.  ordinal numbers must be unique within the DLL declarations.
  4069.  
  4070.  
  4071.  129. Licensing LAN Manager
  4072.  
  4073.  OEMs wishing to license the OS/2 LAN Manager should contact their
  4074.  Microsoft account representative. The OS/2 LAN Manager is an OEM
  4075.  product and licensing is subject to the terms and conditions of a
  4076.  systems software contract.
  4077.  
  4078.  
  4079.  130. OS/2 SDK: IPC Support for LAN Manager for DOS 3.x
  4080.  
  4081.  Question:
  4082.  
  4083.  How can an MS-DOS Version 3.x (3.00, 3.10, 3.20, 3.21, 3.22, 3.30,
  4084.  3.30a) application access the pipes from an MS-DOS node to an OS/2
  4085.  server? What must be added to MS-DOS to make this possible?
  4086.  
  4087.  Response:
  4088.  
  4089.  The MS-DOS 3.x program must issue Interrupt 21H, Function 3DH (open
  4090.  file), where the filename is of the form \\COMPUTERNAME\PIPE\PIPENAME.
  4091.  The program could also use the Family API DosOpen() call with such a
  4092.  pathname. The remote pipe handle can now be read and written like a
  4093.  normal file or local pipe handle. An additional set of named-pipe
  4094.  specific library functions for MS-DOS 3.x supports extended pipe
  4095.  functions such as DosPeekNmPipe() and DosTransactNmPipe().
  4096.  
  4097.  The MS-DOS 3.x program could either issue Interrupt 21H, Function 3DH,
  4098.  or it could use sopen(). The share security flags must be set to
  4099.  something other than "0x00". If the assembler interface is used, the
  4100.  system must first establish a connection to the server's "IPC$" by
  4101.  performing the following command:
  4102.  
  4103.     NET USE \\SERVER\IPC$
  4104.  
  4105.  DosOpen() may be used only if the application is bound. There is no
  4106.  support for the DosOpen() API in real-mode-only applications.
  4107.  
  4108.  
  4109.  131. OS/2 SDK: IPC Pipes Are Not Prioritized
  4110.  
  4111.  Question:
  4112.  
  4113.  Most queuing systems support the concept of priority. Can IPC
  4114.  (inter-process communication) pipes be prioritized?
  4115.  
  4116.  Response:
  4117.  
  4118.  Pipes have no concept of priority. The mailslot API, which is more
  4119.  queue-like than pipes, does support priority of queued messages.
  4120.  
  4121.  
  4122.  132. OS/2 SDK: Pooling Devices and Using Remote Ports
  4123.  
  4124.  Question:
  4125.  
  4126.  Will special networking features such as pooling devices or using
  4127.  remote COM and LPT ports require that both the server and workstation
  4128.  run OS/2 and LAN Manager Version 1.00, or must just the server run
  4129.  OS/2 and LAN Manager Version 1.00?
  4130.  
  4131.  Response:
  4132.  
  4133.  Printer pooling for spooled print service requires a LAN Manager
  4134.  server. Existing MS-NET or IBM PC LAN workstations can print to a LAN
  4135.  Manager server and take advantage of printer pooling.
  4136.  
  4137.  Access to remote COM and LPT devices directly (without spooling)
  4138.  requires that both ends be running OS/2 (and therefore LAN Manager).
  4139.  This is because the remote device service supports direct I/O to the
  4140.  remote device drivers themselves, and OS/2 device drivers have
  4141.  different interfaces than MS-DOS drivers.
  4142.  
  4143.  
  4144.  133. OS/2 SDK: Client and Server Can Be One and the Same
  4145.  
  4146.  Question:
  4147.  
  4148.  With named pipes, can the client PC and server PC be one and the same?
  4149.  
  4150.  Response:
  4151.  
  4152.  Yes; both named pipes and mailslots will work between local processes
  4153.  exactly the same way that they work between remote ones. Local named
  4154.  pipes and mailslots do NOT require the client PC to be running the
  4155.  server software. The client software provides this ability for local
  4156.  IPC (inter-process communication). Remote IPC does require that at
  4157.  least one of the two ends be running the server-level function.
  4158.  Because the server software is a superset of the workstation software,
  4159.  any workstation can run both client and server functions.
  4160.  
  4161.  Also, in OS/2 Version 1.10, support for named pipes was moved into the
  4162.  OS/2 kernel. Thus, local named pipes can be used without the OS/2 LAN
  4163.  Manager being installed.
  4164.  
  4165.  
  4166.  134. OS/2 SDK: DOS File Sharing Functions
  4167.  
  4168.  Question:
  4169.  
  4170.  In the DOS compatibility environment, all DOS Int 21H file sharing and
  4171.  record locking functions are supported.
  4172.  
  4173.  
  4174.  135. OS/2 SDK: Freeing Memory with DosFreeSeg()
  4175.  
  4176.  Question:
  4177.  
  4178.  I would like clarification on the ability to allocate and free
  4179.  segments. I use DosAllocSeg() to generate segments for my data
  4180.  storage. I then set the segment by using DosSubSet(), and allocate
  4181.  actual memory by using DosSubAllocate(). To return the memory back to
  4182.  the operating system, I use DosSubFree() to remove the actual memory
  4183.  allocation. Then, when the segment is empty, I use DosFreeSeg() to
  4184.  free the actual segment.
  4185.  
  4186.  If I do not use DosSubFree(), may I free the entire segment with only
  4187.  the DosFreeSeg() function call? When I want to free the segment I have
  4188.  finished with the entire memory used in that segment.
  4189.  
  4190.  Response:
  4191.  
  4192.  Yes, you can use DosFreeSeg() to free up the memory area. The
  4193.  following program demonstrates this fact:
  4194.  
  4195.  #define INCL_BASE
  4196.  #include <os2.h>
  4197.  
  4198.  void main(void);
  4199.  
  4200.  void main(void)
  4201.  {
  4202.  
  4203.      SEL     sel;
  4204.      USHORT  usSegAttribs = SEG_NONSHARED;
  4205.      USHORT  usOffset;
  4206.  
  4207.      printf("Result of DosAllocSeg is %u\n",
  4208.             DosAllocSeg(200,&sel,usSegAttribs));
  4209.  
  4210.      printf("Result of DosSubSet is %u\n",
  4211.             DosSubSet(sel,0x0001,200));
  4212.  
  4213.      printf("Result of DosSubAlloc is %u\n",
  4214.             DosSubAlloc(sel,&usOffset,30));
  4215.  
  4216.  /* The above call keeps part of the segment in use to ensure
  4217.     that an error will occur if the procedure is invalid.        */
  4218.  
  4219.      printf("Result of DosFreeSeg is %u\n",
  4220.             DosFreeSeg(sel));
  4221.  
  4222.  }
  4223.  
  4224.  No errors are returned; therefore, this code is valid. Because you are
  4225.  finished with the variables involved in the DosSubAlloc() process,
  4226.  there is no need to free them up individually.
  4227.  
  4228.  
  4229.  136. OS/2 SDK: Real-Mode and Protected-Mode NetBIOS Drivers
  4230.  
  4231.  Question:
  4232.  
  4233.  What are the major differences between the real-mode and
  4234.  protected-mode NetBIOS drivers? What is the penalty on NetBIOS access
  4235.  from protected mode?
  4236.  
  4237.  Response:
  4238.  
  4239.  The protected-mode NetBIOS allows multiple NetBIOS drivers to be
  4240.  installed, even for different kinds of net cards. The interface also
  4241.  prevents conflicts among multiple applications accessing the same
  4242.  NetBIOS driver. For example, one application cannot reset an adapter
  4243.  that another application is using. The protected-mode NetBIOS
  4244.  redefines the NCP_POST@ field to be a semaphore handle rather than a
  4245.  calling address. All buffer addresses are virtual. Only one
  4246.  protected-mode NetBIOS interface is available (Interrupt 5CH).
  4247.  
  4248.  
  4249.  137. VioPrtSc() Was Removed from Version 1.10 API.LIB
  4250.  
  4251.  The Family API function VioPrtSc() is not included in the 1.10 release
  4252.  of API.LIB.
  4253.  
  4254.  VioPrtSc() was removed because it was considered unstable, and was
  4255.  also listed as an API for systems programs to use, not application
  4256.  programs. If you need to use this API, you can move it from the old
  4257.  API.LIB to the new one; however, Microsoft does not support this
  4258.  change. Otherwise, you can write your own version of VioPrtSc() for
  4259.  real mode and link with that library.
  4260.  
  4261.  
  4262.  138. OS/2 SDK: Forced User Response from Background Task
  4263.  
  4264.  Question:
  4265.  
  4266.  Is there any way to interrupt the DOS compatibility environment and
  4267.  force a user to respond to a message from a background task or notify
  4268.  the user that he or she has mail, no matter what he or she is doing on
  4269.  the system at the time?
  4270.  
  4271.  Response:
  4272.  
  4273.  Yes, the VioPopup() system call is used by a background application
  4274.  that needs to immediately display a message to the user without
  4275.  becoming the active foreground process.
  4276.  
  4277.  For more information on the VioPopup() call, please refer to the
  4278.  "Microsoft Operating System/2 Programmer's Reference."
  4279.  
  4280.  
  4281.  139. DevHlp Services PortUsage() and PortAccess() Do Not Exist
  4282.  
  4283.  Question:
  4284.  
  4285.  What is wrong with the Device Helper services PortUsage() and
  4286.  GrantPortAccess()?
  4287.  
  4288.  Response:
  4289.  
  4290.  DevHlp PortUsage() and GrantPortAccess() do not exist as described
  4291.  in the "Microsoft Operating System/2 Device Drivers Guide," Pages 294,
  4292.  297, 300, and 387-391. These DevHlp services were designed to be used
  4293.  on 80386 machines where we have the ability to trap all port I/O
  4294.  instructions. On the 80286-based machines, these calls are not needed
  4295.  and hence, have not been provided in the SDK release of OS/2. Since
  4296.  these two calls have been removed, the VerifyAccess() call has been
  4297.  moved from number 29H to 27H.
  4298.  
  4299.  The following are some other changes or additions to the DevHlp
  4300.  services and function codes:
  4301.  
  4302.     DevHlp_RAS            EQU 28H
  4303.     DevHlp_AttachDD        EQU 2AH
  4304.     DevHlp_AllocGDTSelector    EQU 2DH
  4305.     DevHlp_PhysToGDTSelector    EQU 2EH
  4306.     DevHlp_RealToProt        EQU 2FH
  4307.     DevHlp_ProtToReal        EQU 30H
  4308.     DevHlp_EOI            EQU 31H
  4309.     DevHlp_UnPhysToVirt        EQU 32H
  4310.     DevHlp_TickCount        EQU 33H
  4311.  
  4312.  
  4313.  140. OS/2 SDK: Competition for the Same Hotkey
  4314.  
  4315.  Question:
  4316.  
  4317.  Is it true that if two monitors are contending for the same hotkey and
  4318.  neither passes the hotkey on, you have cut out one monitor?
  4319.  
  4320.  Response:
  4321.  
  4322.  By definition, if one monitor chooses not to pass on a packet, then
  4323.  subsequent monitors will not see the packet.
  4324.  
  4325.  
  4326.  141. OS/2 SDK: Third-Party Compilers and Languages
  4327.  
  4328.  Question:
  4329.  
  4330.  Are current third-party compilers, etc., usable in the MS OS/2
  4331.  compatibility environment? Will the resulting application execute
  4332.  after LINK and BIND?
  4333.  
  4334.  Response:
  4335.  
  4336.  Yes, many real-mode language products work in the compatibility
  4337.  environment. It is likely that all current language libraries are
  4338.  real-mode specific and a bound application using them would not run in
  4339.  protected mode.
  4340.  
  4341.  
  4342.  142. OS/2 SDK: Timing-Dependent Applications
  4343.  
  4344.  Question:
  4345.  
  4346.  I understand that timing-dependent DOS applications would not run in
  4347.  the compatibility environment because they would be suspended when in
  4348.  the background. Does this mean that they may be compatible if they are
  4349.  not moved to the background?
  4350.  
  4351.  Response:
  4352.  
  4353.  When timing-dependent applications are run in the compatibility box,
  4354.  they do not behave exactly as they do under MS-DOS.
  4355.  
  4356.  First, there is the problem of the user switching away from the
  4357.  compatibility box to use an OS/2 screen group. This results in the
  4358.  compatibility box being suspended until it becomes the active screen
  4359.  group again.
  4360.  
  4361.  Another obstacle is the fact that OS/2 is a multitasking operating
  4362.  system: the entire CPU is not dedicated to the compatibility-box
  4363.  process. The OS/2 applications in the other screen groups still get
  4364.  slices of the CPU, as does OS/2 itself. Therefore, the application
  4365.  will never have sole possession of the CPU as it does under MS-DOS.
  4366.  
  4367.  
  4368.  143. OS/2 1.10 Dualboot Doesn't Work with Compaq's FDISK
  4369.  
  4370.  Problem:
  4371.  
  4372.  I am trying to install the Version 1.10 OS/2 SDK (Software Development
  4373.  Kit). I am using a version of FDISK developed by Compaq. After a
  4374.  successful installation of Microsoft OS/2, I tried to install the
  4375.  dualboot capability. The actual installation of the dualboot
  4376.  capability appeared to be successful. However, when I rebooted my
  4377.  computer, I received the following error message:
  4378.  
  4379.     Can't find file DBMON.COM
  4380.  
  4381.  Response:
  4382.  
  4383.  Microsoft has confirmed this to be a problem in OS/2 SDK Version 1.10.
  4384.  This problem was corrected in Version 1.10.
  4385.  
  4386.  DUALBOOT expects some return codes to be specific values and the
  4387.  direction flag to be reset. If these conditions are not met, the error
  4388.  above is reported.
  4389.  
  4390.  There is a file in the Software Library named DUALBOOT that contains a
  4391.  new version of DUALBOOT.EXE that corrects this problem. DUALBOOT can
  4392.  be found in the Software/Data Library by searching on the keyword
  4393.  DUALBOOT, the Q number of this article, or S12335. DUALBOOT was
  4394.  archived using the PKware file-compression utility.
  4395.  
  4396.  Keywords: DUALBOOT.ARC S12335.EXE
  4397.  
  4398.  
  4399.  144. Communications Packages That Work in Protected Mode Under OS/2
  4400.  
  4401.  The communications packages listed below will run in the protected
  4402.  mode of OS/2.
  4403.  
  4404.  There is a package available as a sample application included with the
  4405.  Microsoft OS/2 Final OS/2 SDK (Software Development Kit) Version 1.10
  4406.  sample sources on the TOOLKIT3 disk in the following subdirectory:
  4407.  
  4408.     \pmsdk\samples\comtalk
  4409.  
  4410.  The products listed below are manufactured by vendors independent of
  4411.  Microsoft. We make no warranty, implied or otherwise, regarding these
  4412.  product's performance or reliability. This information is provided
  4413.  only for your convenience.
  4414.  
  4415.  The following two packages can be downloaded from an IBM
  4416.  bulletin-board system:
  4417.  
  4418.  IBM Atlanta BBS @ (404)988-2913
  4419.  
  4420.  Directory 8, downloads:
  4421.  
  4422.  > LOG200.ARC     110464  09-27-88  Version 2 of LOGICOMM OS/2
  4423.                                     Communication Pgm
  4424.  
  4425.  > TERMOS2.ARC     52224  08-07-88  OS/2 Comm Prog With D/L
  4426.                                     Capabilities
  4427.  
  4428.  KERMIT is also available for OS/2. Please contact Columbia University
  4429.  for its availability.
  4430.  
  4431.  
  4432.  145. OS/2 SDK: DBCS Status and Shift Byte Information
  4433.  
  4434.  Listed below is some additional information on the DBCS status and
  4435.  DBCS shift bytes of the Keystroke Monitor Data Packet.
  4436.  
  4437.  The following bits define the DBCS status byte:
  4438.  
  4439.     Bit 0 = 1        Shift status returned without character
  4440.     Bit 1 to 4       Reserved = 0
  4441.     Bit 5 = 1        On-the-spot conversion requested
  4442.  
  4443.     Bit 6 and Bit 7
  4444.     ---------------
  4445.       0        0     Undefined
  4446.       0        1     Interim character
  4447.       1        0     Final character; interim character flag off
  4448.       1        1     Final character; interim character flag on
  4449.  
  4450.  The DBCS shift byte is reserved and is always 0.
  4451.  
  4452.  
  4453.  146. OS/2 1.10 COMMAND.COM Corresponds to MS-DOS 4.01 COMMAND.COM
  4454.  
  4455.  Question:
  4456.  
  4457.  Does the COMMAND.COM that is installed by OS/2 in the root directory
  4458.  and in the \OS2 subdirectory correspond to the MS-DOS Version 4.01
  4459.  COMMAND.COM?
  4460.  
  4461.  Response:
  4462.  
  4463.  These two versions of COMMAND.COM provide roughly the same
  4464.  functionality. Functions have been added to MS-DOS Version 4.01's
  4465.  COMMAND.COM to make it closer in functionality to the OS/2
  4466.  COMMAND.COM; however, not everything works exactly in the same way. At
  4467.  this time, no list of differences is available.
  4468.  
  4469.  
  4470.  147. General Information on OS/2 Swapper
  4471.  
  4472.  Question:
  4473.  
  4474.  I have the following questions regarding the swapper:
  4475.  
  4476.  1. Does the swapper use the standard DISK01.SYS driver? If so, which
  4477.     interfaces or functions are used?
  4478.  
  4479.  2. In what size blocks does the swapper perform output?
  4480.  
  4481.  3. On system initialization, does the swapper "create" a new
  4482.     SWAPPER.DAT file?
  4483.  
  4484.  4. Are there any swapping performance numbers?
  4485.  
  4486.  Response:
  4487.  
  4488.  The answers to the above questions are as follows:
  4489.  
  4490.  1. Yes, the OS/2 swapper uses the standard DISK0x.SYS driver, and
  4491.     communicates with it by using IOCtls.
  4492.  
  4493.  2. The swapper writes out only the number of bytes in the segment
  4494.     being swapped, rounding out to a sector boundary.
  4495.  
  4496.  3. During system initialization, the swapper creates or resizes the
  4497.     swap file to 640K (if SWAPPER.DAT already exists). If subsequent
  4498.     disk space is needed, the minimum disk space used is whatever the
  4499.     allocation size is for the particular hard drive OS/2 is running
  4500.     on.
  4501.  
  4502.  4. There are no swapping performance numbers because when a memory
  4503.     request is issued, the OS/2 memory manager first invokes the memory
  4504.     compactor. If a large enough block cannot be created this way, the
  4505.     swapper is invoked using an LRU (least recently used) algorithm.
  4506.     There are too many dynamic variables involved to come up with any
  4507.     reliable performance numbers.
  4508.  
  4509.  For more information on the OS/2 swapping scheme, search on the
  4510.  following keyword in the OnLine Knowledge Base:
  4511.  
  4512.     swapper
  4513.  
  4514.  
  4515.  148. Partial List of Changes Between OS/2 Versions 1.00 and 1.10
  4516.  
  4517.  Listed below is a partial list of the changes between OS/2 Version
  4518.  1.00 and OS/2 Version 1.10.
  4519.  
  4520.  1. The following API function calls are new to OS/2 Version 1.10:
  4521.  
  4522.     Function Call         Function
  4523.  
  4524.     DosCallBack()         Allows a ring-2 call to a ring-3 routine
  4525.  
  4526.     DosGetPPID()          Retrieves the PID for a process' parent
  4527.  
  4528.     DosGetResource()      Retrieves a resource for a module
  4529.  
  4530.     DosQAppType()         Retrieves the type of an executable file
  4531.  
  4532.     DosR2StackRealloc()   Reallocates a ring-2 stack
  4533.  
  4534.     DosSizeSeg()          Retrieves the size of a segment
  4535.  
  4536.     Fast-Safe RAM Semaphore calls (DosFS..) are new.
  4537.  
  4538.     Named pipe calls (Dos..NmPipe..) are new.
  4539.  
  4540.     Presentation Manager calls (Win.., Gpi.., Dev.., etc.) are new.
  4541.  
  4542.     Advanced VIO (AVIO) calls are new. They start with "Vio", except
  4543.     for the WinDefAVioWindowProc() function. As part of the support
  4544.     for AVIO, the "hvio" parameter to the VIO calls is now used to
  4545.     specify a handle to the AVIO presentation space.
  4546.  
  4547.  2. The following API function calls were changed in OS/2 Version 1.10:
  4548.  
  4549.     a. DosExecPgm() has a new exec flag.
  4550.  
  4551.     b. DosExit() now terminates all threads in the process, if thread
  4552.        one is exiting, regardless of the fTerminate flag.
  4553.  
  4554.     c. DosExitList() now allows some control over the position of the
  4555.        function in the exit list chain.
  4556.  
  4557.     d. DosGetInfoSeg() has new fields added onto the end of the
  4558.        GINFOSEG and LINFOSEG structures.
  4559.  
  4560.     e. DosMonReg() has new position codes for monitors with special
  4561.        requirements.
  4562.  
  4563.     f. DosSetPrty() has a new priority class called "Fixed High" that
  4564.        is between Normal priority and Time Critical priority.
  4565.  
  4566.     g. DosStartSession() has new fields added onto the end of the
  4567.        STARTDATA structure to support Presentation Manager sessions.
  4568.  
  4569.     h. VioGetMode() and VioSetMode() have had fields removed from the
  4570.        end of the MODEINFO structure.
  4571.  
  4572.  3. The following new programming features were added to OS/2 Version
  4573.     1.10:
  4574.  
  4575.     a. Load-high segments are allowed in device drivers.
  4576.  
  4577.     b. Device driver communication is supported (attachdd or IDC).
  4578.  
  4579.     c. The device driver helper dh_registerstackusage is new.
  4580.  
  4581.  4. Listed below are some of the command differences in OS/2
  4582.     Version 1.10:
  4583.  
  4584.     a. DDINSTAL was added to aid in installing device drivers on the
  4585.        hard disk.
  4586.  
  4587.     b. E.EXE, a system editor, was added.
  4588.  
  4589.     c. The FORMAT command's /s option has been removed.
  4590.  
  4591.     d. The FORMAT command now displays status in percentages rather
  4592.        than tracks.
  4593.  
  4594.     e. MODE now allows the following baud rates: 1800, 3600, and 7200.
  4595.  
  4596.     f. SPOOL was changed to just start the PM spooler.
  4597.  
  4598.     g. The START command takes new flags for support of windowed
  4599.        command prompts.
  4600.  
  4601.     h. The SYS command has been removed.
  4602.  
  4603.     i. UNPACK was added to unpack files on the installation disks.
  4604.  
  4605.  5. Listed below are some of the configuration differences in OS/2
  4606.     Version 1.10:
  4607.  
  4608.     a. OS2DOS.COM is renamed to OS2KRNL.
  4609.  
  4610.     b. OS2BIO.COM is renamed to OS2LDR.
  4611.  
  4612.     c. The SET command is allowed in the CONFIG.SYS file, and allows a
  4613.        default environment to be specified for all new processes
  4614.        started in the system.
  4615.  
  4616.     d. SWAPPATH allows the specification of how much space to attempt
  4617.        to leave free on the hard disk.
  4618.  
  4619.     e. EXTDSKDD.SYS no longer allows the /C or /N parameter.
  4620.  
  4621.     f. Partitions larger than 32 megabytes are allowed.
  4622.  
  4623.     g. The Install program is enhanced.
  4624.  
  4625.  
  4626.  
  4627.  149. OS/2 SDK: Call Gates
  4628.  
  4629.  Gates, which are four-word descriptors, are used as control transfer
  4630.  redirectors to a different code segment in the identical or higher
  4631.  privileged level in the same task. They can also redirect transfers to
  4632.  code segments in different tasks.
  4633.  
  4634.  Call gates are specifically used for control transfers that need to be
  4635.  transparently redirected or involve an increase in the privilege
  4636.  level. For more information on call gates or gates in general, please
  4637.  refer to the "Intel 80286 Programmer's Reference Manual."
  4638.  
  4639.  
  4640.  150. OS/2 SDK: Multiple Code Segments in a C Code File
  4641.  
  4642.  It is possible to declare multiple code segments inside one C code
  4643.  file if your language supports multiple code segments. (Microsoft
  4644.  languages do.)
  4645.  
  4646.  
  4647.  151. OS/2 SDK: 286 Protection Ring
  4648.  
  4649.  Currently, nothing runs in 286 protection ring 1; it is reserved for
  4650.  future use.
  4651.  
  4652.  
  4653.  152. OS/2 SDK: Stack Fault Handling
  4654.  
  4655.  Stack faults cannot be restarted on most 286 chips due to a problem in
  4656.  the silicon.
  4657.  
  4658.  
  4659.  153. OS/2 SDK: DosMemAvail() in a Virtual Memory System
  4660.  
  4661.  In a virtual memory system, DosMemAvail() can be used as a hint of the
  4662.  memory availability of the system so that applications can modify
  4663.  their demands. It is not a complete statistics facility.
  4664.  
  4665.  
  4666.  154. OS/2 SDK: Releasing of DLL Modules
  4667.  
  4668.  DLL modules are released and the real memory is returned to the system
  4669.  when the reference count goes from one to zero.
  4670.  
  4671.  
  4672.  155. OS/2 SDK: Avoiding Name Conflicts
  4673.  
  4674.  With dynamic links, to avoid name conflicts of added services across
  4675.  applications, use a long name with some application or vendor-specific
  4676.  component.
  4677.  
  4678.  
  4679.  156. Determining Exported Entry Points in A DLL
  4680.  
  4681.  Question:
  4682.  
  4683.  How difficult would it be to examine a DLL (Dynamic Linked Library)
  4684.  and determine the routine names and their parameters?
  4685.  
  4686.  Response:
  4687.  
  4688.  You can obtain this information by using EXEHDR with the "/v" option.
  4689.  The "v" (verbose) option allows you to display all of the exported
  4690.  entry points in a DLL.
  4691.  
  4692.  
  4693.  157. Implementing Fully Protected/Secure File System
  4694.  
  4695.  Question:
  4696.  
  4697.  It is stated that a fully protected/secure file system will be
  4698.  implemented in the 286 and 386 versions of OS/2. Does this mean that
  4699.  to implement true security, all workstations need to be 286 or 386
  4700.  machines?
  4701.  
  4702.  Response:
  4703.  
  4704.  No. The existing LAN Manager product provides a protected file system
  4705.  environment on a 286 or 386 for any remote client workstation
  4706.  accessing that server, i.e., no remote workstation can access server
  4707.  resources not explicitly permitted it. However, there is a limitation
  4708.  in that a user local to the server is not subject to permission checks
  4709.  (a local user is treated with administrative privilege). The protected
  4710.  286 or 386 file system will remove this limitation, allowing a user
  4711.  local to a server to be subject to the same permission checking that a
  4712.  remote user is.
  4713.  
  4714.  Please note that there is a distinction between protected and secure
  4715.  file systems. A protected file allows access only if you have
  4716.  permission. A secure file system prevents a permitted user from
  4717.  passing on information to non-permitted users. In this respect, the
  4718.  LAN Manager provides a filing system that is protected relative to
  4719.  remote users but not secure.
  4720.  
  4721.  
  4722.  158. Linking Made Easier
  4723.  
  4724.  Question:
  4725.     After years of making DOS and BIOS function calls in high-level
  4726.  languages, we now have a system where it is easier to do the function
  4727.  calls in high-level languages than in assembler. OS/2 assembly
  4728.  language programs seem awkward. It is not so much the pushes (we could
  4729.  have macros for those), but every DOS call must be listed in both the
  4730.  ASM file (as an external) and the DEF file (as an import). Is there
  4731.  something we can link to so we do not need the import listing in DEF?
  4732.  
  4733.  Response:
  4734.     Yes; link with OS2.LIB. You can create additional imports libraries
  4735.  for your own dynlink libraries using IMPLIB.
  4736.  
  4737.  
  4738.  159. DosGetEnv Returns Pointer to Asciiz String
  4739.  
  4740.  Problem:
  4741.  
  4742.  According to Page 126 of the "Microsoft Operating System/2
  4743.  Programmer's Reference Guide," DosGetEnv returns the offset of the
  4744.  command line start. If I enter "myprog cmdtail" at the OS/2 prompt,
  4745.  the command line is "myprog cmdtail". Therefore, I would expect a
  4746.  pointer to the string "myprog cmdtail". However, it seems that
  4747.  DosGetEnv returns a pointer to the asciiz string "c:\myprog.exe". This
  4748.  string seems to always be followed by the asciiz string "cmdtail";
  4749.  however, I can't find this documented.
  4750.  
  4751.  Response:
  4752.  
  4753.  This is a documentation error. The command line pointer is a pointer
  4754.  to an argument string that has the same format as the argument string
  4755.  passed from DosExecPgm. See Page 17 of the "Microsoft Operating
  4756.  System/2 Programmer's Reference Update" for a description of how
  4757.  DosExecPgm passes the environment information to a new process.
  4758.  
  4759.  
  4760.  160. Problem in Real Mode APPEND Command
  4761.  
  4762.  Problem:
  4763.     The real mode APPEND command does not work after being used the
  4764.  first time with Microsoft OS/2 Version 1.00.
  4765.  
  4766.  Response:
  4767.     Microsoft is researching this problem and will post new information
  4768.  as it becomes available.
  4769.  
  4770.  
  4771.  161. OS/2 User's Guide Error in Spool Documentation
  4772.  
  4773.  Question:
  4774.  
  4775.  How do I use a serial printer under OS/2? I have installed OS/2
  4776.  Version 1.02 and the SDK on my PS/2 Model 60. The PS/2 has a single
  4777.  parallel port and single async port. I am running with the dual boot
  4778.  option installed, with MS-DOS Version 3.30 and OS/2 installed on the
  4779.  same hard disk.
  4780.  
  4781.  Response:
  4782.  
  4783.  The documentation on Page 194 of the "Microsoft Operating System/2
  4784.  Beginning User's Guide" is incomplete. The following is the correct
  4785.  documentation for the SPOOL command:
  4786.  
  4787.  The Spool command initializes the printer spooler to print in the
  4788.  background while you are executing other OS/2 commands or programs.
  4789.  The following syntax should be used:
  4790.  
  4791.  [drive:][pathname] spool [drive2:][pathname2]   [/d:device] [/o:device2]
  4792.  
  4793.  [drive:][pathname]  Preceding spool, specifies the drive and path
  4794.                      that contains the spool command file.
  4795.  
  4796.  drive2:pathname2    Specifies the print spool subdirectory. This
  4797.                      is where the temporary spool files will be
  4798.                      created. The default is \SPOOL.
  4799.  
  4800.  /d                  Specifies the print device. If not specified,
  4801.                      the default device is LPT1:.
  4802.  
  4803.                      Any character device that supports monitors can
  4804.                      be specified. Only the output portion of the
  4805.                      device is affected.
  4806.  
  4807.                      COM1: and COM3: may not be specified as the input
  4808.                      print device since the Async device driver does
  4809.                      not support character device monitors. When COM1:
  4810.                      and COM3: are specified as the output print device,
  4811.                      the spooler uses DosWrite rather than the monitor
  4812.                      interface to output the data.
  4813.  
  4814.  /o                  Specifies the output print device. If not
  4815.                      specified, the default will be the same as the
  4816.                      /d: device.
  4817.  
  4818.  The Spool utility is a true spooler. It uses the Monitor facility of
  4819.  OS/2 to intercept data going to the printer device drivers. The Spool
  4820.  utility sorts the data by process so that the printer output is not
  4821.  intermixed. Print streams that are not closed (in the process of being
  4822.  updated) are placed in temporary files on the disk in the subdirectory
  4823.  specified on the Spool command line.
  4824.  
  4825.  The Printer Spooler (Spool Utility) serves a single printer device at
  4826.  a time. It uses the Character Device Monitor mechanism to intercept
  4827.  data passing through a device driver and to insert data back into the
  4828.  device driver data stream.
  4829.  
  4830.  Since printers are attached to the PC with both parallel and serial
  4831.  connections, the printer spooler will support printer devices
  4832.  (LPT1->3, PRN) and serial devices (COM1->2, AUX).
  4833.  
  4834.  The printer spooler will also support any other character device whose
  4835.  device driver contains monitor support compatible with the printer
  4836.  device driver.
  4837.  
  4838.  The Print command interfaces to the Spool command when the /t or /c
  4839.  options are specified on print.
  4840.  
  4841.  
  4842.  162. Generic Printer Ioctl
  4843.  
  4844.  The "Microsoft OS/2 Device Driver's Guide" documentation on printer
  4845.  function 65H (Pages 114 and 214) is incorrect in the function number.
  4846.  The correct ioctl function code to return printer status is 66H, not
  4847.  65H as documented.
  4848.  
  4849.  
  4850.  163. Corrected Version of Microsoft Segmented Executable Format
  4851.  
  4852.  There are a number of errors in the EXE file information in the
  4853.  "Microsoft Operating System/2 Software Development Kit Programmer's
  4854.  Reference" Pages 555-558. A corrected version of this information is
  4855.  available in the Software Library. This file can be found in the
  4856.  Software Library by searching on the filename SEGEXEC.ARC, the Q
  4857.  number of this article, or S12069.
  4858.  
  4859.  
  4860.  164. Missing Documentation on Printer Font Monitors
  4861.  
  4862.  Several pages of information were omitted from the OS/2 SDK
  4863.  documentation. These pages concern the writing of printer monitors to
  4864.  monitor the font commands and the data path.
  4865.  
  4866.  This missing documentation is available in the Software Library. This
  4867.  file can be found by searching on the filename FONTMON.ARC, the Q
  4868.  number of this article, or S12117.
  4869.  
  4870.  The missing information is as follows:
  4871.  
  4872.  Printer/Spooler
  4873.  
  4874.  The major functional changes to the printer device driver and the
  4875.  spooler in OS/2 Version 1.1 from OS/2 Version 1.0 are to accommodate
  4876.  code page and font switching for National Language Support (NLS) by
  4877.  providing a generalized printer font handling mechanism.
  4878.  
  4879.  Printer/Spooler Overview
  4880.  
  4881.  The printer/spooler is structured as shown in the Figure 1 below:
  4882.  
  4883.    .-App---Process--.    .-----------Spooler--Process----------.
  4884.    | .------------. |    | .--------------. (3) .------------. |
  4885.    | |Application | |    | |   Spooler    .----->  Code Page | |
  4886.    | |  Program   | |    | |              |     |  Switcher  | |
  4887.    | .-----.------. |  .--->  (Monitor)   <-----. (Dynalink) | |
  4888.    |       |        |  | | .-.-----A----.-. (4) .------------. |
  4889.    .-------|--------.  | .---|-----|----|----------------------.
  4890.         (1)|        (2)|  (7)|  (6)|    |(5)
  4891.            |           |     |  .--.----V----.
  4892.            |           |     |  |Spooled File|
  4893.            |           |     |  |   (disk)   |
  4894.            |           |     |  .------------.
  4895.     - - - -|- - - - - -|- - -|- - - - - - - - - - - - - - - - -
  4896.            |           |     |      .--------.         Kernel
  4897.            |           |     | (7b) | Async  |
  4898.            |           |     . - - -> Device | (8b) .---------.
  4899.            |           | (7a)|      | Driver . - - -> Printer |
  4900.            |     .-----.-----V.     .--------.      .---------.
  4901.            .----->  Printer   |
  4902.                  |  Device    | (8a) .---------.
  4903.                  |  Driver    .------> Printer |
  4904.                  .------------.      .---------.
  4905.  
  4906.  Printer/Spooler Structure
  4907.  
  4908.  The data flow shown in the printer/spooler structure above is as
  4909.  follows:
  4910.  
  4911.  1. This flow is the normal API to the printer. The application program
  4912.     issues DosOpen, followed by "n" DosWrites/DosIoctls to the printer.
  4913.     The file system sends an Open IOCTL to the printer device driver,
  4914.     followed by an Activate Font IOCTL. The application program's
  4915.     DosWrites go to the printer device driver until a DosClose is issued.
  4916.  
  4917.  2. This flow is from the printer device driver to the spooler through
  4918.     the MonRead monitor interface. The printer device driver sends an
  4919.     Open command buffer, followed by an Activate Font monitor command
  4920.     buffer, and then "n" buffers corresponding to the DosWrites.
  4921.  
  4922.  3. This flow is via a Call interface to the Font Switcher dynalink
  4923.     routine. This occurs when the Activate Font monitor command buffer
  4924.     is received by the spooler from the printer device driver as a
  4925.     result of the Activate Font Ioctl.
  4926.  
  4927.  4. This flow is the return from the call described in the flow
  4928.     previously.
  4929.  
  4930.     The data returned contains the escape sequences and/or font data
  4931.     necessary to cause the printer to perform the actual code page and
  4932.     font switch. This data is treated by the spooler as part of, and in
  4933.     sequence with, the data being printed by the application program
  4934.     and is put into the spool file described in the next flow.
  4935.  
  4936.  5. This flow is the data being written by the spooler to a temporary
  4937.     spool file on the disk using DosWrites.
  4938.  
  4939.  6. The spooler reads data from its temporary spool files on the disk,
  4940.     in sequence based on its spool queues, using DosReads.
  4941.  
  4942.  7. The spooler sends data to the device driver to be printed using the
  4943.     monitor output buffer and MonWrite function interfaces.
  4944.  
  4945.      a. If the spooled printer is parallel attached, the spooler sends
  4946.         the data back to the printer device driver.
  4947.  
  4948.      b. If the spooled printer is async attached, the spooler sends the
  4949.         data back to the async device driver.
  4950.  
  4951.  8. The device driver sends data to the printer through the hardware
  4952.     adapter.
  4953.  
  4954.      a. The printer device driver sends the data to parallel attached
  4955.         printers.
  4956.  
  4957.      b. The async device driver sends the data to async attached
  4958.         printers.
  4959.  
  4960.  Printer Device Driver Operational Description
  4961.  
  4962.  The printer device driver has three new printer specific Ioctl
  4963.  commands to support the code page and font switching provided in OS/2
  4964.  Version 1.1. All of the actual code page and font switching function
  4965.  for printers is provided by the spooler which is a printer device
  4966.  driver monitor. In addition, in order to support these new Ioctls,
  4967.  there are Font Monitor Buffer Command/responses added to the monitor
  4968.  interface to the spooler. The functions provided by the Ioctls and
  4969.  Font Monitor Buffer Command/responses are:
  4970.  
  4971.  1. Activate Font
  4972.  
  4973.  2. Query Active Font
  4974.  
  4975.  3. Verify Font
  4976.  
  4977.  These Ioctls and monitor code page and font buffer command/responses
  4978.  are described in detail elsewhere in this item.
  4979.  
  4980.  1. Activate Font
  4981.  
  4982.     Using Figure 1 as an illustration, when an application within a
  4983.     process issues a DosOpen for a printer, i.e., LPT1, LPT2, LPT3 or
  4984.     PRN, the file system issues an Activate Font Ioctl to the printer
  4985.     device driver to set the active code page and font according the
  4986.     active code page of the process making the open request.
  4987.  
  4988.     An application within a process may also issue the Activate Font
  4989.     Ioctl to the printer device driver by using the handle returned
  4990.     from the DosOpen at any time. This allows the application to change
  4991.     the active code page and font in the middle of its print job.
  4992.  
  4993.     When the printer device driver receives the Activate Font Ioctl, if
  4994.     the spooler or another monitor is registered, the printer device
  4995.     driver will use the Font Monitor Buffer Command to send the Activate
  4996.     Font command to the registered monitor in its monitor input buffer.
  4997.     If the spooler, or another monitor, is not registered the printer
  4998.     device driver will return the appropriate return code to the caller
  4999.     of the Activate Font Ioctl.
  5000.  
  5001.  2. Query Active Font
  5002.  
  5003.     When the printer device driver receives the Query Active Font
  5004.     Ioctl, if the spooler or another monitor is registered, the printer
  5005.     device driver will use the Font Monitor Buffer Command to send the
  5006.     Query Active Font command to the registered monitor in its monitor
  5007.     input buffer. The monitor will return the active code page and font
  5008.     information to the printer device driver in its monitor output
  5009.     buffer. The printer device driver then returns the active code page
  5010.     and font information to the caller of the Query Active Font Ioctl.
  5011.  
  5012.     If the spooler, or another monitor, is not registered the printer
  5013.     device driver will return the appropriate return code to the caller
  5014.     of the Query Active Font Ioctl.
  5015.  
  5016.  3. Verify Font
  5017.  
  5018.     When the printer device driver receives the Verify Font Ioctl, if
  5019.     the spooler or another monitor is registered, the printer device
  5020.     driver will use the Font Monitor Buffer Command to send the Verify
  5021.     Font command to the registered monitor in its monitor input buffer.
  5022.     The monitor will return whether the specified code page  and font
  5023.     is valid to the printer device driver in its monitor output buffer.
  5024.     The printer device driver then returns the return code to the
  5025.     caller of the Verify Font Ioctl.
  5026.  
  5027.     If the spooler, or another monitor, is not registered the printer
  5028.     device driver will return the appropriate return code to the caller
  5029.     of the Verify Font Ioctl.
  5030.  
  5031.  Printer Device Driver Interfaces
  5032.  
  5033.  The interfaces required by the printer device driver for code page and
  5034.  font switching are as follows:
  5035.  
  5036.        Activate Font Ioctl
  5037.        Query Active Font Ioctl
  5038.        Verify Font Ioctl
  5039.        Font Monitor Buffer Commands
  5040.           Activate Font
  5041.           Query Active Font
  5042.           Verify Font
  5043.  
  5044.  These interfaces are described in the following sections.
  5045.  
  5046.  Activate Font Ioctl:
  5047.  
  5048.     Category 5  Function 48h
  5049.  
  5050.     Purpose:   Activate Font
  5051.  
  5052.     Parameter Packet Format:
  5053.  
  5054.              .------------------------------------.
  5055.              |     BYTE Command Information       |
  5056.              .------------------------------------.
  5057.  
  5058.     Data Packet Format:
  5059.  
  5060.              .------------------------------------.
  5061.              |     WORD  Code Page                |
  5062.              .------------------------------------.
  5063.              |     WORD  Font Id                  |
  5064.              .------------------------------------.
  5065.  
  5066.     Remarks:
  5067.     Command Information: This field is currently reserved and must
  5068.                          be set to zero.
  5069.     Code Page: The value of the code page to make the currently
  5070.                active code page.
  5071.  
  5072.                0000h     If both the Code Page value and Font Id
  5073.                          are specified as zero (0), set printer to
  5074.                          hardware default code page and font.
  5075.  
  5076.                0001h-FFFFh  Valid code page numbers.
  5077.  
  5078.     Font Id: The id value of the Font to make currently active.
  5079.  
  5080.               0000h     If both the Code Page value and Font Id
  5081.                         are specified as zero (0), set printer to
  5082.                         hardware default code page and font.
  5083.  
  5084.                         If only the Font Id is specified as zero,
  5085.                         any font within the specified code page is
  5086.                         acceptable.
  5087.  
  5088.               0001h-FFFFh  Valid font id numbers, font types
  5089.                            defined by the font file definitions.
  5090.  
  5091.     Returns: IF AX = 0
  5092.  
  5093.                  NO error
  5094.  
  5095.              ELSE
  5096.  
  5097.                  AX = Error Code:
  5098.  
  5099.                      Code page and font switching not active
  5100.                      Unable to access specified font file
  5101.                      Unable to locate or activate specified code page
  5102.                      Unable to locate or activate specified font
  5103.  
  5104.  Query Active Font Ioctl:
  5105.  
  5106.     Category 5  Function 69h
  5107.  
  5108.     Purpose: Query Active Font
  5109.  
  5110.     Parameter Packet Format:
  5111.  
  5112.              .------------------------------------.
  5113.              |     BYTE Command Information       |
  5114.              .------------------------------------.
  5115.  
  5116.     Data Packet Format:
  5117.  
  5118.              .------------------------------------.
  5119.              |     WORD  Code Page                |
  5120.              .------------------------------------.
  5121.              |     WORD  Font Id                  |
  5122.              .------------------------------------.
  5123.  
  5124.     Remarks:
  5125.     Command Information: This field is currently reserved and must
  5126.                          be set to zero.
  5127.     Code Page: On return, this word is set to currently active code
  5128.                page.
  5129.  
  5130.                0000h    If both the Code Page value and Font Id
  5131.                         are returned as zero (0), the printer is
  5132.                         set to the hardware default code page and
  5133.                         font.
  5134.  
  5135.                0001h-FFFFh  Valid code page numbers.
  5136.  
  5137.     Font Id: On return, the id value of the Font which is
  5138.              currently active.
  5139.  
  5140.                0000h     If both the Code Page value and Font Id
  5141.                          are specified as zero (0), the printer is
  5142.                          set to the hardware default code page and
  5143.                          font.
  5144.  
  5145.                          A Font Id value of zero may indicate the
  5146.                          default font of a particular code page.
  5147.  
  5148.                0001h-FFFFh  Valid font id numbers, font types
  5149.                             defined by the font file definitions.
  5150.  
  5151.     Returns: IF AX = 0
  5152.  
  5153.                  NO error
  5154.  
  5155.              ELSE
  5156.  
  5157.                  AX = Error Code:
  5158.  
  5159.                      Code page and font switching not active
  5160.  
  5161.  Verify Font Ioctl:
  5162.  
  5163.     Category 5  Function 6Ah
  5164.  
  5165.     Purpose: Verify that a particular code page and font is available for the
  5166.             specified printer.
  5167.  
  5168.     Parameter Packet Format:
  5169.  
  5170.              .------------------------------------.
  5171.              |     BYTE Command Information       |
  5172.              .------------------------------------.
  5173.  
  5174.     Data Packet Format:
  5175.  
  5176.              .------------------------------------.
  5177.              |     WORD  Code Page                |
  5178.              .------------------------------------.
  5179.              |     WORD  Font Id                  |
  5180.              .------------------------------------.
  5181.  
  5182.     Remarks:
  5183.     Command Information: Reserved, must be set to zero.
  5184.  
  5185.     Code Page: The Code Page number to validate.
  5186.                Values may be 0 to 65535.
  5187.  
  5188.     Font Id: The Font Id value to validate.
  5189.              Values may be 0 to 65535.
  5190.  
  5191.     Note: A value of zero (0) for both the Code Page number and Font Id
  5192.           indicates the default hardware code page and font; this
  5193.           combination is always valid.
  5194.  
  5195.     Returns: IF AX = 0
  5196.  
  5197.                  NO error, Code Page is valid
  5198.  
  5199.              ELSE
  5200.  
  5201.                  AX = Error Code:
  5202.  
  5203.                      Code page and font switching not active
  5204.                      Code Page not valid
  5205.                      Font Id not valid
  5206.  
  5207.  Font Monitor Buffer Commands:
  5208.  
  5209.  Printer Monitor Record:
  5210.  
  5211.  Each monitor record can be of variable length. However, there must be
  5212.  a word of flags at the beginning of each monitor record. The flags are
  5213.  defined as follows:
  5214.  
  5215.        Monitor Flags
  5216.  
  5217.                                                  Device Driver
  5218.           Byte 0                       Byte 1    Dependent
  5219.     .--.--.--.--.--.--.--.--.    .--.--.--.--.--.--.--.--.
  5220.     | 7| 6| 5| 4| 3| 2| 1| 0|    | 7| 6| 5| 4| 3| 2| 1| 0|
  5221.     .--.--.--.--.--.--.--.--.    .--.--.--.--.--.--.--.--.
  5222.       A           A  A  A  A       A              A  A  A
  5223.       . Reserved -.  |  |  |       .-- Reserved --.  |  |
  5224.                      |  |  |                         |  |
  5225.                      |  |  .- Open                   |  |
  5226.  |                   |  .- Close  Code Page Command -.  |
  5227.  |                   .- Flush        Processed          |
  5228.                                                         |
  5229.                        Printer Code Page Monitor -------.
  5230.                        Buffer Command/Response
  5231.  
  5232.  When the Font Monitor Buffer Command bit is set to 1 (byte 1, bit 0),
  5233.  this indicates that the monitor buffer is a Font Monitor Buffer
  5234.  Command or a response to a previous Font Monitor Buffer Command. In
  5235.  this case, the next six bytes are as follows:
  5236.  
  5237.       Byte 2 & 3
  5238.     .-------------------------------------------.
  5239.     |            ProcessId                      |
  5240.     .-------------------------------------------.
  5241.  
  5242.       Byte 4               Byte 5
  5243.     .--------------------.----------------------.
  5244.     |  Command  Byte     |  Reserved, Set to 0  |
  5245.     .--------------------.----------------------.
  5246.  
  5247.       Byte 6 & 7
  5248.     .-------------------------------------------.
  5249.     |       Reserved,  Set to 0                 |
  5250.     .-------------------------------------------.
  5251.  
  5252.     Byte 2 & 3  Process Id WORD
  5253.  
  5254.     Byte 4    Font Monitor Buffer Command Byte which indicates the type of
  5255.               command or response.
  5256.  
  5257.     Byte 5    Reserved, and must be set to zero (0).
  5258.  
  5259.     Byte 6 & 7  Reserved WORD, must be set to zero (0).
  5260.  
  5261.  When the Code Page Command Processed bit is set to 1 (byte 1, bit 1),
  5262.  this indicates that the Font Monitor Buffer Command has been processed
  5263.  by the spooler.
  5264.  
  5265.  The valid Font Monitor Buffer Commands, along with the remainder of
  5266.  the buffer contents for the responses, are as follows:
  5267.  
  5268.     Byte 4 = 01h  Activate Font
  5269.  
  5270.              Command Data, starting at byte 8:
  5271.  
  5272.                .------------------------------------.
  5273.              08|     WORD  Return Code              |
  5274.                .------------------------------------.
  5275.              0A|     WORD  Code Page                |
  5276.                .------------------------------------.
  5277.              0C|     WORD  Font Id                  |
  5278.  |             .------------------------------------.
  5279.  |           0E|     DATA to print (optional)       |
  5280.  |             =                                    =
  5281.                .------------------------------------.
  5282.  
  5283.     Code Page: The value of the code page to make the currently active
  5284.                code page.
  5285.  
  5286.                0000h  If both the Code Page value and Font Id are
  5287.                       specified as zero (0), set printer to
  5288.                       hardware default code page and font.
  5289.  
  5290.                0001h-FFFFh  Valid code page numbers.
  5291.  
  5292.     FontId: The id value of the Font to make currently active.
  5293.  
  5294.                0000h  If both the Code Page value and Font Id are
  5295.                       specified as zero (0), set printer to
  5296.                       hardware default code page and font.
  5297.  
  5298.                       If only the Font Id is specified as zero,
  5299.                       any font within the specified code page is
  5300.                       acceptable.
  5301.  
  5302.                0001h-FFFFh  Valid font id numbers, font types defined
  5303.                             by the font file definitions.
  5304.  
  5305.     Data: Optionally, data to be printed may follow the FontId of the
  5306.           Activate Font Font Monitor Buffer Command. The length of the
  5307.           buffer indicates that there is data following the command.
  5308.  
  5309.           The response is a return code WORD value starting at byte 8,
  5310.           and includes the following values:
  5311.  
  5312.           Successful completion
  5313.           Code page and font switching not active
  5314.           Unable to access specified font file
  5315.           Unable to locate or activate specified code page
  5316.           Unable to locate or activate specified font
  5317.  
  5318.     Byte 4 = 02h  Query Active Font
  5319.  
  5320.              There is no additional command data.
  5321.  
  5322.              The response is as follows:
  5323.  
  5324.                .------------------------------------.
  5325.              08|     WORD  Return Code              |
  5326.                .------------------------------------.
  5327.              0A|     WORD  Code Page                |
  5328.                .------------------------------------.
  5329.              0C|     WORD  Font Id                  |
  5330.                .------------------------------------.
  5331.  
  5332.              Return Code: A WORD value starting at byte 8, and includes
  5333.                           the following values:
  5334.  
  5335.                           Successful completion
  5336.                           Code page and font switching not active
  5337.  
  5338.              Code Page: The value of the currently active code page.
  5339.  
  5340.                         Valid numbers are between 0 and 65535.
  5341.  
  5342.                         A value of 0 for both the code page and font id
  5343.                         indicates that the hardware default code page
  5344.                         and font is active.
  5345.  
  5346.              Font Id: The id value of the currently active font.
  5347.  
  5348.                       Valid numbers are between 0 and 65535.
  5349.  
  5350.    Byte 4 = 03h  Verify Font
  5351.  
  5352.              Command Data, starting at byte 8:
  5353.  
  5354.                 .------------------------------------.
  5355.              08 |     WORD  Return Code              |
  5356.                 .------------------------------------.
  5357.              0A |     WORD  Code Page                |
  5358.                 .------------------------------------.
  5359.              0C |     WORD  Font Id                  |
  5360.                 .------------------------------------.
  5361.  
  5362.              Code Page: The value of the code page to validate.
  5363.  
  5364.                         Values may be 0 to 65535.
  5365.  
  5366.              FontId: The Font Id to validate.
  5367.  
  5368.                       Values may be 0 to 65535. A value of zero
  5369.                       indicates that any font within the specified
  5370.                       code page is acceptable.
  5371.  
  5372.  The response is a return code WORD value starting at byte 8, and
  5373.  includes the following values:
  5374.  
  5375.      Code page and font valid
  5376.      Code page not valid
  5377.      Font not valid
  5378.      Code page and font switching not active
  5379.      Unable to access specified font file
  5380.  
  5381.  Spooler
  5382.  DOS Version 3.x Box Force Output to Printer
  5383.  
  5384.  The print spooler spools the printer output until a DosClose is
  5385.  issued. When printing from the DOS 3.x box, many applications use the
  5386.  INT17 interface which does not require DosOpen/DosClose's. In this
  5387.  case, the printer output is spooled until the program exits. The user
  5388.  may press CTL-ALT-PRTSCRN (while the DOS 3.x box is in the foreground)
  5389.  to force printed output to be printed from DOS 3.x box applications.
  5390.  
  5391.  Spooler Operational Description
  5392.  
  5393.  The Spooler uses a dynalink module called the Font Switcher to perform
  5394.  the code page and font switching.
  5395.  
  5396.  Initialization:
  5397.  
  5398.  When the Spooler is invoked by the user (user command SPOOL), it
  5399.  accesses the system data structure which contains the code page and
  5400.  font information provided by the DEVINFO command in CONFIG.SYS. If
  5401.  DEVINFO code page and font information is present for the specified
  5402.  printer name (LPTx or PRN) in the code page and font data structure,
  5403.  the spooler will call the Dos_PFS_Init entry point of the Font
  5404.  Switcher dynalink module to initialize font switching. Once the
  5405.  Spooler and Font Switcher have completed initialization, print
  5406.  spooling along with code page and font switching are enabled for the
  5407.  specified printer.
  5408.  
  5409.  If the DEVINFO code page and font information are not present in the
  5410.  code page and font data structure maintained by the system for the
  5411.  specified printer name, the spooler completes its initialization
  5412.  without initializing the Font Switcher for the specified printer. In
  5413.  this case spooling is enabled for the specified printer, however, code
  5414.  page and font switching are not.
  5415.  
  5416.  Activate Font:
  5417.  
  5418.  When an Activate Font Font Monitor Buffer Command is received by the
  5419.  spooler for a specific Process ID, the spooler calls the
  5420.  Dos_PFS_Activate entry point of the Font Switcher. The Font Switcher
  5421.  changes the active code page and font for the Process ID/handle, and
  5422.  uses the font file to cause the code page and font switch to occur.
  5423.  The code page and font switch occurs in one of the following ways
  5424.  depending on the font support provided by the target printer:
  5425.  
  5426.  1. If the specified font is contained in the printer hardware (ROM or
  5427.     cartridge, as specified by the DEVINFO command CONFIG.SYS), the
  5428.     Font Switcher writes the escape sequence required to switch the
  5429.     printer to this hardware font directly into the temporary spool
  5430.     file. The escape sequence necessary to perform this switch is
  5431.     available for the Font Switcher in the font file specified for the
  5432.     printer.
  5433.  
  5434.  2. If the specified font is not contained in printer hardware, and the
  5435.     printer allows multiple downloadable fonts, the Font Switcher will
  5436.     determine which font buffer to download the font to. The Font
  5437.     Switcher writes the escape sequence required to download a font to
  5438.     the printer to a font buffer in the printer along with the font
  5439.     information, followed by the escape sequence which changes the
  5440.     printer's active font buffer directly into the temporary spool
  5441.     file. If the Activate Font command specifies a font that has been
  5442.     previously loaded into a font buffer other than the one which is
  5443.     currently active, the Font Switcher writes the escape sequence
  5444.     required to switch the printer to the desired font buffer directly
  5445.     into the temporary spool file.
  5446.  
  5447.     All escape sequences and font information required are available
  5448.     for the Font Switcher in the font file specified for the printer.
  5449.  
  5450.  3. If the specified font is not contained in printer hardware, and the
  5451.     printer allows a single font to be downloaded, the Font Switcher
  5452.     writes the escape sequence required to download a font to the
  5453.     printer to a font buffer in the printer along with the font
  5454.     information directly into the temporary spool file.
  5455.  
  5456.     All escape sequences and font information required are available
  5457.     for the Font Switcher in the font file specified for the printer.
  5458.  
  5459.  Query Active Font:
  5460.  
  5461.  When a Query Active Font Font Monitor Buffer Command is received by
  5462.  the spooler for a specific Process ID, the spooler calls the
  5463.  Dos_PFS_Query_Act entry point of the Font Switcher. The
  5464.  Dos_PFS_Query_Act function returns the active code page and font for
  5465.  the specified Process ID(/handle) to the spooler. The spooler returns
  5466.  the information to the printer device driver using the Query Active
  5467.  Font Font Monitor Buffer Response. The printer device driver then
  5468.  returns the information to the Query Active Font Ioctl caller.
  5469.  
  5470.  Verify Font:
  5471.  
  5472.  When a Verify Font Font Monitor Buffer Command is received by the
  5473.  spooler for a specific Process ID, the spooler calls the
  5474.  Dos_PFS_Verify_Font entry point of the Font Switcher. The
  5475.  Dos_PFS_Verify_Font function returns whether the specified code page
  5476.  and font is available in the font file for the specified printer.
  5477.  
  5478.  Spooler Interfaces
  5479.  
  5480.  The interfaces required by the spooler for code page and font
  5481.  switching are as follows:
  5482.  
  5483.     System code page and font information
  5484.     Font Monitor Buffer Commands
  5485.  
  5486.     Activate Font
  5487.     Query Active Font
  5488.     Verify Font
  5489.  
  5490.     Font Switcher Dynalink Module
  5491.  
  5492.     Dos_PFS_Init             Initialize code page and font
  5493.     Dos_PFS_Activate         Activate Font
  5494.     Dos_PFS_Query_Act        Query Active Font
  5495.     Dos_PFS_Verify_Font      Verify Font
  5496.     Dos_PFS_Close_User       Close Font User Instance
  5497.  
  5498.  Printer Font File Format
  5499.  
  5500.  These interfaces are described in the following sections.
  5501.  
  5502.  System Code Page Information:
  5503.  
  5504.  The spooler must be able to access the System Code Page Information
  5505.  when it is invoked (user command SPOOL) from some system provided data
  5506.  segment. The information required is that provided by the CONFIG.SYS
  5507.  command DEVINFO. This information includes the printer name, printer
  5508.  type, code page, and fonts provided in the printer hardware and the
  5509.  path name of the font file to be used.
  5510.  
  5511.  Font Monitor Buffer Commands
  5512.  
  5513.  The Font Monitor Buffer Commands that provide the code page and font
  5514.  switch interface between the printer device driver and the spooler
  5515.  monitor are as follows:
  5516.  
  5517.  1. Activate Font
  5518.  
  5519.  2. Query Active Font
  5520.  
  5521.  3. Verify Font
  5522.  
  5523.  These commands and their responses are described in detail in "Font
  5524.  Monitor Buffer Commands."
  5525.  
  5526.  
  5527.  165. DOSMUXSEMWAIT Does Not Work with PHYSTOUVIRT Selectors
  5528.  
  5529.  
  5530.  Problem:
  5531.     When a Device Driver gives an application access to a portion of
  5532.  its Data Segment (via PHYSTOUVIRT) and the application uses that
  5533.  storage for RAM Semaphores between it and the Device Driver, the
  5534.  application cannot use the MUXSEMWAIT function when RAM Semaphores
  5535.  from that Data Segment are included in the Semaphore List. OS/2
  5536.  indicates that a General Protection Fault (Trap D) has occurred even
  5537.  though the selector of the RAM Semaphore is valid in the LDT.
  5538.     SEMWAIT on a single semaphore is able to use that PHYTOUVIRT Data
  5539.  Segment successfully but the MUXSEMWAIT does not. Currently,
  5540.  MUXSEMWAIT does not allow storage created via PHYSTOUVIRT to be used
  5541.  for RAM Semaphores.
  5542.  
  5543.  Solution:
  5544.     Microsoft is researching this problem for a possible solution to be
  5545.  included in OS/2 Version 1.1
  5546.  
  5547.  
  5548.  166. Cannot CALL CALL.BAT, but Can CALL CALL.CMD
  5549.  
  5550.  Problem:
  5551.     Consider two BAT/CMD files named CALL.BAT and CALL.CMD. Each file
  5552.  contains the command DIR. When the command "CALL CALL" is entered in
  5553.  protect mode, the file CALL.CMD is executed and you get a DIR as
  5554.  expected. When the command "CALL CALL" is entered in real mode, the
  5555.  file CALL.BAT is not executed at all.
  5556.     This same thing happens also in DOS Version 3.30. However, this is
  5557.  a problem in Version 3.30, and should be corrected in a future version
  5558.  of DOS. The command "CALL" really should have meaning to DOS only when
  5559.  it is the first lexical token on a line.
  5560.  
  5561.  
  5562.  167. Protect Mode "Dir | More" Requires Two CTRL-BREAKs to Stop
  5563.  
  5564.  Problem:
  5565.     Protect Mode "dir | more" or "type file | more" requires two
  5566.  CTRL-BREAKs to stop. If you press only one CTRL-BREAK, then press any
  5567.  key at "-- More --", the process ends without warning before another
  5568.  "-- More --" is encountered. The problem may be occurring because a
  5569.  new CMD.EXE is exceeded for the DIR command.
  5570.  
  5571.  Response:
  5572.     Microsoft is researching this problem and will post new information
  5573.  as it becomes available.
  5574.  
  5575.  
  5576.  168. VioPopUps Can Hang System
  5577.  
  5578.  Problem:
  5579.     The system hangs if an application does not end a VioPopUp.
  5580.  
  5581.  Response:
  5582.     Microsoft is researching this problem and will post new information
  5583.  as it becomes available.
  5584.  
  5585.  
  5586.  169. With ANSI.SYS, ESC in Real Mode Takes Cursor in Wrong Place
  5587.  
  5588.  Problem:
  5589.  
  5590.  With DEVICE=C:\OS2\ANSI.SYS in CONFIG.SYS, pressing the ESC key on
  5591.  the real-mode command line takes the cursor two lines down and 17
  5592.  columns to the right on a PS/2 with an 8513 display. The following
  5593.  command will be echoed starting from that position. The cursor should
  5594.  go to the first position (after the prompt) in the next line, as it
  5595.  does without ANSI.SYS in real mode and in protect mode with or without
  5596.  ANSI ON. This problem occurs on a PS/2 model 80 with 8513 color
  5597.  display, but the problem does not seem to occur on an AT with EGA.
  5598.  However, PC-DOS Version 3.30 fails in the same way on an AT with EGA.
  5599.  
  5600.  Response:
  5601.  
  5602.  Microsoft has confirmed this to be a problem in Version 1.00. We are
  5603.  researching this problem and will post new information as it becomes
  5604.  available.
  5605.  
  5606.  One possible workaround is to place the following commands at the end
  5607.  of your prompt, as follows
  5608.  
  5609.  $e1s$e1A$_$e1u
  5610.  
  5611.  where the three "1" characters are replaced by cents signs, char(155).
  5612.  
  5613.  
  5614.  170. Under Topview Copy to Open Drive Hangs System
  5615.  
  5616.  Problem:
  5617.  
  5618.  Under Topview, the following steps will produce a system hang:
  5619.  
  5620.  1. Select command processor.
  5621.  
  5622.  2. Copy a file to Drive A with no disk in it.
  5623.  
  5624.  The system hangs without giving any message and it has to be powered
  5625.  off and back on again.
  5626.  
  5627.  Response:
  5628.  
  5629.  Microsoft has confirmed this to be a problem in Version 1.00. We are
  5630.  researching this problem and will post new information as it becomes
  5631.  available.
  5632.  
  5633.  
  5634.  171. Mdraw Program Does Not Restore the Screen after VioPopUp
  5635.  
  5636.  Problem:
  5637.     When using the mdraw program in the MANDEL example, the screen is
  5638.  not restored correctly after a VioPopUp occurs. Also, the system
  5639.  sometimes locks up when running the program on the new version of OS/2
  5640.  (87294) even though it ran properly on the old OS/2 SDK (3.42.1.1).
  5641.  
  5642.  Response:
  5643.     We found that removing the SetScanClear call in the ModeWait thread
  5644.  eliminated the problem. Following are the ModeWait and SaveRedrawWait
  5645.  threads from the modified mdraw program.
  5646.     You will notice that the semaphore requests and clears have been
  5647.  removed; this is because they were originally put in the program as a
  5648.  workaround for a problem in the OS/2 kernel. That problem has been
  5649.  corrected in the new version and if you leave the semaphores in, then
  5650.  a deadlock condition can result.
  5651.  
  5652.  /**     mode_wait - wait for mode reset request
  5653.   *
  5654.   *      This routine is executed by another thread that is started
  5655.   *      by the main routine.
  5656.   *
  5657.   *      This routine calls VIOmode_wait requesting to be notified
  5658.   *      after the completion of an application or hard error pop-up.
  5659.   *      On such a notification, it puts the screen in the desired
  5660.   *      graphics mode.
  5661.   */
  5662.  
  5663.  void mode_wait ()
  5664.  {
  5665.          unsigned NotifyType;
  5666.  
  5667.          while (TRUE) {
  5668.                  /* wait for notification to restore mode */
  5669.                  VIOMODEWAIT (0, &NotifyType, 0);
  5670.                  if (NotifyType == 0 && graphics)
  5671.                          VIOSETMODE ((struct ModeData far *)&grmode, 0);
  5672.                      /*  SetScanClear ();  */
  5673.          }
  5674.  }
  5675.  
  5676.  /**     redraw_wait - wait for mode reset request
  5677.   *
  5678.   *      This routine is executed by another thread that is started
  5679.   *      by the main routine.
  5680.   *
  5681.   *      This routine calls VioSavRedrawWait requesting to be notified
  5682.   *      for both save and redraw. On save notification, it copies the
  5683.   *      EGA adapter memory to allocated memory segments. On redraw
  5684.   *      notification, it puts the screen in the desired graphics mode
  5685.   *      and then redraws the Mandelbrot set.
  5686.   */
  5687.  
  5688.  void redraw_wait ()
  5689.  {
  5690.          unsigned NotifyType;
  5691.  
  5692.          while (TRUE) {
  5693.                  VIOSAVREDRAWWAIT (0, &NotifyType, 0);
  5694.  
  5695.                  if (graphics) {
  5696.                          if (NotifyType == 0) {
  5697.                                  /* save graphics screen */
  5698.      /*     DOSSEMREQUEST ((unsigned long)(long far *)&drawsem, (long)-1); */
  5699.                                  SetScanSave (curr->desc->savesel);
  5700.                                  SetScanClear ();
  5701.                                  continue;
  5702.                          }
  5703.                          else if (NotifyType == 1) {
  5704.                                /* restore graphics screen */
  5705.                                dpoffset = 0;
  5706.                                VIOSETMODE ((struct ModeData far *)&grmode, 0);
  5707.                                SetScanClear ();
  5708.                                SetDVideo ();
  5709.                                SetScanRestore (curr->desc->savesel);
  5710.                                SetEVideo ();
  5711.              /*       DOSSEMCLEAR ((unsigned long)(long far *)&drawsem);  */
  5712.                          }
  5713.                  }
  5714.          }
  5715.  }
  5716.  
  5717.  
  5718.  172. Correct Use of Length Parameters in OS/2 API Calls
  5719.  
  5720.  The following considerations are necessary when calling API calls that
  5721.  require a length parameter.
  5722.  
  5723.  1. Check the documentation to see if a parameter must be set to the
  5724.     size of the receiving structure. If this is not done before the
  5725.     call, OS/2 will return an error code. An example is VioGetMode.
  5726.     This call takes a pointer to a structure, the first two bytes of
  5727.     which must be set to the size of the structure before the call. The
  5728.     following code fragment is an example:
  5729.  
  5730.     unsigned rc;
  5731.     struct ModeData VioMode;
  5732.  
  5733.     VioMode.length = sizeof(VioMode);       /* set to the right size*/
  5734.     rc = VIOGETMODE((struct ModeData far *) &VioMode);
  5735.  
  5736.  2. If the parameter is used for both informing OS/2 about a size upon
  5737.     calling the API and returning a length, it may need to be checked
  5738.     and/or reset before calling the API call again. An example is the
  5739.     ByteCnt parameter in the DosMonRead call. This must be set to the
  5740.     size of DataBuffer before calling DosMonRead but upon completion of
  5741.     the call will contain the count of bytes actually read. Therefore,
  5742.     the ByteCnt parameter might have to be reset before every call to
  5743.     DosMonRead and not just once in the initialization of the program
  5744.     using it.
  5745.  
  5746.  
  5747.  173. PS/2 Model 80 Not Booting Microsoft OS/2
  5748.  
  5749.  Some PS/2 Model 80s are being shipped with a parameter in their setup
  5750.  that causes the OS/2 SDK to hang when booting. The problem can be
  5751.  resolved by following the steps below.
  5752.  
  5753.   1. Boot up the PS/2 Model 80 Reference Configuration (Setup) Disk to
  5754.      enter setup for the PS/2.
  5755.  
  5756.   2. From the Main menu, enter option 3, Set Configuration.
  5757.  
  5758.   3. From the Set Configuration menu, enter option 5, Run Auto
  5759.      Configuration. This will reset options based on what the setup
  5760.      program can detect regarding installed hardware.
  5761.  
  5762.   4. Exit and save the configuration values.
  5763.  
  5764.   5. Attempt to boot the MS OS/2 installation disk.
  5765.  
  5766.   6. If it still does not boot, proceed to step 7; if it does boot,
  5767.      you're finished.
  5768.  
  5769.   7. Boot from the PS/2 Model 80 Reference Configuration (Setup) disk
  5770.      and go to the Set Configuration menu again.
  5771.  
  5772.   8. Enter option 2, Change Configuration.
  5773.  
  5774.   9. Go to the page that show the options for the slot number that your
  5775.      hard disk controller card is on and note the value of the adapter
  5776.      memory location.
  5777.  
  5778.  10. Use the F5 and F6 keys to select different values for the adapter
  5779.      memory location and then go to step 4 above.
  5780.  
  5781.  11. Any special options that were not detected by Run Auto
  5782.      Configuration can be added after confirming that OS/2 can be
  5783.      booted off of the machine with a minimum configuration set by the
  5784.      setup program.
  5785.  
  5786.  
  5787.  174. Differences between KBD, VIO, and MOU Calls and IOCTLs
  5788.  
  5789.  Question:
  5790.     An OS/2 application can call for video, keyboard, mouse, and disk
  5791.  I/O services. Some of these functions are duplicates of those
  5792.  available with the VIO, KBD, and mouse subsystems.
  5793.     Are there any differences between using the KBDxxx call and the
  5794.  equivalent IOCTL call?
  5795.  
  5796.  Response:
  5797.     The KBDxxx calls are mapped to the appropriate IOCTL call in the
  5798.  KBDxxx.dll library. The difference is that if you used the KbdRegister
  5799.  call to register replacement routines for the keyboard driver, the
  5800.  KBDxxx calls would go to your routine, while the IOCTLs would still go
  5801.  to the KBD driver.
  5802.     This would be useful within a registered routine that wanted to
  5803.  access the real keyboard but could not because it had re-registered the
  5804.  KBDxxx functions it wanted to use.
  5805.     This also applies to the VIOxxx calls and MOUxxx calls.
  5806.  
  5807.  
  5808.  175. Calling DosExit from within Thread 1
  5809.  
  5810.     There will be a change in the way DosExit behaves when it is called
  5811.  in the context of thread 1 of a process. This change will affect
  5812.  Versions 1.1 and later of OS/2. The ActionCode parameter of the
  5813.  DosExit call will be ignored and all threads in the process will be
  5814.  marked to terminate.
  5815.  
  5816.  
  5817.  176. Hiding Entry Points in a DLL
  5818.  
  5819.  Question:
  5820.  
  5821.  When you create a DLL (Dynamic Linked Library), there may be many
  5822.  entry points used by the library itself. Can you hide these entry
  5823.  points to keep other programmers from calling anything but the
  5824.  approved entry points?
  5825.  
  5826.  Response:
  5827.  
  5828.  You can use ordinals instead of names to make it a little harder to
  5829.  figure out. However, that procedure has never stopped people in the
  5830.  past from obtaining these entry points by disassembling your code.
  5831.  
  5832.  
  5833.  177. OS/2 SDK: Novell's DOS Netware Doesn't Run in DOS 3.x Box
  5834.  
  5835.  Novell's DOS Netware will not run in the OS/2 DOS compatibility mode;
  5836.  neither will the Microsoft Networks or DOS LAN Manager software. The
  5837.  Microsoft network software that is available for OS/2 (licensed to
  5838.  network board manufacturers, not sold retail to the public) is OS/2
  5839.  LAN Manager. Once a drive is connected in an OS/2 application (such as
  5840.  CMD.EXE), programs in the DOS compatibility mode can access the drive.
  5841.  However, they are not able to make new connections (these must be done
  5842.  in an OS/2 application). Please contact Novell for information about
  5843.  OS/2 versions of its Netware software.
  5844.  
  5845.  
  5846.  178. OS/2 SDK: Problem When Using DOSFREESEG on Locked Segments
  5847.  
  5848.  Question:
  5849.  
  5850.  Is there a problem when using DOSFREESEG on locked segments?
  5851.  
  5852.  Response:
  5853.  
  5854.  Microsoft has confirmed this to be a problem in Version 1.00. This
  5855.  problem will be corrected in a future release.
  5856.  
  5857.  In the SDK release, one thread in an application may free a segment
  5858.  using DOSFREESEG while the segment is locked by a device driver for
  5859.  another thread in the same process. This has the possibility of
  5860.  causing unpredictable system failures, because the memory to which the
  5861.  device driver is writing may no longer be owned by the process.
  5862.  
  5863.  The workaround is for the process to ensure it does not free a memory
  5864.  segment while another thread in the process may be performing I/O to
  5865.  it.
  5866.  
  5867.  
  5868.  179. VioGetConfig Adapter Type and Display Type Values
  5869.  
  5870.  Question:
  5871.     In the listing for the VioGetConfig call in the OS/2 SDK
  5872.  programmer's reference, possible values for the "adapter type" and
  5873.  "display type" fields in the returned ConfigData structure are listed
  5874.  as follows:
  5875.  
  5876.      Adapter Type
  5877.       0 = Monochrome/printer adapter
  5878.       1 = Color graphics adapter
  5879.       2 = Enhanced graphics adapter
  5880.  
  5881.      Display Type
  5882.       0 = Monochrome display
  5883.       1 = Color display
  5884.       2 = Enhanced color display
  5885.  
  5886.     Are there any others? Would it be safe to check for EGA
  5887.  compatibility by checking that the adapter type is greater than or
  5888.  equal to two?
  5889.  
  5890.  Response:
  5891.     The following are possible values for these fields:
  5892.  
  5893.      Adapter Type
  5894.       0 = Monochrome/printer adapter
  5895.       1 = Color graphics adapter
  5896.       2 = Enhanced graphics adapter
  5897.       3 = VGA or PS/2 display adapter
  5898.       4-6 = Reserved
  5899.       7 = PS/2 8514/A display adapter
  5900.  
  5901.      Display Type
  5902.       0 = Monochrome display
  5903.       1 = Color display
  5904.       2 = Enhanced color display
  5905.       3 = PS/2 Monochrome display 8503
  5906.       4 = PS/2 Color displays 8512 and 8513
  5907.       5-8 = Reserved
  5908.       9 = PS/2 Color display 8514
  5909.  
  5910.        Note that you should not interpret values above two as
  5911.  representing EGA compatibility.
  5912.  
  5913.  
  5914.  
  5915.  180. Recapturing Thread's Stacks
  5916.  
  5917.  Question:
  5918.     What is the best method for freeing the memory used for a thread's
  5919.  stack? I have several threads starting up and subsequently dying off.
  5920.  I used MALLOC() to create the thread's stacks and should free up this
  5921.  memory when the threads die because not doing so adds thousands of
  5922.  bytes of unusable memory.
  5923.     If there is a method for freeing this memory, how can I be sure it
  5924.  is serialized properly? For example, just before thread A dies, it
  5925.  clears a semaphore that signals another thread (B) that it can "clean
  5926.  up" after thread A. Thread B unblocks from the DosSemWait() call and
  5927.  issues a FREE() call that releases thread A's stack. However, if the
  5928.  DosExit in thread A has not yet been executed, this situation creates
  5929.  a "window" that could toss the stack before thread A is properly
  5930.  terminated.
  5931.  
  5932.  Response:
  5933.     In any case, the thread that exits cannot free its own stack. The
  5934.  best you can do is to set a flag (stack-free flag) (i.e., have the
  5935.  routine that spawns threads re-use or free the stacks).
  5936.     To clear a semaphore before exiting the process, do the following:
  5937.  
  5938.     DosEnterCritSec
  5939.     DosSemClear
  5940.     DosExit
  5941.  
  5942.     When the thread exits, the other threads in the process will be
  5943.  thawed (i.e., the equivalent of DosExitCritSec occurs at DosExit
  5944.  time). This method has some benefits (i.e., you could put the stack
  5945.  selector into a list before exiting). However, this method only works
  5946.  within one process (although this may not even be a problem because
  5947.  threads belong to processes).
  5948.     Another way to set a flag (not a semaphore) is to do the following:
  5949.  
  5950.       mov       flag, STACK_FREE
  5951.  ; now from this point you can't use the stack.
  5952.       mov       ax, segment  STACK_EXIT
  5953.       mov       ss, ax
  5954.       mov       sp, offset   STACK_EXIT
  5955.       call      DosExit
  5956.  ....
  5957.                 dw   2 dup (0)
  5958.  STACK_EXIT     dw   2 dup (0)
  5959.  
  5960.     After you flag the stack as being free, you cannot use the stack
  5961.  again. However, simply switch the "ss" to point to another area, and
  5962.  call DosExit. The area you point to (reserved for doing this), always
  5963.  has two zeros (as parameters) and a place to put the return address.
  5964.  It does not matter if the return address gets overwritten (by another
  5965.  exiting thread) because it will not be used to return. (Note that the
  5966.  return address is not used anyway. DosExit API is performed through a
  5967.  call gate and the return address will be put on the threads ring 0
  5968.  stack. However, this should not be assumed.)
  5969.     Therefore, in the above example, when "flag" has STACK_FREE the
  5970.  stack can be reused/freed. This method works correctly for a program
  5971.  that creates stacks and threads as they run short (i.e., no blocking
  5972.  to wait for a stack to become available). If you will need to block, a
  5973.  semaphore will have to be added; however, you will still need to use
  5974.  the flag to prevent a "window."
  5975.     Similar to the prior solution, the thread spawning off a new thread
  5976.  could check to see if other threads are still in existence. (If there
  5977.  are no other threads, the spawning thread's stack may be reused). To
  5978.  do this, issue the DosGetPrty call with the TID of the thread you are
  5979.  checking. If the thread has already exited, this API will return an
  5980.  error (ERROR_INVALID_THREADID).
  5981.     Depending on the application, you may have a pool of threads
  5982.  waiting for functions to call, i.e., as threads become idle, they add
  5983.  on to a count (threads_waiting), and as they start performing tasks,
  5984.  they naturally subtract one from the count. (Of course, the
  5985.  count_waiting has to be protected by semaphores). The following is an
  5986.  example:
  5987.  
  5988.  long      SemSerialWaiting;
  5989.  int       vCntWait;
  5990.  int       vCntWorkerThreads;
  5991.  
  5992.  long      SemCallFnc;
  5993.  long      SemWaiting;
  5994.  void far  (*vpFncToCall)();
  5995.  
  5996.  SpawnThread (fnc)
  5997.  void far (*fnc)();
  5998.  {
  5999.  
  6000.       DosSemRequest (&SemCallFnc, -1L);
  6001.       DosSemRequest (&SemSerialWaiting, -1L);
  6002.       if (vCntWait == 0  &&  vCntWorkerThreads < MAX_THREADS) {
  6003.            ... alloc stack ...
  6004.            DosCreateThread (threadwaiting ... );
  6005.            vCntWorkerThreads++;
  6006.       }
  6007.       vpFncToCall = fnc;
  6008.       DosSemClear (&SemSerialWaiting);
  6009.       DosSemClear (&SemWaiting);
  6010.  }
  6011.  
  6012.  ThreadWaiting ()
  6013.  {
  6014.       void far  (*fnc)();
  6015.  
  6016.       for (; ;) {
  6017.            DosSemRequest  (&SemSerialWaiting, -1L);
  6018.            vCntWait++;
  6019.            DosSemClear    (&SemSerialWaiting);
  6020.  
  6021.            /*
  6022.             * Wait for something to do
  6023.             */
  6024.            DosSemRequest  (&SemWaiting, -1L);
  6025.  
  6026.            DosSemRequest  (&SemSerialWaiting, -1L);
  6027.            vCntWait--;
  6028.            fnc = vpFncToCall;
  6029.            DosSemClear    (&SemCallFnc);
  6030.            DosSemClear    (&SemSerialWaiting);
  6031.  
  6032.            (*fnc)();
  6033.       }
  6034.  }
  6035.  
  6036.     If you are creating threads quickly for small tasks, use this
  6037.  method (however, it is probably application dependent).
  6038.     When SpawnThread (fnc) is called, (*fnc)() is invoked. A "waiting"
  6039.  thread in a pool of threads calls the function. If no threads are
  6040.  waiting, a new thread may be created. If all threads are in use and no
  6041.  more threads may be created, SpawnThread may be blocked. (A useful
  6042.  modification is to put a time-out on SemWaiting in ThreadWaiting so
  6043.  that the threads exit after a couple of seconds of waiting, instead of
  6044.  waiting indefinitely. However, this modification requires some form of
  6045.  stack recapturing.)
  6046.     A combination of the above suggested solutions will probably work
  6047.  best, depending on the speed at which your application creates and
  6048.  destroys threads, the amount of CPU used, the thread life, the number
  6049.  of threads required, and so on.
  6050.  
  6051.  
  6052.  181. Semaphores on a LAN Manager Server
  6053.  
  6054.  Question:
  6055.     Can system semaphores created with DOSCREATESEM be used across a
  6056.  network just like named pipes and mailslots, since a file name must be
  6057.  specified as it is in named pipes and mailslots?
  6058.  
  6059.  Response:
  6060.     No, we do not have a "net semaphore." As an alternative (other than
  6061.  record locking) you could use a named pipe.
  6062.     On the server end you would need a thread looping on the following:
  6063.  
  6064.       DosConnectNmPipe
  6065.       DosDisconnectNmPipe
  6066.  
  6067.     From the remote end you could then use the following:
  6068.  
  6069.       DosWaitNmPipe  - Wait for named pipe (semaphore)
  6070.       DosOpen        - Get the named pipe (semaphore)
  6071.       DosClose       - Clear the named pipe (semaphore)
  6072.  
  6073.     Note: You could create a counting semaphore with multiple instances
  6074.  of a named pipe.
  6075.  
  6076.  
  6077.  182. Control-C and Control-Break Signals in the Protected Mode
  6078.  
  6079.  Question:
  6080.     What is the difference between Control-C and Control-Break signals
  6081.  in protected mode?
  6082.  
  6083.  Response:
  6084.     In protected mode, when the keyboard is in the "raw mode,"
  6085.  Control-C generates a Control-C and Control-Break is converted into
  6086.  SIGBREAK.
  6087.     If the keyboard is in "cooked mode," then Control-C and
  6088.  Control-Break will be converted into SIGBREAK.
  6089.  
  6090.  
  6091.  183. OS/2 API Calls
  6092.  
  6093.  Question:
  6094.     Are all of the OS/2 API calls (system calls, LAN Manager,
  6095.  Presentation Manager, etc.) reentrant? If not, which are reentrant and
  6096.  which are not?
  6097.  
  6098.  Response:
  6099.     All OS/2 API calls are reentrant.
  6100.  
  6101.  
  6102.  184. Shared Memory Segments and/or System Semaphores
  6103.  
  6104.  Question:
  6105.     What happens when a process that created a shared segment and/or a
  6106.  system semaphore dies?
  6107.  
  6108.  Response:
  6109.     OS/2 maintains a use-count for every shared segment. When a process
  6110.  wants to use a shared segment, the use-count is increased by one. When
  6111.  a process using a shared segment terminates (or frees a shared
  6112.  segment), the use-count associated with the segment is decremented.
  6113.  The OS/2 memory manager does not free a shared memory segment until
  6114.  its use-count is zero.
  6115.     In the case of system semaphores, when the owner dies, OS/2
  6116.  releases the semaphore and notifies the next thread that gets the
  6117.  semaphore that the owner ended while holding the semaphore.
  6118.  
  6119.  
  6120.  185. Using FORMAT Utility with "/s" Option
  6121.  
  6122.  Problem:
  6123.     Why does not FORMAT.COM with /s work from any given directory other
  6124.  than the root ?
  6125.  
  6126.  Response:
  6127.     The FORMATS.TBL must be modified so that each line is preceded by a
  6128.  backslash (\). This would allow the operating system files listed in
  6129.  the FORMATS.TBL to be to extracted correctly from the root.
  6130.  
  6131.  
  6132.  186. Units of MouGetScaleFact and MouSetScaleFact Calls
  6133.  
  6134.  Question:
  6135.     In what units are the scale factors? It is the same when the screen
  6136.  is in text mode or graphics mode?
  6137.  
  6138.  Response:
  6139.     The units of the scaling factors used in MouSetScaleFact depend on
  6140.  the current screen mode. The units field specifies the number of
  6141.  mickeys the mouse must move to change the screen position by one
  6142.  screen coordinate (either one character or one pixel depending on the
  6143.  current mode).
  6144.  
  6145.  
  6146.  187. OS/2 SDK: Track Layout Table Information
  6147.  
  6148.  Question:
  6149.  
  6150.  How can I obtain the track layout information to be used on read or
  6151.  write requests to a specific physical disk drive?
  6152.  
  6153.  Response:
  6154.  
  6155.  The IOCtl category 8 (Logical Disk Control IOCtl commands) function
  6156.  63H returns the extended BPB for the device. You can get the number of
  6157.  sectors and the sector size from this structure and prepare the track
  6158.  layout table as described in functions 44H, 64H, and 65H. The
  6159.  following is a description of the track layout table:
  6160.  
  6161.     Sector number for sector 1           WORD
  6162.     Sector size   for sector 1           WORD
  6163.     Sector number for sector 2           WORD
  6164.     Sector size   for sector 2           WORD
  6165.     Sector number for sector 3           WORD
  6166.     Sector size   for sector 3           WORD
  6167.                    .............
  6168.                    .............
  6169.     Sector number for sector n           WORD
  6170.     Sector size   for sector n           WORD
  6171.  
  6172.  The track layout table can be passed on to read or write calls.
  6173.  
  6174.  
  6175.  188. Use of Malloc() Versus Dosallocseg in C Programs
  6176.  
  6177.  Question:
  6178.     In the sample program ARGUMENT.C in the OS/2 SDK, the following
  6179.  space is being allocated for a child thread's stack area:
  6180.  
  6181.         /* since this is written in C, Dosallocseg cannot be used here
  6182.  */ if( threadStack = (int *)malloc(sizeof(int) * STACK_SIZE) ) {
  6183.  
  6184.     What does this mean? Can Dosallocseg be used?
  6185.  
  6186.  Response:
  6187.     You cannot use Dosallocseg to allocate a thread's stack area from a
  6188.  C program because the C run-time libraries expect SS=DS for small and
  6189.  medium model programs.
  6190.     Dosallocseg allocates space out of the global heap, which is not in
  6191.  the DS segment. Therefore, the thread's SS would not be the same as
  6192.  its DS.
  6193.     Since malloc() allocates space out of the local heap, which is in
  6194.  the DS segment, the thread's SS would be the same as its DS.
  6195.     If you were coding in assembler, the C run times would not matter
  6196.  and Dosallocseg would work.
  6197.     Also, in large-model C programs, the run times do not assume SS=DS.
  6198.  As a result, they also will work. Dosallocseg can be used to allocate
  6199.  space from small model programs, but that space cannot be used for a
  6200.  child thread's stack.
  6201.  
  6202.  
  6203.  189. Can CTRL-ESC and ALT-ESC Be Disabled?
  6204.  
  6205.  Question:
  6206.     Can I disable or set my own handler for CTRL-ESC and ALT-ESC to
  6207.  prevent someone from switching my screen groups?
  6208.  
  6209.  Response:
  6210.     No. These key combinations cannot be disabled or trapped by any
  6211.  method, including keyboard monitors.
  6212.  
  6213.  
  6214.  190. Disk Driver Differences Between 3.5" and 5.25" Disks
  6215.  
  6216.  Question:
  6217.     Why are there several different files (OS2BIO.COM, DISK01.SYS)
  6218.  between 3.5 inch and 5.25 inch MS OS/2?
  6219.     Why are DISK01.506 and DISK01.ESD found only in the 3.5 inch MS OS/2?
  6220.     How are they used?
  6221.  
  6222.  Response:
  6223.     These files are the drive-specific part of MS OS/2. There are
  6224.  different files for different hardware.
  6225.     The DISK01.ESD is copied to DISK01.SYS for the PS/2 equipped with
  6226.  an ESDI hard disk.
  6227.     The DISK01.506 is the installed default driver. If the PS/2 is
  6228.  equipped with an ESDI hard disk, the DISK01.ESD must be copied to
  6229.  DISK01.SYS to access the hard drive.
  6230.  
  6231.  
  6232.  191. How To Determine if a Process Is Detached
  6233.  
  6234.     The correct procedure used to determine if a process is running
  6235.  "detached" is as follows:
  6236.  
  6237.     Call VioGetAnsi and look for a return code of either zero or 465,
  6238.  ERROR_VIO_DETACHED. If you receive an error code of zero, you are not
  6239.  running a detached process. If you receive an error code of 465, you
  6240.  are running a detached process.
  6241.  
  6242.     It also is important not to call VioGetAnsi when a VioPopUp is in
  6243.  effect, as this will return zero even if the process doing the popup
  6244.  is detached.
  6245.     To be compatible with future releases of OS/2, a process should not
  6246.  be relying on the value of its current screen group.
  6247.  
  6248.  
  6249.  192. Loading OS/2 SDK 1.05 on Drive D and Booting off Floppy Disk
  6250.  
  6251.  Question:
  6252.  
  6253.  I wish to load the SDK Version 1.05 for OS/2 Version 1.10 onto Drive D
  6254.  and boot off a floppy. In this way I can leave my DOS environment
  6255.  unaffected. I was able to do this with SDK Version 1.03 but not with
  6256.  SDK Version 1.05. How can this be done?
  6257.  
  6258.  Response:
  6259.  
  6260.  To load the SDK Version 1.05 onto Drive D and boot off a floppy, do
  6261.  the following:
  6262.  
  6263.  1. Make a copy of the SDK Version 1.05 Install disk (Disk 1). It will
  6264.     later be used to boot the system.
  6265.  
  6266.  2. Use XCOPY to copy the first five disks to Drive D. These disks are
  6267.     Install, Program 1, Program 2, Program 3, and Supplement.
  6268.  
  6269.  3. In the directory D:\OS2 there is now a file called OS2.INI. This
  6270.     file contains configuration information used by Presentation
  6271.     Manager. This file also contains approximately 49 references to
  6272.     Drive C. Use a tool such as DOS DEBUG to change these references to
  6273.     Drive D.
  6274.  
  6275.  4. In the directory D:\OS2\DLL there two files, EGA.DLL and VGA.DLL.
  6276.     Copy the appropriate file for your environment to DISPLAY.DLL.
  6277.  
  6278.  5. On the copy of the Install disk, copy CONFIG.211 to CONFIG.SYS,
  6279.     OS2INIT.211 to OS2INIT.CMD, and STARTUP.211 to STARTUP.CMD.
  6280.  
  6281.  6. Make the modifications to OS2INIT and STARTUP that fit your
  6282.     environment.
  6283.  
  6284.  7. In the CONFIG.SYS, change all reference to Drive C to Drive D.
  6285.  
  6286.  8. Also in the CONFIG.SYS file, modify the PROTSHELL command to read
  6287.     as follows:
  6288.  
  6289.     PROTSHELL=D:\OS2\PMSHELL.EXE D:\OS2\OS2.INI D:\OS2\PBIN\CMD.EXE /K
  6290.            D:\OS2INIT.CMD
  6291.  
  6292.  9. You should now be able to boot from the disk with OS/2 loaded on
  6293.     Drive D.
  6294.  
  6295.  
  6296.  
  6297.  193. OS/2 DosGetMessage() Informational Messages
  6298.  
  6299.  OS/2 API call DosGetMessage() does not return the message number in
  6300.  the user's buffer for "I" (informational) type messages.
  6301.  
  6302.  The following table summarizes the behavior of DosGetMessage() for
  6303.  different types of message classifications. Please note that the
  6304.  Message ID (or classification) appears as the eighth character in the
  6305.  message number (e.g. OSO0001E, FOO0010W, BAR0001I). Only the first
  6306.  seven characters of the Message ID are returned for "E" (error) and
  6307.  "W" (warning) messages, so the message classification is not placed
  6308.  with the message number.
  6309.  
  6310.       Message
  6311.     Classification   Message display
  6312.     --------------   ---------------
  6313.  
  6314.     E, W             Includes message number (i.e., OSO0001:
  6315.                                           <message text>)
  6316.  
  6317.     All Other        No message number (i.e., <message text>) displayed
  6318.     messages         for "I" (informational) or other messages.
  6319.  
  6320.  Message classifications were created to allow the user (and the
  6321.  system) to distinguish between system messages (with Error and Warning
  6322.  classifications), and informational or help messages.
  6323.  
  6324.  
  6325.  194. OS/2 SDK: Definition of APIENTRY
  6326.  
  6327.  Using APIENTRY is equivalent to using the C keywords far and pascal.
  6328.  APIENTRY is defined in the C include file OS2DEF.H, as follows:
  6329.  
  6330.     #define APIENTRY far pascal
  6331.  
  6332.  All OS/2 APIs are defined as being APIENTRY. In addition to these
  6333.  system APIs, some application functions (such as thread-handling
  6334.  functions) must be defined using the far keyword. For example, an
  6335.  application function can use the following APIENTRY definition:
  6336.  
  6337.     int APIENTRY Foo(int bar);
  6338.  
  6339.  If this function is then used in a non-DOS or OS/2 environment (in
  6340.  an environment where far and/or pascal code is not supported or
  6341.  necessary), APIENTRY can be redefined as follows:
  6342.  
  6343.     #define APIENTRY /* defined as nothing */
  6344.  
  6345.  This allows more flexibility than typing "far pascal" in front of each
  6346.  function.
  6347.  
  6348.  For more information on the far and pascal keywords, see the Microsoft
  6349.  C compiler reference manuals.
  6350.  
  6351.  
  6352.  195. Programmer's Reference Missing Register Bitmasks
  6353.  
  6354.  Pages 363-365 in the "Microsoft Operating System/2 Programmer's
  6355.  Reference" do not completely list the bitmasks and function indexes
  6356.  for KBD calls. The indexes should also include the following entries:
  6357.  
  6358.  Bit     Function        Index
  6359.  
  6360.  6      KbdOpen           6
  6361.  7      KbdClose          7
  6362.  8      KbdGetFocus       8
  6363.  9      KbdFreeFocus      9
  6364.  10     KbdGetCP          0Ah
  6365.  11     KbdSetCP          0Bh
  6366.  12     KbdXlate          0Ch
  6367.  13     KbdSetCusXT       0Dh
  6368.  
  6369.  
  6370.  196. IFS and File Names
  6371.  
  6372.  Question:
  6373.      I have heard that the 8.3 file name convention will change
  6374.  with installable file systems. What steps should I take so that my
  6375.  applications will be able to handle this change?
  6376.  
  6377.  Response:
  6378.      On the OS/2 API set, note that all API calls interacting with
  6379.  the file system use a handle or, if a name is required, an ASCII
  6380.  null-terminated string (ASCIIZ).
  6381.     Your programs should follow this convention whenever possible;
  6382.  do not count on such features as 8.30, forward/backward slashes, or
  6383.  any other internal structure of the file name string.
  6384.     Applications should not parse file names; leave space for 256
  6385.  characters in your file name buffer specifications. These rules should
  6386.  ensure an application's compatibility with future installable file
  6387.  systems.
  6388.  
  6389.  
  6390.  197. OS/2 and ANSI.SYS
  6391.  
  6392.  Question:
  6393.     Do the ANSI sequences of MS OS/2 support redefinition of the
  6394.  keyboard?
  6395.  
  6396.  Response:
  6397.     In real mode, ANSI support is obtained by including the ANSI.SYS
  6398.  device driver in your CONFIG.OS2 file. This is the same as using ANSI
  6399.  under DOS.
  6400.     In protected mode, ANSI is obtained by the base video drivers. It
  6401.  also support the remapping of keys through KbdRegister. One
  6402.  KbdRegister is allowed per screen group.
  6403.     If you are using ANSI for your own purposes, then the remapping of
  6404.  the keys will not work.
  6405.  
  6406.  
  6407.  198. OS/2 Disk Volume Identification (ID) Information
  6408.  
  6409.  Question:
  6410.  
  6411.  We would like to know more about disk Volume IDs. We ran across these
  6412.  by accident when we DISKCOMPed two OS/2 disks (made with OS/2
  6413.  DISKCOPY) under DOS Version 3.30 and they did not compare. Where does
  6414.  this ID come from? Why is it different on two disks made with OS/2
  6415.  DISKCOPY, and why doesn't OS/2 DISKCOMP find this difference? What
  6416.  should we put in this field on our distribution disks?
  6417.  
  6418.  Response:
  6419.  
  6420.  The Volume ID field was added to the boot sector of OS/2 disks to
  6421.  verify whether the disk in the floppy drive has been changed. It is a
  6422.  32-bit random number that is put into the boot sector when the disk is
  6423.  formatted.
  6424.  
  6425.  OS/2 checks this ID field before doing I/O on the drive. If the ID is
  6426.  not correct, you receive a message asking for the correct disk.
  6427.  
  6428.  When a disk is duplicated under OS/2 DISKCOPY, a new value is put in
  6429.  the Volume ID field to indicate that the two disks are physically
  6430.  different, even though their contents may be the same.
  6431.  
  6432.  OS/2 DISKCOMP knows about the ID field, and ignores it when making its
  6433.  comparisons. DOS DISKCOMP does not know about the Volume ID, and flags
  6434.  it as a difference.
  6435.  
  6436.  Disks formatted under DOS do not have the Volume ID field, so OS/2 has
  6437.  a harder time telling if the disk has been changed. It is forced to
  6438.  checksum parts of the disk's root directory and FAT table, which
  6439.  requires extra disk operations for media identification. Because of
  6440.  this, we advise that you supply the Volume ID for disks to be used in
  6441.  OS/2 systems.
  6442.  
  6443.  Create the disk either through OS/2 FORMAT or DISKCOPY, or supply the
  6444.  Volume ID value by some other method. You can use anything you like
  6445.  because the number is truly random.
  6446.  
  6447.  
  6448.  199. OS/2 Does Not Recognize InPort Mouse as Bus Mouse
  6449.  
  6450.  Question:
  6451.     I have a Microsoft Bus Mouse, and I am using the MOUSEA03.SYS
  6452.  device driver. The mouse is not working properly. What is wrong?
  6453.  
  6454.  Response:
  6455.     There seems to be some confusion about mouse types. The InPort
  6456.  mouse is a Bus-type mouse, and has been marketed under that
  6457.  description. However, OS/2 considers the InPort mouse to be different
  6458.  from a Bus mouse.
  6459.     You may actually have an InPort mouse, not a Bus mouse. If this is
  6460.  the case, using the MOUSEA04.SYS driver will solve your problem.
  6461.     An easy way to confirm which type of mouse you have is to look at
  6462.  the connector with which your mouse plugs into the machine.
  6463.     If the connector is a round 9-pin connector, you have an InPort
  6464.  mouse.
  6465.     If it is a D-shaped 9-pin connector, as pictured in the following
  6466.  diagram, you have a Bus mouse:
  6467.                      ___________
  6468.                     | o o o o o |
  6469.                      \ o o o o /
  6470.                        -------
  6471.  
  6472.  
  6473.  200. MouRegister Bitmasks Incomplete in Programmer's Reference
  6474.  
  6475.  Question:
  6476.  
  6477.  Page 418 of the "Microsoft Operating System/2 Programmer's Reference"
  6478.  specifies bitmasks for registering replacement MOU calls. Are these
  6479.  masks complete?
  6480.  
  6481.  Response:
  6482.  
  6483.  No, the masks are incomplete. The high word also should contain the
  6484.  following entries:
  6485.  
  6486.  Bit    Meaning             Code
  6487.  
  6488.  20     MouFlushQue         14H
  6489.  21     MouSetDevStatus     15H
  6490.  
  6491.  
  6492.  201. Getting Selector to Video RAM
  6493.  
  6494.  Question:
  6495.     Is there an API call that will allow me to convert a physical
  6496.  segment to a valid segment selector, e.g. the DevHlp function
  6497.  PhysToVirt?
  6498.     I am trying to clear the video memory at segment B000h. I linked
  6499.  the program with IOPL. I am able to initialize the video card through
  6500.  in/out instructions, but I can not talk to its memory.
  6501.  
  6502.  Response:
  6503.     To get selectors for direct access to the video buffer, you can use
  6504.  the VioGetPhysBuf API call.
  6505.     In the more general case of nonvideo memory, you need to write a
  6506.  device driver that will communicate with your application through
  6507.  IOCTLs.
  6508.  
  6509.  
  6510.  202. Volume Label Error
  6511.  
  6512.  Page 161 of the "Microsoft Operating System/2 User's Reference" manual
  6513.  incorrectly states that the LABEL.EXE command will delete the volume
  6514.  label on the disk; Microsoft does not recommend using MS OS/2 without
  6515.  a volume label.
  6516.  
  6517.  The LABEL.EXE command will only allow you to change the existing
  6518.  label.
  6519.  
  6520.  The OS/2 user's guide incorrectly states the following:
  6521.  
  6522.     Type the volume label that you want and press the ENTER key. A
  6523.     volume label may be up to 11 characters in length and may include
  6524.     spaces, but not tabs. Or, you can press the ENTER key immediately
  6525.     if you want to delete the volume label. MS OS/2 will prompt with
  6526.     the following message:
  6527.  
  6528.     Delete current volume label  (Y/N)?_
  6529.  
  6530.     If you type "Y", MS OS/2 deletes the volume label on the disk.
  6531.     Otherwise, the volume label stays the same.
  6532.  
  6533.  If you press the ENTER key, the "no volume update" message may appear.
  6534.  
  6535.  
  6536.  203. PTrace Documentation Update
  6537.  
  6538.    Many of the functions and return codes for DosPTrace are not
  6539.  documented or are incorrectly documented.
  6540.     There is a file called PTRACE.ARC in the Software Library with more
  6541.  complete documentation on return values, functions, and how to use
  6542.  DosPTrace. This file can be found in the Software Library by searching
  6543.  for the filename, the Q number of this article, or S12008.
  6544.  
  6545.  
  6546.  204. Process IDs and Kill Signals
  6547.  
  6548.     The DosKillProcess API will unconditionally terminate any process
  6549.  (i.e., orphaned grandchildren processes). The only exception is if the
  6550.  process has installed a signal handler for the SIG_KILLPROCESS signal.
  6551.  This signal handler ignores or otherwise disables the SIG_KILLPROCESS
  6552.  signal.
  6553.     To use DosKillProcess, you must know the PID of the process you
  6554.  wish to kill. The PID is returned by the DosExecPgm call when you
  6555.  start the process. You must save this value and, if necessary, pass it
  6556.  to the process sending the kill signal because there is no subsequent
  6557.  means of determining the PID of a process.
  6558.  
  6559.  
  6560.  205. Windows 2.03 in OS/2 Compatibility Box: Mouse Cursor Nonmoving
  6561.  
  6562.     In the OS/2 compatibility box under Windows Version 2.03, the mouse
  6563.  cursor will not move. Adding "mode=B" to the mouse DEVICE statement in
  6564.  the CONFIG.SYS file will not correct this problem.
  6565.     This is a known problem in machines with VGA video adapters.
  6566.     A workaround is to remove the MOUSEA0x.SYS and POINTDD.SYS mouse
  6567.  driver files from the CONFIG.SYS file; this will enable your mouse
  6568.  under Windows in the 3.x box. Please note that removing these files
  6569.  will disable the mouse in the protect mode.
  6570.  
  6571.  
  6572.  206. Keystroke Information for OS/2
  6573.  
  6574.  Question:
  6575.     How can I get information about key presses and releases for keys
  6576.  other than the SHIFT state keys?
  6577.     Only the press generates a KbdCharIn record for normal keys. Also,
  6578.  the SHIFT state keys always return 00 for the scan code. How do I get
  6579.  the original untranslated scan code?
  6580.  
  6581.  Response:
  6582.     This information is not available in the data packet returned by
  6583.  the KbdCharIn call.
  6584.     If you register a keyboard monitor, however, you will receive data
  6585.  packets that have the KbdCharIn packet embedded, and that also contain
  6586.  the untranslated scan code and information about whether the event was
  6587.  a press or release. A monitor packet is generated for all presses and
  6588.  releases.
  6589.  
  6590.  
  6591.  207. Running Epsilon Text Editor in 3.x Box in OS/2
  6592.  
  6593.  Problem:
  6594.  
  6595.  We have a problem with the Epsilon Text Editor when running a program
  6596.  in the 3.x box of the current release of OS/2. Sometimes when we type
  6597.  a key, a different key appears.
  6598.  
  6599.  Response:
  6600.  
  6601.  The Epsilon Extension Language source that follows provides a
  6602.  workaround for those Epsilon users who use OS/2. It causes Epsilon to
  6603.  operate correctly in the DOS 3.x box, but makes it impossible to bring
  6604.  up most resident programs while Epsilon runs.
  6605.  
  6606.  To use it, perform the following steps:
  6607.  
  6608.  1. Download the following source text and put it in a file (e.g.
  6609.     OS2BOX.E).
  6610.  
  6611.  2. Run the EEL compiler on the file by typing the following:
  6612.  
  6613.     eel os2box
  6614.  
  6615.  3. Start Epsilon, and load the file by typing the following:
  6616.  
  6617.     F-3 os2box
  6618.  
  6619.  4. To make the change permanent, use the write-state command.
  6620.  
  6621.  (This information was provided by Steven Doerfler, Lugaru Software
  6622.  Ltd. "Epsilon", "EEL" and "Lugaru" are trademarks of Lugaru Software,
  6623.  Ltd. Copyright (C) 1987 Lugaru Software Ltd. All rights reserved.
  6624.  
  6625.  Limited permission is hereby granted to reproduce and modify this
  6626.  copyrighted material provided that the resulting code is used only in
  6627.  conjunction with Lugaru products and that this notice is retained in
  6628.  any such reproduction or modification.)
  6629.  
  6630.  Epsilon's normal keyboard-handling scheme involves intercepting all
  6631.  keys and passing some through the BIOS and whatever resident software
  6632.  may be present. Specifically, Epsilon passes all keys except those the
  6633.  BIOS would discard as an unrecognized combination, but which Epsilon
  6634.  recognizes. The current beta release of OS/2 occasionally gets
  6635.  confused by this, and mixes up the keys when Epsilon runs in its
  6636.  compatibility box.
  6637.  
  6638.  This file instructs Epsilon to keep all keys, so that Epsilon works in
  6639.  OS/2's compatibility box. Loading it with F-3 makes the change in the
  6640.  running version of Epsilon. The following write-state command may be
  6641.  used to make this change permanent:
  6642.  
  6643.     #include "eel.h"
  6644.  
  6645.     when_loading()
  6646.     {
  6647.     int k, tokey;
  6648.  
  6649.     for (k = 0; k < NUMKEYS; k++)/* keep all keys */
  6650.     keytran[k] = k;
  6651.     /* and translate some grey keys */
  6652.     for (k = GREYPLUS; k <= GREYESC; k++) {
  6653.     tokey = "+-*\r\b\t\033"[k - GREYPLUS];
  6654.     keytran[k] = tokey;
  6655.     keytran[NUMALT(k)] = ALT(tokey);
  6656.     }
  6657.     keytran[NUMCTRL(GREYBACK)] = DEL;
  6658.     keytran[NUMCTRL(GREYENTER)] = '\n';
  6659.  
  6660.     keytran[NUMCTRL(GREYESC)] = -1;/* but pass these to OS/2 */
  6661.     keytran[NUMALT(GREYESC)] = -1;
  6662.     }
  6663.  
  6664.  
  6665.  208. Providing Display Device Driver Support
  6666.  
  6667.  Question:
  6668.  
  6669.  My application needs to run using the features of many types of
  6670.  display adapters and displays (e.g. Tseng Labs, Paradise, STB). I
  6671.  have the following questions about how display manufacturers and
  6672.  applications get support from OS/2.
  6673.  
  6674.  First of all, will the hardware manufacturers supply device drivers
  6675.  and replacement Vio DynaLinks for their hardware? If so, will there be
  6676.  some sort of standardization of return values of calls such as
  6677.  VIOGETCONFIG [VioGetConfig() in Version 1.06 and above]?
  6678.  
  6679.  Also, if the hardware manufacturers do not supply these components,
  6680.  will each and every software application have to supply its own?
  6681.  
  6682.  Response:
  6683.  
  6684.  Most hardware manufacturers will need to supply a device driver to use
  6685.  their hardware if it is not standard. As far as the type of standards
  6686.  for return values, we will provide only what already is documented.
  6687.  The hardware manufacturers may decide some other type of information
  6688.  is important, and include that information in their version of OS/2.
  6689.  
  6690.  If the hardware manufacturers do not supply the components, each
  6691.  software application will have to do the work.
  6692.  
  6693.  
  6694.  209. Internal Error Occurs When MAXTHREADS is Too Low
  6695.  
  6696.  Problem:
  6697.  
  6698.  I am having problems running the product version of Epsilon with the
  6699.  new SDK release. I get the SYS0164 error message when I try to execute
  6700.  the program.
  6701.  
  6702.  Response:
  6703.  
  6704.  This error occurs when the maximum number of threads has been reached.
  6705.  It is documented in the BSEERR.H file. To avoid this problem, change
  6706.  the value of MAXTHREADS in your CONFIG.SYS file to a higher number
  6707.  when running this program.
  6708.  
  6709.  
  6710.  210. DosFindFirst/FindNext in Real Mode
  6711.  
  6712.  Problem:
  6713.  
  6714.  I have written a program in MS-DOS Version 3.20 that displays all the
  6715.  files on a disk. The program uses INT 21h with the functions
  6716.  FindFirst/FindNext to traverse the directory tree structure. I
  6717.  converted the program to OS/2 using DosFindFirst/FindNext and it
  6718.  worked in protected mode. However, it failed when I tried to bind it
  6719.  to run in real mode.
  6720.  
  6721.  Response:
  6722.  
  6723.  There is a restriction on DosFindFirst/FindNext in the real mode box
  6724.  (dirhandle=1) that does not allow allocation of new dirhandles as you
  6725.  descend the directory tree. This makes it difficult to write a program
  6726.  that displays all the files on a disk, and that will run in real, as
  6727.  well as protected, mode.
  6728.  
  6729.  This restriction occurs because you would have to malloc a new DTA
  6730.  whenever a FindFirst (with a handle = FFFFh) to emulate the full
  6731.  functionality of DosFindFirst/FindNext in real mode. Memory
  6732.  fragmentation would result, causing problems for many application
  6733.  programs.
  6734.  
  6735.  There are three solutions to this problem. First, use the function
  6736.  DosGetMachineMode to determine whether you are in the 3.x box or in
  6737.  protected mode at run time. If you are in protected mode, do
  6738.  DosFindFirst/FindNext calls, recursively allocating a new dirhandle
  6739.  (dirhandle=-1) as you descend the tree. If you are in real mode, use
  6740.  the program in the same way as you tried under DOS Version 3.x, using
  6741.  INT 21 calls and allocating a new DTA each time you descend the tree.
  6742.  
  6743.  The second method consists of using the program with the
  6744.  DosFindFirst/FindNext calls. However, remember where you left off in
  6745.  the parent directory when descending into a child. When you finish
  6746.  displaying the child tree's files, continue where you left off on the
  6747.  parent's files. Write the program without using recursion so that
  6748.  allocation of new dirhandles is not needed as you descend the tree.
  6749.  
  6750.  The final option is to write your own FAPI support module to expand
  6751.  the functionality of DosFindFirst/FindNext; then, link this module on
  6752.  the BIND command line. This object would be substituted for the
  6753.  API.LIB FindFirst/FindNext. See the MS OS/2 Application Program
  6754.  Interface section of the programmer's guide for more information on
  6755.  expanding FAPI functionality.
  6756.  
  6757.  
  6758.  211. Set Typamatic Rate IOCTL Documentation Error
  6759.  
  6760.  Problem:
  6761.  
  6762.  The KBD Set Typamatic rate IOCTL call does not work correctly.
  6763.  
  6764.  Response:
  6765.  
  6766.  The problem you encountered was an error in our documentation of the
  6767.  KBD Set Typamatic rate IOCTL call. The parameter packet format should
  6768.  have been two words, not two bytes, for delay and rate, respectively.
  6769.  KbdSetRate is described on Page 190 of the "Microsoft Operating
  6770.  System/2 Software Development Kit Device Drivers Guide."
  6771.  
  6772.  
  6773.  212. Using OS/2 API Calls in Presentation Manager Applications
  6774.  
  6775.  Question:
  6776.     For the Presentation Manager, should I use OS/2 API functions in my
  6777.  PM application and DLL or strictly use all PM functions--e.g.
  6778.  DosAllocSeg vs. WinCreateHeap and WinAllocSeg; DosOpen versus
  6779.  WinOpenFile?
  6780.  
  6781.  Response:
  6782.     You can use both OS/2 API and PM API functions in PM applications
  6783.  depending on what you want to do. Similar OS/2 and PM functions will
  6784.  generally have some differences that determine which one you would use
  6785.  in a given situation.
  6786.  
  6787.  
  6788.  213. Using DosStartSession() to Create a Related Session
  6789.  
  6790.  Problem:
  6791.  
  6792.  I am having difficulty using DosStartSession() to create a related
  6793.  session.
  6794.  
  6795.  Response:
  6796.  
  6797.  The documentation for DosStartSession() is out of date. (See the
  6798.  "Microsoft Operating System/2 Programmer's Reference," Page 306.) The
  6799.  current calling sequence is as follows:
  6800.  
  6801.     push @other StartData
  6802.     push @word Sessionid
  6803.     push @word ProcessID
  6804.     CALL DOSSTARTSESSION
  6805.  
  6806.  The following three things should be noted:
  6807.  
  6808.  1. ProcessID has been added to the call and is the address of where
  6809.     the operating system may place the ProcessID.
  6810.  
  6811.  2. The description for PgmName (on Page 307 of the programmer's
  6812.     reference) is actually the description of PgmInputs; PgmName is the
  6813.     far address of an ASCIIZ string containing the fully qualified
  6814.     drive, path, and filename of the program to be loaded.
  6815.  
  6816.  3. TraceOpt (a word parameter that comes after FgBg) specifies whether
  6817.     the program started in the new session should be executed under
  6818.     conditions for tracing with DOSPTRACE:
  6819.  
  6820.     TraceOpt = 0 ; no trace
  6821.     TraceOpt = 1 ; trace
  6822.  
  6823.  No parameter currently exists for passing environment variables. One
  6824.  option is to start CMD.EXE with the /k switch to run a CMD file to set
  6825.  the environment before executing the program. An example is as follows:
  6826.  
  6827.     PgmName = CMD.EXE
  6828.     PgmInputs = /k initenv.cmd
  6829.  
  6830.  The following is an example of using DosStartSession() with the OS/2
  6831.  application BIGBEN:
  6832.  
  6833.  #include    <doscalls.h>
  6834.  #include    <subcalls.h>
  6835.  
  6836.  char    PgmTitle[]  = "BIGBEN";
  6837.  char    PgmInputs[] = "";
  6838.  
  6839.  char    PgmName[]   =
  6840.  
  6841.   "D:\\PROJECTS\\DEMOS\\APPS\\BIGBEN\\BIGBEN.EXE";
  6842.  
  6843.  main(argc,argv)
  6844.  int     argc;
  6845.  char    *argv[];
  6846.  {
  6847.      struct StartData    StrtData;
  6848.      unsigned            SessID;
  6849.      unsigned            ProcessID;
  6850.      unsigned            rc;
  6851.  
  6852.      StrtData.Length    = sizeof(StrtData);
  6853.      StrtData.Related   = 1;
  6854.      StrtData.FgBg      = 0;
  6855.      StrtData.TraceOpt  = 0;
  6856.      StrtData.PgmTitle  = (char far *)PgmTitle;
  6857.      StrtData.PgmName   = (char far *)PgmName;
  6858.      StrtData.PgmInputs = (char far *)PgmInputs;
  6859.      StrtData.TermQ     = (char far *)0;
  6860.      rc = DOSSTARTSESSION((struct StartData far *)&StrtData,
  6861.                                   (unsigned far *)&SessID,
  6862.                                   (unsigned far *)&ProcessID);
  6863.  
  6864.      printf("DOSSTARTSESSION return code = %d\r\n", rc);
  6865.  
  6866.      while ( 1 )
  6867.          DOSSLEEP(0L);
  6868.  }
  6869.  
  6870.  
  6871.  214. Error Codes Returned from DosSetFileMode()
  6872.  
  6873.  Problem:
  6874.  
  6875.  I have encountered two error messages listed below:
  6876.  
  6877.  1. When DosSetFileMode() is given a path that begins with an invalid
  6878.     drive letter (e.g., Q:SOMENAME.DOC), it returns the message
  6879.     "error code 3, path not found". This is inconsistent; the proper
  6880.     return code should be "error code 15, invalid drive".
  6881.  
  6882.  2. When DosSetFileMode() is given an improper attribute word, i.e.,
  6883.     one containing one of the bits FFE8H, it returns the message "error
  6884.     code 5, access denied". This is incorrect; the error has nothing to
  6885.     do with access. Other calls that take attribute parameters return
  6886.     "error code 87, invalid parameter" when given an improper attribute
  6887.     word.
  6888.  
  6889.  Response:
  6890.  
  6891.  Both of these errors exist for compatibility reasons. The Interrupt 21H
  6892.  equivalent of the DosSetFileMode() call is Function 43H. If a path with
  6893.  an invalid drive is passed in, it returns error 3. If an invalid
  6894.  attribute is passed in, it returns error 5. The DosSetFileMode() was
  6895.  written to be compatible with the Interrupt 21 function.
  6896.  
  6897.  
  6898.  215. OS/2 SDK: Internal Format of OS2.INI
  6899.  
  6900.  The internal format of OS2.INI is subject to change; therefore, it is
  6901.  not documented. The following is a list of the APIs specifically
  6902.  provided for reading and modifying entries in OS2.INI:
  6903.  
  6904.  1. WinQueryProfileData()
  6905.  
  6906.  2. WinQueryProfileString()
  6907.  
  6908.  3. WinQueryProfileInt()
  6909.  
  6910.  4. WinQueryProfileSize()
  6911.  
  6912.  5. WinWriteProfileData()
  6913.  
  6914.  6. WinWriteProfileString()
  6915.  
  6916.  
  6917.  216. DOSEXECPGM : Asynctraceflags 4 and 5 Information
  6918.  
  6919.  Question:
  6920.  
  6921.  What do the DosExecPgm : asynctraceflags 4 and 5 do?
  6922.  
  6923.  Response:
  6924.  
  6925.  With DosExecPgm : asynctraceflag 4, the program executes asynchronous
  6926.  to the parent process, detached from the parent process's screen
  6927.  group. If the parent process is stopped, it is treated as an orphan
  6928.  process and does not affect the detached process. The process should
  6929.  not require any input from the keyboard or output to the screen other
  6930.  than VioPopups. It should not use any console I/O calls, e.g. VIO,
  6931.  KBD, or MOU calls.
  6932.  
  6933.  With DosExecPgm : asynctraceflag 5, the program is loaded into storage
  6934.  and made ready to execute, but is not actually executed until the
  6935.  session manager issues a DosSystemService() thaw process request.
  6936.  
  6937.  
  6938.  217. DosSearchPath Documentation Error in Programmer's Reference
  6939.  
  6940.  The entry for DosSearchPath on Pages 257-259 in the "Microsoft
  6941.  Operating System/2 Programmer's Reference" is in error. The fifth
  6942.  parameter is shown as follows:
  6943.  
  6944.     PUSH@ OTHER ResultBufferLen
  6945.  
  6946.  This is incorrect because no indirection is required. The entry should
  6947.  be as follows:
  6948.  
  6949.     PUSH WORD ResultBufferLen
  6950.  
  6951.  This documentation error can be verified by looking in DOSCALLS.H.
  6952.  
  6953.  
  6954.  218. Setting Timestamps with DosSetFileInfo()
  6955.  
  6956.  Problem:
  6957.  
  6958.  DosSetFileInfo() is supposed to allow the setting of the three
  6959.  timestamps (creation, last access, last write). However, only the last
  6960.  write stamp can be set: if either of the other date/time word pairs
  6961.  contains nonzero values, the function returns "error code 87, invalid
  6962.  parameter." This restriction is not documented. It would be useful to
  6963.  allow an OS/2 program to update these fields, which neither MS-DOS nor
  6964.  OS/2 maintain.
  6965.  
  6966.  Response:
  6967.  
  6968.  The extra date fields are there for future use; therefore, we could
  6969.  have allowed the programmer to do either of the following with these
  6970.  fields at the present time:
  6971.  
  6972.  1. Let the caller pass in data but ignore the data.
  6973.  
  6974.  2. Let the caller only pass in zeros in the unused fields (the zero
  6975.     means to leave the value untouched).
  6976.  
  6977.  We chose to do the latter. The problem with the first solution is that
  6978.  many programs might not put valid data in the fields. When we begin
  6979.  using the fields, these programs break.
  6980.  
  6981.  
  6982.  219. Creating a Unique Temporary Filename
  6983.  
  6984.  Problem:
  6985.  
  6986.  OS/2 appears to have no equivalent of the function supplied by MS-DOS
  6987.  Interrupt 21H subfunction 5AH, "make a scratch file with a unique
  6988.  name". It would seem that it is nearly impossible for a program to
  6989.  generate a unique scratch filename in OS/2, but fairly easy for the
  6990.  kernel to do so.
  6991.  
  6992.  Response:
  6993.  
  6994.  You are correct: there is no equivalent function. The best method to
  6995.  create a unique name is to use your process ID [DosGetPid()] and
  6996.  append an application-specific prefix to it. The kernel guarantees
  6997.  that there are never two processes with the same ID. If you have
  6998.  multiple threads creating temp files, append the thread ID to the
  6999.  name. This must fit into the 8.3 file name restrictions.
  7000.  
  7001.  After generating the name, the program should use the flag of the
  7002.  DosOpen() command to fail if the file already exists. If, for some
  7003.  reason, the file happens to exist, the DosOpen() command fails. You
  7004.  can attempt to generate another unique name in either a random fashion
  7005.  or by using another method of your choice.
  7006.  
  7007.  
  7008.  220. Definitions of Attribute Byte for VIO Calls
  7009.  
  7010.  Question:
  7011.  
  7012.  I can't seem to find a description of the attribute codes for the
  7013.  VIOXXXXX calls that require them, such as VIOWRTCELLSTR().
  7014.  
  7015.  Response:
  7016.  
  7017.  The definitions for the attributes are not currently listed in the
  7018.  OS/2 manuals. However, they are the same as they were for MS-DOS,
  7019.  since the attributes are hardware dependent.
  7020.  
  7021.  The following is a description of each bit of the attribute byte. For
  7022.  a more detailed description, see Pages 76-80 of Peter Norton's
  7023.  "Programmers Guide to the IBM PC."
  7024.  
  7025.  Bits of attribute byte are as follows:
  7026.  
  7027.  7 6 5 4 3 2 1 0
  7028.  
  7029.  1 . . . . . . .   Blinking of foreground character
  7030.  . 1 . . . . . .   Red component of background color
  7031.  . . 1 . . . . .   Green component of background
  7032.  . . . 1 . . . .   Blue component of background
  7033.  . . . . 1 . . .   Intensity of foreground color
  7034.  . . . . . 1 . .   Red component of foreground
  7035.  . . . . . . 1 .   Green component of foreground
  7036.  . . . . . . . 1   Blue component of foreground
  7037.  
  7038.  
  7039.  221. Errors in LAN Manager Overview Documentation Page Sequence
  7040.  
  7041.  The version of the document, part number 00261, "Microsoft OS/2 LAN
  7042.  Manager Version 1.0 Introduction and Technical Product Overview"
  7043.  shipped with the recent OS/2 developer's kit update package #1 (cover
  7044.  letter dated August 1, 1987) appears to have been miscollated in
  7045.  reproduction.
  7046.  
  7047.  Pages 1 and 2 appear to be in sequence. Page 3 begins with "The data
  7048.  buffer is filled in..." and continues with the NetbiosLinkage
  7049.  structure description. It appears to be out of place (actually, it
  7050.  appears not to belong in the Introduction and Overview at all). Page 4
  7051.  begins with item 8 in a numbered list, the first seven items of which
  7052.  are nowhere to be found. Pages 5 to 9 appear to be in sequence.
  7053.  
  7054.  Microsoft is aware of this problem. The problems with the LAN manager
  7055.  documentation will be corrected when the LAN manager is available in
  7056.  an update to the OS/2 SDK.
  7057.  
  7058.  
  7059.  222. Context Switches at Ring 2
  7060.  
  7061.  Question:
  7062.  
  7063.  According to the "Operating System/2 Device Drivers Guide", a context
  7064.  switch cannot occur while a process is executing in kernel mode (ring
  7065.  0), unless the process explicitly relinquishes control. Can a
  7066.  system-imposed (e.g., time-slicing, or a higher priority thread being
  7067.  unblocked by an interrupt, or by the executing thread) context switch
  7068.  occur while a thread is executing at ring 2 (i.e., while executing a
  7069.  DLL module with IOPL privilege)?
  7070.  
  7071.  Response:
  7072.  
  7073.  Context switches can occur in ring 2. You must use a semaphore to
  7074.  control access if you need to serialize or protect a code segment from
  7075.  a context switch.
  7076.  
  7077.  
  7078.  223. Keyboard Locked Out When Running Word
  7079.  
  7080.  If you press either the NUM LOCK key or the CAPS LOCK key when
  7081.  Microsoft Word is running in the compatibility box, the entire
  7082.  keyboard is locked out. The indicator lights remain the same and
  7083.  background processes continue, but there is no way to switch modes.
  7084.  
  7085.  Microsoft has confirmed this to be a problem in Version 1.00. This
  7086.  problem was corrected in Version 1.10.
  7087.  
  7088.  
  7089.  224. OS/2 SDK: Cursor Addressing Using Escape Codes
  7090.  
  7091.  Question:
  7092.  
  7093.  Does OS/2 currently honor the escape sequences to control the screen,
  7094.  as in the MS-DOS driver ANSI.SYS, and as described in the MS-DOS
  7095.  technical reference manual? I have an application that I want to
  7096.  convert from MS-DOS to OS/2 that makes heavy use of screen control
  7097.  sequences (ESC+BRACKET+<keyname>) for changing color and cursor
  7098.  position. What problems can I expect to run into?
  7099.  
  7100.  Response:
  7101.  
  7102.  ANSI escape sequences are supported in protected mode, but they must
  7103.  be sent to the console for the ANSI driver to intercept them.
  7104.  
  7105.  OS/2 does support terminal-like character-code controlled cursor
  7106.  addressing. Use the system call VIOSETANSI to set the system into ANSI
  7107.  mode. To be the most friendly to other applications, do a VIOGETANSI
  7108.  to get the current state, store it somewhere, and restore the system
  7109.  to that state upon exit from your program.
  7110.  
  7111.  There should be no problem porting your application to OS/2.
  7112.  Single-thread C programs basically just need to be compiled for
  7113.  protected-mode operation, or they need to be compiled and then bound
  7114.  with the BIND utility to run in either protected or real mode.
  7115.  
  7116.  
  7117.  225. Using DosExecPgm to Execute CMD.EXE
  7118.  
  7119.  Problem:
  7120.  
  7121.  I can start a session with DOSSTARTSESSION (e.g., "cmd.exe /c start
  7122.  "session 1" c:\bigben.exe"), but the documentation is confusing on how
  7123.  to execute this same command through DosExecPgm.
  7124.  
  7125.  Response:
  7126.  
  7127.  Below is an example of how to use DosExecPgm to execute CMD.EXE, which
  7128.  then executes the program passed to it. The program EXECPGM.EXE uses
  7129.  DosExecPgm to execute CMD.EXE and to pass CMD.EXE the program PGM.EXE.
  7130.  Both programs were compiled with the following switches: "cl -AL -G2
  7131.  -Lp <filename.c>". The programs are as follows:
  7132.  
  7133.  -----------------------EXECPGM.C----------------------------------------
  7134.  
  7135.  #include <stdio.h>
  7136.  #include <doscalls.h>
  7137.  #include <subcalls.h>
  7138.  
  7139.  #define LEN_OBJ_NAME_BUF        64   /* length of error message buffer */
  7140.  #define ASYNC_TRACE_FLAGS       4  /* run child processes asynchronously */
  7141.  
  7142.  /*---- structures for creating processes ---*/
  7143.  
  7144.  struct ResultCodes return_codes;      /* 1st word is child process id */
  7145.  char obj_name_buf [LEN_OBJ_NAME_BUF]; /* buffer for error information */
  7146.  
  7147.  main()
  7148.  {
  7149.      int    rc;
  7150.      struct KeyData c;
  7151.  
  7152.  /*  create process, set the path for CMD.EXE and PGM.EXE to fit your system *
  7153.  /*  Note that a \0 is needed to separate the program name from the  */
  7154.  /*  arguments and that two \0s are needed to end the argument line. */
  7155.  
  7156.      rc = DOSEXECPGM (obj_name_buf,
  7157.                       LEN_OBJ_NAME_BUF,
  7158.                       ASYNC_TRACE_FLAGS,
  7159.                       (char far *) "CMD.EXE\0/C C:\\work\\PGM.EXE\0\0",
  7160.                       0L,
  7161.                       &return_codes,
  7162.                       (char far *) "C:\\OS2\\BIN\\CMD.EXE\0\0");
  7163.      if (rc) {
  7164.          printf ("*** error creating Pgm.exe - %d\n", rc);
  7165.          DOSEXIT (1,4);
  7166.      }
  7167.  
  7168.      DOSSLEEP(3000L);
  7169.  
  7170.      printf("Exiting ExecPgm.exe\n");
  7171.  }
  7172.  
  7173.  ---------------------------------PGM.EXE------------------------------------
  7174.  
  7175.  #include <doscalls.h>
  7176.  #include <subcalls.h>
  7177.  
  7178.  /* simple pop up window example */
  7179.  
  7180.  main ()
  7181.  {
  7182.      char text[50];
  7183.      struct KeyData;
  7184.      unsigned waitflags, length;
  7185.  
  7186.      waitflags = 0;
  7187.      strcpy(text, "Hello from PGM.EXE");
  7188.      VIOPOPUP(&waitflags, 0);
  7189.      length = strlen(text);
  7190.      VIOWRTCHARSTR ((char far *)text, length, 12, 15, 0);
  7191.      DOSSLEEP(4000L);
  7192.      VIOENDPOPUP (0);
  7193.  }
  7194.  ---------------------------------------------------------------------------
  7195.  
  7196.  
  7197.  226. Documentation Error in Request Queue Device Help Routines
  7198.  
  7199.  Question:
  7200.  
  7201.  The following is the calling sequence for Device Helper PushReqPacket:
  7202.  
  7203.   LDS SI,[Queue]
  7204.   LES BX,RequestPacket
  7205.   MOV DL,DEVHLP_PUSHREQPACKET
  7206.   CALL [Device_Help]
  7207.  
  7208.  Since both DS and ES are used to pass parameters, how do I call
  7209.  Device_Help? The address of Device_Help is passed by the system at
  7210.  initialization time and has to be saved at some place. To call
  7211.  Device_Help, I must have DS point to my DATA segment. If DS must point
  7212.  to my DATA segment, it cannot be used to pass parameters to
  7213.  Device_Help. What should I do?
  7214.  
  7215.  Response:
  7216.  
  7217.  There is an error in the documentation of the Device Help routines
  7218.  (Pages 320-329 of the "Microsoft Operating System/2 Device Drivers
  7219.  Guide") that deal with request queue management. The correct
  7220.  parameters for dh_PushReqPacket are as follows. (This also applies to
  7221.  the other Request Packet management device help calls.) The following
  7222.  is the correct calling sequence:
  7223.  
  7224.      MOV     SI,OFFSET DS:queue      ; Pointer to DWORD queue head
  7225.                                      ;   (which points to the first request
  7226.                                      ;   packet in the queue)
  7227.  
  7228.      LES     BX,request_packet       ; Pointer to device request packet
  7229.      MOV     DL,DevHlp_PushReqPacket
  7230.      CALL    [Device_Help]
  7231.  
  7232.  
  7233.  227. Not Passing Keystrokes Through with a Keyboard Monitor
  7234.  
  7235.  Question:
  7236.  
  7237.  I have the following questions on keyboard monitors:
  7238.  
  7239.  1. Can a keyboard monitor choose to not pass on a particular hotkey
  7240.     that it wants to use?
  7241.  
  7242.  2. If DosMonWrite() must still be called (to allow the driver to clean
  7243.     up), should the count be set to 0 to indicate that the hotkey was not
  7244.     passed?
  7245.  
  7246.  3. I find that putting a DosMonClose(KBDHandle) in a clean-up routine
  7247.     in a DosExitList() chain consistently returns nonzero (381
  7248.     ERROR_MON_INVALID_HANDLE). Is this normal?
  7249.  
  7250.  Response:
  7251.  
  7252.  The following are answers to the above questions:
  7253.  
  7254.  1. Yes. It is not necessary to pass on every packet that comes through
  7255.     a monitor chain. Flush packets are an exception, and should always
  7256.     be quickly passed through. It is fine to "consume" keystrokes by
  7257.     not passing them through.
  7258.  
  7259.  2. No; the count parameter of DosMonWrite() is the count of bytes to
  7260.     pass through. It would be invalid to give it a zero size.
  7261.  
  7262.  3. Yes; in the exiting process, the first thing that is done is that
  7263.     all extra threads are destroyed. Then, any open monitors are closed
  7264.     and the exit list routines are called (in an indeterminate order if
  7265.     there is more than one). This is why you are getting the error from
  7266.     DosMonClose(). It doesn't hurt to leave the DosMonClose() call in,
  7267.     as it helps document the intent of your code.
  7268.  
  7269.  
  7270.  228. KbdPeek Determination of Empty Buffer
  7271.  
  7272.  Question:
  7273.  
  7274.  I am using KbdPeek to determine if there are any characters in the
  7275.  stdin buffer. How does KbdPeek indicate that the buffer is empty?
  7276.  
  7277.  Response:
  7278.  
  7279.  There is a documentation error in the KbdPeek call. Page 360 of the
  7280.  "Microsoft Operating System/2 Programmer's Reference" manual should
  7281.  read as follows:
  7282.  
  7283.     A returned character is indicated by the final character flag, bit
  7284.     6 of the status byte, being set to one. Bit six set to zero
  7285.     indicates that no character was returned. KbdPeek will only
  7286.     complete when the handle has the focus or the handle is zero and no
  7287.     other handle has the focus.
  7288.  
  7289.  
  7290.  229. OS/2 SDK: Permanently Disabling Compatibility Box
  7291.  
  7292.  Question:
  7293.  
  7294.  Can I permanently disable the compatibility box beyond what can be
  7295.  done by setting PROTECTONLY to YES in CONFIG.SYS?
  7296.  
  7297.  Response:
  7298.  
  7299.  Yes, you can. You need to remove the SHELL statement from the
  7300.  CONFIG.SYS file, along with any references to MS-DOS device drivers.
  7301.  Also, remove any references to C:\COMMAND.COM and C:\OS2\COMMAND.COM,
  7302.  and set PROTECTONLY to YES.
  7303.  
  7304.  Thus, the only way anyone could ever get the DOS 3.x box up and
  7305.  running again would be to change the CONFIG.SYS file. It would also be
  7306.  necessary to obtain a copy of COMMAND.COM (for OS/2).
  7307.  
  7308.  If a user were to change the CONFIG.SYS file to "PROTECTONLY=NO" and
  7309.  insert a SHELL statement, he or she would still get an error on the
  7310.  screen at boot time indicating that the DOS 3.x box could not be
  7311.  loaded.
  7312.  
  7313.  
  7314.  230. OS/2 SDK: Calling of Exit List Routine
  7315.  
  7316.  Question:
  7317.  
  7318.  Assume a process uses DosExitList() to request the OS/2 kernel to call
  7319.  a routine to be executed during process exit, and that same process
  7320.  uses DosOpen() to open a device. When that process exits due to, say,
  7321.  a CTRL+C, does the kernel call the exit list routine before calling
  7322.  the device driver with a close request, or does the device driver get
  7323.  called first?
  7324.  
  7325.  Response:
  7326.  
  7327.  Currently, the exit list routines are all allowed to complete before
  7328.  the system cleans up files by closing them. The exceptions are devices
  7329.  that are opened for device monitors. These will be closed before the
  7330.  exit list routines are called. This exception isn't documented; please
  7331.  note that it might be subject to change.
  7332.  
  7333.  
  7334.  231. Root Directory Clutter
  7335.  
  7336.  Question:
  7337.     It appears that the root directory needs to be cluttered with
  7338.  device drivers and several executable files. Why can I not put all of
  7339.  my device drivers into a subdirectory of the root and have the path to
  7340.  these drivers specified in my config.sys file (i.e., c:\sys\*.sys)? I
  7341.  prefer to maintain my root directory with only the minimum number of
  7342.  files.
  7343.  
  7344.  Response:
  7345.     At boot, the file system does not know enough about directory
  7346.  structures to be able to access the files in a subdirectory,
  7347.  Therefore, it cannot look for the files that it needs except in the
  7348.  root directory of the boot drive.
  7349.  
  7350.  
  7351.  232. Overview of OS/2 Dispatch Scheduler
  7352.  
  7353.  This article provides an overview of the OS/2 Dispatch Scheduler.
  7354.  
  7355.  Introduction
  7356.  ------------
  7357.  
  7358.  The OS/2 scheduler uses time slicing to share CPU time among all
  7359.  running programs and their threads. It does not share the CPU's time
  7360.  equally among all programs. The dispatching entity of the OS/2
  7361.  scheduler is the thread, rather than the process. Each process
  7362.  contains at least one thread, and each of the threads of a process run
  7363.  is given the same priority.
  7364.  
  7365.  The scheduler is a priority-based scheduler. It assigns each thread a
  7366.  priority and uses this priority to decide when to allot CPU time for a
  7367.  particular thread. The scheduler is preemptive, meaning that if a
  7368.  higher-priority thread is ready to run, the scheduler preempts a
  7369.  running lower-priority thread to accommodate the higher-priority
  7370.  thread. Later, the lower-priority thread is allowed to continue where
  7371.  it left off.
  7372.  
  7373.  The scheduler's algorithm, simply put, is to execute the
  7374.  highest-priority thread for as long as the thread wants to use the
  7375.  CPU. When the thread is blocked, e.g. waiting for a peripheral (such
  7376.  as a disk drive) to complete an operation, the scheduler executes the
  7377.  next-highest priority thread that is ready to run. Therefore, the
  7378.  system is always running the highest-priority thread.
  7379.  
  7380.  Program Classes
  7381.  ---------------
  7382.  
  7383.  The OS/2 scheduler classifies programs as follows:
  7384.  
  7385.     Time-critical threads (system and application)
  7386.     Foreground threads (application)
  7387.     Regular threads (application)
  7388.     Idle threads (system and application)
  7389.  
  7390.  The higher the class, the more precedence a process has. Programs at a
  7391.  higher class are run before programs at a lower class. Programs can
  7392.  change themselves to be in the time-critical, regular-application
  7393.  (default), and idle classes.
  7394.  
  7395.  Priority Level
  7396.  --------------
  7397.  
  7398.  Within a class, there is a numeric priority level that prioritizes
  7399.  threads running within the same class. If two or more threads are in
  7400.  the same class and have the same priority level, OS/2 shares the CPU
  7401.  time to the threads in a round-robin manner.
  7402.  
  7403.  User-Configurable Areas
  7404.  -----------------------
  7405.  
  7406.  Some portions of the OS/2 scheduler are user configurable. There are
  7407.  entries in the OS/2 configuration file CONFIG.SYS, most notably
  7408.  MAXWAIT, PRIORITY, and TIMESLICE, that affect the way the scheduler
  7409.  works.
  7410.  
  7411.  The TIMESLICE Configuration Option
  7412.  ----------------------------------
  7413.  
  7414.  The TIMESLICE configuration command determines the amount of time in
  7415.  milliseconds that the CPU allocates to a thread before giving CPU time
  7416.  to another thread of the same priority level to execute. This ensures
  7417.  that threads of equal priority level are given an equal, round-robin
  7418.  opportunity to execute. There are minimum and maximum values that are
  7419.  given on the TIMESLICE command line. The default minimum value is 32
  7420.  milliseconds, and the default maximum is 248 milliseconds. If only one
  7421.  value is specified, both minimum and maximum ranges are set to the
  7422.  value of the first/only value specified. Changing this value is not
  7423.  usually recommended, unless specified by an application that has to
  7424.  perform timing-dependent activities (and this would normally require
  7425.  that the value be lower, to ensure that applications are given a slice
  7426.  of the CPU more frequently). However, the lower the value, the more
  7427.  time the OS/2 scheduler has to spend scheduling time.
  7428.  
  7429.  The PRIORITY Configuration Option
  7430.  ---------------------------------
  7431.  
  7432.  The PRIORITY configuration command determines how the OS/2 scheduler
  7433.  will behave. If set to PRIORITY=ABSOLUTE, many of the tricks that the
  7434.  scheduler could perform are not done, and the scheduler uses a much
  7435.  simpler, static algorithm. If set to PRIORITY=DYNAMIC, the scheduler
  7436.  tries to get performance boosts for threads running by temporarily
  7437.  boosting the priority level of an application within a class.
  7438.  
  7439.  One such performance boost is the MAXWAIT configuration command. The
  7440.  scheduler boosts the priority level of a thread if it is
  7441.  "starving." This scheduling logic is only available when
  7442.  PRIORITY=DYNAMIC and the thread is in the regular application class.
  7443.  
  7444.  There are some situations when the OS/2 scheduler boosts the priority
  7445.  level (staying within the same class) of a thread if it is spending an
  7446.  inordinate amount of time blocking on an I/O device. This is called an
  7447.  I/O boost. This scheduling logic is available only when
  7448.  PRIORITY=DYNAMIC and the thread is in the regular-application class.
  7449.  
  7450.  When a thread is in the regular-application class and is part of a
  7451.  process being selected by the user in the foreground, the thread is
  7452.  given a boost to the foreground-application class while it is in the
  7453.  foreground (however, this class is not selectable by an application).
  7454.  This is called a foreground boost. Foreground-application-class
  7455.  threads are higher than regular-application-class threads; thus, the
  7456.  scheduler runs foreground threads before regular threads. This
  7457.  scheduling logic is available only when PRIORITY=DYNAMIC and the
  7458.  thread is in the regular-application class.
  7459.  
  7460.  Again, if PRIORITY=ABSOLUTE, the scheduling optimizations, starvation
  7461.  boosts, I/O boosts, and foreground-application boosts will not take
  7462.  place.
  7463.  
  7464.  The MAXWAIT Configuration Option
  7465.  --------------------------------
  7466.  
  7467.  The MAXWAIT configuration command roughly determines the amount of
  7468.  time an eligible thread waits before being given a temporary boost in
  7469.  priority level. This is also known as the starvation boost. The
  7470.  scheduler, after the amount of time specified on the MAXWAIT command
  7471.  line, temporarily boosts the priority level of the thread to a higher
  7472.  value within the same class to give it CPU time. This scheduling logic
  7473.  is available only when PRIORITY=DYNAMIC and the thread is in the
  7474.  regular-application class.
  7475.  
  7476.  Application Configurable Areas
  7477.  ------------------------------
  7478.  
  7479.  An application can also change the way the OS/2 scheduler treats it.
  7480.  The API DosSetPrty() can be used to do this. This API can change the
  7481.  class of the application (being one of the idle-application,
  7482.  regular-application, and time-critical-application classes).
  7483.  DosSetPrty() also specifies the priority level with the priority
  7484.  class. This value can be from 0 to 31, where 0 is the lowest priority.
  7485.  Related to DosSetPrty() is the DosGetPrty() call, which retrieves the
  7486.  current process priority information from the system.
  7487.  
  7488.  System Threads
  7489.  --------------
  7490.  
  7491.  The threads of system programs are located at various levels. There
  7492.  are some, such as the spooler, that are in the idle-time class. Other
  7493.  threads are time critical. Also, there are classes between the
  7494.  regular-application and the time-critical classes that are reserved
  7495.  for system threads. An application program can set only its class to
  7496.  be in the idle, regular-application, or time-critical classes.
  7497.  
  7498.  Conclusion
  7499.  ----------
  7500.  
  7501.  For a general overview of the scheduler, please refer to Chapter 5 of
  7502.  Gordon Letwin's book, "Inside OS/2." For more information on the
  7503.  CONFIG.SYS commands PRIORITY, MAXWAIT, and TIMESLICE, refer to the
  7504.  "Microsoft OS/2 User's Reference" for Version 1.00. For more
  7505.  information on the DosGetPrty() and DosSetPrty() APIs, refer to the
  7506.  "Microsoft Operating System/2 Programmer's Toolkit Programmer's
  7507.  Reference" for Version 1.00.
  7508.  
  7509.  
  7510.  233. DosGetPid() Function Not Documented in Programmer's Reference
  7511.  
  7512.  Question:
  7513.  
  7514.  The DosGetPid() function is not documented in the "Microsoft Operating
  7515.  System/2 Software Development Kit Programmer's Reference." How is it
  7516.  used and what parameters are required?
  7517.  
  7518.  Response:
  7519.  
  7520.  Although the DosGetPid() function was not included in the SDK
  7521.  documentation, the API call works correctly. The following is a short
  7522.  example demonstrating how the call works (see the structure and
  7523.  function declarations in DOSCALLS.H for a description of the
  7524.  parameters of the DosGetPid() call):
  7525.  
  7526.  #include <doscalls.h>
  7527.  
  7528.  main()
  7529.  
  7530.  {
  7531.     int rc;
  7532.     struct ProcIDsArea ID;
  7533.  
  7534.     rc=DOSGETPID(  (char far *) &ID );
  7535.     printf("result of call is %d\n",rc);
  7536.  
  7537.     printf("curr pid is %d\n",ID. procid_cpid);
  7538.     printf("curr tid is %d\n",ID. procid_ctid);
  7539.     printf("parents pid is %d\n",ID. procid_ppid);
  7540.  }
  7541.  
  7542.  
  7543.  234. Mouse Driver Problems
  7544.  
  7545.  Problem:
  7546.     My application uses the mouse driver to handle the mouse movement
  7547.  and event processing. It simply reads the event queue and acts upon
  7548.  the events. Unfortunately, the current implementation of the mouse
  7549.  driver does not simply move a block cursor around the screen by just
  7550.  modifying attributes or something similar, but it actually copies the
  7551.  character that will be replaced by the mouse cursor and then replaces
  7552.  the character when the mouse moves from that position. This causes a
  7553.  problem for me because when a mouse click occurs, the character
  7554.  changes to reflect a click, but when the mouse driver moves the cursor
  7555.  from the current position, it destroys the new character.
  7556.  
  7557.  Response:
  7558.     The way the mouse driver works now is not likely to change in the
  7559.  near future. One workaround is to replace the character most recently
  7560.  clicked on when the mouse moves to another position at the time you
  7561.  detect a move (i.e., insert into your mouse movement response routine
  7562.  a flag for "just clicked somewhere, need to replace character at xy").
  7563.     A second workaround is to hide the mouse cursor and have the
  7564.  application paint its own cursor, e.g. by modifying attributes.
  7565.  
  7566.  
  7567.  235. OS/2 SDK: DosReadQueue() Documentation Error
  7568.  
  7569.  This article contains information on the documentation errors for the
  7570.  DosReadQueue() function call in the "Microsoft Operating System/2
  7571.  Programmer's Toolkit Programmer's Reference" for Version 1.00.
  7572.  
  7573.  Page 195 of the "Microsoft Operating System/2 Programmer's Toolkit
  7574.  Programmer's Reference" for Version 1.00 incorrectly states the
  7575.  following:
  7576.  
  7577.     PULONG pulBuf;       pointer to buffer for element
  7578.  
  7579.     It copies the element to the buffer pointed to by the pulBuf
  7580.     parameter.
  7581.  
  7582.     pulBuf               Points to the buffer that receives the
  7583.                          element being retrieved from the queue
  7584.  
  7585.  Instead, it should state the following:
  7586.  
  7587.     PULONG pulBuf;        pointer to buffer for element
  7588.  
  7589.     It sets the indicated buffer pointer to the address of the queue
  7590.     data.
  7591.  
  7592.     pulBuf                Points to the pointer that receives the
  7593.                           address of the element in the queue
  7594.  
  7595.  Page 197 of the "Microsoft Operating System/2 Programmer's Toolkit
  7596.  Programmer's Reference" for Version 1.00 incorrectly states the
  7597.  following:
  7598.  
  7599.     If the function waits, it clears the semaphore identified by the
  7600.     hsem parameter as soon as the element is retrieved.
  7601.  
  7602.  It should instead state the following:
  7603.  
  7604.     If fNoWait is DCWW_WAIT and there is no element available,
  7605.     DosReadQueue() will return immediately without retrieving an
  7606.     element from the queue, and the semaphore identified by the hsem
  7607.     parameter will be asynchronously cleared as soon as an element is
  7608.     written to the queue.
  7609.  
  7610.  These documentation errors were corrected in the "Microsoft Operating
  7611.  System/2 Programmer's Reference Volume 3 for Version 1.10." Included
  7612.  below is a copy of the documentation for DosReadQueue() from the
  7613.  Version 1.10 documentation:
  7614.  
  7615.  #define INCL_DOSQUEUES                                         [1.1]
  7616.  
  7617.  USHORT DosReadQueue(hqueue, pqresc, pcbElement, ppv, usElement,
  7618.      fWait, pbElemPrty, hsem)
  7619.  HQUEUE hqueue;          /* handle of queue to read                */
  7620.  PQUEUERESULT pqresc;    /* pointer to structure for PID and request
  7621.                             code                                   */
  7622.  PUSHORT pcbElement;     /* pointer to variable for length of
  7623.                             element                                */
  7624.  PVOID FAR * ppv;        /* pointer to buffer for element          */
  7625.  USHORT usElement;       /* element number to read                 */
  7626.  UCHAR fWait;            /* wait/no wait indicator                 */
  7627.  PBYTE pbElemPrty;       /* pointer to variable for priority of
  7628.                             element                                */
  7629.  HSEM hsem;              /* semaphore handle                       */
  7630.  
  7631.  The DosReadQueue function retrieves an element and then removes it
  7632.  from a queue. It copies the address of the element to the supplied
  7633.  pointer and fills a structure with information about the element.
  7634.  
  7635.  Parameter   Description
  7636.  --------------------------------------------------------------------
  7637.  hqueue      Identifies the queue to read. This handle must have been
  7638.              created or opened by using the DosCreateQueue or
  7639.              DosOpenQueue function.
  7640.  
  7641.  pqresc      Points to the QUEUERESULT structure that receives
  7642.              information about the request.
  7643.  
  7644.  pcbElement  Points to the variable that receives the length (in bytes)
  7645.              of the element.
  7646.  
  7647.  ppv         Points to the pointer that receives the address of the
  7648.              element in the queue.
  7649.  
  7650.  usElement   Specifies where to look in the queue for the element. If
  7651.              this parameter is 0x0000, the function looks at the
  7652.              beginning of the queue. Otherwise, the function assumes
  7653.              the value is an element identifier retrieved by using the
  7654.              DosPeekQueue function and looks for the specified element.
  7655.  
  7656.  fWait       Specifies whether to wait for an element to be placed in
  7657.              the queue, if the queue is empty. If this parameter is
  7658.              DCWW_WAIT, the function waits until an element is
  7659.              available. If this parameter is DCWW_NOWAIT, the function
  7660.              returns immediately with a code that indicates there are
  7661.              no entries in the queue.
  7662.  
  7663.  pbElemPrty  Points to the variable that receives the priority value
  7664.              specified when the element was added to the queue. This
  7665.              is a value in the range 0 through 15; 15 indicates the
  7666.              highest priority.
  7667.  
  7668.  hsem        Identifies a semaphore. This value can be the handle of
  7669.              a system semaphore that has been created or opened by
  7670.              using the DosCreateSem or DosOpenSem function, or it can
  7671.              be the address of a RAM semaphore. This semaphore would
  7672.              typically be used in a call to the DosMuxSemWait
  7673.              function to wait until the queue has an element. If the
  7674.              fWait parameter is DCWW_WAIT, hsem is ignored.
  7675.  
  7676.  Return Value
  7677.  ------------
  7678.  
  7679.  The return value is zero if the function is successful. Otherwise, it
  7680.  is an error value, which may be one of the following:
  7681.  
  7682.     ERROR_QUE_ELEMENT_NOT_EXIST
  7683.     ERROR_QUE_EMPTY
  7684.     ERROR_QUE_INVALID_HANDLE
  7685.     ERROR_QUE_INVALID_WAIT
  7686.     ERROR_QUE_PROC_NOT_OWNED
  7687.  
  7688.  Comments
  7689.  --------
  7690.  
  7691.  If the queue is empty, the DosReadQueue function either returns
  7692.  immediately or waits for an element to be written to the queue,
  7693.  depending on the value of the fWait parameter.
  7694.  
  7695.  Only the process that created the queue can call the DosReadQueue
  7696.  function.
  7697.  
  7698.  Example
  7699.  -------
  7700.  
  7701.  This example reads the queue and waits until an element is received.
  7702.  After the element is read and the data processed, the process frees
  7703.  the shared memory that was passed to it. This assumes the process
  7704.  writing to the queue created a shared-memory segment. For more
  7705.  information, see the DosWriteQueue function.
  7706.  
  7707.  QUEUERESULT qresc;
  7708.  USHORT cbElement;
  7709.  PVOID pv;
  7710.  BYTE bElemPrty;
  7711.  
  7712.  DosReadQueue(hqueue, /* queue handle                        */
  7713.      &qresc,          /* address of result structure         */
  7714.      &cbElement,      /* receives element number             */
  7715.      &pv,             /* receives data address               */
  7716.      0,               /* element number to read              */
  7717.      DCWW_WAIT,       /* waits until something is written    */
  7718.      &bElemPrty,      /* receives priority level             */
  7719.      NULL);           /* semaphore not needed, since waiting */
  7720.      .
  7721.      .   /* Process the data. */
  7722.      .
  7723.  DosFreeSeg(SELECTOROF(pv));    /* frees shared memory */
  7724.  
  7725.  See Also
  7726.  --------
  7727.  
  7728.  DosCreateQueue, DosMuxSemWait, DosOpenQueue, DosOpenSem, DosPeekQueue,
  7729.  DosWriteQueue, QUEUERESULT
  7730.  
  7731.  
  7732.  236. Getting Mouse Coordinate Information in Pixels
  7733.  
  7734.  Question:
  7735.  
  7736.  How do I get the MouReadEventQueue() call to return information in
  7737.  pixel coordinates instead of in character coordinates?
  7738.  
  7739.  Response:
  7740.  
  7741.  Getting the mouse to return information in pixel coordinates is not
  7742.  straightforward. You need to perform the following steps, in order,
  7743.  for it to work properly:
  7744.  
  7745.  1. MouOpen( )          -  Opens the mouse device driver
  7746.  
  7747.  2. MouSetDevStatus( )  -  Tells the mouse driver not to draw the pointer
  7748.  
  7749.  3. VioGetMode()        -  Gets the current state of the screen
  7750.  
  7751.  4. type=3              -  Changes it to graphics mode
  7752.  
  7753.  5. VioSetMode()        -  Sets screen to graphics mode
  7754.  
  7755.  6. MouReadEventQueue() -  Gets mouse events in pixel coordinates
  7756.  
  7757.  You need to do the VioSetMode() after the MouSetDevStatus() so that
  7758.  the mouse driver does not get confused by trying to draw a pointer
  7759.  that it does not know how to draw in graphics mode.
  7760.  
  7761.  The following is a short program that performs the above steps and
  7762.  then reads either up to 50 mouse events or until you push both buttons
  7763.  (you can run this with output redirected to a file and then look at
  7764.  the file and see the coordinates of the mouse events):
  7765.  
  7766.  #include "stdio.h"
  7767.  
  7768.  #include "doscalls.h"
  7769.  #include "subcalls.h"
  7770.  
  7771.  typedef unsigned int    Word;
  7772.  typedef unsigned long   DWord;
  7773.  
  7774.  struct {
  7775.           int row;
  7776.           int column;
  7777.         } point[50];
  7778.  
  7779.  main()
  7780.  
  7781.  {
  7782.  
  7783.     int i;
  7784.     unsigned short DeviceHandle;
  7785.     Word  Status;
  7786.     Word  NumberOfButtons;
  7787.     Word  NumberOfMickeys;
  7788.     Word  EventMask;
  7789.     Word  DeviceStatus;
  7790.     Word  ButtonMask;
  7791.     Word  ReadType;
  7792.     struct PtrLoc PtrPos;
  7793.  
  7794.     struct EventInfo Buffer;
  7795.     struct ModeData DisplayMode;
  7796.     int count;
  7797.     DisplayMode.length=12;
  7798.  
  7799.     Status = MOUOPEN( 0L, (unsigned far *) &DeviceHandle );
  7800.     printf("Open Status         : %5d  Handle=%d\n", Status,DeviceHandle);
  7801.  
  7802.     DeviceStatus = 0x0100;
  7803.     Status = MOUSETDEVSTATUS( &DeviceStatus, DeviceHandle );
  7804.     printf("SetDevStatus Status : %5d\n", Status );
  7805.  
  7806.     Status= VIOGETMODE( (struct ModeData far *) &DisplayMode, 0);
  7807.     printf("Status =%d\n",Status);
  7808.  
  7809.     DisplayMode.type=3;
  7810.  
  7811.     Status=VIOSETMODE( (struct ModeData far *) &DisplayMode, 0);
  7812.     printf("Status of viosetmode is %d\n",Status);
  7813.  
  7814.     ReadType = 1;       /* 1= wait */
  7815.     Buffer.Mask = 0;
  7816.     count=1;
  7817.     while ( (Buffer.Mask & 0x0014) != 0x0014 && count < 50) {
  7818.        Status = MOUREADEVENTQUE( &Buffer, &ReadType, DeviceHandle );
  7819.        point[count].row =   Buffer.Row;
  7820.        point[count].column = Buffer.Col;
  7821.        count ++;
  7822.     };
  7823.  
  7824.     Status = MOUCLOSE( DeviceHandle );
  7825.     DisplayMode.type=1;   /* reset to text mode */
  7826.  
  7827.     Status=VIOSETMODE( (struct ModeData far *) &DisplayMode, 0);
  7828.  
  7829.     for(count=1; count < 50; count++)
  7830.        printf("point  %d  are  row= %d    column=%d  \n",
  7831.               count,point[count].row,point[count].column);
  7832.  
  7833.     printf("Close Status        : %5d\n", Status );
  7834.  
  7835.     return 0;
  7836.  
  7837.  }
  7838.  
  7839.  
  7840.  237. Using Two Monitors with OS/2
  7841.  
  7842.  Problem:
  7843.  
  7844.  I have two monitors on my system (EGA and MDA). When I do the
  7845.  following, the monochrome screen group has its output frozen:
  7846.  
  7847.  1. Start an OS/2 CMD session and start something, e.g. a MAKE,
  7848.     running
  7849.  
  7850.  2. Switch to a screen group on the EGA (or the SHELL)
  7851.  
  7852.  Response:
  7853.  
  7854.  OS/2 does not support two monitors operating concurrently with each
  7855.  monitor in its own screen group. When a screen group is in the
  7856.  background, all of its output is sent to its virtual screen buffer and
  7857.  not to the actual screen. Therefore, the output on the other monitor
  7858.  is frozen.
  7859.  
  7860.  You can use the second monitor with CodeView and it will work properly.
  7861.  
  7862.  
  7863.  238. Determining the PID of the Current ForeGround Screen Group
  7864.  
  7865.  Question:
  7866.  
  7867.  Would you please clarify the documentation of the Global and Local
  7868.  information segments on Pages 130-132 of the "Microsoft Operating
  7869.  System/2 Programmer's Reference"? When I examine the word "PID of
  7870.  current foreground process," it is always the same as the local
  7871.  segment word, "Process ID of Parent." It is never the same as the PID
  7872.  of the executing program, even when the executing program was started
  7873.  from the Start a Program menu of the Program Selector so that it would
  7874.  be the root process in its screen group. Furthermore, I have not found
  7875.  any way to cause a nonzero value in the word "Current process is in
  7876.  foreground."
  7877.  
  7878.  Response:
  7879.  
  7880.  We consider the current foreground process to be the last process to
  7881.  read something from the keyboard (i.e., do a KBDCHARIN call). If you
  7882.  insert a KBDCHARIN call before the DosGetInfoSeg(), it will return the
  7883.  values you expect for current foreground PID and "Current process is
  7884.  in foreground."
  7885.  
  7886.  
  7887.  239. Booting OS/2 Directly into Real Mode
  7888.  
  7889.  Question:
  7890.  
  7891.  Is there a (programmatic) way under OS/2 to go straight into the DOS
  7892.  3.x box at boot time?
  7893.  
  7894.  Response:
  7895.  
  7896.  No, there is no way to go straight into the DOS 3.x box at boot time.
  7897.  OS/2 was primarily designed to be a protected-mode operating system
  7898.  so as to take advantage of the increased capability of the 80286 in
  7899.  protected mode. The real-mode box was provided as a way to maintain
  7900.  compatibility with old applications that have been written for MS-DOS.
  7901.  Therefore, OS/2 boots into the session manager or into a protected
  7902.  mode program, and from there you can enter real mode if you wish.
  7903.  
  7904.  
  7905.  240. Use of DosKillProcess to Kill Processes in Other Sessions?
  7906.  
  7907.  Question:
  7908.     To terminate(kill) processes in other sessions, can an
  7909.  application program use the DosKillProcess call? Can
  7910.  application programs know Process IDs in other sessions?
  7911.  
  7912.  Response:
  7913.     Processes can call DosKillProcess and terminate other
  7914.  processes in the system. However, the only way for a
  7915.  process to determine the PID of another process is the
  7916.  following:
  7917.  
  7918.     1. The process created the other process with
  7919.  DosExecPgm.
  7920.     2. A process uses some method of IPC to tell the other
  7921.  process its PID.
  7922.  
  7923.  
  7924.  241. Writing Device Drivers for Microsoft
  7925.  
  7926.  Are you an experienced device driver writer? Have you written both DOS
  7927.  and OS/2 device drivers? Are you interested in possible contract
  7928.  device driver development work?
  7929.  
  7930.  Please contact Microsoft if you are interested. Email "markmac" your
  7931.  name, phone number(s), and Microsoft will contact you. Please indicate
  7932.  that you are responding to this bulletin board item.
  7933.  
  7934.  
  7935.  242. Windowable Applications in Presentation Manager
  7936.  
  7937.  Question:
  7938.  
  7939.  Which OS/2 Version 1.00 applications will be windowable by the
  7940.  Presentation Manager in OS/2 Version 1.10?
  7941.  
  7942.  Response:
  7943.  
  7944.  A broad class of applications will be windowable by the Presentation
  7945.  Manager in its screen group. The following is a brief summary of OS/2
  7946.  Version 1.00 functionality that is not supported (the Presentation
  7947.  Manager specification included in the Microsoft OS/2 SDK describes
  7948.  these restrictions in more detail):
  7949.  
  7950.   1. Nonalphanumeric modes
  7951.   2. Asking for the selector of the physical screen buffer
  7952.   3. Keystroke and mouse monitors
  7953.   4. VioRegister, KbdRegister, and MouRegister
  7954.   5. VioSavRedrawWait
  7955.   6. VioSavRedrawUndo
  7956.   7. VioScrLock
  7957.   8. VioScrUnlock
  7958.   9. VioModeWait
  7959.  10. VioModeUndo
  7960.  11. VioSetFont
  7961.  12. VioGetFont
  7962.  13. VioSetState
  7963.  14. VioGetState
  7964.  15. Any of the mouse calls that attempt to set driver parameters (set
  7965.      scale factor, set hot key, ...) that would affect its use as a
  7966.      shared resource.
  7967.  
  7968.  
  7969.  243. Using KbdCharIn() from Multiple Threads of Same Process
  7970.  
  7971.  Question:
  7972.  
  7973.  We are having a problem using KbdCharIn() from multiple threads of the
  7974.  same process. One thread consists of a call to KbdCharIn() with wait
  7975.  specified. The other thread does a call to KbdCharIn() with no_wait
  7976.  specified to determine the scroll lock status.
  7977.  
  7978.  Using versions of OS/2 prior to the OS/2 Software Development Kit
  7979.  (SDK) Version 1.06, the no_wait thread returns immediately. However,
  7980.  using Version 1.06, the thread using no_wait waits until the key is
  7981.  pressed. Which behavior is correct?
  7982.  
  7983.  Response:
  7984.  
  7985.  The proper behavior is for the second thread doing the KbdCharIn()
  7986.  call to wait until the first KbdCharIn() is complete. This is the same
  7987.  for any of the subsystems: VIO, KBD, or MOU. There are
  7988.  per-screen-group semaphores that will only allow one thread per screen
  7989.  group to be executing within these subsystems. When you do a
  7990.  KbdCharIn() with wait specified, it claims a semaphore that the second
  7991.  call to KbdCharIn() should block on until the first call completes and
  7992.  the semaphore is released. If you have a requirement for another
  7993.  process in the same screen group to use the keyboard to interact with
  7994.  the user, one of the processes would have to open its own logical
  7995.  keyboard and use that keyboard, after getting the focus, so that the
  7996.  keystrokes go to the different processes in a controlled manner.
  7997.  
  7998.  You may want to look into using KbdGetStatus() to get the status of
  7999.  the keyboard and saving this information for your second thread to
  8000.  use, instead of using a second KbdCharIn() call, which might
  8001.  potentially consume another keystroke.
  8002.  
  8003.  
  8004.  244. Programmer's Reference Missing Documentation for DosSendSignal
  8005.  
  8006.  Problem:
  8007.  
  8008.  The DosSendSignal() call is not documented in the OS/2 SDK manuals.
  8009.  
  8010.  Response:
  8011.  
  8012.  The following is the documentation for DosSendSignal that should
  8013.  appear on Page 274 of the "Microsoft OS/2 Software Development Kit
  8014.  Programmer's Reference":
  8015.  
  8016.  int DOSSENDSIGNAL(ProcessID, SigNumber)
  8017.  unsigned ProcessID;   /* pid of root of subtree */
  8018.  unsigned SigNumber;   /* signal to send */
  8019.  
  8020.  The DosSendSignal() function sends a CTRL+C or CTRL+BREAK signal to
  8021.  the last descendant process in a command subtree that has a
  8022.  corresponding signal handler installed, as follows:
  8023.  
  8024.  Function                Meaning
  8025.  
  8026.  ProcessID    Specifies the process identification code (PID) of the
  8027.               root process of the subtree. It is not necessary that
  8028.               this process still be running, but it is necessary
  8029.               that this process be a direct child of the process
  8030.               that issues this call.
  8031.  
  8032.  SigNumber    Specifies the signal to send. It can be one of the
  8033.               following values:
  8034.  
  8035.               Value           Meaning
  8036.               0x001           SIGINTR (CONTROL-C)
  8037.               0x004K          SIGBREAK (CONTROL-BREAK)
  8038.  
  8039.  The return value is zero if the function is successful. Otherwise, it
  8040.  is an error value.
  8041.  
  8042.  The signal is sent by descending the process tree to the "leaf-most"
  8043.  process and then, starting with that process, look for one that has a
  8044.  handler installed for the corresponding signal. (The leaf-most process
  8045.  is the last process in the command subtree.) If a handler is found,
  8046.  give the signal to that process; otherwise, look at the parent
  8047.  process. Continue until either the signal is sent or the original
  8048.  process is looked at; the latter case is indicated by a unique error
  8049.  code.
  8050.  
  8051.  
  8052.  245. Which VIO Calls Are Allowed in a Window
  8053.  
  8054.  Question:
  8055.     If a full screen application is written using only the VIO and KBD
  8056.  subsystems, will it run in a window under Presentation Manager? Please
  8057.  give me as much detail as you can.
  8058.  
  8059.  Response:
  8060.     See Page 353 (and following) of the Presentation Manager
  8061.  Specification Volume 2 for a list of which VIO calls will be allowed
  8062.  for an application to be able to run in a window under PM. A beta
  8063.  version of the PM is scheduled to be shipped in the first quarter of
  8064.  next year and will contain further information on writing programs
  8065.  that will work with the Presentation Manager.
  8066.  
  8067.  
  8068.  246. Booting DOS and OS/2 From the Same Hard Disk
  8069.  
  8070.  Question:
  8071.     I have a Compaq 386, currently with DOS 3.1, and am doing Windows
  8072.  development. I will be getting one of the $3K OS/2 kits, and have the
  8073.  following question: If I had a 70M disk in my Compaq, would it be
  8074.  possible for me to set it up with two partitions, one with DOS 3.x,
  8075.  and one with OS/2, so I can do development on either environment,
  8076.  depending on how I boot the machine?
  8077.     I have heard of a machine having both DOS 3.x and XENIX in separate
  8078.  partitions.
  8079.  
  8080.  Response:
  8081.    The next update to the OS/2 SDK will contain an installation program
  8082.  that will let you install OS/2 on your hard disk in such a way that
  8083.  you can decide at boot time whether to boot MS-DOS or OS/2. Both
  8084.  MS-DOS and OS/2 will both be on the same hard disk, but after you boot
  8085.  you can organize your files on the two partitions as you wish.
  8086.  
  8087.  
  8088.  247. Problem in SSE Screen Editor
  8089.  
  8090.  Question:
  8091.     When I use the SSE screen editor built from the example programs in
  8092.  the SDK, the CARRIAGE RETURN LINE FEED pair at the end of each line in
  8093.  my source file is replaced with a LINE FEED when the file is resaved.
  8094.  
  8095.  Response:
  8096.     This editor is found in the directory /DEMOS/APPS/SSE.
  8097.     You are correct, the editor as shipped exhibits the problem you
  8098.  describe. The CARRIAGE RETURN LINE FEED pair delimiting the end of
  8099.  each line of text is not preserved--only the LINE FEED is kept. In
  8100.  other words, byte pairs of 0x0D,0x0A in the original file will be
  8101.  replaced with 0x0A only.
  8102.     The broken code is in the file SSEFILE.C, in the routine SAVEFILE.
  8103.  The code change necessary to correct this problem is as follows:
  8104.  
  8105.  OLD CODE
  8106.  
  8107.  /*  place lines in fbuffer */
  8108.      for (i = 0, j = 0; (i < TotalLines) && (!rc); i++) {
  8109.          if ((LineTable[i]->linelength) < (FBUFFSIZE - j)) {
  8110.              for (k = 0; k < LineTable[i]->linelength; k++, j++)
  8111.                  fbuffer[j] = LineTable[i]->firstchar[k];
  8112.              fbuffer[j] = '\n';
  8113.              j++;
  8114.          }
  8115.  
  8116.  NEW CODE
  8117.  
  8118.  /*  place lines in fbuffer */
  8119.      for (i = 0, j = 0; (i < TotalLines) && (!rc); i++) {
  8120.          if ((LineTable[i]->linelength) < (FBUFFSIZE - j)) {
  8121.              for (k = 0; k < LineTable[i]->linelength; k++, j++)
  8122.                  fbuffer[j] = LineTable[i]->firstchar[k];
  8123.              fbuffer[j] = '\r';
  8124.              j++;
  8125.              fbuffer[j] = '\n';
  8126.              j++;
  8127.          }
  8128.  
  8129.  
  8130.  248. Use Presentation Manager for Display Code
  8131.  
  8132.  Question:
  8133.     Should I write my new application using "ANSI.SYS" calls, or the
  8134.  Microsoft OS/2 Windows Presentation Manager?
  8135.  
  8136.  Response:
  8137.     Microsoft's OS/2 Windows Presentation Manager is the screen
  8138.  handling vehicle of choice for OS/2. The OS/2 Windows Presentation
  8139.  Manager (OS/2 PM) provides a superset of Microsoft's Windows for DOS
  8140.  functionality, and thus allows your application to have a standard
  8141.  interface on both OS/2 and MS-DOS. Using ANSI.SYS within a window
  8142.  running in the OS/2 PM domain will be possible, but is not the I/O
  8143.  handling method of choice. Some possible problems one may encounter
  8144.  are handling different window sizes, resizing, not having the ability
  8145.  to adapt to differing character sets, having to handle ALL keyboard
  8146.  and mouse I/O, etc. Even if your application is a character based
  8147.  application, the OS/2 PM provides you with a much richer environment
  8148.  and tool chest to work with. If you'd like to get a feel for what
  8149.  writing an application for the OS/2 PM is like, while still using DOS,
  8150.  purchase a Microsoft Windows for DOS Software Development Kit. The
  8151.  Windows for DOS and the OS/2 PM programming models are the same.
  8152.  
  8153.  
  8154.  249. Error in Make File for Huge-Memory Model Sample Application
  8155.  
  8156.     There is an error in the make file for the HUGE sample application
  8157.  that is included on the "Sample OS/2 System Programs Disk 2" (which is
  8158.  mislabeled Disk 1) for the Microsoft Operating System/2 Programmer's
  8159.  Toolkit. The original make file used the large-memory model compile
  8160.  option, -AL, instead of the huge-memory model option, -AH. The
  8161.  corrected make file follows:
  8162.  
  8163.     # Makefile for huge
  8164.  
  8165.     INC=..\..\..\include
  8166.     LIB=..\..\..\lib
  8167.     OPT=-AH -G0 -Lp -I$(INC)
  8168.  
  8169.     huge.exe: huge.c huge
  8170.        cl $(OPT) huge.c
  8171.        bind huge.exe $(LIB)\api.lib $(LIB)\doscalls.lib
  8172.  
  8173.  
  8174.  250. System Resource Limits for OS/2 Version 1.20
  8175.  
  8176.  Question:
  8177.  
  8178.  Is there any documentation on the limits set by OS/2 for system
  8179.  resources: file handles, pipe handles, semaphores, shared and
  8180.  nonshared segments, processes, threads, timers, sessions, queues, and
  8181.  queue entries? This information is very important for the system
  8182.  planner, because I'm sure that OS/2 cannot maintain an infinite number
  8183.  of these resources.
  8184.  
  8185.  Response:
  8186.  
  8187.  Below is a list of the current maximum values for the resources you
  8188.  listed. These values may change in future versions of OS/2.
  8189.  
  8190.  The following list is for the final version of OS/2 1.20. The SDK that
  8191.  you have may differ in some areas.
  8192.  
  8193.  Memory Segments
  8194.  ---------------
  8195.  
  8196.  There is an overall system limit of 7680 segments of all kinds. This
  8197.  includes: shared, nonshared, code, data, and swapped-out segments.
  8198.  Also included in this limit are: discarded segments (read-only or
  8199.  execute segments that will be reloaded later) and segments that could
  8200.  be demand loaded (for an application that is currently running) in the
  8201.  future.
  8202.  
  8203.  If swapping is enabled, there is a system limit of 2000 swappable
  8204.  segments. Once this limit of 2000 swappable segments is reached,
  8205.  further requests for swappable memory [which is what DosAllocSeg()
  8206.  gets] are denied.
  8207.  
  8208.  There is an overall limit of 6144 segments for all types of shared
  8209.  segments. These types are: shared, name-shared, code, and CS-aliased.
  8210.  For each process there is a limit of 30 name-shared segments.
  8211.  
  8212.  Each process is limited to 2048 nonshared segments.
  8213.  
  8214.  The recommended maximums for one application are: 300 shared segments,
  8215.  100 nonshared segments, and 10 name-shared segments.
  8216.  
  8217.  Processes and Threads
  8218.  ---------------------
  8219.  
  8220.  The maximum number of threads that can exist in the system at any one
  8221.  time is 512. Each process must have at least one thread; therefore,
  8222.  the maximum number of processes is also 512. Currently, the default
  8223.  maximum number of threads is set to 128. This can be changed by using
  8224.  the THREADS command in the CONFIG.SYS file. Each process is limited to
  8225.  no more than 56 threads.
  8226.  
  8227.  The recommended maximum number of threads for one application is 12.
  8228.  
  8229.  Screen Groups
  8230.  -------------
  8231.  
  8232.  Currently, there is a maximum of 16 screen groups.
  8233.  
  8234.  Timers
  8235.  ------
  8236.  
  8237.  DosStartTimer() and DosTimerAsync() start timers. The maximum number
  8238.  of active timers is equal to the current maximum number of threads.
  8239.  Each timer also requires a system semaphore; however, one system
  8240.  semaphore can be used for more than one timer.
  8241.  
  8242.  The recommended maximum number of timers for one application is 6.
  8243.  
  8244.  System Semaphores
  8245.  -----------------
  8246.  
  8247.  Currently, the maximum number of system semaphores is 256.
  8248.  
  8249.  The recommended maximum number of system semaphores for one
  8250.  application is 6.
  8251.  
  8252.  Queues
  8253.  ------
  8254.  
  8255.  The maximum number of queues is related to the number of queue
  8256.  entries. The more queue entries there are, the fewer queues there can
  8257.  be, and vice versa. With no queue entries, the maximum number of
  8258.  queues in the system is 409. If there is only one queue, the maximum
  8259.  number of queue entries is 3268.
  8260.  
  8261.  For each application, the recommended maximum number of queues is 6
  8262.  and 100 queue entries.
  8263.  
  8264.  File, Device, and Pipe Handles
  8265.  ------------------------------
  8266.  
  8267.  Each file or device needs one handle to reference it. Each pipe
  8268.  requires two handles. The maximum number of handles in the system is
  8269.  limited to 255. Handles created by DosDupHandle() have a system limit
  8270.  of 999 dup'd handles.
  8271.  
  8272.  The recommended maximum number of file handles for one application is
  8273.  20.
  8274.  
  8275.  Directory Handles
  8276.  -----------------
  8277.  
  8278.  DosFindFirst() allocates a directory handle. Each process is limited
  8279.  to 1000 directory handles.
  8280.  
  8281.  The recommended maximum number of directory handles for one
  8282.  application is 10.
  8283.  
  8284.  
  8285.  251. Incorrect Documentation on Category 9 IOCTL Call
  8286.  
  8287.  Problem:
  8288.  
  8289.  I am getting an invalid parameter error when I try to use the Category
  8290.  9 function 64 (read physical track command) IOCTL call.
  8291.  
  8292.  Response:
  8293.  
  8294.  This is a documentation error affecting Pages 273, 276, and 279 of the
  8295.  "Microsoft Operating System/2 Device Drivers Guide." The command field
  8296.  of the DevIOCtl call should be as follows:
  8297.  
  8298.     Bit    Value
  8299.  
  8300.     0      0   Track layout contains nonconsecutive sectors or
  8301.                does not start with sector 1.
  8302.  
  8303.            1   Track layout starts with sector 1 and contains only
  8304.                consecutive sectors.
  8305.  
  8306.  All other bits are reserved and must be zero.
  8307.  
  8308.  
  8309.  252. Process GP Faults when Signaling a Signal Handler
  8310.  
  8311.  Question:
  8312.     I wrote a simple program to trap a CTRL-C and display a message
  8313.  when the signal handler received a CTRL-C. When I press CTRL-C the
  8314.  program generates a GP fault. What is wrong?
  8315.  
  8316.  Response:
  8317.     The signal handler must declare the arguments that it receives even
  8318.  if it does not do anything with them. See the following example.
  8319.  
  8320.     However, note that the following is a very simple example of a
  8321.  signal handler. This handler does not acknowledge the signal.
  8322.  Therefore the screen group will be hung after the first signal is
  8323.  received. This is because only one signal is allowed to be waiting for
  8324.  acknowledgment and so other incoming signals are lost. Since all
  8325.  future CTRL-Cs are lost, there is not an easy way to kill this
  8326.  program. For a better example of signals, see the example on the OS/2
  8327.  SDK disks named SIGNAL.C.
  8328.  
  8329.  #include <doscalls.h>
  8330.  
  8331.  unsigned old_action;
  8332.  unsigned far * old_action_p = &old_action;
  8333.  unsigned flag;
  8334.  unsigned far * flag_p = &flag;
  8335.  unsigned long old_handler;
  8336.  
  8337.  void far pascal handler(sig_arg, sig_num) /* you must declare these */
  8338.  unsigned sig_arg, sig_num;            /*  two arguments even though */
  8339.                                        /* nothing is done with them. */
  8340.  
  8341.  {
  8342.      *flag_p = 1;
  8343.  
  8344.  }
  8345.  
  8346.  main(argc,argv)
  8347.  int argc;
  8348.  char * argv[];
  8349.  {
  8350.      printf("dossetsighandler value %x\n",
  8351.       DOSSETSIGHANDLER(handler, 0L,
  8352.         0L,2,1));
  8353.  
  8354.      while (1)
  8355.   if (flag) {
  8356.       flag = 0;
  8357.       printf("event_happened\n");
  8358.   }
  8359.  }
  8360.  
  8361.  
  8362.  253. Saving Registers Across a Call to PhysToVirt
  8363.  
  8364.  Question:
  8365.     Does the PhysToVirt Device Help call preserve the caller's BP
  8366.  register?
  8367.  
  8368.  Response:
  8369.     The PhysToVirt call is only guaranteed to preserve the segment registers
  8370.  CS, SS, and either DS or ES, depending on the value of DH at the time the
  8371.  call is made, and the SP register. Any other registers that you need to
  8372.  preserve need to be stored and reloaded across the call.
  8373.  
  8374.  
  8375.  254. DEL Command Quits Too Soon on Multiple Deletions
  8376.  
  8377.  Question:
  8378.     Take three directories called A, B, and C. Directory A is empty; B
  8379.  and C have files in them. The command "DEL A B C" quits after the "are
  8380.  you sure" prompt on the first directory (A), leaving the B and C
  8381.  directories intact. Directory A being empty shouldn't have any effect
  8382.  on B and C. The same sort of thing happens if A, B, and C are files
  8383.  and A is read-only.
  8384.  
  8385.  Response:
  8386.     Not finding any files is considered an error from delete. It is
  8387.  used to set the error level and can be checked for by programs. All
  8388.  internal commands that accept multiple arguments like DEL, MKDIR, and
  8389.  RMDIR will all quit if there is an error in one of the arguments. This
  8390.  is because they work from left to right and what is on the right often
  8391.  depends on what was on the left being successful.
  8392.  
  8393.  
  8394.  255. Global Seg Current Foreground PID Is Not Always Current
  8395.  
  8396.  Problem:
  8397.     Global Seg Current Foreground PID is not always current. The only
  8398.  time the current foreground PID in the global information segment is
  8399.  updated is when the process occupying the current foreground screen
  8400.  executes a KBDCHARIN. Therefore, if a process (especially a detached
  8401.  process) does a DOSGETINFOSEG it will not always be able to correctly
  8402.  discern if there is a process other than the command line prompt
  8403.  active. Basically, the Global Seg Current Foreground PID seems to
  8404.  often not be current.
  8405.  
  8406.  Response:
  8407.     This problem will be fixed in the 1.1 release of OS/2 with the
  8408.  Presentation Manager.
  8409.  
  8410.  
  8411.  256. "COPY *.* *.BAK" Does Not Always Give Desired Results
  8412.  
  8413.  Question:
  8414.     "COPY *.* *.BAK", when there is an opening in the second position
  8415.  of the FAT, returns an error after the first copy and quits. Copy
  8416.  should be smart enough not to try to recopy a file that it has already
  8417.  copied. This is also a problem in PC-DOS.
  8418.  
  8419.  Response:
  8420.     Use XCOPY /p. There is nothing that can be done with a GLOBAL type
  8421.  copy that essentially stumbles upon itself to copy. It should not
  8422.  usually be necessary to use that type of syntax during a copy
  8423.  operation.
  8424.  
  8425.  
  8426.  257. VioGetConfig Values Missing from Documentation
  8427.  
  8428.  Question:
  8429.  
  8430.  I am running OS/2 with a VGA adapter/monitor. When I do a VioGetConfig
  8431.  I get AdapterType 3 and DisplayType 4, neither of which is listed in
  8432.  the documentation.
  8433.  
  8434.  Could you please give me the complete list of values?
  8435.  
  8436.  Response:
  8437.  
  8438.  The adapter type values should be as follows:
  8439.  
  8440.  Value       Adapter
  8441.  
  8442.    0         Monochrome / printer adapter
  8443.    1         Color graphics adapter
  8444.    2         Enhanced graphics adapter
  8445.    3         VGA
  8446.    4-6       Reserved
  8447.  
  8448.  The values for display type should be as follows:
  8449.  
  8450.  Value       Display
  8451.  
  8452.    0         Monochrome display
  8453.    1         Color display
  8454.    2         Enhanced color display
  8455.    3         PS/2 Monochrome display
  8456.    4         PS/2 Color display
  8457.    5-8       Reserved
  8458.  
  8459.  
  8460.  258. When Processes Receive Priority Boosts by the System
  8461.  
  8462.  Question:
  8463.     From experimentation I have determined that the foreground screen
  8464.  group is given higher priority than either processes in background
  8465.  screen groups or detached processes. Is there a rule for how the
  8466.  priorities of various processes are adjusted based on their screen
  8467.  group's state?
  8468.     Given a process that creates children within the same screen group,
  8469.  detached children, and children in new screen group, how does that
  8470.  process ensure that all its children compete on an equal basis for the
  8471.  system resources?
  8472.  
  8473.  Response:
  8474.     Processes are given temporary priority boosts under the following
  8475.  circumstances:
  8476.  
  8477.     1. They are in the current screen group.
  8478.     2. More than MAXWAIT number of seconds has elapsed since the
  8479.  process was last executed. The priority of the process will be boosted
  8480.  for one timeslice. MAXWAIT is a parameter in the config.sys file.
  8481.  
  8482.     You can disable the dynamic variation of priority by using the
  8483.  PRIORITY= parameter in config.sys. This can be set to either absolute
  8484.  or dynamic, with dynamic the default. Generally we presume that
  8485.  processes in the foreground have your attention and therefore should
  8486.  be given a slight boost over processes in the background.
  8487.     You could use the DosSetPrty call to increase the priority of
  8488.  background processes/threads so that all your threads ran at
  8489.  essentially the same level even though some of them were originally
  8490.  lower and received a boost by the system because they were in the
  8491.  foreground.
  8492.  
  8493.  
  8494.  259. COMP Doesn't Handle Environment Parameters Correctly
  8495.  
  8496.  Question:
  8497.  
  8498.  Assume there is a directory D:\TEST and two identical files TEST1.DAT
  8499.  and TEST2.DAT. After you set the following environment variable in
  8500.  protect mode, as follows
  8501.  
  8502.  SET Z:=D:\TEST\
  8503.  
  8504.  you will be able to use variable %Z:% in COMP from the protect mode
  8505.  command line, as follows:
  8506.  
  8507.  COMP %Z:%TEST1.DAT %Z%TEST2.DAT
  8508.  
  8509.  The utility compares these two files correctly no matter what the
  8510.  current directory and/or drive is.
  8511.  
  8512.  However, after the comparison, the utility asks if you want to compare
  8513.  more files. If you answer "Y," it asks the first filename and then the
  8514.  second. If the first filename is entered as %Z:%TEST1.DAT and the
  8515.  second as %Z:%TEST2.DAT, the error message "SYS1171: The system cannot
  8516.  find the d:%Z:%TEST1.DAT path" appears and no comparison occurs
  8517.  although the same syntax is valid when typing from the protect mode
  8518.  command line. This means that COMP is inconsistent with itself.
  8519.  
  8520.  Response:
  8521.  
  8522.  COMP is consistent. COMP does not handle the conversion of "SET"
  8523.  variables at all. This is done by the command interpreter in protect
  8524.  mode and by the batch file processor. We agree that this sounds like a
  8525.  good enhancement for the COMP utility and will be considered for
  8526.  inclusion in a future release. It is now, however, working as
  8527.  designed.
  8528.  
  8529.  
  8530.  260. SYS Command Option /S Documentation Error in User's Reference
  8531.  
  8532.  Question:
  8533.  
  8534.  The SYS command has documented an option /S that is not recognized by
  8535.  the command. The /S is supposed to copy all the files in the
  8536.  FORMATS.TBL file. Is there a problem in the SYS command or is it no
  8537.  longer supported?
  8538.  
  8539.  Response:
  8540.  
  8541.  The SYS command copies only the system files (OS2BIO.COM and
  8542.  OS2DOS.COM) onto the disk you are SYS'ing. The /S command is no longer
  8543.  valid. This is a documentation error on Page 193 of the "Microsoft
  8544.  Operating System/2 Software Development Kit User's Reference."
  8545.  
  8546.  
  8547.  261. DOSWRITE Error Conditions Not Well Documented
  8548.  
  8549.     The OS/2 documentation section on DOSWRITE needs a better
  8550.  description of the out-of-disk-space condition. Add the following to
  8551.  the Remarks section on Page 333 of the "Microsoft Operating System/2
  8552.  Programmer's Reference":
  8553.  
  8554.        "Note that in order to determine if the entire buffer requested
  8555.     was successfully written it is necessary to check the return code
  8556.     from DOSWRITE for error and also to check that the 'BytesWritten'
  8557.     value returned is the same as the 'BufferLength' parameter.
  8558.     Insufficient disk space is not indicated with an error return."
  8559.  
  8560.  
  8561.  262. Swapper Run from Command Line Crashes System
  8562.  
  8563.  Problem:
  8564.     In the SDK release, if the swapper is run from the command line,
  8565.  the system halts with an internal error.
  8566.  
  8567.  Response:
  8568.     In the SDK release if the swapper is run from the command line, the
  8569.  system does halt with an internal error. The solution is to not invoke
  8570.  the swapper from the command line. The swapper will be correctly
  8571.  invoked by setting MEMMAN=swap in the config.sys file.
  8572.  
  8573.  
  8574.  263. What Happens when DosReAllocSeg Fails
  8575.  
  8576.  Question:
  8577.     What condition is the allocated memory in after attempting a
  8578.  DosReAllocSeg if the DosReAllocSeg failed? Is it left alone or freed?
  8579.  
  8580.  Response:
  8581.     If the DosReAllocSeg call fails, the memory will be left alone. It will
  8582.  not be freed or have its size changed.
  8583.  
  8584.  
  8585.  264. Device Driver Stack Size
  8586.  
  8587.  Question:
  8588.     How much stack space is available on entry to an OS/2 device
  8589.  driver?
  8590.  
  8591.  Response:
  8592.     When the device driver's strategy routine is entered, it is running
  8593.  on the kernel stack of the calling thread. Therefore, the amount of
  8594.  stack space that is available depends on the state of the thread that
  8595.  called it. When the device driver is entered at interrupt time it is
  8596.  running on the interrupt stack, which is not very big.
  8597.     We recommend that you keep your use of the stack to a minimum
  8598.  within device drivers. At strategy time you should keep your stack use
  8599.  to under 500 bytes and at interrupt time you should use less than 100
  8600.  bytes of stack space.
  8601.  
  8602.  
  8603.  265. Additional Semaphore Information
  8604.  
  8605.  The description of RAM semaphores and how they compare/contrast to
  8606.  system semaphores was not well described in the "Microsoft OS/2
  8607.  Programmer's Guide" (Pages 103+). The following is a more complete
  8608.  description of the two types of semaphores.
  8609.  
  8610.  The semaphore functions provided by OS/2 allow multiple processes (or
  8611.  threads) to control access to serially reusable resources in an
  8612.  efficient, well-controlled fashion. Two types of semaphores are
  8613.  supported: RAM semaphores and system semaphores. This requires the
  8614.  using processes to have shared access to the same area of memory in
  8615.  which the RAM semaphore is defined. The affected processes define the
  8616.  semaphore by convention (mutual agreement) as a particular double-word
  8617.  in some shared storage area.
  8618.  
  8619.  The system semaphore is a full-function mechanism providing control
  8620.  between any processes and threads with OS/2 managing the storage for
  8621.  the semaphore data structure. System semaphores are defined within the
  8622.  file-system name space as a "pseudo-file" instead of a RAM location.
  8623.  The semaphore is a "pseudo-file" in that its name takes the form of a
  8624.  file in the subdirectory "SEM" although this subdirectory does not
  8625.  actually exist; system semaphores and their names are kept in memory.
  8626.  
  8627.  The following is a comparison of RAM and system semaphores:
  8628.  
  8629.  1. System semaphores are more flexible and easier to use than RAM
  8630.     semaphores because of the following qualities:
  8631.  
  8632.     a. They can be used by processes that share no memory.
  8633.  
  8634.     b. Their ownership is relinquished when the owner terminates.
  8635.  
  8636.     c. In future versions of OS/2, when protection mechanisms are added
  8637.        to the OS/2 file system, access to system semaphores will be
  8638.        protected by the same mechanism that protects access to files.
  8639.  
  8640.     d. Future versions that manage file names across a network could
  8641.        also support system semaphores across the network between
  8642.        processes on different machines.
  8643.  
  8644.  2. From a performance standpoint, RAM semaphores offer a performance
  8645.     advantage over system semaphores because the handle used to refer
  8646.     to them is actually the address of the semaphore, while the handles
  8647.     of system semaphores must be translated to the memory address of
  8648.     the semaphore data structure.
  8649.  
  8650.  3. RAM semaphores should not be used between processes to control
  8651.     access to a serially reusable resource because it will not be
  8652.     possible to relinquish the semaphore, should the owner end
  8653.     abnormally. In the case of system semaphores, should the owner end,
  8654.     OS/2 will release the semaphore and notify the next thread that
  8655.     gets the semaphore that the owner ended while holding the
  8656.     semaphore.
  8657.  
  8658.  When discussing semaphores, the terms "owned," "unowned," "set," and
  8659.  "clear" are used to describe the state of a semaphore at a particular
  8660.  time. The concept of ownership applies only to system semaphores that
  8661.  are created with exclusive ownership indicated. When a semaphore is
  8662.  owned, it is an error for a thread other than the owner to try to
  8663.  modify that semaphore.
  8664.  
  8665.  The handle for a RAM semaphore is the address of the double-word of
  8666.  storage allocated. If this address of the RAM semaphore is invalid,
  8667.  the system will terminate the process with a general protection fault.
  8668.  The semaphore system calls will not return an error code when passed
  8669.  an invalid semaphore handle.
  8670.  
  8671.  The functions provided to support semaphores in their classical
  8672.  serialization mode of usage are DosSemRequest and DosSemClear. In
  8673.  addition to these functions, there is a set of functions for using
  8674.  semaphores as an efficient means of signaling between threads. These
  8675.  functions are DosSemSet, DosSemSetWait, and DosSemWait.
  8676.  
  8677.  To wait for the occurrences of multiple events, there is a multiple
  8678.  semaphore wait function, DosMuxSemWait, described on Page 179 of the
  8679.  "Microsoft Operating System/2 Programmer's Reference."
  8680.  
  8681.  
  8682.  266. Detecting Extra Keys on Enhanced Keyboards
  8683.  
  8684.  Question:
  8685.     We are trying to make our keyboard routine act the same under OS/2
  8686.  as it does under DOS. For this reason we want the ARROW keys to first
  8687.  return a 00 and then the code (such as 80).  The numeric ARROW keys
  8688.  appear to work this way (with NUM LOCK off).  However, the gray ARROW
  8689.  keys on the PS/2 Model 80 behave differently under OS/2 and DOS.
  8690.  Under DOS they are the same as the numeric arrow keys.  Under OS/2 it
  8691.  appears that they return a 224 as the char_code and the code is in
  8692.  scan_code.
  8693.  
  8694.  Response:
  8695.     Under OS/2 you are able to tell the difference between the numeric
  8696.  ARROW keys and the gray ARROW keys. You should write your program to
  8697.  be sensitive to either value in the char_code field (0 or 224) if you
  8698.  wish to be able to run the same program in DOS and OS/2.  It will work
  8699.  in OS/2 if you don't, but you would then have to always use the
  8700.  numeric ARROW keys and special function keys rather than the gray keys
  8701.  on enhanced keyboards.
  8702.  
  8703.  
  8704.  267. Using DOSFREESEG
  8705.  
  8706.  Question:
  8707.     Is the DOSFREESEG call used to free up memory allocated with
  8708.  DOSALLOCSEG or DOSALLOCHUGE? Or, can we use DOSFREESEG for either
  8709.  allocation scheme?
  8710.  
  8711.  Response:
  8712.     You may use DOSFREESEG for either allocation scheme.
  8713.  
  8714.  
  8715.  268. VGA Mouse Cursor
  8716.  
  8717.  Problem:
  8718.     I am having problems using my mouse in applications in real mode
  8719.  (such as Word Version 4.0) in VGA mode.
  8720.  
  8721.  Response:
  8722.     The problem is that POINTDD.SYS currently only supports graphics
  8723.  cursors for display modes 0-7, which does not include the VGA modes.
  8724.  
  8725.  
  8726.  269. When to Call UnPhysToVirt in the Device Driver
  8727.  
  8728.  Question:
  8729.     The documentation for the DevHelp UnPhysToVirt states:
  8730.  "UnPhysToVirt must be called by the same procedure that issued
  8731.  PhysToVirt when use of the converted address is completed and before
  8732.  the procedure returns to its caller."
  8733.  
  8734.  Response:
  8735.     It is correct that you must be in the same procedure when you do
  8736.  the UnPhysToVirt as when you did the PhysToVirt. This is because if a
  8737.  mode switch occurred on the PhysToVirt call, then the return address on
  8738.  the stack might not be valid for the current mode when you tried to
  8739.  return from the procedure.
  8740.  
  8741.  
  8742.  270. Device Driver Memory Access
  8743.  
  8744.  Question:
  8745.     We need to pass information between the PC and some card that has
  8746.  512K of memory accessible to the PC through a 64K window at address
  8747.  D000:0000. We are writing a device driver to interface with this card.
  8748.  What does the device driver have to do to access shared memory at
  8749.  D000:0000?
  8750.  
  8751.  Response:
  8752.   Since the memory is either between 640K and 1 megabyte or above the
  8753.  range of contiguous memory you can use the Selector : offset pair
  8754.  returned from either PhysToVirt or PhysToUvirt without needing to
  8755.  verify or lock down the memory, since memory in these ranges is
  8756.  ignored by the OS/2 memory manager.
  8757.  
  8758.  
  8759.  271. EGA.SYS Error when Booting OS/2
  8760.  
  8761.  Question:
  8762.     Do I need EGA.SYS at all? If so, how do I get one that works?
  8763.  
  8764.  Response:
  8765.     This is only for the real mode box. Programs such as Word need it
  8766.  to draw the mouse cursor on the screen.
  8767.     If your system is set up to run only in protected mode then you
  8768.  will get this error. Remove the line in the STARTUP.CMD file that
  8769.  says "Protectonly=yes". This line is needed only if you want a 3x box.
  8770.  
  8771.  
  8772.  272. Inherited Attributes of Files
  8773.  
  8774.  Question:
  8775.     What attributes of a file handle are inherited by child processes
  8776.  that inherit the handle?
  8777.  
  8778.  Response:
  8779.     The inheritance flag and the write through bits are not inherited
  8780.  by child processes. The other attributes of a file handle are
  8781.  inherited by child processes.
  8782.  
  8783.  
  8784.  273. File System ID
  8785.  
  8786.  Question:
  8787.     Page 234 of the OS/2 programmer's reference mentioned the parameter
  8788.  File System ID for DOSQFSINFO. Could you please tell us what it means
  8789.  and what it is used for?
  8790.  
  8791.  Response:
  8792.     The File System ID parameter returns the file system ID/number for
  8793.  the file system; there is currently only one file system for OS/2.
  8794.  
  8795.  
  8796.  274. Running Character Applications with PM Applications
  8797.  
  8798.  Question:
  8799.     Can the other 11 sessions run while the Presentation Manager is
  8800.  running in session 1?
  8801.  
  8802.  Response:
  8803.     Yes. But you can only have one Presentation Manager screen group.
  8804.  
  8805.  
  8806.  275. RM and Losing Disk Space
  8807.  
  8808.  Question:
  8809.     OS/2 seems to be loosing disk space quite rapidly. Two days ago I
  8810.  had 15 megabytes free on my D partition. Today I have none. I have
  8811.  carefully checked all files; CHKDSK /f does not help.
  8812.     I have found that RM places deleted files into a "deleted"
  8813.  subdirectory. This continues to consume disk space. To recover the
  8814.  disk space, I must "del deleted" in each directory. Is there a better
  8815.  way to do this?
  8816.  
  8817.  Response:
  8818.     RM comes with the SDKED editor; it is documented on Page 36 of the
  8819.  user's guide to the SDKED editor.
  8820.     Two other commands, UNDEL and EXP, may be used on files that were
  8821.  "deleted" with RM. UNDEL restores a specified file from the deleted
  8822.  subdirectory. EXP expunges the contents of a deleted subdirectory--for
  8823.  example, "EXP /r c:\" will recursively expunge all the deleted
  8824.  subdirectories starting from the root of C.
  8825.  
  8826.  
  8827.  276. Calling C Routines from a Device Driver
  8828.  
  8829.  Question:
  8830.  
  8831.  How can I call a routine written in C from an OS/2 device driver
  8832.  written in assembly language?
  8833.  
  8834.  Response:
  8835.  
  8836.  Below is a simple device driver that calls a C routine. The following
  8837.  is a list of the problems we encountered:
  8838.  
  8839.  1. Segment names in the assembly code must match those generated by
  8840.     the C compiler (_DATA and _TEXT).
  8841.  
  8842.  2. The order of the segments must be defined in the assembly so that
  8843.     all the data and code are each in one segment. Refer to the top of
  8844.     the STRAT.ASM file.
  8845.  
  8846.  3. C code must be compiled with Gs to disable stack checking.
  8847.  
  8848.  4. C code should not use any C run-time routines because the C
  8849.     routines are nonreentrant; assume SS==DS, and have stack checking
  8850.     enabled.
  8851.  
  8852.  The C routine (C_ROUTINE) is called from init time and when a read of
  8853.  the device is done. It does not perform any function other than that
  8854.  it adds the numbers from 0 to whatever number you call it with;
  8855.  however, it demonstrates calling C in a device driver and passing
  8856.  parameters to the C routine.
  8857.  
  8858.  You do not need all the declarations in MYDEVICE.INC, which was copied
  8859.  from another device driver and was not cut down to the bare minimum.
  8860.  
  8861.  mydevice.def ===========================================================
  8862.  LIBRARY
  8863.  PROTMODE
  8864.  
  8865.  mydevice.inc ===========================================================
  8866.  
  8867.  ;     Include file for mydevice device driver
  8868.  ;
  8869.  ;     contains macro definitions for the driver routines
  8870.  ;
  8871.  ;    By John Bartlow
  8872.  ;
  8873.  
  8874.  WO      EQU     WORD PTR
  8875.  BY      EQU     BYTE PTR
  8876.  
  8877.  ALLOC_MEM_LOW   EQU 1
  8878.  ALLOC_MEM_HIGH  EQU 0
  8879.  STDOUT          EQU 1
  8880.  
  8881.  MemBufSz        EQU 256
  8882.  
  8883.  ToDS_SI         EQU 0
  8884.  ToES_DI         EQU 1
  8885.  
  8886.  ;=====================================================================
  8887.  ;
  8888.  ; Local Data Area
  8889.  ;   LocalData structure is allocated on the stack and initialized by the
  8890.  ;   Strategy routine for each device driver instance.
  8891.  ;
  8892.  LOCALDATA STRUC
  8893.      LD_PTRSAVE  DD   (?)                ; Far pointer to the request header
  8894.  LOCALDATA ENDS
  8895.  
  8896.  ;****   DevHelp - a macro to call DevHlp
  8897.  ;
  8898.  
  8899.  DEVHELP MACRO   func
  8900.          mov     dl,DEVHLP_&func
  8901.          call    [DevHlp]
  8902.  ENDM
  8903.  
  8904.  FX_LAST_CLOSE   EQU     00000010b       ;  last close in progress
  8905.  
  8906.  PhysAddr struc
  8907.          _lo     dw      (?)     ; low word of a 32-bit pointer
  8908.          _hi     dw      (?)     ; high word of a 32-bit pointer
  8909.  PhysAddr ends
  8910.  
  8911.  DataPacket Struc                ;  data packet for IOctl to register
  8912.              Placement   dw  ?        ;  a monitor
  8913.              Index       dw  ?
  8914.              Inbuff      dd  ?
  8915.              Outbuff     dw  ?
  8916.  DataPacket ends
  8917.  
  8918.  GetLocInfoSeg    equ   2      ; parameters for dh_GetDosVar
  8919.  GetYeildFlag     equ   7
  8920.  
  8921.  BUFFSIZE         equ   256
  8922.  MIN_BUFFSIZE    equ     10
  8923.  TimerInterval   equ    100    ; Call timer routine every 100 tics
  8924.  
  8925.  mydevice. ===========================================================
  8926.  #
  8927.  #**     makefile for OS/2 simple sample device driver
  8928.  #
  8929.  
  8930.  ASM=masm
  8931.  
  8932.  #       Definitions for assembler
  8933.  
  8934.  #       To make debug version use --
  8935.  #       AFLAGS= -Mx -t -P -DSAMPDEBUG -L
  8936.  
  8937.  #       To make non-debug version use --
  8938.  #       AFLAGS= -Mx -t -P
  8939.  
  8940.  #       -Mx -- preserve case sensitivity in external names
  8941.  #       -t  -- "terse" mode, don't print out unneeded messages
  8942.  #       -P  -- check for IMPURE code
  8943.  #       -L  -- Create a listing file
  8944.  #       -n  -- Suppress tables in listing
  8945.  #       -Dsymbol  -- Define assembler symbol
  8946.  
  8947.  AFLAGS= -Mx -t -P -DMYDEBUG -L -n
  8948.  
  8949.  #       Definitions for new style linker
  8950.  
  8951.  LINK=link
  8952.  LFLAGS=/nod /map
  8953.  LIBS=c:\lib\doscalls.lib
  8954.  
  8955.  #       List of object files required
  8956.  #       ORDER IS IMPORTANT!
  8957.  #       "sample" must come first, "sampinit" must be last
  8958.  OBJS=   strat.obj init.obj csub.obj
  8959.  
  8960.  #       Production rules
  8961.  
  8962.  strat.obj: strat.asm mydevice.inc
  8963.          $(ASM) $(AFLAGS) strat.asm,strat.obj;
  8964.  
  8965.  mysubs.obj: mysubs.asm mydevice.inc
  8966.          $(ASM) $(AFLAGS) mysubs.asm,mysubs.obj;
  8967.  
  8968.  csub.obj: csub.c
  8969.          cl -Lp -c -Asnw -G2s -Zp -Od -c csub.c
  8970.  
  8971.  init.obj: init.asm mydevice.inc
  8972.          $(ASM) $(AFLAGS) init.asm,init.obj;
  8973.  
  8974.  mydevice.sys: $(OBJS) $(LIBS) mydevice.def
  8975.          $(LINK) $(LFLAGS) @mydevice.lrf
  8976.          mapsym  mydevice
  8977.  
  8978.  strat.asm =============================================================
  8979.  .286p
  8980.  
  8981.  _DATA   SEGMENT  WORD PUBLIC 'DATA'
  8982.  _DATA   ENDS
  8983.  CONST   SEGMENT  WORD PUBLIC 'CONST'
  8984.  CONST   ENDS
  8985.  _BSS    SEGMENT  WORD PUBLIC 'BSS'
  8986.  _BSS    ENDS
  8987.  
  8988.  _TEXT   SEGMENT  WORD PUBLIC 'CODE'
  8989.  _TEXT   ENDS
  8990.  
  8991.  DGROUP  GROUP   CONST, _BSS, _DATA
  8992.          ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  8993.  
  8994.  include devhlp.inc
  8995.  include devsym.inc
  8996.  include dosmac.inc
  8997.  include error.inc
  8998.  include ioctl.inc
  8999.  ;  include infoseg.inc
  9000.  
  9001.  include mydevice.inc
  9002.  
  9003.  EXTRN CmxInit : NEAR
  9004.  EXTRN C_ROUTINE : NEAR
  9005.  
  9006.  ATTRIB EQU  DEV_CHAR_DEV OR DEV_30 OR DEVLEV_1 OR DEV_GIOCTL
  9007.  
  9008.  _DATA SEGMENT WORD PUBLIC 'DATA'
  9009.  
  9010.  ;  The header must be at the head of the data segment
  9011.  
  9012.  MyDevice SysDev < -1,ATTRIB, OFFSET _TEXT:Strategy,0,'MYDEVICE'>
  9013.  
  9014.  .ERRNZ  OFFSET _DATA:MyDevice            ; enforce the above warning
  9015.  
  9016.  EVEN
  9017.  CommandTab  LABEL   WORD
  9018.      DW      OFFSET _TEXT:CmxInit      ;0 :  Initialization routine
  9019.      DW      OFFSET _TEXT:CmxUnknown   ;1 :
  9020.      DW      OFFSET _TEXT:CmxUnknown   ;2 :
  9021.      DW      OFFSET _TEXT:CmxUnknown   ;3 :
  9022.      DW      OFFSET _TEXT:CmxRead      ;4 :  Read from device
  9023.      DW      OFFSET _TEXT:CmxUnknown   ;5 :
  9024.      DW      OFFSET _TEXT:CmxUnknown   ;6 :
  9025.      DW      OFFSET _TEXT:CmxUnknown   ;7 :
  9026.      DW      OFFSET _TEXT:CmxWrite     ;8 :  Write to device
  9027.      DW      OFFSET _TEXT:CmxUnknown   ;9 :
  9028.      DW      OFFSET _TEXT:CmxUnknown   ;10:
  9029.      DW      OFFSET _TEXT:CmxUnknown   ;11:
  9030.      DW      OFFSET _TEXT:CmxUnknown   ;12:
  9031.      DW      OFFSET _TEXT:CmxOpen      ;13:  Open
  9032.      DW      OFFSET _TEXT:CmxClose     ;14:  Close
  9033.      DW      OFFSET _TEXT:CmxUnknown   ;15:
  9034.      DW      OFFSET _TEXT:CmxUnknown   ;16:
  9035.  
  9036.  MAXCMD = (($ - CommandTab)/2) -1
  9037.  
  9038.              PUBLIC  TimeCount,DevHlp,Buff,YeildAddr
  9039.  
  9040.  Buff        dd      ?               ; pointer to allocated buffer to xfer
  9041.                                      ;  through
  9042.  DevHlp      dd      ?               ; Pointer to device help routine
  9043.  TimeCount   dw      0
  9044.  ReqPacket   dd      0               ; address of request packet
  9045.  YeildAddr   dd      ?               ; address of yield flag
  9046.  WritMsgLen  dw      ?               ; Length of message in buff
  9047.  OpenCount   db      0            ; count of number of opens on this device
  9048.  PID         dw      ?               ; PID of task making open request
  9049.  
  9050.  _DATA ENDS
  9051.  
  9052.  _TEXT SEGMENT WORD PUBLIC 'CODE'
  9053.          ASSUME cs:_TEXT
  9054.  
  9055.  ;  The strategy routine is called by DOS to handle I/O requests to the
  9056.  ;  device
  9057.  ;
  9058.  ;  Entry
  9059.  ;        es:bx -> request packet
  9060.  ;        ds  data segment for mydevice.sys
  9061.  
  9062.  ;  Exit
  9063.  ;        result of operation set in request packet status field
  9064.  ;
  9065.  ;  Uses
  9066.  ;        ax, di, ds, es, bx
  9067.  
  9068.  Procedure Strategy,FAR
  9069.         ASSUME cs:_TEXT, ds:_DATA, es:NOTHING, ss:NOTHING
  9070.  
  9071.  IFDEF MYDEBUG
  9072.         int 3
  9073.  ENDIF
  9074.         mov         di,bx           ; (es:di) -> Request packet
  9075.  
  9076.         SUB         SP,SIZE LOCALDATA
  9077.                           ; reserve space for LocalData (Defined in .INC file)
  9078.         MOV         BP,SP
  9079.                           ; ...referenced with positive offsets
  9080.  
  9081.         MOV         [BP].LD_PTRSAVE._lo,BX  ; Save the virtual address  (ES:BX
  9082.         MOV         [BP].LD_PTRSAVE._hi,ES  ; ...of the Request Packet.
  9083.  
  9084.         xor         bx,bx
  9085.         mov         bl,es:[di].pktcmd   ; get command from request packet
  9086.  
  9087.         cmp         bl,MAXCMD           ; is it out of range ?
  9088.         ja          CmxUnknown
  9089.  
  9090.         shl         bx,1
  9091.  
  9092.  ; Entry to command handlers
  9093.  ; (es:di) -> request packet
  9094.  
  9095.         jmp         CommandTab[bx]
  9096.  
  9097.  Entry CmxDone
  9098.         mov     ax,STDON
  9099.         jmp     SHORT cmx
  9100.  
  9101.  Entry CmxUnknown           ;  error unknown command
  9102.         mov     ax,STDON OR STERR OR ERROR_I24_BAD_COMMAND
  9103.         JMP     SHORT cmx
  9104.  Entry CmxNotReady
  9105.         mov     ax,STDON OR STERR OR ERROR_I24_BAD_COMMAND
  9106.         jmp     short cmx
  9107.  
  9108.  Entry CmxBusy
  9109.         mov     ax,STDON OR STBUI
  9110.         JMP     SHORT cmx
  9111.  
  9112.  Entry CmxGenFail
  9113.         mov     ax,STDON OR STERR OR ERROR_I24_GEN_FAILURE
  9114.  
  9115.  cmx:   sti
  9116.         LDS     BX,[BP].LD_PTRSAVE         ;Load packet address back into DS:B
  9117.         MOV     [BX].PKTSTATUS,AX          ;Mark operation complete
  9118.  
  9119.         MOV     SP,BP                      ;Re-Load SP form BP (clean up stack
  9120.         ADD     SP,SIZE LOCALDATA          ;And de-allocate local data space
  9121.  
  9122.         ret
  9123.  
  9124.  EndProc Strategy
  9125.  
  9126.  ;************************************************
  9127.  ;  The Open routine gets the PID of the process opening the device
  9128.  ;  and then checks to see if the device is already open.
  9129.  ;  If it is open by the same process we increment the counter.
  9130.  ;  If it is open by another process we fail then open request.
  9131.  ;  If it is not open we save the PID of the opening process and
  9132.  ;    return DONE.
  9133.  ;
  9134.  ;************************************************
  9135.  
  9136.  Procedure CmxOpen,NEAR
  9137.      ASSUME cs:_TEXT,ds:_DATA,es:NOTHING,ss:NOTHING
  9138.  
  9139.         jmp  CmxDone
  9140.  EndProc CmxOpen
  9141.  
  9142.  ; **********************************************
  9143.  ;   We get the PID of the closing process and check it against the opening
  9144.  ;   processes PID.
  9145.  ;   If they are the same we decrement the open counter and if it reaches 0.
  9146.  ;   We set the PID to 0 so subsequent closes will fail due to a bad PID.
  9147.  ;
  9148.  ; **********************************************
  9149.  
  9150.  Procedure CmxClose,NEAR
  9151.      ASSUME cs:_TEXT,ds:_DATA,es:NOTHING,ss:NOTHING
  9152.  
  9153.         jmp     CmxDone
  9154.  
  9155.  EndProc CmxClose
  9156.  
  9157.  ; ***********************************
  9158.  
  9159.  ;========================================================================
  9160.  ;
  9161.  ;           READ
  9162.  ; Get the transfer address, which is PHYSICAL
  9163.  ; Convert it to VIRTUAL
  9164.  ; Load it into registers to do transfer from "readmsg" area
  9165.  ;   Set up es:di for destination
  9166.  ;   Set up ds:si for source
  9167.  ;   Set up cx for number of characters
  9168.  ;   Do movsb to move data
  9169.  ;
  9170.  ;========================================================================
  9171.  
  9172.  Procedure CmxRead,NEAR
  9173.          ASSUME  DS:_DATA
  9174.  
  9175.          push    25                              ;  A parameter to pass
  9176.          call    C_routine
  9177.          pop     ax                              ;  a return value
  9178.  
  9179.          mov     cx,es:[di].IOcount              ; count of chars to move in c
  9180.          cmp     cx,WritMsgLen                ; make sure we have enough chars
  9181.          jl      rd01
  9182.          mov     cx,WritMsgLen                   ; Only do max of WritMsgLen
  9183.  rd01:
  9184.          mov     es:[di].IOcount,cx              ; Assume transfer works
  9185.          mov     ax,es:[di].IOpData._hi
  9186.          mov     bx,es:[di].IOpData._lo          ; ax:bx = physycal xfer addr
  9187.          mov     dh,ToES_DI                      ; want result in es:di
  9188.          DEVHELP PHYSTOVIRT
  9189.          jnc     rd00
  9190.          jmp     CmxGenFail                      ; error on conversion
  9191.  rd00:
  9192.          mov     ax,BUFF._hi
  9193.          mov     bx,BUFF._lo                     ; ax:bx = physical addr of sr
  9194.          mov     dh,ToDS_SI                      ; want result in ds:si
  9195.                                                  ; cx already set up
  9196.          push    ds                              ; save data segment ptr
  9197.          DEVHELP PHYSTOVIRT
  9198.          jnc     rd02
  9199.          pop     ds
  9200.          jmp     CmxGenFail                       ; error on conversion
  9201.  rd02:
  9202.          rep     movsb                           ; move the data
  9203.          pop     ds
  9204.          ASSUME  DS:_DATA
  9205.          DEVHELP UNPHYSTOVIRT                    ; Release the virtual address
  9206.  
  9207.          jmp     CmxDone                       ; done, no error
  9208.  
  9209.  EndProc CmxRead
  9210.  
  9211.  ;**************************************
  9212.  ;  Write routine takes a buffer of _DATA pointed to by the request Packet
  9213.  ;  and copies it to the buffer previously allocated by the init routine to
  9214.  ;  store the data.
  9215.  ;**************************************
  9216.  
  9217.  Procedure CmxWrite,NEAR
  9218.          ASSUME  DS:_DATA
  9219.  
  9220.          mov     ax,BUFF._hi
  9221.          mov     bx,BUFF._lo                    ; ax:bx = physical addr of des
  9222.          mov     dh,ToES_DI                      ; want result in es:di
  9223.          mov     cx,MemBufSz                     ; cx = size of segment we wan
  9224.          DEVHELP PHYSTOVIRT
  9225.          jnc     wr00
  9226.          jmp     CmxGenFail                      ; error on conversion
  9227.  wr00:
  9228.          push    ds                              ; save data seg pointer
  9229.          ASSUME  DS:NOTHING
  9230.          lds     si,[bp].LD_PTRSAVE              ; ds:si now point to packet
  9231.          mov     cx,ds:[si].IOcount              ; count of chars to move in c
  9232.          cmp     cx,MemBufSz                   ; make sure request isn't bigge
  9233.                                                  ; than buffer size
  9234.          jl      wr01
  9235.          mov     cx,MemBufSz                     ; Only do max of MemBufSz
  9236.                                                ; Also sets up cx for phystovir
  9237.  wr01:
  9238.          mov     ax,ds:[si].IOpData._hi
  9239.          mov     bx,ds:[si].IOpData._lo          ; ax:bx = physical xfer addr
  9240.          mov     dh,ToDS_SI                      ; want result in ds:si
  9241.          mov     ds:[si].IOcount,cx              ; assume transfer works
  9242.          pop     ds                              ; we're back
  9243.          ASSUME  DS:_DATA
  9244.          mov     WritMsgLen,cx                   ; save length transferred
  9245.                                                  ; for read
  9246.          push    ds                              ; going to need it again
  9247.          DEVHELP PHYSTOVIRT
  9248.          jnc     wr02
  9249.          pop     ds
  9250.          jmp     CmxGenFail                       ; error on conversion
  9251.  wr02:
  9252.          rep     movsb                           ; move the data
  9253.          pop     ds                              ; get data seg back
  9254.          DEVHELP UNPHYSTOVIRT                   ; Release the virtual addresse
  9255.  
  9256.          Jmp     CmxDone                      ; done, no error
  9257.  
  9258.  EndProc CmxWrite
  9259.  
  9260.  _Text ends
  9261.  
  9262.  END
  9263.  
  9264.  init.asm ==================================================================
  9265.  
  9266.  .286p
  9267.  
  9268.  include devhlp.inc
  9269.  include devsym.inc
  9270.  include dosmac.inc
  9271.  
  9272.  include mydevice.inc
  9273.  
  9274.      EXTRN DOSPUTMESSAGE:FAR
  9275.  
  9276.      EXTRN   CmxDone : Near
  9277.      EXTRN   CmxGenFail : Near
  9278.      EXTRN   DOSPUTMESSAGE:FAR
  9279.  
  9280.      EXTRN   TimeCount : WORD
  9281.      EXTRN   DevHlp : DWord
  9282.      EXTRN   Buff : DWORD               ; Physical addr of allocated buffer
  9283.      EXTRN   YeildAddr : DWORD
  9284.      EXTRN   C_ROUTINE : NEAR
  9285.  
  9286.  _DATA Segment Word Public 'DATA'
  9287.  
  9288.  EVEN
  9289.  
  9290.  END_DATA             dw  ?      ; pointer to use when freeing _DATA after ini
  9291.  
  9292.  SignOnMsg           db      'Hello world this is my device driver'
  9293.  SignOnLen = $ - SignOnMsg
  9294.  
  9295.  _DATA    Ends
  9296.  
  9297.  _TEXT Segment Word Public 'CODE'
  9298.      ASSUME cs:_TEXT,ds:_DATA,es:NOTHING,ss:NOTHING
  9299.  
  9300.  ENDCODE     EQU     $
  9301.  
  9302.  ; CmxInit - initialize the device driver
  9303.  ;
  9304.  ;  - Saves pointer to DevHlp
  9305.  ;  - Stores pointers to end of code and _DATA in the request packet
  9306.  ;
  9307.  ;   Entry
  9308.  ;       (es:di) -> request packet
  9309.  ;
  9310.  ;   Exit
  9311.  ;       (es:di).InitEcode = end of code
  9312.  ;       (es:di).InitEdata = end of _DATA
  9313.  ;   Uses
  9314.  ;       ax,bx,es,ds,si,di
  9315.  
  9316.  Procedure CmxInit,NEAR
  9317.      ASSUME cs:_TEXT, ds:_DATA, es:NOTHING, ss:NOTHING
  9318.  
  9319.  ; Save pointer to DevHlp
  9320.  IFDEF MYDEBUG
  9321.       int 3
  9322.  ENDIF
  9323.          push    25
  9324.          call    C_ROUTINE
  9325.  
  9326.          mov     bx,es:[di].IOpDATA._hi        ; save the pointer to the DevHl
  9327.          mov     [DevHlp]._hi,bx               ; routine
  9328.          mov     bx,es:[di].IOpDATA._lo
  9329.          mov     [DevHlp]._lo,bx
  9330.  
  9331.  ;  Get Address of Yeild flag and store in YeildAddr
  9332.  
  9333.          mov     al,GetYeildFlag
  9334.          DEVHELP GetDosVar
  9335.          mov     [YeildAddr._hi],ax
  9336.          mov     [YeildAddr._lo],bx
  9337.  
  9338.  ;  Allocate a buffer to do transfers through
  9339.  
  9340.          mov     bx,MemBufSz                     ; size low
  9341.          mov     ax,0                            ; size high
  9342.          mov     dh,ALLOC_MEM_LOW
  9343.          DEVHELP ALLOCPHYS
  9344.          jnc     OKALLOC
  9345.  
  9346.          mov     dh,ALLOC_MEM_HIGH               ; Failed low lets try to allo
  9347.          DEVHELP ALLOCPHYS                       ; in high memory
  9348.          jnc     OKALLOC
  9349.          jmp     CmxGenFail
  9350.  
  9351.  OKALLOC:
  9352.          mov     BUFF._HI,AX              ; Save physical address of buffer
  9353.          mov     BUFF._LO,BX
  9354.  
  9355.  ;
  9356.  ; Output Sign-on Message
  9357.  ;
  9358.          push    WORD PTR    STDOUT              ;File handle - standard outpu
  9359.          push    WORD PTR    SignonLen           ;Length of message
  9360.          push    ds                              ;Selector of message
  9361.          push    OFFSET  SignonMsg               ;Address of message
  9362.          call    DOSPUTMESSAGE                   ;AX destroyed
  9363.  
  9364.          mov     bx,OFFSET ENDCODE
  9365.          mov     es:[di].InitEcode,bx
  9366.  
  9367.          mov     bx,END_DATA                  ; End of _DATA
  9368.          mov     es:[di].InitEDATA,bx
  9369.  
  9370.          jmp     CmxDone
  9371.  
  9372.  EndProc CmxInit
  9373.  
  9374.  _TEXT    Ends
  9375.          End
  9376.  
  9377.  mydevice.lrf ==============================================================
  9378.  
  9379.  strat.obj csub.obj init.obj
  9380.  mydevice.sys
  9381.  mydevice.map /map /nod /noi
  9382.  c:\lib\doscalls.lib
  9383.  mydevice.def;
  9384.  
  9385.  csub.c ===================================================================
  9386.  int _acrtused;    /* to keep out the C runtime stuff */
  9387.  
  9388.  near pascal C_ROUTINE(param)
  9389.  unsigned int param;
  9390.  
  9391.  {
  9392.  
  9393.  int x;
  9394.  int sum=0;
  9395.  
  9396.      for (x=0; x<param; x++)
  9397.      sum+=x;
  9398.  return(sum);
  9399.  
  9400.  }
  9401.  ==========================  THE END =======================================
  9402.  
  9403.  
  9404.  277. CodeView Will Not Run under OS/2
  9405.  
  9406.  Question:
  9407.  
  9408.  When trying to invoke CodeView (CVP.EXE) under OS/2, I receive the
  9409.  error message "SYS0197 OS/2 not configured to run this application."
  9410.  Why is this error occurring?
  9411.  
  9412.  Response:
  9413.  
  9414.  To run the protected-mode version of CodeView, you need to have your
  9415.  system set up with IOPL segments enabled. You can enable IOPL segments
  9416.  by adding the following line to your CONFIG.SYS file:
  9417.  
  9418.     IOPL=YES
  9419.  
  9420.  
  9421.  278. Freeing Memory when a Process Dies
  9422.  
  9423.  Question:
  9424.     Is it true that memory allocated using DOSALLOCHUGE or DOSALLOCSEG
  9425.  is not freed when a process is terminated (the process may have
  9426.  neglected to free the memory using DOSFREESEG)? If so, does this
  9427.  "dead" memory accumulate until the system is rebooted?
  9428.  
  9429.  Response:
  9430.     All memory owned by a process is deallocated when the process dies.
  9431.  If there are other processes that have access to shared memory created
  9432.  by the dying process, those selectors will remain valid until no
  9433.  processes are alive that had access to them.
  9434.  
  9435.  
  9436.  279. DosSemWait Incorrectly Documented in Programmer's Reference
  9437.  
  9438.  In the "Microsoft Operating System/2 Programmer's Reference" on Page
  9439.  271 it incorrectly states, "DosSemWait cannot be issued against a
  9440.  system semaphore which is owned by another process unless the
  9441.  NoExclusive option was selected on the DosCreateSem request that
  9442.  created the semaphore."
  9443.  
  9444.  The correct documentation is as follows (note that nothing has been
  9445.  added, but that there are two deletions):
  9446.  
  9447.  2.2.4.10.2  DOSSEMWAIT - WAIT FOR A SEMAPHORE TO BE CLEARED
  9448.  
  9449.  Purpose   DosSemWait blocks the current thread until the indicated
  9450.            semaphore is cleared but does not establish ownership of
  9451.            the semaphore.
  9452.  
  9453.  Format    Calling Sequence:
  9454.  
  9455.            EXTRN DosSemWait:FAR
  9456.  
  9457.            PUSH  DWORD SemHandle ; Semaphore handle
  9458.            PUSH  DWORD Timeout   ; Timeout
  9459.            CALL  DosSemWait
  9460.  
  9461.            where     SemHandle is the double-word handle of the
  9462.                      semaphore. For a system semaphore, this handle
  9463.                      is the result of the DosCreateSem or DosOpenSem
  9464.                      request which granted this thread access to the
  9465.                      semaphore. For a RAM semaphore, this handle is
  9466.                      the address of the double-word of storage
  9467.                      allocated for the semaphore.
  9468.  
  9469.                      Timeout is the count, in milliseconds, until the
  9470.                      requesting task is to resume execution if the
  9471.                      requested semaphore does not become available.
  9472.                      The meaning of the values specified is as follows:
  9473.  
  9474.                      o  If value = -1, when the semaphore is set,
  9475.                         there will be no timeout - the requester will
  9476.                         wait indefinitely.
  9477.  
  9478.                      o  If value = 0, there will be an immediate
  9479.                         return if the semaphore is set.
  9480.  
  9481.                      o  If value > 0, value is the number of
  9482.                         milliseconds to wait if the semaphore is set.
  9483.  
  9484.            Returns:  IF AX = 0
  9485.  
  9486.                         NO error
  9487.  
  9488.                      ELSE
  9489.  
  9490.                         AX = Error Code:
  9491.  
  9492.                         o   Invalid semaphore handle
  9493.  
  9494.                         o   Timeout
  9495.  
  9496.  Remarks:  DosSemWait is similar to DosSemRequest with the difference
  9497.            being that the semaphore is unowned on return.
  9498.  
  9499.            The unblocking of a DosSemWait is "level triggered" in
  9500.            that it will not return unless the indicated semaphore
  9501.            remains clear until the affected thread has been
  9502.            redispatched and has been able to ascertain that the
  9503.            indicated semaphore is clear.
  9504.  
  9505.  o  DosSemWait
  9506.  
  9507.         ERROR_SEM_TIMEOUT
  9508.  
  9509.         ERROR_INTERRUPT
  9510.  
  9511.         ERROR_INVALID_HANDLE
  9512.  
  9513.  
  9514.  280. Information about Dual Boot
  9515.  
  9516.  Question:
  9517.     I do not understand how to remove dual boot. Can you provide
  9518.  details about how it works?
  9519.  
  9520.  Response:
  9521.     Dual boot modifies the boot sector of the hard disk, and a section
  9522.  of OS2BIO.COM. It replaces the traditional boot sector with a special
  9523.  boot sector to support dual boot. Commonly asked questions are as
  9524.  follows:
  9525.  
  9526.     1. How do I remove dual boot?
  9527.        Boot from a DOS Version 3.2x or Version 3.30 floppy and SYS C:
  9528.        to replace the boot sector. You may also wish to copy the hidden
  9529.        DOS files.
  9530.     2. What happens if I install dual boot twice?
  9531.        The MSDOS option will hang. To restore it, SYS your hard disk
  9532.        and reinstall dual boot.
  9533.        This is fixed in MS OS/2 SDK 1.05.  The new install program
  9534.        allows for re-installing dual boot with the OS/2 upgrade.
  9535.     3. What version of DOS have you tested dual boot with?
  9536.        All DOS Versions 3.21 or later. Dual boot does not support
  9537.        earlier versions.
  9538.  
  9539.  
  9540.  281. DLLs and File Handle Requirements
  9541.  
  9542.  Question:
  9543.     How may file handles are required for each DLL? May the DLL be run
  9544.  time or load time?
  9545.     Assuming each DLL will require a file handle, if the process
  9546.  default of file handles is 20, will the system automatically allocate
  9547.  a greater number of file handles if more are needed for DLLS (e.g.
  9548.  when using 100D LLs concurrently)?
  9549.  
  9550.  Response:
  9551.     An open DLL does not use a file handle from the process. A file
  9552.  handle is an index number into a table (one per process) that contains
  9553.  its true system-file number. DLLs are opened and loaded by using a
  9554.  system-file number, i.e., you can load (DosLoadModule) as many DLLs as
  9555.  the system can handle.
  9556.     However, there is one requirement: the process must have at least
  9557.  one file handle available, although it is not used. (A file handle is
  9558.  created out of the system file number to perform a removable media
  9559.  test, and then it is freed. A context switch does not look possible at
  9560.  this point.)
  9561.     Please note that if the file is on removable media or over a
  9562.  network, the code segments are not marked as discardable; they are
  9563.  marked as swappable, which allows the disk to be removed with none of
  9564.  the segments demand loaded out of the EXE file. (They would have been
  9565.  written to the swap file and loaded from there.)
  9566.  
  9567.  
  9568.  282. Application Requests to KBDXLAT Are Not Performed Correctly
  9569.  
  9570.  Question:
  9571.     I am writing an application that takes input from a terminal in the
  9572.  form of make and break codes as per the IBM AT technical reference
  9573.  manual. I would like to use KBDXLAT to convert these to ASCII
  9574.  characters. Are these make/break codes the same as the scan codes
  9575.  KBDXLAT expects to receive? Is the application responsible for keeping
  9576.  track of the make/break on the SHIFT key and setting the SHIFT key
  9577.  status, or will KBDXLAT handle the SHIFT key status itself? This
  9578.  question also applies to the ALT, CTRL, etc. keys.
  9579.  
  9580.  Response:
  9581.     The make/break codes in the IBM technical reference manual are
  9582.  indeed what KBDXLAT expects for input. KBDXLAT will also keep track of
  9583.  SHIFT-state keys for you. However, in researching this question, we
  9584.  have discovered a problem in KBDXLAT that is present in both Version
  9585.  1.00 and Version 1.10 of the Microsoft OS/2SDK. Application requests
  9586.  to KBDXLAT are not being performed independent of the hardware state
  9587.  as they should be; in particular, the XHotKeyShift field in the KBD
  9588.  driver can affect the outcome of application translations, returning
  9589.  inconsistent results to the KBDXLAT caller. This is why KBDXLAT did
  9590.  not appear to be working properly for you.
  9591.     Microsoft has confirmed this to be a problem in Versions 1.00 and
  9592.  1.10. We are researching this problem and will post new information
  9593.  as it becomes available.
  9594.  
  9595.  
  9596.  283. COM1: Device Driver Fix for PS/2 Model 80
  9597.  
  9598.  Question:
  9599.     How do I find the COM01.SYS file that corrects the COM1: problem on
  9600.  my PS/2 Model 80?
  9601.  
  9602.  Response:
  9603.     This file can be found in the Software Library by searching for
  9604.  COM01.ARC, the Q number of this article, or S10023.
  9605.  
  9606.  
  9607.  284. OS/2 SDK: Memory Swap to Disk Information
  9608.  
  9609.  Question:
  9610.  
  9611.  How long does it take to do a memory swap to disk? I would like to
  9612.  know some kind of average time to allocate a segment (and get it ready
  9613.  for a MOV mem,AX operation) that causes a swap to disk to occur.
  9614.  
  9615.  Also, is memory swapped when it is allocated or when it is used, and
  9616.  what will be the limits on the number of segments (shared, unshared,
  9617.  etc.) for Version 1.1 with the Presentation Manager?
  9618.  
  9619.  Response:
  9620.  
  9621.  We do not have any figures on the time to swap to disk for OS/2. When
  9622.  a process requests memory using DosAllocSeg(), DosAllocHuge(), or
  9623.  DosAllocShrSeg(), the compactor may be invoked if a large enough block
  9624.  cannot be found. If moving memory around does not create a large
  9625.  enough block to satisfy the memory request, the swapper will then be
  9626.  invoked, which will swap least recently used segments to disk, growing
  9627.  the swap file if necessary. Data within the swap file itself is not
  9628.  rearranged. Note that whole segments are swapped or moved in the
  9629.  current implementation of OS/2.
  9630.  
  9631.  As far as the system limits are concerned, the following are some
  9632.  figures for OS/2 Version 1.1:
  9633.  
  9634.  1. Approximately 28K swappable segments are allowed system wide.
  9635.  2. Approximately 57K total segments are allowed system wide.
  9636.  3. The limit is still 8K segments total for each process; 6K of these
  9637.     are swappable, 2K are private.
  9638.  
  9639.  
  9640.  285. OS/2 SDK: Support for MS-DOS and Windows
  9641.  
  9642.  Question:
  9643.  
  9644.  My question concerns the Software Development Kit (SDK) for OS/2. Will
  9645.  Microsoft Windows for MS-DOS, and Microsoft language products for
  9646.  MS-DOS continue to be supported?
  9647.  
  9648.  Response:
  9649.  
  9650.  Yes, Microsoft Windows for MS-DOS, and Microsoft Language products for
  9651.  MS-DOS will continue to be supported products from Microsoft. Updates,
  9652.  at Microsoft update prices, will be provided to holders of those
  9653.  products who have complied with the registration requirements. Holders
  9654.  of the Windows Version 1.03 SDK will be updated to Version 2.00.
  9655.  
  9656.  Microsoft OS/2 is a new product. It is a major addition and
  9657.  enhancement to the operating software for personal computers. There is
  9658.  no current Microsoft product that properly qualifies the holder for an
  9659.  update to OS/2. Microsoft has announced that the OS/2 SDK will be
  9660.  available August 1, 1987. The price is $3000, and we are currently
  9661.  taking orders. An OS/2 information kit (including an order form) is
  9662.  available by calling Microsoft's ad response number: (800) 227-4679.
  9663.  
  9664.  
  9665.  286. List of OS/2 Developers and Applications
  9666.  
  9667.  There is a list of OS/2 developers and OS/2 applications that are
  9668.  currently available or have been announced in the Software Library.
  9669.  The file is called OS2APPS.ARC, and can be found in the Software
  9670.  Library by searching for the filename, the Q number of this article,
  9671.  or S12020.
  9672.  
  9673.  
  9674.  287. Placement of MOUSEA02.SYS in CONFIG.SYS in OS/2 SDK
  9675.  
  9676.  Question:
  9677.  
  9678.  The bottom of Page 70 in the "Microsoft Operating System/2 Software
  9679.  Development Kit Setup Guide" states that MOUSEA02.SYS should be
  9680.  installed before the COM.SYS driver. This seems to imply that both
  9681.  drivers are needed to use a serial mouse. Is this true?
  9682.  
  9683.  Response:
  9684.  
  9685.  No, the COM.SYS driver is not required for the serial mouse. However,
  9686.  if you have a serial mouse and also want to use the COM.SYS driver,
  9687.  you should install the mouse driver first; otherwise, the COM.SYS
  9688.  driver will take the interrupts and the mouse driver will not be able
  9689.  to get loaded and initialized.
  9690.  
  9691.  
  9692.  288. Shell Command Problem in CONFIG.SYS File
  9693.  
  9694.  Problem:
  9695.  
  9696.  If the /C switch is specified for the command processor, COMMAND.COM,
  9697.  the 3.x box cannot be entered. The batch file specified by the /C
  9698.  switch is executed, but after it is finished, the following error
  9699.  appears:
  9700.  
  9701.  SYS2064: There is not enough storage to create DOS mode.
  9702.  DOS mode cannot be started.
  9703.  
  9704.  If the /C switch is removed, the 3.x box loads correctly.
  9705.  
  9706.  Response:
  9707.  
  9708.  The COMMAND.COM /C switch allows you to run a secondary command
  9709.  processor long enough to execute a program and then exit back to the
  9710.  primary command processor. In the case of the SHELL statement in your
  9711.  CONFIG.SYS file, it is not appropriate to use the /C switch because
  9712.  the SHELL statement is describing what must be the primary command
  9713.  processor. The system should not give such a vague error when this is
  9714.  done; however, it is being confused by the COMMAND.COM that it started
  9715.  executing for the 3.x box when the system exited suddenly.
  9716.  
  9717.  
  9718.  
  9719.  289. Printing out Size of Free Memory with DosMemAvail
  9720.  
  9721.  Problem:
  9722.  
  9723.  My sample program below fails with the following error when I execute
  9724.  it:
  9725.  
  9726.  The system detected a general protection fault (trap D) in a system
  9727.  call.
  9728.  
  9729.  My sample program is as follows:
  9730.  
  9731.   */
  9732.  
  9733.  #include <stdio.h>
  9734.  #define   INCL_DOS
  9735.  #include <os2.h>
  9736.  
  9737.  main()
  9738.       {
  9739.       PULONG mem_avail;
  9740.       DosMemAvail((PULONG)mem_avail);
  9741.       printf("\nLargest memory block available is %li bytes.",mem_avail);
  9742.       }
  9743.  
  9744.  Response:
  9745.  
  9746.  When using this API, you must provide an area to return the value in.
  9747.  In this case, you were only providing an uninitialized pointer to an
  9748.  area that was outside your memory address space. Since the value
  9749.  returned is an unsigned long integer, it is also important to print it
  9750.  out using the %lu format string of printf. See the following code
  9751.  example for more information:
  9752.  
  9753.   */
  9754.  
  9755.  #include <stdio.h>
  9756.  #define   INCL_DOS
  9757.  #include <os2.h>
  9758.  
  9759.  main()
  9760.     {
  9761.        ULONG mem_avail;
  9762.        DosMemAvail((PULONG) &mem_avail);
  9763.        printf("\nLargest memory block available is %lu bytes.",mem_avail);
  9764.     }
  9765.  
  9766.  
  9767.  
  9768.  290. Using an Interrupt Service Routine to Flag Ring 2 or 3
  9769.  
  9770.  Question:
  9771.  
  9772.  I want to be able to have an Interrupt Service Routine (ISR) in a
  9773.  device driver that will flag a ring 2 or ring 3 thread to get it
  9774.  scheduled again. I have two questions about doing this, as follows:
  9775.  
  9776.  1. It looks to me like the only way to do this is to have the device
  9777.     driver write a value into RAM or a system semaphore, since there
  9778.     doesn't seem to be an equivalent to DosSemSet in the DevHlps. If
  9779.     this is true, what is the semaphore data structure?
  9780.  
  9781.  2. Assuming that my thread is set at the critical highest priority
  9782.     time level and it's blocked on a semaphore that the ISR sets, I
  9783.     think I still have a problem. Won't OS/2 first finish the time
  9784.     slice for the thread that was interrupted (even if it was of lower
  9785.     priority than my thread) before running my thread? If so, can I
  9786.     override this and preempt the current thread?
  9787.  
  9788.  Response:
  9789.  
  9790.  There is a DevHlp to clear a semaphore at interrupt time. It would
  9791.  also be possible to have an application's thread do a generic ioctl
  9792.  call with DosDevIOCtl and have the device driver block that calling
  9793.  thread with a ProcBlock DevHlp. Then when an interrupt comes in,
  9794.  either DevDone or ProcRun could be used to allow the application's
  9795.  thread to be scheduled again. To use a semaphore, it must be a system
  9796.  semaphore.
  9797.  
  9798.  When the thread will be scheduled cannot be guaranteed. In most cases
  9799.  when the ISR completes, the scheduler will be invoked and can schedule
  9800.  the higher priority threads in the system to run. A case where this
  9801.  would not happen is when the interrupted thread is already in the
  9802.  kernel when the interrupt occurs.
  9803.  
  9804.  
  9805.  
  9806.  291. SetIRQ Interrupt Number Information
  9807.  
  9808.  Problem:
  9809.  
  9810.  I have found some inconsistencies in the SetIRQ:Set Hardware Interrupt
  9811.  Handler documentation. The "IBM Operating System/2 Version 1.1
  9812.  Technical Reference: Programming Reference" manual indicates that the
  9813.  interrupt number can range from 0 to 0FH, except for number 2, which
  9814.  is used for cascading the slave 8259 interrupts. It also says that
  9815.  only hardware interrupts can be set.
  9816.  
  9817.  The documentation on Page 358 of the "Microsoft Operating System/2
  9818.  Device Drivers Guide" also indicates that the interrupt number can
  9819.  range from 00H to 0FH, but then says that software interrupt vectors
  9820.  can also be set. It also states that invalid ranges are 08H-0FH,
  9821.  50H-57H, and 70H-77H.
  9822.  
  9823.  Response:
  9824.  
  9825.  Our documentation is incorrect and IBM's documentation is correct. In
  9826.  a future release of our documentation this error will be corrected.
  9827.  Please note that you can't get 0DH, which is the NPX, because the
  9828.  kernel takes that.
  9829.  
  9830.  
  9831.  
  9832.  292. DosFreeModule() Returns Error Code 12
  9833.  
  9834.  Question:
  9835.  
  9836.  When I use the DosFreeModule() function in my program, it returns an
  9837.  error code of 12 (ERROR_INVALID_ACCESS). The error occurs in a C
  9838.  program that loads and calls a Dynamic Linked Library (DLL) created
  9839.  with MicroFocus COBOL. After the module is loaded and a function
  9840.  inside the DLL module is called, the module handle is passed to the
  9841.  DosFreeModule() function. This is when the error occurs. The error
  9842.  does not consistently happen every time this function is called. This
  9843.  error is not documented to my knowledge. What does it mean?
  9844.  
  9845.  Response:
  9846.  
  9847.  Error code 12 will be returned if a routine in the DLL has been added
  9848.  to your exit list. Since the routine is needed by exit list when the
  9849.  the program exits, and calling a routine in a module that has used the
  9850.  DosFreeModule function would cause a general-protection fault, freeing
  9851.  the module that contains the routine is not allowed. The code in the
  9852.  DLL would have to be checked to see if any routines are being added to
  9853.  your exit list. Error code 12 might also be caused by the COBOL run
  9854.  time adding routines to your exit list without your application
  9855.  necessarily knowing about it.
  9856.  
  9857.  
  9858.  
  9859.  293. Get Device Information IOCTL 44H Fails in Compatibility Box
  9860.  
  9861.  There is a problem with running programs compiled and linked using the
  9862.  Turbo C Version 1.50 Compiler in the OS/2 compatibility box. It is due
  9863.  to a difference in the way the MS-DOS Get Device Information IOCTL
  9864.  function call 44H works under OS/2.
  9865.  
  9866.  When run in the compatibility box, the IOCTL Get Device Information
  9867.  function call for the predefined file handles (0-4) does not return
  9868.  the same values as under MS-DOS.
  9869.  
  9870.  This function call returns device information in DX. According to the
  9871.  "Microsoft MS-DOS Version 3.3 Programmer's Reference" on Pages
  9872.  329-330, bit 15 indicates whether the device is a character or block
  9873.  device.
  9874.  
  9875.  When run under MS-DOS for file handles 0-4, bit 15 = 1, indicating
  9876.  that the devices are character devices. When run under OS/2 in the
  9877.  compatibility box, bit 15 = 0. The same is true for IBM OS/2 Standard
  9878.  Edition Version 1.00.
  9879.  
  9880.  This causes a problem for Turbo C because the run-time library
  9881.  function isatty() does an IOCTL Get Device Information function call
  9882.  and does not work correctly under OS/2 for character devices.
  9883.  Unfortunately, any program that calls printf() or scanf() has the
  9884.  potential for not working correctly in the compatibility box because
  9885.  these functions call isatty().
  9886.  
  9887.  The current workaround is not to use Turbo C if you want to run your
  9888.  programs in the compatibility box.
  9889.  
  9890.  Microsoft is researching this problem and will post new information
  9891.  as it becomes available.
  9892.  
  9893.  
  9894.  
  9895.  294. Converting Terminate and Stay Resident Programs to OS/2
  9896.  
  9897.  Question:
  9898.  
  9899.  We plan to convert several terminate-and-stay-resident (TSR) modules
  9900.  that we are currently using under MS-DOS so that they can be used
  9901.  under OS/2 and the 3.x box. Current applications make use of these TSR
  9902.  modules through user-software interrupts. The logical conversion for
  9903.  OS/2 would be in the form of DLL's; however, the 3.x box has no
  9904.  published way to allow the transfer of information to OS/2 for
  9905.  processing. I understand that OS2DOS.COM traps software interrupts,
  9906.  but the actual processing is done by software on the OS/2 side. Is
  9907.  there a way to collect information from a software interrupt in the
  9908.  3.x box and pass that information and function request to OS/2
  9909.  software for processing?
  9910.  
  9911.  Response:
  9912.  
  9913.  You need to do write a bimodal OS/2 device driver and use the
  9914.  SetROMVector DevHlp call to take over a software interrupt. When a 3.x
  9915.  box application issues that software interrupt, your device driver
  9916.  will get control. From that point, you could pass the information to a
  9917.  protected-mode routine through shared memory or some other interprocess
  9918.  communication method.
  9919.  
  9920.  
  9921.  
  9922.  295. Use of Profiler Calls Returns Many Errors
  9923.  
  9924.  Question:
  9925.  
  9926.  The C program below was created using the Microsoft example profile
  9927.  calls. These wrappers were inserted into our code (a large program,
  9928.  using Presentation Manager (PM)) and the error codes shown in the
  9929.  comments were returned. Could you please tell us what the error codes
  9930.  mean and how to stop them from occurring?
  9931.  
  9932.  #include <os2.h>
  9933.  #include <stdio.h>
  9934.  #include <conio.h>
  9935.  #include <profile.h>
  9936.  
  9937.  start_profiling ()
  9938.  
  9939.  {
  9940.  
  9941.    int ec;
  9942.    ec = PROFINIT(PT_USER|PT_USEKP, (char far *)NULL);
  9943.         /* error code == 8 */
  9944.    ec = PROFCLEAR(PT_USER);
  9945.        /* error code == 9 */
  9946.    ec = PROFON(PT_USER);
  9947.        /* error code == 9 */
  9948.  }
  9949.  
  9950.  end_profiling (dumpfile)
  9951.  char *dumpfile;
  9952.  
  9953.  {
  9954.      int ec;
  9955.      ec = PROFOFF(PT_USER);
  9956.           /* error code == 9 */
  9957.      ec = PROFDUMP(PT_USER, (char far *) dumpfile);
  9958.          /* error code == 0 */
  9959.      ec = PROFFREE(PT_USER);
  9960.          /* error code == 0 */
  9961.  }
  9962.  
  9963.  Response:
  9964.  
  9965.  Error code 8 is ERROR_NOT_ENOUGH_MEMORY. Error code 9 on the
  9966.  subsequent call probably occurred because the PROFINIT failed. The
  9967.  error codes returned by the profiling API's are the same as for the
  9968.  other DOSxxx calls, and are defined in the BSEERR.H include file. The
  9969.  particular type of memory being asked for turns out to be "fixed", so
  9970.  it is possible that the system cannot find enough memory available if
  9971.  your PM application is large and your machine does not have much
  9972.  memory on it. You may need more memory for your development machine.
  9973.  
  9974.  Also please verify that you have swapping and memory movement enabled.
  9975.  You need to have "MEMMAN=SWAP,MOVE" in your CONFIG.SYS file (or in
  9976.  CONFIG.OS2 if you have dual-boot) to enable swapping and memory
  9977.  movement.
  9978.  
  9979.  
  9980.  
  9981.  296. GetTextExtent Equivalent in Presentation Manager
  9982.  
  9983.  Question:
  9984.  
  9985.  What is the recommended Presentation Manager method to get the same
  9986.  kind of information that the Windows call GetTextExtent does?
  9987.  
  9988.  Response:
  9989.  
  9990.  The method for obtaining text metrics in Presentation Manager is
  9991.  through the GpiQueryFontMetrics() function.
  9992.  
  9993.  
  9994.  297. PM Dialog Box Editor Hangs in Group Move Mode
  9995.  
  9996.  Problem:
  9997.  
  9998.  After I get into group move mode and move a group of controls, I can't
  9999.  get back out of group move mode. The dialog box editor appears to get
  10000.  hung up in a modal window.
  10001.  
  10002.  Response:
  10003.  
  10004.  Microsoft has confirmed this to be a problem in Version 1.03. This
  10005.  problem was corrected in the Version 1.05 SDK release.
  10006.  
  10007.  The Version 1.05 SDK dialog box editor now works as described in the
  10008.  documentation.
  10009.  
  10010.  
  10011.  298. Unrecognized PS/2 Disk Controller Card
  10012.  
  10013.  Question:
  10014.  
  10015.  When attempting to install Software Development Kit (SDK) Version 1.05
  10016.  on my PS/2 model 70, I receive the following message:
  10017.  
  10018.  Unrecognized PS/2 disk controller card
  10019.  
  10020.  Why am I getting this message?
  10021.  
  10022.  Response:
  10023.  
  10024.  Some PS/2s (including model 70s) have a new ESDI controller. These new
  10025.  controllers have a different ROM ID than the older controllers. The
  10026.  SDK Version 1.05 device driver loader does not recognize this newer ID
  10027.  as valid for PS/2s.
  10028.  
  10029.  There is a patch available that corrects this problem in most PS/2s,
  10030.  except for those that have two ESDI drives. The patch is called
  10031.  PS2105A.ARC and is available in the Software Library. The patch can be
  10032.  found in the Software Library by searching on the filename
  10033.  PS2105A.ARC, the Q number of this article, or S12068.
  10034.  
  10035.  You will need to use the PKXARC utility to unarc the file PS2105A.ARC.
  10036.  
  10037.  
  10038.  299. Using High-Resolution Graphics Programs in the DOS 3.x Box
  10039.  
  10040.  This article describes how an OS/2 real-mode application (running
  10041.  inside the OS/2 DOS compatibility mode or 3.x box) can detect when
  10042.  OS/2 will switch into and out of the 3.x box screen group. It
  10043.  discusses the interface with which an application can obtain this
  10044.  information from OS/2, and what options are available to the
  10045.  application.
  10046.  
  10047.  Screen-Switch Notification
  10048.  
  10049.  OS/2 provides a screen-switch notification mechanism in the 3.x box
  10050.  to support high-performance DOS EGA graphics applications that cannot
  10051.  accept the overhead of the EGA register interface (EGARI).
  10052.  
  10053.  The notification is made by issuing the DOS multiplex interrupt
  10054.  (interrupt 2FH) with AH=40H and AL indicating what kind of screen
  10055.  switch is occurring. AL=01H indicates that the 3.x box is moving into
  10056.  the background; AL=02H indicates that the 3.x box is moving into the
  10057.  foreground.
  10058.  
  10059.  A DOS application that wishes to receive this signal must "hook" the
  10060.  multiplex interrupt vector; i.e., when the application is started, it
  10061.  must save the current interrupt 2FH vector and set the interrupt 2FH
  10062.  vector to point to the application's own multiplex interrupt handler.
  10063.  
  10064.  When an application receives an interrupt 2FH with an unexpected value
  10065.  in AX (in this case, a value other than 4001H or 4002H), the
  10066.  application must do a JMP FAR to the previous interrupt 2FH vector.
  10067.  
  10068.  Since only one DOS application may have control of the screen at a
  10069.  particular instant in time, the proper behavior for an application's
  10070.  interrupt 2FH handler, when it recognizes a screen-switch
  10071.  notification, is to perform its screen switch work and IRET. This
  10072.  approach ensures that only one application is responsible for
  10073.  preserving the screen state.
  10074.  
  10075.  3.x Box Moving Background Notification
  10076.  
  10077.  When OS/2 is making the 3.x box the background screen group, the
  10078.  following sequence of operations is performed:
  10079.  
  10080.  1. Make the 3.x box ineligible for hardware interrupts.
  10081.  
  10082.  2. Perform a "3.x Box Background" notification.
  10083.  
  10084.  3. Interrogate EGARI to save the EGA state (if present).
  10085.  
  10086.  4. Save the video RAM.
  10087.  
  10088.  5. Freeze the 3.x box.
  10089.  
  10090.  To perform "3.x Box Background" notification, OS/2 issues a software
  10091.  interrupt 2FH, with AX=4001H. The application must perform whatever
  10092.  "save" processing it requires and IRET back to OS/2; it need not
  10093.  preserve any registers.
  10094.  
  10095.  This notification may occur at ANY time, including during code where
  10096.  the application is directly programming the EGA. At the point where
  10097.  the notification occurs, the application (other than its interrupt 2FH
  10098.  handler) will not continue execution until the 3.x box is brought into
  10099.  the foreground. If the application has any sections of code that are
  10100.  sensitive to being interrupted in this fashion, the application must
  10101.  either protect the code by doing a CLI/STI, or have the interrupt 2FH
  10102.  handler do appropriate work so that when the "3.x box foreground"
  10103.  notification occurs, the state of the EGA and application can be
  10104.  properly restored.
  10105.  
  10106.  When the notification occurs, the application might do one or more of
  10107.  the following operations:
  10108.  
  10109.  1. Use EGARI calls to set the EGA state for OS/2 to save.
  10110.  
  10111.  2. Save the EGA/application state in private memory.
  10112.  
  10113.  Once notification is complete, the application should be written, if
  10114.  possible, to avoid accessing all video I/O ports and memory until
  10115.  after a foreground notification has been processed, since it may
  10116.  eventually be possible for applications using this interface to
  10117.  continue to run in the background.
  10118.  
  10119.  3.x Box Moving Foreground Notification
  10120.  
  10121.  When OS/2 is making the 3.x box the foreground screen group, the
  10122.  following sequence of operations is performed:
  10123.  
  10124.  1. Thaw (reinstate) the 3.x box.
  10125.  
  10126.  2. Restore video RAM.
  10127.  
  10128.  3. Restore the EGA state (using EGARI information if present).
  10129.  
  10130.  4. Perform a "3.x Box Foreground" notification.
  10131.  
  10132.  5. Make the 3.x box eligible for hardware interrupts.
  10133.  
  10134.  To perform "3.x Box Foreground" notification, OS/2 issues a software
  10135.  interrupt 2FH, with AX=4002H. The application must perform whatever
  10136.  "restore" processing it requires and IRET back to OS/2; it need not
  10137.  preserve any registers.
  10138.  
  10139.  When the notification occurs, the application might do one or more of
  10140.  the following operations:
  10141.  
  10142.  1. Restore the EGA/application state from private memory.
  10143.  
  10144.  2. Do nothing (if EGARI calls were made at "3.x Box Background"
  10145.     notification, EGARI will do the restore).
  10146.  
  10147.  If the application used EGARI calls to set the EGA state at the time
  10148.  of the "3.x Box Background" notification, the application need do
  10149.  nothing when it receives the "3.x Box Foreground" notification.
  10150.  
  10151.  
  10152.  300. #define INCL_DOS Does Not Define INCL_DOSDEVICES in SDK 1.05
  10153.  
  10154.  Question:
  10155.  
  10156.  The documentation states that "#define INCL_DOS" preceding "#include
  10157.  <os2.h>" will get all of the include files in BSEDOS.H. However, upon
  10158.  closer examination, "#define INCL_DOS" is found to define all of the
  10159.  subsequent "INCL_..." statements EXCEPT "INCL_DOSDEVICES", wherein
  10160.  DosDevIOCtl and a few other calls are defined. Is this an error or
  10161.  should "INCL_DOS" define "INCL_DOSDEVICES"?
  10162.  
  10163.  Response:
  10164.  
  10165.  Microsoft has confirmed to be a problem in the BSEDOS.H file of the
  10166.  Version 1.05 OS/2 Software Development Kit. We are researching this
  10167.  problem and will post new information as it becomes available.
  10168.  
  10169.  
  10170.  301. Asych Device Driver and DosDevIOCtl
  10171.  
  10172.  Question:
  10173.  
  10174.  The "Microsoft Operating System/2 Device Drivers Guide" Section 2.4.2,
  10175.  Page 48, paragraph two, reads as follows:
  10176.  
  10177.     Since data is lost when the input queue has no space, programs
  10178.     should use DosDevIOCtl to specify an appropriate input size.
  10179.     Similarly, output queue size should be adjusted for an
  10180.     application's needs. The input queue's default length is 150 bytes;
  10181.     the output queue's default length is 64."
  10182.  
  10183.  I've looked through all of the IOCTL functions and found nothing to
  10184.  adjust the queue size. Could you please tell me where to find this
  10185.  information?
  10186.  
  10187.  Response:
  10188.  
  10189.  An application program cannot change the size of the transmit and
  10190.  receive queues. These queues are owned by the communications device
  10191.  driver. A documentation errata sent with the Version 1.02 SDK
  10192.  discusses the transmit and receive queues on Page 3. However, an
  10193.  application program can query the size of these queues through
  10194.  category 1 function 68h and 69h IOCTLs.
  10195.  
  10196.  
  10197.  302. DosExecPgm() Flag Paramenters: EXEC_LOAD Not Documented
  10198.  
  10199.  Both Page 45 of the "Microsoft Operating System/2 Programmer's
  10200.  Reference Volume 3" for Version 1.10 and QuickHelp incorrectly
  10201.  show only five possible values for the fExecFlags parameter to
  10202.  DosExecPgm(). However, the BSEDOS.H header file correctly shows
  10203.  six possible values, as follows:
  10204.  
  10205.     #define EXEC_SYNC           0
  10206.     #define EXEC_ASYNC          1
  10207.     #define EXEC_ASYNCRESULT    2
  10208.     #define EXEC_TRACE          3
  10209.     #define EXEC_BACKGROUND     4
  10210.     #define EXEC_LOAD           5
  10211.  
  10212.  EXEC_LOAD is not documented anywhere. EXEC_LOAD allows you to load a
  10213.  program into storage and make it ready to execute. This program is not
  10214.  executed until the session manager thaws the process.
  10215.  
  10216.  
  10217.  303. Problem with Using VioPopUp and VioEndPopUp with DosExitList
  10218.  
  10219.  Question:
  10220.  
  10221.  In my test program, once an application has terminated, it is executed
  10222.  using a DosExitList. The test program calls a DosStartSession that
  10223.  begins another session; it operates correctly. The test program then
  10224.  displays a message on the screen using a VioPopUp; this also works
  10225.  correctly. Then to terminate that message, a VioEndPopUp is issued.
  10226.  At this point, the DosExitList is terminated even though there is code
  10227.  following the VioEndPopUp.
  10228.  
  10229.  I also put together another test program that only tests the VioPopUp
  10230.  and VioEndPopUp. The results are still the same; the code after the
  10231.  VioEndPopUp is not executed. Is this a problem in OS/2?
  10232.  
  10233.  Response:
  10234.  
  10235.  Exit-list routines are documented on Page 94 of the "Microsoft
  10236.  Operating System/2 Programmer's Reference" for Version 1.00 as not
  10237.  supporting the functions DosExecPgm and DosCreateThread. This list
  10238.  should also include DosStartSession because it does an implicit
  10239.  DosExecPgm. This is what is happening here.
  10240.  
  10241.  In general, exit-list routines are intended to be as short and as
  10242.  fail-safe as possible. You are not running into a problem with it
  10243.  here, but it would be best if you did not do anything like a VioPopUp.
  10244.  There is a possibility of an exit-list routine not being run if an
  10245.  exit list that you have designed fails or causes an error and has been
  10246.  added by a routine transparently to your application. An example of
  10247.  this is the exit-list routine that is added by the queue's dynamic
  10248.  link library. If this exit list is not run because your application's
  10249.  exit list fails, the system will be left with an orphan queue until
  10250.  the next reboot.
  10251.  
  10252.  VioPopUp is internally executing DosExitList(EXLST_ADD, VioEndPopUp).
  10253.  This is done to allow for the case when VioPopUp is used in a
  10254.  "nonexit" routine. Should the process exit (normally or not) with the
  10255.  pop-up opened, its resources can be freed. In the event that VioPopUp
  10256.  is used in an exit routine, the exit-routine list is modified so that
  10257.  when VioEndPopUp is executed, the system returns to CMD.EXE. Though it
  10258.  is not documented on Page 94 of the programmer's reference as an
  10259.  invalid routine for exit-list routines, it should not be used for this
  10260.  type of routine.
  10261.  
  10262.  In Version 1.05 of the Software Development Kit there is a problem
  10263.  with VioPopUp. After doing a VioPopUp, and ending with a VioEndPopUp,
  10264.  the problem occurs when you attempt to exit back to OS/2. At this
  10265.  point the system appears to hang. What is happening is that the
  10266.  current screen group is hung in such a way that you cannot return to
  10267.  the command prompt and you cannot change screen groups. You must
  10268.  reboot the system to recover from this problem. Microsoft has
  10269.  confirmed this to be a problem in Version 1.05. We are researching
  10270.  this problem and will post new information as it becomes available.
  10271.  
  10272.  If you wish to continue using DosStartSession within an exit routine
  10273.  and have a pop-up to announce the event, you may want to try the
  10274.  following:
  10275.  
  10276.  1. Move the VioPopUp and keyboard I/O into the main routine just prior
  10277.     to the exit.
  10278.  
  10279.  2. Do not insert a VioEndPopUp into your code; let the system take
  10280.     care of it.
  10281.  
  10282.  
  10283.  304. Monochrome VGA Monitor Color Incompatibility: IBM and MS OS/2
  10284.  
  10285.  Question:
  10286.  
  10287.  There is an incompatibility between Microsoft's version of OS/2 and
  10288.  IBM's version of OS/2 when using a monochrome VGA monitor in color
  10289.  mode. The "summed" values that are programmed into the VGA's
  10290.  Digital-To-Analog Controller are not identical.
  10291.  
  10292.  When a VGA monochrome monitor is used in a color mode, the VGA's DAC
  10293.  is programmed with "summed" values, which are calculated with the
  10294.  following formula:
  10295.  
  10296.           30% of the Red Value
  10297.         + 59% of the Green Value
  10298.         + 11% of the Blue Value
  10299.         ------------------------
  10300.              Gray Shade
  10301.  
  10302.  The resulting sum represents one of the 64 gray shades the monochrome
  10303.  monitor can display. The sum is programmed into all three DAC color
  10304.  registers: red, green, and blue, even though the hardware uses only
  10305.  the green value to drive the display.
  10306.  
  10307.  In protected mode under Microsoft OS/2, BVSCALLS.DLL programs the DAC
  10308.  with "summed" values. These values are found in the table "sumregs",
  10309.  located in the source file BVSMODES.INC. In protected mode under IBM
  10310.  OS/2, the DAC is programmed with different values for 12 of the
  10311.  colors. These match IBM's VGA ROM, leading me to believe that ABIOS,
  10312.  instead of the BVS table, is being used by IBM to program the DAC.
  10313.  
  10314.  Why aren't these "summed" values identical?
  10315.  
  10316.  Response:
  10317.  
  10318.  If you test this with IBM OS/2 on an AT and compare it to what is
  10319.  happening on a PS/2, we think you might find that the results will be
  10320.  similar to what you found with our OS/2 and IBM's. We cannot guarantee
  10321.  that what we do on a PS/2 and what IBM does will be identical; what is
  10322.  done on the PS/2 with IBM OS/2 and on an AT with our OS/2 will be
  10323.  different in certain areas.
  10324.  
  10325.  You are correct in assuming that IBM OS/2 on a PS/2 uses the tables in
  10326.  the ABIOS, which causes the differences you are discovering.
  10327.  
  10328.  
  10329.  305. Setting Up a Selector to Access Shared Memory
  10330.  
  10331.  Question:
  10332.  
  10333.  I am trying to use the AllocateGDTSelector and PhysToGDTSelector to
  10334.  set up a selector to access shared memory on an I/O card. I then want
  10335.  to pass this selector to a process, allowing the process to access the
  10336.  shared memory.
  10337.  
  10338.  My device driver fails on one of the above calls, displaying the
  10339.  "internal error processing DevHlp at 1F90.." message. Are these
  10340.  DevHlps supported in Version 1.10 of OS/2? If so, then why does OS/2
  10341.  crash?
  10342.  
  10343.  Response:
  10344.  
  10345.  The DevHlps AllocGDTSelector and PhysToGDTSelector work as documented.
  10346.  These DevHlps are supported in Version 1.10 of OS/2. There is a
  10347.  description of these DevHlps in an archived file named DEVHLP.ARC in
  10348.  the Software library. This file can be found in the Software Library
  10349.  by searching for the filename, the Q number of this article, or
  10350.  S12066. You will need to unarchive the file using the PKXARC utility.
  10351.  
  10352.  If you want to give an access to a portion of shared memory from a
  10353.  device driver, use DevHlp "PhysToUVirt". This DevHlp creates a
  10354.  descriptor in the Local Descriptor Table (LDT) of the current process
  10355.  and returns a selector, which then can be passed to the process using
  10356.  an IOCTL.
  10357.  
  10358.  
  10359.  306. Memory Requirements in OS/2 Version 1.05
  10360.  
  10361.  Question:
  10362.  
  10363.  I am running the OS/2 Software Development Kit (SDK) Version 1.05 on a
  10364.  machine with 4 megabytes of memory. Does it require more memory to run
  10365.  the OS/2 (SDK) Version 1.05 than previous versions of the OS/2 SDK?
  10366.  
  10367.  Response:
  10368.  
  10369.  Yes, the OS/2 SDK Version 1.05 may require more memory than previous
  10370.  SDK's. Recently we have been able to trim things down so that the
  10371.  final version will perhaps be smaller. The following are a few
  10372.  workarounds to help you work within the memory requirements:
  10373.  
  10374.  1. Disable the DOS compatibility box. By doing so, this will save you
  10375.     a considerable amount of memory. Even if you have 4 megabtyes of
  10376.     memory, when you try to run LAN Manager and the Presentation
  10377.     Manager (PM) Shell, and build applications, you can still run out
  10378.     of memory.
  10379.  
  10380.  2. Make sure that swapping is enabled. The system in general will be
  10381.     less responsive if you rely on virtual memory. However, swapping
  10382.     will help other processes that are not used very often.
  10383.  
  10384.  3. Do not install LAN Manager as a server. This takes up more memory
  10385.     and requires a minimum 4 megabytes of memory.
  10386.  
  10387.  4. Remove the PM spooler. To remove the PM spooler do the following:
  10388.  
  10389.     a. Enter the Program Starter from the Presentation Manager.
  10390.  
  10391.     b. Click on "Group".
  10392.  
  10393.     c. Click on "Utility Programs".
  10394.  
  10395.     d. Double click on "Control Panel".
  10396.  
  10397.     e. Click on "Setup".
  10398.  
  10399.     f. Click on "Spooler options".
  10400.  
  10401.     g. Activate the "Spooler is not Selected" box.
  10402.  
  10403.     h. Click on "Enter".
  10404.  
  10405.     i. Exit the Control Panel, answer "Yes" to save prompt.
  10406.  
  10407.     j. Reboot the system.
  10408.  
  10409.  
  10410.  
  10411.  307. Slow Video Input/Output on Compaq Portable IIIs
  10412.  
  10413.  Microsoft OS/2's VIO functions run slowly on Compaq Portable IIIs
  10414.  because the Compaq Portable III uses a gas plasma screen. Microsoft
  10415.  OS/2 screen drivers do not take this into consideration and the output
  10416.  method they use runs slowly on these types of displays.
  10417.  
  10418.  Compaq's release of Microsoft OS/2 includes modified screen drivers
  10419.  that improve video I/O performance on the Compaq Portable III gas
  10420.  plasma display.
  10421.  
  10422.  
  10423.  308. Determining Whether System Is Running Under HPFS or FAT
  10424.  
  10425.  Question:
  10426.  
  10427.  What call can be used in OS/2 to determine whether the system is
  10428.  running under FAT or HPFS?
  10429.  
  10430.  Response:
  10431.  
  10432.  If you use the DosQFSAttach() call, the file system type is returned
  10433.  in the SzFSDName field of the FSQBUFFER structure. The following is a
  10434.  sample program that demonstrates this method:
  10435.  
  10436.  /* be sure to compile with small model! /AS */
  10437.  
  10438.  #define INCL_DOSFILEMGR
  10439.  #define INCL_DOSMEMMGR
  10440.  #define INCL_VIO
  10441.  #include <os2.h>
  10442.  #include <stdio.h>
  10443.  
  10444.  main()
  10445.  {
  10446.    PSZ psz;
  10447.    PUSHORT pcb;
  10448.    USHORT cb;
  10449.    SEL sel;
  10450.    USHORT err;
  10451.    char drvLet[3];
  10452.  
  10453.    if (DosAllocSeg(0x1000, &sel, SEG_NONSHARED))
  10454.      {
  10455.      printf("DosAllocSeg failed!\n");
  10456.      exit(0);
  10457.      }
  10458.    printf("enter drive letter: ");
  10459.    scanf("%2s", &drvLet);
  10460.    drvLet[1] = ':';
  10461.    drvLet[2] = 0;
  10462.    err = DosQFSAttach(drvLet, 0, FSAIL_QUERYNAME, MAKEP(sel,0),
  10463.                        &cb, 0L);
  10464.    if (err)
  10465.      {
  10466.      printf("DosQFSAttach failed, err=%u\n", err);
  10467.      exit(0);
  10468.      }
  10469.    pcb = MAKEP(sel, 2);        /* points to length of device name */
  10470.    psz = MAKEP(sel, 4);        /* points to device name           */
  10471.    VioWrtTTY(psz, *pcb, 0);    /* displays device name            */
  10472.    VioWrtTTY("\r\n", 2, 0);
  10473.    psz += *pcb + 3;            /* adds null character and name-length
  10474.                                    variable                       */
  10475.    pcb = (PUSHORT) (psz - 2);  /* points to length of name        */
  10476.    VioWrtTTY(psz, *pcb, 0);    /* displays file-system name       */
  10477.    VioWrtTTY("\r\n", 2, 0);
  10478.  }
  10479.  
  10480.  
  10481.  309. OS/2 SDK 1.02 PRINT01.SYS Driver Replacement
  10482.  
  10483.  There is a replacement driver for PRINT01.SYS in the Software Library
  10484.  that adds support for the 20 Mhz PS/2 Model 80.
  10485.  
  10486.  This file can be found in the Software Library by searching for the
  10487.  filename PRINT01.ARC, the Q number of this article, or S10058.
  10488.  PRINT01.ARC has been archived with PKARC so you will need to unarchive
  10489.  it with PKXARC. The PKXARC utility is located on your OnLine Utilities
  10490.  Disk 2.
  10491.  
  10492.  
  10493.  310. QuickHelp Documentation Problems
  10494.  
  10495.  There are numerous errors and missing information in QuickHelp. Some
  10496.  of these problems are as follows:
  10497.  
  10498.  1. DosStartSession is incorrectly documented.
  10499.  
  10500.  2. There is no information on named pipes.
  10501.  
  10502.  3. DosMonRead still has the DCWW_xxxx values (and has them
  10503.     _backwards_).
  10504.  
  10505.  4. There is no information on monitor packet formats.
  10506.  
  10507.  Microsoft has confirmed these problems in Version 1.10. We are
  10508.  researching these problems and will post new information as as it
  10509.  becomes available.
  10510.  
  10511.  
  10512.  
  10513.  311. OS/2 SDK QuickHelp Documentation Suggestion
  10514.  
  10515.  Question:
  10516.  
  10517.  Is there any way of getting either a different version of QuickHelp or
  10518.  an update to the documentation that has things written from an
  10519.  assembler programmer's point of view?
  10520.  
  10521.  The C format of the OS/2 function description is very difficult to
  10522.  read. All the data types and return codes are in symbolic notation,
  10523.  and there is no reference as to what the symbols stand for.
  10524.  
  10525.  The first set of documentation had everything in terms of there actual
  10526.  integer value; this documentation was much more readable.
  10527.  
  10528.  Response:
  10529.  
  10530.  At this time, there is only one version of QuickHelp available and
  10531.  there is no update to the documentation available that references
  10532.  Assembly language as opposed to the C language.
  10533.  
  10534.  This feature is under review and will be considered for inclusion in a
  10535.  future release.
  10536.  
  10537.  
  10538.  
  10539.  312. Compilation Problems Due to Use of Wrong Include File
  10540.  
  10541.  The "#include <pm.h>" statement used to be the last line in the OS2.H
  10542.  file but is now commented out in the Version 1.05 Software Development
  10543.  Kit (SDK). If you use the OS2.H file without the "#include <pm.h>"
  10544.  statement commented out, it resolves the original problem (i.e.,
  10545.  compile error C2054) but still does not allow compilation. When using
  10546.  the OS2.H file with the "#include <pm.h>" statement commented out, the
  10547.  following error appears when you try to run MAKE on the sample HELLO.C
  10548.  program:
  10549.  
  10550.  MAKE HELLO > ERR
  10551.  
  10552.  This error produces the following:
  10553.  
  10554.  Microsoft (R) Program Maintenance Utility Version 4.07
  10555.  Copyright (C) Microsoft Corp 1984-1988. All rights reserved.
  10556.  
  10557.    cl -c -W3 -AS -G2sw -Os -Zpei hello.c
  10558.  
  10559.  hello.c
  10560.  C:/pmsdk/include/pmwin.h(215) : warning C4074: non standard extension
  10561.    used -'trailing ',' used for variable argument list'
  10562.  C:/pmsdk/include/pmwin.h(215) : error C2061: syntax error : identifier
  10563.    'PRECTL'
  10564.  C:/pmsdk/include/pmwin.h(215) : fatal error C1022: expected '#endif'
  10565.  
  10566.  The symptoms described indicate that old versions of the include files
  10567.  are still being found. You have to make sure that you do not use the
  10568.  OS2.H file that comes with the C compiler. It is this copy of the
  10569.  include file that has the line "#include <pm.h>" commented out in it.
  10570.  The copy of OS2.H that came with the Version 1.05 Software Development
  10571.  Kit (SDK) should not have this line commented out in it.
  10572.  
  10573.  We suggest that you use the WHERE utility and find all copies of the
  10574.  following files:
  10575.  
  10576.     OS2.H
  10577.     OS2DEF.H
  10578.  
  10579.  You should then replace the older versions of these files with the
  10580.  versions that came with the SDK.
  10581.  
  10582.  
  10583.  
  10584.  313. HELLO.C Returns C2054: Expected '(' to Follow 'MRESULT' Error
  10585.  
  10586.  Problem:
  10587.  
  10588.  Using the OS/2 Software Development Kit (SDK) Version 1.05 I cannot
  10589.  compile most of the sample programs, or the Petzold sample code. On
  10590.  the sample program HELLO.C I receive an error "C2054: expected '(' to
  10591.  follow 'MRESULT'". On the Petzold sample programs I receive the error
  10592.  "C4071: 'WinInitialize': no function prototype given".
  10593.  
  10594.  Response:
  10595.  
  10596.  The errors you are receiving indicate that you have not included the
  10597.  correct include file. MRESULT is typedef'ed in PMWIN.H to be a far
  10598.  pointer. If the typedef for MRESULT is not found, the compiler assumes
  10599.  that you are making a function declaration, and you get the error
  10600.  about the missing '('. You will need to make sure that you have
  10601.  everything configured correctly so that the most current versions of
  10602.  the include files are being found along your include environment
  10603.  variable.
  10604.  
  10605.  Also, make sure that you are using the correct version of the include
  10606.  file OS2.H. The one that comes with the OS/2 SDK Version 1.05 includes
  10607.  the following extra statement which was not present in the OS2.H file
  10608.  that came with the C compiler, or with the SDK Version 1.03:
  10609.  
  10610.     #include <pm.h>
  10611.  
  10612.  
  10613.  314. QuickHelp Returns Invalid Error of "qh.hlp Already Open"
  10614.  
  10615.  After trying to access QuickHelp, a "qh.hlp already open" message
  10616.  appears when the QH environment variable is set using OS2INIT.CMD with
  10617.  the following statement in a new screen group:
  10618.  
  10619.    set QH=c:\pmsdk\pbin +50
  10620.  
  10621.  When a key is pressed to continue, a protection violation (trap 13)
  10622.  occurs. Starting QuickHelp with the command: qh +50 seems to work
  10623.  correctly.
  10624.  
  10625.  Microsoft has confirmed this to be a problem with the QuickHelp
  10626.  shipped with the OS/2 Software Development Kit (SDK) Version 1.05. We
  10627.  are researching this problem and will post new information as it
  10628.  becomes available.
  10629.  
  10630.  
  10631.  315. VGA Support under OS/2 and C Compiler Version 5.10
  10632.  
  10633.  The following are questions and answers regarding VGA support under
  10634.  OS/2 and C Compiler Version 5.10.
  10635.  
  10636.  1. Does OS/2 include a driver for VGA support, or is it up to the VGA
  10637.     manufacturer to supply one?
  10638.  
  10639.     Yes, OS/2 does provide support for the VGA card.
  10640.  
  10641.  2. Will the C Compiler Version 5.10 graphic functions work with VGA or
  10642.     any graphic display device in OS/2 protected mode?
  10643.  
  10644.     The C Compiler Version 5.10 graphics functions (i.e.,
  10645.     _setvideomode, _rectangle, etc.) are not supported in protected
  10646.     mode. They do work in the DOS compatibility box.
  10647.  
  10648.  3. Can a VGA and a monochrome display be present at the same time, and
  10649.     will the new OS/2 Presentation Manager use the VGA and allow the
  10650.     monochrome to be used for dual booting of MS-DOS?
  10651.  
  10652.     Whatever video configuration you have set up as the primary one is
  10653.     the one that will be used for both real mode and protected mode. In
  10654.     other words, if you have the VGA set up as the primary display, the
  10655.     dual-boot feature will use this as the default adapter when you go
  10656.     into either the OS/2 protected mode or the MS-DOS real mode. It
  10657.     will not use the VGA as the primary for OS/2 and monochrome as the
  10658.     primary for MS-DOS.
  10659.  
  10660.  
  10661.  316. Multi-Thread Programming Hints
  10662.  
  10663.  The THREADS.C example states that a thread should terminate with a
  10664.  DosExit() call or unpredictable results can occur. The documentation
  10665.  and QuickHelp program indicate that a thread terminates when the
  10666.  function returns or calls the DosExit function.
  10667.  
  10668.  The following are questions regarding this information:
  10669.  
  10670.  1. Is it possible for a thread to "know" that it is running as a
  10671.     thread and not as a function?
  10672.  
  10673.  2. There appears to be a conflict between the THREADS.C example and
  10674.     the documentation. Is the DosExit function required in a thread?
  10675.  
  10676.  The example that you are referring to is not completely correct. The
  10677.  original version of this example was created some time ago and is
  10678.  somewhat misleading.
  10679.  
  10680.  Several things have changed. It is no longer a problem to use the C
  10681.  run time for multi-threaded programs. You can create multi-threaded
  10682.  programs using one of a couple of libraries available with the
  10683.  C Compiler Version 5.10. For complete details on creating multi-threaded
  10684.  programs using the new C run time, refer to the MTDYNA.DOC file that
  10685.  comes with the C Compiler package.
  10686.  
  10687.  In the MTDYNA.DOC file, note that it is recommended that you use the new
  10688.  run-time functions _beginthread and _endthread to start and end your
  10689.  threads instead of the OS/2 calls DosCreateThread and DosExit, because
  10690.  there is some initialization that is done for each thread.
  10691.  
  10692.  If you choose to use the method described in the example THREADS.C, it
  10693.  is not necessary to explicitly exit the thread with DosExit, although
  10694.  it is recommended.
  10695.  
  10696.  As for identifying whether you are a thread or a function, a call to
  10697.  the function DosGetPid will return the thread id (TID). If you are in
  10698.  the main program, your thread identification will always be one under
  10699.  the current release of OS/2.
  10700.  
  10701.  If you are running a thread that is not the main thread, it will have
  10702.  a different thread identification. We do not recommend that you depend
  10703.  on the TID of the main program being one. If it is necessary for you
  10704.  to see if you are in the main thread or in a separate thread, call
  10705.  DosGetPid from the main thread and store the thread identification in
  10706.  a global variable. If you are in a function and the value returned by
  10707.  DosGetPid is not the same as that returned when in the main function,
  10708.  then you are executing as a thread.
  10709.  
  10710.  
  10711.  317. 32 Thread Limitation when Using C 5.00 Run-Time Library
  10712.  
  10713.  Question:
  10714.  
  10715.  What happens if I need more than the 32 threads that are supported by
  10716.  Version 5.00 of the C run-time library to be used with multithreaded
  10717.  programs?
  10718.  
  10719.  Response:
  10720.  
  10721.  The limitation of 32 threads is considerably over the recommended
  10722.  maximum per process (of 12) and is a fairly reasonable limit. There
  10723.  are no plans at this time to change this limit.
  10724.  
  10725.  If you don't use the C run-time library, you can create more than 32
  10726.  threads per process with the DosCreateThread() function call. The
  10727.  current process limit is about 52. This limit is version dependent and
  10728.  is subject to change.
  10729.  
  10730.  
  10731.  318. Moving the Mouse Cursor Causes Exception Error
  10732.  
  10733.  If the "device=c:\os2\dev\pointdd.sys" line in the OS/2 CONFIG.SYS
  10734.  file is not present or is remarked out (REM appears at the beginning
  10735.  of the line), the following error may occur when you attempt to move
  10736.  the mouse after the system has finished booting:
  10737.  
  10738.                      TRAP 000
  10739.                      AX=0010 ...
  10740.                         .
  10741.                         .
  10742.                         .
  10743.     Exception Error in device driver MOUSE$
  10744.     The system detected an internal processing error
  10745.     at location #00B0:084E
  10746.     Exception while in kernel mode
  10747.  
  10748.  To correct this problem, remove the REM statement from the line
  10749.  "device=c:\os2\dev\pointdd.sys" or insert the line if it is not
  10750.  present.
  10751.  
  10752.  
  10753.  319. Writing a Signal Handler to Capture Keyboard Input
  10754.  
  10755.  Question:
  10756.  
  10757.  I have written a signal handler to capture CTRL+BREAK. KbdCharIn
  10758.  correctly indicates that an error occurs by returning a positive
  10759.  value. However, if I issue a KbdCharIn immediately after the
  10760.  CTRL+BREAK has been handled by my handler routine, the return value
  10761.  indicates that the read was successful (zero is returned) but the
  10762.  character that is returned has a scan code of zero (0). Is this
  10763.  expected behavior, and how should I handle this?
  10764.  
  10765.  Response:
  10766.  
  10767.  It is expected behavior; you need to flush the keyboard buffer after
  10768.  receiving a CTRL+BREAK. One way to accomplish this is to use the
  10769.  function KbdFlush either in your handler function or whenever
  10770.  KbdCharIn returns an error value.
  10771.  
  10772.  Below is a sample program that takes input from the keyboard and
  10773.  echoes it back. If you press CTRL+BREAK, the handler is called and
  10774.  prints out a message. If you do not put the KbdFlushBuffer(hkbd)
  10775.  call in the "do...while" loop, KbdCharIn will pick up a character
  10776.  from the buffer that has a scan code of zero. The KbdFlushBuffer
  10777.  call could also be put into the handler if you chose to do it
  10778.  that way instead.
  10779.  
  10780.  The sample program is as follows:
  10781.  
  10782.  #include <stdio.h>
  10783.  #define INCL_BASE
  10784.  #include <os2.h>
  10785.  
  10786.  void pascal far ctrlBreakHandler(USHORT usSigArg, USHORT usSigNum);
  10787.  
  10788.  int main(int argc, char **argv)
  10789.  {
  10790.       KBDINFO kbstInfo;
  10791.       KBDKEYINFO kbciKey;
  10792.       HKBD hkbd;
  10793.       USHORT rc;
  10794.       PFNSIGHANDLER FAR *prevCtrlBreakHandler;
  10795.       USHORT prevAction;
  10796.  
  10797.       printf("Hello, World!\n");
  10798.  
  10799.       rc = KbdOpen(&hkbd);
  10800.       printf("KbdOpen rc %d   hkbd %d\n", rc, hkbd);
  10801.  
  10802.       rc = KbdGetFocus(IO_WAIT, hkbd);
  10803.       printf("KbdGetFocus rc %d\n", rc);
  10804.  
  10805.       kbstInfo.cb = sizeof(kbstInfo);
  10806.       rc = KbdGetStatus(&kbstInfo, hkbd);
  10807.       printf("KbdGetStatus rc %d\n", rc);
  10808.       /* mask cooked bit, set raw bit */
  10809.       kbstInfo.fsMask = (kbstInfo.fsMask & 0x00F7) | 0x004;
  10810.       rc = KbdSetStatus(&kbstInfo, hkbd);
  10811.       printf("KbdSetStatus rc %d\n", rc);
  10812.  
  10813.       rc = DosSetSigHandler(0L, 0L, 0L, SIGA_ERROR, SIG_PFLG_A);
  10814.       printf("DosSetSigHandler disallow PFLG_A rc %d\n", rc);
  10815.       rc = DosSetSigHandler(ctrlBreakHandler, prevCtrlBreakHandler,
  10816.            &prevAction, SIGA_ACCEPT, SIG_CTRLBREAK);
  10817.       printf("DosSetSigHandler rc %d   prevAction %d   prevCtrlBreakHandler
  10818.            %p\n", rc, prevAction, prevCtrlBreakHandler);
  10819.  
  10820.       kbciKey.chChar = ' ';
  10821.       while('A' != kbciKey.chChar)
  10822.       {
  10823.            do {
  10824.                 if (rc)
  10825.                  KbdFlushBuffer(hkbd);
  10826.                 rc = KbdCharIn(&kbciKey, IO_WAIT, hkbd);
  10827.  
  10828.            } while(ERROR_INTERRUPT == rc);
  10829.            printf("rc %d   char:%d   scan:%d\n",
  10830.                 rc, kbciKey.chChar, kbciKey.chScan);
  10831.            if(0 != rc)
  10832.                 break;
  10833.       }
  10834.       rc = KbdClose(hkbd);
  10835.       printf("KbdClose rc %d\n", rc);
  10836.  }
  10837.  
  10838.  void pascal far ctrlBreakHandler(USHORT usSigArg, USHORT usSigNum)
  10839.  {
  10840.       PFNSIGHANDLER FAR *prevCtrlBreakHandler;
  10841.       USHORT prevAction, rc;
  10842.  
  10843.       printf("ctrlBreakHandler usSigArg %u   usSigNum %u\n",
  10844.            usSigArg, usSigNum);
  10845.       rc = DosSetSigHandler(ctrlBreakHandler, prevCtrlBreakHandler,
  10846.            &prevAction, SIGA_ACCEPT, SIG_CTRLBREAK);
  10847.       printf("reset DosSetSigHandler rc %d   prevAction %d
  10848.              prevCtrlBreakHandler %p\n", rc, prevAction,
  10849.              prevCtrlBreakHandler);
  10850.  }
  10851.  
  10852.  
  10853.  320. INSTALL.TXT Is an ASCII Version of Word Document INSTALL.DOC
  10854.  
  10855.  In the Microsoft OS/2 Software Development Kit (SDK) Version 1.05, the
  10856.  file INSTALL.DOC is a Microsoft Word document, not an ASCII text
  10857.  document. An ASCII version of this document is located in the file
  10858.  INSTALL.TXT. Both of these files are located on the INSTALL disk.
  10859.  
  10860.  
  10861.  321. Program Doesn't Run in 1.05 Because Include Files Not Updated
  10862.  
  10863.  Question:
  10864.  
  10865.  Some of my programs that were working correctly under Version 1.03 of
  10866.  the OS/2 SDK Presentation Manager no longer run under Version 1.05.
  10867.  When I checked the \include subdirectory in Version 1.05, I saw that
  10868.  it contains revised files; however, I didn't see any revised files in
  10869.  the \include\mt subdirectory for Version 1.05. Could this be part of
  10870.  the problem?
  10871.  
  10872.  Response:
  10873.  
  10874.  Microsoft has confirmed this to be a problem in Version 1.05. We are
  10875.  researching this problem and will post new information as it becomes
  10876.  available.
  10877.  
  10878.  As you discovered, there is a problem in the OS/2 Software Development
  10879.  Kit (SDK) Version 1.05 Install program. It did not update the OS/2
  10880.  include files in the \include\mt subdirectory.
  10881.  
  10882.  To correct this problem, copy the OS/2-specific files that were
  10883.  updated from the \include subdirectory into the \include\mt
  10884.  subdirectory. Please note that you should not copy the regular C
  10885.  include files.
  10886.  
  10887.  
  10888.  322. OS/2 SDK 1.03 Spool Files Cause 1.05 to Hang after 10 Seconds
  10889.  
  10890.  Problem:
  10891.  
  10892.  After booting from the floppy disk, everything appears to be correct
  10893.  and the screen ends up with a CMD.EXE window in the upper-left, which
  10894.  is overlaid in the center with a Program Starter window with icons for
  10895.  MS-DOS and the print spooler at the lower left, and a black sunburst
  10896.  at the lower right. After the above screen is displayed and a period
  10897.  of about 10 seconds passes, a beep sounds and a pop-up box appears.
  10898.  The pop-up looks like an example template, and across the top it says
  10899.  "Problem Caption" and below that it says "Problem Text", with buttons
  10900.  for "retry" and "cancel" at the bottom. I am unable to either retry or
  10901.  cancel because the system is hung at this point. I can press ALT+ESC
  10902.  to the get to the 3.x compatibility box, where everything seems
  10903.  correct, and then return to Presentation Manager (PM), where the
  10904.  system is still hung. In the 10-second period before the beep and
  10905.  pop-up box, the PM seems functional; if I press the F1 key, help is
  10906.  displayed, the cursor up/down arrow keys move the selected line in the
  10907.  Program Starter window, and so on.
  10908.  
  10909.  Response:
  10910.  
  10911.  The spool files created from the OS/2 SDK Version 1.03 are causing the
  10912.  system to display this error and hang up. To correct this problem,
  10913.  reboot the system and delete all the old spool files in the c:\spool
  10914.  subdirectory while running MS-DOS.
  10915.  
  10916.  Microsoft has confirmed this to be a problem in Version 1.03. We are
  10917.  researching this problem and will post new information as it becomes
  10918.  available.
  10919.  
  10920.  
  10921.  323. DosR2StackRealloc Defined in Different Library in 1.05 SDK
  10922.  
  10923.  Problem:
  10924.  
  10925.  In the OS/2 Software Development Kit (SDK) Version 1.05, what library
  10926.  is DosR2StackRealloc defined in? It used to be defined in the
  10927.  DOSCALLS.LIB library, but it no longer is.
  10928.  
  10929.  Response:
  10930.  
  10931.  This function, along with other new Version 1.10 functions, is now
  10932.  defined in a file named OS2.LIB. The OS2.LIB file is the OS/2 Version
  10933.  1.10 replacement library for the DOSCALLS.LIB library.
  10934.  
  10935.  
  10936.  324. Passing Addresses with DosWriteQueue Function in OS/2
  10937.  
  10938.  Question:
  10939.  
  10940.  On Page 257 in the "Microsoft Operating System/2 Software Development
  10941.  Kit Programmer's Reference" Version 1.00 manual is the following
  10942.  example that demonstrates the usage of the DosWriteQueue function
  10943.  call:
  10944.  
  10945.     DosWriteQueue(handle, 0, 11, "Hello World",0);
  10946.  
  10947.  Does the address of the string get passed, or the string itself? Also,
  10948.  if another process tries to use that address, will it generate a
  10949.  general protection (GP) fault?
  10950.  
  10951.  Response:
  10952.  
  10953.  In the sample piece of code, it is the address of the string that gets
  10954.  passed. If another process uses this address, which is actually a
  10955.  selector, it will not necessarily cause a GP fault, nor will it point
  10956.  to the string. This is because each process has its own set of
  10957.  descriptors (located in the LDT). For example, consider the following:
  10958.  
  10959.     Process A has its own LDT. In Process A's LDT, descriptor number 1
  10960.     points to the physical address 100.
  10961.  
  10962.     Process B has its own LDT. In Process B's LDT, descriptor number 1
  10963.     points to the physical address 200.
  10964.  
  10965.     Each process can legally have the selector value of 1 (remember, a
  10966.     selector points to the descriptor contained in the current
  10967.     process's LDT). However, while each may have the selector value of
  10968.     1, this selector points to a different descriptor. Since each
  10969.     descriptor points to a different physical address, the values
  10970.     obtained will be different.
  10971.  
  10972.  DosWriteQueue has access to the process's LDT that called it. When you
  10973.  pass in your selector, DosWriteQueue uses the selector to point to the
  10974.  descriptor in your LDT. This way DosWriteQueue is sure to obtain the
  10975.  correct data. As mentioned above, this may or may not cause a GP
  10976.  fault. Consider the following example:
  10977.  
  10978.     If Process A's LDT has 30 descriptors in it, its selectors can be
  10979.     in the range of 1-30.
  10980.  
  10981.     If Process B's LDT has 20 descriptors in it, its selectors can be
  10982.     in the range of 1-20.
  10983.  
  10984.     If Process B gets any of Process A's selectors that are above 20
  10985.     and tries to use them, this will generate a GP fault because the
  10986.     CPU "knows" Process B has only 20 descriptors.
  10987.  
  10988.  If Process B must access data in Process A, Process A must set up
  10989.  some sort of shared memory. The selector for this shared memory will
  10990.  then be valid for both Process A and Process B. This situation is
  10991.  discussed starting at the middle of Page 165 in the book "Inside OS/2"
  10992.  by Gordon Letwin. This section reads as follows:
  10993.  
  10994.     "Thus, the data body of the queue message must be addressable to
  10995.     both the client and the serving process. This is straightforward if
  10996.     both the client and serving threads belong to the same process
  10997.     (because they both automatically use the same LDT). If the client
  10998.     and serving threads are from different processes, however, the data
  10999.     body of the queue message must be in a shared memory segment that
  11000.     is addressable to both the client and the server."
  11001.  
  11002.  The book then describes how to use memory suballocation to work around
  11003.  this situation.
  11004.  
  11005.  
  11006.  325. Allocating Huge Blocks of Shared Memory with DosAllocSeg
  11007.  
  11008.  Question:
  11009.  
  11010.  The documentation on Pages 48 and 52 of the "Microsoft Operating
  11011.  System/2 Software Development Kit Programmer's Reference" for Version
  11012.  1.00 states that the function calls DosAllocHuge and DosAllocSeg can
  11013.  allocate shared memory using either the DosGiveSeg or the DosGetSeg
  11014.  function calls. For DosAllocSeg, this translates to one segment at a
  11015.  time. I have the following questions about sharing memory:
  11016.  
  11017.  1. What happens (or should happen) if a huge block of memory is
  11018.     shared?
  11019.  
  11020.  2. Does it have to be shared one segment at a time?
  11021.  
  11022.  3. If the base selector is passed, can the receiving process use the
  11023.     entire huge block?
  11024.  
  11025.  4. Is there an advantage to suballocating a huge block of memory in
  11026.     this way?
  11027.  
  11028.  Response:
  11029.  
  11030.  The following are answers to your questions:
  11031.  
  11032.  1. If a huge block is shared, all segments of it are shared.
  11033.  
  11034.  2. It does not have to be shared one segment at a time.
  11035.  
  11036.  3. Yes, if the base selector is passed, the other process can use
  11037.     the whole block.
  11038.  
  11039.  4. One advantage of suballocating a huge block of memory this way
  11040.     is that the process can reference the segment the same way it
  11041.     would reference a huge block that it had allocated for itself,
  11042.     after it has, of course, been given addressability to the block
  11043.     by the sending process.
  11044.  
  11045.  
  11046.  326. OS/2 SDK 1.05 Linker Doesn't Accept /NOE Switch
  11047.  
  11048.  Problem:
  11049.  
  11050.  The new linker (Version 1.10) shipped with the Version 1.05 OS/2
  11051.  Software Development Kit (SDK) no longer supports the /NOE switch.
  11052.  
  11053.  Response:
  11054.  
  11055.  The linker shipped with the OS/2 SDK Version 1.05 is a stripped-down
  11056.  version of the one we provide with our languages. We recommend that
  11057.  you use the linker from the OS/2 SDK Version 1.03 release if you need
  11058.  to use the /NOE switch.
  11059.  
  11060.  
  11061.  327. Control Panel Doesn't Work from Command Line in OS/2 SDK
  11062.  
  11063.  Question:
  11064.  
  11065.  How do I get the Control Panel (PMCPL.EXE) to run from the command
  11066.  line? When I run it, nothing happens. It seems to go through some
  11067.  motions and then the window title reads "Completed."
  11068.  
  11069.  Response:
  11070.  
  11071.  In the OS/2 Software Development Kit (SDK) Version 1.05, the Control
  11072.  Panel does not function when run from the command line.
  11073.  
  11074.  Microsoft has confirmed this to be a problem in Version 1.05. We are
  11075.  researching this problem and will post new information as it becomes
  11076.  available.
  11077.  
  11078.  In the meantime, you should just run the Control Panel from the
  11079.  Utility Programs group in the Program Starter by doing the following:
  11080.  
  11081.  1. Go to the Program Starter window.
  11082.  
  11083.  2. Click Group.
  11084.  
  11085.  3. Select Utility Programs.
  11086.  
  11087.  The Control Panel should be the first entry in the list.
  11088.  
  11089.  
  11090.  328. Support for COM Port 3 in OS/2 SDK
  11091.  
  11092.  The Microsoft OS/2 Software Development Kit (SDK) does not have a
  11093.  driver for the third communications port that is unique to IBM's PS/2;
  11094.  however, the retail version of IBM's OS/2 will have support for this
  11095.  port.
  11096.  
  11097.  
  11098.  329. Taking Advantage of Enhanced EGA or VGA Support
  11099.  
  11100.  The version of Presentation Manager (PM) shipped with the Version 1.03
  11101.  OS/2 Software Development Kit (SDK) supports the EGA in a 640 x 350
  11102.  16-color mode and the VGA in a 640 x 480 16-color mode. The
  11103.  instructions for setting up PM for the VGA are included in the
  11104.  INSTALL.DOC file. Version 1.05 of the OS/2 SDK prompts for display
  11105.  type during installation. These two display modes are still the only
  11106.  ones supported. Device driver kits (beta versions) are now being
  11107.  released to hardware manufactures to bring wider device support to PM.
  11108.  
  11109.  
  11110.  330. Capturing Mouse Events in Graphics Mode
  11111.  
  11112.  Problem:
  11113.  
  11114.  We are trying to use MouReadEventQue() to capture mouse events.
  11115.  Everything works properly in text mode, but when we set the mode to
  11116.  graphics, we no longer receive mouse events. The following is an
  11117.  outline of the program:
  11118.  
  11119.        .
  11120.        .
  11121.        .
  11122.  
  11123.   VioSetMode(&viom,0))
  11124.   MouOpen(0L,&hmou);
  11125.   mevent = 0x0100;
  11126.   MouSetDevStatus(&mevent,hmou);
  11127.   mevent = MOU_BUTTON1_MASK;
  11128.   MouSetEventMask(&mevent,hmou);
  11129.  
  11130.   while(count < 10)
  11131.   {
  11132.   MouReadEventQue(&mouevent,&fWait,hmou);
  11133.  
  11134.    if (mouevent.fs)
  11135.        {
  11136.            DosBeep(600,150L);
  11137.        }
  11138.    }
  11139.  
  11140.    VioSetMode(&oldmode,0);
  11141.        .
  11142.        .
  11143.        .
  11144.  
  11145.  Response:
  11146.  
  11147.  You can get events from the mouse in graphics mode, but you need to be
  11148.  sure that you open the mouse and set the device status before you set
  11149.  the video mode. Changing the above code so that the MOU calls are
  11150.  before the VIO calls will correct the problem.
  11151.  
  11152.  
  11153.  331. Trouble Setting Border Color (Overscan) with EGA
  11154.  
  11155.  Problem:
  11156.  
  11157.  I am using OS/2 with an EGA and I am trying to set the border color
  11158.  using VioSetState(). When I do this, the error status 421 (invalid
  11159.  parm) is returned. The following is a copy of my program:
  11160.  
  11161.  main ()
  11162.    {
  11163.      struct _VIOINTENSITY request1;
  11164.      struct _VIOOVERSCAN request;
  11165.      int status;
  11166.  
  11167.      request.cb = sizeof request;
  11168.      request.type=1;
  11169.      request.color=0x10;
  11170.      status = VioSetState(&request, 0);
  11171.      if (status)
  11172.       printf ("Set border failed. Status=%i", status);
  11173.  
  11174.     }
  11175.  
  11176.  Response:
  11177.  
  11178.  Setting the border (overscan) color is only legal for CGA, VGA, or IBM
  11179.  PS/2 display adapters.
  11180.  
  11181.  
  11182.  332. OS/2 SDK: MARKEXE Returns Fatal Error U1013
  11183.  
  11184.  Question:
  11185.  
  11186.  When I use MARKEXE.EXE in a MAKE file, it returns fatal error U1013
  11187.  even though it successfully marked the .EXE file. Why does MARKEXE.EXE
  11188.  return this error?
  11189.  
  11190.  Response:
  11191.  
  11192.  MARKEXE.EXE does not initialize a return value upon completion. This
  11193.  causes other programs that expect a return value (such as MAKE) to
  11194.  incorrectly state that an error has occurred. If you invoke MAKE with
  11195.  the /I option (see Page 312, Section 14.5 of the "Microsoft CodeView
  11196.  and Utilities Software Development Tools for the MS-DOS Operating
  11197.  System" manual for Version 5.10), MAKE will ignore all exit codes
  11198.  returned by programs called from within the MAKE descriptions.
  11199.  
  11200.  
  11201.  333. Unable to Get Shifted Characters from within PM Shell
  11202.  
  11203.  Problem:
  11204.  
  11205.  In Version 1.05 of the OS/2 Software Development Kit (SDK), if you
  11206.  start up the DOS compatibility box from the Presentation Manager (PM)
  11207.  Shell and then attempt to run a PM program from within PM, such as
  11208.  Petzold's Typer program, you can no longer get shifted characters when
  11209.  you type.
  11210.  
  11211.  Response:
  11212.  
  11213.  Microsoft has confirmed this to be a problem in Version 1.05. This
  11214.  problem was corrected in Version 1.06 of the OS/2 SDK.
  11215.  
  11216.  
  11217.  334. Memory and Display Requirements for OS/2 1.10 Final Release
  11218.  
  11219.  Question:
  11220.  
  11221.  What will the memory and display adapter requirements be in the final
  11222.  release of OS/2 Version 1.10? Also, will the Program Selector Shell
  11223.  from the OS/2 Software Development Kit (SDK) Version 1.03 be supported
  11224.  in the final release of Version 1.10?
  11225.  
  11226.  Response:
  11227.  
  11228.  The final release of OS/2 Version 1.10 will require from 3 to 3.5
  11229.  megabytes of memory. It will only support EGA and VGA graphics cards.
  11230.  
  11231.  The Program Selector Shell from Version 1.03 will not be supported in
  11232.  the final release of OS/2 Version 1.10. The only shell that will be
  11233.  supported is the Presentation Manager graphics-based shell.
  11234.  
  11235.  
  11236.  335. Sending C and Pascal Output to Printer in OS/2 SDK 1.05
  11237.  
  11238.  Question:
  11239.  
  11240.  I had trouble printing bound programs in Pascal and C with previous
  11241.  versions of the OS/2 Software Development Kit (SDK). In C, it was
  11242.  necessary to do an open and then an fdopen to print, and in Pascal, it
  11243.  was impossible to print altogether. Have these problems been resolved
  11244.  in Version 1.05 of the OS/2 SDK?
  11245.  
  11246.  Response:
  11247.  
  11248.  Yes. In OS/2 SDK Version 1.05, you do not have to print to a file
  11249.  handle obtained using the open command by associating it with an I/O
  11250.  stream with the fdopen command. As the following program demonstrates,
  11251.  you can open the printer with the open command and then write to it
  11252.  using the write command:
  11253.  
  11254.  #include <fcntl.h>
  11255.  #include <sys\types.h>
  11256.  #include <sys\stat.h>
  11257.  #include <io.h>
  11258.  #include <stdio.h>
  11259.  
  11260.  int fh;
  11261.  
  11262.  main()
  11263.  {
  11264.       if ((fh = open("prn",O_WRONLY)) == -1)
  11265.            printf("Unable to obtain File Handle.\n");
  11266.       else
  11267.            write(fh,"Hello",11);
  11268.  }
  11269.  
  11270.  You can then compile this program for dual mode by using the /Fb
  11271.  compile option.
  11272.  
  11273.  
  11274.  336. OS/2 Utility to Modify/Create QuickHelp Files
  11275.  
  11276.  Question:
  11277.  
  11278.  Is there a tool or sample code so that we can modify and/or create our
  11279.  own QuickHelp files?
  11280.  
  11281.  Response:
  11282.  
  11283.  In the OS/2 Software Development Kit (SDK) Version 1.06 we have
  11284.  included a compiler called HELPMAKE.EXE that allows you to create
  11285.  databases readable by the QuickHelp utility.
  11286.  
  11287.  
  11288.  337. Handling an NMI Issued from a Graphics Card under OS/2
  11289.  
  11290.  Question:
  11291.  
  11292.  If OS/2 can't handle a nonmaskable interrupt (NMI) that a graphics
  11293.  card has issued, is it possible to do a simple IRET to alleviate the
  11294.  condition?
  11295.  
  11296.  Response:
  11297.  
  11298.  Issuing an IRET will not work in cases where OS/2 is in protected mode
  11299.  because the routine on the graphics card is written for the real-mode
  11300.  environment. The NMI would probably only cause a protection-violation
  11301.  error to occur.
  11302.  
  11303.  
  11304.  338. No Way to Change Program Title on Program Selector in OS/2 SDK
  11305.  
  11306.  Question:
  11307.  
  11308.  Is there a way to change the program title on the Program Selector for
  11309.  the current session?
  11310.  
  11311.  Response:
  11312.  
  11313.  A Presentation Manager (PM) application can use the API function call
  11314.  WinChangeSwitchEntry() to change its title in the OS/2 Version 1.10
  11315.  Task Manager. There is currently no official way for an application
  11316.  other than a PM application to programmatically change the title in
  11317.  the Task Manager or the Version 1.00 Program Selector. This feature is
  11318.  under review and will be considered for inclusion in a future release.
  11319.  
  11320.  
  11321.  339. How to Enable CVP Support for IBM's OS/2
  11322.  
  11323.  Problem:
  11324.  
  11325.  When I run CVP on IBM's OS/2, I get the following error message:
  11326.  
  11327.     SYS0197: IBM Operating System/2 is not presently configured
  11328.              to run this application.
  11329.  
  11330.  Response:
  11331.  
  11332.  CodeView uses IOPL segments. By default, IBM's OS/2 does not come with
  11333.  support for IOPL programs enabled. To enable this support, add the
  11334.  following line to your CONFIG.SYS file and reboot:
  11335.  
  11336.     IOPL=YES
  11337.  
  11338.  
  11339.  340. Determining Screen Mode when Using VioSaveRedrawWait()
  11340.  
  11341.  Question:
  11342.  
  11343.  How can a background process, such as a keyboard monitor, find the
  11344.  current foreground screen mode, assuming the foreground process has
  11345.  done a VioSaveRedrawWait() [which means the background process can't
  11346.  do a transparent VioPopUp()]?
  11347.  
  11348.  Response:
  11349.  
  11350.  Using VioSaveRedrawWait() [and VioModeWait()] in your application
  11351.  prevents you from finding out what the screen mode of the foreground
  11352.  application is. Because these modes indicate direct hardware
  11353.  manipulation, there is no way for a separate process (or the system)
  11354.  to know what mode you are using, particularly with graphics cards that
  11355.  have write-only registers, such as the EGA.
  11356.  
  11357.  
  11358.  341. Incorrect Documentation on OS/2 Multitasking Functions
  11359.  
  11360.  The comments on Pages 14-15 in Section 2.2, "Multitasking Functions,"
  11361.  in the "Microsoft Operating System/2 Programmer's Reference" manual
  11362.  regarding the inheritance of queues by child processes are incorrect.
  11363.  
  11364.  The queues are actually just an abstraction that is implemented with a
  11365.  DLL, QUECALLS.DLL, that runs at ring 3 (application level). An
  11366.  application can write its own queue routines that would accomplish the
  11367.  same thing. Because this code is at the application level, the kernel
  11368.  is not managing it; therefore, queue handles are not inherited by a
  11369.  child process created with the kernel call DosExecPgm().
  11370.  
  11371.  
  11372.  342. Inheritance of System & RAM Semaphores between Parent & Child
  11373.  
  11374.  Question:
  11375.  
  11376.  Does inheritance between parent and child also apply to system and RAM
  11377.  semaphores? We are using generalized DLL-based routines to perform
  11378.  queue creation, sending, and receiving, as well as semaphore creation,
  11379.  setting, requesting, and clearing for different applications. Are
  11380.  there any problems with using DLLs in this way (especially between the
  11381.  parent and child processes using the same DLL)?
  11382.  
  11383.  Response:
  11384.  
  11385.  System semaphore handles are not inherited. It is the responsibility of
  11386.  each process to open the system semaphore.
  11387.  
  11388.  A RAM semaphore "handle" is actually the address of the location in
  11389.  memory where there is a LONG. Because of this, it is possible for the
  11390.  RAM semaphore to be placed in shared memory and have more than one
  11391.  process access it. However, there is one important problem with this.
  11392.  If process A sets this semaphore and then dies, there is no automatic
  11393.  cleanup done for it like there is for system semaphores, which the
  11394.  kernel knows about. This means that if process B now blocks on the RAM
  11395.  semaphore that was set by process A, process B will block forever. A
  11396.  good alternative to RAM semaphores is FS (Fast Safe) RAM semaphores,
  11397.  which is a new feature of OS/2 Version 1.10. FS RAM semaphores have
  11398.  ownership and use counts, so they are cleaned up by the kernel if the
  11399.  owning process dies while owning them. They are also good for
  11400.  recursive applications.
  11401.  
  11402.  Another alternative to using the queue calls is to use named pipes in
  11403.  message mode. Support for named pipes is available in Version 1.00
  11404.  with a device driver. They provide a very efficient means of
  11405.  transferring data between client/server processes and their handles
  11406.  can be inherited. Another advantage to named pipes is that they will
  11407.  work transparently over a network, as well as between processes on the
  11408.  same computer. Please refer to the LAN Manager reference manuals that
  11409.  come with Version 1.04 of the OS/2 SDK.
  11410.  
  11411.  
  11412.  343. OS/2 SDK: Setting Up Automatic Reboot when GP Error Occurs
  11413.  
  11414.  Question:
  11415.  
  11416.  Is there an easy way to make OS/2 automatically reboot after a general
  11417.  protection error that occurs at the application level?
  11418.  
  11419.  Response:
  11420.  
  11421.  There are a variety of techniques to accomplish this task; two of
  11422.  them are as follows:
  11423.  
  11424.  1. You could write a device driver that attaches itself to the
  11425.     32-millisecond timer interrupt and then periodically checks a
  11426.     dedicated semaphore in its data segment for each application you
  11427.     wish to monitor. This semaphore would be set up with a
  11428.     PhysToUVirt() DevHelp() command. Each application would then
  11429.     periodically write a 1 (for example) to its semaphore from a
  11430.     separate thread. The device driver would check for this 1 before
  11431.     writing a 0. If it ever detected a 0, the device driver would know
  11432.     the application had crashed and been aborted by OS/2, and it could
  11433.     then take appropriate action.
  11434.  
  11435.  2. A similar and probably simpler technique is to have a background
  11436.     job communicating and checking on your application in a way
  11437.     similar to the one described above using OS/2 interprocess
  11438.     semaphore commands.
  11439.  
  11440.  
  11441.  344. Considerations for Applications That Read Key and Mouse Events
  11442.  
  11443.  When using two threads, one blocking on MouReadEventQueue() (mouse
  11444.  events) and the other blocking on KbdCharIn() (keystrokes), you must
  11445.  observe certain cautions.
  11446.  
  11447.  For instance, if the customer presses a key that would cause part of
  11448.  the screen that might have the mouse pointer over it to be drawn, it
  11449.  is necessary to remove the mouse pointer with a call to
  11450.  MouRemovePtr(), then use MouDrawPtr() after the screen has been
  11451.  updated. Normally this is not a problem, but if the thread reading the
  11452.  mouse is blocked on the MouReadEventQueue() call, there is a semaphore
  11453.  internal to the MOU subsystem that will block the MouRemovePtr() call
  11454.  until a mouse event occurs and the mouse reading the thread returns
  11455.  from its MouReadEventQueue() call. A workaround for this problem is to
  11456.  draw your own pointer and not call the MouRemovePtr()/MouDrawPtr()
  11457.  calls.
  11458.  
  11459.  Another problem occurs if the customer presses a key that would cause
  11460.  the application to exit; in this case, MouClose() is typically called
  11461.  to close the mouse. Again, this call will block on the internal MOU
  11462.  semaphore until an event occurs. The workaround is to not call
  11463.  MouClose(), but instead to let the system close the mouse for you
  11464.  implicitly when your application exits. This is not the best
  11465.  programming style, but it works.
  11466.  
  11467.  The following are four other workarounds to these general problems:
  11468.  
  11469.  1. Send IOCTLs directly to the mouse device driver when it is
  11470.     necessary to do something from the keyboard while reading a thread.
  11471.     Most of the MOU calls have equivalent IOCTLs that can be used and
  11472.     will bypass the "per screen group" semaphore in the MOU subsystem.
  11473.  
  11474.  2. Use a mouse monitor that reads mouse events directly; therefore, it
  11475.     will not be necessary to block on MouReadEventQueue().
  11476.  
  11477.  3. Use a polling loop. This is obviously not as desirable in a
  11478.     multitasking operating system like OS/2; if it is necessary to use
  11479.     this approach, the loop must have a DosSleep() call within it so
  11480.     that other threads in the system still get time. The value to use
  11481.     for DosSleep() can be experimentally determined; the value of 25
  11482.     has been reported to work acceptably.
  11483.  
  11484.  4. Presentation Manager (PM) applications do not have these
  11485.     limitations. The mouse and keyboard events are converted into
  11486.     "messages" and are combined into one message queue. This queue
  11487.     contains both types of events in time sequence order.
  11488.  
  11489.  
  11490.  345. Turning NUM LOCK Off or CAPS LOCK On with KbdSetStatus()
  11491.  
  11492.  Question:
  11493.  
  11494.  I used the following code to attempt to turn NUM LOCK off:
  11495.  
  11496.  struct  KbdStatus  OurKbdStatus;
  11497.  /* KbdStatus is defined in subcalls.h */
  11498.  OurKbdStatus.length = sizeof(OurKbdStatus);
  11499.  KBDGETSTATUS((struct KbdStatus *)&OurKbdStatus,0);
  11500.  OurKbdStatus.shift_state &= 0xFFDF;              /* turn off bit 5 */
  11501.  KBDSETSTATUS((struct KbdStatus *)&OurKbdStatus,0);
  11502.  
  11503.  Both KbdGetStatus() and KbdSetStatus() returned 0, no error, but
  11504.  NUM LOCK was not turned off. I also tried to turn CAPS LOCK on by doing
  11505.  the following:
  11506.  
  11507.  OurKbdStatus.shift_state |= 0x0040;              /* turn on bit 6 */
  11508.  KBDSETSTATUS((struct KbdStatus *)&OurKbdStatus,0);
  11509.  
  11510.  This didn't work either. How do you turn NUM LOCK, CAPS LOCK, etc. on
  11511.  and off?
  11512.  
  11513.  Response:
  11514.  
  11515.  When setting the status of the shift state, you must turn on a bit in
  11516.  the bit_mask field of the keyboard status structure to tell
  11517.  KbdSetStatus() that you want to change the shift_state field. By
  11518.  default, it will not change that field. The following code
  11519.  demonstrates how to turn on a bit in the bit_mask field:
  11520.  
  11521.  #include <subcalls.h>
  11522.  #include <stdio.h>
  11523.  
  11524.  struct KbdStatus kbds;
  11525.  unsigned short rc;
  11526.  
  11527.  main()
  11528.  {
  11529.      kbds.length = sizeof(kbds);
  11530.      rc = KBDGETSTATUS(&kbds, 0);
  11531.  
  11532.      kbds.shift_state &= 0xFFDF; /*mask out numlock              */
  11533.      kbds.bit_mask |= 0x0010;    /*enable setting the shift state*/
  11534.      rc = KBDSETSTATUS(&kbds, 0);
  11535.  }
  11536.  
  11537.  The setting of the bit_mask field, now called fsMask, is described in
  11538.  QuickHelp and in the "Microsoft Operating System/2 Programmer's
  11539.  Toolkit Reference" manual under KbdSetStatus().
  11540.  
  11541.  
  11542.  346. Determining if Computer Has a MicroChannel Backplane (PS/2)
  11543.  
  11544.  Question:
  11545.  
  11546.  How does an OS/2 device driver determine at initialization time if the
  11547.  machine it's running on has a MicroChannel backplane (PS/2)? Under
  11548.  MS-DOS this was done by doing an INT 15H. Under OS/2 you can only do
  11549.  BIOS calls from real mode, but the initialization strategy routine
  11550.  calls the driver in protected mode and a RealToProt() can't be done at
  11551.  initialization time.
  11552.  
  11553.  Response:
  11554.  
  11555.  An OS/2 device driver can issue some of the APIs at initialization
  11556.  time. One of them is DosDevConfig(), which gets the information about
  11557.  the machine and the attached devices. Your device driver needs to
  11558.  issue DOS API DosDevConfig() from the initialization routine for items
  11559.  4 and 5 (please refer to Pages 74 and 75 of the "Microsoft Operating
  11560.  System/2 Programmer's Toolkit Programmer's Reference" manual for
  11561.  Version 1.00). When this API returns, it will have the information
  11562.  about the PC submodel and the model type.
  11563.  
  11564.  
  11565.  347. Writing to Screen After Device Driver Has Been Initialized
  11566.  
  11567.  Question:
  11568.  
  11569.  We want to print debug information to the screen from within a device
  11570.  driver at KERNEL time. Of course, this is trivial in MS-DOS, because
  11571.  we can simply use the INT 10H services without too much concern about
  11572.  reentrancy. However, this can't be done in OS/2 since the driver is in
  11573.  protected mode at that time. The DevHlp ProtToReal() call cannot be
  11574.  made at that time either, and the DosPutMessage() and VIO calls are
  11575.  useless as well.
  11576.  
  11577.  Use of the KERNEL debugger is not a viable option for what we want to
  11578.  do at this time, nor can we write directly to video RAM since it may
  11579.  be in graphics mode. How can we write to the screen at this time?
  11580.  
  11581.  Response:
  11582.  
  11583.  There is no direct way of writing to the screen from the device
  11584.  driver after the initialization is completed. However, you may want
  11585.  to consider the following suggestion: have a ring 3 process write
  11586.  the message for you.
  11587.  
  11588.  To accomplish this, you will first need to write a daemon process to
  11589.  accompany your device driver. Then, have your daemon process call down
  11590.  into your driver via a general IOCtl that you have defined. When your
  11591.  device driver receives this IOCtl, it can trap that ring 3 thread and
  11592.  hold it until it wants to write a message. When your driver is ready
  11593.  to write, it just needs to release the thread, which should then go on
  11594.  to write the message onto the screen (either directly or by using the
  11595.  VioPopup mechanism). The device driver can save the message string
  11596.  somewhere in memory, which is shared by both the ring 3 process and
  11597.  the device driver.
  11598.  
  11599.  
  11600.  348. Real Mode Device Driver in .EXE Format Can't Be Loaded
  11601.  
  11602.  Problem:
  11603.  
  11604.  If a real mode device driver in OS/2 1.00 is in .EXE format, an
  11605.  error occurs when the device driver is loaded.
  11606.  
  11607.  Response:
  11608.  
  11609.  You need to convert the .EXE format of the MS-DOS device driver into .SYS
  11610.  format using the EXE2BIN utility. This should allow the MS-DOS driver to
  11611.  be loaded under OS/2. There are some restrictions on the MS-DOS drivers
  11612.  that are used under OS/2. The restrictions are as follows:
  11613.  
  11614.  1. Block device drivers are not permitted in MS-DOS mode.
  11615.  
  11616.  2. Only a limited set of character device drivers can be supported by
  11617.     OS/2. To run in the MS-DOS mode, a character device driver cannot have
  11618.     a hardware-interrupt handler. Its device must be polled rather than
  11619.     interrupt driven.
  11620.  
  11621.  3. The device driver should support the request packet for all the
  11622.     commands, which is a character device driver that OS/2 supports.
  11623.  
  11624.  For more information, please refer to Section 1.13, on Page 28 of the
  11625.  "Microsoft Operating System/2 Device Drivers Guide."
  11626.  
  11627.  
  11628.  349. OS/2 SDK: Limit of 254 Segments Per Process
  11629.  
  11630.  Question:
  11631.  
  11632.  I have a FORTRAN application that has exceeded the limit of 254
  11633.  segments per process. Will this limitation be changed in future
  11634.  versions of OS/2?
  11635.  
  11636.  Response:
  11637.  
  11638.  The limitation of 254 segments is actually a limit in the executable
  11639.  header in an .EXE file. This means that an application that uses DLLs
  11640.  can have 254 segments in its main .EXE and 254 in each DLL that it
  11641.  accesses. Since 254 segments times 64K for each segment produces an
  11642.  .EXE that is over 16 megabytes, the problem is not really in the limit
  11643.  in the .EXE header, but rather in the way the segments are built into
  11644.  the FORTRAN executables. Currently, there are no plans to change
  11645.  either the limit on the .EXE header or the default behavior of the
  11646.  FORTRAN compiler. Therefore, the only workaround is to combine the
  11647.  common blocks in the program so that fewer physical segments are
  11648.  required.
  11649.  
  11650.  
  11651.  350. Clarification of Process Status and Profile Support in OS/2
  11652.  
  11653.  Profiling and the Process Status (PS) utility use APIs in the KERNEL
  11654.  that will not be in any final release of the product. They are only
  11655.  included in special builds of the KERNEL provided to Microsoft OS/2
  11656.  SDK customers. In the Microsoft OS/2 SDK Version 1.05 release, the
  11657.  KERNEL contains these APIs, and the utilities and header files are in
  11658.  the subdirectory \PMSDK\PROFILER.
  11659.  
  11660.  
  11661.  351. OS/2 SDK: Description of DLL Load Architecture
  11662.  
  11663.  Below is a description of the dynamic link library (DLL) loading
  11664.  mechanisms concerning segment-selector allocation and actual segment
  11665.  loading.
  11666.  
  11667.  When the loader loads a program and resolves references to a dynamic
  11668.  link library, which can in turn load more DLLs, all of the selectors
  11669.  are reserved in each process's local descriptor table (LDT). It is
  11670.  necessary to reserve the selectors in all LDTs because the code and
  11671.  usually the data in a DLL can be shared by all processes. The
  11672.  descriptors are initially marked as not present.
  11673.  
  11674.  In building the DLL, it is possible to specify two options for the
  11675.  code and data segments: PRELOAD and LOADONCALL. The default is
  11676.  LOADONCALL, which means that the segments that are necessary for a
  11677.  routine are only loaded into memory the first time the routine is
  11678.  called. The PRELOAD option means that at load time all segments will
  11679.  come into memory. If the DLL is located on removable media like a
  11680.  floppy drive, the default is PRELOAD because the system cannot assume
  11681.  that the media with the DLL will not be removed.
  11682.  
  11683.  
  11684.  352. OS/2 SDK: Information on DosGetResource()
  11685.  
  11686.  Problem:
  11687.  
  11688.  If I call the same TypeID and NameID within the same process with the
  11689.  DosGetResource() call, the system assumes that the segment is already
  11690.  loaded. The following is a portion of my code:
  11691.  
  11692.     DosGetResource(NULL, Topic, SubTopic, &selHelpText);
  11693.     DosSizeSeg(selHelpText, &ulSegSize);
  11694.     lpHelpText = MAKEP(selHelpText, 0);
  11695.     _fstrncpy(szText, lpHelpText, ulSegSize);
  11696.     DosFreeSeg(selHelpText);
  11697.  
  11698.  Response:
  11699.  
  11700.  DosGetResource() acts a little differently than you might expect. It
  11701.  does not get you a fresh copy of the resource each time, but instead
  11702.  gives you a selector to an already loaded resource segment. It would be
  11703.  more efficient if you kept the selector around as long as you need it,
  11704.  but you should also be able to call DosGetResource() again and get the
  11705.  same selector. In your case, problems occur because you are calling
  11706.  DosFreeSeg() on memory that has not been allocated with DosAllocSeg().
  11707.  Your code should work properly, provided that you remove the call to
  11708.  DosFreeSeg().
  11709.  
  11710.  
  11711.  353. OS/2 SDK: File and Pipe Mode Information
  11712.  
  11713.  OS/2 function calls such as DosWrite() and DosMkPipe() default to
  11714.  binary mode. OS/2 does not provide support for text mode. The C
  11715.  run-time function calls such as write() are what contain the options
  11716.  for text or binary mode. In the C run-time, you can specify text or
  11717.  binary mode with the open() function. There is no such feature with
  11718.  OS/2.
  11719.  
  11720.  The handles stdin and stdout also default to binary mode. However, C
  11721.  run-time function calls, such as printf(), usually "massage" the data
  11722.  before sending it to stdout, so in this environment it could be
  11723.  considered "text" mode. OS/2 itself will not do this, however.
  11724.  
  11725.  If a process starts a child process, the child process will inherit
  11726.  the file handle, but not the mode specified by the parent. This is
  11727.  because the text/binary mode is maintained by the C run-time and the
  11728.  kernel has no knowledge of it; therefore, the text/binary mode cannot
  11729.  be inherited.
  11730.  
  11731.  
  11732.  354. Returning Virtual Address in Shared Memory to Application
  11733.  
  11734.  Question:
  11735.  
  11736.  I have the following two questions about returning virtual addresses
  11737.  in shared memory to an application:
  11738.  
  11739.  1. Assuming I use DevHlp_PhyToUVirt(), how do I make the virtual
  11740.     address obtained available to an application? Do I need to create
  11741.     my own IOCtl call, and then do a DosDevIOCtl() and return the
  11742.     value?
  11743.  
  11744.  2. Is it possible to return a value like this from DosOpen()? If so,
  11745.     how?
  11746.  
  11747.  Response:
  11748.  
  11749.  The answers to your questions are as follows:
  11750.  
  11751.  1. Yes, you do have to make your own IOCtl call, and also do a
  11752.     DosDevIOCtl() in the application program. This will start the
  11753.     strategy routine of your driver. In the strategy routine, you
  11754.     should do a DevHlp_PhyToUVirt() and return the selector to the
  11755.     application program as one of the parameters.
  11756.  
  11757.  2. No, it is not possible to return this kind of value from DosOpen().
  11758.  
  11759.  
  11760.  355. OS/2 SDK: VioGetBuf() and VioShowBuf() Removed from API.LIB
  11761.  
  11762.  VioGetBuf() and VioShowBuf() were removed from API.LIB when it was
  11763.  discovered that there were potential problems under certain
  11764.  circumstances when using these functions in MS-DOS. These functions
  11765.  will not be included in the FAPI; therefore, you will need to create
  11766.  your own functions with the same names and link them in to resolve the
  11767.  external references.
  11768.  
  11769.  The references to VioGetBuf() on Pages 326-327 and to VioShowBuf() on
  11770.  Pages 379-380 of the "Microsoft Operating System/2 Programmer's
  11771.  Toolkit Programmer's Reference" manual for Version 1.00 will be
  11772.  removed in a future release of the documentation.
  11773.  
  11774.  
  11775.  356. OS/2 SDK: DosDevIoctl() Category 03H Documentation Error
  11776.  
  11777.  There is a documentation error on Page 162 of the "Microsoft Operating
  11778.  System/2 Device Drivers Guide" labeled "Pre-release". The only IOCtl
  11779.  available to an application program under Category 03H is function 72H
  11780.  (Get Pointer-Draw Address); the other IOCtl commands listed on Page
  11781.  162 are not available.
  11782.  
  11783.  
  11784.  357. OS/2 SDK: Allocating Memory on 64K Boundary for DMA Transfer
  11785.  
  11786.  Question:
  11787.  
  11788.  Could you give me some information on how to allocate memory on a 64K
  11789.  boundary from an application to allow for correct DMA transfer?
  11790.  
  11791.  Response:
  11792.  
  11793.  A device driver will allow you to do this, but it cannot be done from
  11794.  an application. From the application level, the OS/2 memory-management
  11795.  scheme is a virtual scheme, and it does not allow such physical
  11796.  segment alignment. A device driver should be used in this case, where
  11797.  such physical demands are required.
  11798.  
  11799.  
  11800.  358. Specifying a Device Rather Than a Filename in DosOpen()
  11801.  
  11802.  To specify a device rather than a filename in DosOpen(), do the
  11803.  following:
  11804.  
  11805.     DosOpen ( (char far *) "TEST$",
  11806.               (unsigned far *) &Shandle,
  11807.               (int far *) &Result,
  11808.               0l,
  11809.               (int) 0,
  11810.               (int) 1,        /* open if there, fail if not  */
  11811.               (int) 0x42,
  11812.               0l,
  11813.             ) ;
  11814.  
  11815.  
  11816.  359. Presentation Manager: File Manager Selection Problem
  11817.  
  11818.  When using the File Manager in OS/2 Presentation Manager (PM), a
  11819.  problem exists associated with file selection. After selecting a
  11820.  single file and deleting it, the next time a file is selected, two
  11821.  items are shown as selected. Deselecting the second item results in
  11822.  both being shown as not selected.
  11823.  
  11824.  Microsoft has confirmed this to be a problem in the OS/2 Software
  11825.  Development Kit (SDK) Version 1.05. This problem was corrected in
  11826.  Version 1.06 of the OS/2 SDK.
  11827.  
  11828.  
  11829.  360. OS/2 SDK: Inquiring about a Module Name
  11830.  
  11831.  Question:
  11832.  
  11833.  How can you access the name of a module?
  11834.  
  11835.  Response:
  11836.  
  11837.  This information is contained in the .EXE header. Look in the file
  11838.  NEWEXE.H for information on the .EXE header. This file should be in
  11839.  your include directory after you have installed the OS/2 Software
  11840.  Development Kit (SDK). There is no API that will directly give you the
  11841.  module name instead of the filename, but NEWEXE.H should give you the
  11842.  location in the .EXE header where the module name is found, so you can
  11843.  open the .EXE file and look for the module name there.
  11844.  
  11845.  
  11846.  361. OS/2 SDK: Queued Semaphore Requests Not Allowed
  11847.  
  11848.  Question:
  11849.  
  11850.  How would you use semaphores to serialize access to a resource in a
  11851.  queued fashion? The order in which requesting processes are granted
  11852.  semaphores depends on scheduling rather than the order in which the
  11853.  semaphores are requested. Does the semaphore interface provide the
  11854.  ability to have semaphore requests queued so that they are granted in
  11855.  the order in which they were requested? The requirement for queued
  11856.  access to a resource would seem to be fairly common.
  11857.  
  11858.  Response:
  11859.  
  11860.  Unfortunately, there are no semaphore mechanisms built into OS/2 that
  11861.  allow queued access. When threads are being scheduled, the next thread
  11862.  to run is chosen based on its priority. The semaphore APIs are
  11863.  primitives, and any higher-level behavior that you want to accomplish
  11864.  will have to be built off of them. To accomplish what you want to do,
  11865.  you need to explicitly implement the queuing in your application.
  11866.  
  11867.  
  11868.  362. OS/2 SDK: How to Run .CMD Files in Program Starter
  11869.  
  11870.  The steps below describe how to run a .CMD file from the Program
  11871.  Starter.
  11872.  
  11873.  To run a .CMD file from the Program Starter, do the following:
  11874.  
  11875.   1. Create the .CMD file.
  11876.  
  11877.   2. Select Program from the Program Starter menu.
  11878.  
  11879.   3. Select Add from the Program Starter menu.
  11880.  
  11881.   4. Type in the program title.
  11882.  
  11883.   5. Enter the complete path and filename. The following is an example:
  11884.  
  11885.         c:\os2\test.cmd
  11886.  
  11887.   6. Select Add from the Program Starter menu.
  11888.  
  11889.   7. A warning message should appear that asks you if the .CMD file is
  11890.      a Presentation Manager application. Click the No button.
  11891.  
  11892.   8. Another pop-up menu will appear asking for the mode this character
  11893.      application should run under. Select the Run on Full Screen option.
  11894.  
  11895.   9. Click the Enter button.
  11896.  
  11897.  10. The .CMD file should then be added to the Program Starter's menu.
  11898.      Select the .CMD file from this menu.
  11899.  
  11900.  11. The .CMD file should run and immediately return to the Task Manager
  11901.      when it completes.
  11902.  
  11903.  If you make a mistake while entering the .CMD file into the Program
  11904.  Starter menu (e.g. you selected Take System Default instead of Run on
  11905.  Full Screen) and then try to use the Change command to reset it, a
  11906.  SYS1041 error message is still returned. To correct the mistake you
  11907.  have made, you must select Delete and start over again.
  11908.  
  11909.  
  11910.  363. OS/2 SDK: Displaying Mouse Pointer in EGA/VGA Graphics Mode
  11911.  
  11912.  Question:
  11913.  
  11914.  How do we get the mouse pointer to appear when using OS/2 with an EGA
  11915.  or VGA graphics card?
  11916.  
  11917.  Response:
  11918.  
  11919.  OS/2 supports the mouse under EGA and VGA graphics modes, but does not
  11920.  provide pointer drawing for the graphics modes. This means that you
  11921.  can go into loop reading events with MouReadEventQueue() and will be
  11922.  informed of button presses and mouse motion, but OS/2 will not draw
  11923.  the cursor on the screen. If you are going to be using a graphics
  11924.  mode, you must use MouSetDevStatus() to specify that you will be doing
  11925.  your own pointer drawing, and it is the responsibility of your
  11926.  application to draw the shape of the pointer on the graphics screen
  11927.  when you get a mouse event saying that the mouse has moved. This is
  11928.  only a high-level overview. There is a specific example of drawing
  11929.  your own mouse pointer and using a graphic screen mode in the LIFE
  11930.  example included with the Microsoft OS/2 Version 1.00 Programmer's
  11931.  Toolkit.
  11932.  
  11933.  
  11934.  364. BLOCK.ARC: Drive Not Ready Detection Sample Program
  11935.  
  11936.  Question:
  11937.  
  11938.  I want to be able to detect the hard error returned when selecting a
  11939.  disk drive that is not ready (e.g. when a user selects a drive for my
  11940.  application to use). However, DosSelectDisk(1), which selects Drive A,
  11941.  does not return the error INVALID DRIVE, even if I've previously
  11942.  disabled handling hard errors with the call DosErrors(0). INVALID
  11943.  DRIVE seems to mean the drive number is out of range. How can I detect
  11944.  if the drive is not ready?
  11945.  
  11946.  Response:
  11947.  
  11948.  The most common way to detect if a drive is not ready is to use the
  11949.  DosOpen() function with the DASD option. To avoid the "Drive not
  11950.  Ready" message from OS/2, you should call DosError(0) to disable
  11951.  critical-error handling. When you do this, DosOpen() will return an
  11952.  error of ERROR_NOT_READY.
  11953.  
  11954.  A sample program in the Software Library named BLOCK.ARC detects if a
  11955.  drive is not ready. This file can be found in the Software Library by
  11956.  searching for the filename BLOCK.ARC, the Q number of this article, or
  11957.  S12147. BLOCK.ARC has been archived with the PKARC utility. You will
  11958.  need to unarchive it with PKXARC. A copy of PKXARC can be found on
  11959.  your Microsoft OnLine Utilities Disk 2.
  11960.  
  11961.  
  11962.  365. Additional Segment after Init, and Load High Device Drivers
  11963.  
  11964.  Question:
  11965.  
  11966.  Is there any way that an OS/2 Version 1.10 device driver can keep
  11967.  extra segments after the initialization process has completed?
  11968.  
  11969.  Response:
  11970.  
  11971.  Yes, starting with OS/2 Version 1.10, a device driver can keep
  11972.  additional segments even after initialization. These segments must be
  11973.  specified as IOPL segments in the definition file. All segments in a
  11974.  device driver must be specified in the correct order. These segments
  11975.  also have to be locked down from the initialization routine.
  11976.  
  11977.  The additional segments are located in the High Memory Area at boot-up
  11978.  time. These segments can only be accessed in protected mode. The
  11979.  primary segments (original segments) are located in low memory as
  11980.  usual. The kernel only calls the primary segment of the device driver.
  11981.  If a device driver wants to execute the code in the additional
  11982.  segment, it should transfer the execution through a FAR call. These
  11983.  FAR addresses should be stored in the primary segment.
  11984.  
  11985.  A device driver can change the CPU mode by using the DevHlps
  11986.  RealToProt() and ProtToReal(). After the processing is complete, the
  11987.  device driver must return the processor to the mode it was in when the
  11988.  device driver was entered.
  11989.  
  11990.  The following is a list of rules and steps to get segments in your
  11991.  device driver to load into the High Memory Area:
  11992.  
  11993.  1. The first two segments that appear in the .SYS file must be the
  11994.     default low-data segment and the default low-code segment.
  11995.  
  11996.  2. All dispatching from the OS/2 kernel will be made to the default
  11997.     low-code segment (i.e., strategy routine, interrupt handlers, timer
  11998.     ticks, etc.). These routines must still be bimodal.
  11999.  
  12000.  3. To get other segments to load into High Memory, the IOPL bit must
  12001.     be set by the device driver's .DEF file.
  12002.  
  12003.     Note: When listing segments in a .DEF file, be sure to list all the
  12004.     segments in the order you wish them to be linked (i.e., low data,
  12005.     low code, init code/data, high code/data). By setting the IOPL bit
  12006.     on a segment, it will be loaded into High Memory, and it will not
  12007.     be discarded after initialization time.
  12008.  
  12009.  4. The high-code segments are not locked down after the device driver
  12010.     is loaded. To lock them down, call DevHlp_Lock, sub function 1.
  12011.     This step is required. If the device driver attempts to access
  12012.     memory that is not present, the system will crash.
  12013.  
  12014.     Note: This now works at INIT time. Older documentation will claim
  12015.     it doesn't. Also, newer documentation may suggest using DevHlp_Lock
  12016.     type 3. This may cause a protection fault during the boot; we
  12017.     recommend using type 1 to avoid this problem.
  12018.  
  12019.  5. The high segments can only be accessed in protected mode.
  12020.     DevHlp_RealToProt can be used to get into protected mode when
  12021.     necessary (even at strategy time). If the device driver switches
  12022.     the processing mode, it must restore the mode before returning to
  12023.     the kernel (i.e., DevHlp_ProtToReal).
  12024.  
  12025.     Note: For performance reasons, your device driver should attempt to
  12026.     keep the mode switching as low as possible.
  12027.  
  12028.  6. Base device drivers cannot have any load-high segments.
  12029.  
  12030.  
  12031.  366. Reason for General Protection (Trap D) Error Message
  12032.  
  12033.  Question:
  12034.  
  12035.  Sometimes my OS/2 application crashes with the following error
  12036.  message:
  12037.  
  12038.     The system detected a general protection fault (trap D) in a
  12039.     system call.
  12040.  
  12041.  What causes this error to occur?
  12042.  
  12043.  Response:
  12044.  
  12045.  The "trap D" error message can occur in the following two situations:
  12046.  
  12047.  1. When an application tries to use a segment that has not been
  12048.     allocated to the application.
  12049.  
  12050.  2. When a reference is made that is out of the range of a segment's
  12051.     size. Generally, this occurs when a buffer is passed to a system
  12052.     routine and the size of the buffer is less than the size parameter
  12053.     passed to the system routine.
  12054.  
  12055.  The system detects this overflow within the kernel, which is why the
  12056.  error says that it was detected in a system call. Even though the
  12057.  system says that it detected the error in the system call, this does
  12058.  not imply that the system had an error. Rather, it means that the
  12059.  application passed an incorrect buffer and/or size parameter to the
  12060.  system call.
  12061.  
  12062.  
  12063.  367. OS/2 SDK: HELPMSG Documentation Error
  12064.  
  12065.  The text displayed when HELPMSG is invoked with SYS 2092 in Version
  12066.  1.05 of the OS/2 SDK is incorrect. For example, it contains
  12067.  "1Microsoft", and the first line contains asterisks instead of a
  12068.  parameter. This problem was corrected in Version 1.06 of the OS/2 SDK.
  12069.  
  12070.  
  12071.  368. OS/2 SDK: VDISK.SYS Sector Size Documentation Error
  12072.  
  12073.  The "Microsoft Operating System/2 Setup Guide" (document number
  12074.  510830003-200-001-1087) incorrectly states on Page 72 that the sector
  12075.  size can be set to 1024. If you set the sector size to 1024, VDISK.SYS
  12076.  resets it to 512, which is the maximum value allowed for this
  12077.  parameter.
  12078.  
  12079.  
  12080.  369. OS/2 SDK: System File Number Information
  12081.  
  12082.  Question:
  12083.  
  12084.  What is the meaning of what IBM calls the System File Number? What is
  12085.  its intended use in a device driver?
  12086.  
  12087.  Response:
  12088.  
  12089.  The System File Number is a unique number that is assigned with an
  12090.  open request [i.e., DosOpen()]. It is usually not used by the device
  12091.  drivers except the printer device driver. The printer device driver
  12092.  uses the System File Number for spooling the files, which is how it
  12093.  associates a DosClose() with a temporary file in the spooler.
  12094.  
  12095.  
  12096.  370. OS/2 SDK: Killing Thread 1 Causes Process to Die
  12097.  
  12098.  Question:
  12099.  
  12100.  In the OS/2 Software Development Kit (SDK) Version 1.05, when you kill
  12101.  Thread 1 the whole process dies. Why is this happening?
  12102.  
  12103.  Response:
  12104.  
  12105.  You should kill off only subsidiary threads with DosExit(EXIT_PROCESS,
  12106.  return_code). Thread 1 has special properties. You should kill Thread
  12107.  1 with DosExit(EXIT_PROCESS, return_code) only when the entire process
  12108.  is done. Thread 1 is the thread that is interrupted by the system when
  12109.  the process receives a signal. (See Chapter 5 of Gordon Letwin's
  12110.  "Inside OS/2" book for more details on threads).
  12111.  
  12112.  This is a permanent change for OS/2 Version 1.10 from OS/2 Version
  12113.  1.00.
  12114.  
  12115.  
  12116.  371. OS/2 SDK: United Kingdom (UK) Keyboard Mapping Problems
  12117.  
  12118.  Problem
  12119.  
  12120.  I am changing the VIOTBL.DCP and KEYBOARD.DCP code-page files from the
  12121.  US configuration to the United Kingdom (UK) configuration. I have
  12122.  "un-remarked" the following line in my CONFIG.SYS file and changed the
  12123.  "US" to "UK" as follows:
  12124.  
  12125.     devinfo=kbd,UK, c:\os2\dev\keyboard.dcp
  12126.  
  12127.  The keyboard translation gives a number of incorrect mappings as
  12128.  follows:
  12129.  
  12130.  Key           Key Mapping     Shifted Key   Shifted Key Mapping
  12131.  
  12132.   6                6               ^                 &
  12133.   7                7               &                 '
  12134.   8                8               *                 (
  12135.   #                ]               ~                 }
  12136.  
  12137.  Response:
  12138.  
  12139.  Microsoft has confirmed this to be a problem in Version 1.05. This
  12140.  problem was corrected in Version 1.06.
  12141.  
  12142.  
  12143.  372. OS/2 SDK: DevHlp_Block Rescheduling Priority
  12144.  
  12145.  What is the rescheduling priority after a device driver's kernel
  12146.  routine issues a DevHlp_Block?
  12147.  
  12148.  Response:
  12149.  
  12150.  When a device driver uses DevHlp_Block, the scheduler removes this
  12151.  thread from the current run queue and starts a thread whose priority
  12152.  is highest at that time.
  12153.  
  12154.  
  12155.  373. OS/2 SDK: Unresolved External Error Occurs with VioWrtTTy()
  12156.  
  12157.  VioWrtTTy() was changed to VioWrtTTY() (the "y" was changed to "Y") to
  12158.  maintain compatibility with IBM's OS/2, which has the uppercase "Y" in
  12159.  it. If you do not use VioWrtTTY() with Version 1.05, you will receive
  12160.  an "unresolved external" error when compiling your program.
  12161.  
  12162.  
  12163.  374. MOU.ARC: Sample Mouse Program That Interprets Up/Down Events
  12164.  
  12165.  MOU.ARC is a sample program in the Software Library that detects a
  12166.  mouse-down or a mouse-up event. This program has been tested with the
  12167.  OS/2 SDK Version 1.05 and the Microsoft Mouse. The program does not
  12168.  attempt to interpret anything but up and down events and does not
  12169.  "weed out" other possibilities, such as down movement.
  12170.  
  12171.  MOU.ARC can be found in the Software Library by searching for the
  12172.  filename, the Q number of this article, or S12160. MOU.ARC has been
  12173.  archived with the PKARC utility. You will need to use PKXARC to
  12174.  unarchive it. A copy of PKXARC can be found on the Microsoft OnLine
  12175.  Utilities Disk 2.
  12176.  
  12177.  
  12178.  375. Determining Which Process Has Sent a Request to Device Driver
  12179.  
  12180.  Question:
  12181.  
  12182.  I am in the process of designing an OS/2 (probably bimodal) character
  12183.  device driver. Because I need to create and maintain a "minor" device
  12184.  for each process that makes a request of the device driver, I need a
  12185.  way to find out which process has made the OS/2 API call which in turn
  12186.  has caused OS/2 to generate and send the request packet to my device
  12187.  driver. Thus, I want to create a "minor" device when a process opens
  12188.  the driver by recording the identity of the requesting process (PID #)
  12189.  and then mapping all subsequent I/O requests to the proper minor
  12190.  device.
  12191.  
  12192.  Is there a DevHlp routine or some other mechanism that would provide
  12193.  me with this information?
  12194.  
  12195.  Response:
  12196.  
  12197.  The DevHlp GetDosVar() routine returns the address of important kernel
  12198.  variables. There are 11 such variables that the kernel maintains for
  12199.  device drivers. If a device driver needs a pointer to any of these
  12200.  variables, it loads the variable number in register AL and issues
  12201.  the DevHlp GetDosVar(). On return, the register AX:BX points to a
  12202.  memory location that contains the Segment/Selector Offset pair of some
  12203.  structure.
  12204.  
  12205.  One of these variables, LocalInfoSeg(), gives the process-specific
  12206.  information (PID, priority, session, etc.). You may want to use this
  12207.  variable to find out the PID of the process whose thread of execution
  12208.  is in the device driver.
  12209.  
  12210.  The address in the register AX:BX is a bimodal address.
  12211.  
  12212.  
  12213.  376. OS/2 SDK: Methods of Reading Boot Sector
  12214.  
  12215.  The following are two different methods for reading the boot sector:
  12216.  
  12217.  1. Open the device as a DASD and do DosReads on it.
  12218.  
  12219.  2. Use the IOCtls to do the reads. In this case, you would first open
  12220.     the device and use category 8 function 64H (read track) to read
  12221.     sector 0 (the first sector, which is called the Master Boot
  12222.     Sector). This sector contains information about the number of
  12223.     hidden sectors (please refer to the IBM AT technical reference
  12224.     manual for more information on the Master Boot Record format); skip
  12225.     these sectors and read the next sector. That next sector will be
  12226.     the boot sector of Drive C.
  12227.  
  12228.     If you want to read the boot sector of an extended volume, sector 0
  12229.     will get you the extended boot record (not the boot sector of the
  12230.     D: partition). Again, you need to figure out the position of the
  12231.     boot sector, as described above.
  12232.  
  12233.  
  12234.  377. PM: Changing Text Limit in Edit Control in Dialog Box
  12235.  
  12236.  Question:
  12237.  
  12238.  When I put an edit control in a dialog box, no matter what the size
  12239.  of the box is on the screen, or whether I set ES_AUTOSCROLL, the
  12240.  dialog box won't accept more than 30 characters. If I try to enter
  12241.  more than 30 characters, it beeps at me. How can I get the dialog box
  12242.  to accept more than 30 characters?
  12243.  
  12244.  Response:
  12245.  
  12246.  The default text limit in an edit control in a dialog box is 30
  12247.  characters. To change it for a particular edit control, send the
  12248.  control an EM_SETTEXTLIMIT, where the low-order word of mp1 specifies
  12249.  the maximum number of characters. You must also set mp2 to zero.
  12250.  
  12251.  
  12252.  378. PM: Meaning of DosStartSession() 0x110F Return Code
  12253.  
  12254.  Question:
  12255.  
  12256.  When I try to start a session with DosStartSession(), I get a return
  12257.  code of 0x110F. What does this mean? The session is started as a debug
  12258.  session. This message appears whenever I set the Length field of the
  12259.  StartData record to 50 (for maximum control), but not when I set it to
  12260.  30.
  12261.  
  12262.  Response:
  12263.  
  12264.  To avoid this problem, pass the size of the STARTDATA structure in the
  12265.  Length field. We also recommend that you use the sizeof() operator.
  12266.  The following is an example:
  12267.  
  12268.     StartData.Length = sizeof(STARTDATA);
  12269.  
  12270.  
  12271.  379. OS/2 SDK: Identifying .EXE File's Session Type
  12272.  
  12273.  Question:
  12274.  
  12275.  How can you identify an .EXE file's session type, as per
  12276.  DosStartSession()?
  12277.  
  12278.  Response:
  12279.  
  12280.  The session type can be obtained with the DosQAppType() function call.
  12281.  You pass DosQAppType() the .EXE filename, and DosQAppType() returns
  12282.  the executable type (i.e., windowable, nonwindowable, window API) in a
  12283.  pointer to a short.
  12284.  
  12285.  
  12286.  380. OS/2 SDK: DosStartSession() pgmTitle Parameter Information
  12287.  
  12288.  Question:
  12289.  
  12290.  There is an entry called pgmTitle in the start-area structure for the
  12291.  DosStartSession() call. What is pgmTitle used for?
  12292.  
  12293.  Response:
  12294.  
  12295.  The entry pgmTitle is the name that will be displayed in the program
  12296.  shell's task-manager switch list. You do not have to use this field,
  12297.  but it gives you the opportunity to select whatever name you want
  12298.  people to see when they are selecting a session to switch to from the
  12299.  task manager.
  12300.  
  12301.  
  12302.  381. OS/2 SDK: Definition of SessionID and/or Screen Group
  12303.  
  12304.  The terms "SessionID" and "Screen Group" are synonymous. They are
  12305.  defined to be one or more processes running together that share the
  12306.  keyboard, video display, and mouse.
  12307.  
  12308.  
  12309.  382. OS/2 SDK: General RAM Semaphore Information
  12310.  
  12311.  Question:
  12312.  
  12313.  I have the following questions regarding the creation of transient RAM
  12314.  semaphores in malloc()'ed space or on the stack:
  12315.  
  12316.  1. When I'm done using the semaphores and I want to return the
  12317.     space to the heap, is it necessary to clean up the contents, e.g.
  12318.     should I use DosSemClear() to clear the space before freeing it?
  12319.  
  12320.  2. When I'm creating a semaphore that I want to be initially clear,
  12321.     all I need to do is set it to 0:0. However, if I want it initially
  12322.     set, can I just set it to 0:255 [as it appears DosSemSet() does],
  12323.     or must I use the DosSemSet() call to do this?
  12324.  
  12325.  Response:
  12326.  
  12327.  The answers to your questions are as follows:
  12328.  
  12329.  1. Yes, you should do some sort of cleanup. This would prevent the
  12330.     possibility of a process blocking indefinitely on an abandoned
  12331.     semaphore.
  12332.  
  12333.  2. You should use the DosSemSet() call. This will prevent race
  12334.     conditions from occurring if two processes should ever attempt to
  12335.     modify the semaphore at the same time. If you are trying to make
  12336.     sure that the semaphore is set before anyone tries to read it, you
  12337.     should DosEnterCritSec() just before you create the semaphore, set
  12338.     it using DosSemSet(), and then use DosExitCritSec().
  12339.  
  12340.  
  12341.  383. OS/2 Returns "Not Enough Memory to Run Application" Error
  12342.  
  12343.  Question:
  12344.  
  12345.  Occasionally, OS/2 returns "not enough memory to run application"
  12346.  errors. The CMD processor then will refuse to run programs. How is
  12347.  this possible? I have SWAPPING and MOVING enabled, 2 megabytes of
  12348.  RAM, and the disk on which the swap file is placed has plenty of free
  12349.  space (approximately 5 megabytes)?
  12350.  
  12351.  Response:
  12352.  
  12353.  OS/2 will return the "not enough memory to run application" message if
  12354.  it determines that there is not enough RAM and/or disk space to allow
  12355.  the program to be loaded and run. Although 2 megabytes of RAM and 5
  12356.  megabytes of disk space are sufficient to run OS/2 and several
  12357.  applications simultaneously, it is not surprising that you would
  12358.  receive this message if you attempt to run many applications at the
  12359.  same time. Check the size of the file SWAPPER.DAT, and the amount of
  12360.  disk space at the time that you receive the error. As SWAPPER.DAT
  12361.  grows (by increasing the number of items that are swapped), the
  12362.  amount of available disk space diminishes until the operating system
  12363.  calculates that it could potentially be prevented from loading a
  12364.  segment into RAM because it does not have room on the disk to swap out
  12365.  another segment to make room.
  12366.  
  12367.  You can do the following two things to address this problem:
  12368.  
  12369.  1. Increase the amount of RAM you have [3 to 4 megabytes is a good
  12370.     amount, especially if you are doing Presentation Manager (PM)
  12371.     work].
  12372.  
  12373.  2. Make room on your swap disk to allow more files to be swapped.
  12374.  
  12375.  Getting more RAM is the best solution if you are concerned about
  12376.  speed, but making more disk space available will work just as well.
  12377.  
  12378.  
  12379.  384. OS/2 SDK: KbdCharIn() hkbd Parameters Information
  12380.  
  12381.  Question:
  12382.  
  12383.  On Page 258 of the "Microsoft Operating System/2 Programmer's Toolkit
  12384.  Programmer's Reference" for Version 1.00, under the KbdCharIn() call,
  12385.  it states that the hkbd parameter "must have been previously opened by
  12386.  using the KbdOpen function." However, the example on Page 261 passes a
  12387.  keyboard handle (third parameter) of zero. The hkbd parameter is
  12388.  ignored in real mode, but what is the meaning of a zero for that
  12389.  parameter under OS/2?
  12390.  
  12391.  Also, will KbdCharIn() behave this way in the future with a zero value
  12392.  for the hkbd parameter?
  12393.  
  12394.  Response:
  12395.  
  12396.  The zero (0) parameter is the default keyboard and identifies the
  12397.  physical keyboard. To access the physical keyboard, it is not
  12398.  necessary to explicitly open it. This will remain true for future
  12399.  versions of OS/2.
  12400.  
  12401.  
  12402.  385. OS/2 SDK: Protection Violation ERLIM & ERACC Field Information
  12403.  
  12404.  Question:
  12405.  
  12406.  What do the ERLIM & ERACC fields mean in the message displayed when a
  12407.  protection violation fault occurs?
  12408.  
  12409.  Response:
  12410.  
  12411.  When a fault is caused by violating the limit or access rights of a
  12412.  selector, ERRCD will contain that selector, and ERLIM and ERACC will
  12413.  contain the limit and access codes for that selector. If ERRCD does
  12414.  not contain a selector, ERLIM and ERACC will contain "**" instead.
  12415.  
  12416.  
  12417.  386. OS/2 SDK: DLL Call Gate Information
  12418.  
  12419.  Question:
  12420.  
  12421.  Does a call to a dynamic link library (DLL) go through a call gate
  12422.  mechanism? In other words, do the parameters passed to the DLL on the
  12423.  stack get transferred to a new stack?
  12424.  
  12425.  Response:
  12426.  
  12427.  A call to a DLL does not have to go through a call gate. This only
  12428.  happens when a ring transition occurs, such as when calling a ring 2
  12429.  IOPL segment function from a ring 3 code segment.
  12430.  
  12431.  
  12432.  387. INSTALL.TXT File for OS/2 SDK Version 1.06 Is Available
  12433.  
  12434.  The file 106READ.ARC contains the complete contents of the INSTALL.TXT
  12435.  file distributed with the Microsoft OS/2 Software Development Kit
  12436.  Version 1.06. This file can be found in the Software Library by
  12437.  searching for the filename 106READ.ARC, the Q number of this article,
  12438.  or S12165.
  12439.  
  12440.  The INSTALL.TXT file contains information about Version 1.06 of the
  12441.  Microsoft OS/2 Software Development Kit. The INSTALL.TXT file
  12442.  consists of the following six parts:
  12443.  
  12444.     Part     Title
  12445.  
  12446.      1       Introduction
  12447.      2       MS OS/2 SDK Components
  12448.      3       Installation Notes
  12449.      4       Miscellaneous
  12450.      5       Hardware Compatibility Caveats
  12451.      6       New SDK Owners Only
  12452.  
  12453.  
  12454.  388. Installation and General Information for OS/2 SDK 1.06
  12455.  
  12456.  The file INSTALL.TXT, "Microsoft Operating System/2 Software
  12457.  Development Kit Installation Notes Version 1.06," is included with the
  12458.  OS/2 Software Development Kit (SDK) Version 1.06. This file contains
  12459.  answers to many commonly asked questions about OS/2 SDK Version 1.06.
  12460.  This file is located on the Toolkit 1 disk. Please read this file
  12461.  before attempting to install OS/2 SDK Version 1.06 on your system.
  12462.  
  12463.  INSTALL.TXT can also be found in the Software Library by searching for
  12464.  the filename 106READ.ARC, the Q number of this article, or S12165.
  12465.  
  12466.  
  12467.  389. Dual-Boot Ability Not Supported in OS/2 SDK Version 1.06
  12468.  
  12469.  The dual-boot ability, included with previous releases of the OS/2
  12470.  Software Development Kit (SDK) is no longer included with the OS/2
  12471.  SDK Version 1.06. For more information on this and other changes to
  12472.  this release of the OS/2 SDK, refer to the file INSTALL.TXT,
  12473.  "Microsoft Operating System/2 Software Development Kit Installation
  12474.  Notes Version 1.06," located on the Toolkit 1 disk.
  12475.  
  12476.  INSTALL.TXT can also be found in the Software Library by searching for
  12477.  the filename 106READ.ARC, the Q number of this article, or S12165.
  12478.  
  12479.  
  12480.  390. OS/2 SDK Reentrancy of Multiple Copies of Program
  12481.  
  12482.  Question:
  12483.  
  12484.  Under OS/2, are multiple instances of a program running off the same
  12485.  executable file automatically reentrant? In other words, does each
  12486.  instance of an executable file get a separate data segment for static
  12487.  variables?
  12488.  
  12489.  Response:
  12490.  
  12491.  Yes. There is only one copy of the code segments in memory for each
  12492.  executable file at any one time. If the same executable file is loaded
  12493.  twice, another copy of the data segments will be made. However, if the
  12494.  application is not using any named objects, such as named pipes,
  12495.  queues, or system semaphores, and if it also does not use any of its
  12496.  own DLLs, you should not have to do anything special to run two or
  12497.  more copies.
  12498.  
  12499.  
  12500.  391. OS/2 SDK: Directly Switching to Task Manager from Application
  12501.  
  12502.  Question:
  12503.  
  12504.  Is there a way for my program to directly switch to the task manager?
  12505.  I have a text-based OS/2 application in which I would like to be able
  12506.  to switch from the text-based screen group to the Presentation Manager
  12507.  (PM) screen group by clipping the mouse on a pull-down menu item
  12508.  within the text-based OS/2 application.
  12509.  
  12510.  Response:
  12511.  
  12512.  Currently, there is no way for your program to directly switch to the
  12513.  task manager. This feature is under review and will be considered for
  12514.  inclusion in a future release.
  12515.  
  12516.  
  12517.  392. OS/2 SDK: Reason DosRead() Gets Zero Byte-Count of Bytes Read
  12518.  
  12519.  Question:
  12520.  
  12521.  We have a program that makes a named pipe, then does DosRead()s to the
  12522.  pipe and receives data from another program in another screen group.
  12523.  Sometimes the DosRead() gets a zero return value (i.e., successful
  12524.  read) but also gets zero for the byte-count of bytes read. What does
  12525.  this mean?
  12526.  
  12527.  Response:
  12528.  
  12529.  This can happen in the following cases:
  12530.  
  12531.  1. If the pipe is closed at the other end, reading 0 bytes means that
  12532.     the end of the file was reached.
  12533.  
  12534.  2. If the pipe is in message mode and the writer writes a message
  12535.     having zero bytes, the reader will get a message with zero bytes.
  12536.  
  12537.  
  12538.  393. OS/2 SDK: Using CodeView to Debug a PM Application
  12539.  
  12540.  Debugging a Presentation Manager (PM) application is most easily
  12541.  accomplished if you have a second monitor.
  12542.  
  12543.  You can also use sequential-mode debugging redirected through the COM
  12544.  port to a dumb terminal. This works well, although it is not windowed.
  12545.  It is also slower than using a second monitor.
  12546.  
  12547.  If neither of the options mentioned above are available to you, you
  12548.  will have to toggle back and forth between the PM screen group and the
  12549.  CVP screen group. This is the least desirable way of debugging an
  12550.  application because you can end up in situations where you can't
  12551.  switch screen groups because of a hang or a loss of keyboard focus.
  12552.  You will have to reboot your computer to recover from either of these
  12553.  situations.
  12554.  
  12555.  
  12556.  394. OS/2 SDK: Device-Driver-Defined Error Statuses
  12557.  
  12558.  Question:
  12559.  
  12560.  Can you provide me with information concerning device-driver-defined
  12561.  error statuses (return statuses with bit 14 set)? I would like to know
  12562.  how to use this feature and what limitations exist.
  12563.  
  12564.  Response:
  12565.  
  12566.  In case of an error, a device driver would set bit 15 and specify the
  12567.  error code in bits 0-7. The error code is processed by OS/2 in one of
  12568.  the following ways:
  12569.  
  12570.  1. If the IOCtl category is system defined, FF00H is ORed with the
  12571.     error code specified in bits 0-7.
  12572.  
  12573.  2. If the IOCtl category is user defined, FE00H is ORed with the error
  12574.     code specified in bits 0-7.
  12575.  
  12576.  3. The error code must be one that is system defined (as defined on
  12577.     Page 81 of the "Microsoft Operating System/2 Device Drivers Guide")
  12578.     and is mapped into one of the standard OS/2 API return codes.
  12579.  
  12580.  
  12581.  395. OS/2 SDK: Use of DevHelps Character Queue Management Functions
  12582.  
  12583.  Question:
  12584.  
  12585.  I need to use a pair of the Character Queue Management functions
  12586.  provided with the DevHelps in a way that raises the question whether
  12587.  they will work concurrently from the kernel and interrupt states.
  12588.  Specifically, I want to enqueue items in the kernel state, and dequeue
  12589.  them from the same queue in the interrupt state (and vice versa).
  12590.  
  12591.  Do I need to protect the kernel state DevHelps call by bracketing it
  12592.  with CLI/STI, or are these functions designed to be re-enterable in
  12593.  situations such as the one described above?
  12594.  
  12595.  Response:
  12596.  
  12597.  These calls can be used to do what is described above; however, you do
  12598.  need to bracket them by disabling interrupts if you are calling them
  12599.  at task time (kernel state).
  12600.  
  12601.  
  12602.  396. Accessing ROM Area During Initialization of Device Driver
  12603.  
  12604.  I am writing an OS/2 device driver for a hard disk. I need to access
  12605.  the ROM on my adapter board during initialization. I used the DevHelp
  12606.  functions AllocateGDTSelector() and PhysToGDTSelector() to obtain
  12607.  access to this ROM. However, when I try to access it using the
  12608.  selector given to me, I get a general protection (GP) fault. The GP
  12609.  fault occurs because the DPL = 0 for the selector. If I change the DPL
  12610.  to 3 or execute the same code during Strategy time, the code works
  12611.  properly. Is there a better way to change the IOPL of the selector (I
  12612.  modified memory to do it), or is there some other way to read the ROM
  12613.  space during Init time?
  12614.  
  12615.  Response:
  12616.  
  12617.  You would typically use PhysToVirt() during Init time to gain
  12618.  accessibility to the ROM area because it gives you temporary
  12619.  addressability to the data area that you need during Init time.
  12620.  
  12621.  You can still use PhysToGDTSelector() to allocate a GDT selector;
  12622.  however, this means that the GDT selector is permanently allocated,
  12623.  even after Init time. This may or may not be desired.
  12624.  
  12625.  
  12626.  397. OS/2 SDK: Using Floating Point Math Libraries in DLLs and EXEs
  12627.  
  12628.  Question:
  12629.  
  12630.  1. Is it possible to use the Emulator library in a DLL (Dynamic Link
  12631.     Library)? Single threaded? Multithreaded? If not, why?
  12632.  
  12633.  2. Can I use the emulator library in a regular OS/2 .EXE file?
  12634.  
  12635.  3. What options can I choose from when doing floating point operations
  12636.     in DLL and .EXE files?
  12637.  
  12638.  Response:
  12639.  
  12640.  1. The single-threaded DLL support library LLIBCDLL.LIB does not use
  12641.     emulator math; it uses only the alternate math library. The
  12642.     multithreaded DLL support library CRTLIB does use emulator math.
  12643.     Technically, it is not possible to use the emulator library in any
  12644.     DLL because you can link only to the appropriate library (LLIBCDLL
  12645.     or CRTLIB + DOSCALLS).
  12646.  
  12647.     This relates only to what the dynamically linked libraries will use
  12648.     themselves and is independent of what the calling program is doing.
  12649.     For example, you can have a program that uses an emulator math call
  12650.     into the single-threaded DLL. The same holds true for the
  12651.     multithreaded DLL support library; you can call into the library
  12652.     from an application using any floating point option.
  12653.  
  12654.  2. Yes, you can use the emulator library in a regular OS/2 .EXE file.
  12655.  
  12656.  3. There are no restrictions on which floating point option you can
  12657.     use when calling into the multithreaded dynamic link support
  12658.     library, CRTLIB or the single-threaded DLL support library. When
  12659.     creating dynamic link libraries, you can only link to the
  12660.     appropriate library that will provide either alternate (within
  12661.     LLIBCDLL) or emulator (within CRTLIB) math support within the
  12662.     dynamic link library.
  12663.  
  12664.  
  12665.  398. OS/2 SDK: How to Catch Protection Faults
  12666.  
  12667.  Question:
  12668.  
  12669.  Is there any way to catch protection faults using DosSetVec() and
  12670.  DosError()?
  12671.  
  12672.  Response:
  12673.  
  12674.  DosError() and DosSetVec() will not allow you to catch protection
  12675.  faults. To catch protection faults in an application, it is necessary
  12676.  to use the DosExecPgm() function to start up the application as a
  12677.  child with the fExecFlags parameter set to EXEC_TRACE. You then can
  12678.  use the DosPTrace() function to retrieve information about the child
  12679.  processes, including whether a general protection fault occurred.
  12680.  DosPTrace() is documented on Pages 171-175 of the "Microsoft Operating
  12681.  System/2 Programmer's Toolkit Programmer's Reference" manual for
  12682.  Version 1.00.
  12683.  
  12684.  
  12685.  399. OS/2 SDK: Return Line Control Register Documentation Error
  12686.  
  12687.  The section on Function 62H: Return Line Control Register on Page 140
  12688.  of the "Microsoft Operating System/2 Device Drivers Guide" is no
  12689.  longer up to date. The "Microsoft Operating System/2 Programmer's
  12690.  Toolkit Programmer's Reference" for Version 1.00 does contain the
  12691.  correct documentation for reading and writing to the Return Line
  12692.  Control Register; Pages 484 (SETLINCTRL) and 420 (GETLINECTRL)
  12693.  document the calls and the structures they use. These are the calls
  12694.  you should use.
  12695.  
  12696.  
  12697.  400. OS/2 SDK: General Environment Block Information
  12698.  
  12699.  Question:
  12700.  
  12701.  1. Is it possible for a child process to read the environment block of
  12702.     its parent? In other words, is the parent's environment block
  12703.     shareable?
  12704.  
  12705.  2. There is a DosGetEnv() OS/2 function, but no companion DosPutEnv()
  12706.     function. Is it correct to assume that the maintenance of the
  12707.     environment block is completely up to each program?
  12708.  
  12709.  Response:
  12710.  
  12711.  1. The parent's environment block is in memory private to the parent;
  12712.     the child process cannot access it directly.
  12713.  
  12714.  2. Yes, the maintenance of the environment block is completely up to
  12715.     each program. You can substitute the C run-time function putenv as
  12716.     a replacement for DosPutEnv().
  12717.  
  12718.  
  12719.  401. OS/2 SDK: Changing Current Drive & Directory in a Command File
  12720.  
  12721.  Problem:
  12722.  
  12723.  I have a program that parses the path and changes both the drive and
  12724.  directory. It works correctly under MS-DOS and in the compatibility
  12725.  box, but does not work in protected mode. In protected mode, the
  12726.  current drive and directory revert to the previous values at the
  12727.  completion of the program.
  12728.  
  12729.  Response:
  12730.  
  12731.  The reason your program does not work in protected mode is that the
  12732.  current drive and drive path assignments are on a per-process basis in
  12733.  protected mode. When you call the program to change the drive name and
  12734.  pathname, this creates a new process. When the process ends, the drive
  12735.  and path for the calling process have not changed.
  12736.  
  12737.  
  12738.  402. OS/2 SDK: #include Files Contain Bitwise Inclusive OR Operator
  12739.  
  12740.  Problem:
  12741.  
  12742.  The OS/2 Software Development Kit (SDK) Version 1.05 release contains
  12743.  #include files that use preprocessor directives of the following form:
  12744.  
  12745.  #if  ( defined( A ) | !defined( B ) )
  12746.  .
  12747.  .
  12748.  .
  12749.  #endif
  12750.  
  12751.  I think that the following was intended:
  12752.  
  12753.  #if  ( defined( A ) || !defined( B ) )
  12754.  .
  12755.  .
  12756.  .
  12757.  #endif
  12758.  
  12759.  It appears that the implementor intended to use the logical-OR (||)
  12760.  operator, but instead used the bitwise-inclusive-OR (|) operator.
  12761.  
  12762.  This is a nuisance when using syntax-checking utilities such as
  12763.  PC-lint for OS/2 by Gimpel Software. It correctly flags the suspicious
  12764.  usage of the bitwise operator, and the files need to be patched by
  12765.  hand each time they are updated by a new release of the OS/2 SDK.
  12766.  
  12767.  Response:
  12768.  
  12769.  Microsoft has confirmed this to be a problem in the OS/2 SDK Version
  12770.  1.05. We are researching this problem and will post new information as
  12771.  it becomes available.
  12772.  
  12773.  
  12774.  403. Characters-Per-Line Value for Set Frame Control Command
  12775.  
  12776.  Question:
  12777.  
  12778.  The parameters 80 and 132 are allowed in the characters-per-line value
  12779.  for the Set Frame Control command (function 42H) of the Printer
  12780.  Control IOCTL commands. If 132 is indicated, it outputs the control
  12781.  code for reduced characters, and it allows you to print more than 132
  12782.  characters in one line. Is this by design?
  12783.  
  12784.  Response:
  12785.  
  12786.  No, this is not by design. The only required characters-per-line
  12787.  values are 80 and 132. The printer may support many more values.
  12788.  The decision to use reduced characters is made by the device driver
  12789.  itself. It does not have to be this way, but the particular printer
  12790.  device driver you have installed does it that way. The IOCTL does not
  12791.  control the printer; it only calls the device driver.
  12792.  
  12793.  
  12794.  404. OS/2 SDK: Displaying Fonts at an Angle
  12795.  
  12796.  Question:
  12797.  
  12798.  Is it possible to use "simple" fonts on an angle? I would like to be
  12799.  able to display a sans-serif font on an angle, rather than displaying
  12800.  a serif font. The serif font looks somewhat "mushy" and is difficult
  12801.  to read when you reduce the size by 25 percent.
  12802.  
  12803.  I understand that only vector fonts can be displayed at angles.
  12804.  Ideally, I would like to use a font similar to type 6 in the OS/2
  12805.  Software Development Kit (SDK) sample program named FontTest. It looks
  12806.  like the system font with a height of 8 and width of 4.
  12807.  
  12808.  Response:
  12809.  
  12810.  You are correct; currently, only vector fonts can be displayed at
  12811.  angles. We are evaluating various ways to provide future support for
  12812.  angling bitmap fonts; however, there is no schedule yet for when or if
  12813.  this support will be implemented.
  12814.  
  12815.  The font you mentioned (#6 from FontTest) is "Helvetica proportional,"
  12816.  and it is a bitmap font; thus, it cannot be rotated. There are two
  12817.  sans-serif vector fonts in the Version 1.05 OS/2 SDK, and the Version
  12818.  1.06 OS/2 SDK also has some different fonts. There is a Helvetica
  12819.  Proportional font and a Sans Proportional font. However, neither of
  12820.  these fonts looks good at a size much smaller then 32, and rotating
  12821.  them doesn't help any. Also, the vector fonts will be noticeably
  12822.  slower to draw. Depending on your exact needs, you might want to just
  12823.  use the raster fonts, specify the rotation using mode 2, and let the
  12824.  character placement be rotated, without actually rotating each
  12825.  individual letter.
  12826.  
  12827.  
  12828.  405. OS/2 SDK: .EXE File Header Information
  12829.  
  12830.  Question:
  12831.  
  12832.  What are the meanings of the bytes at locations 0x88, 0x89, and 0x8D
  12833.  in an OS/2 program's executable file? I noticed that when I take the
  12834.  "WINDOWAPI" statement out of the module definition file, these values
  12835.  change upon relinking.
  12836.  
  12837.  Response:
  12838.  
  12839.  The bytes at those locations are the least significant portion of a
  12840.  long that is a CRC sum of the whole file. The word after the CRC sum
  12841.  is a flag that contains three bits that are set depending on the type
  12842.  of the executable. The MARKEXE program modifies this word, but does
  12843.  not bother to update the CRC. This is probably due to the fact that
  12844.  neither the DOS nor the OS/2 loader checks this CRC value.
  12845.  
  12846.  This information is included in the include file NEWEXE.H that comes
  12847.  with the OS/2 Software Development Kit (SDK).
  12848.  
  12849.  
  12850.  406. OS/2 SDK: DosOpen() Error Return Values Information
  12851.  
  12852.  Question:
  12853.  
  12854.  I have the following questions concerning DosOpen() error return
  12855.  values:
  12856.  
  12857.  1. Attempting to use DosOpen() to open a nonexistent file with
  12858.     fOpenFlags=1 returns the error of ERROR_OPEN_FAILED rather than
  12859.     ERROR_FILE_NOT_FOUND. Is this intentional?
  12860.  
  12861.  2. DosOpen() returns the error of ERROR_INVALID_DRIVE, which is not
  12862.     mentioned in the "Microsoft Operating System/2 Programmer's
  12863.     Toolkit Programmer's Reference" manual for Version 1.00.
  12864.  
  12865.  Response:
  12866.  
  12867.  1. Yes, this is expected behavior. ERROR_OPEN_FAILED will be generated
  12868.     if you attempt to do an explicit open on a file that does not
  12869.     exist. If you want to open a file and create it if it does not
  12870.     exist, you should use fOpenFlags of 0x0010.
  12871.  
  12872.     ERROR_FILE_NOT_FOUND will be generated if you pass an invalid
  12873.     filename to DosOpen(); for example, attempting to open ".xyz" will
  12874.     generate this error.
  12875.  
  12876.  2. You are correct; this error is not documented under DosOpen(). We
  12877.     plan to document this error in a future release of the
  12878.     documentation.
  12879.  
  12880.  
  12881.  407. Parent Is Blocked if Child Issues MouReadEventQueue() Call
  12882.  
  12883.  Question:
  12884.  
  12885.  I have a child process that has been started up with DosExecPgm()
  12886.  asynchronously. When the child process issues a MouReadEventQueue()
  12887.  function call, the parent process is stopped if it executes any MOU
  12888.  API function calls. Why is this happening?
  12889.  
  12890.  Response:
  12891.  
  12892.  The mouse subsystem has a per-screen group semaphore that controls
  12893.  access to the mouse from the different threads and processes in each
  12894.  screen group. When the child process executes a blocking
  12895.  MouReadEventQueue(), it takes possession of this semaphore and will not
  12896.  release it until the call completes. When the first process tries to
  12897.  do any MOU API calls that require this semaphore, it will block until
  12898.  the semaphore is freed. This is by design and is not a bug.
  12899.  
  12900.  If your application design requires you to have more than one thread
  12901.  doing MouXXX calls in the same screen group, you will need to use one
  12902.  of the following workarounds:
  12903.  
  12904.  1. Probably the best solution is to do your own drawing of the mouse
  12905.     pointer. This is not very difficult to do, and this way you can do
  12906.     your own removing and showing of the pointer.
  12907.  
  12908.  2. To bypass the mouse subsystem semaphore, do direct ioctls to the
  12909.     mouse device driver to hide and show the mouse pointer. Most of the
  12910.     high-level MOU API calls have similar DosDevIOCtl() function codes
  12911.     that can be used instead.
  12912.  
  12913.  3. You could set up a flag or a semaphore and have the child process
  12914.     not block during the mouse read. You have to be careful of this,
  12915.     however, because you don't want to consume a lot of CPU resources
  12916.     just doing polling of the mouse. You would want to be sure that you
  12917.     do a DosSleep() call within the loop so that you give other
  12918.     processes a chance to run.
  12919.  
  12920.  Note that this problem does not occur in the Presentation Manager,
  12921.  because the system handles the mouse and keyboard messages coming into
  12922.  the system.
  12923.  
  12924.  
  12925.  408. QuickHelp 1.06 IBM PS/2 Model 80-071 ENTER Key Problem
  12926.  
  12927.  Problem:
  12928.  
  12929.  While using QuickHelp, the ENTER key on the numeric keypad of my IBM
  12930.  PS/2 model 80-071 seems to be ignored. The ENTER key on the main
  12931.  keyboard works correctly.
  12932.  
  12933.  Response:
  12934.  
  12935.  Microsoft has confirmed this to be a problem with the QuickHelp
  12936.  included with the OS/2 Software Development Kit (SDK) Version 1.06. We
  12937.  are researching this problem and will post new information as it
  12938.  becomes available.
  12939.  
  12940.  
  12941.  409. OS/2 SDK QuickHelp 1.06 OVERVIEW.HLP Problems
  12942.  
  12943.  Problem:
  12944.  
  12945.  The QH.DATABASE entry states that OVERVIEW.HLP contains "descriptions
  12946.  of CMD.EXE commands." I cannot find these descriptions.
  12947.  
  12948.  Also, after paging through the OVERVIEW.HLP file, I noticed that the
  12949.  last screen displayed was not text, but instead included garbage
  12950.  characters.
  12951.  
  12952.  Response:
  12953.  
  12954.  Microsoft has confirmed both of these anomalies to be a problem with
  12955.  the QuickHelp shipped with the OS/2 SDK (Software Development Kit)
  12956.  Version 1.06. We are researching these problems and will post new
  12957.  information as it becomes available.
  12958.  
  12959.  
  12960.  410. WHERE and KBDP Are Not Listed in OS/2 SDK QuickHelp 1.06
  12961.  
  12962.  Question:
  12963.  
  12964.  When using QuickHelp, is there a way to list all the entries in a
  12965.  database or section? For example, is there a way to list all the C
  12966.  function calls or all the utilities (such as WHERE.EXE and KBDP.EXE)?
  12967.  
  12968.  Response:
  12969.  
  12970.  Other than paging through the database, there is no way to see every
  12971.  help entry.
  12972.  
  12973.  The entries for WHERE.EXE and KBDP.EXE used to be in the categories
  12974.  list for tools in previous versions of QuickHelp. Microsoft has
  12975.  confirmed that these utilities are not listed for tools in the
  12976.  QuickHelp shipped with the Version 1.06 OS/2 Software Development Kit
  12977.  (SDK). We are researching this problem and will post new information
  12978.  as it becomes available.
  12979.  
  12980.  
  12981.  411. When to Use Preserve Start-up Option in Installation Program
  12982.  
  12983.  Question:
  12984.  
  12985.  I specified the option to preserve the start-up information that
  12986.  previously existed during the installation procedure; however, when I
  12987.  rebooted OS/2, the Start Programs window was empty. Why wasn't the
  12988.  information preserved?
  12989.  
  12990.  Response:
  12991.  
  12992.  The preserve start-up option should only be used if you are going from
  12993.  IBM Version 1.00 to Version 1.10. If you have installed any of the
  12994.  intermediate releases of Version 1.10 (OS/2 SDK Version 1.03 or 1.05),
  12995.  your Start Programs window will be empty. You will need to reinstall
  12996.  the OS/2 SDK and choose not to save previous installation information.
  12997.  
  12998.  
  12999.  412. Wrong Topic Displayed in OS/2 SDK Version 1.06 QuickHelp
  13000.  
  13001.  Problem:
  13002.  
  13003.  Sometimes while using QuickHelp, the wrong topic is displayed. For
  13004.  example, I am unable to view the documentation for the Microsoft
  13005.  Editor "Window" topic, because it always brings up the information for
  13006.  the RC.EXE WINDOW command instead.
  13007.  
  13008.  Response:
  13009.  
  13010.  Microsoft has confirmed this to be a problem with the QuickHelp
  13011.  included with the OS/2 Software Development Kit (SDK) Version 1.06. We
  13012.  are researching this problem and will post new information as it
  13013.  becomes available.
  13014.  
  13015.  
  13016.  413. How to Stop QuickHelp from Exiting after Paste Is Executed
  13017.  
  13018.  Question:
  13019.  
  13020.  When the Paste option is executed, QuickHelp exits instead of
  13021.  remaining in the topic. This means that you have to keep going back
  13022.  into QuickHelp and selecting topics each time you do a Paste. Is there
  13023.  a way to prevent QuickHelp from exiting after the Paste option is
  13024.  executed?
  13025.  
  13026.  Response:
  13027.  
  13028.  Yes; there is both a command-line option and a menu option that will
  13029.  allow you to do this. If you start QuickHelp with "qh -pa [filename]",
  13030.  QuickHelp will not exit after executing the Paste option. You must
  13031.  press "X" to exit. The filename is optional, and specifies where to
  13032.  send the Paste data.
  13033.  
  13034.  If you use the Append Paste File option, all Paste operations will be
  13035.  copied to the end of the file instead of overwriting the file. When
  13036.  the Append option is chosen, QuickHelp does not automatically exit
  13037.  after a Paste command.
  13038.  
  13039.  
  13040.  414. OS/2 SDK: PRINT Commands /C and /B Option Documentation Errors
  13041.  
  13042.  Question:
  13043.  
  13044.  I have the following questions regarding the PRINT command:
  13045.  
  13046.  1. The "SYS 1526" error message states that you should use "PRINT /C";
  13047.     however, the "Microsoft Operating System/2 User's Reference" manual
  13048.     for Version 1.00 states on Pages 175-176 that you should use "PRINT
  13049.     filename /C". Which syntax is correct?
  13050.  
  13051.  2. The error message "SYS 1525" indicates that a /B option is
  13052.     available; however, this option is not documented in the "Microsoft
  13053.     Operating System/2 User's Reference" manual for Version 1.00. What
  13054.     is this option used for?
  13055.  
  13056.  Response:
  13057.  
  13058.  1. The documentation on Pages 175-176 of the "Microsoft Operating
  13059.     System/2 User's Reference" manual for Version 1.00 is incorrect.
  13060.     The correct syntax is "PRINT /C". This problem will be corrected in
  13061.     a future release of the documentation. We will post new information
  13062.     as it becomes available.
  13063.  
  13064.  2. The /B option tells the spooler to read the first CTRL+Z character
  13065.     in the file as an EOF character. The EOF character is not printed.
  13066.  
  13067.  The following are the proper syntaxes that can be used with the PRINT
  13068.  command:
  13069.  
  13070.     PRINT /C [/D:device]
  13071.     PRINT /T [/D:device]
  13072.     PRINT pathname... [/D:device] [/B]
  13073.  
  13074.  Options /B, /C, /T, and /D: are the only options the system accepts.
  13075.  
  13076.  
  13077.  415. OS/2 SDK: Various Ways to Detect Redirected Input
  13078.  
  13079.  Problem:
  13080.  
  13081.  I am trying to detect a single keystroke from the keyboard under OS/2
  13082.  in my C program; however, I need the code to be capable of being
  13083.  redirectable to the COM port. Attempting to use DOSREADASYNC on the
  13084.  STDIN handle 0 does not set "key read" until the ENTER key has been
  13085.  pressed on the main keyboard. However, redirecting it through the COM
  13086.  port works as I expect it to.
  13087.  
  13088.  Response:
  13089.  
  13090.  We have the following suggestions on various ways to accomplish this:
  13091.  
  13092.  1. This is what we consider to be the best suggestion: there is a
  13093.     DosQHandType() function that will tell you whether a handle is a
  13094.     file, a device, or a pipe. When using stdin, whether keyboard or
  13095.     COM, it returns as a device. Along with the device return is a
  13096.     device attribute word. This is unique (not necessarily, but for the
  13097.     purpose of comparing the keyboard or COM1:, it is). By using the
  13098.     device attribute word and DosQHandType(), you can then tell when
  13099.     your I/O is redirected and to what (approximately).
  13100.  
  13101.     The bits you would probably be interested in would be 0 and 1
  13102.     (stdin/stdout bits), bit 6 (generic IOCtl control), and bits 11 and
  13103.     12 (open/close bit and shared bit). You can get descriptions of all
  13104.     the fields from the "IBM Operating System/2 Version 1.10 Technical
  13105.     Reference" or the "Microsoft Operating System/2 Device Drivers
  13106.     Guide."
  13107.  
  13108.     This requires separate code, but it relieves you of the additional
  13109.     command switch(es).
  13110.  
  13111.  2. You could create a detached process that monitors the COM port and
  13112.     does one of the following two things:
  13113.  
  13114.     a. The detached process communicates with the parent through a pipe
  13115.        or queue. This would allow you to identify the source of the
  13116.        input, but it requires disjointed code.
  13117.  
  13118.     b. The detached process is a monitor that reads the COM port and
  13119.        stuffs the keyboard buffer. This will allow you to use the same
  13120.        code for reading from stdin, but it might not work as well as
  13121.        the above idea.
  13122.  
  13123.  3. Use a command-line switch that identifies that input/output has
  13124.     been redirected to another device/file. This isn't as eloquent, but
  13125.     at least you will know what is going on and which sequence of code
  13126.     to execute.
  13127.  
  13128.  
  13129.  416. OS/2 SDK: EMS Drivers for DOS Compatibility Mode
  13130.  
  13131.  The release of OS/2 provided with the Microsoft OS/2 Software
  13132.  Development Kit (SDK) does not provide a device driver for using
  13133.  LIM/EMS memory in the DOS compatibility mode. There normally are two
  13134.  kinds of EMMs (expanded memory managers): ones that use actual
  13135.  expanded memory and ones that use extended memory to emulate expanded
  13136.  memory.
  13137.  
  13138.  One form of EMM directly manipulates extended memory and simulates
  13139.  expanded memory. This form of EMM cannot be used in OS/2 because the
  13140.  driver must perform absolute memory manipulations, which OS/2 does not
  13141.  allow, for security reasons. Instead, an OS/2 device driver (an OS/2
  13142.  version of an EMM) must be written to control this EMS memory and to
  13143.  make it available to applications.
  13144.  
  13145.  The other form of EMM, which works with true expanded-memory hardware,
  13146.  is not using memory that is addressable by OS/2, because OS/2 only
  13147.  understands conventional and extended memory. Since OS/2 doesn't use
  13148.  this memory, it is theoretically possible for an EMM written as a DOS
  13149.  device driver to be loaded and to work in the OS/2 DOS compatibility
  13150.  mode. Contact your EMS board manufacturer for the availability of a
  13151.  driver that will meet this and the other requirements of being able to
  13152.  be run under OS/2.
  13153.  
  13154.  
  13155.  417. OS/2 SDK Disk/Documentation Updates/Replacements
  13156.  
  13157.  If you need any changes, replacements, or updates to disks, or if you
  13158.  have documentation requests for the OS/2 Software Development Kit
  13159.  (SDK) -- for example, if you receive disks in the wrong media size --
  13160.  please call the toll-free number provided for Microsoft OS/2 SDK
  13161.  owners. The phone number is (800) 227-4679. The people at this number
  13162.  can verify that you are properly set up to receive the latest OS/2 SDK
  13163.  disks in the proper media size, and that you have the latest OS/2 SDK
  13164.  release.
  13165.  
  13166.  
  13167.  418. Using SCSI Drives with OS/2
  13168.  
  13169.  Question:
  13170.  
  13171.  I would like to use OS/2 on a system with a SCSI disk controller. Is
  13172.  this possible? If so, how?
  13173.  
  13174.  Response:
  13175.  
  13176.  Yes, it is possible to use a SCSI drive with OS/2. However, it
  13177.  requires an OS/2 disk device driver that supports a SCSI drive. The
  13178.  Microsoft OS/2 SDK release of OS/2 does not come with such a driver.
  13179.  You must contact your system hardware OEM (or a third party SCSI drive
  13180.  hardware OEM) to obtain such a device driver to support your drive.
  13181.  
  13182.  
  13183.  419. OS/2 SDK: No Transparent Method to Take Back Giveable Memory
  13184.  
  13185.  Question:
  13186.  
  13187.  I would like to allocate a portion of giveable memory, give it to a
  13188.  process, let another process use it, and then take it back without the
  13189.  other process knowing that it was shared memory. I know that such an
  13190.  OS/2 memory API doesn't exist, but my question is the following: is
  13191.  there some function that will allow me to take back a segment I gave
  13192.  away and free it?
  13193.  
  13194.  Response:
  13195.  
  13196.  OS/2 does not have such an API, since an application that gives a
  13197.  segment of memory has no way of telling when the recipient of the
  13198.  memory is finished with it. Thus, an application cannot tell when it
  13199.  would be safe to take back this segment of memory.
  13200.  
  13201.  The normal situation in which shared segments are used between two
  13202.  applications (in this case "app1" and "app2") is as follows:
  13203.  
  13204.      app1: DosAllocSeg(giveable)     lock count = 1
  13205.      app1: DosGiveSeg(app2)          lock count = 2
  13206.      ... (apps use segment)
  13207.      app2: DosFreeSeg()              lock count = 1
  13208.      app1: DosFreeSeg()              lock count = 0
  13209.  
  13210.  The order in which app1 and app2 call DosFreeSeg() does not matter: in
  13211.  either case, both must call this API in order for the lock count to
  13212.  come down to 0. In this case, app1 is taking on more of the duties by
  13213.  calling DosGiveSeg(app2), which is in essence a DosAllocSeg() done in
  13214.  the guise of app2. Thus, app1 must allocate the segment for itself,
  13215.  allocate it for app2, and free it once. The other application, app2,
  13216.  must only free it once.
  13217.  
  13218.  The following is another situation in which shared memory services can
  13219.  be used:
  13220.  
  13221.      app1: DosAllocSeg(gettable)     lock count = 1
  13222.      app2: DosGetSeg()               lock count = 2
  13223.      ... (apps use segment)
  13224.      app2: DosFreeSeg()              lock count = 1
  13225.      app1: DosFreeSeg()              lock count = 0
  13226.  
  13227.  In this scenario, application app1 creates the segment, but this time
  13228.  with the gettable bits set. (This is in contrast with the previous
  13229.  method, in which the DosAllocSeg() call by app1 was with the giveable
  13230.  bits set.) Application app2 must call DosGetSeg() to obtain
  13231.  accessibility of the segment. (This is in contrast to the previous
  13232.  method, in which app2 didn't need to worry about GETting the segment,
  13233.  since it was GIVEn to him or her.) Then, after both apps are done,
  13234.  they can free their lock counts to the segment. In this case, just as
  13235.  in the first method, BOTH applications must call DosFreeSeg(), to
  13236.  decrement the lock counts to 0.
  13237.  
  13238.  The reason that there is no such DosTakeSeg() is that app1 generally
  13239.  would not have the information to tell it that app2 is done with a
  13240.  segment. Also, as stated earlier, this was part of the OS/2 design
  13241.  theory in the memory management area. For this reason, both
  13242.  applications must call DosFreeSeg(), and can't rely on anything else
  13243.  to do it.
  13244.  
  13245.  It is possible to implement an abstract API to take back memory using
  13246.  some method of interprocess communication and knowledge between the
  13247.  applications involved. However, this still requires that both
  13248.  applications fundamentally call DosFreeSeg().
  13249.  
  13250.  
  13251.  420. OS/2 SDK 1.06 Hangs with Error R6003, Divide By Zero
  13252.  
  13253.  On some systems, the OS/2 Software Development Kit (SDK) Version 1.06
  13254.  hangs with a run-time error R6003, divide by zero. This is caused by a
  13255.  video portion of OS/2 not recognizing the system's video adapter. OS/2
  13256.  does not understand how to work with this video card. To work around
  13257.  this problem, try using a more standard EGA or VGA card and/or
  13258.  adapter.
  13259.  
  13260.  Note that this boot error can sometimes be confused by the COM and
  13261.  MOUSE drivers. To eliminate this possibility, remove these drivers
  13262.  from the CONFIG.SYS file. This will help isolate the problem to the
  13263.  video system and will remove the possibility of mouse or serial
  13264.  hardware incompatibilities.
  13265.  
  13266.  Other possible temporary workarounds are described in the OS/2 SDK
  13267.  Version 1.05 installation notes document. See Section 4 of this
  13268.  document, which describes two alternative shells that are available
  13269.  with this release of OS/2 (i.e., two possible methods that you can try
  13270.  to get your system up and running). These shells are not available or
  13271.  supported in OS/2 SDK Version 1.06 or later, but are contained on
  13272.  older releases of the OS/2 SDK and may help you until another video
  13273.  card or adapter can be found.
  13274.  
  13275.  
  13276.  421. OS/2 SDK: Using Debugging Modules & Second Monochrome Monitor
  13277.  
  13278.  Problem:
  13279.  
  13280.  I am trying to use the debugging modules that come with the Version
  13281.  1.06 OS/2 Software Development Kit (SDK) with a VGA and a monochrome
  13282.  monitor. I have copied all three .DLL modules into \OS2\DLL and I have
  13283.  copied PMDD.SYS into \OS2. I also added the /2 switch to the
  13284.  DEVICE=C:\OS2\PMDD.SYS line in CONFIG.SYS.
  13285.  
  13286.  When Presentation Manager (PM) comes up, it displays a message at the
  13287.  bottom of the screen indicating that the debugging version has been
  13288.  installed; however, no output ever goes to the monochrome monitor.
  13289.  
  13290.  Response:
  13291.  
  13292.  The documentation in both the INSTALL.DOC and INSTALL.TXT files is in
  13293.  error regarding the switch to use for the second monochrome monitor.
  13294.  In Section 4.5.2, the documentation incorrectly states that you should
  13295.  use the /2 switch. The correct switch to use is /m.
  13296.  
  13297.  
  13298.  422. OS/2 SDK: DosPeekQueue() Documentation Errors
  13299.  
  13300.  Below is information on the documentation errors for the
  13301.  DosPeekQueue() function call in the "Microsoft Operating System/2
  13302.  Programmer's Toolkit Programmer's Reference" for Version 1.00.
  13303.  
  13304.  Page 165 of the "Microsoft Operating System/2 Programmer's Toolkit
  13305.  Programmer's Reference" for Version 1.00 incorrectly states the
  13306.  following:
  13307.  
  13308.     PULONG pulDataAddr;        address of element received
  13309.  
  13310.     It copies the element to the buffer pointed to by the pulDataAddr
  13311.     parameter
  13312.  
  13313.  Instead, it should state the following:
  13314.  
  13315.     PULONG pulDataAddr;        Address of pointer that points to
  13316.                                element read
  13317.  
  13318.     It sets the indicated buffer pointer to the address of the queue
  13319.     data.
  13320.  
  13321.  Page 166 of the "Microsoft Operating System/2 Programmer's Toolkit
  13322.  Programmer's Reference" for Version 1.00 incorrectly states the
  13323.  following:
  13324.  
  13325.     If the function waits, the function clears the semaphore identified
  13326.     by the hsem parameter as soon as the element is retrieved.
  13327.  
  13328.     pulDataAddr          Points to the buffer that receives the
  13329.                          element being retrieved from the queue
  13330.  
  13331.  Instead, it should state the following:
  13332.  
  13333.     If fNoWait is DCWW_WAIT and there is no element available,
  13334.     DosPeekQueue() will return immediately without retrieving an
  13335.     element from the queue, and the semaphore identified by the hsem
  13336.     parameter will be asynchronously cleared as soon as an element is
  13337.     written to the queue.
  13338.  
  13339.     pulDataAddr          Address of pointer to be set to point to the
  13340.                          queue element read
  13341.  
  13342.  
  13343.  423. Version 1.06 OS/2 SDK Case Changes in Certain API Calls
  13344.  
  13345.  The case of some characters in the following API calls in the BSEDOS.H
  13346.  header file included with the Version 1.06 OS/2 Software Development
  13347.  Kit (SDK) has changed. The following is a list of the old and new
  13348.  naming conventions:
  13349.  
  13350.  Old      New
  13351.  
  13352.  DosCWait DosCwait
  13353.  DosChdir DosChDir
  13354.  DosMkdir DosMkDir
  13355.  DosRmdir DosRmDir
  13356.  DosChdir DosChDir
  13357.  
  13358.  The version of QuickHelp included with the Version 1.06 OS/2 SDK still
  13359.  contains the old naming conventions for these API calls.
  13360.  
  13361.  The API names were changed for these API calls in the Version 1.06
  13362.  OS/2 SDK. QuickHelp has not yet been updated with this new information
  13363.  regarding these name changes. The other information still applies. We
  13364.  will post new information when a new release of QuickHelp is released
  13365.  that corrects this problem.
  13366.  
  13367.  You should also make sure you replace your old DOSCALLS.LIB or OS2.LIB
  13368.  files with the new ones from the Toolkit. If you use the old library
  13369.  with the new header files or the new library with the old header
  13370.  files, you will get unresolved externals when you try to link your
  13371.  program.
  13372.  
  13373.  
  13374.  424. OS/2 SDK: QuickHelp DosQFileInfo() Documentation Error
  13375.  
  13376.  Question:
  13377.  
  13378.  The documentation in QuickHelp included with the Version 1.06 OS/2
  13379.  Software Development Kit (SDK) regarding the DosQFileInfo() API call
  13380.  does not match the header files included with the Version 1.06 OS/2
  13381.  SDK. Listed below is the QuickHelp syntax from the QuickHelp files
  13382.  dated 1/6/89 and the function prototype from the BSEDOS.H header file
  13383.  with the same date.
  13384.  
  13385.  The QuickHelp syntax is as follows:
  13386.  
  13387.  USHORT DosQFileInfo(hf, usInfoLevel, pfstsInfo, cbInfoBuf)
  13388.  HFILE hf;                 /* file handle                 */
  13389.  USHORT usInfoLevel;       /* file data required          */
  13390.  PFILESTATUS pfstsInfo;    /* pointer to file-data buffer */
  13391.  USHORT cbInfoBuf;         /* length of file-data buffer  */
  13392.  
  13393.  The BSEDOS.H function prototype is as follows:
  13394.  
  13395.  USHORT APIENTRY DosQFileInfo(HFILE, USHORT, PBYTE, USHORT);
  13396.  
  13397.  In QuickHelp, the third parameter is declared to be a PFILESTATUS
  13398.  type; however, in the include file BSEDOS.H it is defined to be a
  13399.  PBYTE type. Which is correct?
  13400.  
  13401.  Response:
  13402.  
  13403.  This is an error in the include file. The correct syntax for this
  13404.  function is in QuickHelp.
  13405.  
  13406.  The third parameter of DosQFileInfo() will be changed to be a
  13407.  PFILESTATUS type for the include files that will be provided with the
  13408.  next version of the OS/2 SDK.
  13409.  
  13410.  
  13411.  425. OS/2 SDK: Piping stdout/stderr to Parent from Grandchild
  13412.  
  13413.  Problem:
  13414.  
  13415.  I'm trying to write an OS/2 utility similar to the ERROUT utility
  13416.  supplied with Microsoft C Version 5.10. I would like my utility to
  13417.  capture the stdout and stderr of all its children using a pipe and
  13418.  write that output to both the screen and a file. I'm creating an
  13419.  anonymous pipe and DUPing its write handle into both stdout and
  13420.  stderr.
  13421.  
  13422.  Response:
  13423.  
  13424.  A sample program that demonstrates a method of using anonymous pipes
  13425.  to get the stdout and stderr from both child and grandchild processes
  13426.  is located in the Software Library. This file can be found by
  13427.  searching on the filename INHERIT.ARC, the Q number of this article,
  13428.  or S12187.
  13429.  
  13430.  You will need to use the PKXARC utility to unarc the file INHERIT.ARC.
  13431.  INHERIT.ARC contains INHERIT.C. INHERIT.C demonstrates the use of
  13432.  DosMakePipe(), DosDupHandle(), and DosExecPgm() to accomplish the
  13433.  redirection of stderr and stdout handles.
  13434.  
  13435.  
  13436.  426. OS/2 SDK: EGA.SYS Doesn't Load When PROTECTONLY=YES
  13437.  
  13438.  Question:
  13439.  
  13440.  Why doesn't the device driver EGA.SYS load properly when PROTECTONLY
  13441.  is set to YES in CONFIG.SYS?
  13442.  
  13443.  Response:
  13444.  
  13445.  The device driver EGA.SYS is a MS-DOS-style device driver, and should
  13446.  only be loaded when the DOS compatibility mode of OS/2 is enabled.
  13447.  When this mode is enabled (PROTECTONLY=NO), this driver can be loaded
  13448.  properly. However, if the system is configured so that there is no
  13449.  real-mode emulation of MS-DOS (PROTECTONLY=YES), this driver (and any
  13450.  other MS-DOS-style device driver) will be rejected by the operating
  13451.  system.
  13452.  
  13453.  
  13454.  427. KbdXlate() Function in QuickHelp Gives Structure Information
  13455.  
  13456.  Problem:
  13457.  
  13458.  If I start QuickHelp, go into the Kbd category, and select KbdXlate(),
  13459.  QuickHelp transfers me into the structures category and the _KBDXLATE
  13460.  topic.
  13461.  
  13462.  Response:
  13463.  
  13464.  This is a circular reference problem in the QuickHelp database.
  13465.  Microsoft has confirmed this to be a problem in the QuickHelp included
  13466.  with the OS/2 SDK Version 1.06. We are researching this problem and
  13467.  will post new information as it becomes available.
  13468.  
  13469.  The following is the entry for KbdXlate() as it should have appeared
  13470.  in QuickHelp:
  13471.  
  13472.  #define INCL_KBD
  13473.  
  13474.  USHORT KbdXlate(pkbxlKeyStroke, hkbd)
  13475.  PKBDXLATE pkbxlKeyStroke;    /* pointer to structure for scan code */
  13476.  HKBD hkbd;                   /* keyboard handle                    */
  13477.  
  13478.  The KbdXlate() function translates a scan code and its shift states
  13479.  into a character value. The function uses the current translation
  13480.  table of the specified logical keyboard.
  13481.  
  13482.  In order to be translated, accent-key combinations, double-byte
  13483.  characters, and extended ASCII characters may require several calls to
  13484.  the KbdXlate() function.
  13485.  
  13486.  Parameters      Description
  13487.  -----------------------------------------------------------------------
  13488.  pkbxlKeyStroke  Points to the KBDTRANS structure that contains the scan
  13489.                  code to translate. It also receives the character value
  13490.                  when the function returns.
  13491.  
  13492.  hkbd            Identifies the logical keyboard. The handle must have
  13493.                  been created previously by using the KbdOpen() function.
  13494.  
  13495.  Return Value
  13496.  
  13497.  The return value is zero if the function is successful. Otherwise, it
  13498.  is an error value.
  13499.  
  13500.  See Also
  13501.  
  13502.  DosMonReg, KbdOpen, KbdSetCustXt, _KBDTRANS
  13503.  
  13504.  
  13505.  428. Redirecting Printer Output to COM2: under PM
  13506.  
  13507.  Problem:
  13508.  
  13509.  We are having problems redirecting printer output to COM2: under
  13510.  Presentation Manager (PM). We set up the printer PRINTER1 to print to
  13511.  COM2: using the Control Panel.
  13512.  
  13513.  Within a windowed command prompt, we successfully redirected output to
  13514.  COM2:. However, we cannot print using the print command. OS/2 always
  13515.  tries to print to LPT1: and then returns a "printer out of paper"
  13516.  error. Using SPOOL to redirect output to COM2: does not work either.
  13517.  
  13518.  Response:
  13519.  
  13520.  The PRINT command will always try to send output to the LPT1: device
  13521.  unless you use the /D:device parameter to specify another device, but
  13522.  even then, the only valid devices are LPT1:, LPT2:, or LPT3:. The
  13523.  SPOOL command has the options of /D:lpt1 and /O:com2, which should
  13524.  normally work; however, these features do not work in Version 1.06 of
  13525.  the OS/2 SDK. Microsoft has confirmed this to be a problem in Version
  13526.  1.06 of the OS/2 SDK. We are researching this problem and will post
  13527.  new information as it becomes available.
  13528.  
  13529.  For now, you must either use a parallel printer or print directly to
  13530.  COM2: with the "COPY file COM2" command.
  13531.  
  13532.  
  13533.  429. Sharing Interrupt with Multiple COM Ports in Device Driver
  13534.  
  13535.  Question:
  13536.  
  13537.  I am writing a COM driver that supports three COM ports and shares an
  13538.  interrupt for two of the COM ports. How does UnSetIRQ() know which of
  13539.  the ports sharing an interrupt to unset? Is the DS the deciding
  13540.  factor?
  13541.  
  13542.  Response:
  13543.  
  13544.  There is no way for UnSetIRQ() to know which COM port to unset if you
  13545.  are managing three COM ports under one interrupt. Also, UnSetIRQ() has
  13546.  no knowledge of ports; it only affects the IRQInfoTable and the 8259
  13547.  mask register. UnSetIRQ() will completely remove the interrupt
  13548.  handler, thereby affecting all devices under it. It's up to your code
  13549.  in the device driver to determine which COM port needs to be closed.
  13550.  In general, you must provide all the individual COM port control (such
  13551.  as open, close, read, write, buffering, etc.). There are no OS/2
  13552.  function calls available to help you manipulate the COM hardware.
  13553.  Using UnSetIRQ() to close one COM port will actually affect them all.
  13554.  
  13555.  
  13556.  430. OS/2 SDK: DosRead() Being Blocked on Read to Empty Pipe
  13557.  
  13558.  Question:
  13559.  
  13560.  I am trying to use a pipe to pass information between two threads. I
  13561.  am having problems with DosRead(). When the pipe is empty and I do a
  13562.  DosRead(), the process hangs. Because CodeView is hung at this point, I
  13563.  can't tell whether my DosRead() has been blocked or whether something
  13564.  else has happened.
  13565.  
  13566.  If the pipe is empty, will DosRead() return with 0 bytes read, or will
  13567.  DosRead() block the thread until the requested data is written into
  13568.  the pipe?
  13569.  
  13570.  Response:
  13571.  
  13572.  If the pipe is empty, DosRead() will block the thread until the
  13573.  requested data is written into the pipe. The DosRead() blocking
  13574.  behavior is to be expected with anonymous pipes. It is like any other
  13575.  stream I/O and therefore waits for the data rather than returning 0
  13576.  bytes read.
  13577.  
  13578.  There is a file in the Software Library named RDNMPIPE.ARC that
  13579.  includes documentation for the various named pipe function calls.
  13580.  RDNMPIPE.ARC can be found in the Software Library by searching for the
  13581.  filename, the Q number of this article, or S12189. RDNMPIPE.ARC has
  13582.  been archived with the PKARC utility. You will need to unarchive it
  13583.  with PKXARC. A copy of PKXARC can be found on the Microsoft OnLine
  13584.  Utilities Disk 2.
  13585.  
  13586.  
  13587.  431. OS/2 SDK: DosError() Critical Error Handler
  13588.  
  13589.  Question:
  13590.  
  13591.  Is there a FAPI equivalent to the DOS critical error handler INT 24 so
  13592.  that critical errors can be intercepted in OS/2?
  13593.  
  13594.  Response:
  13595.  
  13596.  Yes; the FAPI call DosError() can be used to suppress the hard error
  13597.  pop-up window message. This is just like saying to OS/2 that all hard
  13598.  errors are to be treated as if the user had selected "Fail" from the
  13599.  pop-up.
  13600.  
  13601.  If a process disables hard-error processing with DosError(), it does
  13602.  so for all forms of I/O errors. You can also disable hard-error
  13603.  processing for a specific file or device by setting special bits in
  13604.  the DosOpen() call for the device or file.
  13605.  
  13606.  DosError() allows the suppression of pop-up messages that result from
  13607.  CPU faults, such as GP faults; however, the application will still be
  13608.  terminated when a CPU fault occurs.
  13609.  
  13610.  If you use DosError() to suppress the pop-up message, your application
  13611.  will terminate unless you have set up a handler using the DosSetVec()
  13612.  call.
  13613.  
  13614.  For MS-DOS, passing a 0 to DosError() causes the system critical error
  13615.  handler to return a "Fail" code until DosError() is called again with
  13616.  an argument of 1.
  13617.  
  13618.  FAPI calls that are related to DosError() that you should look at to
  13619.  see how you want to handle your critical errors include DosErrClass(),
  13620.  DosOpen(), DosSetFHandState(), and DosSetVec().
  13621.  
  13622.  The "OS/2 Programmer's Guide" by Ed Iacobucci (Osborne McGraw-Hill)
  13623.  also contains some useful information on this topic.
  13624.  
  13625.  
  13626.  432. OS/2 SDK: DosStartSession() Error Return Code 457
  13627.  
  13628.  Question:
  13629.  
  13630.  I sometimes get an error return code of 457 when calling the
  13631.  DosStartSession() function call. What does this error mean?
  13632.  
  13633.  Response:
  13634.  
  13635.  This error is defined in the include file BSEERR.H to be
  13636.  ERROR_SMG_START_IN_BACKGROUND. This error occurs when
  13637.  DosStartSession() is called with the flag set to indicate that the
  13638.  started session should be started in the foreground, and the calling
  13639.  session is NOT in the foreground itself. This can happen when the user
  13640.  screen switches away from the session before the call to
  13641.  DosStartSession() or if the session has been switched away from
  13642.  because a VioPopUp() is in progress.
  13643.  
  13644.  Depending on what your application is trying to do, a possible
  13645.  workaround would be to change the flag to specify that the session
  13646.  should be started in the background and retry the call. Also note that
  13647.  foreground and background in the context of DosStartSession() does NOT
  13648.  mean that the process should be run detached or not detached. When you
  13649.  specify that a session should be started in the background mode, it
  13650.  simply means that it is started, but not immediately screen switched
  13651.  to.
  13652.  
  13653.  
  13654.  433. R2_to FM_ Constants (GpiSetMix) Translation Not Defined In QH
  13655.  
  13656.  In the QuickHelp section of Windows Equivalents, under SetROP2, it
  13657.  says to see the help on the R2_ constants to see how they map to the
  13658.  new FM_ constants to be used with GpiSetMix(). This translation of the
  13659.  R2_ values to the FM_values is not included in the Version 1.06 OS/2
  13660.  Software Development Kit (SDK) release of QuickHelp.
  13661.  
  13662.  The best way to make this conversion would be to look at the names
  13663.  given to the various ROP2 codes in WINDOWS.H and you should be able to
  13664.  convert the actions of those values to the appropriate FM_ values
  13665.  defined in PMGPI.H.
  13666.  
  13667.  Microsoft has confirmed this to be a problem in Version 1.06. We are
  13668.  researching this problem and will post new information as it becomes
  13669.  available.
  13670.  
  13671.  
  13672.  434. QuickHelp MENUITEM MIA_ENABLED Documentation Error
  13673.  
  13674.  There is a problem with the QuickHelp documentation on the MENUITEM
  13675.  statement under the Tools category regarding the RC.EXE program. The
  13676.  second MENUITEM statement in the Example section uses a #define that
  13677.  does not exist. The MIA_ENABLED definition should not be documented
  13678.  because it is not present in the OS2.H include file.
  13679.  
  13680.  Microsoft has confirmed this to be a problem in the QuickHelp
  13681.  included with the Version 1.06 OS/2 SDK (Software Development Kit).
  13682.  We are researching this problem and will post new information as it
  13683.  becomes available.
  13684.  
  13685.  
  13686.  
  13687.  435. QuickHelp CheckMenuItem Message Documentation Error
  13688.  
  13689.  Part of the QuickHelp documentation on the CheckMenuItem() function
  13690.  under the Windows Equivalent category is in error. The first paragraph
  13691.  after the syntax definition of the WinSendMesg() function references
  13692.  an incorrect message name. The function references the message
  13693.  MM_SETATTR, when it should actually be referencing the message
  13694.  MM_SETITEMATTR.
  13695.  
  13696.  Microsoft has confirmed this to be a problem with the QuickHelp
  13697.  included with the Version 1.06 OS/2 SDK (Software Development Kit).
  13698.  We are researching this problem and will post new information as it
  13699.  becomes available.
  13700.  
  13701.  
  13702.  
  13703.  436. Argv
  13704.  
  13705.  Problem:
  13706.  
  13707.  The environment generated for C programs in MS-DOS Version 3.30 and
  13708.  OS/2 bound programs is not the same. The contents of argv[0] are
  13709.  different depending on whether the application is a real-mode or
  13710.  protected-mode program.
  13711.  
  13712.  Under MS-DOS, the complete pathname of the EXECed program is placed in
  13713.  argv[0]. In an OS/2 bound program, only the primary part of the
  13714.  filename with no path and no extension is placed in argv[0].
  13715.  
  13716.  Response:
  13717.  
  13718.  The difference between a protected-mode and real-mode argv[0] occurs
  13719.  because the only thing that you are guaranteed to get in argv[0] is
  13720.  what the parent process (COMMAND.COM or CMD.EXE) passes to you. You
  13721.  could write a program that spawned child processes using the EXEC
  13722.  function and pass whatever you want to your children. It just so
  13723.  happens that COMMAND.COM and CMD.EXE do things differently.
  13724.  
  13725.  Microsoft has confirmed this to be a problem in Version 1.06. We are
  13726.  researching this problem and will post new information as it becomes
  13727.  available.
  13728.  
  13729.  
  13730.  437. Determining Block of Memory Allocated by DosSubAlloc()
  13731.  
  13732.  Question:
  13733.  
  13734.  Is there a way to determine the size of a block of memory allocated by
  13735.  DosSubAlloc()? It seems that the USHORT at sel:offset-8 could be used,
  13736.  but I don't want to hard code that into my program. I'm asking because
  13737.  DosSubFree() wants a block size, but I don't have that available.
  13738.  
  13739.  Also, why does DosSubFree want a size when it can read it from the
  13740.  block header? If I give it a value that is too big, it returns an
  13741.  overlap error. However, no error is returned if the value is too
  13742.  small.
  13743.  
  13744.  Response:
  13745.  
  13746.  The method of looking at sel:offset-8 is not valid. It does not work
  13747.  correctly and even if it did work, it could be changed in the future
  13748.  because the module involved is a DLL.
  13749.  
  13750.  The length of the block to free is required because you can free a
  13751.  size of memory that is less than what you allocated. If you allocated
  13752.  100 bytes, then found that you only needed 60, you could free up 40
  13753.  bytes. As a result, if your original DosSubSet() initialized a heap
  13754.  segment that was 200 bytes in size, and you did a DosSubAlloc() for
  13755.  100 bytes, then you could use the offset into the 100 bytes to do a
  13756.  DosSubFree() of less than 100 bytes. For example, this could be 40
  13757.  bytes.
  13758.  
  13759.  The bookkeeping is left up to you. The offset that you give to
  13760.  DosSubFree() does not have to be the same as the offset that you got
  13761.  back from DosSubAlloc(). You can decide how to free the memory as
  13762.  you desire. Most people want to be consistent about freeing the memory
  13763.  (from the top or bottom of the offset), though.
  13764.  
  13765.  One method for bookkeeping is similar to the 8-byte rule you mentioned
  13766.  above. You could write a couple of routines named Alloc and Free,
  13767.  which call DosSubAlloc() and DosSubFree(), respectively. Alloc could
  13768.  ask DosSubAlloc() for one or more bytes more than the application
  13769.  asked for and could store the length in byte(s). Alloc would then pass
  13770.  back the pointer to the length of the data, with the data being a
  13771.  standard offset from the pointer. Free could then look at the length
  13772.  you wanted to free and could free the memory and change the size
  13773.  accordingly.
  13774.  
  13775.  
  13776.  438. Obtaining Serial Printer Status Information
  13777.  
  13778.  Question:
  13779.  
  13780.  We are trying to use DosDevIOCtl category 5 function 66H to check the
  13781.  status of a serial printer (on-line, out of paper, etc..), but it
  13782.  seems to be returning inconsistent results. Is it supposed to work
  13783.  correctly with serial printers? If not, what can we use instead?
  13784.  
  13785.  Response:
  13786.  
  13787.  To print to the serial printer, your application must open one of the
  13788.  COM ports and use the handle returned from DosOpen (,COMx,..). When
  13789.  you use this handle in a subsequent DosDevIOCtl API for function 66H,
  13790.  it returns the "modem control output signals" instead of the "printer
  13791.  status" information. This behavior occurs because the handle
  13792.  corresponds to the COM driver. So, you cannot use any of the printer
  13793.  driver IOCtls when talking to a serial printer.
  13794.  
  13795.  To get the serial printer status information, you can write an
  13796.  application program, which sends the printer specific commands to
  13797.  the COM port and gets the response from the printer.
  13798.  
  13799.  
  13800.  439. OS/2 SDK: Using DosGetPPID() to Determine Root Process
  13801.  
  13802.  Question:
  13803.  
  13804.  I have the following questions regarding the function call,
  13805.  DosGetPPID():
  13806.  
  13807.  1. In what versions of OS/2 is DosGetPPID() supported?
  13808.  
  13809.  2. What is the "official" technique for determining whether I've
  13810.     reached the "first" process?
  13811.  
  13812.  Response:
  13813.  
  13814.  1. DosGetPPID() is only valid under OS/2 1.10.
  13815.  
  13816.  2. The supported method is to check for a parent PID of 0, which means
  13817.     you are at the root process in the chain. When the parent PID is
  13818.     returned as zero, the process has no parent. Also, if you pass zero
  13819.     as the child PID, it is assumed that you want the parent PID of the
  13820.     current calling process (i.e., your parent). This information can
  13821.     also be obtained from the structure PIDINFO in the pidParent field
  13822.     by using the DosGetPID() function call.
  13823.  
  13824.  
  13825.  440. Backward Compatibility with OS/2 Version 1.00
  13826.  
  13827.  Question:
  13828.  
  13829.  If you have a working Version 1.00 OS/2 application and you recompile
  13830.  and link it with the new OS2.LIB, API.LIB, and header files included
  13831.  with the OS/2 SDK (Software Development Kit) Version 1.06, will it
  13832.  still work on OS/2 Versions 1.00?
  13833.  
  13834.  Response:
  13835.  
  13836.  It will not work in all cases. Many APIs have changed from Versions
  13837.  1.00 to 1.10. One example is DosStartSession(), which now accepts
  13838.  almost twice as many arguments as it did originally. It has been
  13839.  updated in an upwardly compatible fashion, however.
  13840.  
  13841.  If you want your application to run on both Versions 1.00 and 1.10 of
  13842.  OS/2, you should use the includes and libraries (doscalls) from the
  13843.  latest version of OS/2 Version 1.00, NOT Version 1.10.
  13844.  
  13845.  This way you can ensure that you do not accidentally call unsupported
  13846.  or changed Version 1.10 functions. If you write for OS/2 Version 1.00,
  13847.  you can be safe in assuming that everything will be supported in
  13848.  future versions of 1.00 and 1.10. If you use the header files and
  13849.  libraries from the OS/2 Version 1.10 SDK, you run the risk of having
  13850.  things fail on a kernel that is later than Version 1.10.
  13851.  
  13852.  
  13853.  441. DosExecPgm First Argument String Parameter Information
  13854.  
  13855.  Question:
  13856.  
  13857.  When a C program is executed synchronously using the OS/2 function
  13858.  call DosExecPgm(), the "arguments" pointer must contain the program name
  13859.  so that the normal C convention of having your first argument pointer
  13860.  at argv[1] is upheld. Is this what it is supposed to do?
  13861.  
  13862.  Response:
  13863.  
  13864.  Yes; the convention used by CMD.EXE is that the first argument string
  13865.  is the program name either as it was entered on the command line or
  13866.  as it was found in a batch (.CMD) file. We suggest that you follow
  13867.  this convention to ensure the correct operation of programs (if not
  13868.  your own) that you spawn from your application with DosExecPgm().
  13869.  
  13870.  
  13871.  
  13872.  442. OS/2 SDK: Print Spooler Problem When No Printer Is Present
  13873.  
  13874.  There is a problem with the OS/2 Spool utility in the OS/2 Software
  13875.  Development Kit (SDK) Version 1.06. If you create a spool job and do
  13876.  not have a printer connected to your system, you will get a spooler
  13877.  error of PMV8006, followed by "n" number of PMV8005 errors, where "n"
  13878.  is determined by the number of times you press ENTER or Cancel for
  13879.  this error before you physically restart your system and delete the
  13880.  job file from the \SPOOL subdirectory.
  13881.  
  13882.  Microsoft has confirmed this to be a problem in Version 1.06. We are
  13883.  researching this problem and will post new information as it becomes
  13884.  available.
  13885.  
  13886.  
  13887.  443. OS/2 SDK: Problem with SETCOM40 Command
  13888.  
  13889.  Problem:
  13890.  
  13891.  There appears to be a problem with SETCOM40. In the DOS 3.x mode, I
  13892.  issue a SETCOM40 COM2=ON command, which produces normal behavior with
  13893.  my software communications package. After exiting from my software
  13894.  communications package, I issue a SETCOM40 COM2=OFF command, which
  13895.  produces a "SYS0049 The COM2 device is not functioning" error,
  13896.  followed by a "SYS2087 Port can not be opened" error when the error is
  13897.  returned to SETCOM40.
  13898.  
  13899.  The port is still available and functions correctly in the DOS 3.x
  13900.  mode, but it is not available in protected mode. I must reboot my
  13901.  system to make the port available again in protected mode.
  13902.  
  13903.  Response:
  13904.  
  13905.  Microsoft has confirmed this to be a problem in Version 1.06 of the
  13906.  OS/2 Software Development Kit (SDK). We are researching this problem
  13907.  and will post new information as it becomes available.
  13908.  
  13909.  
  13910.  444. OS/2 SDK: No FAPI Equivalent for MS-DOS IOCtl 4406H or 4407H
  13911.  
  13912.  Question:
  13913.  
  13914.  Are there FAPI equivalents for the MS-DOS Interrupt 21H IOCtl services
  13915.  4406H (check input status) and 4407H (check output status)?
  13916.  
  13917.  Response:
  13918.  
  13919.  No, there is no FAPI that is the equivalent of either of these
  13920.  functions. These IOCtl functions are only generated by the DOS
  13921.  emulation mode. No OS/2 API can cause the file system to generate
  13922.  these functions. OS/2 block device drivers will never get these calls.
  13923.  OS/2 character device drivers may get these calls, if called from a
  13924.  DOS application.
  13925.  
  13926.  
  13927.  445. OS/2 DosDevIOCtl() GETDEVICEPARAMS "bMedia" Not Documented
  13928.  
  13929.  There is no documentation in either QuickHelp or the hard-copy
  13930.  documentation concerning the meaning of the field bMedia in the
  13931.  DosDevIOCtl() GETDEVICEPARAMS.
  13932.  
  13933.  Microsoft has confirmed that the bMedia field is not documented in
  13934.  either QuickHelp or the hard-copy documentation. We are researching
  13935.  this problem and will post new information as it becomes available.
  13936.  Below is some information regarding bMedia.
  13937.  
  13938.  The bMedia field of the BIOS Parameter Block structure returned in the
  13939.  GETDEVICEPARAMS function of the OS/2 DosDevIOCtl() API is the media
  13940.  descriptor byte. The following is information on the Media Descriptor
  13941.  Byte that is included in the "MS-DOS Version 4.00 Programmer's
  13942.  Reference" manual:
  13943.  
  13944.     2.8 The Media Descriptor Byte
  13945.  
  13946.     In MS-DOS, the media descriptor byte is used to inform the DOS
  13947.     that a different type of media is present. The media descriptor
  13948.     byte can be any value between 00h and FFh. It does not need to
  13949.     be the same as the FAT ID byte. The FAT ID byte, which is the
  13950.     first byte of the FAT, was used in MS-DOS 1.00 to distinguish
  13951.     between different types of disk media, and may be used as well
  13952.     under 2.x and 3.x [and 4.x] disk drivers. However, FAT ID bytes
  13953.     have significance only for block device drivers where non-FAT ID
  13954.     bit is not set (0). Values of the media descriptor byte or the
  13955.     FAT ID byte have no significance to MS-DOS. They are passed to
  13956.     the device driver so that programs can determine the media type.
  13957.  
  13958.  The following are some standard media descriptor bytes, taken from
  13959.  Section 3.7 of this same reference:
  13960.  
  13961.     Table 3.1: MS-DOS Standard Removable-Disk Formats
  13962.  
  13963.     -----------------------------------------------------------
  13964.     Disk Size in inches              5.25              8
  13965.     -----------------------------------------------------------
  13966.     WORD no. heads              1   1   2   2     1    2    1
  13967.     Tracks/side                 40  40  40  40    77   77   77
  13968.     WORD sectors/track          8   9   8   9     26   26   8
  13969.     WORD bytes/sector           512 512 512 512   128  128  024
  13970.     BYTE sectors/ cluster       1   1   2   2     4    4    1
  13971.     WORD reserved sectors       1   1   1   1     1    4    1
  13972.     Byte no. FATs               2   2   2   2     2    2    2
  13973.     WORD root directory entries 64  64  112 112   68   68   192
  13974.     WORD no. sectors            320 360 640 720   2002 2002 616
  13975.     BYTE media descriptor       FE  FC  FF  FD    *FE  FD   *FE
  13976.     WORD sectors/FAT            1   2   1   2     6    6    2
  13977.     WORD no. hidden sectors     0   0   0   0     0    0    0
  13978.     -----------------------------------------------------------
  13979.     *The two media descriptor bytes are the same for 8" disks
  13980.     (FEH). This is not a misprint. To establish whether a disk
  13981.     is single- or double-density, try a read of a single-density
  13982.     address mark. If an error occurs, the media is double-density.
  13983.  
  13984.     Table 3.2: MS-DOS Standard Removable-Disk Formats (High-Density)
  13985.  
  13986.     ----------------------------------------------------------
  13987.     Disk Size in inches       3.5 or 5.25       3.5     5.25
  13988.     ----------------------------------------------------------
  13989.     WORD no. heads          1   2   2    2       2       2
  13990.     Tracks/side             80  80  80   80      80      80
  13991.     WORD sectors/track      8   9   8    9       18      15
  13992.     WORD bytes/sector       512 512 512  512     512     512
  13993.     BYTE sectors/cluster    2   2   2    2       1       1
  13994.     WORD reserved sectors   1   1   1    1       1       1
  13995.     BYTE no. FATs           2   2   2    2       2       2
  13996.     WORD root dir entries   112 112 112  112     224     224
  13997.     WORD no. sectors        640 720 1280 1440    2880    2400
  13998.     BYTE media descriptor*  FA  FC  FB   F9      F0      F9
  13999.     WORD sectors/FAT        1   2   2    3       9       7
  14000.     WORD no. hidden sectors 0   0   0    0       0       0
  14001.     ----------------------------------------------------------
  14002.     *The value F0H in the media descriptor byte may be used to
  14003.     describe other media types.
  14004.  
  14005.  
  14006.  446. How OS/2 Handles "Badly-Behaved" Applications
  14007.  
  14008.  Question:
  14009.  
  14010.  We have noticed that there is a problem with poorly written
  14011.  Presentation Manager (PM) programs. For example, sometimes the
  14012.  terminal emulator that we are using will hang the system for quite
  14013.  some time if you ask it to dial a modem on a communications port
  14014.  without a modem hooked up. We understand that the terminal emulator
  14015.  should have multiple threads to avoid this problem, but it doesn't.
  14016.  
  14017.  To the beginning user who isn't very familiar with OS/2, OS/2 appears
  14018.  to be very slow or it appears to be a system with performance
  14019.  problems, when in fact this isn't true. What is the best way to handle
  14020.  this problem?
  14021.  
  14022.  Response:
  14023.  
  14024.  Synchronization problems go beyond mouse and keyboard messages. When a
  14025.  PM program handles any message and decides to undertake an
  14026.  indefinitely long activity without calling WinGetMsg() or
  14027.  WinPeekMsg(), it creates a bottleneck in the send message activity
  14028.  that occurs between windows. As a result of this, it appears that the
  14029.  system is hung.
  14030.  
  14031.  Messages that are sent [via WinSendMsg()] are not interrupts. They do
  14032.  not override messages currently being processed. These messages sent
  14033.  via WinSendMsg() send messages that are block waiting for the
  14034.  "badly-behaved" application to finish processing the message. While
  14035.  blocking, other windows may attempt to send messages to either of
  14036.  these applications (the application with a blocked send message, or
  14037.  the badly-behaved application). These processes will also block on
  14038.  their send messages. This sequence of events continues, and ends up
  14039.  blocking most of the threads with windows in the system.
  14040.  
  14041.  The problem described above normally is encountered by the user when
  14042.  attempting to switch to another window while the badly-behaved
  14043.  application is holding up message processing. Many messages are sent
  14044.  at this time to switch focus, activation, selection, adjust window
  14045.  z-order, etc. Since messages sent to the badly-behaved application
  14046.  block, the switch to the other window cannot be completed and the
  14047.  bottleneck occurs.
  14048.  
  14049.  A feature does exist in the current PM system for dealing with
  14050.  badly-behaved applications. If task switches cannot be made using
  14051.  hotkeys such as CTRL+ESC, ALT+ESC, or by using the mouse, a message
  14052.  box will appear informing the user that an application is failing to
  14053.  process its messages, and asks if this application should be shut
  14054.  down. When a task switch is requested, a timer is set at approximately
  14055.  15 seconds. If the switch does not occur in that time, the system
  14056.  walks through the list of blocked send messages to determine which
  14057.  application is the badly-behaved application.
  14058.  
  14059.  Only by destroying the process (badly-behaved application), or by the
  14060.  process completing its message processing, will the send messages be
  14061.  processed and the blocked send messages released. The situation
  14062.  described above only works for normal window threads. If a message
  14063.  queue thread boosts its priority to time-critical and goes into an
  14064.  infinite loop, the message box for killing badly-behaved applications
  14065.  cannot come up. Time-critical threads do as their name implies: they
  14066.  allow handling of critical events without interference. If the
  14067.  terminal emulator described above uses this type of technique, then it
  14068.  is by design and the system will not interfere with it.
  14069.  
  14070.  
  14071.  447. OS/2 DosDevIOCtl GETDEVICEPARAMS Doesn't Work with MS-DOS 3.x
  14072.  
  14073.  The FAPI call DosDevIOCtl(pbBPB, bpCommand, 0x0063, 0x0008, hDevice)
  14074.  (GETDEVICEPARAMS) does not work correctly under MS-DOS Version 3.30.
  14075.  It returns an "invalid command" error.
  14076.  
  14077.  The error is returned because this function call is not supported
  14078.  under MS-DOS Versions 3.x.
  14079.  
  14080.  
  14081.  448. OS/2 SDK: BPB Structure for Device Documentation
  14082.  
  14083.  The structure for the device of the BPB is not documented in either
  14084.  QuickHelp or the printed documentation.
  14085.  
  14086.  The BPB structures for the device and the current media are identical.
  14087.  The only difference is what is returned in the structure. If you are
  14088.  looking for the device BPB, the parameters for the device are
  14089.  returned. If you are looking for the current media, the parameters for
  14090.  the disk in the device are returned. For example, if you had a 360K
  14091.  disk in a 1.2-megabyte disk drive, the parameters would change,
  14092.  depending on whether you were looking for the device or the actual
  14093.  disk in the drive.
  14094.  
  14095.  We will clarify this information in a future release of the
  14096.  documentation.
  14097.  
  14098.  
  14099.  449. OS/2 SDK: DosErrClass() Not Documented Correctly in QuickHelp
  14100.  
  14101.  In QuickHelp, the error handling topic mentions "DosErrorClass()" in
  14102.  its body, but the API name is actually "DosErrClass()" (which does
  14103.  appear in the reference list).
  14104.  
  14105.  Microsoft has confirmed this to be a problem with the QuickHelp
  14106.  included with the Version 1.06 OS/2 SDK (Software Development Kit). We
  14107.  are researching this problem and will post new information as it
  14108.  becomes available.
  14109.  
  14110.  
  14111.  450. OS/2 SDK: Maximum Length Allowed for PATH in CONFIG.SYS
  14112.  
  14113.  Question:
  14114.  
  14115.  What is the maximum length allowed for subdirectory names in the PATH
  14116.  command in CONFIG.SYS?
  14117.  
  14118.  Response:
  14119.  
  14120.  When using Microsoft OS/2 Version 1.00 (OS/2 SDK Version 1.02), the
  14121.  PATH environment variable is restricted to 128 characters, a
  14122.  restriction made by the command-line buffer length of CMD.EXE. Under
  14123.  OS/2 Version 1.10 (OS/2 SDK Version 1.06), this restriction has been
  14124.  changed to 512 characters.
  14125.  
  14126.  To get around this restriction, you could use short subdirectory
  14127.  names. For example, you could use \LMP for LAN Manager in protected
  14128.  mode, and \LMR for LAN Manager in real mode. This naming convention
  14129.  would work because the LAN Manager allows you to specify the directory
  14130.  in which you want the LAN Manager installed. Also, you could
  14131.  consolidate by keeping most of your executables in subdirectories
  14132.  named \BINR, \BINP, and \BINB.
  14133.  
  14134.  
  14135.  451. OS/2 SDK: MARKEXE Return Values
  14136.  
  14137.  Question:
  14138.  
  14139.  MARKEXE is setting the error level to 3 for some of my .EXE files.
  14140.  What does this mean? The .EXE files seem to work in a window, but I
  14141.  hesitate to release them for general use because of the nonzero error
  14142.  level returned.
  14143.  
  14144.  Response:
  14145.  
  14146.  You need not be concerned with this error. Currently, MARKEXE does not
  14147.  explicitly set its return code; therefore, the return value returned
  14148.  from it is not meaningful. If you do a comparison of the file before
  14149.  and after running MARKEXE on it, you should only notice a 1-byte
  14150.  change in the OS/2 header that specifies what type of an executable
  14151.  the file is. In a future release of MARKEXE, we plan to make the
  14152.  return value information returned more meaningful.
  14153.  
  14154.  
  14155.  452. ANSI Key Reassignment Problem in OS/2 SDK
  14156.  
  14157.  There is a problem with ANSI key reassignments in the Version 1.06
  14158.  OS/2 Software Development Kit (SDK). The following steps show how
  14159.  to reproduce the problem:
  14160.  
  14161.  1. Start up a new copy of CMD.EXE from an existing copy of CMD.EXE.
  14162.  
  14163.  2. Perform a key reassignment by sending an ASCII escape sequence to
  14164.     redefine the key sequences to the screen. For example, the key
  14165.     sequence "ESC[65;81p" will redefine the "A" key to the "Q" key.
  14166.  
  14167.  3. Exit the child process and return to the parent CMD.EXE process.
  14168.  
  14169.  4. In the parent process, the key reassignment has been released. If
  14170.     you press the "A" key, an "A" will be displayed, instead of the
  14171.     redefined "Q" key.
  14172.  
  14173.  5. Repeat Steps 1 to 3 (above) a few times. The key reassignment in
  14174.     the child process will remain; if you press the "A" key, a "Q" will
  14175.     be displayed.
  14176.  
  14177.  Microsoft has confirmed this to be a problem in Version 1.06 of the
  14178.  OS/2 SDK. We are researching this problem and will post new
  14179.  information as it becomes available.
  14180.  
  14181.  
  14182.  
  14183.  453. OS/2 SDK: Freeing Virtual Address in DevHlp PhysToUVirt()
  14184.  
  14185.  Question:
  14186.  
  14187.  In the DevHlp PhysToUVirt(), does the virtual address have to be freed
  14188.  (request type #2) when you no longer need it?
  14189.  
  14190.  Response:
  14191.  
  14192.  Yes, we advise that you use "request type = 2" to free the selector;
  14193.  otherwise, the selector will stay in the LDT (local descriptor table)
  14194.  of the process.
  14195.  
  14196.  
  14197.  454. OS/2 SDK: Using Logo Display Option in Control Panel
  14198.  
  14199.  Question:
  14200.  
  14201.  What is the purpose of the Logo Display option available in the
  14202.  Control Panel in the OS/2 Software Development Kit (SDK) Version 1.06?
  14203.  
  14204.  Response:
  14205.  
  14206.  The Logo Display option allows you to add certain entries to the
  14207.  OS2.INI file so that other applications can check this entry to
  14208.  determine how long they should display a start-up logo screen before
  14209.  continuing. Some of the applications that do this are ICONEDIT,
  14210.  DLGBOX, and FONTEDIT. Please note that this is only a convention and
  14211.  does not affect applications that are not written to check the OS2.INI
  14212.  value for logo display.
  14213.  
  14214.  
  14215.  455. OS/2 SDK: Loading All Databases in the QuickHelp Directory
  14216.  
  14217.  Question:
  14218.  
  14219.  I have created my own QuickHelp database and have put it into the
  14220.  same directory as the databases that came with QuickHelp. My "qh"
  14221.  variable points to this directory. When I bring up QuickHelp, my
  14222.  database is not loaded automatically like the supplied databases.
  14223.  I can set my "qh" variable to include a -d <my database name>
  14224.  after the path and it works fine, but what if I create a second
  14225.  database? Is there some way to get QuickHelp to load all databases
  14226.  in the QuickHelp directory?
  14227.  
  14228.  Response:
  14229.  
  14230.  For now, you will have to add each new database name to the command
  14231.  line (or environment) using the -d switch, as in the following
  14232.  example:
  14233.  
  14234.     qh=d:\qh d:\qh\foo.hlp d:\qh\bar.hlp
  14235.  
  14236.  This will open the default databases from the d:\qh directory and also
  14237.  open the two additional databases "foo.hlp" and "bar.hlp" from their
  14238.  respective subdirectories.
  14239.  
  14240.  Please note that if you use the "qh" environment variable, you do
  14241.  not have to use the -d switch. This is required only when you invoke
  14242.  QuickHelp from the command line without a "qh" variable in the
  14243.  environment.
  14244.  
  14245.  Microsoft is considering changing this behavior so that QuickHelp will
  14246.  be allowed to open all *.hlp files in the directory passed by the "qh"
  14247.  variable or on the command line. We will post new information as it
  14248.  becomes available.
  14249.  
  14250.  
  14251.  456. OS/2 SDK: Trapping Critical Errors
  14252.  
  14253.  Question:
  14254.  
  14255.  Is it possible to capture critical errors such as the following?
  14256.  
  14257.     Drive Door Not Open.
  14258.     Printer not turned on.
  14259.     Disk out of space.
  14260.  
  14261.  We would like to trap the critical errors and display our own error
  14262.  messages/warnings rather than have the operating system step in and
  14263.  display the black and white monitor screen with the "retry, ignore,
  14264.  abort" options.
  14265.  
  14266.  Response:
  14267.  
  14268.  It is possible to tell the operating system that file I/O operations
  14269.  that would cause a hard-error pop-up should return a unique error code
  14270.  instead. You do this by specifying the 0x2000 bit flag in the
  14271.  fsOpenMode (seventh parameter) to DosOpen(). When this bit is set in
  14272.  the open mode parameter to DosOpen(), any subsequent calls that
  14273.  operate on that handle, with the exception of DosDevIOCtl(), will
  14274.  return an error code instead of invoking a hard-error pop-up. For
  14275.  instance, if you remove the floppy disk that you have just opened a
  14276.  file on using DosOpen(), and you do a DosWrite() on that file, the
  14277.  DosWrite() call will fail with a return code.
  14278.  
  14279.  
  14280.  457. Killing Hung Programs in DOS 3.x Box or in Protected Mode
  14281.  
  14282.  Question:
  14283.  
  14284.  How do you kill a hung program that is/was running in either the DOS
  14285.  3.x box or in protected mode?
  14286.  
  14287.  Response:
  14288.  
  14289.  This depends on how the program is hung, but the normal DOS methods
  14290.  apply to the DOS 3.x box. You should first try pressing CTRL+C,
  14291.  then CTRL+BREAK. If this doesn't work, switch to any
  14292.  protected-mode programs that you have running, close them down in
  14293.  an orderly fashion, then use CTRL+ALT+DEL to reboot the computer.
  14294.  
  14295.  The same method applies for protected mode programs, except that you
  14296.  can also send a kill signal to the process if you know its Process ID
  14297.  (PID). You would do this using the DosKillProcess() call. Another
  14298.  possibility is to use the Presentation Manager (PM) shell to force the
  14299.  application to be sent a kill signal. To do this, use the control menu
  14300.  for either the icon of the session that contains the program that is
  14301.  hung, or the system menu for the hung session, if that session is in a
  14302.  VIO window. In either case, bring up the control menu by either
  14303.  clicking on the icon or clicking on the control menu control in the
  14304.  upper left corner of the window and selecting "Close". The system will
  14305.  confirm that you want to close the session and then should recover.
  14306.  
  14307.  
  14308.  458. VioQueryFonts() QuickHelp Documentation Problem
  14309.  
  14310.  The version of Quickhelp included with the Version 1.06 OS/2 SDK
  14311.  (Software Development Kit) defines VioQueryFonts() with six
  14312.  parameters. VioQueryFonts() actually has seven parameters. Below is
  14313.  the correct documentation for VioQueryFonts().
  14314.  
  14315.  USHORT VioQueryFonts(pcbMetrics, pfm, cbMetrics, pcFonts,
  14316.                       pszFacename, flOptions, hvps)
  14317.  PLONG pcbMetrics;    /* pointer to variable for structure length */
  14318.  PFONTMETRICS pfm;    /* pointer to structure for font metrics    */
  14319.  LONG cbMetrics;      /* length of structure                      */
  14320.  PLONG pcFonts;       /* pointer to variable for number of fonts  */
  14321.  PSZ pszFacename;     /* pointer to string for face name          */
  14322.  ULONG flOptions;     /* enumeration options                      */
  14323.  HVPS hvps;           /* presentation-space handle                */
  14324.  
  14325.  The VioQueryFonts() function retrieves a font-metrics structure (or
  14326.  structures) that contains characteristics of the fonts that match the
  14327.  specified face name. These characteristics, or font metrics, are
  14328.  returned for as many matching fonts as will fit in the structure
  14329.  pointed to by the pfm parameter.
  14330.  
  14331.  After examining the returned data, the application selects the font
  14332.  most appropriate for its requirements, and if necessary, forces
  14333.  selection of a particular font by specifying the lMatch field (as
  14334.  returned in the pfm parameter) in the FATTRS structure for the
  14335.  VioCreateLogFont() function.
  14336.  
  14337.  By specifying zero for the pcFonts parameter and then examining the
  14338.  value returned, the application determines how many fonts match the
  14339.  specified face name.
  14340.  
  14341.  All sizes are returned in world coordinates. For more information,
  14342.  refer to the "Microsoft Operating System/2 Programmer's Reference,"
  14343.  Volume 1.
  14344.  
  14345.  Parameters   Description
  14346.  --------------------------------------------------------------------
  14347.  pcbMetrics   Points to the variable that receives the length (in
  14348.               bytes) of each FONTMETRICS structure. The structure
  14349.               pointed to by the pfm parameter must contain the number
  14350.               of bytes given by pcFonts x pcMetrics.
  14351.  
  14352.  pfm          Points to the FONTMETRICS structure that receives the
  14353.               font metrics of the specified matching fonts. The format
  14354.               for each record is defined in the GpiQueryFontMetrics()
  14355.               function.
  14356.  
  14357.  cbMetrics    Specifies the length (in bytes) of the font-metrics
  14358.               structure(s).
  14359.  
  14360.  pcFonts      Points to the variable that receives the number of fonts
  14361.               for which the application requires metrics.
  14362.  
  14363.  pszFacename  Points to the null-terminated string that specifies the
  14364.               face name.
  14365.  
  14366.  flOptions    Specifies whether to enumerate public or private fonts.
  14367.               This parameter may be any combination of the following
  14368.               values:
  14369.  
  14370.               Value        Meaning
  14371.               --------------------------------------------------------
  14372.               VQF_PUBLIC   Enumerate public fonts.
  14373.  
  14374.               VQF_PRIVATE  Enumerate private fonts.
  14375.  
  14376.  hvps         Identifies the advanced video-input-and-output (AVIO)
  14377.               presentation space. This handle must have been created
  14378.               previously by using the VioCreatePS() function.
  14379.  
  14380.  Return Value
  14381.  
  14382.  The return value is the number of fonts not retrieved. The return
  14383.  value is -1 if an error occurs.
  14384.  
  14385.  See Also
  14386.  
  14387.  GpiQueryFonts, VioCreateLogFont, VioCreatePS, _FATTRS, _FONTMETRICS
  14388.  
  14389.  
  14390.  459. OS/2 SDK: ALT+ESC Doesn't Select Foreground Session Correctly
  14391.  
  14392.  Microsoft has confirmed that there is a problem with OS/2 not
  14393.  selecting foreground sessions correctly in the OS/2 Software
  14394.  Development Kit (SDK) Versions 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, and
  14395.  1.06. We are researching this problem and will post new information as
  14396.  it becomes available.
  14397.  
  14398.  The following steps reproduce the problem:
  14399.  
  14400.  1. Start up PARENT.EXE in a session.
  14401.  
  14402.  2. Start up MEP.EXE.
  14403.  
  14404.  3. Have PARENT.EXE do a DosStartSession() to start up CHILD.EXE
  14405.     (specifying "related").
  14406.  
  14407.  4. Use DosSetSession() to establish a "bond" so that when the parent
  14408.     session (PARENT.EXE) is selected by the user, the child session
  14409.     (CHILD.EXE) will be brought to the foreground session instead.
  14410.  
  14411.  5. The Task Manager (or the Program Selector in Version 1.00) now
  14412.     looks like the following:
  14413.  
  14414.        Start Programs
  14415.  
  14416.        PARENT.EXE
  14417.        MEP.EXE
  14418.        CHILD.EXE
  14419.  
  14420.  6. If you press ALT+ESC to switch between the sessions, the MEP.EXE
  14421.     session will be skipped in the sequence.
  14422.  
  14423.  Keywords: buglist1.03 buglist1.04 buglist1.05 buglist1.06
  14424.  
  14425.  
  14426.  460. OS/2 SDK: Accessing Buffer Memory on an Auxiliary Memory Board
  14427.  
  14428.  Question:
  14429.  
  14430.  If the processor is going to access buffer memory on an auxiliary
  14431.  board, does the physical address of the memory have to be above 1
  14432.  megabyte, rather than in the standard ranges used for MS-DOS?
  14433.  
  14434.  Response:
  14435.  
  14436.  The memory on the auxiliary board should be mapped to an address range
  14437.  such that there is no conflict with the memory already present in the
  14438.  system. Conventionally, a ROM BIOS is mapped in the 640K to 1 megabyte
  14439.  range.
  14440.  
  14441.  If you do not want the memory manager to manage the buffer memory on
  14442.  the auxiliary board, this block of memory should be placed in a
  14443.  disjoint address space.
  14444.  
  14445.  
  14446.  461. Interpreting High-Order Byte Returned by DosGetVersion()
  14447.  
  14448.  The following is information about how to translate the high-order and
  14449.  low-order bytes of the DosGetVersion() function call into the major
  14450.  and minor version values.
  14451.  
  14452.  The high-order byte of DosGetVersion() is the major version and the
  14453.  low-order byte is the minor version. The current values returned in
  14454.  the major version byte represent the major version multiplied by 10,
  14455.  and the current values returned in the minor version byte represent a
  14456.  two-digit minor version. Thus, 10.00 translates to OS/2 Version 1.00,
  14457.  and 10.10 translates to OS/2 Version 1.10. The minor version byte has
  14458.  the potential to contain a two digit number. For example, a minor
  14459.  release of OS/2 Version 1.00 could have been called 1.01. To date, the
  14460.  least significant digit of this minor version byte has not been used.
  14461.  
  14462.  The following table lists the values of the high-order and low-order
  14463.  bytes of released OS/2 versions and what they translate to:
  14464.  
  14465.      Word    Hibyte    Lobyte  Version
  14466.      ----------------------------------
  14467.      0A00h  0Ah (10)  00h (00)   1.0
  14468.      0A0Ah  0Ah (10)  0Ah (10)   1.1
  14469.  
  14470.  
  14471.  462. OS/2 SDK: Large RAM Disks Used with VDISK.SYS Hang OS/2
  14472.  
  14473.  Microsoft has confirmed that there is a problem with the version of
  14474.  VDISK.SYS included with Versions 1.00, 1.01, 1.02, 1.03, 1.04, 1.05,
  14475.  1.06, and 1.10 of the OS/2 Software Development Kit (SDK). If a very
  14476.  large size for VDISK.SYS is specified, the system will not behave
  14477.  properly. With smaller sizes, the system will not have enough extended
  14478.  memory to operate without swapping to disk, so response time will
  14479.  increase and system performance will decrease. However, with extremely
  14480.  large virtual RAM disks (such as a 3-megabyte RAM disk on a system
  14481.  with 4 megabytes of extended memory), the system will hang
  14482.  unpredictably.
  14483.  
  14484.  We are researching this problem and will post new information as it
  14485.  becomes available. The workaround is to not use a very large virtual
  14486.  RAM disk with VDISK.SYS, so that the system will have enough extended
  14487.  memory to work properly and efficiently.
  14488.  
  14489.  Keywords: buglist1.03 buglist1.04 buglist1.05 buglist1.06 buglist1.10
  14490.  
  14491.  
  14492.  463. OS/2 SDK: System Not Closing Open Keyboard Handle
  14493.  
  14494.  Microsoft has confirmed that there is a problem with the system not
  14495.  closing the logical keyboard if the program that opened the keyboard
  14496.  fails to close it before exiting. This problem can be duplicated by
  14497.  running the KBDOPEN.C program below at least 17 times in a row in a
  14498.  Presentation Manager (PM) text window (e.g. with CMD.EXE). The program
  14499.  will fail with a return code of 440 (ERROR_KBD_NO_MORE_HANDLE). The
  14500.  program can be run an unlimited number of times full screen with no
  14501.  failure. The program is as follows:
  14502.  
  14503.  KBDOPEN.C:
  14504.  
  14505.  #define  INCL_SUB
  14506.  #include <os2.h>
  14507.  #include <stdio.h>
  14508.  main()
  14509.     {
  14510.     HKBD keyboard;
  14511.     USHORT rc;
  14512.     if (rc = KbdOpen(&keyboard))
  14513.        printf("Keyboard open failed, rc = %d\n", rc);
  14514.     }
  14515.  
  14516.  Microsoft has confirmed this to be a problem in Version 1.06. We are
  14517.  researching this problem and will post new information as it becomes
  14518.  available.
  14519.  
  14520.  To work around this problem, you must close the logical keyboard,
  14521.  using an exitlist routine if necessary.
  14522.  
  14523.  
  14524.  464. OS/2 SDK: Support of 16550 UART in OS/2 1.00 and 1.10
  14525.  
  14526.  Question:
  14527.  
  14528.  In addition to the 8250 UART and the 16450 UART, does the OS/2 COM
  14529.  device driver provide support for the 16550 UART?
  14530.  
  14531.  Response:
  14532.  
  14533.  The 16550 UART initializes itself in 16450 emulation mode and thus
  14534.  operates exactly as a 16450, using none of the extra abilities of this
  14535.  newer generation UART (such as FIFO buffers, etc.). Therefore, the
  14536.  OS/2 COM device drivers of OS/2 Versions 1.00 and 1.10 will work with
  14537.  the 16550 UART, treating it like a fast 16450 UART.
  14538.  
  14539.  
  14540.  465. Information and Guidelines to Use When Submitting OS/2 SRs
  14541.  
  14542.  ISVONLY |
  14543.  
  14544.  The following is a list of the information that Microsoft needs to
  14545.  process your OS/2 Service Requests:
  14546.  
  14547.  1. Hardware configuration
  14548.  
  14549.     a. Make/model of computer, and disk drive type
  14550.  
  14551.     b. Make/model of hard disk drive
  14552.  
  14553.     c. Make/model of monitor and display adapter, and ROM version
  14554.        numbers
  14555.  
  14556.     d. Make/model of disk controller
  14557.  
  14558.     e. Amount and type (conventional, extended, expanded) of memory in
  14559.        machine
  14560.  
  14561.     f. CPU speed
  14562.  
  14563.     g. Amount of hard disk memory free
  14564.  
  14565.     h. Any added cards that are installed, e.g. added memory, pointing
  14566.        devices, floating-point accelerator, or asynchronous cards
  14567.  
  14568.  2. Software configuration
  14569.  
  14570.     a. Operating system version number
  14571.  
  14572.     b. Product vendor (if product was purchased outside of Microsoft)
  14573.  
  14574.     c. A copy of your AUTOEXEC.BAT file
  14575.  
  14576.     d. A copy of your CONFIG.SYS file
  14577.  
  14578.     e. A copy of your STARTUP.CMD file
  14579.  
  14580.     f. A copy of your environment variables
  14581.  
  14582.     g. Any TSR (terminate-and-stay-resident) programs, or monitors that
  14583.        you have installed
  14584.  
  14585.  Following the guidelines listed below will help you get a faster
  14586.  response time for your Service Requests:
  14587.  
  14588.  1. Split your questions into multiple Service Requests
  14589.  
  14590.     Questions that are specific to the area they address are sent to a
  14591.     specialist in that area. A Service Request covering a variety of
  14592.     questions or products is assigned at random to be answered. You
  14593.     always get a faster response to your Service Request from a
  14594.     specialist.
  14595.  
  14596.     The Service Request cannot be released until all questions on it
  14597.     have been answered. This restriction slows an otherwise immediate
  14598.     response. Thus, the response time is the time it takes to answer
  14599.     the most difficult question; sometimes this can be a week or more.
  14600.  
  14601.     Multiple Service Requests allow several individuals to work on
  14602.     answering your questions, e.g. with multiple Service Requests,
  14603.     there may be four or more individuals answering your questions
  14604.     instead of one engineer working on answering all of your questions
  14605.     submitted in one Service Request.
  14606.  
  14607.  2. Provide code examples where applicable
  14608.  
  14609.     If you have a problem with any API, or if you have a programming
  14610.     question, always reduce the program to the minimum needed to
  14611.     reproduce the problem. Also, please make sure the code is self
  14612.     contained. Please provide the sample code in a form so that it
  14613.     can be compiled and linked without errors (unless the problem is
  14614.     with compiling or linking). We prefer that the sample code be
  14615.     written in C; however, MASM code is acceptable. If you are using
  14616.     the Version 5.10 C Compiler, please use the -W3 warning level
  14617.     option, and verify that no error messages are returned. We also
  14618.     recommend that you check all return codes from all function calls.
  14619.     Please include copies of all include files. Also, send in copies of
  14620.     the make file used to maintain the program, as well as the compiler
  14621.     and linker options used to compile and link your program. Please
  14622.     remember to archive the source code and all related files with the
  14623.     PKware file-compression utility, and submit the archived file as an
  14624.     attachment to the Service Request.
  14625.  
  14626.     Very large examples are not useful to help isolate the problem
  14627.     (unless the problem is directly related to the size of the
  14628.     example). If it is impossible to send the original code, write a
  14629.     separate example.
  14630.  
  14631.     Providing a sample program or a large program as an attachment to
  14632.     the Service Request allows easy verification that the problem is
  14633.     solved in the next release. This procedure allows us to verify
  14634.     that you are using the call correctly. Also, if the problem is
  14635.     not solved in the next release, this procedure gives us what we
  14636.     need to take the problem to development to get it resolved.
  14637.  
  14638.  3. General Service Request information
  14639.  
  14640.     a. Provide as much background information as possible if your
  14641.        problem or question is unique.
  14642.  
  14643.     b. Please do not send the Service Request description as an
  14644.        attachment.
  14645.  
  14646.     c. Please remember to insert an appropriate summarized version of
  14647.        your Service Request in the Subject line.
  14648.  
  14649.     d. Please do not direct questions to a specific person at
  14650.        Microsoft.
  14651.  
  14652.     e. Please report differences in behavior between different versions
  14653.        of the product or documentation.
  14654.  
  14655.     f. Assign the correct Severity to the Service Request.
  14656.  
  14657.     g. Select the correct product information when filling out the
  14658.        Service Request screen.
  14659.  
  14660.     h. Verify that the phone number is correct in your ONLINE.INI file
  14661.        so we can easily reach you if necessary.
  14662.  
  14663.     i. Please query the OnLine Knowledge Base before submitting a
  14664.        Service Request.
  14665.  
  14666.  By following the above guidelines, we can process your Service
  14667.  Requests much more efficiently.
  14668.  
  14669.  
  14670.  466. CTRL+C/CTRL+BREAK Difference, Depending on Keyboard Mode
  14671.  
  14672.  Different signals are returned for the CTRL+C and CTRL+BREAK key
  14673.  combinations, depending on the keyboard mode. For example:
  14674.  
  14675.     Keyboard Mode     Input Key      Signal Returned
  14676.     -------------     ---------      ---------------
  14677.  
  14678.     ASCII Mode        CTRL+C         SIG-CTRLC
  14679.                       CTRL+BREAK     SIG-CTRLC
  14680.  
  14681.     Binary Mode       CTRL+C         Nothing
  14682.                       CTRL+BREAK     SIG-CTRLBREAK
  14683.  
  14684.  Microsoft has confirmed that this information should be included in
  14685.  the "Microsoft Operating System/2 Programmer's Reference"
  14686.  documentation. We will post new information when the documentation has
  14687.  been updated to include this information.
  14688.  
  14689.  
  14690.  467. Making 3.5-Inch Install Disks for AT Machines
  14691.  
  14692.  Microsoft does not supply OS/2 version 1.20 on 3.5-inch disks for use
  14693.  on non-PS/2 machines. However, an increasing number of non-PS/2
  14694.  machines are configured with a high-density (1.44 MB) 3.5-inch floppy
  14695.  as the "A:" drive. Usually, these machines will also have a 1.2 MB
  14696.  "B:" drive, so it is possible to open the machine and swap drive
  14697.  cables, then boot from the 5.25-inch install disk and complete the
  14698.  installation process.
  14699.  
  14700.  If only one or two machines are being configured with OS/2 1.20, this
  14701.  is probably the easiest solution. Once the software has been
  14702.  installed, the drive cables can be swapped back. However, if it is
  14703.  necessary to install OS/2 1.20 on a number of machines that are
  14704.  configured with a 3.5-inch boot drive, this becomes very tedious. The
  14705.  instructions below describe the process of creating a set of 3.5-inch
  14706.  installation disks from the provided 5.25-inch disks.
  14707.  
  14708.  You will need eight high-density 1.44 MB disks. Format the disks, and
  14709.  as they are formatted, give them the following volume labels:
  14710.  
  14711.     Disk                          Volume Label
  14712.     ----                          ------------
  14713.  
  14714.     Disk #1 (Install disk)        OS2 INSTALL
  14715.     Disk #2 (Disk #1)             OS2 DISK 1
  14716.     Disk #3 (Disk #2)             OS2 DISK 2
  14717.     Disk #4 (Disk #3)             OS2 DISK 3
  14718.     Disk #5 (Disk #4)             OS2 DISK 4
  14719.     Disk #6 (Disk #5)             OS2 DISK 5
  14720.     Disk #7 (Drivers 1)           OS2 DRIVER1
  14721.     Disk #8 (Drivers 2)           OS2 DRIVER2
  14722.  
  14723.  For all of the disks except the install disk, you can use the XCOPY
  14724.  command, using the /s, /e, and /v parameters to indicate that you want
  14725.  to copy subdirectories if they exist, even if empty, and you want the
  14726.  data verified. Create Disks #2 - #8 using XCOPY.
  14727.  
  14728.  To make the install disk, you must create a bootable disk. The program
  14729.  that performs this function is called SYSINSTX.COM, and can be found
  14730.  on the install disk. You must have a machine that either is already
  14731.  running OS/2 1.20 or that can be booted from the 5.25-inch install
  14732.  disk for this to work correctly. The SYSINSTX utility takes a drive
  14733.  letter as its only parameter. This drive letter refers to the
  14734.  destination drive, containing the disk that is to receive the version
  14735.  1.20 system files. Once this has been completed, use XCOPY, as above,
  14736.  to copy over the remaining files.
  14737.  
  14738.  
  14739.  468. Toggling CAPS LOCK Light from VIO Window Fails in OS/2 1.20
  14740.  
  14741.  There is a problem in OS/2 Version 1.20 that is associated with
  14742.  attempting to toggle the CAPS LOCK mode from an application that is
  14743.  running in a VIO window.
  14744.  
  14745.  In a VIO window under OS/2 Version 1.20, the CAPS LOCK mode of the
  14746.  keyboard can be successfully toggled, but the CAPS LOCK light is not
  14747.  similarly toggled.
  14748.  
  14749.  The problem is that when an application makes KBD or KBD IOCTLs to set
  14750.  the shift state of the LED indicators, the KBD device driver SHOULD
  14751.  receive a Category 4 IOCTL 5AH. Unfortunately, this does not occur if
  14752.  the application is running in a VIO window.
  14753.  
  14754.  The source of this problem lies in the part of the PM shell that
  14755.  creates and manages VIO windows.
  14756.  
  14757.  Microsoft has confirmed this to be a problem in OS/2 Version 1.20. We
  14758.  are researching this problem and will post new information here as it
  14759.  becomes available.
  14760.  
  14761.  
  14762.  469. Critical Error in DOS 3.x Box Can Cause System to Hang
  14763.  
  14764.  Two cases of the system hanging when a critical error is generated
  14765.  while in the DOS 3.x box have been reported. The following information
  14766.  describes the exact circumstances in which this problem occurs.
  14767.  
  14768.  This problem involves the use of the monochrome printer adapter (MPA).
  14769.  
  14770.  If the VIO_IBMMPA video device driver is loaded, and you go into the
  14771.  DOS 3.x box and enter "dir a:" with no disk in Drive A, the system
  14772.  will hang. On one occasion it was possible to press ALT+ESC to exit
  14773.  out of the DOS 3.x box, but every other time, the only keys that had
  14774.  any effect were the CTRL+ALT+DEL keys.
  14775.  
  14776.  The second scenario requires that VIO_IBMMPA not be loaded. You need
  14777.  to go into the DOS 3.x box and enter "MODE MONO" (this is on an EGA
  14778.  system with the monochrome adapter as the secondary monitor). At this
  14779.  point, if you enter "dir a:" with no disk in Drive A, the system will
  14780.  hang again.
  14781.  
  14782.  If VIO_IBMMPA is not loaded and you stay away from the monochrome
  14783.  adapter (no mode mono), you will get the standard hard error pop-up
  14784.  screen.
  14785.  
  14786.  If you do the same thing on a PS/2 with a VGA and no monochrome
  14787.  adapter, it works correctly.
  14788.  
  14789.  The equipment that the hanging occurred on is a clone 386/20 with an
  14790.  EGA and a monochrome adapter attached to it.
  14791.  
  14792.  Microsoft has confirmed this to be a problem in OS/2 version 1.20. We
  14793.  are researching this problem and will post new information here as it
  14794.  becomes available.
  14795.  
  14796.  
  14797.  470. OS/2 Serial I/O Data Communications Guidelines
  14798.  
  14799.  Listed below are some guidelines that should be considered when
  14800.  performing serial I/O data communications under OS/2.
  14801.  
  14802.  1. The COM driver included with OS/2 is specified to provide
  14803.     one-way communication at 9600 baud. Attempting two-way
  14804.     communication at 9600 baud may result in lost characters.
  14805.  
  14806.  2. The use of better microprocessors (for example, an 80386 instead of
  14807.     an 80286, or a faster 80386 instead of a slower 80386) tends to
  14808.     improve performance.
  14809.  
  14810.  3. To improve serial I/O, use OS/2 Version 1.2 on a machine with a
  14811.     16550 UART. More recent computers use the faster 16550 UART instead of
  14812.     the older and slower 16450 UART. Under OS/2 Version 1.10, the COM
  14813.     driver treats the 16550 as a fast 16450. However, under OS/2 Version
  14814.     1.20, the new features of the faster 16550 are supported.
  14815.  
  14816.  4. Because OS/2 is a multitasking operating system, there is no way to
  14817.     monopolize the entire system in order to absolutely ensure that no
  14818.     data is missed during serial I/O. However, you can minimize
  14819.     the possibility of losing data that is coming in through the COM
  14820.     port by doing the following:
  14821.  
  14822.     a. Use some sort of hardware or software handshaking so that there
  14823.        is no data loss. Hardware handshaking is preferred, but software
  14824.        handshaking is fine as long as "full duplex automatic receive
  14825.        flow control" is also enabled.
  14826.  
  14827.     b. Use the SetDCBInfo IOCTL (Category 1, Function 53H) to specify
  14828.        MODE_WAIT_READ_TIMEOUT time-out processing (this is a bit in the
  14829.        fbTimeout byte in the DCBInfo structure passed to the IOCTL).
  14830.  
  14831.     c. The user buffer size should be as large as possible to decrease the
  14832.        system call overhead per byte transferred. Using 1K DosRead() calls
  14833.        is a good place to start.
  14834.  
  14835.     d. To get maximum throughput without overrunning the device driver
  14836.        buffer, you need to get another DosRead() request down to the
  14837.        device driver as soon as possible after the current DosRead()
  14838.        completes. This requires two "time-critical" threads, which
  14839.        should behave as follows:
  14840.  
  14841.           Thread 1 - DosRead into a pool of buffers
  14842.                      DosRead into next free buffer
  14843.                      Save number of bytes read in variable associated
  14844.                        with the buffer
  14845.                      Wake thread 2 to process data in buffer
  14846.  
  14847.           Thread 2 - Process data
  14848.                      Wait for data from thread 1
  14849.                      Process data in buffer
  14850.  
  14851.  5. If you have the 3.x box enabled, avoid bringing it to the
  14852.     foreground when performing serial I/O. Mode switching introduces
  14853.     fairly large interrupt latency periods.
  14854.  
  14855.  
  14856.  471. OS/2: Determining If Given Drive Is of Removable Media
  14857.  
  14858.  Question:
  14859.  
  14860.  Our application needs to be able to tell whether or not a given drive
  14861.  is of removable media. What is the recommended way of doing this?
  14862.  
  14863.  Response:
  14864.  
  14865.  You need to open the disk with the OPEN_FLAGS_DASD option and then
  14866.  call the IOCtl for removable media. You should do a DosError() call
  14867.  beforehand to get the error returned to the open call because there
  14868.  may not be any media in the drive and you will get a hard error if you
  14869.  don't make the DosError() call.
  14870.  
  14871.  Below is a code fragment that demonstrates this type of functionality.
  14872.  
  14873.  The sample code below should be compiled with the following options:
  14874.  
  14875.     cl /Lp /W3 ioctl.c
  14876.  
  14877.  Sample Code
  14878.  -----------
  14879.  
  14880.  #define INCL_DOS
  14881.  #include <os2.h>
  14882.  #include <stdio.h>
  14883.  
  14884.  int main(int argc, char *argv[]);
  14885.  
  14886.  int main(int argc, char *argv[])
  14887.  {
  14888.      HFILE   hfile;
  14889.      USHORT  usAction;
  14890.      ULONG   ulFileSize   = 0L;
  14891.      USHORT  usFileAttr   = FILE_NORMAL;
  14892.      USHORT  usOpenFlags  = FILE_OPEN;
  14893.      USHORT  usOpenMode   = OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE
  14894.                             | OPEN_FLAGS_DASD;
  14895.      ULONG   ulReserved   = 0L;
  14896.  
  14897.      BYTE    fRemovable;
  14898.      BYTE    Reserved     = 0;
  14899.  
  14900.      DosError(HARDERROR_DISABLE);
  14901.  
  14902.      if(DosOpen(argv[1],&hfile,&usAction,ulFileSize,usFileAttr,
  14903.              usOpenFlags,usOpenMode,ulReserved))
  14904.  
  14905.       {
  14906.        printf("Bad open.\n");
  14907.        DosExit(EXIT_PROCESS,0);
  14908.       }
  14909.  
  14910.      if(DosDevIOCtl(&fRemovable,&Reserved,DSK_BLOCKREMOVABLE,0x08,
  14911.                      hfile))
  14912.       {
  14913.        printf("Bad IOCtl.\n");
  14914.        DosExit(EXIT_PROCESS,0);
  14915.       }
  14916.  
  14917.      if(fRemovable)
  14918.       printf("Non-removable\n");
  14919.      else
  14920.       printf("Removable\n");
  14921.  
  14922.      DosClose(hfile);
  14923.  
  14924.      return(0);
  14925.  
  14926.  
  14927.  472. OS/2 SDK: Adding Support for Expanded Memory in Device Driver
  14928.  
  14929.  Question:
  14930.  
  14931.  Could you please provide us with some information on how to add
  14932.  support for our built-in EMM (Expanded Memory Manager) hardware in the
  14933.  DOS 3.x box under OS/2?
  14934.  
  14935.  Response:
  14936.  
  14937.  This can be done in one of the following ways:
  14938.  
  14939.  1. You can modify your DosHlpSizeMem() routine and return less memory
  14940.     than actually is present in the system, then let your EMM driver
  14941.     use that extra memory.
  14942.  
  14943.  2. You can develop an OS/2 device driver. This driver would ask for a
  14944.     user-defined amount of memory from the system using the DevHlp
  14945.     "AllocPhys". The driver then would install a software interrupt
  14946.     handler to handle EMM interrupts (e.g. INT 67H) using the DevHlp
  14947.     "SetROMVector". When a program running in the DOS 3.x box issues an
  14948.     INT 67H, this software interrupt handler would get control. This
  14949.     would allow you to manage the allocated memory.
  14950.  
  14951.  
  14952.  473. OS/2 SDK: BACKUP/RESTORE Problem on Files in 32nd Subdirectory
  14953.  
  14954.  If you try to use BACKUP or RESTORE to backup or restore files in the
  14955.  32nd subdirectory from the root directory, only one file is backed up
  14956.  or restored. Microsoft has confirmed this to be a problem in the
  14957.  Version 1.06 OS/2 Software Development Kit (SDK). We are researching
  14958.  this problem and will post new information as it becomes available.
  14959.  
  14960.  The workaround is to not use this many levels of subdirectories. In
  14961.  any case, this deep nesting of subdirectories (32 is the maximum level
  14962.  allowed in MS-DOS) seriously degrades performance.
  14963.  
  14964.  
  14965.  474. OS/2 SDK: Obtaining OS2.INI Details
  14966.  
  14967.  Question:
  14968.  
  14969.  What are the predefined OS2.INI strings and where can I get a list of
  14970.  these strings?
  14971.  
  14972.  Response:
  14973.  
  14974.  We plan to release a utility that displays the information in the
  14975.  OS2.INI file in a future release of the OS/2 SDK (Software Development
  14976.  Kit). Until this utility becomes available, you can write a similar
  14977.  utility by using the WinQueryProfileString() function call. If you
  14978.  pass this function an "application name" of NULL, it will return in
  14979.  the buffer the full list of application names. If you pass the
  14980.  function a valid application name and a NULL key name parameter, it
  14981.  will return in the buffer a full list of the valid key names for that
  14982.  application. In both cases, the buffer will be filled with
  14983.  null-terminated strings, with two nulls after the last string. In this
  14984.  fashion, you could loop through all of the application names and
  14985.  obtain all of the key names.
  14986.  
  14987.  
  14988.  475. OS/2 SDK: Interrupt Latency Benchmark
  14989.  
  14990.  Question:
  14991.  
  14992.  Has a benchmark been done to determine the typical latency time and
  14993.  task switch times for OS/2 on a 6 MHz IBM AT computer?
  14994.  
  14995.  Response:
  14996.  
  14997.  The interrupt latency values for an AT running at 6 MHz with one wait
  14998.  state are as follows:
  14999.  
  15000.                         3.x Box in      3.x Box in
  15001.                         Background      Foreground
  15002.                        ============================
  15003.  
  15004.     Dispatch latency          6 ms             6 ms
  15005.     Interrupt latency       500 us          1100 us
  15006.     Disable time            400 us           400 us
  15007.  
  15008.  These values do not include random latency caused by applications with
  15009.  IOPL that disable interrupts, or real mode applications doing CLI/STI.
  15010.  
  15011.  
  15012.  476. OS/2 SDK: Setting Environment Variable in Application
  15013.  
  15014.  Question:
  15015.  
  15016.  I have an application in which I am setting environment variables. I
  15017.  would like these variables set when I exit the application; however,
  15018.  the parent process (I assume CMD.EXE) doesn't recognize any changes.
  15019.  Thus, when I exit the application, it appears as though I never made a
  15020.  change.
  15021.  
  15022.  How do I tell a parent process to set an environmental variable? In
  15023.  general, how do I tell CMD.EXE to change its environment?
  15024.  
  15025.  Response:
  15026.  
  15027.  The command processor of OS/2, CMD.EXE, does not allow child processes
  15028.  to update the environment of their parents. The parent application,
  15029.  when using DosExecPgm() or DosStartSession(), passes an environment to
  15030.  the child process, and the child process receives a copy of this. The
  15031.  child process can modify the environment it has received from its
  15032.  parent, but the child cannot update the parent's environment.
  15033.  
  15034.  This environment inheritance behavior is isolated to the command
  15035.  processor, CMD.EXE (and COMMAND.COM for MS-DOS and for the OS/2 DOS
  15036.  compatibility mode), and another command processor could choose to use
  15037.  different inheritance rules. Actually, the command processor is almost
  15038.  completely in charge of the responsibilities of controlling the
  15039.  environment of different processes and who gets to see, use, or modify
  15040.  them. So, a UNIX-like command processor such as a C shell may choose
  15041.  to implement a mechanism such as the UNIX EXPORT command, which allows
  15042.  a specified environment string of a parent to be updated by a child.
  15043.  
  15044.  This behavior is consistent with the behavior of the command processor
  15045.  of MS-DOS, COMMAND.COM. Environment inheritance works in one direction
  15046.  only (from parent to child process).
  15047.  
  15048.  
  15049.  477. OS/2 SDK: When to Allocate Memory with DosAllocSeg()
  15050.  
  15051.  Question:
  15052.  
  15053.  My application needs up to 30 4K segments. I can either create all of
  15054.  the segments with DosAllocSeg() at the beginning of the application,
  15055.  or I can wait until each segment is actually needed to allocate it.
  15056.  Does allocating the segments at the beginning of the application
  15057.  actually take memory (or swap space) away from other applications,
  15058.  even if the segments may not ever be accessed?
  15059.  
  15060.  Response:
  15061.  
  15062.  At the time the application calls DosAllocSeg(), the memory is
  15063.  obtained for your use. This might require memory compaction and also
  15064.  might involve swapping before the API call returns. The same thing is
  15065.  true for any memory allocation call. In your case, you would probably
  15066.  want to refrain from allocating the memory until it is actually
  15067.  needed.
  15068.  
  15069.  This is the current behavior for OS/2 Versions 1.00 and 1.10; however,
  15070.  in future versions the memory model may change such that either method
  15071.  has effectively the same result. The actual method you decide to use
  15072.  will depend on such factors as the total size of what is being
  15073.  allocated, how easy it is to model your code each way, and how likely
  15074.  it is that you will really need the memory. If you are allocating a
  15075.  small total amount of memory, and if it would be easiest to allocate
  15076.  this memory up front and you will probably use it, then it would be
  15077.  acceptable to do this. Generally, it is good practice to allocate
  15078.  resources as needed and free them when you are finished; however, the
  15079.  final design of your code is a decision you need to make.
  15080.  
  15081.  
  15082.  478. Menu Cursor Not Highlighted Correctly in Program Selector
  15083.  
  15084.  There is a problem with the Program Selector shipped with OS/2 Version
  15085.  1.00. The following steps duplicate the problem:
  15086.  
  15087.  1. Move the mouse cursor to the first character of the program name
  15088.     displayed at the top of the programs (top left end) in the "Switch
  15089.     to a running program" list.
  15090.  
  15091.  2. Display the screen of the screen group and return to the Program
  15092.     Selector.
  15093.  
  15094.  3. Move the menu bar (reversed portion) at the third (or subsequent)
  15095.     selection from the top with the vertical arrow keys.
  15096.  
  15097.  4. Move the menu bar horizontally with the horizontal arrow keys.
  15098.  
  15099.  5. Move the cursor to its original position.
  15100.  
  15101.  6. Move the menu bar with the vertical arrow keys.
  15102.  
  15103.  The part of the menu bar that was reversed in pink (where the menu
  15104.  cursor was located formerly) has now turned red.
  15105.  
  15106.  It is possible to duplicate this incorrect "highlighting" problem with
  15107.  only two items on either or both sides of the Program Selector menus.
  15108.  It is in fact possible to highlight every line on both sides at once.
  15109.  
  15110.  Microsoft has confirmed this to be a problem with the Program Selector
  15111.  in OS/2 Version 1.00; however, it is only a cosmetic problem. This
  15112.  problem does not interfere with the functionality of the Program
  15113.  Selector.
  15114.  
  15115.  We are researching this problem and will post new information as it
  15116.  becomes available.
  15117.  
  15118.  Keywords: buglist1.03 buglist1.04
  15119.  
  15120.  
  15121.  479. OS/2 SDK: Device Driver DosExitList() Processing
  15122.  
  15123.  Question:
  15124.  
  15125.  We are using a third party IEEE device driver that currently is a bit
  15126.  unstable and therefore occasionally traps out while performing an I/O
  15127.  operation on our behalf. When this happens, no DosExitList()
  15128.  processing for our application appears to occur. Is this normal
  15129.  behavior?
  15130.  
  15131.  Response:
  15132.  
  15133.  Yes, this is expected behavior. If a trap occurs while executing the
  15134.  code of a device driver, the system is considered corrupt and
  15135.  unstable. No DosExitList() processing will be performed.
  15136.  
  15137.  What is also happening is that technically it is your thread that is
  15138.  trapping, since it is your thread traveling down into the kernel and
  15139.  executing within the device driver. With the exception of interrupt
  15140.  time, the GDT (Global Descriptor Table) and LDT (Local Descriptor
  15141.  Table) entries for the device driver are the ones belonging to your
  15142.  application's thread of execution. When you trap at ring 0, there is
  15143.  no way for the thread to make it back up to ring 3 to perform the
  15144.  exitlist.
  15145.  
  15146.  There is no modification you can make to the device driver other than
  15147.  correcting its logic to avoid a trap.
  15148.  
  15149.  
  15150.  480. OS/2 SDK: Number of GDTs and LDTs Allocated at Config Time
  15151.  
  15152.  Question:
  15153.  
  15154.  Is the number of GDTs (Global Descriptor Tables) allocated during
  15155.  configuration time fixed, or is there a parameter in CONFIG.SYS that
  15156.  controls how many GDTs are allocated?
  15157.  
  15158.  Response:
  15159.  
  15160.  Under OS/2, there is one GDT and one or more LDTs (Local Descriptor
  15161.  Tables) allocated at configuration time. The LDTs belong to the
  15162.  processes that are executing. Of all the LDTs present, only one of the
  15163.  LDTs is active: the one that belongs to the process that has the CPU
  15164.  at that time.
  15165.  
  15166.  
  15167.  481. OS/2 SDK: DosGetMessage() and Message Segments
  15168.  
  15169.  Question:
  15170.  
  15171.  How is the segment created that is referred to in the documentation on
  15172.  the DosGetMessage() function call? Also, if DosGetMessage() is to be
  15173.  issued by a DLL (Dynamic Linked Library), should I use MSGBIND to bind
  15174.  the messages to the DLL, or to the .EXE file that uses the DLL? Can
  15175.  both the .EXE file and the DLL have message segments?
  15176.  
  15177.  Response:
  15178.  
  15179.  Two of the parameters that are specified in the DosGetMessage() API
  15180.  are the message number to retrieve, and the name of the file
  15181.  containing the messages. To retrieve the requested message,
  15182.  DosGetMessage() first searches the process's message segment, if there
  15183.  is one present. If DosGetMessage() cannot find the message, then it
  15184.  searches the specified file for the message.
  15185.  
  15186.  The MKMSGF program is used to build a message file. The message file
  15187.  can then be bound to the message segment of an executable file using
  15188.  the utility MSGBIND.
  15189.  
  15190.  The MSGBIND utility binds a message segment to an "executable
  15191.  program." It does this by reading an input file that specifies which
  15192.  executable files to modify.
  15193.  
  15194.  These utilities are described in the "Microsoft Operating System/2
  15195.  Programmer's Learning Guide and Programming Tools" manual in Sections
  15196.  3.4 and 3.5, on Pages 32 to 35.
  15197.  
  15198.  The messages are bound to executable files only; DLLs do not have
  15199.  message segments.
  15200.  
  15201.  
  15202.  482. OS/2 SDK: Increasing Keyboard Buffer Size
  15203.  
  15204.  Question:
  15205.  
  15206.  Is there any way to increase the length of the keyboard buffer in
  15207.  OS/2? I could write my own keyboard monitor and then have the monitor
  15208.  buffer the keys with a larger buffer, but there must be a system
  15209.  parameter that allocates the initial buffer.
  15210.  
  15211.  Response:
  15212.  
  15213.  There are only two ways to increase the size of the keyboard buffer.
  15214.  The first way is to write a keyboard device driver and the second way
  15215.  would be to write a monitor such as the one mentioned above.
  15216.  
  15217.  There are no system parameters available that you can send to the
  15218.  keyboard driver to make it initialize its buffers to be any bigger
  15219.  than they already are.
  15220.  
  15221.  
  15222.  483. OS/2 SDK: ESC
  15223.  
  15224.  There is a problem with ANSI.DLL and ESC[>4H. You can see it best by
  15225.  running the sample program TERMINAL, connected to another machine.
  15226.  Create a text file with the following line:
  15227.  
  15228.          ESC[>4H (where ESC is replaced with the ASCII escape
  15229.                   character 27 decimal)
  15230.  
  15231.  Now, type the file and your screen will look very strange. At this
  15232.  point, the machine is fine, and if you enter the correct commands
  15233.  (which will not be displayed on the screen) you can exit your program
  15234.  and the screen will be restored.
  15235.  
  15236.  You can get a similar effect by typing the same file in OS/2. The
  15237.  screen will flash, then restore itself.
  15238.  
  15239.  Microsoft has confirmed this to be a problem with the OS/2 SDK
  15240.  (Software Development Kit) Versions 1.06 and 1.10. We are researching
  15241.  this problem and will post new information as it becomes available.
  15242.  
  15243.  
  15244.  484. VioGetPhysBuf() Only Allowed in Foreground Full-Screen Group
  15245.  
  15246.  Question:
  15247.  
  15248.  As part of a program we are developing, we wish to write directly to a
  15249.  monochrome monitor that is included as an add-on to our PCs. Our
  15250.  program runs fine if we are in OS/2 full-screen command mode. However,
  15251.  we get a protection violation if we execute it using the Program
  15252.  Starter or from a windowed CMD.EXE. Why is this error occurring?
  15253.  
  15254.  Response:
  15255.  
  15256.  The VioGetPhysBuf() in your program is failing with error 494, which
  15257.  is ERROR_VIO_EXTENDED_SG. VioGetPhysBuf() is not allowed from a window
  15258.  or a PM (Presentation Manager) screen group. It has always been the
  15259.  intent not to allow the VioGetPhysBuf() call from the extended screen
  15260.  groups. However, this information is not documented; we will post new
  15261.  information when it has been documented.
  15262.  
  15263.  If you must get to the MDA memory segment, there is another way to do
  15264.  this. Write a simple device driver whose only function is to install
  15265.  and respond to IOCtl calls to pass back selectors for the video
  15266.  memory. This is done using the DevHlp routine PhysToUVirt(). You can
  15267.  make IOCtl calls from any screen group and the selector passed back
  15268.  will always be valid.
  15269.  
  15270.  
  15271.  485. RESTORE Sometimes Restores Files Out of Specified Range
  15272.  
  15273.  The RESTORE command restores all files, including the files out of the
  15274.  range that were indicated with the /a:, /b:, /e:, or /l: option,
  15275.  unless the hard disk to be restored contains the same files as those
  15276.  to be BACKUPed.
  15277.  
  15278.  Microsoft has confirmed this to be a problem with Versions 1.00, 1.01,
  15279.  1.02, 1.03, 1.04, 1.05, and 1.06 of the OS/2 SDK (Software Development
  15280.  Kit). We are researching this problem and will post new information as
  15281.  it becomes available.
  15282.  
  15283.  Keywords: buglist1.03 buglist1.04 buglist1.05 buglist1.06
  15284.  
  15285.  
  15286.  486. Information Needed When Submitting Service Requests
  15287.  
  15288.  OS/2
  15289.  ISVONLY |
  15290.  
  15291.  A list of the information Microsoft needs to process your OS/2 Service
  15292.  Requests is as follows:
  15293.  
  15294.  1. Hardware configuration
  15295.  
  15296.  a. Make / Model of computer
  15297.  
  15298.  b. Amount of memory in machine
  15299.  
  15300.  c. Make / Model of monitor and display adapter
  15301.  
  15302.  d. Make / Model of Disk controller
  15303.  
  15304.  e. Any added cards that are installed, e.g. added memory, pointing
  15305.     devices, floating-point accelerator, asynchronous cards
  15306.  
  15307.  2. Software configuration
  15308.  
  15309.  a. A copy of your CONFIG.SYS file
  15310.  
  15311.  b. A copy of your STARTUP.CMD file
  15312.  
  15313.  c. A copy of your environment variables
  15314.  
  15315.  If you need to send in sample code, we request that the code be in a
  15316.  form so that it can be compiled and linked without errors (unless
  15317.  compiling/linking are the reason for the SR). Please include copies of
  15318.  all include files. Also, send in copies of the Makefile used to
  15319.  maintain the program as well as the compiler and linker options used
  15320.  to compile and link your program.
  15321.  
  15322.  By following the above guidelines, we can process your SRs much more
  15323.  efficiently.
  15324.  
  15325.  
  15326.  487. OS/2 SDK: COMMAND.COM Requirements to Run 3.x Box
  15327.  
  15328.  OS/2 does not start the 3.x box if COMMAND.COM is deleted from the
  15329.  root directory. The "SHELL=\os2\command.com /p" statement does not
  15330.  boot the 3.x box.
  15331.  
  15332.  Below is the relevant information on these statements. A more thorough
  15333.  discussion of these statements can be found on Pages 782-783 of "The
  15334.  MS-DOS Encyclopedia."
  15335.  
  15336.  There are two copies of COMMAND.COM installed by OS/2. One copy is
  15337.  placed in the root directory of the boot drive, and another copy is
  15338.  placed in the \OS2 subdirectory of this drive. Only one copy is
  15339.  needed; whenever possible, you should eliminate files from the root
  15340.  directory. The reason a copy of COMMAND.COM is placed in the root
  15341.  directory is for compatibility, since many applications may expect it
  15342.  to be there. An optimal system would only have one copy of COMMAND.COM
  15343.  with a SHELL statement in the CONFIG.SYS file that properly refers to
  15344.  this file.
  15345.  
  15346.  The usage for the SHELL statement of both MS-DOS and OS/2 (for the DOS
  15347.  compatibility mode of OS/2) is as follows:
  15348.  
  15349.     SHELL=[drive:][path]<command_processor> [<arguments>]
  15350.  
  15351.  <command_processor> is the name of the executable command processor.
  15352.  This is normally COMMAND.COM.
  15353.  
  15354.  <arguments> are zero or more command line arguments that are specific
  15355.  to the command processor being used. See the documentation on the
  15356.  specific command processor for more information.
  15357.  
  15358.  The usage for the COMMAND.COM is as follows:
  15359.  
  15360.     COMMAND.COM [<starting_directory>] [/E:<env_size>] [/P]
  15361.                 [/C <command>]
  15362.  
  15363.  <starting_directory> is the directory in which MS-DOS will reload
  15364.  COMMAND.COM. If this is the root directory, this option is not
  15365.  necessary. This option should only be used during the first execution
  15366.  (the root copy) of COMMAND.COM.
  15367.  
  15368.  /E:<env_size> specifies the size of the environment, where <env_size>
  15369.  is in bytes. This option should only be used during the first
  15370.  execution (the root copy) of COMMAND.COM.
  15371.  
  15372.  /P means that this is the parent/root copy of the command processor.
  15373.  This option should only be used during the first execution (the root
  15374.  copy) of COMMAND.COM.
  15375.  
  15376.  /C <command> specifies that the DOS command <command> is to be
  15377.  executed and then the copy of COMMAND.COM will exit. This option
  15378.  should only be used during the second and subsequent (child copies) of
  15379.  COMMAND.COM.
  15380.  
  15381.  OS/2 installs COMMAND.COM (for the DOS compatibility mode) in the root
  15382.  directory of the boot drive, as well as in the directory \OS2. The
  15383.  CONFIG.SYS statement specifies the copy in the \OS2 directory.
  15384.  However, since the <starting_directory> option is not specified on the
  15385.  SHELL line in the CONFIG.SYS file, if the copy of COMMAND.COM is not
  15386.  present in the root directory, COMMAND.COM will not load and the DOS
  15387.  compatibility mode will halt.
  15388.  
  15389.  The solution to this is to modify the default OS/2 CONFIG.SYS entry
  15390.  for the SHELL statement, adding the <starting_directory> of X:\OS2,
  15391.  where X is the boot drive. Another way to keep the DOS compatibility
  15392.  mode working properly is to not delete COMMAND.COM from the root
  15393.  directory of the boot drive.
  15394.  
  15395.  We have requested that the following change be reviewed and considered
  15396.  for inclusion in a future release. The default CONFIG.SYS file should
  15397.  be modified to contain the following statement so that this problem
  15398.  does not occur:
  15399.  
  15400.     shell=c:\os2\command.com c:\os2
  15401.  
  15402.  
  15403.  488. File System Utility Cannot Delete Nested Subdirectories
  15404.  
  15405.  Question:
  15406.  
  15407.  We have found a problem with the File System Utility in the
  15408.  Presentation Manager screen.
  15409.  
  15410.  We created a long list of nested subdirectories. The path length of
  15411.  these subdirectories was 128 characters. When we attempted to delete
  15412.  one of the subdirectories, we were unable to. We used the delete
  15413.  option under the File menu and the system deleted the bottom three
  15414.  subdirectories in the list, but that was all; we were unable to delete
  15415.  the other subdirectories. We then went into the 3.x box to try to
  15416.  delete the subdirectories from there, but we were unable to because
  15417.  MS-DOS would not allow us to enter a path that long. Finally, we were
  15418.  able to use the MS-DOS XTree program to rename the nested
  15419.  subdirectories so that they were only one character long each, which
  15420.  shortened the path length, and we were then able to delete the
  15421.  subdirectories. We have the following questions regarding this
  15422.  problem:
  15423.  
  15424.  1. Is this a bug in the File System Utility?
  15425.  
  15426.  2. What is the maximum path length allowed under the File Manager?
  15427.  
  15428.  3. What is the maximum path length allowed in the 3.x box?
  15429.  
  15430.  Response:
  15431.  
  15432.  The following are answers to the above questions:
  15433.  
  15434.  1. Microsoft has confirmed this to be a problem with the OS/2 SDK
  15435.     (Software Development Kit) Version 1.06. We are researching this
  15436.     problem and will post new information as it becomes available.
  15437.  
  15438.  2. The maximum path length allowed under the File Manager and in
  15439.     protected mode is limited by the operating system. Under OS/2 1.00
  15440.     and 1.10, the maximum path length allowed is 127 characters. This
  15441.     length is subject to change and may increase in a future release.
  15442.  
  15443.  3. The maximum path length allowed in the 3.x box is 63 characters
  15444.     for compatibility.
  15445.  
  15446.  
  15447.  489. OS/2 SDK: Increasing Available Memory for DOS 3.x Box
  15448.  
  15449.  Question:
  15450.  
  15451.  The DOS 3.x box seems to only give applications about 467K of memory.
  15452.  Is there any way to maximize this memory?
  15453.  
  15454.  Response:
  15455.  
  15456.  There are a few things that you can do to maximize memory available in
  15457.  the 3.x box.
  15458.  
  15459.  The primary thing you need to do is to remove as many device drivers
  15460.  as possible. Under OS/2 1.00, all of a device driver's code and data
  15461.  must be in low memory (below 1 MB). Under OS/2 1.10, device drivers
  15462.  can have code and data above 1 MB, but it is not always as efficient
  15463.  to do so. If you are using any installable device drivers that you
  15464.  don't need, such as the COM driver, EGA driver, mouse driver, or
  15465.  vdisk, then you will be able to get more memory available in the 3.x
  15466.  box by removing these drivers from your CONFIG.SYS file. You can also
  15467.  lower the amount of memory taken up by some buffers, such as the
  15468.  buffers in the BUFFERS=, FCBS=, and THREADS= options. You should also
  15469.  be sure that your RMSIZE value is set to 640.
  15470.  
  15471.  It is our concern also that the DOS box have the maximum amount of
  15472.  memory available for applications, and we will be addressing this
  15473.  concern in future releases of OS/2. However, for now there is a
  15474.  contention among kernel code, buffers, and drivers, that must remain
  15475.  below the 1 MB boundary and MS-DOS applications running in the 3.x
  15476.  box.
  15477.  
  15478.  
  15479.  490. OS/2 SDK: Invocation Order of Items Placed in DosExitList()
  15480.  
  15481.  Question:
  15482.  
  15483.  How do you control the execution order of items placed in the
  15484.  DosExitList()?
  15485.  
  15486.  Response:
  15487.  
  15488.  The high byte of the first parameter, fFnCode, defines the invocation
  15489.  order in OS/2 1.10. This does not work in OS/2 1.00. It is only valid
  15490.  when the low-order byte is 1. This list determines the order in which
  15491.  the exit list routines will be invoked. Routines given a value of 0
  15492.  will be invoked first, and routines with a value of 255 will be
  15493.  invoked last. If more than one exit list routine is added with the
  15494.  same value, then the last routine added will be invoked first. The
  15495.  values used by the OS/2 components are as follows:
  15496.  
  15497.     Value       Component
  15498.  
  15499.     A0H - A8H   OS/2 Presentation Manager
  15500.     B0H         OS/2 KBD
  15501.     C0H         OS/2 VIO
  15502.  
  15503.  
  15504.  491. OS/2 SDK: ExecFlags Values for DosExecPgm() Not Documented
  15505.  
  15506.  The following ExecFlags values for the DosExecPgm() function call are
  15507.  not documented in the versions of QuickHelp included with the Versions
  15508.  1.05 and 1.06 OS/2 SDK (Software Development Kit):
  15509.  
  15510.     Value          Description
  15511.  
  15512.     5              The program is loaded and is not running until the
  15513.                    session manager dispatches the threads belonging to
  15514.                    the process.
  15515.  
  15516.     6              The process and all of its descendants will execute
  15517.                    under conditions for debugging.
  15518.  
  15519.  Microsoft has confirmed this to be a problem in Versions 1.05 and
  15520.  1.06. We are researching this problem and will post new information as
  15521.  it becomes available.
  15522.  
  15523.  
  15524.  492. Increasing Maximum Number of Open Files with DosSetMaxFH()
  15525.  
  15526.  Question:
  15527.  
  15528.  When implementing a database server application using named pipes, the
  15529.  following error was returned from DosMakeNmPipe():
  15530.  
  15531.     4 "ERROR_TOO_MANY_OPEN_FILES"
  15532.  
  15533.  This error occurs when the total number of pipes plus database files
  15534.  reaches approximately 15. How can we increase the maximum number of
  15535.  files that we can open?
  15536.  
  15537.  Response:
  15538.  
  15539.  The DosSetMaxFH() API can be used to set the maximum number of file
  15540.  handles a process can open. The range is from 20 to 255.
  15541.  
  15542.  
  15543.  493. OS/2 SDK 1.06 Wrongly Assumes System Is a PS/2
  15544.  
  15545.  The OS/2 SDK (Software Development Kit) Version 1.06 install program
  15546.  needs to know the ROM BIOS model and submodel bytes of a system, to
  15547.  determine if the system is an AT compatible system or a PS/2 (more
  15548.  properly termed an MCA architecture) compatible system. If the model
  15549.  byte has a value of FCH, the OS/2 install program checks the submodel
  15550.  byte to see if it is a recognized AT; if not, it assumes that it is a
  15551.  PS/2. The values for the submodel byte that identify a system as an
  15552.  recognized AT are 00H, 01H, 02H, 06H, and 09H. Any other submodel byte
  15553.  value causes the install program to assume that the system is a PS/2.
  15554.  
  15555.  For systems that cannot run or use the normal OS/2 installation
  15556.  program, a method is available for manually installing OS/2 that
  15557.  bypasses this installation program. This manual installation procedure
  15558.  is described in Section 3.1.1 of the file INSTALL.TXT, located on the
  15559.  OS/2 SDK Version 1.06 TOOLKIT1 disk.
  15560.  
  15561.  If the OS/2 install program wrongly assumes that the system is a PS/2,
  15562.  it tries to use the PS/2 device drivers instead of the AT drivers
  15563.  (i.e., CLOCK02.SYS is used rather than CLOCK01.SYS, and COM02.SYS is
  15564.  used rather than COM01.SYS). In general, OS/2 comes with a set of
  15565.  device drivers with "01" in them for ATs and "02" in them for PS/2s.
  15566.  
  15567.  When the OS/2 installation program mistakes an AT system for a PS/2
  15568.  system, it wrongly tries to copy the "02" device driver files onto the
  15569.  target system. However, on the 5.25-inch disks included with the OS/2
  15570.  SDK Version 1.06, the PS/2 "02" device drivers are not included. This
  15571.  is because IBM PS/2 systems only come with 3.5-inch disk drives. Thus,
  15572.  a set needs to be created to fool the OS/2 install program; this can
  15573.  be done by copying the set "01" files to the "02" files. If a set of
  15574.  "02" files is available, the OS/2 install program will continue to
  15575.  install OS/2 on the target system.
  15576.  
  15577.  However, after installation, once the OS/2 kernel is loaded, the
  15578.  kernel DOES properly identify the system as an AT and not as a PS/2;
  15579.  in such a case, the kernel will be looking for the set of "01" files.
  15580.  So, a set of valid AT-style "01" files must exist on the system. Since
  15581.  the OS/2 install program did not copy the "01" files, they must be
  15582.  copied manually, or the "02" files must be renamed. The end result is
  15583.  that a set of proper AT-style "01" device drivers exists on the OS/2
  15584.  target system in its normal "01" filenames.
  15585.  
  15586.  This procedure is not a supported method of installing OS/2; the
  15587.  supported procedure is to use the manual installation technique
  15588.  mentioned above and described in Section 3.1.1 of the file
  15589.  INSTALL.TXT, located on the OS/2 SDK Version 1.06 TOOLKIT1 disk. If
  15590.  the system is not 100-percent AT compatible, it may not run the IBM
  15591.  version provided with the Microsoft OS/2 SDK Version 1.06. Owners of
  15592.  such systems should contact their OEM for information regarding
  15593.  versions of OS/2 adapted for their hardware.
  15594.  
  15595.  There is a file in the Software Library named SYSMODEL.ARC that
  15596.  contains a program that displays the model and submodel bytes of a
  15597.  system. SYSMODEL.ARC can be found in the Software Library by searching
  15598.  for the filename, the Q number of this article, or S12239.
  15599.  SYSMODEL.ARC was archived using the PKware file-compression utility.
  15600.  
  15601.  SYSMODEL.ARC obtains this information by calling ROM BIOS interrupt
  15602.  15H, with AH=C0. The C source code for this program is also included.
  15603.  For more information on IBM (and 100-percent compatible) ROM BIOS
  15604.  information, refer to the reference "IBM PS/2 and PC BIOS Interface
  15605.  Technical Reference," part number 68X2260, available from IBM by
  15606.  calling (800) IBM-PCTB. Another reference that contains similar
  15607.  material is the Microsoft Press book, "Programmer's Quick Reference
  15608.  Series: IBM ROM BIOS," by Ray Duncan, ISBN 1-55615-135-7.
  15609.  
  15610.  
  15611.  494. OS/2 SDK: XMS Drivers for DOS Compatibility Mode
  15612.  
  15613.  The release of OS/2 provided with the Microsoft OS/2 Software
  15614.  Development Kit (SDK) does not provide a device driver for using XMS
  15615.  (eXpanded Memory Specification) memory in the DOS compatibility mode.
  15616.  
  15617.  The Microsoft eXpanded Memory Manager (XMM), HIMEM.SYS, will only work
  15618.  in an MS-DOS environment where the extended memory in the system is
  15619.  accessible by MS-DOS. In OS/2, all extended memory is used for
  15620.  protected mode programs, so none is available in the DOS compatibility
  15621.  box.
  15622.  
  15623.  It would be possible to write an XMM that supports a subset of the
  15624.  standard XMS API. This XMM would have to be a bimodal OS/2 device
  15625.  driver. The driver would allocate some extended memory, which could be
  15626.  used as extended memory blocks (EMBs), as described in the formal XMS
  15627.  document, XMS.TXT. In addition, the XMM would also be able to
  15628.  implement upper memory block (UMB) support, since these areas of
  15629.  memory are between 640K and 1 MB, an area of memory that OS/2 does not
  15630.  control. Note, however, that UMB support currently is not implemented
  15631.  in HIMEM.SYS.
  15632.  
  15633.  However, the high memory area (HMA) portion of XMS cannot be
  15634.  implemented, since this portion of memory must occupy the first 64K of
  15635.  extended memory (which starts at the 1 MB address). OS/2 already
  15636.  occupies that area of memory: the "high memory kernel" is loaded there
  15637.  during system startup. This area cannot be relocated to another area,
  15638.  since MS-DOS applications that use the HMA rely on it having the same
  15639.  physical address, as well as it being addressable in real mode with
  15640.  the A20 line of the 80286 or 80386 chip being enabled. These unique
  15641.  features of the HMA make it nonrelocatable.
  15642.  
  15643.  For more information on XMS memory, refer to the official
  15644.  specification, the "eXtended Memory Specification Version 2.0,"
  15645.  jointly developed by Microsoft Corporation, Lotus Development
  15646.  Corporation, Intel Corporation, and AST Research, Inc., which is
  15647.  available free from Microsoft by calling (800) 426-9400 (make sure
  15648.  that you ask for the supplemental XMS disk, too). The contents of the
  15649.  XMS disk, which contains a machine-readable copy of the XMS
  15650.  specification named XMS20.ARC, are available on many information
  15651.  systems and bulletin-board systems, such as the Microsoft OnLine
  15652.  Software Library and ARPAnet's SIMTEL20 archives. XMS20.ARC can be
  15653.  found in the Software Library by searching on the filename, the Q
  15654.  number of this article, or S12023. XMS20.ARC was archived using the
  15655.  PKware file-compression utility.
  15656.  
  15657.  For more information on the high memory area (HMA) subsection of XMS
  15658.  memory, refer to the "Microsoft Systems Journal," Volume 10, Number 6,
  15659.  November 1988, in the article titled "The High Memory Area: 64KB More
  15660.  Memory in Real Mode," by Chip Anderson, Pages 53-57.
  15661.  
  15662.  
  15663.  495. OS/2 SDK: DISKCACHE Information
  15664.  
  15665.  Question:
  15666.  
  15667.  No matter what value I set DISKCACHE to in my CONFIG.SYS file, the
  15668.  disk performance does not seem to improve. When running any normal
  15669.  programs such as the editor or the C compiler, or even just test
  15670.  programs that only read and never write, it is clear that everything
  15671.  is read from the disk on each invocation, with no discernible
  15672.  improvement in disk performance. Why is this happening?
  15673.  
  15674.  Response:
  15675.  
  15676.  This behavior is due to the cache implementation. OS/2's built-in
  15677.  cache is different in its operation than most other cache schemes you
  15678.  might be familiar with (e.g. SMARTDRV, etc.). The performance you are
  15679.  seeing is consistent with the current implementation.
  15680.  
  15681.  The cache algorithm passes all requests greater than the sector
  15682.  threshold (currently the threshold is seven sectors) directly to the
  15683.  disk driver, and the cache is not used. Anything over seven sectors is
  15684.  considered sequential access. There are two reasons for this; they are
  15685.  as follows:
  15686.  
  15687.  1. To prevent the cache from being flushed by a large read request.
  15688.  
  15689.  2. As alluded to above, for a large read request, the cache gets in
  15690.     the way because it will further break down the request into
  15691.     page-sized requests to suit the cache. This would further delay the
  15692.     read such that it is as fast or faster (average case) to read
  15693.     straight from the disk.
  15694.  
  15695.  We are looking into alternate caching methods for future releases. In
  15696.  the meantime, caches larger than 512K or 1 MB probably will not
  15697.  provide improved performance. If you want to have fast load times for
  15698.  the C compiler, etc., and you have memory to spare, we recommend using
  15699.  this memory for a RAM disk instead.
  15700.  
  15701.  
  15702.  496. OS/2 SDK: Device Driver Return Error 104 Documentation
  15703.  
  15704.  Question:
  15705.  
  15706.  When an OS/2 device driver tries to clear a system semaphore (which
  15707.  was created and set by the user, passed to the driver using an IOCtl,
  15708.  and marked in_use at task time), the DEV_HLP returns an error code of
  15709.  104 (68 hex). What does this error mean?
  15710.  
  15711.  Response:
  15712.  
  15713.  You are getting a return value that indicates the handle is invalid at
  15714.  interrupt time. Error 104 is documented in the BSEERR.H include file.
  15715.  
  15716.  In your device driver, you must use the SemHandle() DevHlp to convert
  15717.  the handle the user passes in the IOCtl call to a system handle the
  15718.  device driver can use at interrupt time. This is only necessary if you
  15719.  need to be able to use the semaphore at interrupt time.
  15720.  
  15721.  You need to do this because at task time, the handle you are passing
  15722.  is contained in the user's LDT (Local Descriptor Table). If you only
  15723.  access the semaphore during kernel mode, there will be no problem
  15724.  because the LDT is still around at that time. But at interrupt time,
  15725.  the LDT is gone and all that is left is the GDT (Global Descriptor
  15726.  Table). Thus, you no longer have addressability to the semaphore.
  15727.  
  15728.  The SemHandle() DevHlp will create a GDT entry for the semaphore, and
  15729.  the handle will be valid at either task time or interrupt time.
  15730.  
  15731.  
  15732.  497. OS/2 SDK 1.06: Problems on Dell 310/325 Systems with 80387s
  15733.  
  15734.  On some Dell 310 and 325 80386 systems, the IBM OS/2 Version 1.10
  15735.  standard edition (Microsoft OS/2 SDK Version 1.06) may not work if the
  15736.  system has an Intel 80387 Numeric Processor Extension (NPX) installed.
  15737.  Removal of this 80387 NCP allows OS/2 to work with these releases of
  15738.  OS/2. Microsoft has confirmed this to be a problem in Version 1.06 of
  15739.  the OS/2 SDK. This problem was corrected in Version 1.10 of the OS/2
  15740.  SDK.
  15741.  
  15742.  
  15743.  498. DosMuxSemWait() Example Has Mismatched Braces in IF Statement
  15744.  
  15745.  In the most recent version of QuickHelp, the "Microsoft OS/2 1.0
  15746.  Programmer's Reference" (Section 3.2, Pages 152-155), and the
  15747.  "Microsoft OS/2 1.1 Programmer's Reference" (Volume 3, Section 2.2,
  15748.  Pages 92-94), the example for DosMuxSemWait() has an invalid C
  15749.  statement in it. The following is the code from this example:
  15750.  
  15751.      DEFINEMUXSEMLIST(MuxList, 2)         /* creates structure array */
  15752.      USHORT usSemIndex;
  15753.      MuxList.cmxs = 2;
  15754.      DosCreateSem(CSEM_PUBLIC, &MuxList.amxs[0].hsem,
  15755.          "\\sem\\timer0.sem");
  15756.      DosCreateSem(CSEM_PUBLIC, &MuxList.amxs[1].hsem,
  15757.          "\\sem\\timer1.sem");
  15758.          .
  15759.          .
  15760.          .
  15761.      DosMuxSemWait(&usSemIndex, &MuxList, 5000L);
  15762.      if (usSemIndex == 1) {
  15763.          DosSemSet(MuxList.amxs[1].hsem);
  15764.  
  15765.  In the if() statement above, there is an opening brace but no closing
  15766.  brace. Since there is only one line of code inside the if() loop, the
  15767.  opening brace is not needed. Or, a closing brace should be added.
  15768.  Thus, to correct this, one of the following two methods can be used:
  15769.  
  15770.      if (usSemIndex == 1)
  15771.          DosSemSet(MuxList.amxs[1].hsem);
  15772.  
  15773.  or
  15774.  
  15775.      if (usSemIndex == 1) {
  15776.          DosSemSet(MuxList.amxs[1].hsem);
  15777.      }
  15778.  
  15779.  The example omitted the closing brace to imply that actual code would
  15780.  continue to perform other activities with the semaphore (such as
  15781.  setting the appropriate semaphore again). Thus, the code could be
  15782.  written more properly as follows:
  15783.  
  15784.      if (usSemIndex == 1) {
  15785.          DosSemSet(MuxList.amxs[1].hsem);
  15786.          .
  15787.          .
  15788.          .
  15789.      }
  15790.  
  15791.  Microsoft has confirmed this to be a problem in the QuickHelp included
  15792.  with the OS/2 SDK Version 1.06. We are researching this problem and
  15793.  will post new information as it becomes available.
  15794.  
  15795.  
  15796.  499. QuickHelp DosError() Sample Source Incorrectly Uses DosExit()
  15797.  
  15798.  In the QuickHelp entry for the DosError() API, the source code example
  15799.  uses the DosExit() API incorrectly. DosExit() is listed as follows:
  15800.  
  15801.     DosExit(1, EXIT_PROCESS);
  15802.  
  15803.  Instead, DosExit() should be listed as follows:
  15804.  
  15805.     DosExit(EXIT_PROCESS, 1);
  15806.  
  15807.  The problem is that the first and second parameters are switched.
  15808.  However, this will not affect the behavior adversely, because OS/2
  15809.  will translate this to DosExit(1,1), since EXIT_PROCESS maps out to a
  15810.  value of 1 anyway.
  15811.  
  15812.  Microsoft has confirmed this to be a problem in the QuickHelp included
  15813.  with the OS/2 SDK Version 1.06. We are researching this problem and
  15814.  will post new information as it becomes available.
  15815.  
  15816.  
  15817.  500. QuickHelp SYS1943: Asterisk (*) Causes GP Violation
  15818.  
  15819.  QuickHelp causes a general protection violation when the asterisk
  15820.  character (*) is used within the search topic field. One or more
  15821.  additional characters in the search string are usually required to
  15822.  cause this violation.
  15823.  
  15824.  Microsoft has confirmed this to be a problem with the QuickHelp
  15825.  included in the OS/2 SDK Versions 1.06 and 1.10. We are researching
  15826.  this problem and will post new information as it becomes available.
  15827.  
  15828.  The following sequence of events produces a protection violation with
  15829.  QuickHelp:
  15830.  
  15831.  1. Open an OS/2 full-screen command prompt screen group.
  15832.  
  15833.  2. At the command prompt, type the command "QH".
  15834.  
  15835.  3. When the "Microsoft QuickHelp" screen is displayed, type "s"
  15836.     (search).
  15837.  
  15838.  4. When "Enter topic to search for:" is displayed, type "*tr".
  15839.  
  15840.  An error window will be displayed with the session title and the
  15841.  following contents:
  15842.  
  15843.     SYS1943: A program caused a protection violation.
  15844.  
  15845.     TRAP 000D
  15846.     AX=0000 BX=0000 CX=0000 DX=04E7 BP=A520
  15847.     SI=E4E8 DI=1248 DS=0C5F ES=04E7 FLG=2A96
  15848.     CS=02FF IP=0c35 ss=0087 SP=A518 MSW=FFFD
  15849.     CSLIM=19D0 SSLIM=AB8F DSLIM=009F ESLIM=1A41
  15850.     CSACC=F8 SSACC=F3 DSACC=F3 ESACC=F3
  15851.     ERRCD=0000 ERLIM=**** ERACC=**
  15852.  
  15853.  You can then end the program and the session is returned to normal.
  15854.  
  15855.  
  15856.  501. OS/2 SDK: Removing Subdirectories That Contain Hidden Files
  15857.  
  15858.  When the removal of an otherwise empty subdirectory fails, Microsoft
  15859.  OS/2 Versions 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, and 1.06 will
  15860.  return one of the following error messages:
  15861.  
  15862.  1. In an OS/2 screen group, the following error message will be
  15863.     returned:
  15864.  
  15865.        SYS0016: The directory cannot be removed
  15866.  
  15867.  2. In the DOS compatibility box, the following error message will be
  15868.     returned:
  15869.  
  15870.        Invalid path, not directory, or directory not empty
  15871.  
  15872.  In most cases, if either of these messages is displayed, it means
  15873.  that there is at least one file or subdirectory contained in the
  15874.  directory being deleted. However, the error message is not totally
  15875.  complete. There are two other situations when these messages will be
  15876.  generated; they are as follows:
  15877.  
  15878.  1. If, in one of the OS/2 screen groups or the DOS compatibility box,
  15879.     the current directory is set to that subdirectory.
  15880.  
  15881.  2. If there are hidden files in that subdirectory. The attributes of
  15882.     these files need to be set to unhidden and then deleted. For
  15883.     example, the Microsoft M Editor creates hidden files in a hidden
  15884.     \DELETED subdirectory. These files should only be removed using
  15885.     the EXP(unge) command included with the M Editor.
  15886.  
  15887.  In the first case, scan through each of the opened OS/2 screen groups
  15888.  and either change directories to another directory, or EXIT from that
  15889.  screen group. In the second case, using the EXP(unge) command may be
  15890.  helpful only if there is a hidden subdirectory named DELETED. If
  15891.  there are other hidden files or subdirectories, it may be necessary
  15892.  to use other utilities to unhide and delete the hidden files or
  15893.  subdirectories.
  15894.  
  15895.  
  15896.  502. OS/2 SDK: DosMuxSemWait() Semaphore and Event Limits
  15897.  
  15898.  The following information describes the semaphore and event limits
  15899.  involving the DosMuxSemWait() API.
  15900.  
  15901.  The MUXSEM and MUXSEMLIST data structures are defined in the Microsoft
  15902.  OS/2 SDK (Software Development Kit) include file BSEDOS.H, in the
  15903.  section around INCL_DOSSEMAPHORES. The MUXSEMLIST data structure
  15904.  contains a list of the semaphores to be acted on by the OS/2
  15905.  DosMuxSemWait() API. This MUXSEMLIST structure holds up to 16
  15906.  semaphores.
  15907.  
  15908.  OS/2 Version 1.10 has an upper limit of 256 system semaphores at one
  15909.  time. It also has an upper limit of up to 16 events per
  15910.  DosMuxSemWait() call. Finally, it has an upper limit of 128
  15911.  system-wide maximum number of MuxSemWait events. This information is
  15912.  summarized as follows:
  15913.  
  15914.     #define MAX_SYSSEM     256 /* maximum number of system semaphores */
  15915.     #define MAX_MUXEVENTS   16 /* maximum number of events per
  15916.                                   DosMuxSemWait call */
  15917.     #define MAX_MUXENTRIES 128 /* total system wide maximum number of
  15918.                                   MuxSemWait events */
  15919.  
  15920.  
  15921.  503. Bound Executable File Clears Command Line Buffer in MS-DOS
  15922.  
  15923.  Question:
  15924.  
  15925.  Why does a bound executable file clear the command-line buffer in
  15926.  MS-DOS Version 4.00? Even the most simple C program, when made a FAPI
  15927.  with BIND.EXE, clears the F3 buffer after the program has finished
  15928.  executing.
  15929.  
  15930.  Response:
  15931.  
  15932.  The COMMAND.COM command-line buffer is being cleared because the bound
  15933.  application is allocating all of MS-DOS memory, or at least enough to
  15934.  cause COMMAND.COM to be reloaded. The transient portion of
  15935.  COMMAND.COM, sitting at the top of available memory, gets written
  15936.  over, causing COMMAND.COM's resident portion to reload the transient
  15937.  portion. The transient portion of COMMAND.COM is where the
  15938.  command-line buffer information is stored.
  15939.  
  15940.  This problem does not occur with the COMMAND.COM of OS/2's DOS
  15941.  compatibility mode, but it DOES occur with normal MS-DOS. This
  15942.  difference is not easily explainable; the DOS compatibility mode
  15943.  appears to be better suited to accept these bound files. The stub
  15944.  loader that is used while running under DOS to load/exec the OS/2 EXE
  15945.  code/data that is in this bound executable file behaves differently
  15946.  when running in the OS/2 DOS compatibility mode as opposed to "normal"
  15947.  DOS.
  15948.  
  15949.  
  15950.  504. DosCaseMap() Case Error and DosGetMessage() Missing in API.LIB
  15951.  
  15952.  Problem:
  15953.  
  15954.  In the library API.LIB, DosCaseMap() is not all caps, as required for
  15955.  PASCAL calling conventions. Also, DosGetMessage() is not listed in
  15956.  API.LIB.
  15957.  
  15958.  Response:
  15959.  
  15960.  The code for DosGetMessage() is actually in OS2.LIB, the
  15961.  protected-mode library. Most of the APIs in this library do not have
  15962.  any actual code and are only import definition records, but
  15963.  DosGetMessage() is an exception. There is a small routine here that
  15964.  calls the routine DosTrueGetMessage(), and the code for
  15965.  DosTrueGetMessage() is in API.LIB. The problem that you are seeing
  15966.  only occurs when you try linking directly to the FAPI (Family API)
  15967.  library, API.LIB rather than using it in conjunction with the BIND
  15968.  utility. For some of the routines in API.LIB to work properly, it is
  15969.  necessary that a piece of start-up code be executed. This start-up
  15970.  code is placed into the .EXE file as part of the binding process. It
  15971.  will not be present if a program is compiled for MS-DOS and is linked
  15972.  with the API.LIB library. The only way to ensure that the routines in
  15973.  API.LIB function properly is to compile the program for OS/2 (although
  15974.  this can be done while running under MS-DOS with the -Lp command line
  15975.  parameter to the C compiler) and then using the BIND utility to bind
  15976.  the program for use in both OS/2 and MS-DOS. When used this way,
  15977.  DosGetMessage() is properly resolved.
  15978.  
  15979.  In a similar manner, the problem with the case of the APIs in API.LIB
  15980.  is resolved when you bind. The BIND utility does not consider case as
  15981.  significant when binding an application, and so it properly resolves
  15982.  the calls to the MS-DOS routines in API.LIB that are in mixed case. As
  15983.  a matter of consistency, however, we have suggested that the case be
  15984.  changed to all uppercase for the DosCaseMap() API, as well as any
  15985.  other APIs that have this problem, in a future release of the product.
  15986.  
  15987.  
  15988.  505. Cannot Use KbdSetStatus with fsMask Set to 0x000A in Real Mode
  15989.  
  15990.  Problem:
  15991.  
  15992.  When I use KbdSetStatus() and set the second parameter, fsMask, to
  15993.  cooked mode on and echo mode off (Ox000A), I get the following error
  15994.  message when I run my program in real mode:
  15995.  
  15996.     378 ERROR_KBD_INVALID_INPUT_MASK
  15997.  
  15998.  This error is not returned when I run my program in protected mode.
  15999.  
  16000.  Response:
  16001.  
  16002.  This set of parameters is not supported in real mode. We have asked
  16003.  that this information be added to the "Microsoft Operating System/2
  16004.  Programmer's Toolkit Programmer's Reference" Version 1.00 manual and
  16005.  QuickHelp.
  16006.  
  16007.  
  16008.  506. Using Old MS-DOS Device Drivers under OS/2
  16009.  
  16010.  Question:
  16011.  
  16012.  Can old MS-DOS device drivers be used under OS/2?
  16013.  
  16014.  Response:
  16015.  
  16016.  Yes, some old MS-DOS device drivers can be used in OS/2. They would
  16017.  need to be loaded in the OS/2 CONFIG.SYS file. However, not all MS-DOS
  16018.  device drivers can be used. Block device drivers cannot be loaded
  16019.  (thus, only MS-DOS character drivers can be loaded). The MS-DOS
  16020.  character device driver cannot have a hardware interrupt handler
  16021.  (i.e., the device must be POLLED rather than interrupt-driven). Also,
  16022.  the MS-DOS character device driver cannot have exclusive control of
  16023.  some types of hardware, such as the mouse or the clock. This
  16024.  information is also documented in the "Microsoft Operating System/2
  16025.  Device Drivers Guide" in Section 1.13, "Compatibility with Old Device
  16026.  Drivers."
  16027.  
  16028.  
  16029.  507. OS/2 SDK: Resizing the SWAPPER.DAT File
  16030.  
  16031.  Question:
  16032.  
  16033.  I am using OS/2 Version 1.10 with 3.5 MB of memory. I am using OS/2
  16034.  heavily and my SWAPPER.DAT file has reached 1.7 MB. Does this file
  16035.  keep growing indefinitely?
  16036.  
  16037.  Response:
  16038.  
  16039.  Under OS/2 1.10, rebooting the machine will cause the SWAPPER.DAT file
  16040.  to be resized to its default size, which is about 650K. There is no
  16041.  way to shrink the size of the SWAPPER.DAT file during a session of
  16042.  OS/2.
  16043.  
  16044.  Under OS/2 1.00, the size of the SWAPPER.DAT file does not change when
  16045.  the system is rebooted. One way to reduce the SWAPPER.DAT file to its
  16046.  default size is to boot with a different operating system (e.g.
  16047.  MS-DOS), delete the SWAPPER.DAT file, and then reboot OS/2.
  16048.  
  16049.  You can also delete the SWAPPER.DAT file under OS/2 1.00 without
  16050.  booting MS-DOS. To do this, change the SWAPPATH environment variable
  16051.  to  something else, and then reboot OS/2. You can then delete the
  16052.  SWAPPER.DAT file and set the SWAPPATH environment variable back to its
  16053.  original setting.
  16054.  
  16055.  
  16056.  508. DosFindNext() Searches Incorrect Subdirectory in Version 1.06
  16057.  
  16058.  There is a problem when calling DosFindFirst()/DosFindNext() on the
  16059.  root directory of a drive in which the first entry in the root
  16060.  directory is a subdirectory (not a file). With only DosFindFirst()/
  16061.  DosFindNext(), this works as expected. When _beginthread() is called
  16062.  immediately before the DosFindFirst()/DosFindNext() code,
  16063.  DosFindFirst() works properly (finding the first subdirectory entry).
  16064.  However, DosFindNext() incorrectly shifts down to begin looping into
  16065.  the files of this first subdirectory, instead of continuing with the
  16066.  second and subsequent entries in the root directory, as expected.
  16067.  
  16068.  Using DosCreateThread() instead of _beginthread() will result in
  16069.  the same problem.
  16070.  
  16071.  Microsoft has confirmed this to be a problem with the DosFindNext()
  16072.  function call in the Version 1.06 OS/2 SDK (Software Development Kit).
  16073.  We are researching this problem and will post new information as it
  16074.  becomes available.
  16075.  
  16076.  Another issue to complicate the problem is that the first run of
  16077.  this sequence of function calls will fail (as expected). However,
  16078.  the second and subsequent runs of this sequence of function calls
  16079.  will work (unexpectedly). To get this problem to occur reliably, a
  16080.  large program must be run to flush the system. If you execute "cl
  16081.  -help" between each run of this sequence of function calls, the
  16082.  problem will occur consistently. Under MS-DOS, this symptom could be
  16083.  explained by uninitialized variables that the first sequence of
  16084.  function calls initializes, and the second and subsequent sequence of
  16085.  function calls can use, while executing CL.EXE in this case can
  16086.  be used to flush memory back to an uninitialized state. However, this
  16087.  situation is not as easily explained under OS/2.
  16088.  
  16089.  One workaround for this problem is to call DosSleep() to allow the
  16090.  system to coalesce the newly created thread after creating the thread
  16091.  and before beginning the DosFindFirst()/DosFindNext() loop, thus not
  16092.  interfering with the DosFindFirst()/DosFindNext() loop. For example,
  16093.  with this delay after creating the thread, the DosFindFirst()/
  16094.  DosFindNext() loop will properly find all files on the root directory,
  16095.  regardless of whether or not the first entry is a subdirectory. If you
  16096.  use DosSleep() with a value of 500L, the problem seems to be
  16097.  eliminated.
  16098.  
  16099.  
  16100.  509. Product Purchase Information for International ISVs and IHVs
  16101.  
  16102.  International ISVs and IHVs that wish to obtain OS/2 and LAN Manager
  16103.  products such as the OS/2 SDK (Software Development Kit), OS/2 DDDK
  16104.  (Device Driver Development Kit), and SQL NDK (Structured Query
  16105.  Language Network Development Kit) should contact their nearest
  16106.  Microsoft subsidiary office. If the subsidiary does not distribute the
  16107.  product you want to purchase, contact the domestic US Microsoft
  16108.  International Customer Service at the following number:
  16109.  
  16110.     +1 (206) 882-8661
  16111.  
  16112.  They can obtain Microsoft licensed products that are not handled by a
  16113.  regional Microsoft subsidiary office.
  16114.  
  16115.  
  16116.  510. OS/2 SDK: SPOOL.EXE and PMSPOOL.EXE Information
  16117.  
  16118.  Question:
  16119.  
  16120.  What is the difference between PMSPOOL.EXE and SPOOL.EXE. Are they
  16121.  linked together at all?
  16122.  
  16123.  Response:
  16124.  
  16125.  PMSPOOL.EXE and SPOOL.EXE divide up the functionality of the PM
  16126.  (Presentation Manager) spooler. PMSPOOL.EXE is the visual interface
  16127.  of the spooler. It is what puts the icon on the screen and processes
  16128.  the messages. No spool queue management is done by PMSPOOL.EXE, and
  16129.  the OS2.INI file is not updated to reflect that the spooler is active
  16130.  at boot-up time if this is the only file that is loaded.
  16131.  
  16132.  SPOOL.EXE is the spool queue manager. It accepts and dispatches print
  16133.  jobs. It also changes the OS2.INI file and marks the spooler as
  16134.  active.
  16135.  
  16136.  SPOOL.EXE calls PMSPOOL.EXE after the queues are set up to give the
  16137.  spooler the visual interface that it needs to be operative under PM.
  16138.  
  16139.  If you type "PMSPOOL" at the command prompt, you will get the visual
  16140.  interface, but not the spooler itself. It will appear to be there
  16141.  (visually), but actually will not be.
  16142.  
  16143.  
  16144.  511. OS/2 SDK: "usNumSeg" Value Incorrect in DosAllocHuge() Example
  16145.  
  16146.  Microsoft has confirmed that there is a documentation error involving
  16147.  the DosAllocHuge() function call example on Page 49 of the "Microsoft
  16148.  Operating System/2 Programmer's Toolkit Programmer's Reference Version
  16149.  1.0" manual, and in the version of QuickHelp included with the Version
  16150.  1.06 OS/2 SDK (Software Development Kit).
  16151.  
  16152.  The example on Page 49 states that the "usNumSeg" parameter should be
  16153.  set to "3". It should be instead set to "2", since the example is
  16154.  allocating only two segments that are 64K in size, and the third
  16155.  segment is only 200 bytes.
  16156.  
  16157.  
  16158.  512. DosClose() Invalidates File Handle If Drive Door Is Open
  16159.  
  16160.  Question:
  16161.  
  16162.  There seems to be a problem with the DosClose() function. If I attempt
  16163.  a DosClose() with a file handle for a floppy-disk file, and the
  16164.  floppy-disk door is open, I get a pop-up window asking me whether to
  16165.  end, retry, or return the error to the program. If I choose to return
  16166.  the error, close the floppy-disk door, and do another DosClose() with
  16167.  that file handle, I get an error indicating that the file handle is
  16168.  invalid. Since the file has not been closed, why is the file handle
  16169.  considered invalid?
  16170.  
  16171.  Response:
  16172.  
  16173.  When the floppy disk is removed from the disk drive, the system is in
  16174.  an inconsistent state. There is no way to tell which floppy disk is in
  16175.  the disk drive; therefore, the file handle is invalidated. This occurs
  16176.  because even though OS/2 writes a serial number on the floppy disk,
  16177.  MS-DOS Version 3.30 does not. This would cause problems if OS/2
  16178.  counted on the serial number. Also, if the MS-DOS Version 3.30 DISKCOPY
  16179.  utility copied the floppy disk with the same serial number and then
  16180.  the first floppy disk were modified, the second floppy disk could be
  16181.  put in the disk drive at a critical point and OS/2 would not be able
  16182.  to tell that the wrong floppy disk was in the disk drive.
  16183.  
  16184.  
  16185.  513. OS/2 SDK: Interpreting Trap Information
  16186.  
  16187.  Question:
  16188.  
  16189.  Our OS/2 machine had a trap occur. The registers were dumped and then
  16190.  the system halted. Where can I find documentation that tells me why
  16191.  this happened? Also, how can I interpret the dump information?
  16192.  
  16193.  Response:
  16194.  
  16195.  Most of the information from this trap dump is a raw dump of the Intel
  16196.  80286 register set. Chapter 9 ("Interrupts and Exceptions") in the
  16197.  "Intel 80286 Software Reference" manual is the best reference for this
  16198.  register set; the manual explains how to interpret the register set.
  16199.  
  16200.  One thing OS/2 puts in the dump that is not in the 80286 register set
  16201.  is the OS/2 session ID.
  16202.  
  16203.  The following is a list of what to look for in the register dump:
  16204.  
  16205.  1. Check the ring level. Bits 5 and 6 of the CSACC byte contain the
  16206.     descriptor privilege level (DPL), also known as the ring level.
  16207.     For more information on DPL, refer to Figure 6-7 of the "Intel
  16208.     80286 Programmer's Reference" manual. If the ring is 3, then the
  16209.     trap most likely came from an application. If the ring is 0, then
  16210.     the trap probably came from a device driver or the OS/2 kernel.
  16211.  
  16212.  2. Check to see if the LDT (local descriptor table) or GDT (global
  16213.     descriptor table) is being referenced.
  16214.  
  16215.  3. Check to see if the segment registers are nonzero, which they
  16216.     should be.
  16217.  
  16218.  4. Check to see if the SP is beyond the SS.
  16219.  
  16220.  5. Check to see if ES or DS contain an "*" (asterisk); it could be
  16221.     pointing to an invalid selector.
  16222.  
  16223.  Again, Chapter 9 of the "Intel 80286 Programmer's Reference" manual
  16224.  describes the many 80286 traps and exceptions that could possibly
  16225.  cause a dump to occur.
  16226.  
  16227.  
  16228.  514. Next Scheduling Opportunity for Blocked High-Priority Thread
  16229.  
  16230.  Question:
  16231.  
  16232.  When will a blocked high priority thread be given control following a
  16233.  DevHlp Run? The documentation refers to the "next scheduling
  16234.  opportunity," but doesn't define it.
  16235.  
  16236.  Response:
  16237.  
  16238.  The OS model we have has two modes: user and kernel. User mode occurs
  16239.  when the processor is executing user application ring 2 or ring 3
  16240.  code. Kernel mode occurs when the processor is executing ring 0 code.
  16241.  Whenever the CPU transitions from kernel to user mode, or when a
  16242.  process in kernel mode calls internal scheduler routines to yield the
  16243.  CPU to another thread or to block until an event occurs, these are the
  16244.  "scheduling opportunities" we look for so that higher-priority threads
  16245.  are allowed to be executed.
  16246.  
  16247.  
  16248.  515. OS/2 SDK: Interrupt Latency Information
  16249.  
  16250.  Question:
  16251.  
  16252.  What is the longest possible interrupt latency?
  16253.  
  16254.  Response:
  16255.  
  16256.  The theoretical limit is infinite. The lowest-priority interrupt can
  16257.  be prevented from being executed by higher-priority interrupt
  16258.  saturation.
  16259.  
  16260.  
  16261.  516. OS/2 SDK: Intercepting File I/O or DLL Calls
  16262.  
  16263.  Question:
  16264.  
  16265.  I have the following questions on intercepting file I/O or DLL calls:
  16266.  
  16267.  1. Is it possible to intercept file I/O calls before they go through
  16268.     the file system and either do some other processing or pass the
  16269.     call on to the file system unaltered?
  16270.  
  16271.  2. Is it possible to intercept DLL (dynamic linked library) calls by
  16272.     providing a DLL with the same function entry points (same names)?
  16273.  
  16274.  Response:
  16275.  
  16276.  The following are answers to the questions listed above:
  16277.  
  16278.  1. File I/O calls are entries into OS/2 system DLLs. See the answer
  16279.     below for more information on this topic.
  16280.  
  16281.  2. OS/2 provides no mechanism for intercepting a DLL entry. In terms
  16282.     of most OS/2 APIs, this means that OS/2 provides no mechanism for
  16283.     intercepting an OS/2 API. However, SOME OS/2 APIs, and many of the
  16284.     KBD and VIO APIs, have been designed so that they CAN be replaced.
  16285.     Other than these APIs, which have been designed to provide an
  16286.     interface for replacing (and/or intercepting) them, none of the
  16287.     other OS/2 APIs have a mechanism to be intercepted. In more general
  16288.     terms, this applies to function entry points in a DLL. Intercepting
  16289.     a DLL entry is possible if a DLL is designed so that it can be
  16290.     replaced (such as the VIO and KBD entry points in the OS/2 system
  16291.     DLLs). Otherwise, there is no other mechanism you can use to do
  16292.     this.
  16293.  
  16294.     Intercepting a DLL entry might be done in a situation where a
  16295.     function was behaving improperly. A reasonable thing to do would be
  16296.     to replace the DLL. This is one advantage of DLLs, since they are
  16297.     modular and easily replaceable portions of a program.
  16298.  
  16299.     The entry point of a DLL can be obtained by using
  16300.     DosGetProcAddr() after using DosLoadModule() on a DLL.
  16301.  
  16302.  An application can reroute the way that a DLL function enters itself
  16303.  (but not for other applications). It is possible for a program to
  16304.  reroute a DLL function by using the IMPORT statement of the .DEF
  16305.  file. The application can change the entry point for the program to
  16306.  another name. For example, a function called DosFooBar() could be
  16307.  mapped into DosFubar(). Then, the application could create its own
  16308.  function and name it DosFooBar(), which could perform its own tasks,
  16309.  and then turn around and call the REAL function, which it knows as
  16310.  DosFubar(). This technique is useful for debugging purposes. For
  16311.  example it could be used to show a count of file handles by rerouting
  16312.  DosOpen() to RealDosOpen(), then have a stub DosOpen() which displays
  16313.  the request information, passes the request to RealDosOpen(), and then
  16314.  displays the file handle after RealDosOpen() returns. This method can
  16315.  be used by an application for its own view of DLL entry points. It
  16316.  cannot be used by child processes or other programs running. This
  16317.  technique does not allow applications to take over the system, however.
  16318.  
  16319.  
  16320.  517. OS/2 SDK: BPB BIOSPARMETERBLOCK Documentation Error
  16321.  
  16322.  Microsoft has confirmed that the BPB structure definition documented
  16323.  in the QuickHelp included with the Version 1.06 OS/2 SDK (Software
  16324.  Development Kit) is incorrect.
  16325.  
  16326.  Listed below is the correct documentation for this structure:
  16327.  
  16328.  typedef struct _BIOSPARAMETERBLOCK {    /* bspblk */
  16329.      USHORT usBytesPerSector;
  16330.      BYTE   bSectorsPerCluster;
  16331.      USHORT usReservedSectors;
  16332.      BYTE   cFATs;
  16333.      USHORT cRootEntries;
  16334.      USHORT cSectors;
  16335.      BYTE   bMedia;
  16336.      USHORT usSectorsPerFAT;
  16337.      USHORT usSectorsPerTrack;
  16338.      USHORT cHeads;
  16339.      ULONG  cHiddenSectors;
  16340.      ULONG  cLargeSectors;
  16341.      BYTE   abReserved[6];
  16342.      USHORT cCylinders;
  16343.      BYTE   bDeviceType;
  16344.      USHORT fsDeviceAttr;
  16345.  } BIOSPARAMETERBLOCK;
  16346.  
  16347.  The BIOSPARAMETERBLOCK structure contains BIOS parameter blocks.
  16348.  
  16349.     Parameters          Description
  16350.     ----------          -----------
  16351.  
  16352.     usBytesPerSector    Specifies the bytes per sector.
  16353.  
  16354.     bSectorsPerCluster  Specifies the sectors per cluster.
  16355.  
  16356.     usReservedSectors   Specifies the reserved sectors.
  16357.  
  16358.     cFATs               Specifies the number of file-allocation tables.
  16359.  
  16360.     cRootEntries        Specifies the maximum number of entries in the
  16361.                         root directory.
  16362.  
  16363.     cSectors            Specifies the number of sectors.
  16364.  
  16365.     bMedia              Specifies the media descriptor.
  16366.  
  16367.     usSectorsPerFAT     Specifies the number of sectors per
  16368.                         file-allocation table.
  16369.  
  16370.     usSectorsPerTrack   Specifies the number of sectors per track.
  16371.  
  16372.     cHeads              Specifies the number of heads.
  16373.  
  16374.     cHiddenSectors      Specifies the number of hidden sectors.
  16375.  
  16376.     cLargeSectors       Specifies the number of large sectors.
  16377.  
  16378.     abReserved[6]       Specifies six reserved bytes. These must be zero.
  16379.  
  16380.     cCylinders          Specifies the number of cylinders defined for
  16381.                         the device.
  16382.  
  16383.     bDeviceType         Specifies the type of device. It can be one of
  16384.                         the following values:
  16385.  
  16386.                         Value            Meaning
  16387.                         -----            -------
  16388.  
  16389.                         DEVTYPE_48TPI    48 tracks-per-inch, low-density
  16390.                                          floppy-disk drive
  16391.  
  16392.                         DEVTYPE_96TPI    96 tracks-per-inch, high-density
  16393.                                          floppy-disk drive
  16394.  
  16395.                         DEVTYPE_35       3.5-inch (720K) floppy-disk drive
  16396.  
  16397.                         DEVTYPE_8SD      8-inch, single-density
  16398.                                          floppy-disk drive
  16399.  
  16400.                         DEVTYPE_8DD      8-inch, double-density
  16401.                                          floppy-disk drive
  16402.  
  16403.                         DEVTYPE_FIXED    Fixed disk
  16404.  
  16405.                         DEVTYPE_TAPE     Tape drive
  16406.  
  16407.                         DEVTYPE_UNKNOWN  Other (unknown type of device)
  16408.  
  16409.     fsDeviceAttr        Specifies information about the drive. If this
  16410.                         value is 0x0001, the media are not removable. If
  16411.                         it is 0x0002, the media can detect changes. This
  16412.                         field can be one or both of these values.
  16413.  
  16414.  See Also
  16415.  
  16416.  DSK_GETDEVICEPARAMS, DSK_SETDEVICEPARAMS
  16417.  
  16418.  
  16419.  518. OS/2 Initialization File Information
  16420.  
  16421.  The following is a list of detailed information concerning the major
  16422.  OS/2 initialization files:
  16423.  
  16424.  CONFIG.SYS:    This file is read once by OS/2 when the system boots,
  16425.                 and is used to determine many system characteristics.
  16426.  
  16427.  STARTUP.CMD:   This file is run once by OS/2 when the system starts,
  16428.                 and is used to run programs that only need to be run
  16429.                 once during the lifetime of a system, such as starting
  16430.                 a network.
  16431.  
  16432.  AUTOEXEC.BAT:  This file is run once by OS/2's DOS compatibility mode
  16433.                 the first time the DOS screen group is selected, just
  16434.                 as with MS-DOS systems.
  16435.  
  16436.  OS2.INI:       This file is used by Presentation Manager (PM) and PM
  16437.                 applications. It is an initialization file similar to
  16438.                 the Microsoft Windows file WIN.INI. However, while
  16439.                 WIN.INI is an ASCII file, OS2.INI is a binary file,
  16440.                 and it is not easy to directly manipulate this file.
  16441.                 Instead, you can use the OS/2 APIs such as
  16442.                 WinQueryProfileData(), WinQueryProfileInt(),
  16443.                 WinQueryProfileSize(), WinQueryProfileString(),
  16444.                 WinWriteProfileData(), and WinWriteProfileString() to
  16445.                 change OS2.INI. For more information on these APIs,
  16446.                 refer to the "Microsoft OS/2 Programmer's Reference"
  16447.                 manual.
  16448.  
  16449.  OS2INIT.CMD:   This file is run every time a new copy of CMD.EXE is
  16450.                 executed. This file name is NOT hard coded in OS/2; the
  16451.                 name is user-configurable. In previous releases of
  16452.                 OS/2, the CONFIG.SYS PROTSHELL statement used the /K
  16453.                 switch of CMD.EXE, followed by the filename of
  16454.                 OS2INIT.CMD. Thus, whenever a copy of CMD.EXE was
  16455.                 executed, the OS2INIT.CMD file was run. One reason why
  16456.                 this was useful was that in OS/2 1.00, environment
  16457.                 variables were not inherited by child processes, and
  16458.                 OS2INIT.CMD was used to re-SET all of the standard
  16459.                 environment variables. However, in OS/2 1.10,
  16460.                 environment variables can now be SET in CONFIG.SYS, and
  16461.                 these variables are the default variables passed to all
  16462.                 processes (unless the parent wants to send something
  16463.                 else to its children). Therefore, the use of
  16464.                 OS2INIT.CMD in this manner is not as useful in OS/2
  16465.                 1.10 as it was in 1.00. Thus, the default installation
  16466.                 of OS/2 does not include "/K OS2INIT.CMD" after CMD.EXE
  16467.                 in the PROTSHELL statement, as in previous releases of
  16468.                 OS/2. However, you may add this information back to
  16469.                 your PROTSHELL statement if you wish to use it.
  16470.  
  16471.  
  16472.  519. Communication between the DOS 3.x Box and an OS/2 Session
  16473.  
  16474.  Question:
  16475.  
  16476.  I have a program running in the DOS 3.x box, which communicates with
  16477.  OS/2 processes through a "common" memory area (the physical address
  16478.  is converted to a selector by a simple OS/2 device driver). I have the
  16479.  following questions about the DOS 3.x box:
  16480.  
  16481.  1. How can a program in the DOS 3.x box yield to OS/2?
  16482.  
  16483.  2. What is the priority of the DOS 3.x box?
  16484.  
  16485.  3. Is there a fast way to allow communication between a program
  16486.     running in the DOS 3.x box and an OS/2 session?
  16487.  
  16488.  Response:
  16489.  
  16490.  Listed below are the answers to the above questions:
  16491.  
  16492.  1. A program in the DOS 3.x box can be made to yield to OS/2 by
  16493.     calling DosSleep(0L) from your DOS FAPI application. Otherwise,
  16494.     there is no way to give up your time slice.
  16495.  
  16496.  2. The priority of the DOS 3.x box is approximately the same as a
  16497.     normal OS/2 foreground application, with added boosts to its
  16498.     priority based on the fact that it is the DOS 3.x box and may have
  16499.     applications that are time dependent. Very high priority threads
  16500.     and interrupts may run before the DOS 3.x box will run. However,
  16501.     the DOS 3.x box will be running most of the time when it is in the
  16502.     foreground.
  16503.  
  16504.     In the background, the DOS 3.x box has no priority and receives no
  16505.     time slices.
  16506.  
  16507.  3. There aren't very many ways to communicate between the two sessions,
  16508.     as this is not done very often. The DOS application must poll to be
  16509.     able to communicate with an OS/2 session because no IPC (Inter-
  16510.     Process Communication) mechanisms are allowed in the DOS 3.x box.
  16511.  
  16512.     However, since OS/2 does have IPC mechanisms (namely semaphores),
  16513.     you could instead write a device driver to handle the memory
  16514.     sharing. Then, the OS/2 application could wait on a semaphore
  16515.     instead of having the DOS application do polling. When data is
  16516.     available, the device driver could clear the semaphore and let the
  16517.     OS/2 application run.
  16518.  
  16519.  
  16520.  520. Do NOT Use Device Monitors in the PM Screen Group
  16521.  
  16522.  Character device monitors should ONLY be used in full-screen screen
  16523.  groups used by full-screen VIO applications. Do not count on character
  16524.  device monitors [e.g. APIs such as DosMonReg()] working in the
  16525.  Presentation Manager screen group. Monitoring character devices using
  16526.  the DosMon* APIs may not work in future releases of OS/2. In the
  16527.  future, all attempts to register a monitor for these screen groups
  16528.  should fail.
  16529.  
  16530.  A monitor in the Presentation Manager screen group cannot monitor
  16531.  device activity for an individual application. It must monitor all
  16532.  programs currently running in this screen group. This makes using a
  16533.  monitor in the Presentation Manager screen group impossible. Monitors
  16534.  are only useful for VIO applications running in full-screen groups.
  16535.  Advanced VIO (AVIO) and Presentation Manager applications running in
  16536.  the Presentation Manager screen group don't have to worry about the
  16537.  inability to use the DosMon* APIs: they can use the message queues
  16538.  provided by the Presentation Manager to obtain the analogous
  16539.  information as a monitor. This sort of message "monitoring" is the
  16540.  recommended method in this screen group.
  16541.  
  16542.  
  16543.  521. Using Charles Petzold Sample Code in Production Application
  16544.  
  16545.  Question:
  16546.  
  16547.  What is your position regarding the use of the sample code copyrighted
  16548.  by Microsoft and Charles Petzold in a production application?
  16549.  
  16550.  Response:
  16551.  
  16552.  The book "Programming the OS/2 Presentation Manager" by Charles
  16553.  Petzold is distributed by Microsoft Press. Mr. Petzold has royalty
  16554.  contracts from Microsoft Press for his code. Therefore, the use of
  16555.  this code is more restrictive than the other sample code from the OS/2
  16556.  Software Development Kit (SDK).
  16557.  
  16558.  To obtain legal permission to use code from any of Petzold's sample
  16559.  programs from his PM book, write to Microsoft Press at the following
  16560.  address:
  16561.  
  16562.     Microsoft Press
  16563.     Attn: Susan McRhoton
  16564.     16011 NE 36th Way
  16565.     Box 97017
  16566.     Redmond, WA 98073-9717
  16567.  
  16568.  The letter should include a description of your product, the number of
  16569.  copies you expect to distribute, the cost of the product, the source
  16570.  module you want to use, and the percentage of the source code you are
  16571.  going to use. Microsoft Press will either grant or deny your request.
  16572.  
  16573.  
  16574.  522. OS/2 SDK: Adding to PM Main Menu with WinAddProgram()
  16575.  
  16576.  Question:
  16577.  
  16578.  I would like to add an entry to the OS/2 Presentation Manager's main
  16579.  menu using the WinAddProgram() function. Can I do this from a
  16580.  character-based application? WinAddProgram() doesn't work consistently
  16581.  if I haven't done a call to WinCreateMsgQueue().
  16582.  
  16583.  Response:
  16584.  
  16585.  WinAddProgram() is meant to be used by Presentation Manager (and AVIO)
  16586.  applications. VIO applications (windowable and full-screen) have no
  16587.  concept that they are running in the Presentation Manager
  16588.  windowable, graphical environment, and therefore don't have access to
  16589.  modify this environment.
  16590.  
  16591.  
  16592.  523. OS/2 SDK: Installing New Versions of DLLs in CONFIG.SYS
  16593.  
  16594.  Question:
  16595.  
  16596.  Can I install new versions of DLLs (dynamic linked libraries), such as
  16597.  DISPLAY.DLL, without booting the computer with MS-DOS?
  16598.  
  16599.  Response:
  16600.  
  16601.  Yes, you can install new versions of DLLs; however, there are a few
  16602.  things you should be aware of. Once a DLL is loaded, OS/2 locks it so
  16603.  you can't change it. The environment variable that is used for
  16604.  locating the DLL is the LIBPATH variable that is specified in
  16605.  CONFIG.SYS.
  16606.  
  16607.  The following method will allow you to change DISPLAY.DLL without
  16608.  booting the computer with MS-DOS:
  16609.  
  16610.  1. Add another directory path before the original directory path to
  16611.     the LIBPATH line in CONFIG.SYS. For example:
  16612.  
  16613.        Original LIBPATH statement: LIBPATH=C:\OS2\DLL
  16614.        New LIBPATH statement:      LIBPATH=C:\NEWDLL;C:\OS2\DLL
  16615.  
  16616.  2. Place the new version of DISPLAY.DLL in C:\NEWDLL.
  16617.  
  16618.  3. Reboot the computer.
  16619.  
  16620.  The new version of DISPLAY.DLL will be loaded first because it is
  16621.  located earlier in the LIBPATH statement than the old version of
  16622.  DISPLAY.DLL. This procedure can then be reversed to replace the
  16623.  version of DISPLAY.DLL that was originally being used and to restore
  16624.  the LIBPATH back to its original state.
  16625.  
  16626.  
  16627.  524. Keyboard Monitors Not Supported in the Compatibility Box
  16628.  
  16629.  Question:
  16630.  
  16631.  The keyboard monitor that I wrote works correctly with a
  16632.  protected-mode screen group. Will I be able to use this same keyboard
  16633.  monitor to monitor keystrokes for the compatibility-box screen group
  16634.  from a protected-mode process?
  16635.  
  16636.  Response:
  16637.  
  16638.  Keyboard monitors are not supported in the compatibility box. To
  16639.  accomplish what you are trying to do, we suggest that you write a
  16640.  terminate-and-stay-resident (TSR) program in the compatibility box
  16641.  that emulates the keyboard monitor you are using with a protected-mode
  16642.  screen group.
  16643.  
  16644.  If you want to communicate between the two modes (compatibility and
  16645.  protected), write a shared-memory device driver that both the
  16646.  real-mode TSR monitor and the protected-mode monitor can read and
  16647.  write to.
  16648.  
  16649.  
  16650.  525. OS/2 SDK: Using WINDOWAPI in Module Definition File
  16651.  
  16652.  Problem:
  16653.  
  16654.  When I build and run the program listed below, I get a directory
  16655.  listing in the window that I started the program from. However, if I
  16656.  change the line in the module definition file from WINDOWCOMPAT to
  16657.  WINDOWAPI and rebuild the program, the program returns me to the
  16658.  command prompt.
  16659.  
  16660.  Program
  16661.  -------
  16662.  
  16663.  #include <stdio.h>
  16664.  #include <process.h>
  16665.  
  16666.  main()
  16667.  {
  16668.      spawnl(P_WAIT, "C:\\OS2\\CMD.EXE", "C:\\OS2\\CMD.EXE",
  16669.             "/c dir", NULL);
  16670.  }
  16671.  
  16672.  Module Definition File
  16673.  ----------------------
  16674.  
  16675.   NAME           os2stub   WINDOWAPI
  16676.  
  16677.  PROTMODE
  16678.  
  16679.  Response:
  16680.  
  16681.  This is expected behavior. When you use the WINDOWAPI setting, you are
  16682.  telling the linker that this is a Presentation Manager (PM)
  16683.  application. However, your application is not a PM application if it
  16684.  has no application window, no message queue, etc. When your
  16685.  application is run, the system switches to the PM display to start the
  16686.  program (this is where all PM applications are run from). Because
  16687.  there is no code for your application that is relevant to PM, the
  16688.  application returns.
  16689.  
  16690.  You should use the "WINDOWCOMPAT" option in your module definition
  16691.  file.
  16692.  
  16693.  
  16694.  526. Address Space of Physical Video Buffer Using VioGetPhysBuf()
  16695.  
  16696.  Question:
  16697.  
  16698.  I am using VioGetPhysBuf() to perform physical video I/O in an OS/2
  16699.  VIO application. The VIOPHYSBUF structure that this API uses has the
  16700.  following field in it:
  16701.  
  16702.      SEL asel[1];
  16703.  
  16704.  This field is an array of selectors to point to the PVB (physical
  16705.  video buffer). This array is only defined to be 1. I need to use two
  16706.  selectors, thus getting up to 128K of PVB access space. How can I use
  16707.  the VIOPHYSBUF structure definition to accomplish this?
  16708.  
  16709.  Response:
  16710.  
  16711.  The "Microsoft Operating System/2 Programmer's Toolkit Programmer's
  16712.  Reference" for Version 1.00 documentation for the "VIOPHYSBUF.asel"
  16713.  field states the following on Page 338:
  16714.  
  16715.     Specifies an array that receives the selectors used to address the
  16716.     physical video buffer. If more than one selector is received, the
  16717.     first selector addresses the first 64K bytes of the physical video
  16718.     buffer, the second selector addresses the next 64K bytes, and so
  16719.     on. The number of selectors depends on the actual size of the
  16720.     physical buffer as specified by the cb field. The last selector may
  16721.     address less than 64K bytes of buffer.
  16722.  
  16723.  The "Comments" section for this data structure states the following:
  16724.  
  16725.     The actual size of the asel[1] field depends on the size of
  16726.     physical memory. The program must ensure that there is adequate
  16727.     space to receive all selectors.
  16728.  
  16729.  Because of current architecture limitations, the PVB is located in the
  16730.  region from A000H to C000H in the system memory map, which limits to
  16731.  two the maximum number of selectors that this API can use. Generally,
  16732.  the first selector points to the 64K region starting at A000H, and the
  16733.  second selector points to the 64K region starting at B000H. To address
  16734.  a video adapter that supports an address space larger than 128K, you
  16735.  must page banks of up to 128K memory, one bank of memory at a time
  16736.  (e.g. one bitplane at a time).
  16737.  
  16738.  The problem is how to use two selectors instead of only one. The
  16739.  VIOPHYSBUF structure is defined in the include file BSESUB.H, which is
  16740.  included with the Microsoft OS/2 Software Development Kit (SDK) and
  16741.  the OS/2 Programmer's Toolkit (PTK). The definition for this structure
  16742.  is as follows:
  16743.  
  16744.      typedef struct _VIOPHYSBUF {    /* viopb */
  16745.          PBYTE    pBuf;
  16746.          ULONG    cb;
  16747.          SEL      asel[1];
  16748.      } VIOPHYSBUF;
  16749.      typedef VIOPHYSBUF far *PVIOPHYSBUF;
  16750.  
  16751.  The "VIOPHYSBUF.asel" field is typical of how a C structure is mapped
  16752.  onto a data structure that has a variable-length array at the end.
  16753.  This is about the closest that C can come to handling this kind of
  16754.  situation, and does not imply that the dimension of the array is "1".
  16755.  
  16756.  In addition to the VIOPHYSBUF structure, another example of this kind
  16757.  of data structure in the OS/2 PTK include files is the TRACKFORMAT
  16758.  structure. The definition of this structure is as follows:
  16759.  
  16760.      typedef struct _TRACKFORMAT {    /* trckfmt */
  16761.          /* ... some fields omitted here ... */
  16762.          struct {
  16763.              BYTE bCylinder;
  16764.              BYTE bHead;
  16765.              BYTE idSector;
  16766.              BYTE bBytesSector;
  16767.          } FormatTable[1];
  16768.      } TRACKFORMAT;
  16769.  
  16770.  For example, to allocate TWO selectors using the existing definition
  16771.  of the VIOPHYSBUF structure, allocate a buffer area big enough to
  16772.  handle the largest dimension that you want to use. Then, cast a
  16773.  pointer to this area to be a pointer of this type and use however many
  16774.  elements of the array that were there. For example, the allocation
  16775.  could be as follows:
  16776.  
  16777.    PVIOPHYSBUF pviopb;
  16778.    USHORT cElements = 2;
  16779.  
  16780.    pviopb = (PVIOPHYSBUF)malloc(sizeof(VIOPHYSBUF) + ((cElements - 1)
  16781.              * sizeof(SEL)));
  16782.  
  16783.  In the above calculation, the subtraction of 1 from cElements is used
  16784.  because one array element is included in the sizeof(VIOPHYSBUF) value,
  16785.  which is the SEL asel[1] field.
  16786.  
  16787.  Alternately, you could have two VIOPHYSBUF structures allocated in
  16788.  your program, and each one could only have a single selector to a
  16789.  portion of the PVB. Then, your application could call VioGetPhysBuf()
  16790.  multiple times to obtain these selectors.
  16791.  
  16792.  For more information on video hardware programming, refer to the
  16793.  hardware technical reference document(s) for your video adapter. In
  16794.  addition to the vendor-supplied hardware technical reference
  16795.  document(s) on the video adapter, many books are available that
  16796.  discuss register-level programming for popular video adapters such as
  16797.  the EGA and VGA. The MANDEL example, included with some versions of
  16798.  the OS/2 SDK and OS/2 PTK, demonstrates how to write a base VIO
  16799.  application that performs register-level programming of the EGA
  16800.  adapter.
  16801.  
  16802.  
  16803.  527. OS/2 SDK: Older Definition of VIOMODEINFO Structure Invalid
  16804.  
  16805.  The proper definition for the VIOMODEINFO structure, as defined in
  16806.  BSESUB.H, is as follows:
  16807.  
  16808.      typedef struct _VIOMODEINFO {   /* viomi */
  16809.          USHORT cb;
  16810.          UCHAR  fbType;
  16811.          UCHAR  color;
  16812.          USHORT col;
  16813.          USHORT row;
  16814.          USHORT hres;
  16815.          USHORT vres;
  16816.      } VIOMODEINFO;
  16817.      typedef VIOMODEINFO FAR *PVIOMODEINFO;
  16818.  
  16819.  The "VIOMODEINFO.cb" field is defined as the sizeof(VIOMODEINFO),
  16820.  which is 12 bytes, not 14. The "Microsoft Operating System/2
  16821.  Programmer's Reference Volume 3" for Version 1.10 describes this field
  16822.  on Page 370, with the following information:
  16823.  
  16824.     Specifies the length of the [VIOMODEINFO] data structure (in
  16825.     bytes). This field must be set to 12.
  16826.  
  16827.  Older versions of BSESUB.H (for example, the version included with the
  16828.  Microsoft C Compiler Version 5.10) incorrectly show the "fmt_ID" and
  16829.  "attrib" fields at the end of this structure. These two fields should
  16830.  not be there. The include files from a recent Microsoft OS/2 Software
  16831.  Development Kit (SDK) or OS/2 Programmer's Toolkit (PTK) should be
  16832.  used instead; they are more up-to-date than the Microsoft C Compiler's
  16833.  OS/2-specific include files or very old OS/2 SDK include files.
  16834.  
  16835.  In summary, do not use the "fmt_ID" and "attrib" fields. Also, the
  16836.  "cb" field should be set to the proper sizeof(VIOMODEINFO), which is
  16837.  12 bytes.
  16838.  
  16839.  
  16840.  528. OS/2 SDK: CBIOS and ABIOS Information and References
  16841.  
  16842.  This article summarizes the terms CBIOS and ABIOS, and provides ABIOS
  16843.  reference information for writers of OS/2 device drivers.
  16844.  
  16845.  In this context, the term BIOS stands for "Basic Input/Output System".
  16846.  It is the ROM code in the IBM Personal Computer (and OEM-compatible)
  16847.  systems. This is also commonly referred to as the "PC ROM BIOS". The
  16848.  BIOS provides a set of low-level services, which manipulate the
  16849.  system's hardware. On PC-compatible versions of MS-DOS, the MS-DOS
  16850.  kernel issues calls to the ROM BIOS in order to complete I/O requests.
  16851.  
  16852.  The BIOS can only be used in real mode of an Intel 80286 or 80386 CPU
  16853.  (the Intel 8086 only operates in real mode.) In general, these
  16854.  real-mode system services are not reentrant, and they are limited to
  16855.  using memory under the 1 MB address space (not being able to use
  16856.  extended memory). When the PS/2 family of computers was released, a
  16857.  new term called "Compatibility BIOS" or "CBIOS" was given to the BIOS.
  16858.  The term ABIOS stands for "Advanced Basic Input/Output System," or
  16859.  "Advanced BIOS," termed when IBM released their Personal System/2
  16860.  family of computers. This set of system services are bimodal; that is,
  16861.  they will operate in the real mode of the 80286 and 80386, as well as
  16862.  in protected mode. A PS/2 system has both a BIOS and an ABIOS.
  16863.  
  16864.  On PS/2 (and compatible) systems that have an ABIOS, Microsoft
  16865.  releases of OS/2 do NOT use the ABIOS system services. Instead, the
  16866.  OS/2 device drivers bypass the ABIOS abstraction layer and talk
  16867.  directly with the hardware, as with the PC/AT family of computers
  16868.  (which do not have ABIOS). On IBM PS/2 systems, IBM releases of OS/2
  16869.  may use the ABIOS system services. The ABIOS-specific DevHlps will
  16870.  fail if the OS/2 kernel does not use the ABIOS interface to the
  16871.  hardware. Thus, the ABIOS DevHlps are not available on non-ABIOS
  16872.  systems, such as PC/ATs.
  16873.  
  16874.  Implementations of OS/2 that use the ABIOS as an abstraction layer to
  16875.  communicate with the hardware will support four DevHlp device driver
  16876.  helper routines. These DevHlps are as follows:
  16877.  
  16878.     DevHlp Service    Code
  16879.  
  16880.     FreeLIDEntry      34H
  16881.     GetLIDEntry       35H
  16882.     ABIOSCall         36H
  16883.     ABIOSCommonEntry  37H
  16884.  
  16885.  As stated above, if the OS/2 kernel does not support ABIOS, these
  16886.  ABIOS-specific DevHlps will return failure. Information on these
  16887.  DevHlps is listed in the technical references provided by Microsoft,
  16888.  IBM, and OS/2 OEMs; some of these references are listed below.
  16889.  
  16890.  The following is a list of reference information available for CBIOS
  16891.  programmers:
  16892.  
  16893.     "IBM PS/2 and PC BIOS Interface Technical Reference"
  16894.     IBM Corporation
  16895.     Part number 68X2260
  16896.     1987
  16897.     [This document can be ordered from IBM by calling (800) IBM-PCTB.]
  16898.  
  16899.     "IBM PS/2 Seminar Proceedings"
  16900.     IBM Corporation
  16901.     May 1987
  16902.     Volume 5, Number 4
  16903.     Pages 16-23: Compatibility BIOS
  16904.  
  16905.     "Programmer's Quick Reference Series: IBM ROM BIOS"
  16906.     Ray Duncan
  16907.     Microsoft Press
  16908.     1988
  16909.     ISBN 1-55615-135-7
  16910.  
  16911.  Also refer to the hardware technical reference for your computer. Many
  16912.  of these references include the source code listing to the ROM BIOS.
  16913.  In addition to these references, there are many third-party books
  16914.  whose primary topic is MS-DOS programming. Many of these books discuss
  16915.  using CBIOS.
  16916.  
  16917.  The following is a list of general reference information available for
  16918.  ABIOS programmers:
  16919.  
  16920.     "Advanced BIOS Supplement"
  16921.     "IBM PS/2 and PC BIOS Interface Technical Reference"
  16922.     IBM Corporation
  16923.     Part number 68X2288
  16924.     1987
  16925.     [This document can be ordered from IBM by calling (800) IBM-PCTB.]
  16926.  
  16927.     "IBM PS/2 Seminar Proceedings"
  16928.     IBM Corporation
  16929.     May 1987
  16930.     Volume 5, Number 4
  16931.     Pages 41-71: Advanced BIOS
  16932.  
  16933.  Currently, probably the most definitive information on the ABIOS
  16934.  system services is the "IBM PS/2 and PC BIOS Interface Technical
  16935.  Reference: Advanced BIOS Supplement," available from IBM. If you have
  16936.  an OEM system that uses an ABIOS, refer to the OEM for technical
  16937.  documentation on their ABIOS implementation.
  16938.  
  16939.  The following is a list of general reference information available for
  16940.  ABIOS device driver writers:
  16941.  
  16942.     "IBM OS/2 Technical Reference Version 1.10"
  16943.     "I/O Subsystems and Device Drivers Volume 1"
  16944.     IBM Corporation
  16945.     1989
  16946.     Part number 00F8873
  16947.  
  16948.     "Microsoft OS/2 Device Drivers Reference Version 1.10"
  16949.     Microsoft Corporation
  16950.     1989
  16951.     Part number 07017
  16952.     (This reference is part of the Microsoft OS/2 Device Driver Kit.)
  16953.  
  16954.     "Advanced OS/2 Programming"
  16955.     Ray Duncan
  16956.     Microsoft Press
  16957.     1989
  16958.     ISBN 1-55615-045-8
  16959.  
  16960.  Currently, probably the most definitive information on using the ABIOS
  16961.  system services in an OS/2 device driver is the "IBM OS/2 Technical
  16962.  Reference Version 1.10: I/O Subsystems and Device Drivers Volume 1,"
  16963.  available from IBM. The Microsoft OS/2 Version 1.00 Device Driver
  16964.  documentation, included with the Microsoft OS/2 Version 1.00 Device
  16965.  Driver Kit (DDK), did not contain information on the OS/2 ABIOS
  16966.  DevHlps. This information has been added to the Version 1.10 Device
  16967.  Driver documentation listed above.
  16968.  
  16969.  
  16970.  529. Using Keyboard Monitor to Disable the F10 Key in OS/2 1.00
  16971.  
  16972.  Question:
  16973.  
  16974.  Can I disable the F10 key to switch to the Update Menu in the OS/2
  16975.  Version 1.00 (1.00, 1.01, 1.02) Program Selector?
  16976.  
  16977.  Response:
  16978.  
  16979.  Yes; to do this, use a keyboard monitor that monitors screen group 1
  16980.  and looks for the F10 key. The sample monitor code in the file
  16981.  MONITORS.C, included with the Version 1.02 OS/2 SDK (Software
  16982.  Development Kit) and the Version 1.00 Programmer's Toolkit, can be
  16983.  modified to do this.
  16984.  
  16985.  When the F10 key is found, the program should just return. Pass
  16986.  everything else to the next process in the chain via the DosMonWrite()
  16987.  call.
  16988.  
  16989.  
  16990.  530. OS/2 ABIOS DevHlps Availability
  16991.  
  16992.  Question:
  16993.  
  16994.  Does the Microsoft version of OS/2 (in contrast to the IBM version of
  16995.  OS/2) use ABIOS to communicate with the hardware on systems that have
  16996.  ABIOS? I would like to use the ABIOS DevHlps in my device driver, but
  16997.  I cannot use them on some implementations of OS/2.
  16998.  
  16999.  Response:
  17000.  
  17001.  Microsoft releases of OS/2 do NOT use the ABIOS system services.
  17002.  Instead, the OS/2 device drivers bypass the ABIOS abstraction layer
  17003.  and talk directly with the hardware, as with the PC/AT family of
  17004.  computers. IBM releases of OS/2 may use the ABIOS system services. The
  17005.  DevHlps specific to ABIOS kernel implementations (FreeLIDEntry,
  17006.  GetLIDEntry, ABIOSCall, and ABIOSCommonEntry) fail if the OS/2 kernel
  17007.  does not use the ABIOS interface to the hardware. Thus, a device
  17008.  driver can tell if the OS/2 kernel it is running on supports these
  17009.  ABIOS DevHlps by trying to use them. If the OS/2 kernel does not
  17010.  support ABIOS, these ABIOS-specific DevHlps return failure.
  17011.  Information on these DevHlps are listed in the technical references
  17012.  provided by Microsoft, IBM, and OS/2 OEMs.
  17013.  
  17014.  
  17015.  531. OS/2 SDK: Tutorial on Writing a Multithreaded Program
  17016.  
  17017.  The sample program listed below demonstrates the basics of starting a
  17018.  thread in a multithreaded program. It is a trivial example, and
  17019.  obviously performs no real function.
  17020.  
  17021.  In the sample program, there is minimum coordinating control to keep
  17022.  the threads synchronized. There is no use of semaphores that would be
  17023.  needed in anything but such a trivial example. A flag is used to HOLD
  17024.  the main program until the threads are completed. DosSleep() is used
  17025.  to pause the second thread.
  17026.  
  17027.  Please refer to Section 2 of MTDYNA.DOC for more information on the
  17028.  use of multithreaded programs.
  17029.  
  17030.  The sample program is as follows:
  17031.  
  17032.  /* Use the following commands to compile and link the sample
  17033.     program listed below.
  17034.  
  17035.  cl -Alfw -Zl -Gs mt.c /link llibcmt doscalls
  17036.  
  17037.  The options used in the "cl" line listed above are described below:
  17038.  
  17039.    -A (l)pointer size large  (f)pointer size far  (w) ss!=ds; ds fixed
  17040.    -Zl no default lib search (use only llibcmt.lib)
  17041.    -Gs no stack check
  17042.  
  17043.     llibcmt(.lib) is the large model library that supports
  17044.     multithreaded programs.
  17045.  
  17046.  del mt.obj
  17047.  */
  17048.  
  17049.  #define INCL_BASE      // this defines/includes all
  17050.  #include<mt\os2.h>     // multithreaded include file
  17051.  #define STACKSIZE 4096 // used to create a stack for the thread to use
  17052.  void far thread1();    // prototype
  17053.  void far thread2();
  17054.  int hold;              // flag to hold main until threads complete
  17055.  main()
  17056.  {
  17057.      SEL stacksel;  // used to return stack selector (unsigned short)
  17058.      TID tid1,tid2; // thread ids (USHORT  - unsigned int)
  17059.      PCH pStack1,pStack2; // stack pointers (far char *)
  17060.  //
  17061.      hold=0;
  17062.  /*
  17063.      This program was originally written with Doscreatethread().
  17064.      It is recommended that you use _beginthread instead, as the
  17065.      DosCreateThread() call can give unpredictable results.
  17066.  
  17067.      pStack1 = MAKEP(stacksel,0);
  17068.      tid1 = _beginthread(thread1,pStack1,STACKSIZE,"");
  17069.  
  17070.      When using _beginthread, you must use 0 (zero) instead of
  17071.      STACKSIZE in the call to MAKEP. If you use 0, a pointer is
  17072.      returned to the bottom of the stack instead of the top. You then
  17073.      send the STACKSIZE value as a parameter in the _beginthread call.
  17074.      The null parameter at the end of the _beginthread call is the
  17075.      parameter list that can be sent with this call.
  17076.  
  17077.      */
  17078.  
  17079.      DosAllocSeg(STACKSIZE,&stacksel,0);  // return stacksel, use below
  17080.      pStack1=MAKEP(stacksel,STACKSIZE);   // return pStack1, use below
  17081.      DosCreateThread(thread1,&tid1,pStack1); // return tid1
  17082.      hold++;
  17083.  
  17084.      DosAllocSeg(STACKSIZE,&stacksel,0);
  17085.      pStack2=MAKEP(stacksel,STACKSIZE);
  17086.      DosCreateThread(thread2,&tid2,pStack2);
  17087.      hold++;
  17088.  
  17089.  while (hold);
  17090.  
  17091.      /*
  17092.      Hold was set to zero, then incremented for each thread started.
  17093.      When the threads complete they will each decrement the hold
  17094.      count and the main program will end when all threads have
  17095.      completed.
  17096.      */
  17097.  }
  17098.  
  17099.  void far thread1()
  17100.  {
  17101.      DosBeep(1000,100);
  17102.      VioWrtTTy("hello from thread 1\r\n",21,0);
  17103.      hold--;
  17104.  }
  17105.  
  17106.  void far thread2()
  17107.  {
  17108.      DosSleep(1000L); // pause the thread
  17109.      DosBeep(3000,100);
  17110.      VioWrtTTy("hello from thread 2\r\n",21,0);
  17111.      hold--;
  17112.  }
  17113.  
  17114.  
  17115.  532. Turning Standard Device Driver into Base Device Driver
  17116.  
  17117.  Question:
  17118.  
  17119.  I have written a standard device driver and must make it a base device
  17120.  driver. What changes are required to do this?
  17121.  
  17122.  Response:
  17123.  
  17124.  The most reliable thing to do is to leave your device driver as an
  17125.  installable driver.
  17126.  
  17127.  The only way to make an installable device driver a base device
  17128.  driver is to modify a list of base device drivers kept inside the
  17129.  OS/2 kernel. The Version 1.10 OS/2 BAK (Binary Adaptation Kit) allows
  17130.  OEMs to modify this list if they wish, as part of their adaptation
  17131.  process. OEMs are also allowed to modify or enhance other
  17132.  hardware-dependent portions of the OS/2 kernel. As a result, each
  17133.  OEM's version of OS/2 is customized for their hardware and therefore
  17134.  is different from all other OEM versions of OS/2. There is no way you
  17135.  can modify the base device driver list without deleting all the
  17136.  other changes or enhancements a given OEM may have made.
  17137.  
  17138.  The best you might be able to do is to rewrite DISK01.SYS (which is a
  17139.  base driver) to include your features. However, this has potential
  17140.  problems; when your DISK01.SYS driver replaces the OEM's DISK01.SYS
  17141.  driver, all the changes the OEM may have made to their DISK01.SYS
  17142.  driver will be lost, possibly breaking the system.
  17143.  
  17144.  
  17145.  533. OS/2 SDK: GINFOSEG cusecTimerInterval Documented Incorrectly
  17146.  
  17147.  Microsoft has confirmed that the cusecTimerInterval parameter of the
  17148.  GINFOSEG structure is not documented correctly in the versions of
  17149.  QuickHelp included with the Version 1.06 and Version 1.10 OS/2 SDKs
  17150.  (Software Development Kits), and on Page 343 of the "Microsoft
  17151.  Operating System/2 Programmer's Reference Volume 3 for Version 1.1"
  17152.  manual. The correct documentation should state the following:
  17153.  
  17154.     cusecTimerInterval    Specifies the timer interval (in tenths of
  17155.                           milliseconds, units = 0.0001 seconds)
  17156.  
  17157.  We will post new information when this error has been corrected in
  17158.  the documentation.
  17159.  
  17160.  
  17161.  534. OS/2 SDK: Example of Using a Single-Threaded DLL
  17162.  
  17163.  The following four files are required when writing a single-threaded
  17164.  DLL (dynamic linked library):
  17165.  
  17166.  1. Main program file
  17167.  
  17168.  2. Main definition file
  17169.  
  17170.  3. DLL code file
  17171.  
  17172.  4. DLL definition file
  17173.  
  17174.  In the example below, we will use the following names for these four
  17175.  files: STMAIN.C, STMAIN.DEF, STDLL.C, and STDLL.DEF, respectively.
  17176.  Another file, ST.CMD, is used to run the compile and link steps. This
  17177.  method is used instead of using a make file. Included below are the
  17178.  files used to create a simple example of how to use a single-threaded
  17179.  DLL.
  17180.  
  17181.  The STMAIN.DEF file declares the name of the program and the name of
  17182.  the DLL that contains the function "dlltest" (STDLL2). The STDLL.DEF
  17183.  file contains information on the name of the DLL and the functions it
  17184.  contains. For more information on .DEF files, refer to Section 2.6,
  17185.  "Using Module-Definition Files," in the "Microsoft Operating System/2
  17186.  Presentation Manager Softset" manual.
  17187.  
  17188.  STMAIN.C
  17189.  --------
  17190.  /*
  17191.  COMPILE and LINK commands:
  17192.  cl -AC -G2 -c stmain.c
  17193.  link stmain.obj/NOI,,,clibce.lib doscalls.lib/NOD,stmain.def;
  17194.  */
  17195.  #define INCL_BASE
  17196.  #include<os2.h>
  17197.  extern void far dlltest(void);  // prototype declaration of function
  17198.                                  // in DLL
  17199.  main()
  17200.  {
  17201.  printf("single thread main\n"); // verifies we are in main program
  17202.  dlltest();                      // function call that is in the DLL
  17203.  printf("single thread main\n"); // verifies we are back in main
  17204.  }
  17205.  
  17206.  STMAIN.DEF
  17207.  ----------
  17208.  
  17209.  NAME STMAIN
  17210.  IMPORTS STDLL2._dlltest
  17211.  
  17212.  STDLL.C
  17213.  -------
  17214.  
  17215.  /*
  17216.  COMPILE and LINK commands:
  17217.  cl -Alfw -G2 -Gs -c stdll.c
  17218.  link stdll.obj,stdll2.dll/NOI,,llibcdll.lib doscalls.lib/NOD,
  17219.       stdll.def;
  17220.  copy stdll.dll2 c:\dll
  17221.  rem    this places the DLL in LIBPATH
  17222.  */
  17223.  #include <stdio.h>
  17224.  void far _loadds dlltest(void);  // function declaration
  17225.  void far _loadds dlltest(void)   // body of function
  17226.  {
  17227.     fprintf(stdout,"this is from dlltest\n");
  17228.  }
  17229.  
  17230.  STDLL.DEF
  17231.  ---------
  17232.  
  17233.  LIBRARY STDLL2 INITINSTANCE
  17234.  rem You must use INITINSTANCE in the LIBRARY line if you are using
  17235.  rem the C Runtime. If you don't use INITINSTANCE, other instances
  17236.  rem of the application that refer to this DLL will not initialize
  17237.  rem their data segments.
  17238.  DESCRIPTION 'SAMPLE DLL'
  17239.  PROTMODE
  17240.  EXPORTS _dlltest
  17241.  DATA MULTIPLE
  17242.  
  17243.  ST.CMD
  17244.  ------
  17245.  
  17246.  cl -AC -G2 -c stmain.c
  17247.  link stmain.obj/NOI,,,clibce.lib doscalls.lib/NOD,stmain.def;
  17248.  cl -Alfw -G2 -Gs -c stdll.c
  17249.  link stdll.obj,stdll2.dll/NOI,,llibcdll.lib doscalls.lib/NOD,
  17250.       stdll.def;
  17251.  copy stdll2.dll c:\dll
  17252.  rem copy stdll.dll2 c:\dll ** this puts the DLL on LIBPATH**
  17253.  
  17254.  
  17255.  535. OS/2 SDK: Reasons Why LIBPATH Isn't a Dynamic Value
  17256.  
  17257.  Question:
  17258.  
  17259.  It is very inconvenient to have to set the LIBPATH value at boot time.
  17260.  Why can't LIBPATH be a dynamic value, like an environment variable?
  17261.  
  17262.  Response:
  17263.  
  17264.  One reason the LIBPATH variable is not dynamic is because OS/2 must
  17265.  have a stable method of locating its DLLs (dynamic linked libraries).
  17266.  All the kernel APIs [i.e., DosFindFirst(), DosDelete(), etc.] and some
  17267.  other kernel functions, such as the subsystems BVSCALLS (video
  17268.  subsystem) and BKSCALLS (keyboard subsystem), are all implemented as
  17269.  ring 3 DLLs. If you allow the user to freely change the LIBPATH
  17270.  variable, the system could very easily lose track of the files it
  17271.  needs to perform basic kernel functions, or perhaps even load the
  17272.  wrong or outdated versions of a file with the same name.
  17273.  
  17274.  Another reason LIBPATH is not dynamic is because of speed
  17275.  considerations. Once the DLL path is known, it is static. OS/2 can use
  17276.  a different method of searching, rather than checking an environment
  17277.  variable and searching different directories each time a DLL is
  17278.  needed.
  17279.  
  17280.  One trick that you might be unaware of is to put a period (.) as the
  17281.  first directory in your LIBPATH variable. For example:
  17282.  
  17283.     LIBPATH=.;c:\;c:\os2\dll...)
  17284.  
  17285.  This will give LIBPATH the appearance of being dynamic in many
  17286.  situations. It will definitely help when you are trying to develop
  17287.  DLLs because you can avoid copying your newly built DLL to some
  17288.  directory in your LIBPATH. Instead, you can just run it from the
  17289.  current directory.
  17290.  
  17291.  However, there will be a performance penalty because OS/2 will have to
  17292.  continually update the pointer to the first search directory, based on
  17293.  the directory you are in at the time. Still, it is a very convenient
  17294.  method.
  17295.  
  17296.  
  17297.  536. OS/2 SDK: Intermittent KBD01.SYS CTRL Key Timing Problem
  17298.  
  17299.  Microsoft has confirmed that there is a problem with the KBD01.SYS
  17300.  file included with the Version 1.10 OS/2 SDK (Software Development
  17301.  Kit). There is a rare, intermittent timing problem with KBD01.SYS
  17302.  losing the toggle status of the CTRL key. The symptom occurs when you
  17303.  press the CTRL key simultaneously with another key. When this problem
  17304.  occurs, KBD01.SYS assumes that the CTRL key is being pressed, even
  17305.  though it isn't being pressed. Thus, a  CTRL character is added before
  17306.  any key you press. For example, if you press "A", "^A" is displayed
  17307.  on the screen. If you press and release only the CTRL key, the problem
  17308.  goes away.
  17309.  
  17310.  We are researching this problem and will post new information as it
  17311.  becomes available.
  17312.  
  17313.  
  17314.  537. OS/2 SDK: Initializing Another Programmer's Multithreaded DLL
  17315.  
  17316.  Question:
  17317.  
  17318.  A developer has written a multithreaded DLL (dynamic linked library)
  17319.  that requires its own initialization. The developer seems to have the
  17320.  following two choices:
  17321.  
  17322.  1. Let the Microsoft C Compiler do its initialization and his DLL code
  17323.     specific initialization not take place
  17324.  
  17325.  2. Let his DLL do its own initialization and therefore none of the
  17326.     Microsoft C Compiler initialization takes place
  17327.  
  17328.  Is there any way that the developer can do both of the
  17329.  initializations?
  17330.  
  17331.  Response:
  17332.  
  17333.  If the developer's DLL is a C run-time DLL, the developer has no
  17334.  choice but to choose the first option, and then use a workaround to
  17335.  get the code to run at initialization time. However, if the developer
  17336.  is not using any run-time calls, he or she can write his or her own
  17337.  startup code for the DLL in assembly language and get his or her code
  17338.  started.
  17339.  
  17340.  A workaround for the first option is to set a flag when the
  17341.  developer's initialization code has been run, and then have every
  17342.  function in the developer's DLL check this flag to determine if the
  17343.  initialization code has been run. If the function checked the flag
  17344.  and it hadn't been set, then the initialization routine would need to
  17345.  be executed. Another workaround is to have all applications using the
  17346.  developer's DLL call the initialization function first, before using
  17347.  any of the other code in the DLL.
  17348.  
  17349.  
  17350.  538. PM Printer Output Flow Explanation
  17351.  
  17352.  Question:
  17353.  
  17354.  How is control of the printer hardware done when Presentation Manager
  17355.  (PM) printing is used? If I issue a "PRINT CONFIG.SYS" command from
  17356.  the command prompt, I appear to go through the PRINT01.SYS driver. If
  17357.  I print using GPI calls in a PM program, I do not go through the
  17358.  PRINT01.SYS driver. I assume that the IBM4201.DRV file controls the
  17359.  printer hardware.
  17360.  
  17361.  Response:
  17362.  
  17363.  The output from using the PM spooler will end up going through the
  17364.  base device driver (LPT1:, LPT2:, COM1:, etc.).
  17365.  
  17366.  The process of how output goes through the PM spooler is described
  17367.  below. The PM spooler is a PM application with associated DLLs
  17368.  (dynamic linked libraries) that control the Spl* APIs that PM
  17369.  applications can call. The PM spooler also includes a spool queue
  17370.  manager, which queues up output for a device (by writing it to a
  17371.  temporary file until it is done) and then sends the completed output
  17372.  on to be printed. At this point, after the output exits the spool
  17373.  queue, the output enters the PM device driver (*.DRV). This .DRV file
  17374.  opens the base device driver and performs output to that device.
  17375.  
  17376.  The following steps summarize the above information (where PSCRIPT.DRV
  17377.  is the PM driver, and COM1: is the output device):
  17378.  
  17379.  1. A PM application does a GPI call that is sent to the PM spooler.
  17380.  
  17381.  2. The PM spooler queues up the output.
  17382.  
  17383.  3. The PM spooler sends the output to the PSCRIPT.DRV file.
  17384.  
  17385.  4. The .DRV file translates the output and sends the output to COM1:.
  17386.  
  17387.  A base application, which doesn't use the PM spooler or the PM .DRV
  17388.  files, talks directly with the base device driver (e.g. LPT1:).
  17389.  However, this could cause problems for the spooler. Therefore, the
  17390.  spooler uses a device monitor [DosMon*()] to monitor the OS/2 base
  17391.  device drivers that the device monitor is spooling to, and looks for
  17392.  output that is NOT coming from the spooler itself. In other words, the
  17393.  spooler looks for output sent to this device that is not coming from
  17394.  the PM .DRV file, as this .DRV file is what talks to this device, not
  17395.  the spooler.
  17396.  
  17397.  When the spooler monitors activity to the base device that is not
  17398.  coming from the .DRV file, the spooler takes the output and puts it
  17399.  inside the PM queue, forcing it to act like another print job.
  17400.  
  17401.  However, as mentioned above, the spooler always takes a completed
  17402.  queue job and passes it on to the .DRV file to be sent to the printer.
  17403.  In this case, the output originally came from a base application, not
  17404.  a PM application. This can cause problems because base applications
  17405.  generally do not write out printer escape codes, and this is what
  17406.  would be expected by the .DRV file. Therefore, the IBMNULL.DRV driver
  17407.  is used to pass exact output on to the printer, unmodified. This
  17408.  allows base applications to use a command of "PRINT CONFIG.SYS", and
  17409.  have the CONFIG.SYS file not be interpreted as printer escape codes.
  17410.  
  17411.  Thus, the printer output from the PM .DRV printer driver comes to the
  17412.  base .SYS printer device driver, and does not go directly to the
  17413.  hardware. However, there is an interface between the base printer
  17414.  device driver and the spooler that allows the spooler to send output
  17415.  to the printer driver and not have its (the spooler's) own printer
  17416.  device monitor return this output back to the spooler, looping
  17417.  forever. That is, output from PM applications that funnel out of the
  17418.  .DRV printer driver come to the base .SYS printer driver, but they
  17419.  come via a different interface.
  17420.  
  17421.  
  17422.  539. OS/2 SDK: Example of Using a Multithreaded DLL
  17423.  
  17424.  The following four files are required when writing a multithreaded DLL
  17425.  (dynamic linked library):
  17426.  
  17427.  1. Main program file
  17428.  
  17429.  2. Main definition file
  17430.  
  17431.  3. DLL code file
  17432.  
  17433.  4. DLL definition file
  17434.  
  17435.  In the example described below, the following names are used for the
  17436.  four files listed above: MT.C, MT.DEF, MTDLL.C, and MTDLL.DEF,
  17437.  respectively. Included below are the files used to create a simple
  17438.  example of how to use a multithreaded DLL.
  17439.  
  17440.  The MT.DEF file declares the name of the program and the name of the
  17441.  DLL that contains the function "dlltest" (MTDLL2). The MTDLL.DEF file
  17442.  contains information on the name of the DLL and what functions it
  17443.  contains. For more information on .DEF files, see Section 2.6, "Using
  17444.  Module-Definition Files," in the "Microsoft Operating System/2
  17445.  Presentation Manager Softset" manual.
  17446.  
  17447.  MT.C
  17448.  ----
  17449.  
  17450.  /* Compile and link the program in the following manner:
  17451.  cl -I%INCLUDE%\MT -Alfw -Zl -Gs -c mt.c -DDLL
  17452.  link mt.obj crtexe.obj /NOI,,nul,crtlib.lib doscalls.lib /NOD,mt.def
  17453.  del mt.obj
  17454.  */
  17455.  
  17456.  #define INCL_BASE
  17457.  #include<os2.h>
  17458.  #define STACKSIZE 4096
  17459.  extern void far dlltest(void);
  17460.  void far thread1();
  17461.  void far thread2();
  17462.  int hold;
  17463.  main()
  17464.  {
  17465.          SEL stacksel;
  17466.          TID tid1,tid2;
  17467.          PCH pStack1,pStack2;
  17468.  
  17469.          hold=0;
  17470.  
  17471.          DosAllocSeg(STACKSIZE,&stacksel,0);
  17472.       //0 alloc flag - non(share,discard)able
  17473.          pStack1=MAKEP(stacksel,0);
  17474.          tid1=_beginthread(thread1,pStack1,STACKSIZE,"");
  17475.          hold++;
  17476.  
  17477.          DosAllocSeg(STACKSIZE,&stacksel,0);
  17478.          pStack2=MAKEP(stacksel,0);
  17479.          tid2=_beginthread(thread2,pStack2,STACKSIZE,"");
  17480.          hold++;
  17481.  
  17482.  while (hold);
  17483.  }
  17484.  
  17485.  void far thread1()
  17486.  {
  17487.  extern void far dlltest(void); // not needed, this is declared
  17488.                                 // above main
  17489.      DosBeep(1000,100);
  17490.      VioWrtTTy("hello from thread 1\r\n",21,0);
  17491.      dlltest();
  17492.      printf("thread1\n");
  17493.      hold--;
  17494.  /*
  17495.  This shows a few simple calls. The calls are in different order
  17496.  in the two threads to show that threads run as they are scheduled.
  17497.  */
  17498.  }
  17499.  
  17500.  void far thread2()
  17501.  {
  17502.      printf("thread2\n");
  17503.      DosBeep(3000,100);
  17504.      VioWrtTTy("hello from thread 2\r\n",21,0);
  17505.      dlltest();
  17506.      hold--;
  17507.  }
  17508.  
  17509.  MT.DEF
  17510.  ------
  17511.  
  17512.  NAME MT
  17513.  IMPORTS MTDLL2._dlltest
  17514.  
  17515.  MTDLL.C
  17516.  -------
  17517.  /* Compile and link the program in the following manner:
  17518.  cl -I%INCLUDE%\MT -Alfw -DDLL -cMTDLL.C
  17519.  link mtdll.obj crtdll.obj,mtdll.dll/NOI,nul,crtlib.lib
  17520.       doscalls.lib/NOD,mtdll.def
  17521.  del mtdll.obj
  17522.  copy mtdll.dll c:\dll
  17523.  rem the copy statement above is needed to place the DLL in the
  17524.  rem LIBPATH variable
  17525.  */
  17526.  
  17527.  #include <stdio.h>
  17528.  void far _loadds dlltest(void);
  17529.  void far _loadds dlltest(void);
  17530.  {
  17531.     fprintf(stdout,"this is from dlltest\n");
  17532.  
  17533.  }
  17534.  
  17535.  MTDLL.DEF
  17536.  ---------
  17537.  
  17538.  LIBRARY MTDLL2
  17539.  DESCRIPTION 'SAMPLE DLL'
  17540.  PROTMODE
  17541.  EXPORTS _dlltest
  17542.  DATA MULTIPLE
  17543.  
  17544.  
  17545.  540. OS/2 SDK: DosStartSession() Fails from Detached Process
  17546.  
  17547.  Question:
  17548.  
  17549.  When calling DosStartSession() from a detached process, the call fails
  17550.  with a 418 error code (SMG_INVALID_CALL). Why is this happening?
  17551.  
  17552.  Response:
  17553.  
  17554.  The behavior described above is correct. The session manager must
  17555.  restrict the use of ALL session manager API calls from a detached
  17556.  process because the RUN statement in CONFIG.SYS will cause a detached
  17557.  process to be started before the session manager has been initialized.
  17558.  This restriction is not documented. It should be described in the
  17559.  documentation for the "RUN", "DETACH", and all of the session manager
  17560.  API calls. We will post new information when the documentation has
  17561.  been updated.
  17562.  
  17563.  
  17564.  541. OS/2 SDK: Using IMPLIB Command to Create Import Library
  17565.  
  17566.  This article demonstrates how to use the IMPLIB command to create an
  17567.  import library. It also demonstrates how to use an import library when
  17568.  linking, instead of using a .DEF file when creating a multithreaded
  17569.  DLL (dynamic linked library).
  17570.  
  17571.  To create an import library, issue the following command, where
  17572.  MTDLL.LIB is the name you want to give the import library and
  17573.  MTDLL.DEF is the name of the .DEF file used when creating the DLL.
  17574.  
  17575.     implib mtdll.lib mtdll.def
  17576.  
  17577.  The following is a sample .DEF file:
  17578.  
  17579.  MTDLL.DEF
  17580.  ---------
  17581.  
  17582.  LIBRARY MTDLL2
  17583.  DESCRIPTION 'SAMPLE DLL'
  17584.  PROTMODE
  17585.  EXPORTS _dlltest
  17586.  DATA MULTIPLE
  17587.  
  17588.  The following example demonstrates how to compile and link a DLL:
  17589.  
  17590.   cl -Id:\c\include\mt -Alfw -G2 -c -DDLL mtdll.c
  17591.   link mtdll.obj d:\c\lib\crtdll.obj,mtdll2.dll/NOI,,crtlib.lib
  17592.        doscalls.lib/NOD,mtdll.def;
  17593.                         ^^^^^^^^^
  17594.  Note the use of MTDLL.DEF.
  17595.  
  17596.  The following information describes how to use an import library.
  17597.  
  17598.  A program may normally be compiled and linked in the following manner:
  17599.  
  17600.    cl -Id:\c\include\mt -Alfw -Zl -Gs -c -DDLL mt.c
  17601.    link mt.obj d:\c\lib\crtexe.obj /NOI,,nul,crtlib.lib
  17602.         doscalls.lib /NOD,mt.def
  17603.                           ^^^^^^
  17604.  Note that MT.DEF is included as the last parameter in the LINK
  17605.  command.
  17606.  
  17607.  Instead of using the .DEF file when linking, you may instead use a
  17608.  import library created by the IMPLIB command. The following example
  17609.  demonstrates how to do this:
  17610.  
  17611.   cl -Id:\c\include\mt -Alfw -Zil -Od -Gs -c -DDLL mt.c
  17612.   link mt.obj d:\c\lib\crtexe.obj/NOI,,nul,mtdll.lib crtlib.lib
  17613.        doscalls.lib/NOD;                   ^^^^^^^^^
  17614.  
  17615.  Notice the extra library, MTDLL.LIB, which is the import library
  17616.  created with IMPLIB. Also, no .DEF file is used.
  17617.  
  17618.  
  17619.  542. Server Adaptation OS/2 Won't Install on PS/2 with Large ESDIs
  17620.  
  17621.  The following information applies to the OS/2 SDK Version 1.07 and to
  17622.  the SQL Server NDK (Network Development Kit) Version 1.00.
  17623.  
  17624.  The Server Adaptation OS/2 included with the Version 1.07 OS/2 SDK
  17625.  (Software Development Kit) may fail to install on IBM PS/2s with large
  17626.  ESDI hard drives. The problem has to do with the ROM chip ID on the
  17627.  hard disk drive controller.
  17628.  
  17629.  The only ESDI ROM ID Microsoft has verified as working is 15F6587.
  17630.  This has been verified as working in a Model 60, and it has also been
  17631.  reported to work in the Model 80-111.
  17632.  
  17633.  The following IDs are reported not to work:
  17634.  
  17635.     15F6807
  17636.     15F6865
  17637.     15F6866
  17638.  
  17639.  If you order updated ROMs, check the ID before you install them.
  17640.  There may have been a part numbering mix-up on these ROMs that may
  17641.  or may not have been cleared up by now, so check the ID printed on
  17642.  any ROMs that arrive. Do not rely on the ROM ID number given by the
  17643.  part number description.
  17644.  
  17645.  
  17646.  543. OS/2 SDK: Exit List Processing Information
  17647.  
  17648.  Question:
  17649.  
  17650.  We would like some more information on DosExitList() processing. The
  17651.  system we are developing has multithreaded and single-threaded non-PM
  17652.  applications, as well as PM applications calling a single-threaded
  17653.  large model DLL (dynamic linked library) (with GLOBAL INITIALIZATION),
  17654.  whose functions contain semaphore protection around C run-time calls
  17655.  and data accesses. The DLL contains a "LOGIN" function called by each
  17656.  application to register itself with the DLL, and a "LOGOUT" function
  17657.  to de-register the application with the DLL.
  17658.  
  17659.  After an application has successfully called the "LOGIN" function, it
  17660.  adds a local "CLEANUP" function to its DosExitList() processing. The
  17661.  "CLEANUP" function in turn calls the DLL's "LOGOUT" function on behalf
  17662.  of the application if it terminates unexpectedly. If the application
  17663.  is operating normally, it will call the "LOGOUT" function in the DLL
  17664.  itself, and then it will remove "CLEANUP" from its DosExitList()
  17665.  processing.
  17666.  
  17667.  The problem we have noticed is that when a multithreaded application
  17668.  terminates unexpectedly and the DosExitList() processing calls
  17669.  "CLEANUP," which in turn calls the "LOGOUT" function in the DLL, the
  17670.  DosSemRequest() of the serialization semaphore used to protect the C
  17671.  run-time calls in "LOGOUT" returns an error of (ERROR_SEM_OWNER_DIED),
  17672.  which prevents us from completing the "LOGOUT" function correctly.
  17673.  
  17674.  What effects do thread termination and DosExitList() processing have
  17675.  on access to system resources such as RAM and system semaphores,
  17676.  queues, pipes, etc., for a (fatally) terminating application? Is there
  17677.  a problem calling the following routines:
  17678.  
  17679.  1. A DLL-based "CLEANUP" routine for an application
  17680.  
  17681.  2. An application-based "CLEANUP" routine, which in turn calls another
  17682.     routine in a DLL
  17683.  
  17684.  Also, is there any problem accessing GLOBAL (not STACK-based)
  17685.  variables in these "CLEANUP" routines, and is there any difference in
  17686.  the way DosExitList() handles DLL and application-based DosExitList()
  17687.  "CLEANUP" functions?
  17688.  
  17689.  Response:
  17690.  
  17691.  You can make almost any kernel call in an exit list function. However,
  17692.  functions such as DosExecPgm(), DosCreateThread(), DosStartSession(),
  17693.  etc., are not allowed. Also, you cannot assume the order in which the
  17694.  DosExitList() routines will be run in OS/2 Version 1.00. However, in
  17695.  OS/2 Version 1.10, the high-order byte of the first parameter,
  17696.  fFnCode, defines the invocation order of the DosExitList() routines.
  17697.  For more information on this topic, query on G890310-13698 and
  17698.  fFnCode. You also cannot assume that queues are still around at the
  17699.  time the DosExitList() function is executed.
  17700.  
  17701.  Signals are held during the exit list, but all threads, except for
  17702.  thread 1 of your process, are killed. All file handles (not closed by
  17703.  other exit list functions) will be available.
  17704.  
  17705.  From the information listed above, you can assume that all system
  17706.  resources should be available for you to access, given that you have
  17707.  access rights to them in the main thread of execution.
  17708.  
  17709.  When the exit list routines gain control, all system semaphores owned
  17710.  by the process will have ownership transferred to thread 1 of the
  17711.  process. This will allow requests for serialization of these
  17712.  semaphores by thread 1 to not block in the event that the semaphore is
  17713.  created by another thread in the process that has been killed. The
  17714.  semaphores must have been created with nonexclusive ownership.
  17715.  
  17716.  All kernel calls are available, and many of the calls are located in
  17717.  DLLs. You should also be able to access global data.
  17718.  
  17719.  
  17720.  544. OS/2 SDK: Obtaining Current Screen Group in Keyboard Monitor
  17721.  
  17722.  Question:
  17723.  
  17724.  I want to load a device monitor in my CONFIG.OS2 file, but I can't get
  17725.  the monitor to find a meaningful current screen group. I have the
  17726.  following command in my CONFIG.OS2 file:
  17727.  
  17728.     RUN=MON.EXE
  17729.  
  17730.  The MON.EXE program does the following to get the current screen
  17731.  group:
  17732.  
  17733.       PGINFOSEG     GlobalInfo;
  17734.       SEL           GlobalInfoSel;
  17735.       SEL           LocalInfoSel;
  17736.       .
  17737.       .
  17738.       .
  17739.  
  17740.       DosGetInfoSeg (&GlobalInfoSel, &LocalInfoSel);
  17741.       GlobalInfo = MAKEPGINFOSEG(GlobalInfoSel);
  17742.       DosMonOpen ("KBD$", &KBD_Handle);
  17743.       DosMonReg (KBD_Handle, &KInBuffer, &KOutBuffer, FRONT,
  17744.                  GlobalInfo -> sgCurrent);
  17745.  
  17746.  When MON.EXE is run from CONFIG.OS2, the code listed above doesn't
  17747.  seem to monitor the keyboard correctly. Is there a way to both load
  17748.  MON.EXE in CONFIG.OS2 and monitor an actual session's keyboard?
  17749.  
  17750.  Response:
  17751.  
  17752.  This is intended behavior. If you check the return code for the
  17753.  DosMonReg() function call, it will be nonzero. The ID returned in the
  17754.  "sgCurrent" field will indicate that you are in the detached screen
  17755.  group, or that you are in the hard-error screen group, which is
  17756.  essentially the same thing. By definition, this group has no keyboard
  17757.  or screen I/O access other than that provided through the VioPopUp()
  17758.  mechanism.
  17759.  
  17760.  The problem is that at initialization time (when the RUN commands are
  17761.  issued) no regular screen groups are initialized except maybe the
  17762.  detached group, the hard-error group, and the compatibility box (if
  17763.  you have one). "Normal" operation does not really begin until the PM
  17764.  session manager is in place.
  17765.  
  17766.  Because the detached screen group does not really have a keyboard to
  17767.  monitor, you will never see any keystrokes.
  17768.  
  17769.  To resolve the problem that you are experiencing, try detaching your
  17770.  monitor from a full-screen group and the method you are using above
  17771.  should work fine. Also, you could hard code in a screen group value
  17772.  such as "4", and your monitor will register to monitor that session
  17773.  (this would most likely be the first or second full-screen group you
  17774.  start up). There is nothing wrong with registering a session that does
  17775.  not yet exist. The thread will just block until the session is created
  17776.  and the appropriate monitor chain is activated.
  17777.  
  17778.  The method you are using is valid only when you intend to start it
  17779.  from a current session. If you make the DosGetInfoSeg() call too early
  17780.  (e.g. at initialization time), the current screen group may be an
  17781.  invalid or nonexistent value. You can also try to delay or otherwise
  17782.  inhibit the DosMonReg() call until you know that a screen group of
  17783.  interest to you exists.
  17784.  
  17785.  
  17786.  545. Using InPort Mouse with OS/2 SDK Version 1.07
  17787.  
  17788.  Problem:
  17789.  
  17790.  I am having a problem with the Microsoft InPort bus mouse when running
  17791.  the Version 1.07 OS/2 SDK (Software Development Kit) on the Dell PC's
  17792.  Limited 286 AT clone. When I use the mouse in the Presentation Manager
  17793.  (PM) screen group, the system reboots to the memory check.
  17794.  
  17795.  Response:
  17796.  
  17797.  The Version 1.07 OS/2 SDK is a kernel meant to be used with the OS/2
  17798.  LAN Manager product. The Version 1.07 OS/2 SDK contains an OS/2 1.00
  17799.  kernel, not a Version 1.10 kernel. Presentation Manager was introduced
  17800.  into OS/2 in OS/2 Version 1.10 and was not present in OS/2 Version
  17801.  1.00. OS/2 SDK Version 1.07 is not meant to be used with PM.
  17802.  
  17803.  When using OS/2 SDK Version 1.07, you must use the character-based
  17804.  shell that is provided with the Version 1.07 release, not PM. Also,
  17805.  you should use the mouse drivers included with the Version 1.07 OS/2
  17806.  SDK release.
  17807.  
  17808.  If you are using OS/2 SDK Version 1.06, which is OS/2 Version 1.10,
  17809.  which also supports and includes Presentation Manager, then you should
  17810.  use the mouse drivers included with the Version 1.06 OS/2 SDK release.
  17811.  
  17812.  
  17813.  546. OS/2 SDK: Category 8 Functions 45H and 65H Documentation Error
  17814.  
  17815.  Microsoft has confirmed that part of the documentation on Pages 276
  17816.  and 281 in the "Microsoft Operating System/2 Programmer's Reference
  17817.  Volume 3 for Version 1.1" for Category 8 Functions 45H
  17818.  (DSK_FORMATVERIFY) and 65H (DSK_VERIFYTRACK) is incorrect. The
  17819.  documentation incorrectly states that the first parameter should be
  17820.  "0L". Instead, the first parameter should be a pointer to an integer
  17821.  indicating the first sector to be accessed (usually 0).
  17822.  
  17823.  We will post new information when the documentation has been updated
  17824.  to correct this error.
  17825.  
  17826.  
  17827.  547. VER Command Used in 3.x Box Returns OS/2 Version Number
  17828.  
  17829.  Question:
  17830.  
  17831.  When I type "VER" in the DOS 3.x box, an OS/2 version number is
  17832.  displayed. Does that mean that any MS-DOS application that checks the
  17833.  MS-DOS version number will not work in the DOS 3.x box?
  17834.  
  17835.  Response:
  17836.  
  17837.  Yes. That is why new utilities had to be included with the
  17838.  compatibility box. These new utilities will not work under MS-DOS
  17839.  Versions 2.x, 3.x (3.00, 3.10, 3.20, 3.21, 3.22, 3.30, and 3.30a), and
  17840.  4.x (4.00, 4.00a, and 4.01). Likewise, the MS-DOS 2.x, 3.x, and 4.x
  17841.  utilities will not work in the compatibility box due to version
  17842.  checks.
  17843.  
  17844.  
  17845.  548. OS/2 1.10 Does Not Access Memory Beyond 16 MB
  17846.  
  17847.  Question:
  17848.  
  17849.  On 80386 machines, does OS/2 access memory beyond the reported value?
  17850.  Specifically, does OS/2 access the last 2 gigabytes of system memory?
  17851.  
  17852.  Response:
  17853.  
  17854.  The CPU type does not affect OS/2 memory usage behavior (OS/2 Version
  17855.  1.10 is really an 80286 operating system). OS/2 will never try to
  17856.  access any memory beyond 16 MB. As a matter of fact, OS/2 will not
  17857.  even boot up on a machine with more than 16 MB of memory installed in
  17858.  it.
  17859.  
  17860.  
  17861.  549. OS/2 Tape Drive Backup Systems
  17862.  
  17863.  The companies listed below sell tape drives that work under OS/2. The
  17864.  products listed below are manufactured by vendors independent of
  17865.  Microsoft. We make no warranty, implied or otherwise, regarding these
  17866.  products' performance or reliability. This information is provided
  17867.  only for your convenience.
  17868.  
  17869.  1. Compaq has a tape drive that works in OS/2 protected mode.
  17870.  
  17871.  2. Sy-Tos has a 3.0 version of their tape drive that works in OS/2.
  17872.     For more information about their product, contact Sy-Tos at (508)
  17873.     898-0100.
  17874.  
  17875.  3. Irwin Magnetic Systems has a product called EzTape(R) for OS/2. For
  17876.     more information on this product, contact Irwin Magnetic Systems at
  17877.     (313) 930-9000.
  17878.  
  17879.  
  17880.  550. OS/2 Limitations on Fast Data Transfer Rates
  17881.  
  17882.  Question:
  17883.  
  17884.  We want to write an application that requires data transfer rates to
  17885.  and from a PC of no less than 320 kilobits/second, with 500
  17886.  kilobits/second desirable. Are there any inherent limitations that
  17887.  OS/2 and Presentation Manager (PM), as the base software for this
  17888.  application, might impose?
  17889.  
  17890.  Response:
  17891.  
  17892.  For the OS/2 device drivers, the amount of time from when an interrupt
  17893.  occurs to when interrupts are enabled again should be a maximum of 400
  17894.  microseconds (uS). This time is when the interrupt occurs, the kernel
  17895.  does some processing of the interrupt in its interrupt manager code,
  17896.  then passes it on to the appropriate device driver that handles the
  17897.  interrupt. If this driver is not one of the base drivers, the
  17898.  developer who wrote the driver may have not have stayed within the
  17899.  limit of 400 uS.
  17900.  
  17901.  There is a good discussion of these inherent delays in mode switching
  17902.  on an 80286 in the May 1987 issue of the "Microsoft Systems Journal,"
  17903.  Volume 2, Number 2, on Pages 61-66. The article titled "An Interview
  17904.  with Gordon Letwin, OS/2: Turning Off the Car to Change Gears" was
  17905.  interviewed and written by Lori Valigra.
  17906.  
  17907.  Switching to and from the DOS compatibility mode (3.x box) takes a lot
  17908.  of time, due to mode switching overhead. Based on Gordon's comments in
  17909.  the above article, this delay can be 1000 microseconds, in which no
  17910.  interrupts can be serviced.
  17911.  
  17912.  The COM driver included with OS/2 is specified to work with one-way
  17913.  communication at 9600 baud. This area is one in which mode switching
  17914.  to and from the 3.x box really degrades performance. Also, a better
  17915.  quality (i.e., faster) UART will help here. These timings are for a 6
  17916.  MHz IBM PC/AT; your actual timings may vary. Using an 80386 is
  17917.  generally better, especially when it comes to mode switching.
  17918.  
  17919.  In general, a better processor (80386 over 80286) will improve
  17920.  performance. Of course, in general, the better the hardware, the
  17921.  faster the system performance (faster UARTs for faster serial I/O,
  17922.  faster hard disks for faster disk I/O, faster memory, etc.). Also, if
  17923.  the DOS 3.x box is not enabled (PROTECTONLY=YES in CONFIG.SYS), the
  17924.  system performance will improve even more.
  17925.  
  17926.  
  17927.  551. OS/2 SDK: Use of Global Variables in DLLs
  17928.  
  17929.  Question:
  17930.  
  17931.  If a DLL (dynamic link library) has global variables in it, does each
  17932.  process that uses that DLL get its own copy of the variables, or are
  17933.  the variables shared among the various processes? Also, how do I
  17934.  specify which type of segment my DLL global variables go into? What
  17935.  happens by default? If the default is to put them in the shared
  17936.  segment, how do I create unique segments for each process so that
  17937.  there won't be any conflicts?
  17938.  
  17939.  Response:
  17940.  
  17941.  The method used to define whether or not a given segment is shared is
  17942.  to use the SHARED or NONSHARED attribute for the data segment in the
  17943.  module definition file. The default for all data segments in a DLL is
  17944.  for the segments to be SHARED between processes.
  17945.  
  17946.  As mentioned above, if all of your segments don't have the same
  17947.  attributes, the method used to make your global variables be contained
  17948.  within a NONSHARED segment (private to the process making the call) is
  17949.  to use the NONSHARED directive with the name of the segment in the
  17950.  SEGMENTS section of the module definition file. Or, if all data
  17951.  segments will have the same attributes, you should use the NONSHARED
  17952.  directive within the DATA section of the module definition file.
  17953.  
  17954.  The DATA section provides the defaults for all data segments within
  17955.  the library, while the SEGMENTS section allows the programmer to
  17956.  override the defaults for specific segments.
  17957.  
  17958.  
  17959.  552. BROWSE Works Only if OPENDLG.DLL Is in LIBPATH Subdirectory
  17960.  
  17961.  Question:
  17962.  
  17963.  I tried running BROWSE.EXE, which is included in the
  17964.  PMSDK\SAMPLES\BROWSE\AVBROWSE subdirectory. I got an error message
  17965.  that said it could not find OPENDLG.DLL. I used the command "BROWSE
  17966.  BROWSE.C", as instructed in the README file. Then, I tried to run MAKE
  17967.  on the BROWSE files and the file "OPENDLG.H" could not be found. Where
  17968.  is this file located?
  17969.  
  17970.  Response:
  17971.  
  17972.  Before executing BROWSE, you need to make sure that OPENDLG.DLL is
  17973.  located in a subdirectory that is included in your LIBPATH variable.
  17974.  
  17975.  OPENDLG.H is located in both the \PMSDK\SAMPLES\INCLUDE and in the
  17976.  PMSDK\SAMPLES\OPENDLG subdirectories.
  17977.  
  17978.  
  17979.  553. VioCreatePS() Can Create Presentation Space Up to 64K
  17980.  
  17981.  Question:
  17982.  
  17983.  What is the largest buffer I can allocate with VioCreatePS()? Page 203
  17984.  of the "Microsoft Operating System/2 Programmer's Reference Volume 3"
  17985.  Version 1.10 manual says that the largest buffer I can allocate is
  17986.  32K; however, on Page 309 of Charles Petzold's "Programming the OS/2
  17987.  Presentation Manager" it says that the largest buffer I can allocate
  17988.  is 64K.
  17989.  
  17990.  Response:
  17991.  
  17992.  Microsoft has confirmed that the "Microsoft Operating System/2
  17993.  Programmer's Reference Volume 3" Version 1.10 manual is in error. The
  17994.  largest size that you can allocate is 64K. As in Petzold's book, IBM's
  17995.  OS/2 1.10 documentation discusses this properly. Section 11-4 of the
  17996.  "OS/2 Version 1.10 Technical Reference: Programmer's Reference Volume
  17997.  2" states that the presentation space size that can be calculated with
  17998.  the following must not exceed 64K.
  17999.  
  18000.     (width * depth * (attributes + 1))
  18001.  
  18002.  The VioCreatePS() documentation in Versions 1.06 and 1.10 of QuickHelp
  18003.  is also in error.
  18004.  
  18005.  We will post new information when the documentation is updated to
  18006.  correct this error.
  18007.  
  18008.  
  18009.  554. AVIO and VIO Calls Do Not Directly Manipulate Physical Window
  18010.  
  18011.  Question:
  18012.  
  18013.  Do the AVIO calls do anything intelligent when they reach the bottom
  18014.  of the buffer (e.g. treat the buffer as a circular buffer)? Is it best
  18015.  to use a large separate circular buffer and scroll by copying the
  18016.  appropriate text to a VIO buffer that is only the size of the screen,
  18017.  or is it best to use VIO calls to treat the buffer as a circular
  18018.  buffer?
  18019.  
  18020.  Response:
  18021.  
  18022.  The VIO calls (including the AVIO calls) don't have any routines that
  18023.  manipulate the window directly. For example, when you call
  18024.  VioCreatePS(), a physical window is created. The VIO subsystem
  18025.  scrolling calls will move the logical window up, down, left, and
  18026.  right, around this physical window. However, there are no VIO or AVIO
  18027.  calls that will do things such as directly "folding" the physical
  18028.  window, similar to what the Windows application Excel can do when
  18029.  displaying a spreadsheet.
  18030.  
  18031.  A Windows or Presentation Manager application can create two logical
  18032.  windows that can be scrolled separately, thus achieving this sort of
  18033.  "folding" from the user's perspective.
  18034.  
  18035.  
  18036.  555. HLPMSG: Sample Help Message File Information
  18037.  
  18038.  There is a file in the Software Library named HLPMSG that contains a
  18039.  sample OS/2 application message file, which can be used by an
  18040.  application via the DosGetMessage() and DosPutMessage() APIs. It also
  18041.  can be used via the HELPMSG.EXE utility (which is transparently used
  18042.  when the user runs the HELP.BAT or HELP.CMD script files). HLPMSG can
  18043.  be found in the Software Library by searching on the keyword HLPMSG,
  18044.  the Q number of this article, or S12321. HLPMSG was archived with the
  18045.  PKware file-compression utility and contains the following files:
  18046.  FOO.TXT, FOOH.TXT, READ.ME, and MAKEFILE.
  18047.  
  18048.  The file FOO.TXT contains the error messages; the MAKEFILE runs the
  18049.  MKMSGF utility on this file, which generates FOO.MSG. The file
  18050.  FOOH.TXT contains the error message help text; the MAKEFILE runs the
  18051.  MKMSGF utility on this file, which generates FOOH.MSG. For comparison
  18052.  purposes, the files FOO.MSG and FOOH.MSG are roughly analogous in
  18053.  functionality to the OS/2 system message files, OSO001.MSG and
  18054.  OSO001H.MSG.
  18055.  
  18056.  To build the .MSG files, enter one of the following:
  18057.  
  18058.     NMAKE
  18059.  
  18060.  or
  18061.  
  18062.     MAKE MAKEFILE
  18063.  
  18064.  To see the results, type the following:
  18065.  
  18066.     HELPMSG FOO0001
  18067.  
  18068.  Or, use FOO0002-FOO0005 as the messages, since there are only five
  18069.  errors in the message text files. Make sure that the .MSG files are in
  18070.  either the DPATH (when in OS/2), in the APPEND path (when in the DOS
  18071.  3.x box), or in the current directory, so that OS/2 can find the
  18072.  files.
  18073.  
  18074.  
  18075.  556. Determining Current Country Code with DosGetCtryInfo()
  18076.  
  18077.  Question:
  18078.  
  18079.  The only way I have figured out to determine the current country code
  18080.  is to set the country field of the COUNTRYCODE structure to 0 (zero),
  18081.  call DosGetCtryInfo(), and then examine the country field information
  18082.  that is returned in the COUNTRYINFO structure. Is this the correct
  18083.  method?
  18084.  
  18085.  Response:
  18086.  
  18087.  Yes. DosGetCtryInfo() is the API that should be used to retrieve the
  18088.  current country code. And as stated above, if you set
  18089.  COUNTRYCODE.country to 0 (zero), the current country information will
  18090.  be returned. The syntax for the DosGetCtryInfo() API is as follows:
  18091.  
  18092.      DosGetCtryInfo(sizeof(buffer), &COUNTRYCODE, &COUNTRYINFO,
  18093.                     &buffer);
  18094.  
  18095.  The COUNTRYCODE structure contains information about the country and
  18096.  codepage that you are interested in. If the country and codepage are
  18097.  both set to 0 (zero), this means that you want to get the current
  18098.  country with the currently selected codepage. Therefore, the
  18099.  COUNTRYCODE structure is where you specify what you want
  18100.  DosGetCtryInfo() to get information about. COUNTRYINFO is the
  18101.  structure that returns this information.
  18102.  
  18103.  The country is user defined, not application defined. However, an
  18104.  application can select which of the codepages (which the current
  18105.  country supports) to use. Thus, you can give COUNTRYCODE.country a
  18106.  value of 0 (zero) and specify a particular COUNTRYCODE.codepage. The
  18107.  normal situation would be to specify 0 (zero) for both values, thus
  18108.  obtaining information about the current country with the current
  18109.  codepage.
  18110.  
  18111.  
  18112.  557. MouEventReadQue Doesn't Work Correctly in Windowed-Screen Mode
  18113.  
  18114.  Problem:
  18115.  
  18116.  I am having a problem using MouEventReadQue(). If you run the sample
  18117.  code listed below in full-screen mode, the output is as follows:
  18118.  
  18119.     MouInfo.fs -> 4         After pressing the left button
  18120.     MouInfo.fs -> 0         After releasing the left button
  18121.     MouInfo.fs -> 16        After pressing the right button
  18122.     MouInfo.fs -> 0         After releasing the right button
  18123.  
  18124.  If you next run the sample code listed below in windowed-screen mode,
  18125.  the output is as follows:
  18126.  
  18127.     MouInfo.fs -> 4         After pressing the left button
  18128.     MouInfo.fs -> 0         After releasing...
  18129.     MouInfo.fs -> 1         ... the left button
  18130.     MouInfo.fs -> 16        After pressing the right button
  18131.     MouInfo.fs -> 0         After releasing...
  18132.     MouInfo.fs -> 1         ... the right button
  18133.  
  18134.  Why is an extra mouse event (MouInfo.fs = 1) occurring when either
  18135.  button is released, even though the mouse has not moved at all? The
  18136.  following code can be used to reproduce this problem:
  18137.  
  18138.  ******************** TEST.C ********************
  18139.  
  18140.  /* Compiled as: cl -AL -Lp x.c */
  18141.  
  18142.  #define INCL_DOSERRORS
  18143.  #define INCL_SUB
  18144.  
  18145.  #include <os2.h>
  18146.  
  18147.  main ()
  18148.  {
  18149.          HMOU MouseHandle;         /* mouse handle                 */
  18150.          MOUEVENTINFO MouInfo;     /* mouse event packet structure */
  18151.          unsigned MouReadType = 1; /* 0=do not wait, 1=wait for
  18152.                                       mouse event                  */
  18153.          unsigned moustatus;
  18154.  
  18155.          /* open the mouse */
  18156.          MouOpen (0L, &MouseHandle );
  18157.  
  18158.          MouGetDevStatus (&moustatus, MouseHandle);
  18159.          moustatus = 0x100;
  18160.          MouSetDevStatus (&moustatus, MouseHandle);
  18161.  
  18162.          do {
  18163.                  MouReadEventQue ((PMOUEVENTINFO) &MouInfo,
  18164.                                   (unsigned far *)&MouReadType,
  18165.                                   MouseHandle);
  18166.  
  18167.                  printf ("MouInfo.fs --> %d\n", MouInfo.fs);
  18168.          } while (1);
  18169.  }  /* end main */
  18170.  ******************** END TEST.C ********************
  18171.  
  18172.  Response:
  18173.  
  18174.  Microsoft has confirmed this to be a problem with the Version 1.10
  18175.  OS/2 SDK (Software Development Kit). We are researching this problem
  18176.  and will post new information as it becomes available.
  18177.  
  18178.  As a temporary workaround, which shouldn't degrade performance very
  18179.  much, make an extra call to determine the mouse position. You could
  18180.  also check the type of screen group you are in. Then, if you are in a
  18181.  windowed screen group, you could ignore the third parameter after a 4
  18182.  0, 16 0, or 20 0 sequence of mouse events.
  18183.  
  18184.  
  18185.  558. OS/2 SDK: Using Memory Management Options in CONFIG.SYS
  18186.  
  18187.  Question:
  18188.  
  18189.  I have a question about movable data segments. Under Windows, you
  18190.  can't save data pointers for memory models other than for the small
  18191.  memory model, since segments are moved at Windows' discretion. How
  18192.  does OS/2 handle this issue, and how does this correspond to the
  18193.  MEMMAN command in CONFIG.SYS?
  18194.  
  18195.  Response:
  18196.  
  18197.  The problem with data pointers becoming invalid under Windows is not a
  18198.  problem in OS/2.
  18199.  
  18200.  The MEMMAN command in CONFIG.SYS configures the way the OS/2 memory manager
  18201.  utilizes physical memory and swapping.
  18202.  
  18203.  If the SWAP option is selected, the OS/2 memory manager is allowed to
  18204.  swap segments to the OS/2 swapper disk file named SWAPPER.DAT. If the
  18205.  NOSWAP option is selected, the OS/2 memory manager is NOT able to do
  18206.  this, and must keep segments in memory at all times.
  18207.  
  18208.  In addition to the SWAP and NOSWAP options (these two options are
  18209.  mutually exclusive), the MEMMAN also has the MOVE and NOMOVE options
  18210.  (these two options are also mutually exclusive).
  18211.  
  18212.  If the MOVE option is selected, the OS/2 memory manager can
  18213.  temporarily move segments when it needs to (while the application is
  18214.  not active or using the segment). If the NOMOVE option is selected,
  18215.  the OS/2 memory manager cannot do this.
  18216.  
  18217.  For the OS/2 memory manager to take the most advantage of memory, the
  18218.  normal options for MEMMAN are SWAP,MOVE. For more information on
  18219.  MEMMAN, refer to the "Microsoft OS/2 User's Guide."
  18220.  
  18221.  
  18222.  559. Incorrect Declaration of PFNSIGHANDLER in OS/2 Version 1.06
  18223.  
  18224.  In BSEDOS.H, the definition of the PFNSIGHANDLER type does not mention
  18225.  the fact that the function has the Pascal attribute. This causes an
  18226.  error message when you try to call DosSetSigHandler() with a function
  18227.  that you have declared with the Pascal attribute and you don't
  18228.  explicitly cast it to type PFNSIGHANDLER.
  18229.  
  18230.  The PASCAL keyword is needed by PFNSIGHANDLER. If it is NOT specified,
  18231.  the stack will be corrupted when the system calls the signal handling
  18232.  function and then returns. The two USHORTs are not removed from the
  18233.  stack and the system GP-faults trying to return to an incorrect
  18234.  address.
  18235.  
  18236.  Thus, the CORRECT way to define PFNSIGHANDLER is as follows:
  18237.  
  18238.     typedef VOID (PASCAL FAR *PFNSIGHANDLER)(USHORT, USHORT);
  18239.  
  18240.  The INCORRECT way to define PFNSIGHANDLER is as follows:
  18241.  
  18242.     typedef VOID (FAR *PFNSIGHANDLER)(USHORT, USHORT);
  18243.  
  18244.  In the version of BSEDOS.H that was included with the Version 1.05
  18245.  OS/2 SDK (Software Development Kit), PFNSIGHANDLER was properly
  18246.  defined. However, Microsoft has confirmed that in the Version 1.06
  18247.  OS/2 SDK, PFNSIGHANDLER was incorrectly changed to not include the
  18248.  PASCAL keyword. This problem (introduced in OS/2 SDK Version 1.06) was
  18249.  corrected in the Version 1.07 OS/2 SDK.
  18250.  
  18251.  
  18252.  560. OS/2 BAK Version 1.10 Will Not Install in 32 MB Partition
  18253.  
  18254.  Problem:
  18255.  
  18256.  In following the installation procedures in the manual and using the
  18257.  SETUP.BAT batch file that comes with the Version 1.10 OS/2 Binary
  18258.  Adaptation Kit (BAK), I ran out of disk space at about disk 27 out of
  18259.  29. I started with a clean 32 MB partition. The README.DOC file on
  18260.  Binary Disk 1 states that I can use MS-DOS Version 3.30 to build and
  18261.  develop the OS/2 BAK. However, MS-DOS Version 3.30 does not allow
  18262.  partitions larger than 32 MB.
  18263.  
  18264.  Response:
  18265.  
  18266.  Microsoft has confirmed that the README.DOC file is in error. Also,
  18267.  Page 16 of the "Microsoft Operating System/2 Binary Adaptation Guide"
  18268.  for Version 1.10 incorrectly states that MS-DOS Version 3.30 can be
  18269.  used to build and develop the OS/2 BAK.
  18270.  
  18271.  You can no longer perform the adaptation under MS-DOS Version 3.30.
  18272.  You must use another version of MS-DOS that supports partitions larger
  18273.  than 32 MB, such as MS-DOS Version 4.01 or Compaq's MS-DOS Version
  18274.  3.31. We will post new information when this error has been corrected
  18275.  in the documentation.
  18276.  
  18277.  
  18278.  561. Open File Handles Are Inherited by Detached Screen Group
  18279.  
  18280.  If you use the DETACH command from a screen group that has open files
  18281.  in it, the file handles of the open files are inherited by the
  18282.  detached screen group. Subsequent use of these files by the original
  18283.  screen group causes an error.
  18284.  
  18285.  This is expected behavior. When CMD.EXE encounters a DETACH statement,
  18286.  the program specified is executed via the DosExecPgm() function call.
  18287.  The DosExecPgm() call does not close file handles, and all handles
  18288.  that are open are therefore inherited by the child process (the
  18289.  DETACHed process).
  18290.  
  18291.  To work around this situation, do one of the following:
  18292.  
  18293.  1. Either close the handles before "execing" CMD.EXE (your program
  18294.     probably already does this, since the file handles are open while
  18295.     the command interpreter is running) or open the files with the
  18296.     inherit option turned off.
  18297.  
  18298.  2. Change the inheritance state on an open file by using the
  18299.     DosSetFHandState() function call and setting the noinheritance
  18300.     flag. Please refer to the QuickHelp documentation on the
  18301.     DosSetFHandState() function call for an example of how to do this.
  18302.  
  18303.  
  18304.  562. OS/2 SDK 1.10 QuickHelp Missing KBDKEYINFO Documentation
  18305.  
  18306.  Microsoft has confirmed that the documentation in the OS/2 Version
  18307.  1.10 Software Development Kit (SDK) QuickHelp database for the OS/2
  18308.  API does not include information on the KBDKEYINFO data structure (the
  18309.  struct called _KBDKEYINFO, a.k.a. the typedef called KBDKEYINFO) used
  18310.  by the KbdCharIn() API. This problem has been corrected in the
  18311.  QuickHelp database included with the Microsoft OS/2 Version 1.10
  18312.  Programmer's Toolkit (PTK). Below is the text for this KBDKEYINFO
  18313.  structure, taken from the Version 1.10 PTK QuickHelp database.
  18314.  
  18315.  #define INCL_KBD
  18316.  
  18317.  typedef struct _KBDKEYINFO {    /* kbci */
  18318.      UCHAR  chChar;
  18319.      UCHAR  chScan;
  18320.      UCHAR  fbStatus;
  18321.      UCHAR  bNlsShift;
  18322.      USHORT fsState;
  18323.      ULONG  time;
  18324.  } KBDKEYINFO;
  18325.  
  18326.  The KBDKEYINFO structure contains information when a key is pressed.
  18327.  
  18328.  Parameters  Description
  18329.  ---------------------------------------------------------------------
  18330.  chChar      Specifies the character derived from translation of the
  18331.              chScan field.
  18332.  
  18333.  chScan      Specifies the scan code received from the keyboard,
  18334.              identifying the key pressed. This scan code may be
  18335.              modified during the translation process.
  18336.  
  18337.  fbStatus    Specifies the state of the retrieved scan code. It can be
  18338.              any combination of the following values:
  18339.  
  18340.              Value               Meaning
  18341.              ---------------------------------------------------------
  18342.              SHIFT_KEY_IN        SHIFT key is received (valid only in
  18343.                                  binary mode when shift reporting is
  18344.                                  turned on).
  18345.  
  18346.              CONVERSION_REQUEST  Conversion requested.
  18347.  
  18348.              FINAL_CHAR_IN       Final character received.
  18349.  
  18350.              INTERIM_CHAR_IN     Interim character received.
  18351.  
  18352.  bNlsShift   Specifies a reserved value; must be zero.
  18353.  
  18354.  fsState     Specifies the state of the SHIFT keys. It can be any
  18355.              combination of the following values:
  18356.  
  18357.              Value          Meaning
  18358.              ---------------------------------------------------------
  18359.              RIGHTSHIFT     Right SHIFT key down.
  18360.  
  18361.              LEFTSHIFT      Left SHIFT key down.
  18362.  
  18363.              CONTROL        Either CTRL key down.
  18364.  
  18365.              ALT            Either ALT key down.
  18366.  
  18367.              SCROLLLOCK_ON  SCROLL LOCK mode turned on.
  18368.  
  18369.              NUMLOCK_ON     NUM LOCK mode turned on.
  18370.  
  18371.              CAPSLOCK_ON    CAPS LOCK mode turned on.
  18372.  
  18373.              INSERT_ON      INSERT key turned on.
  18374.  
  18375.              LEFTCONTROL    Left CTRL key down.
  18376.  
  18377.              LEFTALT        Left ALT key down.
  18378.  
  18379.              RIGHTCONTROL   Right CTRL key down.
  18380.  
  18381.              RIGHTALT       Right ALT key down.
  18382.  
  18383.              SCROLLLOCK     SCROLL LOCK key down.
  18384.  
  18385.              NUMLOCK        NUM LOCK key down.
  18386.  
  18387.              CAPSLOCK       CAPS LOCK key down.
  18388.  
  18389.              SYSREQ         SYS REQ key down.
  18390.  
  18391.  time        Specifies the time stamp of the keystroke (in
  18392.              milliseconds).
  18393.  
  18394.  See Also:
  18395.  
  18396.  KbdCharIn, KbdPeek, KBD_PEEKCHAR
  18397.  
  18398.  
  18399.  563. OS/2 DLL File Format
  18400.  
  18401.  Information about the format of an OS/2 DLL (dynamic linked library)
  18402.  file can be obtained from two sources. An earlier version of the OS/2
  18403.  SDK (Software Development Kit) included a file named NEWEXE.H that
  18404.  describes the structure of the new EXE format, which is also the
  18405.  format of an OS/2 DLL file. Also, Appendix D of Ray Duncan's "Advanced
  18406.  OS/2 Programming" book contains a detailed layout of the file
  18407.  structure.
  18408.  
  18409.  In the Software Library is a file named NEWEXE that contains an
  18410.  archived copy of NEWEXE.H. This file can be found in the Software/Data
  18411.  Library by searching on the keyword NEWEXE, the Q number of this
  18412.  article, or S12338. NEWEXE was archived using the PKware
  18413.  file-compression utility.
  18414.  
  18415.  
  18416.  564. Using OS/2 SDK Version 1.10 with OS/2 LAN Manager
  18417.  
  18418.  Question:
  18419.  
  18420.  Can I run the final release of the OS/2 LAN Manager under the Version
  18421.  1.10 OS/2 SDK (Software Development Kit)?
  18422.  
  18423.  Response:
  18424.  
  18425.  Yes, you can use OS/2 LAN Manager under OS/2 SDK Version 1.10.
  18426.  However, by not using the LAN Manager kernel, you will lose the
  18427.  ability to use the LAN Manager disk cache.
  18428.  
  18429.  If this feature is not important to you, you can use the OS/2 SDK
  18430.  Version 1.10 kernel.
  18431.  
  18432.  When upgrading to OS/2 SDK Version 1.10, be sure that the "\OS2\DLL"
  18433.  path appears before "\LANMAN\NETLIB" in your LIBPATH variable, so that
  18434.  the system will default first to the OS/2 Version 1.10 NAMPIPES.DLL.
  18435.  For example:
  18436.  
  18437.     LIBPATH=C:\OS2\DLL;C:\LANMAN\NETLIB;
  18438.  
  18439.  
  18440.  565. Version 1.00 DUALBOOT Utility Can't Be Used in OS/2 SDK 1.10
  18441.  
  18442.  Question:
  18443.  
  18444.  Can I use the old (Version 1.00) DUALBOOT utility with the Version
  18445.  1.10 OS/2 SDK (Software Development Kit)?
  18446.  
  18447.  Response:
  18448.  
  18449.  No. The older DUALBOOT utility was built into the OS/2 1.00 loader
  18450.  program and thus has dependencies toward that release. The OS/2 1.10
  18451.  loader does not have these hooks. The new DUALBOOT utility is isolated
  18452.  from the kernel, so that OEMs can easily choose whether to include it
  18453.  or not with their OS/2 release. For example, IBM doesn't include the
  18454.  DUALBOOT utility with its release.
  18455.  
  18456.  In addition, OS/2 1.00 had to contend with two sets of CONFIG.SYS and
  18457.  AUTOEXEC.BAT files when loading OS/2 or MS-DOS. OS/2 1.10 doesn't have
  18458.  to worry about this, as the new DUALBOOT utility takes care of the
  18459.  problem of renaming the appropriate set of CONFIG and AUTOEXEC files
  18460.  for the currently selected operating system, MS-DOS or OS/2.
  18461.  
  18462.  The new DUALBOOT utility has many more features than the older one, in
  18463.  response to feedback that we have received from OnLine OEMs and ISVs.
  18464.  Among these, it has closer conformance to SAA's CUA, it allows you to
  18465.  change the default operating system, has a time delay to auto-boot the
  18466.  default operating system if you don't select one, and allows you to
  18467.  easily install or uninstall DUALBOOT.
  18468.  
  18469.  One reason why it is now a separate utility is so that it can be used
  18470.  on IBM's release of OS/2, as well as the Microsoft releases of OS/2.
  18471.  The previous release of DUALBOOT was partially in Microsoft-specific
  18472.  portions of the OS/2 1.00 loader, and in a Microsoft-specific OS/2
  18473.  1.00 installation program. DUALBOOT has been isolated so the same
  18474.  installation program and loader can be used by OEMs with very little
  18475.  modification, unlike the 1.00 DUALBOOT utility.
  18476.  
  18477.  
  18478.  566. Serial Port Buffering in OS/2
  18479.  
  18480.  Question:
  18481.  
  18482.  How does OS/2 implement COM port buffering? I have a program that,
  18483.  when running on a heavily loaded machine, regularly loses characters
  18484.  that are coming in through a COM port.
  18485.  
  18486.  Response:
  18487.  
  18488.  Because OS/2 is a multitasking operating system, no single function
  18489.  (such as reading the serial port) can monopolize the entire system
  18490.  (like it could in MS-DOS) to ensure that no data is missed during
  18491.  real-time input. However, you can minimize the possibility of losing
  18492.  data that is coming in through the COM port by doing the following:
  18493.  
  18494.  1. Never switch to the 3.x Box when expecting serial data from the COM
  18495.     port.
  18496.  
  18497.  2. Use the DosReadAsync() function to get serial data from the COM
  18498.     port.
  18499.  
  18500.  3. Use the SetDCBInfo IOCTL (Category 1, Function 53H) to specify
  18501.     MODE_WAIT_READ_TIMEOUT time-out processing (this is a bit in the
  18502.     fbTimeout byte in the DCBInfo structure passed to the IOCTL).
  18503.  
  18504.  
  18505.  567. OS/2 SDK: Determining If Application Is in the Foreground
  18506.  
  18507.  Problem:
  18508.  
  18509.  DosGetInfoSeg() will not properly return the current foreground or
  18510.  background status (via the boolean flag in the local information
  18511.  segment).
  18512.  
  18513.  Response:
  18514.  
  18515.  This is not a problem with the DosGetInfoSeg() function call; however,
  18516.  the documentation is unclear. What the flag means is that the current
  18517.  process has the input focus, not that the current process is in the
  18518.  foreground.
  18519.  
  18520.  To determine whether an application is in the foreground, compare the
  18521.  session ID in the local info seg with the current foreground session
  18522.  ID in the global info seg. The following program demonstrates how to
  18523.  do this:
  18524.  
  18525.  #define INCL_BASE
  18526.  #include <os2.h>
  18527.  #include <stdio.h>
  18528.  
  18529.  void main(void);
  18530.  
  18531.  void main(void)
  18532.  
  18533.  {
  18534.      SEL       GlobSel;
  18535.      SEL       LocSel;
  18536.  
  18537.      GINFOSEG  FAR *pgisInfo;
  18538.      LINFOSEG  FAR *plisInfo;
  18539.  
  18540.      DosGetInfoSeg(&GlobSel,&LocSel);
  18541.  
  18542.      pgisInfo = MAKEPGINFOSEG(GlobSel);
  18543.      plisInfo = MAKEPLINFOSEG(LocSel);
  18544.  
  18545.      if ((pgisInfo -> sgCurrent) == (plisInfo -> sgCurrent))
  18546.          printf("Current foreground process\n"
  18547.                 "Process Screen Group = %u Current Screen Group = %u\n",
  18548.                 plisInfo -> sgCurrent,pgisInfo -> sgCurrent);
  18549.      else
  18550.          printf("\n\n\n\n\n\nNot current foreground app\n"
  18551.                 "Process Screen Group = %u Current Screen Group = %u\n",
  18552.                 plisInfo -> sgCurrent,pgisInfo -> sgCurrent);
  18553.  }
  18554.  
  18555.  
  18556.  568. OS/2 SDK: QuickHelp POLYLINE Sample Code Is Incorrect
  18557.  
  18558.  Microsoft has confirmed that the following problems exist in the
  18559.  versions of QuickHelp included with the Version 1.06 and Version 1.10
  18560.  OS/2 SDK (Software Development Kit); we are researching these
  18561.  problems and will post new information as it becomes available. The
  18562.  POLYLINE.C sample code is incorrect and needs the following changes
  18563.  made to it:
  18564.  
  18565.  1. The definitions for CLR_PALE* should be replaced with CLR_DARK*
  18566.     (error).
  18567.  
  18568.  2. DosCreateThread() should be prototyped properly because it is
  18569.     producing a warning message.
  18570.  
  18571.  3. The Thread() function should be prototyped properly because it
  18572.     is producing a warning message.
  18573.  
  18574.  4. STRING.H should be #included in POLYLINE.C, because a warning
  18575.     message is being displayed.
  18576.  
  18577.  Another problem related to the POLYLINE example in QuickHelp is that
  18578.  if you select any of the source files (POLYLINE.C, POLYLINE.H,
  18579.  POLYLINE.RC, or POLYLINE.DEF) other than the makefile (POLYLINE.MAK)
  18580.  and then use the Reference menu selection to try to select the
  18581.  makefile, QuickHelp will incorrectly attempt to select "POLYLINE" with
  18582.  no .MAK extension. This results in an error of "polyline topic not
  18583.  found."
  18584.  
  18585.  The POLYLINE sample source code is still contained in the versions of
  18586.  QuickHelp included with Versions 1.06 and 1.10 of the OS/2 SDK, but
  18587.  this source code has been removed from the version of QuickHelp
  18588.  included with the OS/2 Version 1.10 PTK (Programmer's Tool Kit).
  18589.  
  18590.  
  18591.  569. OS/2 SDK: PMDD.SYS Functionality
  18592.  
  18593.  Question:
  18594.  
  18595.  What is the functionality of PMDD.SYS? I cannot find any
  18596.  documentation on it in the manuals.
  18597.  
  18598.  Response:
  18599.  
  18600.  It is the SINGLEQ driver. Its purpose is to provide serialization of
  18601.  multiple events from multiple input devices (e.g. keyboard, mouse,
  18602.  light pen, trackball, etc.). It has no options and is necessary for
  18603.  PM (Presentation Manager) operation. This is how PM can respond to
  18604.  mouse and keyboard events in sequence but seemingly at the same time
  18605.  without delay. All the input events are funneled into the SINGLEQ
  18606.  driver, and PM reads out of this queue. This way all events are
  18607.  captured, and the sequence of events is preserved.
  18608.  
  18609.  PMDD.SYS is not documented because it's a necessary item that the
  18610.  INSTALL program puts in the user's CONFIG.SYS file and is therefore
  18611.  apparent to the user. If you only have one input device, it is
  18612.  possible that you can get by without it, but this is subject to
  18613.  change in future versions of PM.
  18614.  
  18615.  
  18616.  570. OS/2 SDK: EGA.SYS Functionality
  18617.  
  18618.  Question:
  18619.  
  18620.  My system is equipped with a VGA card and monitor. After installing
  18621.  OS/2 Version 1.10, the CONFIG.SYS file contains a line with
  18622.  "DEVICE=C:\OS2\EGA.SYS". Why is the EGA.SYS driver installed? Is this
  18623.  optional during installation?
  18624.  
  18625.  Response:
  18626.  
  18627.  The EGA.SYS driver is a real-mode-only driver. It is added to your
  18628.  CONFIG.SYS file if you accept an installation that includes the DOS
  18629.  3.x Box. It is a driver that shadows the EGA registers, and if it
  18630.  isn't included, it may prevent certain high resolution graphic
  18631.  programs from working properly in the DOS 3.x Box. It is also used by
  18632.  the mouse driver in certain video modes when in the DOS 3.x Box.
  18633.  
  18634.  The functionality of EGA.SYS is not really related to the
  18635.  monitor/adapter type, but to what modes your applications may or may
  18636.  not use under real mode. Any time you run an application that might
  18637.  program the monitor/adapter to an EGA mode (whether you have a VGA or
  18638.  not), you will probably want to have this driver loaded. This is
  18639.  true for graphics modes only; text modes are not a problem.
  18640.  
  18641.  You could leave EGA.SYS out without causing a problem. The driver
  18642.  will not load if OS/2 finds EGA.SYS in CONFIG.SYS, and PROTECTONLY is
  18643.  set to YES.
  18644.  
  18645.  
  18646.  571. OS/2 SDK: Using MSGBIND to Bind Message Segment to Executable
  18647.  
  18648.  Question:
  18649.  
  18650.  Can the MSGBIND utility be used to bind a message file that is larger
  18651.  than 64K?
  18652.  
  18653.  Response:
  18654.  
  18655.  The MSGBIND utility is used to modify an OS/2 executable file to
  18656.  contain RAM-based messages. It takes a message file and "binds" the
  18657.  file to the executable. Thus, the executable does not need to have
  18658.  external message files to be able to display messages with the
  18659.  DosGetMessage(), DosInsMessage(), and DosDosPutMessage() APIs.
  18660.  
  18661.  The code segment for the message APIs are placed in a code segment
  18662.  publicly called MSGSEGCODE. The MSGBIND utility and the Dos*Message()
  18663.  set of APIs are designed so that only a single segment of messages can
  18664.  be bound to an executable file. Therefore, although a message file can
  18665.  be larger than 64K, a message file must fit into a single segment in
  18666.  order for MSGBIND to bind the message segment to the executable. If a
  18667.  message file is larger than 64K, then the executable can use the
  18668.  Dos*Message() set of APIs to manipulate this external file.
  18669.  
  18670.  
  18671.  572. OS/2 SDK: QuickHelp 1.10 Numeric Keypad ENTER Key Problem
  18672.  
  18673.  Microsoft has confirmed that the following problem occurs with the
  18674.  version of QuickHelp included with the Version 1.01 OS/2 SDK (Software
  18675.  Development Kit). The numeric keypad ENTER key on a 101 keyboard
  18676.  doesn't always work in QuickHelp. For example, after installing
  18677.  QuickHelp as a TSR (terminate-and-stay-resident) program, do the
  18678.  following:
  18679.  
  18680.  1. Press ALT+Q.
  18681.  
  18682.  2. Press "V".
  18683.  
  18684.  3. Press "I".
  18685.  
  18686.  4. Select QuickHelp.
  18687.  
  18688.  5. Press "R".
  18689.  
  18690.  6. When the ENTER key on the numeric keypad is pressed, there is no
  18691.     response. However, when the ENTER key on the main keyboard is
  18692.     pressed, the appropriate response is returned.
  18693.  
  18694.  We are researching this problem and will post new information as
  18695.  it becomes available.
  18696.  
  18697.  
  18698.  573. Determining If File Handle Is for a File or Character Device
  18699.  
  18700.  Question:
  18701.  
  18702.  Given a file handle, is there any way to tell if that handle is for a
  18703.  file or for a device? I want to be able to check for the serial (COM)
  18704.  ports.
  18705.  
  18706.  Response:
  18707.  
  18708.  To determine whether a handle is for a device or a file, use the
  18709.  DosQHandType() call. This function will tell you whether the handle is
  18710.  a device, a file, or a pipe. Also, if the handle is a network handle,
  18711.  this value is ANDed with the device, file, or pipe value.
  18712.  
  18713.  To determine whether a serial port is being used, look for COMn:.
  18714.  
  18715.  
  18716.  574. KBDKEYINFO and KBDINFO Information Incorrect in Windowed Mode
  18717.  
  18718.  The KBDKEYINFO and KBDINFO structures contain different values,
  18719.  depending on whether you are running in full-screen or windowed mode.
  18720.  In certain cases, the information contained in these structures can be
  18721.  incorrect in windowed mode.
  18722.  
  18723.  Microsoft has confirmed this to be a problem in the Version 1.10 OS/2
  18724.  SDK (Software Development Kit). We are researching this problem and
  18725.  will post new information as it becomes available.
  18726.  
  18727.  The program below illustrates this problem. Before using this program,
  18728.  turn on all the lock keys (SCROLL LOCK, NUM LOCK, and CAPS LOCK). In
  18729.  full-screen mode, the fsState after the first KbdGetStatus() is set to
  18730.  "0X70", which is correct, but in windowed mode, it incorrectly returns
  18731.  0 (zero). The following is a sample program:
  18732.  
  18733.  /* test program */
  18734.  #include <os2.h>
  18735.  
  18736.  #define KbdHandle       0
  18737.  
  18738.  main ()
  18739.  {
  18740.          KBDKEYINFO kp;          /* keyboard packet */
  18741.          KBDINFO ks;
  18742.          unsigned err;
  18743.  
  18744.          printf ("Press ESC to quit...\n");
  18745.  
  18746.          do {
  18747.                  ks.cb = sizeof (ks);
  18748.                  KbdGetStatus (&ks, KbdHandle);
  18749.                  printf ("After KbdGetStatus:\n");
  18750.                  printf ("\t ks.cb (in hex): %X\n", ks.cb);
  18751.                  printf ("\t ks.fsMask (in hex): %X\n", ks.fsMask);
  18752.                  printf ("\t ks.chTurnAround (in hex): %X\n",
  18753.                          ks.chTurnAround);
  18754.                  printf ("\t ks.fsInterim (in hex): %X\n", ks.fsInterim);
  18755.                  printf ("\t ks.fsState (in hex): %X\n", ks.fsState);
  18756.  
  18757.                  err = KbdCharIn (&kp, IO_WAIT, KbdHandle);
  18758.  
  18759.                  printf ("\nAfter KbdCharIn:\n");
  18760.                  printf ("\t kp.chChar (in hex): %X\n", kp.chChar);
  18761.                  printf ("\t kp.chScan (in hex): %X\n", kp.chScan);
  18762.                  printf ("\t kp.fbStatus (in hex): %X\n", kp.fbStatus);
  18763.                  printf ("\t kp.bNlsShift (in hex): %X\n", kp.bNlsShift);
  18764.                  printf ("\t kp.fsState (in hex): %X\n\n", kp.fsState);
  18765.          } while (kp.chChar != 0x1B);
  18766.  }
  18767.  /* end test program */
  18768.  
  18769.  
  18770.  575. Current Mouse Driver List for OS/2 Version 1.10
  18771.  
  18772.  The following is a list of the mouse drivers currently released with
  18773.  OS/2 Version 1.10:
  18774.  
  18775.     Driver        System  Mouse
  18776.     ------------  ------  -----------------------------------------
  18777.  
  18778.     MOUSEA00.SYS  PC/AT   Mouse Systems Mouse
  18779.     MOUSEA01.SYS  PC/AT   Visi-On Mouse
  18780.     MOUSEA02.SYS  PC/AT   Microsoft Serial Mouse (039-099, 039-199)
  18781.     MOUSEA03.SYS  PC/AT   Microsoft Bus Mouse (037-099, 037-199)
  18782.     MOUSEA04.SYS  PC/AT   Microsoft InPort (parallel) Mouse
  18783.     MOUSEA05.SYS  PC/AT   IBM Personal System/2 Mouse
  18784.     MOUSEB00.SYS  PS/2    Mouse Systems Mouse
  18785.     MOUSEB01.SYS  PS/2    Visi-On Mouse
  18786.     MOUSEB02.SYS  PS/2    Microsoft Serial Mouse (039-099, 039-199)
  18787.     MOUSEB05.SYS  PS/2    IBM PS/2 Mouse
  18788.  
  18789.  
  18790.  576. OS/2 SDK: Reallocating Huge Segments of Memory
  18791.  
  18792.  Question:
  18793.  
  18794.  There appears to be a barrier at 64K for the DosAllocSeg(),
  18795.  DosReAllocSeg(), DosAllocHuge(), and DosReAllocHuge() APIs. How do you
  18796.  allocate an amount of memory starting at less than 64K that can be
  18797.  reallocated at a later time to an amount greater than 64K?
  18798.  
  18799.  Also, the DosAllocHuge() API includes a parameter that defines the
  18800.  largest number of segments that can be reallocated. How do you define
  18801.  a huge segment that can be reallocated to any larger size?
  18802.  
  18803.  Response:
  18804.  
  18805.  Due to the Intel 80286 protected mode memory management hardware
  18806.  model, OS/2 restricts each segment to 64K or less. Because of this
  18807.  environmental constraint, a single segment in OS/2 cannot be grown to
  18808.  be greater than 64K.
  18809.  
  18810.  However, OS/2 tries to overcome this hardware restriction by making
  18811.  what it calls huge segments, which are a series of multiple 64K
  18812.  segments with selectors spaced equidistantly that are linked together
  18813.  by a method of shifting between each 64K segment.
  18814.  
  18815.  The DosGetHugeShift() API returns the shift count, which is used to
  18816.  determine how near or how far these segments are spaced. The
  18817.  DosAllocHuge() API allocates the series of huge segments. When using
  18818.  this API, you specify the number of segments to allocate (and since
  18819.  the last segment can possibly be less than 64K, this is specified in
  18820.  bytes as a separate parameter). In addition to specifying how many
  18821.  segments to allocate, the DosAllocHuge() API has another parameter
  18822.  that allows you to specify the maximum number of segments that can be
  18823.  called by the corresponding DosReallocHuge() API.
  18824.  
  18825.  This means that if you allocate 3 segments (2 full segments plus a
  18826.  partial segment) and specify that a maximum of 10 segments will ever
  18827.  be used, then DosAllocHuge() will reserve 10 entries in your LDT
  18828.  (local descriptor table) and will allocate 3 segments of memory for
  18829.  your immediate use. Later, you could use the DosReallocHuge() API to
  18830.  allocate some of the additional 7 segments.
  18831.  
  18832.  However, once you've called DosAllocSeg() and specified the maximum
  18833.  number of segments that this series of huge segments will be, you
  18834.  cannot change this number to a larger value. Of course, you could free
  18835.  up the set of huge segments by invoking DosFreeSeg() and passing it
  18836.  the first selector in the set. You then could allocate the huge
  18837.  segment set again with your new maximum value. However, this is not a
  18838.  reasonable thing to do. We recommend that you choose a realistic
  18839.  maximum for the initial invocation of DosAllocHuge().
  18840.  
  18841.  
  18842.  577. Reading and Writing Files with Different Codepages
  18843.  
  18844.  Question:
  18845.  
  18846.  Does Microsoft have a standard way of dealing with saved files written
  18847.  in one codepage and read in another codepage?
  18848.  
  18849.  Response:
  18850.  
  18851.  Codepage support in MS-DOS Versions 3.30 and 4.00, and in OS/2
  18852.  Versions 1.00 and 1.10 does not have a way to tie a codepage to a
  18853.  file. We agree that it would be very useful to know what codepage a
  18854.  file was created under, so that this same codepage could be used to
  18855.  process the file at some later time.
  18856.  
  18857.  However, as mentioned, this support is not available. If the file is a
  18858.  data file of your own, or in some other way has the ability to store
  18859.  information in it, it would be wise to store the codepage in the file
  18860.  somewhere. This is difficult to do in some cases. For example, in .EXE
  18861.  files created by linkers or in ASCII text files that a user created in
  18862.  an editor, there really isn't room for such a field.
  18863.  
  18864.  The best place to store this information would probably be outside the
  18865.  file, stored with the other file characteristics such as the file
  18866.  date, time, attributes, size, etc. This idea of tagging a codepage to
  18867.  a file is under consideration by the MS-DOS and OS/2 groups, and will
  18868.  be considered for inclusion in future releases of these operating
  18869.  systems.
  18870.  
  18871.  If the information (on what codepage the file was created with) is not
  18872.  stored by the operating system (as is currently the case), and the
  18873.  information is not contained within the file itself, then there are
  18874.  few other places for a program to get this information. You could ask
  18875.  the user for this information, or you could store this information in
  18876.  some other location, such as an initialization file or an environment
  18877.  variable. Of course, all of these alternatives have disadvantages and
  18878.  are not foolproof, since they rely on the user to tell the application
  18879.  what codepage should be used.
  18880.  
  18881.  One way you can store this information is to have a variable in
  18882.  OS2.INI that specifies the default codepage for the application. When
  18883.  interpreting a file, you can then assume that this variable is the
  18884.  default codepage and act accordingly. Then, the application needs a
  18885.  way for the user to change the default codepage value, such as in a
  18886.  setup portion of the application. In addition, it might also be
  18887.  helpful to have such an option in a dialog box when reading any files,
  18888.  so that the user would have the ability to change this value on the
  18889.  fly.
  18890.  
  18891.  Finally, you can obtain this type of information from the country
  18892.  information, which you can get from OS/2 by calling the
  18893.  DosGetCtryInfo() function. If you specify default codepage and country
  18894.  information in the COUNTRYCODE structure (which tells this API which
  18895.  country and codepage to get information on), this API will return the
  18896.  COUNTRYINFO structure filled with the default country and codepage. If
  18897.  you have no other idea about which codepage to default to, you could
  18898.  try defaulting to the current country's default codepage.
  18899.  
  18900.  Please refer to the QuickHelp databases or to the "Microsoft Operating
  18901.  System/2 Programmer's Reference Volume 3" for more information on the
  18902.  DosGetCtryInfo() API and the COUNTRYCODE and COUNTRYINFO data
  18903.  structures.
  18904.  
  18905.  When all else fails, default to codepage 850, the multilingual
  18906.  codepage.
  18907.  
  18908.  
  18909.  578. Jumper UB Card to Work in 8-Bit Mode with NCR PC-916
  18910.  
  18911.  The NCR PC-916 computer will not run any OS/2 1.10 release until the
  18912.  Ungermann-Bass 16-bit network card in it is jumpered to run at 8-bit
  18913.  mode (you still use the 16-bit LANMAN driver, and it's 5 percent or
  18914.  less slower).
  18915.  
  18916.  
  18917.  579. How to Use Mouse Driver in DOS 3.x Box Under OS/2
  18918.  
  18919.  The OS/2 mouse device drivers included with the OS/2 SDK (Software
  18920.  Development Kit) have different command-line arguments. The following
  18921.  command-line argument, the MODE option, controls which environment the
  18922.  mouse driver will be used in:
  18923.  
  18924.     MODE=<mode>
  18925.  
  18926.  This option specifies whether you'll be using the mouse in an OS/2
  18927.  session, the DOS session, or both sessions. Acceptable values for mode
  18928.  are P (protected mode, OS/2 session), R (real mode, DOS session), and
  18929.  B (both sessions); the default is B.
  18930.  
  18931.  Therefore, if B is specified, the mouse driver is set up to work in
  18932.  both modes. This will allow three classes of applications to use mouse
  18933.  input: OS/2 base applications will be able to use the MOU* subsystem
  18934.  APIs, OS/2 Presentation Manager applications will be able to use the
  18935.  WM_MOU* message queue model mouse input, and real-mode applications
  18936.  running in the 3.x box screen group will be able to use the MS-DOS INT
  18937.  33H mouse input method.
  18938.  
  18939.  An MS-DOS mouse device driver (such as the Microsoft MOUSE.SYS driver)
  18940.  cannot be installed in the OS/2 CONFIG.SYS file. However, if no OS/2
  18941.  mouse device driver is installed, then it is possible to install a
  18942.  MS-DOS TSR (terminate-and-stay-resident) mouse driver (such as the
  18943.  Microsoft MOUSE.COM driver), since it does not have the same list of
  18944.  restrictions as real-mode device drivers.
  18945.  
  18946.  Running a MS-DOS mouse program such as MOUSE.COM is mutually exclusive
  18947.  with loading an OS/2 mouse device driver such as MOUSExxx.SYS.
  18948.  
  18949.  Finally, some versions of some applications (such as Windows/286) can
  18950.  at times bypass the conventional MS-DOS driver mechanisms and obtain
  18951.  mouse input directly from the mouse hardware. If these programs cannot
  18952.  be modified (or patched) or in some other way changed to use the
  18953.  MS-DOS INT 33H mouse input standard, then these applications cannot
  18954.  obtain mouse input in the OS/2 DOS 3.x box. In the case of Windows,
  18955.  there is a patch available that allows the mouse to work. Newer
  18956.  versions of Windows will work without the application of this patch.
  18957.  Information on this patch can be found by searching on the words
  18958.  "mouse and patch" in the KnowledgeBase.
  18959.  
  18960.  
  18961.  580. Determining Amount of Data Written to Swap File
  18962.  
  18963.  Question:
  18964.  
  18965.  When OS/2 swaps out memory, does it write 64K worth of data to the
  18966.  swap file, or does it only write the number of bytes contained in the
  18967.  segment?
  18968.  
  18969.  Response:
  18970.  
  18971.  The swapper writes only the bytes in the segment and always rounds
  18972.  writes out to a sector boundary. Reads are the same, with the swapper
  18973.  always starting reads on a sector boundary with at most one partial
  18974.  trailing sector.
  18975.  
  18976.  
  18977.  581. OS/2 SDK 1.10 PM Line Drawing Character Problem
  18978.  
  18979.  The ASCII line drawing characters defined to be 179 and 212 do not
  18980.  line up correctly in a Presentation Manager (PM) windowed command
  18981.  processor. The 212 character's vertical line is offset 1 pixel too far
  18982.  to the left.
  18983.  
  18984.  Microsoft has confirmed this to be a problem in Version 1.10 of the
  18985.  OS/2 SDK (Software Development Kit). We are researching this problem
  18986.  and will post new information as it becomes available.
  18987.  
  18988.  
  18989.  582. OS/2 SDK: Setting and Using File Attributes
  18990.  
  18991.  Question:
  18992.  
  18993.  I have the following questions regarding the use and setting of file
  18994.  attributes:
  18995.  
  18996.  1. Is it correct that OS/2 sets the FILE_ARCHIVED attribute of a file
  18997.     only when the file is created or opened with OPEN_ACCESS_WRITEONLY
  18998.     or OPEN_ACCESS_READWRITE?
  18999.  
  19000.  2. My program wants to use DosFindFirst() [and DosFindNext(), if
  19001.     necessary] to search for existing files that have the FILE_ARCHIVED
  19002.     attribute set. Setting the DosFindFirst() attribute argument to
  19003.     FILE_ARCHIVED doesn't seem to find only files with the ARCHIVED
  19004.     attribute. Rather, all NORMAL files are returned. Is there a way to
  19005.     tell DosFindFirst() to only return names of files with the ARCHIVED
  19006.     attribute set?
  19007.  
  19008.  3. What does it mean when an application gives only the attribute
  19009.     parameter FILE_ARCHIVED to DosFindFirst()?
  19010.  
  19011.  Response:
  19012.  
  19013.  The following are answers to the questions above:
  19014.  
  19015.  1. Yes, you are correct. However, the explanation is usually more
  19016.     generalized: whenever a file is modified, the archive bit is set.
  19017.     This only happens when a file is opened and written to, or when a
  19018.     file is created.
  19019.  
  19020.  2. No, whenever DosFindFirst() and DosFindNext() search for files, all
  19021.     normal files, plus whichever other files have the attribute you are
  19022.     looking for, are returned. All you can do is check the attributes
  19023.     when you get a file returned from your DosFindFirst()/Next() call
  19024.     to see if any other attributes are set.
  19025.  
  19026.  3. When an application gives only the attribute parameter
  19027.     FILE_ARCHIVED to DosFindFirst(), you will get back all files that
  19028.     have the archive bit set, plus all normal files. You need to check
  19029.     the attribute byte of each file to see if it has the attribute bit
  19030.     set.
  19031.  
  19032.  
  19033.  
  19034.  583. OS/2 SDK: Determining If Math Coprocessor Is Present
  19035.  
  19036.  Question:
  19037.  
  19038.  Is there an API call for determining the presence of a math
  19039.  coprocessor?
  19040.  
  19041.  Response:
  19042.  
  19043.  Yes; the DosDevConfig() API call allows you to determine such things
  19044.  as number of printers attached, number of serial ports, number of
  19045.  floppy disk drives, presence of a coprocessor, and a few other machine
  19046.  configuration variables, depending on the type of information that you
  19047.  request. The following program demonstrates how to determine if a
  19048.  coprocessor is installed:
  19049.  
  19050.  #define INCL_BASE
  19051.  #include <os2.h>
  19052.  #include <stdio.h>
  19053.  
  19054.  void main(void);
  19055.  
  19056.  void main(void)
  19057.  
  19058.  {
  19059.      BYTE    fPresent;
  19060.      USHORT  usResult;
  19061.  
  19062.      usResult = DosDevConfig(&fPresent,DEVINFO_COPROCESSOR,0);
  19063.  
  19064.      if (usResult)
  19065.          printf("Error in DosDevConfig call: %u\n",usResult);
  19066.      else
  19067.          if (fPresent)
  19068.              printf("Coprocessor present.\n");
  19069.          else
  19070.              printf("No coprocessor present.\n");
  19071.  
  19072.  }
  19073.  
  19074.  
  19075.  584. Using Processor Extension Exist Subclass Vector
  19076.  
  19077.  Question:
  19078.  
  19079.  I am trying to provide an application with a VIO pop-up instead of
  19080.  the standard OS/2 Exception VIO pop-up for the
  19081.  "processor_extension_not_available" exception. I am using DosSetVec()
  19082.  to set up my own vector. I then put up my own VIO pop-up and pass
  19083.  control to the default vector returned in the DosSetVec() invocation.
  19084.  
  19085.  All works well in the application. However, when the first
  19086.  floating-point routine is called, this exception is taken. It appears
  19087.  by registering my own vector here; the first floating-point operation
  19088.  executed causes this exception itself. How can I cause the
  19089.  floating-point operations to be performed without this exception?
  19090.  
  19091.  Response:
  19092.  
  19093.  The behavior you are seeing when you use DosSetVec() to install your
  19094.  exception handler for the "processor_extension_not_available"
  19095.  exception is correct. Although the documentation is not very clear
  19096.  about this topic, the purpose of making this exception available to
  19097.  application programs is to allow them to install their own
  19098.  floating-point emulator even if a numeric coprocessor is installed in
  19099.  the system.
  19100.  
  19101.  As a result, every time a floating-point operation is executed after
  19102.  you install this handler, the exception will be taken because OS/2 has
  19103.  modified the MSW EM and MP bits to indicate "no coprocessor is
  19104.  present." Also, since access to the MSW is allowed only at privilege
  19105.  level 0, your application cannot change this behavior (because it runs
  19106.  at level 3).
  19107.  
  19108.  
  19109.  585. Installing CTRL+C and CTRL+BREAK Signal Handlers
  19110.  
  19111.  Question:
  19112.  
  19113.  How can different signal handlers be installed for CTRL+C and
  19114.  CTRL+BREAK signals? Whenever I attempt to install two signal handlers,
  19115.  the CTRL+C signal handler is invoked when either CTRL+C or CTRL+BREAK
  19116.  is generated from the keyboard.
  19117.  
  19118.  Response:
  19119.  
  19120.  You can never generate these two signals; the method of keyboard input
  19121.  (cooked or raw) is a factor in how they are read in.
  19122.  
  19123.  When keyboard input is in cooked mode, CTRL+C and CTRL+BREAK both
  19124.  generate a SIGINTR signal.
  19125.  
  19126.  When keyboard input is in raw mode, CTRL+C signals are not trapped and
  19127.  are read in via the keyboard input mechanism as the 0x03 character
  19128.  (and the 0x02E scan code). Therefore, in raw mode, you should check
  19129.  the key received by the keyboard input mechanism if you want to act on
  19130.  the CTRL+C character.
  19131.  
  19132.  If you require two different handlers to be available for these two
  19133.  different keystrokes, you should set up a CTRL+BREAK signal handler to
  19134.  intercept the CTRL+BREAK key and read keystrokes in raw mode looking
  19135.  for the CTRL+C key.
  19136.  
  19137.  
  19138.  586. Spawning a Full-Screen or Windowed Session
  19139.  
  19140.  Problem:
  19141.  
  19142.  From my application, I would like to give the user the ability to
  19143.  spawn off another session that will run a full-screen editor (in
  19144.  either a window or a full-screen mode). I tried to do this using
  19145.  DosCreateSession(), but I wasn't successful; I kept getting the return
  19146.  error code of 491 (ERROR_SMG_INVALID_PROGRAM_TYPE).
  19147.  
  19148.  Response:
  19149.  
  19150.  Use DosStartSession() instead of DosCreateSession(). The two APIs for
  19151.  executing an application are DosStartSession() and DosExecPgm(). The
  19152.  DosStartSession() API has more functionality, and it allows you to
  19153.  specify the type of executable you are trying to execute (e.g. full-
  19154.  screen, Presentation Manager, etc.). This information is stored in the
  19155.  "SessionType" field of the STARTDATA data structure used by
  19156.  DosStartSession(). The "SessionType" field, which determines what
  19157.  session type the program should be executed in, can have one of the
  19158.  following values:
  19159.  
  19160.     0  Let OS/2 or the STARTDATA.PgmHandle determine the session type.
  19161.     1  Full-screen VIO application in its own screen group.
  19162.     2  Windowable VIO application in a PM screen group.
  19163.     3  PM (or AVIO) application in a PM screen group.
  19164.  
  19165.  Because you want to execute a full-screen VIO application in its own
  19166.  screen group, you should set STARTDATA.SessionType equal to 1 when you
  19167.  use DosStartSession().
  19168.  
  19169.  Included below is a condensed version of the logic that CMD.EXE uses
  19170.  to determine which API to call when executing an application. CMD.EXE
  19171.  has to execute full-screen and windowable VIO applications, AVIO
  19172.  applications, and PM applications, from either a full-screen group or
  19173.  a PM screen group. CMD.EXE will use either DosExecPgm() or
  19174.  DosStartSession() to execute a program based on both of the following:
  19175.  
  19176.  1. What kind of executable the program to execute is [this information
  19177.     is obtained by reading the EXE header or by calling DosQAppType()]
  19178.  
  19179.  2. What kind of screen group is currently being run [this information
  19180.     is stored in DosGetInfoSeg()'s LINFOSEG.typeProcess]
  19181.  
  19182.  In summary, DosStartSession() is used to execute PM and AVIO
  19183.  applications. DosStartSession() is also used when CMD.EXE is running
  19184.  in a PM screen group and trying to execute a full-screen application;
  19185.  DosExecPgm() is used when executing VIO applications. The following
  19186.  table shows these relationships:
  19187.  
  19188.                           Windowable VIO
  19189.     Executable            (aka PM Screen)    Full-Screen VIO
  19190.     Type of File          Screen Group       Screen Group
  19191.     --------------------  -----------------  -----------------
  19192.  
  19193.     Full-Screen VIO       DosStartSession()  DosExecPgm()
  19194.     Windowable VIO        DosExecPgm()       DosExecPgm()
  19195.     Advanced VIO          DosStartSession()  DosStartSession()
  19196.     Presentation Manager  DosStartSession()  DosStartSession()
  19197.  
  19198.  
  19199.  587. WIN Memory Management Routine Information
  19200.  
  19201.  Question:
  19202.  
  19203.  Why were the WinCreateHeap() function and its associated WIN functions
  19204.  made into WIN functions rather than just base functions?
  19205.  
  19206.  Response:
  19207.  
  19208.  The Windows (WIN) memory management routines are APIs that were added
  19209.  by the Presentation Manager (PM) developers in the OS/2 development
  19210.  group. They were added because they are presumably faster in some
  19211.  areas than the base memory management routines.
  19212.  
  19213.  The WIN memory management routines should be used only by PM or AVIO
  19214.  applications. You must call WinInitialize() before you call
  19215.  WinCreateMsgQueue(). After these two calls are made, you can then
  19216.  begin using the WIN memory management APIs, starting with the
  19217.  WinCreateHeap() API. WinInitialize() must be called before any other
  19218.  WIN function is called. WinCreateMsgQueue() internally initializes
  19219.  some WIN memory management information, so it must be called before
  19220.  WinCreateHeap() (or any other GPI calls, for that matter) is called.
  19221.  
  19222.  
  19223.  588. DevHlp_Lock Return Handle Information
  19224.  
  19225.  Question:
  19226.  
  19227.  Is the lock handle returned from DevHlp_Lock just a 32-bit physical
  19228.  address? If it is an address, can it be passed across process
  19229.  contexts?
  19230.  
  19231.  Response:
  19232.  
  19233.  The handle returned by the DevHlp_Lock function is NOT a 32-bit
  19234.  physical address. It is a unique number used to identify that block of
  19235.  memory to the OS/2 memory manager. You must supply this handle to
  19236.  DevHlp_UnLock when you are done using the memory.
  19237.  
  19238.  To obtain a 32-bit physical address after using DevHlp_Lock, you must
  19239.  do a DevHlp_VirtToPhys. This will give you a fixed 32-bit address that
  19240.  can be used across process contexts. We strongly recommend that you
  19241.  also do a DevHlp_VerifyAccess in protected mode to confirm that the
  19242.  user has access to the memory segment in question before the
  19243.  DevHlp_Lock is done. All of this information is explained in the
  19244.  Microsoft OS/2 DDDK (Device Driver's Development Kit) Version 1.10
  19245.  documentation, and also in the book "Advanced OS/2 Programming," by
  19246.  Ray Duncan.
  19247.  
  19248.  
  19249.  589. Allocating Memory in One Thread & Freeing It in Another Thread
  19250.  
  19251.  Question:
  19252.  
  19253.  Can you allocate memory in one thread and free it in another thread?
  19254.  The QuickHelp documentation under the "Heap Management Overview"
  19255.  implies that different threads can't share a heap.
  19256.  
  19257.  Response:
  19258.  
  19259.  Yes, you can allocate memory in one thread and free it in another
  19260.  thread. Threads are both part of a single process, and the memory is
  19261.  owned by the process, not the thread. However, you have to make sure
  19262.  that your threads cooperate with these "global" resources. If one
  19263.  thread tries to free up memory that another thread is using, then your
  19264.  code will not function properly. Because potential problems may occur,
  19265.  applications that don't need to commonly allocate and free memory in
  19266.  different threads should not do so, and the applications should
  19267.  instead allocate and free the memory in a single place; this avoids
  19268.  potential contention problems within threads. However, a properly
  19269.  designed application whose threads properly cooperate should have no
  19270.  problem commonly allocating and freeing memory.
  19271.  
  19272.  Also, consider that many threads allocate memory for their own stack
  19273.  and local variables. This memory, while actually not owned by any one
  19274.  thread, is generally considered to be off limits by other threads.
  19275.  
  19276.  
  19277.  590. Caller's Process Context Information
  19278.  
  19279.  Question:
  19280.  
  19281.  We have a device driver whose primary scheduling is off of the threads
  19282.  that started up the process; this is how our device driver (which
  19283.  requires a lot of asynchronous scheduling capability) gets its
  19284.  timeslice independent of any calling user threads. When the user
  19285.  threads call our strategy routine with IOCTLs and the like, are we
  19286.  running in the caller's process context? Hence, when the threads
  19287.  awaken, is it considered a separate process context?
  19288.  
  19289.  Response:
  19290.  
  19291.  When an application (user thread) calls a device driver [through OS/2
  19292.  via DosDevIOCtl(), DosRead(), DosWrite(), etc.], the strategy routine
  19293.  runs in that user thread's context. This means that the strategy
  19294.  routine is on the user thread's kernel stack, and in the user thread's
  19295.  LDT (local descriptor table). These values will be unique for every
  19296.  thread that invokes the device driver. Thus, the device driver does
  19297.  run in the calling thread's process context when it is entered; this
  19298.  is different from any other process's context that may have previously
  19299.  called your device driver.
  19300.  
  19301.  
  19302.  591. Trying to Predict Dynamic Linked Library Initialization Order
  19303.  
  19304.  Problem:
  19305.  
  19306.  Is there any way to predict the initialization order of DLLs (dynamic
  19307.  linked libraries)? I have a DLL that, as part of doing its
  19308.  initialization routine, needs to call another DLL. However, the second
  19309.  DLL needs to perform some housekeeping code when it gets initialized.
  19310.  As it stands now, the second DLL has not been initialized before I
  19311.  call it, and consequently it doesn't load correctly. How can I correct
  19312.  this problem?
  19313.  
  19314.  Response:
  19315.  
  19316.  There is no reliable, portable way for OS/2 to guarantee the load
  19317.  order or the initialization order of a DLL when an application has
  19318.  multiple DLLs.
  19319.  
  19320.  One method of reliably determining the way DLLs are used is to use an
  19321.  initialization mechanism similar to the one that PM (Presentation
  19322.  Manager) uses. PM has a specific initialization function in each DLL
  19323.  [for example, something such as WinInitDLL() for PMWIN.DLL and
  19324.  GreInitDLL() for PMGRE.DLL]. The application controlling the DLLs and
  19325.  requiring some specific loader order should call into the
  19326.  initialization functions explicitly in the order that they require.
  19327.  
  19328.  Another method of reliably determining the way DLLs are used is to
  19329.  explicitly call them yourself via DosLoadModule(), rather than by
  19330.  letting the EXE loader implicitly load the DLLs for you. In this way,
  19331.  you'll know that a certain DLL will be called before another, since
  19332.  your application called them in that order.
  19333.  
  19334.  One other method that you could use is to modify the initialization
  19335.  routines of the DLLs so that one calls the other; this will ensure
  19336.  that the second one is loaded properly. This is rather reverse logic:
  19337.  the first DLL calls the second one, which ensures that the second one
  19338.  is fully loaded. This is rather like the first DLL making sure that
  19339.  the second one is loaded first, but in reverse order. This sort of
  19340.  calling sequence will help lock your dependencies between the DLLs,
  19341.  and will enforce that the DLLs are loaded/initialized in ways that you
  19342.  can depend on.
  19343.  
  19344.  The first method (PM initialization mechanism) is the cleanest method,
  19345.  but you may use any of the methods described above.
  19346.  
  19347.  
  19348.  592. DosExit() Terminates Parent Before Child Processes Are Done
  19349.  
  19350.  When the DosExit() system function is called, it waits for all of the
  19351.  child processes to terminate before terminating the parent [which
  19352.  called DosExit()]. The DosStartSession() function can be used to start
  19353.  a completely independent process that no longer is affected by
  19354.  anything the parent process does [including the use of DosExit()].
  19355.  
  19356.  
  19357.  593. Exitlist Routines Are Run If GP Fault Occurs in Main Program
  19358.  
  19359.  Exitlist routines are run if a GP fault occurs in the main program. If
  19360.  the GP fault occurs in the exitlist routine, the exitlist routine will
  19361.  not be run again.
  19362.  
  19363.  The following sample program demonstrates that exitlist routines are
  19364.  run if a GP fault occurs in the main program:
  19365.  
  19366.  /* gp.c - compile "cl gp.c" */
  19367.  
  19368.  #define INCL_BASE
  19369.  
  19370.  #include <os2.h>
  19371.  #include <stdio.h>
  19372.  #include <conio.h>
  19373.  #include <io.h>
  19374.  
  19375.  void pascal far CleanUp(USHORT arg);
  19376.  void main(void);
  19377.  
  19378.  void main(void)
  19379.  {
  19380.     char c;
  19381.  
  19382.     DosExitList(EXLST_ADD, CleanUp);
  19383.  
  19384.     printf("\nstrike a key to continue...");
  19385.     getch();
  19386.     puts("");
  19387.  
  19388.     printf("\n generate a protection violation...\n");
  19389.     c = *((char far *)0xb8000);
  19390.     printf("\n code after protection violation...\n");
  19391.  
  19392.     DosExit(EXIT_PROCESS, 0);
  19393.  }
  19394.  
  19395.  void pascal far CleanUp(USHORT arg)
  19396.  {
  19397.  
  19398.     switch (arg) {
  19399.  
  19400.        case TC_EXIT:
  19401.           VioWrtTTY("\n\rThis process terminated normally...\n\r\n",
  19402.                      40, 0);
  19403.           break;
  19404.  
  19405.        case TC_TRAP:
  19406.           VioWrtTTY("\n\rThis process was terminated by a trap...
  19407.                      \n\r\n", 45, 0);
  19408.           break;
  19409.  
  19410.        case TC_HARDERROR:
  19411.           VioWrtTTY("\n\rThis process was aborted from a hard error
  19412.                     ...\n\r\n", 50, 0);
  19413.           break;
  19414.  
  19415.        case TC_KILLPROCESS:
  19416.           VioWrtTTY("\n\rThis process was killed by a signal...
  19417.                     \n\r\n", 43, 0);
  19418.           break;
  19419.     }
  19420.  
  19421.        DosExitList(EXLST_EXIT,0L);         /* Termination complete */
  19422.  }
  19423.  
  19424.  
  19425.  594. Different Software Methods That Can Be Used to Reboot OS/2
  19426.  
  19427.  In the Software/Data Library is an archived file named REBOOT that
  19428.  contains two different methods of rebooting a system running OS/2.
  19429.  This file can be found in the Software/Data Library by searching on
  19430.  the keyword REBOOT, the Q number of this article, or S12362. REBOOT
  19431.  was archived using the PKware file-compression utility.
  19432.  
  19433.  REBOOT contains the following files:
  19434.  
  19435.     BOOTDD
  19436.     BOOTDD.ASM
  19437.     BOOTDD.DEF
  19438.     BOOTDD.SYS
  19439.     REBOOT.C
  19440.     REBOOT.EXE
  19441.  
  19442.     RB8042
  19443.     RB8042.ASM
  19444.     RB8042.DEF
  19445.     RB8042.EXE
  19446.  
  19447.  How to Reboot the System Using a Device Driver
  19448.  ----------------------------------------------
  19449.  
  19450.  You can reboot the system using a device driver, which can call the
  19451.  DevHlp GetDOSVar() (Service 24H), using index 05H to retrieve the
  19452.  DWORD reboot vector. After obtaining this information, the device
  19453.  driver can then reboot the system. Included in REBOOT is a sample
  19454.  device driver (named "REBOOT$") that does this. A sample application
  19455.  is also included in REBOOT that calls this sample device driver. The
  19456.  sample program performs a DosOpen() on the device driver "REBOOT$",
  19457.  and then sends it an IOCtl (category 80H, function 41H) via
  19458.  DosDevIOCtl(), which causes the system to reboot.
  19459.  
  19460.  For more information on writing device drivers, refer to the
  19461.  "Microsoft OS/2 Device Driver Reference."
  19462.  
  19463.  How to Reboot the System Using the Keyboard Controller
  19464.  ------------------------------------------------------
  19465.  
  19466.  You can reboot the system using the keyboard controller by having an
  19467.  application running at ring 2 (IOPL) that sends the data to the 8042
  19468.  Keyboard Controller to pulse the system reset pin. This can be
  19469.  accomplished by sending the value 0x00FE to the port address 0x64.
  19470.  After you have sent this value, a "cold boot" will occur. Included in
  19471.  REBOOT is an application that will accomplish this. Please note that
  19472.  this method will NOT work on any system that doesn't use an 8042
  19473.  Keyboard Controller. In addition, this method may not work in future
  19474.  releases of OS/2. If an OS/2 release specific to the 80386 is ever
  19475.  released, the operating system will be able to control access to
  19476.  ports, preventing a rogue application from rebooting the system.
  19477.  
  19478.  For more information on writing applications, refer to the "Microsoft
  19479.  OS/2 Programmer's Reference" manuals (three volumes). For more
  19480.  information about hardware (such as the keyboard hardware), refer to
  19481.  your system's hardware technical reference.
  19482.  
  19483.  Conclusion
  19484.  ----------
  19485.  
  19486.  In summary, the device driver method is more portable than the 8042
  19487.  Keyboard Controller method, since the device driver asks OS/2 for the
  19488.  location to jump to in order to reset the system. The Keyboard
  19489.  Controller method assumes that particular 8042 hardware exists, and
  19490.  may not work in future releases of OS/2 if access to certain I/O ports
  19491.  are considered off limits to IOPL applications. If any ports would be
  19492.  considered off limits, it would most likely be dangerous ports, such
  19493.  as this one, that allow applications to reset the system.
  19494.  
  19495.  Of course, you should be aware that rebooting a multitasking operating
  19496.  system is not a wise thing to do, because unlike in MS-DOS, your
  19497.  application is not the only program running on the system. We do not
  19498.  recommend that any normal application reboot the system. We recommend
  19499.  that any application that does reboot the system should give you ample
  19500.  notice to properly terminate all other active processes running in the
  19501.  system.
  19502.  
  19503.  
  19504.  595. PS/2 Profiler in OS/2 SDK 1.10 Only Works with PMSHELL
  19505.  
  19506.  Under the PS/2 kernel running the pinfo (profiler) utility with a
  19507.  dumpfile, will show the name of PMSHELL, (or PMEXEC), instead of the
  19508.  test application name. When running pinfo with a dumpfile and a map
  19509.  file, the error "Ignored: No segments for module XXX" occurs. Running
  19510.  the same series of commands on the AT profile kernel works correctly.
  19511.  
  19512.  Microsoft has confirmed this to be a problem with the Profiler
  19513.  included with the OS/2 SDK (Software Development Kit) Version 1.10. We
  19514.  are researching this problem and will post new information as it
  19515.  becomes available.
  19516.  
  19517.  
  19518.  596. Translating DosDevIOCtl() OS/2 Calls to MS-DOS Calls
  19519.  
  19520.  Question:
  19521.  
  19522.  I have some questions about the portability of applications from one
  19523.  operating system to another operating system. Specifically, are the
  19524.  OS/2 DosDevIOCtl() functions for the COM driver supported by the
  19525.  MS-DOS COM driver? If not, then we need to make a MS-DOS driver that
  19526.  does support these functions, but where do we pass the parameters
  19527.  buffer? Also, please provide us with a full description of the IOCtl
  19528.  function supported by the MS-DOS COM driver.
  19529.  
  19530.  Response:
  19531.  
  19532.  The MS-DOS support for the serial ports is very minimal. Most work
  19533.  with the ports (via the Mode command) is done through the BIOS. When
  19534.  MS-DOS is reading from the port, it calls the device driver READ
  19535.  function and does similar things for WRITE.
  19536.  
  19537.  When you use the DosDevIOCtl() calls from OS/2 in a bound program, the
  19538.  DevIOCtl calls just turn the call into Interrupt 21, Function 44H
  19539.  calls.
  19540.  
  19541.  All parameters are passed, including the parameter packet. The
  19542.  following is a list of how the parts of the call are transferred from
  19543.  OS/2 to MS-DOS via the API.LIB library:
  19544.  
  19545.        AH = 44H
  19546.        AL = 0CH (handle IOCtls)
  19547.        BX = Device handle (hDevice)
  19548.        CH = Serial Category (0x0001)
  19549.        CL = Function Code
  19550.     DS:DX = Pointer to data buffer
  19551.     SI:DI = Pointer to parameter packet
  19552.  
  19553.  The current device driver does not look for the parameter packet, but
  19554.  you can write a device driver to do this.
  19555.  
  19556.  When the DosDevIOCtl() is passed through to MS-DOS via the generic
  19557.  IOCtl call, no parameters are checked. Therefore, any call that is not
  19558.  supported by MS-DOS or the device driver will get passed onto the
  19559.  driver. You should make sure that in your driver you have an escape
  19560.  clause for all generic IOCtls that are called that you don't support.
  19561.  
  19562.  
  19563.  597. Per-Process File Handle Limit Increased in OS/2 SDK 1.10
  19564.  
  19565.  Question:
  19566.  
  19567.  What is the maximum number of file handles allowed, and how is that
  19568.  maximum reached? On page 142 of the "Microsoft Operating System/2
  19569.  Programmer's Reference Volume 3 for Version 1.1," it states that
  19570.  DosSetMaxFH() limits the maximum number of file handles to 255 that
  19571.  can be provided to the calling process. Is this correct for OS/2
  19572.  Version 1.10?
  19573.  
  19574.  Response:
  19575.  
  19576.  No; this is a documentation error in both the "Microsoft Operating
  19577.  System/2 Programmer's Reference Volume 3 for Version 1.1" manual, and
  19578.  in the version of QuickHelp included with the OS/2 SDK (Software
  19579.  Development Kit) Version 1.10. This limit was correct for OS/2 Version
  19580.  1.00, but it is not correct for OS/2 Version 1.10. The limit of file
  19581.  handles in OS/2 Version 1.10 is 32K of file handles per system, with a
  19582.  per-process limit of 32K. Please note that since the per-system limit
  19583.  is the same as the per-process limit, and this is a multi-process
  19584.  operating system, it is doubtful that a single process will max out on
  19585.  all of the file handles, since some of them will be in use by other
  19586.  processes. The number of file handles per process by default is 20,
  19587.  with three file handles being automatically allocated to stdin,
  19588.  stdout, and stderr. For a process to open more than 20 file handles,
  19589.  the application must call the OS/2 API DosSetMaxFH().
  19590.  
  19591.  In contrast, the limit of file handles in MS-DOS Versions 3.30 and
  19592.  later is 64K per process, but with a system limit of 255 (the maximum
  19593.  value of the unsigned byte of FILES=nnn). Thus, while a single process
  19594.  can open 64K files, there are only 255 for the whole system to work
  19595.  with, so that the system can only have 255 unique files open at once
  19596.  but a process can open 64K duplicate handles to the same file. When
  19597.  SHARE is not loaded, the number of FCBs is limited only by the user's
  19598.  memory, which is itself under the 640K system limit. The number of
  19599.  file handles per process by default is 20, with five file handles
  19600.  being allocated automatically to stdin, stdout, stderr, stdaux, and
  19601.  stdprn. For a process to open more than 20 file handles, the
  19602.  application must call the MS-DOS service Interrupt 21H, AH=67H, the
  19603.  MS-DOS equivalent to the OS/2 DosSetMaxFH() function call.
  19604.  
  19605.  We will post new information when the documentation has been updated
  19606.  to correct this error.
  19607.  
  19608.  
  19609.  598. Coprocessor State of 80x87 Is on a Per-Process Basis
  19610.  
  19611.  Question:
  19612.  
  19613.  Does each thread in the system maintain its own 80x87 state if a
  19614.  coprocessor is present?
  19615.  
  19616.  Response:
  19617.  
  19618.  No, the coprocessor state of the 80x87 is kept track of on a
  19619.  per-process basis by OS/2. The coprocessor can be thought of as a
  19620.  resource; threads cannot own resources, only use them.
  19621.  
  19622.  
  19623.  599. Path Information of Critical Files Necessary for OS/2 Boot
  19624.  
  19625.  Question:
  19626.  
  19627.  Can you please provide us with a list of the files that must be on
  19628.  specified paths to assure system integrity during boot time? For
  19629.  example, does OS/2 look for PMWIN.DLL on DPATH, LIBPATH, or elsewhere?
  19630.  
  19631.  Response:
  19632.  
  19633.  When OS/2 boots, it needs OS2KRNL, OS2LDR, and the base (keyboard,
  19634.  video, disk, etc.) device drivers in the root directory. After that,
  19635.  OS/2 uses the LIBPATH variable to find DLLs, and the PATH directory to
  19636.  find any executable that it needs to run, if the executable is not
  19637.  found in the current directory. Any installable device drivers are
  19638.  loaded without any need for environment variables, and the
  19639.  command-line editor (usually CMD.EXE) is obtained via the COMSPEC
  19640.  environment variable. If the compatibility box is enabled, then the
  19641.  COMSPEC variable is set in AUTOEXEC.BAT to the location of
  19642.  COMMAND.COM. Otherwise, no other environment variables are used.
  19643.  
  19644.  
  19645.  600. 3.x Box Programming Limitations
  19646.  
  19647.  Listed below is some general information on the 3.x box of OS/2,
  19648.  including programming limitations under the OS/2 compatibility box and
  19649.  which BIOS and Interrupt calls are (not) allowed.
  19650.  
  19651.  Restrictions
  19652.  ------------
  19653.  
  19654.   1. The environment is that of MS-DOS Version 3.20 with SHARE installed.
  19655.  
  19656.   2. The MS-DOS 3.x network redirector will not work. New functionality
  19657.      is provided through the OS/2 LAN Manager.
  19658.  
  19659.   3. The 3.x box is frozen in the background (may lose interrupts for
  19660.      3.x box).
  19661.  
  19662.   4. Only old character device drivers can be used, and these may not
  19663.      issue INT 21H calls at initialization time.
  19664.  
  19665.   5. INT 13H and INT 26H may not access a hard disk.
  19666.  
  19667.   6. INT 2FH, the print spooler interrupt, returns with the error "Print
  19668.      spooler not installed, not OK to install." [INT 2F with (AL)= 0,
  19669.      Get installed state, returns with (AL)=1.]
  19670.  
  19671.   7. No direct calls to ROM services can be made (must use INT 10-1F).
  19672.  
  19673.   8. No calls can be made to user code from device drivers.
  19674.  
  19675.   9. No 3.x print spooler is allowed.
  19676.  
  19677.  10. No application may move the 8259 interrupt vectors.
  19678.  
  19679.  Device Drivers
  19680.  --------------
  19681.  
  19682.  Most device drivers in OS/2 are "new" model device drivers. These
  19683.  drivers are loaded as new-EXE modules, and the code is dual-mode so
  19684.  that they can handle interrupts in either real mode (RM) or protected
  19685.  mode (PTM). The drivers contain some RM code to support/manage the ROM
  19686.  Services interrupts that pertain to the device that the driver
  19687.  manages.
  19688.  
  19689.  The 3.x box has its own console driver (CON), which is separate from
  19690.  any PRM support, and thus may be replaced (by ANSI.SYS, for example).
  19691.  
  19692.  Please note that RM device drivers cannot issue INT 21H calls.
  19693.  
  19694.  The ROM BIOS performs programmed I/O, which is not acceptable in a
  19695.  multitasking operating system. Therefore, those ROM BIOS services
  19696.  that can take an appreciable amount of time to complete are emulated
  19697.  by the OS/2 device driver responsible for the appropriate device.
  19698.  
  19699.  The device drivers maintain those areas of the ROM Data Area
  19700.  (40:0-...) that relate to the device they service. They do all updates
  19701.  that are required at interrupt time, and they do updates for those ROM
  19702.  BIOS services that they emulate.
  19703.  
  19704.  Interrupt Management
  19705.  --------------------
  19706.  
  19707.  1. Hardware interrupts
  19708.  
  19709.     a. Master 8259 generates interrupts in the 50-57H range (as opposed
  19710.        to the default of 8-FH). The handlers at 50-57H route to the
  19711.        handlers at 8-FH.
  19712.  
  19713.     b. Slave 8259 generates interrupts in the 70-77H range, as usual.
  19714.  
  19715.     c. The Interrupt Manager checks for direct editing of interrupt
  19716.        vectors. Except for the keyboard interrupt, the 3.x box may only
  19717.        set a vector if it is not owned by a new device driver, and vice
  19718.        versa.
  19719.  
  19720.  2. Software interrupts
  19721.  
  19722.     OS/2 hooks the same vectors as in MS-DOS Version 3.20. It does not
  19723.     interfere with other software interrupt vectors.
  19724.  
  19725.  MS-DOS 3.x API Support
  19726.  ----------------------
  19727.  
  19728.  1. All INT 21H system calls documented in the references are
  19729.     supported. However, the file system acts as if SHARE is installed.
  19730.  
  19731.  2. INT 2FH, the print spooler interrupt, returns with the error "Print
  19732.     spooler not installed, not OK to install." [INT 2F with (AL)=0, Get
  19733.     installed state, returns with (AL)=1.]
  19734.  
  19735.  3. INT 24H, the hard error interrupt, is ignored. Real-mode
  19736.     applications may set this interrupt, but OS/2 never calls the
  19737.     application's handler.
  19738.  
  19739.  Interrupt Usage
  19740.  ---------------
  19741.  
  19742.  Vector   Usage                     Comments
  19743.  ------   -----                     --------
  19744.  
  19745.   0       Divide error
  19746.  
  19747.   1       Single step
  19748.  
  19749.   2       NMI
  19750.  
  19751.   3       Breakpoint
  19752.  
  19753.   4       INTO
  19754.  
  19755.   5       PrtSc
  19756.  
  19757.   6       Invalid opcode
  19758.  
  19759.   7       287 not present
  19760.  
  19761.   8-F     IRQ 0-7 jump table        Address of actual handlers.
  19762.                                     Master 8259 is moved to 50-57
  19763.                                     range so that chip faults can
  19764.                                     be differentiated from hardware
  19765.                                     interrupts when in protected
  19766.                                     mode. Also permits OS/2 to
  19767.                                     detect direct editing of these
  19768.                                     vectors.
  19769.  
  19770.  10       Screen                    OS/2 chains to track EGA
  19771.                                     write-only registers.
  19772.  11       Equipment
  19773.  
  19774.  12       Memory                    ROM Data area value changed by
  19775.                                     SysInit.
  19776.  
  19777.  13       Disk                      OS/2 chains to interlock disk
  19778.                                     access. Writes to hard disks are
  19779.                                     not allowed.
  19780.  
  19781.  14       Serial                    If the COM driver is loaded, it
  19782.                                     emulates to provide interrupt
  19783.                                     driven I/O.
  19784.  
  19785.  15       Misc
  19786.  
  19787.  16       Keyboard                  KBD driver checks for hotkey,
  19788.                                     blocks if no characters are
  19789.                                     available, else it passes on to
  19790.                                     the ROM.
  19791.  
  19792.  17       Printer                   PRT driver emulates.
  19793.  
  19794.  18       ROM BASIC
  19795.  
  19796.  19       Reboot
  19797.  
  19798.  1A       Time/date
  19799.  
  19800.  1B       CTRL+BREAK                KBD issues this on CTRL+BREAK.
  19801.  
  19802.  1C       User Timer                OS/2 IRQ 0 handler issues this.
  19803.  
  19804.  1D       Screen data
  19805.  
  19806.  1E       Floppy data               Maintained by disk driver code.
  19807.  
  19808.  1F       Screen font data
  19809.  
  19810.  20       DOS abort
  19811.  
  19812.  21       DOS functions
  19813.  
  19814.  22       DOS terminate addr
  19815.  
  19816.  23       CTRL+C handler
  19817.  
  19818.  24       Hard error handler        OS/2 never issues this.
  19819.  
  19820.  25       Abs disk read
  19821.  
  19822.  26       Abs disk write            Not allowed to hard disks.
  19823.  
  19824.  27       TSR
  19825.  
  19826.  28-29    DOS reserved - unused
  19827.  
  19828.  2A       IBM network
  19829.  
  19830.  2B-2E    DOS reserved - unused
  19831.  
  19832.  2F       Multiplex channels
  19833.  
  19834.  30-31    CALL 5 mechanism
  19835.  
  19836.  32       DOS reserved - unused
  19837.  
  19838.  33       MOUSE services
  19839.  
  19840.  34-38    DOS reserved - unused
  19841.  
  19842.  39-3E    BASIC or unused
  19843.  
  19844.  3F       Windows thunk loader
  19845.  
  19846.  40       BIOS hard/floppy hook
  19847.  
  19848.  41       First hard disk data
  19849.  
  19850.  42       BIOS INT 10 EGA hook
  19851.  
  19852.  43       EGA data
  19853.  
  19854.  44       EGA font
  19855.  
  19856.  45       Unused
  19857.  
  19858.  46       Second hard disk data
  19859.  
  19860.  47-4F    Unused
  19861.  
  19862.  50       IRQ 0 - timer             OS/2 receives interrupts for IRQ
  19863.  51       IRQ 1 - keyboard          0-7 in the 50-57 range. After
  19864.  52       IRQ 2 - mouse/NET/...     checking for direct editing of
  19865.  53       IRQ 3 - COM2/...          the INT 8-F vectors, it CALLS
  19866.  54       IRQ 4 - COM1/...          indirectly through those vectors.
  19867.  55       IRQ 5 - mouse/NET/...
  19868.  56       IRQ 6 - floppy
  19869.  57       IRQ 7 - printer
  19870.  
  19871.  58-5B    Unused
  19872.  
  19873.  5C       ROM BIOS Network
  19874.  
  19875.  5D-66    Unused
  19876.  
  19877.  67       EMM device driver
  19878.  
  19879.  68-6F    Unused
  19880.  
  19881.  70       IRQ 8 - real-time clock
  19882.  
  19883.  71       IRQ 9
  19884.  
  19885.  72       IRQ A
  19886.  
  19887.  73       IRQ B
  19888.  
  19889.  74       IRQ C
  19890.  
  19891.  75       IRQ D - 80287
  19892.  
  19893.  76       IRQ E - hard disk
  19894.  
  19895.  77       IRQ F
  19896.  
  19897.  78-FF    Unused
  19898.  
  19899.  For more information on this topic, please refer to the "Microsoft
  19900.  Operating System/2 Programmer's Reference" manuals (3 volumes), and
  19901.  the "Microsoft Operating System/2 Device Driver Guide."
  19902.  
  19903.  
  19904.  601. DEVINFO_SUBMODEL (Item) Parameter of DosDevConfig()
  19905.  
  19906.  Question:
  19907.  
  19908.  What is the DEVINFO_SUBMODEL (item) parameter of the DosDevConfig()
  19909.  function call defined to be?
  19910.  
  19911.  Response:
  19912.  
  19913.  Listed below are the particulars concerning the "item" parameter in
  19914.  the OS/2 DosDevConfig() function call:
  19915.  
  19916.     Item #      Information Returned
  19917.     ------      --------------------
  19918.  
  19919.     0           Number of attached printer ports
  19920.  
  19921.     1           Number of RS232 ports
  19922.  
  19923.     2           Number of removable disk (floppy) drives
  19924.  
  19925.     3           Math coprocessor presence:
  19926.                 0 - not present, 1 - present
  19927.  
  19928.     4           PC (ROM BIOS) submodel code
  19929.  
  19930.     5           PC (ROM BIOS) model code
  19931.  
  19932.                 Model Code  Submodel Code  Machine Type
  19933.                 ----------  -------------  ------------
  19934.  
  19935.                 FCH         0 or 1         PC/AT
  19936.                 FCH         2              PC/XT-286
  19937.                 FAH         0              PS/2 model 30
  19938.                 FCH         4              PS/2 model 50
  19939.                 FCH         5              PS/2 model 60
  19940.                 F8H         0 or 1         PS/2 model 80
  19941.  
  19942.     6           Primary display adapter type:
  19943.                 0 - monochrome, 1 - other
  19944.  
  19945.  Please note that the PC model/submodel codes come from the machine's
  19946.  ROM BIOS and are therefore OEM hardware-dependent. The validity of
  19947.  these codes is a hardware compatibility issue, since the codes were
  19948.  originated by IBM each time they came out with a new machine (not all
  19949.  machines/codes are listed above, since they don't apply to OS/2).
  19950.  
  19951.  
  19952.  602. QuickHelp -t Option Broken in Versions 1.06 and 1.10
  19953.  
  19954.  When you specify the -t option, QuickHelp does not display its window.
  19955.  Instead, it searches for the topic specified on the command line,
  19956.  pastes the topic to the current paste file, and then exits.
  19957.  
  19958.  You should be able to copy either the entire topic of an OS/2
  19959.  function into the paste file, or just the syntax or example sections
  19960.  of that topic, depending on what you specify on the command line. For
  19961.  example, if you type the following, QuickHelp should find and copy the
  19962.  entire DosBeep() topic and paste it into the current paste file:
  19963.  
  19964.     qh DosBeep -t all
  19965.  
  19966.  Similarly, if you type
  19967.  
  19968.     qh DosBeep -t syntax
  19969.  
  19970.  or
  19971.  
  19972.     qh DosBeep -t example
  19973.  
  19974.  QuickHelp should find and copy just the syntax or example section of
  19975.  the DosBeep() topic, and then paste it into the current paste file.
  19976.  
  19977.  Microsoft has confirmed that in Version 1.39 of QuickHelp that was
  19978.  released with Version 1.10 of the OS/2 SDK (Software Development Kit),
  19979.  and in Version 1.40 of QuickHelp that was released with Version 1.10
  19980.  of the OS/2 Presentation Manager Toolkit, the -t switch does not copy
  19981.  and paste just the syntax or example section of a topic. If you
  19982.  specify "-t syntax" or "-t example" at the command line, QuickHelp
  19983.  responds with a message box that contains either "Syntax section not
  19984.  found in <Topicname>" or "Example section not found in <Topicname>."
  19985.  We are researching this problem and will post new information as it
  19986.  becomes available.
  19987.  
  19988.  
  19989.  603. Retrieving Description Information from .EXE Header
  19990.  
  19991.  Question:
  19992.  
  19993.  If an .EXE file is built using a .DEF file that contains a
  19994.  DESCRIPTION directive, is there a way to retrieve that description
  19995.  from the .EXE file (e.g. is there a field in the EXE header that
  19996.  indicates where the description is stored)?
  19997.  
  19998.  Response:
  19999.  
  20000.  The description can be found by checking the following location:
  20001.  
  20002.  The offset to the nonresident names table is located at offset 2CH
  20003.  relative to the start of the file. The first entry in the nonresident
  20004.  names table is either the description string (if defined in the .DEF
  20005.  file) or the name of the file.
  20006.  
  20007.  For more information, see Pages 720-725 in Ray Duncan's "Advanced OS/2
  20008.  Programming" book.
  20009.  
  20010.  
  20011.  604. Format Incorrectly Works with SUBSTituted Drives
  20012.  
  20013.  If you execute "FORMAT A:", after executing "SUBST A: D:\" in the 3.x
  20014.  box, Drive D is still formatted. Drive D is an extended MS-DOS
  20015.  partition on a hard disk. The FORMAT command should reject the D
  20016.  drive, instead of going ahead with the format.
  20017.  
  20018.  This is not appropriate behavior for the FORMAT command, it should not
  20019.  be used with drives involved in a substitution (SUBST).
  20020.  
  20021.  Microsoft has confirmed this to be a problem in the OS/2 SDK (Software
  20022.  Development Kit) Version 1.10. We are researching this problem and
  20023.  will post new information as it becomes available.
  20024.  
  20025.  
  20026.  605. Starting OS/2 in Full-Screen CMD Line Mode from STARTUP.CMD
  20027.  
  20028.  Question:
  20029.  
  20030.  How do I start the OS/2 full screen CMD line mode from STARTUP.CMD and
  20031.  also from under program control? I do not want to start a new session;
  20032.  rather, I want OS/2 to be the only icon up, and to then run an
  20033.  AUTOEXEC.CMD file.
  20034.  
  20035.  Response:
  20036.  
  20037.  Use the START command. This command allows you to start new commands.
  20038.  It allows you to specify which screen group (SG) to use: a full-screen
  20039.  SG for VIO applications, or the Presentation Manager SG for windowable
  20040.  VIO, AVIO, or Presentation Manager applications. In addition, you can
  20041.  specify whether the application is placed in the foreground or
  20042.  background. When running an application in the Presentation Manager
  20043.  SG, "foreground" means that this application is the window with the
  20044.  focus; when running a full-screen application, "foreground" means that
  20045.  this SG is the currently selected SG.
  20046.  
  20047.  Thus, you could have one or more START commands in your STARTUP.CMD
  20048.  file, starting various applications in various screen groups.
  20049.  
  20050.  If you want to start the OS/2 full-screen CMD line mode from
  20051.  STARTUP.CMD, you can create the file STARTUP.CMD as follows:
  20052.  
  20053.     start /fs
  20054.     rem ... other STARTUP.CMD things should be added here ...
  20055.     exit
  20056.  
  20057.  The first line creates a full-screen CMD session. STARTUP.CMD
  20058.  continues to complete its other actions, then exits, leaving only this
  20059.  new CMD.EXE running. If you would rather see all the commands in
  20060.  STARTUP.CMD running in the full-screen session, rather than hidden in
  20061.  the windowed STARTUP.CMD session, you could have a STARTUP.CMD file
  20062.  similar to the one listed below:
  20063.  
  20064.     start /fs c:\AUTOEXEC.CMD
  20065.     exit
  20066.  
  20067.  Then, edit your AUTOEXEC.CMD file to contain the following:
  20068.  
  20069.     rem ... other STARTUP.CMD things should be added here ...
  20070.  
  20071.  Thus, STARTUP.CMD would start a full-screen CMD.EXE session,
  20072.  which will then continue to initialize your system (start the network,
  20073.  etc.). If you want it to go away when the initialization is done, you
  20074.  can specify the appropriate START switch, or you can call EXIT at the
  20075.  end of the .CMD file.
  20076.  
  20077.  However, there isn't a way to specify that STARTUP.CMD be run full
  20078.  screen rather than windowed. There isn't a configuration to change the
  20079.  way in which STARTUP.CMD is run. Also, if you don't like windowed CMD
  20080.  prompts, you can go into the Start Programs window, select "Windows
  20081.  command prompt," then select Program Change. At this point, you can
  20082.  change this so that it will start full screen, rather than in a VIO
  20083.  window. Better yet, if you don't like windowed CMD.EXE prompts, you
  20084.  can select this item, then select the menu item Program Delete,
  20085.  removing this from your Start Programs window altogether.
  20086.  
  20087.  Please refer to the Microsoft OS/2 Version 1.10 user's documentation
  20088.  for more information on the START command and the STARTUP.CMD file.
  20089.  
  20090.  Or, if you want to start the OS/2 full-screen CMD line mode under
  20091.  program control, write a program that controls the execution of
  20092.  sessions. You can do this by using DosStartSession(). The STARTDATA
  20093.  data structure used by DosStartSession() should have the parameter
  20094.  FbBg set to TRUE, and SessionType should be set to 1, meaning that the
  20095.  program should be run full screen. If the PgmName parameter in the
  20096.  STARTDATA structure is set to NULL, then CMD.EXE (or whatever the
  20097.  default PROTSHELL is) will be run.
  20098.  
  20099.  Please refer to the QuickHelp database as well as the "Microsoft
  20100.  Operating System/2 Programmer's Reference" (Volumes 1 and 3) for more
  20101.  information on DosStartSession() and the STARTDATA data structure.
  20102.  
  20103.  
  20104.  606. EXTPROC Incorrectly Duplicates Script Extension to Shell
  20105.  
  20106.  There is a problem with the OS/2 Version 1.10 EXTPROC command, which
  20107.  is an internal command of CMD.EXE.
  20108.  
  20109.  Given a simplified external command processor (an example of a program
  20110.  that EXTPROC would be used with) called YASH.EXE, based on the
  20111.  following file named YASH.C
  20112.  
  20113.     /* yash.exe -- yet another shell (example of an extproc) */
  20114.  
  20115.     #include <stdio.h>
  20116.     #include <stdlib.h>
  20117.  
  20118.     int main(int argc, char *argv[]);
  20119.  
  20120.     int main(int argc, char *argv[])
  20121.     {
  20122.         printf("yash: processing file \"%s\"\n" argv[1]);
  20123.     }
  20124.  
  20125.  and given a .CMD file called TEST.CMD
  20126.  
  20127.     extproc yash.exe
  20128.     this is a line of try.cmd
  20129.  
  20130.  when at a CMD.EXE prompt, typing the command of
  20131.  
  20132.     TEST
  20133.  
  20134.  should result in CMD.EXE's EXTPROC reading the file, realizing
  20135.  that it is a YASH script and not a CMD script, and then trying to
  20136.  internally invoke TEST.CMD with the following command:
  20137.  
  20138.     YASH TEST.CMD
  20139.  
  20140.  The problem in OS/2 Version 1.10 is that the file extension is
  20141.  incorrectly duplicated, so that the external command interpreter
  20142.  incorrectly receives a script filename of "TEST.CMD.CMD" rather than
  20143.  "TEST.CMD".
  20144.  
  20145.  Microsoft has confirmed this to be a problem with EXTPROC in OS/2
  20146.  Version 1.10. We are researching this problem and will post new
  20147.  information as it becomes available.
  20148.  
  20149.  One workaround for ISVs writing command processors is to perform a
  20150.  version check. If the OS/2 version is 1.10, remove the extra extension
  20151.  from the supplied .CMD filename.
  20152.  
  20153.  For more information on the EXTPROC command, please refer to the
  20154.  "Microsoft Operating System/2 Version 1.10 User's Guide and Desktop
  20155.  Reference."
  20156.  
  20157.  
  20158.  607. Files Required to Boot Up and Load PM Version 1.10
  20159.  
  20160.  The following information describes the minimum required files to boot
  20161.  up and load the OS/2 Version 1.10 Presentation Manager, and the method
  20162.  OS/2 uses to find these files.
  20163.  
  20164.  The following files must be in the root directory of the boot disk:
  20165.  
  20166.     CLOCK01  SYS
  20167.     DISK01   SYS
  20168.     KBD01    SYS
  20169.     PRINT01  SYS
  20170.     SCREEN01 SYS
  20171.     CONFIG   SYS
  20172.  
  20173.  The location of the following files is specified by the PATH= command
  20174.  in CONFIG.SYS:
  20175.  
  20176.     PMCPL    EXE
  20177.     PMEXEC   EXE
  20178.     VIOHELP  EXE
  20179.     SWAPPER  EXE
  20180.     HARDERR  EXE
  20181.     OSO001   MSG
  20182.  
  20183.  The location of the following files is specified by the PROTSHELL=
  20184.  command in CONFIG.SYS:
  20185.  
  20186.     CMD      EXE
  20187.     PMSHELL  EXE
  20188.     OS2      INI
  20189.  
  20190.  The location of the following file is specified by the DEVINFO=
  20191.  command in CONFIG.SYS:
  20192.  
  20193.     VIOTBL   DCP
  20194.  
  20195.  The location of the following file is specified by the DEVICE= command
  20196.  in CONFIG.SYS:
  20197.  
  20198.     PMDD     SYS
  20199.  
  20200.  The location of the following file is specified by the COUNTRY=
  20201.  command in CONFIG.SYS:
  20202.  
  20203.     COUNTRY  SYS
  20204.  
  20205.  The location of the following file is specified by the SWAPPATH=
  20206.  command in CONFIG.SYS:
  20207.  
  20208.     SWAPPER  DAT
  20209.  
  20210.  The location of the following files is specified by the LIBPATH=
  20211.  command in CONFIG.SYS:
  20212.  
  20213.     ANSICALL DLL
  20214.     BKSCALLS DLL
  20215.     BVSCALLS DLL
  20216.     DOSCALL1 DLL
  20217.     KBDCALLS DLL
  20218.     MOUCALLS DLL
  20219.     MSG      DLL
  20220.     NLS      DLL
  20221.     QUECALLS DLL
  20222.     SESMGR   DLL
  20223.     VIOCALLS DLL
  20224.     OS2SPLFS DLL
  20225.     PMGPI    DLL
  20226.     PMGRE    DLL
  20227.     PMSPL    DLL
  20228.     PMTKT    DLL
  20229.     PMWIN    DLL
  20230.     SPL1B    DLL
  20231.     SPLPRMAP DLL
  20232.     OS2SM    DLL
  20233.     PMSHAPI  DLL
  20234.     PMVIOP   DLL
  20235.     DISPLAY  DLL
  20236.  
  20237.  The preceding list assumes a system configured with no mouse, no
  20238.  serial ports, no 3.x BOX, and no print spooler.
  20239.  
  20240.  
  20241.  608. Allocating Memory for Use with Multiple Threads
  20242.  
  20243.  Question:
  20244.  
  20245.  I am working on an OS/2 PM program that uses multiple threads and
  20246.  having problems that seem to be caused by my use of large amounts of
  20247.  global memory. I am declaring my stack space for my threads as global,
  20248.  and which uses from 48-96K (24, 2K stacks or 24, 4K stacks). By also
  20249.  trying to allocate space from the global memory to hold a large data
  20250.  array, my program cannot start the threads. It seems as if by using a
  20251.  large amount of global memory, I have damaged the stack spaces for my
  20252.  threads.
  20253.  
  20254.  Do I need to dynamically allocate memory for the thread stacks and
  20255.  data arrays, or does this also violate some maximum allocatable memory
  20256.  bound?
  20257.  
  20258.  Response:
  20259.  
  20260.  Regarding your C stack, make sure that the stack size of your
  20261.  program is large enough for all of the data put on it.
  20262.  
  20263.  There are generally three ways to allocate memory for a thread, as
  20264.  follows:
  20265.  
  20266.  1. The first way is to use C's stack to statically define the thread's
  20267.     stackspace. This is useful if you are using only a single thread,
  20268.     and the thread never terminates, or the memory never is reused by
  20269.     another thread.
  20270.  
  20271.  2. The other two ways are to dynamically allocate the thread's stack
  20272.     space. Both of these methods are useful if you're creating (and
  20273.     terminating) multiple threads (and perhaps the program doesn't know
  20274.     how many threads will be created until at runtime). You can
  20275.     dynamically allocate memory by using C's run-time library (malloc,
  20276.     free, etc.), which takes memory from C's heap. Or you can use the
  20277.     OS/2 memory management APIs (DosAllocSeg(), DosFreeSeg(), etc.),
  20278.     allocating new segments from the system, each one taking up an
  20279.     entry in your LDT (Local Descriptor Table).
  20280.  
  20281.  The most common problem with memory and threads is that,  if not
  20282.  carefully written, the threads can overwrite each other's stack space.
  20283.  Since the threads are in the same process, OS/2 does not protect each
  20284.  thread from other threads.
  20285.  
  20286.  For this reason alone, we recommend trying to allocate each thread's
  20287.  stack as a separate segment using DosAllocSeg(). In this way, when
  20288.  you start the thread, you pass the selector of that segment only
  20289.  to that thread, and thus no other threads have a valid selector to
  20290.  that segment. If another thread tries to access memory outside the
  20291.  boundary of its stack, it will GP fault, telling you that you need
  20292.  to perform some range checking. And since the threads are in separate
  20293.  segments and the selector is given only to the thread when begun, it
  20294.  is very unlikely that other threads will disturb other threads'
  20295.  memory.
  20296.  
  20297.  Thus, the main advantages of dynamically allocating multiple threads'
  20298.  stack space in separate segments are that it separates the segments
  20299.  and gives your multi-threaded application more security against rogue
  20300.  threads overreaching their own space and also invading the space of
  20301.  other threads. Another advantage is that the thread stack space won't
  20302.  reside on your C stack or heap, giving your program more room to work.
  20303.  
  20304.  
  20305.  609. Creating Device Monitor to Cover Multiple Screen Groups
  20306.  
  20307.  Question:
  20308.  
  20309.  How do I create a global device monitor that covers all screen groups,
  20310.  or more than one screen group?
  20311.  
  20312.  Response:
  20313.  
  20314.  Your character device monitor should loop through each screen group
  20315.  and call DosMonReg() for each screen group, changing the screen group
  20316.  number in each call.
  20317.  
  20318.  Your global device monitor won't work in the DOS screen groups. It
  20319.  will work in the PM (Presentation Manager) screen groups in Version
  20320.  1.10. Please note that this is subject to change, so do not count on
  20321.  this behavior to work in future versions of PM.
  20322.  
  20323.  Listed below is some pseudo C code that demonstrates how you could
  20324.  implement the functionality described above:
  20325.  
  20326.      #define INCL_DOSMONITORS
  20327.      #define INCL_BASE
  20328.      #include <os2.h>
  20329.  
  20330.      #define MAX_SCREEN_GROUPS 16
  20331.  
  20332.      BOOL afIsValidScreenGroup[MAX_SCREEN_GROUPS];
  20333.      HMONITOR ahmon[MAX_SCREEN_GROUPS];
  20334.      int iIndex;
  20335.      /* Setup MONIN and MONOUT structures for each screen group...*/
  20336.      USHORT usError;
  20337.  
  20338.      for (i = 0; i < MAX_SCREEN_GROUPS; i++)
  20339.      {
  20340.          usError = DosMonReg(
  20341.              hmon[iIndex];      /* mon handle to register */
  20342.              &bInBuf[iIndex];   /* pointer to structure for input
  20343.                                    buffer */
  20344.              &bOutBuf[iIndex];  /* pointer to structure for output
  20345.                                    buffer */
  20346.              MONITOR_DEFAULT;   /* mon position flag */
  20347.              iIndex);           /* screen group number */
  20348.          afIsValidScreenGroup[iIndex] = usError == NO_ERROR ? TRUE :
  20349.                                                    FALSE;
  20350.      }
  20351.  
  20352.  QuickHelp includes an example of a device monitor that installs itself
  20353.  in multiple screen groups. The example allows you to select the number
  20354.  of screen groups it installs in. Included below is an excerpt from
  20355.  QH.EXE's command-line documentation:
  20356.  
  20357.      -sg1-12  Specifies the number of full-screen sessions that
  20358.               QuickHelp should monitor. This option is valid only
  20359.               when you run QuickHelp as a keyboard monitor. The
  20360.               default is to monitor the first six sessions created.
  20361.  
  20362.  
  20363.  610. Two Different Function Prototypes for DosCwait() in BSEDOS.H
  20364.  
  20365.  Question:
  20366.  
  20367.  Why are there two different function prototypes for the DosCwait()
  20368.  function in BSEDOS.H?
  20369.  
  20370.  On line 112 of c:\pmsdk\include\bsedos.h, it states the following:
  20371.  
  20372.     USHORT APIENTRY DosCwait(USHORT, USHORT, PRESULTCODES, PPID, PID);
  20373.  
  20374.  On line 104 of c:\include\bsedos.h, it states the following:
  20375.  
  20376.     USHORT APIENTRY DosCWait(USHORT, USHORT, PRESULTCODES, PPID, PID);
  20377.  
  20378.  Response:
  20379.  
  20380.  The proper function declaration for this API is as follows:
  20381.  
  20382.     USHORT APIENTRY DosCwait(USHORT, USHORT, PRESULTCODES, PPID, PID);
  20383.  
  20384.  where the name is "DosCwait" (lowercase w), defined in BSEDOS.H.
  20385.  
  20386.  It was incorrectly named "DosCWait" (capital W) in a previous version
  20387.  of BSEDOS.H [such as the OS/2-specific include files included with the
  20388.  C Compiler Version 5.10, roughly based on the OS/2 Version 1.00 SDK
  20389.  (Software Development Kit)]. However, if you look at the comments of
  20390.  the latest BSEDOS.H, you can see a few references to this older name
  20391.  in some comments:
  20392.  
  20393.      /* DosCWait fScope code values */
  20394.      /* DosCWait wait option values */
  20395.  
  20396.  
  20397.  611. Swapping between Screen Groups
  20398.  
  20399.  If you are running in the detached screen group, there is no way to
  20400.  bring the application (or the screen group) to the foreground.
  20401.  Instead, the application must use the VioPopup() mechanism to
  20402.  communicate with the user.
  20403.  
  20404.  If you have created sessions using DosStartSession(), you can use
  20405.  DosSelectSession() to bring one of these sessions to the foreground.
  20406.  This does not work for sessions that your process did not start.
  20407.  
  20408.  For other sessions, there is no API or standard method to switch from
  20409.  one session to another. The closest method available is to write a
  20410.  character device monitor for the keyboard device driver. Then, you can
  20411.  stuff key packets into the buffer to manually switch from one screen
  20412.  group to another. This method is filled with dependencies and
  20413.  problems. You can't create a keyboard monitor in the MS-DOS screen
  20414.  group, detached screen group, or Presentation Manager screen group.
  20415.  Also, you have no definite idea of how many screen groups there are,
  20416.  and where you are, so without such a firm point of reference it is
  20417.  very difficult to accurately navigate through the screen groups.
  20418.  
  20419.  In spite of all these difficulties, developers still want to try this.
  20420.  There is a sample C program in the Software/Data Library named SWAPSG
  20421.  that is a keyboard device monitor that demonstrates how to switch
  20422.  between screen groups.
  20423.  
  20424.  SWAPSG contains the following files: MONITOR (the makefile),
  20425.  MONITOR.C, MONITOR.DEF, MONITOR.LNK, and MONITOR.EXE.
  20426.  
  20427.  SWAPSG can be found in the Software/Data Library by searching on the
  20428.  keyword SWAPSG, the Q number of this article, or S12364. SWAPSG was
  20429.  archived using the PKware file-compression utility.
  20430.  
  20431.  
  20432.  612. ERROR_INTERRUPT Is Returned When DosMuxSemWait() Is Used
  20433.  
  20434.  Question:
  20435.  
  20436.  In an application with multiple threads using DosMuxSemWait() to block
  20437.  until queue data is available, we are experiencing the following
  20438.  problem. For many calls to DosMuxSemWait(), the result is as expected:
  20439.  either an ERROR_SEM_TIMEOUT error message or 0 (zero).
  20440.  
  20441.  It appears that one of the calls to DosMuxSemWait() is attempting to
  20442.  return ERROR_INTERRUPT (0x57). This causes a protection violation when
  20443.  attempting to store the returned value into a local USHORT variable.
  20444.  
  20445.  Under what circumstances will this function return ERROR_INTERRUPT?
  20446.  What does this return value really indicate? Why are we getting the
  20447.  protection violation?
  20448.  
  20449.  Response:
  20450.  
  20451.  This error/protection violation may be returned because you aren't
  20452.  referencing the semaphore correctly, which can cause errors if the
  20453.  system cannot properly access the semaphore.
  20454.  
  20455.  The ERROR_INTERRUPT error means that the system call was interrupted.
  20456.  It is a very general error; there are approximately 45 places in the
  20457.  OS/2 kernel where this value is returned. The API DosMuxSemWait()
  20458.  never directly returns ERROR_INTERRUPT, nor does there seem to be any
  20459.  directly related kernel routine closely tied with DosMuxSemWait()
  20460.  returning this ERROR_INTERRUPT.
  20461.  
  20462.  In general, the most common place in which a kernel routine returns
  20463.  this error is right after the kernel process block function, a
  20464.  scheduler routine that puts the current process to "sleep" until
  20465.  another process (or an interrupt service routine) issues an
  20466.  appropriate process run routine (which "wakes up" the process). If
  20467.  this routine is unable to properly block the process, it returns an
  20468.  error. Many other areas of the kernel, after calling this routine,
  20469.  also will return the error of ERROR_INTERRUPT if this routine returns
  20470.  an error.
  20471.  
  20472.  The following is a list of some general areas in which this error can
  20473.  be returned:
  20474.  
  20475.   1. It appears that the closest area this error is used to the
  20476.      DosMuxSemWait() semaphore routine is in some kernel functions
  20477.      related to the OS/2 kernel semaphore routines. A routine will
  20478.      return this error if it has been determined that a bad address has
  20479.      been passed to the semaphore routines, and this routine will be
  20480.      called to kill off the process, returning this error.
  20481.  
  20482.   2. If a device is abnormally interrupted, a DosRead(), DosWrite(), or
  20483.      DosDevIOCtl() primitive may return ERROR_INTERRUPT.
  20484.  
  20485.   3. The error is returned by the EXEC loader, trying to serialize
  20486.      multiple threads that use per-process variables.
  20487.  
  20488.   4. The error is returned by the HARDERR.EXE, the hard-error daemon.
  20489.  
  20490.   5. The error is returned when the kernel cannot allocate LDT (Local
  20491.      Descriptor Table) entries to EXEC an application.
  20492.  
  20493.   6. The error is returned when the EXEC loader is in the middle of
  20494.      starting a process, when the thread (most likely its entire
  20495.      process) that instigated the new process is terminating or
  20496.      responding to a kill process signal.
  20497.  
  20498.   7. The error is returned when terminating a process and disassociating
  20499.      the process from any shared memory segments, and if the kernel
  20500.      cannot obtain the semaphore to the shared memory segment(s).
  20501.  
  20502.   8. The error is returned when performing various named pipe APIs, such
  20503.      as DosConnectNmPipe().
  20504.  
  20505.   9. This error occurs in a low-level semaphore waiting routine, if the
  20506.      process waiting for the semaphore is interrupted.
  20507.  
  20508.  10. This error occurs while using DosPTrace(), tracing through a child
  20509.      debugee process, if certain conditions occur in the child.
  20510.  
  20511.  11. This error can be returned by the routines that the Presentation
  20512.      Manager session manager (PMSHELL.EXE) uses to thaw and freeze
  20513.      threads, among other areas it has to dispatch processes.
  20514.  
  20515.  12. The error can be returned by DosCWait(), waiting for a child
  20516.      process to finish, if the child process was somehow interrupted.
  20517.  
  20518.  13. The error can be returned by some memory-management segment
  20519.      reallocation routines if the routine is interrupted by a signal.
  20520.  
  20521.  14. The error can be returned by some kernel exit list processing
  20522.      routines, which coordinate (add, remove, and execute) the various
  20523.      exit list user procedures.
  20524.  
  20525.  15. When loading a dynlink at run-time via DosLoadModule(), it is
  20526.      possible to receive this error if the dynlink loader is
  20527.      interrupted by a signal.
  20528.  
  20529.  
  20530.  613. OS/2 Magnetic Tape/Optical Disk Device Driver API Information
  20531.  
  20532.  Question:
  20533.  
  20534.  I am developing a Presentation Manager (PM) application that will
  20535.  eventually use magnetic tape devices (cartridges) and I would like
  20536.  some information about the application interface to the tape devices.
  20537.  I understand that in general, drivers for tapes will not be a part of
  20538.  OS/2 but will come as drivers provided by the tape device vendors.
  20539.  However, is there a basic application interface (API) pattern to which
  20540.  all or most cartridge tape device drivers will conform? I can imagine
  20541.  several possibilities:
  20542.  
  20543.  1. All drivers for cartridge tape devices provide the same API to
  20544.     applications.
  20545.  
  20546.  2. Drivers will provide basically the same API, with minor differences
  20547.     (e.g. API extensions to take advantage of special device features).
  20548.  
  20549.  3. Drivers for cartridge tape devices will not closely follow any
  20550.     particular API pattern. Each device will offer its own API.
  20551.  
  20552.  My questions are listed below:
  20553.  
  20554.  1. Would you please describe as best you can what the API situation
  20555.     will be for OS/2 (PM) applications needing to use cartridge
  20556.     tape devices?
  20557.  
  20558.  2. Does there exist today a good pattern for what the cartridge tape
  20559.     device interface API will be?
  20560.  
  20561.  3. What can I expect for other types of devices such as (writeable)
  20562.     optical disks? That is, will each vendor develop its own API or
  20563.     will there be a single strong API for the device type?
  20564.  
  20565.  4. How can a developer, like myself, best plan to support a variety
  20566.     of cartridge tape devices, or optical storage units?
  20567.  
  20568.  Response:
  20569.  
  20570.  As a general answer to your questions regarding the API interface to
  20571.  tape and optical disk devices, we believe that most vendors of these
  20572.  products will implement a block device interface to them. This means
  20573.  that accessing them will be similar to accessing a disk drive. There
  20574.  will usually be some kind of directory structure and a file system
  20575.  associated with the device. Therefore, the OS/2 API DosOpen(),
  20576.  DosRead(), DosWrite(), and DosClose() functions will most likely be
  20577.  used to perform I/O with these devices. The area of greatest
  20578.  variability will be in the utility functions such as reset/initialize,
  20579.  seek, rewind, eject, etc. These are usually implemented via
  20580.  DosDevIOCtl() functions, where the command and data formats will be
  20581.  defined by each individual vendor.
  20582.  
  20583.  As for an API pattern for these devices, you should look at the MS-DOS
  20584.  implementation of accessing these devices from a program. You can send
  20585.  for the user manual and/or the programmer's or technical reference
  20586.  guide for several of the popular tape drives to see how they have done
  20587.  this under MS-DOS. Probably for at least some time, the API interface
  20588.  scheme for OS/2 will be similar. Becoming familiar with the MS-DOS
  20589.  scheme is probably the best way to support these devices under OS/2.
  20590.  
  20591.  
  20592.  614. Sending Output from Program to Monochrome (Second) Monitor
  20593.  
  20594.  Question:
  20595.  
  20596.  How can I send output to a monochrome (second) monitor while running a
  20597.  Presentation Manager (PM) program? I already know how to set up the
  20598.  debugging kernel.
  20599.  
  20600.  Under Windows, with OX.SYS, the following statement prints the string
  20601.  on the monochrome monitor:
  20602.  
  20603.     fprintf(stdaux,"\r\nThis message will output to the monochrome.");
  20604.  
  20605.  However, under PM, there is no documentation on how to send
  20606.  application data to the monochrome monitor.
  20607.  
  20608.  Response:
  20609.  
  20610.  There is no equivalent method under PM that allows you to send
  20611.  debugging information to a second monitor/terminal, as you can do
  20612.  using the fprintf() statements under Windows. However, there is
  20613.  something that is similar and quite simple.
  20614.  
  20615.  You can add printf() statements to your PM application and take
  20616.  advantage of redirection into another utility that actually echoes the
  20617.  output. Normally, the printf()s would go into the bit bucket. However,
  20618.  if you pipe the output into something else that then prints out the
  20619.  output, this produces the desired effect.
  20620.  
  20621.  After adding the debugging printf() statements that you want, open a
  20622.  windowed command prompt and issue the following command:
  20623.  
  20624.     PMappname | megrep ^^?
  20625.  
  20626.  If you use this command, you must make MEGREP (it comes as part of the
  20627.  M editor with the C Compiler package) windowable, then use MARKEXE on
  20628.  it. You can choose any utility you like, as long as it echoes input
  20629.  from stdin to stdout in some form, and it can be made to run in a
  20630.  window.
  20631.  
  20632.  Once your application gets started, any output that is sent to stdout
  20633.  [such as printf()] gets piped into MEGREP. The question mark (?) means
  20634.  match any character. The second caret (^) means only do this at the
  20635.  beginning of the line. The first caret is used to escape the second
  20636.  caret, because the caret character (^) has special meaning for OS/2's
  20637.  CMD.EXE.
  20638.  
  20639.  You now have your debugging statements going to one window, while your
  20640.  application runs in another window.
  20641.  
  20642.  For more information about additional debugging functions for OS/2
  20643.  1.10 and 1.20 that describes another method that makes use of calls
  20644.  supported by the debugging version of PMDD.SYS, query on the following
  20645.  keywords in this Knowledge Base or in the Software/Data Library:
  20646.  
  20647.     PMUTILS and UTILS.C
  20648.  
  20649.  These calls work only for OS/2 version 1.10, and since they are
  20650.  undocumented, they are subject to change and may or may not work with
  20651.  later releases of OS/2.
  20652.  
  20653.  PMUTILS can be found in the Software/Data Library by searching on the
  20654.  keyword PMUTILS, the Q number of this article, or S12251.
  20655.  
  20656.  
  20657.  615. Improving Performance of Data Transfer Speed to Disk Drive
  20658.  
  20659.  Question:
  20660.  
  20661.  What steps can I take to get the best possible DosWrite() throughput
  20662.  on floppy-disk devices? For the moment, I only want to consider
  20663.  solutions where a single thread writes to a floppy disk (other threads
  20664.  are used to prepare the buffers to be written to the floppy disk).
  20665.  
  20666.  The following factors might come into play: size of blocks written to
  20667.  floppy disk, priority of thread writing floppy disk relative to that
  20668.  of the other threads, and use of "direct disk access" via the "DASD"
  20669.  DosOpen() openmode flag. Are there any other factors I need to
  20670.  consider?
  20671.  
  20672.  I am particularly interested in what performance gains might be
  20673.  realized through the use of "direct disk access" (DASD flag on open).
  20674.  
  20675.  Are there any other ways to improve floppy-disk write performance?
  20676.  
  20677.  Response:
  20678.  
  20679.  The use of large blocks to transfer data is a very good way to ensure
  20680.  that you get proper performance. You can use DASD opens to speed this
  20681.  up even further, but there are a few issues you should be aware of:
  20682.  
  20683.  1. When using DASD, you are communicating directly with the device
  20684.     driver and are bypassing the file system. This is good for speed,
  20685.     but bad for maintaining a file system on the disk. This method is
  20686.     good if you don't need things such as a root directory or FAT to
  20687.     make the disk readable by anything other than your restore program.
  20688.     Image-type backup programs are useful for this strategy.
  20689.  
  20690.  2. Have the entire contents of the source information be stored in one
  20691.     file on the destination drive. This allows you to use fewer open
  20692.     and close calls to the operating system and file system. This is
  20693.     the method that the standard OS/2 backup and restore programs use.
  20694.  
  20695.  3. Another method to get the data moving faster (although filling an
  20696.     entire disk takes the same amount of time) is to compress the data
  20697.     before writing it out. You could move a lot more data in the same
  20698.     amount of time without having to hurry up the process.
  20699.  
  20700.  Although the above information doesn't really recommend a best method
  20701.  to use, it does explain some of the tradeoffs you should be aware of
  20702.  when using any of the more common approaches to improving data
  20703.  transfer speed. The fact that OS/2 is multitasking should allow you to
  20704.  be more flexible because the user can be doing other things while the
  20705.  backup is going on. This multitasking ability provides a performance
  20706.  boost.
  20707.  
  20708.  In general, the fewer interfaces (DASD and DevIOCtls versus through
  20709.  the kernel) and the larger the buffers that you are writing, the
  20710.  better. However, these two objectives are only part of the picture,
  20711.  and the saving and restoring of the data must also be taken into
  20712.  account.
  20713.  
  20714.  
  20715.  616. Obtaining EXE Filename for Current Process
  20716.  
  20717.  This article discusses how to obtain the EXE filename of each process.
  20718.  
  20719.  The module handle is listed in the local info segment of the current
  20720.  process. The following code sample demonstrates how to obtain this
  20721.  information:
  20722.  
  20723.  #define INCL_BASE
  20724.  
  20725.  #include <os2.h>
  20726.  
  20727.  #include <stdio.h>
  20728.  #include <conio.h>
  20729.  #include <stdlib.h>
  20730.  
  20731.  void main(void);
  20732.  
  20733.  void main(void)
  20734.  {
  20735.  
  20736.     USHORT usRetCode;
  20737.  
  20738.     UCHAR auchName[40];
  20739.     SEL selGlobalSeg, selLocalSeg;
  20740.     LINFOSEG FAR *pgis;
  20741.  
  20742.     usRetCode = DosGetInfoSeg(&selGlobalSeg, &selLocalSeg);
  20743.     pgis = MAKEPLINFOSEG(selLocalSeg);
  20744.  
  20745.     if (!usRetCode)
  20746.        usRetCode = DosGetModName(pgis->hmod, sizeof(auchName),
  20747.                                  auchName);
  20748.     else {
  20749.        printf("\nDosGetInfoSeg failed returning %u\n",usRetCode);
  20750.        exit(1);
  20751.     }
  20752.  
  20753.     printf("\n The module name is %s\n",auchName);
  20754.     exit(0);
  20755.  }
  20756.  
  20757.  This program works for the current process. It also works if an
  20758.  unrelated process can discover other processes' module handles [that
  20759.  is, as long as a valid module handle is passed to GetModName(), you
  20760.  can find out that module's name also].
  20761.  
  20762.  You must find out what the other processes' module handles are. You
  20763.  can try to obtain this information from the task list.
  20764.  
  20765.  
  20766.  617. How to Debug a Detached Process in OS/2
  20767.  
  20768.  Question:
  20769.  
  20770.  I am trying to debug a detached process and because this program
  20771.  monitors the screen memory and keyboard, I can't debug under CodeView.
  20772.  How can I debug detached processes?
  20773.  
  20774.  Response:
  20775.  
  20776.  There are three possible ways to debug detached processes:
  20777.  
  20778.  1. A process that is detached should run the same when not detached;
  20779.     therefore, you could debug your process first as a foreground
  20780.     application and then detach it. You could do this with CVP
  20781.     (CodeView) and dual monitors, although the keyboard monitor may be
  20782.     troublesome, as you might have to use keys in CVP that would affect
  20783.     your monitor.
  20784.  
  20785.  2. Use a debugging file. Send debugging information out to a file that
  20786.     details what your program is doing as a detached process.
  20787.  
  20788.  3. Use VioPopUp() to have your application communicate to you what is
  20789.     going on.
  20790.  
  20791.  Another useful item is a debugging kernel for OS/2 that does not have
  20792.  a CodeView front end, but allows you to debug your application while
  20793.  it is in the detached screen group.
  20794.  
  20795.  To obtain this debugging kernel, you must purchase the OS/2 DDDK
  20796.  (Device Driver Development Kit). For more information on purchasing
  20797.  the OS/2 DDDK, please contact Customer Service at (800) 227-4679.
  20798.  
  20799.  
  20800.  618. OS/2 General Information
  20801.  
  20802.  Question:
  20803.  
  20804.  What is OS/2?
  20805.  
  20806.  Response:
  20807.  
  20808.  Operating System/2 (OS/2) is an operating system designed to meet
  20809.  today's and tomorrow's user needs. It exploits the advanced
  20810.  capabilities of 80286- and 80386-based personal computers such as the
  20811.  IBM PC/AT, COMPAQ DESKPRO 386, and IBM PS/2 models 50 through 80. It
  20812.  is the successor to the MS-DOS operating system.
  20813.  
  20814.  OS/2 removes the limitations of the DOS environment allowing
  20815.  application developers to create much more powerful applications that
  20816.  are easier to learn and use than they have been able to in the past.
  20817.  More powerful applications can be written because there is more memory
  20818.  available to OS/2 applications, and also because there are many more
  20819.  features that are built into the operating system that an application
  20820.  can take advantage of. Features such as multitasking within an
  20821.  application, and facilities for sharing data between applications are
  20822.  available. In the past, developers had to design around these
  20823.  limitations in MS-DOS (lack of multitasking, large memory usage,
  20824.  protected-mode operation). With the standard graphic user interface
  20825.  provided by the OS/2 Presentation Manager, the system will also be
  20826.  much easier to use.
  20827.  
  20828.  
  20829.  619. Memory Available in DOS 3.x Box Environment
  20830.  
  20831.  Question:
  20832.  
  20833.  How much memory is available to a DOS application running in the DOS
  20834.  environment of OS/2?
  20835.  
  20836.  Response:
  20837.  
  20838.  It varies, depending upon the version of OS/2, how the system is
  20839.  configured, and which device drivers are loaded. For OS/2 1.10
  20840.  Standard Edition with the standard device drivers loaded, including a
  20841.  mouse, there is approximately 500K of memory available to the
  20842.  application.
  20843.  
  20844.  For comparison, with MS-DOS Version 3.30 there is approximately 576K
  20845.  of memory available to a MS-DOS application.
  20846.  
  20847.  
  20848.  620. Why You Cannot Go Directly into DOS 3.x Box at Boot Time
  20849.  
  20850.  Question:
  20851.  
  20852.  Is there any way under OS/2 to go straight into the DOS 3.x box at
  20853.  boot time?
  20854.  
  20855.  Response:
  20856.  
  20857.  No, there is no way to go straight into the DOS box at boot time. OS/2
  20858.  was designed primarily to be a protected-mode operating system so as
  20859.  to take advantage of the increased capability of the 80286 in
  20860.  protected mode. The real mode (DOS) box was provided as a way to
  20861.  maintain compatibility with existing applications that were written
  20862.  for MS-DOS. A PC with OS/2 installed will boot directly into OS/2.
  20863.  From there, you can switch into various OS/2 applications, or you can
  20864.  switch directly into the DOS environment.
  20865.  
  20866.  However, there is currently available for OS/2 1.10 a "dual boot"
  20867.  utility that allows you to choose at boot time whether the PC will
  20868.  boot into DOS or into OS/2. If the DOS choice is made at boot time,
  20869.  the PC boots only DOS, and does not load either OS/2 or its DOS
  20870.  compatibility session. Most OEMs include the dual-boot utility in
  20871.  their version of OS/2 1.10.
  20872.  
  20873.  
  20874.  621. MS-DOS Applications That Run in the OS/2 DOS Environment
  20875.  
  20876.  Question:
  20877.  
  20878.  Which MS-DOS applications run in the OS/2 DOS environment?
  20879.  
  20880.  Response:
  20881.  
  20882.  The following applications were tested and run in the OS/2 DOS
  20883.  environment (this is also referred to as the "DOS compatibility box").
  20884.  There are many other DOS applications that also run in the OS/2 DOS
  20885.  environment. Consult the application supplier for information on a
  20886.  specific application.
  20887.  
  20888.  IBM Assistance Series 2.0             Multimate Advantage 3.50, 3.60
  20889.  Chartmaster 6.1                       PFS Professional File 1.0
  20890.  dBaseIII PLUS 1.0 and 1.1             PFS Professional Write 1.0
  20891.  Easy 1.0                              Prokey 4.0
  20892.  Enable 1.1                            RBase 5000 1.0
  20893.  First Choice 1.0                      Sidekick 1.56A and 1.59F
  20894.  Framework II 2.0                      Sideways 3.11
  20895.  IBM Displaywrite 3 release 1.10       SuperCalc 3 2.0
  20896.  IBM Displaywrite 4 release 1.10       Superkey 1.11A
  20897.  IBM File 1.0                          Turbo Pascal 3.01A
  20898.  IBM Report 1.0                        Volkswriter 2.1
  20899.  IBM Writing Assistance 1.0            WordPerfect 4.1
  20900.  Lotus 1-2-3 releases 2.0 and 2.1      WordStar 2000
  20901.  Lotus HAL 1.0                         WordStar release 3.31
  20902.  Lotus Symphony releases 1.1 and 1.2   Microsoft C Compiler 4.0, 5.1
  20903.  Microsoft Chart 2.03                  Microsoft COBOL 2.20
  20904.  Microsoft FORTRAN 4.00                Microsoft MASM 4.00
  20905.  Microsoft Pascal 3.32                 Microsoft Project 3.01
  20906.  Microsoft QuickBASIC 2.01             Microsoft Windows 2.00, 2.10
  20907.  Microsoft Windows/286 2.10            Microsoft Word 3.11, 4.00, 5.00
  20908.  
  20909.  
  20910.  622. Reasons to Purchase OS/2
  20911.  
  20912.  Question:
  20913.  
  20914.  Why should I purchase OS/2?
  20915.  
  20916.  Response:
  20917.  
  20918.  OS/2 allows you to write much more powerful applications than you can
  20919.  under MS-DOS. This means that you will have much more powerful
  20920.  applications that are easier to use. It also allows you to write new
  20921.  types of applications.
  20922.  
  20923.  OS/2 applications can access up to 16 MB of real memory that may be
  20924.  installed in the PC. This frees you from the 640K limitation of
  20925.  MS-DOS, allowing you to design applications that could not be
  20926.  developed for the MS-DOS environment.
  20927.  
  20928.  Another feature of OS/2 is multitasking. OS/2 has two types of
  20929.  multitasking: the ability to run more than one application at the same
  20930.  time (multi-application multitasking) and multitasking within an
  20931.  application. Multi-application multitasking allows you to run more
  20932.  than one application at a time. This means that you can be downloading
  20933.  data from a mainframe while writing a memo with your word processor.
  20934.  
  20935.  Multitasking within an application (multithreading) is an important
  20936.  feature of OS/2. It greatly simplifies the development of a complex
  20937.  application. For example, an MS-DOS spreadsheet program in which you
  20938.  can input more data before the recalculation is complete is
  20939.  multitasking within itself. The code to implement this ability is very
  20940.  complex since the program has to constantly check for keyboard input
  20941.  several times a second during the recalculation. Under OS/2, it is
  20942.  fairly easy to implement this capability because it was designed into
  20943.  the operating system. MS-DOS has no built-in capability to implement
  20944.  this type of functionality.
  20945.  
  20946.  All OS/2 applications written for the Presentation Manager interface
  20947.  will have the same "look and feel," making it easy to learn new
  20948.  applications as they become available. End users will not have to be
  20949.  retrained completely for each new application.
  20950.  
  20951.  However, only OS/2 applications can take advantage of the new features
  20952.  of OS/2. Existing MS-DOS and Windows applications can be run in the
  20953.  DOS mode of OS/2, but they cannot take advantage of the larger memory
  20954.  available under OS/2.
  20955.  
  20956.  
  20957.  623. MODE XON Parameter Does Not Enable RECEIVE_FLOW_CONTROL
  20958.  
  20959.  Problem:
  20960.  
  20961.  There seems to be a problem with the MODE command with respect to
  20962.  setting the communications parameters. The statement listed below sets
  20963.  only the TRANSMIT_FLOW_CONTROL for the device driver:
  20964.  
  20965.     MODE COM1:9600,N,8,1,XON=ON, ....
  20966.  
  20967.  I determined this by doing an IOCTL after opening the device from a
  20968.  program. I think that XON=ON should either enable both TRANSMIT and
  20969.  RECEIVE_FLOW_CONTROL or there should be separate command-line options.
  20970.  
  20971.  RECEIVE_FLOW_CONTROL works correctly as long as I use IOCTL from
  20972.  within my program to enable it. However, this is not desirable because
  20973.  it makes my program more device dependent.
  20974.  
  20975.  Response:
  20976.  
  20977.  Microsoft has confirmed the behavior described above; however, we have
  20978.  not yet confirmed whether or not this is a documentation error or a
  20979.  problem with the actual software. We are researching this problem and
  20980.  will post new information as it becomes available.
  20981.  
  20982.  
  20983.  624. OS/2 Device Driver Can't Use GDT Selector at Initialization
  20984.  
  20985.  Problem:
  20986.  
  20987.  I am having a problem with an installable device driver I am
  20988.  developing that requires memory mapped I/O.
  20989.  
  20990.  At initialization time, I call the DevHelp routines to successfully
  20991.  allocate a GDT (global descriptor table) selector and then map the
  20992.  selector to the physical address of the ROM (e.g. D4000H). However,
  20993.  loading the selector (in protected mode) into the DS register causes a
  20994.  protection violation. The selector is a GDT entry with DPL=0 and the
  20995.  CS/DS selectors are LDT (local descriptor table) entries with DPL=3.
  20996.  
  20997.  Response:
  20998.  
  20999.  This is expected behavior. At initialization time, an installable
  21000.  device driver is running under single-tasking conditions at ring 3
  21001.  with IOPL privilege.
  21002.  
  21003.  You can set up and map the GDT selectors, but you do not have the
  21004.  privilege to use them until task time, when the device driver is
  21005.  running at ring 0. If you need access to your mapped memory at
  21006.  initialization time, you must use some of the "phys" calls to give you
  21007.  addressability.
  21008.  
  21009.  If you want to use the GDT selectors to initialize your device, you
  21010.  need to write an application to call down to your device driver with
  21011.  an IOCtl after initialization time, and do the device initialization
  21012.  the first time you enter your strategy routine.
  21013.  
  21014.  
  21015.  625. Time Field in GINFOSEG Is in Greenwich Mean Time
  21016.  
  21017.  Question:
  21018.  
  21019.  I am using the DosGetInfoSeg() function and the time field of the
  21020.  GINFOSEG structure. The time field specifies the time from January 1,
  21021.  1970 (in seconds). The return value is different (exactly seven hours)
  21022.  from the value that the time() function returns. Why is the return
  21023.  value different?
  21024.  
  21025.  Response:
  21026.  
  21027.  The value contained in the GINFOSEG structure defaults to Greenwich
  21028.  Mean Time. The Microsoft C *time() functions default to reporting Daylight
  21029.  Savings Time in the Pacific Standard Time zone.
  21030.  
  21031.  You can change the default for the *time() functions by setting the TZ
  21032.  environment variable to the appropriate time zone and daylight savings
  21033.  mode. For further information on this subject, please consult the
  21034.  Microsoft C Compiler Version 5.10 documentation for the tzset()
  21035.  function.
  21036.  
  21037.  
  21038.  626. Using STDIO to Write in Text Window at Windowed Command Prompt
  21039.  
  21040.  Question:
  21041.  
  21042.  When I bring up an OS/2 windowed command prompt, I'd like to have
  21043.  programs that use STDIO to write into the text window, instead of
  21044.  flipping to the full screen. Flipping back and forth makes it
  21045.  difficult to view the error codes from MAKE, CL, and LINK. I could
  21046.  work up something for the "Start Program" box, but it seems that I
  21047.  would have to make a separate entry for each makefile.
  21048.  
  21049.  I would prefer to type "make makefile" in the appropriate directory
  21050.  from the windowed command prompt. Can I do this?
  21051.  
  21052.  Response:
  21053.  
  21054.  The proper way to do this is to add a "NAME" statement to your .DEF
  21055.  file and add the keyword "WINDOWCOMPAT", as in the following example:
  21056.  
  21057.           NAME windowableapp WINDOWCOMPAT
  21058.           PROTMODE
  21059.           .
  21060.           .
  21061.           .
  21062.  
  21063.  This procedure sets a byte in the EXEHDR that tells the loader it can
  21064.  be run in a window. The default put in the header is NOTWINDOWCOMPAT,
  21065.  which tells the loader to run the program in a full-screen group. If
  21066.  you don't have a .DEF file already, you can create one with only the
  21067.  NAME statement in it for this purpose.
  21068.  
  21069.  The NAME statement and other .DEF file commands are discussed in the
  21070.  Utilities update sections of the Microsoft OS/2 compatible languages
  21071.  (i.e., C Compiler, MASM, etc.) and also in the linker section of the
  21072.  Presentation Manager (PM) Softset manual.
  21073.  
  21074.  Another way to do this is to use the MARKEXE tool that comes with the
  21075.  OS/2 SDK (Software Development Kit), OS/2 Programmer's Toolkit, or the
  21076.  PM Softset. MARKEXE allows you to set the byte in the EXEHDR of an
  21077.  already existing .EXE file. This procedure also is documented in the
  21078.  PM Softset. You could also use MARKEXE to mark the C compiler, linker,
  21079.  and other binaries so that they run in a window without flipping to a
  21080.  full screen; in fact, many already have done this. Later releases of
  21081.  Microsoft OS/2 compatible tools already have the WINDOWCOMPAT byte
  21082.  set for operation in a window (when appropriate).
  21083.  
  21084.  
  21085.  627. OS/2 Scheduler Is Not Run upon Completion of Interrupt Handler
  21086.  
  21087.  Question:
  21088.  
  21089.  If a device driver interrupt handler does not execute the Run()
  21090.  DevHlp, is the scheduler run upon completion of the interrupt handler?
  21091.  I have a device driver that does not perform I/O in the standard OS/2
  21092.  manner (i.e., request, program device, block thread, wait for
  21093.  interrupt, run thread). Is there any scheduler overhead on completion
  21094.  of the driver interrupt handler, and is there any way I can avoid such
  21095.  overhead?
  21096.  
  21097.  Response:
  21098.  
  21099.  The OS/2 scheduler is not run automatically upon completion of a
  21100.  device driver interrupt handler. Execution just returns to the point
  21101.  where the interrupt occurred, assuming that there are no other pending
  21102.  interrupts waiting.
  21103.  
  21104.  
  21105.  628. CMD.EXE GP Faults If First Character of File Is Binary Byte 26
  21106.  
  21107.  Problem:
  21108.  
  21109.  I have a file in the default directory that has a binary byte 26 as
  21110.  its first character. If I issue either of the following commands in a
  21111.  batch file, CMD.EXE will GP fault when it encounters this file:
  21112.  
  21113.     copy *.* nul
  21114.  
  21115.  or the equivalent command:
  21116.  
  21117.     copy . nul
  21118.  
  21119.  Response:
  21120.  
  21121.  Microsoft has confirmed that this problem occurs in Version 1.10. It
  21122.  only occurs when using the "*.*" or "." copy syntax. We are
  21123.  researching this problem and will post new information as it becomes
  21124.  available.
  21125.  
  21126.  In the meantime, substituting the following lines for the "copy *.*
  21127.  nul" command in your batch file will give you the same results:
  21128.  
  21129.     del foo
  21130.     for %%f in (*.*) do echo %%f >> foo
  21131.  
  21132.  
  21133.  629. Multiple Sessions Printing to LPT1: Is Incorrectly Allowed
  21134.  
  21135.  Problem:
  21136.  
  21137.  We are designing an application with multiple session parallel/serial
  21138.  print capability. When attempting to open a serial output port (e.g.
  21139.  COM1:) using DosOpen() with the following characteristics, we receive
  21140.  the expected failure on a concurrent second session invocation:
  21141.  
  21142.     deny all
  21143.     write only
  21144.     fail on creation
  21145.     open on existence
  21146.  
  21147.  However, when we attempt to open a parallel port (e.g. LPT1:), access
  21148.  is granted to BOTH sessions with catastrophic results. This was tested
  21149.  with the print spooler deactivated.
  21150.  
  21151.  Response:
  21152.  
  21153.  Microsoft has confirmed this to be a problem with the printer device
  21154.  driver included with Version 1.10. We are researching this problem and
  21155.  will post new information as it becomes available.
  21156.  
  21157.  In the meantime, use one of the following workarounds:
  21158.  
  21159.  1. Create a system semaphore that will alert your applications when
  21160.     they can have access to the printer (this only works for your
  21161.     application).
  21162.  
  21163.  2. Always use the spooler.
  21164.  
  21165.  
  21166.  630. Size of DISK01.SYS or DISK02.SYS Cannot Exceed 64K
  21167.  
  21168.  Question:
  21169.  
  21170.  When our disk device driver has a size of 64,980 bytes, OS/2 does not
  21171.  recognize it as a valid device driver. I know that DISK01.SYS has a
  21172.  size limitation of 64K. Does DISK02.SYS have an even smaller size
  21173.  limitation?
  21174.  
  21175.  Response:
  21176.  
  21177.  Both DISK01.SYS and DISK02.SYS have the 64K size limitation. This
  21178.  limitation applies to the combined sum of the code plus data segments
  21179.  after they are loaded into memory. This is not necessarily equal to
  21180.  the file size (in fact, it rarely is), due to factors such as
  21181.  uninitialized data storage, which consumes DS space but is not
  21182.  reflected in the size of the .SYS file.
  21183.  
  21184.  
  21185.  631. Reading in Files Larger Than 64K
  21186.  
  21187.  Question:
  21188.  
  21189.  Can the function DosRead() read in files larger than 65,535 bytes?
  21190.  
  21191.  Response:
  21192.  
  21193.  The functions DosRead(), DosWrite(), and some of the other related I/O
  21194.  APIs are currently limited to an unsigned WORD in their amount of data
  21195.  to read. Therefore, passing an unsigned DWORD to DosRead() causes it
  21196.  to work improperly.
  21197.  
  21198.  To work around this situation, write a higher level function such as
  21199.  the following:
  21200.  
  21201.     USHORT DosReadLots(HFILE hf, PVOID pvBuf, ULONG ulBuf,
  21202.                        PULONG pulRead);
  21203.  
  21204.  This function loops through the appropriate number of times, each time
  21205.  calling DosRead() with an unsigned WORD's worth of data to read, and
  21206.  in the last iteration of the loop it reads in the remainder of the
  21207.  data.
  21208.  
  21209.  
  21210.  632. OS/2 Does Not Interpret ALT Key Correctly in 3.x Box
  21211.  
  21212.  Problem:
  21213.  
  21214.  My application uses KbdSetStatus() to turn on raw mode and shift
  21215.  reporting, and then calls KbdCharIn() with IO_WAIT. When I perform the
  21216.  following steps, the ALT key is not interpreted correctly:
  21217.  
  21218.  1. Press ALT+ESC to switch to the DOS session.
  21219.  
  21220.  2. Release the ALT key.
  21221.  
  21222.  3. Press ALT+ESC to get to the session running my application.
  21223.  
  21224.  4. Without releasing the ALT key, press F1.
  21225.  
  21226.  KbdCharIn() sends the scan code/character code for F1, not ALT+F1. The
  21227.  correct scan code/character code (i.e., ALT+F1) is returned if I don't
  21228.  release the ALT key between the time I start switching sessions to
  21229.  when I get back to the original session and press F1 in addition to
  21230.  the ALT key.
  21231.  
  21232.  Response:
  21233.  
  21234.  Microsoft has confirmed this to be a problem in Version 1.10. This
  21235.  appears to be a minor problem with the 3.x box, where the system
  21236.  remembers an ALT key release, but not an ALT key press. We are
  21237.  researching this problem and will post new information as it becomes
  21238.  available.
  21239.  
  21240.  
  21241.  633. Expanding a CS-Aliased Segment
  21242.  
  21243.  Question:
  21244.  
  21245.  Can you do a DosReallocSeg() on a segment that has been CS aliased?
  21246.  For example, I do a DosAllocSeg() to get a segment of 16K and then I
  21247.  do a DosCreateCSAlias() on that segment. I am generating code in that
  21248.  segment that will later be executed. I now find that 16K isn't enough,
  21249.  so I want to expand that segment. How should I do this? I have tried
  21250.  using DosReallocSeg() on the DS selector; however, I seem to randomly
  21251.  get error number 5 back from the call, even if I am later just trying
  21252.  to expand a plain data segment.
  21253.  
  21254.  Response:
  21255.  
  21256.  As the documentation states, the segment used by DosCreateCSAlias()
  21257.  cannot be a "huge" segment [thus you cannot use DosAllocHuge() to
  21258.  create it] and it must be exclusively available only to your process,
  21259.  not shared by any other processes [thus DosAllocShrSeg() cannot be
  21260.  used to create it]. Therefore, the segment must be ring 2 or ring 3
  21261.  data, and it cannot be huge, shared, or discardable.
  21262.  
  21263.  However, this issue apparently is not documented in the DosAllocSeg(),
  21264.  DosReallocSeg(), or DosCreateCSAlias() sections of the "Microsoft
  21265.  Operating System/2 Programmer's Reference Volume 3" for Version 1.10.
  21266.  
  21267.  DosReallocSeg() does not reallocate CS-aliased or huge segments. It
  21268.  can be used only with unshared and shared segments. We will post new
  21269.  information when the documentation has been updated.
  21270.  
  21271.  One way to work around this problem is to use a normal segment [i.e.,
  21272.  not the segment created for DosCreateCSAlias()] using DosAllocSeg(),
  21273.  and put the dynamically-created code into this segment. As the code is
  21274.  being generated, you could resize the segment via DosReallocSeg().
  21275.  When you are done generating your code dynamically, you could then
  21276.  call DosAllocSeg() to create a segment of the proper size. You would
  21277.  then call DosCreateCSAlias() using the final size of this normal data
  21278.  segment, and then copy the contents of the data segment into the code
  21279.  segment. This is of course an added step, but it is required if you
  21280.  don't know the final size of the segment which will become the
  21281.  CS-aliased segment.
  21282.  
  21283.  
  21284.  634. Comparison between OS/2 and Microsoft Windows
  21285.  
  21286.  The information below compares OS/2 and Windows/386 in the areas of
  21287.  multitasking, memory requirements, and the graphical user interface.
  21288.  Interprocess communication and hardware requirements are also covered.
  21289.  
  21290.  Multitasking
  21291.  ------------
  21292.  
  21293.  There are distinct differences between the multitasking methods that
  21294.  are used by Windows/386 and OS/2.
  21295.  
  21296.  Windows/386 employs two different types of multitasking, depending on
  21297.  whether the applications are Windows programs or standard MS-DOS
  21298.  programs running in virtual 8086 mode. Preemptive time-slicing is used
  21299.  to allocate CPU time between the various virtual MS-DOS machines that
  21300.  may be running and the Windows applications session. However, within
  21301.  the graphical Windows applications session, Windows/386 uses
  21302.  event-driven multitasking, just like Windows/286. That is, the
  21303.  currently executing Windows program must finish an operation and
  21304.  voluntarily yield control of the CPU before another Windows
  21305.  application can start or continue executing. When this doesn't happen,
  21306.  a condition known as "CPU starvation" can set in, and an application
  21307.  slows down or can temporarily stop running because it can't get enough
  21308.  CPU time. If the program that's running crashes, the entire system
  21309.  stops.
  21310.  
  21311.  OS/2 employs time-slicing multitasking, rather than event-driven
  21312.  multitasking. OS/2 has the ability to switch the CPU's attention from
  21313.  activity to activity very rapidly, up to hundreds of times a second.
  21314.  
  21315.  Moreover, OS/2 implements time-slicing using a preemptive,
  21316.  priority-based task scheduler. This provides a smoother multitasking
  21317.  behavior for the user: one application doesn't have to wait until
  21318.  another application relinquishes control of the CPU before it gets
  21319.  some processor time. Under preemptive scheduling, the OS/2 scheduler
  21320.  preempts or takes the CPU away from an application and assigns it to
  21321.  another application according to a dynamic, multilevel priority scheme
  21322.  that's designed to provide maximum responsiveness to the user.
  21323.  
  21324.  In addition to scheduling the execution of multiple, concurrent
  21325.  processes, OS/2 provides an additional layer of multitasking that's
  21326.  not available under any other major personal computer operating
  21327.  system. That is, OS/2 allows multiple, simultaneous "threads of
  21328.  execution" within a single application. In other words, a program can
  21329.  execute in two or more places in its code at the same time. This
  21330.  allows an individual application to perform a number of foreground and
  21331.  background tasks all at the same time.
  21332.  
  21333.  For example, most PC-based spreadsheets process keyboard input and
  21334.  recalculation sequentially. Some are designed to check for input at
  21335.  predetermined intervals. This is extremely inefficient because the
  21336.  system must waste time checking for input even when there is none
  21337.  available. Under OS/2, a spreadsheet could approach this situation by
  21338.  using two threads of execution. One thread is used to prompt the user,
  21339.  wait for and then read the user's input, and then execute the user's
  21340.  commands (for example, entering a value in a cell). The other thread
  21341.  is used to recalculate the spreadsheet. When the user requests a
  21342.  recalculation, the second thread starts calculating in the background
  21343.  while the first thread prompts the user for the next command, without
  21344.  having to wait for the calculation to finish. In this manner, separate
  21345.  concurrent threads allow multiple operations to overlap, making the
  21346.  program faster, more responsive, and more efficient.
  21347.  
  21348.  In addition, OS/2 multitasking is protected at the hardware level.
  21349.  Memory is protected between processes; one process cannot
  21350.  inadvertently overwrite the code or data of another process. This
  21351.  provides the same level of reliability and integrity as found on
  21352.  mainframe computers.
  21353.  
  21354.  Memory Requirements
  21355.  -------------------
  21356.  
  21357.  The current version of Windows uses expanded memory (EMS) to get
  21358.  around the 640K limit of MS-DOS running in the real mode of the Intel
  21359.  8086/8088. While this greatly extends the amount of memory available
  21360.  to Windows applications, there are still some problems involved.
  21361.  Switching banks of memory in and out of expanded memory takes time,
  21362.  noticeably degrading performance.
  21363.  
  21364.  OS/2 was designed from the ground up to take advantage of the
  21365.  protected mode of the 80286/80386 processors. Moreover, OS/2 employs a
  21366.  virtual memory manager to extend accessible memory up to 1 gigabyte.
  21367.  
  21368.  Virtual 8086 Real Mode
  21369.  ----------------------
  21370.  
  21371.  Currently in Windows/386, protection faults are not as robust as they
  21372.  are in OS/2. Windows/386 recommends that you reboot your system if an
  21373.  application fails in one of the virtual machines.
  21374.  
  21375.  Graphical User Interface
  21376.  ------------------------
  21377.  
  21378.  The Graphical User Interface (GUI) employed by the OS/2 Presentation
  21379.  Manager (PM) and Microsoft Windows look and feel almost entirely the
  21380.  same. Any apparent differences are short-lived and are mostly due to
  21381.  differences in their respective production schedules. Even though
  21382.  these environments are implemented on two different operating systems,
  21383.  it is Microsoft's goal to eliminate any differences in their operation
  21384.  so that users of Microsoft Windows will not face any hurdles when
  21385.  upgrading to the OS/2 Presentation Manager.
  21386.  
  21387.  Interprocess Communication
  21388.  --------------------------
  21389.  
  21390.  OS/2 provides a complete system for interprocess communication (IPC)
  21391.  that lets concurrently executing programs (and threads within a
  21392.  program) share data and exchange messages. A variety of IPC mechanisms
  21393.  are available for different situations, including shared memory, named
  21394.  pipes, queues, and the Dynamic Data Exchange (DDE). For developers,
  21395.  this means much greater flexibility and power in selecting and using
  21396.  IPC techniques in their applications. Windows only supports DDE at
  21397.  this time.
  21398.  
  21399.  Who Should Use OS/2?
  21400.  --------------------
  21401.  
  21402.  OS/2 is the ideal operating system for intermediate to power users
  21403.  in business and engineering fields who need sophisticated
  21404.  multitasking, extensive graphics, advanced networking, or complex
  21405.  data-exchange capabilities.
  21406.  
  21407.  It's the operating system of choice for users who need the maximum
  21408.  functionality that can be delivered by today's personal computer
  21409.  systems. Typical applications range from business applications, such
  21410.  as accounting, human resources, and relational database systems to
  21411.  CAD, desktop publishing, or complex "mission-critical" applications.
  21412.  Mission-critical applications are designed to handle strategic
  21413.  business operations that are oriented to "the business of the
  21414.  business." Mission-critical applications usually deal with real-time
  21415.  or time-critical events. They are update intensive, involve many
  21416.  users, and usually include distributed functions. In Version 1.20 of
  21417.  OS/2, new enhancements will include a High Performance File System
  21418.  (HPFS) and extended file attributes.
  21419.  
  21420.  Typical Machine Configuration
  21421.  -----------------------------
  21422.  
  21423.  The hardware requirements for OS/2 and Windows/386 are essentially the
  21424.  same. The actual amount of memory you will require depends on the type
  21425.  of applications you are running, and whether or not you will be on a
  21426.  network (networks tend to use a lot of RAM). The hardware requirements
  21427.  are as follows:
  21428.  
  21429.  1. Fast Intel 80286-based or 80386-based personal computer
  21430.  
  21431.  2. Two to four MB memory
  21432.  
  21433.  3. IBM EGA or higher (or compatible) video adapter and monitor
  21434.  
  21435.  4. Microsoft Mouse or compatible
  21436.  
  21437.  
  21438.  635. RIPS Occur When WinDdePostMsg() Is Used in PM
  21439.  
  21440.  Problem:
  21441.  
  21442.  I have modified the sample DDE server code named PMSERVER in the
  21443.  Software Library. I put a DosSemRequest() and DosSemClear() around the
  21444.  code that handles the WM_DDE_ADVISE message (the semaphore doesn't
  21445.  protect anything, it just illustrates the problem). I also added more
  21446.  stocks and created an Excel spreadsheet that created 16 hot links (one
  21447.  for each stock). When you start the server and run the spreadsheet
  21448.  (under Excel for PM), the system hangs, even if you are using
  21449.  CodeView. If WinDdePostMsg() is removed from the semaphore, the system
  21450.  does not hang. The following sequence of events appears to occur:
  21451.  
  21452.  1. Excel posts a WM_DDE_ADVISE message.
  21453.  
  21454.  2. The server callback function gets the semaphore.
  21455.  
  21456.  3. The server tries to post an acknowledgment (still holding the
  21457.     semaphore).
  21458.  
  21459.  4. Excel posts another WM_DDE_ADVISE message.
  21460.  
  21461.  5. The server callback function is re-entered. The semaphore is not
  21462.     available, so something else blocks.
  21463.  
  21464.  Response:
  21465.  
  21466.  Microsoft has confirmed this to be a problem in Version 1.10. We are
  21467.  researching this problem and will post new information as it becomes
  21468.  available.
  21469.  
  21470.  Running the server and Excel does generate several unusual huge RIPs
  21471.  and 10 to 20 "cannot post msg, queue full" messages. The system is
  21472.  also left in an inconsistent state, although several display driver
  21473.  errors follow the "graceful" exit.
  21474.  
  21475.  The first RIPs seem to be generated from Excel code, i.e., they may be
  21476.  the ones causing the segmentation failure, although many RIPs from PM
  21477.  were quick to follow. Therefore, this problem appears to be a side
  21478.  effect of the way PM handles WinDdePostMsg().
  21479.  
  21480.  The workaround is to ensure that WinDdePostMsg() is not surrounded by
  21481.  DosSem*() functions that could potentially (easily) result in
  21482.  deadlock or other unexpected results in client applications not ready
  21483.  to be "delayed," or handle the effects of modal message loops.
  21484.  
  21485.  Additional reference words: softlib PMSERVER.ARC S12267.EXE
  21486.  
  21487.  
  21488.  636. CodeView Dotted Line Problem Occurs on VGA and EGA Systems
  21489.  
  21490.  The problem listed below appears to occur on most EGA and VGA systems.
  21491.  The following steps can be used to reproduce this problem:
  21492.  
  21493.  1. Start up CodeView on one monitor.
  21494.  
  21495.  2. Trace through an application until the initial border appears.
  21496.  
  21497.  3. Quit CodeView.
  21498.  
  21499.  4. At this point, you will be back to a full-screen prompt.
  21500.  
  21501.  5. Switch back to the task manager.
  21502.  
  21503.  6. A dotted line will be displayed on the screen.
  21504.  
  21505.  Microsoft has confirmed that this problem occurs in Version 1.10. We
  21506.  are researching this problem and will post new information as it
  21507.  becomes available.
  21508.  
  21509.  
  21510.  637. Sample Device Driver in C
  21511.  
  21512.  Question:
  21513.  
  21514.  Is there a sample device driver for OS/2 written in C?
  21515.  
  21516.  Response:
  21517.  
  21518.  There is a sample program in the Software Library that demonstrates
  21519.  the development of an OS/2 device driver written in C. This file can
  21520.  be found in the Software/Data Library by searching on the keyword
  21521.  SAMPDD, the Q number of this article, or S12374. SAMPDD was archived
  21522.  using the PKware file-compression utility.
  21523.  
  21524.  This archived library contains the following files:
  21525.  
  21526.     Filename             Contents
  21527.     --------             --------
  21528.  
  21529.     SAMPDD               Make file for the device driver
  21530.     ACRTUSED.ASM         Replacement main routine
  21531.     SAMPDD.C             C source for the device driver
  21532.     SEGENDS.ASM          Segment end routines
  21533.     STDDD.H              Device driver definition header
  21534.     SAMPDD.DEF           Linker definition file
  21535.  
  21536.  
  21537.  638. Non-PM Program Cannot Determine Window Size
  21538.  
  21539.  Question:
  21540.  
  21541.  How can a non-Presentation Manager (PM) program determine the size of
  21542.  the window that it is running in?
  21543.  
  21544.  Response:
  21545.  
  21546.  A VIO application running in a window of the PM screen group does not
  21547.  realize that it is running in this environment, and not in a
  21548.  full-screen screen group.
  21549.  
  21550.  PM runs a "shield layer" to control the PM window that the VIO
  21551.  application is running in. This shield layer bridges the normal
  21552.  application interface with PM (similar to the PM method of I/O, such
  21553.  as message-based keyboard and mouse I/O) with the base interface that
  21554.  the VIO application is used to. This shield layer is conceptually
  21555.  similar to the WINOLDAP interface that Microsoft Windows uses to run
  21556.  non-Windows applications under Windows.
  21557.  
  21558.  PM and AVIO applications can use the PM APIs to manipulate their
  21559.  environment. VIO applications don't have a window size when in full
  21560.  screen, so there are no VIO APIs to manipulate window size (since this
  21561.  is not a concern). And VIO applications do not have any system
  21562.  services to manipulate their window in this hybrid environment. The
  21563.  user can change the size of the window by using the size bars and the
  21564.  system menu of the window (controlled by this shield layer).
  21565.  
  21566.  Only executables that can be used properly in a PM window should be
  21567.  marked as being able to run in this environment (setting the
  21568.  WINDOWCOMPAT bit in the EXE header via the .DEF file or the MARKEXE
  21569.  utility).
  21570.  
  21571.  
  21572.  639. Change Directory Drive Problem in Version 1.10
  21573.  
  21574.  The command "CD DIR_NAME D:" (where "DIR_NAME" is the name of a
  21575.  directory and "D:" designates a drive letter) incorrectly causes the
  21576.  command processor to access the designated drive. This behavior occurs
  21577.  under both the real-mode and the protected-mode command processors.
  21578.  
  21579.  Microsoft has confirmed this to be a problem in Version 1.10. We are
  21580.  researching this problem and will post new information as it becomes
  21581.  available.
  21582.  
  21583.  
  21584.  640. Deciding Whether to Enable or Disable Spooler
  21585.  
  21586.  Question:
  21587.  
  21588.  With OS/2 Version 1.10, the Spooler Queue Manager is automatically
  21589.  loaded upon bootup. What factors should we take into consideration
  21590.  when we are deciding whether to enable or disable the spooler?
  21591.  
  21592.  Response:
  21593.  
  21594.  The decision on whether or not to use the spooler depends greatly on
  21595.  your own needs and system configuration.
  21596.  
  21597.  One factor you should consider is whether or not you need to run the
  21598.  LAN Manager Server Spooler (a different spooler than the PM Spooler).
  21599.  In Version 1.10 of Microsoft OS/2, these two spoolers are
  21600.  incompatible.
  21601.  
  21602.  If you are using LAN Manager Version 1.00 or 1.10 under OS/2 Version
  21603.  1.10, you should use the LAN spooler and disable the PM spooler. The
  21604.  spoolers are unaware of each other, and this causes conflicts in
  21605.  accessing the output device when both are enabled.
  21606.  
  21607.  Another factor to consider is that the PM Spooler is very resource
  21608.  intensive. It consumes a large chunk of low memory, and needs
  21609.  approximately 50 threads of its own. Consequently, the use of so many
  21610.  threads lowers the amount of threads available for other applications,
  21611.  and tends to take up a lot of CPU time (although the spooler threads
  21612.  will likely be low-priority threads).
  21613.  
  21614.  One final factor you should consider is whether you are running PM
  21615.  applications that have installable printer drivers. In Version 1.10 of
  21616.  Microsoft OS/2, these PM printer drivers depend on the presence of a
  21617.  spooler.
  21618.  
  21619.  Beyond these general guidelines, you will probably have to
  21620.  experiment with printing, with the spooler enabled or disabled to
  21621.  find out which configuration works best for you.
  21622.  
  21623.  
  21624.  641. Date Is Set Incorrectly When Time Command Is Used
  21625.  
  21626.  The following problems occur in Version 1.10 of OS/2:
  21627.  
  21628.  1. At a full-screen command prompt, if the current date is 6-30-89 and
  21629.     I execute the following command
  21630.  
  21631.        TIME 23:59:59.99
  21632.  
  21633.     the date incorrectly changes to 6-31-89, even though June only has
  21634.     30 days in it. If I then execute "TIME 23:59:59.99" again, the date
  21635.     changes to 7-2-89.
  21636.  
  21637.  2. At a windowed command prompt, if the current date is 6-30-89 and I
  21638.     execute the following command:
  21639.  
  21640.        TIME 23:59:59.99
  21641.  
  21642.     the date incorrectly changes to 6-31-89, even though June only has
  21643.     30 days in it. If I then execute "TIME 23:59:59.99" again, an error
  21644.     code of SYS1044 is returned. This problem also occurs with the
  21645.     dates of 4/30 and 9/30.
  21646.  
  21647.  Microsoft has confirmed these to be problems in Version 1.10 of OS/2.
  21648.  We are researching these problems and will post new information as it
  21649.  becomes available.
  21650.  
  21651.  
  21652.  642. XCOPY with /S Option Incorrectly Copies Empty Subdirectories
  21653.  
  21654.  When I run XCOPY when using the /s option, XCOPY copies all of the
  21655.  subdirectories, even if they are empty.
  21656.  
  21657.  Microsoft has confirmed this to be a problem in Version 1.10 of MS
  21658.  OS/2. We are researching this problem and will post new information as
  21659.  it becomes available.
  21660.  
  21661.  
  21662.  643. DIR Command Fails with Trap D Error in OS/2 Version 1.10
  21663.  
  21664.  When you run the following DIR command, a TRAP D error occurs:
  21665.  
  21666.     DIR aaaa.....a  (until input area is full)
  21667.  
  21668.  Microsoft has confirmed this to be a problem in Version 1.10 of OS/2.
  21669.  We are researching this problem and will post new information as it
  21670.  becomes available.
  21671.  
  21672.  
  21673.  644. Resizing Segments with DosRealloc()
  21674.  
  21675.  Question:
  21676.  
  21677.  Can I reallocate a block of memory that I used DosSubAlloc() on?
  21678.  
  21679.  Response:
  21680.  
  21681.  You can only increase the size of a local heap created with
  21682.  DosSubSet(); you cannot decrease it.
  21683.  
  21684.  Segments that are resized with DosReallocSeg() must be resized with
  21685.  DosSubSet(). If not, the manipulation of the suballocations within the
  21686.  segment is undefined. For example:
  21687.  
  21688.     DosReallocSeg(tbytes,pGRFCB.sel); /* Reallocates fine when Adding,
  21689.                                          but returns an error of 5L when
  21690.                                          the memory size is decreased */
  21691.  
  21692.  To do this correctly (with shared segments only), you must set up your
  21693.  segment and OR it with 0x0008 for the attribute. For example:
  21694.  
  21695.     SEG_GETTABLE | 0x0008
  21696.  
  21697.  
  21698.  645. STATUSDATA "BindInd" Field Name Documentation Error
  21699.  
  21700.  Microsoft has confirmed the following to be a problem in the version
  21701.  of QuickHelp included with the Version 1.10 OS/2 SDK (Software
  21702.  Development Kit), and on Page 365 of the "Microsoft Operating System/2
  21703.  Programmer's Reference Volume 3" for Version 1.10. The STATUSDATA
  21704.  entry incorrectly lists a field called "BindInd". However, in the
  21705.  include file named BSEDEF.H, the actual name is "BondInd".
  21706.  
  21707.  We are researching this problem and will post new information when the
  21708.  documentation has been updated to correct this problem.
  21709.  
  21710.  
  21711.  646. DosStartSession() "Related" Field Documentation Error
  21712.  
  21713.  Microsoft has confirmed that the information for the "Related" field
  21714.  of the STARTDATA structure listed in the DosStartSession()
  21715.  documentation is incorrect on Page 153 of the "Microsoft Operating
  21716.  System/2 Programmer's Reference Volume 3" for Version 1.10, and in the
  21717.  version of QuickHelp included with the Version 1.10 OS/2 SDK (Software
  21718.  Development Kit).
  21719.  
  21720.  The documentation incorrectly states the following:
  21721.  
  21722.     An independent session is created when the Related field of the
  21723.     STARTDATA structure is set to TRUE.
  21724.  
  21725.  Instead, it should state the following:
  21726.  
  21727.     If the related field is FALSE, the new session is an independent
  21728.     session (not related).
  21729.  
  21730.  We are researching this problem and will post new information when
  21731.  the documentation has been updated to correct this error.
  21732.  
  21733.  
  21734.  647. "See Also" Section of WM_QUERYTRACKINFO Documentation Error
  21735.  
  21736.  The "See Also" section of the WM_QUERYTRACKINFO documentation
  21737.  incorrectly lists WM_QUERYTRACKINFO again as a reference.
  21738.  
  21739.  Microsoft has confirmed this to be a problem in the version of
  21740.  QuickHelp included with the Version 1.10 OS/2 SDK (Software
  21741.  Development Kit), and on Page 452 of the "Microsoft Operating System/2
  21742.  Programmer's Reference Volume 2" for Version 1.10. We are researching
  21743.  this problem and will post new information when the documentation has
  21744.  been updated to correct this error.
  21745.  
  21746.  
  21747.  648. NLSINFO: National Language Support Sample Program
  21748.  
  21749.  There is a file in the Software/Data Library named NLSINFO that
  21750.  displays most of the NLS (National Language Support) features of
  21751.  OS/2. NLSINFO can be found in the Software/Data Library by searching
  21752.  on the keyword NLSINFO, the Q number of this article, or S12409.
  21753.  NLSINFO was archived with the PKware file-compression utility.
  21754.  
  21755.  NLSINFO uses the Family API functions DosGetCntryInfo(),
  21756.  DosGetCollate(), and DosGetCp() to obtain various local-dependent
  21757.  information. In addition to the information returned by these three
  21758.  FAPI functions, NLSINFO also creates a table of information based on
  21759.  the MS-DOS and OS/2 user documentation to provide more information
  21760.  about the localized environment. For example, see the COUNTRYNAME
  21761.  table. This table can easily become outdated because it is not part of
  21762.  the operating system. Please refer to the MS-DOS and OS/2 user
  21763.  documentation for the most recent information on this table.
  21764.  
  21765.  The compile instructions for NLSINFO are as follows:
  21766.  
  21767.     cl /Lp /Fb /W3 NLSINFO.C
  21768.  
  21769.  After compiling NLSINFO.C, a dual-mode NLSINFO.EXE file will be
  21770.  created that can be run in MS-DOS (Version 3.30 or later) real mode or
  21771.  in OS/2 protected mode.
  21772.  
  21773.  The run-time command-line usage of NLSINFO is as follows, where
  21774.  <countrycode> is a valid country code and <codepage> is a valid
  21775.  codepage:
  21776.  
  21777.     NLSINFO <countrycode> <codepage>
  21778.  
  21779.  If these values are both omitted, the program uses the default values
  21780.  of 0 (zero) for each parameter, and also uses the current country and
  21781.  codepage information for the current process. See the batch files
  21782.  NLSTEST.CMD and NLSTEST.BAT for examples of how to invoke NLSINFO.EXE.
  21783.  
  21784.  Remember, when using MS-DOS, the program NLSFUNC must be running if
  21785.  you want to obtain NLS-related information for any country but the
  21786.  current (default) country. No similar precaution is required when
  21787.  running OS/2.
  21788.  
  21789.  
  21790.  649. CSALIAS.C: Dynamic Creation of CS-Aliased Code Segment
  21791.  
  21792.  Listed below is the program CSALIAS.C, which dynamically creates a
  21793.  CS-aliased code segment and executes some code from within this
  21794.  segment. CSALIAS.C demonstrates how to use the following OS/2 APIs:
  21795.  
  21796.     DosCreateCSAlias()
  21797.     DosAllocSeg()
  21798.     DosFreeSeg()
  21799.  
  21800.  A data segment is allocated by calling DosAllocSeg(). A small
  21801.  assembly-language routine is created in this data segment. An
  21802.  alias-code selector for this data segment is obtained by calling
  21803.  DosCreateCSAlias(). Using the alias-code selector, the routine in the
  21804.  data segment is called. After returning from the routine, the
  21805.  alias-code selector and the data segment are freed by calling
  21806.  DosFreeSeg().
  21807.  
  21808.  CSALIAS.C illustrates the use of DosCreateCSAlias(); it does not do
  21809.  anything useful. A more likely use of aliasing code to data is where
  21810.  the code is actually generated at run time, rather than statically
  21811.  declared in this example.
  21812.  
  21813.  If DEBUG is #defined, then the program will display more verbose
  21814.  output about the success or failure of an API call.
  21815.  
  21816.  CSALIAS.C uses only Family API functions and thus can be linked and
  21817.  bound to work in either the MS-DOS or OS/2 environments.
  21818.  
  21819.  CSALIAS.C should be compiled with the following options:
  21820.  
  21821.     cl /AL /G2 /Lp /Fb /W3 CSALIAS.C
  21822.  
  21823.  This software is provided for demonstration purposes only. Microsoft
  21824.  makes no warranty, implied or otherwise, regarding its performance or
  21825.  reliability in any situation.
  21826.  
  21827.  Copyright (C) Microsoft Corp. 1986, 1989
  21828.  
  21829.  /* include files */
  21830.  
  21831.  #define INCL_DOS
  21832.  #define INCL_DOSMEMMGR
  21833.  #include <os2.h>
  21834.  
  21835.  #include <stdio.h>
  21836.  #include <stdlib.h>
  21837.  #include <string.h>
  21838.  
  21839.  /* -------------------------------------------------------------- */
  21840.  
  21841.  /* constants */
  21842.  
  21843.  #define TEST_VALUE  3  /* To be squared by procedure in CSAliased
  21844.                            segment */
  21845.  
  21846.  /* A routine that computes the square of an integer */
  21847.  UCHAR aucOpCodes[] =
  21848.  {
  21849.      0x55,                                 /* push  bp        */
  21850.      0x8B, 0xEC,                           /* mov   bp,sp     */
  21851.      0x8B, 0x46, 0x06,                     /* mov   ax,[bp+6] */
  21852.      0xF7, 0xE0,                           /* mul   ax        */
  21853.      0x8B, 0xE5,                           /* mov   sp,bp     */
  21854.      0x5D,                                 /* pop   bp        */
  21855.      0xCB                                  /* retf            */
  21856.  };
  21857.  
  21858.  /* -------------------------------------------------------------- */
  21859.  
  21860.  /* Function prototypes */
  21861.  
  21862.  int main(int argc, char *argv[]);
  21863.  void TestError(USHORT usError, PSZ pszApiName);
  21864.  
  21865.  /* -------------------------------------------------------------- */
  21866.  
  21867.  /* Main program */
  21868.  
  21869.  int main(int argc, char *argv[])
  21870.  {
  21871.  
  21872.      USHORT usError;                 /* API return code */
  21873.      SEL selDataSegment;             /* Selector to data segment */
  21874.      SEL selCodeSegment;             /* Alias code segment selector */
  21875.      PCH pchDataSegment;             /* Pointer to data segment */
  21876.      LONG lSquareOfInt;              /* Holds square of an integer */
  21877.      PVOID pvResult;                   /* result of memcpy() */
  21878.      LONG (*pfnIntSquareRoot)(USHORT); /* Pointer to a procedure */
  21879.  
  21880.      /* Allocate a segment */
  21881.      usError = DosAllocSeg(sizeof(aucOpCodes), &selDataSegment,
  21882.                            SEG_NONSHARED);
  21883.      TestError(usError, "DosAllocSeg");
  21884.  
  21885.      /* Construct a far pointer to the data segment */
  21886.      pchDataSegment = MAKEP(selDataSegment, 0);
  21887.  
  21888.      /* Copy an assembly language procedure into the data segment */
  21889.      printf("fyi: sizeof(aucOpCodes) = %d\n", sizeof(aucOpCodes));
  21890.      pvResult = memcpy(pchDataSegment, aucOpCodes,
  21891.                        sizeof(aucOpCodes));
  21892.  
  21893.      /* Get a CSAlias selector for the data segment */
  21894.      usError = DosCreateCSAlias(selDataSegment, &selCodeSegment);
  21895.      TestError(usError, "DosCreateCSAlias");
  21896.  
  21897.      /* Construct the address to the procedure in the CSAliased
  21898.         segment */
  21899.      pfnIntSquareRoot = MAKEP(selCodeSegment, 0);
  21900.  
  21901.      /* Execute the code in the CSAliased data segment */
  21902.      lSquareOfInt = (*pfnIntSquareRoot)(TEST_VALUE);
  21903.      if (lSquareOfInt != (TEST_VALUE * TEST_VALUE))
  21904.      {
  21905.          printf("Failure: procedure in CSAliased segment failed\n");
  21906.      }
  21907.      else
  21908.      {
  21909.          printf("Success: procedure in CSAliased segment worked\n");
  21910.      }
  21911.  
  21912.      /* Free the alias code selector */
  21913.      usError = DosFreeSeg(selCodeSegment);
  21914.      TestError(usError, "DosFreeSeg");
  21915.  
  21916.      /* Free the data segment */
  21917.      usError = DosFreeSeg(selDataSegment);
  21918.      TestError(usError, "DosFreeSeg");
  21919.  
  21920.      /* End the program */
  21921.      exit(0);
  21922.  
  21923.  } /* main */
  21924.  
  21925.  /* -------------------------------------------------------------- */
  21926.  
  21927.  /* Test an OS/2 API return code; choke and die if unsuccessful */
  21928.  
  21929.  void TestError(USHORT usError, PSZ pszApi)
  21930.  {
  21931.  
  21932.      if (usError)
  21933.      {
  21934.          printf("Error: %s API returned %u!\n", pszApi, usError);
  21935.          exit(1);
  21936.      }
  21937.  #ifdef DEBUG
  21938.      else
  21939.      {
  21940.          printf("debug: %s API worked successfully\n", pszApi);
  21941.      }
  21942.  #endif /* DEBUG */
  21943.  
  21944.  } /* TestError */
  21945.  
  21946.  /* ------------------------------------------------------------ */
  21947.  
  21948.  
  21949.  650. Using DosOpen() File Size Option
  21950.  
  21951.  Question:
  21952.  
  21953.  I have a question concerning the file-size option in the DosOpen()
  21954.  function, and the cbFilealloc parameter of the DosQFileInfo()
  21955.  function. Does the file-size parameter of DosOpen() specify the size
  21956.  of the file, or the amount of data that is going to be written to it?
  21957.  
  21958.  If I specify a file size of 200 and then use the DosQFileInfo()
  21959.  function, it shows the end of data to be 200 when in actuality I have
  21960.  only written 13 bytes to the file. DosQFileInfo() also shows the
  21961.  cbFilealloc parameter to be 2048 (2K) when I would expect it to be
  21962.  200, or 2K, or some other kind of default value.
  21963.  
  21964.  Response:
  21965.  
  21966.  The DosOpen() file-size parameter is used to pre-allocate space for
  21967.  your file when you create a new file. If you open an existing file,
  21968.  this parameter is ignored. Usually, when you create a new file with
  21969.  DosOpen(), you will specify a size of 0 (zero) since DosWrite() gets
  21970.  space as it needs it. You would use a file size other than 0 if you
  21971.  were concerned that a file would not fit on the disk and you needed to
  21972.  know this information before you started writing to the file (e.g.
  21973.  if you were running a real-time application).
  21974.  
  21975.  The size of the file and the space allocated the file on the disk are
  21976.  actually two different things. The smallest amount of space that can
  21977.  be allocated to a file is a cluster. A cluster is some fixed number of
  21978.  sectors (1 sector = 512 bytes). On your hard disk, 1 cluster = 4
  21979.  sectors (2K bytes). Space is allocated one whole cluster at a time.
  21980.  
  21981.  Thus, for every file, up to 2K bytes (1 cluster) of space on your hard
  21982.  disk may be wasted. This is necessary because otherwise performance on
  21983.  your hard disk would be unbearably slow. If you are interested in more
  21984.  details about how files are stored, you can find this information in
  21985.  one of Peter Norton's books, or in one of the many other books on
  21986.  MS-DOS (the system hasn't changed from MS-DOS in this respect).
  21987.  
  21988.  
  21989.  651. Using DosOpen() to Open and Write to a COM: Port
  21990.  
  21991.  Problem:
  21992.  
  21993.  I am trying to write a debug utility for Presentation Manager (PM)
  21994.  that writes the output of a passed parameter to a debug terminal
  21995.  connected to COM1:. When I try to open COM1: for writing using the
  21996.  DosOpen() API function, it returns an error 12, ERROR_INVALIDACCESS.
  21997.  In Chapter 46, on Page 626 of the "Microsoft Operating System/2
  21998.  Programmer's Reference Volume 1" for Version 1.10, it states that
  21999.  DosOpen() can be used to open COM1: and then DosWrite() can be used to
  22000.  write to the device.
  22001.  
  22002.  Response:
  22003.  
  22004.  To avoid receiving this error, you need to use the OPEN_SHARE_*
  22005.  attribute in addition to the OPEN_ACCESS_* flag in the DosOpen() API.
  22006.  Listed below is a sample program that demonstrates how to use these
  22007.  attributes correctly:
  22008.  
  22009.  #include <stdio.h>
  22010.  #include <stdlib.h>
  22011.  #define INCL_BASE
  22012.  #include <os2.h>
  22013.  
  22014.  int main(void);
  22015.  
  22016.  int main(void)
  22017.  {
  22018.  
  22019.     CHAR   szbuffer[10];
  22020.     HFILE  hf;
  22021.     USHORT usBytesWritten;
  22022.     USHORT usRes;
  22023.     USHORT usAction = FILE_EXISTED;
  22024.  
  22025.     usRes = DosOpen("com1", &hf, &usAction, 0L, FILE_NORMAL,
  22026.                      FILE_OPEN,OPEN_ACCESS_READWRITE |
  22027.                      OPEN_SHARE_DENYREADWRITE, 0L);
  22028.     if (usRes != 0)
  22029.     {
  22030.         itoa(usRes, szbuffer, 10);
  22031.         puts("Error opening file");
  22032.     }
  22033.     else
  22034.     {
  22035.         puts("opened COM1, writing to it...");
  22036.         DosWrite(hf, "Hey you guys!!!/n/r", 18, &usBytesWritten);
  22037.         if (usBytesWritten < 15)
  22038.         {
  22039.             puts("bytes written != string sent");
  22040.         }
  22041.         else
  22042.         {
  22043.             puts("DosWrite to COM1 worked");
  22044.         }
  22045.  
  22046.         DosClose(hf);
  22047.     }
  22048.     exit(0);
  22049.     return (0);
  22050.  
  22051.  } /* main */
  22052.  
  22053.  
  22054.  652. Spooler Queue Manager Problems in OS/2 SDK Version 1.10
  22055.  
  22056.  Microsoft has confirmed that the following problems exist with the
  22057.  Spooler Queue Manager included with the Version 1.10 OS/2 SDK
  22058.  (Software Development Kit):
  22059.  
  22060.  1. The Spooler Queue Manager does not delete the files that have
  22061.     already been sent to the printer. These files remain in the
  22062.     \SPOOL subdirectory and their file length is zero bytes.
  22063.  
  22064.  2. The Spooler Queue Manager cannot delete a print job directed to a
  22065.     device that is not currently available, e.g. if no printer is
  22066.     installed on LPT1:. Sometimes even a reboot does not help the job
  22067.     to disappear from the print queue.
  22068.  
  22069.  We are researching these problems and will post new information as
  22070.  it becomes available.
  22071.  
  22072.  
  22073.  653. Programmatically Querying LIBPATH Information in CONFIG.SYS
  22074.  
  22075.  Question:
  22076.  
  22077.  Is there a way to query the LIBPATH information in the CONFIG.SYS file
  22078.  programmatically?
  22079.  
  22080.  Response:
  22081.  
  22082.  Unfortunately, LIBPATH is one piece of system information that is not
  22083.  directly available from an API. LIBPATH is not an environment variable
  22084.  and its value is not as easy to determine as some of the other system
  22085.  configuration parameters set in the CONFIG.SYS file.
  22086.  
  22087.  Given the present constraints, one workaround is to set a LIBPATH
  22088.  environment variable in your CONFIG.SYS file.
  22089.  
  22090.  An alternative is to take the same approach as the LIBWHERE utility.
  22091.  Generally speaking, this utility first calls DosGetInfoSeg() to
  22092.  retrieve the boot drive from the GINFOSEG structure. Next, it opens
  22093.  the file CONFIG.SYS (or CONFIG.OS2, as appropriate to the
  22094.  circumstances) and performs a DosExecPgm() on WHERE.EXE, directing the
  22095.  WHERE utility to traverse the LIBPATH string and look for what the
  22096.  user has specified.
  22097.  
  22098.  
  22099.  654. Use of CTRL+P in DOS 3.x Box Doesn't Echo Output to Printer
  22100.  
  22101.  In the DOS 3.x box, the use of CTRL+P does not echo output to the
  22102.  printer as it should.
  22103.  
  22104.  Microsoft has confirmed this to be a problem in Version 1.10. We are
  22105.  researching this problem and will post new information as it becomes
  22106.  available.
  22107.  
  22108.  
  22109.  655. JOIN Command Doesn't Work Correctly in OS/2 1.10
  22110.  
  22111.  Using the following operations in the DOS 3.x box causes OS/2 to crash
  22112.  with a Trap 000D error:
  22113.  
  22114.  1. JOIN A: JOINDIR
  22115.  
  22116.  2. MD \JOINDIR\ABC
  22117.  
  22118.  3. RD \JOINDIR\ABC
  22119.  
  22120.  Also, deleting a JOINed subdirectory is incorrectly allowed in Step 6
  22121.  of the following operations:
  22122.  
  22123.  1. Change to DOS 3.x box
  22124.  
  22125.  2. C:\> JOIN A: JOINDIR
  22126.  
  22127.  3. C:\> MD \JOINDIR\ABC
  22128.  
  22129.  4. C:\> CD \JOINDIR\ABC
  22130.  
  22131.  5. Change to protected mode
  22132.  
  22133.  6. (C:\) RD A:\ABC
  22134.  
  22135.  Microsoft has confirmed these to be problems in Version 1.10. We are
  22136.  researching these problems and will post new information here as it
  22137.  becomes available.
  22138.  
  22139.  
  22140.  656. Using Access and Share Modes with DosOpen()
  22141.  
  22142.  When setting the parameter fsOpenMode to assign the access and share
  22143.  modes for a DosOpen() call, a share mode MUST be specified. An access
  22144.  mode may be bitwise ORed with the share mode, as well as one or more
  22145.  miscellaneous open flags.
  22146.  
  22147.  Refer to the "DosOpen" section of the "Microsoft Operating System/2
  22148.  Programmer's Reference Volume 3," Pages 95-98, for more information on
  22149.  DosOpen().
  22150.  
  22151.  Share modes specify what operations other processes can perform on the
  22152.  opened file. Every DosOpen() call must have a share mode specified.
  22153.  The following are the share modes available for DosOpen() in OS/2
  22154.  Version 1.10:
  22155.  
  22156.       Constant                      Value
  22157.       --------                      ------
  22158.       OPEN_SHARE_DENYREADWRITE      0x0010
  22159.       OPEN_SHARE_DENYWRITE          0x0020
  22160.       OPEN_SHARE_DENYREAD           0x0030
  22161.       OPEN_SHARE_DENYNONE           Ox0040
  22162.  
  22163.  An access mode may be bitwise ORed with the share mode. Access modes
  22164.  specify the operations the opening process may perform on the opened
  22165.  file. The access modes for DosOpen() in OS/2 1.10 are as follows:
  22166.  
  22167.       Constant                      Value
  22168.       --------                      ------
  22169.       OPEN_ACCESS_READONLY          0x0000
  22170.       OPEN_ACCESS_WRITEONLY         0x0001
  22171.       OPEN_ACCESS_READWRITE         0x0002
  22172.  
  22173.  There are four other flags that may be ORed with the share mode in
  22174.  OS/2 1.10. These are:
  22175.  
  22176.       Constant                      Value
  22177.       --------                      ------
  22178.       OPEN_FLAGS_NO_INHERIT         0x0080
  22179.       OPEN_FLAGS_FAIL_ON_ERROR      0x2000
  22180.       OPEN_FLAGS_WRITE_THROUGH      0x4000
  22181.       OPEN_FLAGS_DASD               0x8000
  22182.  
  22183.  When using DosOpen() to open a drive with OPEN_FLAGS_DASD (0x8000), an
  22184.  access mode of 10H is also required.
  22185.  
  22186.  The following is a sample program using DosOpen():
  22187.  
  22188.  #include<os2def.h>
  22189.  #include<bsedos.h>
  22190.  #include<stdio.h>
  22191.  
  22192.  void main(void)
  22193.  {
  22194.      USHORT ret = 0;                /* return code */
  22195.      USHORT Action;                 /* DosOpen returns action taken */
  22196.      HFILE Handle;                  /* file handle variable */
  22197.  
  22198.      ret = DosOpen("direct.c",&Handle, &Action, 0L, FILE_NORMAL,
  22199.                 FILE_OPEN, OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE,
  22200.                 0L);
  22201.  
  22202.      printf("Return value = %hu, action = %hu\n", ret, Action);
  22203.  }
  22204.  
  22205.  
  22206.  657. How to Correctly Install DUALBOOT Option
  22207.  
  22208.  Problem:
  22209.  
  22210.  I cannot install the DUALBOOT option on my machine when using MS-DOS
  22211.  Version 3.30 and OS/2 Version 1.10. I first made a MS-DOS partition,
  22212.  then installed OS/2 Version 1.10 and the DUALBOOT option. During the
  22213.  installation of the DUALBOOT option, I received the following error
  22214.  message:
  22215.  
  22216.     Dual boot cannot be installed because DOS could not be installed
  22217.     on Drive C.
  22218.  
  22219.  Response:
  22220.  
  22221.  This error occurs because the SYS command on the MS-DOS disk failed;
  22222.  there is not enough room for the system files (MS-DOS), or the first
  22223.  two entries in the root directory are not available.
  22224.  
  22225.  To work around this problem, do the following:
  22226.  
  22227.  1. Use FDISK on the drive with either OS/2 or MS-DOS (using MS-DOS
  22228.     guarantees the correct partition size for the MS-DOS system files).
  22229.  
  22230.  2. Format the drive using the MS-DOS FORMAT.COM program with the /s
  22231.     parameter. This will give you the first two slots for MS-DOS. You
  22232.     should be careful that there are no clashes with the MS-DOS utility
  22233.     names; therefore, you should copy the MS-DOS utilities into a
  22234.     separate subdirectory.
  22235.  
  22236.  3. Install OS/2. During the install process, when it asks if you want
  22237.     to install the DUALBOOT option, answer yes. When the system is
  22238.     running, enter "boot /dos" and CTRL+ALT+DEL, and you will boot
  22239.     automatically into MS-DOS.
  22240.  
  22241.  
  22242.  658. DIR > PRN Printer Redirection Error Handling Problem in 1.10
  22243.  
  22244.  Microsoft has confirmed that the following printer error handling
  22245.  problem occurs in Version 1.10. We are researching this problem and
  22246.  will post new information here as it becomes available.
  22247.  
  22248.  The following steps reproduce this problem:
  22249.  
  22250.  1. Disable the print spooler.
  22251.  
  22252.  2. Start the OS/2 command prompt.
  22253.  
  22254.  3. Enter "DIR > PRN".
  22255.  
  22256.  4. Turn off the printer before the DIR command completes.
  22257.  
  22258.  5. Wait until the error box is generated.
  22259.  
  22260.  6. Select "END PROGRAM".
  22261.  
  22262.  7. Turn on the printer; note that the printer does not reset itself.
  22263.  
  22264.  8. Enter "DIR > PRN".
  22265.  
  22266.  Once this error occurs, the printer will not work until it is
  22267.  reinitialized.
  22268.  
  22269.  
  22270.  659. Sending Printer Output to COM1 in OS/2 Versions 1.10, 1.20
  22271.  
  22272.  Problem:
  22273.  
  22274.  I can't get the OS/2 PRINT command to send output to the COM1 port
  22275.  under OS/2 Version 1.10. Under Version 1.00, I only have to do the
  22276.  following:
  22277.  
  22278.     MODE COM1: 9600,N,8,1,XON=ON
  22279.     SPOOL c:\spool /D:lpt1 /O:com1
  22280.  
  22281.  I then enter "PRINT <filename>" to send output to COM1.
  22282.  
  22283.  Under OS/2 Version 1.10, the /D and /O options to SPOOL don't seem to
  22284.  do the same thing as they did in Version 1.00. If I use the same
  22285.  commands (above) under Version 1.10 (ensuring that the Control Panel
  22286.  does not start the spooler first), I can copy a file to COM1 with no
  22287.  problems; however, the use of PRINT or COPY to LPT1 or to PRN causes
  22288.  an error of "SYS0047" (can't write to LPT1 device) to occur.
  22289.  
  22290.  Response:
  22291.  
  22292.  Currently, there are some problems with OS/2 Version 1.10 trying to
  22293.  redirect printer output from LPTn to a COM port. We suggest you use
  22294.  the following steps to redirect printer output from LPTn to a COM
  22295.  port:
  22296.  
  22297.  1. Make sure that the Control Panel printer connection is not on the
  22298.     COM port you want.
  22299.  
  22300.  2. From the command line, issue the MODE command to set the baud rate,
  22301.     etc., for the COM port. For example:
  22302.  
  22303.        MODE COM2:96,n,8,1
  22304.  
  22305.  3. From the command line, issue the SPOOL command to redirect printing
  22306.     from LPTn to a COM port. For example:
  22307.  
  22308.        SPOOL /D:LPT1 /O:COM2
  22309.  
  22310.  4. Go back to the Control Panel and set the printer connection to the
  22311.     COM2 port, then set the COM2 parameters to the same parameters as
  22312.     specified in the MODE command.
  22313.  
  22314.  5. Direct OS/2 to print your file. For example:
  22315.  
  22316.        PRINT /D:LPT1 FILENAME.EXT
  22317.  
  22318.  You now should be able to print to COM2. However, you will not be
  22319.  able to use the SPOOL command a second time for redirection. If you
  22320.  try to do this, the following message is displayed:
  22321.  
  22322.     SYS1793 The Presentation Manager input device specified by
  22323.     the spool command is busy and cannot be used by the spooler
  22324.  
  22325.  Currently, you must go through these steps every time you boot up your
  22326.  machine.
  22327.  
  22328.  Microsoft has confirmed that the workaround listed above does not work
  22329.  in Version 1.20. In Version 1.20, the SPOOL command accepts the
  22330.  redirection of the printer output; however, it doesn't really redirect
  22331.  the printer output. We are researching this problem and will post new
  22332.  information here as it becomes available.
  22333.  
  22334.  
  22335.  660. Named Pipes Can Be Redirected Like Files
  22336.  
  22337.  Question:
  22338.  
  22339.  Can named pipes be used in redirection the same way files are? For
  22340.  example, assuming that I have a named pipe server that made or
  22341.  connected a named pipe called /PIPE/MARK in byte mode, can I do the
  22342.  following?
  22343.  
  22344.     C> dir >/PIPE/MARK
  22345.  
  22346.     C> copy  x.dat  /PIPE/MARK
  22347.  
  22348.     C> echo "This is a string" > /PIPE/MARK
  22349.  
  22350.  Just how far are named pipes embedded in the file system?
  22351.  
  22352.  Response:
  22353.  
  22354.  The commands listed above will work as long as the named pipes are
  22355.  manipulated at the server end with the DosRead() function instead of
  22356.  transacts. In other words, as long as the named pipe is set up
  22357.  correctly, it will work. However, this does mean that the named pipes
  22358.  are not seamlessly embedded into the file system. You cannot find a
  22359.  named pipe on your system and use it in the above fashion and expect
  22360.  it to work every time.
  22361.  
  22362.  
  22363.  661. How to Detect When End of Pipe Has Been Reached
  22364.  
  22365.  Question:
  22366.  
  22367.  How can we detect when we have reached the end of a pipe?
  22368.  
  22369.  Response:
  22370.  
  22371.  For anonymous pipes, there is no way to tell when you have reached the
  22372.  end of the pipe (at least, there is no system-defined method). When
  22373.  you have no bytes in a pipe (whether at the end or there has been no
  22374.  write), a DosRead() will block until something is written. If the pipe
  22375.  has been closed, a DosRead() will return with an error. At this point,
  22376.  you know that you have reached the end of the pipe. You can also set
  22377.  up some sort of communication between processes so that you can send a
  22378.  string of bytes that represents the end of transmission or something
  22379.  similar to this.
  22380.  
  22381.  
  22382.  662. Moving Subdirectory Entries under OS/2
  22383.  
  22384.  Question:
  22385.  
  22386.  We are trying to move a subdirectory entry. We would like to use
  22387.  DosMove(); however, this doesn't work unless we use both DosMkDir()
  22388.  and DosMove() on each of the individual files and subdirectory entry.
  22389.  Is there an easier way to do this?
  22390.  
  22391.  Response:
  22392.  
  22393.  Unfortunately, there is no better way under OS/2 Version 1.10 to move
  22394.  entire subdirectories.
  22395.  
  22396.  
  22397.  663. PRTYC_FOREGROUND Priority Class Is Undocumented in 1.10
  22398.  
  22399.  Microsoft OS/2 has a priority class of 4 and it is called
  22400.  PRTYC_FOREGROUND. It works the same as IBM's "Fixed High" priority
  22401.  class. PRTYC_FOREGROUND became available in OS/2 Version 1.10, but was
  22402.  not documented in either the "Microsoft Operating System/2
  22403.  Programmer's Reference Volume 3 for Version 1.10" (Page 145) or the
  22404.  version of QuickHelp included with the Version 1.10 OS/2 SDK (Software
  22405.  Development Kit. The following is the correct description for
  22406.  PRTYC_FOREGROUND and the other priority classes:
  22407.  
  22408.     Parameter   Description
  22409.     ---------   -----------
  22410.     fPrtyClass  Specifies the priority class of a process or thread.
  22411.                 This can be one of the following values:
  22412.  
  22413.                 Value               Meaning
  22414.                 -----               -------
  22415.                 PRTYC_IDLETIME      Idle time.
  22416.                 PRTYC_NOCHANGE      No change; leave as is.
  22417.                 PRTYC_REGULAR       Regular.
  22418.                 PRTYC_FOREGROUND    Foreground server.
  22419.                 PRTYC_TIMECRITICAL  Time-critical.
  22420.  
  22421.  Comments
  22422.  --------
  22423.  
  22424.  The PRTYC_FOREGROUND priority is higher than PRTYC_REGULAR, but lower
  22425.  than PRTYC_TIMECRITICAL. PRTYC_FOREGROUND is a static priority that is
  22426.  not changed by the system. This allows a thread or process in a
  22427.  background screen group to service requests of a foreground process in
  22428.  a timely manner. Because the priority level is static, this priority
  22429.  should be used only when absolutely necessary. Indiscriminate use
  22430.  degrades system performance.
  22431.  
  22432.  
  22433.  664. DosSetMaxFH() usHandles Parameter Maximum Value Is 32,768
  22434.  
  22435.  Microsoft has confirmed that there is a documentation error on Page
  22436.  142 of the "Microsoft Operating System/2 Programmer's Reference Volume
  22437.  3" for Version 1.10 and in the Version of QuickHelp included with the
  22438.  Version 1.10 OS/2 SDK (Software Development Kit). The documentation
  22439.  incorrectly states that the maximum value for the "usHandles"
  22440.  parameter is 255. The maximum value has been changed to 32,768.
  22441.  
  22442.  We will post new information when the documentation has been updated
  22443.  to correct this error.
  22444.  
  22445.  
  22446.  665. DosPeekNmPipe() "pcbAvail" Parameter Documentation Error
  22447.  
  22448.  The documentation for the DosPeekNmPipe() "pcbAvail" parameter is
  22449.  incorrect on Page 100 of the "Microsoft Operating System/2
  22450.  Programmer's Reference Volume 3" for Version 1.10 and in the Version
  22451.  of QuickHelp included with the Version 1.10 OS/2 SDK (Software
  22452.  Development Kit). This problem was corrected in the version of
  22453.  QuickHelp included in the version of the Presentation Manager Toolkit
  22454.  for Version 1.20.
  22455.  
  22456.  The correct documentation for this parameter is listed below, along
  22457.  with the rest of the documentation for the DosPeekNmPipe() function
  22458.  and the AVAILDATA structure. Please note that a new structure,
  22459.  AVAILDATA, has been defined. This structure definition should be
  22460.  placed in your BSEDOS.H file, along with a corrected function
  22461.  prototype for DosPeekNmPipe().
  22462.  
  22463.  #define INCL_DOSNMPIPES
  22464.  
  22465.  USHORT DosPeekNmPipe(hp, pbBuf, cbBuf, pcbRead, pcbAvail, pfsState)
  22466.  HPIPE hp;             /* pipe handle                               */
  22467.  PBYTE pbBuf;          /* pointer to buffer for data                */
  22468.  USHORT cbBuf;         /* length of buffer for data                 */
  22469.  PUSHORT pcbRead;      /* pointer to variable for number bytes read */
  22470.  PAVAILDATA pAvail;    /* pointer to variable for number bytes
  22471.                           available                                 */
  22472.  PUSHORT pfsState;     /* pointer to variable for pipe state        */
  22473.  
  22474.  The DosPeekNmPipe function copies a pipe's data into a buffer.
  22475.  
  22476.     Parameter  Description
  22477.     ---------  -----------
  22478.     hp         Identifies the pipe to read from.
  22479.  
  22480.     pbBuf      Points to a buffer that receives the data from the pipe.
  22481.  
  22482.     cbBuf      Specifies the length (in bytes) of the buffer that
  22483.                receives the data from the pipe.
  22484.  
  22485.     pcbRead    Points to the variable that receives a value specifying
  22486.                the number of bytes read from the pipe.
  22487.  
  22488.     pAvail     Points to the AVAILDATA structure that the receives a
  22489.                value specifying the number of bytes that were available
  22490.                to be read.
  22491.  
  22492.     pfsState   Points to the variable that receives the state of the
  22493.                pipe. The state may be one of the following values:
  22494.  
  22495.                Value                    Meaning
  22496.                -----                    -------
  22497.                PIPE_STATE_CLOSING       The pipe is closed and can no
  22498.                                         longer be used.
  22499.  
  22500.                PIPE_STATE_CONNECTED     The pipe has been opened and is
  22501.                                         available for reading and
  22502.                                         writing.
  22503.  
  22504.                PIPE_STATE_DISCONNECTED  The serving end must call the
  22505.                                         DosConnectNmPipe function to put
  22506.                                         the pipe into a listening state
  22507.                                         before a call to the DosOpen
  22508.                                         function will be accepted. A pipe
  22509.                                         is in a disconnected state between
  22510.                                         a call to the DosMakeNmPipe
  22511.                                         function and a call to the
  22512.                                         DosConnectNmPipe function.
  22513.  
  22514.                PIPE_STATE_LISTENING     The pipe will accept a call to
  22515.                                         the DosOpen function.
  22516.  
  22517.  Return Value
  22518.  ------------
  22519.  
  22520.  The return value is zero if the function is successful. Otherwise,
  22521.  it is an error value, which may be one of the following:
  22522.  
  22523.     ERROR_BAD_PIPE
  22524.     ERROR_PIPE_NOT_CONNECTED
  22525.  
  22526.  Comments
  22527.  --------
  22528.  
  22529.  The DosPeekNmPipe function never blocks, regardless of the blocking
  22530.  mode of the pipe.
  22531.  
  22532.  If the DosDisConnectNmPipe function has been called, the pipe will
  22533.  remain disconnected until a call is made to the DosConnectNmPipe
  22534.  function.
  22535.  
  22536.  #define INCL_DOSNMPIPES
  22537.  
  22538.  typedef struct _AVAILDATA {    /* avldt */
  22539.      USHORT  cbpipe;
  22540.      USHORT  cbmessage;
  22541.  } AVAILDATA;
  22542.  
  22543.  The AVAILDATA structure contains information about the bytes in a
  22544.  named pipe.
  22545.  
  22546.     Field      Description
  22547.     -----      -----------
  22548.     cbpipe     Specifies the number of bytes left in the pipe.
  22549.  
  22550.     cbmessage  Specifies the number of bytes left in the current
  22551.                message.
  22552.  
  22553.  
  22554.  666. Documentation Incorrect for UNPACK "/v" Switch
  22555.  
  22556.  Microsoft has confirmed that the documentation for the "/v" option of
  22557.  the UNPACK program on Page 142 of the "Microsoft Operating System/2
  22558.  Desktop Reference" for Version 1.10 is incorrect.
  22559.  
  22560.  The documentation should state that when the "/v" option is specified,
  22561.  it enables disk write verification. This means that it has the same
  22562.  meaning and effect as the "/v" switch used with the COPY command.
  22563.  
  22564.  We will post new information when this error has been corrected in the
  22565.  documentation.
  22566.  
  22567.  
  22568.  667. DCBINFO Structure Fields Not Documented Correctly
  22569.  
  22570.  The DCBINFO structure is defined on Pages 263, 270, and 336 in the
  22571.  "Microsoft Operating System/2 Programmer's Reference Volume 3" for
  22572.  Version 1.10. Listed below are the definitions for this structure that
  22573.  demonstrate that three of the fields are named differently on the
  22574.  various pages of the documentation:
  22575.  
  22576.      Pages 263 and 270                 Page 336 and BSEDEV.H
  22577.      -----------------                 ----------------------
  22578.  
  22579.     typedef struct _DCBINFO {          typedef struct _DCBINFO {
  22580.         USHORT usWriteTimeout;             USHORT usWriteTimeout;
  22581.         USHORT usReadTimeout;              USHORT usReadTimeout;
  22582.         BYTE   fbFlages1;                  BYTE   fbCtlHndShake;
  22583.         BYTE   fbFlages2;                  BYTE   fbFlowReplace;
  22584.         BYTE   fbFlages3;                  BYTE   fbTimeout;
  22585.         BYTE   bErrorReplacementChar;      BYTE   bErrorReplacementChar;
  22586.         BYTE   bBreakReplacementChar;      BYTE   bBreakReplacementChar;
  22587.         BYTE   bXONChar;                   BYTE   bXONChar;
  22588.         BYTE   bXOFFChar;                  BYTE   bXOFFChar;
  22589.     } DCBINFO;                         } DCBINFO;
  22590.  
  22591.  The field names for the DCBINFO structure were changed in the Version
  22592.  1.10 OS/2 Software Development Kit (SDK) so that they more clearly
  22593.  documented their intended purpose. The physical definition and use of
  22594.  the DCBINFO structure have not changed.
  22595.  
  22596.  The documentation of the DCBINFO structure as it appears on Page 263
  22597.  and 270 is in error. To be consistent, these pages should be changed
  22598.  to agree with the documentation of the DCBINFO structure as it appears
  22599.  in the header file BSEDEV.H, and as it appears on Page 336.
  22600.  
  22601.  
  22602.  668. Detached QuickHelp Session Hangs If ALT+Q Is Pressed
  22603.  
  22604.  When you issue the command DETACH QH from a full-screen session and
  22605.  hold down the ALT+Q keystroke sequence until the QuickHelp logo screen
  22606.  is displayed, the session appears to hang until you switch to another
  22607.  session, then bring up and terminate the detached QuickHelp session.
  22608.  This problem seems to occur because the ALT+Q keystroke sequence is
  22609.  being held down at the wrong time (i.e., before QuickHelp has finished
  22610.  initializing itself).
  22611.  
  22612.  Microsoft has confirmed this to be a problem in the Version 1.10 OS/2
  22613.  SDK (Software Development Kit). We are researching this problem and
  22614.  will post new information as it becomes available.
  22615.  
  22616.  
  22617.  669. TABLE Referenced But Not Documented in QuickHelp
  22618.  
  22619.  Microsoft has confirmed that in the version of QuickHelp included with
  22620.  the Version 1.10 OS/2 Software Development Kit (SDK) the ACCEL entry
  22621.  lists TABLE as a reference; however, there isn't any further
  22622.  documentation included for TABLE in QuickHelp.
  22623.  
  22624.  We are researching this problem and will post new information as it
  22625.  becomes available.
  22626.  
  22627.  
  22628.  670. KbdClose() Is Not Flushing Keyboard Buffer in OS/2 1.10
  22629.  
  22630.  In OS/2 Version 1.10, KbdClose() does not flush the keyboard buffer
  22631.  before closing the logical keyboard. The following code can be used to
  22632.  duplicate this problem:
  22633.  
  22634.  #define INCL_DOS
  22635.  #define INCL_KBD
  22636.  #include <os2.h>
  22637.  #include <stdio.h>
  22638.  #include <stdlib.h>
  22639.  
  22640.  #ifndef NO_DEBUG
  22641.      #define EXIT_ON_ERROR( szAPI, usErr )                       \
  22642.          {                                                       \
  22643.          if( (usErr) )                                           \
  22644.              {                                                   \
  22645.              printf( "\n%s error %d at line %d in file %s\n",    \
  22646.                      (szAPI), (usErr), __LINE__, __FILE__ );     \
  22647.              exit( (usErr) );                                    \
  22648.              }                                                   \
  22649.          }
  22650.  #else
  22651.      #define EXIT_ON_ERROR( szAPI, usErr )     ;
  22652.  #endif
  22653.  
  22654.  VOID main( VOID )
  22655.      {
  22656.      HKBD    hkbd;
  22657.      USHORT  usError;
  22658.  
  22659.      usError = KbdOpen( &hkbd );
  22660.      EXIT_ON_ERROR( "KbdOpen", usError );
  22661.  
  22662.      usError = KbdGetFocus( 0, hkbd );
  22663.      EXIT_ON_ERROR( "KbdGetFocus", usError );
  22664.  
  22665.      usError = DosSleep( 5000L );
  22666.      EXIT_ON_ERROR( "KbdGetFocus", usError );
  22667.  
  22668.      /*
  22669.      ** usError = KbdFlushBuffer( hkbd );
  22670.      ** EXIT_ON_ERROR( "KbdFlushBuffer", usError );
  22671.      */
  22672.  
  22673.      usError = KbdClose( hkbd );
  22674.      EXIT_ON_ERROR( "KbdClose", usError );
  22675.  
  22676.      } /* End main() */
  22677.  
  22678.  Microsoft has confirmed that if you run the code listed above in
  22679.  either a full-screen group or a VIO text window under PM in Version
  22680.  1.10, either a GP fault occurs or the system crashes. This problem
  22681.  does not occur in Version 1.10 if you call KbdFlushBuffer() before
  22682.  KbdClose() and run the code in a full screen group. However, calling
  22683.  KbdFlushBuffer() before KbdClose() does not help the situation when
  22684.  running the sample code in a VIO window under PM in Version 1.10.
  22685.  
  22686.  We are researching this problem and will post new information as it
  22687.  becomes available.
  22688.  
  22689.  
  22690.  671. When to Use DosExecPgm() and/or DosStartSession()
  22691.  
  22692.  Question:
  22693.  
  22694.  If I make a Presentation Manager (PM) program a detached child
  22695.  process, a protection violation occurs when the parent process starts
  22696.  the child process. Why does this protection violation occur?
  22697.  
  22698.  Response:
  22699.  
  22700.  A protection violation occurs if you execute the child application
  22701.  incorrectly. Listed below is the method that CMD.EXE uses to execute
  22702.  applications. It has to execute full-screen and windowable VIO
  22703.  applications, AVIO applications, and PM applications, from either a
  22704.  full-screen group or the PM screen group. CMD.EXE will use either
  22705.  DosExecPgm() or DosStartSession() to execute a program, based on the
  22706.  type of executable the program to execute is [this is done by reading
  22707.  the EXE header or by using DosQAppType()] and what kind of screen
  22708.  group is currently being run [a field in DosGetInfoSeg()'s
  22709.  LINFOSEG.typeProcess].
  22710.  
  22711.  In summary, DosStartSession() is used to execute PM and AVIO
  22712.  applications. DosStartSession() is also used when CMD is running in
  22713.  the PM screen group and trying to execute a full-screen application,
  22714.  and DosExecPgm() is used when executing VIO applications. The
  22715.  following table shows these relationships:
  22716.  
  22717.     Executable              VIO-Windowable      Full-Screen
  22718.     Type File               Screen Group        Screen Group
  22719.     ----------              ------------        ------------
  22720.  
  22721.     VIO-Full Screen         DosStartSession()   DosExecPgm()
  22722.     VIO-Windowable          DosExecPgm()        DosExecPgm()
  22723.     Advanced VIO            DosStartSession()   DosStartSession()
  22724.     Presentation Manager    DosStartSession()   DosStartSession()
  22725.  
  22726.  
  22727.  672. Interpreting Trap Information in OS/2
  22728.  
  22729.  The following is information on how to interpret and use the
  22730.  information the system provides in an OS/2 trap message.
  22731.  
  22732.  There are two kinds of traps. These traps are described below,
  22733.  followed by a discussion of the information contained in traps and how
  22734.  that information is used:
  22735.  
  22736.  RING 3 TRAPS
  22737.  ------------
  22738.  
  22739.  Ring 3 traps occur at the application level and are usually
  22740.  distinguished by the harderr pop-up that gives you a choice of ending
  22741.  the program. This usually is a protection fault (Trap D) or a stack
  22742.  fault (Trap C). When you get either of these traps, the process has
  22743.  already been killed and has been cleaned up.
  22744.  
  22745.  RING 0 TRAPS
  22746.  ------------
  22747.  
  22748.  Ring 0 traps are a more serious error that occurs in kernel or device
  22749.  driver code. These traps are usually accompanied by the phrases
  22750.  "internal system error" and "the system is stopped." They are serious
  22751.  problems with the kernel and/or your configuration that are not
  22752.  necessarily caused by any one program you might be running.
  22753.  
  22754.  Another issue is the type of OS/2 kernel being used. The different
  22755.  types of kernels are listed below:
  22756.  
  22757.  Retail Kernel
  22758.  -------------
  22759.  
  22760.  The Retail kernel is the kernel that is most likely in use out in the
  22761.  field by most application users, and it is also most likely the
  22762.  development kernel for most application developers. This kernel is
  22763.  somewhat faster and smaller than the debug kernel.
  22764.  
  22765.  Debug Kernel
  22766.  ------------
  22767.  
  22768.  The Debug kernel is used by device driver developers, OS/2 developers,
  22769.  and PM systems developers. Theoretically, it is functionally
  22770.  equivalent to the Retail kernel (it is a superset of the Retail
  22771.  kernel). This kernel has an additional built-in debugging interface,
  22772.  similar to SYMDEB or CodeView in line-sequential mode. It connects to
  22773.  a serial terminal and allows the user to "break" into the system and
  22774.  examine the registers, selectors, privilege levels, etc.
  22775.  
  22776.  The Debug kernel is a must for developing ring 0 code. This kernel is
  22777.  available through the purchase of the OS/2 Device Driver Development
  22778.  Kit (DDDK).
  22779.  
  22780.  Note: OS/2 knows very little about an application or device driver,
  22781.  except its register set and context. OS/2 cannot make guesses about
  22782.  what the application is doing or is attempting to do; it only knows
  22783.  what instruction to execute and the privileges associated with that
  22784.  particular instruction.
  22785.  
  22786.  INFORMATION CONTAINED IN TRAPS
  22787.  ------------------------------
  22788.  
  22789.  With this information in mind, let's return to what is displayed when
  22790.  a trap error occurs. The term "trap" is Intel nomenclature for an
  22791.  exception or error condition that is generated when executing an
  22792.  instruction on the chip. Depending on the sophistication of the
  22793.  operating system, this condition may be made known to the user.
  22794.  
  22795.  Under MS-DOS, these conditions normally result in a system hang,
  22796.  which is not considered user-friendly behavior. However, under OS/2,
  22797.  these conditions take two forms, each of which is associated with
  22798.  the first discussion on ring level traps.
  22799.  
  22800.  At ring 3, the protection layer where applications execute, a trap
  22801.  condition results in the operating system being notified (since the
  22802.  system executive runs at ring 0 and all applications are technically
  22803.  children of the executive) and the system then notifies the user. This
  22804.  notification is in the form of a VioPopUp generated by the harderr
  22805.  mechanism. The VioPopUp will contain the OS/2 session and/or process
  22806.  ID, and the register set context of the process at the time the
  22807.  exception occurred. Granted, this notification is usually accompanied
  22808.  by only one choice for the user, which is termination. However, in
  22809.  most cases, this choice is a better option than having the entire
  22810.  system hang.
  22811.  
  22812.  If a trap occurs at ring 0 in the kernel or a device driver, the
  22813.  problem is more serious. The information displayed is essentially the
  22814.  same as a ring 3 trap, but it is the result of a "panic write." This
  22815.  is a mechanism in the OS/2 kernel that is activated any time the
  22816.  kernel gets out of sync, and finally realizes that it is out of sync.
  22817.  At this point, the system traps and issues a message that means that
  22818.  it is stopping because it is too dangerous to go on, and that the
  22819.  system doesn't know how it got there. The message also tells you where
  22820.  the system is quitting, and the register set and context at the time
  22821.  it stops.
  22822.  
  22823.  Most of the information from this trap dump is a raw dump of the Intel
  22824.  80286 register set. Since OS/2 needs to run on 286 machines as well as
  22825.  386 platforms, it must restrict itself to 286 functionality for the
  22826.  most part. Chapter 9 ("Interrupts and Exceptions") in the "Intel 80286
  22827.  Software Reference" manual is the best reference for interpreting the
  22828.  286 register set.
  22829.  
  22830.  HOW TRAP INFORMATION IS USED
  22831.  ----------------------------
  22832.  
  22833.  Now that we have covered how OS/2 traps are generated and what
  22834.  information they contain, we can move on to how that information might
  22835.  be used.
  22836.  
  22837.  Ring 0 trap information is of no immediate use to an average user or
  22838.  application writer running the retail kernel. About all the user can
  22839.  do is report the trap information and the duplication scenario to the
  22840.  application developer and/or the OS/2 original equipment manufacturer
  22841.  (OEM).
  22842.  
  22843.  However, if you are using the debug kernel, you can (if you know how
  22844.  and choose to do it) break into the system and determine the
  22845.  instruction causing the problem and perhaps the context of how the
  22846.  trap occurs. This will not only help the person experiencing this
  22847.  problem to avoid it, but it will also provide extra information when
  22848.  other people report these types of problems.
  22849.  
  22850.  Ring 0 trap information helps device driver, PM, and OS/2 base
  22851.  developers improve their systems. With the ring 0 trap information and
  22852.  version number of the system being run, a system developer can use the
  22853.  map file and the debugging kernel to determine in which routine the
  22854.  system trapped, and sometimes why it trapped.
  22855.  
  22856.  Ring 3 traps under the retail kernel can be of limited use to the
  22857.  average user. However, although it is an inexact science, an
  22858.  application developer who uses CodeView can break into his application
  22859.  and figure out which segments map to the elements of his load image
  22860.  (programs often load into the same segments on different runs of the
  22861.  program). With the CS:IP values, the information listed above, and a
  22862.  map file, you can determine the routine that trapped out.
  22863.  
  22864.  If the application developer also happens to have a debugging kernel,
  22865.  the application developer then can more easily access the information
  22866.  regarding the state of the application at the time of the trap.
  22867.  
  22868.  As you can see, OS/2 trap messages are the most basic form of OS/2
  22869.  system error reporting. They are fundamentally related to the Intel
  22870.  286/386 chips and the error/exception handling these chips provide.
  22871.  The traps are not very fancy and provide minimal information toward
  22872.  understanding where an application might be failing.
  22873.  
  22874.  This information is worth considerably more to you if you are using
  22875.  the OS/2 debug kernel. If not, you must use other means or tools to
  22876.  help make use of this information such as by using CodeView, linker
  22877.  map files, and other debugging aids that may be available.
  22878.  
  22879.  The following information contains a list of things you might want
  22880.  to look for in the register dump, if you need to try to interpret
  22881.  a dump in the process of writing an application:
  22882.  
  22883.  1. Check the ring level. Bits 5 and 6 of the CSACC byte contain the
  22884.     DPL (descriptor privilege level), also known as the ring level.
  22885.     For more information on DPL, refer to Figure 6-7 of the "Intel
  22886.     80286 Programmer's Reference" manual. If the ring is 3, the
  22887.     trap most likely came from an application. If the ring is 0,
  22888.     the trap probably came from a device driver or the OS/2 kernel.
  22889.  
  22890.  2. Check to see if the LDT (local descriptor table) or GDT (global
  22891.     descriptor table) is being referenced.
  22892.  
  22893.  3. Check to see if the segment registers are nonzero, which they
  22894.     should be.
  22895.  
  22896.  4. Check to see if the SP is beyond the SS.
  22897.  
  22898.  5. Check to see if ES or DS contain an "*" (asterisk), which could
  22899.     means it's pointing to an invalid selector.
  22900.  
  22901.  6. Check the CS:IP value. Depending on the number of code segments
  22902.     and your ability to determine which code segment is in use, the
  22903.     IP will tell you what instruction is failing.
  22904.  
  22905.  Once again, Chapter 9 of the "Intel 80286 Programmer's Reference"
  22906.  manual describes the many 80286 traps and exceptions that could
  22907.  possibly cause a dump to occur.
  22908.  
  22909.  
  22910.  673. THREADS: Using DosSemSetWait() with RAM Semaphores
  22911.  
  22912.  There is a file in the Software/Data Library named THREADS that
  22913.  demonstrates the use of DosSemSetWait() in conjunction with RAM
  22914.  semaphores. THREADS demonstrates how to create, set, and clear a RAM
  22915.  semaphore.
  22916.  
  22917.  THREADS can be found in the Software/Data Library by searching on the
  22918.  keyword THREADS, the Q number of this article, or S12444. THREADS was
  22919.  archived using the PKware file-compression utility.
  22920.  
  22921.  
  22922.  674. CHKDSK On-Line Command Reference Documentation Error
  22923.  
  22924.  In the on-line command reference, under the CHKDSK entry it
  22925.  incorrectly suggests that to repair Drive C, you should boot with the
  22926.  install disk, press ESC to get a command prompt, and then type the
  22927.  following command:
  22928.  
  22929.     CHKDSK C: /F
  22930.  
  22931.  This command doesn't work because CHKDSK.COM is not on the install
  22932.  disk. The following command also doesn't work because you get the
  22933.  message that Drive C is in use by another process:
  22934.  
  22935.     C:\OS2\CHKDSK C: /F
  22936.  
  22937.  To repair Drive C, you should instead do the following:
  22938.  
  22939.  1. Boot with the install disk.
  22940.  
  22941.  2. Press the ESC key to get a command prompt.
  22942.  
  22943.  3. Enter the following command:
  22944.  
  22945.        COPY C:\OS2\CHKDSK.COM D:
  22946.  
  22947.  4. Run CHKDSK with the following command:
  22948.  
  22949.        D:CHKDSK C: /F
  22950.  
  22951.  This works properly because the install disk creates a small virtual
  22952.  Drive D.
  22953.  
  22954.  
  22955.  675. Using DevDone() to Reopen Device
  22956.  
  22957.  Question:
  22958.  
  22959.  I blocked a device by calling ProcBlock() in a strategy routine of a
  22960.  device driver. I then reopened it with the interrupt routine,
  22961.  DevDone(). Is this the correct way to use DevDone()? The parameter of
  22962.  DevDone() is the pointer to a request packet processed when
  22963.  ProcBlock() is called.
  22964.  
  22965.  Response:
  22966.  
  22967.  Yes, you can use DevDone() in this manner. However, it only works if
  22968.  you follow the convention of using the request packet's address as the
  22969.  block ID. DevDone() assumes that is what was used in the block call.
  22970.  
  22971.  DevDone() takes the request packet address and uses it to issue a run
  22972.  to restart the thread. It then uses the address to release the request
  22973.  packet.
  22974.  
  22975.  If you use any other type of convention to generate the block ID, you
  22976.  need to issue a run call yourself to restart the thread.
  22977.  
  22978.  
  22979.  676. OS/2 SDK: CREATEDD Memory Dump Format
  22980.  
  22981.  Question:
  22982.  
  22983.  We want to use the system dump facility [CTRL+ALT+NUM LOCK+NUM LOCK
  22984.  (press NUM LOCK twice)] and CREATEDD to help us debug device drivers
  22985.  we are developing. What is the format of the dump file
  22986.  (DUMPDATA.XXX)?
  22987.  
  22988.  Response:
  22989.  
  22990.  OS/2 currently has a command called CREATEDD that formats a disk for
  22991.  receiving a complete memory dump if you hold down CTRL+ALT and then
  22992.  press the NUM LOCK key twice. However, the output from CREATEDD is
  22993.  generally not useful to anyone but OS/2 system developers -- that is,
  22994.  the developers who are creating OS/2 itself. To make use of the output
  22995.  from CREATEDD, you need to know various internal data structures of
  22996.  OS/2, plus the specific software and hardware configuration of the
  22997.  machine used at the time of the memory dump. IBM does provide a
  22998.  service where under the direction of an IBM service representative,
  22999.  the dump can be sent to IBM for analysis. The tools that IBM uses to
  23000.  perform this analysis are the property of IBM, and Microsoft does not
  23001.  have access to whatever proprietary tools IBM may be using.
  23002.  
  23003.  At this time, Microsoft does not provide any kind of service or
  23004.  documentation (we don't even have any internal documentation) to
  23005.  assist the analysis of this memory dump. Microsoft does supply an
  23006.  OS/2 DDDK (Device Driver Development Kit), which contains a debugging
  23007.  kernel. The debugging kernel should give you the debugging
  23008.  information you need in an understandable format on the screen. If
  23009.  you do not already have the OS/2 DDDK, you can obtain the kit by
  23010.  contacting Microsoft Sales Support at (800) 227-4679 7 AM - 5 PM PST,
  23011.  or contact Microsoft International Customer Service at (206) 882-8661.
  23012.  
  23013.  
  23014.  677. Using C-Stream Function with DosMakePipe() Handle
  23015.  
  23016.  The following program demonstrates the use of C-stream I/O functions
  23017.  with read/write file handles returned by DosMakePipe():
  23018.  
  23019.  /* MKPIPE.C
  23020.   *
  23021.   * Description:
  23022.   *
  23023.   * This program demonstrates the usage of read/write file handles
  23024.   * returned by DosMakePipe() with C stream I/O functions, fputs()
  23025.   * and fgets().
  23026.   *
  23027.   * Compile and link instructions:
  23028.   *
  23029.   *    cl -c -Zi -Od - W3 mkpipe.c
  23030.   *    link /CO mkpipe,,,;
  23031.   *
  23032.   * Execution instructions:
  23033.   *
  23034.   *    mkpipe   (press the ENTER key)
  23035.   *
  23036.   *    MKPIPE prints "hello world" on the screen.
  23037.   *
  23038.   * This software is provided for demonstration purposes only.
  23039.   * Microsoft makes no warranty, either express or implied
  23040.   * as to its usability in any given situation.
  23041.   */
  23042.  
  23043.  #define  INCL_DOSQUEUES
  23044.  #define  INCL_DOSFILEMGR
  23045.  
  23046.  #include <os2.h>
  23047.  #include <stdio.h>
  23048.  #include <fcntl.h>
  23049.    main ()
  23050.  
  23051.      {
  23052.  
  23053.       int rc;
  23054.  
  23055.       HFILE hfRead;        /* pointer to variable for read handle  */
  23056.       HFILE hfWrite;       /* pointer to variable for write handle */
  23057.       USHORT cbPipe = 512; /* number of bytes reserved for pipe    */
  23058.       CHAR  chzBuf[20], *prc;
  23059.       FILE  *fRead, *fWrite ;
  23060.       USHORT cbRead;
  23061.       static CHAR  Message[] = "Hello World\n";
  23062.  
  23063.       rc = DosMakePipe(&hfRead, &hfWrite, cbPipe);
  23064.  
  23065.       if (rc){
  23066.              printf("Error DosMakePipe %i\n", rc);
  23067.              return rc; }
  23068.       else {                                       /* get a FILE pointer */
  23069.              fWrite = fdopen( (int) hfWrite, "w");
  23070.              if (fWrite == NULL)
  23071.                  {
  23072.                   printf("Error fdopen fWrite\n");
  23073.                   return -1; }
  23074.  
  23075.              rc = fputs(Message,fWrite);          /* write to pipe */
  23076.              if (rc ) {
  23077.                   printf("Error fwrite %i\n", rc);
  23078.                   return rc; }
  23079.                                                  /* flush: VERY IMPORTANT */
  23080.              rc = fflush(fWrite);
  23081.              if (rc ) {
  23082.                   printf("Error fflush %i\n", rc);
  23083.                   return rc; }
  23084.  
  23085.              fRead = fdopen( (int) hfRead, "r"); /* get a FILE pointer */
  23086.              if (fRead == NULL)
  23087.                  {
  23088.                   printf("Error fdopen fRead\n");
  23089.                   return -1; }
  23090.                                                         /* read the pipe */
  23091.              prc = fgets(chzBuf, sizeof(chzBuf), fRead);
  23092.              if (prc==NULL) {
  23093.                   printf("Error fgets %i\n", rc);
  23094.                   return rc; }
  23095.              printf("%s\n", chzBuf);
  23096.       }
  23097.                              /* close the read handle of pipe*/
  23098.       rc =  DosClose(hfRead);
  23099.  
  23100.                              /* close the write handle of pipe*/
  23101.       rc =  DosClose(hfWrite);
  23102.   }
  23103.  
  23104.  
  23105.  678. Using Multithreaded DLL with a Device Driver
  23106.  
  23107.  Question:
  23108.  
  23109.  I am trying to design a group of interrelated applications and DLLs
  23110.  (dynamic linked libraries). The following components are involved:
  23111.  
  23112.  1. A character-based device driver interacting with a memory board
  23113.     (real time)
  23114.  
  23115.  2. A DLL buffering request to and from a device driver
  23116.  
  23117.  3. Several applications interacting with the DLL
  23118.  
  23119.  I have the following questions regarding the designing of the
  23120.  interaction between these components:
  23121.  
  23122.  1. Is there any way for the device driver to call the DLL? I would
  23123.     like to have an in and out queue in the DLL. Incoming information
  23124.     has to be queued in as little time as possible, and I am worried
  23125.     that setting a semaphore and waiting for the DLL to unblock and
  23126.     ask for the data would be too slow.
  23127.  
  23128.  2. How can I design a hybrid of an application and a DLL? I need a
  23129.     single executable that can have two active threads at all times
  23130.     (one waiting for information from the device driver and one
  23131.     waiting for application requests to be passed to the device
  23132.     driver). In addition, the executable must export about ten
  23133.     functions to be called by the applications. In other words, is it
  23134.     possible for a DLL to always be active (perhaps started with RUN=
  23135.     in CONFIG.SYS), contain active threads, and still be called by
  23136.     other applications?
  23137.  
  23138.  3. How can I ensure that the data segment of a DLL is never discarded
  23139.     after it has been initialized? After using DosOpen() to get access
  23140.     to the device driver, the DLL must stay in memory. If the DLL is
  23141.     discarded, I need to at least issue a DosClose() call to stop the
  23142.     device driver from buffering data coming from the board.
  23143.  
  23144.  Response:
  23145.  
  23146.  The answers to the above questions are as follows:
  23147.  
  23148.  1. No, the device driver can't call the DLL. You can use a
  23149.     multithreaded DLL to handle requests to the device driver. One
  23150.     thread in the DLL will be used just for this purpose. The device
  23151.     driver can block this thread until the request is complete.
  23152.  
  23153.  2. The RUN command can be used only with a process. However, that
  23154.     process can call a routine or routines in a DLL. You could also
  23155.     start this process with the DETACH command. All application
  23156.     programs are run at ring 3. This means that they are swappable (not
  23157.     the same as discardable). There isn't a method to make them
  23158.     unswappable. For this reason, we suggest a different approach to
  23159.     your problem, explained in the answer to Question 3 listed below.
  23160.  
  23161.  3. You need to use a slightly different approach. You should allocate
  23162.     and lock the memory you need in the device driver. This way the
  23163.     memory will not be swapped out or discarded.
  23164.  
  23165.  
  23166.  679. Limiting Access to Global Variables
  23167.  
  23168.  Question:
  23169.  
  23170.  Our existing product runs under MS-DOS and makes heavy use of global
  23171.  variables. We want to start multiple instances of this program under
  23172.  OS/2, and we want to use threads instead of processes to do this.
  23173.  Since global variables can be seen by any thread, using threads to
  23174.  start multiple instances of the program (as written currently) will
  23175.  not work (all threads would be accessing the same global variables).
  23176.  Local variables can't be used to pass data between functions.
  23177.  
  23178.  Is there a way to get a new set of variables for each thread
  23179.  (variables that could be seen by any functions called within the
  23180.  thread but not by functions in another thread) using C and OS/2?
  23181.  
  23182.  Response:
  23183.  
  23184.  One way to do this is to start with the segregation of your global
  23185.  data into the following types of data:
  23186.  
  23187.  1. Read-only data
  23188.  
  23189.  2. Read/write data
  23190.  
  23191.  For read-only data, each thread can go ahead and read the global data
  23192.  without any problem. For read/write data, you need to create a large
  23193.  global area. You then can use semaphores to protect/serialize the
  23194.  access of this data. You can use DosSemSet() and DosSemClear()
  23195.  semaphore API calls to serialize the access.
  23196.  
  23197.  There are also the DosEnterCritSec() and DosExitCritSec() API calls
  23198.  that can be used so that you can encapsulate the piece of code that
  23199.  manipulates global data. Thus, instead of every thread changing a set
  23200.  of global variables, you can have one routine that has a critical
  23201.  section, and it will be the only routine that can change this data.
  23202.  However, for efficiency, you should keep this piece of code to a
  23203.  minimum. Also, threads should be run at the highest priority in the
  23204.  critical section of the code so that you don't starve other threads of
  23205.  CPU time.
  23206.  
  23207.  Another possible solution is to have a global data manager that
  23208.  resumes/suspends threads when they need to access global data by using
  23209.  the DosResumeThread() and DosSuspendThread() function calls.
  23210.  
  23211.  Also, you can explicitly name allocated memory segments as
  23212.  \SHAREMEM\NAME, or use DosAllocSeg() for shareable segments. You then
  23213.  can pass the selector of the global segments to only those threads
  23214.  that need to see this information. This way, one thread can see part
  23215.  of the global data and another thread can see another part (or none)
  23216.  of the global segment.
  23217.  
  23218.  You can use any or all of these ideas. You can also dynamically
  23219.  allocate a copy of the "global" data segment to each thread and
  23220.  implement your own "write-through" for each thread's personal copy of
  23221.  the "global" data area.
  23222.  
  23223.  We recommend that you use semaphores to serialize data access, since
  23224.  it is the simplest way to accomplish this functionality. Further
  23225.  information on this topic can be found in "Advanced OS/2 Programming"
  23226.  by Ray Duncan.
  23227.  
  23228.  
  23229.  680. LABEL.COM Ignores Parameter Passed by DosExecPgm()
  23230.  
  23231.  Question:
  23232.  
  23233.  If I call the LABEL.COM utility with the DosExecPgm() function, it
  23234.  seems to ignore the drive letter argument (with or without a colon).
  23235.  LABEL.COM always reports just the current drive, yet CMD.EXE seems to
  23236.  have no problem invoking it. LABEL.COM is the only text application
  23237.  I've had any problem executing with arguments. You can work around
  23238.  this problem by invoking CMD.EXE with a "/C LABEL A:" style argument
  23239.  instead.
  23240.  
  23241.  Response:
  23242.  
  23243.  The OS/2 LABEL.COM command seems to require that its command line
  23244.  argument be padded in the following format
  23245.  
  23246.     <ProgramName><Null><Space><arg1><Null><Null>
  23247.  
  23248.  for example
  23249.  
  23250.     LABEL.COM\0 B:\0\0
  23251.  
  23252.  instead of the following (more commonly used) format
  23253.  
  23254.     <ProgramName><Null><arg1><Null><Null>
  23255.  
  23256.  for example
  23257.  
  23258.     LABEL.COM\0B:\0\0
  23259.  
  23260.  In both of the above examples, the argument option to DosExecPgm() is
  23261.  set up to execute LABEL.COM with the option "B:", such as in the
  23262.  following example:
  23263.  
  23264.     LABEL.COM B:
  23265.  
  23266.  However, only the version with the command line built with the space
  23267.  preceding the first command-line argument (after the null that follows
  23268.  the program name) works with LABEL.COM.
  23269.  
  23270.  Microsoft has confirmed that the command-line parsing in LABEL.COM in
  23271.  Version 1.10 is incorrect. We are researching this problem and will
  23272.  post new information here as it becomes available.
  23273.  
  23274.  Sample Programs
  23275.  ---------------
  23276.  
  23277.  Listed below are two sample C programs named FOO.C and BAR.C. FOO.EXE
  23278.  uses DosExecPgm() to execute BAR.EXE, and BAR simply displays its
  23279.  command line. FOO uses both methods listed above to show the
  23280.  difference the space character makes.
  23281.  
  23282.  To test FOO with LABEL.COM, either modify FOO.C to call LABEL.COM
  23283.  instead of FOO.EXE, or copy LABEL.COM to FOO.EXE. When you use the
  23284.  child program of BAR.EXE, both command lines work properly. When you
  23285.  use the child program of LABEL.COM, LABEL works properly only with a
  23286.  space preceding what C programmers call argv[1], the first
  23287.  command-line option.
  23288.  
  23289.  With the method that has NO space in this location, LABEL.COM
  23290.  incorrectly parses the command line and does not find the first
  23291.  command-line argument, thus defaulting to the current drive. For this
  23292.  reason, we recommend using the command-line building method with the
  23293.  space, for compatibility with LABEL.COM.
  23294.  
  23295.  /* -------------------------------------------------------------- */
  23296.  
  23297.  /* FOO.C -- Calls BAR.EXE with various arguments */
  23298.  
  23299.  #include <stdio.h>
  23300.  #include <stdlib.h>
  23301.  #define INCL_DOSPROCESS
  23302.  #include <os2.h>
  23303.  
  23304.  int main(int argc, char *argv[]);
  23305.  
  23306.  int main(int argc, char *argv[])
  23307.  {
  23308.  
  23309.      USHORT usError;
  23310.      char szszBuf[128];
  23311.      RESULTCODES rescResults;
  23312.  
  23313.      printf("Test 1: <ProgramName><Null><arg1><Null><Null>\n");
  23314.      usError = DosExecPgm(szszBuf, sizeof(szszBuf), EXEC_SYNC,
  23315.          "bar.exe\0b:\0\0", 0, &rescResults, "bar.exe\0\0");
  23316.      if (usError)
  23317.          printf("Error %u in DosExecPgm()!\n", usError);
  23318.  
  23319.      printf("Test 2: <ProgramName><Null><Space><arg1><Null><Null>\n");
  23320.      usError = DosExecPgm(szszBuf, sizeof(szszBuf), EXEC_SYNC,
  23321.          "bar.exe\0 b:\0\0", 0, &rescResults, "bar.exe\0\0");
  23322.      if (usError)
  23323.          printf("Error %u in DosExecPgm()!\n", usError);
  23324.  
  23325.      exit(0);
  23326.  
  23327.  } /* main */
  23328.  
  23329.  /* -------------------------------------------------------------- */
  23330.  
  23331.  /* BAR.C -- Displays its arguments as invoked by FOO.EXE */
  23332.  
  23333.  #include <stdio.h>
  23334.  #include <stdlib.h>
  23335.  
  23336.  void main(int argc, char *argv[]);
  23337.  
  23338.  void main(int argc, char *argv[])
  23339.  {
  23340.  
  23341.      printf("%s: %s (argc = %d)\n", argv[0], argv[1], argc);
  23342.      exit(0);
  23343.  
  23344.  }
  23345.  /* -------------------------------------------------------------- */
  23346.  
  23347.  
  23348.  681. KEYB Doesn't Work As a Windowed Application
  23349.  
  23350.  KEYB does not work as a windowed application.
  23351.  
  23352.  To reproduce this problem, enter a window and type "KEYB". The screen
  23353.  clears and then returns to the window.
  23354.  
  23355.  Microsoft has confirmed this to be a problem in Version 1.10. We are
  23356.  researching this problem to see if KEYB was originally designed to
  23357.  only work as a full screen application, because of problems that may
  23358.  occur at the windowed prompt. We will post new information here as it
  23359.  becomes available.
  23360.  
  23361.  
  23362.  682. Input Parameters to VioSetCurType() Not Treated Correctly
  23363.  
  23364.  VioSetCurType() does not treat the input parameters as unsigned
  23365.  integers, as described on Page 240 in the "Microsoft Operating
  23366.  System/2 Programmer's Reference Volume 3" for Version 1.10. If you
  23367.  give VioSetCurType() the following parameters, a 421 error should
  23368.  occur, but it does not:
  23369.  
  23370.     VioHandle(0)
  23371.     startline(256)
  23372.     endline(0)
  23373.     cursorwidth(0)
  23374.     attrib(0)
  23375.  
  23376.  Instead, VioSetCurType() is valid and treats the startline(256) as
  23377.  zero, which infers that the unsigned integer is being treated like a
  23378.  byte and not a 2-byte unsigned integer value as specified. This also
  23379.  applies to endline. This same problem also occurs with the
  23380.  VioGetCurType() function.
  23381.  
  23382.  Microsoft has confirmed this to be a problem in Version 1.10. This
  23383.  problem has been corrected in Version 1.20.
  23384.  
  23385.  
  23386.  683. Using DosError() to Trap Hard Errors
  23387.  
  23388.  Question:
  23389.  
  23390.  How do you check if a floppy disk is available without getting the
  23391.  black screen (abort, retry, ignore) message? Also, is there a way to
  23392.  trap these type of errors from a program?
  23393.  
  23394.  Response:
  23395.  
  23396.  You can trap all hard errors by calling DosError(). However, if you do
  23397.  trap the errors you need to check for them after every call. It is
  23398.  easier to intercept them when you think you may be getting one of
  23399.  these errors (e.g. when you are going to the floppy disk); otherwise,
  23400.  let the system handle them. See the sample code listed below for more
  23401.  information. Please note that this same mechanism works for all hard
  23402.  errors.
  23403.  
  23404.  The following example calls the DosError() function to turn off
  23405.  hard-error processing, calls the DosErrClass() function to process any
  23406.  error that is received, and then turns hard-error processing back on:
  23407.  
  23408.  USHORT usAttribute, usError, usClass, fsAction, usLocus;
  23409.  DosError(HARDERROR_DISABLE);     /* turn off hard-error processing */
  23410.  usError = DosQFileMode("a:\\abc.ext", &usAttribute, 0L);
  23411.  if (usError) {
  23412.      DosErrClass(usError, &usClass, &fsAction, &usLocus);
  23413.      if (usClass == ERRCLASS_HRDFAIL)
  23414.          DosExit(EXIT_PROCESS, 1);
  23415.  DosError(HARDERROR_ENABLE);        /* turn on hard-error processing */
  23416.  
  23417.  
  23418.  684. INT21H Fails with Certain CODEPAGE and COUNTRY Settings
  23419.  
  23420.  The problem listed below occurs when the following settings are used
  23421.  in CONFIG.SYS:
  23422.  
  23423.     CODEPAGE = 437,850
  23424.     COUNTRY  = 001,C\OS2\SYSEM\COUNTRY.SYS
  23425.  
  23426.  The program included below does not control and stop within the "INT
  23427.  21H" routine when it is executed by SYMDEB in the DOS compatibility
  23428.  box:
  23429.  
  23430.     MOV  AX,6501H
  23431.     MOV  BX,1B5H
  23432.     MOV  DX,2CH        ; (Specify a country number except US)
  23433.     MOV  CX,2AH
  23434.     MOV  DI,200H
  23435.     INT  21H
  23436.     INT  3H
  23437.  
  23438.  Microsoft has confirmed this to be a problem in Version 1.10. This
  23439.  problem has been corrected in Version 1.20.
  23440.  
  23441.  
  23442.  685. Identifying Missing DLLs
  23443.  
  23444.  Question:
  23445.  
  23446.  If a dynamic linked library (DLL) that is required by a program is not
  23447.  found when the program is started, OS/2 gives one of two or three
  23448.  error messages, none of which identifies the missing DLL. Is there a
  23449.  way to force OS/2 to consistently identify which DLL is missing?
  23450.  
  23451.  Response:
  23452.  
  23453.  It depends on the type of DLL that is missing and the type of program
  23454.  calling the DLL. If one of the base DLLs from C:\OS2\DLL is missing,
  23455.  you may get an error at boot time and sometimes the system will hang,
  23456.  depending on the DLL.
  23457.  
  23458.  An error message usually is generated for less critical DLLs.
  23459.  
  23460.  For all DLLs requested by an application program or OS/2 utility, it
  23461.  is up to the application to generate the appropriate error message.
  23462.  You can use DosLoadModule() to specifically load a DLL. If the DLL is
  23463.  in a directory defined in the LIBPATH= statement in CONFIG.SYS,
  23464.  DosLoadModule() will load the DLL. You can also use DosGetModHandle()
  23465.  to determine if the DLL is currently loaded. If it isn't loaded, you
  23466.  can load it at run time by using DosLoadModule().
  23467.  
  23468.  Another way to identify the name of a missing DLL is to detach the
  23469.  program that won't load. You will be informed of exactly which DLL was
  23470.  not found.
  23471.  
  23472.  The .EXE file doesn't have to be able to run detached, because it
  23473.  never actually gets to start executing. For example, if you try to run
  23474.  CUE.EXE without its DLL, CUESUBS.DLL, you get the following message:
  23475.  
  23476.     C:\> CUE
  23477.  
  23478.     SYS1804: The system cannot find the file.
  23479.  
  23480.  If you try and detach CUE, you get the following message:
  23481.  
  23482.     C:\> DETACH CUE
  23483.  
  23484.     SYS1804: The system cannot find the file CUESUBS.
  23485.  
  23486.  
  23487.  686. Refresh Command Returns Error If Floppy Disk Is Changed
  23488.  
  23489.  Microsoft has confirmed that the following problem occurs in OS/2
  23490.  Version 1.10 and Version 1.20 with the Refresh command in the File
  23491.  System menu. The following steps can be used to reproduce this
  23492.  problem:
  23493.  
  23494.  1. Open the File System.
  23495.  
  23496.  2. Insert a disk into the floppy disk drive.
  23497.  
  23498.  3. Change the drive to use a floppy drive.
  23499.  
  23500.  4. Open some directory windows.
  23501.  
  23502.  5. Remove the floppy disk and insert another floppy disk that does not
  23503.     have the same pathnames as those of the first floppy disk.
  23504.  
  23505.  6. Choose Refresh from the Window menu.
  23506.  
  23507.  A [PMV1010] error message is displayed. The error message refers to a
  23508.  number of opened files, which are actually the directory windows. The
  23509.  number will be one less than that of the opened directory windows.
  23510.  
  23511.  We are researching this problem and will post new information here as
  23512.  it becomes available.
  23513.  
  23514.  
  23515.  687. DosSetMaxFH() Returns Error If File Handles Are 32768
  23516.  
  23517.  If you use DosSetMaxFH() and set the number of file handles to 32,768,
  23518.  an error is returned if you then issue a DosOpen() call.
  23519.  
  23520.  Microsoft has confirmed this to be a problem in OS/2 Version 1.10.
  23521.  This problem was corrected in Version 1.20.
  23522.  
  23523.  
  23524.  688. TRSEL.EXE Information
  23525.  
  23526.  Question:
  23527.  
  23528.  TRSEL.EXE is a dynamic trace selector program. It is used internally
  23529.  by the system and is not meant to be run by a user. It basically uses
  23530.  the same type of filenames as the trace command, and follows the same
  23531.  rules.
  23532.  
  23533.  
  23534.  689. Refresh Doesn't Work Properly If Floppy Disk Is Changed
  23535.  
  23536.  The problem listed below occurs when using the Refresh command on the
  23537.  File System menu. The following steps can be used to reproduce this
  23538.  problem:
  23539.  
  23540.  1. Open the File System menu.
  23541.  
  23542.  2. Change the Drive selection to use a floppy disk.
  23543.  
  23544.  3. Insert a floppy disk containing some subdirectories into the floppy
  23545.     disk drive.
  23546.  
  23547.  4. Open some directory windows.
  23548.  
  23549.  5. Remove the floppy disk and insert another floppy disk that does not
  23550.     have the same subdirectories as the first floppy disk.
  23551.  
  23552.  6. Choose Refresh from the Window menu.
  23553.  
  23554.  At this time, a [PMV1010] error message should be displayed in
  23555.  proportion to the number of opened files (that is, directory windows)
  23556.  because the floppy disk was changed to a different disk before the
  23557.  Refresh command took place. However, the number of [PMV1010] error
  23558.  messages displayed is less than that of the opened directory windows.
  23559.  
  23560.  Microsoft has confirmed this to be a problem in Version 1.10. We are
  23561.  researching this problem and will post new information here as it
  23562.  becomes available.
  23563.  
  23564.  
  23565.  690. German Keyboard Support Doesn't Work with ANSI.SYS
  23566.  
  23567.  If ANSI.SYS for the DOS 3.x box is loaded, the German-keyboard support
  23568.  in the 3.x box is not available. If you execute the following command
  23569.  
  23570.     CHCP 850 (or 437)
  23571.  
  23572.  the German-keyboard support is available.
  23573.  
  23574.  The CONFIG.SYS entries are as follows:
  23575.  
  23576.     COUNTRY=049,C:\OS2\SYSTEM\COUNTRY.SYS
  23577.     DEVINFO=KBD,GR,C:\OS2\KEYBOARD.DCP
  23578.     DEVICE=C:\OS2\ANSI.SYS
  23579.     CODEPAGE=850,437
  23580.  
  23581.  Microsoft has confirmed this to be a problem with the ANSI.SYS file
  23582.  included with Version 1.20. We are researching this problem and will
  23583.  post new information here as it becomes available.
  23584.  
  23585.  The only workaround is to put a "CHCP 850" (or 437) command in the
  23586.  AUTOEXEC.BAT file.
  23587.  
  23588.  
  23589.  691. Scheduler Doesn't Preempt Execution of DD at Task Time
  23590.  
  23591.  Question:
  23592.  
  23593.  Will the OS/2 system scheduler ever preempt execution of task time
  23594.  code in an installable device driver? In other words, will more than
  23595.  one process ever be allowed to enter the task time section of a device
  23596.  driver at any one time?
  23597.  
  23598.  Response:
  23599.  
  23600.  The scheduler will not preempt the execution of a device driver at
  23601.  task time. If you disable interrupts, you could run forever. If you
  23602.  want to allow other threads to run, you can use the DevHelp() function
  23603.  YIELD or TCYIELD.
  23604.  
  23605.  
  23606.  692. .TYPE Extended Attribute Information
  23607.  
  23608.  Question:
  23609.  
  23610.  The documentation describes the .TYPE EA (Extended Attribute) as
  23611.  "similar to the earlier use of filename extensions" on Page 25 of the
  23612.  "Microsoft Operating System/2 Programmer's Reference Volume 4" for
  23613.  Version 1.20. Does this literally mean that OS/2 will be moving away
  23614.  from using file extensions of .EXE, .CMD, etc., for recognizing
  23615.  executable files? Also, we didn't find any .EXE files with a .TYPE EA
  23616.  in the files included with Version 1.20. Is there a reason for this?
  23617.  
  23618.  Response:
  23619.  
  23620.  We are moving toward using the .TYPE fields rather than file
  23621.  extensions. This transition will take quite a while since most or all
  23622.  current applications aren't yet aware of the .TYPE field or EAs in
  23623.  general. As you noticed, the .EXE files shipped with Version 1.20
  23624.  don't contain .TYPE EAs. This is an example of the fact that it will
  23625.  take a while for more applications to become EA aware.
  23626.  
  23627.  In the case of our .EXE files, the linker would need to be EA aware to
  23628.  write the .TYPE field of the .EXE file when it created the file. Since
  23629.  the linker isn't aware of EAs yet, it didn't add those EAs.
  23630.  
  23631.  
  23632.  693. DosFindFirst() Returns Incorrect Results on HPFS
  23633.  
  23634.  Problem:
  23635.  
  23636.  We are using DosFindFirst() to scan for files that we can open. We are
  23637.  seeing a different type of behavior, depending upon the file system
  23638.  type. In a search for normal files (attributes == 0), using the search
  23639.  specification of ".", we get the following results:
  23640.  
  23641.     Current Directory   FAT File System  HPFS File System
  23642.     -----------------   ---------------  ----------------
  23643.     \pm3                no_more_files    no_more_files
  23644.     \                   no_more_files    success
  23645.  
  23646.  Because DosFindFirst() returns success on an HPFS root directory, we
  23647.  end up doing the scan twice.
  23648.  
  23649.  Response:
  23650.  
  23651.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  23652.  researching this problem and will post new information here as it
  23653.  becomes available.
  23654.  
  23655.  As a possible workaround, you could choose a different filename
  23656.  specification for your search.
  23657.  
  23658.  
  23659.  694. Calculating HEAPSIZE and STACKSIZE
  23660.  
  23661.  Question:
  23662.  
  23663.  How do I calculate the HEAPSIZE and STACKSIZE needed for a given
  23664.  .DEF file? So far, I have just guessed and used 4096 byte jumps.
  23665.  
  23666.  Response:
  23667.  
  23668.  Actually, guessing is a reasonable approach. The HEAPSIZE is not
  23669.  critical, since it is dynamically expanded, as necessary, by the
  23670.  system at run time. An application's stack requirements depend on
  23671.  which OS/2 services it uses. A good estimate for the stack size is
  23672.  double the internal "application" stack requirements.
  23673.  
  23674.  A careful examination of the .MAP file generated by LINK will help you
  23675.  to get a finer perspective on your stack requirements. For more
  23676.  information on .MAP files, please consult your documentation for the
  23677.  Microsoft Macro Assembler and the Microsoft C Compiler. In addition,
  23678.  there is an article in the Knowledge Base on this topic. Please query
  23679.  on the following words:
  23680.  
  23681.     dgroup and origin and map and 20 and text and description
  23682.  
  23683.  Finally, listed below is some general information relating to
  23684.  HEAPSIZE and STACKSIZE:
  23685.  
  23686.  1. The local heap is located in DGROUP along with the near data and
  23687.     default stack. Memory can be allocated from the heap with
  23688.     malloc(), related Microsoft C Compiler run-time functions, and
  23689.     some Presentation Manager (PM) functions that let you allocate
  23690.     memory from the heap.
  23691.  
  23692.     Regardless of the heap's initial size, it is expanded at run time
  23693.     whenever necessary until DGROUP has reached its maximum size of
  23694.     65,536 bytes. If HEAPSIZE is absent, the default initial heap size
  23695.     is 0 bytes.
  23696.  
  23697.  2. STACKSIZE defines the size of the application's default stack
  23698.     (that is, the stack that is used by the application's primary
  23699.     thread when it is first entered from OS/2).
  23700.  
  23701.     The recommended general size is 2K for base API OS/2 applications
  23702.     and 8K for PM applications that create a window. Increase this as
  23703.     necessary.
  23704.  
  23705.     If the STACKSIZE directive is present, it overrides any stack
  23706.     segment declared in the application source code, or with the linker
  23707.     /STACK switch.
  23708.  
  23709.  
  23710.  695. PRINT /C Command Doesn't Cancel Printing in OS/2 SDK 1.10
  23711.  
  23712.  Printing cannot be canceled with the PRINT /C command after some files
  23713.  are queued up to be printed with the PRINT command at the OS/2
  23714.  full-screen command prompt. The following steps can be used to
  23715.  reproduce this problem:
  23716.  
  23717.  1. Queue up some files to be printed with the PRINT command at the
  23718.     OS/2 full-screen command prompt.
  23719.  
  23720.  2. Enter a PRINT /C command to cancel the printing of the files.
  23721.  
  23722.  3. Open the Print Queue Manager. The files that are waiting to be
  23723.     printed are all printed, with "printing" displayed next to them.
  23724.  
  23725.  Microsoft has confirmed this to be a problem in Version 1.10. We are
  23726.  researching this problem and will post new information here as it
  23727.  becomes available.
  23728.  
  23729.  
  23730.  696. OS/2 Physical Interrupt Utilization
  23731.  
  23732.  Question:
  23733.  
  23734.  I am building some hardware to run under OS/2 and would like to know
  23735.  which physical interrupts I can use. Also, which interrupts does OS/2
  23736.  use?
  23737.  
  23738.  Response:
  23739.  
  23740.  The following is a list of the interrupts OS/2 uses:
  23741.  
  23742.     IRQ 0 is the 8254 timer
  23743.     IRQ 1 is the keyboard
  23744.     IRQ 2 is used to connect to the second PIC
  23745.     IRQ 8 is the MC146818 RTC
  23746.     IRQ 13 is the 80287
  23747.  
  23748.  The following interrupts are not set by OS/2 but by the device drivers
  23749.  when they are loaded:
  23750.  
  23751.     IRQ3  - COM2
  23752.     IRQ4  - COM1
  23753.     IRQ5  - LPT2
  23754.     IRQ6  - Floppy
  23755.     IRQ7  - LPT1
  23756.     IRQ9  - EGA may use this, but not all EGAs do.
  23757.     IRQ14 - Hard disk
  23758.  
  23759.  If a mouse is installed, it will generally use IRQ3 or IRQ5. Thus, the
  23760.  following interrupts are generally available:
  23761.  
  23762.     IRQ10, IRQ11, IRQ12, and IRQ15
  23763.  
  23764.  
  23765.  697. Death of Thread 1 and Continuation of Other Threads
  23766.  
  23767.  Question:
  23768.  
  23769.  In OS/2 Version 1.00, if thread 1 exits with the following statement
  23770.  
  23771.     DosExit(EXIT_THREAD,0)
  23772.  
  23773.  and there are still some other threads alive, the process remains
  23774.  active until the last thread dies. When I run this same statement with
  23775.  OS/2 Version 1.10, I find that if thread 1 exits in this manner, the
  23776.  process terminates. Was the DosExit() function changed in OS/2 Version
  23777.  1.10?
  23778.  
  23779.  Response:
  23780.  
  23781.  Yes, there was a change to OS/2 Version 1.10. When thread 1 exits, the
  23782.  process should terminate: that is, all threads in that process are
  23783.  terminated. This was incorrect behavior in OS/2 Versions 1.0x;
  23784.  however, it was corrected in OS/2 Version 1.10. See Chapters 5 and 12
  23785.  of Gordon Letwin's "Inside OS/2" book for a discussion on this topic.
  23786.  Thread 1 is the thread that receives signals from the operating
  23787.  system. If thread 1 (the thread that receives the signals from the
  23788.  outside world) is killed, there should be no way for the application
  23789.  to receive signals.
  23790.  
  23791.  
  23792.  698. Message Mode Pipe Versus Byte Mode Pipe Operation
  23793.  
  23794.  Question:
  23795.  
  23796.  What is the difference in operations of reading and writing to message
  23797.  mode pipes, as opposed to byte mode pipes?
  23798.  
  23799.  Response:
  23800.  
  23801.  Message mode pipes have a header attached to each message as opposed
  23802.  to a byte mode pipe, which is just a byte stream. When a DosRead()
  23803.  call is done on a message pipe, and the message is larger than the
  23804.  (read) buffer, you get part of the message in the (read) buffer, and
  23805.  an error code of ERROR_MORE_DATA. When using message pipes, you can do
  23806.  a DosPeekNmPipe() call to determine the size of the remaining data,
  23807.  and then do a DosRead() call on the second part of the message. In
  23808.  byte mode, this type of error code (ERROR_MORE_DATA) is not returned.
  23809.  
  23810.  In byte mode, a unit of information is a byte, whereas in message mode
  23811.  the unit of information is a message, no matter what size the message
  23812.  may be. The best way to test the difference is to write/read messages
  23813.  that are larger than the (read) buffer as explained above.
  23814.  
  23815.  More specifically, a byte mode pipe behaves like an anonymous pipe,
  23816.  where all data that is written is transferred without any special
  23817.  processing performed on it. In message mode, a named pipe can
  23818.  distinguish between different messages and the size of each message.
  23819.  
  23820.  
  23821.  699. DosWrite() Write Behind Bit Information
  23822.  
  23823.  Question:
  23824.  
  23825.  What does the write behind bit do when set?
  23826.  
  23827.  Response:
  23828.  
  23829.  The write behind bit applies to DosWrite(). If this bit is set,
  23830.  DosWrite() returns before the buffer has been written to the remote
  23831.  device. A corresponding parameter is bit 2 in server heuristic, in
  23832.  LANMAN.INI of the server. If this bit is set, it tells the client that
  23833.  a write is complete before actually performing the write. If the write
  23834.  generates an error, the error code is returned in the subsequent
  23835.  write.
  23836.  
  23837.  
  23838.  700. Debugging Process Under CVP with DosPTrace()
  23839.  
  23840.  Listed below is an example of the DosPTrace() function. The following
  23841.  code will allow you to single step through a process that is indicated
  23842.  by argv[1] on the command line:
  23843.  
  23844.  #define INCL_BASE
  23845.  #define INCL_DOSTRACE
  23846.  #include <os2.h>
  23847.  #include <stdio.h>
  23848.  
  23849.  /***** Definitions *****/
  23850.  
  23851.  /* Ptrace command numbers */
  23852.  
  23853.  #define TRC_C_Null         0   // Null
  23854.  #define TRC_C_ReadMem      1   // Read Word
  23855.  #define TRC_C_ReadMem_I    1   // Read Word (instruction)
  23856.  #define TRC_C_ReadMem_D    2   // Read Word (data)
  23857.  #define TRC_C_ReadReg      3   // Read Registers
  23858.  #define TRC_C_WriteMem     4   // Write Word
  23859.  #define TRC_C_WriteMem_I   4   // Write Word (instruction)
  23860.  #define TRC_C_WriteMem_D   5   // Write Word (data)
  23861.  #define TRC_C_WriteReg     6   // Write Registers
  23862.  #define TRC_C_Go           7   // Go
  23863.  #define TRC_C_Term         8   // Terminate
  23864.  #define TRC_C_SStep        9   // Single Step
  23865.  #define TRC_C_Stop         10  // Stop
  23866.  #define TRC_C_Freeze       11  // Freeze Thread
  23867.  #define TRC_C_Resume       12  // Resume Thread
  23868.  #define TRC_C_NumtoSel     13  // Segment Number to Selector
  23869.  #define TRC_C_GetFPRegs    14  // Get 80287 Registers
  23870.  #define TRC_C_SetFPRegs    15  // Set 80287 Registers
  23871.  #define TRC_C_GetLibName   16  // Get Library Name
  23872.  #define TRC_C_ThrdStat     17  // Thread Status
  23873.  #define TRC_C_MapROAlias   18  // Map Read-Only Memory Alias
  23874.  #define TRC_C_MapRWAlias   19  // Map Read-Write Memory Alias
  23875.  #define TRC_C_UnMapAlias   20  // UnMap Memory Alias
  23876.  
  23877.  /* Notification Numbers */
  23878.  
  23879.  #define TRC_C_SUC_ret           0   // Success
  23880.  #define TRC_C_ERR_ret          -1   // Error
  23881.  #define TRC_C_SIG_ret          -2   // Signal
  23882.  #define TRC_C_TBT_ret          -3   // Single-Step
  23883.  #define TRC_C_BPT_ret          -4   // Breakpoint
  23884.  #define TRC_C_NMI_ret          -5   // NMI (NOT USED)
  23885.  #define TRC_C_KIL_ret          -6   // Process Termination
  23886.  #define TRC_C_GPF_ret          -7   // GP Fault
  23887.  #define TRC_C_LIB_ret          -8   // DLL Library Attachment
  23888.  #define TRC_C_FPE_ret          -9   // Floating Point Error
  23889.  #define TRC_C_THD_ret          -10  // Thread Termination
  23890.  #define TRC_C_STP_ret          -11  // Asynchronous Stop
  23891.  #define TRC_C_NEW_ret          -12  // New Process
  23892.  #define TRC_C_AFR_ret          -13  // Alias Free
  23893.  
  23894.  /* Error numbers with TRC_C_ERR_ret */
  23895.  
  23896.  #define trace_bad_command       1   // command failed
  23897.  #define trace_child_not_found   2   // process not found
  23898.  #define trace_child_untraceable 5   // cannot debug this process
  23899.  
  23900.  /***** Function Prototypes *****/
  23901.  
  23902.  int main(int argc, char *argv[]);
  23903.  
  23904.  int main(int argc, char *argv[])
  23905.  {
  23906.  
  23907.      CHAR  pchFailBuf[128];
  23908.      RESULTCODES result;
  23909.      PTRACEBUF  ptrbuf;
  23910.  
  23911.      printf("Result of execing %s is %u\n",
  23912.           argv[1],
  23913.           DosExecPgm(pchFailBuf,128,EXEC_ASYNC | EXEC_TRACE,
  23914.                   0,0,&result,argv[1]));
  23915.  
  23916.      /* Debug the direct child until notified of child executed */
  23917.  
  23918.      printf("Debugging %s...\n",argv[1]);
  23919.  
  23920.      ptrbuf.pid = result.codeTerminate;
  23921.      ptrbuf.cmd = TRC_C_SStep;
  23922.  
  23923.      while(1)
  23924.      {
  23925.       DosPTrace((PVOID)&ptrbuf);
  23926.       printf("Result of trace = %d\n",ptrbuf.value);
  23927.      }
  23928.  
  23929.      return(0);
  23930.      argc;
  23931.  }
  23932.  
  23933.  
  23934.  701. Creating Session That Is Invisible to Task Manager
  23935.  
  23936.  Question:
  23937.  
  23938.  Is it possible to create a session using DosStartSession() that does
  23939.  not appear as a selectable/destroyable item in the Task Manager shell?
  23940.  
  23941.  Response:
  23942.  
  23943.  After creating a session with DosStartSession(), you can use the
  23944.  DosSetSession() API to accomplish what you are trying to do. The
  23945.  DosSetSession() function allows a parent session to use the
  23946.  "SelectInd" and "BondInd" fields of the STATUSDATA structure to
  23947.  specify whether the child session can be selected by the user, and
  23948.  whether or not the child session will be brought to the foreground
  23949.  when the user selects the parent session.
  23950.  
  23951.  
  23952.  702. OS/2 and LAN Manager Installation Problem Causes Hang
  23953.  
  23954.  Problem:
  23955.  
  23956.  When I modify my CONFIG.SYS file to work with OS/2 LAN Manager
  23957.  Version 2.00, the system hangs after painting the screen and the
  23958.  mouse pointer, but before the MS-DOS icon is painted on the screen.
  23959.  The mouse moves, but none of the keystrokes appear to work.
  23960.  
  23961.  Response:
  23962.  
  23963.  This problem is due to a basic antagonism between the OS/2 LAN Manager
  23964.  spooler and the PM spooler. If you wish to run OS/2 LAN Manager and
  23965.  the OS/2 LAN Manager spooler, you must copy \LANMAN\NETLIB\PMPRINT.QPR
  23966.  to \OS2\DLL and place the \LANMAN\NETLIB at the beginning of the
  23967.  LIBPATH statement, which is set in your CONFIG.SYS file. You must also
  23968.  delete the \SPOOL subdirectory.
  23969.  
  23970.  To go back to the PM spooler, delete the \SPOOL subdirectory, remove
  23971.  \LANMAN\NETLIB from the LIBPATH statement, or at least move it to the
  23972.  end of the path, and copy the PM spooler back into the \OS2\DLL
  23973.  subdirectory.
  23974.  
  23975.  
  23976.  703. Internal Consistency Error Occurs When Starting Spooler
  23977.  
  23978.  Question:
  23979.  
  23980.  I receive an "internal consistency error" when I start the spooler.
  23981.  What causes this error to occur?
  23982.  
  23983.  Response:
  23984.  
  23985.  The C:\LANMAN\NETLIB subdirectory must be listed as the first
  23986.  subdirectory in the LIBPATH= statement in your CONFIG.SYS file. If
  23987.  \OS2\DLL is listed as the first subdirectory in your LIBPATH=
  23988.  statement, then the OS/2 LAN Manager will get some Hursley spooler
  23989.  components and will refuse to work properly.
  23990.  
  23991.  
  23992.  704. DosExecPgm() "fExecFlags" Documentation Error
  23993.  
  23994.  Question:
  23995.  
  23996.  I am having a problem in which I am not getting notified when my child
  23997.  spawns a process while using DosPtrace().
  23998.  
  23999.  The documentation for DosExecPgm() states that a value of EXEC_TRACE
  24000.  (3) in the "fExecFlags" parameter causes a child to be traced. This is
  24001.  true, but it only applies to the direct child. If the direct child
  24002.  spawns children, the PTRACE'er is not notified. I have found by
  24003.  experimenting that using a value of 6 for "fExecFlags" causes other
  24004.  child to be traced and notification of all spawns to be sent to the
  24005.  PTRACE'er. This is not documented in either QuickHelp or in the
  24006.  Microsoft OS/2 programmer's reference manuals, but it seems to work.
  24007.  
  24008.  Is this the correct value to use to trace spawned children and be
  24009.  notified of all spawns?
  24010.  
  24011.  Response:
  24012.  
  24013.  Yes, this value for the "fExecFlags" works as stated above. Microsoft
  24014.  has confirmed that this information was inadvertently left out of the
  24015.  "Microsoft Operating System/2 Programmer's Reference Volume 3" for
  24016.  Version 1.10 on Page 45, and in QuickHelp. We will post new
  24017.  information here once the documentation is updated to correct this
  24018.  error.
  24019.  
  24020.  
  24021.  705. OS/2 SDK: DosDevIOCtl() and Track Layout Table
  24022.  
  24023.  Question:
  24024.  
  24025.  I am building an application that collects data from an interface and
  24026.  stores the data on a floppy disk. I would like to maximize the
  24027.  transfer rate to the floppy disk. A file system is not required. I
  24028.  want to use the DosDevIOCtl() function to read/write data to the
  24029.  floppy disk. The track layout table is confusing to me, and I cannot
  24030.  figure out how to use it. The questions I have are as follows:
  24031.  
  24032.  1. What is meant by "usFirstSector"?
  24033.  
  24034.  2. How do you know what track you are using when a read or write is
  24035.     issued?
  24036.  
  24037.  3. Which tracks correspond to which logical head?
  24038.  
  24039.  4. Can you format a floppy disk using DosDevIOCtl() commands?
  24040.  
  24041.  5. To use DosDevIOCtl(), must I "open" a file to get a handle?
  24042.  
  24043.  6. What is Microsoft's recommendation on how to maximize disk
  24044.     performance?
  24045.  
  24046.  Response:
  24047.  
  24048.  The answers to the above questions are as follows:
  24049.  
  24050.  1. "usFirstSector" is the index into the track table that you wish
  24051.     to start the readtrack from. This is a value of 0-n, where n
  24052.     represents the number of sectors per track, minus 1.
  24053.  
  24054.  2. You specify the track with the cylinder/head combination.
  24055.  
  24056.  3. Track 0 starts at cylinder 0, head 0. Track 1 at cylinder 0, head
  24057.     1, etc.
  24058.  
  24059.  4. Yes, you can. Included below is some sample code that shows the
  24060.     basic methods of how to perform this functionality.
  24061.  
  24062.  5. Yes, you must open the device (such as "a:").
  24063.  
  24064.  6. The fastest method to write to a disk is with the IOCtls, so you
  24065.     are already using the preferred method. We suggest that you buffer
  24066.     the reads and writes, and deal with track size reads and writes to
  24067.     make sure you write as much as you can every time.
  24068.  
  24069.  Format Code
  24070.  -----------
  24071.  
  24072.  Compile with /Zp /W3 /Lp
  24073.  
  24074.  #define INCL_BASE
  24075.  #define INCL_DOSDEVIOCTL
  24076.  #include <os2.h>
  24077.  
  24078.  #include <stdio.h>
  24079.  
  24080.  #define  FORMAT_TABLE_SIZE  0x0004
  24081.  
  24082.  int main(int argc, char *argv[]);
  24083.  
  24084.  int main(int argc, char *argv[])
  24085.  {
  24086.      /* Variables for DosOpen */
  24087.  
  24088.      HFILE      hfile;
  24089.      USHORT     usAction;
  24090.      ULONG      ulFileSize  = 0L;
  24091.      USHORT     usAttrs     = FILE_NORMAL;
  24092.      USHORT     usOpenFlags = FILE_OPEN;
  24093.      USHORT     usOpenMode  = OPEN_SHARE_DENYNONE | OPEN_FLAGS_DASD;
  24094.      ULONG      ulReserved  = 0L;
  24095.  
  24096.      /* Variables for DosDevIOCtl() */
  24097.  
  24098.      USHO\023\021RT          usCommand   = 0;
  24099.  
  24100.      TRACKFORMAT FAR    *tf;
  24101.      BIOSPARAMETERBLOCK   bpb;
  24102.      USHORT          getcommand  = 0x0000;
  24103.      USHORT          setcommand  = REPLACE_BPB_FOR_MEDIUM;
  24104.  
  24105.      /* Variable for DosAllocSeg */
  24106.      SEL        sel;
  24107.  
  24108.      /* Variables for looping through the tracks on the disk */
  24109.  
  24110.      BYTE       bIndex;
  24111.      USHORT     usTotalCylinders;
  24112.  
  24113.      USHORT     usRetCode;
  24114.  
  24115.      /* Open the disk specified in argv[1], get the device parameters
  24116.         for the drive, and set the parameters for the medium to those
  24117.         of the drive. */
  24118.  
  24119.      usRetCode = DosOpen(argv[1],&hfile,&usAction,ulFileSize,usAttrs,
  24120.                 usOpenFlags,usOpenMode,ulReserved);
  24121.  
  24122.      if(usRetCode == 0)
  24123.       usRetCode = DosDevIOCtl(&bpb,&getcommand,DSK_GETDEVICEPARAMS,
  24124.                      0x0008,hfile);
  24125.  
  24126.      if(usRetCode == 0)
  24127.       usRetCode = DosDevIOCtl(&bpb,&setcommand,DSK_SETDEVICEPARAMS,
  24128.                      0x0008,hfile);
  24129.  
  24130.      /* Allocate memory to hold the TRACKFORMAT structure */
  24131.  
  24132.      if(usRetCode == 0)
  24133.       usRetCode = DosAllocSeg(sizeof(TRACKFORMAT) +
  24134.                      (FORMAT_TABLE_SIZE * bpb.usSectorsPerTrack),
  24135.                      &sel, SEG_NONSHARED);
  24136.  
  24137.      if(usRetCode == 0)
  24138.      {
  24139.  
  24140.       tf = (TRACKFORMAT FAR *) MAKEP(sel,0);
  24141.  
  24142.       tf->bCommand   = 0x0001;
  24143.       tf->usReserved = 0;
  24144.       tf->cSectors   = bpb.usSectorsPerTrack;
  24145.  
  24146.       usTotalCylinders = (bpb.cSectors / bpb.usSectorsPerTrack)
  24147.                          / bpb.cHeads;
  24148.  
  24149.       for(bIndex = 0; bIndex < (BYTE) bpb.usSectorsPerTrack; bIndex++)
  24150.       {
  24151.          tf->FormatTable[bIndex].idSector = bIndex + 1;
  24152.          tf->FormatTable[bIndex].bBytesSector = 2;
  24153.       }
  24154.  
  24155.       for(tf->usCylinder = 0; tf->usCylinder < usTotalCylinders;
  24156.           tf->usCylinder++)
  24157.       {
  24158.           tf->FormatTable[bIndex].bCylinder = (BYTE) tf->usCylinder;
  24159.  
  24160.           for(tf->usHead = 0; tf->usHead < bpb.cHeads; tf->usHead++)
  24161.           {
  24162.            tf->FormatTable[bIndex].bHead      = (BYTE) tf->usHead;
  24163.            usRetCode = DosDevIOCtl(&usCommand,(PBYTE)tf,
  24164.                           DSK_FORMATVERIFY,0x0008,hfile);
  24165.            printf("Cylinder %03u, Head %u formatted\r",tf->usCylinder,
  24166.                 tf->usHead);
  24167.           }
  24168.       }
  24169.      }
  24170.  
  24171.      if(usRetCode != 0)
  24172.       printf("An error occurred while formatting the disk.");
  24173.  
  24174.      return(usRetCode);
  24175.  
  24176.      /* The following variable does not get accessed and is here to
  24177.         avoid a /W3 compiler warning message. */
  24178.  
  24179.      argc;
  24180.   }
  24181.  
  24182.  
  24183.  706. SET Returns Error Incorrectly at Full Screen Prompt
  24184.  
  24185.  When OS/2 executes the SET command from the command prompt, the
  24186.  results are not consistent with the results arising when OS/2 executes
  24187.  the SET command during processing of the CONFIG.SYS file at boot time.
  24188.  
  24189.  If you use the following command at the OS/2 full screen or screen
  24190.  command prompt, a "SYS1003: The syntax of the command is incorrect"
  24191.  error message is returned:
  24192.  
  24193.     SET a=b=c=d
  24194.  
  24195.  However, if you insert the same SET statement into your CONFIG.SYS
  24196.  file and then reboot your system, no error message is returned.
  24197.  Setting PAUSEONERROR=YES in your CONFIG.SYS file does not change this
  24198.  behavior.
  24199.  
  24200.  Microsoft has confirmed that this inconsistency occurs in Version
  24201.  1.20. We are researching this problem and will post new information
  24202.  here as it becomes available.
  24203.  
  24204.  
  24205.  707. PRINT /C and /T Options Don't Cancel Print Jobs Correctly
  24206.  
  24207.  Microsoft has confirmed that the following problems occur with the /C
  24208.  and /T options of the PRINT command in Microsoft OS/2 Versions 1.10
  24209.  and 1.20. This is true for both the PM spooler and the OS/2 LAN
  24210.  Manager spooler, although the behavior is slightly different,
  24211.  depending on which spooler you are using. Please note that you can
  24212.  work around these problems by canceling the print jobs from the Print
  24213.  Manager program. We are researching these problems and will post new
  24214.  information here as it becomes available.
  24215.  
  24216.  The following information describes these problems in more detail.
  24217.  Before performing the steps below, you need to save either one or
  24218.  several files in the queue by using the "hold queue" option in the
  24219.  Print Manager. Release the "hold queue" after opening an OS/2 window
  24220.  to type the commands listed below.
  24221.  
  24222.  The following problem occurs when only one file has been saved in the
  24223.  queue:
  24224.  
  24225.  If you enter PRINT/C or PRINT/T, the file is still printed out. If you
  24226.  press CTRL+C just after entering PRINT/C, the following error message
  24227.  is displayed:
  24228.  
  24229.     SYS1780: The PRINT command has detected an unexpected Presentation
  24230.              Manager error.
  24231.  
  24232.  The following problem occurs when several files have been saved in the
  24233.  queue:
  24234.  
  24235.  If you enter PRINT/C, the files are still printed out. However, if you
  24236.  enter PRINT/T, printing ceases and the files are not printed out.
  24237.  
  24238.  If you enter PRINT/T while the first file is being printed, only
  24239.  the first file will be printed (all other files will not).
  24240.  
  24241.  If you press CTRL+C right after entering PRINT/C or PRINT/T, these
  24242.  commands do not take effect and the following error message is
  24243.  displayed:
  24244.  
  24245.     SYS1780: The PRINT command has detected an unexpected Presentation
  24246.              Manager error.
  24247.  
  24248.  
  24249.  708. Getting/Setting Extended Attribute Information
  24250.  
  24251.  The following are questions about EAs (extended attributes):
  24252.  
  24253.  1. Is there a way to obtain all of the EAs for a file by using the
  24254.     DosQFileInfo() function? It appears that you have to fill in the
  24255.     GEALIST with the name of each attribute that you want information
  24256.     about. The only way that I've been able to do this is to use the
  24257.     DosEnumAttribute() function.
  24258.  
  24259.     You need to fill in the GEALIST with values. This is required. One
  24260.     good reason for this is so you can calculate the total space you
  24261.     need to hold the FEALIST. The DosEnumAttribute() function provides
  24262.     this functionality. For OS/2 Version 1.20, this call is
  24263.     unnecessary if you always use a 64K segment for the FEALIST.
  24264.     However, this limitation will be raised in future versions of
  24265.     OS/2; therefore, you will have to go through this process in the
  24266.     future.
  24267.  
  24268.  2. In the case of existing files that I don't want to truncate, can I
  24269.     get the EAs when I open the file or must I use the DosQFileInfo()
  24270.     function?
  24271.  
  24272.     You must use DosQFileInfo(). When opening a file, you can only set
  24273.     attributes, not get them.
  24274.  
  24275.  3. Do I have to use the DosSetFileInfo() function or can I set the
  24276.     attributes when the file is being opened?
  24277.  
  24278.     You can set the attributes when opening the file, only for files
  24279.     that are being created, replaced, or truncated. Otherwise, you will
  24280.     have to set the attributes with the DosSetFileInfo() function.
  24281.  
  24282.  
  24283.  709. XON/XOFF Flow Control in COM1 Driver
  24284.  
  24285.  The following are questions about the XON/XOFF flow control in the
  24286.  COM1 driver:
  24287.  
  24288.  1. What is the size of the default receive buffer in the OS/2
  24289.     Version 1.10 COM1 driver?
  24290.  
  24291.     The default receive buffer size is 1025 bytes. This number is
  24292.     subject to change, as any original equipment manufacturer (OEM) can
  24293.     change this value (they have the source to the COM1 driver).
  24294.  
  24295.  2. If we are controlling the flow of incoming characters by sending
  24296.     XON/XOFF characters, what are the "trigger" points for the XON and
  24297.     XOFF transmissions? Can these "trigger" points be changed?
  24298.  
  24299.     The "trigger" points are 850 bytes and 400 bytes. These numbers are
  24300.     from the OS/2 Version 1.10 Device Driver Developer's Kit (DDDK).
  24301.     These values cannot be changed on the fly, since there is no
  24302.     DosDevIOCtl() command to do this. If you write your own COM1
  24303.     driver, you can use different values. These numbers are also
  24304.     subject to change, as an OEM can change these values.
  24305.  
  24306.  3. When an XOFF character is transmitted based upon reaching a
  24307.     certain buffer filled state, is there a second "trigger" if
  24308.     characters continue to be received beyond a second point? For
  24309.     example, if the first XOFF character gets sent when the receive
  24310.     buffer is 80 percent full, does another XOFF character get
  24311.     transmitted again when the receive buffer is 95 percent full, or
  24312.     some other such point (in case the first XOFF character was
  24313.     missed)?
  24314.  
  24315.     No, the COM1 driver does not use this method because many COM
  24316.     drivers assume the next character after a XOFF character is an XON
  24317.     character. At certain times, the input buffer can be overrun and
  24318.     an RX_QUE_OVERRUN error will be returned. If this is a problem for
  24319.     you, then you need to use DTR/RTS handshaking.
  24320.  
  24321.  
  24322.  710. Named Pipes Constants in BSEDOS.H Changed in 1.20
  24323.  
  24324.  Question:
  24325.  
  24326.  In OS/2 Version 1.10, the following named-pipe constants were defined
  24327.  in the BSEDOS.H file:
  24328.  
  24329.     #define PIPE_READMODE_BYTE        0x0000
  24330.     #define PIPE_READMODE_MESSAGE     0x0100
  24331.     #define PIPE_TYPE_BYTE            0x0000
  24332.     #define PIPE_TYPE_MESSAGE         0x0400
  24333.     #define PIPE_END_CLIENT           0x0000
  24334.     #define PIPE_END_SERVER           0x4000
  24335.     #define PIPE_WAIT                 0x0000
  24336.     #define PIPE_NOWAIT               0x8000
  24337.     #define PIPE_UNLIMITED_INSTANCES  0x00FF
  24338.  
  24339.  In OS/2 1.20, these constants are no longer defined in BSEDOS.H. Where
  24340.  are these constants defined in Version 1.20?
  24341.  
  24342.  Response:
  24343.  
  24344.  In the OS/2 Version 1.20 Programmer's Toolkit, these constants have
  24345.  been replaced with the following:
  24346.  
  24347.     Define in Version 1.10             New Define in Version 1.20
  24348.     ----------------------             --------------------------
  24349.  
  24350.     PIPE_READMODE_BYTE        0x0000   NP_READMODE_BYTE        0x0000
  24351.     PIPE_READMODE_MESSAGE     0x0100   NP_READMODE_MESSAGE     0x0100
  24352.     PIPE_TYPE_BYTE            0x0000   NP_TYPE_BYTE            0x0000
  24353.     PIPE_TYPE_MESSAGE         0x0400   NP_TYPE_MESSAGE         0x0400
  24354.     PIPE_END_CLIENT           0x0000   NP_END_CLIENT           0x0000
  24355.     PIPE_END_SERVER           0x4000   NP_END_SERVER           0x4000
  24356.     PIPE_WAIT                 0x0000   NP_WAIT                 0x0000
  24357.     PIPE_NOWAIT               0x8000   NP_NOWAIT               0x8000
  24358.     PIPE_UNLIMITED_INSTANCES  0x00FF   NP_UNLIMITED_INSTANCES  0x00FF
  24359.  
  24360.  These new constants are defined in BSEDOS.H.
  24361.  
  24362.  
  24363.  711. Maximum Number of Semaphore Handles Available
  24364.  
  24365.  Question:
  24366.  
  24367.  What is the maximum number of semaphore handles [addition of all
  24368.  semaphore handles passed in each DosSemMuxWait() call] available?
  24369.  Also, what is meaning of the ERROR_TOO_MANY_MUXWAITERS error message?
  24370.  
  24371.  Response:
  24372.  
  24373.  To keep track of a clear on a semaphore for DosMuxSemWait(), OS/2
  24374.  needs to maintain a list of the semaphores being muxwaited upon. This
  24375.  list is implemented as a chain of data structures, where each
  24376.  structure identifies a waiting semaphore.
  24377.  
  24378.  When a semaphore ID structure is added to the linked list, it is
  24379.  allocated from a limited pool of structures. Under Versions 1.10 and
  24380.  1.20 of OS/2, the maximum number of semaphore ID structures available
  24381.  is 255.
  24382.  
  24383.  If DosMuxSemWait() attempts to allocate more structures then there are
  24384.  available, you will receive the error message of
  24385.  ERROR_TOO_MANY_MUXWAITERS.
  24386.  
  24387.  
  24388.  712. usConfigId VioGetConfig() Parameter Values Not Defined
  24389.  
  24390.  The #defines for the new "usConfigId" parameter of the VioGetConfig()
  24391.  function were mistakenly left out of the .H files. The values should
  24392.  be defined as follows:
  24393.  
  24394.     #define VIO_CONFIG_CURRENT    0
  24395.     #define VIO_CONFIG_PRIMARY    1
  24396.     #define VIO_CONFIG_SECONDARY  2
  24397.  
  24398.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  24399.  researching this problem and will post new information here as it
  24400.  becomes available.
  24401.  
  24402.  
  24403.  713. Format of OS/2 Version 1.20 EXE Header
  24404.  
  24405.  In the Software/Data Library is a file named NEWEXE12 that describes
  24406.  the format of the OS/2 Version 1.20 EXE header. NEWEXE12 can be found
  24407.  in the Software/Data Library by searching on the keyword NEWEXE12, the
  24408.  Q number of this article, or S12532. NEWEXE12 was archived using the
  24409.  PKware file-compression utility.
  24410.  
  24411.  
  24412.  714. IMPLIB, DLL, LIB, and LIBPATH Information
  24413.  
  24414.  Question:
  24415.  
  24416.  What is the connection between IMPLIB's .LIB files and the location of
  24417.  a DLL (dynamic linked library)?
  24418.  
  24419.  My application uses a DLL with no problem as long as the DLL stays in
  24420.  a particular subdirectory. When the LINK (of the DLL) refers to
  24421.  another subdirectory (in this case, the application's own
  24422.  subdirectory), the application fails to find the DLL.
  24423.  
  24424.  When I put the DLL back where it used to be, the application works
  24425.  correctly.
  24426.  
  24427.  However, CodeView then can't use the DLL because it needs the DLL in
  24428.  the application's executable subdirectory. Having two copies of the
  24429.  DLL works in both cases, but this seems less than ideal (I do tell
  24430.  CodeView about the DLL by using the /L LIB.DLL switch).
  24431.  
  24432.  My LIB environment variable points to the subdirectory that contains
  24433.  the .LIB file produced by IMPLIB and not to where the DLL is stored.
  24434.  
  24435.  Both .LIB files and the two DLLs are produced in the same MAKE file.
  24436.  
  24437.  Response:
  24438.  
  24439.  A process that is trying to locate a DLL does not know or care about
  24440.  the import library that was used to link the DLL. All that is
  24441.  important is that the DLL in question be located in a subdirectory
  24442.  that is listed in your LIBPATH system setting.
  24443.  
  24444.  Please note that the LIBPATH system setting and the LIB environment
  24445.  variable have separate and distinct purposes. LINK uses the LIB
  24446.  environment variable to locate .LIB files that it uses when building
  24447.  an executable file, or DLL. The LIBPATH system setting is used by OS/2
  24448.  when it tries to locate DLLs.
  24449.  
  24450.  If your application is able to locate your .DLL only when the .DLL is
  24451.  located in the same subdirectory as the .EXE file, your current
  24452.  directory probably is located in your LIBPATH system setting. This is
  24453.  a common way for developers to set up the LIBPATH system setting. For
  24454.  example, you might have a LIBPATH such as the following:
  24455.  
  24456.     LIBPATH=.;C:\OS2\DLL;C:\;C:\BINP\DLL
  24457.  
  24458.  So that your application can locate your .DLL from subdirectories
  24459.  other than the current working directory (the . directory), put your
  24460.  DLL in a subdirectory listed in your LIBPATH system setting. For
  24461.  example, in the LIBPATH example above, you could put your DLL in
  24462.  either C:\OS2\DLL or in C:\BINP\DLL (assuming, of course, that you
  24463.  have a subdirectory called C:\OS2\DLL or C:\BINP\DLL).
  24464.  
  24465.  If you change your LIBPATH system setting in your CONFIG.SYS file, you
  24466.  will need to reboot for the change to be recognized by OS/2.
  24467.  
  24468.  
  24469.  715. OS/2 Equivalent of MS-DOS CTTY Command
  24470.  
  24471.  Question:
  24472.  
  24473.  Is there a CTTY command in OS/2 like the one in MS-DOS that will let
  24474.  me use a terminal to prompt a command such as "CTTY > COM1"?
  24475.  
  24476.  Response:
  24477.  
  24478.  You can assign standard input and output to a different keyboard and
  24479.  terminal using the redirection operators. For example, to assign
  24480.  standard input and standard output to the keyboard and terminal
  24481.  attached to COM1, type the following:
  24482.  
  24483.     cmd < com1 > com1
  24484.  
  24485.  This would allow you to run CMD on your computer from a remote
  24486.  terminal. This is equivalent to the CTTY command in MS-DOS.
  24487.  
  24488.  
  24489.  716. Keyboard Monitors Not Allowed in PM Screen Group
  24490.  
  24491.  Question:
  24492.  
  24493.  Why can we no longer monitor keys in the Presentation Manager (PM)
  24494.  screen group? This worked properly in previous releases such as
  24495.  Version 1.10, yet it appears that this functionality has been
  24496.  disabled.
  24497.  
  24498.  Response:
  24499.  
  24500.  Keyboard monitors, mouse monitors, and any other character input
  24501.  device monitors are no longer allowed in the PM screen group.
  24502.  
  24503.  The monitors that cannot be registered for the PM screen group are
  24504.  those monitors that are screen group dependent. Input devices such as
  24505.  the keyboard, the mouse, a light pen, etc., are virtualized for each
  24506.  screen group. Devices such as the printer are system-wide devices that
  24507.  have no relationship to the screen group model. Only one process can
  24508.  own the printer at a time, while many processes can own the keyboard
  24509.  or mouse, but only one process per screen group.
  24510.  
  24511.  There are such things in PM called journal hooks that will help you to
  24512.  accomplish what you are trying to do. However, your application must
  24513.  have some or all of the properties of a PM program to perform this
  24514.  type of functionality.
  24515.  
  24516.  What you are doing in Version 1.10 with monitors was not intended to
  24517.  work with Version 1.10. It works because the original design goals
  24518.  were not enforced. It is a coincidence that monitors could be
  24519.  registered to work with the PM desktop in Version 1.10.
  24520.  
  24521.  The PM philosophy forces all applications to be well-behaved and work
  24522.  within the message model. In past releases of OS/2, this was not
  24523.  strictly enforced, although it was our intent make this enforcement
  24524.  all along. This enforcement was put into place in OS/2 Version 1.20.
  24525.  
  24526.  
  24527.  717. Setting Serial Port Time-out Parameters
  24528.  
  24529.  Question:
  24530.  
  24531.  We are trying to run an external serial display over an RS232 port
  24532.  under OS/2 Versions 1.10 and 1.20. We are having problems with the
  24533.  time-out values. The device times out and is unavailable.
  24534.  
  24535.  What are the various time-out parameters, and which parameters should
  24536.  we be using?
  24537.  
  24538.  Response:
  24539.  
  24540.  To change the device time-out values in the serial port driver, you
  24541.  need to use the DosDevIOCtl() calls ASYNC_GETDCBINFO and
  24542.  ASYNC_SETDCBINFO. These calls are documented on Pages 39, 263, 270,
  24543.  and 336 of the "Microsoft Operating System/2 Programmer's Reference
  24544.  Volume 3" for Version 1.10.
  24545.  
  24546.  The "usReadTimeout" field of the DCBINFO structure specifies the
  24547.  time-out value in one-hundredths of a second. If the field is set to
  24548.  zero, the time-out is 0.01 seconds; if it is set to 1, the time-out is
  24549.  0.02 seconds, and so on.
  24550.  
  24551.  The "fbTimeout" field of the DCBINFO structure specifies the time-out
  24552.  processing for the device. It can be a combination of the following
  24553.  values:
  24554.  
  24555.     Value                     Meaning
  24556.     -----                     -------
  24557.  
  24558.     MODE_NO_WRITE_TIMEOUT     Enable write infinite
  24559.                               time-out processing.
  24560.  
  24561.     MODE_READ_TIMEOUT         Enable normal read time-out
  24562.                               processing.
  24563.  
  24564.     MODE_WAIT_READ_TIMEOUT    Enable wait-for-something
  24565.                               read time-out processing.
  24566.  
  24567.     MODE_NOWAIT_READ_TIMEOUT  Enable no-wait read
  24568.                               time-out processing.
  24569.  
  24570.  If you want to adjust the amount of time that the COM driver waits
  24571.  until it performs a time-out, set "fbTimeout" to MODE_READ_TIMEOUT (if
  24572.  it is not already set to that) and set the "usReadTimeout" field of
  24573.  the DCBINFO structure to the desired value (see below). The default is
  24574.  60 seconds.
  24575.  
  24576.  If you want to force the COM driver to wait for data and prevent it
  24577.  from timing out on a read, set "fbTimeout" to MODE_WAIT_READ_TIMEOUT.
  24578.  
  24579.  For some sample code that demonstrates how to set the read time-out
  24580.  and other COM port parameters, please see the COMTALK sample program
  24581.  included with Versions 1.10 and 1.20 of the Microsoft Operating
  24582.  System/2 Programmer's Toolkit.
  24583.  
  24584.  If you are still having difficulty receiving data after examining the
  24585.  COMTALK sample application, the problem you are experiencing may lie
  24586.  in your hardware setup, that is, your serial cable, serial port, or
  24587.  dumb terminal. For example, be sure to match up the serial
  24588.  communication parameters of your serial port with that of your
  24589.  terminal.
  24590.  
  24591.  An excellent general reference on data communications is a book named
  24592.  the "C Programmer's Guide to Serial Communications" by Joe Campbell,
  24593.  Howard W. Sams & Company 1988. While this book does not specifically
  24594.  address the OS/2 API, it is very helpful in describing how to set the
  24595.  various parameters of a serial port device driver.
  24596.  
  24597.  
  24598.  718. Querying Country Information
  24599.  
  24600.  Question:
  24601.  
  24602.  When using the DosGetCountryInfo() function, where does the
  24603.  information come from? For instance, when I change the currency symbol
  24604.  via the Control Panel, it does not seem to make any difference;
  24605.  DosGetCountryInfo() still returns the default values.
  24606.  
  24607.  Response:
  24608.  
  24609.  The recommended way to query the country information is to first use
  24610.  the PRF functions (these calls were added to Version 1.20) to query
  24611.  the OS2*.INI file for the PM_NATIONAL key name country information. If
  24612.  these calls fail, use the default information from DosGetCntryInfo().
  24613.  
  24614.  DosGetCountryInfo() gets data from COUNTRY.SYS. The Control Panel does
  24615.  not modify this file; it instead changes the file OS2.INI. You need to
  24616.  use WinQueryProfileString() to get information from the OS2.INI file.
  24617.  Use the application name PM_NATIONAL and the keyname sCurrency.
  24618.  
  24619.  
  24620.  719. Country PM_NATIONAL Key Name Information
  24621.  
  24622.  The list of PM_NATIONAL key names can be found by either looking at
  24623.  the OS2.INI file with INIEDIT, or by referring to the following list.
  24624.  These key names are not documented in any of the OS/2 or Presentation
  24625.  Manager (PM) printed documentation.
  24626.  
  24627.     Key         Meaning
  24628.     ---         -------
  24629.  
  24630.     iCountry    Country code
  24631.     iDate       Date format
  24632.     iCurrency   Whether the currency symbol precedes the amount
  24633.     iDigits     Number of digits following decimal point
  24634.     iTime       Whether time is 12 or 24 hour clock
  24635.     iLzero      Whether leading zeros should be displayed
  24636.     s1159       NLS string describing AM
  24637.     s2359       NLS string describing PM
  24638.     sCurrency   Currency symbol
  24639.     sThousand   Thousands separator
  24640.     sDecimal    Decimal marker
  24641.     sDate       Date separator
  24642.     sTime       Time separator
  24643.     sList       List separator
  24644.  
  24645.  
  24646.  720. Process Block Timeout Queue Update Causes Hang to Occur
  24647.  
  24648.  Microsoft has confirmed that there is a problem with OS/2 Version 1.10
  24649.  involving the update of the process block timeout queue. The problem
  24650.  seems to reside in the removal of process entries from the OS/2 kernel
  24651.  process block timeout queue data structure.
  24652.  
  24653.  This problem has been observed on OS/2 Version 1.10 machines that are
  24654.  heavily loaded with applications that cause a high rate of blocking
  24655.  activity to occur (such as communication related programs).
  24656.  
  24657.  This problem has been isolated to a problem with the timeout queue.
  24658.  The link list structure gets corrupted and loses the trailing dummy
  24659.  entry (thread 0), causing a subsequent entry into a procedure to insert
  24660.  the process into the ProcBlock timeout queue, which in turn hangs the
  24661.  system. This procedure is executed when the ProcBlock procedure is
  24662.  called and a timeout value is specified in DI:CX.
  24663.  
  24664.  This problem has been corrected in Version 1.20.
  24665.  
  24666.  The timeout queue consists of a circular list of entries that is based
  24667.  on the thread number. The procedure adds an entry into the timeout
  24668.  queue. The code loop "hang" occurs while it is trying to locate the
  24669.  end of the timeout queue (to add a new entry), but is unable to. This
  24670.  problem could occur if the thread number to be added to the timeout
  24671.  queue by ProcBlock is already in the queue.
  24672.  
  24673.  Because interrupts are disabled while the code is looping, you cannot
  24674.  get control using the kernel debugger by pressing CTRL+C.
  24675.  
  24676.  The code fragment where the hang occurs is listed below:
  24677.  
  24678.      0090:71A7  MOV  BL,[BX,SI]
  24679.      0090:71A9  AND  BX,0FFH
  24680.      0090:71AD  JL   $+01EH
  24681.      0090:71AF  ADD  BX,BX
  24682.      0090:71B1  MOV  DI,BX
  24683.      0090:71B3  ADD  BX,BX
  24684.      0090:71B5  ADD  BX,DI
  24685.      0090:71B7  CMP  DX,[BX+SI+4]  SI=4FC8 BX=00F6 DX=0000
  24686.      0090:71BA  JB   $+011H
  24687.      0090:71BC  JA   $+7
  24688.      0090:71BE  CMP  CX,[BX+SI+2]  SI=4FC8 BX=00F6 CX=0A07
  24689.      0090:71C1  JB   $+0AH
  24690.      0090:71C3  SUB  CX,[BX+SI+2]
  24691.      0090:71C6  SBB  DX,[BX+SI+4]
  24692.      0090:71C9  JMP  $-022H
  24693.  
  24694.  Turning the interrupt flag back ON gets the code out of the hang.
  24695.  
  24696.  IOPL = 2 when the hang occurs.
  24697.  
  24698.  
  24699.  721. OS/2 Programmer's Reference Volume 4 Documentation Errors
  24700.  
  24701.  Microsoft has confirmed that the following documentation errors occur
  24702.  on Page 31 in the "Microsoft Operating System/2 Programmer's Reference
  24703.  Volume 4" for Version 1.20. The following problems have been found
  24704.  with the example on Page 31:
  24705.  
  24706.  1. On line 3, "pprogde" should be changed to "progde".
  24707.  
  24708.  2. On lines 9 and 10, all backslashes should be escaped (doubled). For
  24709.     example, "c:\os2" should instead be "c:\\os2".
  24710.  
  24711.  3. On line 12, it states that it is okay to set pszEnvironment to ""
  24712.     (one null character). When no environment strings are provided, one
  24713.     null character will work correctly. However, you need to have two
  24714.     null characters when there are environment strings. For
  24715.     consistency, two null characters should be used in this example.
  24716.  
  24717.  
  24718.  722. DosError() Deals Only with Critical Errors
  24719.  
  24720.  Problem:
  24721.  
  24722.  I have a system with one floppy disk drive. When executing
  24723.  DosQFSInfo() in the DOS compatibility box, the hard-error screen pops
  24724.  up even though I am using the DosError(0) function. In protected mode,
  24725.  the DosError(0) function works correctly, and the hard-error screen
  24726.  does pop up. What else can I do to suppress the hard-error screen in
  24727.  the DOS compatibility box?
  24728.  
  24729.  Response:
  24730.  
  24731.  You are running into a restriction on the DosError() function. The
  24732.  restriction on DosError() concerning real mode programming is that the
  24733.  DosError() call deals only with INT 24H (critical errors). Since the
  24734.  prompt to change disks from Drive A to Drive B is not a critical
  24735.  error, this will not work as it does under OS/2 protected mode. The
  24736.  only way to disable the prompt under MS-DOS and the pop-up under the
  24737.  OS/2 compatibility box is to set the logical drive map. For
  24738.  protected-mode OS/2, the screen is a "pop-up" and is already disabled.
  24739.  
  24740.  You can work around this restriction by using the code included below.
  24741.  If you are on a one-drive machine and in real mode, you should set the
  24742.  logical drive map yourself. Otherwise, the system can handle the
  24743.  change (if necessary).
  24744.  
  24745.  To perform this functionality, you must make a call to DosDevConfig()
  24746.  and a call to DosGetMachineMode(). To get access to the MS-DOS call
  24747.  for setting the logical drive map, you must make a call into an
  24748.  assembly language routine. This is because the protected-mode C
  24749.  run-time libraries that you have do not have the int86(x) or intdos
  24750.  functions in them.
  24751.  
  24752.  Listed below is SETMAP.ASM, the assembly language routine you will
  24753.  need along with the C code necessary to perform this functionality.
  24754.  
  24755.  Use the following commands to compile and link the sample code:
  24756.  
  24757.  cl /c /W3 error.c
  24758.  masm setmap.asm;
  24759.  link error+setmap /nod,error.exe,nul.map,os2 slibcep;
  24760.  bind error.exe \lib\doscalls.lib \lib\api.lib
  24761.  
  24762.  Sample Code
  24763.  -----------
  24764.  
  24765.  #define INCL_SUB
  24766.  #define INCL_BASE
  24767.  #define INCL_DOSDEVICE
  24768.  #include <os2.h>
  24769.  
  24770.  int main(void);
  24771.  extern void setmap(USHORT drivenum);
  24772.  
  24773.  int main(void)
  24774.  {
  24775.      struct  {
  24776.        FDATE fdateCreation;
  24777.        FTIME ftimeCreation;
  24778.        CHAR cchName;
  24779.        CHAR achVolumeName[14];
  24780.      } FSInfoBuf;
  24781.  
  24782.      BYTE    bMachineMode;
  24783.      USHORT  usDevInfo;
  24784.  
  24785.      BOOL    bSpecial = FALSE;
  24786.  
  24787.      DosDevConfig((PVOID)&usDevInfo,DEVINFO_FLOPPY,0);
  24788.  
  24789.      DosGetMachineMode(&bMachineMode);
  24790.  
  24791.      if((usDevInfo < 2)   && (bMachineMode == MODE_REAL))
  24792.       bSpecial = TRUE;
  24793.  
  24794.      DosError(0);
  24795.  
  24796.      if(bSpecial)
  24797.       setmap(1);
  24798.  
  24799.        DosQFSInfo(1,
  24800.             2,
  24801.             (PBYTE) &FSInfoBuf,
  24802.             sizeof(FSInfoBuf));
  24803.  
  24804.      /* The calls to setmap are done just prior to accessing the drive.
  24805.         This could be improved by keeping a current disk variable and
  24806.         then not doing the setmap call if not needed. For this small
  24807.         example, the extra variable is unnecessary. */
  24808.  
  24809.      if(bSpecial)
  24810.       setmap(2);
  24811.  
  24812.      DosQFSInfo(2,
  24813.              2,
  24814.              (PBYTE) &FSInfoBuf,
  24815.              sizeof(FSInfoBuf));
  24816.      return(0);
  24817.  }
  24818.  
  24819.  .MODEL SMALL
  24820.  .CODE
  24821.  public _setmap
  24822.  _setmap PROC
  24823.  
  24824.      push    bp
  24825.      mov     bp,sp
  24826.  
  24827.      mov     ax,440FH     ; Set Map call.
  24828.      mov     bx,[bp+4]    ; Pass in drive number parameter.
  24829.      int     21H         ; Set the logical drive.
  24830.  
  24831.      pop     bp
  24832.      ret
  24833.  _setmap endp
  24834.  END
  24835.  
  24836.  
  24837.  723. Monitor Chain Notification Information
  24838.  
  24839.  Question:
  24840.  
  24841.  Is it possible to send an error back through the monitor chain? Also,
  24842.  can I block a thread in my Monitor Notify routine? What are the
  24843.  repercussions? What happens to the chain? Do other monitors block
  24844.  trying to write to the chain?
  24845.  
  24846.  Response:
  24847.  
  24848.  The data stream in a monitor chain runs in one direction only. A
  24849.  monitor can send information down the chain, but not back up from
  24850.  where it came.
  24851.  
  24852.  Whether or not you can block a thread in your monitor notification
  24853.  routine depends on what the context of your thread is. It is possible
  24854.  for your monitor notification routine to be called at interrupt time
  24855.  (for example, if your monitor chain is empty; that is, no monitors
  24856.  have registered). In that case, you cannot call the Block DevHlp. If
  24857.  you can guarantee that you will never have an empty monitor chain, you
  24858.  are probably safe to block. You shouldn't have to worry about monitors
  24859.  in the chain; the notification routine doesn't get called until data
  24860.  comes out of the last monitor in the chain in question.
  24861.  
  24862.  For more information on this topic, please refer to IBM's technical
  24863.  reference manuals, or to "Writing OS/2 Device Drivers" by Raymond
  24864.  Westwater, Addison-Wesley, 1989.
  24865.  
  24866.  
  24867.  724. KBDINFO Flags Undefined in Version 1.20
  24868.  
  24869.  Question:
  24870.  
  24871.  I have Version 1.20 of the Presentation Manager (PM) Toolkit and am
  24872.  using the KbdSetStatus() function. Within this function, I use the
  24873.  KBDINFO structure. I pass the fsMask parameter to the KBDINFO
  24874.  structure. The flag set for fsMask is KEYBOARD_ECHO_ON. When I
  24875.  compile my application I receive the error message "C2029 error,
  24876.  KEYBOARD_ECHO_ON; undefined." This same function worked correctly with
  24877.  Version 1.10 of the PM Toolkit. Why doesn't it work with Version 1.20?
  24878.  
  24879.  Response:
  24880.  
  24881.  The KEYBOARD_*_* flags (KEYBOARD_ECHO_ON, etc.) are undefined in the
  24882.  Version 1.20 header files. You can use the hexadecimal values,
  24883.  assigned to these in the Version 1.10 header files, in your
  24884.  application. For example:
  24885.  
  24886.     KbdSetStatus(&kbdinfo, 0);
  24887.     Kbdinfo.fsMask = 0x0001;        // KEYBOARD_ECHO_ON
  24888.  
  24889.  The value 0x0001 corresponds to the flag KEYBOARD_ECHO_ON in the
  24890.  Version 1.10 BSESUB.H header file. The corresponding flags are as
  24891.  follows:
  24892.  
  24893.     KEYBOARD_ECHO_ON                0x0001
  24894.     KEYBOARD_ECHO_OFF               0x0002
  24895.     KEYBOARD_BINARY_MODE            0x0004
  24896.     KEYBOARD_ASCII_MODE             0x0008
  24897.     KEYBOARD_MODIFY_STATE           0x0010
  24898.     KEYBOARD_MODIFY_INTERIM         0x0020
  24899.     KEYBOARD_MODIFY_TURNAROUND      0x0040
  24900.     KEYBOARD_2B_TURNAROUND          0x0080
  24901.     KEYBOARD_SHIFT_REPORT           0x0100
  24902.  
  24903.  
  24904.  725. Invalid Value Listed for DosSetSigHandler() usSigNumber
  24905.  
  24906.  On Page 147 of the "Microsoft Operating System/2 Programmer's
  24907.  Reference Volume 3" for Version 1.10, it states that a valid value for
  24908.  the DosSetSigHandler() usSigNumber parameter is SIG_BROKENPIPE.
  24909.  However, a signal of this type does not exist. It is defined in
  24910.  BSEDOS.H as having a value of 2; however, this value is invalid.
  24911.  
  24912.  The SIG_BROKENPIPE is defined as a broken connection to a pipe. We do
  24913.  not plan to implement this functionality in the future.
  24914.  
  24915.  Microsoft has confirmed that this error occurs in the "Microsoft
  24916.  Operating System/2 Programmer's Reference Volume 3" for Version 1.10,
  24917.  and also in QuickHelp. We will post new information here when the
  24918.  documentation and QuickHelp has been updated to correct this error.
  24919.  
  24920.  
  24921.  726. DLL Version of gets() Not Working with OS/2 1.10
  24922.  
  24923.  Microsoft has confirmed that the DLL version of gets() does not work
  24924.  correctly under OS/2 Version 1.10. We are researching this problem and
  24925.  will post new information here as it becomes available.
  24926.  
  24927.  As a workaround, you can either use one of calls in the scanf()
  24928.  family, or write your own gets() call, using the getc() or getchar()
  24929.  functions.
  24930.  
  24931.  
  24932.  727. Accessing Addresses Above 16 MB in OS/2 Version 1.20
  24933.  
  24934.  Question:
  24935.  
  24936.  I have the following questions about accessing physical addresses
  24937.  above 16 MB:
  24938.  
  24939.  1. Does OS/2 support physical addresses outside of the 80286 address
  24940.     space (that is, above 16 MB)?
  24941.  
  24942.  2. Will the PhysToVirt() DevHlp work with physical addresses above
  24943.     16 MB (01000000H)?
  24944.  
  24945.  3. Can RAM above 16 MB be used by OS/2 Version 1.20 in general?
  24946.  
  24947.  Response:
  24948.  
  24949.  The following are the answers to the above questions:
  24950.  
  24951.  1. Actually, OS/2 (that is, the OS/2 kernel) does NOT support physical
  24952.     addresses outside of the 80286 address space. The Version 1.20
  24953.     kernel operates on virtual addresses, and the Version 1.20 virtual
  24954.     memory manager only understands addresses that lie within the 80286
  24955.     physical address space.
  24956.  
  24957.     A device driver, on the other hand, can DIRECTLY address physical
  24958.     memory without first going through OS/2's virtual memory manager.
  24959.     Therefore, you could (on an 80386) write a device driver to
  24960.     directly address memory above the 16 MB line.
  24961.  
  24962.  2. The PhysToVirt() DevHlp will not accept physical addresses outside
  24963.     the 16 MB address space of the 80286. There is a check in the
  24964.     PhysToVirt() code to prevent this from happening.
  24965.  
  24966.     However, as stated above, this does not prevent you from writing a
  24967.     device driver to access 80386 memory above the 16 MB boundary.
  24968.  
  24969.  3. No, you cannot use RAM above 16 MB because the OS/2 Version 1.20
  24970.     kernel cannot address physical memory outside the 16 MB address
  24971.     space of the 80286. When adapting OS/2 for your hardware, you should
  24972.     not specify arena boundaries (i.e. physical memory addresses) beyond
  24973.     16 MB.
  24974.  
  24975.  
  24976.  728. INT 1AH Function 02H Returns Incorrect Value in 3.x Box
  24977.  
  24978.  Microsoft has confirmed that the following problem occurs in OS/2
  24979.  Version 1.20. The interrupt 1AH function 02H, read real time clock,
  24980.  does not return the correct values. When the following is typed in
  24981.  under SYMDEB in the 3.x compatibility box
  24982.  
  24983.     a
  24984.     mov ah,2
  24985.     int 1a
  24986.     int 3
  24987.  
  24988.     g 100
  24989.  
  24990.  the CX and DX registers are set to 0 and the carry flag is incorrectly
  24991.  set.
  24992.  
  24993.  We are researching this problem and will post new information here as
  24994.  it becomes available.
  24995.  
  24996.  
  24997.  729. Incorrect Error Code Returned by VioSetFont() in Version 1.20
  24998.  
  24999.  Issuing a VioSetFont() call with the following parameters
  25000.  
  25001.     (cb=14,type=0,cxCell=0,cyCell=10,pbData,cbData=2560,VioHandle=0)
  25002.  
  25003.  returns ERROR_VIO_USER_FONT(468).
  25004.  
  25005.  This return code (468) represents a warning. It indicates that
  25006.  although the font could not be loaded into the video adapter using the
  25007.  current mode, the font was saved as part of a special user code page
  25008.  for use with VioSetMode().
  25009.  
  25010.  Since the specified column (cxCell) and row (cyCell) values are
  25011.  invalid for a valid mode setting (column = 0, row = 10), the
  25012.  ERROR_VIO_INVALID_PARMS error should instead be returned.
  25013.  
  25014.  Microsoft has confirmed that this problem occurs in Version 1.20. The
  25015.  parameters should be checked and the appropriate error code should be
  25016.  returned.
  25017.  
  25018.  We are researching this problem and will post new information here as
  25019.  it becomes available.
  25020.  
  25021.  
  25022.  730. Wrong Error Returned If VioSetFont() cbData Is Invalid
  25023.  
  25024.  Issuing a VioSetFont() call with the following parameters
  25025.  
  25026.     (cb=14,type=0,cxCell=8,cyCell=16,pbData,cbData=2048,VioHandle=0)
  25027.  
  25028.  incorrectly returns ERROR_VIO_INVALID_LENGTH(438) instead of the
  25029.  correct error of ERROR_VIO_INVALID_PARMS(421).
  25030.  
  25031.  The ERROR_VIO_INVALID_LENGTH(438) error is normally returned when it
  25032.  has been determined that the structure is an incorrect size. The
  25033.  ERROR_VIO_INVALID_PARMS(421) error is normally returned when it has
  25034.  been determined that one of the parameters is incorrect. In this case,
  25035.  "cbData=2048" should have been used instead of "cbData=4096", which
  25036.  means that the error involved an incorrect parameter.
  25037.  
  25038.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25039.  researching this problem and will post new information here as it
  25040.  becomes available.
  25041.  
  25042.  
  25043.  731. MEMMAN MOVE and NOMOVE Option Syntax Problem in 1.20
  25044.  
  25045.  According to Page 83 of the "Microsoft Operating System/2 Desktop
  25046.  Reference" for Version 1.10, if you are just specifying the MOVE or
  25047.  NOMOVE options of the MEMMAN command, you should be able to use the
  25048.  following syntax:
  25049.  
  25050.       MEMMAN=,MOVE  or  MEMMAN=,NOMOVE
  25051.  
  25052.  However, if you use either of these commands, the following error
  25053.  message is returned when you reboot your system:
  25054.  
  25055.     SYS1196: The parameter "," on Line<n> of the config.sys file is
  25056.     not acceptable for the MEMMAN command. Line<n> is ignored.
  25057.  
  25058.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25059.  researching this problem and will post new information here as it
  25060.  becomes available.
  25061.  
  25062.  
  25063.  732. VioPopup() "pfWait" Parameter Value Not Checked Correctly
  25064.  
  25065.  The VioPopUp() "pfWait" parameter is not being checked correctly. If
  25066.  you use a value greater than 3 and less than 0x8000 for this
  25067.  parameter, an incorrect error message of "ERROR_VIO_NO_POPUP" is
  25068.  returned. Instead, the correct error message of
  25069.  "ERROR_VIO_INVALID_PARMS" should be returned. Also, if you use a value
  25070.  from 0x8000 to 0xFFFF, no error message is returned at all.
  25071.  
  25072.  Microsoft has confirmed this to be a problem in OS/2 Version 1.10. We
  25073.  are researching this problem and will post new information here as it
  25074.  becomes available.
  25075.  
  25076.  
  25077.  733. CACHE Parameter Values Displayed Incorrectly
  25078.  
  25079.  The values for the HPFS286 CACHE parameters MAXAGE, BUFFERIDLE, and
  25080.  DISKIDLE are not displayed correctly.
  25081.  
  25082.  If a value N (greater than 65,535) is entered, the above parameters
  25083.  display N as N modulo 65536. For example:
  25084.  
  25085.     CACHE /MAXAGE:65536
  25086.     CACHE                 Displays a maxage of 0.
  25087.  
  25088.     CACHE /MAXAGE:65537
  25089.     CACHE                 Displays a maxage of 1.
  25090.  
  25091.     CACHE /MAXAGE:600000
  25092.     CACHE                 Displays a maxage of 10176.
  25093.  
  25094.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25095.  researching this problem and will post new information here as it
  25096.  becomes available.
  25097.  
  25098.  
  25099.  734. Memory Segment Allocated by VioGetFont() Must Be Freed
  25100.  
  25101.  Problem:
  25102.  
  25103.  The documentation for VioGetFont() does not state that the user must
  25104.  free up any memory segment that VioGetFont() has allocated. I did not
  25105.  know I was supposed to free the memory used by VioGetFont() and ran
  25106.  out of memory. This resulted in VioGetFont() returning an error code
  25107.  of 8. If you call VioGetFont() enough times with no memory available,
  25108.  OS/2 will lock up. I thought VioGetFont() would use the same piece of
  25109.  memory every time it was invoked, since the documentation does not
  25110.  state that you must free it back up.
  25111.  
  25112.  Response:
  25113.  
  25114.  OS/2 can't use the same piece of memory. If you called VioGetFont()
  25115.  and then set the font to something different, the original buffer
  25116.  wouldn't change. Therefore, OS/2 must create a new buffer each time
  25117.  and put a copy of the font table into the buffer. This is how most of
  25118.  OS/2 works. Any time you request information from the system, you are
  25119.  given a copy of the information, not the information itself. This
  25120.  allows you to manipulate the data without affecting the system until
  25121.  you actually want to [VioSetFont()].
  25122.  
  25123.  We have suggested that a reminder be included in the comments section
  25124.  in the documentation to inform users that they must free the memory
  25125.  buffer with a DosFreeSeg() call.
  25126.  
  25127.  This feature is being reviewed and will be considered for inclusion in
  25128.  a future release of the documentation.
  25129.  
  25130.  
  25131.  735. Memory Management Swapping Information
  25132.  
  25133.  Question:
  25134.  
  25135.  I have the following questions about memory management under OS/2 with
  25136.  Presentation Manager (PM):
  25137.  
  25138.  1. How large a virtual address space can be supported given a hard
  25139.     disk for swapping of finite size (but smaller than that of the full
  25140.     virtual address space)? Also, how much hard disk space will OS/2
  25141.     ensure is free when swapping, or will the swap file allocate all
  25142.     available disk space if required?
  25143.  
  25144.  2. Does the memory manager use an algorithm to determine what portions
  25145.     of a block of memory must be swapped? Also, does the memory manager
  25146.     reload the entire block when swapping back into memory, or only the
  25147.     section required? How large is the smallest section?
  25148.  
  25149.  3. Is PM swappable? In an OS/2 PM environment where the only active
  25150.     application is an OS/2 Kernel program (uses "OS/2 base system
  25151.     function calls" only), how much of PM must reside in memory? How
  25152.     much would be swapped out if sufficient memory requests occurred?
  25153.  
  25154.  Response:
  25155.  
  25156.  The answers to the above questions are as follows:
  25157.  
  25158.  1. When you set up a SWAPPATH, you indicate the number of kilobytes of
  25159.     memory to leave free on the disk. This allows the swap file to grow
  25160.     until there are only x kilobytes of space left on the hard disk
  25161.     (where x is the number of kilobytes indicated in the SWAPPATH
  25162.     CONFIG.SYS file command). The swap file will not grow beyond this
  25163.     size.
  25164.  
  25165.  2. Memory is swapped out on a per-segment basis. No partial segments
  25166.     are swapped out. Therefore, the largest segment to be swapped is
  25167.     64K, and the smallest is 1 byte (zero-length segments are not
  25168.     allowed).
  25169.  
  25170.  3. Basically, everything is swappable with a few exceptions: for the
  25171.     most part, the operating system kernel is not swappable, nor are
  25172.     the device drivers.
  25173.  
  25174.     Along with that, any data that is brought in as nonswappable will
  25175.     not be swapped. PM may have some nonswappable data in it, but for
  25176.     the most part it is swappable.
  25177.  
  25178.  
  25179.  736. BIOSPARAMETERBLOCK "fsDeviceAttr" Documentation Error
  25180.  
  25181.  Question:
  25182.  
  25183.  I am unsure how to use the "fsDeviceAttr" of the BIOSPARAMETERBLOCK
  25184.  structure. QuickHelp and Page 332 in the "Microsoft Operating System/2
  25185.  Programmer's Reference Volume 3" for Version 1.10 define
  25186.  "fsDeviceAttr" to be the following:
  25187.  
  25188.  fsDeviceAttr   Specifies information about the drive. If this value is
  25189.                 0x0001, the media are not removable. If it is 0x0002,
  25190.                 the media can detect changes. This field can be one or
  25191.                 both of these values.
  25192.  
  25193.  Are there only three states: not removable, aware of change, and aware
  25194.  of change and not removable? It seems illogical that a device could be
  25195.  aware of change and nonremovable.
  25196.  
  25197.  Response:
  25198.  
  25199.  Microsoft has confirmed that the documentation is incomplete for this
  25200.  parameter. The last value, which is aware of change and nonremovable,
  25201.  does not make much sense, but it could be reported. However, the 00
  25202.  (no change and removable) case is a valid value, but the documentation
  25203.  does not indicate that it is a possible return value.
  25204.  
  25205.  We will post new information here once the documentation has been
  25206.  updated to correct this error.
  25207.  
  25208.  
  25209.  737. OS/2 DosOpen() Return Code Error Information
  25210.  
  25211.  The following return codes are returned by the DosOpen() function call
  25212.  under the following circumstances:
  25213.  
  25214.  1. The file already exists.
  25215.  
  25216.        DosOpen() error == 110 (ERROR_OPEN_FAILED).
  25217.  
  25218.  2. The path provided does not exist.
  25219.  
  25220.        DosOpen() error == 3 (ERROR_PATH_NOT_FOUND).
  25221.  
  25222.  3. The disk is full.
  25223.  
  25224.        DosOpen() error == 112 (ERROR_DISK_FULL).
  25225.  
  25226.  4. The directory is full.
  25227.  
  25228.        DosOpen() error == 82 (ERROR_CANNOT_MAKE).
  25229.  
  25230.  5. The filename provided is not a valid filename, or the pathname
  25231.     provided is not valid.
  25232.  
  25233.        DosOpen() error == 2 (ERROR_FILE_NOT_FOUND). This means you
  25234.                             included a wild card in the filename, which
  25235.                             is not allowed.
  25236.  
  25237.     or
  25238.  
  25239.        DosOpen() error == 3 (ERROR_PATH_NOT_FOUND). This means you
  25240.                             included a wild card in the filename, which
  25241.                             is not allowed.
  25242.     or
  25243.  
  25244.        DosOpen() error == 123 (ERROR_INVALID_NAME). This means an
  25245.                               illegal character or malformed file system
  25246.                               name was used.
  25247.  
  25248.  
  25249.  738. OS/2 DosCloseSem() General Information
  25250.  
  25251.  Question:
  25252.  
  25253.  I have the following questions when DosCloseSem(system_sem) is called
  25254.  and the semaphore is set (owned):
  25255.  
  25256.  1. Does DosCloseSem() always return a code of 102, or does it depend
  25257.     on the issuing process to be the owner of the semaphore? Also, is
  25258.     this affected by the semaphore being exclusive?
  25259.  
  25260.  2. If a code of 102 is returned, what happens to the semaphore: is it
  25261.     closed, cleared, closed and cleared, or none of the above?
  25262.  
  25263.  3. If a process calls DosCloseSem() and the semaphore is owned by
  25264.     this process, does the first thread (or process) receiving the
  25265.     ownership of the semaphore get a return code of 105?
  25266.  
  25267.  Response:
  25268.  
  25269.  The following are answers to the above questions:
  25270.  
  25271.  1. A 0 (zero) is returned by DosCloseSem() if the operation was
  25272.     successful. You get a return code of 102 if the owner tries to
  25273.     close an exclusive semaphore.
  25274.  
  25275.  2. As is the standard procedure with the OS/2 API, a nonzero return
  25276.     code means the call failed. DosCloseSem() does not clear or close
  25277.     the semaphore. Clearing would be an unexpected side effect.
  25278.  
  25279.  3. No, this return code occurs when a thread owning a semaphore dies
  25280.     (exits). This is not the same as closing a semaphore.
  25281.  
  25282.  For more general information about semaphores and their usage, there
  25283.  is a good article on semaphores in the May 1988 issue of "The
  25284.  Microsoft Systems Journal," titled "Using OS/2 Semaphores to
  25285.  Coordinate Concurrent Threads of Execution."
  25286.  
  25287.  
  25288.  739. Must Use DosGetMessage() to Obtain Length of Message
  25289.  
  25290.  Question:
  25291.  
  25292.  Is there any way of determining the length of a message without using
  25293.  a DosGetMessage() call?
  25294.  
  25295.  Response:
  25296.  
  25297.  No. The only way to see the messages in the file is to use the
  25298.  DosGetMessage() call. It is difficult to tell the length of a given
  25299.  message, as it may include replaceable parameters that are replaced
  25300.  with the text when the DosGetMessage() call is made.
  25301.  
  25302.  
  25303.  740. HPFS Versus FAT File System Performance Information
  25304.  
  25305.  There are several factors that affect HPFS performance. These factors
  25306.  are discussed below.
  25307.  
  25308.  First, the buffer size affects HPFS performance. HPFS is designed to
  25309.  use a larger buffer pool than the MS-DOS FAT file system because
  25310.  buffer RAM is much more available when the operating system is not
  25311.  constrained to a 640K address space. HPFS buffers are 2K each; this
  25312.  improves performance when buffering data and directories, but it also
  25313.  means a poorer buffer hit ratio compared to the MS-DOS FAT file
  25314.  system, which has 512 byte buffers.
  25315.  
  25316.  For a "good sized" HPFS buffer pool-- say, 256K -- the difference is
  25317.  minor, but for a default buffer pool of 32K or 64K, HPFS is impacted
  25318.  by the small size of the buffer. In other words, the default buffer
  25319.  size for HPFS is smaller than optimal.
  25320.  
  25321.  Second, HPFS is an installable file system, whereas the MS-DOS FAT
  25322.  file system is built into OS/2. HPFS is much faster than FAT, but it
  25323.  takes longer for a DosRead() call to get to the HPFS code than it does
  25324.  to the FAT code. As a result, the more calls you make for smaller and
  25325.  smaller requests, the more HPFS's speed is masked by the OS/2
  25326.  overhead. Issuing DosFindNext() calls for a single name rather than
  25327.  several names; otherwise, issuing reads for 10 bytes, etc., won't be
  25328.  any faster with HPFS. Naturally, future releases of OS/2 will improve
  25329.  the performance of IFS (Installable File System) to alleviate this
  25330.  problem.
  25331.  
  25332.  Finally, and most importantly, HPFS gains much of its performance for
  25333.  "small, short" operations via its lazy-write mechanism. To improve
  25334.  HPFS performance, you should make sure that the lazy-write handler is
  25335.  installed. You should also increase the default buffer size.
  25336.  
  25337.  If properly configured, HPFS has significantly improved performance in
  25338.  most areas over the MS-DOS FAT file system. However, because of the
  25339.  OS/2 overhead, improvements are masked for small and quick operations.
  25340.  
  25341.  Another factor to consider is the reduced limitation of HPFS. HPFS is
  25342.  slightly faster than the FAT file system when opening a file in a
  25343.  directory with 10 files, but HPFS is many times faster when opening a
  25344.  file in a directory with 1000 or 10,000 files. The same holds true for
  25345.  random access to large files -- HPFS can be orders of magnitude
  25346.  faster. You also will see improved performance in HPFS in heavy I/O
  25347.  systems if you can dedicate a large (2 MB) amount of memory to buffers
  25348.  on the disk.
  25349.  
  25350.  Currently, most users don't normally do the things mentioned above.
  25351.  However, this is mainly because in the past these things weren't
  25352.  possible. Now, HPFS gives you the capability to do these things, which
  25353.  for some programs and some users can be very handy. Users will rarely
  25354.  want to manage 1000 files in a directory, but a mail manager program,
  25355.  for example, may find it convenient to have 10,000 files named "1" to
  25356.  "10000". When the mail manager program is told to display a mail
  25357.  message, it would find the message's name in a database file, and tell
  25358.  the system to open file "5267". This is an example of why one of the
  25359.  most important goals for HPFS was to remove the performance-mediated
  25360.  restrictions on file, directory, and disk sizes.
  25361.  
  25362.  There is one more point to make about the relative performance of HPFS
  25363.  or any other file system. You should remember that it is the speed of
  25364.  the file system that is described as 30 to 400 percent faster, not
  25365.  especially the speed of the application. This point is often
  25366.  overlooked.
  25367.  
  25368.  Obviously, a real life application spends a lot of time doing other
  25369.  tasks besides I/O. Even when it appears to be "I/O bound," the
  25370.  application is probably doing something to process or prepare the data
  25371.  that it is reading or writing. Even using a copy program may introduce
  25372.  additional extra overhead. Perhaps the program transfers the data
  25373.  within its memory buffers, etc. When file systems are benchmarked,
  25374.  special programs are used that just do file system operations. There
  25375.  are significant gains with real programs such as database programs,
  25376.  C-compilers, etc., but not a 400 percent gain in performance.
  25377.  
  25378.  The 30 percent gain in performance comes from comparing HPFS and FAT
  25379.  simple file operations such as the reading and writing of moderately
  25380.  sized transfers of data. It's hard for HPFS to be much better than FAT
  25381.  for moderately sized sequential I/O because both systems just write
  25382.  the data out to the disk in a contiguous hunk, so there isn't much to
  25383.  be improved upon. HPFS works hard to keep files contiguous and is very
  25384.  successful at doing this. The FAT file system tends to keep files
  25385.  contiguous when there is only one file being written at one time
  25386.  because of the FAT chain. Also, the large allocation unit that the FAT
  25387.  file system needs for large disks is a waste of space, but it's a win
  25388.  on performance because it guarantees local contiguity. HPFS allocates
  25389.  on a sector basis but still maintains a high degree of contiguity even
  25390.  when multiple files are being simultaneously written.
  25391.  
  25392.  The 400 percent gain in performance comes from tasks such as creating
  25393.  and deleting files, for example, the time it takes to create three
  25394.  interpass files for a compiler. HPFS does particularly well at this,
  25395.  and the FAT file system does particularly poorly; hence, there is a 4
  25396.  to 1 performance difference.
  25397.  
  25398.  
  25399.  741. VioSetState() Palette Values Not Checked Correctly
  25400.  
  25401.  VioSetState() does not report errors consistently. For example, no
  25402.  error message is returned for palette values in the range of
  25403.  65520-65532. However, palette values from 65533-65535 do cause
  25404.  VioSetState() to return error 438, ERROR_VIO_INVALID_LENGTH.
  25405.  
  25406.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25407.  researching this problem and will post new information here as it
  25408.  becomes available.
  25409.  
  25410.  
  25411.  742. VioSetMode() Incorrectly Handles Row and Column Values
  25412.  
  25413.  When issuing a call of VioSetMode(12,3,4,40,25,320,200) no error
  25414.  message is returned. This is correct. If you issue a call of
  25415.  VioSetMode(12,3,4,0,0,320,200), the incorrect error message of
  25416.  "ERROR_VIO_MODE" is returned. If you change the row or column fields
  25417.  to any value other than 0, the following call works correctly:
  25418.  
  25419.     VioSetMode(12,3,4,1,1,320,200)
  25420.  
  25421.  In the above example, the row and column fields were both set to 1.
  25422.  
  25423.  It should not matter what values are used in the VioSetMode() call for
  25424.  the text row and column fields of the VIOMODEINFO structure when
  25425.  setting the screen mode to graphics mode.
  25426.  
  25427.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25428.  researching this problem and will post new information here as it
  25429.  becomes available.
  25430.  
  25431.  
  25432.  743. OS/2 Version 1.20 Doesn't Recognize Disk Change
  25433.  
  25434.  When a DIR is done on a floppy disk with the same volume ID and serial
  25435.  number as the previous disk, the same "Bytes Free" value is reported,
  25436.  regardless of the actual contents of the disk.
  25437.  
  25438.  This problem can be reproduced by making two floppy disks using the
  25439.  same image file with a program that copies disks including the volume
  25440.  and serial number information. Then, delete some of the files on one
  25441.  of the disks and do a DIR on one disk, then on the other disk. The
  25442.  "Bytes Free" value will be the same for both disks, even though the
  25443.  disks are different.
  25444.  
  25445.  Microsoft has confirmed this to be a problem in OS/2 version 1.20. We
  25446.  are researching this problem and will post new information here as it
  25447.  becomes available.
  25448.  
  25449.  
  25450.  744. DosSetSigHandler() Signal Handler Information
  25451.  
  25452.  Question:
  25453.  
  25454.  I have the following questions about signal handling in OS/2:
  25455.  
  25456.  1. On Page 6-183 in the "IBM Operating System/2 Version 1.1 Technical
  25457.     Reference Programming Reference: Volume 1," it states the following
  25458.     for the DosSetSigHandler() function call:
  25459.  
  25460.        The handler may exit by executing an intersegment return
  25461.        instruction, or by manually setting the stack frame to some
  25462.        known state and jumping to some known location.
  25463.  
  25464.     On Page 148 of the "Microsoft Operating System/2 Programmer's
  25465.     Reference Volume 3" for Version 1.10, the documentation leaves out
  25466.     the second half of the statement above. Is it true that I don't
  25467.     actually have to return from the signal handler?
  25468.  
  25469.  2. On Page 171 of Gordon Letwin's book, "Inside OS/2," Letwin goes
  25470.     into a lot of detail about what happens if you are inside the
  25471.     kernel when you get a signal. He states that basically you will
  25472.     not get the signal until you are about to resume executing the
  25473.     application. Therefore, from this information and the information
  25474.     listed above from the IBM documentation, is it correct to assume
  25475.     that our signal handler will always be called with ss set to our
  25476.     application stack, and not that of the operating system?
  25477.  
  25478.  3. The following sentence is included on Page 148 in the "Microsoft
  25479.     Operating System/2 Programmer's Reference Volume 3" for Version
  25480.     1.10:
  25481.  
  25482.        All registers other than cs, ip, ss, sp, and flags in
  25483.        assembly-language signal handlers contain the same values as
  25484.        when the signal was received.
  25485.  
  25486.     Does this mean that ss is always switched back to the stack segment
  25487.     defined for the handler during compile/link time?
  25488.  
  25489.  Response:
  25490.  
  25491.  The answers to the above questions are as follows:
  25492.  
  25493.  1. Yes, this is true. Your signal handler may reset the stack pointer
  25494.     to a valid stack frame and jump to some other part of your program
  25495.     without actually returning from your handler in the normal fashion.
  25496.     See Paragraph 4 on Page 6-183 of the "IBM Operating System/2
  25497.     Version 1.1 Technical Reference Programming Reference: Volume 1"
  25498.     for more information. You are also correct that the "Microsoft
  25499.     Operating System/2 Programmer's Reference Volume 3" for Version
  25500.     1.10, and the versions of QuickHelp included with OS/2 Versions
  25501.     1.10 and 1.20 do not mention this information. We will post new
  25502.     information when the documentation has been updated to include this
  25503.     information.
  25504.  
  25505.  2. Yes, your signal handler's stack segment will be set to the stack
  25506.     segment defined for that handler at compile/link time. If, for
  25507.     instance, your handler is in the same C source file as main(),
  25508.     your handler will use the same stack segment as your main()
  25509.     routine does. This will not be the same stack segment that the
  25510.     operating system uses.
  25511.  
  25512.  3. Yes, ss is always switched back to the stack segment defined for
  25513.     the handler during compile/link time. The ss and sp registers do
  25514.     not contain the same values as when the signal was received because
  25515.     you may be executing a thread that has its own stack segment. For
  25516.     example, DosExecPgm() starts a child with its own local descriptor
  25517.     table. The parent and child, by default, do not share ANY memory
  25518.     segments. When OS/2 jumps into your signal handler, ss and sp are
  25519.     set to the stack segment defined for that handler during
  25520.     compile/link time.
  25521.  
  25522.  
  25523.  745. Starting Program in Maximized and/or Smaller Font Mode
  25524.  
  25525.  Question:
  25526.  
  25527.  How can I start a program in the maximized and/or smaller font
  25528.  (43-line) state? For example, I want to be able to start MEP from the
  25529.  Start Programs menu in OS/2 Presentation Manager (PM), and have it
  25530.  already maximized and in the smaller font. Currently, I have to start
  25531.  the editor, maximize it, and then set it to smaller font. I have set
  25532.  the MEP.EXE file to WINDOWCOMPAT using MARKEXE, and I have set the
  25533.  TOOLS.INI file so that MEP runs properly once set to the 43-line mode.
  25534.  
  25535.  Response:
  25536.  
  25537.  To change the default size of a VIO text window to a smaller font,
  25538.  press SHIFT+F (or press SHIFT and click the left mouse button on the
  25539.  Font menu-item) instead of just pressing F to select the Font
  25540.  menu-item. After that, every time you start a character application in
  25541.  a VIO window, it will come up in the default font size you selected.
  25542.  
  25543.  Although the PM shell does allow you to change the default font size
  25544.  of a VIO text window, there isn't any method to change the default
  25545.  maximum/minimum size of the text windows for the PM shell. However, if
  25546.  you don't mind an intermediate step, you can write an application that
  25547.  calls DosStartSession() to launch a character application in a
  25548.  full-size VIO window. You then need to set the SessionType field of
  25549.  the STARTDATA structure to the value of 2, and the PgmControl field of
  25550.  the STARTDATA structure to the value of 2.
  25551.  
  25552.  For example, the following values for the STARTDATA structure will
  25553.  launch the application QH.EXE, located in the C:\BINB subdirectory:
  25554.  
  25555.      STARTDATA   stdata;
  25556.      USHORT      usSID;
  25557.      USHORT      usPID;
  25558.      USHORT      usErr;
  25559.  
  25560.      stdata.Length      = sizeof( stdata );
  25561.      stdata.Related     = FALSE;              /* Independent session */
  25562.      stdata.FgBg        = TRUE;               /* Run in Background   */
  25563.      stdata.TraceOpt    = 0;                  /* No tracing          */
  25564.      stdata.PgmTitle    = NULL;
  25565.      stdata.PgmName     = "C:\\BINB\\QH.EXE";
  25566.      stdata.PgmInputs   = NULL;               /* No Parameters       */
  25567.      stdata.TermQ       = NULL;               /* Optional            */
  25568.      stdata.Environment = (PBYTE)1;           /* Parent PROCESS's
  25569.                                                   environment        */
  25570.      stdata.InheritOpt  = 1;                  /* Parent PROCESS's
  25571.                                                   environment        */
  25572.      stdata.SessionType = 2;                  /* VIO window session  */
  25573.      stdata.IconFile    = "";
  25574.      stdata.PgmHandle   = 0;
  25575.      stdata.PgmControl  = 2;                  /*  2 == maximize      */
  25576.      stdata.InitXPos    = 0;
  25577.      stdata.InitYPos    = 0;
  25578.      stdata.InitXSize   = 0;
  25579.      stdata.InitYSize   = 0;
  25580.  
  25581.      /* Try to launch a VIO maximized application */
  25582.      usErr = DosStartSession( &stdata, &usSID, &usPID );
  25583.  
  25584.  
  25585.  746. Symbolic Constants for KBDINFO Flags Missing from BSESUB.H
  25586.  
  25587.  Question:
  25588.  
  25589.  I have Version 1.20 of the Presentation Manager (PM) Toolkit and I am
  25590.  using the KbdSetStatus() function. Within this function, I use the
  25591.  KBDINFO structure. I pass the fsMask parameter to the KBDINFO
  25592.  structure. The flag set for fsMask is KEYBOARD_ECHO_ON. When I compile
  25593.  my application, I receive the error message "C2029 error,
  25594.  KEYBOARD_ECHO_ON; undefined." This same function worked properly with
  25595.  Version 1.10 of the PM Toolkit. Why won't it work with Version 1.20?
  25596.  
  25597.  Response:
  25598.  
  25599.  In Version 1.20 of the PM Toolkit, KEYBOARD_ECHO_ON and other symbolic
  25600.  constants for the KBDINFO masks were mistakenly omitted from the
  25601.  header file BSESUB.H.
  25602.  
  25603.  The following are two workarounds for this problem:
  25604.  
  25605.  1. Instead of using the symbolic constants for the KBDINFO masks, you
  25606.     can use the actual values that correspond to the KBDINFO symbolic
  25607.     constants. For example, instead of using the following assignment
  25608.  
  25609.        Kbdinfo.fsMask = KEYBOARD_ECHO_ON;
  25610.  
  25611.     you could use the following assignment:
  25612.  
  25613.        Kbdinfo.fsMask = 0x0001;        // KEYBOARD_ECHO_ON
  25614.  
  25615.     This solution has the negative side-effect that you are using
  25616.     hard-coded values in your code. Code that uses symbolic constants
  25617.     is generally more flexible and easier to maintain.
  25618.  
  25619.  2. Modify the header file BSESUB.H so that it includes all the
  25620.     symbolic constants for the KBDINFO masks that were inadvertently
  25621.     left out. This workaround to the problem is probably the best
  25622.     approach to take, but you might want to keep an unedited copy of
  25623.     the original file BSESUB.H for archival purposes. The symbolic
  25624.     constants for the KBDINFO masks are as follows:
  25625.  
  25626.      /* KBDINFO.fsMask */
  25627.  
  25628.      #define KEYBOARD_ECHO_ON                0x0001
  25629.      #define KEYBOARD_ECHO_OFF               0x0002
  25630.      #define KEYBOARD_BINARY_MODE            0x0004
  25631.      #define KEYBOARD_ASCII_MODE             0x0008
  25632.      #define KEYBOARD_MODIFY_STATE           0x0010
  25633.      #define KEYBOARD_MODIFY_INTERIM         0x0020
  25634.      #define KEYBOARD_MODIFY_TURNAROUND      0x0040
  25635.      #define KEYBOARD_2B_TURNAROUND          0x0080
  25636.      #define KEYBOARD_SHIFT_REPORT           0x0100
  25637.  
  25638.  
  25639.  747. DosMakeNmPipe() and Four Instances of Given Pipe Problem
  25640.  
  25641.  A problem has been found with the DosMakeNmPipe() function that occurs
  25642.  under the following circumstances. In a client-server application, if
  25643.  there are four instances of a given pipe, the client end can
  25644.  successfully open the pipe, perform transactions, and close the pipe.
  25645.  However, if the first instance of the pipe is closed and the server
  25646.  tries to execute the DosMakeNmPipe() function again, an error is
  25647.  incorrectly returned.
  25648.  
  25649.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25650.  researching this problem and will post new information here as it
  25651.  becomes available.
  25652.  
  25653.  The following is the pseudo (rough) code for the server program:
  25654.  
  25655.  while (1) {
  25656.          DosMakeNmPipe (...)
  25657.          if busy continue;
  25658.  
  25659.          DosConnectNmPipe (...)
  25660.  
  25661.          save handle in a 4 element table
  25662.          start a child process passing it the newly connected handle
  25663.  }
  25664.  
  25665.  The child process will subsequently perform all of the read/write
  25666.  transactions from/to the pipe, and upon completion it will execute a
  25667.  DosDisConnectNmPipe() call on its handle. Thus, the server just makes
  25668.  the pipes, and passes the handle to the child process, which actually
  25669.  performs the pipe read/write. The server then disconnects and closes
  25670.  the pipe, once the child process has been terminated.
  25671.  
  25672.  You can start four clients successfully. If you then close the first
  25673.  client program, this should result in one free instance of a pipe.
  25674.  However, if the server tries to make a DosMakeNmPipe() call, an error
  25675.  of ERROR_PIPE_BUSY is incorrectly returned.
  25676.  
  25677.  At this point, if the remaining three client programs are closed as
  25678.  well, the server can once again successfully make new pipes; that is,
  25679.  DosMakeNmPipe() does not return an error.
  25680.  
  25681.  
  25682.  748. DosQNmPipeInfo() Returns Incorrect Values in 1.20
  25683.  
  25684.  A problem has been found with the DosQNmPipeInfo() function that
  25685.  occurs under the following circumstances. In a client-server
  25686.  application, if there are four instances of a given pipe, the client
  25687.  end can successfully open the pipe, perform transactions, and close
  25688.  the pipe. However, on the server end, if you close one of the pipes
  25689.  and reopen it again, the number of pipes reported by DosQNmPipeInfo()
  25690.  is not correct.
  25691.  
  25692.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  25693.  researching this problem and will post new information here as it
  25694.  becomes available.
  25695.  
  25696.  The following is the pseudo (rough) code for the server program:
  25697.  
  25698.  while (1) {
  25699.          DosMakeNmPipe (...)
  25700.          if busy continue;
  25701.  
  25702.          DosConnectNmPipe (...)
  25703.  
  25704.          save handle in a 4 element table
  25705.          start a child process passing it the newly connected handle
  25706.  }
  25707.  
  25708.  The child process will subsequently perform all of the read/write
  25709.  transactions from/to the pipe, and upon completion it will execute a
  25710.  DosDisConnectNmPipe() call on its handle. Thus, the server just makes
  25711.  the pipes, and passes the handle to the child process, which actually
  25712.  performs the pipe read/write transactions. The server then disconnects
  25713.  and closes the pipe, once the child has been terminated.
  25714.  
  25715.  After starting a client by using the DosQNmPipeHandle() call, the
  25716.  number of current pipe instances in use is 1. If you now close the
  25717.  client and start it again, the number of pipe instances in use is now
  25718.  2, and will never go back down to 1 again. This information was
  25719.  obtained by using the DosQNmPipeInfo() call.
  25720.  
  25721.  
  25722.  749. Executing Different .CMD File, Depending on Session Type
  25723.  
  25724.  Question:
  25725.  
  25726.  In my OS/2 CONFIG.SYS file, I have the following statement:
  25727.  
  25728.     PROTSHELL=C:\OS2\PMSHELL.EXE C:\OS2\OS2.INI
  25729.                C:\OS2\CMD.EXE /k c:\progs\cmd\os2init.cmd
  25730.  
  25731.  One of the side effects of this statement is to cause the command file
  25732.  OS2INIT.CMD to be run whenever a command processor is started up. This
  25733.  is true for both the full-screen and windowed command processors.
  25734.  
  25735.  However, I would like to run a different set of commands depending on
  25736.  whether the windowed command processor or the full-screen shell is
  25737.  being run. Can this be done?
  25738.  
  25739.  Response:
  25740.  
  25741.  Yes, this can be done, but not directly with an OS/2 command. You can
  25742.  write your OS2INIT.CMD file so that it runs a program that you have
  25743.  written that checks what type of session you are running in, and then
  25744.  returns an appropriate error level. Your .CMD file then can have an
  25745.  errorlevel check, and it can call whatever .CMD file you want to run,
  25746.  depending on the session type.
  25747.  
  25748.  The following example demonstrates this technique:
  25749.  
  25750.  OS2INIT.CMD
  25751.  -----------
  25752.  
  25753.  @echo off
  25754.  sesstype
  25755.  IF errorlevel 2
  25756.      fullscrn.cmd
  25757.  IF errorlevel 1
  25758.      windscrn.cmd
  25759.  
  25760.  SESSTYPE.EXE would be a WINDOWCOMPAT program that calls
  25761.  DosGetInfoSeg(), then looks at the value in the typeProcess field in
  25762.  the LINFOSEG structure to see what type of session it was started in.
  25763.  The program would then return the appropriate error code (2 if
  25764.  PT_FULLSCREEN and 1 if PT_WINDOWABLEVIO).
  25765.  
  25766.  An alternative way to do this is included in the Software/Data Library
  25767.  in a file named IFNOTWIN. IFNOTWIN contains two programs named
  25768.  IFWIN.EXE and IFNOTWIN.EXE. These sample programs run or do not run a
  25769.  command, based on whether it is running in a windowed session or not.
  25770.  
  25771.  To use IFWIN.EXE and IFNOTWIN.EXE for the example above, use the
  25772.  following commands in your OS2INIT.CMD file:
  25773.  
  25774.     @ifnotwin cmd.exe /c fullscrn.cmd
  25775.     @ifwin cmd.exe /c windscrn.cmd
  25776.  
  25777.  Currently, you are required to run CMD.EXE for internal commands, but
  25778.  you can change this if you want to.
  25779.  
  25780.  Because it is running a secondary copy of CMD.EXE, actions such as
  25781.  changing directories and setting the environment, if placed within
  25782.  FULLSCRN.CMD or WINDSCRN.CMD, will not remain in effect after IFNOTWIN
  25783.  or IFWIN completes, so you need to use the first method if you want to
  25784.  do those operations.
  25785.  
  25786.  IFNOTWIN can be found in the Software/Data Library by searching on the
  25787.  keyword IFNOTWIN, the Q number of this article, or S12555. IFNOTWIN
  25788.  was archived using the PKware file-compression utility.
  25789.  
  25790.  
  25791.  750. Incorrect Error Codes Listed for DosGetResource()
  25792.  
  25793.  Page 76 of the "Microsoft Operating System/2 Programmer's Reference
  25794.  Volume 3" for Version 1.10 lists the following return values for the
  25795.  DosGetResource() function:
  25796.  
  25797.     ERROR_CANT_FIND_RESOURCE
  25798.     ERROR_INVALID_MODULE
  25799.  
  25800.  However, ERROR_CANT_FIND_RESOURCE and ERROR_INVALID_MODULE are not
  25801.  defined in any of the .H files.
  25802.  
  25803.  After doing some testing, we found that the following error codes
  25804.  are returned instead. For the ERROR_CANT_FIND_RESOURCE error, if you
  25805.  ask for an invalid resource, DosGetResource() returns error code 87;
  25806.  which is defined in BSEERR.H as ERROR_INVALID_PARAMETER. For the
  25807.  ERROR_INVALID_MODULE error, if you ask for an invalid module,
  25808.  DosGetResource() returns error code 6, which is defined in BSEERR.H
  25809.  as ERROR_INVALID_HANDLE (which refers to the handle of the invalid
  25810.  module).
  25811.  
  25812.  Microsoft has confirmed this to be a problem in OS/2 Version 1.10. We
  25813.  are researching this problem and will post new information here as it
  25814.  becomes available.
  25815.  
  25816.  
  25817.  751. Improving Speed of Numeric Calculations in OS/2
  25818.  
  25819.  Question:
  25820.  
  25821.  A significant portion of our work using the C Compiler requires
  25822.  numeric (floating-point) calculations. The C Compiler has been
  25823.  installed with the Alternate Math Library. Is this the optimum
  25824.  configuration for our requirements? If it would increase performance,
  25825.  we could require a numeric coprocessor for use with our software.
  25826.  Alternatively, we could use the Emulator Library instead.
  25827.  
  25828.  Response:
  25829.  
  25830.  You are not using the optimum configuration, if by optimum you are
  25831.  referring to speed.
  25832.  
  25833.  For the fastest performance, you should require a numeric coprocessor
  25834.  used in conjunction with your own floating-point libraries. OS/2 will
  25835.  support multiple threads by saving their status during context
  25836.  switching through the numeric coprocessor. Of course, this means more
  25837.  work on your part.
  25838.  
  25839.  The second fastest performance can be obtained by using a C run-time
  25840.  library with an Emulator AND a numeric coprocessor. This is a more
  25841.  straightforward method. The Emulator will let the numeric coprocessor
  25842.  run if it exists, but it will run anyway even if the numeric
  25843.  coprocessor does not exist. Unfortunately, if a numeric coprocessor is
  25844.  not installed, this will produce the slowest performance. The Emulator
  25845.  is just as precise as the numeric coprocessor, but this precision
  25846.  costs you in speed. Also, if you use an Emulator, you cannot use
  25847.  LLIBCDLL.LIB because it only uses Alternate Math.
  25848.  
  25849.  The third fastest performance can be obtained by using Alternate Math.
  25850.  The Alternate Math Library is not as precise as the Emulator, but it
  25851.  is faster than an Emulator (one that is used without the numeric
  25852.  coprocessor) and it doesn't use a numeric coprocessor. Using Alternate
  25853.  Math allows you to use LLIBCDLL.LIB, if that's a requirement for you.
  25854.  
  25855.  In summary, the fastest performance can be obtained by using a numeric
  25856.  coprocessor with your own floating-point library. OS/2 will support
  25857.  multiple threads within the numeric coprocessor. The second fastest
  25858.  performance can be obtained by using an Emulator AND a numeric
  25859.  coprocessor. The third fastest performance can be obtained by using
  25860.  Alternate Math; it's faster than a stand-alone Emulator, but not as
  25861.  accurate. The fourth fastest performance can be obtained by using the
  25862.  Emulator without the numeric coprocessor. This option is very
  25863.  accurate, but you will sacrafice some speed.
  25864.  
  25865.  
  25866.  752. OS/2 Thread ID Numbers Are Reused
  25867.  
  25868.  Thread ID numbers within an OS/2 process are reused, as the example
  25869.  program included below demonstrates.
  25870.  
  25871.  This means that you need to do additional bookkeeping in an
  25872.  application that creates threads on an ongoing basis (as opposed to
  25873.  all threads being created at the start of your application), if your
  25874.  application needs to know when threads have died.
  25875.  
  25876.  Many applications do not need to know when threads die. The example
  25877.  listed below does not need to know this information.
  25878.  
  25879.  In the example included below, stack deallocation is not a problem,
  25880.  because each stack for the threads in the example is automatically
  25881.  deallocated by the _beginthread routine in the Microsoft C Compiler
  25882.  version 6.00 when the thread ID is reused. See Page 372 of the
  25883.  "Microsoft C 6.00 Advanced Programming Techniques" manual for more
  25884.  information on this topic.
  25885.  
  25886.  If you run the sample code listed below, the thread ID number in the
  25887.  example will always be 2.
  25888.  
  25889.  While stack deallocation is the most common reason to need to know
  25890.  when a thread has died, there can be other application dependent
  25891.  reasons.
  25892.  
  25893.  Stack deallocation may be a less important reason to need to know when
  25894.  a thread has died, now that the Microsoft C Compiler version 6.00
  25895.  performs stack checking on all threads created with _beginthread. See
  25896.  Page 379 of the "Microsoft C 6.00 Advanced Programming Techniques"
  25897.  manual for more information on this topic.
  25898.  
  25899.  Now that the Microsoft C Compiler version 6.00 performs stack checking
  25900.  on all threads created with _beginthread, it is convenient to let
  25901.  _beginthread both allocate and deallocate threads' stacks. Using the
  25902.  Microsoft C Compiler version 6.00, you won't need to use DosAllocSeg()
  25903.  to allocate thread stacks (to get GP fault protection against threads
  25904.  overflowing their stacks), unless you intend to run your .EXE with the
  25905.  Microsoft C Compiler's stack checking disabled.
  25906.  
  25907.  If your application creates all threads at start-up time, DosGetPrty()
  25908.  can be used to detect when a thread has died. DosGetPrty() returns an
  25909.  ERROR_INVALID_THREADID error when the thread has died.
  25910.  
  25911.  However, you might want to write an application where within a process
  25912.  you would do the following. Some threads would be created at start-up
  25913.  time, and some threads might die at any time. Also, still other
  25914.  threads might be created at any time. This sort of application cannot
  25915.  use DosGetPrty() to see if a thread has died, because by the time
  25916.  DosGetPrty() is called, another part of the application may have
  25917.  already reused the thread ID number.
  25918.  
  25919.  Under those conditions, to determine if a thread has died, you must
  25920.  devise a bookkeeping scheme such as the following. Have each thread
  25921.  indicate in a table that it is about to die; then, any part of your
  25922.  application that needs to create a thread will have to check this
  25923.  table just before creating the thread.
  25924.  
  25925.  If a thread has acknowledged it is about to die, do the DosGetPrty()
  25926.  call on that thread ID number. If this call to DosGetPrty() returns an
  25927.  ERROR_INVALID_THREADID error, you can assume that the thread actually
  25928.  died.
  25929.  
  25930.  However, if the call to DosGetPrty(), does not return an
  25931.  ERROR_INVALID_THREADID error, you can assume that the thread got
  25932.  interrupted sometime between the time it acknowledged that it was
  25933.  about to die, and before its _endthread routine had been completed.
  25934.  
  25935.  Sample Code
  25936.  -----------
  25937.  
  25938.  /* Compile with the Microsoft C Compiler version 6.00.
  25939.     Use PWB, and click on Multithreaded .EXE */
  25940.  
  25941.  #define   INCL_BASE
  25942.  #define   INCL_DOS
  25943.  #include  <os2.h>
  25944.  
  25945.  #include <process.h>
  25946.  #include <string.h>
  25947.  #include <stdio.h>
  25948.  #include <stdlib.h>
  25949.  
  25950.  void tryThread(void *dummy)
  25951.  {
  25952.    TID       tid;
  25953.    PLINFOSEG Local;
  25954.    SEL       selGlobalSeg, selLocalSeg;
  25955.  
  25956.    DosGetInfoSeg(&selGlobalSeg,&selLocalSeg);
  25957.    Local = MAKEPLINFOSEG(selLocalSeg);
  25958.    tid=Local->tidCurrent;
  25959.  
  25960.    printf("\nI am thread tid=%2d\n",tid);
  25961.  
  25962.    _endthread();
  25963.  }
  25964.  
  25965.  void main(int argc,char *argv[])
  25966.  {
  25967.    #define MAXTHREADS     5
  25968.    #define STACKSIZE      4096
  25969.  
  25970.    TID    tidThreads[MAXTHREADS];
  25971.    USHORT rc;
  25972.    int    i;
  25973.  
  25974.    for (i=0; i<MAXTHREADS; i++) {
  25975.      tidThreads[i]=_beginthread(tryThread,NULL,STACKSIZE,NULL);
  25976.      printf("\n\rrc on _beginthread[%2d]=%2d",i+1,tidThreads[i]);
  25977.  
  25978.      /* give thread time to die */
  25979.      DosSleep(1000L);
  25980.      }
  25981.  }
  25982.  
  25983.  
  25984.  753. OS/2 Primary HPFS (or Other IFS) Partition Boot Process
  25985.  
  25986.  Listed below is a comparison of the boot process for both OS/2 FAT
  25987.  and Non-FAT partitions.
  25988.  
  25989.  A PC that boots from a primary FAT partition cannot read information
  25990.  from partitions that are managed by File System Drivers (FSDs) until
  25991.  their FSDs are loaded. For example, given a FAT partition on drive C:
  25992.  and an HPFS partition on drive D:, it is not possible to access data
  25993.  stored on drive D: until the following line from CONFIG.SYS is read
  25994.  and processed:
  25995.  
  25996.      IFS=C:\OS2\HPFS.IFS
  25997.  
  25998.  A PC that boots from a primary FSD-managed partition can, on the other
  25999.  hand, gain limited access to that partition even before that
  26000.  partition's FSD is loaded. In this configuration, the boot sector
  26001.  loads a mini-FSD which has just enough functionality to allow it to
  26002.  scan the directory structure of the FSD-managed partition. The
  26003.  mini-FSD is then able to load the appropriate full FSD driver and turn
  26004.  over control to the full FSD driver.
  26005.  
  26006.  FAT Boot Process
  26007.  ================
  26008.  
  26009.  At the completion of the power-on-self-test (POST), Int 19h is
  26010.  executed and control is transferred to the reboot code. The BIOS' Int
  26011.  19h handler reads the boot sector from the disk into memory and
  26012.  transfers control to it.
  26013.  
  26014.  The boot sector contains a structure that describes the disk's
  26015.  parameters. It also contains code to read in the root directory, scan
  26016.  for OS2LDR, and read it into memory. Control is then passed to OS2LDR.
  26017.  
  26018.  OS2LDR contains the OS/2 loader. It performs some initialization,
  26019.  scans the root directory for OS2KRNL, and reads it into memory.
  26020.  Control is then passed to OS2KRNL.
  26021.  
  26022.  OS2KRNL contains the OS/2 kernel and initialization code. It scans the
  26023.  root directory and loads in the base device drivers and some required
  26024.  DLLs. It then loads the file and system drivers specified in
  26025.  CONFIG.SYS (for example, HPFS.IFS). Secondary nonboot FSD-managed
  26026.  volumes (such as the HPFS Drive D: in the above scenario) can now be
  26027.  accessed.
  26028.  
  26029.  All of the above directory scans and file loads are done with standard
  26030.  DOS calls and therefore go through the regular file system and device
  26031.  drivers.
  26032.  
  26033.  Non-FAT Boot Process
  26034.  ====================
  26035.  
  26036.  When a primary boot partition is formatted as an FSD-managed volume,
  26037.  special code is written to the hard disk's boot sector. At the
  26038.  completion of POST, the BIOS' Int 19h handler reads this "special
  26039.  code" from the boot sector into memory and transfers control to it.
  26040.  
  26041.  This special code is responsible for (among other things) establishing
  26042.  an image of the OS2LDR, OS2KRNL, and a "mini-FSD" in memory. Control
  26043.  is then passed to OS2LDR.
  26044.  
  26045.  OS2LDR performs its standard initialization routine, then passes
  26046.  control to OS2KRNL.
  26047.  
  26048.  OS2KRNL goes through an initialization routine similar to the FAT boot
  26049.  procedures, but with two important exceptions: the module loader is
  26050.  called to "load" the mini-FSD from its memory image in memory and the
  26051.  mini-FSD is called to read the base device drivers (one at a time)
  26052.  from the root directory.
  26053.  
  26054.  The required DLLs are then loaded via the mini-FSD, followed by the
  26055.  device and system drivers.
  26056.  
  26057.  The mini-FSD is required to support only a small number of the
  26058.  functions of an FSD. Therefore, the first FSD loaded must be the
  26059.  replacement for the mini-FSD.
  26060.  
  26061.  After the replacement, full FSD has been loaded (per the CONFIG.SYS IFS
  26062.  line(s) parameters), it is then told to initialize itself and take
  26063.  whatever action is necessary to effect a smooth transition from the
  26064.  mini-FSD to the FSD. The full FSD replaces the mini-FSD.
  26065.  
  26066.  From this point on, the system continues normally.
  26067.  
  26068.  
  26069.  754. SYS2070 Error Can Occur If OS/2 Executable Is Corrupted
  26070.  
  26071.  If an OS/2 executable (for example, PROGRAM.EXE) is invoked and the
  26072.  executable file is corrupted, the following OS/2 error can occur:
  26073.  
  26074.     ----------------------------------------------------------------------
  26075.     |   Session Title:                                                   |
  26076.     |   PROGRAM.EXE                                                      |
  26077.     |                                                                    |
  26078.     |      SYS2070: The system could not demand load the                 |
  26079.     |      application's segment.  PROGRAM is in error.                  |
  26080.     |      For additional detailed information also see message SYS0201. |
  26081.     |--------------------------------------------------------------------|
  26082.     |      End of program                                                |
  26083.     ----------------------------------------------------------------------
  26084.  
  26085.  The following is the help message for SYS0201, which is available by
  26086.  typing "HELP SYS0201":
  26087.  
  26088.     SYS0201:  The operating system cannot be run ***.
  26089.  
  26090.     EXPLANATION: The relocation-chain for a segment
  26091.     exceeds the segment limit.
  26092.     ACTION: Contact the supplier of the application
  26093.     program.
  26094.  
  26095.  This error message was observed when the executable file contained
  26096.  several blocks of 0xF6, where machine code should have been located.
  26097.  
  26098.  To correct this problem, obtain an uncorrupted version of the
  26099.  executable file.
  26100.  
  26101.  
  26102.  755. DosMakeNmPipe() Parameter Constant Documentation Error
  26103.  
  26104.  Microsoft has confirmed that the following documentation error occurs
  26105.  in the "Microsoft Operating System/2 Programmer's Reference Volume 3"
  26106.  for Version 1.10 on Pages 84-85 for the DosMakeNmPipe() function. On
  26107.  these pages, all of the constants should start with "NP" instead of
  26108.  "PIPE". For example:
  26109.  
  26110.     Use                      Instead of
  26111.     ---                      ----------
  26112.  
  26113.     NP_WAIT                  PIPE_WAIT
  26114.     NP_NOWAIT                PIPE_NOWAIT
  26115.     NP_READMODE_BYTE         PIPE_READMODE_BYTE
  26116.     NP_READMODE_MESSAGE      PIPE_READMODE_MESSAGE
  26117.     NP_TYPE_BYTE             PIPE_TYPE_BYTE
  26118.     NP_TYPE_MESSAGE          PIPE_TYPE_MESSAGE
  26119.     NP_UNLIMITED_INSTANCES   PIPE_UNLIMITED_INSTANCES
  26120.     NP_ACCESS_DUPLEX         PIPE_ACCESS_DUPLEX
  26121.     NP_ACCESS_INBOUND        PIPE_ACCESS_INBOUND
  26122.     NP_ACCESS_OUTBOUND       PIPE_ACCESS_OUTBOUND
  26123.     NP_INHERIT               PIPE_INHERIT
  26124.     NP_NOINHERIT             PIPE_NOINHERIT
  26125.     NP_NOWRITEBEHIND         PIPE_NOWRITEBEHIND
  26126.     NP_WRITEBEHIND           PIPE_WRITEBEHIND
  26127.  
  26128.  In BSEDOS.H, all of these constants start with "NP" instead of "PIPE".
  26129.  
  26130.  This error also occurs in the versions of QuickHelp included with the
  26131.  Version 1.10 OS/2 Software Development Kit (SDK), and the Version 1.20
  26132.  OS/2 Programmer's Toolkit.
  26133.  
  26134.  We will post new information when the documentation and QuickHelp have
  26135.  been updated to correct this error.
  26136.  
  26137.  
  26138.  756. Misleading Error Occurs If HPFS386 and HPFS Are Both Used
  26139.  
  26140.  When HPFS386 is included in CONFIG.SYS and an IFS statement for a
  26141.  normal HPFS follows, system error SYS1719 is returned stating that the
  26142.  file C:\OS2\HPFS.IFS is not a valid IFS. This error message is
  26143.  misleading.
  26144.  
  26145.  System error SYS1719, invalid device driver or file system driver, is
  26146.  not an inappropriate error message for the case where the loader
  26147.  encounters a conflicting file system driver. A more descriptive error
  26148.  message should be returned in this situation.
  26149.  
  26150.  This feature is under review and will be considered for inclusion in a
  26151.  future release.
  26152.  
  26153.  
  26154.  757. OS/2 SDK 1.10 Profiler Information
  26155.  
  26156.  Question:
  26157.  
  26158.  I have a question about the profiler included in the OS/2 Version 1.10
  26159.  Software Development Kit (SDK). What do the various return codes mean?
  26160.  In particular, I am getting an 8 from ProfInit(), and a 9 from
  26161.  ProfOff().
  26162.  
  26163.  Response:
  26164.  
  26165.  The error codes returned by the profiling APIs are the same as for the
  26166.  base Dos*() calls, and are defined in the BSEERR.H include file. Error
  26167.  code 8 is ERROR_NOT_ENOUGH_MEMORY, and error code 9 is
  26168.  ERROR_INVALID_BLOCK. The error code 9 on the ProfOff() call is
  26169.  probably happening because the ProfInit() call failed.
  26170.  
  26171.  When evaluating the cause of these memory errors, be aware that there
  26172.  is a limit on the size of the program that the profiler can profile.
  26173.  Therefore, it is possible that the system cannot find memory available
  26174.  if your application is large and/or your machine is short on available
  26175.  RAM.
  26176.  
  26177.  The profiler works in the following manner. For every code segment
  26178.  that your application has, a corresponding and equal sized data
  26179.  segment is allocated. The clock interrupt is then hooked. For every
  26180.  clock tick that comes in, the DS value is examined. If it belongs to
  26181.  the application being profiled, a DWORD value in the data segment
  26182.  corresponding to the code segment is incremented, based at an offset
  26183.  into the data segment that corresponds to the offset into the code
  26184.  segment. After incrementing the value, the clock interrupt handler
  26185.  returns control back to the system.
  26186.  
  26187.  Please note that because the data segment is updated at interrupt
  26188.  time, it MUST be present in memory at all times. This means that it
  26189.  cannot be swapped out. Consequently, the memory requirements for
  26190.  profiling an application are much larger than just running the
  26191.  application without profiling. Moreover, for every code segment in
  26192.  your application, there is also going to be an additional LDT slot
  26193.  used to allocate the corresponding data segment. Therefore, you could
  26194.  potentially run out of selectors, and an out of memory error may occur
  26195.  for this reason.
  26196.  
  26197.  
  26198.  758. New DosWaitNmPipe() NP_INDEFINITE and NP_DEFAULT Values
  26199.  
  26200.  Question:
  26201.  
  26202.  The DosWaitNmPipe() function parameters NP_INDEFINITE and NP_DEFAULT
  26203.  are described in the documentation, but they do not exist in any of
  26204.  the files in \OS2TOOLS\INCLUDE. What are their values?
  26205.  
  26206.  Response:
  26207.  
  26208.  NP_INDEFINITE and NP_DEFAULT have the following values:
  26209.  
  26210.     NP_INDEFINITE_WAIT = -1
  26211.     NP_DEFAULT_WAIT = 0
  26212.  
  26213.  You are correct; these values should be included in one of the include
  26214.  files.
  26215.  
  26216.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  26217.  researching this problem and will post new information here as it
  26218.  becomes available.
  26219.  
  26220.  
  26221.  759. OS/2 SDK: Alignment of Memory in DMA Transfer
  26222.  
  26223.  Question:
  26224.  
  26225.  I need to write a routine to transfer data from an I/O adapter card
  26226.  into memory using DMA. My requirements dictate that the routine be
  26227.  fast; therefore, I intend to write it in assembly. In addition, the
  26228.  routine must be callable from a C program, and it must accept as an
  26229.  argument a pointer to a buffer defined in the C program. I have the
  26230.  following questions about how to implement this type of functionality:
  26231.  
  26232.  1. Can this routine run at Ring 3 as part of my application, or do I
  26233.     have to write a device driver?
  26234.  
  26235.  2. The DMA operation needs to know the physical address of the
  26236.     destination memory. How does the assembly code find out the address
  26237.     of the array?
  26238.  
  26239.  3. The data to be transferred could be larger than 64K. Will DMA still
  26240.     work if the data has to cross a segment boundary?
  26241.  
  26242.  Response:
  26243.  
  26244.  The answers to the above questions are as follows:
  26245.  
  26246.  1. Your DMA transfer routine must be part of a device driver for the
  26247.     following reasons:
  26248.  
  26249.     a. To use DMA, your destination buffer must be aligned on 64K
  26250.        boundaries. However, a Ring 2 or Ring 3 process has no control
  26251.        over the alignment of memory. Processes running at Rings 2 or 3
  26252.        can only use the kernel's virtual memory management calls, and
  26253.        these calls cannot assure you that this boundary condition will
  26254.        be met (most likely it will not be met). A device driver, on the
  26255.        other hand, runs at Ring 0 and is capable of controlling memory
  26256.        alignment.
  26257.  
  26258.     b. To perform a DMA transfer to a buffer, you need to lock down the
  26259.        segment containing the destination buffer. If you did not lock
  26260.        down the DMA transfer segment, it could get swapped out by the
  26261.        kernel's virtual memory manager. The consequences of this would
  26262.        be the delay or corruption of the DMA transfer. The only way to
  26263.        lock down segments in memory is from a device driver.
  26264.  
  26265.  2. If you have written a device driver to handle these DMA transfers,
  26266.     as recommended above, the answer to this question is fairly
  26267.     straightforward. An outline of the necessary steps you need to
  26268.     perform is listed below:
  26269.  
  26270.     Application
  26271.     -----------
  26272.  
  26273.     *  Perform a DosOpen() call on your device driver.
  26274.  
  26275.     *  Do a DosRead() call on the returned handle, passing the address
  26276.        of your transfer buffer as a normal part of the DosRead() call.
  26277.  
  26278.     Device Driver Routine
  26279.     ---------------------
  26280.  
  26281.     *  Upon receipt of the READ request packet, directly reference the
  26282.        buffer address contained in the READ request packet.
  26283.  
  26284.        Note: When your device driver receives the READ request packet,
  26285.        the OS/2 kernel will have already (and automatically) locked
  26286.        down the segment containing the buffer address. The kernel will
  26287.        also have inserted a 32-bit physical address into your transfer
  26288.        buffer (into the READ request packet).
  26289.  
  26290.  3. Data transfers of more than 64K must first be broken up into blocks
  26291.     of less than or equal to 64K bytes, and then transferred using
  26292.     multiple DMA requests. This is really a hardware restriction, not a
  26293.     limitation of OS/2. The standard 8237A DMA Controller used in
  26294.     AT-class machines is basically just a 16-bit device. That is, it
  26295.     can only address up to 64K at a time.
  26296.  
  26297.     An easy way to accomplish this in a device driver is to use the
  26298.     AllocReqPacket() and PushReqPacket() DevHlps to effectively send
  26299.     yourself as many request packets as needed to complete a large
  26300.     (more than 64K) data transfer.
  26301.  
  26302.  
  26303.  760. Named-Pipe Functions QuickHelp Documentation Error
  26304.  
  26305.  In QuickHelp, the entry for "Named-Pipe Functions" that is under the
  26306.  "OS/2 API" category does not take you to the listing for named pipes.
  26307.  The following steps can be used to reproduce this problem:
  26308.  
  26309.  1. Select the "OS/2 API" category.
  26310.  
  26311.  2. Select "Function Groups."
  26312.  
  26313.  3. Select "Named-Pipe Functions."
  26314.  
  26315.  A list of Clipboard functions is incorrectly displayed.
  26316.  
  26317.  Microsoft has confirmed this to be a problem in the version of
  26318.  QuickHelp included with OS/2 Version 1.20. We are researching this
  26319.  problem and will post new information here as it becomes available.
  26320.  
  26321.  
  26322.  761. Obtaining Instance of Pipe over Network
  26323.  
  26324.  Question:
  26325.  
  26326.  Given a single instance of a pipe on a server, and several clients on
  26327.  independent workstations, is there any synchronization of the
  26328.  DosWaitNmPipe() call, or can a client be (theoretically) frozen out of
  26329.  access to this pipe forever by (luckier) competing clients?
  26330.  
  26331.  Response:
  26332.  
  26333.  Suppose a number of clients are waiting for an instance of a pipe to
  26334.  become free by making a DosWaitNmPipe() call. If an instance of a
  26335.  pipe becomes available, the (client) process with the highest
  26336.  priority gets this instance of the pipe. If two (client) processes
  26337.  have the same priority, the (client) process that has been
  26338.  waiting the longest gets the instance of the pipe.
  26339.  
  26340.  The behavior is the same over a network. The client (through the
  26341.  redirector) passes the request [DosWaitNmPipe()] to a server, which
  26342.  basically implements the same strategy for giving instances of a pipe
  26343.  to waiting (remote or local) pipes. For remote client cases, the
  26344.  client process, which first makes a DosWaitNmPipe() call and gets to
  26345.  the server first, will get the first available instance of the pipe.
  26346.  
  26347.  
  26348.  762. DosMonReg() Returns Incorrect Error Code in 1.20
  26349.  
  26350.  If you create a monitor and the buffers are too small, DosMonReg()
  26351.  will return an incorrect error code of ERROR_NOT_ENOUGH_MEMORY (error
  26352.  code 8). DosMonReg() should return the correct error code of
  26353.  ERROR_MON_BUFFER_TOO_SMALL (error code 382).
  26354.  
  26355.  Microsoft has confirmed this to be a problem in Version 1.20. We are
  26356.  researching this problem and will post new information here as it
  26357.  becomes available.
  26358.  
  26359.  
  26360.  763. File Manager Program Name Filters Aren't Case Sensitive
  26361.  
  26362.  Case sensitivity does not work properly in the File Manager when used
  26363.  with program name filters. For example, a *.TXT filter does not work
  26364.  properly with a file using lowercase letters, as in *.txt. The icon
  26365.  will not display under the File Manager, although the application will
  26366.  run when the file is double-clicked.
  26367.  
  26368.  Microsoft has confirmed this to be a problem in version 1.20. We are
  26369.  researching this problem and will post new information here as it
  26370.  becomes available.
  26371.  
  26372.  
  26373.  764. AMI Keyboard BIOS Compatibility Problems with OS/2 1.20
  26374.  
  26375.  Using the updated release of OS/2 version 1.20 from IBM, you may
  26376.  encounter various problems while using the File Manager. These
  26377.  problems include spurious "too many directory windows open" error
  26378.  messages (when only one directory window was open), "filename too
  26379.  long" error messages (even while opening windows on a FAT volume), and
  26380.  many other problems.
  26381.  
  26382.  One workaround to these problems is to use the original version 1.20
  26383.  HPFS.IFS file. However, these problems are due to incompatibility
  26384.  problems with OS/2 version 1.20 and the AMI keyboard BIOS.
  26385.  
  26386.  The AMI BIOS (known as the "K8" BIOS), which works properly with
  26387.  MS-DOS, seems to cause a number of problems under the most recent
  26388.  release of OS/2 Version 1.20. AMI has an updated BIOS, called the "KD"
  26389.  BIOS, which resolves these problems.
  26390.  
  26391.  Another problem that is also resolved by the updated BIOS is the more
  26392.  well-known problem of the extended cursor controls not working under
  26393.  Presentation Manager (PM). The cursor keys work properly in the
  26394.  character-mode windows and in the compatibility box, but not under PM.
  26395.  Upgrading the keyboard BIOS solves this problem as well as the file
  26396.  system problems.
  26397.  
  26398.  
  26399.  765. Protection Fault Occurs If Entry Field Overflows in QuickHelp
  26400.  
  26401.  QuickHelp (QH) version 1.60 causes a protection fault when a text entry
  26402.  field overflows. The following steps can be used to reproduce this
  26403.  problem:
  26404.  
  26405.  1. Choose Rename Paste File from the File menu.
  26406.  
  26407.  2. Type random characters until the cursor reaches the end of the
  26408.     entry field and QuickHelp starts beeping.
  26409.  
  26410.  3. Press the HOME key to move to the start of the entry field.
  26411.  
  26412.  4. Press the INS key.
  26413.  
  26414.  5. Type characters again until QuickHelp stops accepting characters.
  26415.     The text will overflow the entry field. If the cursor reaches the
  26416.     end of the entry field before QuickHelp stops accepting characters,
  26417.     press the HOME key and repeat this step.
  26418.  
  26419.  6. Press the ENTER key. A protection violation will occur.
  26420.  
  26421.  Microsoft has confirmed this to be a problem in version 1.60 of
  26422.  QuickHelp included with the version 1.20 Presentation Manager (PM)
  26423.  Toolkit. We are researching this problem and will post new information
  26424.  here as it becomes available.
  26425.  
  26426.  
  26427.  766. System Can Hang in OS/2 1.10 If VioPrtSc() Has Been Replaced
  26428.  
  26429.  Problem:
  26430.  
  26431.  We are having problems when attempting to register a replacement for
  26432.  the VioPrtSc() function in OS/2. The replacement is successfully
  26433.  registered, and under normal circumstances works correctly, but if the
  26434.  PRINT SCREEN key is pressed repeatedly, the machine eventually hangs
  26435.  up completely. As far as we can tell, by using the Presentation
  26436.  Manager (PM) Developer's Kit Process Status utility, registering a
  26437.  replacement for this function causes a separate thread of the process
  26438.  to be launched, which presumably waits on a semaphore that is cleared
  26439.  by the Task Manager (or something else) when the PRINT SCREEN key is
  26440.  pressed. The machine seems to hang when the PRINT SCREEN key is pressed
  26441.  while this secondary thread is running.
  26442.  
  26443.  Response:
  26444.  
  26445.  Microsoft has confirmed this to be a problem in OS/2 versions 1.10 and
  26446.  1.20. We are researching this problem and will post new information
  26447.  here as it becomes available.
  26448.  
  26449.  There is a workaround to this problem, but unfortunately the
  26450.  workaround does not work under version 1.10.
  26451.  
  26452.  You are correct that the system creates a special thread if you
  26453.  register a replacement for the VioPrtSc() or VioPrtScToggle()
  26454.  functions via the VioRegister() function. This thread is created only
  26455.  for these two replacement routines. This thread is blocked by the
  26456.  system until you press the PRINT SCREEN key, at which time Thread 2 of
  26457.  HARDERR.EXE does some processing in preparation to printing the
  26458.  screen, then unblocks this special thread (that belongs to your
  26459.  application) to execute the replacement routine(s) that you registered
  26460.  with VioRegister(). This thread has a rather small stack of 512 bytes
  26461.  that is created by the system at the time you register your
  26462.  replacement routine with VioRegister().
  26463.  
  26464.  When you create a replacement VIO routine entry-point handler that
  26465.  will be registered with VioRegister(), you must set this routine up in
  26466.  a certain way. First of all, it must be declared as shown in the
  26467.  documentation for VioRegister() in the "Microsoft Operating System/2
  26468.  Programmer's Reference Volume 3" for version 1.10. This entry-point
  26469.  function must NOT be of type PASCAL. This is critical!
  26470.  
  26471.  Another critical requirement is that the entry-point function must
  26472.  save the state of the CPU registers when it enters and restore them
  26473.  when it leaves. This can be done in C with the _saveregs function
  26474.  modifier; see the C compiler version 5.10 update section for more
  26475.  information on this topic. As stated in the documentation for
  26476.  VioRegister(), the stack must be left in its original state when
  26477.  returning from the entry-point function. If this entry-point function
  26478.  is written in C, this will be done for you.
  26479.  
  26480.  In the Software/Data Library is a file named PRTSCR that contains a
  26481.  sample application with an entry-point function that shows how to
  26482.  accomplish these tasks in Assembler. This function can be easily
  26483.  adapted to handle one or more different functions registered with
  26484.  VioRegister().
  26485.  
  26486.  PRTSCR can be found in the Software/Data Library by searching on the
  26487.  filename, the Q number of this article, or S12603. PRTSCR was archived
  26488.  with the PKware file-compression utility.
  26489.  
  26490.  Notes
  26491.  -----
  26492.  
  26493.  After the system calls into your entry-point function with the thread
  26494.  created by the system when you register either VioPrtSc() or
  26495.  VioPrtScToggle() via VioRegister(), on return to the system, it does
  26496.  not clean up the stack of the thread that was created. This means that
  26497.  the stack is shrunk by six USHORT parameters (12 bytes) with each call
  26498.  into your entry-point routine. With the small stack that the system
  26499.  creates for this thread (512 bytes), after about 36 calls (PRINT
  26500.  SCREEN key presses), the system will crash.
  26501.  
  26502.  Also, if you press the PRINT SCREEN key very quickly, it will only
  26503.  take a few presses of the key before this small stack will underflow,
  26504.  and the system will crash. Please note that this only happens if you
  26505.  register for a replacement for VioPrtSc() or VioPrtScToggle(). These
  26506.  are the only two routines the system creates a special thread for. If
  26507.  you register any other VIO routine, the stack is cleaned off correctly
  26508.  by the system VIO router after calling your entry-point function.
  26509.  
  26510.  If you have the version 1.20 OS/2 SDK, with a debug kernel version
  26511.  before 12.177, you can use the following temporary workaround. If you
  26512.  pop those 12 bytes in your entry-point function, which you are not
  26513.  supposed to do according to the documentation, the stack will be
  26514.  cleaned off "before" you return to the system VIO router, and
  26515.  everything will function correctly.
  26516.  
  26517.  However, there are some special considerations. Doing this means that
  26518.  a routine written to replace the VioPrtSc() and/or VioPrtScToggle()
  26519.  functions must be written in Assembler, since the stack must be set up
  26520.  C-style, but the stack must be cleaned up in the callee (your
  26521.  entry-point function), which C will not do. Furthermore, you must put
  26522.  some special coding in your entry-point routine to decide when you
  26523.  need to do this special stack cleanup. You can easily look at the
  26524.  "fFunction" parameter (accessed by [bp].s_indx in the sample code) to
  26525.  determine whether this is a VioPrtSc() or VioPrtScToggle() call, and
  26526.  if it is, then do a "ret 12"; otherwise, do a regular "ret" when
  26527.  returning from your entry-point routine, and things should work
  26528.  correctly.
  26529.  
  26530.  When this problem is corrected, this extra stack popping will cause
  26531.  problems in the corrected version. Since you can have only one
  26532.  VioRegister() call outstanding, you will have a problem. However, this
  26533.  would probably be a relatively simple thing to distribute a patch for.
  26534.  
  26535.  
  26536.  767. DosSetSigHandler() pfnPrev Parameter Documentation Error
  26537.  
  26538.  On Page 146 of the "Microsoft Operating System/2 Programmer's
  26539.  Reference Volume 3" for version 1.10, and in QuickHelp included with
  26540.  OS/2 versions 1.10 and 1.20, it incorrectly states the following for
  26541.  the DosSetSigHandler() function:
  26542.  
  26543.     USHORT DosSetSigHandler(pfnSigHandler, pfnPrev, [...])
  26544.     PFNSIGHANDLER pfnSigHandler; /* pointer to signal-handler function */
  26545.     PFNSIGHANDLER FAR *pfnPrev;  /* pointer to previous handler address */
  26546.  
  26547.  In the first and third lines there is a documentation error: "pfnPrev"
  26548.  should be replaced with "ppfnPrev".
  26549.  
  26550.  Microsoft has confirmed this to be a problem in the printed
  26551.  documentation and in QuickHelp for OS/2 versions 1.10 and 1.20. We are
  26552.  researching this problem and will post new information here when both
  26553.  of these references have been updated to correct this error.
  26554.  
  26555.  
  26556.  768. System Hangs If Message Is Larger Than Length of Named Pipe
  26557.  
  26558.  When a client process tries to write a message larger than the length
  26559.  of a named pipe, and the server process is waiting for a semaphore
  26560.  associated to this pipe, the message is split into two pieces. The
  26561.  first piece of the message fills the pipe buffer, and the client hangs
  26562.  on the WRITE because the end of the message cannot be written. On the
  26563.  other hand, the server always waits for the semaphore because the
  26564.  message has not been completely written. The operating system should
  26565.  unlock the semaphore associated to the named pipe when the pipe is
  26566.  full, and not only when the entire message has been received.
  26567.  
  26568.  Microsoft has confirmed this to be a problem in OS/2 version 1.20. We
  26569.  are researching this problem and will post new information here as it
  26570.  becomes available.
  26571.  
  26572.  
  26573.  769. Message File Not Found If DPATH Is Set to Invalid Drive
  26574.  
  26575.  The DPATH variable is not searched completely if an invalid drive is
  26576.  entered in the DPATH variable. After booting the system, if an invalid
  26577.  drive is entered in the DPATH variable, the following error message
  26578.  occurs:
  26579.  
  26580.     SYS0319: The system cannot read the message file:OSO001.MSG
  26581.  
  26582.  For some reason, DPATH is not searched after encountering the invalid
  26583.  drive.
  26584.  
  26585.  On a system with only a Drive C partition, this problem can be
  26586.  reproduced by changing the DPATH variable to the following:
  26587.  
  26588.     SET PATH=C:\OS2;D:\TEST;C:\OS2\SYSTEM;C:\OS2\INSTALL;C:\;
  26589.  
  26590.  If you then reboot the system, the error message listed above is
  26591.  displayed because the VDISK and COM01 device drivers are trying to get
  26592.  their messages from the OSO001.MSG message file. If you type DPATH
  26593.  from the command line, DPATH is set up correctly, but any time you do
  26594.  something that requires a message from the OSO001.MSG message file, it
  26595.  can't be found.
  26596.  
  26597.  You can get the same behavior without having to change the CONFIG.SYS
  26598.  file. Simply change the DPATH variable from CMD.EXE.
  26599.  
  26600.  Microsoft has confirmed this to be a problem in OS/2 version 1.20. We
  26601.  are researching this problem and will post new information here as it
  26602.  becomes available.
  26603.  
  26604.  
  26605.  770. System Hangs If DosWaitNmPipe() Is Called and Pipe Is Broken
  26606.  
  26607.  If a process uses the system call DosWaitNmPipe() call, that process
  26608.  will wait forever if the pipe is broken (for example, if the other
  26609.  process has been killed by a CTRL+C).
  26610.  
  26611.  In this situation, the waiting process should be awakened by the
  26612.  operating system, even if the SEM_INDEFINITE_WAIT option has been
  26613.  selected in the DosWaitNmPipe() call.
  26614.  
  26615.  Microsoft has confirmed this to be a problem in OS/2 version 1.20. We
  26616.  are researching this problem and will post new information here as it
  26617.  becomes available.
  26618.  
  26619.  
  26620.  771. Updating a DLL While a Program Is Still Using the DLL
  26621.  
  26622.  Question:
  26623.  
  26624.  How can I update a dynamic linked library (DLL) while a program that
  26625.  uses this same DLL is still running? We tried to do this under OS/2 by
  26626.  loading the DLL, freeing the DLL, modifying, and then reloading the
  26627.  DLL, but the change is not reflected. OS/2 still seems to think the
  26628.  DLL is in use even after calling DosFreeModule().
  26629.  
  26630.  Response:
  26631.  
  26632.  You need to check the return code from DosFreeModule(). If the return
  26633.  code is error 12, some part of the DLL is needed by an exitlist
  26634.  routine. If you do not get an error, the DLL must be being used by
  26635.  some other process.
  26636.  
  26637.  
  26638.  772. Using System Error Messages with DosGetMessage() in a Program
  26639.  
  26640.  Question:
  26641.  
  26642.  I would like to use the system error messages in my program. For
  26643.  example, if DosFindFirst() returns 15, I want to return the following
  26644.  error message to the user:
  26645.  
  26646.     SYS0015: The system cannot find the drive specified.
  26647.  
  26648.  For my own messages, I can use DosGetMessage() and DosPutMessage()
  26649.  with my message file. For the system messages, should I use
  26650.  DosGetMessage() with the message filename hard-coded to OSO001.MSG?
  26651.  
  26652.  Response:
  26653.  
  26654.  Yes, this is the correct way to perform this type of functionality.
  26655.  This is how the system does it. If you give the name "OSO001.MSG", the
  26656.  system will search for OSO001.MSG on the DPATH variable. OSO001.MSG is
  26657.  set up to be on the DPATH variable by default, so you can always find
  26658.  it.
  26659.  
  26660.  
  26661.  773. Processing Data Returned from DosQNmPipeSemState()
  26662.  
  26663.  DosQNmPipeSemState() returns information in the form of PIPESEMSTATE
  26664.  structures. In earlier releases, these structures were named "npss".
  26665.  The following questions are frequently asked involving these
  26666.  structures:
  26667.  
  26668.  1. How much space do you have to pass to DosQNmPipeSemState() to hold
  26669.     the PIPESEMSTATE structures returned?
  26670.  
  26671.     You can set the variable "pipes" to the number of pipes associated
  26672.     with the semaphore you pass to DosQNmPipeSemState(), and then use
  26673.     the following statement to calculate the buffer size:
  26674.  
  26675.        USHORT PipeInfoSize=((3*pipes)+1)*sizeof(PIPESEMSTATE);
  26676.  
  26677.  2. In what order does DosQNmPipeSemState() return the PIPESEMSTATE
  26678.     structures?
  26679.  
  26680.     Your application cannot safely make any assumptions about the order
  26681.     returned, because the order is not specified. Since the order is
  26682.     not specified, the order may change; therefore, do not rely on any
  26683.     order that you may see in the current releases of OS/2.
  26684.  
  26685.  Further information regarding the above questions is listed below.
  26686.  
  26687.  The long answer to question 1 is listed below:
  26688.  
  26689.  More detailed information regarding the above questions is as follows:
  26690.  
  26691.  1. [How much space do you have to pass to DosQNmPipeSemState() to hold
  26692.     the PIPESEMSTATE structures returned?]
  26693.  
  26694.     OS/2 does not allocate any space to hold PIPESEMSTATE structures.
  26695.     Each time you call DosQNmPipeSemState(), OS/2 looks at each named
  26696.     pipe currently associated with the semaphore you passed to
  26697.     DosQNmPipeSemState(), and builds the PIPESEMSTATE structures in the
  26698.     buffer you passed to DosQNmPipeSemState().
  26699.  
  26700.     In other words, each time you call DosQNmPipeSemState(), OS/2
  26701.     builds the PIPESEMSTATE structures "on the fly" into the buffer you
  26702.     pass.
  26703.  
  26704.     If the buffer you pass to DosQNmPipeSemState() isn't big enough to
  26705.     hold all the PIPESEMSTATE structures that OS/2 might have returned,
  26706.     OS/2 just stops building PIPESEMSTATE structures into your buffer,
  26707.     and returns to you the ones it was able to build before your buffer
  26708.     filled up.
  26709.  
  26710.     Although you can check the DosQNmPipeSemState() return code to see
  26711.     whether the buffer you passed was too small, the only practical
  26712.     approach to use is to pass DosQNmPipeSemState() a buffer you know
  26713.     in advance will be big enough to hold all of the structures.
  26714.  
  26715.     The reason for this is that if your buffer is too small, you may
  26716.     have been returned no PIPESEMSTATE structures at all for some of
  26717.     the named pipes associated with the semaphore.
  26718.  
  26719.     If the return code from DosQNmPipeSemState() states that your
  26720.     buffer was too small, you cannot call DosQNmPipeSemState() again
  26721.     with the same size buffer to get the rest of the PIPESEMSTATE
  26722.     structures that wouldn't fit in your buffer on the previous call.
  26723.     You can, of course, make as many calls as you want, it's just that
  26724.     subsequent calls don't get "the rest of the PIPESEMSTATE
  26725.     structures"; subsequent calls build complete new lists of
  26726.     PIPESEMSTATE structures.
  26727.  
  26728.     If you try to get "the rest of the PIPESEMSTATE structures,"
  26729.     DosQNmPipeSemState() will again build PIPESEMSTATE structures on
  26730.     the fly into your buffer, and will probably again return you no
  26731.     PIPESEMSTATE structures at all for the same named pipes associated
  26732.     with the semaphore for which it returned you no PIPESEMSTATE
  26733.     structures the first time you called DosQNmPipeSemState().
  26734.  
  26735.     This is because DosQNmPipeSemState() builds PIPESEMSTATE structures
  26736.     into your buffer on the fly, and DosQNmPipeSemState() keeps no
  26737.     records of what named pipes were previously successfully queried.
  26738.  
  26739.     Therefore, it's fine to call again if the return code states that
  26740.     your buffer was too small; however, you should understand that the
  26741.     second call will behave as if the first call had not been made.
  26742.  
  26743.     For some other OS/2 APIs, a practical approach to use is to make
  26744.     the call with a buffer that you know is too small, and have the API
  26745.     return to you how much data was available (total). You then can
  26746.     allocate a buffer of that size, and make the call again. This
  26747.     approach allows you to allocate a buffer not one byte larger than
  26748.     is needed for those other APIs. This approach, however, does not
  26749.     work for DosQNmPipeSemState(), because DosQNmPipeSemState() gives
  26750.     no indication of how much data is available.
  26751.  
  26752.     Fortunately, the approach mentioned above as "the only practical
  26753.     approach" for DosQNmPipeSemState() is both easy and cheap enough
  26754.     for most applications.
  26755.  
  26756.     Allocating a buffer you know in advance is big enough costs about
  26757.     18 bytes per pipe associated with the semaphore, because the
  26758.     PIPESEMSTATE structures are only 6 bytes long, and you need to
  26759.     allocate three of them per pipe.
  26760.  
  26761.     As mentioned above, just set the variable "pipes" to the number of
  26762.     pipes associated with the semaphore you pass to
  26763.     DosQNmPipeSemState(), then use the following statement to calculate
  26764.     the buffer size:
  26765.  
  26766.        USHORT PipeInfoSize=((3*pipes)+1)*sizeof(PIPESEMSTATE);
  26767.  
  26768.     This allocates space for three PIPESEMSTATE structures per pipe
  26769.     associated with the semaphore, plus space for one PIPESEMSTATE
  26770.     structure for the NPSS_EOI (end of information) structure that is
  26771.     always returned at the end of your buffer.
  26772.  
  26773.     The reason you need to allocate three PIPESEMSTATES structures per
  26774.     pipe is that at most, DosQNmPipeSemState() will return for each
  26775.     pipe associated with the semaphore one NPSS_RDATA, one NPSS_WSPACE,
  26776.     and one NPSS_CLOSE PIPESEMSTATE structure.
  26777.  
  26778.     NPSS_RDATA, NPSS_WSPACE, and NPSS_CLOSE are defined in BSEDOS.H.
  26779.     The following is an extract from BSEDOS.H for your convenience:
  26780.  
  26781.        #define NPSS_EOI         0 /* End Of Information    */
  26782.        #define NPSS_RDATA       1 /* read data available   */
  26783.        #define NPSS_WSPACE      2 /* write space available */
  26784.        #define NPSS_CLOSE       3 /* pipe in CLOSING state */
  26785.  
  26786.     For some applications, you might be able to get by with a little
  26787.     less than ((3*pipes)+1)*sizeof(PIPESEMSTATE) because you know at a
  26788.     certain point that there can't be any data to read in a certain
  26789.     pipe, or there can't be any write space available, or the pipe
  26790.     can't be closing.
  26791.  
  26792.     However, please remember that you shave off only 6 bytes per
  26793.     PIPESEMSTATE structure you don't allocate. In most cases, shaving
  26794.     off only 6 bytes is not worth the risk that the buffer you pass
  26795.     will be too small.
  26796.  
  26797.     It is not recommended that you attempt to save 5 bytes by only
  26798.     allocating 1 byte in your buffer for the NPSS_EOI structure instead
  26799.     of the full 6. This may work in some releases of OS/2, but the
  26800.     specified behavior is that the NPSS_EOI structure is a PIPESEMSTATE
  26801.     structure, so you should allocate the same space for it as you
  26802.     would for the other structures.
  26803.  
  26804.     To summarize the information for Question 1: the recommended
  26805.     approach is to use the following statement to calculate your buffer
  26806.     size:
  26807.  
  26808.        USHORT PipeInfoSize=((3*pipes)+1)*sizeof(PIPESEMSTATE);
  26809.  
  26810.     It is not recommended that you try to get by with less, because the
  26811.     risks outweigh the number of bytes you might save.
  26812.  
  26813.  2. [In what order does DosQNmPipeSemState() return the PIPESEMSTATE
  26814.     structures?]
  26815.  
  26816.     There is no specific order regarding the order in which
  26817.     DosQNmPipeSemState() must return the PIPESEMSTATE structures in
  26818.     your buffer.
  26819.  
  26820.     Therefore, your application should not make any assumptions about
  26821.     the order of these struc