Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / IO / __ConsoleStream.cs / 1 / __ConsoleStream.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: ConsoleStream
**
**
** Purpose: Exposes a separate Stream for Console IO and
** handles WinCE appropriately. Also keeps us from using the
** ThreadPool for all Console output.
**
**
===========================================================*/
using System;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
namespace System.IO {
internal sealed class __ConsoleStream : Stream
{
internal const int DefaultBufferSize = 128;
// From winerror.h
private const int ERROR_BROKEN_PIPE = 109;
// ERROR_NO_DATA ("The pipe is being closed") is returned when we write to
// a console that is closing.
private const int ERROR_NO_DATA = 232;
private SafeFileHandle _handle;
private bool _canRead;
private bool _canWrite;
[ResourceExposure(ResourceScope.Process)]
internal __ConsoleStream(SafeFileHandle handle, FileAccess access)
{
BCLDebug.Assert(handle != null && !handle.IsInvalid, "__ConsoleStream expects a valid handle!");
_handle = handle;
_canRead = access == FileAccess.Read;
_canWrite = access == FileAccess.Write;
}
public override bool CanRead {
get { return _canRead; }
}
public override bool CanWrite {
get { return _canWrite; }
}
public override bool CanSeek {
get { return false; }
}
public override long Length {
get {
__Error.SeekNotSupported();
return 0; // compiler appeasement
}
}
public override long Position {
get {
__Error.SeekNotSupported();
return 0; // compiler appeasement
}
set {
__Error.SeekNotSupported();
}
}
protected override void Dispose(bool disposing)
{
// We're probably better off not closing the OS handle here. First,
// we allow a program to get multiple instances of __ConsoleStreams
// around the same OS handle, so closing one handle would invalidate
// them all. Additionally, we want a second AppDomain to be able to
// write to stdout if a second AppDomain quits.
if (_handle != null) {
_handle = null;
}
_canRead = false;
_canWrite = false;
base.Dispose(disposing);
}
public override void Flush()
{
if (_handle == null) __Error.FileNotOpen();
if (!CanWrite) __Error.WriteNotSupported();
}
public override void SetLength(long value)
{
__Error.SeekNotSupported();
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
public override int Read([In, Out] byte[] buffer, int offset, int count) {
if (buffer==null)
throw new ArgumentNullException("buffer");
if (offset < 0 || count < 0)
throw new ArgumentOutOfRangeException((offset < 0 ? "offset" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
if (!_canRead) __Error.ReadNotSupported();
int errorCode = 0;
int result = ReadFileNative(_handle, buffer, offset, count, 0, out errorCode);
if (result == -1) {
__Error.WinIOError(errorCode, String.Empty);
}
return result;
}
public override long Seek(long offset, SeekOrigin origin) {
__Error.SeekNotSupported();
return 0; // compiler appeasement
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
public override void Write(byte[] buffer, int offset, int count) {
if (buffer==null)
throw new ArgumentNullException("buffer");
if (offset < 0 || count < 0)
throw new ArgumentOutOfRangeException((offset < 0 ? "offset" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
if (!_canWrite) __Error.WriteNotSupported();
int errorCode = 0;
int result = WriteFileNative(_handle, buffer, offset, count, 0, out errorCode);
if (result == -1) {
//BCLDebug.ConsoleError("__ConsoleStream::Write: throwing on error. Error code: "+errorCode+" 0x"+errorCode.ToString("x")+" handle: "+_handle.ToString());
__Error.WinIOError(errorCode, String.Empty);
}
return;
}
// P/Invoke wrappers for writing to and from a file, nearly identical
// to the ones on FileStream. These are duplicated to save startup/hello
// world working set.
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private unsafe static int ReadFileNative(SafeFileHandle hFile, byte[] bytes, int offset, int count, int mustBeZero, out int errorCode)
{
BCLDebug.Assert(offset >= 0, "offset >= 0");
BCLDebug.Assert(count >= 0, "count >= 0");
BCLDebug.Assert(bytes != null, "bytes != null");
// Don't corrupt memory when multiple threads are erroneously writing
// to this stream simultaneously.
if (bytes.Length - offset < count)
throw new IndexOutOfRangeException(Environment.GetResourceString("IndexOutOfRange_IORaceCondition"));
// You can't use the fixed statement on an array of length 0.
if (bytes.Length==0) {
errorCode = 0;
return 0;
}
int r;
int numBytesRead;
fixed(byte* p = bytes) {
r = ReadFile(hFile, p + offset, count, out numBytesRead, Win32Native.NULL);
}
if (r==0) {
errorCode = Marshal.GetLastWin32Error();
if (errorCode == ERROR_BROKEN_PIPE) {
// A pipe into stdin was closed. Not an error, but EOF.
return 0;
}
return -1;
}
else
errorCode = 0;
return numBytesRead;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private static unsafe int WriteFileNative(SafeFileHandle hFile, byte[] bytes, int offset, int count, int mustBeZero, out int errorCode) {
BCLDebug.Assert(offset >= 0, "offset >= 0");
BCLDebug.Assert(count >= 0, "count >= 0");
BCLDebug.Assert(bytes != null, "bytes != null");
BCLDebug.Assert(bytes.Length >= offset + count, "bytes.Length >= offset + count");
// You can't use the fixed statement on an array of length 0.
if (bytes.Length==0) {
errorCode = 0;
return 0;
}
int numBytesWritten = 0;
int r;
fixed(byte* p = bytes) {
r = WriteFile(hFile, p + offset, count, out numBytesWritten, Win32Native.NULL);
}
if (r==0) {
errorCode = Marshal.GetLastWin32Error();
// For pipes that are closing or broken, just stop.
if (errorCode==ERROR_NO_DATA || errorCode==ERROR_BROKEN_PIPE)
return 0;
return -1;
}
else {
errorCode = 0;
}
return numBytesWritten;
}
// The P/Invoke declarations for ReadFile and WriteFile are here for a reason! This prevents us from loading several classes
// in the trivial hello world case.
[DllImport(Win32Native.KERNEL32, SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
[ResourceExposure(ResourceScope.Process)]
unsafe private static extern int ReadFile(SafeFileHandle handle, byte* bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero);
[DllImport(Win32Native.KERNEL32, SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
[ResourceExposure(ResourceScope.Process)]
internal static unsafe extern int WriteFile(SafeFileHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlUrlResolver.cs
- EmptyStringExpandableObjectConverter.cs
- BindingCollection.cs
- XmlComplianceUtil.cs
- RandomNumberGenerator.cs
- Profiler.cs
- CompositeDuplexBindingElement.cs
- DBPropSet.cs
- ObjectListCommandCollection.cs
- ListControlConvertEventArgs.cs
- Section.cs
- Component.cs
- NameValueCache.cs
- StreamReader.cs
- ComplexPropertyEntry.cs
- DBConnectionString.cs
- DataGridViewToolTip.cs
- InvokeProviderWrapper.cs
- TransactionTraceIdentifier.cs
- AudioStateChangedEventArgs.cs
- sqlpipe.cs
- AutoGeneratedFieldProperties.cs
- TextElementCollectionHelper.cs
- SafeProcessHandle.cs
- ScriptManagerProxy.cs
- SoapProcessingBehavior.cs
- PositiveTimeSpanValidator.cs
- CommandField.cs
- LostFocusEventManager.cs
- AllMembershipCondition.cs
- SpecularMaterial.cs
- TableRowGroupCollection.cs
- XmlBaseReader.cs
- UniformGrid.cs
- TileBrush.cs
- _ShellExpression.cs
- PartialTrustHelpers.cs
- WinFormsSpinner.cs
- ServiceHostingEnvironment.cs
- DPTypeDescriptorContext.cs
- XmlUTF8TextWriter.cs
- DataService.cs
- Dispatcher.cs
- BinaryObjectWriter.cs
- Itemizer.cs
- DocumentPage.cs
- UpDownBaseDesigner.cs
- Int64Animation.cs
- BamlStream.cs
- RemoteWebConfigurationHostStream.cs
- StatusBar.cs
- GenericWebPart.cs
- CharStorage.cs
- CompilerResults.cs
- RangeValueProviderWrapper.cs
- ObsoleteAttribute.cs
- QilPatternVisitor.cs
- DataGridTable.cs
- Point3DAnimationBase.cs
- Point3DConverter.cs
- TemplateXamlParser.cs
- FixedSOMTextRun.cs
- ResourceCategoryAttribute.cs
- ThousandthOfEmRealPoints.cs
- GenericIdentity.cs
- DocumentPageTextView.cs
- GifBitmapDecoder.cs
- DataService.cs
- HMAC.cs
- MarginsConverter.cs
- GradientSpreadMethodValidation.cs
- FixedPage.cs
- StopStoryboard.cs
- ApplicationManager.cs
- odbcmetadatacolumnnames.cs
- DataTemplateSelector.cs
- ObjectHelper.cs
- HandlerMappingMemo.cs
- BinaryObjectWriter.cs
- ExpressionValueEditor.cs
- _ChunkParse.cs
- AnchorEditor.cs
- JoinElimination.cs
- FlowDocumentPage.cs
- Double.cs
- COSERVERINFO.cs
- PropertyGridDesigner.cs
- ExecutedRoutedEventArgs.cs
- CatalogPart.cs
- StringInfo.cs
- CellTreeSimplifier.cs
- DataGridView.cs
- SchemaNotation.cs
- SHA1.cs
- FileDialog.cs
- CodePageEncoding.cs
- StoreUtilities.cs
- TableItemStyle.cs
- StringStorage.cs
- cache.cs