DotNetNewsgroup.com  
web access to complete list of Microsoft.NET newsgroups
   home   |   control panel login   |   archive  |  
 
  carried group
academic
adonet
aspnet
aspnet.announcements
aspnet.buildingcontrols
aspnet.caching
aspnet.datagridcontrol
aspnet.mobile
aspnet.security
aspnet.webcontrols
aspnet.webservices
assignment_manager
datatools
dotnet.distributed_apps
dotnet.general
dotnet.myservices
dotnet.nternationalization
dotnet.scripting
dotnet.security
dotnet.vjsharp
dotnet.vsa
dotnet.xml
dotnetfaqs
framework
framework.clr
framework.compactframework
framework.component_services
framework.controls
framework.databinding
framework.drawing
framework.enhancements
framework.interop
framework.odbcnet
framework.performance
framework.remoting
framework.sdk
framework.setup
framework.webservices
framework.windowsforms
framework.wmi
frwk.windowsforms.designtime
lang.csharp
lang.jscript
lang.vb
lang.vb.controls
lang.vb.data
lang.vb.upgrade
lang.vc
lang.vc.libraries
  
 
start date: Tue, 7 Aug 2007 11:13:40 +0200,    posted on: microsoft.public.dotnet.framework.interop        back       

Thread Index
  1    Beat Bucheli
          2    Beat Bucheli


E_NOTIMPL in GetData method when querying objectSID from Directory Object Picker   
Hi,

I'm trying to get the objectSID from the active directory objects selected 
in the directory object picker dialog. But IDataObject.GetData() returns 
always 0x80004001 (E_NOTIMPL) when I supply the attribute 'objectSID' in 
DSOP_INIT_INFO. Without this attribute (cAttributesToFetch=0), the code 
works. I also have a sample using the same flags and settings written in 
Delphi that works fine. So I suppose the marshalling is incorrect, but I 
don't know where. Below is an excerpt of my code.

Thanks very much for any help.
Beat


[ComImport, Guid("17D6CCD8-3B7B-11D2-B9E0-00C04FD8DBF7")]
public class DSObjectPicker {}

[ComImport, Guid("0C87E64E-3B7A-11D2-B9E0-00C04FD8DBF7"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDsObjectPicker
{
    void Initialize(ref DSOP_INIT_INFO pInitInfo);
    void InvokeDialog(IntPtr HWND, out IDataObject lpDataObject);
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DSOP_INIT_INFO
{
    public uint cbSize;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pwzTargetComputer;
    public uint cDsScopeInfos;
    public IntPtr aDsScopeInfos;
    public uint flOptions;
    public uint cAttributesToFetch;
    public IntPtr apwzAttributeNames;
}

// other structs, enums, ... (skipped)

public class ObjectPickerWrapper
{
    public ADObject[] ShowObjectPicker(IntPtr parentHandle)
    {
        DSObjectPicker picker = new DSObjectPicker();
        IDsObjectPicker ipicker = (IDsObjectPicker)picker;

        DSOP_SCOPE_INIT_INFO[] scopeInitInfo = new DSOP_SCOPE_INIT_INFO[1];

        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].FilterFlags.Uplevel.flBothModes =
            DSOP_FILTER_FLAGS_FLAGS.DSOP_FILTER_USERS; // ...

        scopeInitInfo[0].FilterFlags.flDownlevel =
            DSOP_DOWNLEVEL_FLAGS.DSOP_DOWNLEVEL_FILTER_USERS; // ...

        scopeInitInfo[0].pwzADsPath = null;
        scopeInitInfo[0].pwzDcName = null;
        scopeInitInfo[0].hr = 0;

        IntPtr refScopeInitInfo = Marshal.AllocHGlobal(
            Marshal.SizeOf(typeof(DSOP_SCOPE_INIT_INFO)) * 
scopeInitInfo.Length);
        Marshal.StructureToPtr(scopeInitInfo[0], refScopeInitInfo, true);

        DSOP_INIT_INFO initInfo = new DSOP_INIT_INFO();
        initInfo.pwzTargetComputer = null;
        initInfo.flOptions = DSOP_INIT_INFO_FLAGS.DSOP_FLAG_MULTISELECT;
        initInfo.cDsScopeInfos = 1;
        initInfo.aDsScopeInfos = refScopeInitInfo;

        string attrName = "objectSID";
        IntPtr refAttrName = Marshal.StringToHGlobalUni(attrName);
        initInfo.cAttributesToFetch = 1;
        initInfo.apwzAttributeNames = refAttrName;  // <== marshalling / 
memory layout ok??

        ipicker.Initialize(ref initInfo);

        // show the dialog
        IDataObject dataObj = null;
        ipicker.InvokeDialog(parentHandle, out dataObj);

        FORMATETC fmt = new FORMATETC();
        fmt.cfFormat = 
(short)System.Windows.Forms.DataFormats.GetFormat("CFSTR_DSOP_DS_SELECTION_LIST").Id; 
// -15497 (unsigned 50039)
        fmt.ptd = IntPtr.Zero;
        fmt.dwAspect = DVASPECT.DVASPECT_CONTENT;
        fmt.lindex = -1;
        fmt.tymed = TYMED.TYMED_HGLOBAL;

        STGMEDIUM stg = new STGMEDIUM();

        // int res = dataObj.QueryGetData(ref fmt);   // <== HRESULT is 
always 0x80004001 (E_NOTIMPL)

        dataObj.GetData(ref fmt, out stg);  // throws 'not implemented' 
Exception from HRESULT 0x80004001 (E_NOTIMPL)

        // ... processing stg... (skipped)

        return new ADObject[0];
    }
}
Date:Tue, 7 Aug 2007 11:13:40 +0200   Author:  

Re: E_NOTIMPL in GetData method when querying objectSID from Directory Object Picker   
.... the marshalling of the string array was incorrect. It can be done like 
this:



public sealed class packLPArray

{

    private IntPtr taskAlloc;

    private readonly int _length;

    private IntPtr[] _strings;



    public packLPArray(string[] theArray)

    {

        int sizeIntPtr = IntPtr.Size;

        int neededSize = 0;

        if (theArray != null)

        {

            this._length = theArray.Length;

            this._strings = new IntPtr[this._length];

            neededSize = this._length * sizeIntPtr;

            this.taskAlloc = Marshal.AllocCoTaskMem(neededSize);

            for (int cx = this._length - 1; cx >= 0; cx--)

            {

                this._strings[cx] = 
Marshal.StringToCoTaskMemUni(theArray[cx]);

                Marshal.WriteIntPtr(this.taskAlloc, cx * sizeIntPtr, 
this._strings[cx]);

            }

        }

    }



    public IntPtr arrayPtr

    {

        get { return this.taskAlloc; }

    }



    ~packLPArray()

    {

        if (taskAlloc != IntPtr.Zero)

        {

            Marshal.FreeCoTaskMem(this.taskAlloc);

            int cx = this._length;

            while(cx-- != 0)

                Marshal.FreeCoTaskMem(this._strings[cx]);

        }

    }

}



....

packLPArray packit = new packLPArray( new string[] 
{"SamAccountName","cn","Adspath","objectsid"});

initInfo.cAttributesToFetch = 4;

initInfo.apwzAttributeNames = packit.arrayPtr;

....



Beat
Date:Mon, 20 Aug 2007 15:31:27 +0200   Author:  

Google
 
Web dotnetnewsgroup.com


COPYRIGHT ?2005, EUROFRONT WORLDWIDE LTD., ALL RIGHT RESERVE  |   Contact us