static NTSTATUS DOKAN_CALLBACK FuseSetAllocationSize( LPCWSTR FileName, LONGLONG ByteOffset, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FPRINTF(stderr, "SetAllocationSize: %ls, %lld\n", FileName, ByteOffset); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); BY_HANDLE_FILE_INFORMATION byHandleFileInfo; ZeroMemory(&byHandleFileInfo, sizeof(BY_HANDLE_FILE_INFORMATION)); NTSTATUS ret = errno_to_ntstatus_error( impl->get_file_information(FileName, &byHandleFileInfo, DokanFileInfo)); LARGE_INTEGER fileSize; fileSize.LowPart = byHandleFileInfo.nFileSizeLow; fileSize.HighPart = byHandleFileInfo.nFileSizeHigh; if (ret != 0) { return ret; } else if (ByteOffset < fileSize.QuadPart) { /* https://msdn.microsoft.com/en-us/library/windows/hardware/ff540232(v=vs.85).aspx * The end-of-file position must always be less than or equal to the * allocation size. If the allocation size is set to a value that is * less than the end - of - file position, the end - of - file position * is automatically adjusted to match the allocation size.*/ return errno_to_ntstatus_error( impl->set_end_of_file(FileName, ByteOffset, DokanFileInfo)); } else { return 0; } }
static NTSTATUS DOKAN_CALLBACK FuseUnmount(PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl=the_impl; if (impl->debug()) FWPRINTF(stderr, L"Unmount\n"); impl_chain_guard guard(impl,DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->unmount(DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseDeleteFile(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"DeleteFile %s\n", FileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->delete_file(FileName, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseFlushFileBuffers(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FPRINTF(stderr, "FlushFileBuffers: %ls\n", FileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error( impl->flush_file_buffers(FileName, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseSetEndOfFile( LPCWSTR FileName, LONGLONG ByteOffset, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"SetEndOfFile %s, %I64d\n", FileName, ByteOffset); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error( impl->set_end_of_file(FileName, ByteOffset, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseSetFileAttributes( LPCWSTR FileName, DWORD FileAttributes, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"SetFileAttributes %s\n", FileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error( impl->set_file_attributes(FileName, FileAttributes, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseGetDiskFreeSpace(PULONGLONG FreeBytesAvailable, PULONGLONG TotalNumberOfBytes, PULONGLONG TotalNumberOfFreeBytes, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl=the_impl; if (impl->debug()) FWPRINTF(stderr, L"GetDiskFreeSpace\n"); impl_chain_guard guard(impl,DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->get_disk_free_space(FreeBytesAvailable,TotalNumberOfBytes, TotalNumberOfFreeBytes, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseGetFileInformation( LPCWSTR FileName, LPBY_HANDLE_FILE_INFORMATION HandleFileInformation, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"GetFileInfo : %s\n", FileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->get_file_information( FileName, HandleFileInformation, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseUnlockFile(LPCWSTR FileName, LONGLONG ByteOffset, LONGLONG Length, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"UnlockFile %s\n", FileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error( impl->unlock_file(FileName, ByteOffset, Length, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseFindFiles( LPCWSTR FileName, PFillFindData FillFindData, // function pointer PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl=the_impl; if (impl->debug()) FWPRINTF(stderr, L"FindFiles :%s\n", FileName); impl_chain_guard guard(impl,DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->find_files(FileName,FillFindData, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseMoveFile(LPCWSTR FileName, // existing file name LPCWSTR NewFileName, BOOL ReplaceIfExisting, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"MoveFile %s -> %s\n\n", FileName, NewFileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error( impl->move_file(FileName, NewFileName, ReplaceIfExisting, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseSetFileTime(LPCWSTR FileName, CONST FILETIME *CreationTime, CONST FILETIME *LastAccessTime, CONST FILETIME *LastWriteTime, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"SetFileTime %s\n", FileName); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->set_file_time( FileName, CreationTime, LastAccessTime, LastWriteTime, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseReadFile(LPCWSTR FileName, LPVOID Buffer, DWORD BufferLength, LPDWORD ReadLength, LONGLONG Offset, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"ReadFile : %s from %I64d len %u\n", FileName, (__int64)Offset, (unsigned)BufferLength); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error(impl->read_file( FileName, Buffer, BufferLength, ReadLength, Offset, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseCreateFile( LPCWSTR FileName, PDOKAN_IO_SECURITY_CONTEXT SecurityContext, ACCESS_MASK DesiredAccess, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) { FWPRINTF(stderr, L"CreateFile : %s\n", FileName); DebugConstantBit("\tDesiredAccess", DesiredAccess, cAccessMode); DebugConstantBit("\tShareAccess", ShareAccess, cShareMode); DebugConstant("\tDisposition", CreateDisposition, cDisposition); FWPRINTF(stderr, L"\tAttributes: %u (0x%x)\n", FileAttributes, FileAttributes); FWPRINTF(stderr, L"\tOptions: %u (0x%x)\n", CreateOptions, CreateOptions); fflush(stderr); } impl_chain_guard guard(impl,DokanFileInfo->ProcessId); if((CreateOptions & FILE_DIRECTORY_FILE) == FILE_DIRECTORY_FILE) { if(CreateDisposition == FILE_CREATE || CreateDisposition == FILE_OPEN_IF) { return errno_to_ntstatus_error(impl->create_directory(FileName, DokanFileInfo)); } else if(CreateDisposition == FILE_OPEN) { return errno_to_ntstatus_error(impl->open_directory(FileName, DokanFileInfo)); } } return -win_error(impl->create_file(FileName, CreateDisposition, ShareAccess, DesiredAccess, FileAttributes, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK FuseWriteFile(LPCWSTR FileName, LPCVOID Buffer, DWORD NumberOfBytesToWrite, LPDWORD NumberOfBytesWritten, LONGLONG Offset, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"WriteFile : %s, offset %I64d, length %lu\n", FileName, Offset, NumberOfBytesToWrite); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); return errno_to_ntstatus_error( impl->write_file(FileName, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten, Offset, DokanFileInfo)); }
static NTSTATUS DOKAN_CALLBACK GetVolumeInformation(LPWSTR VolumeNameBuffer, DWORD VolumeNameSize, LPDWORD VolumeSerialNumber, LPDWORD MaximumComponentLength, LPDWORD FileSystemFlags, LPWSTR FileSystemNameBuffer, DWORD FileSystemNameSize, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FWPRINTF(stderr, L"GetVolumeInformation\n"); impl_chain_guard guard(impl, DokanFileInfo->ProcessId); *VolumeSerialNumber = 0; *MaximumComponentLength = 255; return errno_to_ntstatus_error(impl->get_volume_information( VolumeNameBuffer, VolumeNameSize, FileSystemNameBuffer, FileSystemNameSize, DokanFileInfo, FileSystemFlags)); }
static NTSTATUS DOKAN_CALLBACK FuseGetFileSecurity(LPCWSTR FileName, PSECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG BufferLength, PULONG LengthNeeded, PDOKAN_FILE_INFO DokanFileInfo) { impl_fuse_context *impl = the_impl; if (impl->debug()) FPRINTF(stderr, "GetFileSecurity: " PRIxDWORD "\n", *SecurityInformation); BY_HANDLE_FILE_INFORMATION byHandleFileInfo; ZeroMemory(&byHandleFileInfo, sizeof(BY_HANDLE_FILE_INFORMATION)); int ret; { impl_chain_guard guard(impl, DokanFileInfo->ProcessId); ret = impl->get_file_information(FileName, &byHandleFileInfo, DokanFileInfo); } if (0 != ret) { return errno_to_ntstatus_error(ret); } if (byHandleFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // We handle directories for the Explorer's // context menu. (New Folder, ...) // Authenticated users rights PSECURITY_DESCRIPTOR SecurityDescriptorTmp = nullptr; ULONG Size = 0; if (!ConvertStringSecurityDescriptorToSecurityDescriptor( "D:PAI(A;OICI;FA;;;AU)", SDDL_REVISION_1, &SecurityDescriptorTmp, &Size)) { return STATUS_NOT_IMPLEMENTED; } LPTSTR pStringBuffer = nullptr; if (!ConvertSecurityDescriptorToStringSecurityDescriptor( SecurityDescriptorTmp, SDDL_REVISION_1, *SecurityInformation, &pStringBuffer, nullptr)) { return STATUS_NOT_IMPLEMENTED; } LocalFree(SecurityDescriptorTmp); SecurityDescriptorTmp = nullptr; Size = 0; if (!ConvertStringSecurityDescriptorToSecurityDescriptor( pStringBuffer, SDDL_REVISION_1, &SecurityDescriptorTmp, &Size)) { return STATUS_NOT_IMPLEMENTED; } if (Size > BufferLength) { *LengthNeeded = Size; return STATUS_BUFFER_OVERFLOW; } memcpy(SecurityDescriptor, SecurityDescriptorTmp, Size); *LengthNeeded = Size; if (pStringBuffer != nullptr) LocalFree(pStringBuffer); if (SecurityDescriptorTmp != nullptr) LocalFree(SecurityDescriptorTmp); return STATUS_SUCCESS; } return STATUS_NOT_IMPLEMENTED; }