home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Aktief 1995 #3 / CDA3.iso / os2 / diskio14.rar / DISKACC2.C next >
C/C++ Source or Header  |  1994-07-08  |  5KB  |  212 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.1 1994/07/08 21:34:12 rommel Exp $";
  9. static char *rcsrev = "$Revision: 1.1 $";
  10.  
  11. /*
  12.  * $Log: diskacc2.c,v $
  13.  * Revision 1.1  1994/07/08 21:34:12  rommel
  14.  * Initial revision
  15.  * 
  16.  */
  17.  
  18. #define INCL_DOSDEVICES
  19. #define INCL_DOSDEVIOCTL
  20. #define INCL_NOPM
  21. #include <os2.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24.  
  25. #include "diskacc2.h"
  26.  
  27. #define PHYSICAL     0x1000
  28. #define CATEGORY(x)  (((x) & PHYSICAL) ? IOCTL_PHYSICALDISK : IOCTL_DISK)
  29. #define HANDLE(x)    ((x) & ~PHYSICAL)
  30.  
  31. #pragma pack(1)
  32.  
  33. typedef struct
  34. {
  35.   BYTE   bCommand;
  36.   USHORT usHead;
  37.   USHORT usCylinder;
  38.   USHORT usFirstSector;
  39.   USHORT cSectors;
  40.   struct
  41.   {
  42.     USHORT usSectorNumber;
  43.     USHORT usSectorSize;
  44.   }
  45.   TrackTable[64];
  46. }
  47. TRACK;
  48.  
  49. ULONG DosDevIOCtl32(PVOID pData, ULONG cbData, PVOID pParms, ULONG cbParms,
  50.             ULONG usFunction, HFILE hDevice)
  51. {
  52.   ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData;
  53.   return DosDevIOCtl(HANDLE(hDevice), CATEGORY(hDevice), usFunction,
  54.              pParms, cbParms, &ulParmLengthInOut, 
  55.              pData, cbData, &ulDataLengthInOut);
  56. }
  57.  
  58. static int test_sector(int handle, int side, int track, int sector)
  59. {
  60.   char buffer[1024];
  61.   TRACK trk;
  62.  
  63.   trk.bCommand      = 0;
  64.   trk.usHead        = side;
  65.   trk.usCylinder    = track;
  66.   trk.usFirstSector = 0;
  67.   trk.cSectors      = 1;
  68.  
  69.   trk.TrackTable[0].usSectorNumber = sector;
  70.   trk.TrackTable[0].usSectorSize   = 512;
  71.  
  72.   return DosDevIOCtl32(buffer, sizeof(buffer), &trk, sizeof(trk), 
  73.                DSK_READTRACK, handle) == 0;
  74. }
  75.  
  76. int DskOpen(char *drv, int lock, 
  77.         unsigned *sides, unsigned *tracks, unsigned *sectors)
  78. {
  79.   BIOSPARAMETERBLOCK bpb;
  80.   DEVICEPARAMETERBLOCK dpb;
  81.   HFILE handle;
  82.   USHORT physical;
  83.   ULONG action;
  84.   BYTE cmd = 0;
  85.  
  86.   if (isalpha(drv[0]) && drv[1] == ':' && drv[2] == 0)
  87.   {
  88.     if (DosOpen(drv, &handle, &action, 0L, FILE_NORMAL, FILE_OPEN,
  89.         OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |
  90.         OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE, 0L))
  91.       return -1;
  92.   }
  93.   else if (drv[0] == '$' && isdigit(drv[1]) && drv[2] == ':' && drv[3] == 0)
  94.   {
  95.     if (DosPhysicalDisk(INFO_GETIOCTLHANDLE, &physical, sizeof(physical), 
  96.             drv + 1, strlen(drv + 1) + 1))
  97.       return -1;
  98.     handle = physical | PHYSICAL;
  99.   }
  100.   else
  101.     return -1;
  102.  
  103.   if (handle & PHYSICAL)
  104.   {
  105.     if (DosDevIOCtl32(&dpb, sizeof(dpb), &cmd, sizeof(cmd), 
  106.               DSK_GETDEVICEPARAMS, handle))
  107.     {
  108.       DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &physical, sizeof(physical));
  109.       return -1;
  110.     }
  111.  
  112.     *sectors = dpb.cSectorsPerTrack;
  113.     *tracks  = dpb.cCylinders;
  114.     *sides   = dpb.cHeads;
  115.   }
  116.   else
  117.   {
  118.     if (DosDevIOCtl32(&bpb, sizeof(bpb), &cmd, sizeof(cmd), 
  119.               DSK_GETDEVICEPARAMS, handle))
  120.     {
  121.       DosClose(handle);
  122.       return -1;
  123.     }
  124.  
  125.     *sectors = bpb.usSectorsPerTrack;
  126.     *tracks  = bpb.cCylinders;
  127.     *sides   = bpb.cHeads;
  128.   }
  129.  
  130.  
  131.   if (lock && DosDevIOCtl32(0L, 0, &cmd, sizeof(cmd), DSK_LOCKDRIVE, handle))
  132.   {
  133.     if (handle & PHYSICAL)
  134.       DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &physical, sizeof(physical));
  135.     else
  136.       DosClose(handle);
  137.     return -1;
  138.   }
  139.  
  140.   if (*sectors >= 15) /* 360k floppies ... */
  141.     if (!test_sector(handle, 0, 0, 15))
  142.     {
  143.       if (*sectors == 15)
  144.         *tracks = 40;
  145.  
  146.       *sectors = 9;
  147.     }
  148.  
  149.   return handle;
  150. }
  151.  
  152. int DskClose(int handle)
  153. {
  154.   BYTE cmd = 0;
  155.   USHORT physical = handle & ~PHYSICAL;
  156.  
  157.   DosDevIOCtl32(0L, 0, &cmd, sizeof(cmd), DSK_UNLOCKDRIVE, handle);
  158.  
  159.   if (handle & PHYSICAL)
  160.     return DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, 
  161.                &physical, sizeof(physical));
  162.   else
  163.     return DosClose(handle);
  164. }
  165.  
  166. int DskRead(int handle, unsigned side, unsigned  track,
  167.             unsigned sector, unsigned nsects, void *buf)
  168. {
  169.   TRACK trk;
  170.   unsigned cnt;
  171.  
  172.   trk.bCommand      = 0;
  173.   trk.usHead        = side;
  174.   trk.usCylinder    = track;
  175.   trk.usFirstSector = 0;
  176.   trk.cSectors      = nsects;
  177.  
  178.   for (cnt = 0; cnt < nsects; cnt++)
  179.   {
  180.     trk.TrackTable[cnt].usSectorNumber = sector + cnt;
  181.     trk.TrackTable[cnt].usSectorSize   = 512;
  182.   }
  183.  
  184.   return DosDevIOCtl32(buf, nsects * 512, &trk, sizeof(trk), 
  185.                        DSK_READTRACK, handle);
  186. }
  187.  
  188. int DskWrite(int handle, unsigned side, unsigned  track,
  189.              unsigned sector, unsigned nsects, void *buf)
  190. {
  191.   TRACK trk;
  192.   unsigned cnt;
  193.  
  194.   trk.bCommand      = 0;
  195.   trk.usHead        = side;
  196.   trk.usCylinder    = track;
  197.   trk.usFirstSector = 0;
  198.   trk.cSectors      = nsects;
  199.  
  200.   for (cnt = 0; cnt < nsects; cnt++)
  201.   {
  202.     trk.TrackTable[cnt].usSectorNumber = sector + cnt;
  203.     trk.TrackTable[cnt].usSectorSize   = 512;
  204.   }
  205.  
  206.   return DosDevIOCtl32(buf, nsects * 512, &trk, sizeof(trk), 
  207.                        DSK_WRITETRACK, handle);
  208. }
  209.  
  210.  
  211. /* end of diskacc2.c */
  212.