home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1997 December / Internet_Info_CD-ROM_Walnut_Creek_December_1997.iso / faqs / alt / msdos / programmer / comp.os.msdos.programmer_FAQ_part_3_5 < prev    next >
Internet Message Format  |  1997-10-01  |  31KB

  1. Path: senator-bedfellow.mit.edu!faqserv
  2. From: jeffrey@carlyle.com (Jeffrey Carlyle)
  3. Newsgroups: comp.os.msdos.programmer,alt.msdos.programmer,comp.answers,alt.answers,news.answers
  4. Subject: comp.os.msdos.programmer FAQ part 3/5
  5. Supersedes: <msdos-programmer-faq/part3_873193441@rtfm.mit.edu>
  6. Followup-To: comp.os.msdos.programmer
  7. Date: 30 Sep 1997 09:50:04 GMT
  8. Organization: The COMP-FAQ Project
  9. Lines: 968
  10. Sender: jeffrey@carlyle.com (Jeffrey Carlyle)
  11. Approved: news-answers-request@MIT.Edu
  12. Expires: 3 Nov 1997 09:49:05 GMT
  13. Message-ID: <msdos-programmer-faq/part3_875612945@rtfm.mit.edu>
  14. References: <msdos-programmer-faq/part1_875612945@rtfm.mit.edu>
  15. Reply-To: jeffrey@carlyle.com (Jeffrey Carlyle)
  16. NNTP-Posting-Host: penguin-lust.mit.edu
  17. Summary: Frequently asked questions by DOS programmers with tested answers.
  18. X-Last-Updated: 1997/08/04
  19. Originator: faqserv@penguin-lust.MIT.EDU
  20. Xref: senator-bedfellow.mit.edu comp.os.msdos.programmer:92882 alt.msdos.programmer:39079 comp.answers:28270 alt.answers:29277 news.answers:113415
  21.  
  22. Archive-name: msdos-programmer-faq/part3
  23. Comp-os-msdos-programmer-archive-name: dos-faq-pt3.txt
  24. Posting-frequency: 28 days
  25. Last-modified: 04 Aug 97
  26.  
  27. ------------------------------
  28.  
  29. Subject: comp.os.msdos.programmer FAQ part 3/5
  30.  
  31.  
  32.  For more information about this FAQ list please see Part 1.
  33.  
  34.  
  35.  FAQ        updates       can       be       found        at
  36.  <http://www.premiernet.net/~carlyle>.
  37.  
  38.  
  39.  This  is  part 3 of the frequently asked question list  for
  40.  the newsgroup comp.os.msdos.programmer.
  41.  
  42. Part 3:
  43.   Section 5.  Disks and files
  44.   Section 6.  Serial ports (COM ports)
  45.  
  46. ------------------------------
  47.  
  48. Subject: comp.os.msdos.programmer FAQ
  49.  
  50.  
  51.  Comp.os.msdos.programmer FAQ Version 1997.08
  52.  
  53.  
  54.  Copyright  1997  by Jeffrey Carlyle. All  rights  reserved.
  55.  This  article is not in the public domain, but  it  may  be
  56.  redistributed  so long as this notice, the acknowledgments,
  57.  and  the  information on obtaining the latest copy of  this
  58.  list are retained and no fee is charged. The code fragments
  59.  may be used freely; credit to the FAQ would be polite. This
  60.  FAQ  is not to be included in any static archive (e.g.  CD-
  61.  ROM  or  book);  however,  a pointer  to  the  FAQ  may  be
  62.  included.
  63.  
  64. =============================
  65. TABLE OF CONTENTS
  66. =============================
  67. Part 1:
  68.   Section 1.  General FAQ and Newsgroup Information
  69.   Section 2.  General Reference
  70. Part 2:
  71.   Section 3.  Compile and Link
  72.   Section 4.  Keyboard
  73. Part 3:
  74.   Section 5.  Disks and files
  75.   Section 6.  Serial ports (COM ports)
  76. Part 4:
  77.   Section 7.  Other hardware questions and problems
  78.   Section 8.  Other software questions and problems
  79. Part 5:
  80.   Section 9.  Downloading
  81.   Section 10. Vendors and products
  82.  
  83. ------------------------------
  84.  
  85. Subject: Section 5.  Disks and files
  86.  
  87. <Q: 5.01> - What drive was the PC booted from?
  88. <Q: 5.02> - How can I boot from drive B:?
  89. <Q: 5.03> - Which real and virtual disk drives are valid?
  90. <Q: 5.04>  -  How can I make my single floppy drive both  B:
  91.      and B:?
  92. <Q: 5.05> - How can I disable access to a drive?
  93. <Q: 5.06>  -  How  can  a  batch file test  existence  of  a
  94.      directory?
  95. <Q: 5.07> - Why won't my C program open a file with a path?
  96. <Q: 5.08> - How can I redirect printer output to a file?
  97. <Q: 5.09> - How can I redirect the output of a batch file?
  98. <Q: 5.10> - How can I redirect stderr?
  99. <Q: 5.11>  -  How can my program open more files than  DOS's
  100.      limit of 20?
  101. <Q: 5.12>  -  How can I read, create, change, or delete  the
  102.      volume label?
  103. <Q: 5.13> - How can I get the disk serial number?
  104. <Q: 5.14> - What's the format of .OBJ, .EXE, .COM files?
  105. <Q: 5.15> - How can I flush the software disk cache?
  106. <Q: 5.16> - How can I see if a drive is a RAM drive?
  107.  
  108. ------------------------------
  109.  
  110. Subject: <Q: 5.01> - What drive was the PC booted from?
  111.  
  112.  
  113.  Under DOS 4.0 or later, use INT 21 AX=3305.  DL is returned
  114.  with an integer indicating the boot drive (1=A:, etc.).
  115.  
  116.  
  117. ------------------------------
  118.  
  119. Subject: <Q: 5.02> - How can I boot from drive B:?
  120. Date: Sun, 03 Aug 97 20:07:24 CST
  121.  
  122.  
  123.  Downloadable shareware:
  124.  
  125.   <ftp://ftp.simtel.net/pub/simtelnet/msdos/diskutil/boot_b.
  126.   zip>
  127.   <ftp://garbo.uwasa.fi/pc/bootutil/boot_b.zip>
  128.  
  129.  The  included documentation says it works by writing a  new
  130.  boot  sector on a disk in your a: drive that redirects  the
  131.  boot to your B: drive.  (A similar utility is bboot.zip  in
  132.  the same directory at Garbo only.)
  133.  
  134.  
  135.  If  that  doesn't work, you can always interchange your  A:
  136.  and  B: drives by switching ribbon cables and changing  the
  137.  setup in your BIOS.  From an article posted 27 Jan 1993  on
  138.  another newsgroup:
  139.  
  140.   
  141.   Take  the  "ribbon" connector, as you call it, and  switch
  142.   them.  To double-check, start at the end of the cable that
  143.   connects to the motherboard or floppy controller.   Follow
  144.   the  cable until you get to the first connector.   Connect
  145.   this to the drive you want to be B:.
  146.   
  147.   
  148.   After this, there should be a few lines on the cable  that
  149.   get flipped left to right.  (On most cables, they just cut
  150.   the lines and physically reverse them.  It should be quite
  151.   obvious from looking at the cable.)  Anyway, the connector
  152.   after  the pins get flipped right to left is the connector
  153.   for your a: drive.
  154.   
  155.  
  156. ------------------------------
  157.  
  158. Subject: <Q: 5.03> - Which real and virtual disk drives are
  159.      valid?
  160. Date: Wed, 11 Jan 95 15:34:00 CDT
  161.  
  162.  
  163.  Use  INT 21 AH=29 (parse filename).  Point DS:SI at a null-
  164.  terminated ASCII string that contains the drive letter  and
  165.  a  colon,  point ES:DI at a 37-byte dummy FCB  buffer,  and
  166.  call  INT 21 AX=2900.  On return, AL is FF if the drive  is
  167.  invalid,  something else if the drive is valid.  RAM  disks
  168.  and SUBSTed drives are considered valid.
  169.  
  170.  
  171.  You  can detect whether the drive is ASSIGNed by using  INT
  172.  2F AX=0601.  To check whether the drive is SUBSTed, use INT
  173.  21  AX=4409;  or use INT 21 AH=52 to test for both JOIN and
  174.  SUBST.  See Ralf Brown's interrupt list <Q: 2.03>.
  175.  
  176.  
  177.  Unfortunately, the b: drive is considered valid even  on  a
  178.  single-diskette system.  You can check that special case by
  179.  interrogating the BIOS equipment byte at 0040:0010.  Bits 7-
  180.  6  contain the one less than the number of diskette drives,
  181.  so  if  those bits are zero you know that b: is an  invalid
  182.  drive even though function 29 says it's valid.
  183.  
  184.  
  185.  Following  is some code originally posted by Doug Dougherty
  186.  to test valid drives (treating SUBSTed and JOINed drives as
  187.  valid),  with  my  fix for the b: special case,  tested  in
  188.  Borland C++ 4.5 (in the large model):
  189.  
  190.   #include <dos.h>
  191.   #include <stdio.h>
  192.   void drvlist(void)
  193.   {
  194.     char s[3] = "A:", fcb_buff[37];
  195.     int valid;
  196.   
  197.     for( ;  *s<='Z';  (*s)++)
  198.     {
  199.       _SI = (unsigned) s;
  200.       _DI = (unsigned) fcb_buff;
  201.       _ES = _DS;
  202.       _AX = 0x2900;
  203.   
  204.       geninterrupt(0x21);
  205.       valid = _AL != 0xFF;
  206.   
  207.       if (*s == 'B'  &&  valid)
  208.       {
  209.         char far *equipbyte = (char far *)0x00400010UL;
  210.         valid = (*equipbyte & (3 << 6)) != 0;
  211.        }
  212.   
  213.       printf("Drive '%s' is %sa valid drive.\n", s,
  214.         valid ? "" : "not ");
  215.      }
  216.   }
  217.  
  218.  This  code was translated to MSC 7.0 and tested it in small
  219.  model:
  220.  
  221.   #include <dos.h>
  222.   #include <stdio.h>
  223.   
  224.   void drvlist(void)
  225.   {
  226.     char s[3] = "A:", fcb_buff[37], *buff=fcb_buff;
  227.     int valid;
  228.   
  229.     for (   ;  *s<='Z';  (*s)++)
  230.     {
  231.       __asm mov si,s      __asm mov di,buff
  232.       __asm mov ax,ds     __asm mov es,ax
  233.       __asm mov ax,0x2900 __asm int 21h
  234.       __asm xor ah,ah     __asm mov valid,ax
  235.   
  236.       valid = (valid != 0xFF);
  237.   
  238.       if (*s == 'B'  &&  valid)
  239.       {
  240.         char far *equipbyte = (char far *)0x00400010UL;
  241.         valid = (*equipbyte & (3 << 6)) != 0;
  242.       }
  243.   
  244.       printf("Drive '%s' is %sa valid drive.\n", s,
  245.         valid ? "" : "not");
  246.      }
  247.   }
  248.  
  249. ------------------------------
  250.  
  251. Subject: <Q: 5.04> - How can I make my single floppy drive
  252.      both a: and b:?
  253.  
  254.  
  255.  Under  any  DOS  since DOS 2.0, you can put  the  following
  256.  command into your AUTOEXEC.BAT file:
  257.  
  258.   assign b=a
  259.  
  260.  Then,  when  you  type "dir b:" you'll no  longer  get  the
  261.  annoying  prompt to insert diskette B (and  the  even  more
  262.  annoying  prompt to insert A the next time  you  type  "dir
  263.  a:").
  264.  
  265.  
  266.  You  may  be wondering why anybody would want to  do  this.
  267.  Suppose  you use two different machines, maybe one at  home
  268.  and  one  at  work.  One of them has only a  3.5"  diskette
  269.  drive; the other machine has two drives, and b: is the 3.5"
  270.  one.   You're bound to type "dir b:" on the first one,  and
  271.  get the nuisance message:
  272.  
  273.  
  274.  Insert diskette for drive B: and press any key when ready.
  275.  
  276.  
  277.  But  if you assign drive b: to point to a:, you avoid  this
  278.  problem.
  279.  
  280.  
  281.  Caution:  there are a few commands, such as DISKCOPY,  that
  282.  will not work right on ASSIGNed or SUBSTed drives.  See the
  283.  DOS  manual for the full list.  Before typing one of  those
  284.  commands,  be  sure  to  turn off  the  mapping  by  typing
  285.  "assign" without arguments.
  286.  
  287.  
  288.  The  DOS  5.0  manual  says that ASSIGN  is  obsolete,  and
  289.  recommends  the equivalent form of SUBST: "subst  b:  a:\".
  290.  Unfortunately, if this command is executed when a:  doesn't
  291.  hold  a  diskette, the command fails.  ASSIGN doesn't  have
  292.  this  problem,  so under DOS 5.0 you should disregard  that
  293.  particular bit of advice in the manual.
  294.  
  295.  
  296. ------------------------------
  297.  
  298. Subject: <Q: 5.05> - How can I disable access to a drive?
  299. Date: Sun, 03 Aug 97 20:08:47 CST
  300.  
  301.  
  302.  Reader  Eric  DeVolder writes that he has made available  a
  303.  program  to  do  this.   I  haven't  tried  it,  but   it's
  304.  downloadable as
  305.  
  306.  <ftp://ftp.simtel.net/pub/simtelnet/msdos/diskutil/rmdriv30
  307.  .zip>
  308.  
  309.  Reader  Igor  Karp  reports that  MS-DOS  version  5.0  and
  310.  greater provides two interrupts to do this.
  311.  
  312.   --------D-215F07-----------------------------
  313.   INT 21 - DOS 5+ - ENABLE DRIVE
  314.      AX = 5F07h
  315.      DL = drive number (0=A:)
  316.   Return: CF clear if successful
  317.      CF set on error
  318.      AX = error code (0Fh) (see #0885 at AH=59h)
  319.   Notes:   simply  sets the "valid" bit in the  drive's  CDS
  320.   this function is not supported by Novell DOS 7
  321.   See Also: AH=52h,AX=5F08h"DOS"
  322.   
  323.   --------D-215F08-----------------------------
  324.   INT 21 - DOS 5+ - DISABLE DRIVE
  325.      AX = 5F08h
  326.      DL = drive number (0=A:)
  327.   Return: CF clear if successful
  328.      CF set on error
  329.      AX = error code (0Fh) (see #0885 at AH=59h)
  330.   Notes:   simply clears the "valid" bit in the drive's  CDS
  331.   this function is not supported by Novell DOS 7
  332.  
  333. ------------------------------
  334.  
  335. Subject: <Q: 5.06> - How can a batch file test existence of
  336.      a directory?
  337. Date: Tue, 7 Mar 95 12:00:00 CDT
  338.  
  339.  
  340.  The  standard way, which in fact is documented in  the  DOS
  341.  manual, is
  342.  
  343.   if exist d:\path\nul goto found
  344.  
  345.  Unfortunately, this is not entirely reliable.  I  found  it
  346.  failed  in  Pathworks  (a/k/a  PCSA,  DEC's  network   that
  347.  connects PCs and VAXes), or on a MARS box that uses an  OEM
  348.  version  of MS-DOS 5.0. Readers have reported that it  gave
  349.  the  wrong answer on Novell networks, on DR-DOS, and  in  a
  350.  DOS  window under OS/2.  By "failed" I mean that it "found"
  351.  a  directory that didn't exist, or failed to find one  that
  352.  did  exist, or both.  (I'm told that IBM fixed the OS/2 bug
  353.  in version 2.11 of OS/2.) As a legacy from earlier versions
  354.  of DOS it always succeeds if the path is DEV.
  355.  
  356.  
  357.  There  appears  to be no foolproof way to  use  pure  batch
  358.  commands  to test for existence of a directory.   The  real
  359.  solution is to write a program, which returns a value  that
  360.  your  batch  program can then test with an "if errorlevel".
  361.  Reader  Duncan  Murdoch kindly posted the  following  Turbo
  362.  Pascal version:
  363.  
  364.   program existdir;
  365.   {  Confirms  the  existence of a directory  given  on  the
  366.   command  line.  Returns errorlevel 2 on error,  1  if  not
  367.   found, 0 if found. }
  368.   
  369.   uses dos;
  370.   
  371.   var
  372.     s : searchrec;
  373.   
  374.   begin
  375.     if paramcount <> 1 then
  376.       begin
  377.         writeln('Syntax:  EXISTDIR directory');
  378.         halt(2);
  379.       end
  380.     else
  381.       begin
  382.         findfirst(paramstr(1),Directory,S);
  383.          while (Doserror = 0) and ((Directory and S.Attr)  =
  384.   0) do
  385.           findnext(S);
  386.   
  387.         if Doserror <> 0 then
  388.           begin
  389.             Writeln('Directory not found.');
  390.             halt(1);
  391.           end
  392.         else
  393.           begin
  394.             Writeln('Directory found.');
  395.             halt(0);
  396.           end;
  397.     end;
  398.   end.
  399.  
  400.  Timo  Salmi  also has a Turbo Pascal version in  his  Turbo
  401.  Pascal FAQ, which is downloadable as:
  402.  
  403.  <ftp://garbo.uwasa.fi/pc/ts/tsfaqp*.zip>
  404.  
  405. ------------------------------
  406.  
  407. Subject: <Q: 5.07> - Why won't my C program open a file with
  408.      a path?
  409.  
  410.  
  411.  You've probably got something like the following code:
  412.  
  413.   char *filename = "c:\foo\bar\mumble.dat";
  414.   FILE *fptr;
  415.   /*.*/
  416.   fptr = fopen(filename, "r");
  417.  
  418.  The  problem is that \f is a form feed, \b is a  backspace,
  419.  and  \m  is m.  Whenever you want a backslash in  a  string
  420.  constant in C, you must use two backslashes:
  421.  
  422.   char *filename = "c:\\foo\\bar\\mumble.dat";
  423.  
  424.  This  is  a  feature  of every C compiler,  because  Dennis
  425.  Ritchie designed C this way.  It's a problem only on MS-DOS
  426.  systems,  because  only DOS (and Atari ST/TT  running  TOS)
  427.  uses  the  backslash in directory paths.  But even  in  DOS
  428.  this   backslash  convention  applies  _only_   to   string
  429.  constants in your source code.  For file and keyboard input
  430.  at run time, \ is just a normal character, so users running
  431.  your  program would type in file specs the same way  as  in
  432.  DOS commands, with single \ characters.
  433.  
  434.  
  435.  Another possibility is to code all paths in source programs
  436.  with / rather than \ characters:
  437.  
  438.   char *filename = "c:/foo/bar/mumble.dat";
  439.  
  440.  Ralf  Brown writes, "All versions of the DOS kernel  accept
  441.  either  forward or backslashes as directory separators.   I
  442.  tend  to  use  this  form more frequently than  backslashes
  443.  since it is easier to type and read."  This applies to  DOS
  444.  function calls (and therefore to calls to the file  library
  445.  of every programming language), but not to DOS commands.
  446.  
  447.  
  448. ------------------------------
  449.  
  450. Subject: <Q: 5.08> - How can I redirect printer output to a
  451.      file?
  452. Date: Sun, 03 Aug 97 20:16:07 CST
  453.  
  454.  
  455.  Recommended: PRN2FILE from PC Magazine, downloadable as:
  456.  
  457.  <ftp://ftp.simtel.net/pub/simtelnet/msdos/printer/prn2fil3.
  458.  zip>
  459.  
  460.  PRN2FILE  contains ASM source code. PC Magazine  has  given
  461.  copies  away  as part of its utilities disks,  so  you  may
  462.  already have a copy.
  463.  
  464.  
  465.  The   directories  mentioned  above  have  lots  of   other
  466.  utilities to redirect printer output.
  467.  
  468.  
  469. ------------------------------
  470.  
  471. Subject: <Q: 5.09> - How can I redirect the output of a
  472.      batch file?
  473. Date: Sun, 03 Aug 97 20:18:26 CST
  474.  
  475.  
  476.  Assuming  the batch file is called batch.bat, to  send  its
  477.  output (stdout) to another file, just invoke COMMAND.COM as
  478.  a secondary command processor:
  479.  
  480.   command /c batch parameters_if_any >outfile
  481.  
  482.  Timo  Salmi's  notes  on this and other  batch  tricks  are
  483.  downloadable:
  484.  
  485.  <ftp://ftp.simtel.net/pub/simtelnet/msdos/batchutil/tsbat*.
  486.  zip>
  487.  <ftp://garbo.uwasa.fi/pc/ts/tsbat*.zip>
  488.  
  489. ------------------------------
  490.  
  491. Subject: <Q: 5.10> - How can I redirect stderr?
  492. Date: Sun, 03 Aug 97 20:20:33 CST
  493.  
  494.  
  495.  Use  freopen(...,  stderr)  and then  execute  the  desired
  496.  command  via system().  There are downloadable versions  of
  497.  programs to do this.
  498.  
  499.  
  500.  I  recommend  this  file,  which includes  TP4  source  and
  501.  executable:
  502.  
  503.  <ftp://ftp.simtel.net/pub/simtelnet/msdos/sysutl/rdstderr.z
  504.  ip>
  505.  
  506.  A C example is downloadable as:
  507.  
  508.  <ftp://ftp.simtel.net/pub/simtelnet/msdos/c/redirect.c>
  509.  
  510.  I  compiled  it  with MSC 7.0, and it works fine  with  one
  511.  exception:  Contrary  to the included comments,  redirected
  512.  output  starts writing at the beginning of the output  file
  513.  rather  than  appending.  That is easily solved  by  adding
  514.  "fseek(stderr, 0L, SEEK_END);" after the freopen() call for
  515.  stderr.
  516.  
  517.  
  518. ------------------------------
  519.  
  520. Subject: <Q: 5.11> - How can my program open more files than
  521.      DOS's limit of 20?
  522.  
  523.  
  524.  This  is  a  summary of an article Ralf Brown posted  on  8
  525.  August 1992, with some additions from a Microsoft tech note
  526.  and information from Chin Huang.)
  527.  
  528.  
  529.  DOS imposes some limits.  Once you overcome those, which is
  530.  pretty  easy, you may have to take additional  measures  to
  531.  overcome  the  limitations built into your compiler's  run-
  532.  time library.
  533.  
  534.  
  535.  1) Limitations imposed by DOS:
  536.  
  537.  
  538.  There  are separate limits on files and file handles.   For
  539.  example, DOS opens three files but five file handles:   CON
  540.  (stdin,   stdout,  and  stderr),  AUX  (stdaux),  and   PRN
  541.  (stdprn).
  542.  
  543.  
  544.  The limit in FILES= in CONFIG.SYS is a system-wide limit on
  545.  files opened by all programs (including the three that  DOS
  546.  opens and any opened by TSRs); each process has a limit  of
  547.  20  handles (including the five that DOS opens).   Example:
  548.  CONFIG.SYS has FILES=40.  Then program #1 will be  able  to
  549.  open  15  file handles.  Assuming that the program actually
  550.  does  open 15 handles pointing to 15 different files, other
  551.  programs  could still open a total of 22 files  (40-3-15  =
  552.  22),  though  no one program could open more than  15  file
  553.  handles.  If  you're  running DOS 3.3  or  later,  you  can
  554.  increase the per-process limit of 20 file handles by a call
  555.  to  INT 21 AH=67, Set Handle Count.  Your program is  still
  556.  limited by the system-wide limit on open files, so you  may
  557.  also  need  to increase the FILES= value in your CONFIG.SYS
  558.  file  (and reboot).  The run-time library that you're using
  559.  may  have  a fixed-size table of file handles, so  you  may
  560.  also  need to get source code for the module that  contains
  561.  the table, increase the table size, and recompile it.
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  2) Limitations in Microsoft C run-time library:
  568.  
  569.  
  570.  In  Microsoft C the run-time library limits you to 20  file
  571.  handles. To change this, you must be aware of two limits:
  572.  
  573.  
  574.  File handles used with _open(), _read(), etc.: Edit _NFILE_
  575.  in CRT0DAT.ASM.
  576.  
  577.  
  578.  Stream files used with fopen(), fread(), etc.: Edit _NFILE_
  579.  in  _FILE.C for DOS or FILE.ASM for Windows/QuickWin.  This
  580.  must  not  exceed  the  value of  _NFILE_  in  CRT0DAT.ASM.
  581.  (QuickWin  uses  the  constant _WFILE_ in  CRT0DAT.ASM  and
  582.  WFILE.ASM for the maximum number of child text windows.)
  583.  
  584.  
  585.  After  changing  the limits, recompile using  CSTARTUP.BAT.
  586.  Microsoft recommends that you first read README.TXT in  the
  587.  same directory.
  588.  
  589.  
  590.  3) Limitations in Borland C++ run-time library:
  591.  
  592.  
  593.  (Reader  Chin  Huang provided this information  on  12  Sep
  594.  1993.)
  595.  
  596.  
  597.  To  increase the open file limit for a program you  compile
  598.  with Borland C++ 3.1, edit the file _NFILE.H in the include
  599.  directory and change the _NFILE_ value.  Compile  and  link
  600.  the  modules  FILES.C and FILES2.C from the  lib  directory
  601.  into your program.
  602.  
  603.  
  604. ------------------------------
  605.  
  606. Subject: <Q: 5.12> - How can I read, create, change, or
  607.      delete the volume label?
  608.  
  609.  
  610.  In  DOS  5.0  (and  possibly in 4.0  as  well),  there  are
  611.  actually two volume labels: the LABEL command reports  only
  612.  the first but changes both of them.
  613.  
  614.  
  615.  -     The traditional volume label is an entry with "volume
  616.    label" attribute in the root directory of the disk.   The
  617.    DIR, VOL, and LABEL commands report this volume label, and
  618.    LABEL sets it.
  619.    
  620.  
  621.  -    There is a second volume label, which may be different,
  622.    in the boot record along with the serial number. In DOS 4.0
  623.    and  later,  INT 21 AH=69 gets or sets the boot  record's
  624.    serial number and  volume label together; see "<Q: 5.13> -
  625.    How can I get the disk serial number?"  DIR and VOL ignore
  626.    this volume label; the LABEL command doesn't report it but
  627.    does set it.
  628.    
  629.  
  630.  The  rest of this answer assumes that by "volume label" you
  631.  mean the traditional one, the one that DIR and VOL display.
  632.  Though  it's  a directory entry in the root directory,  you
  633.  can't  change it using the newer DOS file-access  functions
  634.  (INT  21  AH=3C, 41, 43); instead, use the old FCB-oriented
  635.  directory functions.  Specifically, you need to allocate  a
  636.  64-byte  buffer and a 41- byte extended FCB  (file  control
  637.  block).  Call INT 21 AH=1A to find out whether there  is  a
  638.  volume label.  If there is, AL returns 0 and you can change
  639.  the  label  using DOS function 17 or delete  it  using  DOS
  640.  function 13.  If there's no volume label, function 1A  will
  641.  return  FF  and  you can create a label  via  function  16.
  642.  Important points to notice are that ? wildcards are allowed
  643.  but  *  are not; the volume label must be space filled  not
  644.  null terminated.
  645.  
  646.  
  647.  The  following MSC 7.0 code worked for me in DOS  5.0;  the
  648.  functions  it  uses have been around since  DOS  2.0.   The
  649.  function parameter is 0 for the current disk, 1 for  a:,  2
  650.  for b:, etc.  It doesn't matter what your current directory
  651.  is;  these  functions always search the root directory  for
  652.  volume labels.  (I didn't try to change the volume label of
  653.  any networked drives.)
  654.  
  655.   // Requires DOS.H, STDIO.H, STRING.H
  656.   
  657.   void vollabel(unsigned char drivenum)
  658.   {
  659.       static  unsigned  char  extfcb[41],  dta[64],  status,
  660.   *newlabel;
  661.     int chars_got = 0;
  662.   
  663.      #define DOS(buff,func) __asm { __asm mov dx,offset buff
  664.   \
  665.        __asm mov ax,seg buff  __asm push ds  __asm mov ds,ax
  666.   \
  667.        __asm  mov  ah,func   __asm int  21h   __asm  pop  ds
  668.   \
  669.       __asm mov status,al }
  670.   
  671.     #define getlabel(buff,prompt) newlabel = buff;  \
  672.       memset(newlabel,' ',11);  printf(prompt);   \
  673.       scanf("%11[^\n]%n", newlabel, &chars_got);  \
  674.       if (chars_got < 11) newlabel[chars_got] = ' ';
  675.   
  676.     // Set up the 64-byte transfer area used by function 1A.
  677.     DOS(dta, 1Ah)
  678.   
  679.      //  Set  up  an extended FCB and search for the  volume
  680.   label.
  681.     memset(extfcb, 0, sizeof extfcb);
  682.     extfcb[0] = 0xFF;           // denotes extended FCB
  683.      extfcb[6]  = 8;              // volume-label  attribute
  684.   bit
  685.      extfcb[7]  = drivenum;       // 1=A,2=B,...;  0=current
  686.   drive
  687.   
  688.     memset(&extfcb[8], '?', 11);// wildcard *.*
  689.     DOS(extfcb,11h)
  690.      if  (status == 0) {          // DTA has volume  label's
  691.   FCB
  692.       printf("volume label is %11.11s\n", &dta[8]);
  693.       getlabel(&dta[0x18],
  694.         "new label (\"delete\" to delete): ");
  695.       if (chars_got == 0)
  696.         printf("label not changed\n");
  697.       else if (strncmp(newlabel,"delete  ",11) == 0) {
  698.         DOS(dta,13h)
  699.         printf(status ? "label failed\n" :
  700.           "label deleted\n");
  701.       }
  702.       else {                  // user wants to change label
  703.         DOS(dta,17h)
  704.         printf(status ? "label failed\n" :
  705.           "label changed\n");
  706.       }
  707.     }
  708.     else {                      // no volume label was found
  709.       printf("disk has no volume label.\n");
  710.        getlabel(&extfcb[8], "new label (<Enter>  for  none):
  711.   ");
  712.       if (chars_got > 0) {
  713.         DOS(extfcb,16h)
  714.         printf(status ? "label failed\n" :
  715.           "label created\n");
  716.       }
  717.     }
  718.   }        // end function vollabel
  719.  
  720. ------------------------------
  721.  
  722. Subject: <Q: 5.13> - How can I get the disk serial number?
  723.  
  724.  
  725.  If  the disk was formatted by DOS 4.0 or later, use INT 21:
  726.  AX=6900 gets the serial number; AX=6901 sets it.  (The disk
  727.  serial number doesn't exist if the disk was formatted  with
  728.  an  earlier  version  of  DOS,  or  with  some  third-party
  729.  formatters.)  See Ralf Brown's interrupt list <Q: 2.03>, or
  730.  PC Magazine July 1992 (xi:13) page 496, for details.
  731.  
  732.  
  733.  INT  21  AH=69 also gets and sets the volume label  in  the
  734.  boot  record,  which is not necessarily the same  as  "the"
  735.  volume label displayed by the DIR, VOL, and LABEL commands.
  736.  For  that  volume label, see <Q: 5.12> - "How can  I  read,
  737.  create, change, or delete the volume label?"
  738.  
  739.  
  740. ------------------------------
  741.  
  742. Subject: <Q: 5.14> - What's the format of .OBJ, .EXE., .COM
  743.      files?
  744.  
  745.  
  746.  Please  see <Q: 3.06> "What's the format of an .OBJ file?";
  747.  <Q:  3.07> "What's the format of an .EXE header?"; and  <Q:
  748.  3.08>   "What's  the  difference  between  .COM  and   .EXE
  749.  formats?"
  750.  
  751.  
  752. ------------------------------
  753.  
  754. Subject: <Q: 5.15> - How can I flush the software disk
  755.      cache?
  756.  
  757.  
  758.  Please  see "<Q: 8.01> - How can a program reboot  my  PC?"
  759.  (Trust me.)
  760.  
  761.  
  762. ------------------------------
  763.  
  764. Subject: <Q: 5.16> - How can I see if a drive is a RAM
  765.      drive?
  766. Date: Tue, 7 Mar 95 12:00:00 CDT
  767.  
  768.  
  769.  Use  INT 21 AX=4409h. See Ralph Brown's interrupt list  <Q:
  770.  2.03> for more information.
  771.  
  772.  
  773. ------------------------------
  774.  
  775. Subject: Section 6.  Serial ports (COM ports)
  776.  
  777. <Q: 6.01> - How do I set my machine up to use COM3 and COM4?
  778. <Q: 6.02> - How do I find the I/O address of a COM port?
  779. <Q: 6.03> - But aren't the COM ports always at I/O addresses
  780.      3F8, 2F8, 3E8, and 2E8?
  781. <Q: 6.04>  -  How do I configure a COM port and  use  it  to
  782.      transmit data?
  783.  
  784. ------------------------------
  785.  
  786. Subject: <Q: 6.01> - How do I set my machine up to use COM3
  787.      and COM4?
  788.  
  789.  
  790.  Unless  your  machine is fairly old, it's probably  already
  791.  set  up. After installing the board that contains the extra
  792.  COM  port(s), check the I/O addresses in word 0040:0004  or
  793.  0040:0006.   (In DEBUG, type "D 40:4 L4" and remember  that
  794.  every  word is displayed low byte first, so if you see  "03
  795.  56"  the  word  is 5603.)  If those addresses are  nonzero,
  796.  your  PC  is ready to use the ports and you don't need  the
  797.  rest of this answer.
  798.  
  799.  
  800.  If the I/O address words in the 0040 segment are zero after
  801.  you've installed the I/O board, you need some code to store
  802.  these values into the BIOS data segment:
  803.  
  804.   0040:0004  word  I/O address of COM3
  805.   0040:0006  word  I/O address of COM4
  806.   0040:0011   byte  (bits  3-1):  number  of  serial   ports
  807.   installed
  808.  
  809.  The  documentation with your I/O board should tell you  the
  810.  port  addresses.  When you know the proper port  addresses,
  811.  you  can  add  code to your program to store them  and  the
  812.  number  of serial ports into the BIOS data area before  you
  813.  open  communications.  Or you can use  DEBUG  to  create  a
  814.  little program to include in your AUTOEXEC.BAT file,  using
  815.  this script:
  816.  
  817.   n  SET_ADDR.COM       <--- or a different name  ending  in
  818.   .COM
  819.   a 100
  820.   mov  AX,0040
  821.   mov  DS,AX
  822.   mov  wo [0004],aaaa <--- replace aaaa with COM3 address or
  823.   0
  824.   mov  wo [0006],ffff <--- replace ffff with COM4 address or
  825.   0
  826.   and  by [0011],f1
  827.   or    by [0011],8    <--- use number of serial ports times
  828.   2
  829.   mov  AH,0
  830.   int  21
  831.                          <--- this line must be blank
  832.   rCX
  833.   1f
  834.   rBX
  835.   0
  836.   w
  837.   q
  838.  
  839. ------------------------------
  840.  
  841. Subject: <Q: 6.02> - How do I find the I/O address of a COM
  842.      port?
  843. Date: Sun, 03 Aug 97 20:27:12 CST
  844.  
  845.  
  846.  Look  in  the  four words beginning at 0040:0000  for  COM1
  847.  through COM4. (The DEBUG command "D 40:0 L8" will do  this.
  848.  Remember  that  words  are stored and  displayed  low  byte
  849.  first, so a word value of 03F8 will be displayed as F8 03.)
  850.  If  the  value is zero, that COM port is not installed  (or
  851.  you've  got  an  old BIOS; see "5.01> - How  do  I  set  my
  852.  machine  up  to  use COM3 and COM4?").   If  the  value  is
  853.  nonzero,  it  is  the  I/O address of the  transmit/receive
  854.  register for the COM port.
  855.  
  856.  
  857.  Each  COM  port  occupies eight consecutive  I/O  addresses
  858.  (though many chips use only the first seven).
  859.  
  860.  
  861.  Here's some C code to find the I/O address:
  862.  
  863.   unsigned ptSel(unsigned comport)
  864.   {
  865.     unsigned io_addr;
  866.   
  867.     if (comport >= 1  &&  comport <= 4)
  868.     {
  869.       unsigned far *com_addr = (unsigned far *)0x00400000UL;
  870.       io_addr = com_addr[comport-1];
  871.     }
  872.     else
  873.       io_addr = 0;
  874.   
  875.     return io_addr;
  876.   }
  877.  
  878.  You  might  also want to explore Port Finder,  downloadable
  879.  as:
  880.  
  881.  <ftp://ftp.simtel.net/pub/msdos/io_util/pf271.zip>
  882.  
  883.  I haven't tried it myself, but a posted article reviewed it
  884.  very favorably and said it also lets you swap ports around.
  885.  
  886.  
  887. ------------------------------
  888.  
  889. Subject: <Q: 6.03> - But aren't the COM ports always at I/O
  890.      addresses 3F8, 2F8, 3E8, and 2E8?
  891.  
  892.  
  893.  The  first  two are usually right (though not always);  the
  894.  last two are different on many machines.
  895.  
  896.  
  897. ------------------------------
  898.  
  899. Subject: <Q: 6.04> - How do I configure a COM port and use
  900.      it to transmit data?
  901. Date: Sun, 03 Aug 97 20:27:31 CST
  902.  
  903.  
  904.  Do  you want actual code, or do you want books that explain
  905.  what's going on?
  906.  
  907.  
  908.  1) Source code
  909.  
  910.  
  911.  First,  check  your  compiler's  run-time  library.    Many
  912.  compilers   offer  functions  similar  to   Microsoft   C's
  913.  _bios_serialcom() or Borland's bioscom(),  which  may  meet
  914.  your needs.
  915.  
  916.  
  917.  Second,  check  for downloadable resources  at  SimTel  and
  918.  Garbo.                       At                     SimTel,
  919.  <ftp://oak.oakland.edu/pub/msdos/c/pcl4c34.zip>      (March
  920.  1993)  is described as "Asynchronous communications library
  921.  for  C";  Garbo  has a whole <ftp://garbo.uwasa.fi/pc/comm>
  922.  directory.   Also,  an  extended example  is  in  Borland's
  923.  TechFax TI445, downloadable as part of:
  924.  
  925.  <ftp://ftp.simtel.net/pub/msdos/turbo-c/bchelp10.zip>
  926.  <ftp://garbo.uwasa.fi/pc/turbopas/bchelp10.zip>
  927.  
  928.  Though  written  by Borland, much of it  is  applicable  to
  929.  other  forms of C, and it should give you ideas  for  other
  930.  programming languages.
  931.  
  932.  
  933.  2) Reference books
  934.  
  935.  
  936.  Highly recommended: Joe Campbell's {C Programmer's Guide to
  937.  Serial  Communications},  ISBN  0-672-22584-0.   He   gives
  938.  complete  details  on  how serial ports  work,  along  with
  939.  complete programs for doing polled or interrupt-driver I/O.
  940.  The book is quite thick, and none of it looks like filler.
  941.  
  942.  
  943.  If  Campbell's book is overkill for you, you'll find a good
  944.  short  description of serial I/O in {DOS 5:  A  Developer's
  945.  Guide}, ISBN 1-55851-177-6, by Al Williams.
  946.  
  947.  
  948.  Finally,  a  reader has recommended {Serial  Communications
  949.  Programming in C/C++} by Mark Goodwin (ISBN 1-55828-198-3),
  950.  with  source code in the book and on disk.  Topics  include
  951.  the basics, various methods of serial communications on the
  952.  PC  (with consideration of high-speed modems), ANSI  screen
  953.  interface,  file  transfer protocols (Xmodem  and  Ymodem),
  954.  etc.  There is code in C, and that code is extended into  a
  955.  C++   class  for  those  who  use  C++.   There  are   also
  956.  subroutines in Assembly.
  957.  
  958.  
  959.  3) Downloadable information files
  960.  
  961.  
  962.  A   "Serial  Port  FAQ"  is  occasionally  posted  to  this
  963.  newsgroup, and is downloadable as multiple files:
  964.  
  965.  <ftp://ftp.phil.uni-sb.de/pub/people/chris/*Serial*>
  966.  
  967.  For rtfm.mit.edu instructions, see <Q: 1.13> "Where are FAQ
  968.  lists archived?"
  969.  
  970.  
  971. ------------------------------
  972.  
  973. Subject: End
  974.  
  975.  (FAQ       updates       can       be       found        at
  976.  <http://www.premiernet.net/~carlyle>.)
  977.  (End  of comp.os.msdos.programmer FAQ Version 1997.08  Part
  978.  3/5)
  979.  (This text is copyright 1997 by Jeffrey Carlyle. All rights
  980.  reserved.)
  981.  
  982.  
  983.  
  984. // Jeffrey Carlyle, Bowling Green, Kentucy USA
  985. // 
  986. // comp.os.msdos.programmer FAQ maintainer
  987. // <http://www.premiernet.net/~carlyle> 
  988.  
  989.  
  990.