예제 #1
0
파일: ntstream.c 프로젝트: OPSF/uClinux
unsigned long read_stream(unsigned char *dest, unsigned long bytes, struct nt_sid *sid)
{
 unsigned long br, rc;

 if(sid->is_write)
  return(0);
 br=(sid->rem.HighPart==0&&sid->rem.LowPart<bytes)?sid->rem.LowPart:bytes;
 if(br==0)
  return(0);
 if(!BackupRead(sid->hf, dest, br, &rc, FALSE, TRUE, &sid->lpcontext))
  return(0);
 sid->rem=LargeIntegerSubtract(sid->rem, ConvertUlongToLargeInteger(rc));
 return(rc);
}
예제 #2
0
파일: ntstream.c 프로젝트: OPSF/uClinux
unsigned long write_stream(unsigned char *src, unsigned long bytes, struct nt_sid *sid)
{
 unsigned long bw, rc;

 if(!sid->is_write)
  return(0);
 /* This is crucial to prevent overflow */
 bw=(sid->rem.HighPart==0&&sid->rem.LowPart<bytes)?sid->rem.LowPart:bytes;
 if(bw==0)
  return(0);
 if(!BackupWrite(sid->hf, src, bw, &rc, FALSE, TRUE, &sid->lpcontext))
  return(0);
 sid->rem=LargeIntegerSubtract(sid->rem, ConvertUlongToLargeInteger(rc));
 return(rc);
}
예제 #3
0
파일: rawops.c 프로젝트: bagdxk/openafs
/*
 * called with scp->rw lock held exclusive
 */
afs_int32
raw_ReadData( cm_scache_t *scp, osi_hyper_t *offsetp,
              afs_uint32 length, char *bufferp, afs_uint32 *readp,
              cm_user_t *userp, cm_req_t *reqp)
{
    long code;
    cm_buf_t *bufp = NULL;
    osi_hyper_t fileLength;
    osi_hyper_t thyper;
    osi_hyper_t lastByte;
    osi_hyper_t bufferOffset;
    long bufIndex, nbytes;
    int sequential = 0;

    /* start by looking up the file's end */
    code = cm_SyncOp(scp, NULL, userp, reqp, 0,
                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
    if (code)
        goto done;

    cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);

    /* now we have the entry locked, look up the length */
    fileLength = scp->length;

    /* adjust length down so that it won't go past EOF */
    thyper.LowPart = length;
    thyper.HighPart = 0;
    thyper = LargeIntegerAdd(*offsetp, thyper);	/* where read should end */
    lastByte = thyper;
    if (LargeIntegerGreaterThan(thyper, fileLength)) {
        /* we'd read past EOF, so just stop at fileLength bytes.
        * Start by computing how many bytes remain in the file.
        */
        thyper = LargeIntegerSubtract(fileLength, *offsetp);

        /* if we are past EOF, read 0 bytes */
        if (LargeIntegerLessThanZero(thyper))
            length = 0;
        else
            length = thyper.LowPart;
    }

    *readp = length;

    /* now, copy the data one buffer at a time,
     * until we've filled the request packet
     */
    while (1) {
        /* if we've copied all the data requested, we're done */
        if (length <= 0) break;

        /* otherwise, load up a buffer of data */
        thyper.HighPart = offsetp->HighPart;
        thyper.LowPart = offsetp->LowPart & ~(cm_data.blockSize-1);
        if (!bufp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
            /* wrong buffer */
            if (bufp) {
                buf_Release(bufp);
                bufp = NULL;
            }
            lock_ReleaseWrite(&scp->rw);

            code = buf_Get(scp, &thyper, reqp, 0, &bufp);

            lock_ObtainWrite(&scp->rw);
            if (code) goto done;
            bufferOffset = thyper;

            /* now get the data in the cache */
            while (1) {
                code = cm_SyncOp(scp, bufp, userp, reqp, 0,
                                 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
                if (code)
                    goto done;

		cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);

                if (cm_HaveBuffer(scp, bufp, 0)) break;

                /* otherwise, load the buffer and try again */
                code = cm_GetBuffer(scp, bufp, NULL, userp, reqp);
                if (code) break;
            }
            if (code) {
                buf_Release(bufp);
                bufp = NULL;
                goto done;
            }
        }	/* if (wrong buffer) ... */

        /* now we have the right buffer loaded.  Copy out the
         * data from here to the user's buffer.
         */
        bufIndex = offsetp->LowPart & (cm_data.blockSize - 1);

        /* and figure out how many bytes we want from this buffer */
        nbytes = cm_data.blockSize - bufIndex;	/* what remains in buffer */
        if (nbytes > length) nbytes = length;	/* don't go past EOF */

        /* now copy the data */
        memcpy(bufferp, bufp->datap + bufIndex, nbytes);

        /* adjust lengthers, pointers, etc. */
        bufferp += nbytes;
        length -= nbytes;
        thyper.LowPart = nbytes;
        thyper.HighPart = 0;
        *offsetp = LargeIntegerAdd(thyper, *offsetp);
    } /* while 1 */

  done:
    if (bufp)
        buf_Release(bufp);

    if (code == 0 && sequential)
        cm_ConsiderPrefetch(scp, &lastByte, *readp, userp, reqp);

    return code;
}