private void Init(FileMode mode, FileShare share)
{
// Disallow access to all non-file devices from the Win32FileStream
// constructors that take a String. Everyone else can call
// CreateFile themselves then use the constructor that takes an
// IntPtr. Disallows "con:", "com1:", "lpt1:", etc.
int fileType = Interop.Kernel32.GetFileType(_fileHandle);
if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
{
_fileHandle.Dispose();
throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
}
// This is necessary for async IO using IO Completion ports via our
// managed Threadpool API's. This (theoretically) calls the OS's
// BindIoCompletionCallback method, and passes in a stub for the
// LPOVERLAPPED_COMPLETION_ROUTINE. This stub looks at the Overlapped
// struct for this request and gets a delegate to a managed callback
// from there, which it then calls on a threadpool thread. (We allocate
// our native OVERLAPPED structs 2 pointers too large and store EE state
// & GC handles there, one to an IAsyncResult, the other to a delegate.)
if (_useAsyncIO)
{
try
{
_fileHandle.ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(_fileHandle);
}
catch (ArgumentException ex)
{
throw new IOException(SR.IO_BindHandleFailed, ex);
}
finally
{
if (_fileHandle.ThreadPoolBinding == null)
{
// We should close the handle so that the handle is not open until SafeFileHandle GC
Debug.Assert(!_exposedHandle, "Are we closing handle that we exposed/not own, how?");
_fileHandle.Dispose();
}
}
}
_canSeek = true;
// For Append mode...
if (mode == FileMode.Append)
{
_appendStart = SeekCore(0, SeekOrigin.End);
}
else
{
_appendStart = -1;
}
}