home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / viscobv6.zip / vac22os2 / ibmcobol / samples / toolkit / mm / fssht / fsshseek.c < prev    next >
C/C++ Source or Header  |  1996-11-19  |  14KB  |  278 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                    Copyright (c) IBM Corporation 1992, 1993              */
  4. /*                           All Rights Reserved                            */
  5. /*                                                                          */
  6. /* SOURCE FILE NAME: FSSHSEEK.C                                             */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME:  Stream Handler Seek stream routine                    */
  9. /*                                                                          */
  10. /* FUNCTION: Seek a file system stream                                      */
  11. /*                                                                          */
  12. /* ENTRY POINTS: ShcSeek                                                    */
  13. /*                                                                          */
  14. /*************************** END OF SPECIFICATIONS **************************/
  15. #define  INCL_NOPMAPI                  /* no PM include files required */
  16. #define  INCL_DOSSEMAPHORES
  17. #define  INCL_DOSPROCESS
  18. #define  INCL_DOSERRORS
  19. #define  INCL_MMIOOS2
  20. #include <os2.h>
  21. #include <os2me.h>
  22. #include <hhpheap.h>
  23. #include <shi.h>
  24. #include <fssh.h>
  25. #include <seekcalc.h>
  26.  
  27. /************************** START OF SPECIFICATIONS *************************/
  28. /*                                                                          */
  29. /* SUBROUTINE NAME: ShcSeek                                                 */
  30. /*                                                                          */
  31. /* DESCRIPTIVE NAME: Stream Handler Command Seek stream routine.            */
  32. /*                                                                          */
  33. /* FUNCTION: This seeks the specified stream to the position specified by   */
  34. /*   lSeekPoint.  This seek point is qualified by the flags passed to       */
  35. /*   indicate if the seek is from 1) the beginning of the file; 2) from the */
  36. /*   current position in the file; or 3) from the end of the file.          */
  37. /*                                                                          */
  38. /* NOTES:                                                                   */
  39. /*                                                                          */
  40. /* ENTRY POINT: ShcSeek                                                     */
  41. /*   LINKAGE:   CALL NEAR (0:32)                                            */
  42. /*                                                                          */
  43. /* INPUT: Pointer to shc seek parameter block PARM_SEEK containing:         */
  44. /*   ULONG   ulFunction  Handler command function SHC_SEEK                  */
  45. /*   HID     hid         handler ID                                         */
  46. /*   HSTREAM hstream     handle of stream instance                          */
  47. /*   ULONG   ulFlags      Seek flag with following possible Flags:          */
  48. /*                         SPI_SEEK_ABSOLUTE                                */
  49. /*                         SPI_SEEK_RELATIVE                                */
  50. /*                         SPI_SEEK_FROMEND                                 */
  51. /*                         SPI_SEEK_SLAVES                                  */
  52. /*                         SPI_SEEK_MMTIME                                  */
  53. /*                         SPI_SEEK_BYTES                                   */
  54. /*   LONG    lSeekPoint  Seek position. Signed. Seeking from end should be  */
  55. /*                       negative.                                          */
  56. /*                                                                          */
  57. /* EXIT-NORMAL: NO_ERROR (0)                                                */
  58. /*                                                                          */
  59. /* EXIT-ERROR:                                                              */
  60. /*   ERROR_NOT_SEEKABLE_BY_TIME                                             */
  61. /*   ERROR_DATA_ITEM_NOT_SEEKABLE                                           */
  62. /*   ERROR_STREAM_NOT_STOP                                                  */
  63. /*   Errors from the external routines:                                     */
  64. /*     mmioSeek - the extended error code from mmioGetLastError             */
  65. /*     mmioSendMessage (MMIOM_SEEKBYTIME) - extended error code from        */
  66. /*                                          mmioGetLastError                */
  67. /*     ShFindSib - ERROR_INVALID_STREAM, and errors from DosRequestMutexSem */
  68. /*                                                                          */
  69. /* SIDE EFFECTS: The mmio file pointer is positioned to the new location.   */
  70. /*                                                                          */
  71. /* INTERNAL REFERENCES:                                                     */
  72. /*        ROUTINES: None                                                    */
  73. /*                                                                          */
  74. /* EXTERNAL REFERENCES:                                                     */
  75. /*   ROUTINES:                                                              */
  76. /*     mmioSeek                                                             */
  77. /*     mmioSendMessage                                                      */
  78. /*     mmioGetLastError                                                     */
  79. /*     ShFindSib                                                            */
  80. /*                                                                          */
  81. /*   DATA STRUCTURES: None                                                  */
  82. /*                                                                          */
  83. /*************************** END OF SPECIFICATIONS **************************/
  84.  
  85. RC ShcSeek(pskparm)
  86. PPARM_SEEK pskparm;
  87.  
  88. { /* Start of ShcSeek */
  89.  
  90. RC rc = NO_ERROR;                       /* local return code */
  91. PSIB psib;                              /* Stream instance block */
  92. ULONG ulrc;                             /* temp rc from special seek */
  93. LONG lByteSeekPoint;                    /* Seek point in bytes */
  94. LONG lAbsFilePos;                       /* absolute file position from seek */
  95. SHORT sTempFlags;                       /* Flags to call mmioseek */
  96. BOOL bSeekTried = FALSE;                /* have we tried the seek yet? */
  97.  
  98.   /*
  99.    * Find our Stream Instance Block
  100.    */
  101.   if (!(rc = ShFindSib(&psib, pskparm->hstream, pskparm->hid)))
  102.     { /* We have SIB */
  103.  
  104.       /* We can only seek when stopped in ready to run state */
  105.  
  106.       if ((psib->ulStatus == SIB_RUNNING) &&
  107.           !(psib->ulActionFlags & SIBACTFLG_THREAD_DEAD))
  108.         { /* Good state */
  109.  
  110.           /* Check if this datatype is phsically seekable. If not just return.*/
  111.  
  112.           if (!(psib->espcb.spcb.ulHandFlags & SPCBHAND_PHYS_SEEK))
  113.              {
  114.              return(rc);
  115.              }
  116.  
  117.           /* Check if this datatype is seekable */
  118.  
  119.           if (!(psib->espcb.spcb.ulDataFlags & SPCBDATA_NOSEEK))
  120.  
  121.             /* and the psib->espcb.spcb.ulHandFlags field has a value of ? */
  122.             /* otherwise it this not a physically seekable target. */
  123.  
  124.             { /* datatype is seekable */
  125.  
  126.               /* If seek by bytes, just use what's passed.  If not, then it */
  127.               /*  is in mmtime units.  So we must convert it to bytes first. */
  128.  
  129.               if (pskparm->ulFlags & SPI_SEEK_BYTES)
  130.                 {
  131.                   lByteSeekPoint = pskparm->lSeekPoint;
  132.                 }
  133.               else
  134.                 { /* in mmtime units, need to convert to bytes */
  135.  
  136.                   /* Check the bytes per unit and mmtime per unit values. */
  137.                   /* If either are zero then we don't know how to convert the */
  138.                   /* time units passed into bytes so just call mmioSendMessage */
  139.                   /* with MMIOM_SEEKBYTIME, to see if the IOProc can figure */
  140.                   /* it out. */
  141.  
  142.                   if (psib->espcb.spcb.ulBytesPerUnit && psib->espcb.spcb.mmtimePerUnit)
  143.                     {
  144.                       /* Call routine to do calc and check for overflow */
  145.  
  146.                      if (Mmtime2Bytes( psib->espcb.spcb.ulBytesPerUnit,
  147.                                        pskparm->lSeekPoint,
  148.                                        (LONG)psib->espcb.spcb.mmtimePerUnit,
  149.                                        &lByteSeekPoint ))
  150.                         {
  151.                         rc = ERROR_LARGE_SEEK_BY_TIME;
  152.                         }
  153.                     }
  154.                   else
  155.                     { /* don't know how to convert time to bytes */
  156.  
  157.                       ulrc = mmioSendMessage((HMMIO)psib->ulAssocP1,
  158.                                              MMIOM_SEEKBYTIME,
  159.                                              pskparm->lSeekPoint,
  160.                                              pskparm->ulFlags);
  161.  
  162.                       /* The error processing is a little tricky for this */
  163.                       /* message since the IOProc will be handling the message */
  164.                       /* just like a regular Seek it will return values just */
  165.                       /* as it would for Seek. So the return value should be */
  166.                       /* the new file position which could be 0.  If an error */
  167.                       /* occurs then MMIO_ERROR is returned and we need */
  168.                       /* to call getlasterror for the real error code. */
  169.                       /* Now, since this is actually being called using */
  170.                       /* mmioSendMessage it may return MMIO_ERROR for bad */
  171.                       /* handle and the getlasterror would return */
  172.                       /* MMIO_INVALID_HANDLE.  Also, if the SEEKBYTIME */
  173.                       /* message is not supported then the mmioSendMessage */
  174.                       /* rc will be 0, and the getlasterror will be */
  175.                       /* MMIOERR_UNSUPPORTED_MESSAGE. */
  176.  
  177.                       if ((ulrc == MMIO_ERROR) || (ulrc == 0L))
  178.                         { /* Seek failed */
  179.                           rc = mmioGetLastError((HMMIO)psib->ulAssocP1);
  180.                         } /* Seek failed */
  181.  
  182.                       if ((ulrc == 0L) && (rc == MMIOERR_UNSUPPORTED_MESSAGE))
  183.                         rc = ERROR_NOT_SEEKABLE_BY_TIME;
  184.  
  185.                       bSeekTried = TRUE;
  186.  
  187.                       /* Set the absolute file position in mmtime units. */
  188.                       /* NOTE: This is only implemented for SEEK_FROMEND now. */
  189.  
  190.                       if (!rc)
  191.                         {
  192.                         if (pskparm->ulFlags & SPI_SEEK_FROMEND)
  193.                            pskparm->lSeekPoint = ulrc;
  194.                         }
  195.                     } /* don't know how to convert time to bytes */
  196.                 } /* in mmtime units, need to convert to bytes */
  197.  
  198.               if ((!rc) && (!bSeekTried))
  199.                 { /* ok to seek */
  200.  
  201.                   /* Get rid of all flags but seek origin */
  202.  
  203.                   sTempFlags = (SHORT)(pskparm->ulFlags &
  204.                                       (SPI_SEEK_RELATIVE+SPI_SEEK_ABSOLUTE+SPI_SEEK_FROMEND));
  205.  
  206.                   lAbsFilePos = mmioSeek((HMMIO)psib->ulAssocP1,
  207.                                          lByteSeekPoint,
  208.                                          sTempFlags);
  209.  
  210.                   if (lAbsFilePos == -1L)
  211.                     { /* Seek failed */
  212.                       rc = mmioGetLastError((HMMIO)psib->ulAssocP1);
  213.                     } /* Seek failed */
  214.                   else
  215.                      {
  216.                      /* Seek was OK - set the absolute position in pksparm. */
  217.                      /* Set the position in either bytes or time, depending */
  218.                      /* on the seek mode that was requested. */
  219.                      /* NOTE: This is only implemented for SEEK_FROMEND now. */
  220.  
  221.                      if (pskparm->ulFlags & SPI_SEEK_FROMEND)
  222.                         {
  223.  
  224.                         if (pskparm->ulFlags & SPI_SEEK_BYTES)
  225.                            {
  226.                            pskparm->lSeekPoint = lAbsFilePos;
  227.                            }
  228.                         else
  229.                            {
  230.  
  231.                            /* Check the bytes per unit and mmtime per unit */
  232.                            /* values. If either are zero then we don't know how to */
  233.                            /* convert bytes back into time units. */
  234.  
  235.                            if (psib->espcb.spcb.ulBytesPerUnit && psib->espcb.spcb.mmtimePerUnit)
  236.                               {
  237.  
  238.                               /* Set the returned seek point to absolute offset in mmtime units. */
  239.  
  240.  
  241.                               /* Set the returned seek point to absolute offset in mmtime units. */
  242.  
  243.                               if ( Bytes2Mmtime( psib->espcb.spcb.ulBytesPerUnit,
  244.                                                  lAbsFilePos,
  245.                                                  (LONG)psib->espcb.spcb.mmtimePerUnit,
  246.                                                  &pskparm->lSeekPoint ))
  247.                                  {
  248.                                  rc = ERROR_LARGE_SEEK_BY_TIME;
  249.                                  }
  250.                               }
  251.                            else
  252.                               {
  253.                               rc = ERROR_NOT_SEEKABLE_BY_TIME;
  254.                               }
  255.                            }
  256.                         } /* Seek from END */
  257.                      } /* Seek was OK */
  258.                 }  /* ok to seek */
  259.             } /* datatype is seekable */
  260.           else
  261.             {
  262.               rc = ERROR_DATA_ITEM_NOT_SEEKABLE;
  263.             }
  264.         } /* Good state */
  265.       else
  266.         {
  267.           if (psib->ulStatus < SIB_RUNNING)
  268.             rc = ERROR_DATA_ITEM_NOT_SPECIFIED;
  269.           else
  270.             rc = ERROR_INVALID_SEQUENCE;
  271.         }
  272.     } /* We have SIB */
  273.  
  274.   return(rc);
  275.  
  276. } /* End of ShcSeek */
  277.  
  278.