0

I am trying to implement a COM interface in a C# service. The interface is from MS and documented here: https://msdn.microsoft.com/en-us/library/hh948551.aspx. All appears fine until I add this one method, DownloadContent. After adding that, the client COM service crashes with 0xc0000005. This makes me believe that there is some type of mismatch.

Here is my C# Interface code.

    [PreserveSig]
    [return: MarshalAs(UnmanagedType.Error)]
    int DownloadContent(
        [In]
        StringBuilder szContentId,
        [In]
        StringBuilder szContentVersion,
        [In]
        StringBuilder szRemotePath,
        [In]
        StringBuilder szLocalPath,
        [In]
        StringBuilder szNotifyEndpoint,
        [In]
        StringBuilder szNotifyData,
        [In]
        CCM_DTS_PRIORITY Priority,
        [In]
        int dwTimeoutSeconds,
        [In]
        int dwChunkSize,
        [In]
        int dwFlags,
        [In]
        StringBuilder szLocationOptions,
        [In]
        StringBuilder szFileManifest,
        [In]
        StringBuilder szOwnerSID,
        [In]
        [MarshalAs(UnmanagedType.Bool)]
        bool bDeleteJobOnError,
        [In]
        StringBuilder szProviderData,
        [In]
        StringBuilder szPackageData,
        [Out]
        out Guid pJobID
    );

Building a type library using regasm.exe /tlb I get the following IDL:

    HRESULT DownloadContent(
                    [in] LPWSTR szContentId, 
                    [in] LPWSTR szContentVersion, 
                    [in] LPWSTR szRemotePath, 
                    [in] LPWSTR szLocalPath, 
                    [in] LPWSTR szNotifyEndpoint, 
                    [in] LPWSTR szNotifyData, 
                    [in] CCM_DTS_PRIORITY Priority, 
                    [in] long dwTimeoutSeconds, 
                    [in] long dwChunkSize, 
                    [in] long dwFlags, 
                    [in] LPWSTR szLocationOptions, 
                    [in] LPWSTR szFileManifest, 
                    [in] LPWSTR szOwnerSID, 
                    [in] long bDeleteJobOnError, 
                    [in] LPWSTR szProviderData, 
                    [in] LPWSTR szPackageData, 
                    [out] GUID* pJobID);

The documentation from Microsoft shows the method should be:

HRESULT DownloadContent(
        LPCWSTR szContentId, 
        LPCWSTR szContentVersion, 
        LPCWSTR szRemotePath, 
        LPCWSTR szLocalPath, 
        LPCWSTR szNotifyEndpoint, 
        LPCWSTR szNotifyData, 
        CCM_DTS_PRIORITY Priority, 
        DWORD dwTimeoutSeconds, 
        DWORD dwChunkSize, 
        DWORD dwFlags, 
        LPCWSTR szLocationOptions, 
        LPCWSTR szFileManifest, 
        LPCWSTR szOwnerSID, 
        BOOL bDeleteJobOnError, 
        LPCWSTR szProviderData, 
        LPCWSTR szPackageData, 
        GUID *pJobID
    ); 

The only difference I can see is that the C# method is using LPWSTR instead of LPCWSTR. Is there anyway to get a LPCWSTR in C# or does anyone else have any ideas as to why it would be crashing the COM client?

  • From a P/Invoke point of view, there's no difference between LPWSTR and LPCWSTR (C is just for 'const' in c/c++). Can you try with string instead of StringBuilder? Also check the orders of methods in the interface definition. I can't find any .h file that would help us, and sometimes MSDN-only definitions do not strictly correspond to c/c++ definitions... Do you have a .h file or .idl or a TLB or a DLL from Microsoft to check all that? – Simon Mourier Feb 12 '17 at 07:58
  • Yes, I tried to use string but then it changed to BSTR* in the IDL export. I do not have a .h or .idl from Microsoft, just the MSDN documentation. It is part of their ConfigMgr product. There are many DLL files. I tried to open a couple with oleview but so far I have either not been able to open the file via Bind or View or it does not have the definition for ICcmAlternateDowloadProvider. Is there a way in C# to order the methods? Thanks for your help! – testuser900 Feb 12 '17 at 11:57
  • ok, then can you try `[MarshalAs(UnmanagedType.LPWSTR)] string`. Methods should just be ordered the same as in the real c/c++ definition (names are not significant, just order and binary equivalence), but the difficulty here is we're not 100% sure of the real c/c++ definition... A definition of ICcmAlternateDowloadProvider from oleview would be nice. – Simon Mourier Feb 12 '17 at 18:09
  • Changing the order to be the same as the MSDN docs seems to have fixed the crash. Attaching to the service, I can hit breakpoints in other methods. However, this method, the DownloadContent, still does not hit a breakpoint and never appears to be called by the client. I am guessing there is still something wrong with the method signature. I tried the above MarshalAs(UnmanagedType.LPWSTR) with a string type, but still no luck. Tried ref string and ref IntPtr also without luck. Any other ideas? I appreciate your help! – testuser900 Feb 13 '17 at 02:18

0 Answers0