Problem with marshaling stringbuilder RRS feed

  • Question

  • Hi,

    Im have implemented the IWMCredentialCallback for a windows media pushsink in my application.

    My pushsink works fine for publishing to the windows media server when no authentication is required, but when credentials are required, my implentation of AcquireCredentials is called, but i cannot seem to copy my user details into the stringbuilder buffers successfully.

    I am using this ComImport...

        public interface IWMCredentialCallback  
            void AcquireCredentials(  
              [In, MarshalAs(UnmanagedType.LPWStr)] string bstrRealm,  
              [In, MarshalAs(UnmanagedType.LPWStr)] string bstrSite,  
              [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszUser,  
              [In] uint cchUser,  
              [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszPassword,  
              [In] uint cchPassword,  
              [In] IntPtr hrStatus,  
              [In, Out] ref uint pdwFlags);  

    And this is my method implementation...

           public void AcquireCredentials(string bstrRealm, string bstrSite, 
                StringBuilder pwszUser, uint cchUser, StringBuilder pwszPassword, 
                    uint cchPassword, IntPtr hrStatus, ref uint pdwFlags)  
            // the bstrRealm here is correct as it contains the name of the server i am publishing to  
            pwszUser.Append("username");        // these lines throw "System.ArgumentOutOfRangeException"  
            pwszPassword.Append("password");    // capacity was less than the current size  
            pdwFlags = 0x00;  

    i have tried various things to copy the username into the stringbuilder.
    the pwszUser has a maxcapacity of zero, and so i cannot write anything into it.
    i cannot reset the capacity of it either, as it throws "capacity exceeds maxcapacity"

    pwszPassword also shows zero capacity, however when the method is called a second and third time trying to authenticate,
    its buffer shows a capacity of 8 and will print '*' chars to the debug output

    my understanding of using marshal with stringbuilder is to make sure the capacity is set first.
    This method is initially called by the media server when the pushsink connects, so i have no control over this.

    From Microsoft description of the SDK AcquireCredentials, the value of cchUser is supposed to be the buffer size allocated to pwszUser.
    This is clearly not happening.

    Perhaps i have implemented this interface the wrong way?

    Can anyone help me with this?

    Thursday, July 10, 2008 1:34 AM


  • Fuzzy, but if a COM client is calling this interface, it would pass a BSTR.  That's the default marshaling for a string, you should be able to declare the argument as a simple string without MarshalAs.  Declare the argument with the "ref" keyword if you modify the string.
    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Monday, July 14, 2008 2:35 AM
    Thursday, July 10, 2008 1:10 PM