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