home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / ods2 / src / phyos2.c < prev    next >
C/C++ Source or Header  |  1998-09-11  |  7KB  |  211 lines

  1. /* PHYOS2.C   v1.2   Physical I/O module for OS2 */
  2.  
  3. /*  This version implemented to read from Floppy or CD by
  4.     guessing that A: or B: will be a floppy and anything
  5.     else is probably a CD? */
  6.  
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #define INCL_DOS
  12. #define INCL_DOSDEVIOCTL
  13. #define INCL_NOPMAPI
  14. #include <os2.h>
  15. #include "phyio.h"
  16. #include "ssdef.h"
  17.  
  18.  
  19.  
  20. unsigned init_count = 0;
  21. unsigned read_count = 0;
  22. unsigned write_count = 0;
  23.  
  24. void phyio_show(void)
  25. {
  26.     printf("PHYIO_SHOW Initializations: %d Reads: %d Writes: %d\n",
  27.            init_count,read_count,write_count);
  28. }
  29.  
  30.  
  31. #pragma pack(1)
  32. /*------------------------------------------------*
  33.  * Cat 0x80, Func 0x72: Read Long                 *
  34.  *------------------------------------------------*/
  35. struct ReadLong {
  36.     ULONG ID_code;
  37.     UCHAR address_mode;
  38.     USHORT transfer_count;
  39.     ULONG start_sector;
  40.     UCHAR reserved;
  41.     UCHAR interleave_size;
  42.     UCHAR interleave_skip_factor;
  43. };
  44. #pragma pack()
  45.  
  46. #define SECTORSIZE 2048
  47. struct ReadLong rl = {
  48.     0x31304443L,    /* "CD01" */
  49.     0,                 /* Address mode */
  50.     1,                 /* Transfer count */
  51.     0,                 /* Start Sector */
  52.     0,                 /* Reserved */
  53.     0,                 /* Interleave size */
  54.     0/* Skip factor */
  55. };
  56.  
  57. #define HANDLE_MAX 32
  58. int hand_count = 0;
  59. struct HANDLE {
  60.     HFILE hand_hfile;
  61.     int hand_drive;
  62. } handle[HANDLE_MAX];
  63.  
  64. unsigned phyio_init(int devlen,char *devnam,unsigned *hand,struct phyio_info *info)
  65. {
  66.     if (hand_count < HANDLE_MAX - 1) {
  67.         ULONG usAction;
  68.         ULONG open_mode;
  69.         ULONG bCmd;
  70.         ULONG stat;
  71.         char device[40];
  72.         memcpy(device,devnam,devlen);
  73.         device[devlen] = '\0';
  74.         handle[hand_count].hand_drive = toupper(*device);
  75.         open_mode = OPEN_FLAGS_DASD | OPEN_SHARE_DENYREADWRITE
  76.              | OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR
  77.              | OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READWRITE;
  78.         stat = DosOpen(device,  /* filename to open              */
  79.                        &handle[hand_count].hand_hfile,
  80.          /* address of file handle        */
  81.                        &usAction,
  82.          /* address to store action taken */
  83.                        0L,
  84.          /* size of new file              */
  85.                        FILE_NORMAL,
  86.          /* file's attribute              */
  87.                        FILE_OPEN,
  88.          /* action to take if file exists */
  89.                        open_mode,
  90.          /* file's open mode              */
  91.                        0L);
  92.         /* Reserved                      */
  93.         if (stat) {
  94.             switch (stat) {
  95.                 case 15:
  96.                     printf("Drive %s is invalid.\n",device);
  97.                     break;
  98.                 case 21:
  99.                     printf("Drive %s is not ready.\n",device);
  100.                     break;
  101.                 case 32:
  102.                     printf("Drive %s is currently locked by another process.\n",device);
  103.                     break;
  104.                 case 65:
  105.                     printf("Drive %s is a network drive.\n",device);
  106.                     break;
  107.                 default:
  108.                     printf("error %d opening drive %s\n",stat,device);
  109.             }
  110.             return SS$_PARITY;
  111.         }
  112.         bCmd = 0;
  113.         stat = DosDevIOCtl(handle[hand_count].hand_hfile,IOCTL_DISK,DSK_LOCKDRIVE,&bCmd,1,NULL,NULL,0,NULL);
  114.         if (stat) {
  115.             printf("Error %d locking drive\n",stat);
  116.             return SS$_DEVNOTALLOC;
  117.         }
  118.         if (handle[hand_count].hand_drive > 'C') {
  119.             info->status = PHYIO_READONLY;
  120.         } else {
  121.             info->status = 0;
  122.         }
  123.         *hand = hand_count++;
  124.         init_count++;
  125.         return 1;
  126.     } else {
  127.         return SS$_IVCHAN;
  128.     }
  129. }
  130.  
  131.  
  132. unsigned phy_getsect(HFILE hfile,unsigned sector,char *buffer)
  133. {
  134.     ULONG ulPinout,ulDinout;
  135.     ULONG stat;
  136.     char rawsect[SECTORSIZE + 304];
  137.     ulPinout = sizeof(rl);
  138.     ulDinout = sizeof(rawsect);
  139.     rl.start_sector = sector;
  140.     stat = DosDevIOCtl(hfile,
  141.                        IOCTL_CDROMDISK,
  142.                        CDROMDISK_READLONG,
  143.                        &rl,sizeof(rl),&ulPinout,
  144.                        rawsect,sizeof(rawsect),&ulDinout);
  145.     if (stat) {
  146.         printf("sys%04u: CDROMDISK_READLONG error\n",stat);
  147.         return SS$_PARITY;
  148.     }
  149.     memcpy(buffer,rawsect + 16,SECTORSIZE);
  150.     return 1;
  151. }
  152.  
  153.  
  154.  
  155.  
  156.  
  157. unsigned phyio_read(unsigned handno,unsigned block,unsigned length,char *buffer)
  158. {
  159.     register unsigned sts = 1;
  160. #ifdef DEBUG
  161.     printf("PHYIO_READ block %d length %d\n",block,length);
  162. #endif
  163.     if (handno >= hand_count) {
  164.         sts = SS$_IVCHAN;
  165.     } else {
  166.         if (handle[handno].hand_drive > 'C') {
  167.             register unsigned sect = block * 512 / SECTORSIZE;
  168.             register unsigned offset = (block - sect * SECTORSIZE / 512) * 512;
  169.             while (length > 0) {
  170.                 register unsigned transfer;
  171.                 if (offset == 0 && length >= SECTORSIZE) {
  172.                     transfer = SECTORSIZE;
  173.                     if (((sts = phy_getsect(handle[handno].hand_hfile,sect,buffer)) & 1) == 0) break;
  174.                 } else {
  175.                     char sector[SECTORSIZE];
  176.                     if (((sts = phy_getsect(handle[handno].hand_hfile,sect,sector)) & 1) == 0) break;
  177.                     transfer = SECTORSIZE - offset;
  178.                     if (transfer > length) transfer = length;
  179.                     memcpy(buffer,sector + offset,transfer);
  180.                 }
  181.                 buffer += transfer;
  182.                 length -= transfer;
  183.                 sect++;
  184.                 offset = 0;
  185.             }
  186.         } else {
  187.             USHORT rc;
  188.             ULONG oldpos,lenread;
  189.             sts = SS$_PARITY;
  190.             rc = DosSetFilePtr(handle[handno].hand_hfile,block * 512,0,&oldpos);
  191.             if (rc == 0) {
  192.                 rc = DosRead(handle[handno].hand_hfile,buffer,length,&lenread);
  193.                 if (rc == 0 && lenread == length) sts = 1;
  194.             }
  195.         }
  196.     }
  197.     if (sts & 1) {
  198.         read_count++;
  199.     } else {
  200.         printf("PHYOS2 Error %d Block %d Length %d\n",sts,block,length);
  201.     }
  202.     return sts;
  203. }
  204.  
  205.  
  206. unsigned phyio_write(unsigned handle,unsigned block,unsigned length,char *buffer)
  207. {
  208.     write_count++;
  209.     return SS$_WRITLCK;
  210. }
  211.