You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,76 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ChangedFilters.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Specifies the changes to watch
|
||||
/// for in a file or folder.</para>
|
||||
/// </devdoc>
|
||||
[Flags]
|
||||
public enum NotifyFilters {
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
FileName = 0x00000001,
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
DirectoryName= 0x00000002,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
///
|
||||
/// The attributes of the file or folder.
|
||||
///
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Attributes = 0x00000004,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
///
|
||||
/// The size of the file or folder.
|
||||
///
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Size = 0x00000008,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// The
|
||||
/// date that the file or folder last had anything written to it.
|
||||
///
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
LastWrite = 0x00000010,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
///
|
||||
/// The date that the file or folder was last opened.
|
||||
///
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
LastAccess = 0x00000020,
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
CreationTime = 0x00000040,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
///
|
||||
/// The security settings of the file or folder.
|
||||
///
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Security = 0x00000100,
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ErrorEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Provides
|
||||
/// data for the <see cref='E:System.IO.FileSystemWatcher.Error'/> event.</para>
|
||||
/// </devdoc>
|
||||
public class ErrorEventArgs : EventArgs {
|
||||
private Exception exception;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Initializes a new instance of the class.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public ErrorEventArgs(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets the <see cref='System.Exception'/> that represents the error that occurred.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public virtual Exception GetException() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="ErrorEventHandler.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Represents the method that will
|
||||
/// handle the <see cref='E:System.IO.FileSystemWatcher.Error'/>
|
||||
/// event of
|
||||
/// a <see cref='T:System.IO.FileSystemWatcher'/>.</para>
|
||||
/// </devdoc>
|
||||
public delegate void ErrorEventHandler(object sender, ErrorEventArgs e);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="FileSystemEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Security.Permissions;
|
||||
|
||||
using System;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Provides data for the directory events: <see cref='System.IO.FileSystemWatcher.Changed'/>, <see cref='System.IO.FileSystemWatcher.Created'/>, <see cref='System.IO.FileSystemWatcher.Deleted'/>.</para>
|
||||
/// </devdoc>
|
||||
public class FileSystemEventArgs : EventArgs {
|
||||
private WatcherChangeTypes changeType;
|
||||
private string name;
|
||||
private string fullPath;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new instance of the <see cref='System.IO.FileSystemEventArgs'/> class.</para>
|
||||
/// </devdoc>
|
||||
public FileSystemEventArgs(WatcherChangeTypes changeType, string directory, string name)
|
||||
{
|
||||
this.changeType = changeType;
|
||||
this.name = name;
|
||||
|
||||
// Ensure that the directory name ends with a "\"
|
||||
if (!directory.EndsWith("\\", StringComparison.Ordinal)) {
|
||||
directory = directory + "\\";
|
||||
}
|
||||
|
||||
this.fullPath = directory + name;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets
|
||||
/// one of the <see cref='System.IO.WatcherChangeTypes'/>
|
||||
/// values.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public WatcherChangeTypes ChangeType {
|
||||
get {
|
||||
return changeType;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets
|
||||
/// the
|
||||
/// fully qualifed path of the affected file or directory.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public string FullPath {
|
||||
get {
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets
|
||||
/// the name of the affected file or directory.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="FileSystemEventHandler.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Represents the method that will handle the <see cref='System.IO.FileSystemWatcher.Changed'/>, <see cref='System.IO.FileSystemWatcher.Created'/>, or <see cref='System.IO.FileSystemWatcher.Deleted'/> event of a <see cref='System.IO.FileSystemWatcher'/>
|
||||
/// class.</para>
|
||||
/// </devdoc>
|
||||
public delegate void FileSystemEventHandler(object sender, FileSystemEventArgs e);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="IODescriptionAttribute.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
/// <devdoc>
|
||||
/// DescriptionAttribute marks a property, event, or extender with a
|
||||
/// description. Visual designers can display this description when referencing
|
||||
/// the member.
|
||||
/// </devdoc>
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class IODescriptionAttribute : DescriptionAttribute {
|
||||
|
||||
private bool replaced = false;
|
||||
|
||||
/// <devdoc>
|
||||
/// Constructs a new sys description.
|
||||
/// </devdoc>
|
||||
public IODescriptionAttribute(string description) : base(description) {
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Retrieves the description text.
|
||||
/// </devdoc>
|
||||
public override string Description {
|
||||
get {
|
||||
if (!replaced) {
|
||||
replaced = true;
|
||||
DescriptionValue = SR.GetString(base.Description);
|
||||
}
|
||||
return base.Description;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="InternalBufferOverflowException.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
*/
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Serialization;
|
||||
using System;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>The exception that is thrown when the internal buffer overflows.</para>
|
||||
/// </devdoc>
|
||||
[Serializable]
|
||||
public class InternalBufferOverflowException : SystemException {
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new default instance of the <see cref='System.IO.InternalBufferOverflowException'/> class.</para>
|
||||
/// </devdoc>
|
||||
public InternalBufferOverflowException() : base() {
|
||||
HResult = HResults.InternalBufferOverflow;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new instance of the <see cref='System.IO.InternalBufferOverflowException'/> class with the error
|
||||
/// message to be displayed
|
||||
/// specified.</para>
|
||||
/// </devdoc>
|
||||
public InternalBufferOverflowException(string message) : base(message) {
|
||||
HResult =HResults.InternalBufferOverflow;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Initializes a new instance of the <see cref='System.IO.InternalBufferOverflowException'/>
|
||||
/// class with the message to be displayed and the generated inner exception specified.</para>
|
||||
/// </devdoc>
|
||||
public InternalBufferOverflowException(string message, Exception inner) : base(message, inner) {
|
||||
HResult = HResults.InternalBufferOverflow;
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
protected InternalBufferOverflowException(SerializationInfo info, StreamingContext context) : base (info, context) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,484 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="PatternMatcher.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
*/
|
||||
namespace System.IO {
|
||||
using System.Text;
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System.Globalization;
|
||||
|
||||
internal static class PatternMatcher {
|
||||
/// <devdoc>
|
||||
/// Private constants (directly from C header files)
|
||||
/// </devdoc>
|
||||
private const int MATCHES_ARRAY_SIZE = 16;
|
||||
private const char ANSI_DOS_STAR = '>';
|
||||
private const char ANSI_DOS_QM = '<';
|
||||
private const char DOS_DOT = '"';
|
||||
|
||||
/// <devdoc>
|
||||
/// Tells whether a given name matches the expression given with a strict (i.e. UNIX like)
|
||||
/// semantics. This code is a port of unmanaged code. Original code comment follows:
|
||||
///
|
||||
/// Routine Description:
|
||||
///
|
||||
/// This routine compares a Dbcs name and an expression and tells the caller
|
||||
/// if the name is in the language defined by the expression. The input name
|
||||
/// cannot contain wildcards, while the expression may contain wildcards.
|
||||
///
|
||||
/// Expression wild cards are evaluated as shown in the nondeterministic
|
||||
/// finite automatons below. Note that ~* and ~? are DOS_STAR and DOS_QM.
|
||||
///
|
||||
///
|
||||
/// ~* is DOS_STAR, ~? is DOS_QM, and ~. is DOS_DOT
|
||||
///
|
||||
///
|
||||
/// S
|
||||
/// <-----<
|
||||
/// X | | e Y
|
||||
/// X * Y == (0)----->-(1)->-----(2)-----(3)
|
||||
///
|
||||
///
|
||||
/// S-.
|
||||
/// <-----<
|
||||
/// X | | e Y
|
||||
/// X ~* Y == (0)----->-(1)->-----(2)-----(3)
|
||||
///
|
||||
///
|
||||
///
|
||||
/// X S S Y
|
||||
/// X ?? Y == (0)---(1)---(2)---(3)---(4)
|
||||
///
|
||||
///
|
||||
///
|
||||
/// X . . Y
|
||||
/// X ~.~. Y == (0)---(1)----(2)------(3)---(4)
|
||||
/// | |________|
|
||||
/// | ^ |
|
||||
/// |_______________|
|
||||
/// ^EOF or .^
|
||||
///
|
||||
///
|
||||
/// X S-. S-. Y
|
||||
/// X ~?~? Y == (0)---(1)-----(2)-----(3)---(4)
|
||||
/// | |________|
|
||||
/// | ^ |
|
||||
/// |_______________|
|
||||
/// ^EOF or .^
|
||||
///
|
||||
///
|
||||
///
|
||||
/// where S is any single character
|
||||
///
|
||||
/// S-. is any single character except the final .
|
||||
///
|
||||
/// e is a null character transition
|
||||
///
|
||||
/// EOF is the end of the name string
|
||||
///
|
||||
/// In words:
|
||||
///
|
||||
/// * matches 0 or more characters.
|
||||
///
|
||||
/// ? matches exactly 1 character.
|
||||
///
|
||||
/// DOS_STAR matches 0 or more characters until encountering and matching
|
||||
/// the final . in the name.
|
||||
///
|
||||
/// DOS_QM matches any single character, or upon encountering a period or
|
||||
/// end of name string, advances the expression to the end of the
|
||||
/// set of contiguous DOS_QMs.
|
||||
///
|
||||
/// DOS_DOT matches either a . or zero characters beyond name string.
|
||||
///
|
||||
/// Arguments:
|
||||
///
|
||||
/// Expression - Supplies the input expression to check against
|
||||
///
|
||||
/// Name - Supplies the input name to check for.
|
||||
///
|
||||
/// Return Value:
|
||||
///
|
||||
/// BOOLEAN - TRUE if Name is an element in the set of strings denoted
|
||||
/// by the input Expression and FALSE otherwise.
|
||||
///
|
||||
/// </devdoc>
|
||||
public static bool StrictMatchPattern(string expression, string name) {
|
||||
int nameOffset;
|
||||
int exprOffset;
|
||||
int length;
|
||||
|
||||
int srcCount;
|
||||
int destCount;
|
||||
int previousDestCount;
|
||||
int matchesCount;
|
||||
|
||||
char nameChar = '\0';
|
||||
char exprChar = '\0';
|
||||
|
||||
int[] previousMatches = new int[MATCHES_ARRAY_SIZE];
|
||||
int[] currentMatches = new int[MATCHES_ARRAY_SIZE];
|
||||
|
||||
int maxState;
|
||||
int currentState;
|
||||
|
||||
bool nameFinished = false;
|
||||
|
||||
//
|
||||
// The idea behind the algorithm is pretty simple. We keep track of
|
||||
// all possible locations in the regular expression that are matching
|
||||
// the name. If when the name has been exhausted one of the locations
|
||||
// in the expression is also just exhausted, the name is in the language
|
||||
// defined by the regular expression.
|
||||
//
|
||||
|
||||
if (name == null || name.Length == 0 || expression == null || expression.Length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Special case by far the most common wild card search of * or *.*
|
||||
//
|
||||
|
||||
if (expression.Equals("*") || expression.Equals("*.*")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this class is ever exposed for generic use,
|
||||
// we need to make sure that name doesn't contain wildcards. Currently
|
||||
// the only component that calls this method is FileSystemWatcher and
|
||||
// it will never pass a name that contains a wildcard.
|
||||
|
||||
|
||||
//
|
||||
// Also special case expressions of the form *X. With this and the prior
|
||||
// case we have covered virtually all normal queries.
|
||||
//
|
||||
if (expression[0] == '*' && expression.IndexOf('*', 1) == -1) {
|
||||
int rightLength = expression.Length - 1;
|
||||
// if name is shorter that the stuff to the right of * in expression, we don't
|
||||
// need to do the string compare, otherwise we compare rightlength characters
|
||||
// and the end of both strings.
|
||||
if (name.Length >= rightLength && String.Compare(expression, 1, name, name.Length - rightLength, rightLength, StringComparison.OrdinalIgnoreCase) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Walk through the name string, picking off characters. We go one
|
||||
// character beyond the end because some wild cards are able to match
|
||||
// zero characters beyond the end of the string.
|
||||
//
|
||||
// With each new name character we determine a new set of states that
|
||||
// match the name so far. We use two arrays that we swap back and forth
|
||||
// for this purpose. One array lists the possible expression states for
|
||||
// all name characters up to but not including the current one, and other
|
||||
// array is used to build up the list of states considering the current
|
||||
// name character as well. The arrays are then switched and the process
|
||||
// repeated.
|
||||
//
|
||||
// There is not a one-to-one correspondence between state number and
|
||||
// offset into the expression. This is evident from the NFAs in the
|
||||
// initial comment to this function. State numbering is not continuous.
|
||||
// This allows a simple conversion between state number and expression
|
||||
// offset. Each character in the expression can represent one or two
|
||||
// states. * and DOS_STAR generate two states: ExprOffset*2 and
|
||||
// ExprOffset*2 + 1. All other expreesion characters can produce only
|
||||
// a single state. Thus ExprOffset = State/2.
|
||||
//
|
||||
//
|
||||
// Here is a short description of the variables involved:
|
||||
//
|
||||
// NameOffset - The offset of the current name char being processed.
|
||||
//
|
||||
// ExprOffset - The offset of the current expression char being processed.
|
||||
//
|
||||
// SrcCount - Prior match being investigated with current name char
|
||||
//
|
||||
// DestCount - Next location to put a matching assuming current name char
|
||||
//
|
||||
// NameFinished - Allows one more itteration through the Matches array
|
||||
// after the name is exhusted (to come *s for example)
|
||||
//
|
||||
// PreviousDestCount - This is used to prevent entry duplication, see coment
|
||||
//
|
||||
// PreviousMatches - Holds the previous set of matches (the Src array)
|
||||
//
|
||||
// CurrentMatches - Holds the current set of matches (the Dest array)
|
||||
//
|
||||
// AuxBuffer, LocalBuffer - the storage for the Matches arrays
|
||||
//
|
||||
|
||||
//
|
||||
// Set up the initial variables
|
||||
//
|
||||
|
||||
previousMatches[0] = 0;
|
||||
matchesCount = 1;
|
||||
|
||||
nameOffset = 0;
|
||||
maxState = expression.Length * 2;
|
||||
|
||||
while (! nameFinished) {
|
||||
if (nameOffset < name.Length) {
|
||||
nameChar = name[nameOffset];
|
||||
length = 1;
|
||||
nameOffset++;
|
||||
}
|
||||
else {
|
||||
nameFinished = true;
|
||||
|
||||
//
|
||||
// if we have already exhasted the expression, C#. Don't
|
||||
// continue.
|
||||
//
|
||||
if (previousMatches[matchesCount - 1] == maxState) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Now, for each of the previous stored expression matches, see what
|
||||
// we can do with this name character.
|
||||
//
|
||||
srcCount = 0;
|
||||
destCount = 0;
|
||||
previousDestCount = 0;
|
||||
|
||||
while (srcCount < matchesCount) {
|
||||
|
||||
//
|
||||
// We have to carry on our expression analysis as far as possible
|
||||
// for each character of name, so we loop here until the
|
||||
// expression stops matching. A clue here is that expression
|
||||
// cases that can match zero or more characters end with a
|
||||
// continue, while those that can accept only a single character
|
||||
// end with a break.
|
||||
//
|
||||
exprOffset = ((previousMatches[srcCount++] + 1) / 2);
|
||||
length = 0;
|
||||
|
||||
while (true) {
|
||||
if ( exprOffset == expression.Length ) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// The first time through the loop we don't want
|
||||
// to increment ExprOffset.
|
||||
//
|
||||
|
||||
exprOffset += length;
|
||||
|
||||
currentState = exprOffset * 2;
|
||||
|
||||
if (exprOffset == expression.Length) {
|
||||
currentMatches[destCount++] = maxState;
|
||||
break;
|
||||
}
|
||||
|
||||
exprChar = expression[exprOffset];
|
||||
length = 1;
|
||||
|
||||
//
|
||||
// Before we get started, we have to check for something
|
||||
// really gross. We may be about to exhaust the local
|
||||
// space for ExpressionMatches[][], so we have to allocate
|
||||
// some pool if this is the case. Yuk!
|
||||
//
|
||||
|
||||
if (destCount >= MATCHES_ARRAY_SIZE - 2) {
|
||||
int newSize = currentMatches.Length * 2;
|
||||
int [] tmp = new int[newSize];
|
||||
Array.Copy(currentMatches, tmp, currentMatches.Length);
|
||||
currentMatches = tmp;
|
||||
|
||||
tmp = new int[newSize];
|
||||
Array.Copy(previousMatches, tmp, previousMatches.Length);
|
||||
previousMatches = tmp;
|
||||
}
|
||||
|
||||
//
|
||||
// * matches any character zero or more times.
|
||||
//
|
||||
|
||||
if (exprChar == '*') {
|
||||
currentMatches[destCount++] = currentState;
|
||||
currentMatches[destCount++] = (currentState + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// DOS_STAR matches any character except . zero or more times.
|
||||
//
|
||||
|
||||
if (exprChar == ANSI_DOS_STAR) {
|
||||
bool iCanEatADot = false;
|
||||
|
||||
//
|
||||
// If we are at a period, determine if we are allowed to
|
||||
// consume it, ie. make sure it is not the last one.
|
||||
//
|
||||
if (!nameFinished && (nameChar == '.') ) {
|
||||
char tmpChar;
|
||||
int offset;
|
||||
|
||||
int nameLength = name.Length;
|
||||
for (offset = nameOffset; offset < nameLength; offset ++ ) {
|
||||
tmpChar = name[offset];
|
||||
length = 1;
|
||||
|
||||
if (tmpChar == '.') {
|
||||
iCanEatADot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nameFinished || (nameChar != '.') || iCanEatADot) {
|
||||
currentMatches[destCount++] = currentState;
|
||||
currentMatches[destCount++] = (currentState + 1);
|
||||
continue;
|
||||
} else {
|
||||
|
||||
//
|
||||
// We are at a period. We can only match zero
|
||||
// characters (ie. the epsilon transition).
|
||||
//
|
||||
currentMatches[destCount++] = (currentState + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The following expreesion characters all match by consuming
|
||||
// a character, thus force the expression, and thus state
|
||||
// forward.
|
||||
//
|
||||
currentState += length * 2;
|
||||
|
||||
//
|
||||
// DOS_QM is the most complicated. If the name is finished,
|
||||
// we can match zero characters. If this name is a '.', we
|
||||
// don't match, but look at the next expression. Otherwise
|
||||
// we match a single character.
|
||||
//
|
||||
if (exprChar == ANSI_DOS_QM) {
|
||||
|
||||
if (nameFinished || (nameChar == '.') ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
currentMatches[destCount++] = currentState;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// A DOS_DOT can match either a period, or zero characters
|
||||
// beyond the end of name.
|
||||
//
|
||||
if (exprChar == DOS_DOT) {
|
||||
|
||||
if (nameFinished) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameChar == '.') {
|
||||
currentMatches[destCount++] = currentState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// From this point on a name character is required to even
|
||||
// continue, let alone make a match.
|
||||
//
|
||||
if (nameFinished) {
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// If this expression was a '?' we can match it once.
|
||||
//
|
||||
if (exprChar == '?') {
|
||||
currentMatches[destCount++] = currentState;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Finally, check if the expression char matches the name char
|
||||
//
|
||||
if (exprChar == nameChar) {
|
||||
currentMatches[destCount++] = currentState;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// The expression didn't match so go look at the next
|
||||
// previous match.
|
||||
//
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Prevent duplication in the destination array.
|
||||
//
|
||||
// Each of the arrays is montonically increasing and non-
|
||||
// duplicating, thus we skip over any source element in the src
|
||||
// array if we just added the same element to the destination
|
||||
// array. This guarentees non-duplication in the dest. array.
|
||||
//
|
||||
|
||||
if ((srcCount < matchesCount) && (previousDestCount < destCount) ) {
|
||||
while (previousDestCount < destCount) {
|
||||
int previousLength = previousMatches.Length;
|
||||
while ((srcCount < previousLength) && (previousMatches[srcCount] < currentMatches[previousDestCount])) {
|
||||
srcCount += 1;
|
||||
}
|
||||
previousDestCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If we found no matches in the just finished itteration, it's time
|
||||
// to bail.
|
||||
//
|
||||
|
||||
if ( destCount == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Swap the meaning the two arrays
|
||||
//
|
||||
|
||||
{
|
||||
int[] tmp;
|
||||
|
||||
tmp = previousMatches;
|
||||
|
||||
previousMatches = currentMatches;
|
||||
|
||||
currentMatches = tmp;
|
||||
}
|
||||
|
||||
matchesCount = destCount;
|
||||
}
|
||||
|
||||
currentState = previousMatches[matchesCount - 1];
|
||||
|
||||
return currentState == maxState;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="RenamedEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Security.Permissions;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Provides data for the <see cref='System.IO.FileSystemWatcher.Renamed'/> event.</para>
|
||||
/// </devdoc>
|
||||
public class RenamedEventArgs : FileSystemEventArgs {
|
||||
private string oldName;
|
||||
private string oldFullPath;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Initializes a new instance of the <see cref='System.IO.RenamedEventArgs'/>
|
||||
/// class.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public RenamedEventArgs(WatcherChangeTypes changeType, string directory, string name, string oldName)
|
||||
: base(changeType, directory, name) {
|
||||
|
||||
// Ensure that the directory name ends with a "\"
|
||||
if (!directory.EndsWith("\\", StringComparison.Ordinal)) {
|
||||
directory = directory + "\\";
|
||||
}
|
||||
|
||||
this.oldName = oldName;
|
||||
this.oldFullPath = directory + oldName;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets
|
||||
/// the previous fully qualified path of the affected file or directory.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public string OldFullPath {
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
get {
|
||||
new FileIOPermission(FileIOPermissionAccess.Read, Path.GetPathRoot(oldFullPath)).Demand();
|
||||
return oldFullPath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets
|
||||
/// the old name of the affected file or directory.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public string OldName {
|
||||
get {
|
||||
return oldName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="RenamedEventHandler.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Represents the method that will handle the <see cref='System.IO.FileSystemWatcher.Renamed'/> event of a <see cref='System.IO.FileSystemWatcher'/>
|
||||
/// class.</para>
|
||||
/// </devdoc>
|
||||
public delegate void RenamedEventHandler(object sender, RenamedEventArgs e);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="WaitForChangedResult.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using System;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Waits for a change in the specified path.</para>
|
||||
/// </devdoc>
|
||||
public struct WaitForChangedResult {
|
||||
private WatcherChangeTypes changeType;
|
||||
private string name;
|
||||
private string oldName;
|
||||
private bool timedOut;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Specifies that the call has timed out.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
internal static readonly WaitForChangedResult TimedOutResult = new WaitForChangedResult(0, null, true);
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Initializes a new instance of the <see cref='System.IO.WaitForChangedResult'/> class, given the
|
||||
/// type of change to watch for, the folder to watch, and whether the call has
|
||||
/// timed out.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
internal WaitForChangedResult(WatcherChangeTypes changeType, string name, bool timedOut)
|
||||
: this(changeType, name, null, timedOut){
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Initializes a new instance of the <see cref='System.IO.WaitForChangedResult'/> class. This constructor is called when you are waiting
|
||||
/// for a change in a file or directory name.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
internal WaitForChangedResult(WatcherChangeTypes changeType, string name, string oldName, bool timedOut) {
|
||||
this.changeType = changeType;
|
||||
this.name = name;
|
||||
this.oldName = oldName;
|
||||
this.timedOut = timedOut;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets or sets the type of change to watch for.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public WatcherChangeTypes ChangeType {
|
||||
get {
|
||||
return changeType;
|
||||
}
|
||||
set {
|
||||
changeType = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets or sets the name of the file or subdirectory that has changed.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
set {
|
||||
name = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets or sets the original name of the file or subdirectory that has been
|
||||
/// renamed.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public string OldName {
|
||||
get {
|
||||
return oldName;
|
||||
}
|
||||
set {
|
||||
oldName = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Gets or sets a value indicating whether the process has timed out.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
public bool TimedOut {
|
||||
get {
|
||||
return timedOut;
|
||||
}
|
||||
set {
|
||||
timedOut = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="WatcherChangeTypes.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.IO {
|
||||
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Changes that may occur to a file or directory.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
[Flags()]
|
||||
public enum WatcherChangeTypes {
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// The creation of a file or folder.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Created = 1,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// The deletion of a file or folder.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Deleted = 2,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// The change of a file or folder.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Changed = 4,
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// The renaming of a file or folder.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
Renamed = 8,
|
||||
// all of the above
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
All = Created | Deleted | Changed | Renamed
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="AlphabeticalEnumConverter.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Diagnostics {
|
||||
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
|
||||
/// <internalonly/>
|
||||
/// <devdoc>
|
||||
/// <para>
|
||||
/// Provides a type converter to
|
||||
/// convert ???? objects to and from various other representations.
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
internal class AlphabeticalEnumConverter : EnumConverter {
|
||||
|
||||
public AlphabeticalEnumConverter(Type type) : base(type) {
|
||||
}
|
||||
|
||||
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
|
||||
if (Values == null) {
|
||||
Array objValues = Enum.GetValues(EnumType);
|
||||
//IComparer comparer = Comparer;
|
||||
object[] names = new object[objValues.Length];
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
names[i] = ConvertTo(context, null, objValues.GetValue(i), typeof(string));
|
||||
Array.Sort(names, objValues, 0, objValues.Length, System.Collections.Comparer.Default);
|
||||
Values = new StandardValuesCollection(objValues);
|
||||
}
|
||||
return Values;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Class: AsyncStreamReader
|
||||
**
|
||||
** Purpose: For reading text from streams using a particular
|
||||
** encoding in an asychronous manner used by the process class
|
||||
**
|
||||
**
|
||||
===========================================================*/
|
||||
|
||||
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
|
||||
internal delegate void UserCallBack(String data);
|
||||
|
||||
internal class AsyncStreamReader : IDisposable
|
||||
{
|
||||
internal const int DefaultBufferSize = 1024; // Byte buffer size
|
||||
private const int MinBufferSize = 128;
|
||||
|
||||
private Stream stream;
|
||||
private Encoding encoding;
|
||||
private Decoder decoder;
|
||||
private byte[] byteBuffer;
|
||||
private char[] charBuffer;
|
||||
// Record the number of valid bytes in the byteBuffer, for a few checks.
|
||||
|
||||
// This is the maximum number of chars we can get from one call to
|
||||
// ReadBuffer. Used so ReadBuffer can tell when to copy data into
|
||||
// a user's char[] directly, instead of our internal char[].
|
||||
private int _maxCharsPerBuffer;
|
||||
|
||||
// Store a backpointer to the process class, to check for user callbacks
|
||||
private Process process;
|
||||
|
||||
// Delegate to call user function.
|
||||
private UserCallBack userCallBack;
|
||||
|
||||
// Internal Cancel operation
|
||||
private bool cancelOperation;
|
||||
private ManualResetEvent eofEvent;
|
||||
private Queue messageQueue;
|
||||
private StringBuilder sb;
|
||||
private bool bLastCarriageReturn;
|
||||
|
||||
// Cache the last position scanned in sb when searching for lines.
|
||||
private int currentLinePos;
|
||||
|
||||
internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding)
|
||||
: this(process, stream, callback, encoding, DefaultBufferSize) {
|
||||
}
|
||||
|
||||
|
||||
// Creates a new AsyncStreamReader for the given stream. The
|
||||
// character encoding is set by encoding and the buffer size,
|
||||
// in number of 16-bit characters, is set by bufferSize.
|
||||
//
|
||||
internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
|
||||
{
|
||||
Debug.Assert (process != null && stream !=null && encoding !=null && callback != null, "Invalid arguments!");
|
||||
Debug.Assert(stream.CanRead, "Stream must be readable!");
|
||||
Debug.Assert(bufferSize > 0, "Invalid buffer size!");
|
||||
|
||||
Init(process, stream, callback, encoding, bufferSize);
|
||||
messageQueue = new Queue();
|
||||
}
|
||||
|
||||
private void Init(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize) {
|
||||
this.process = process;
|
||||
this.stream = stream;
|
||||
this.encoding = encoding;
|
||||
this.userCallBack = callback;
|
||||
decoder = encoding.GetDecoder();
|
||||
if (bufferSize < MinBufferSize) bufferSize = MinBufferSize;
|
||||
byteBuffer = new byte[bufferSize];
|
||||
_maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize);
|
||||
charBuffer = new char[_maxCharsPerBuffer];
|
||||
cancelOperation = false;
|
||||
eofEvent = new ManualResetEvent(false);
|
||||
sb = null;
|
||||
this.bLastCarriageReturn = false;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
void IDisposable.Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing) {
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
}
|
||||
if (stream != null) {
|
||||
stream = null;
|
||||
encoding = null;
|
||||
decoder = null;
|
||||
byteBuffer = null;
|
||||
charBuffer = null;
|
||||
}
|
||||
|
||||
if( eofEvent != null) {
|
||||
eofEvent.Close();
|
||||
eofEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Encoding CurrentEncoding {
|
||||
get { return encoding; }
|
||||
}
|
||||
|
||||
public virtual Stream BaseStream {
|
||||
get { return stream; }
|
||||
}
|
||||
|
||||
// User calls BeginRead to start the asynchronous read
|
||||
internal void BeginReadLine() {
|
||||
if( cancelOperation) {
|
||||
cancelOperation = false;
|
||||
}
|
||||
|
||||
if( sb == null ) {
|
||||
sb = new StringBuilder(DefaultBufferSize);
|
||||
stream.BeginRead(byteBuffer, 0 , byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
|
||||
}
|
||||
else {
|
||||
FlushMessageQueue();
|
||||
}
|
||||
}
|
||||
|
||||
internal void CancelOperation() {
|
||||
cancelOperation = true;
|
||||
}
|
||||
|
||||
// This is the async callback function. Only one thread could/should call this.
|
||||
private void ReadBuffer(IAsyncResult ar) {
|
||||
|
||||
int byteLen;
|
||||
|
||||
try {
|
||||
byteLen = stream.EndRead(ar);
|
||||
}
|
||||
catch (IOException ) {
|
||||
// We should ideally consume errors from operations getting cancelled
|
||||
// so that we don't crash the unsuspecting parent with an unhandled exc.
|
||||
// This seems to come in 2 forms of exceptions (depending on platform and scenario),
|
||||
// namely OperationCanceledException and IOException (for errorcode that we don't
|
||||
// map explicitly).
|
||||
byteLen = 0; // Treat this as EOF
|
||||
}
|
||||
catch (OperationCanceledException ) {
|
||||
// We should consume any OperationCanceledException from child read here
|
||||
// so that we don't crash the parent with an unhandled exc
|
||||
byteLen = 0; // Treat this as EOF
|
||||
}
|
||||
|
||||
if (byteLen == 0) {
|
||||
// We're at EOF, we won't call this function again from here on.
|
||||
lock(messageQueue) {
|
||||
if( sb.Length != 0) {
|
||||
messageQueue.Enqueue(sb.ToString());
|
||||
sb.Length = 0;
|
||||
}
|
||||
messageQueue.Enqueue(null);
|
||||
}
|
||||
|
||||
try {
|
||||
// UserCallback could throw, we should still set the eofEvent
|
||||
FlushMessageQueue();
|
||||
}
|
||||
finally {
|
||||
eofEvent.Set();
|
||||
}
|
||||
} else {
|
||||
int charLen = decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, 0);
|
||||
sb.Append(charBuffer, 0, charLen);
|
||||
GetLinesFromStringBuilder();
|
||||
stream.BeginRead(byteBuffer, 0 , byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read lines stored in StringBuilder and the buffer we just read into.
|
||||
// A line is defined as a sequence of characters followed by
|
||||
// a carriage return ('\r'), a line feed ('\n'), or a carriage return
|
||||
// immediately followed by a line feed. The resulting string does not
|
||||
// contain the terminating carriage return and/or line feed. The returned
|
||||
// value is null if the end of the input stream has been reached.
|
||||
//
|
||||
|
||||
private void GetLinesFromStringBuilder() {
|
||||
int currentIndex = currentLinePos;
|
||||
int lineStart = 0;
|
||||
int len = sb.Length;
|
||||
|
||||
// skip a beginning '\n' character of new block if last block ended
|
||||
// with '\r'
|
||||
if (bLastCarriageReturn && (len > 0) && sb[0] == '\n')
|
||||
{
|
||||
currentIndex = 1;
|
||||
lineStart = 1;
|
||||
bLastCarriageReturn = false;
|
||||
}
|
||||
|
||||
while (currentIndex < len) {
|
||||
char ch = sb[currentIndex];
|
||||
// Note the following common line feed chars:
|
||||
// \n - UNIX \r\n - DOS \r - Mac
|
||||
if (ch == '\r' || ch == '\n') {
|
||||
string s = sb.ToString(lineStart, currentIndex - lineStart);
|
||||
lineStart = currentIndex + 1;
|
||||
// skip the "\n" character following "\r" character
|
||||
if ((ch == '\r') && (lineStart < len) && (sb[lineStart] == '\n'))
|
||||
{
|
||||
lineStart++;
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
lock(messageQueue) {
|
||||
messageQueue.Enqueue(s);
|
||||
}
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
if (sb[len - 1] == '\r') {
|
||||
bLastCarriageReturn = true;
|
||||
}
|
||||
// Keep the rest characaters which can't form a new line in string builder.
|
||||
if (lineStart < len) {
|
||||
if (lineStart == 0) {
|
||||
// we found no breaklines, in this case we cache the position
|
||||
// so next time we don't have to restart from the beginning
|
||||
currentLinePos = currentIndex;
|
||||
}
|
||||
else {
|
||||
sb.Remove(0, lineStart);
|
||||
currentLinePos = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sb.Length = 0;
|
||||
currentLinePos = 0;
|
||||
}
|
||||
|
||||
FlushMessageQueue();
|
||||
}
|
||||
|
||||
private void FlushMessageQueue() {
|
||||
while(true) {
|
||||
|
||||
// When we call BeginReadLine, we also need to flush the queue
|
||||
// So there could be a ---- between the ReadBuffer and BeginReadLine
|
||||
// We need to take lock before DeQueue.
|
||||
if( messageQueue.Count > 0) {
|
||||
lock(messageQueue) {
|
||||
if( messageQueue.Count > 0) {
|
||||
string s = (string)messageQueue.Dequeue();
|
||||
// skip if the read is the read is cancelled
|
||||
// this might happen inside UserCallBack
|
||||
// However, continue to drain the queue
|
||||
if (!cancelOperation)
|
||||
{
|
||||
userCallBack(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait until we hit EOF. This is called from Process.WaitForExit
|
||||
// We will lose some information if we don't do this.
|
||||
internal void WaitUtilEOF() {
|
||||
if( eofEvent != null) {
|
||||
eofEvent.WaitOne();
|
||||
eofEvent.Close();
|
||||
eofEvent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CounterCreationData.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Diagnostics {
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
/// <devdoc>
|
||||
/// A struct defining the counter type, name and help string for a custom counter.
|
||||
/// </devdoc>
|
||||
[
|
||||
TypeConverter("System.Diagnostics.Design.CounterCreationDataConverter, " + AssemblyRef.SystemDesign),
|
||||
Serializable
|
||||
]
|
||||
public class CounterCreationData {
|
||||
private PerformanceCounterType counterType = PerformanceCounterType.NumberOfItems32;
|
||||
private string counterName = String.Empty;
|
||||
private string counterHelp = String.Empty;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterCreationData() {
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterCreationData(string counterName, string counterHelp, PerformanceCounterType counterType) {
|
||||
CounterType = counterType;
|
||||
CounterName = counterName;
|
||||
CounterHelp = counterHelp;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
[
|
||||
DefaultValue(PerformanceCounterType.NumberOfItems32),
|
||||
MonitoringDescription(SR.CounterType)
|
||||
]
|
||||
public PerformanceCounterType CounterType {
|
||||
get {
|
||||
return counterType;
|
||||
}
|
||||
set {
|
||||
if (!Enum.IsDefined(typeof(PerformanceCounterType), value))
|
||||
throw new InvalidEnumArgumentException("value", (int)value, typeof(PerformanceCounterType));
|
||||
|
||||
counterType = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
[
|
||||
DefaultValue(""),
|
||||
MonitoringDescription(SR.CounterName),
|
||||
TypeConverter("System.Diagnostics.Design.StringValueConverter, " + AssemblyRef.SystemDesign)
|
||||
]
|
||||
public string CounterName {
|
||||
get {
|
||||
return counterName;
|
||||
}
|
||||
set {
|
||||
PerformanceCounterCategory.CheckValidCounter(value);
|
||||
counterName = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
[
|
||||
DefaultValue(""),
|
||||
MonitoringDescription(SR.CounterHelp)
|
||||
]
|
||||
public string CounterHelp {
|
||||
get {
|
||||
return counterHelp;
|
||||
}
|
||||
set {
|
||||
PerformanceCounterCategory.CheckValidHelp(value);
|
||||
counterHelp = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CounterCreationDataCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Collections;
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
[Serializable()]
|
||||
public class CounterCreationDataCollection : CollectionBase {
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterCreationDataCollection() {
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterCreationDataCollection(CounterCreationDataCollection value) {
|
||||
this.AddRange(value);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterCreationDataCollection(CounterCreationData[] value) {
|
||||
this.AddRange(value);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterCreationData this[int index] {
|
||||
get {
|
||||
return ((CounterCreationData)(List[index]));
|
||||
}
|
||||
set {
|
||||
List[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public int Add(CounterCreationData value) {
|
||||
return List.Add(value);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public void AddRange(CounterCreationData[] value) {
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
for (int i = 0; ((i) < (value.Length)); i = ((i) + (1))) {
|
||||
this.Add(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public void AddRange(CounterCreationDataCollection value) {
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
int currentCount = value.Count;
|
||||
for (int i = 0; i < currentCount; i = ((i) + (1))) {
|
||||
this.Add(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public bool Contains(CounterCreationData value) {
|
||||
return List.Contains(value);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public void CopyTo(CounterCreationData[] array, int index) {
|
||||
List.CopyTo(array, index);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public int IndexOf(CounterCreationData value) {
|
||||
return List.IndexOf(value);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public void Insert(int index, CounterCreationData value) {
|
||||
List.Insert(index, value);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public virtual void Remove(CounterCreationData value) {
|
||||
List.Remove(value);
|
||||
}
|
||||
|
||||
protected override void OnValidate(object value) {
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
CounterCreationData dataToAdd = value as CounterCreationData;
|
||||
if (dataToAdd == null)
|
||||
throw new ArgumentException(SR.GetString(SR.MustAddCounterCreationData));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CounterSample.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Diagnostics {
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
using System;
|
||||
|
||||
/// <devdoc>
|
||||
/// A struct holding the raw data for a performance counter.
|
||||
/// </devdoc>
|
||||
public struct CounterSample {
|
||||
private long rawValue;
|
||||
private long baseValue;
|
||||
private long timeStamp;
|
||||
private long counterFrequency;
|
||||
private PerformanceCounterType counterType;
|
||||
private long timeStamp100nSec;
|
||||
private long systemFrequency;
|
||||
private long counterTimeStamp;
|
||||
|
||||
// Dummy holder for an empty sample
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public static CounterSample Empty = new CounterSample(0, 0, 0, 0, 0, 0, PerformanceCounterType.NumberOfItems32);
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterSample(long rawValue, long baseValue, long counterFrequency, long systemFrequency, long timeStamp, long timeStamp100nSec, PerformanceCounterType counterType) {
|
||||
this.rawValue = rawValue;
|
||||
this.baseValue = baseValue;
|
||||
this.timeStamp = timeStamp;
|
||||
this.counterFrequency = counterFrequency;
|
||||
this.counterType = counterType;
|
||||
this.timeStamp100nSec = timeStamp100nSec;
|
||||
this.systemFrequency = systemFrequency;
|
||||
this.counterTimeStamp = 0;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
public CounterSample(long rawValue, long baseValue, long counterFrequency, long systemFrequency, long timeStamp, long timeStamp100nSec, PerformanceCounterType counterType, long counterTimeStamp) {
|
||||
this.rawValue = rawValue;
|
||||
this.baseValue = baseValue;
|
||||
this.timeStamp = timeStamp;
|
||||
this.counterFrequency = counterFrequency;
|
||||
this.counterType = counterType;
|
||||
this.timeStamp100nSec = timeStamp100nSec;
|
||||
this.systemFrequency = systemFrequency;
|
||||
this.counterTimeStamp = counterTimeStamp;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Raw value of the counter.
|
||||
/// </devdoc>
|
||||
public long RawValue {
|
||||
get {
|
||||
return this.rawValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal ulong UnsignedRawValue {
|
||||
get {
|
||||
return (ulong)this.rawValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Optional base raw value for the counter (only used if multiple counter based).
|
||||
/// </devdoc>
|
||||
public long BaseValue {
|
||||
get {
|
||||
return this.baseValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Raw system frequency
|
||||
/// </devdoc>
|
||||
public long SystemFrequency {
|
||||
get {
|
||||
return this.systemFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Raw counter frequency
|
||||
/// </devdoc>
|
||||
public long CounterFrequency {
|
||||
get {
|
||||
return this.counterFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Raw counter frequency
|
||||
/// </devdoc>
|
||||
public long CounterTimeStamp {
|
||||
get {
|
||||
return this.counterTimeStamp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Raw timestamp
|
||||
/// </devdoc>
|
||||
public long TimeStamp {
|
||||
get {
|
||||
return this.timeStamp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Raw high fidelity timestamp
|
||||
/// </devdoc>
|
||||
public long TimeStamp100nSec {
|
||||
get {
|
||||
return this.timeStamp100nSec;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Counter type
|
||||
/// </devdoc>
|
||||
public PerformanceCounterType CounterType {
|
||||
get {
|
||||
return this.counterType;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Static functions to calculate the performance value off the sample
|
||||
/// </devdoc>
|
||||
public static float Calculate(CounterSample counterSample) {
|
||||
return CounterSampleCalculator.ComputeCounterValue(counterSample);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Static functions to calculate the performance value off the samples
|
||||
/// </devdoc>
|
||||
public static float Calculate(CounterSample counterSample, CounterSample nextCounterSample) {
|
||||
return CounterSampleCalculator.ComputeCounterValue(counterSample, nextCounterSample);
|
||||
}
|
||||
|
||||
public override bool Equals(Object o) {
|
||||
return ( o is CounterSample) && Equals((CounterSample)o);
|
||||
}
|
||||
|
||||
public bool Equals(CounterSample sample) {
|
||||
return (rawValue == sample.rawValue) &&
|
||||
(baseValue == sample.baseValue) &&
|
||||
(timeStamp == sample.timeStamp) &&
|
||||
(counterFrequency == sample.counterFrequency) &&
|
||||
(counterType == sample.counterType) &&
|
||||
(timeStamp100nSec == sample.timeStamp100nSec) &&
|
||||
(systemFrequency == sample.systemFrequency) &&
|
||||
(counterTimeStamp == sample.counterTimeStamp);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return rawValue.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(CounterSample a, CounterSample b) {
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
public static bool operator !=(CounterSample a, CounterSample b) {
|
||||
return !(a.Equals(b));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="CounterSampleCalculator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Diagnostics {
|
||||
using System.Threading;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Microsoft.Win32;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
/// <devdoc>
|
||||
/// Set of utility functions for interpreting the counter data
|
||||
/// NOTE: most of this code was taken and ported from counters.c (PerfMon source code)
|
||||
/// </devdoc>
|
||||
public static class CounterSampleCalculator {
|
||||
static volatile bool perfCounterDllLoaded = false;
|
||||
|
||||
/// <devdoc>
|
||||
/// Converts 100NS elapsed time to fractional seconds
|
||||
/// </devdoc>
|
||||
/// <internalonly/>
|
||||
private static float GetElapsedTime(CounterSample oldSample, CounterSample newSample) {
|
||||
float eSeconds;
|
||||
float eDifference;
|
||||
|
||||
if (newSample.RawValue == 0) {
|
||||
// no data [start time = 0] so return 0
|
||||
return 0.0f;
|
||||
}
|
||||
else {
|
||||
float eFreq;
|
||||
eFreq = (float)(ulong)oldSample.CounterFrequency;
|
||||
|
||||
if (oldSample.UnsignedRawValue >= (ulong)newSample.CounterTimeStamp || eFreq <= 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
// otherwise compute difference between current time and start time
|
||||
eDifference = (float)((ulong)newSample.CounterTimeStamp - oldSample.UnsignedRawValue);
|
||||
|
||||
// convert to fractional seconds using object counter
|
||||
eSeconds = eDifference / eFreq;
|
||||
|
||||
return eSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Computes the calculated value given a raw counter sample.
|
||||
/// </devdoc>
|
||||
public static float ComputeCounterValue(CounterSample newSample) {
|
||||
return ComputeCounterValue(CounterSample.Empty, newSample);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// Computes the calculated value given a raw counter sample.
|
||||
/// </devdoc>
|
||||
public static float ComputeCounterValue(CounterSample oldSample, CounterSample newSample) {
|
||||
int newCounterType = (int) newSample.CounterType;
|
||||
if (oldSample.SystemFrequency == 0) {
|
||||
if ((newCounterType != NativeMethods.PERF_RAW_FRACTION) &&
|
||||
(newCounterType != NativeMethods.PERF_COUNTER_RAWCOUNT) &&
|
||||
(newCounterType != NativeMethods.PERF_COUNTER_RAWCOUNT_HEX) &&
|
||||
(newCounterType != NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT) &&
|
||||
(newCounterType != NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT_HEX) &&
|
||||
(newCounterType != NativeMethods.PERF_COUNTER_MULTI_BASE)) {
|
||||
|
||||
// Since oldSample has a system frequency of 0, this means the newSample is the first sample
|
||||
// on a two sample calculation. Since we can't do anything with it, return 0.
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
else if (oldSample.CounterType != newSample.CounterType) {
|
||||
throw new InvalidOperationException(SR.GetString(SR.MismatchedCounterTypes));
|
||||
}
|
||||
|
||||
if (newCounterType == NativeMethods.PERF_ELAPSED_TIME)
|
||||
return (float)GetElapsedTime(oldSample, newSample);
|
||||
|
||||
NativeMethods.PDH_RAW_COUNTER newPdhValue = new NativeMethods.PDH_RAW_COUNTER();
|
||||
NativeMethods.PDH_RAW_COUNTER oldPdhValue = new NativeMethods.PDH_RAW_COUNTER();
|
||||
|
||||
FillInValues(oldSample, newSample, oldPdhValue, newPdhValue);
|
||||
|
||||
LoadPerfCounterDll();
|
||||
|
||||
NativeMethods.PDH_FMT_COUNTERVALUE pdhFormattedValue= new NativeMethods.PDH_FMT_COUNTERVALUE();
|
||||
long timeBase = newSample.SystemFrequency;
|
||||
int result = SafeNativeMethods.FormatFromRawValue((uint) newCounterType, NativeMethods.PDH_FMT_DOUBLE | NativeMethods.PDH_FMT_NOSCALE | NativeMethods.PDH_FMT_NOCAP100,
|
||||
ref timeBase, newPdhValue, oldPdhValue, pdhFormattedValue);
|
||||
|
||||
if (result != NativeMethods.ERROR_SUCCESS) {
|
||||
// If the numbers go negative, just return 0. This better matches the old behavior.
|
||||
if (result == NativeMethods.PDH_CALC_NEGATIVE_VALUE || result == NativeMethods.PDH_CALC_NEGATIVE_DENOMINATOR || result == NativeMethods.PDH_NO_DATA)
|
||||
return 0;
|
||||
else
|
||||
throw new Win32Exception(result, SR.GetString(SR.PerfCounterPdhError, result.ToString("x", CultureInfo.InvariantCulture)));
|
||||
}
|
||||
|
||||
return (float) pdhFormattedValue.data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// This method figures out which values are supposed to go into which structures so that PDH can do the
|
||||
// calculation for us. This was ported from Window's cutils.c
|
||||
private static void FillInValues(CounterSample oldSample, CounterSample newSample, NativeMethods.PDH_RAW_COUNTER oldPdhValue, NativeMethods.PDH_RAW_COUNTER newPdhValue) {
|
||||
int newCounterType = (int) newSample.CounterType;
|
||||
|
||||
switch (newCounterType) {
|
||||
case NativeMethods.PERF_COUNTER_COUNTER:
|
||||
case NativeMethods.PERF_COUNTER_QUEUELEN_TYPE:
|
||||
case NativeMethods.PERF_SAMPLE_COUNTER:
|
||||
case NativeMethods.PERF_OBJ_TIME_TIMER:
|
||||
case NativeMethods.PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE:
|
||||
newPdhValue.FirstValue = newSample.RawValue;
|
||||
newPdhValue.SecondValue = newSample.TimeStamp;
|
||||
|
||||
oldPdhValue.FirstValue = oldSample.RawValue;
|
||||
oldPdhValue.SecondValue = oldSample.TimeStamp;
|
||||
break;
|
||||
|
||||
case NativeMethods.PERF_COUNTER_100NS_QUEUELEN_TYPE:
|
||||
newPdhValue.FirstValue = newSample.RawValue;
|
||||
newPdhValue.SecondValue = newSample.TimeStamp100nSec;
|
||||
|
||||
oldPdhValue.FirstValue = oldSample.RawValue;
|
||||
oldPdhValue.SecondValue = oldSample.TimeStamp100nSec;
|
||||
break;
|
||||
|
||||
case NativeMethods.PERF_COUNTER_TIMER:
|
||||
case NativeMethods.PERF_COUNTER_TIMER_INV:
|
||||
case NativeMethods.PERF_COUNTER_BULK_COUNT:
|
||||
case NativeMethods.PERF_COUNTER_LARGE_QUEUELEN_TYPE:
|
||||
case NativeMethods.PERF_COUNTER_MULTI_TIMER:
|
||||
case NativeMethods.PERF_COUNTER_MULTI_TIMER_INV:
|
||||
newPdhValue.FirstValue = newSample.RawValue;
|
||||
newPdhValue.SecondValue = newSample.TimeStamp;
|
||||
|
||||
oldPdhValue.FirstValue = oldSample.RawValue;
|
||||
oldPdhValue.SecondValue = oldSample.TimeStamp;
|
||||
if (newCounterType == NativeMethods.PERF_COUNTER_MULTI_TIMER || newCounterType == NativeMethods.PERF_COUNTER_MULTI_TIMER_INV) {
|
||||
// this is to make PDH work like PERFMON for
|
||||
// this counter type
|
||||
newPdhValue.FirstValue *= (uint) newSample.CounterFrequency;
|
||||
if (oldSample.CounterFrequency != 0) {
|
||||
oldPdhValue.FirstValue *= (uint) oldSample.CounterFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
if ((newCounterType & NativeMethods.PERF_MULTI_COUNTER) == NativeMethods.PERF_MULTI_COUNTER) {
|
||||
newPdhValue.MultiCount = (int) newSample.BaseValue;
|
||||
oldPdhValue.MultiCount = (int) oldSample.BaseValue;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
//
|
||||
// These counters do not use any time reference
|
||||
//
|
||||
case NativeMethods.PERF_COUNTER_RAWCOUNT:
|
||||
case NativeMethods.PERF_COUNTER_RAWCOUNT_HEX:
|
||||
case NativeMethods.PERF_COUNTER_DELTA:
|
||||
case NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT:
|
||||
case NativeMethods.PERF_COUNTER_LARGE_RAWCOUNT_HEX:
|
||||
case NativeMethods.PERF_COUNTER_LARGE_DELTA:
|
||||
newPdhValue.FirstValue = newSample.RawValue;
|
||||
newPdhValue.SecondValue = 0;
|
||||
|
||||
oldPdhValue.FirstValue = oldSample.RawValue;
|
||||
oldPdhValue.SecondValue = 0;
|
||||
break;
|
||||
//
|
||||
// These counters use the 100 Ns time base in thier calculation
|
||||
//
|
||||
case NativeMethods.PERF_100NSEC_TIMER:
|
||||
case NativeMethods.PERF_100NSEC_TIMER_INV:
|
||||
case NativeMethods.PERF_100NSEC_MULTI_TIMER:
|
||||
case NativeMethods.PERF_100NSEC_MULTI_TIMER_INV:
|
||||
newPdhValue.FirstValue = newSample.RawValue;
|
||||
newPdhValue.SecondValue = newSample.TimeStamp100nSec;
|
||||
|
||||
oldPdhValue.FirstValue = oldSample.RawValue;
|
||||
oldPdhValue.SecondValue = oldSample.TimeStamp100nSec;
|
||||
if ((newCounterType & NativeMethods.PERF_MULTI_COUNTER) == NativeMethods.PERF_MULTI_COUNTER) {
|
||||
newPdhValue.MultiCount = (int) newSample.BaseValue;
|
||||
oldPdhValue.MultiCount = (int) oldSample.BaseValue;
|
||||
}
|
||||
break;
|
||||
//
|
||||
// These counters use two data points
|
||||
//
|
||||
case NativeMethods.PERF_SAMPLE_FRACTION:
|
||||
case NativeMethods.PERF_RAW_FRACTION:
|
||||
case NativeMethods.PERF_LARGE_RAW_FRACTION:
|
||||
case NativeMethods.PERF_PRECISION_SYSTEM_TIMER:
|
||||
case NativeMethods.PERF_PRECISION_100NS_TIMER:
|
||||
case NativeMethods.PERF_PRECISION_OBJECT_TIMER:
|
||||
case NativeMethods.PERF_AVERAGE_TIMER:
|
||||
case NativeMethods.PERF_AVERAGE_BULK:
|
||||
newPdhValue.FirstValue = newSample.RawValue;
|
||||
newPdhValue.SecondValue = newSample.BaseValue;
|
||||
|
||||
oldPdhValue.FirstValue = oldSample.RawValue;
|
||||
oldPdhValue.SecondValue = oldSample.BaseValue;
|
||||
break;
|
||||
|
||||
default:
|
||||
// an unidentified counter was returned so
|
||||
newPdhValue.FirstValue = 0;
|
||||
newPdhValue.SecondValue = 0;
|
||||
|
||||
oldPdhValue.FirstValue = 0;
|
||||
oldPdhValue.SecondValue = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
private static void LoadPerfCounterDll() {
|
||||
if (perfCounterDllLoaded)
|
||||
return;
|
||||
|
||||
new FileIOPermission(PermissionState.Unrestricted).Assert();
|
||||
|
||||
string installPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
|
||||
string perfcounterPath = Path.Combine(installPath, "perfcounter.dll");
|
||||
if (SafeNativeMethods.LoadLibrary(perfcounterPath) == IntPtr.Zero) {
|
||||
throw new Win32Exception( Marshal.GetLastWin32Error() );
|
||||
}
|
||||
|
||||
perfCounterDllLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="Process.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Diagnostics {
|
||||
using System;
|
||||
|
||||
public delegate void DataReceivedEventHandler(Object sender, DataReceivedEventArgs e);
|
||||
|
||||
public class DataReceivedEventArgs : EventArgs {
|
||||
internal String _data;
|
||||
|
||||
internal DataReceivedEventArgs(String data) {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public String Data {
|
||||
get {
|
||||
return _data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user