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;
        }
        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.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);
            }

            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.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);
            }

            // 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);
        }