How do I correctly use CoInitialize() and CoInitia

2019-05-29 19:57发布

My UI is provided in a DLL that calls CoInitialize() so I can use the Common Item Dialog, shell open folder dialog. and any other new Vista-only stuff that may require COM (I don't know of/don't use any others just yet). The DLL will also provide a UI Automation interface to a custom control (my Table control from questions past, which I've decided to move to UI Automation).

I don't want COM's "helpful" exception handling; I want exceptions in my DLL to bubble through to the DLL so they can be debugged. However, the documentation for IGlobalOptions says I need to call CoInitializeSecurity() beforehand.

I have two questions:

  1. Do I call CoInitializeSecurity() instead of or in addition to CoInitialize()? If in addition to, do I call it before or after?

  2. What would the invocation be if I wanted COM to act as if I didn't call CoInitializeSecurity() at all? After reading MSDN I know what most of the parameters should be, but I'm not sure about some of them.

    CoInitializeSecurity(
        NULL,
        -1,    // or is the default 0 instead?
        /* can this be NULL? (the error returns table on MSDN implies it can...) if not, what should I specify? */,
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        /* what should this be? MSDN says RPC_C_IMP_LEVEL_DEFAULT isn't allowed */,
        /* can this be NULL? if not, what should I specify? */,
        /* what should this be? MSDN says EOAC_DEFAULT isn't allowed */,
        NULL);
    

    Or is this completely wrong both security-wise and defaults-wise and there's a better option?

Or should I not even bother doing any of this since this is a DLL?

Thanks.

标签: c winapi com
1条回答
贪生不怕死
2楼-- · 2019-05-29 20:41

PS: I'm assuming your library doesn't contain the actual main() code.

My UI is provided in a DLL that calls CoInitialize()...

I hope you're doing this in your own thread, otherwise you're asking for trouble.

  1. Do I call CoInitializeSecurity()...

Don't do this in a library, it's a process-wide call, which might be done by the application itself or when cross-apartment marshaling happens for the first time.

  1. What would the invocation be...

I'd say this is it, if no registry information is found. To quote:

CoInitializeSecurity(NULL, -1, NULL, NULL, 
    RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, 
    NULL, EOAC_NONE, NULL);

Or is this completely wrong both security-wise and defaults-wise and there's a better option?

There are better options.

One is to return a constructed HRESULT and store your actual error description in one of your DLL's globals, perhaps using thread-local storage.

If you're using ATL, you may use such an HRESULT and end up using the same information you'd feed to your CComCoClass::Error method, which your objects most probably use as a template inheritance.

Or just use ATL's error handling, it might be enough since you can breakpoint your own code anyway.

Or should I not even bother doing any of this since this is a DLL?

It actually depends on thread ownership. If you own the thread where this happens, it's OK; if not, it's clearly wrong.

But consider alternatives like the ones I suggested.

查看更多
登录 后发表回答