Ejemplo n.º 1
0
        public ADObject[] ShowObjectPicker(IntPtr parentHandle)
        {
            using (logX.loggerX.InfoCall())
            {
                packLPArray            packedAttributeList = null;
                DSOP_SCOPE_INIT_INFO[] scopeInitInfo       = new DSOP_SCOPE_INIT_INFO[2];
                DSObjectPicker         picker   = new DSObjectPicker();
                DSOP_INIT_INFO         initInfo = new DSOP_INIT_INFO();
                IDataObject            dataObj  = null;

                logX.loggerX.Debug("Initialize AD Picker");
                IDsObjectPicker ipicker =
                    Initialize(ref picker, ref packedAttributeList, ref scopeInitInfo, ref initInfo);

                logX.loggerX.Debug("Invoke AD Picker Dialog");
                ipicker.InvokeDialog(parentHandle, out dataObj);

                return(ProcessSelections(dataObj));
            }
        }
        private IDsObjectPicker InitializeObjectPicker()
        {
            DSObjectPicker  picker  = new DSObjectPicker();
            IDsObjectPicker ipicker = (IDsObjectPicker)picker;

            if (mustInit)
            {
                unsafe
                {
                    initInfo.cbSize             = Marshal.SizeOf(initInfo);
                    initInfo.pwzTargetComputer  = null; // local computer
                    initInfo.cDsScopeInfos      = 1;
                    initInfo.flOptions          = (int)initialSettings;
                    initInfo.cAttributesToFetch = 0;
                    initInfo.apwzAttributeNames = null;
                    scopeInitInfo.cbSize        = Marshal.SizeOf(typeof(UnsafeNativeMethods.DsopScopeInitInfo));
                    scopeInitInfo.flType        = (int)scopeTypes;
                    scopeInitInfo.flScope       = (int)initialScopes;
                    scopeInitInfo.FilterFlags.Uplevel.flBothModes      = (int)uplevelFlags;
                    scopeInitInfo.FilterFlags.Uplevel.flMixedModeOnly  = (int)uplevelFlags;
                    scopeInitInfo.FilterFlags.Uplevel.flNativeModeOnly = (int)uplevelFlags;
                    scopeInitInfo.FilterFlags.flDownlevel = (int)downlevelFlags;
                    scopeInitInfo.pwzADZPath = null;
                    scopeInitInfo.pwzDcName  = null;
                    scopeInitInfo.hr         = null;
                    fixed(UnsafeNativeMethods.DsopScopeInitInfo *pdsopScope = &scopeInitInfo)
                    {
                        initInfo.aDsScopeInfos = pdsopScope;
                    }
                }
                mustInit = false;
            }

            ipicker.Initialize(ref initInfo);

            return(ipicker);
        }
        private IDsObjectPicker Initialize()
        {
            var picker  = new DSObjectPicker();
            var ipicker = (IDsObjectPicker)picker;

            var scopeInitInfoList = new List <DSOP_SCOPE_INIT_INFO>();

            // Note the same default and filters are used by all scopes
            var defaultFilter   = GetDefaultFilter();
            var upLevelFilter   = GetUpLevelFilter();
            var downLevelFilter = GetDownLevelFilter();
            var providerFlags   = GetProviderFlags();

            // Internall, use one scope for the default (starting) locations.
            var startingScope = GetScope(DefaultLocations);

            if (startingScope > 0)
            {
                var startingScopeInfo = new DSOP_SCOPE_INIT_INFO
                {
                    cbSize     = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)),
                    flType     = startingScope,
                    flScope    = DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_STARTING_SCOPE | defaultFilter | providerFlags,
                    pwzADsPath = null,
                    pwzDcName  = null,
                    hr         = 0,
                };
                startingScopeInfo.FilterFlags.Uplevel.flBothModes = upLevelFilter;
                startingScopeInfo.FilterFlags.flDownlevel         = downLevelFilter;
                scopeInitInfoList.Add(startingScopeInfo);
            }

            // And another scope for all other locations (AllowedLocation values not in DefaultLocation)
            var otherLocations = AllowedLocations & (~DefaultLocations);
            var otherScope     = GetScope(otherLocations);

            if (otherScope > 0)
            {
                var otherScopeInfo = new DSOP_SCOPE_INIT_INFO
                {
                    cbSize     = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)),
                    flType     = otherScope,
                    flScope    = defaultFilter | providerFlags,
                    pwzADsPath = null,
                    pwzDcName  = null,
                    hr         = 0
                };
                otherScopeInfo.FilterFlags.Uplevel.flBothModes = upLevelFilter;
                otherScopeInfo.FilterFlags.flDownlevel         = downLevelFilter;
                scopeInitInfoList.Add(otherScopeInfo);
            }

            var scopeInitInfo = scopeInitInfoList.ToArray();

            // TODO: Scopes for alternate ADs, alternate domains, alternate computers, etc

            // Allocate memory from the unmananged mem of the process, this should be freed later!??
            var refScopeInitInfo = Marshal.AllocHGlobal
                                       (Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)) * scopeInitInfo.Length);

            // Marshal structs to pointers
            for (var index = 0; index < scopeInitInfo.Length; index++)
            {
                Marshal.StructureToPtr(scopeInitInfo[index],
                                       refScopeInitInfo.OffsetWith(index * Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO))),
                                       false);
            }

            // Initialize structure with data to initialize an object picker dialog box.
            var initInfo = new DSOP_INIT_INFO
            {
                cbSize            = (uint)Marshal.SizeOf(typeof(DSOP_INIT_INFO)),
                pwzTargetComputer = TargetComputer,
                cDsScopeInfos     = (uint)scopeInitInfo.Length,
                aDsScopeInfos     = refScopeInitInfo,
            };
            // Flags that determine the object picker options.
            uint flOptions = 0;

            if (MultiSelect)
            {
                flOptions |= DSOP_INIT_INFO_FLAGS.DSOP_FLAG_MULTISELECT;
            }
            // Only set DSOP_INIT_INFO_FLAGS.DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK if we know target is not a DC (which then saves
            // initialization time).
            if (SkipDomainControllerCheck)
            {
                flOptions |= DSOP_INIT_INFO_FLAGS.DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK;
            }
            initInfo.flOptions = flOptions;

            // there's a (seeming?) bug on my Windows XP when fetching the objectClass attribute - the pwzClass field is corrupted... plus,
            // it returns a multivalued array for this attribute. In Windows 2008 R2, however, only last value is returned, just as in
            // pwzClass. So won't actually be retrieving __objectClass__ - will give pwzClass instead
            var goingToFetch = new List <string>(AttributesToFetch);

            for (var i = 0; i < goingToFetch.Count; i++)
            {
                if (goingToFetch[i].Equals("objectClass", StringComparison.OrdinalIgnoreCase))
                {
                    goingToFetch[i] = "__objectClass__";
                }
            }

            initInfo.cAttributesToFetch = (uint)goingToFetch.Count;
            var unmanagedAttributesToFetch = new UnmanagedArrayOfStrings(goingToFetch);

            initInfo.apwzAttributeNames = unmanagedAttributesToFetch.ArrayPtr;

            // If the user has defined new credentials, set them now
            if (!string.IsNullOrEmpty(userName))
            {
                var cred = (IDsObjectPickerCredentials)ipicker;
                cred.SetCredentials(userName, password);
            }

            try
            {
                // Initialize the Object Picker Dialog Box with our options
                var hresult = ipicker.Initialize(ref initInfo);
                if (hresult != HRESULT.S_OK)
                {
                    Marshal.ReleaseComObject(ipicker);
                    throw new COMException("IDsObjectPicker.Initialize failed", hresult);
                }
                return(ipicker);
            }
            finally
            {
                /*
                 * from MSDN (http://msdn.microsoft.com/en-us/library/ms675899(VS.85).aspx):
                 *
                 *       Initialize can be called multiple times, but only the last call has effect.
                 *       Be aware that object picker makes its own copy of InitInfo.
                 */
                Marshal.FreeHGlobal(refScopeInitInfo);
                unmanagedAttributesToFetch.Dispose();
            }
        }
        private IDsObjectPicker InitializeObjectPicker()
        {
            DSObjectPicker picker = new DSObjectPicker();
            IDsObjectPicker ipicker = (IDsObjectPicker)picker;

            if (mustInit)
            {
                unsafe
                {
                    initInfo.cbSize = Marshal.SizeOf(initInfo);
                    initInfo.pwzTargetComputer = null; // local computer
                    initInfo.cDsScopeInfos = 1;
                    initInfo.flOptions = (int)initialSettings;
                    initInfo.cAttributesToFetch = 0;
                    initInfo.apwzAttributeNames = null;
                    scopeInitInfo.cbSize = Marshal.SizeOf(typeof(UnsafeNativeMethods.DsopScopeInitInfo));
                    scopeInitInfo.flType = (int)scopeTypes;
                    scopeInitInfo.flScope = (int)initialScopes;
                    scopeInitInfo.FilterFlags.Uplevel.flBothModes = (int)uplevelFlags;
                    scopeInitInfo.FilterFlags.Uplevel.flMixedModeOnly = (int)uplevelFlags;
                    scopeInitInfo.FilterFlags.Uplevel.flNativeModeOnly = (int)uplevelFlags;
                    scopeInitInfo.FilterFlags.flDownlevel = (int)downlevelFlags;
                    scopeInitInfo.pwzADZPath = null;
                    scopeInitInfo.pwzDcName = null;
                    scopeInitInfo.hr = null;
                    fixed (UnsafeNativeMethods.DsopScopeInitInfo* pdsopScope = &scopeInitInfo)
                    {
                        initInfo.aDsScopeInfos = pdsopScope;
                    }
                }
                mustInit = false;
            }

            ipicker.Initialize(ref initInfo);

            return ipicker;
        }
Ejemplo n.º 5
0
        private IDsObjectPicker Initialize()
        {
            DSObjectPicker  picker  = new DSObjectPicker();
            IDsObjectPicker ipicker = (IDsObjectPicker)picker;

            System.Collections.ArrayList scopeInitInfoList = new System.Collections.ArrayList();

            //List<DSOP_SCOPE_INIT_INFO> scopeInitInfoList = new List<DSOP_SCOPE_INIT_INFO>();

            // Note the same default and filters are used by all scopes
            uint defaultFilter   = GetDefaultFilter();
            uint upLevelFilter   = GetUpLevelFilter();
            uint downLevelFilter = GetDownLevelFilter();
            // Internall, use one scope for the default (starting) locations.
            uint startingScope = GetStartingScope();

            if (startingScope > 0)
            {
                DSOP_SCOPE_INIT_INFO startingScopeInfo = new DSOP_SCOPE_INIT_INFO();
                startingScopeInfo.cbSize  = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                startingScopeInfo.flType  = startingScope;
                startingScopeInfo.flScope = DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_STARTING_SCOPE | defaultFilter;
                startingScopeInfo.FilterFlags.Uplevel.flBothModes = upLevelFilter;
                startingScopeInfo.FilterFlags.flDownlevel         = downLevelFilter;
                startingScopeInfo.pwzADsPath = null;
                startingScopeInfo.pwzDcName  = null;
                startingScopeInfo.hr         = 0;
                scopeInitInfoList.Add(startingScopeInfo);
            }

            // And another scope for all other locations (AllowedLocation values not in DefaultLocation)
            uint otherScope = GetOtherScope();

            if (otherScope > 0)
            {
                DSOP_SCOPE_INIT_INFO otherScopeInfo = new DSOP_SCOPE_INIT_INFO();
                otherScopeInfo.cbSize  = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                otherScopeInfo.flType  = otherScope;
                otherScopeInfo.flScope = defaultFilter;
                otherScopeInfo.FilterFlags.Uplevel.flBothModes = upLevelFilter;
                otherScopeInfo.FilterFlags.flDownlevel         = downLevelFilter;
                otherScopeInfo.pwzADsPath = null;
                otherScopeInfo.pwzDcName  = null;
                otherScopeInfo.hr         = 0;
                scopeInitInfoList.Add(otherScopeInfo);
            }


            System.Collections.ArrayList scopeInitInfo = new System.Collections.ArrayList();
            scopeInitInfo = scopeInitInfoList;

            //DSOP_SCOPE_INIT_INFO[] scopeInitInfo = scopeInitInfoList.ToArray();

            // TODO: Scopes for alternate ADs, alternate domains, alternate computers, etc

            // Allocate memory from the unmananged mem of the process, this should be freed later!??
            IntPtr refScopeInitInfo = Marshal.AllocHGlobal
                                          (Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)) * scopeInitInfo.Count);

            // Marshal structs to pointers
            for (int index = 0; index < scopeInitInfo.Count; index++)
            {
                //Marshal.StructureToPtr(scopeInitInfo[0],
                //    refScopeInitInfo, true);
                //Marshal.StructureToPtr(scopeInitInfo[index],
                //	(IntPtr)((int)refScopeInitInfo + index * Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO))),	true);
                Marshal.StructureToPtr(scopeInitInfo[index], refScopeInitInfo, false);
            }

            // Initialize structure with data to initialize an object picker dialog box.
            DSOP_INIT_INFO initInfo = new DSOP_INIT_INFO();

            initInfo.cbSize = (uint)Marshal.SizeOf(initInfo);
            //initInfo.pwzTargetComputer = null; // local computer
            initInfo.pwzTargetComputer = targetComputer;
            initInfo.cDsScopeInfos     = (uint)scopeInitInfo.Count;
            initInfo.aDsScopeInfos     = refScopeInitInfo;
            // Flags that determine the object picker options.
            uint flOptions = 0;

            // Only set DSOP_INIT_INFO_FLAGS.DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK
            // if we know target is not a DC (which then saves initialization time).
            if (multiSelect)
            {
                flOptions |= DSOP_INIT_INFO_FLAGS.DSOP_FLAG_MULTISELECT;
            }
            initInfo.flOptions = flOptions;

            // We're not retrieving any additional attributes
            //string[] attributes = new string[] { "sAMaccountName" };
            //initInfo.cAttributesToFetch = (uint)attributes.Length;
            //initInfo.apwzAttributeNames = Marshal.StringToHGlobalUni( attributes[0] );
            initInfo.cAttributesToFetch = 0;
            initInfo.apwzAttributeNames = IntPtr.Zero;

            // Initialize the Object Picker Dialog Box with our options
            int hresult = ipicker.Initialize(ref initInfo);

            if (hresult != HRESULT.S_OK)
            {
                return(null);
            }
            return(ipicker);
        }
Ejemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private IDsObjectPicker Initialize(ref DSObjectPicker picker,
                                           ref packLPArray packedAttributeList,
                                           ref DSOP_SCOPE_INIT_INFO[] scopeInitInfo,
                                           ref DSOP_INIT_INFO initInfo)
        {
            IDsObjectPicker ipicker;

            ipicker = (IDsObjectPicker)picker;
            using (logX.loggerX.InfoCall())
            {
                logX.loggerX.Debug("Initialize 1st search scope");
                // Initialize 1st search scope
                scopeInitInfo[0].cbSize  = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                scopeInitInfo[0].flType  = DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
                scopeInitInfo[0].flScope = DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_STARTING_SCOPE |
                                           DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_WANT_DOWNLEVEL_BUILTIN_PATH |
                                           DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS |
                                           DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS;
                scopeInitInfo[0].FilterFlags.Uplevel.flBothModes =
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_INCLUDE_ADVANCED_VIEW |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_USERS |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_BUILTIN_GROUPS |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_UNIVERSAL_GROUPS_DL |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_UNIVERSAL_GROUPS_SE |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_GLOBAL_GROUPS_DL |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_GLOBAL_GROUPS_SE |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_DOMAIN_LOCAL_GROUPS_DL |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
                scopeInitInfo[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_USERS |
                                                           DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS |
                                                           DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
                scopeInitInfo[0].pwzADsPath = null;
                scopeInitInfo[0].pwzDcName  = null;
                scopeInitInfo[0].hr         = 0;

                logX.loggerX.Debug("Initialize 2nd search scope");
                // Initialize 2nd search scope
                scopeInitInfo[1].cbSize = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                scopeInitInfo[1].flType = DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_TARGET_COMPUTER |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_GLOBAL_CATALOG |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE |
                                          DSOP_SCOPE_TYPE_FLAGS.DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
                scopeInitInfo[1].flScope = DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_WANT_PROVIDER_GC |
                                           DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS |
                                           DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS;
                scopeInitInfo[1].FilterFlags.Uplevel.flBothModes =
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_INCLUDE_ADVANCED_VIEW |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_USERS |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_BUILTIN_GROUPS |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_UNIVERSAL_GROUPS_DL |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_UNIVERSAL_GROUPS_SE |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_GLOBAL_GROUPS_DL |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_GLOBAL_GROUPS_SE |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_DOMAIN_LOCAL_GROUPS_DL |
                    DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
                scopeInitInfo[1].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_USERS |
                                                           DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS |
                                                           DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
                scopeInitInfo[1].pwzADsPath = null;
                scopeInitInfo[1].pwzDcName  = null;
                scopeInitInfo[1].hr         = 0;

                logX.loggerX.Debug("Allocate unmanaged mem for scope searchers");
                // Allocate memory from the unmananged mem of the process, this should be freed later!??
                IntPtr refScopeInitInfo = Marshal.AllocHGlobal
                                              (Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)) * 2);

                logX.loggerX.Debug("Marshal 1st search scope");
                // Marshal structs to pointers
                Marshal.StructureToPtr(scopeInitInfo[0],
                                       refScopeInitInfo, false);

                logX.loggerX.Debug("Marshal 2nd search scope");
                //SQLsecure 3.1 (Tushar)--Making it int64 to make sure the addition does not overflow range of integer.
                Marshal.StructureToPtr(scopeInitInfo[1],
                                       (IntPtr)((Int64)refScopeInitInfo + Marshal.SizeOf
                                                    (typeof(DSOP_SCOPE_INIT_INFO))), false);


                logX.loggerX.Debug("Initialize initInfo structure");
                // Initialize structure with data to initialize an object picker dialog box.
                initInfo.cbSize            = (uint)Marshal.SizeOf(initInfo);
                initInfo.pwzTargetComputer = null; // local computer
                initInfo.cDsScopeInfos     = 2;
                initInfo.aDsScopeInfos     = refScopeInitInfo;
                // Flags that determine the object picker options. Allow user to select
                // multiple objects and specify that this is not a domain controller
                initInfo.flOptions = /*DSOP_INIT_INFO_FLAGS.DSOP_FLAG_MULTISELECT | */
                                     DSOP_INIT_INFO_FLAGS.DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK;
                //initInfo.flOptions = 0;

                logX.loggerX.Debug("Pack array");
                packedAttributeList         = new packLPArray(AttributeList);
                initInfo.cAttributesToFetch = (uint)packedAttributeList.Length;
                initInfo.apwzAttributeNames = packedAttributeList.arrayPtr;

                logX.loggerX.Debug("ipicker.Initialize");
                // Initialize the Object Picker Dialog Box with our options
                ipicker.Initialize(ref initInfo);
            }
            return(ipicker);
        }
        private IDsObjectPicker Initialize()
        {
            DSObjectPicker picker = new DSObjectPicker();
            IDsObjectPicker ipicker = (IDsObjectPicker)picker;

            List<DSOP_SCOPE_INIT_INFO> scopeInitInfoList = new List<DSOP_SCOPE_INIT_INFO>();

            // Note the same default and filters are used by all scopes
            uint defaultFilter = GetDefaultFilter();
            uint upLevelFilter = GetUpLevelFilter();
            uint downLevelFilter = GetDownLevelFilter();
            // Internall, use one scope for the default (starting) locations.
            uint startingScope = GetStartingScope();
            if (startingScope > 0)
            {
                DSOP_SCOPE_INIT_INFO startingScopeInfo = new DSOP_SCOPE_INIT_INFO();
                startingScopeInfo.cbSize = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                startingScopeInfo.cbSize = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                startingScopeInfo.flScope = DSOP_SCOPE_INIT_INFO_FLAGS.DSOP_SCOPE_FLAG_STARTING_SCOPE | defaultFilter;
                startingScopeInfo.flType = startingScope;
                startingScopeInfo.FilterFlags.Uplevel.flBothModes = upLevelFilter;
                startingScopeInfo.FilterFlags.flDownlevel = downLevelFilter;
                startingScopeInfo.pwzADsPath = null;
                startingScopeInfo.pwzDcName = null;
                startingScopeInfo.hr = 0;
                scopeInitInfoList.Add(startingScopeInfo);
            }

            // And another scope for all other locations (AllowedLocation values not in DefaultLocation)
            uint otherScope = GetOtherScope();
            if (otherScope > 0)
            {
                DSOP_SCOPE_INIT_INFO otherScopeInfo = new DSOP_SCOPE_INIT_INFO();
                otherScopeInfo.cbSize = (uint)Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO));
                otherScopeInfo.flType = otherScope;
                otherScopeInfo.flScope = defaultFilter;
                otherScopeInfo.FilterFlags.Uplevel.flBothModes = upLevelFilter;
                otherScopeInfo.FilterFlags.flDownlevel = downLevelFilter;
                otherScopeInfo.pwzADsPath = null;
                otherScopeInfo.pwzDcName = null;
                otherScopeInfo.hr = 0;
                scopeInitInfoList.Add(otherScopeInfo);
            }

            DSOP_SCOPE_INIT_INFO[] scopeInitInfo = scopeInitInfoList.ToArray();

            // Allocate memory from the unmananged mem of the process, this should be freed later!??
            IntPtr refScopeInitInfo = Marshal.AllocHGlobal
                (Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)) * scopeInitInfo.Length);

            // Marshal structs to pointers
            for (int index = 0; index < scopeInitInfo.Length; index++)
            {
                //Marshal.StructureToPtr(scopeInitInfo[0],
                //    refScopeInitInfo, true);

                //Marshal.StructureToPtr(scopeInitInfo[index],
                //    (IntPtr)((int)refScopeInitInfo + index * Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO))),
                //    true);
                Marshal.StructureToPtr(scopeInitInfo[index],
                    (IntPtr)((int)refScopeInitInfo + index * Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO))),
                    false);

            }

            // Initialize structure with data to initialize an object picker dialog box.
            DSOP_INIT_INFO initInfo = new DSOP_INIT_INFO();
            initInfo.cbSize = (uint)Marshal.SizeOf(initInfo);
            //initInfo.pwzTargetComputer = null; // local computer
            initInfo.pwzTargetComputer = targetComputer;
            initInfo.cDsScopeInfos = (uint)scopeInitInfo.Length;
            initInfo.aDsScopeInfos = refScopeInitInfo;
            // Flags that determine the object picker options.
            uint flOptions = 0;
            // Only set DSOP_INIT_INFO_FLAGS.DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK
            // if we know target is not a DC (which then saves initialization time).
            if (multiSelect)
            {
                flOptions |= DSOP_INIT_INFO_FLAGS.DSOP_FLAG_MULTISELECT;
            }
            initInfo.flOptions = flOptions;

            // We're not retrieving any additional attributes
            //string[] attributes = new string[] { "sAMaccountName" };
            //initInfo.cAttributesToFetch = (uint)attributes.Length;
            //initInfo.apwzAttributeNames = Marshal.StringToHGlobalUni( attributes[0] );
            initInfo.cAttributesToFetch = 0;
            initInfo.apwzAttributeNames = IntPtr.Zero;

            // Initialize the Object Picker Dialog Box with our options
            int hresult = ipicker.Initialize(ref initInfo);

            if (hresult != HRESULT.S_OK)
            {
                return null;
            }
            return ipicker;
        }