Esempio n. 1
0
        // Given a single entry or arraylist, check if it or each object in it matches.
        // This just handles the arraylist iteration, and calls through to GetProxyFromEntry to do the actual entry checking.
        static private IRawElementProviderSimple FindProxyInEntryOrArrayList(ProxyScoping findType, object entryOrArrayList, ref string imageName, NativeMethods.HWND hwnd, int idChild, int idObject, string classNameForPartialMatch)
        {
            if (entryOrArrayList == null)
            {
                return(null);
            }

            ArrayList array = entryOrArrayList as ArrayList;

            if (array == null)
            {
                return(GetProxyFromEntry(findType, entryOrArrayList, ref imageName, hwnd, idChild, idObject, classNameForPartialMatch));
            }

            // This the array will only grow in size, it will not shrink. That is the reason why it is
            // safe to capture the count outside the loop.  The reference we have to the Arraylist is
            // kind of like a snapshot.
            int count;

            lock (_lockObj)
            {
                count = array.Count;
            }

            IRawElementProviderSimple proxy = null;

            // this is a for loop because we need this to be thread safe and ClientSideProviderFactoryCallback calls out
            // so there would have been a lock in force when the call out was made which causes
            // deadlock.  We need to make our locks as narrow as possible.
            for (int i = 0; i < count; i++)
            {
                object entry;
                lock (_lockObj)
                {
                    entry = array[i];
                }

                proxy = GetProxyFromEntry(findType, entry, ref imageName, hwnd, idChild, idObject, classNameForPartialMatch);
                if (proxy != null)
                {
                    break;
                }
            }

            return(proxy);
        }
Esempio n. 2
0
        // Given an entry from one of the hash-tables or lists, check if it matches the image/classname, and if so, call the
        // factory method to create the proxy.
        // (Because full classname matching is done via hash-table lookup, this only needs to do string comparisons
        // for partial classname matches.)
        static private IRawElementProviderSimple GetProxyFromEntry(ProxyScoping findType, object entry, ref string imageName, NativeMethods.HWND hwnd, int idChild, int idObject, string classNameForPartialMatch)
        {
            // First, determine if the entry matches, and if so, extract the factory callback...
            ClientSideProviderFactoryCallback factoryCallback = null;

            // The entry may be a ClientSideProviderFactoryCallback or ClientSideProviderDescription...
            if (findType == ProxyScoping.ImageOnlyHandlers || findType == ProxyScoping.FallbackHandlers)
            {
                // Handle the fallback and image cases specially. The array for these is an array
                // of ClientSideProviderFactoryCallbacks, not ClientSideProviderDescription.
                factoryCallback = (ClientSideProviderFactoryCallback)entry;
            }
            else
            {
                // Other cases use ClientSideProviderDescription...
                ClientSideProviderDescription pi = (ClientSideProviderDescription)entry;

                // Get the image name if necessary...
#pragma warning suppress 6507 // Null and Empty string mean different things here.
                if (imageName == null && pi.ImageName != null)
                {
                    imageName = GetImageName(hwnd);
                }

                if (pi.ImageName == null || pi.ImageName == imageName)
                {
                    // Check if we have a match for this entry...
                    switch (findType)
                    {
                    case ProxyScoping.ExactMatchApparentClassName:
                        factoryCallback = pi.ClientSideProviderFactoryCallback;
                        break;

                    case ProxyScoping.ExactMatchRealClassName:
                        if ((pi.Flags & ClientSideProviderMatchIndicator.DisallowBaseClassNameMatch) == 0)
                        {
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                        }
                        break;

                    case ProxyScoping.PartialMatchApparentClassName:
                        if (classNameForPartialMatch.IndexOf(pi.ClassName, StringComparison.Ordinal) >= 0)
                        {
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                        }
                        break;

                    case ProxyScoping.PartialMatchRealClassName:
                        if (classNameForPartialMatch.IndexOf(pi.ClassName, StringComparison.Ordinal) >= 0 &&
                            ((pi.Flags & ClientSideProviderMatchIndicator.DisallowBaseClassNameMatch) == 0))
                        {
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                        }
                        break;

                    default:
                        Debug.Assert(false, "unexpected switch() case:");
                        break;
                    }
                }
            }

            // Second part: did we get a match? If so, use the factory callback to obtain an instance...
            if (factoryCallback == null)
            {
                return(null);
            }

            // if we get an exception creating a proxy just don't create the proxy and let the UIAutomation default proxy be used
            // This will still allow the tree to be navigated  and some properties to be made availible.
            // Catching all exceptions here doesn't follow .NET guidelines, but is it ok in this scenario?
            try
            {
                return(factoryCallback(hwnd, idChild, idObject));
            }
            catch (Exception e)
            {
                if (Misc.IsCriticalException(e))
                {
                    throw;
                }

                return(null);
            }
        }
        // Given an entry from one of the hash-tables or lists, check if it matches the image/classname, and if so, call the
        // factory method to create the proxy.
        // (Because full classname matching is done via hash-table lookup, this only needs to do string comparisons
        // for partial classname matches.)
        static private IRawElementProviderSimple GetProxyFromEntry(ProxyScoping findType, object entry, ref string imageName, NativeMethods.HWND hwnd, int idChild, int idObject, string classNameForPartialMatch)
        {
            // First, determine if the entry matches, and if so, extract the factory callback...
            ClientSideProviderFactoryCallback factoryCallback = null;

            // The entry may be a ClientSideProviderFactoryCallback or ClientSideProviderDescription...
            if (findType == ProxyScoping.ImageOnlyHandlers || findType == ProxyScoping.FallbackHandlers)
            {
                // Handle the fallback and image cases specially. The array for these is an array
                // of ClientSideProviderFactoryCallbacks, not ClientSideProviderDescription.
                factoryCallback = (ClientSideProviderFactoryCallback)entry;
            }
            else
            {
                // Other cases use ClientSideProviderDescription...
                ClientSideProviderDescription pi = (ClientSideProviderDescription)entry;

                // Get the image name if necessary...
#pragma warning suppress 6507 // Null and Empty string mean different things here.
                if (imageName == null && pi.ImageName != null)
                {
                    imageName = GetImageName(hwnd);
                }

                if (pi.ImageName == null || pi.ImageName == imageName)
                {
                    // Check if we have a match for this entry...
                    switch (findType)
                    {
                        case ProxyScoping.ExactMatchApparentClassName:
                            factoryCallback = pi.ClientSideProviderFactoryCallback;
                            break;

                        case ProxyScoping.ExactMatchRealClassName:
                            if ((pi.Flags & ClientSideProviderMatchIndicator.DisallowBaseClassNameMatch) == 0)
                            {
                                factoryCallback = pi.ClientSideProviderFactoryCallback;
                            }
                            break;

                        case ProxyScoping.PartialMatchApparentClassName:
                            if (classNameForPartialMatch.IndexOf(pi.ClassName, StringComparison.Ordinal) >= 0)
                            {
                                factoryCallback = pi.ClientSideProviderFactoryCallback;
                            }
                            break;

                        case ProxyScoping.PartialMatchRealClassName:
                            if (classNameForPartialMatch.IndexOf(pi.ClassName, StringComparison.Ordinal) >= 0
                                && ((pi.Flags & ClientSideProviderMatchIndicator.DisallowBaseClassNameMatch) == 0))
                            {
                                factoryCallback = pi.ClientSideProviderFactoryCallback;
                            }
                            break;

                        default:
                            Debug.Assert(false, "unexpected switch() case:");
                            break;
                    }
                }
            }

            // Second part: did we get a match? If so, use the factory callback to obtain an instance...
            if (factoryCallback == null)
                return null;

            // if we get an exception creating a proxy just don't create the proxy and let the UIAutomation default proxy be used
            // This will still allow the tree to be navigated  and some properties to be made availible.
            // 

            try
            {
                return factoryCallback(hwnd, idChild, idObject);
            }
            catch( Exception e )
            {
                if( Misc.IsCriticalException( e ) )
                    throw;

                return null;
            }
        }
        // Given a single entry or arraylist, check if it or each object in it matches.
        // This just handles the arraylist iteration, and calls through to GetProxyFromEntry to do the actual entry checking.
        static private IRawElementProviderSimple FindProxyInEntryOrArrayList(ProxyScoping findType, object entryOrArrayList, ref string imageName, NativeMethods.HWND hwnd, int idChild, int idObject, string classNameForPartialMatch)
        {
            if (entryOrArrayList == null)
                return null;

            ArrayList array = entryOrArrayList as ArrayList;
            if (array == null)
            {
                return GetProxyFromEntry(findType, entryOrArrayList, ref imageName, hwnd, idChild, idObject, classNameForPartialMatch);
            }

            // This the array will only grow in size, it will not shrink. That is the reason why it is 
            // safe to capture the count outside the loop.  The reference we have to the Arraylist is
            // kind of like a snapshot.
            int count;
            lock (_lockObj)
            {
                count = array.Count;
            }

            IRawElementProviderSimple proxy = null;

            // this is a for loop because we need this to be thread safe and ClientSideProviderFactoryCallback calls out
            // so there would have been a lock in force when the call out was made which causes
            // deadlock.  We need to make our locks as narrow as possible.
            for( int i = 0; i < count; i++ )
            {
                object entry;
                lock (_lockObj)
                {
                    entry = array[i];
                }

                proxy = GetProxyFromEntry(findType, entry, ref imageName, hwnd, idChild, idObject, classNameForPartialMatch);
                if( proxy != null )
                    break;
            }

            return proxy;
        }