Пример #1
0
        /// <summary>
        /// Get a Hashtable object out of a PowerShell data file (.psd1)
        /// </summary>
        /// <param name="parameterName">
        /// Name of the parameter that takes the specified .psd1 file as a value
        /// </param>
        /// <param name="psDataFilePath">
        /// Path to the powershell data file
        /// </param>
        /// <param name="context">
        /// ExecutionContext to use
        /// </param>
        /// <param name="allowedCommands">
        /// Set of command names that are allowed to use in the .psd1 file
        /// </param>
        /// <param name="allowedVariables">
        /// Set of variable names that are allowed to use in the .psd1 file
        /// </param>
        /// <param name="allowEnvironmentVariables">
        /// If true, allow to use environment variables in the .psd1 file
        /// </param>
        /// <param name="skipPathValidation">
        /// If true, caller guarantees the path is valid
        /// </param>
        /// <returns></returns>
        internal static Hashtable EvaluatePowerShellDataFile(
            string parameterName,
            string psDataFilePath,
            ExecutionContext context,
            IEnumerable <string> allowedCommands,
            IEnumerable <string> allowedVariables,
            bool allowEnvironmentVariables,
            bool skipPathValidation)
        {
            if (!skipPathValidation && string.IsNullOrEmpty(parameterName))
            {
                throw PSTraceSource.NewArgumentNullException(nameof(parameterName));
            }

            if (string.IsNullOrEmpty(psDataFilePath))
            {
                throw PSTraceSource.NewArgumentNullException(nameof(psDataFilePath));
            }

            if (context == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(context));
            }

            string resolvedPath;

            if (skipPathValidation)
            {
                resolvedPath = psDataFilePath;
            }
            else
            {
                #region "ValidatePowerShellDataFilePath"

                bool isPathValid = true;

                // File extension needs to be .psd1
                string pathExt = Path.GetExtension(psDataFilePath);
                if (string.IsNullOrEmpty(pathExt) ||
                    !StringLiterals.PowerShellDataFileExtension.Equals(pathExt, StringComparison.OrdinalIgnoreCase))
                {
                    isPathValid = false;
                }

                ProviderInfo provider;
                var          resolvedPaths = context.SessionState.Path.GetResolvedProviderPathFromPSPath(psDataFilePath, out provider);

                // ConfigPath should be resolved as FileSystem provider
                if (provider == null || !Microsoft.PowerShell.Commands.FileSystemProvider.ProviderName.Equals(provider.Name, StringComparison.OrdinalIgnoreCase))
                {
                    isPathValid = false;
                }

                // ConfigPath should be resolved to a single path
                if (resolvedPaths.Count != 1)
                {
                    isPathValid = false;
                }

                if (!isPathValid)
                {
                    throw PSTraceSource.NewArgumentException(
                              parameterName,
                              ParserStrings.CannotResolvePowerShellDataFilePath,
                              psDataFilePath);
                }

                resolvedPath = resolvedPaths[0];

                #endregion "ValidatePowerShellDataFilePath"
            }

            #region "LoadAndEvaluatePowerShellDataFile"

            object evaluationResult;
            try
            {
                // Create the scriptInfo for the .psd1 file
                string      dataFileName       = Path.GetFileName(resolvedPath);
                var         dataFileScriptInfo = new ExternalScriptInfo(dataFileName, resolvedPath, context);
                ScriptBlock scriptBlock        = dataFileScriptInfo.ScriptBlock;

                // Validate the scriptblock
                scriptBlock.CheckRestrictedLanguage(allowedCommands, allowedVariables, allowEnvironmentVariables);

                // Evaluate the scriptblock
                object oldPsScriptRoot = context.GetVariableValue(SpecialVariables.PSScriptRootVarPath);
                try
                {
                    // Set the $PSScriptRoot before the evaluation
                    context.SetVariable(SpecialVariables.PSScriptRootVarPath, Path.GetDirectoryName(resolvedPath));
                    evaluationResult = PSObject.Base(scriptBlock.InvokeReturnAsIs());
                }
                finally
                {
                    context.SetVariable(SpecialVariables.PSScriptRootVarPath, oldPsScriptRoot);
                }
            }
            catch (RuntimeException ex)
            {
                throw PSTraceSource.NewInvalidOperationException(
                          ex,
                          ParserStrings.CannotLoadPowerShellDataFile,
                          psDataFilePath,
                          ex.Message);
            }

            if (!(evaluationResult is Hashtable retResult))
            {
                throw PSTraceSource.NewInvalidOperationException(
                          ParserStrings.InvalidPowerShellDataFile,
                          psDataFilePath);
            }

            #endregion "LoadAndEvaluatePowerShellDataFile"

            return(retResult);
        }
Пример #2
0
        internal static System.Management.Automation.Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm)
        {
            bool flag = false;

            System.Management.Automation.Signature signature = null;
            IntPtr zero   = IntPtr.Zero;
            uint   error  = 0;
            string pszOID = null;

            Utils.CheckArgForNullOrEmpty(fileName, "fileName");
            Utils.CheckArgForNull(certificate, "certificate");
            if (!string.IsNullOrEmpty(timeStampServerUrl) && ((timeStampServerUrl.Length <= 7) || (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0)))
            {
                throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "TimeStampUrlRequired", new object[0]);
            }
            if (!string.IsNullOrEmpty(hashAlgorithm))
            {
                IntPtr pvKey = Marshal.StringToHGlobalUni(hashAlgorithm);
                IntPtr ptr   = System.Management.Automation.Security.NativeMethods.CryptFindOIDInfo(2, pvKey, 0);
                if (ptr == IntPtr.Zero)
                {
                    throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]);
                }
                System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO crypt_oid_info = (System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)Marshal.PtrToStructure(ptr, typeof(System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO));
                pszOID = crypt_oid_info.pszOID;
            }
            if (!SecuritySupport.CertIsGoodForSigning(certificate))
            {
                throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "CertNotGoodForSigning", new object[0]);
            }
            SecuritySupport.CheckIfFileExists(fileName);
            try
            {
                string str2 = null;
                if (!string.IsNullOrEmpty(timeStampServerUrl))
                {
                    str2 = timeStampServerUrl;
                }
                System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO structure = System.Management.Automation.Security.NativeMethods.InitSignInfoStruct(fileName, certificate, str2, pszOID, option);
                zero = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure));
                Marshal.StructureToPtr(structure, zero, false);
                flag = System.Management.Automation.Security.NativeMethods.CryptUIWizDigitalSign(1, IntPtr.Zero, IntPtr.Zero, zero, IntPtr.Zero);
                Marshal.DestroyStructure(structure.pSignExtInfo, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO));
                Marshal.FreeCoTaskMem(structure.pSignExtInfo);
                if (!flag)
                {
                    error = GetLastWin32Error();
                    switch (error)
                    {
                    case 0x80004005:
                    case 0x80070001:
                    case 0x80072ee7:
                        flag = true;
                        goto Label_01CF;

                    case 0x80090008:
                        throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]);
                    }
                    tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}", new object[] { error });
                }
Label_01CF:
                if (flag)
                {
                    return(GetSignature(fileName, null));
                }
                signature = new System.Management.Automation.Signature(fileName, error);
            }
            finally
            {
                Marshal.DestroyStructure(zero, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO));
                Marshal.FreeCoTaskMem(zero);
            }
            return(signature);
        }
        } // SetFunction

        /// <summary>
        /// Set a function in the current scope of session state.
        /// </summary>
        ///
        /// <param name="name">
        /// The name of the function to set.
        /// </param>
        ///
        /// <param name="function">
        /// The new value of the function being set.
        /// </param>
        ///
        /// <param name="originalFunction">
        /// The original function (if any) from which the ScriptBlock is derived.
        /// </param>
        ///
        /// <param name="force">
        /// If true, the function will be set even if its ReadOnly.
        /// </param>
        ///
        /// <param name="origin">
        /// The origin of the caller
        /// </param>
        ///
        /// <exception cref="ArgumentException">
        /// If <paramref name="name"/> is null or empty.
        /// or
        /// If <paramref name="function"/> is not a <see cref="FilterInfo">FilterInfo</see>
        /// or <see cref="FunctionInfo">FunctionInfo</see>
        /// </exception>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="function"/> is null.
        /// </exception>
        ///
        /// <exception cref="SessionStateUnauthorizedAccessException">
        /// If the function is read-only or constant.
        /// </exception>
        ///
        internal FunctionInfo SetFunction(
            string name,
            ScriptBlock function,
            FunctionInfo originalFunction,
            bool force,
            CommandOrigin origin)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw PSTraceSource.NewArgumentException("name");
            }

            if (function == null)
            {
                throw PSTraceSource.NewArgumentNullException("function");
            }

            string originalName = name;

            FunctionLookupPath path = new FunctionLookupPath(name);

            name = path.UnqualifiedPath;

            if (String.IsNullOrEmpty(name))
            {
                SessionStateException exception =
                    new SessionStateException(
                        originalName,
                        SessionStateCategory.Function,
                        "ScopedFunctionMustHaveName",
                        SessionStateStrings.ScopedFunctionMustHaveName,
                        ErrorCategory.InvalidArgument);

                throw exception;
            }

            ScopedItemOptions options = ScopedItemOptions.None;

            if (path.IsPrivate)
            {
                options |= ScopedItemOptions.Private;
            }


            FunctionScopeItemSearcher searcher =
                new FunctionScopeItemSearcher(
                    this,
                    path,
                    origin);

            FunctionInfo result = null;

            SessionStateScope scope = searcher.InitialScope;

            if (searcher.MoveNext())
            {
                scope = searcher.CurrentLookupScope;
                name  = searcher.Name;

                if (path.IsPrivate)
                {
                    // Need to add the Private flag
                    FunctionInfo existingFunction = scope.GetFunction(name);
                    options |= existingFunction.Options;
                    result   = scope.SetFunction(name, function, originalFunction, options, force, origin, ExecutionContext);
                }
                else
                {
                    result = scope.SetFunction(name, function, force, origin, ExecutionContext);
                }
            }
            else
            {
                if (path.IsPrivate)
                {
                    result = scope.SetFunction(name, function, originalFunction, options, force, origin, ExecutionContext);
                }
                else
                {
                    result = scope.SetFunction(name, function, force, origin, ExecutionContext);
                }
            }
            return(result);
        }
Пример #4
0
        internal static Signature SignFile(SigningOption option,
                                           string fileName,
                                           X509Certificate2 certificate,
                                           string timeStampServerUrl,
                                           string hashAlgorithm)
        {
            bool      result    = false;
            Signature signature = null;
            IntPtr    pSignInfo = IntPtr.Zero;
            DWORD     error     = 0;
            string    hashOid   = null;

            Utils.CheckArgForNullOrEmpty(fileName, "fileName");
            Utils.CheckArgForNull(certificate, "certificate");

            // If given, TimeStamp server URLs must begin with http://
            if (!string.IsNullOrEmpty(timeStampServerUrl))
            {
                if ((timeStampServerUrl.Length <= 7) ||
                    (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0))
                {
                    throw PSTraceSource.NewArgumentException(
                              "certificate",
                              Authenticode.TimeStampUrlRequired);
                }
            }

            // Validate that the hash algorithm is valid
            if (!string.IsNullOrEmpty(hashAlgorithm))
            {
                IntPtr intptrAlgorithm = Marshal.StringToHGlobalUni(hashAlgorithm);

                IntPtr oidPtr = NativeMethods.CryptFindOIDInfo(NativeConstants.CRYPT_OID_INFO_NAME_KEY,
                                                               intptrAlgorithm,
                                                               0);

                // If we couldn't find an OID for the hash
                // algorithm, it was invalid.
                if (oidPtr == IntPtr.Zero)
                {
                    throw PSTraceSource.NewArgumentException(
                              "certificate",
                              Authenticode.InvalidHashAlgorithm);
                }
                else
                {
                    NativeMethods.CRYPT_OID_INFO oidInfo =
                        Marshal.PtrToStructure <NativeMethods.CRYPT_OID_INFO>(oidPtr);

                    hashOid = oidInfo.pszOID;
                }
            }

            if (!SecuritySupport.CertIsGoodForSigning(certificate))
            {
                throw PSTraceSource.NewArgumentException(
                          "certificate",
                          Authenticode.CertNotGoodForSigning);
            }

            SecuritySupport.CheckIfFileExists(fileName);
            // SecurityUtils.CheckIfFileSmallerThan4Bytes(fileName);

            try
            {
                // CryptUI is not documented either way, but does not
                // support empty strings for the timestamp server URL.
                // It expects null, only.  Instead, it randomly AVs if you
                // try.
                string timeStampServerUrlForCryptUI = null;
                if (!string.IsNullOrEmpty(timeStampServerUrl))
                {
                    timeStampServerUrlForCryptUI = timeStampServerUrl;
                }

                //
                // first initialize the struct to pass to
                // CryptUIWizDigitalSign() function
                //
                NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO si = NativeMethods.InitSignInfoStruct(fileName,
                                                                                                  certificate,
                                                                                                  timeStampServerUrlForCryptUI,
                                                                                                  hashOid,
                                                                                                  option);

                pSignInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(si));
                Marshal.StructureToPtr(si, pSignInfo, false);

                //
                // sign the file
                //
                // The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be
                // able to see that.
#pragma warning disable 56523
                result = NativeMethods.CryptUIWizDigitalSign(
                    (DWORD)NativeMethods.CryptUIFlags.CRYPTUI_WIZ_NO_UI,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    pSignInfo,
                    IntPtr.Zero);
#pragma warning enable 56523

                if (si.pSignExtInfo != null)
                {
                    Marshal.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO>(si.pSignExtInfo);
                    Marshal.FreeCoTaskMem(si.pSignExtInfo);
                }

                if (!result)
                {
                    error = GetLastWin32Error();

                    //
                    // ISSUE-2004/05/08-kumarp : there seems to be a bug
                    // in CryptUIWizDigitalSign().
                    // It returns 80004005 or 80070001
                    // but it signs the file correctly. Mask this error
                    // till we figure out this odd behavior.
                    //
                    if ((error == 0x80004005) ||
                        (error == 0x80070001) ||

                        // CryptUIWizDigitalSign introduced a breaking change in Win8 to return this
                        // error code (ERROR_INTERNET_NAME_NOT_RESOLVED) when you provide an invalid
                        // timestamp server. It used to be 0x80070001.
                        // Also masking this out so that we don't introduce a breaking change ourselves.
                        (error == 0x80072EE7)
                        )
                    {
                        result = true;
                    }
                    else
                    {
                        if (error == Win32Errors.NTE_BAD_ALGID)
                        {
                            throw PSTraceSource.NewArgumentException(
                                      "certificate",
                                      Authenticode.InvalidHashAlgorithm);
                        }

                        s_tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}",
                                            error);
                    }
                }

                if (result)
                {
                    signature = GetSignature(fileName, null);
                }
                else
                {
                    signature = new Signature(fileName, (DWORD)error);
                }
            }
            finally
            {
                Marshal.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO>(pSignInfo);
                Marshal.FreeCoTaskMem(pSignInfo);
            }

            return(signature);
        }
Пример #5
0
        } // SetLocation

        /// <summary>
        /// Changes the current working directory to the path specified
        /// </summary>
        /// <param name="path">
        /// The path of the new current working directory
        /// </param>
        /// <param name="context">
        /// The context the provider uses when performing the operation.
        /// </param>
        /// <returns>
        /// The PathInfo object representing the path of the location
        /// that was set.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If <paramref name="path"/> does not exist, is not a container, or
        /// resolved to multiple containers.
        /// </exception>
        /// <exception cref="ProviderNotFoundException">
        /// If <paramref name="path"/> refers to a provider that does not exist.
        /// </exception>
        /// <exception cref="DriveNotFoundException">
        /// If <paramref name="path"/> refers to a drive that does not exist.
        /// </exception>
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with <paramref name="path"/> threw an
        /// exception.
        /// </exception>
        /// <exception cref="ItemNotFoundException">
        /// If the <paramref name="path"/> could not be resolved.
        /// </exception>
        internal PathInfo SetLocation(string path, CmdletProviderContext context)
        {
            if (path == null)
            {
                throw PSTraceSource.NewArgumentNullException("path");
            }

            string       originalPath = path;
            string       driveName    = null;
            ProviderInfo provider     = null;
            string       providerId   = null;

            // Replace path with last working directory when '-' was passed.
            bool pushNextLocation = true;

            if (originalPath.Equals("-", StringComparison.OrdinalIgnoreCase))
            {
                if (_SetLocationHistory.Count <= 0)
                {
                    throw new InvalidOperationException(SessionStateStrings.SetContentToLastLocationWhenHistoryIsEmpty);
                }
                var previousLocation = _SetLocationHistory.Pop();
                path             = previousLocation.Path;
                pushNextLocation = false;
            }

            if (pushNextLocation)
            {
                var newPushPathInfo = GetNewPushPathInfo();
                _SetLocationHistory.Push(newPushPathInfo);
            }

            PSDriveInfo previousWorkingDrive = CurrentDrive;

            // First check to see if the path is a home path
            if (LocationGlobber.IsHomePath(path))
            {
                path = Globber.GetHomeRelativePath(path);
            }

            if (LocationGlobber.IsProviderDirectPath(path))
            {
                // The path is a provider-direct path so use the current
                // provider and its hidden drive but don't modify the path
                // at all.

                provider     = CurrentLocation.Provider;
                CurrentDrive = provider.HiddenDrive;
            }
            else if (LocationGlobber.IsProviderQualifiedPath(path, out providerId))
            {
                provider     = GetSingleProvider(providerId);
                CurrentDrive = provider.HiddenDrive;
            }
            else
            {
                // See if the path is a relative or absolute
                // path.

                if (Globber.IsAbsolutePath(path, out driveName))
                {
                    // Since the path is an absolute path
                    // we need to change the current working
                    // drive
                    PSDriveInfo newWorkingDrive = GetDrive(driveName);
                    CurrentDrive = newWorkingDrive;

                    // If the path is simply a colon-terminated drive,
                    // not a slash-terminated path to the root of a drive,
                    // set the path to the current working directory of that drive.
                    string colonTerminatedVolume = CurrentDrive.Name + ':';
                    if (CurrentDrive.VolumeSeparatedByColon && (path.Length == colonTerminatedVolume.Length))
                    {
                        path = Path.Combine((colonTerminatedVolume + Path.DirectorySeparatorChar), CurrentDrive.CurrentLocation);
                    }

                    // Now that the current working drive is set,
                    // process the rest of the path as a relative path.
                }
            }

            if (context == null)
            {
                context = new CmdletProviderContext(this.ExecutionContext);
            }

            if (CurrentDrive != null)
            {
                context.Drive = CurrentDrive;
            }

            CmdletProvider providerInstance = null;

            Collection <PathInfo> workingPath = null;

            try
            {
                workingPath =
                    Globber.GetGlobbedMonadPathsFromMonadPath(
                        path,
                        false,
                        context,
                        out providerInstance);
            }
            catch (LoopFlowException)
            {
                throw;
            }
            catch (PipelineStoppedException)
            {
                throw;
            }
            catch (ActionPreferenceStopException)
            {
                throw;
            }
            catch (Exception) // Catch-all OK, 3rd party callout
            {
                // Reset the drive to the previous drive and
                // then rethrow the error

                CurrentDrive = previousWorkingDrive;
                throw;
            }

            if (workingPath.Count == 0)
            {
                // Set the current working drive back to the previous
                // one in case it was changed.

                CurrentDrive = previousWorkingDrive;

                throw
                    new ItemNotFoundException(
                        path,
                        "PathNotFound",
                        SessionStateStrings.PathNotFound);
            }

            // We allow globbing the location as long as it only resolves a single container.

            bool foundContainer                     = false;
            bool pathIsContainer                    = false;
            bool pathIsProviderQualifiedPath        = false;
            bool currentPathisProviderQualifiedPath = false;

            for (int index = 0; index < workingPath.Count; ++index)
            {
                CmdletProviderContext normalizePathContext =
                    new CmdletProviderContext(context);

                PathInfo resolvedPath = workingPath[index];
                string   currentPath  = path;
                try
                {
                    string providerName = null;
                    currentPathisProviderQualifiedPath = LocationGlobber.IsProviderQualifiedPath(resolvedPath.Path, out providerName);
                    if (currentPathisProviderQualifiedPath)
                    {
                        // The path should be the provider-qualified path without the provider ID
                        // or ::

                        string providerInternalPath = LocationGlobber.RemoveProviderQualifier(resolvedPath.Path);

                        try
                        {
                            currentPath = NormalizeRelativePath(GetSingleProvider(providerName), providerInternalPath, String.Empty, normalizePathContext);
                        }
                        catch (NotSupportedException)
                        {
                            // Since the provider does not support normalizing the path, just
                            // use the path we currently have.
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception) // Catch-all OK, 3rd party callout
                        {
                            // Reset the drive to the previous drive and
                            // then rethrow the error

                            CurrentDrive = previousWorkingDrive;
                            throw;
                        }
                    }
                    else
                    {
                        try
                        {
                            currentPath = NormalizeRelativePath(resolvedPath.Path, CurrentDrive.Root, normalizePathContext);
                        }
                        catch (NotSupportedException)
                        {
                            // Since the provider does not support normalizing the path, just
                            // use the path we currently have.
                        }
                        catch (LoopFlowException)
                        {
                            throw;
                        }
                        catch (PipelineStoppedException)
                        {
                            throw;
                        }
                        catch (ActionPreferenceStopException)
                        {
                            throw;
                        }
                        catch (Exception) // Catch-all OK, 3rd party callout
                        {
                            // Reset the drive to the previous drive and
                            // then rethrow the error

                            CurrentDrive = previousWorkingDrive;
                            throw;
                        }
                    }

                    // Now see if there was errors while normalizing the path

                    if (normalizePathContext.HasErrors())
                    {
                        // Set the current working drive back to the previous
                        // one in case it was changed.

                        CurrentDrive = previousWorkingDrive;

                        normalizePathContext.ThrowFirstErrorOrDoNothing();
                    }
                }
                finally
                {
                    normalizePathContext.RemoveStopReferral();
                }

                // Check to see if the path is a container

                bool isContainer = false;

                CmdletProviderContext itemContainerContext =
                    new CmdletProviderContext(context);
                itemContainerContext.SuppressWildcardExpansion = true;

                try
                {
                    isContainer =
                        IsItemContainer(
                            resolvedPath.Path,
                            itemContainerContext);

                    if (itemContainerContext.HasErrors())
                    {
                        // Set the current working drive back to the previous
                        // one in case it was changed.

                        CurrentDrive = previousWorkingDrive;

                        itemContainerContext.ThrowFirstErrorOrDoNothing();
                    }
                }
                catch (NotSupportedException)
                {
                    if (currentPath.Length == 0)
                    {
                        // Treat this as a container because providers that only
                        // support the ContainerCmdletProvider interface are really
                        // containers at their root.

                        isContainer = true;
                    }
                }
                finally
                {
                    itemContainerContext.RemoveStopReferral();
                }

                if (isContainer)
                {
                    if (foundContainer)
                    {
                        // The path resolved to more than one container

                        // Set the current working drive back to the previous
                        // one in case it was changed.

                        CurrentDrive = previousWorkingDrive;

                        throw
                            PSTraceSource.NewArgumentException(
                                "path",
                                SessionStateStrings.PathResolvedToMultiple,
                                originalPath);
                    }
                    else
                    {
                        // Set the path to use
                        path = currentPath;

                        // Mark it as a container
                        pathIsContainer = true;

                        // Mark whether or not it was provider-qualified
                        pathIsProviderQualifiedPath = currentPathisProviderQualifiedPath;

                        // Mark that we have already found one container. Finding additional
                        // should be an error
                        foundContainer = true;
                    }
                }
            }

            if (pathIsContainer)
            {
                // Remove the root slash since it is implied that the
                // current working directory is relative to the root.

                if (!LocationGlobber.IsProviderDirectPath(path) &&
                    path.StartsWith(StringLiterals.DefaultPathSeparatorString, StringComparison.CurrentCulture) &&
                    !pathIsProviderQualifiedPath)
                {
                    path = path.Substring(1);
                }

                s_tracer.WriteLine(
                    "New working path = {0}",
                    path);

                CurrentDrive.CurrentLocation = path;
            }
            else
            {
                // Set the current working drive back to the previous
                // one in case it was changed.

                CurrentDrive = previousWorkingDrive;

                throw
                    new ItemNotFoundException(
                        originalPath,
                        "PathNotFound",
                        SessionStateStrings.PathNotFound);
            }

            // Now make sure the current drive is set in the provider's
            // current working drive hashtable

            ProvidersCurrentWorkingDrive[CurrentDrive.Provider] =
                CurrentDrive;

            // Set the $PWD variable to the new location

            this.SetVariable(SpecialVariables.PWDVarPath, this.CurrentLocation, false, true, CommandOrigin.Internal);
            return(this.CurrentLocation);
        } // SetLocation
Пример #6
0
        /// <summary>
        /// Resets the current working drive and directory to the first
        /// entry on the working directory stack and removes that entry
        /// from the stack.
        /// </summary>
        /// <param name="stackName">
        /// The ID of the stack to pop the location from. If it is null or
        /// empty the default stack is used.
        /// </param>
        /// <returns>
        /// A PathInfo object representing the location that was popped
        /// from the location stack and set as the new location.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// If the path on the stack does not exist, is not a container, or
        /// resolved to multiple containers.
        /// or
        /// If <paramref name="stackName"/> contains wildcard characters and resolves
        /// to multiple location stacks.
        /// or
        /// A stack was not found with the specified name.
        /// </exception>
        /// <exception cref="ProviderNotFoundException">
        /// If the path on the stack refers to a provider that does not exist.
        /// </exception>
        /// <exception cref="DriveNotFoundException">
        /// If the path on the stack refers to a drive that does not exist.
        /// </exception>
        /// <exception cref="ProviderInvocationException">
        /// If the provider associated with the path on the stack threw an
        /// exception.
        /// </exception>
        internal PathInfo PopLocation(string stackName)
        {
            if (String.IsNullOrEmpty(stackName))
            {
                stackName = _defaultStackName;
            }

            if (WildcardPattern.ContainsWildcardCharacters(stackName))
            {
                // Need to glob the stack name, but it can only glob to a single.

                bool haveMatch = false;

                WildcardPattern stackNamePattern =
                    WildcardPattern.Get(stackName, WildcardOptions.IgnoreCase);

                foreach (string key in _workingLocationStack.Keys)
                {
                    if (stackNamePattern.IsMatch(key))
                    {
                        if (haveMatch)
                        {
                            throw
                                PSTraceSource.NewArgumentException(
                                    "stackName",
                                    SessionStateStrings.StackNameResolvedToMultiple,
                                    stackName);
                        }
                        haveMatch = true;
                        stackName = key;
                    }
                }
            }

            PathInfo result = CurrentLocation;

            try
            {
                Stack <PathInfo> locationStack = null;
                if (!_workingLocationStack.TryGetValue(stackName, out locationStack))
                {
                    if (!string.Equals(stackName, startingDefaultStackName, StringComparison.OrdinalIgnoreCase))
                    {
                        throw
                            PSTraceSource.NewArgumentException(
                                "stackName",
                                SessionStateStrings.StackNotFound,
                                stackName);
                    }
                    return(null);
                }

                PathInfo poppedWorkingDirectory = locationStack.Pop();

                Dbg.Diagnostics.Assert(
                    poppedWorkingDirectory != null,
                    "All items in the workingLocationStack should be " +
                    "of type PathInfo");

                string newPath =
                    LocationGlobber.GetMshQualifiedPath(
                        WildcardPattern.Escape(poppedWorkingDirectory.Path),
                        poppedWorkingDirectory.GetDrive());

                result = SetLocation(newPath);

                if (locationStack.Count == 0 &&
                    !String.Equals(stackName, startingDefaultStackName, StringComparison.OrdinalIgnoreCase))
                {
                    // Remove the stack from the stack list if it
                    // no longer contains any paths.

                    _workingLocationStack.Remove(stackName);
                }
            }
            catch (InvalidOperationException)
            {
                // This is a no-op. We stay with the current working
                // directory.
            }

            return(result);
        }
        /// <summary>
        /// Constructs an instance of the CompiledCommandAttribute using the reflection information retrieved
        /// from the enclosing bindable object type.
        /// </summary>
        ///
        /// <param name="member">
        /// The member information for the parameter
        /// </param>
        ///
        /// <param name="processingDynamicParameters">
        /// True if dynamic parameters are being processed, or false otherwise.
        /// </param>
        ///
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="member"/> is null.
        /// </exception>
        ///
        /// <exception cref="ArgumentException">
        /// If <paramref name="member"/> is not a field or a property.
        /// </exception>
        ///
        /// <exception cref="MetadataException">
        /// If the member has more than one <see cref="ParameterAttribute">ParameterAttribute</see>
        /// that defines the same parameter-set name.
        /// </exception>
        ///
        internal CompiledCommandParameter(MemberInfo member, bool processingDynamicParameters)
        {
            if (member == null)
            {
                throw PSTraceSource.NewArgumentNullException("member");
            }

            this.Name          = member.Name;
            this.DeclaringType = member.DeclaringType;
            this.IsDynamic     = processingDynamicParameters;

            var propertyInfo = member as PropertyInfo;

            if (propertyInfo != null)
            {
                this.Type = propertyInfo.PropertyType;
            }
            else
            {
                var fieldInfo = member as FieldInfo;
                if (fieldInfo != null)
                {
                    this.Type = fieldInfo.FieldType;
                }
                else
                {
                    ArgumentException e =
                        PSTraceSource.NewArgumentException(
                            "member",
                            DiscoveryExceptions.CompiledCommandParameterMemberMustBeFieldOrProperty);

                    throw e;
                }
            }

            this.CollectionTypeInformation = new ParameterCollectionTypeInformation(this.Type);
            this.CompiledAttributes        = new Collection <Attribute>();
            this.ParameterSetData          = new Dictionary <string, ParameterSetSpecificMetadata>(StringComparer.OrdinalIgnoreCase);

            // We do not want to get the inherited custom attributes, only the attributes exposed
            // directly on the member

            var memberAttributes = member.GetCustomAttributes(false);

            Collection <ValidateArgumentsAttribute>      validationAttributes        = null;
            Collection <ArgumentTransformationAttribute> argTransformationAttributes = null;

            string[] aliases = null;

            foreach (Attribute attr in memberAttributes)
            {
                switch (attr)
                {
                case ExperimentalAttribute _:
                case ParameterAttribute param when param.ToHide:
                    break;

                default:
                    ProcessAttribute(member.Name, attr, ref validationAttributes, ref argTransformationAttributes, ref aliases);
                    break;
                }
            }

            this.ValidationAttributes = validationAttributes == null
                ? Utils.EmptyArray <ValidateArgumentsAttribute>()
                : validationAttributes.ToArray();

            this.ArgumentTransformationAttributes = argTransformationAttributes == null
                ? Utils.EmptyArray <ArgumentTransformationAttribute>()
                : argTransformationAttributes.ToArray();

            this.Aliases = aliases ?? Utils.EmptyArray <string>();
        }
Пример #8
0
        /// <summary>
        /// Given a scope identifier, returns the proper session state scope.
        /// </summary>
        /// <param name="scopeID">
        /// A scope identifier that is either one of the "special" scopes like
        /// "global", "local", or "private, or a numeric ID of a relative scope
        /// to the current scope.
        /// </param>
        /// <returns>
        /// The scope identified by the scope ID or the current scope if the
        /// scope ID is not defined as a special or numeric scope identifier.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// If <paramref name="scopeID"/> is less than zero, or not
        /// a number and not "script", "global", "local", or "private"
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently
        /// active scopes.
        /// </exception>
        internal SessionStateScope GetScopeByID(string scopeID)
        {
            SessionStateScope result = _currentScope;

            if (!string.IsNullOrEmpty(scopeID))
            {
                if (string.Equals(
                        scopeID,
                        StringLiterals.Global,
                        StringComparison.OrdinalIgnoreCase))
                {
                    result = GlobalScope;
                }
                else if (string.Equals(
                             scopeID,
                             StringLiterals.Local,
                             StringComparison.OrdinalIgnoreCase))
                {
                    result = _currentScope;
                }
                else if (string.Equals(
                             scopeID,
                             StringLiterals.Private,
                             StringComparison.OrdinalIgnoreCase))
                {
                    result = _currentScope;
                }
                else if (string.Equals(
                             scopeID,
                             StringLiterals.Script,
                             StringComparison.OrdinalIgnoreCase))
                {
                    // Get the current script scope from the stack.
                    result = _currentScope.ScriptScope;
                }
                else
                {
                    // Since the scope is not any of the special scopes
                    // try parsing it as an ID

                    try
                    {
                        int scopeNumericID = Int32.Parse(scopeID, System.Globalization.CultureInfo.CurrentCulture);

                        if (scopeNumericID < 0)
                        {
                            throw PSTraceSource.NewArgumentOutOfRangeException(ScopeParameterName, scopeID);
                        }

                        result = GetScopeByID(scopeNumericID) ?? _currentScope;
                    }
                    catch (FormatException)
                    {
                        throw PSTraceSource.NewArgumentException(ScopeParameterName, AutomationExceptions.InvalidScopeIdArgument, ScopeParameterName);
                    }
                    catch (OverflowException)
                    {
                        throw PSTraceSource.NewArgumentOutOfRangeException(ScopeParameterName, scopeID);
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Gets the parameters by matching its name.
        /// </summary>
        ///
        /// <param name="name">
        /// The name of the parameter.
        /// </param>
        ///
        /// <param name="throwOnParameterNotFound">
        /// If true and a matching parameter is not found, an exception will be
        /// throw. If false and a matching parameter is not found, null is returned.
        /// </param>
        ///
        /// <param name="tryExactMatching">
        /// If true we do exact matching, otherwise we do not.
        /// </param>
        ///
        /// <param name="invocationInfo">
        /// The invocation information about the code being run.
        /// </param>
        ///
        /// <returns>
        /// The a collection of the metadata associated with the parameters that
        /// match the specified name. If no matches were found, an empty collection
        /// is returned.
        /// </returns>
        ///
        /// <exception cref="ArgumentException">
        /// If <paramref name="name"/> is null or empty.
        /// </exception>
        ///
        internal MergedCompiledCommandParameter GetMatchingParameter(
            string name,
            bool throwOnParameterNotFound,
            bool tryExactMatching,
            InvocationInfo invocationInfo)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw PSTraceSource.NewArgumentException("name");
            }

            Collection <MergedCompiledCommandParameter> matchingParameters =
                new Collection <MergedCompiledCommandParameter>();

            // Skip the leading '-' if present
            if (name.Length > 0 && SpecialCharacters.IsDash(name[0]))
            {
                name = name.Substring(1);
            }


            // First try to match the bindable parameters

            foreach (string parameterName in _bindableParameters.Keys)
            {
                if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase))
                {
                    // If it is an exact match then only return the exact match
                    // as the result

                    if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase))
                    {
                        return(_bindableParameters[parameterName]);
                    }
                    else
                    {
                        matchingParameters.Add(_bindableParameters[parameterName]);
                    }
                }
            }

            // Now check the aliases

            foreach (string parameterName in _aliasedParameters.Keys)
            {
                if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase))
                {
                    // If it is an exact match then only return the exact match
                    // as the result

                    if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase))
                    {
                        return(_aliasedParameters[parameterName]);
                    }
                    else
                    {
                        if (!matchingParameters.Contains(_aliasedParameters[parameterName]))
                        {
                            matchingParameters.Add(_aliasedParameters[parameterName]);
                        }
                    }
                }
            }

            if (matchingParameters.Count > 1)
            {
                // Prefer parameters in the cmdlet over common parameters
                Collection <MergedCompiledCommandParameter> filteredParameters =
                    new Collection <MergedCompiledCommandParameter>();

                foreach (MergedCompiledCommandParameter matchingParameter in matchingParameters)
                {
                    if ((matchingParameter.BinderAssociation == ParameterBinderAssociation.DeclaredFormalParameters) ||
                        (matchingParameter.BinderAssociation == ParameterBinderAssociation.DynamicParameters))
                    {
                        filteredParameters.Add(matchingParameter);
                    }
                }

                if (filteredParameters.Count == 1)
                {
                    matchingParameters = filteredParameters;
                }
                else
                {
                    StringBuilder possibleMatches = new StringBuilder();

                    foreach (MergedCompiledCommandParameter matchingParameter in matchingParameters)
                    {
                        possibleMatches.Append(" -");
                        possibleMatches.Append(matchingParameter.Parameter.Name);
                    }

                    ParameterBindingException exception =
                        new ParameterBindingException(
                            ErrorCategory.InvalidArgument,
                            invocationInfo,
                            null,
                            name,
                            null,
                            null,
                            ParameterBinderStrings.AmbiguousParameter,
                            "AmbiguousParameter",
                            possibleMatches);

                    throw exception;
                }
            }
            else if (matchingParameters.Count == 0)
            {
                if (throwOnParameterNotFound)
                {
                    ParameterBindingException exception =
                        new ParameterBindingException(
                            ErrorCategory.InvalidArgument,
                            invocationInfo,
                            null,
                            name,
                            null,
                            null,
                            ParameterBinderStrings.NamedParameterNotFound,
                            "NamedParameterNotFound");

                    throw exception;
                }
            }

            MergedCompiledCommandParameter result = null;

            if (matchingParameters.Count > 0)
            {
                result = matchingParameters[0];
            }
            return(result);
        } // GetMatchingParameter
        /// <summary>
        /// Constructs a scoped item lookup path.
        /// </summary>
        /// <param name="path">The path to parse.</param>
        /// <param name="knownFlags">
        /// These flags for anything known about the path (such as, is it a function) before
        /// being scanned.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="path"/> is null.
        /// </exception>
        internal VariablePath(string path, VariablePathFlags knownFlags)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw PSTraceSource.NewArgumentException(nameof(path));
            }

            _userPath = path;
            _flags    = knownFlags;

            string            candidateScope      = null;
            string            candidateScopeUpper = null;
            VariablePathFlags candidateFlags      = VariablePathFlags.Unqualified;

            int currentCharIndex = 0;
            int lastScannedColon = -1;

scanScope:
            switch (path[0])
            {
            case 'g':
            case 'G':
                candidateScope      = "lobal";
                candidateScopeUpper = "LOBAL";
                candidateFlags      = VariablePathFlags.Global;
                break;

            case 'l':
            case 'L':
                candidateScope      = "ocal";
                candidateScopeUpper = "OCAL";
                candidateFlags      = VariablePathFlags.Local;
                break;

            case 'p':
            case 'P':
                candidateScope      = "rivate";
                candidateScopeUpper = "RIVATE";
                candidateFlags      = VariablePathFlags.Private;
                break;

            case 's':
            case 'S':
                candidateScope      = "cript";
                candidateScopeUpper = "CRIPT";
                candidateFlags      = VariablePathFlags.Script;
                break;

            case 'v':
            case 'V':
                if (knownFlags == VariablePathFlags.None)
                {
                    // If we see 'variable:', our namespaceId will be empty, and
                    // we'll also need to scan for the scope again.
                    candidateScope      = "ariable";
                    candidateScopeUpper = "ARIABLE";
                    candidateFlags      = VariablePathFlags.Variable;
                }

                break;
            }

            if (candidateScope != null)
            {
                currentCharIndex += 1; // First character already matched.
                int j;
                for (j = 0; currentCharIndex < path.Length && j < candidateScope.Length; ++j, ++currentCharIndex)
                {
                    if (path[currentCharIndex] != candidateScope[j] && path[currentCharIndex] != candidateScopeUpper[j])
                    {
                        break;
                    }
                }

                if (j == candidateScope.Length &&
                    currentCharIndex < path.Length &&
                    path[currentCharIndex] == ':')
                {
                    if (_flags == VariablePathFlags.None)
                    {
                        _flags = VariablePathFlags.Variable;
                    }

                    _flags           |= candidateFlags;
                    lastScannedColon  = currentCharIndex;
                    currentCharIndex += 1;

                    // If saw 'variable:', we need to look for a scope after 'variable:'.
                    if (candidateFlags == VariablePathFlags.Variable)
                    {
                        knownFlags     = VariablePathFlags.Variable;
                        candidateScope = candidateScopeUpper = null;
                        candidateFlags = VariablePathFlags.None;
                        goto scanScope;
                    }
                }
            }

            if (_flags == VariablePathFlags.None)
            {
                lastScannedColon = path.IndexOf(':', currentCharIndex);
                // No colon, or a colon as the first character means we have
                // a simple variable, otherwise it's a drive.
                if (lastScannedColon > 0)
                {
                    _flags = VariablePathFlags.DriveQualified;
                }
            }

            if (lastScannedColon == -1)
            {
                _unqualifiedPath = _userPath;
            }
            else
            {
                _unqualifiedPath = _userPath.Substring(lastScannedColon + 1);
            }

            if (_flags == VariablePathFlags.None)
            {
                _flags = VariablePathFlags.Unqualified | VariablePathFlags.Variable;
            }
        }
Пример #11
0
        /// <summary>
        /// Gets the ResourceManager from the cache or gets an instance of the ResourceManager
        /// and returns it if it isn't already present in the cache.
        /// </summary>
        /// <param name="assembly">
        /// The assembly to be used as the base for resource lookup.
        /// </param>
        /// <param name="baseName">
        /// The base name of the resources to get the ResourceManager for.
        /// </param>
        /// <returns>
        /// A ResourceManager instance for the assembly and base name that were specified.
        /// </returns>
        internal static ResourceManager GetResourceManager(
            Assembly assembly,
            string baseName)
        {
            if (assembly == null)
            {
                throw PSTraceSource.NewArgumentNullException("assembly");
            }

            if (String.IsNullOrEmpty(baseName))
            {
                throw PSTraceSource.NewArgumentException("baseName");
            }

            // Check to see if the manager is already in the cache

            ResourceManager manager = null;
            Dictionary <string, ResourceManager> baseNameCache;

            string assemblyManifestFileLocation = assembly.Location;

            lock (s_syncRoot)
            {
                // First do the lookup based on the assembly location

                if (s_resourceManagerCache.TryGetValue(assemblyManifestFileLocation, out baseNameCache) && baseNameCache != null)
                {
                    // Now do the lookup based on the resource base name
                    baseNameCache.TryGetValue(baseName, out manager);
                }
            }

            // If it's not in the cache, create it an add it.
            if (manager == null)
            {
                manager = InitRMWithAssembly(baseName, assembly);

                // Add the new resource manager to the hash

                if (baseNameCache != null)
                {
                    lock (s_syncRoot)
                    {
                        // Since the assembly is already cached, we just have
                        // to cache the base name entry

                        baseNameCache[baseName] = manager;
                    }
                }
                else
                {
                    // Since the assembly wasn't cached, we have to create base name
                    // cache entry and then add it into the cache keyed by the assembly
                    // location

                    var baseNameCacheEntry = new Dictionary <string, ResourceManager>();

                    baseNameCacheEntry[baseName] = manager;

                    lock (s_syncRoot)
                    {
                        s_resourceManagerCache[assemblyManifestFileLocation] = baseNameCacheEntry;
                    }
                }
            }

            Diagnostics.Assert(
                manager != null,
                "If the manager was not already created, it should have been dynamically created or an exception should have been thrown");

            return(manager);
        }
Пример #12
0
        internal VariablePath(string path, VariablePathFlags knownFlags)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw PSTraceSource.NewArgumentException("path");
            }
            this._userPath = path;
            this._flags    = knownFlags;
            string            str         = null;
            string            str2        = null;
            VariablePathFlags unqualified = VariablePathFlags.Unqualified;
            int startIndex = 0;
            int index      = -1;

Label_0036:
            switch (path[0])
            {
            case 'P':
            case 'p':
                str         = "rivate";
                str2        = "RIVATE";
                unqualified = VariablePathFlags.Private;
                break;

            case 'S':
            case 's':
                str         = "cript";
                str2        = "CRIPT";
                unqualified = VariablePathFlags.Script;
                break;

            case 'V':
            case 'v':
                if (knownFlags == VariablePathFlags.None)
                {
                    str         = "ariable";
                    str2        = "ARIABLE";
                    unqualified = VariablePathFlags.Variable;
                }
                break;

            case 'G':
            case 'g':
                str         = "lobal";
                str2        = "LOBAL";
                unqualified = VariablePathFlags.Global;
                break;

            case 'L':
            case 'l':
                str         = "ocal";
                str2        = "OCAL";
                unqualified = VariablePathFlags.Local;
                break;
            }
            if (str != null)
            {
                startIndex++;
                int num3 = 0;
                while ((startIndex < path.Length) && (num3 < str.Length))
                {
                    if ((path[startIndex] != str[num3]) && (path[startIndex] != str2[num3]))
                    {
                        break;
                    }
                    num3++;
                    startIndex++;
                }
                if (((num3 == str.Length) && (startIndex < path.Length)) && (path[startIndex] == ':'))
                {
                    if (this._flags == VariablePathFlags.None)
                    {
                        this._flags = VariablePathFlags.Variable;
                    }
                    this._flags |= unqualified;
                    index        = startIndex;
                    startIndex++;
                    if (unqualified == VariablePathFlags.Variable)
                    {
                        knownFlags  = VariablePathFlags.Variable;
                        str         = (string)(str2 = null);
                        unqualified = VariablePathFlags.None;
                        goto Label_0036;
                    }
                }
            }
            if (this._flags == VariablePathFlags.None)
            {
                index = path.IndexOf(':', startIndex);
                if (index > 0)
                {
                    this._flags = VariablePathFlags.DriveQualified;
                }
            }
            if (index == -1)
            {
                this._unqualifiedPath = this._userPath;
            }
            else
            {
                this._unqualifiedPath = this._userPath.Substring(index + 1);
            }
            if (this._flags == VariablePathFlags.None)
            {
                this._flags = VariablePathFlags.Unqualified | VariablePathFlags.Variable;
            }
        }
Пример #13
0
        /// <summary>
        /// Constructor for the ProviderInfo class.
        /// </summary>
        /// 
        /// <param name="sessionState">
        /// The instance of session state that the provider is being added to.
        /// </param>
        /// 
        /// <param name="implementingType">
        /// The type that implements the provider
        /// </param>
        /// 
        /// <param name="name">
        /// The alternate name to use for the provider instead of the one specified
        /// in the .cmdletprovider file.
        /// </param>
        /// 
        /// <param name="description">
        /// The description of the provider.
        /// </param>
        /// 
        /// <param name="home">
        /// The home path for the provider. This must be an MSH path.
        /// </param>
        /// 
        /// <param name="helpFile">
        /// The help file for the provider.
        /// </param>
        /// 
        /// <param name="psSnapIn">
        /// The Snap-In for the provider.
        /// </param>
        /// 
        /// <exception cref="ArgumentNullException">
        /// If <paramref name="implementingType"/> or <paramref name="sessionState"/> is null.
        /// </exception>
        /// 
        /// <exception cref="ArgumentException">
        /// If <paramref name="name"/> is null or empty.
        /// </exception>
        /// 
        internal ProviderInfo(
            SessionState sessionState,
            Type implementingType,
            string name,
            string description,
            string home,
            string helpFile,
            PSSnapInInfo psSnapIn)
        {
            // Verify parameters
            if (sessionState == null)
            {
                throw PSTraceSource.NewArgumentNullException("sessionState");
            }

            if (implementingType == null)
            {
                throw PSTraceSource.NewArgumentNullException("implementingType");
            }

            if (String.IsNullOrEmpty(name))
            {
                throw PSTraceSource.NewArgumentException("name");
            }


            if (String.IsNullOrEmpty(name))
            {
                throw PSTraceSource.NewArgumentException("name");
            }

            _sessionState = sessionState;

            Name = name;
            Description = description;
            Home = home;
            ImplementingType = implementingType;
            HelpFile = helpFile;
            PSSnapIn = psSnapIn;

#if SUPPORTS_CMDLETPROVIDER_FILE
            LoadProviderFromPath(path);
#endif
            // Create the hidden drive. The name doesn't really
            // matter since we are not adding this drive to a scope.

            _hiddenDrive =
                new PSDriveInfo(
                    this.FullName,
                    this,
                    "",
                    "",
                    null);

            _hiddenDrive.Hidden = true;

            // TODO:PSL
            // this is probably not right here
            if (implementingType == typeof(Microsoft.PowerShell.Commands.FileSystemProvider) && !Platform.IsWindows)
            {
                VolumeSeparatedByColon = false;
            }
        }