I have a function in an IUnknown
-derived COM interface:
HRESULT GetPassword( [in] long bufferLength, [out] WCHAR* buffer );
and the contract is that the implementation should check whether the buffer is large enough to store the string being retrieved. If the buffer is large enough the string is copied and S_OK
is returned, otherwise the function will return an error indication.
However I can't find a suitable HRESULT
value for that. E_UNEXPECTED
seems quite dumb and unhelpful. The closest I found is DISP_E_BUFFERTOOSMALL
but looks like it is for IDispatch
-derived interfaces only.
Which HRESULT
should I returned if a buffer provided is too small?
You shouldn't return an error. You should succeed, fill the buffer with what you can, and return through another parameter how big the buffer needs to be.
If you don't do it this way, how does the caller discover how big a buffer to allocate? You don't seriously want them to call repeatedly, with progressively bigger buffers, until they hit upon a value that suffices? I would hate to have to use such an interface!
As lame as it sounds,
E_INVALIDARG
is probably your best bet, technically speaking. There are not so many standardHRESULT
s which are more specific for arguments. There is alsoE_POINTER
but it would probably be more confusing.I would consider using
DISP_E_BUFFERTOOSMALL
. This will be intuitive to callers, and the only risk would be that they don't recognize it because it's not in the standard set of generic HRESULT values. I think that's a pretty small risk though, for a pretty small problem :)If you can still do something about it, you should really consider changing the interface to return a
BSTR
instead of aWCHAR*
. It simplifies a lot of things.Sometimes you can, sometimes you cannot.
Credit should go to @tenfour for suggesting this. Since you can't post and forward your upvotes to someone else, I'm posting as community wiki.
You can't return DISP_E_* errors, you are not implementing IDispatch. E_INVALIDARG is correct here, it is even unambiguous which doesn't happen too often. Always implement ISupportErrorInfo to generate good error messages, ATL makes it trivial with the Error() method.