Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenerrorinfo.c
Go to the documentation of this file.
00001 /* 00002 * ErrorInfo API 00003 * 00004 * Copyright 2000 Patrik Stridvall, Juergen Schmied 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 * 00020 * NOTES: 00021 * 00022 * The errorinfo is a per-thread object. The reference is stored in the 00023 * TEB at offset 0xf80. 00024 */ 00025 00026 #include <stdarg.h> 00027 #include <string.h> 00028 00029 #define COBJMACROS 00030 00031 #include "windef.h" 00032 #include "winbase.h" 00033 #include "objbase.h" 00034 #include "oleauto.h" 00035 #include "winerror.h" 00036 00037 #include "wine/unicode.h" 00038 #include "compobj_private.h" 00039 00040 #include "wine/debug.h" 00041 00042 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00043 00044 /* this code is from SysAllocStringLen (ole2disp.c in oleaut32) */ 00045 static BSTR ERRORINFO_SysAllocString(const OLECHAR* in) 00046 { 00047 DWORD bufferSize; 00048 DWORD* newBuffer; 00049 WCHAR* stringBuffer; 00050 DWORD len; 00051 00052 if (in == NULL) 00053 return NULL; 00054 /* 00055 * Find the length of the buffer passed-in, in bytes. 00056 */ 00057 len = strlenW(in); 00058 bufferSize = len * sizeof (WCHAR); 00059 00060 /* 00061 * Allocate a new buffer to hold the string. 00062 * don't forget to keep an empty spot at the beginning of the 00063 * buffer for the character count and an extra character at the 00064 * end for the '\0'. 00065 */ 00066 newBuffer = HeapAlloc(GetProcessHeap(), 0, 00067 bufferSize + sizeof(WCHAR) + sizeof(DWORD)); 00068 00069 /* 00070 * If the memory allocation failed, return a null pointer. 00071 */ 00072 if (newBuffer==0) 00073 return 0; 00074 00075 /* 00076 * Copy the length of the string in the placeholder. 00077 */ 00078 *newBuffer = bufferSize; 00079 00080 /* 00081 * Skip the byte count. 00082 */ 00083 newBuffer++; 00084 00085 /* 00086 * Copy the information in the buffer. It is not possible to pass 00087 * a NULL pointer here. 00088 */ 00089 memcpy(newBuffer, in, bufferSize); 00090 00091 /* 00092 * Make sure that there is a nul character at the end of the 00093 * string. 00094 */ 00095 stringBuffer = (WCHAR*)newBuffer; 00096 stringBuffer[len] = 0; 00097 00098 return stringBuffer; 00099 } 00100 00101 /* this code is from SysFreeString (ole2disp.c in oleaut32)*/ 00102 static VOID ERRORINFO_SysFreeString(BSTR in) 00103 { 00104 DWORD* bufferPointer; 00105 00106 /* NULL is a valid parameter */ 00107 if(!in) return; 00108 00109 /* 00110 * We have to be careful when we free a BSTR pointer, it points to 00111 * the beginning of the string but it skips the byte count contained 00112 * before the string. 00113 */ 00114 bufferPointer = (DWORD*)in; 00115 00116 bufferPointer--; 00117 00118 /* 00119 * Free the memory from it's "real" origin. 00120 */ 00121 HeapFree(GetProcessHeap(), 0, bufferPointer); 00122 } 00123 00124 00125 typedef struct ErrorInfoImpl 00126 { 00127 const IErrorInfoVtbl *lpvtei; 00128 const ICreateErrorInfoVtbl *lpvtcei; 00129 const ISupportErrorInfoVtbl *lpvtsei; 00130 LONG ref; 00131 00132 GUID m_Guid; 00133 BSTR bstrSource; 00134 BSTR bstrDescription; 00135 BSTR bstrHelpFile; 00136 DWORD m_dwHelpContext; 00137 } ErrorInfoImpl; 00138 00139 static const IErrorInfoVtbl IErrorInfoImpl_VTable; 00140 static const ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable; 00141 static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable; 00142 00143 /* 00144 converts an object pointer to This 00145 */ 00146 00147 static inline ErrorInfoImpl *impl_from_IErrorInfo( IErrorInfo *iface ) 00148 { 00149 return (ErrorInfoImpl *)((char*)iface - FIELD_OFFSET(ErrorInfoImpl, lpvtei)); 00150 } 00151 00152 static inline ErrorInfoImpl *impl_from_ICreateErrorInfo( ICreateErrorInfo *iface ) 00153 { 00154 return (ErrorInfoImpl *)((char*)iface - FIELD_OFFSET(ErrorInfoImpl, lpvtcei)); 00155 } 00156 00157 static inline ErrorInfoImpl *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface ) 00158 { 00159 return (ErrorInfoImpl *)((char*)iface - FIELD_OFFSET(ErrorInfoImpl, lpvtsei)); 00160 } 00161 00162 00163 /* 00164 converts This to an object pointer 00165 */ 00166 #define _IErrorInfo_(This) ((IErrorInfo*)&(This)->lpvtei) 00167 #define _ICreateErrorInfo_(This) (&(This)->lpvtcei) 00168 #define _ISupportErrorInfo_(This) (&(This)->lpvtsei) 00169 00170 static IErrorInfo * IErrorInfoImpl_Constructor(void) 00171 { 00172 ErrorInfoImpl * ei = HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl)); 00173 if (ei) 00174 { 00175 ei->lpvtei = &IErrorInfoImpl_VTable; 00176 ei->lpvtcei = &ICreateErrorInfoImpl_VTable; 00177 ei->lpvtsei = &ISupportErrorInfoImpl_VTable; 00178 ei->ref = 1; 00179 ei->bstrSource = NULL; 00180 ei->bstrDescription = NULL; 00181 ei->bstrHelpFile = NULL; 00182 ei->m_dwHelpContext = 0; 00183 } 00184 return (IErrorInfo *)ei; 00185 } 00186 00187 00188 static HRESULT WINAPI IErrorInfoImpl_QueryInterface( 00189 IErrorInfo* iface, 00190 REFIID riid, 00191 VOID** ppvoid) 00192 { 00193 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00194 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvoid); 00195 00196 *ppvoid = NULL; 00197 00198 if(IsEqualIID(riid, &IID_IErrorInfo)) 00199 { 00200 *ppvoid = _IErrorInfo_(This); 00201 } 00202 else if(IsEqualIID(riid, &IID_ICreateErrorInfo)) 00203 { 00204 *ppvoid = _ICreateErrorInfo_(This); 00205 } 00206 else if(IsEqualIID(riid, &IID_ISupportErrorInfo)) 00207 { 00208 *ppvoid = _ISupportErrorInfo_(This); 00209 } 00210 00211 if(*ppvoid) 00212 { 00213 IUnknown_AddRef( (IUnknown*)*ppvoid ); 00214 TRACE("-- Interface: (%p)->(%p)\n",ppvoid,*ppvoid); 00215 return S_OK; 00216 } 00217 TRACE("-- Interface: E_NOINTERFACE\n"); 00218 return E_NOINTERFACE; 00219 } 00220 00221 static ULONG WINAPI IErrorInfoImpl_AddRef( 00222 IErrorInfo* iface) 00223 { 00224 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00225 TRACE("(%p)->(count=%u)\n",This,This->ref); 00226 return InterlockedIncrement(&This->ref); 00227 } 00228 00229 static ULONG WINAPI IErrorInfoImpl_Release( 00230 IErrorInfo* iface) 00231 { 00232 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00233 ULONG ref = InterlockedDecrement(&This->ref); 00234 00235 TRACE("(%p)->(count=%u)\n",This,ref+1); 00236 00237 if (!ref) 00238 { 00239 TRACE("-- destroying IErrorInfo(%p)\n",This); 00240 00241 ERRORINFO_SysFreeString(This->bstrSource); 00242 ERRORINFO_SysFreeString(This->bstrDescription); 00243 ERRORINFO_SysFreeString(This->bstrHelpFile); 00244 HeapFree(GetProcessHeap(),0,This); 00245 return 0; 00246 } 00247 return ref; 00248 } 00249 00250 static HRESULT WINAPI IErrorInfoImpl_GetGUID( 00251 IErrorInfo* iface, 00252 GUID * pGUID) 00253 { 00254 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00255 TRACE("(%p)->(count=%u)\n",This,This->ref); 00256 if(!pGUID )return E_INVALIDARG; 00257 *pGUID = This->m_Guid; 00258 return S_OK; 00259 } 00260 00261 static HRESULT WINAPI IErrorInfoImpl_GetSource( 00262 IErrorInfo* iface, 00263 BSTR *pBstrSource) 00264 { 00265 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00266 TRACE("(%p)->(pBstrSource=%p)\n",This,pBstrSource); 00267 if (pBstrSource == NULL) 00268 return E_INVALIDARG; 00269 *pBstrSource = ERRORINFO_SysAllocString(This->bstrSource); 00270 return S_OK; 00271 } 00272 00273 static HRESULT WINAPI IErrorInfoImpl_GetDescription( 00274 IErrorInfo* iface, 00275 BSTR *pBstrDescription) 00276 { 00277 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00278 00279 TRACE("(%p)->(pBstrDescription=%p)\n",This,pBstrDescription); 00280 if (pBstrDescription == NULL) 00281 return E_INVALIDARG; 00282 *pBstrDescription = ERRORINFO_SysAllocString(This->bstrDescription); 00283 00284 return S_OK; 00285 } 00286 00287 static HRESULT WINAPI IErrorInfoImpl_GetHelpFile( 00288 IErrorInfo* iface, 00289 BSTR *pBstrHelpFile) 00290 { 00291 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00292 00293 TRACE("(%p)->(pBstrHelpFile=%p)\n",This, pBstrHelpFile); 00294 if (pBstrHelpFile == NULL) 00295 return E_INVALIDARG; 00296 *pBstrHelpFile = ERRORINFO_SysAllocString(This->bstrHelpFile); 00297 00298 return S_OK; 00299 } 00300 00301 static HRESULT WINAPI IErrorInfoImpl_GetHelpContext( 00302 IErrorInfo* iface, 00303 DWORD *pdwHelpContext) 00304 { 00305 ErrorInfoImpl *This = impl_from_IErrorInfo(iface); 00306 TRACE("(%p)->(pdwHelpContext=%p)\n",This, pdwHelpContext); 00307 if (pdwHelpContext == NULL) 00308 return E_INVALIDARG; 00309 *pdwHelpContext = This->m_dwHelpContext; 00310 00311 return S_OK; 00312 } 00313 00314 static const IErrorInfoVtbl IErrorInfoImpl_VTable = 00315 { 00316 IErrorInfoImpl_QueryInterface, 00317 IErrorInfoImpl_AddRef, 00318 IErrorInfoImpl_Release, 00319 00320 IErrorInfoImpl_GetGUID, 00321 IErrorInfoImpl_GetSource, 00322 IErrorInfoImpl_GetDescription, 00323 IErrorInfoImpl_GetHelpFile, 00324 IErrorInfoImpl_GetHelpContext 00325 }; 00326 00327 00328 static HRESULT WINAPI ICreateErrorInfoImpl_QueryInterface( 00329 ICreateErrorInfo* iface, 00330 REFIID riid, 00331 VOID** ppvoid) 00332 { 00333 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00334 TRACE("(%p)\n", This); 00335 return IErrorInfo_QueryInterface(_IErrorInfo_(This), riid, ppvoid); 00336 } 00337 00338 static ULONG WINAPI ICreateErrorInfoImpl_AddRef( 00339 ICreateErrorInfo* iface) 00340 { 00341 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00342 TRACE("(%p)\n", This); 00343 return IErrorInfo_AddRef(_IErrorInfo_(This)); 00344 } 00345 00346 static ULONG WINAPI ICreateErrorInfoImpl_Release( 00347 ICreateErrorInfo* iface) 00348 { 00349 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00350 TRACE("(%p)\n", This); 00351 return IErrorInfo_Release(_IErrorInfo_(This)); 00352 } 00353 00354 00355 static HRESULT WINAPI ICreateErrorInfoImpl_SetGUID( 00356 ICreateErrorInfo* iface, 00357 REFGUID rguid) 00358 { 00359 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00360 TRACE("(%p)->(%s)\n", This, debugstr_guid(rguid)); 00361 This->m_Guid = *rguid; 00362 return S_OK; 00363 } 00364 00365 static HRESULT WINAPI ICreateErrorInfoImpl_SetSource( 00366 ICreateErrorInfo* iface, 00367 LPOLESTR szSource) 00368 { 00369 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00370 TRACE("(%p): %s\n",This, debugstr_w(szSource)); 00371 if (This->bstrSource != NULL) 00372 ERRORINFO_SysFreeString(This->bstrSource); 00373 This->bstrSource = ERRORINFO_SysAllocString(szSource); 00374 00375 return S_OK; 00376 } 00377 00378 static HRESULT WINAPI ICreateErrorInfoImpl_SetDescription( 00379 ICreateErrorInfo* iface, 00380 LPOLESTR szDescription) 00381 { 00382 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00383 TRACE("(%p): %s\n",This, debugstr_w(szDescription)); 00384 if (This->bstrDescription != NULL) 00385 ERRORINFO_SysFreeString(This->bstrDescription); 00386 This->bstrDescription = ERRORINFO_SysAllocString(szDescription); 00387 00388 return S_OK; 00389 } 00390 00391 static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpFile( 00392 ICreateErrorInfo* iface, 00393 LPOLESTR szHelpFile) 00394 { 00395 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00396 TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile)); 00397 if (This->bstrHelpFile != NULL) 00398 ERRORINFO_SysFreeString(This->bstrHelpFile); 00399 This->bstrHelpFile = ERRORINFO_SysAllocString(szHelpFile); 00400 return S_OK; 00401 } 00402 00403 static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext( 00404 ICreateErrorInfo* iface, 00405 DWORD dwHelpContext) 00406 { 00407 ErrorInfoImpl *This = impl_from_ICreateErrorInfo(iface); 00408 TRACE("(%p,%d)\n",This,dwHelpContext); 00409 This->m_dwHelpContext = dwHelpContext; 00410 return S_OK; 00411 } 00412 00413 static const ICreateErrorInfoVtbl ICreateErrorInfoImpl_VTable = 00414 { 00415 ICreateErrorInfoImpl_QueryInterface, 00416 ICreateErrorInfoImpl_AddRef, 00417 ICreateErrorInfoImpl_Release, 00418 00419 ICreateErrorInfoImpl_SetGUID, 00420 ICreateErrorInfoImpl_SetSource, 00421 ICreateErrorInfoImpl_SetDescription, 00422 ICreateErrorInfoImpl_SetHelpFile, 00423 ICreateErrorInfoImpl_SetHelpContext 00424 }; 00425 00426 static HRESULT WINAPI ISupportErrorInfoImpl_QueryInterface( 00427 ISupportErrorInfo* iface, 00428 REFIID riid, 00429 VOID** ppvoid) 00430 { 00431 ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); 00432 TRACE("(%p)\n", This); 00433 00434 return IErrorInfo_QueryInterface(_IErrorInfo_(This), riid, ppvoid); 00435 } 00436 00437 static ULONG WINAPI ISupportErrorInfoImpl_AddRef( 00438 ISupportErrorInfo* iface) 00439 { 00440 ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); 00441 TRACE("(%p)\n", This); 00442 return IErrorInfo_AddRef(_IErrorInfo_(This)); 00443 } 00444 00445 static ULONG WINAPI ISupportErrorInfoImpl_Release( 00446 ISupportErrorInfo* iface) 00447 { 00448 ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); 00449 TRACE("(%p)\n", This); 00450 return IErrorInfo_Release(_IErrorInfo_(This)); 00451 } 00452 00453 00454 static HRESULT WINAPI ISupportErrorInfoImpl_InterfaceSupportsErrorInfo( 00455 ISupportErrorInfo* iface, 00456 REFIID riid) 00457 { 00458 ErrorInfoImpl *This = impl_from_ISupportErrorInfo(iface); 00459 TRACE("(%p)->(%s)\n", This, debugstr_guid(riid)); 00460 return (IsEqualIID(riid, &This->m_Guid)) ? S_OK : S_FALSE; 00461 } 00462 00463 static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable = 00464 { 00465 ISupportErrorInfoImpl_QueryInterface, 00466 ISupportErrorInfoImpl_AddRef, 00467 ISupportErrorInfoImpl_Release, 00468 00469 00470 ISupportErrorInfoImpl_InterfaceSupportsErrorInfo 00471 }; 00472 00473 /*********************************************************************** 00474 * CreateErrorInfo (OLE32.@) 00475 * 00476 * Creates an object used to set details for an error info object. 00477 * 00478 * PARAMS 00479 * pperrinfo [O]. Address where error info creation object will be stored. 00480 * 00481 * RETURNS 00482 * Success: S_OK. 00483 * Failure: HRESULT code. 00484 */ 00485 HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo) 00486 { 00487 IErrorInfo * pei; 00488 HRESULT res; 00489 TRACE("(%p)\n", pperrinfo); 00490 if(! pperrinfo ) return E_INVALIDARG; 00491 if(!(pei=IErrorInfoImpl_Constructor()))return E_OUTOFMEMORY; 00492 00493 res = IErrorInfo_QueryInterface(pei, &IID_ICreateErrorInfo, (LPVOID*)pperrinfo); 00494 IErrorInfo_Release(pei); 00495 return res; 00496 } 00497 00498 /*********************************************************************** 00499 * GetErrorInfo (OLE32.@) 00500 * 00501 * Retrieves the error information object for the current thread. 00502 * 00503 * PARAMS 00504 * dwReserved [I]. Reserved. Must be zero. 00505 * pperrinfo [O]. Address where error information object will be stored on return. 00506 * 00507 * RETURNS 00508 * Success: S_OK if an error information object was set for the current thread. 00509 * S_FALSE if otherwise. 00510 * Failure: E_INVALIDARG if dwReserved is not zero. 00511 * 00512 * NOTES 00513 * This function causes the current error info object for the thread to be 00514 * cleared if one was set beforehand. 00515 */ 00516 HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo) 00517 { 00518 TRACE("(%d, %p, %p)\n", dwReserved, pperrinfo, COM_CurrentInfo()->errorinfo); 00519 00520 if (dwReserved) 00521 { 00522 ERR("dwReserved (0x%x) != 0\n", dwReserved); 00523 return E_INVALIDARG; 00524 } 00525 00526 if(!pperrinfo) return E_INVALIDARG; 00527 00528 if (!COM_CurrentInfo()->errorinfo) 00529 { 00530 *pperrinfo = NULL; 00531 return S_FALSE; 00532 } 00533 00534 *pperrinfo = COM_CurrentInfo()->errorinfo; 00535 00536 /* clear thread error state */ 00537 COM_CurrentInfo()->errorinfo = NULL; 00538 return S_OK; 00539 } 00540 00541 /*********************************************************************** 00542 * SetErrorInfo (OLE32.@) 00543 * 00544 * Sets the error information object for the current thread. 00545 * 00546 * PARAMS 00547 * dwReserved [I] Reserved. Must be zero. 00548 * perrinfo [I] Error info object. 00549 * 00550 * RETURNS 00551 * Success: S_OK. 00552 * Failure: E_INVALIDARG if dwReserved is not zero. 00553 */ 00554 HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo) 00555 { 00556 IErrorInfo * pei; 00557 00558 TRACE("(%d, %p)\n", dwReserved, perrinfo); 00559 00560 if (dwReserved) 00561 { 00562 ERR("dwReserved (0x%x) != 0\n", dwReserved); 00563 return E_INVALIDARG; 00564 } 00565 00566 /* release old errorinfo */ 00567 pei = COM_CurrentInfo()->errorinfo; 00568 if (pei) IErrorInfo_Release(pei); 00569 00570 /* set to new value */ 00571 COM_CurrentInfo()->errorinfo = perrinfo; 00572 if (perrinfo) IErrorInfo_AddRef(perrinfo); 00573 00574 return S_OK; 00575 } Generated on Sat May 26 2012 04:24:08 for ReactOS by
1.7.6.1
|