NTSTATUS FspToolGetSidFromName(PWSTR Name, PSID *PSid) { PSID Sid; WCHAR Domn[256]; DWORD SidSize, DomnSize; SID_NAME_USE Use; SidSize = 0; DomnSize = sizeof Domn / sizeof Domn[0]; if (LookupAccountNameW(0, Name, 0, &SidSize, Domn, &DomnSize, &Use)) return STATUS_INVALID_PARAMETER; if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) return FspNtStatusFromWin32(GetLastError()); Sid = MemAlloc(SidSize); if (0 == Sid) return STATUS_INSUFFICIENT_RESOURCES; DomnSize = sizeof Domn / sizeof Domn[0]; if (!LookupAccountNameW(0, Name, Sid, &SidSize, Domn, &DomnSize, &Use)) { MemFree(Sid); return FspNtStatusFromWin32(GetLastError()); } *PSid = Sid; return STATUS_SUCCESS; }
static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo) { HANDLE Handle = HandleFromContext(FileContext); LARGE_INTEGER FileSize; OVERLAPPED Overlapped = { 0 }; if (ConstrainedIo) { if (!GetFileSizeEx(Handle, &FileSize)) return FspNtStatusFromWin32(GetLastError()); if (Offset >= (UINT64)FileSize.QuadPart) return STATUS_SUCCESS; if (Offset + Length > (UINT64)FileSize.QuadPart) Length = (ULONG)((UINT64)FileSize.QuadPart - Offset); } Overlapped.Offset = (DWORD)Offset; Overlapped.OffsetHigh = (DWORD)(Offset >> 32); if (!WriteFile(Handle, Buffer, Length, PBytesTransferred, &Overlapped)) return FspNtStatusFromWin32(GetLastError()); return GetFileInfoInternal(Handle, FileInfo); }
static NTSTATUS EnableBackupRestorePrivileges(VOID) { union { TOKEN_PRIVILEGES P; UINT8 B[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)]; } Privileges; HANDLE Token; Privileges.P.PrivilegeCount = 2; Privileges.P.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; Privileges.P.Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; if (!LookupPrivilegeValueW(0, SE_BACKUP_NAME, &Privileges.P.Privileges[0].Luid) || !LookupPrivilegeValueW(0, SE_RESTORE_NAME, &Privileges.P.Privileges[1].Luid)) return FspNtStatusFromWin32(GetLastError()); if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token)) return FspNtStatusFromWin32(GetLastError()); if (!AdjustTokenPrivileges(Token, FALSE, &Privileges.P, 0, 0, 0)) { CloseHandle(Token); return FspNtStatusFromWin32(GetLastError()); } CloseHandle(Token); return STATUS_SUCCESS; }
static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem, PWSTR FileName, PUINT32 PFileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR FullPath[FULLPATH_SIZE]; HANDLE Handle; FILE_ATTRIBUTE_TAG_INFO AttributeTagInfo; DWORD SecurityDescriptorSizeNeeded; NTSTATUS Result; if (!ConcatPath(Ptfs, FileName, FullPath)) return STATUS_OBJECT_NAME_INVALID; Handle = CreateFileW(FullPath, FILE_READ_ATTRIBUTES | READ_CONTROL, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (INVALID_HANDLE_VALUE == Handle) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } if (0 != PFileAttributes) { if (!GetFileInformationByHandleEx(Handle, FileAttributeTagInfo, &AttributeTagInfo, sizeof AttributeTagInfo)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } *PFileAttributes = AttributeTagInfo.FileAttributes; } if (0 != PSecurityDescriptorSize) { if (!GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, SecurityDescriptor, (DWORD)*PSecurityDescriptorSize, &SecurityDescriptorSizeNeeded)) { *PSecurityDescriptorSize = SecurityDescriptorSizeNeeded; Result = FspNtStatusFromWin32(GetLastError()); goto exit; } *PSecurityDescriptorSize = SecurityDescriptorSizeNeeded; } Result = STATUS_SUCCESS; exit: if (INVALID_HANDLE_VALUE != Handle) CloseHandle(Handle); return Result; }
static NTSTATUS CreateHelperProcess(PWSTR FileName, ULONG Timeout, PHANDLE PProcess) { HANDLE Event; SECURITY_ATTRIBUTES EventAttributes; WCHAR CommandLine[MAX_PATH + 64]; STARTUPINFOW StartupInfo; PROCESS_INFORMATION ProcessInfo; DWORD WaitResult; NTSTATUS Result; memset(&EventAttributes, 0, sizeof EventAttributes); EventAttributes.nLength = sizeof EventAttributes; EventAttributes.bInheritHandle = TRUE; Event = CreateEventW(&EventAttributes, TRUE, FALSE, 0); if (0 == Event) return FspNtStatusFromWin32(GetLastError()); StringCbPrintfW(CommandLine, sizeof CommandLine, L"\"%s\" %lx %lx", FileName, (ULONG)(UINT_PTR)Event, Timeout); memset(&StartupInfo, 0, sizeof StartupInfo); StartupInfo.cb = sizeof StartupInfo; // !!!: need hook if (!CreateProcessW(FileName, CommandLine, 0, 0, TRUE, 0, 0, 0, &StartupInfo, &ProcessInfo)) { Result = FspNtStatusFromWin32(GetLastError()); CloseHandle(Event); return Result; } WaitResult = WaitForSingleObject(Event, 3000); if (WaitResult == WAIT_FAILED) Result = FspNtStatusFromWin32(GetLastError()); else if (WaitResult == WAIT_TIMEOUT) Result = STATUS_UNSUCCESSFUL; else Result = STATUS_SUCCESS; CloseHandle(Event); CloseHandle(ProcessInfo.hThread); if (!NT_SUCCESS(Result)) CloseHandle(ProcessInfo.hProcess); else *PProcess = ProcessInfo.hProcess; return Result; }
static NTSTATUS ExtractHelperProgram(PWSTR FileName) { HANDLE Handle; ULONG BytesTransferred; NTSTATUS Result; Handle = CreateFileW(FileName, FILE_WRITE_DATA, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (INVALID_HANDLE_VALUE == Handle) return FspNtStatusFromWin32(GetLastError()); Result = WriteResource( Handle, 0, #if defined(_WIN64) L"winfsp-tests-helper-x64.exe", #elif defined(_WIN32) L"winfsp-tests-helper-x86.exe", #else #error #endif &BytesTransferred); CloseHandle(Handle); return Result; }
static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, UINT32 FileAttributes, UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime, FSP_FSCTL_FILE_INFO *FileInfo) { HANDLE Handle = HandleFromContext(FileContext); FILE_BASIC_INFO BasicInfo = { 0 }; if (INVALID_FILE_ATTRIBUTES == FileAttributes) FileAttributes = 0; else if (0 == FileAttributes) FileAttributes = FILE_ATTRIBUTE_NORMAL; BasicInfo.FileAttributes = FileAttributes; BasicInfo.CreationTime.QuadPart = CreationTime; BasicInfo.LastAccessTime.QuadPart = LastAccessTime; BasicInfo.LastWriteTime.QuadPart = LastWriteTime; //BasicInfo.ChangeTime = ChangeTime; if (!SetFileInformationByHandle(Handle, FileBasicInfo, &BasicInfo, sizeof BasicInfo)) return FspNtStatusFromWin32(GetLastError()); return GetFileInfoInternal(Handle, FileInfo); }
static NTSTATUS id_print_sid(const char *format, PSID Sid) { PWSTR Str = 0; PWSTR Name = 0; UINT32 Uid; NTSTATUS Result; if (!ConvertSidToStringSidW(Sid, &Str)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } Result = FspToolGetNameFromSid(Sid, &Name); if (!NT_SUCCESS(Result)) goto exit; Result = FspPosixMapSidToUid(Sid, &Uid); if (!NT_SUCCESS(Result)) goto exit; info(format, Str, Name, Uid); Result = STATUS_SUCCESS; exit: MemFree(Name); LocalFree(Str); return Result; }
static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR FullPath[FULLPATH_SIZE]; ULONG CreateFlags; PTFS_FILE_CONTEXT *FileContext; if (!ConcatPath(Ptfs, FileName, FullPath)) return STATUS_OBJECT_NAME_INVALID; FileContext = malloc(sizeof *FileContext); if (0 == FileContext) return STATUS_INSUFFICIENT_RESOURCES; memset(FileContext, 0, sizeof *FileContext); CreateFlags = FILE_FLAG_BACKUP_SEMANTICS; if (CreateOptions & FILE_DELETE_ON_CLOSE) CreateFlags |= FILE_FLAG_DELETE_ON_CLOSE; FileContext->Handle = CreateFileW(FullPath, GrantedAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, CreateFlags, 0); if (INVALID_HANDLE_VALUE == FileContext->Handle) { free(FileContext); return FspNtStatusFromWin32(GetLastError()); } *PFileContext = FileContext; return GetFileInfoInternal(FileContext->Handle, FileInfo); }
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult) { NTSTATUS Result; PSID Sid; DWORD Size; Size = SECURITY_MAX_SID_SIZE; Sid = MemAlloc(Size); if (0 == Sid) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } if (!CreateWellKnownSid(WellKnownSidType, 0, Sid, &Size)) { Result = FspNtStatusFromWin32(GetLastError()); MemFree(Sid); Sid = 0; goto exit; } Result = STATUS_SUCCESS; exit: if (0 != PResult) *PResult = Result; return Sid; }
static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR FullPath[FULLPATH_SIZE]; SECURITY_ATTRIBUTES SecurityAttributes; ULONG CreateFlags; PTFS_FILE_CONTEXT *FileContext; if (!ConcatPath(Ptfs, FileName, FullPath)) return STATUS_OBJECT_NAME_INVALID; FileContext = malloc(sizeof *FileContext); if (0 == FileContext) return STATUS_INSUFFICIENT_RESOURCES; memset(FileContext, 0, sizeof *FileContext); SecurityAttributes.nLength = sizeof SecurityAttributes; SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor; SecurityAttributes.bInheritHandle = FALSE; CreateFlags = FILE_FLAG_BACKUP_SEMANTICS; if (CreateOptions & FILE_DELETE_ON_CLOSE) CreateFlags |= FILE_FLAG_DELETE_ON_CLOSE; if (CreateOptions & FILE_DIRECTORY_FILE) { /* * It is not widely known but CreateFileW can be used to create directories! * It requires the specification of both FILE_FLAG_BACKUP_SEMANTICS and * FILE_FLAG_POSIX_SEMANTICS. It also requires that FileAttributes has * FILE_ATTRIBUTE_DIRECTORY set. */ CreateFlags |= FILE_FLAG_POSIX_SEMANTICS; FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; } else FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; if (0 == FileAttributes) FileAttributes = FILE_ATTRIBUTE_NORMAL; FileContext->Handle = CreateFileW(FullPath, GrantedAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SecurityAttributes, CREATE_NEW, CreateFlags | FileAttributes, 0); if (INVALID_HANDLE_VALUE == FileContext->Handle) { free(FileContext); return FspNtStatusFromWin32(GetLastError()); } *PFileContext = FileContext; return GetFileInfoInternal(FileContext->Handle, FileInfo); }
static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_VOLUME_INFO *VolumeInfo) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR Root[MAX_PATH]; ULARGE_INTEGER TotalSize, FreeSize; if (!GetVolumePathName(Ptfs->Path, Root, MAX_PATH)) return FspNtStatusFromWin32(GetLastError()); if (!GetDiskFreeSpaceEx(Root, 0, &TotalSize, &FreeSize)) return FspNtStatusFromWin32(GetLastError()); VolumeInfo->TotalSize = TotalSize.QuadPart; VolumeInfo->FreeSize = FreeSize.QuadPart; return STATUS_SUCCESS; }
static NTSTATUS CreateTestProcess(PWSTR GlobalRoot, PWSTR Prefix, PHANDLE PProcess) { WCHAR Executable[MAX_PATH]; WCHAR CommandLine[1024]; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; HANDLE Event; DWORD WaitResult, ExitCode = -1, MaxTries = 5; *PProcess = 0; GetModuleFileName(0, Executable, MAX_PATH); wsprintfW(CommandLine, L"%s --run-test=%s%s", GetCommandLineW(), GlobalRoot, Prefix); Event = CreateEventW(0, TRUE, FALSE, L"" FSCRASH_EVENT_NAME); if (0 == Event) return FspNtStatusFromWin32(GetLastError()); memset(&StartupInfo, 0, sizeof StartupInfo); memset(&ProcessInfo, 0, sizeof ProcessInfo); StartupInfo.cb = sizeof StartupInfo; if (!CreateProcessW(Executable, CommandLine, 0, 0, FALSE, 0, 0, 0, &StartupInfo, &ProcessInfo)) return FspNtStatusFromWin32(GetLastError()); CloseHandle(ProcessInfo.hThread); do { WaitResult = WaitForSingleObject(Event, 1000); GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode); } while (WAIT_TIMEOUT == WaitResult && 0 != --MaxTries && STILL_ACTIVE == ExitCode); if (WAIT_OBJECT_0 != WaitResult) { CloseHandle(ProcessInfo.hProcess); return STATUS_UNSUCCESSFUL; } *PProcess = ProcessInfo.hProcess; return STATUS_SUCCESS; }
static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor) { HANDLE Handle = HandleFromContext(FileContext); if (!SetKernelObjectSecurity(Handle, SecurityInformation, ModificationDescriptor)) return FspNtStatusFromWin32(GetLastError()); return STATUS_SUCCESS; }
NTSTATUS FspToolGetTokenInfo(HANDLE Token, TOKEN_INFORMATION_CLASS TokenInformationClass, PVOID *PInfo) { PVOID Info = 0; DWORD Size; NTSTATUS Result; if (GetTokenInformation(Token, TokenInformationClass, 0, 0, &Size)) { Result = STATUS_INVALID_PARAMETER; goto exit; } if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } Info = MemAlloc(Size); if (0 == Info) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } if (!GetTokenInformation(Token, TokenInformationClass, Info, Size, &Size)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } *PInfo = Info; Result = STATUS_SUCCESS; exit: if (!NT_SUCCESS(Result)) MemFree(Info); return Result; }
static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, FSP_FSCTL_FILE_INFO *FileInfo) { HANDLE Handle = HandleFromContext(FileContext); FILE_BASIC_INFO BasicInfo = { 0 }; FILE_ALLOCATION_INFO AllocationInfo = { 0 }; FILE_ATTRIBUTE_TAG_INFO AttributeTagInfo; if (ReplaceFileAttributes) { if (0 == FileAttributes) FileAttributes = FILE_ATTRIBUTE_NORMAL; BasicInfo.FileAttributes = FileAttributes; if (!SetFileInformationByHandle(Handle, FileBasicInfo, &BasicInfo, sizeof BasicInfo)) return FspNtStatusFromWin32(GetLastError()); } else if (0 != FileAttributes) { if (!GetFileInformationByHandleEx(Handle, FileAttributeTagInfo, &AttributeTagInfo, sizeof AttributeTagInfo)) return FspNtStatusFromWin32(GetLastError()); BasicInfo.FileAttributes = FileAttributes | AttributeTagInfo.FileAttributes; if (BasicInfo.FileAttributes ^ FileAttributes) { if (!SetFileInformationByHandle(Handle, FileBasicInfo, &BasicInfo, sizeof BasicInfo)) return FspNtStatusFromWin32(GetLastError()); } } if (!SetFileInformationByHandle(Handle, FileAllocationInfo, &AllocationInfo, sizeof AllocationInfo)) return FspNtStatusFromWin32(GetLastError()); return GetFileInfoInternal(Handle, FileInfo); }
static NTSTATUS id_sid(PWSTR SidStr) { PSID Sid = 0; if (!ConvertStringSidToSid(SidStr, &Sid)) return FspNtStatusFromWin32(GetLastError()); id_print_sid("%S(%S) (uid=%u)", Sid); LocalFree(Sid); return STATUS_SUCCESS; }
static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, UINT64 NewSize, BOOLEAN SetAllocationSize, FSP_FSCTL_FILE_INFO *FileInfo) { HANDLE Handle = HandleFromContext(FileContext); FILE_ALLOCATION_INFO AllocationInfo; FILE_END_OF_FILE_INFO EndOfFileInfo; if (SetAllocationSize) { /* * This file system does not maintain AllocationSize, although NTFS clearly can. * However it must always be FileSize <= AllocationSize and NTFS will make sure * to truncate the FileSize if it sees an AllocationSize < FileSize. * * If OTOH a very large AllocationSize is passed, the call below will increase * the AllocationSize of the underlying file, although our file system does not * expose this fact. This AllocationSize is only temporary as NTFS will reset * the AllocationSize of the underlying file when it is closed. */ AllocationInfo.AllocationSize.QuadPart = NewSize; if (!SetFileInformationByHandle(Handle, FileAllocationInfo, &AllocationInfo, sizeof AllocationInfo)) return FspNtStatusFromWin32(GetLastError()); } else { EndOfFileInfo.EndOfFile.QuadPart = NewSize; if (!SetFileInformationByHandle(Handle, FileEndOfFileInfo, &EndOfFileInfo, sizeof EndOfFileInfo)) return FspNtStatusFromWin32(GetLastError()); } return GetFileInfoInternal(Handle, FileInfo); }
static NTSTATUS perm_sddl(PWSTR Sddl) { PSECURITY_DESCRIPTOR SecurityDescriptor = 0; if (!ConvertStringSecurityDescriptorToSecurityDescriptorW( Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0)) return FspNtStatusFromWin32(GetLastError()); perm_print_sd(SecurityDescriptor); LocalFree(SecurityDescriptor); return STATUS_SUCCESS; }
static NTSTATUS SetDelete(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile) { HANDLE Handle = HandleFromContext(FileContext); FILE_DISPOSITION_INFO DispositionInfo; DispositionInfo.DeleteFile = DeleteFile; if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &DispositionInfo, sizeof DispositionInfo)) return FspNtStatusFromWin32(GetLastError()); return STATUS_SUCCESS; }
static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length, PULONG PBytesTransferred) { HANDLE Handle = HandleFromContext(FileContext); OVERLAPPED Overlapped = { 0 }; Overlapped.Offset = (DWORD)Offset; Overlapped.OffsetHigh = (DWORD)(Offset >> 32); if (!ReadFile(Handle, Buffer, Length, PBytesTransferred, &Overlapped)) return FspNtStatusFromWin32(GetLastError()); return STATUS_SUCCESS; }
NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, FSP_FSCTL_FILE_INFO *FileInfo) { HANDLE Handle = HandleFromContext(FileContext); /* we do not flush the whole volume, so just return SUCCESS */ if (0 == Handle) return STATUS_SUCCESS; if (!FlushFileBuffers(Handle)) return FspNtStatusFromWin32(GetLastError()); return GetFileInfoInternal(Handle, FileInfo); }
static NTSTATUS WriteResource( HANDLE Handle, HANDLE Module, PWSTR ResourceName, PULONG PBytesTransferred) { HRSRC Resource; HGLOBAL ResourceGlob; PVOID ResourceData; DWORD ResourceSize; if ((Resource = FindResourceW(Module, ResourceName, RT_RCDATA)) && (ResourceGlob = LoadResource(Module, Resource)) && (ResourceData = LockResource(ResourceGlob)) && (ResourceSize = SizeofResource(Module, Resource)) && (WriteFile(Handle, ResourceData, ResourceSize, PBytesTransferred, 0))) return STATUS_SUCCESS; else return FspNtStatusFromWin32(GetLastError()); }
static NTSTATUS perm_path(PWSTR Path) { PSECURITY_DESCRIPTOR SecurityDescriptor = 0; int ErrorCode; ErrorCode = GetNamedSecurityInfoW(Path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 0, 0, 0, 0, &SecurityDescriptor); if (0 != ErrorCode) return FspNtStatusFromWin32(ErrorCode); perm_print_sd(SecurityDescriptor); LocalFree(SecurityDescriptor); return STATUS_SUCCESS; }
static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR FullPath[FULLPATH_SIZE], NewFullPath[FULLPATH_SIZE]; if (!ConcatPath(Ptfs, FileName, FullPath)) return STATUS_OBJECT_NAME_INVALID; if (!ConcatPath(Ptfs, NewFileName, NewFullPath)) return STATUS_OBJECT_NAME_INVALID; if (!MoveFileExW(FullPath, NewFullPath, ReplaceIfExists ? MOVEFILE_REPLACE_EXISTING : 0)) return FspNtStatusFromWin32(GetLastError()); return STATUS_SUCCESS; }
static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) { HANDLE Handle = HandleFromContext(FileContext); DWORD SecurityDescriptorSizeNeeded; if (!GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, SecurityDescriptor, (DWORD)*PSecurityDescriptorSize, &SecurityDescriptorSizeNeeded)) { *PSecurityDescriptorSize = SecurityDescriptorSizeNeeded; return FspNtStatusFromWin32(GetLastError()); } *PSecurityDescriptorSize = SecurityDescriptorSizeNeeded; return STATUS_SUCCESS; }
static NTSTATUS id_user(void) { HANDLE Token = 0; TOKEN_USER *Uinfo = 0; TOKEN_OWNER *Oinfo = 0; TOKEN_PRIMARY_GROUP *Ginfo = 0; NTSTATUS Result; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } Result = FspToolGetTokenInfo(Token, TokenUser, &Uinfo); if (!NT_SUCCESS(Result)) goto exit; Result = FspToolGetTokenInfo(Token, TokenOwner, &Oinfo); if (!NT_SUCCESS(Result)) goto exit; Result = FspToolGetTokenInfo(Token, TokenPrimaryGroup, &Ginfo); if (!NT_SUCCESS(Result)) goto exit; id_print_sid("User=%S(%S) (uid=%u)", Uinfo->User.Sid); id_print_sid("Owner=%S(%S) (uid=%u)", Oinfo->Owner); id_print_sid("Group=%S(%S) (gid=%u)", Ginfo->PrimaryGroup); Result = STATUS_SUCCESS; exit: MemFree(Ginfo); MemFree(Oinfo); MemFree(Uinfo); if (0 != Token) CloseHandle(Token); return Result; }
static NTSTATUS GetFileInfoInternal(HANDLE Handle, FSP_FSCTL_FILE_INFO *FileInfo) { BY_HANDLE_FILE_INFORMATION ByHandleFileInfo; if (!GetFileInformationByHandle(Handle, &ByHandleFileInfo)) return FspNtStatusFromWin32(GetLastError()); FileInfo->FileAttributes = ByHandleFileInfo.dwFileAttributes; FileInfo->ReparseTag = 0; FileInfo->FileSize = ((UINT64)ByHandleFileInfo.nFileSizeHigh << 32) | (UINT64)ByHandleFileInfo.nFileSizeLow; FileInfo->AllocationSize = (FileInfo->FileSize + ALLOCATION_UNIT - 1) / ALLOCATION_UNIT * ALLOCATION_UNIT; FileInfo->CreationTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftCreationTime)->QuadPart; FileInfo->LastAccessTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftLastAccessTime)->QuadPart; FileInfo->LastWriteTime = ((PLARGE_INTEGER)&ByHandleFileInfo.ftLastWriteTime)->QuadPart; FileInfo->ChangeTime = FileInfo->LastWriteTime; FileInfo->IndexNumber = 0; FileInfo->HardLinks = 0; return STATUS_SUCCESS; }
static NTSTATUS perm_print_sd(PSECURITY_DESCRIPTOR SecurityDescriptor) { UINT32 Uid, Gid, Mode; PWSTR Sddl = 0; NTSTATUS Result; Result = FspPosixMapSecurityDescriptorToPermissions(SecurityDescriptor, &Uid, &Gid, &Mode); if (!NT_SUCCESS(Result)) return Result; if (!ConvertSecurityDescriptorToStringSecurityDescriptorW( SecurityDescriptor, SDDL_REVISION_1, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &Sddl, 0)) return FspNtStatusFromWin32(GetLastError()); info("%S (perm=%u:%u:%d%d%d%d)", Sddl, Uid, Gid, (Mode >> 9) & 7, (Mode >> 6) & 7, (Mode >> 3) & 7, Mode & 7); LocalFree(Sddl); return STATUS_SUCCESS; }
NTSTATUS FspNpRegister(VOID) { extern HINSTANCE DllInstance; WCHAR ProviderPath[MAX_PATH]; WCHAR RegBuffer[1024]; PWSTR P, Part; DWORD RegResult, RegType, RegBufferSize; HKEY RegKey; BOOLEAN FoundProvider; if (0 == GetModuleFileNameW(DllInstance, ProviderPath, MAX_PATH)) return FspNtStatusFromWin32(GetLastError()); RegResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME, 0, 0, 0, KEY_ALL_ACCESS, 0, &RegKey, 0); if (ERROR_SUCCESS != RegResult) return FspNtStatusFromWin32(RegResult); RegResult = RegSetValueExW(RegKey, L"Group", 0, REG_SZ, (PVOID) L"NetworkProvider", sizeof L"NetworkProvider"); if (ERROR_SUCCESS != RegResult) goto close_and_exit; RegCloseKey(RegKey); RegResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME "\\NetworkProvider", 0, 0, 0, KEY_ALL_ACCESS, 0, &RegKey, 0); if (ERROR_SUCCESS != RegResult) return FspNtStatusFromWin32(RegResult); RegResult = ERROR_RESOURCE_NAME_NOT_FOUND; /* not a real resource error! */ { PVOID VersionInfo = 0; DWORD Size; PWSTR Description; Size = GetFileVersionInfoSizeW(ProviderPath, &Size/*dummy*/); if (0 < Size) { VersionInfo = MemAlloc(Size); if (0 != VersionInfo && GetFileVersionInfoW(ProviderPath, 0, Size, VersionInfo) && VerQueryValueW(VersionInfo, L"\\StringFileInfo\\040904b0\\FileDescription", &Description, &Size)) { Size = Size * 2 + sizeof(WCHAR); RegResult = RegSetValueExW(RegKey, L"Name", 0, REG_SZ, (PVOID)Description, Size); } MemFree(VersionInfo); } } if (ERROR_SUCCESS != RegResult) goto close_and_exit; RegResult = RegSetValueExW(RegKey, L"ProviderPath", 0, REG_SZ, (PVOID)ProviderPath, (lstrlenW(ProviderPath) + 1) * sizeof(WCHAR)); if (ERROR_SUCCESS != RegResult) goto close_and_exit; RegCloseKey(RegKey); RegResult = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order", 0, KEY_ALL_ACCESS, &RegKey); if (ERROR_SUCCESS != RegResult) return FspNtStatusFromWin32(RegResult); RegBufferSize = sizeof RegBuffer - sizeof L"," FSP_NP_NAME; RegResult = RegQueryValueExW(RegKey, L"ProviderOrder", 0, &RegType, (PVOID)RegBuffer, &RegBufferSize); if (ERROR_SUCCESS != RegResult) goto close_and_exit; RegBufferSize /= sizeof(WCHAR); FoundProvider = FALSE; RegBuffer[RegBufferSize] = L'\0'; P = RegBuffer, Part = P; do { if (L',' == *P || '\0' == *P) { if (CSTR_EQUAL == CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, Part, (int)(P - Part), L"" FSP_NP_NAME, (int)(sizeof L"" FSP_NP_NAME - sizeof(WCHAR)) / sizeof(WCHAR))) { FoundProvider = TRUE; break; } else Part = P + 1; } } while (L'\0' != *P++); if (!FoundProvider) { P--; memcpy(P, L"," FSP_NP_NAME, sizeof L"," FSP_NP_NAME); RegBufferSize = lstrlenW(RegBuffer); RegBufferSize++; RegResult = RegSetValueExW(RegKey, L"ProviderOrder", 0, REG_SZ, (PVOID)RegBuffer, RegBufferSize * sizeof(WCHAR)); if (ERROR_SUCCESS != RegResult) goto close_and_exit; } RegCloseKey(RegKey); return STATUS_SUCCESS; close_and_exit: RegCloseKey(RegKey); return FspNtStatusFromWin32(RegResult); }