VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode) { PAGED_CODE(); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); FsRtlUninitializeFileLock(&FileNode->FileLock); FsRtlTeardownPerStreamContexts(&FileNode->Header); FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo); FspMetaCacheInvalidateItem(FsvolDeviceExtension->SecurityCache, FileNode->Security); FspDeviceDereference(FileNode->FsvolDeviceObject); if (0 != FileNode->ExternalFileName) FspFree(FileNode->ExternalFileName); ExDeleteResourceLite(&FileNode->NonPaged->PagingIoResource); ExDeleteResourceLite(&FileNode->NonPaged->Resource); FspFree(FileNode->NonPaged); FspFree(FileNode); }
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc) { PAGED_CODE(); if (0 != FileDesc->DirectoryPattern.Buffer && FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer) { if (FileDesc->CaseSensitive) FspFree(FileDesc->DirectoryPattern.Buffer); else RtlFreeUnicodeString(&FileDesc->DirectoryPattern); } FspFree(FileDesc); }
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation) { PAGED_CODE(); if (0 == Length || 0 != Irp->AssociatedIrp.SystemBuffer) return STATUS_SUCCESS; PVOID SystemBuffer = FspAllocNonPagedExternal(Length); if (0 == SystemBuffer) return STATUS_INSUFFICIENT_RESOURCES; if (IoReadAccess == Operation) { try { RtlCopyMemory(SystemBuffer, Irp->UserBuffer, Length); } except (EXCEPTION_EXECUTE_HANDLER) { FspFree(SystemBuffer); NTSTATUS Result = GetExceptionCode(); return FsRtlIsNtstatusExpected(Result) ? STATUS_INVALID_USER_BUFFER : Result; } } else
VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request) { PAGED_CODE(); FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); if (0 != RequestHeader->RequestFini) RequestHeader->RequestFini(Request, RequestHeader->Context); if (0 != RequestHeader->Response) FspFree(RequestHeader->Response); if (0 != RequestHeader->WorkItem) FspFree(RequestHeader->WorkItem); #if 0 != REQ_HEADER_ALIGN_MASK RequestHeader = ((PVOID *)RequestHeader)[-1]; #endif FspFree(RequestHeader); }
NTSTATUS FspFileDescResetDirectoryPattern(FSP_FILE_DESC *FileDesc, PUNICODE_STRING FileName, BOOLEAN Reset) { PAGED_CODE(); if (Reset || 0 == FileDesc->DirectoryPattern.Buffer) { UNICODE_STRING DirectoryPattern; if (0 == FileName || (sizeof(WCHAR) == FileName->Length && L'*' == FileName->Buffer[0])) { DirectoryPattern.Length = DirectoryPattern.MaximumLength = sizeof(WCHAR); /* L"*" */ DirectoryPattern.Buffer = FspFileDescDirectoryPatternMatchAll; } else { if (FileDesc->CaseSensitive) { DirectoryPattern.Length = DirectoryPattern.MaximumLength = FileName->Length; DirectoryPattern.Buffer = FspAlloc(FileName->Length); if (0 == DirectoryPattern.Buffer) return STATUS_INSUFFICIENT_RESOURCES; RtlCopyMemory(DirectoryPattern.Buffer, FileName->Buffer, FileName->Length); } else { NTSTATUS Result = RtlUpcaseUnicodeString(&DirectoryPattern, FileName, TRUE); if (!NT_SUCCESS(Result)) return Result; } } if (0 != FileDesc->DirectoryPattern.Buffer && FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer) { if (FileDesc->CaseSensitive) FspFree(FileDesc->DirectoryPattern.Buffer); else RtlFreeUnicodeString(&FileDesc->DirectoryPattern); } FileDesc->DirectoryPattern = DirectoryPattern; } return STATUS_SUCCESS; }
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, ULONG ExtraSize, FSP_FILE_NODE **PFileNode) { PAGED_CODE(); *PFileNode = 0; FSP_FILE_NODE_NONPAGED *NonPaged = FspAllocNonPaged(sizeof *NonPaged); if (0 == NonPaged) return STATUS_INSUFFICIENT_RESOURCES; FSP_FILE_NODE *FileNode = FspAlloc(sizeof *FileNode + ExtraSize); if (0 == FileNode) { FspFree(NonPaged); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(NonPaged, sizeof *NonPaged); ExInitializeResourceLite(&NonPaged->Resource); ExInitializeResourceLite(&NonPaged->PagingIoResource); ExInitializeFastMutex(&NonPaged->HeaderFastMutex); KeInitializeSpinLock(&NonPaged->DirInfoSpinLock); RtlZeroMemory(FileNode, sizeof *FileNode + ExtraSize); FileNode->Header.NodeTypeCode = FspFileNodeFileKind; FileNode->Header.NodeByteSize = sizeof *FileNode; FileNode->Header.IsFastIoPossible = FastIoIsNotPossible; FileNode->Header.Resource = &NonPaged->Resource; FileNode->Header.PagingIoResource = &NonPaged->PagingIoResource; FileNode->Header.ValidDataLength.QuadPart = MAXLONGLONG; /* disable ValidDataLength functionality */ FsRtlSetupAdvancedHeader(&FileNode->Header, &NonPaged->HeaderFastMutex); FileNode->NonPaged = NonPaged; FileNode->RefCount = 1; FileNode->FsvolDeviceObject = DeviceObject; FspDeviceReference(FileNode->FsvolDeviceObject); RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize); FsRtlInitializeFileLock(&FileNode->FileLock, FspFileNodeCompleteLockIrp, 0); *PFileNode = FileNode; return STATUS_SUCCESS; }
VOID FspIopSetIrpResponse(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) { PAGED_CODE(); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); ASSERT(0 != Request); if (0 != Response && RequestHeader->Response != Response) { if (0 != RequestHeader->Response) FspFree(RequestHeader->Response); RequestHeader->Response = FspAllocMustSucceed(Response->Size); RtlCopyMemory(RequestHeader->Response, Response, Response->Size); Response = RequestHeader->Response; } }
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName) { PAGED_CODE(); PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; BOOLEAN Deleted, Inserted; FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName, &Deleted); ASSERT(Deleted); if (0 != FileNode->ExternalFileName) FspFree(FileNode->ExternalFileName); FileNode->FileName = *NewFileName; FileNode->ExternalFileName = NewFileName->Buffer; FspFsvolDeviceInsertContextByName(FsvolDeviceObject, &FileNode->FileName, FileNode, &FileNode->ContextByNameElementStorage, &Inserted); ASSERT(Inserted); FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); }
NTSTATUS FspIopCreateRequestFunnel( PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, ULONG Flags, FSP_FSCTL_TRANSACT_REQ **PRequest) { PAGED_CODE(); FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader; FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = 0; FSP_FSCTL_TRANSACT_REQ *Request; *PRequest = 0; if (0 != FileName) ExtraSize += FSP_FSCTL_DEFAULT_ALIGN_UP(FileName->Length + sizeof(WCHAR)); if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) return STATUS_INVALID_PARAMETER; if (FlagOn(Flags, FspIopCreateRequestMustSucceedFlag)) { RequestHeader = FspAllocatePoolMustSucceed( FlagOn(Flags, FspIopCreateRequestNonPagedFlag) ? NonPagedPool : PagedPool, sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD, FSP_ALLOC_INTERNAL_TAG); if (FlagOn(Flags, FspIopCreateRequestWorkItemFlag)) { RequestWorkItem = FspAllocatePoolMustSucceed( NonPagedPool, sizeof *RequestWorkItem, FSP_ALLOC_INTERNAL_TAG); RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem); } } else { RequestHeader = ExAllocatePoolWithTag( FlagOn(Flags, FspIopCreateRequestNonPagedFlag) ? NonPagedPool : PagedPool, sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD, FSP_ALLOC_INTERNAL_TAG); if (0 == RequestHeader) return STATUS_INSUFFICIENT_RESOURCES; if (FlagOn(Flags, FspIopCreateRequestWorkItemFlag)) { RequestWorkItem = FspAllocNonPaged(sizeof *RequestWorkItem); if (0 == RequestWorkItem) { FspFree(RequestHeader); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem); } } #if 0 != REQ_HEADER_ALIGN_MASK PVOID Allocation = RequestHeader; RequestHeader = (PVOID)(((UINT_PTR)RequestHeader + REQ_HEADER_ALIGN_OVERHEAD) & ~REQ_HEADER_ALIGN_MASK); ((PVOID *)RequestHeader)[-1] = Allocation; #endif RtlZeroMemory(RequestHeader, sizeof *RequestHeader + sizeof *Request + ExtraSize); RequestHeader->RequestFini = RequestFini; RequestHeader->WorkItem = RequestWorkItem; Request = (PVOID)RequestHeader->RequestBuf; Request->Size = (UINT16)(sizeof *Request + ExtraSize); Request->Hint = (UINT_PTR)Irp; if (0 != FileName) { RtlCopyMemory(Request->Buffer, FileName->Buffer, FileName->Length); //Request->Buffer[FileName->Length] = '\0'; //Request->Buffer[FileName->Length + 1] = '\0'; //Request->FileName.Offset = 0; Request->FileName.Size = FileName->Length + sizeof(WCHAR); } ASSERT(0 == ((UINT_PTR)Request & (FSP_FSCTL_TRANSACT_REQ_ALIGNMENT - 1))); if (0 != Irp) { ASSERT(0 == FspIrpRequest(Irp)); FspIrpSetRequest(Irp, Request); } *PRequest = Request; return STATUS_SUCCESS; }