static NTSTATUS PvfsSetMaximalAccessMask( PIRP pIrp ) { NTSTATUS ntError = STATUS_SUCCESS; PACCESS_MASK pulMaxAccessMask = NULL; ULONG ulEcpSize = 0; ntError = IoRtlEcpListFind( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_MAX_ACCESS, OUT_PPVOID(&pulMaxAccessMask), &ulEcpSize); if (ntError != STATUS_NOT_FOUND) { BAIL_ON_NT_STATUS(ntError); if (ulEcpSize != sizeof(ACCESS_MASK)) { ntError = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntError); } // TODO: Fill in the correct maximal access *pulMaxAccessMask = 0x1F01FF; } else { ntError = STATUS_SUCCESS; } error: return ntError; }
NTSTATUS PvfsCreateDirDoSysOpen( IN PVOID pContext ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_PENDING_CREATE pCreateContext = (PPVFS_PENDING_CREATE)pContext; PIRP pIrp = pCreateContext->pIrpContext->pIrp; IRP_ARGS_CREATE Args = pIrp->Args.Create; int fd = -1; int unixFlags = 0; PIO_CREATE_SECURITY_CONTEXT pSecCtx = Args.SecurityContext; FILE_CREATE_RESULT CreateResult = 0; IO_MATCH_FILE_SPEC FileSpec = {0}; WCHAR wszPattern[2] = {L'*', 0x0 }; PIO_SECURITY_CONTEXT_PROCESS_INFORMATION pProcess = NULL; PBOOLEAN pbEnableAbe = NULL; ULONG ulEcpSize = 0; pProcess = IoSecurityGetProcessInfo(pSecCtx); /* Fail any create that requires setting the security but doesn't have the Unix uid/gid information */ if ((pCreateContext->SetPropertyFlags & PVFS_SET_PROP_SECURITY) && (pProcess == NULL)) { ntError = STATUS_ACCESS_DENIED; BAIL_ON_NT_STATUS(ntError); } /* Do the open() */ ntError = MapPosixOpenFlags( &unixFlags, pCreateContext->GrantedAccess, Args); BAIL_ON_NT_STATUS(ntError); if (!pCreateContext->bFileExisted) { ntError = PvfsSysMkDir( pCreateContext->pszDiskFilename, (mode_t)gPvfsDriverConfig.CreateDirectoryMode); BAIL_ON_NT_STATUS(ntError); } /* Open the DIR* and then open a fd based on that */ ntError = PvfsAllocateMemory( (PVOID)&pCreateContext->pCcb->pDirContext, sizeof(PVFS_DIRECTORY_CONTEXT)); BAIL_ON_NT_STATUS(ntError); pCreateContext->pCcb->pszFilename = pCreateContext->pszDiskFilename; pCreateContext->pszDiskFilename = NULL; ntError = IoRtlEcpListFind( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_ABE, OUT_PPVOID(&pbEnableAbe), &ulEcpSize); if (ntError != STATUS_NOT_FOUND) { BAIL_ON_NT_STATUS(ntError); if (ulEcpSize != sizeof(BOOLEAN)) { ntError = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntError); } if (*pbEnableAbe) { pCreateContext->pCcb->EcpFlags |= PVFS_ECP_ENABLE_ABE; } } do { ntError = PvfsSysOpen( &fd, pCreateContext->pCcb->pszFilename, 0, 0); } while (ntError == STATUS_MORE_PROCESSING_REQUIRED); BAIL_ON_NT_STATUS(ntError); /* Save our state */ pCreateContext->pCcb->fd = fd; pCreateContext->pCcb->ShareFlags = Args.ShareAccess; pCreateContext->pCcb->AccessGranted = pCreateContext->GrantedAccess; pCreateContext->pCcb->CreateOptions = Args.CreateOptions; ntError = PvfsAddCCBToFCB(pCreateContext->pFcb, pCreateContext->pCcb); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSaveFileDeviceInfo(pCreateContext->pCcb); BAIL_ON_NT_STATUS(ntError); if ((pCreateContext->SetPropertyFlags & PVFS_SET_PROP_SECURITY) && pSecCtx) { /* Unix Security */ ntError = PvfsSysChown( pCreateContext->pCcb, pProcess->Uid, pProcess->Gid); BAIL_ON_NT_STATUS(ntError); /* Security Descriptor */ ntError = PvfsCreateFileSecurity( pCreateContext->pCcb->pUserToken, pCreateContext->pCcb, Args.SecurityDescriptor, TRUE); BAIL_ON_NT_STATUS(ntError); } if ((pCreateContext->SetPropertyFlags & PVFS_SET_PROP_ATTRIB) && (Args.FileAttributes != 0)) { ntError = PvfsSetFileAttributes( pCreateContext->pCcb, Args.FileAttributes); BAIL_ON_NT_STATUS(ntError); } /* Save the delete-on-close flag to the FCB */ if (Args.CreateOptions & FILE_DELETE_ON_CLOSE) { LwRtlUnicodeStringInit(&FileSpec.Pattern, wszPattern); ntError = PvfsEnumerateDirectory(pCreateContext->pCcb, &FileSpec, 1, FALSE); if (ntError == STATUS_SUCCESS) { ntError = STATUS_DIRECTORY_NOT_EMPTY; BAIL_ON_NT_STATUS(ntError); } pCreateContext->pCcb->bPendingDeleteHandle = TRUE; } ntError = PvfsStoreCCB(pIrp->FileHandle, pCreateContext->pCcb); BAIL_ON_NT_STATUS(ntError); PvfsInitializeZctSupport(pCreateContext->pCcb, pIrp->FileHandle); CreateResult = PvfsSetCreateResult( Args.CreateDisposition, pCreateContext->bFileExisted, STATUS_SUCCESS); if (CreateResult == FILE_CREATED) { PvfsNotifyScheduleFullReport( pCreateContext->pCcb->pFcb, FILE_NOTIFY_CHANGE_FILE_NAME, FILE_ACTION_ADDED, pCreateContext->pCcb->pszFilename); } /* The CCB has been handled off to the FileHandle so make sure we don't think we still own it */ pCreateContext->pCcb = NULL; cleanup: pIrp->IoStatusBlock.CreateResult = CreateResult; return ntError; error: CreateResult = PvfsSetCreateResult( Args.CreateDisposition, pCreateContext->bFileExisted, ntError); if (fd != -1) { PSTR pszRemovePath = NULL; /* Pick up where we started the pathname */ pszRemovePath = pCreateContext->pszDiskFilename ? pCreateContext->pszDiskFilename : pCreateContext->pCcb->pszFilename; PvfsCleanupFailedCreate( fd, pszRemovePath, !pCreateContext->bFileExisted); } goto cleanup; }
static NTSTATUS NpfsCommonProcessCreateEcp( PNPFS_IRP_CONTEXT pIrpContext, PIRP pIrp, PNPFS_CCB pCCB ) { NTSTATUS ntStatus = STATUS_SUCCESS; PNPFS_PIPE pPipe = pCCB->pPipe; PBYTE pSessionKey = NULL; ULONG ulSessionKeyLength = 0; PBYTE pAddr = NULL; ULONG ulEcpSize = 0; PFILE_NETWORK_OPEN_INFORMATION pNetworkOpenInfo = NULL; PFILE_PIPE_INFORMATION pPipeInfo = NULL; PFILE_PIPE_LOCAL_INFORMATION pPipeLocalInfo = NULL; ntStatus = IoRtlEcpListFind( pIrp->Args.Create.EcpList, IO_ECP_TYPE_SESSION_KEY, OUT_PPVOID(&pSessionKey), &ulSessionKeyLength); if (ntStatus != STATUS_NOT_FOUND) { BAIL_ON_NT_STATUS(ntStatus); ntStatus = RTL_ALLOCATE(&pPipe->pSessionKey, BYTE, ulSessionKeyLength); BAIL_ON_NT_STATUS(ntStatus); memcpy(pPipe->pSessionKey, pSessionKey, ulSessionKeyLength); pPipe->ulSessionKeyLength = ulSessionKeyLength; } ntStatus = IoRtlEcpListFind( pIrp->Args.Create.EcpList, IO_ECP_TYPE_PEER_ADDRESS, OUT_PPVOID(&pAddr), &ulEcpSize); if (ntStatus != STATUS_NOT_FOUND) { BAIL_ON_NT_STATUS(ntStatus); if (ulEcpSize > sizeof(pPipe->ClientAddress)) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } pPipe->usClientAddressLen = (USHORT) ulEcpSize; memcpy(pPipe->ClientAddress, pAddr, ulEcpSize); } ntStatus = IoRtlEcpListFind( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_NET_OPEN_INFO, OUT_PPVOID(&pNetworkOpenInfo), &ulEcpSize); if (ntStatus == STATUS_SUCCESS) { if (ulEcpSize != sizeof(FILE_NETWORK_OPEN_INFORMATION)) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NpfsQueryCcbFileNetworkOpenInfo(pCCB, pNetworkOpenInfo); BAIL_ON_NT_STATUS(ntStatus); ntStatus = IoRtlEcpListAcknowledge( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_NET_OPEN_INFO); BAIL_ON_NT_STATUS(ntStatus); } else { ntStatus = STATUS_SUCCESS; } ntStatus = IoRtlEcpListFind( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_PIPE_INFO, OUT_PPVOID(&pPipeInfo), &ulEcpSize); if (ntStatus == STATUS_SUCCESS) { if (ulEcpSize != sizeof(FILE_PIPE_INFORMATION)) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NpfsQueryCcbFilePipeInfo(pCCB, pPipeInfo); BAIL_ON_NT_STATUS(ntStatus); ntStatus = IoRtlEcpListAcknowledge( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_PIPE_INFO); BAIL_ON_NT_STATUS(ntStatus); } else { ntStatus = STATUS_SUCCESS; } ntStatus = IoRtlEcpListFind( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_PIPE_LOCAL_INFO, OUT_PPVOID(&pPipeLocalInfo), &ulEcpSize); if (ntStatus == STATUS_SUCCESS) { if (ulEcpSize != sizeof(FILE_PIPE_LOCAL_INFORMATION)) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = NpfsQueryCcbFilePipeLocalInfo(pCCB, pPipeLocalInfo); BAIL_ON_NT_STATUS(ntStatus); ntStatus = IoRtlEcpListAcknowledge( pIrp->Args.Create.EcpList, SRV_ECP_TYPE_PIPE_LOCAL_INFO); BAIL_ON_NT_STATUS(ntStatus); } else { ntStatus = STATUS_SUCCESS; } cleanup: return ntStatus; error: goto cleanup; }