2018-02-13 09:23:53 -08:00
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
// Licensed under the MIT License.
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
// TODO/FIXME: move this to Microsoft.PowerShell.Cim namespace (and move in source depot folder as well)
|
2016-07-29 13:02:49 -07:00
|
|
|
|
2016-03-30 14:20:52 -07:00
|
|
|
namespace Microsoft.PowerShell.Cmdletization.Cim
|
|
|
|
|
{
|
|
|
|
|
using System.Management.Automation;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Translates a <see cref="WildcardPattern"/> into a like-operand for WQL.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
2018-06-08 05:49:03 +00:00
|
|
|
/// Documentation on MSDN (http://msdn.microsoft.com/library/aa392263(VS.85).aspx) is
|
2016-03-30 14:20:52 -07:00
|
|
|
/// 1) rather slim / incomplete
|
|
|
|
|
/// 2) sometimes incorrect (i.e. says that '=' is used for character ranges, when it should have said '-')
|
2017-01-16 13:31:14 -08:00
|
|
|
///
|
2016-03-30 14:20:52 -07:00
|
|
|
/// The code below is therefore mainly based on reverse engineering of admin\wmi\wbem\winmgmt\wbecomn\like.cpp
|
|
|
|
|
/// </remarks>
|
|
|
|
|
internal class WildcardPatternToCimQueryParser : WildcardPatternParser
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
private readonly StringBuilder _result = new StringBuilder();
|
|
|
|
|
private bool _needClientSideFiltering;
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
protected override void AppendLiteralCharacter(char c)
|
|
|
|
|
{
|
|
|
|
|
switch (c)
|
|
|
|
|
{
|
|
|
|
|
case '%':
|
|
|
|
|
case '_':
|
|
|
|
|
case '[': // no need to escape ']' character
|
|
|
|
|
this.BeginBracketExpression();
|
|
|
|
|
this.AppendLiteralCharacterToBracketExpression(c);
|
|
|
|
|
this.EndBracketExpression();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append(c);
|
2016-03-30 14:20:52 -07:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void AppendAsterix()
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append('%');
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void AppendQuestionMark()
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append('_');
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void BeginBracketExpression()
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append('[');
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void AppendLiteralCharacterToBracketExpression(char c)
|
|
|
|
|
{
|
|
|
|
|
switch (c)
|
|
|
|
|
{
|
|
|
|
|
case '^':
|
|
|
|
|
case ']':
|
|
|
|
|
case '-':
|
|
|
|
|
case '\\':
|
|
|
|
|
this.AppendCharacterRangeToBracketExpression(c, c);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append(c);
|
2016-03-30 14:20:52 -07:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void AppendCharacterRangeToBracketExpression(char startOfCharacterRange, char endOfCharacterRange)
|
|
|
|
|
{
|
|
|
|
|
// 90 = Z
|
|
|
|
|
// 91 = [
|
|
|
|
|
// 92 = \
|
|
|
|
|
// 93 = ]
|
|
|
|
|
// 94 = ^
|
|
|
|
|
// 95 = _
|
|
|
|
|
if ((91 <= startOfCharacterRange) && (startOfCharacterRange <= 94))
|
|
|
|
|
{
|
|
|
|
|
startOfCharacterRange = (char)90;
|
2016-07-29 13:02:49 -07:00
|
|
|
_needClientSideFiltering = true;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
2018-12-23 22:20:06 -08:00
|
|
|
|
2016-03-30 14:20:52 -07:00
|
|
|
if ((91 <= endOfCharacterRange) && (endOfCharacterRange <= 94))
|
|
|
|
|
{
|
|
|
|
|
endOfCharacterRange = (char)95;
|
2016-07-29 13:02:49 -07:00
|
|
|
_needClientSideFiltering = true;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 44 = ,
|
|
|
|
|
// 45 = -
|
|
|
|
|
// 46 = .
|
|
|
|
|
if (startOfCharacterRange == 45)
|
|
|
|
|
{
|
|
|
|
|
startOfCharacterRange = (char)44;
|
2016-07-29 13:02:49 -07:00
|
|
|
_needClientSideFiltering = true;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
2018-12-23 22:20:06 -08:00
|
|
|
|
2016-03-30 14:20:52 -07:00
|
|
|
if (endOfCharacterRange == 45)
|
|
|
|
|
{
|
|
|
|
|
endOfCharacterRange = (char)46;
|
2016-07-29 13:02:49 -07:00
|
|
|
_needClientSideFiltering = true;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append(startOfCharacterRange);
|
|
|
|
|
_result.Append('-');
|
|
|
|
|
_result.Append(endOfCharacterRange);
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void EndBracketExpression()
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
_result.Append(']');
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2017-01-16 13:31:14 -08:00
|
|
|
/// Converts <paramref name="wildcardPattern"/> into a value of a right-hand-side operand of LIKE operator of a WQL query.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// Return value still has to be string-escaped (i.e. by doubling '\'' character), before embedding it into a query.
|
|
|
|
|
/// </summary>
|
2016-08-02 19:00:50 -07:00
|
|
|
internal static string Parse(WildcardPattern wildcardPattern, out bool needsClientSideFiltering)
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
|
|
|
|
var parser = new WildcardPatternToCimQueryParser();
|
|
|
|
|
WildcardPatternParser.Parse(wildcardPattern, parser);
|
2016-07-29 13:02:49 -07:00
|
|
|
needsClientSideFiltering = parser._needClientSideFiltering;
|
|
|
|
|
return parser._result.ToString();
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|