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

htmlelemcol.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 Jacek Caban for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include <stdarg.h>
00020 
00021 #define COBJMACROS
00022 
00023 #include "windef.h"
00024 #include "winbase.h"
00025 #include "winuser.h"
00026 #include "ole2.h"
00027 
00028 #include "wine/debug.h"
00029 
00030 #include "mshtml_private.h"
00031 
00032 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
00033 
00034 typedef struct {
00035     DispatchEx dispex;
00036     const IHTMLElementCollectionVtbl *lpHTMLElementCollectionVtbl;
00037 
00038     IUnknown *ref_unk;
00039     HTMLElement **elems;
00040     DWORD len;
00041 
00042     LONG ref;
00043 } HTMLElementCollection;
00044 
00045 #define HTMLELEMCOL(x)  ((IHTMLElementCollection*) &(x)->lpHTMLElementCollectionVtbl)
00046 
00047 typedef struct {
00048     HTMLElement **buf;
00049     DWORD len;
00050     DWORD size;
00051 } elem_vector_t;
00052 
00053 static IHTMLElementCollection *HTMLElementCollection_Create(IUnknown *ref_unk,
00054                                                             HTMLElement **elems, DWORD len);
00055 
00056 static void elem_vector_add(elem_vector_t *buf, HTMLElement *elem)
00057 {
00058     if(buf->len == buf->size) {
00059         buf->size <<= 1;
00060         buf->buf = heap_realloc(buf->buf, buf->size*sizeof(HTMLElement**));
00061     }
00062 
00063     buf->buf[buf->len++] = elem;
00064 }
00065 
00066 static void elem_vector_normalize(elem_vector_t *buf)
00067 {
00068     if(!buf->len) {
00069         heap_free(buf->buf);
00070         buf->buf = NULL;
00071     }else if(buf->size > buf->len) {
00072         buf->buf = heap_realloc(buf->buf, buf->len*sizeof(HTMLElement**));
00073     }
00074 
00075     buf->size = buf->len;
00076 }
00077 
00078 static inline BOOL is_elem_node(nsIDOMNode *node)
00079 {
00080     PRUint16 type=0;
00081 
00082     nsIDOMNode_GetNodeType(node, &type);
00083 
00084     return type == ELEMENT_NODE || type == COMMENT_NODE;
00085 }
00086 
00087 #define ELEMCOL_THIS(iface) DEFINE_THIS(HTMLElementCollection, HTMLElementCollection, iface)
00088 #define HTMLELEM_NODE_THIS(iface) DEFINE_THIS2(HTMLElement, node, iface)
00089 
00090 static HRESULT WINAPI HTMLElementCollection_QueryInterface(IHTMLElementCollection *iface,
00091                                                            REFIID riid, void **ppv)
00092 {
00093     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00094 
00095     *ppv = NULL;
00096 
00097     if(IsEqualGUID(&IID_IUnknown, riid)) {
00098         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
00099         *ppv = HTMLELEMCOL(This);
00100     }else if(IsEqualGUID(&IID_IHTMLElementCollection, riid)) {
00101         TRACE("(%p)->(IID_IHTMLElementCollection %p)\n", This, ppv);
00102         *ppv = HTMLELEMCOL(This);
00103     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
00104         return *ppv ? S_OK : E_NOINTERFACE;
00105     }
00106 
00107     if(*ppv) {
00108         IHTMLElementCollection_AddRef(HTMLELEMCOL(This));
00109         return S_OK;
00110     }
00111 
00112     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
00113     return E_NOINTERFACE;
00114 }
00115 
00116 static ULONG WINAPI HTMLElementCollection_AddRef(IHTMLElementCollection *iface)
00117 {
00118     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00119     LONG ref = InterlockedIncrement(&This->ref);
00120 
00121     TRACE("(%p) ref=%d\n", This, ref);
00122 
00123     return ref;
00124 }
00125 
00126 static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface)
00127 {
00128     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00129     LONG ref = InterlockedDecrement(&This->ref);
00130 
00131     TRACE("(%p) ref=%d\n", This, ref);
00132 
00133     if(!ref) {
00134         IUnknown_Release(This->ref_unk);
00135         release_dispex(&This->dispex);
00136         heap_free(This->elems);
00137         heap_free(This);
00138     }
00139 
00140     return ref;
00141 }
00142 
00143 static HRESULT WINAPI HTMLElementCollection_GetTypeInfoCount(IHTMLElementCollection *iface,
00144                                                              UINT *pctinfo)
00145 {
00146     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00147     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
00148 }
00149 
00150 static HRESULT WINAPI HTMLElementCollection_GetTypeInfo(IHTMLElementCollection *iface,
00151         UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
00152 {
00153     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00154     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
00155 }
00156 
00157 static HRESULT WINAPI HTMLElementCollection_GetIDsOfNames(IHTMLElementCollection *iface,
00158         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
00159 {
00160     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00161     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
00162 }
00163 
00164 static HRESULT WINAPI HTMLElementCollection_Invoke(IHTMLElementCollection *iface,
00165         DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
00166         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
00167 {
00168     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00169     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid,
00170             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
00171 }
00172 
00173 static HRESULT WINAPI HTMLElementCollection_toString(IHTMLElementCollection *iface,
00174                                                      BSTR *String)
00175 {
00176     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00177     FIXME("(%p)->(%p)\n", This, String);
00178     return E_NOTIMPL;
00179 }
00180 
00181 static HRESULT WINAPI HTMLElementCollection_put_length(IHTMLElementCollection *iface,
00182                                                        LONG v)
00183 {
00184     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00185     FIXME("(%p)->(%d)\n", This, v);
00186     return E_NOTIMPL;
00187 }
00188 
00189 static HRESULT WINAPI HTMLElementCollection_get_length(IHTMLElementCollection *iface,
00190                                                        LONG *p)
00191 {
00192     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00193 
00194     TRACE("(%p)->(%p)\n", This, p);
00195 
00196     *p = This->len;
00197     return S_OK;
00198 }
00199 
00200 static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection *iface,
00201                                                          IUnknown **p)
00202 {
00203     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00204     FIXME("(%p)->(%p)\n", This, p);
00205     return E_NOTIMPL;
00206 }
00207 
00208 static BOOL is_elem_id(HTMLElement *elem, LPCWSTR name)
00209 {
00210     BSTR elem_id;
00211     HRESULT hres;
00212 
00213     hres = IHTMLElement_get_id(HTMLELEM(elem), &elem_id);
00214     if(FAILED(hres)){
00215         WARN("IHTMLElement_get_id failed: 0x%08x\n", hres);
00216         return FALSE;
00217     }
00218 
00219     if(elem_id && !strcmpW(elem_id, name)) {
00220         SysFreeString(elem_id);
00221         return TRUE;
00222     }
00223 
00224     SysFreeString(elem_id);
00225     return FALSE;
00226 }
00227 
00228 static BOOL is_elem_name(HTMLElement *elem, LPCWSTR name)
00229 {
00230     const PRUnichar *str;
00231     nsAString nsstr, nsname;
00232     BOOL ret = FALSE;
00233     nsresult nsres;
00234 
00235     static const PRUnichar nameW[] = {'n','a','m','e',0};
00236 
00237     if(!elem->nselem)
00238         return FALSE;
00239 
00240     nsAString_Init(&nsstr, NULL);
00241     nsIDOMHTMLElement_GetId(elem->nselem, &nsstr);
00242     nsAString_GetData(&nsstr, &str);
00243     if(!strcmpiW(str, name)) {
00244         nsAString_Finish(&nsstr);
00245         return TRUE;
00246     }
00247 
00248     nsAString_InitDepend(&nsname, nameW);
00249     nsres =  nsIDOMHTMLElement_GetAttribute(elem->nselem, &nsname, &nsstr);
00250     nsAString_Finish(&nsname);
00251     if(NS_SUCCEEDED(nsres)) {
00252         nsAString_GetData(&nsstr, &str);
00253         ret = !strcmpiW(str, name);
00254     }
00255 
00256     nsAString_Finish(&nsstr);
00257     return ret;
00258 }
00259 
00260 static HRESULT get_item_idx(HTMLElementCollection *This, UINT idx, IDispatch **ret)
00261 {
00262     if(idx < This->len) {
00263         *ret = (IDispatch*)This->elems[idx];
00264         IDispatch_AddRef(*ret);
00265     }
00266 
00267     return S_OK;
00268 }
00269 
00270 static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface,
00271         VARIANT name, VARIANT index, IDispatch **pdisp)
00272 {
00273     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00274     HRESULT hres = S_OK;
00275 
00276     TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&name), debugstr_variant(&index), pdisp);
00277 
00278     *pdisp = NULL;
00279 
00280     switch(V_VT(&name)) {
00281     case VT_I4:
00282         if(V_I4(&name) < 0)
00283             return E_INVALIDARG;
00284         hres = get_item_idx(This, V_I4(&name), pdisp);
00285         break;
00286 
00287     case VT_UINT:
00288         hres = get_item_idx(This, V_UINT(&name), pdisp);
00289         break;
00290 
00291     case VT_BSTR: {
00292         DWORD i;
00293 
00294         if(V_VT(&index) == VT_I4) {
00295             LONG idx = V_I4(&index);
00296 
00297             if(idx < 0)
00298                 return E_INVALIDARG;
00299 
00300             for(i=0; i<This->len; i++) {
00301                 if(is_elem_name(This->elems[i], V_BSTR(&name)) && !idx--)
00302                     break;
00303             }
00304 
00305             if(i != This->len) {
00306                 *pdisp = (IDispatch*)HTMLELEM(This->elems[i]);
00307                 IDispatch_AddRef(*pdisp);
00308             }
00309         }else {
00310             elem_vector_t buf = {NULL, 0, 8};
00311 
00312             buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));
00313 
00314             for(i=0; i<This->len; i++) {
00315                 if(is_elem_name(This->elems[i], V_BSTR(&name)))
00316                     elem_vector_add(&buf, This->elems[i]);
00317             }
00318 
00319             if(buf.len > 1) {
00320                 elem_vector_normalize(&buf);
00321                 *pdisp = (IDispatch*)HTMLElementCollection_Create(This->ref_unk, buf.buf, buf.len);
00322             }else {
00323                 if(buf.len == 1) {
00324                     *pdisp = (IDispatch*)HTMLELEM(buf.buf[0]);
00325                     IDispatch_AddRef(*pdisp);
00326                 }
00327 
00328                 heap_free(buf.buf);
00329             }
00330         }
00331         break;
00332     }
00333 
00334     default:
00335         FIXME("Unsupported name %s\n", debugstr_variant(&name));
00336         hres = E_NOTIMPL;
00337     }
00338 
00339     if(SUCCEEDED(hres))
00340         TRACE("returning %p\n", *pdisp);
00341     return hres;
00342 }
00343 
00344 static HRESULT WINAPI HTMLElementCollection_tags(IHTMLElementCollection *iface,
00345                                                  VARIANT tagName, IDispatch **pdisp)
00346 {
00347     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00348     DWORD i;
00349     nsAString tag_str;
00350     const PRUnichar *tag;
00351     elem_vector_t buf = {NULL, 0, 8};
00352 
00353     if(V_VT(&tagName) != VT_BSTR) {
00354         WARN("Invalid arg\n");
00355         return DISP_E_MEMBERNOTFOUND;
00356     }
00357 
00358     TRACE("(%p)->(%s %p)\n", This, debugstr_w(V_BSTR(&tagName)), pdisp);
00359 
00360     buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));
00361 
00362     nsAString_Init(&tag_str, NULL);
00363 
00364     for(i=0; i<This->len; i++) {
00365         if(!This->elems[i]->nselem)
00366             continue;
00367 
00368         nsIDOMElement_GetTagName(This->elems[i]->nselem, &tag_str);
00369         nsAString_GetData(&tag_str, &tag);
00370 
00371         if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, tag, -1,
00372                           V_BSTR(&tagName), -1) == CSTR_EQUAL)
00373             elem_vector_add(&buf, This->elems[i]);
00374     }
00375 
00376     nsAString_Finish(&tag_str);
00377     elem_vector_normalize(&buf);
00378 
00379     TRACE("fount %d tags\n", buf.len);
00380 
00381     *pdisp = (IDispatch*)HTMLElementCollection_Create(This->ref_unk, buf.buf, buf.len);
00382     return S_OK;
00383 }
00384 
00385 #define DISPID_ELEMCOL_0 MSHTML_DISPID_CUSTOM_MIN
00386 
00387 static HRESULT HTMLElementCollection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
00388 {
00389     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00390     WCHAR *ptr;
00391     DWORD idx=0;
00392 
00393     if(!*name)
00394         return DISP_E_UNKNOWNNAME;
00395 
00396     for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
00397         idx = idx*10 + (*ptr-'0');
00398 
00399     if(*ptr) {
00400         /* the name contains alpha characters, so search by name & id */
00401         for(idx = 0; idx < This->len; ++idx) {
00402             if(is_elem_id(This->elems[idx], name) ||
00403                     is_elem_name(This->elems[idx], name))
00404                 break;
00405         }
00406     }
00407 
00408     if(idx >= This->len)
00409         return DISP_E_UNKNOWNNAME;
00410 
00411     *dispid = DISPID_ELEMCOL_0 + idx;
00412     TRACE("ret %x\n", *dispid);
00413     return S_OK;
00414 }
00415 
00416 static HRESULT HTMLElementCollection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
00417         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
00418 {
00419     HTMLElementCollection *This = ELEMCOL_THIS(iface);
00420     DWORD idx;
00421 
00422     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller);
00423 
00424     idx = id - DISPID_ELEMCOL_0;
00425     if(idx >= This->len)
00426         return DISP_E_UNKNOWNNAME;
00427 
00428     switch(flags) {
00429     case DISPATCH_PROPERTYGET:
00430         V_VT(res) = VT_DISPATCH;
00431         V_DISPATCH(res) = (IDispatch*)HTMLELEM(This->elems[idx]);
00432         IHTMLElement_AddRef(HTMLELEM(This->elems[idx]));
00433         break;
00434     default:
00435         FIXME("unimplemented flags %x\n", flags);
00436         return E_NOTIMPL;
00437     }
00438 
00439     return S_OK;
00440 }
00441 
00442 #undef ELEMCOL_THIS
00443 
00444 static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = {
00445     HTMLElementCollection_QueryInterface,
00446     HTMLElementCollection_AddRef,
00447     HTMLElementCollection_Release,
00448     HTMLElementCollection_GetTypeInfoCount,
00449     HTMLElementCollection_GetTypeInfo,
00450     HTMLElementCollection_GetIDsOfNames,
00451     HTMLElementCollection_Invoke,
00452     HTMLElementCollection_toString,
00453     HTMLElementCollection_put_length,
00454     HTMLElementCollection_get_length,
00455     HTMLElementCollection_get__newEnum,
00456     HTMLElementCollection_item,
00457     HTMLElementCollection_tags
00458 };
00459 
00460 static const dispex_static_data_vtbl_t HTMLElementColection_dispex_vtbl = {
00461     NULL,
00462     HTMLElementCollection_get_dispid,
00463     HTMLElementCollection_invoke
00464 };
00465 
00466 static const tid_t HTMLElementCollection_iface_tids[] = {
00467     IHTMLElementCollection_tid,
00468     0
00469 };
00470 static dispex_static_data_t HTMLElementCollection_dispex = {
00471     &HTMLElementColection_dispex_vtbl,
00472     DispHTMLElementCollection_tid,
00473     NULL,
00474     HTMLElementCollection_iface_tids
00475 };
00476 
00477 static void create_all_list(HTMLDocumentNode *doc, HTMLDOMNode *elem, elem_vector_t *buf)
00478 {
00479     nsIDOMNodeList *nsnode_list;
00480     nsIDOMNode *iter;
00481     PRUint32 list_len = 0, i;
00482     nsresult nsres;
00483 
00484     nsres = nsIDOMNode_GetChildNodes(elem->nsnode, &nsnode_list);
00485     if(NS_FAILED(nsres)) {
00486         ERR("GetChildNodes failed: %08x\n", nsres);
00487         return;
00488     }
00489 
00490     nsIDOMNodeList_GetLength(nsnode_list, &list_len);
00491     if(!list_len)
00492         return;
00493 
00494     for(i=0; i<list_len; i++) {
00495         nsres = nsIDOMNodeList_Item(nsnode_list, i, &iter);
00496         if(NS_FAILED(nsres)) {
00497             ERR("Item failed: %08x\n", nsres);
00498             continue;
00499         }
00500 
00501         if(is_elem_node(iter)) {
00502             HTMLDOMNode *node = get_node(doc, iter, TRUE);
00503 
00504             elem_vector_add(buf, HTMLELEM_NODE_THIS(node));
00505             create_all_list(doc, node, buf);
00506         }
00507     }
00508 }
00509 
00510 IHTMLElementCollection *create_all_collection(HTMLDOMNode *node, BOOL include_root)
00511 {
00512     elem_vector_t buf = {NULL, 0, 8};
00513 
00514     buf.buf = heap_alloc(buf.size*sizeof(HTMLElement**));
00515 
00516     if(include_root)
00517         elem_vector_add(&buf, HTMLELEM_NODE_THIS(node));
00518     create_all_list(node->doc, node, &buf);
00519     elem_vector_normalize(&buf);
00520 
00521     return HTMLElementCollection_Create((IUnknown*)HTMLDOMNODE(node), buf.buf, buf.len);
00522 }
00523 
00524 IHTMLElementCollection *create_collection_from_nodelist(HTMLDocumentNode *doc, IUnknown *unk, nsIDOMNodeList *nslist)
00525 {
00526     PRUint32 length = 0, i;
00527     elem_vector_t buf;
00528 
00529     nsIDOMNodeList_GetLength(nslist, &length);
00530 
00531     buf.len = 0;
00532     buf.size = length;
00533     if(length) {
00534         nsIDOMNode *nsnode;
00535 
00536         buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));
00537 
00538         for(i=0; i<length; i++) {
00539             nsIDOMNodeList_Item(nslist, i, &nsnode);
00540             if(is_elem_node(nsnode))
00541                 buf.buf[buf.len++] = HTMLELEM_NODE_THIS(get_node(doc, nsnode, TRUE));
00542             nsIDOMNode_Release(nsnode);
00543         }
00544 
00545         elem_vector_normalize(&buf);
00546     }else {
00547         buf.buf = NULL;
00548     }
00549 
00550     return HTMLElementCollection_Create(unk, buf.buf, buf.len);
00551 }
00552 
00553 IHTMLElementCollection *create_collection_from_htmlcol(HTMLDocumentNode *doc, IUnknown *unk, nsIDOMHTMLCollection *nscol)
00554 {
00555     PRUint32 length = 0, i;
00556     elem_vector_t buf;
00557 
00558     nsIDOMHTMLCollection_GetLength(nscol, &length);
00559 
00560     buf.len = buf.size = length;
00561     if(buf.len) {
00562         nsIDOMNode *nsnode;
00563 
00564         buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));
00565 
00566         for(i=0; i<length; i++) {
00567             nsIDOMHTMLCollection_Item(nscol, i, &nsnode);
00568             buf.buf[i] = HTMLELEM_NODE_THIS(get_node(doc, nsnode, TRUE));
00569             nsIDOMNode_Release(nsnode);
00570         }
00571     }else {
00572         buf.buf = NULL;
00573     }
00574 
00575     return HTMLElementCollection_Create(unk, buf.buf, buf.len);
00576 }
00577 
00578 static IHTMLElementCollection *HTMLElementCollection_Create(IUnknown *ref_unk,
00579             HTMLElement **elems, DWORD len)
00580 {
00581     HTMLElementCollection *ret = heap_alloc_zero(sizeof(HTMLElementCollection));
00582 
00583     ret->lpHTMLElementCollectionVtbl = &HTMLElementCollectionVtbl;
00584     ret->ref = 1;
00585     ret->elems = elems;
00586     ret->len = len;
00587 
00588     init_dispex(&ret->dispex, (IUnknown*)HTMLELEMCOL(ret), &HTMLElementCollection_dispex);
00589 
00590     IUnknown_AddRef(ref_unk);
00591     ret->ref_unk = ref_unk;
00592 
00593     TRACE("ret=%p len=%d\n", ret, len);
00594 
00595     return HTMLELEMCOL(ret);
00596 }

Generated on Sun May 27 2012 04:24:55 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.