NTSTATUS NpfsClientCloseHandle( PNPFS_CCB pCCB ) { NTSTATUS ntStatus = 0; PNPFS_PIPE pPipe = NULL; PNPFS_CCB pSCB = NULL; PLW_LIST_LINKS pLink = NULL; PNPFS_IRP_CONTEXT pReadContext = NULL; pPipe = pCCB->pPipe; ENTER_MUTEX(&pPipe->PipeMutex); pSCB = pPipe->pSCB; pPipe->PipeClientState = PIPE_CLIENT_CLOSED; while (pSCB && !LwListIsEmpty(&pSCB->ReadIrpList)) { pLink = pSCB->ReadIrpList.Next; LwListRemove(pLink); pReadContext = LW_STRUCT_FROM_FIELD(pLink, NPFS_IRP_CONTEXT, Link); NpfsServerCompleteReadFile(pSCB, pReadContext); } pthread_cond_signal(&pPipe->PipeCondition); if (pPipe->PipeServerState == PIPE_SERVER_CLOSED) { ntStatus = NpfsFreePipeContext(pPipe); BAIL_ON_NT_STATUS(ntStatus); } error: pPipe->pCCB = NULL; LEAVE_MUTEX(&pPipe->PipeMutex); NpfsReleaseCCB(pCCB); return(ntStatus); }
NTSTATUS NpfsCommonCreate( PNPFS_IRP_CONTEXT pIrpContext, PIRP pIrp ) { NTSTATUS ntStatus = 0; PUNICODE_STRING pPipeName = &pIrpContext->pIrp->Args.Create.FileName.Name; PNPFS_FCB pFCB = NULL; PNPFS_PIPE pPipe = NULL; PNPFS_CCB pCCB = NULL; BOOLEAN bReleaseLock = FALSE; PNPFS_IRP_CONTEXT pConnectContext = NULL; ntStatus = NpfsValidateCreate(pIrpContext); BAIL_ON_NT_STATUS(ntStatus); ENTER_READER_RW_LOCK(&gServerLock); ntStatus = NpfsFindFCB(pPipeName, &pFCB); LEAVE_READER_RW_LOCK(&gServerLock); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NpfsFindAvailablePipe(pFCB, &pPipe); BAIL_ON_NT_STATUS(ntStatus); ENTER_MUTEX(&pPipe->PipeMutex); bReleaseLock = TRUE; if (pPipe->PipeServerState != PIPE_SERVER_WAITING_FOR_CONNECTION) { ntStatus = STATUS_INVALID_SERVER_STATE; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NpfsCreateCCB(pIrpContext, pPipe, &pCCB); BAIL_ON_NT_STATUS(ntStatus); pPipe->PipeClientState = PIPE_CLIENT_CONNECTED; pPipe->pClientAccessToken = IoSecurityGetAccessToken(pIrp->Args.Create.SecurityContext); RtlReferenceAccessToken(pPipe->pClientAccessToken); ntStatus = NpfsCommonProcessCreateEcp(pIrpContext, pIrp, pCCB); BAIL_ON_NT_STATUS(ntStatus); /* Wake up blocking pipe waiters */ pthread_cond_signal(&pPipe->PipeCondition); /* If there is a pending connect IRP, grab it to complete once we leave the pipe mutex */ if (pPipe->pPendingServerConnect) { pConnectContext = pPipe->pPendingServerConnect; pPipe->pPendingServerConnect = NULL; pPipe->PipeServerState = PIPE_SERVER_CONNECTED; } LEAVE_MUTEX(&pPipe->PipeMutex); bReleaseLock = FALSE; if (pConnectContext) { pConnectContext->pIrp->IoStatusBlock.Status = STATUS_SUCCESS; IoIrpComplete(pConnectContext->pIrp); IO_FREE(&pConnectContext); } ntStatus = NpfsSetCCB(pIrpContext->pIrp->FileHandle, pCCB); BAIL_ON_NT_STATUS(ntStatus); pIrpContext->pIrp->IoStatusBlock.CreateResult = FILE_OPENED; cleanup: if (bReleaseLock) { LEAVE_MUTEX(&pPipe->PipeMutex); } if (pFCB) { NpfsReleaseFCB(pFCB); } if (pPipe) { NpfsReleasePipe(pPipe); } if (pCCB) { NpfsReleaseCCB(pCCB); } pIrpContext->pIrp->IoStatusBlock.Status = ntStatus; return ntStatus; error: pIrpContext->pIrp->IoStatusBlock.CreateResult = FILE_DOES_NOT_EXIST; goto cleanup; }