home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / diski117.zip / diskacc2.c < prev    next >
C/C++ Source or Header  |  1998-07-05  |  9KB  |  378 lines

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