SWP/List/FileSystemApi/FileSystem.cs

237 lines
8.2 KiB
C#
Raw Normal View History

2017-03-09 22:08:25 +01:00
using System;
using System.Net;
using System.Runtime.InteropServices;
using Microsoft.Phone.InteropServices;
namespace FileSystemApi
{
[Flags]
public enum FileAccess : uint
{
/// <summary>
/// Read file access
/// </summary>
Read = 0x80000000,
/// <summary>
/// Write file acecss
/// </summary>
Write = 0x40000000,
/// <summary>
/// Execute file access
/// </summary>
Execute = 0x20000000,
/// <summary>
///
/// </summary>
All = 0x10000000
}
[Flags]
public enum FileShare : uint
{
/// <summary>
///
/// </summary>
None = 0x00000000,
/// <summary>
/// Enables subsequent open operations on an object to request read access.
/// Otherwise, other processes cannot open the object if they request read access.
/// If this flag is not specified, but the object has been opened for read access, the function fails.
/// </summary>
Read = 0x00000001,
/// <summary>
/// Enables subsequent open operations on an object to request write access.
/// Otherwise, other processes cannot open the object if they request write access.
/// If this flag is not specified, but the object has been opened for write access, the function fails.
/// </summary>
Write = 0x00000002,
/// <summary>
/// Enables subsequent open operations on an object to request delete access.
/// Otherwise, other processes cannot open the object if they request delete access.
/// If this flag is not specified, but the object has been opened for delete access, the function fails.
/// </summary>
Delete = 0x00000004
}
public enum CreationDisposition : uint
{
/// <summary>
/// Creates a new file. The function fails if a specified file exists.
/// </summary>
New = 1,
/// <summary>
/// Creates a new file, always.
/// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
/// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
/// </summary>
CreateAlways = 2,
/// <summary>
/// Opens a file. The function fails if the file does not exist.
/// </summary>
OpenExisting = 3,
/// <summary>
/// Opens a file, always.
/// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
/// </summary>
OpenAlways = 4,
/// <summary>
/// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
/// The calling process must open the file with the GENERIC_WRITE access right.
/// </summary>
TruncateExisting = 5
}
[Flags]
public enum FileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline = 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
WriteThrough = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}
internal enum MoveMethod : uint
{
Begin = 0,
Current = 1,
End = 2
}
[StructLayout(LayoutKind.Explicit, Size = 8)]
internal struct LARGE_INTEGER
{
[FieldOffset(0)]
public Int64 QuadPart;
[FieldOffset(0)]
public Int32 LowPart;
[FieldOffset(4)]
public Int32 HighPart;
}
internal static class FileSystem
{
private static IFileSystemIO m_fileSystemIo;
private const int INVALID_FILE_SIZE = unchecked((int) 0xffffffff);
private const int INVALID_SET_FILE_POINTER = -1;
private const int ERROR_ACCESS_DENIED = unchecked((int)0x80000005);
static FileSystem()
{
ComBridge.RegisterComDll("FileSystem.dll", new Guid("F0D5AFD8-DA24-4e85-9335-BEBCADE5B92A"));
m_fileSystemIo = new FileSystemClass() as IFileSystemIO;
}
public static int OpenFile(string lpFilename, FileAccess dwDesiredAccess, FileShare dwShareMode, CreationDisposition dwCreationDisposition, FileAttributes dwFlagsAndAttributes, out IntPtr hFile)
{
int ret = m_fileSystemIo.OpenFile(lpFilename, (int)dwDesiredAccess, (int)dwShareMode, (int)dwCreationDisposition, (int)dwFlagsAndAttributes, out hFile);
return ret;
}
public static int ReadFile(IntPtr hfile, byte[] buffer, int nNumberOfBytesToRead, int offset, out int lpNumberOfBytesRead)
{
var bufferHandle = Microsoft.Phone.InteropServices.GCHandle.Alloc(buffer, GCHandleType.Pinned);
int ret = m_fileSystemIo.ReadFile(hfile, new IntPtr(bufferHandle.AddrOfPinnedObject().ToInt32() + offset),
nNumberOfBytesToRead,
out lpNumberOfBytesRead);
bufferHandle.Free();
if (ret == 0)
{
int err = Microsoft.Phone.InteropServices.Marshal.GetLastWin32Error();
if (err == ERROR_ACCESS_DENIED)
{
throw new UnauthorizedAccessException("Access denied");
}
}
return ret;
}
public static int CloseFile(IntPtr hFile)
{
return m_fileSystemIo.CloseFile(hFile);
}
public static int SeekFile(IntPtr hFile, long lDistanceToMove, MoveMethod dwMoveMethod)
{
var li = new LARGE_INTEGER();
li.QuadPart = lDistanceToMove;
var ret = m_fileSystemIo.SeekFile(hFile, li.LowPart, ref li.HighPart, (int) dwMoveMethod);
if(ret == INVALID_SET_FILE_POINTER)
throw new Exception("Invalid seek");
return ret;
}
public static long GetFileSize(IntPtr hFile)
{
var li = new LARGE_INTEGER();
li.LowPart = m_fileSystemIo.GetFileSize(hFile, out li.HighPart);
if(li.LowPart == INVALID_FILE_SIZE)
throw new Exception("Invalid file size");
return li.QuadPart;
}
public static int CopyFile(string sourceFilename, string destinationFilename, bool failIfExists)
{
int ret = m_fileSystemIo.CopyFile(sourceFilename, destinationFilename, failIfExists);
if (ret == 0)
{
int err = Microsoft.Phone.InteropServices.Marshal.GetLastWin32Error();
if (err == ERROR_ACCESS_DENIED)
{
throw new UnauthorizedAccessException("Access denied");
}
}
return ret;
}
public static int FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData, out IntPtr hFind)
{
return m_fileSystemIo.FindFirstFile(lpFileName, out lpFindFileData, out hFind);
}
public static int FindNextFile(IntPtr hFind, out WIN32_FIND_DATA lpFindFileData)
{
return m_fileSystemIo.FindNextFile(hFind, out lpFindFileData);
}
public static int FindClose(IntPtr hFind)
{
return m_fileSystemIo.FindClose(hFind);
}
}
}