public IntPtr GetFirstCert(CertificateFilterInfo filter)
 {
     this.filterHandle = null;
     if (X509NativeStore.fIsWin8AndAbove && filter != null)
     {
         IntPtr zero = IntPtr.Zero;
         this.filterHandle = new CertificateFilterHandle();
         int num = NativeMethods.CCFindCertificateBuildFilter(filter.FilterString, ref zero);
         if (num == 0)
         {
             this.filterHandle.Handle = zero;
         }
         else
         {
             this.filterHandle = null;
             throw new Win32Exception(num);
         }
     }
     return(this.GetNextCert(IntPtr.Zero));
 }
        public IntPtr GetFirstCert(
            CertificateFilterInfo filter)
        {
            _filterHandle = null;
            if (DownLevelHelper.NativeFilteringSupported() && filter != null)
            {
                IntPtr hFilter = IntPtr.Zero;

                _filterHandle = new CertificateFilterHandle();
                int hr = Security.NativeMethods.CCFindCertificateBuildFilter(
                                                    filter.FilterString,
                                                    ref hFilter);
                if (hr != Security.NativeConstants.S_OK)
                {
                    _filterHandle = null;
                    throw new System.ComponentModel.Win32Exception(hr);
                }
                _filterHandle.Handle = hFilter;
            }
            return GetNextCert(IntPtr.Zero);
        }
        // If it's Win8 or above, filter matching for certain properties is done by
        // the certificate enumeration filter at the API level. In that case,
        // filter.Purpose will be 'None' and MatchesFilter will return 'True'.
        private static bool MatchesFilter(X509Certificate2 cert,
                                   CertificateFilterInfo filter)
        {
            //
            // no filter means, match everything
            //
            if ((filter == null) ||
                (filter.Purpose == CertificatePurpose.NotSpecified) ||
                (filter.Purpose == CertificatePurpose.All))
            {
                return true;
            }

            switch (filter.Purpose)
            {
                case CertificatePurpose.CodeSigning:
                    if (SecuritySupport.CertIsGoodForSigning(cert))
                    {
                        return true;
                    }
                    break;

                case CertificatePurpose.DocumentEncryption:
                    if (SecuritySupport.CertIsGoodForEncryption(cert))
                    {
                        return true;
                    }
                    break;

                default:
                    break;
            }

            return false;
        }
        private CertificateFilterInfo GetFilter()
        {
            CertificateFilterInfo filter = null;

            if (DynamicParameters != null)
            {
                if (DownLevelHelper.NativeFilteringSupported())
                {
                    CertificateProviderDynamicParameters dp =
                        DynamicParameters as CertificateProviderDynamicParameters;
                    if (dp != null)
                    {
                        bool filterSpecified = false;

                        filter = new CertificateFilterInfo();
                        if (dp.CodeSigningCert)
                        {
                            filter.Purpose = CertificatePurpose.CodeSigning;
                            filterSpecified = true;
                        }
                        if (dp.DocumentEncryptionCert)
                        {
                            filter.Purpose = CertificatePurpose.DocumentEncryption;
                            filterSpecified = true;
                        }
                        if (dp.SSLServerAuthentication)
                        {
                            filter.SSLServerAuthentication = true;
                            filterSpecified = true;
                        }
                        if (dp.DnsName.Punycode != null)
                        {
                            filter.DnsName = dp.DnsName.Punycode;
                            filterSpecified = true;
                        }
                        if (dp.Eku != null)
                        {
                            filter.Eku = dp.Eku;
                            filterSpecified = true;
                        }
                        if (dp.ExpiringInDays >= 0)
                        {
                            filter.ExpiringInDays = dp.ExpiringInDays;
                            filterSpecified = true;
                        }
                        if (!filterSpecified)
                        {
                            filter = null;
                        }
                    }
                }
                else
                {
                    CertificateProviderCodeSigningDynamicParameters dp =
                        DynamicParameters as CertificateProviderCodeSigningDynamicParameters;
                    if (dp != null)
                    {
                        if (dp.CodeSigningCert)
                        {
                            filter = new CertificateFilterInfo();
                            filter.Purpose = CertificatePurpose.CodeSigning;
                        }
                    }
                }
            }
            return filter;
        }
        /// <summary>
        /// gets X509NativeStore objects or their name at the specified path.
        /// </summary>
        ///
        /// <param name="path"> path to the store </param>
        ///
        /// <param name="recurse"> recursively return all items if true </param>
        ///
        /// <param name="returnNames">  </param>
        ///
        /// <param name="filter"> filter info </param>
        ///
        /// <returns> Does not return a value </returns>
        ///
        /// <remarks>  </remarks>
        ///
        private void GetStoresOrNames(
            string path,
            bool recurse,
            bool returnNames,
            CertificateFilterInfo filter)
        {
            object thingToReturn = null;

            X509StoreLocation location = GetStoreLocation(path);

            string storePath = null;

            //
            // enumerate over each store
            //
            foreach (string name in location.StoreNames.Keys)
            {
                storePath = MakePath(path, name);
                if (returnNames)
                {
                    thingToReturn = name;
                }
                else
                {
                    X509NativeStore store = GetStore(storePath, name, location);
                    X509Store ManagedStore = new X509Store(
                                                    store.StoreName,
                                                    store.Location.Location);
                    thingToReturn = ManagedStore;
                }

                // 'returnNames' is true only when called from
                // GetChildNames(), in which case 'recurse' will always be
                // false.  When the -Path parameter needs to be globbed,
                // the potential store names should be returned by
                // calling this method from GetChildNames.

                // The original code didn't have a "|| returnNames" clause.
                // Suppose the user types:
                //     dir cert:\CurrentUser\Tru* -CodeSigningCert -recurse
                // We need to do path globbing here to resolve wild cards.
                // Since -CodeSigningCert is present, 'filter' is not null.
                // Since this method is called from GetChildNames() when
                // doing the path globbing, 'returnNames' is true and
                // 'recurse' is false.
                // In the original code, nothing was returned by
                // WriteItemObject(), so the path globbing fails and the
                // above dir command would not display the certificates
                // as expected.

                // Another case is:
                //     dir cert:\CurrentUser -CodeSigningCert -Recurse
                // -Recurse is present, so we need to call
                // DoManualGetChildItems, and inside DoManualGetChildItems,
                // this method will be called to get the names.
                // The original code had the same problem for this case.

                // With the "|| returnNames" clause, we test if this method
                // is called from the GetChildNames().  When this method is
                // called from GetChildNames(), 'recurse' will always be
                // false.  Then we should return the names whether 'filter'
                // is null or not.

                if (filter == null || returnNames)
                {
                    WriteItemObject(thingToReturn, name, true);
                }

                //
                // if recurse is true, get cert objects (or names) as well
                //
                if (recurse)
                {
                    string[] pathElements = GetPathElements(storePath);
                    GetCertificatesOrNames(
                                    storePath,
                                    pathElements,
                                    returnNames,
                                    filter);
                }
            }
        }
        /// <summary>
        /// Get cert objects or their name at the specified path
        /// </summary>
        ///
        /// <param name="path"> path to cert </param>
        ///
        /// <param name="pathElements"> path elements </param>
        ///
        /// <param name="returnNames"> whether we should return only the names (instead of objects) </param>
        ///
        /// <param name="filter"> filter info </param>
        ///
        /// <returns> Does not return a value </returns>
        ///
        private void GetCertificatesOrNames(string path,
                                             string[] pathElements,
                                             bool returnNames,
                                             CertificateFilterInfo filter)
        {
            object thingToReturn = null;
            string certPath = null;
            X509NativeStore store = null;

            //
            // first open the store
            //

            store = GetStore(path, false, pathElements);
            store.Open(IncludeArchivedCerts());

            //
            // enumerate over each cert and return it (or its name)
            //
            IntPtr certContext = store.GetFirstCert(filter);

            while (IntPtr.Zero != certContext)
            {
                X509Certificate2 cert = new X509Certificate2(certContext);

                if (MatchesFilter(cert, filter))
                {
                    string certName = GetCertName(cert);
                    certPath = MakePath(path, certName);

                    if (returnNames)
                    {
                        thingToReturn = (object)certName;
                    }
                    else
                    {
#if CORECLR
                        //TODO:CORECLR See if there is a need to create a copy of cert like its done on Full PS
                        X509Certificate2 cert2 = cert;
#else
                        X509Certificate2 cert2 = new X509Certificate2(cert);
#endif
                        PSObject myPsObj = new PSObject(cert2);
                        thingToReturn = (object)myPsObj;
                    }
                    WriteItemObject(thingToReturn, certPath, false);
                }
                certContext = store.GetNextCert(certContext);
            }
        }
        /// <summary>
        /// Helper function to get store-location/store/cert at
        /// the specified path.
        /// </summary>
        ///
        /// <param name="path"> path to the item  </param>
        ///
        /// <param name="recurse"> whether we need to recursively find all </param>
        ///
        /// <param name="returnContainers">
        /// Determines if all containers should be returned or only those containers that match the
        /// filter(s).
        /// </param>
        ///
        /// <param name="returnNames"> whether we only need the names </param>
        ///
        /// <param name="filter"> filter info </param>
        ///
        /// <returns> Does not return a value </returns>
        ///
        /// <remarks>  </remarks>
        ///
        private void GetChildItemsOrNames(
            string path,
            bool recurse,
            ReturnContainers returnContainers,
            bool returnNames,
            CertificateFilterInfo filter)
        {
            object thingToReturn = null;
            string childPath = null;

            bool returnAllContainers = returnContainers == ReturnContainers.ReturnAllContainers;

            Utils.CheckArgForNull(path, "path");

            //
            // children at the root path are store locations
            //
            if (path.Length == 0)
            {
                foreach (X509StoreLocation l in s_storeLocations)
                {
                    thingToReturn = returnNames ?
                        (object)l.LocationName : (object)l;

                    // 'returnNames' is true only when called from
                    // GetChildNames(), in which case 'recurse' will always be
                    // false.  When the -Path parameter needs to be globbed,
                    // the potential location names should be returned by
                    // calling this method from GetChildNames.

                    // The original code didn't have a "|| returnNames" clause.
                    // Suppose the user types:
                    //     dir cert:\curr* -CodeSigningCert -recurse
                    // We need to do path globbing here to resolve wild cards.
                    // Since -CodeSigningCert is present, 'filter' is not null.
                    // Since this method is called from GetChildNames() when
                    // doing the path globbing, 'returnNames' is true and
                    // 'recurse' is false.
                    // In the original code, nothing was returned by
                    // WriteItemObject(), so the path globbing fails and the
                    // above dir command would not display the certificates
                    // as expected.

                    // Another case is:
                    //     dir cert:\ -CodeSigningCert -Recurse
                    // -Recurse is present, so we need to call
                    // DoManualGetChildItems, and inside DoManualGetChildItems,
                    // this method will be called to get the names.
                    // The original code had the same problem for this case.

                    // With the "|| returnNames" clause, we test if this method
                    // is called from the GetChildNames().  When this method is
                    // called from GetChildNames(), 'recurse' will always be
                    // false.  Then we should return the names whether 'filter'
                    // is null or not.

                    if (filter == null || returnNames)
                    {
                        WriteItemObject(thingToReturn, l.LocationName, true);
                    }
                    childPath = l.LocationName;
                    if (recurse)
                    {
                        GetChildItemsOrNames(
                                        childPath,
                                        recurse,
                                        returnContainers,
                                        returnNames,
                                        filter);
                    }
                }
            }
            else
            {
                string[] pathElements = GetPathElements(path);

                //
                // children at depth 1 are stores
                //
                if (pathElements.Length == 1)
                {
                    GetStoresOrNames(pathElements[0],
                                     recurse,
                                     returnNames,
                                     filter);
                }
                //
                // children at depth 2 are certificates
                //
                else if (pathElements.Length == 2)
                {
                    GetCertificatesOrNames(path,
                                           pathElements,
                                           returnNames,
                                           filter);
                }
                else
                {
                    ThrowItemNotFound(path, CertificateProviderItem.Certificate);
                }
            }
        }