home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / SWAG9605.DDD / 0106_Excellent Disk Drive Unit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-05-31  |  18.0 KB  |  646 lines

  1. unit Drives;
  2. {
  3.     Drives Unit for:
  4.         Getting and setting drive labels.
  5.         Getting and setting drive serial number.
  6.         Testing if a drive is ready.
  7.         Determining the type of drive (hard/3.5/5.25...)
  8.         Return last DOS error status.
  9.  
  10.   All procedures and functions are protected from DOS critical errors.
  11.  
  12.     Author: William R. Florac
  13.   Company: FITCO, Verona, WI (wee little company from my house)
  14.     Copyright 1996, FITCO.  All rights reserved.
  15.  
  16.   1) Users of Drives.pas must accept this disclaimer of warranty:
  17.        This Unit is supplied as is.  The Fitco disclaims all
  18.        warranties, expressed or implied, including, without limitation,
  19.        the warranties of merchantability and of fitness for any purpose.
  20.        Fitco assumes no liability for damages, direct or conse-
  21.        quential, which may result from the use of this Unit."
  22.  
  23.   2) This Unit is donated to the public as public domain except as
  24.      noted below.
  25.  
  26.   3) You must copy all Software without modification and must include
  27.      all pages, if the Software is distributed without inclusion in your
  28.      software product. If you are incorporating the Software in
  29.      conjunction with and as a part of your software product which adds
  30.      substantial value, you may modify and include portions of the
  31.      Software.
  32.  
  33.   4) Fitco retains the copyright for this Unit.  You may not distribute
  34.      the source code (PAS) or its compiled unit (DCU) for profit.
  35.  
  36.   5) If you do find this Unit handy and you feel guilty
  37.      for using such a great product without paying someone,
  38.      please feel free to send a few bucks ($25) to support further
  39.      development.
  40.  
  41.   6) This file was formated with tabs set to 2.
  42.  
  43.     Please forward any comments or suggestions to Bill Florac at:
  44.          email: flash@etcconnect.com
  45.         www: http://sumac.etcconnect.com/~fitco/
  46.         mail: FITCO
  47.                     209 Jenna Dr
  48.                     Verona, WI  53593
  49.  
  50.     Revision History
  51.         2/28/96
  52.         1.0 released
  53. }
  54.  
  55.  
  56. interface
  57.  
  58. uses
  59.     SysUtils, WinProcs, WinTypes;
  60.  
  61. type
  62.       TDriveStyle = (tUnknown, tNoDrive, t3Floppy, t5Floppy, tFixed, tRFixed,
  63.         tNetwork, tCDROM, tTape);
  64.  
  65.         PDeviceParams = ^TDeviceParams;
  66.         TDeviceParams = record
  67.             bSpecFunc:             byte;            {Special functions}
  68.             bDevType:             byte;            {Device type}
  69.             wDevAttr:             word;            {Device attributes}
  70.             wCylinders:         word;            {Number of cylinders}
  71.             bMediaType:         byte;            {Media type}
  72. {                          Beginning of BIOS parameter block (BPB)}
  73.             wBytesPerSec:     word;            {Bytes per sector}
  74.             bSecPerClust:     byte;            {Sectors per cluster}
  75.             wResSectors:         word;            {Number of reserved sectors}
  76.             bFATs:                     byte;            {Number of FATs}
  77.             wRootDirEnts:     word;            {Number of root-directory entries}
  78.             wSectors:             word;            {Total number of sectors}
  79.             bMedia:                 byte;            {Media descriptor}
  80.             wFATsecs:             word;            {Number of sectors per FAT}
  81.             wSecPerTrack:     word;            {Number of sectors per track}
  82.             wHeads:                 word;            {Number of heads}
  83.             dwHiddenSecs:     longInt;    {Number of hidden sectors}
  84.             dwHugeSectors:     longInt;    {Number of sectors if wSectors == 0}
  85.             reserved:             array[0..10] of char;
  86. {                          End of BIOS parameter block (BPB)}
  87.         end;
  88.  
  89.     {parameter block for getting serial number}
  90.     PSerialNumberParams = ^TSerialNumberParams;
  91.     TSerialNumberParams = record
  92.         wInfoLevel:                 word;
  93.         dwDiskSerialNumber: longint;
  94.         caLabel:                         array[0..10] of char;
  95.         baFileSystem:             array[0..7] of char;
  96.       end;
  97.  
  98.  
  99.     {parameter block to get extened error codes}
  100.     PExtErrorParams = ^TExtErrorParams;
  101.   TExtErrorParams = record
  102.     eCode:         word;
  103.         eClass:     word;
  104.         eAction:     word;
  105.         eLocus:     word;
  106.         eVolume:     String;
  107.         end;
  108.  
  109.     {structure for FCB}
  110.   TEFCB = record
  111.     Flag:             byte;
  112.     Reserved:     array [0..4] of char;
  113.     Attribute:     byte;
  114.     Drive:             byte;
  115.     Name:             array [0..7] of char;
  116.     Extension:     array [0..2] of char;
  117.     Misc:             array  [0..24] of char;
  118.     end;
  119.  
  120. DriveLabel = string[11];
  121.  
  122.   {my exception class}
  123.     EDriveException = Class(Exception);
  124.  
  125. const
  126.      {$I strings}  { can be found at the END of this module !}
  127.  
  128. {standard calls}
  129. function DriveReady(wDrive: word): boolean;
  130. {Tests to see if a drive is ready.  (floppy there and door closed)}
  131.  
  132. function GetDriveLabel(wDrive: word): string;
  133. function SetDriveLabel(wDrive: word; s: string): boolean;
  134. {Gets and sets drive label}
  135.  
  136. function GetDriveSerialNumber(wDrive: word): LongInt;
  137. function SetDriveSerialNumber(wDrive: word; SerialNumber: LongInt): boolean;
  138. {Gets and sets drive serial number}
  139.  
  140. function GetDefaultDrive: word;
  141. {Returns current default drive}
  142.  
  143. function GetDriveStyle(wDrive: word): TDriveStyle;
  144. {Returns the drive style (hard, 3-1/2, 5-1/4...)}
  145.  
  146. procedure GetExtendedErrorInfo(ep: PExtErrorParams);
  147. {Gets the parameters for the last DOS error.  Useful after a DriveReady failure.}
  148.  
  149. {other calls}
  150. function IsCDROMDrive(wDrive: word): boolean;
  151. function WriteDriveSNParam(wDrive: word; psnp: PSerialNumberParams): boolean;
  152. function ReadDriveSNParam(wDrive: word; psnp: PSerialNumberParams): boolean;
  153. function GetDeviceParameters(wDrive: word; var dp: TDeviceParams): boolean;
  154.  
  155.  
  156. implementation
  157.  
  158. {determins if the drive is ready w/o critical errors enabled}
  159. function DriveReady(wDrive: word): boolean;
  160. var
  161.   OldErrorMode: Word;
  162. begin
  163.     {turn off errors}
  164.   OldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  165.     try
  166.         if DiskSize(wDrive) = -1
  167.         then result := false
  168.         else result := true;
  169.   finally
  170.         {turn on errors}
  171.         SetErrorMode(OldErrorMode);
  172.     end;
  173.  
  174. end;
  175.  
  176. {get drive parameters w/o drive access}
  177. function GetDeviceParameters(wDrive: word; var dp: TDeviceParams): boolean;
  178. begin
  179.     result := TRUE;      {Assume success}
  180.    asm
  181.             push ds
  182.       mov  bx, wDrive
  183.       mov  ch, 08h      {Device category--must be 08h}
  184.       mov  cl, 60h      {MS-DOS IOCTL Get Device Parameters}
  185.       lds  dx, dp
  186.       mov  ax, 440Dh
  187.       int  21h
  188.       jnc  @gdp_done     {CF SET if error}
  189.       mov  result, FALSE
  190.    @gdp_done:
  191.       pop  ds
  192.     end;
  193. end;
  194.  
  195. {gets last error message from DOS}
  196. procedure GetExtendedErrorInfo(ep: PExtErrorParams);
  197. var
  198.     tCode: word;
  199.     tClass: byte;
  200.     tAction: byte;
  201.     tLocus: byte;
  202. begin
  203.   asm
  204.         push ds
  205.         push bp
  206.       mov  bx, 0
  207.       mov  ah, 59h
  208.     int  21h
  209.         mov     tCode, ax
  210.         mov     tClass, bh
  211.     mov     tAction, bl
  212.         mov     tLocus, ch
  213.         pop  bp
  214.         pop  ds
  215.     end;
  216.   ep^.eCode := tCode;
  217.     ep^.eClass := tClass;
  218.     ep^.eAction := tAction;
  219.     ep^.eLocus := tLocus;
  220.     ep^.eVolume := '?'; {don't support this for now}
  221. end;
  222.  
  223. {get volume serial number for a drive:  0=default, 1=A...}
  224. {returns -1 if unable to read}
  225. function GetDriveSerialNumber(wDrive: word): LongInt;
  226. var
  227.     snp: TSerialNumberParams;
  228. begin
  229.     snp.dwDiskSerialNumber := 0;
  230.     if ReadDriveSNParam(wDrive, @snp)
  231.     then Result := snp.dwDiskSerialNumber
  232.     else Result := -1;
  233. end;
  234.  
  235.  
  236. {set volume serial number for a drive:  0=default, 1=A... }
  237. {returns true if it was sucessful}
  238. function SetDriveSerialNumber(wDrive: word; SerialNumber: LongInt): boolean;
  239. var
  240.     snp: TSerialNumberParams;
  241. begin
  242.     result := false;
  243.     {get current parameters}
  244.     if ReadDriveSNParam(wDrive, @snp) then begin
  245.         {change serial number}
  246.         snp.dwDiskSerialNumber := SerialNumber;
  247.         {and write back out}
  248.         if WriteDriveSNParam(wDrive, @snp) then result := true;
  249.     end;
  250. end;
  251.  
  252. {Write Drive parameters: 0=default, 1=A...}
  253. {Note: wDrive and psnp are treate as var with assembler directive}
  254. {This interupt does NOT generate a critical error!}
  255. function WriteDriveSNParam(wDrive: word; psnp: PSerialNumberParams): boolean; assembler;
  256. asm
  257.     push ds           {ds might get changed so save it}
  258.     mov  bx, wDrive
  259.   mov  al, 01h
  260.     mov  ah, 69h
  261.   lds  dx, psnp
  262.   int  21h
  263.   jnc  @no_error    {CF SET if error}
  264.     xor     ax,ax                {set false}
  265.   jmp     @exit
  266. @no_error:
  267.   mov    ax, 1                    {set true}
  268. @exit:
  269.     pop    ds                        {restore ds}
  270. end;
  271.  
  272. {Read Drive parameters: 0=default, 1=A...}
  273. {Note: wDrive and psnp are treate as var with assembler directive}
  274. {This interupt does NOT generate a critical error!}
  275. function ReadDriveSNParam(wDrive: word; psnp: PSerialNumberParams): boolean; assembler;
  276. asm
  277.     push ds
  278.     mov  bx, wDrive
  279.   mov  al, 00h
  280.     mov  ah, 69h
  281.   lds  dx, psnp
  282.   int  21h
  283.   jnc  @no_error        {CF SET if error}
  284.     xor     ax,ax        {set false}
  285.   jmp     @exit
  286. @no_error:
  287.   mov    ax, 1            {set true}
  288. @exit:
  289.     pop    ds
  290. end;
  291.  
  292. {sets the label of the drive specified: wDrive: 0=default 1=A...}
  293. {returns true if it was sucessful}
  294. function SetDriveLabel(wDrive: word; s: string): boolean;
  295. const
  296.         EFCB: TEFCB = (
  297.         Flag: $FF;                              { Extended FCB Flag }
  298.       Reserved: (#0,#0,#0,#0,#0);           { Reserved}
  299.       Attribute: $08;                       { Volume Label Attribute}
  300.       Drive: 2;                             { Drive Identifier}
  301.       Name: '????????';                                          { File Name}
  302.       Extension: '???';                     { File Extension}
  303.       Misc: (#0, #0, #0, #0, #0,            { Misc. Info filled by DOS}
  304.         ' ',' ',' ',' ',' ',' ',' ',' ',      { Misc. Info filled by DOS}
  305.         ' ',' ',' ',                          { Misc. Info filled by DOS}
  306.         #0, #0, #0, #0, #0, #0, #0, #0, #0  { Misc. Info filled by DOS}
  307.                 )
  308.       );
  309. var
  310.     Ps: pchar;
  311.     err: integer;
  312.     x: integer;
  313.  
  314. begin
  315.     {abort if drive not ready}
  316.     if not DriveReady(wDrive) then begin
  317.         result := false;
  318.         exit;
  319.     end;
  320.     {assume ok}
  321.     result := true;
  322.  
  323.     {default things that change in constant varaiable}
  324.     EFCB.Name := '????????';
  325.     EFCB.Extension := '???';
  326.     EFCB.Drive := wDrive;
  327.  
  328.     {See if it exist using a FCB}
  329.     asm
  330.         {Check to see;  if the volume label exists}
  331.         {point DTA to ourself}
  332.         mov     dx,offset EFCB
  333.         mov     ah,1Ah
  334.         int  21h
  335.         {point to default FCB}
  336.        mov  dx, offset EFCB
  337.     mov  ah, 11h
  338.     int  21h
  339.         {Exit if label is not present}
  340.     cmp  al, 0
  341.     jne  @exit
  342.         {Else delete the volume label}
  343.     mov  dx, offset EFCB
  344.     mov  ah, 013h
  345.     int  21h
  346.     or     al,al
  347.         jz    @exit
  348.         mov    result, 0
  349.   @exit:
  350.     end;
  351.  
  352.     if not result then exit;
  353.  
  354.     {if string is empty, then just erase}
  355.     if length(s) = 0 then exit;
  356.     {format string}
  357.     for x := length(s) + 1 to 11  do s[x] := ' ';
  358.     s[0] := char(11);
  359.     {add drive letter!}
  360.   if wdrive = 0
  361.     then s := '\' + s + #0
  362.     else s := chr(64+wdrive) + ':\' + s + #0;
  363.     ps := @s[1];
  364.  
  365.     {on now make new one it!}
  366.     asm
  367.         push ds
  368.     lds  dx, ps
  369.     mov  cx, faVolumeID
  370.     mov  ah,3Ch
  371.     int  21h
  372.     {CF set if error}
  373.     jnc  @noerror
  374.     mov  result, FALSE
  375.         jmp     @exit
  376.   @noerror:
  377.         {close file ax = handle}
  378.         mov  bx,ax
  379.         mov     ah,3Eh
  380.         int     21h
  381.   @exit:
  382.       pop  ds
  383.     end
  384. end;
  385.  
  386. {Get label from drive.  0=default, 1=A...}
  387. {return string of 11 character or "NO NAME" if not found}
  388. function GetDriveLabel(wDrive: word): string;
  389. const
  390.     pattern: string[6] = 'c:\*.*';
  391. var
  392.     sr: TsearchRec;
  393.   OldErrorMode: Word;
  394.   DotPos: Byte;
  395. begin
  396.     {get default drive}
  397.     if wDrive = 0
  398.     then wDrive := GetDefaultDrive
  399.     else dec(wDrive);
  400.  
  401.     {switch out drive letter}
  402.     pattern[1] := char(65 + wDrive);
  403.  
  404.     {stop errors and try}
  405.   OldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  406.     try
  407.         if FindFirst(Pattern, faVolumeID, sr) = 0 then begin
  408.       Result := sr.Name;
  409.       DotPos := Pos('.', Result);
  410.       if DotPos <> 0 then Delete(Result, DotPos, 1);
  411.       end
  412.         else result := 'NO NAME'
  413.   finally
  414.         {restore errorsa}
  415.         SetErrorMode(OldErrorMode);
  416.   end;
  417. end;
  418.  
  419. function GetDefaultDrive: word; assembler;
  420. asm
  421.     mov    ah, 19h             {convert default to real}
  422.     int    21h
  423.     xor    ah, ah                {clear hi byte}
  424. end;
  425.  
  426. {Determine id drive is a CDROM, 0=default, 1=A ...}
  427. function IsCDROMDrive(wDrive: word): boolean; assembler;
  428. var
  429.     wTempDrive: word;
  430. asm
  431.     mov    ax, wDrive
  432.     or  ax, ax
  433.     jnz    @not_default
  434.     mov    ah, 19h             {convert default to drive}
  435.     int    21h
  436.     xor    ah, ah
  437.     mov wTempDrive, ax
  438.     jmp    @test_it
  439. @not_default:             {zero base it}
  440.     dec    ax
  441.     mov wTempDrive, ax
  442. @test_it:
  443.     mov ax, 1500h     {first test for presence of MSCDEX}
  444.   xor bx, bx
  445.   int 2fh
  446.   mov ax, bx        {MSCDEX is not there if bx is zero}
  447.     or  ax, ax        {so return FALSE}
  448.     jz  @no_mscdex
  449.     mov ax, 150bh     {MSCDEX driver check API}
  450.     mov cx, wTempDrive    {...cx is drive index}
  451.     int 2fh
  452.     or     ax, ax
  453. @no_mscdex:
  454. end;
  455.  
  456. {returns drive type}
  457. {read BOIS not drive so floppy does not have to be in drive}
  458. {I don't have all types of drive so not all could be tested}
  459. function GetDriveStyle(wDrive: word): TDriveStyle;
  460. var
  461.     x: word;
  462.     wTempDrive: word;
  463.     dp: TDeviceParams;
  464. begin
  465.     {convert default to drive}
  466.     if wDrive = 0
  467.     then wTempDrive := GetDefaultDrive
  468.     else wTempDrive := wDrive - 1;
  469.     x := GetDriveType(wTempDrive);
  470.  
  471.     {get types}
  472.     case x of
  473.     drive_Removable: begin
  474.         dp.bSpecFunc := 0; {need to clear this}
  475.         if GetDeviceParameters(wDrive,dp) then begin
  476.             case dp.bDevType of
  477.             0,1: result := t5floppy;        {320K/360K/1.2M}
  478.             2,7,9: result := t3floppy;    {720K/1.44M/2.88M}
  479.             5: result := tRFixed;         {yes a removable fixed drive!}
  480.             6: result := tTape;         {tape}
  481.       else result := tUnknown;
  482.             end;
  483.         end
  484.         else result := tUnknown;
  485.     end;
  486.   drive_Fixed:
  487.         if IsCDROMDrive(wDrive)
  488.         then result := tCDROM
  489.         else result := tFixed;
  490.      drive_Remote:
  491.         if IsCDROMDrive(wDrive) {I think this is possible on a network!}
  492.         then result := tCDROM
  493.         else result := tNetWork;
  494.     else result := tUnknown;
  495.     end;
  496. end;
  497.  
  498. end. {of unit}
  499.  
  500. { ----------------   STRINGS.PAS  ---------------------------------}
  501. { CUT }
  502.  
  503. {string constants for drives.pas}
  504.  
  505. {The error class may be one of the following}
  506.      eClassStr: array[0..$0D] of string = (
  507. {OK                                            }'OK',
  508. {ERRCLASS_OUTRES (01h)    }'Out of resource, such as storage.',
  509. {ERRCLASS_TEMPSIT (02h)    }'Not an error, temporary situation (file or record lock)',
  510. {ERRCLASS_AUTH (03h)        }'Authorization problem.',
  511. {ERRCLASS_INTRN (04h)        }'Internal error in system.',
  512. {ERRCLASS_HRDFAIL (05h)    }'Hardware failure.',
  513. {ERRCLASS_SYSFAIL (06h)    }'System software failure (missing or incorrect configuration files).',
  514. {ERRCLASS_APPERR (07h)    }'Application error.',
  515. {ERRCLASS_NOTFND (08h)  }'File or item not found.',
  516. {ERRCLASS_BADFMT (09h)  }'File or item with an invalid format or type.',
  517. {ERRCLASS_LOCKED (0Ah)  }'Interlocked file or item.',
  518. {ERRCLASS_MEDIA (0Bh)   }'Wrong disk in drive, bad spot on disk, or other storage-medium problem.',
  519. {ERRCLASS_ALREADY (0Ch) }'Existing file or item.',
  520. {ERRCLASS_UNK (0Dh)           }'Unknown.');
  521.  
  522. {*The suggested action may be one of the following:}
  523.      eActionStr: array[0..$07] of string = (
  524. {OK                                            }'OK',
  525. {ERRACT_RETRY (01h)            }'Retry immediately.',
  526. {ERRACT_DLYRET (02h)        }'Delay and retry.',
  527. {ERRACT_USER (03h)            }'Bad user input, get new values.',
  528. {ERRACT_ABORT (04h)            }'Terminate in an orderly manner.',
  529. {ERRACT_PANIC (05h)            }'Terminate immediately.',
  530. {ERRACT_IGNORE (06h)        }'Ignore the error.',
  531. {ERRACT_INTRET (07h)        }'Remove the cause of the error (to change disks, for example) and then retry.');
  532.  
  533. {The error location may be one of the following:}
  534. eLocusStr: array[0..$05] of string = (
  535. {OK                                            }'OK',
  536. {ERRLOC_UNK (01h)                }'Unknown',
  537. {ERRLOC_DISK (02h)            }'Random-access device, such as a disk drive',
  538. {ERRLOC_NET (03h)                }'Network',
  539. {ERRLOC_SERDEV (04h)        }'Serial device',
  540. {ERRLOC_MEM (05h)                }'Memory');
  541.  
  542. {MS DOS error codes}
  543. eDosErrorStr: array[0..$5A] of string = (
  544. {0000h  non error} 'OK',
  545. {0001h}    'ERROR_INVALID_FUNCTION',
  546. {0002h}    'ERROR_FILE_NOT_FOUND',
  547. {0003h}    'ERROR_PATH_NOT_FOUND',
  548. {0004h}    'ERROR_TOO_MANY_OPEN_FILES',
  549. {0005h}    'ERROR_ACCESS_DENIED',
  550. {0006h}    'ERROR_INVALID_HANDLE',
  551. {0007h}    'ERROR_ARENA_TRASHED',
  552. {0008h}    'ERROR_NOT_ENOUGH_MEMORY',
  553. {0009h}    'ERROR_INVALID_BLOCK',
  554. {000Ah}    'ERROR_BAD_ENVIRONMENT',
  555. {000Bh}    'ERROR_BAD_FORMAT',
  556. {000Ch}    'ERROR_INVALID_ACCESS',
  557. {000Dh}    'ERROR_INVALID_DATA',
  558. {000Eh} 'Reserved',
  559. {000Fh}    'ERROR_INVALID_DRIVE',
  560. {0010h}    'ERROR_CURRENT_DIRECTORY',
  561. {0011h}    'ERROR_NOT_SAME_DEVICE',
  562. {0012h}    'ERROR_NO_MORE_FILES',
  563. {0013h}    'ERROR_WRITE_PROTECT',
  564. {0014h}    'ERROR_BAD_UNIT',
  565. {0015h}    'ERROR_NOT_READY',
  566. {0016h}    'ERROR_BAD_COMMAND',
  567. {0017h}    'ERROR_CRC',
  568. {0018h}    'ERROR_BAD_LENGTH',
  569. {0019h}    'ERROR_SEEK',
  570. {001Ah}    'ERROR_NOT_DOS_DISK',
  571. {001Bh}    'ERROR_SECTOR_NOT_FOUND',
  572. {001Ch}    'ERROR_OUT_OF_PAPER',
  573. {001Dh}    'ERROR_WRITE_FAULT',
  574. {001Eh}    'ERROR_READ_FAULT',
  575. {001Fh}    'ERROR_GEN_FAILURE',
  576. {0020h}    'ERROR_SHARING_VIOLATION',
  577. {0021h}    'ERROR_LOCK_VIOLATION',
  578. {0022h}    'ERROR_WRONG_DISK',
  579. {0023h}    'ERROR_FCB_UNAVAILABLE',
  580. {0024h}    'ERROR_SHARING_BUFFER_EXCEEDED',
  581. {0025h}    'ERROR_CODE_PAGE_MISMATCHED',
  582. {0026h}    'ERROR_HANDLE_EOF',
  583. {0027h}    'ERROR_HANDLE_DISK_FULL',
  584. {0028h} 'Reserved',
  585. {0029h} 'Reserved',
  586. {002Ah} 'Reserved',
  587. {002Bh} 'Reserved',
  588. {002Ch} 'Reserved',
  589. {002Dh} 'Reserved',
  590. {002Eh} 'Reserved',
  591. {002Fh} 'Reserved',
  592. {0030h} 'Reserved',
  593. {0031h} 'Reserved',
  594. {0032h}    'ERROR_NOT_SUPPORTED',
  595. {0033h}    'ERROR_REM_NOT_LIST',
  596. {0034h}    'ERROR_DUP_NAME',
  597. {0035h}    'ERROR_BAD_NETPATH',
  598. {0036h}    'ERROR_NETWORK_BUSY',
  599. {0037h}    'ERROR_DEV_NOT_EXIST',
  600. {0038h}    'ERROR_TOO_MANY_CMDS',
  601. {0039h}    'ERROR_ADAP_HDW_ERR',
  602. {003Ah}    'ERROR_BAD_NET_RESP',
  603. {003Bh}    'ERROR_UNEXP_NET_ERR',
  604. {003Ch}    'ERROR_BAD_REM_ADAP',
  605. {003Dh}    'ERROR_PRINTQ _FULL',
  606. {003Eh}    'ERROR_NO_SPOOL_SPACE',
  607. {003Fh}    'ERROR_PRINT_CANCELLED',
  608. {0040h}    'ERROR_NETNAME_DELETED',
  609. {0041h}    'ERROR_NETWORK_ACCESS_DENIED',
  610. {0042h}    'ERROR_BAD_DEV_TYPE',
  611. {0043h}    'ERROR_BAD_NET_NAME',
  612. {0044h}    'ERROR_TOO_MANY_NAMES',
  613. {0045h}    'ERROR_TOO_MANY_SESS',
  614. {0046h}    'ERROR_SHARING_PAUSED',
  615. {0047h}    'ERROR_ERROR_REQ _NOT_ACCEP',
  616. {0048h}    'ERROR_REDIR_PAUSED',
  617. {0049h} 'Reserved',
  618. {004Ah} 'Reserved',
  619. {004Bh} 'Reserved',
  620. {004Ch} 'Reserved',
  621. {004Dh} 'Reserved',
  622. {004Eh} 'Reserved',
  623. {004Fh} 'Reserved',
  624. {0050h}    'ERROR_FILE_EXISTS',
  625. {0051h}    'ERROR_DUP_FCB',
  626. {0052h}    'ERROR_CANNOT_MAKE',
  627. {0053h}    'ERROR_FAIL_I24',
  628. {0054h}    'ERROR_OUT_OF_STRUCTURES',
  629. {0055h}    'ERROR_ALREADY_ASSIGNED',
  630. {0056h}    'ERROR_INVALID_PASSWORD',
  631. {0057h}    'ERROR_INVALID_PARAMETER',
  632. {0058h}    'ERROR_NET_WRITE_FAULT',
  633. {0059h}    'Function not supported on Network',
  634. {005Ah}    'ERROR_SYS_COMP_NOT_LOADED');
  635.  
  636. cDriveStr: array[0..8] of string = (
  637.             'Unknown',
  638.             'NoDrive',
  639.             '3-1/2" floppy',
  640.             '5-1/4" floppy',
  641.              'hard',
  642.             'removable hard',
  643.             'network',
  644.             'CD ROM',
  645.       'tape');
  646.