codice:
#region Win32 IO Enumerations
[Flags]
public enum FileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}
[Flags]
public enum FileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004,
}
public enum CreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
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,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}
#endregion
/// <summary>
/// Descrizione di riepilogo per IOWin32Helper.
/// </summary>
public class IOWin32Helper
{
#region Win32 IO DllImport
[DllImport("kernel32", SetLastError = true)]
static extern unsafe System.IntPtr CreateFile
(
string FileName, // file name
FileAccess DesiredAccess, // access mode
FileShare ShareMode, // share mode
IntPtr SecurityAttributes, // Security Attributes
CreationDisposition CreationDisposition, // how to create
FileAttributes FlagsAndAttributes, // file attributes
IntPtr hTemplateFile // handle to template file
);
[DllImport("kernel32", SetLastError = true)]
static extern unsafe bool ReadFile
(
IntPtr hObject, // handle to file
void* pBuffer, // data buffer
int NumberOfBytesToRead, // number of bytes to read
int* pNumberOfBytesRead, // number of bytes read
int Overlapped // overlapped buffer
);
[DllImport("kernel32", SetLastError = true)]
static extern unsafe bool WriteFile
(
IntPtr hObject, // handle to file
void* pBuffer, // data buffer
int NumberOfBytesToWrite, // number of bytes to write
int* pNumberOfBytesWritten, // number of bytes written
int Overlapped // overlapped buffer
);
[DllImport("kernel32", SetLastError = true)]
static extern unsafe bool CloseHandle
(
IntPtr hObject // handle to object
);
#endregion
public static unsafe IntPtr Create(string FileName, FileAccess FileAccess, FileShare FileShare, CreationDisposition CreationDisposition, FileAttributes FileAttributes)
{
// Apre il file in base ai parametri richiesti
IntPtr handle = IOWin32Helper.CreateFile(FileName, FileAccess, FileShare, IntPtr.Zero, CreationDisposition, FileAttributes, IntPtr.Zero);
// Verifica se l'operazione è riuscita
if (handle == IntPtr.Zero)
{
// Lancia un'eccezione
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
// Restituisce il puntatore
return handle;
}
public static unsafe int Read(IntPtr hObject, byte[] Buffer, int Index, int Count)
{
// Bytes letti
int readBytes = 0;
// Acquisisce il puntatore del buffer
fixed (byte* pBuffer = Buffer)
{
// Legge id ati
if (ReadFile(hObject, pBuffer + Index, Count, &readBytes, 0) == false)
{
// Lancia un'eccezione dato che l'operazione è fallita
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
}
// Restituisce il numero di bytes letti
return readBytes;
}
public static unsafe int Write(IntPtr hObject, byte[] Buffer, int Index, int Count)
{
// Bytes letti
int writtenBytes = 0;
// Acquisisce il puntatore del buffer
fixed (byte* pBuffer = Buffer)
{
// Scrive i dati
if (WriteFile(hObject, pBuffer + Index, Count, &writtenBytes, 0) == false)
{
// Lancia un'eccezione dato che l'operazione è fallita
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
}
// Restituisce il numero di bytes letti
return writtenBytes;
}
public static unsafe bool Close(IntPtr hObject)
{
// Chiude l'handle
return CloseHandle(hObject);
}
}
Buona parte del codice postato sono dichiarazioni varie. Il codice vero e proprio è verso la fine e per la precisione, al momento, sono 4 metodi che si riferiscono a 4 API. A breve ne aggiungerò altre per spostare il puntatore, altrimenti non si ci può spostare, ad esempio, a inizio partizione o altro ... in pratica va implementato il Seek