237 lines
8.2 KiB
C#
237 lines
8.2 KiB
C#
|
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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|