Example #1
0
        private ADObject[] ProcessSelections(IDataObject dataObj)
        {
            if (dataObj == null)
            {
                return(null);
            }
            using (logX.loggerX.InfoCall())
            {
                ADObject[] selections = null;

                // The STGMEDIUM structure is a generalized global memory handle used for data transfer operations
                STGMEDIUM stg = new STGMEDIUM();
                stg.tymed          = (uint)TYMED.TYMED_HGLOBAL;
                stg.hGlobal        = IntPtr.Zero;
                stg.pUnkForRelease = IntPtr.Zero;

                // The FORMATETC structure is a generalized Clipboard format.
                FORMATETC fe = new FORMATETC();
                fe.cfFormat = (short)System.Windows.Forms.DataFormats.GetFormat("CFSTR_DSOP_DS_SELECTION_LIST").Id;
                //The CFSTR_DSOP_DS_SELECTION_LIST clipboard format is provided by the IDataObject obtained by calling IDsObjectPicker::InvokeDialog
                fe.ptd      = IntPtr.Zero;
                fe.dwAspect = (uint)DVASPECT.DVASPECT_CONTENT;
                fe.lindex   = -1;                        // all of the data
                fe.tymed    = (uint)TYMED.TYMED_HGLOBAL; //The storage medium is a global memory handle (HGLOBAL)

                dataObj.GetData(ref fe, ref stg);

                IntPtr pDsSL = PInvoke.GlobalLock(stg.hGlobal);

                try
                {
                    // the start of our structure
                    IntPtr current = pDsSL;
                    // get the # of items selected
                    logX.loggerX.Debug("Start Read Int 32");
                    int cnt = (int)Marshal.ReadInt32(current);
                    logX.loggerX.Debug("Finish Read Int 32");

                    // if we selected at least 1 object
                    if (cnt > 0)
                    {
                        selections = new ADObject[cnt];
                        logX.loggerX.Debug("Line: 1");
                        // increment the pointer so we can read the DS_SELECTION structure
                        current = (IntPtr)((Int64)current + (Marshal.SizeOf(typeof(uint)) * 2)); //SQLsecure 3.1 (Tushar)--Fix for issue SQLSECU-1972
                        logX.loggerX.Debug("Line: 2");
                        // now loop through the structures
                        for (int i = 0; i < cnt; i++)
                        {
                            // marshal the pointer to the structure
                            DS_SELECTION s = (DS_SELECTION)Marshal.PtrToStructure(current, typeof(DS_SELECTION));
                            logX.loggerX.Debug("Line: 3");

                            // Marshal.DestroyStructure(current, typeof (DS_SELECTION));
                            logX.loggerX.Debug("Line: 4");

                            // increment the position of our pointer by the size of the structure
                            current = (IntPtr)((Int64)current + Marshal.SizeOf(typeof(DS_SELECTION)));   //SQLsecure 3.1 (Tushar)--Fix for issue SQLSECU-1972
                            logX.loggerX.Debug("Line: 5");

                            selections[i]           = new ADObject();
                            selections[i].Name      = s.pwzName;
                            selections[i].AdsPath   = s.pwzADsPath;
                            selections[i].UPN       = s.pwzUPN;
                            selections[i].ClassName = s.pwzClass;

                            IntPtr ptrFetched = s.pvarFetchedAttributes;
                            logX.loggerX.Debug("Line: 6");

                            VARIANT vr = (VARIANT)Marshal.PtrToStructure(ptrFetched, typeof(VARIANT));
                            logX.loggerX.Debug("Line: 7");

                            string str = Marshal.PtrToStringUni(vr.bstrVal);
                            logX.loggerX.Debug("Line: 8");

                            selections[i].SamAccountName = str;
                            int vt = vr.vt;

                            IntPtr ptrSid = (IntPtr)((Int64)ptrFetched + (Marshal.SizeOf(typeof(VARIANT))));   //SQLsecure 3.1 (Tushar)--Fix for issue SQLSECU-1972
                            logX.loggerX.Debug("Line: 9");

                            vr = (VARIANT)Marshal.PtrToStructure(ptrSid, typeof(VARIANT));
                            logX.loggerX.Debug("Line: 10");

                            IntPtr pSids   = IntPtr.Zero;
                            IntPtr pUBound = IntPtr.Zero;
                            int    hr      = PInvoke.SafeArrayAccessData(vr.pArray, out pSids);
                            logX.loggerX.Debug("Line: 11");

                            hr = PInvoke.SafeArrayGetUBound(vr.pArray, 1, out pUBound);
                            logX.loggerX.Debug("Line: 12");

                            Byte[] sid = new Byte[pUBound.ToInt32() + 1];
                            logX.loggerX.Debug("Line: 13");

                            for (int nBytes = 0; nBytes <= pUBound.ToInt32(); nBytes++)
                            {
                                sid.SetValue(Marshal.ReadByte(pSids, nBytes), nBytes);
                            }
                            logX.loggerX.Debug("Line: 14");

                            selections[i].Sid = new Sid(sid);

                            ////This is how to obtain the Sid manually via lookup instead of by attribute
                            ////Binding to the User object
                            //DirectoryEntry dr = new DirectoryEntry(selections[i].AdsPath);
                            //dr.RefreshCache();
                            ////To get ObjectSid
                            //selections[i].Sid = new Sid((byte[])dr.Properties["objectSid"].Value);

                            //This will get another string value
                            //ptrNext = (IntPtr)((int)ptrSid + (Marshal.SizeOf(typeof(VARIANT))));
                            //vr = (VARIANT)Marshal.PtrToStructure(ptrNext, typeof(VARIANT));
                            //str = Marshal.PtrToStringUni(vr.bstrVal);

                            //build the SamAccount string with domain\SamAccountName
                            string domain;
                            bool   isFlat;
                            if (Path.IsWinntPath(s.pwzADsPath))
                            {
                                // the browser doesn't return a SamAccountName for winnt paths
                                // so process the path for it
                                string samPath;
                                Path.GetSamPathFromWinNTPath(s.pwzADsPath, out samPath);
                                selections[i].SamAccountName = samPath;
                            }
                            else
                            {
                                //Get Domain Name and build it on to the SamAccountName
                                Path.ExtractDomainFromPath(s.pwzADsPath, out domain, out isFlat);
                                DOMAIN_CONTROLLER_INFO dcInfo;
                                if (!isFlat)
                                {
                                    uint nameInFlag = (uint)DsGetDcFlags.DS_IS_DNS_NAME;
                                    // Call DsGetDcName to get the flat domain info.
                                    uint flags = ((uint)DsGetDcFlags.DS_RETURN_FLAT_NAME | nameInFlag);
                                    uint rc    = DS.DsGetDcName("", domain, flags, out dcInfo);
                                    if (rc != Win32Errors.ERROR_SUCCESS)
                                    {
                                        logX.loggerX.Error("ERROR - Failed to get flat name DC info for the domain",
                                                           domain);
                                        return(null);
                                    }
                                    else
                                    {
                                        domain = dcInfo.DomainName;
                                    }
                                }
                                logX.loggerX.Debug("Line: 100");

                                selections[i].SamAccountName = Path.MakeSamPath(domain, selections[i].SamAccountName);
                            }
                        }
                    }
                }
                finally
                {
                    PInvoke.GlobalUnlock(pDsSL);
                }

                return(selections);
            }
        }