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; }
NTSTATUS FspIopCreateRequestWorkItem(FSP_FSCTL_TRANSACT_REQ *Request) { PAGED_CODE(); FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem; if (0 == RequestHeader->WorkItem) { RequestWorkItem = FspAllocNonPaged(sizeof *RequestWorkItem); if (0 == RequestWorkItem) return STATUS_INSUFFICIENT_RESOURCES; RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem); RequestHeader->WorkItem = RequestWorkItem; } return STATUS_SUCCESS; }
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; }