static NTSTATUS PtfsCreate(PWSTR Path, PWSTR VolumePrefix, PWSTR MountPoint, UINT32 DebugFlags, PTFS **PPtfs) { WCHAR FullPath[MAX_PATH]; ULONG Length; HANDLE Handle; FILETIME CreationTime; DWORD LastError; FSP_FSCTL_VOLUME_PARAMS VolumeParams; PTFS *Ptfs = 0; NTSTATUS Result; *PPtfs = 0; Handle = CreateFileW( Path, FILE_READ_ATTRIBUTES, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (INVALID_HANDLE_VALUE == Handle) return FspNtStatusFromWin32(GetLastError()); Length = GetFinalPathNameByHandleW(Handle, FullPath, FULLPATH_SIZE - 1, 0); if (0 == Length) { LastError = GetLastError(); CloseHandle(Handle); return FspNtStatusFromWin32(LastError); } if (L'\\' == FullPath[Length - 1]) FullPath[--Length] = L'\0'; if (!GetFileTime(Handle, &CreationTime, 0, 0)) { LastError = GetLastError(); CloseHandle(Handle); return FspNtStatusFromWin32(LastError); } CloseHandle(Handle); /* from now on we must goto exit on failure */ Ptfs = malloc(sizeof *Ptfs); if (0 == Ptfs) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } memset(Ptfs, 0, sizeof *Ptfs); Length = (Length + 1) * sizeof(WCHAR); Ptfs->Path = malloc(Length); if (0 == Ptfs->Path) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } memcpy(Ptfs->Path, FullPath, Length); memset(&VolumeParams, 0, sizeof VolumeParams); VolumeParams.SectorSize = ALLOCATION_UNIT; VolumeParams.SectorsPerAllocationUnit = 1; VolumeParams.VolumeCreationTime = ((PLARGE_INTEGER)&CreationTime)->QuadPart; VolumeParams.VolumeSerialNumber = 0; VolumeParams.FileInfoTimeout = 1000; VolumeParams.CaseSensitiveSearch = 0; VolumeParams.CasePreservedNames = 1; VolumeParams.UnicodeOnDisk = 1; VolumeParams.PersistentAcls = 1; VolumeParams.PostCleanupWhenModifiedOnly = 1; VolumeParams.PassQueryDirectoryPattern = 1; VolumeParams.FlushAndPurgeOnCleanup = 1; VolumeParams.UmFileContextIsUserContext2 = 1; if (0 != VolumePrefix) wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix); wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR), L"" PROGNAME); Result = FspFileSystemCreate( VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME, &VolumeParams, &PtfsInterface, &Ptfs->FileSystem); if (!NT_SUCCESS(Result)) goto exit; Ptfs->FileSystem->UserContext = Ptfs; Result = FspFileSystemSetMountPoint(Ptfs->FileSystem, MountPoint); if (!NT_SUCCESS(Result)) goto exit; FspFileSystemSetDebugLog(Ptfs->FileSystem, DebugFlags); Result = STATUS_SUCCESS; exit: if (NT_SUCCESS(Result)) *PPtfs = Ptfs; else if (0 != Ptfs) PtfsDelete(Ptfs); return Result; }
NTSTATUS MemfsCreate( ULONG Flags, ULONG FileInfoTimeout, ULONG MaxFileNodes, ULONG MaxFileSize, PWSTR VolumePrefix, PWSTR RootSddl, MEMFS **PMemfs) { NTSTATUS Result; FSP_FSCTL_VOLUME_PARAMS VolumeParams; PWSTR DevicePath = (Flags & MemfsNet) ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME; UINT64 AllocationUnit; MEMFS *Memfs; MEMFS_FILE_NODE *RootNode; PSECURITY_DESCRIPTOR RootSecurity; ULONG RootSecuritySize; BOOLEAN Inserted; *PMemfs = 0; if (0 == RootSddl) RootSddl = L"O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;WD)"; if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(RootSddl, SDDL_REVISION_1, &RootSecurity, &RootSecuritySize)) return FspNtStatusFromWin32(GetLastError()); Memfs = (MEMFS *)malloc(sizeof *Memfs); if (0 == Memfs) { LocalFree(RootSecurity); return STATUS_INSUFFICIENT_RESOURCES; } memset(Memfs, 0, sizeof *Memfs); Memfs->MaxFileNodes = MaxFileNodes; AllocationUnit = MEMFS_SECTOR_SIZE * MEMFS_SECTORS_PER_ALLOCATION_UNIT; Memfs->MaxFileSize = (ULONG)((MaxFileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit); Result = MemfsFileNodeMapCreate(&Memfs->FileNodeMap); if (!NT_SUCCESS(Result)) { free(Memfs); LocalFree(RootSecurity); return Result; } memset(&VolumeParams, 0, sizeof VolumeParams); VolumeParams.SectorSize = MEMFS_SECTOR_SIZE; VolumeParams.SectorsPerAllocationUnit = MEMFS_SECTORS_PER_ALLOCATION_UNIT; VolumeParams.VolumeCreationTime = MemfsGetSystemTime(); VolumeParams.VolumeSerialNumber = (UINT32)(MemfsGetSystemTime() / (10000 * 1000)); VolumeParams.FileInfoTimeout = FileInfoTimeout; VolumeParams.CaseSensitiveSearch = 1; VolumeParams.CasePreservedNames = 1; VolumeParams.UnicodeOnDisk = 1; VolumeParams.PersistentAcls = 1; if (0 != VolumePrefix) wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix); Result = FspFileSystemCreate(DevicePath, &VolumeParams, &MemfsInterface, &Memfs->FileSystem); if (!NT_SUCCESS(Result)) { MemfsFileNodeMapDelete(Memfs->FileNodeMap); free(Memfs); LocalFree(RootSecurity); return Result; } Memfs->FileSystem->UserContext = Memfs; Memfs->VolumeLabelLength = sizeof L"MEMFS" - sizeof(WCHAR); memcpy(Memfs->VolumeLabel, L"MEMFS", Memfs->VolumeLabelLength); #if 0 FspFileSystemSetOperationGuardStrategy(Memfs->FileSystem, FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE); #endif /* * Create root directory. */ Result = MemfsFileNodeCreate(L"\\", &RootNode); if (!NT_SUCCESS(Result)) { MemfsDelete(Memfs); LocalFree(RootSecurity); return Result; } RootNode->FileInfo.FileAttributes = FILE_ATTRIBUTE_DIRECTORY; RootNode->FileSecurity = malloc(RootSecuritySize); if (0 == RootNode->FileSecurity) { MemfsFileNodeDelete(RootNode); MemfsDelete(Memfs); LocalFree(RootSecurity); return STATUS_INSUFFICIENT_RESOURCES; } RootNode->FileSecuritySize = RootSecuritySize; memcpy(RootNode->FileSecurity, RootSecurity, RootSecuritySize); Result = MemfsFileNodeMapInsert(Memfs->FileNodeMap, RootNode, &Inserted); if (!NT_SUCCESS(Result)) { MemfsFileNodeDelete(RootNode); MemfsDelete(Memfs); LocalFree(RootSecurity); return Result; } LocalFree(RootSecurity); *PMemfs = Memfs; return STATUS_SUCCESS; }