ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

errorinfo.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.