static NTSTATUS SrvTree2AddFile_inlock( PLWIO_SRV_TREE_2 pTree, PLWIO_SRV_FILE_2 pFile ) { NTSTATUS ntStatus = 0; ntStatus = LwRtlRBTreeAdd( pTree->pFileCollection, &pFile->fid, pFile); BAIL_ON_NT_STATUS(ntStatus); // Reference from parent SrvFile2Acquire(pFile); SrvFile2SetInParent(pFile); pTree->lruFile[pFile->fid.ullVolatileId % SRV_LRU_CAPACITY] = pFile; pTree->ulNumOpenFiles++; cleanup: return ntStatus; error: goto cleanup; }
NTSTATUS SrvSession2CreateTree( PLWIO_SRV_SESSION_2 pSession, PSRV_SHARE_INFO pShareInfo, PLWIO_SRV_TREE_2* ppTree ) { NTSTATUS ntStatus = 0; PLWIO_SRV_TREE_2 pTree = NULL; BOOLEAN bInLock = FALSE; ULONG ulTid = 0; LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex); ntStatus = SrvSession2UpdateLastActivityTime_inlock(pSession); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvSession2AcquireTreeId_inlock( pSession, &ulTid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvTree2Create( ulTid, pShareInfo, &pTree); BAIL_ON_NT_STATUS(ntStatus); ntStatus = LwRtlRBTreeAdd( pSession->pTreeCollection, &pTree->ulTid, pTree); BAIL_ON_NT_STATUS(ntStatus); pTree->ullUid = pSession->ullUid; pTree->ulConnectionResourceId = pSession->ulConnectionResourceId; *ppTree = SrvTree2Acquire(pTree); cleanup: LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex); return ntStatus; error: *ppTree = NULL; if (pTree) { SrvTree2Release(pTree); } goto cleanup; }
NTSTATUS SrvTreeAddAsyncState( PLWIO_SRV_TREE pTree, PLWIO_ASYNC_STATE pAsyncState ) { NTSTATUS ntStatus = STATUS_SUCCESS; BOOLEAN bInLock = FALSE; PLWIO_ASYNC_STATE pAsyncState1 = NULL; LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex); ntStatus = LwRtlRBTreeFind( pTree->pAsyncStateCollection, &pAsyncState->ullAsyncId, (PVOID*)&pAsyncState1); switch (ntStatus) { case STATUS_NOT_FOUND: ntStatus = LwRtlRBTreeAdd( pTree->pAsyncStateCollection, &pAsyncState->ullAsyncId, pAsyncState); BAIL_ON_NT_STATUS(ntStatus); SrvAsyncStateAcquire(pAsyncState); break; case STATUS_SUCCESS: ntStatus = STATUS_DUPLICATE_OBJECTID; break; default: ; } BAIL_ON_NT_STATUS(ntStatus); error: LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex); return ntStatus; }
NTSTATUS SrvElementsRegisterResource( PSRV_RESOURCE pResource, /* IN OUT */ PULONG pulResourceId /* IN OUT OPTIONAL */ ) { NTSTATUS ntStatus = 0; BOOLEAN bInLock = FALSE; LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gSrvElements.resources.mutex); ntStatus = SrvElementsResourceAcquireId_inlock( &gSrvElements.resources, &pResource->ulResourceId); BAIL_ON_NT_STATUS(ntStatus); ntStatus = LwRtlRBTreeAdd( gSrvElements.resources.pResources, &pResource->ulResourceId, pResource); BAIL_ON_NT_STATUS(ntStatus); if (pulResourceId) { *pulResourceId = pResource->ulResourceId; } cleanup: LWIO_UNLOCK_RWMUTEX(bInLock, &gSrvElements.resources.mutex); return ntStatus; error: if (pulResourceId) { *pulResourceId = 0; } pResource->ulResourceId = 0; goto cleanup; }
NTSTATUS SrvTreeCreateFile( PLWIO_SRV_TREE pTree, PWSTR pwszFilename, PIO_FILE_HANDLE phFile, PIO_FILE_NAME* ppFilename, ACCESS_MASK desiredAccess, LONG64 allocationSize, FILE_ATTRIBUTES fileAttributes, FILE_SHARE_FLAGS shareAccess, FILE_CREATE_DISPOSITION createDisposition, FILE_CREATE_OPTIONS createOptions, PLWIO_SRV_FILE* ppFile ) { NTSTATUS ntStatus = 0; BOOLEAN bInLock = FALSE; PLWIO_SRV_FILE pFile = NULL; USHORT fid = 0; LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pTree->mutex); ntStatus = SrvTreeAcquireFileId_inlock( pTree, &fid); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvFileCreate( fid, pwszFilename, phFile, ppFilename, desiredAccess, allocationSize, fileAttributes, shareAccess, createDisposition, createOptions, &pFile); BAIL_ON_NT_STATUS(ntStatus); ntStatus = LwRtlRBTreeAdd( pTree->pFileCollection, &pFile->fid, pFile); BAIL_ON_NT_STATUS(ntStatus); pFile->resource.pAttributes->treeId.usTid = pTree->tid; pFile->resource.pAttributes->sessionId.usUid = pTree->uid; pFile->resource.pAttributes->ulConnectionResourceId = pTree->ulConnectionResourceId; pTree->ulNumOpenFiles++; *ppFile = SrvFileAcquire(pFile); cleanup: LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->mutex); return ntStatus; error: *ppFile = NULL; if (pFile) { SrvFileRelease(pFile); } goto cleanup; }
NTSTATUS SrvFinderCreateSearchSpace( IN IO_FILE_HANDLE hRootFileHandle, IN PSRV_SHARE_INFO pShareInfo, IN PIO_CREATE_SECURITY_CONTEXT pIoSecurityContext, IN HANDLE hFinderRepository, IN PWSTR pwszFilesystemPath, IN PWSTR pwszSearchPattern, IN SMB_FILE_ATTRIBUTES usSearchAttrs, IN USHORT usFlags, IN ULONG ulSearchStorageType, IN SMB_INFO_LEVEL infoLevel, IN BOOLEAN bUseLongFilenames, IN ACCESS_MASK accessMask, OUT PHANDLE phFinder, OUT PUSHORT pusSearchId ) { NTSTATUS ntStatus = 0; IO_FILE_HANDLE hFile = NULL; IO_STATUS_BLOCK ioStatusBlock = {0}; IO_FILE_NAME fileName = {0}; PVOID pSecurityDescriptor = NULL; PVOID pSecurityQOS = NULL; PSRV_FINDER_REPOSITORY pFinderRepository = NULL; PSRV_SEARCH_SPACE pSearchSpace = NULL; USHORT usCandidateSearchId = 0; BOOLEAN bFound = FALSE; BOOLEAN bInLock = FALSE; PIO_ECP_LIST pEcpList = NULL; FILE_CREATE_OPTIONS createOptions = 0; pFinderRepository = (PSRV_FINDER_REPOSITORY)hFinderRepository; fileName.RootFileHandle = hRootFileHandle; ntStatus = LwRtlUnicodeStringInitEx(&fileName.Name, pwszFilesystemPath); BAIL_ON_NT_STATUS(ntStatus); if (pShareInfo->Flags & SHARE_INFO_FLAG_ABE_ENABLED) { ntStatus = IoRtlEcpListAllocate(&pEcpList); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvIoPrepareAbeEcpList(pEcpList); BAIL_ON_NT_STATUS(ntStatus); } if (usFlags & SMB_FIND_WITH_BACKUP_INTENT) { createOptions |= FILE_OPEN_FOR_BACKUP_INTENT; } ntStatus = SrvIoCreateFile( pShareInfo, &hFile, NULL, &ioStatusBlock, pIoSecurityContext, &fileName, pSecurityDescriptor, pSecurityQOS, accessMask, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, createOptions, NULL, /* EA Buffer */ 0, /* EA Length */ pEcpList); BAIL_ON_NT_STATUS(ntStatus); LWIO_LOCK_MUTEX(bInLock, &pFinderRepository->mutex); usCandidateSearchId = pFinderRepository->usNextSearchId; do { PSRV_SEARCH_SPACE pSearchSpace = NULL; // 0 is not a valid search id if (!usCandidateSearchId || (usCandidateSearchId == UINT16_MAX)) { usCandidateSearchId = 1; } ntStatus = LwRtlRBTreeFind( pFinderRepository->pSearchSpaceCollection, &usCandidateSearchId, (PVOID*)&pSearchSpace); if (ntStatus == STATUS_NOT_FOUND) { ntStatus = STATUS_SUCCESS; bFound = TRUE; } else { usCandidateSearchId++; } BAIL_ON_NT_STATUS(ntStatus); } while ((usCandidateSearchId != pFinderRepository->usNextSearchId) && !bFound); if (!bFound) { ntStatus = STATUS_TOO_MANY_OPENED_FILES; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = SrvAllocateMemory( sizeof(SRV_SEARCH_SPACE), (PVOID*)&pSearchSpace); BAIL_ON_NT_STATUS(ntStatus); pSearchSpace->refCount = 1; pthread_mutex_init(&pSearchSpace->mutex, NULL); pSearchSpace->pMutex = &pSearchSpace->mutex; pSearchSpace->usSearchId = usCandidateSearchId; ntStatus = LwRtlRBTreeAdd( pFinderRepository->pSearchSpaceCollection, &pSearchSpace->usSearchId, pSearchSpace); BAIL_ON_NT_STATUS(ntStatus); pSearchSpace->hFile = hFile; hFile = NULL; pSearchSpace->infoLevel = infoLevel; pSearchSpace->usSearchAttrs = usSearchAttrs; pSearchSpace->ulSearchStorageType = ulSearchStorageType; pSearchSpace->bUseLongFilenames = bUseLongFilenames; ntStatus = SrvAllocateStringW( pwszSearchPattern, &pSearchSpace->pwszSearchPattern); BAIL_ON_NT_STATUS(ntStatus); InterlockedIncrement(&pSearchSpace->refCount); pFinderRepository->usNextSearchId = usCandidateSearchId + 1; *phFinder = pSearchSpace; *pusSearchId = usCandidateSearchId; cleanup: LWIO_UNLOCK_MUTEX(bInLock, &pFinderRepository->mutex); if (pEcpList) { IoRtlEcpListFree(&pEcpList); } return ntStatus; error: *phFinder = NULL; *pusSearchId = 0; if (pSearchSpace) { SrvFinderReleaseSearchSpace(pSearchSpace); } if (hFile) { IoCloseFile(hFile); } goto cleanup; }