//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: pipe.cxx // //-------------------------------------------------------------------------- #include #include "pipe.h" void I_RpcReadPipeElementsFromBuffer ( PIPE_STATE PAPI *state, char PAPI *TargetBuffer, int TargetBufferSize, int PAPI *NumCopied ) { char PAPI *temp, PAPI *temp1 ; int size ; int totalsize ; ASSERT(state->CurrentState == start || (state->PartialCountSize < sizeof(DWORD) && state->PartialPipeElementSize < state->PipeElementSize)) ; if (TargetBufferSize < state->PipeElementSize) { return ; } while (1) { switch(state->CurrentState) { case start: // read in an element count if (state->BytesRemaining == 0) { return ; } // transition: end of src if (state->BytesRemaining CurrentState = return_partial_count ; break; } // transition: scan chunk count state->PartialCount = 0 ; state->PartialCountSize = 0 ; state->PartialPipeElementSize = 0 ; state->ElementsRemaining = *((DWORD *) state->CurPointer) ; #if DBG PrintToDebugger("PIPES: ElementsRemainaing: %d\n", state->ElementsRemaining) ; #endif state->CurPointer += sizeof(DWORD) ; state->BytesRemaining -= sizeof(DWORD) ; if (state->ElementsRemaining == 0) { state->EndOfPipe = 1 ; return ; } else { state->CurrentState = copy_pipe_elem ; } break; case read_partial_count: // also a start state & final state size = sizeof(DWORD) ; totalsize = 0 ; ASSERT(state->PartialCountSize > 0 && state->PartialCountSize < 4) ; ASSERT(state->ElementsRemaining == 0) ; temp = (char *) &(state->PartialCount) ; temp1 = (char *) &(state->ElementsRemaining) ; for (;state->PartialCountSize; state->PartialCountSize--, size--, totalsize++) { *temp1++ = *temp++ ; } for (;size && state->BytesRemaining; size--,state->BytesRemaining--, totalsize++) { *temp1++ = *state->CurPointer++ ; } #if DBG PrintToDebugger("PIPES: ElementsRemainaing: %d\n", state->ElementsRemaining) ; #endif if (size == 0) { state->CurrentState = copy_pipe_elem ; } else { // copy the stuff back into Partial count // and keep it around for the next call // the next time around, we'll end up in the same // state temp = (char *) &(state->PartialCount) ; temp1 = (char *) &(state->ElementsRemaining) ; ASSERT(totalsize < sizeof(DWORD)) ; for (;totalsize; totalsize--, state->PartialCountSize++) { *temp++ = *temp1++ ; } return ; } break; case read_partial_pipe_elem: //also a start state ASSERT(state->PartialPipeElementSize > 0 && state->PartialPipeElementSize < state->PipeElementSize) ; if (TargetBufferSize < state->PipeElementSize) { // this is not an error return ; } size = state->PipeElementSize ; if (state->BytesRemaining >= size-state->PartialPipeElementSize) { temp = (char *) state->PartialPipeElement ; for (;state->PartialPipeElementSize; state->PartialPipeElementSize--, size--, TargetBufferSize--) { *TargetBuffer++ = *temp++ ; } for (;size && state->BytesRemaining; size--, state->BytesRemaining--, TargetBufferSize--) { *TargetBuffer++ = *state->CurPointer++ ; } state->CurrentState = copy_pipe_elem ; *NumCopied += 1 ; } else { // copy the stuff back into partial pipe buffer // and keep it around for the next call // the next time around, we'll end up in the same // state temp = (char *) state->PartialPipeElement+ state->PartialPipeElementSize ; for (;state->BytesRemaining; state->BytesRemaining--, state->PartialPipeElementSize++) { *temp++ = *state->CurPointer++ ; } return ; } break; case copy_pipe_elem: // also a start state if (state->BytesRemaining >= state->PipeElementSize) { if (TargetBufferSize >= state->PipeElementSize) { for (size = state->PipeElementSize; size; size--, TargetBufferSize--, state->BytesRemaining--) { *TargetBuffer++ = *state->CurPointer++ ; } state->ElementsRemaining-- ; *NumCopied += 1 ; if (state->ElementsRemaining == 0) { state->CurrentState = start ; if (TargetBufferSize < state->PipeElementSize) { return ; } } } else { // end of target buffer // return the appropriate count return ; } } else { if (state->BytesRemaining) { state->CurrentState = return_partial_pipe_elem ; } else { return ; } } break; case return_partial_pipe_elem: // also save pipe elem ASSERT(state->BytesRemaining < state->PipeElementSize) ; state->PartialPipeElementSize = 0; for (temp = (char *) state->PartialPipeElement; state->BytesRemaining; state->BytesRemaining--, state->PartialPipeElementSize++) { *temp++ = *state->CurPointer++ ; } state->CurrentState = read_partial_pipe_elem ; return; case return_partial_count: // also save count state->PartialCountSize = 0 ; ASSERT(state->BytesRemaining < sizeof(DWORD)) ; for (temp = (char *) &(state->PartialCount); state->BytesRemaining; state->BytesRemaining--, state->PartialCountSize++) { *temp++ = *state->CurPointer++ ; } state->CurrentState = read_partial_count ; return; default: ASSERT(0) ; break; } } } RPC_STATUS RPC_ENTRY MyRpcCompleteAsyncCall ( IN PRPC_ASYNC_STATE pAsync, IN void *Reply ) /*++ Function Name:MyRpcCompleteAsyncCall This is function is used by the bvts, the real stuff will call RpcCompleteAsyncCall. Parameters: Description: Returns: --*/ { return STUB(pAsync)->CompletionRoutine (pAsync, Reply) ; }