home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 October / PCO1097.ISO / FilesBBS / OS2 / DISKIO11.ARJ / DISKIO11.ZIP / diskacc2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-09  |  7.8 KB  |  347 lines

  1. /* diskacc2.c - direct disk access library for OS/2 2.x protected mode.
  2.  *
  3.  * Author:  Kai Uwe Rommel <rommel@ars.muc.de>
  4.  * Created: Fri Jul 08 1994
  5.  */
  6.  
  7. static char *rcsid =
  8. "$Id: diskacc2.c,v 1.4 1997/02/09 15:05:57 rommel Exp rommel $";
  9. static char *rcsrev = "$Revision: 1.4 $";
  10.  
  11. /*
  12.  * $Log: diskacc2.c,v $
  13.  * Revision 1.4  1997/02/09 15:05:57  rommel
  14.  * added a few comments
  15.  *
  16.  * Revision 1.3  1997/01/12 21:15:26  rommel
  17.  * added CD-ROM routines
  18.  *
  19.  * Revision 1.2  1995/12/31 21:50:58  rommel
  20.  * added physical/logical mode parameter
  21.  *
  22.  * Revision 1.1  1994/07/08 21:34:12  rommel
  23.  * Initial revision
  24.  * 
  25.  */
  26.  
  27. #define INCL_DOSDEVICES
  28. #define INCL_DOSDEVIOCTL
  29. #define INCL_NOPM
  30. #include <os2.h>
  31. #include <string.h>
  32. #include <ctype.h>
  33.  
  34. #include "diskacc2.h"
  35.  
  36. #define PHYSICAL     0x1000
  37. #define CDROM        0x2000
  38.  
  39. #define CATEGORY(x)  (((x) & CDROM) ? IOCTL_CDROMDISK : ((x) & PHYSICAL) ? IOCTL_PHYSICALDISK : IOCTL_DISK)
  40. #define HANDLE(x)    ((x) & ~(PHYSICAL|CDROM))
  41.  
  42. #pragma pack(1)
  43.  
  44. /* logical/physical hard disk and floppy disk access code */
  45.  
  46. typedef struct
  47. {
  48.   BYTE   bCommand;
  49.   USHORT usHead;
  50.   USHORT usCylinder;
  51.   USHORT usFirstSector;
  52.   USHORT cSectors;
  53.   struct
  54.   {
  55.     USHORT usSectorNumber;
  56.     USHORT usSectorSize;
  57.   }
  58.   TrackTable[64];
  59. }
  60. TRACK;
  61.  
  62. ULONG DosDevIOCtl32(PVOID pData, ULONG cbData, PVOID pParms, ULONG cbParms,
  63.             ULONG usFunction, HFILE hDevice)
  64. {
  65.   ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData;
  66.   return DosDevIOCtl(HANDLE(hDevice), CATEGORY(hDevice), usFunction,
  67.              pParms, cbParms, &ulParmLengthInOut, 
  68.              pData, cbData, &ulDataLengthInOut);
  69. }
  70.  
  71. static int test_sector(int handle, int side, int track, int sector)
  72. {
  73.   char buffer[1024];
  74.   TRACK trk;
  75.  
  76.   trk.bCommand      = 0;
  77.   trk.usHead        = side;
  78.   trk.usCylinder    = track;
  79.   trk.usFirstSector = 0;
  80.   trk.cSectors      = 1;
  81.  
  82.   trk.TrackTable[0].usSectorNumber = sector;
  83.   trk.TrackTable[0].usSectorSize   = 512;
  84.  
  85.   return DosDevIOCtl32(buffer, sizeof(buffer), &trk, sizeof(trk), 
  86.                DSK_READTRACK, handle) == 0;
  87. }
  88.  
  89. int DskOpen(char *drv, int logical, int lock, 
  90.         unsigned *sides, unsigned *tracks, unsigned *sectors)
  91. {
  92.   BIOSPARAMETERBLOCK bpb;
  93.   DEVICEPARAMETERBLOCK dpb;
  94.   HFILE handle;
  95.   USHORT physical;
  96.   ULONG action;
  97.   BYTE cmd = logical;
  98.  
  99.   if (isalpha(drv[0]) && drv[1] == ':' && drv[2] == 0)
  100.   {
  101.     if (DosOpen(drv, &handle, &action, 0, FILE_NORMAL, FILE_OPEN,
  102.         OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
  103.         OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, 0))
  104.       return -1;
  105.   }
  106.   else if (drv[0] == '$' && isdigit(drv[1]) && drv[2] == ':' && drv[3] == 0)
  107.   {
  108.     if (DosPhysicalDisk(INFO_GETIOCTLHANDLE, &physical, sizeof(physical), 
  109.             drv + 1, strlen(drv + 1) + 1))
  110.       return -1;
  111.     handle = physical | PHYSICAL;
  112.   }
  113.   else
  114.     return -1;
  115.  
  116.   if (handle & PHYSICAL)
  117.   {
  118.     if (DosDevIOCtl32(&dpb, sizeof(dpb), &cmd, sizeof(cmd), 
  119.               DSK_GETDEVICEPARAMS, handle))
  120.     {
  121.       DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &physical, sizeof(physical));
  122.       return -1;
  123.     }
  124.  
  125.     *sectors = dpb.cSectorsPerTrack;
  126.     *tracks  = dpb.cCylinders;
  127.     *sides   = dpb.cHeads;
  128.   }
  129.   else
  130.   {
  131.     if (DosDevIOCtl32(&bpb, sizeof(bpb), &cmd, sizeof(cmd), 
  132.               DSK_GETDEVICEPARAMS, handle))
  133.     {
  134.       DosClose(handle);
  135.       return -1;
  136.     }
  137.  
  138.     *sectors = bpb.usSectorsPerTrack;
  139.     *tracks  = bpb.cCylinders;
  140.     *sides   = bpb.cHeads;
  141.   }
  142.  
  143.  
  144.   if (lock && DosDevIOCtl32(0, 0, &cmd, sizeof(cmd), DSK_LOCKDRIVE, handle))
  145.   {
  146.     if (handle & PHYSICAL)
  147.       DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &physical, sizeof(physical));
  148.     else
  149.       DosClose(handle);
  150.     return -1;
  151.   }
  152.  
  153.   if (*sectors >= 15) /* 360k floppies ... */
  154.     if (!test_sector(handle, 0, 0, 15))
  155.     {
  156.       if (*sectors == 15)
  157.         *tracks = 40;
  158.  
  159.       *sectors = 9;
  160.     }
  161.  
  162.   return handle;
  163. }
  164.  
  165. int DskClose(int handle)
  166. {
  167.   BYTE cmd = 0;
  168.   USHORT physical = handle & ~PHYSICAL;
  169.  
  170.   DosDevIOCtl32(0, 0, &cmd, sizeof(cmd), DSK_UNLOCKDRIVE, handle);
  171.  
  172.   if (handle & PHYSICAL)
  173.     return DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, 
  174.                &physical, sizeof(physical));
  175.   else
  176.     return DosClose(handle);
  177. }
  178.  
  179. int DskRead(int handle, unsigned side, unsigned  track,
  180.             unsigned sector, unsigned nsects, void *buf)
  181. {
  182.   TRACK trk;
  183.   unsigned cnt;
  184.  
  185.   trk.bCommand      = 0;
  186.   trk.usHead        = side;
  187.   trk.usCylinder    = track;
  188.   trk.usFirstSector = 0;
  189.   trk.cSectors      = nsects;
  190.  
  191.   for (cnt = 0; cnt < nsects; cnt++)
  192.   {
  193.     trk.TrackTable[cnt].usSectorNumber = sector + cnt;
  194.     trk.TrackTable[cnt].usSectorSize   = 512;
  195.   }
  196.  
  197.   return DosDevIOCtl32(buf, nsects * 512, &trk, sizeof(trk), 
  198.                        DSK_READTRACK, handle);
  199. }
  200.  
  201. int DskWrite(int handle, unsigned side, unsigned  track,
  202.              unsigned sector, unsigned nsects, void *buf)
  203. {
  204.   TRACK trk;
  205.   unsigned cnt;
  206.  
  207.   trk.bCommand      = 0;
  208.   trk.usHead        = side;
  209.   trk.usCylinder    = track;
  210.   trk.usFirstSector = 0;
  211.   trk.cSectors      = nsects;
  212.  
  213.   for (cnt = 0; cnt < nsects; cnt++)
  214.   {
  215.     trk.TrackTable[cnt].usSectorNumber = sector + cnt;
  216.     trk.TrackTable[cnt].usSectorSize   = 512;
  217.   }
  218.  
  219.   return DosDevIOCtl32(buf, nsects * 512, &trk, sizeof(trk), 
  220.                        DSK_WRITETRACK, handle);
  221. }
  222.  
  223. /* CD-ROM access code */
  224.  
  225. static struct
  226. {
  227.   char sig[4];
  228.   char cmd;
  229. }
  230. cdparams;
  231.  
  232. int CDFind(int number)
  233. {
  234.   char drv[3];
  235.   int i;
  236.   HFILE handle;
  237.   ULONG action, status;
  238.   int drives = 0;
  239.  
  240.   memcpy(cdparams.sig, "CD01", 4);
  241.   strcpy(drv, "C:");
  242.  
  243.   for (i = 0; i < 24; i++)
  244.   {
  245.     drv[0] = 'C' + i;
  246.  
  247.     if (DosOpen(drv, &handle, &action, 0, FILE_NORMAL, FILE_OPEN,
  248.         OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
  249.         OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, 0))
  250.       continue;
  251.     
  252.     handle |= CDROM;
  253.  
  254.     if (DosDevIOCtl32(&status, sizeof(status), &cdparams, sizeof(cdparams.sig),
  255.               CDROMDISK_DEVICESTATUS, handle))
  256.     {
  257.       DosClose(HANDLE(handle));
  258.       continue;
  259.     }
  260.  
  261.     DosClose(HANDLE(handle));
  262.  
  263.     if (number == 0)
  264.       drives++;
  265.     else if (number == 1)
  266.       return 'C' + i;
  267.     else
  268.       number--;
  269.   }
  270.  
  271.   return number == 0 ? drives : -1;
  272. }
  273.  
  274. int CDOpen(char *drv, int lock, char *upc, unsigned *sectors)
  275. {
  276.   HFILE handle;
  277.   ULONG action;
  278.   char upcdata[10];
  279.  
  280.   if (isalpha(drv[0]) && drv[1] == ':' && drv[2] == 0)
  281.   {
  282.     if (DosOpen(drv, &handle, &action, 0, FILE_NORMAL, FILE_OPEN,
  283.         OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
  284.         OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, 0))
  285.       return -1;
  286.   }
  287.   else
  288.     return -1;
  289.  
  290.   handle |= CDROM;
  291.   memcpy(cdparams.sig, "CD01", 4);
  292.  
  293.   cdparams.cmd = 1;
  294.   if (lock && DosDevIOCtl32(0, 0, &cdparams, sizeof(cdparams),
  295.                 CDROMDISK_LOCKUNLOCKDOOR, handle))
  296.   {
  297.     DosClose(HANDLE(handle));
  298.     return -1;
  299.   }
  300.  
  301.   if (DosDevIOCtl32(sectors, sizeof(*sectors), &cdparams, sizeof(cdparams.sig),
  302.             CDROMDISK_GETVOLUMESIZE, handle))
  303.   {
  304.     DosClose(HANDLE(handle));
  305.     return -1;
  306.   }
  307.  
  308.   memset(upcdata, 0, sizeof(upcdata));
  309.   if (DosDevIOCtl32(upcdata, sizeof(upcdata), &cdparams, sizeof(cdparams.sig),
  310.             CDROMDISK_GETUPC, handle))
  311.   {
  312.     DosClose(HANDLE(handle));
  313.     return -1;
  314.   }
  315.   else
  316.   {
  317.     memcpy(upc, upcdata + 1, 7);
  318.     upc[7] = 0;
  319.   }
  320.  
  321.   return handle;
  322. }
  323.  
  324. int CDClose(int handle)
  325. {
  326.   cdparams.cmd = 0;
  327.   DosDevIOCtl32(0, 0, &cdparams, sizeof(cdparams.sig), 
  328.         CDROMDISK_LOCKUNLOCKDOOR, handle);
  329.  
  330.   return DosClose(HANDLE(handle));
  331. }
  332.  
  333. int CDRead(int handle, unsigned sector, unsigned nsects, void *buf)
  334. {
  335.   ULONG nActual;
  336.  
  337.   if (DosSetFilePtr(HANDLE(handle), sector * 2048, FILE_BEGIN, &nActual))
  338.     return -1;
  339.  
  340.   if (DosRead(HANDLE(handle), buf, nsects * 2048, &nActual))
  341.     return -1;
  342.  
  343.   return nActual / 2048;
  344. }
  345.  
  346. /* end of diskacc2.c */
  347.