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()
        {
            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();
            uint providerFlags   = GetProviderFlags();

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

            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 | providerFlags;
                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)
            Locations otherLocations = AllowedLocations & (~DefaultLocations);
            uint      otherScope     = GetScope(otherLocations);

            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 | providerFlags;
                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[index],
                                       refScopeInitInfo.OffsetWith(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 = TargetComputer;
            initInfo.cDsScopeInfos     = (uint)scopeInitInfo.Length;
            initInfo.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
            List <string> goingToFetch = new List <string>(AttributesToFetch);

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

            initInfo.cAttributesToFetch = (uint)goingToFetch.Count;
            UnmanagedArrayOfStrings 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
                int 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();
            }
        }
Exemplo n.º 3
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);
        }