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

navigate.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2007 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 #define NONAMELESSUNION
00020 #define NONAMELESSSTRUCT
00021 
00022 #include "wine/debug.h"
00023 
00024 #include "shdocvw.h"
00025 #include "exdispid.h"
00026 #include "shellapi.h"
00027 #include "winreg.h"
00028 #include "shlwapi.h"
00029 #include "wininet.h"
00030 #include "mshtml.h"
00031 
00032 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
00033 
00034 static const WCHAR emptyW[] = {0};
00035 
00036 typedef struct {
00037     const IBindStatusCallbackVtbl  *lpBindStatusCallbackVtbl;
00038     const IHttpNegotiateVtbl       *lpHttpNegotiateVtbl;
00039 
00040     LONG ref;
00041 
00042     DocHost *doc_host;
00043 
00044     LPWSTR url;
00045     HGLOBAL post_data;
00046     BSTR headers;
00047     ULONG post_data_len;
00048 } BindStatusCallback;
00049 
00050 #define BINDSC(x)  ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl)
00051 #define HTTPNEG(x) ((IHttpNegotiate*)      &(x)->lpHttpNegotiateVtbl)
00052 
00053 static void dump_BINDINFO(BINDINFO *bi)
00054 {
00055     static const char * const BINDINFOF_str[] = {
00056         "#0",
00057         "BINDINFOF_URLENCODESTGMEDDATA",
00058         "BINDINFOF_URLENCODEDEXTRAINFO"
00059     };
00060 
00061     static const char * const BINDVERB_str[] = {
00062         "BINDVERB_GET",
00063         "BINDVERB_POST",
00064         "BINDVERB_PUT",
00065         "BINDVERB_CUSTOM"
00066     };
00067 
00068     TRACE("\n"
00069             "BINDINFO = {\n"
00070             "    %d, %s,\n"
00071             "    {%d, %p, %p},\n"
00072             "    %s,\n"
00073             "    %s,\n"
00074             "    %s,\n"
00075             "    %d, %08x, %d, %d\n"
00076             "    {%d %p %x},\n"
00077             "    %s\n"
00078             "    %p, %d\n"
00079             "}\n",
00080 
00081             bi->cbSize, debugstr_w(bi->szExtraInfo),
00082             bi->stgmedData.tymed, bi->stgmedData.u.hGlobal, bi->stgmedData.pUnkForRelease,
00083             bi->grfBindInfoF > BINDINFOF_URLENCODEDEXTRAINFO
00084                 ? "unknown" : BINDINFOF_str[bi->grfBindInfoF],
00085             bi->dwBindVerb > BINDVERB_CUSTOM
00086                 ? "unknown" : BINDVERB_str[bi->dwBindVerb],
00087             debugstr_w(bi->szCustomVerb),
00088             bi->cbstgmedData, bi->dwOptions, bi->dwOptionsFlags, bi->dwCodePage,
00089             bi->securityAttributes.nLength,
00090             bi->securityAttributes.lpSecurityDescriptor,
00091             bi->securityAttributes.bInheritHandle,
00092             debugstr_guid(&bi->iid),
00093             bi->pUnk, bi->dwReserved
00094             );
00095 }
00096 
00097 static void set_status_text(BindStatusCallback *This, LPCWSTR str)
00098 {
00099     VARIANTARG arg;
00100     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
00101 
00102     if(!This->doc_host)
00103         return;
00104 
00105     V_VT(&arg) = VT_BSTR;
00106     V_BSTR(&arg) = str ? SysAllocString(str) : NULL;
00107     call_sink(This->doc_host->cps.wbe2, DISPID_STATUSTEXTCHANGE, &dispparams);
00108     VariantClear(&arg);
00109 
00110     if(This->doc_host->frame)
00111         IOleInPlaceFrame_SetStatusText(This->doc_host->frame, str);
00112 }
00113 
00114 static HRESULT set_dochost_url(DocHost *This, const WCHAR *url)
00115 {
00116     WCHAR *new_url;
00117 
00118     if(url) {
00119         new_url = heap_strdupW(url);
00120         if(!new_url)
00121             return E_OUTOFMEMORY;
00122     }else {
00123         new_url = NULL;
00124     }
00125 
00126     heap_free(This->url);
00127     This->url = new_url;
00128 
00129     This->container_vtbl->SetURL(This, This->url);
00130     return S_OK;
00131 }
00132 
00133 #define BINDSC_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
00134 
00135 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
00136                                                         REFIID riid, void **ppv)
00137 {
00138     BindStatusCallback *This = BINDSC_THIS(iface);
00139 
00140     *ppv = NULL;
00141 
00142     if(IsEqualGUID(&IID_IUnknown, riid)) {
00143         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
00144         *ppv = BINDSC(This);
00145     }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
00146         TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
00147         *ppv = BINDSC(This);
00148     }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
00149         TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
00150         *ppv = HTTPNEG(This);
00151     }
00152 
00153     if(*ppv) {
00154         IBindStatusCallback_AddRef(BINDSC(This));
00155         return S_OK;
00156     }
00157 
00158     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
00159     return E_NOINTERFACE;
00160 }
00161 
00162 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
00163 {
00164     BindStatusCallback *This = BINDSC_THIS(iface);
00165     LONG ref = InterlockedIncrement(&This->ref);
00166 
00167     TRACE("(%p) ref=%d\n", This, ref);
00168 
00169     return ref;
00170 }
00171 
00172 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
00173 {
00174     BindStatusCallback *This = BINDSC_THIS(iface);
00175     LONG ref = InterlockedDecrement(&This->ref);
00176 
00177     TRACE("(%p) ref=%d\n", This, ref);
00178 
00179     if(!ref) {
00180         if(This->doc_host)
00181             IOleClientSite_Release(CLIENTSITE(This->doc_host));
00182         if(This->post_data)
00183             GlobalFree(This->post_data);
00184         SysFreeString(This->headers);
00185         heap_free(This->url);
00186         heap_free(This);
00187     }
00188 
00189     return ref;
00190 }
00191 
00192 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
00193        DWORD dwReserved, IBinding *pbind)
00194 {
00195     BindStatusCallback *This = BINDSC_THIS(iface);
00196 
00197     TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
00198 
00199     return S_OK;
00200 }
00201 
00202 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface,
00203        LONG *pnPriority)
00204 {
00205     BindStatusCallback *This = BINDSC_THIS(iface);
00206     FIXME("(%p)->(%p)\n", This, pnPriority);
00207     return E_NOTIMPL;
00208 }
00209 
00210 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface,
00211        DWORD reserved)
00212 {
00213     BindStatusCallback *This = BINDSC_THIS(iface);
00214     FIXME("(%p)->(%d)\n", This, reserved);
00215     return E_NOTIMPL;
00216 }
00217 
00218 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
00219         ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
00220 {
00221     BindStatusCallback *This = BINDSC_THIS(iface);
00222 
00223     TRACE("(%p)->(%d %d %d %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
00224           debugstr_w(szStatusText));
00225 
00226     switch(ulStatusCode) {
00227     case BINDSTATUS_REDIRECTING:
00228         return set_dochost_url(This->doc_host, szStatusText);
00229     case BINDSTATUS_BEGINDOWNLOADDATA:
00230         set_status_text(This, szStatusText); /* FIXME: "Start downloading from site: %s" */
00231         return S_OK;
00232     case BINDSTATUS_ENDDOWNLOADDATA:
00233         set_status_text(This, szStatusText); /* FIXME: "Downloading from site: %s" */
00234         return S_OK;
00235     case BINDSTATUS_CLASSIDAVAILABLE:
00236     case BINDSTATUS_MIMETYPEAVAILABLE:
00237     case BINDSTATUS_BEGINSYNCOPERATION:
00238     case BINDSTATUS_ENDSYNCOPERATION:
00239         return S_OK;
00240     default:
00241         FIXME("status code %u\n", ulStatusCode);
00242     }
00243 
00244     return S_OK;
00245 }
00246 
00247 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
00248         HRESULT hresult, LPCWSTR szError)
00249 {
00250     BindStatusCallback *This = BINDSC_THIS(iface);
00251 
00252     TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
00253 
00254     set_status_text(This, emptyW);
00255 
00256     if(This->doc_host) {
00257         IOleClientSite_Release(CLIENTSITE(This->doc_host));
00258         This->doc_host = NULL;
00259     }
00260 
00261     return S_OK;
00262 }
00263 
00264 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
00265         DWORD *grfBINDF, BINDINFO *pbindinfo)
00266 {
00267     BindStatusCallback *This = BINDSC_THIS(iface);
00268 
00269     TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
00270 
00271     *grfBINDF = BINDF_ASYNCHRONOUS;
00272 
00273     if(This->post_data) {
00274         pbindinfo->dwBindVerb = BINDVERB_POST;
00275 
00276         pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
00277         pbindinfo->stgmedData.u.hGlobal = This->post_data;
00278         pbindinfo->cbstgmedData = This->post_data_len;
00279         pbindinfo->stgmedData.pUnkForRelease = (IUnknown*)BINDSC(This);
00280         IBindStatusCallback_AddRef(BINDSC(This));
00281     }
00282 
00283     return S_OK;
00284 }
00285 
00286 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface,
00287         DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
00288 {
00289     BindStatusCallback *This = BINDSC_THIS(iface);
00290     FIXME("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
00291     return E_NOTIMPL;
00292 }
00293 
00294 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
00295         REFIID riid, IUnknown *punk)
00296 {
00297     BindStatusCallback *This = BINDSC_THIS(iface);
00298 
00299     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
00300 
00301     return dochost_object_available(This->doc_host, punk);
00302 }
00303 
00304 #undef BSC_THIS
00305 
00306 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
00307     BindStatusCallback_QueryInterface,
00308     BindStatusCallback_AddRef,
00309     BindStatusCallback_Release,
00310     BindStatusCallback_OnStartBinding,
00311     BindStatusCallback_GetPriority,
00312     BindStatusCallback_OnLowResource,
00313     BindStatusCallback_OnProgress,
00314     BindStatusCallback_OnStopBinding,
00315     BindStatusCallback_GetBindInfo,
00316     BindStatusCallback_OnDataAvailable,
00317     BindStatusCallback_OnObjectAvailable
00318 };
00319 
00320 #define HTTPNEG_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate, iface)
00321 
00322 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface,
00323                                                    REFIID riid, void **ppv)
00324 {
00325     BindStatusCallback *This = HTTPNEG_THIS(iface);
00326     return IBindStatusCallback_QueryInterface(BINDSC(This), riid, ppv);
00327 }
00328 
00329 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
00330 {
00331     BindStatusCallback *This = HTTPNEG_THIS(iface);
00332     return IBindStatusCallback_AddRef(BINDSC(This));
00333 }
00334 
00335 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
00336 {
00337     BindStatusCallback *This = HTTPNEG_THIS(iface);
00338     return IBindStatusCallback_Release(BINDSC(This));
00339 }
00340 
00341 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
00342         LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
00343 {
00344     BindStatusCallback *This = HTTPNEG_THIS(iface);
00345 
00346     TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders),
00347           dwReserved, pszAdditionalHeaders);
00348 
00349     if(This->headers) {
00350         int size = (strlenW(This->headers)+1)*sizeof(WCHAR);
00351         *pszAdditionalHeaders = CoTaskMemAlloc(size);
00352         memcpy(*pszAdditionalHeaders, This->headers, size);
00353     }
00354 
00355     return S_OK;
00356 }
00357 
00358 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface,
00359         DWORD dwResponseCode, LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
00360         LPWSTR *pszAdditionalRequestHeaders)
00361 {
00362     BindStatusCallback *This = HTTPNEG_THIS(iface);
00363     TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
00364           debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
00365     return S_OK;
00366 }
00367 
00368 #undef HTTPNEG_THIS
00369 
00370 static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
00371     HttpNegotiate_QueryInterface,
00372     HttpNegotiate_AddRef,
00373     HttpNegotiate_Release,
00374     HttpNegotiate_BeginningTransaction,
00375     HttpNegotiate_OnResponse
00376 };
00377 
00378 static BindStatusCallback *create_callback(DocHost *doc_host, LPCWSTR url, PBYTE post_data,
00379         ULONG post_data_len, LPCWSTR headers)
00380 {
00381     BindStatusCallback *ret = heap_alloc(sizeof(BindStatusCallback));
00382 
00383     ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl;
00384     ret->lpHttpNegotiateVtbl      = &HttpNegotiateVtbl;
00385 
00386     ret->ref = 1;
00387     ret->url = heap_strdupW(url);
00388     ret->post_data = NULL;
00389     ret->post_data_len = post_data_len;
00390     ret->headers = headers ? SysAllocString(headers) : NULL;
00391 
00392     ret->doc_host = doc_host;
00393     IOleClientSite_AddRef(CLIENTSITE(doc_host));
00394 
00395     if(post_data) {
00396         ret->post_data = GlobalAlloc(0, post_data_len);
00397         memcpy(ret->post_data, post_data, post_data_len);
00398     }
00399 
00400     return ret;
00401 }
00402 
00403 static void on_before_navigate2(DocHost *This, LPCWSTR url, SAFEARRAY *post_data, LPWSTR headers, VARIANT_BOOL *cancel)
00404 {
00405     VARIANT var_url, var_flags, var_frame_name, var_post_data, var_post_data2, var_headers;
00406     DISPPARAMS dispparams;
00407     VARIANTARG params[7];
00408 
00409     dispparams.cArgs = 7;
00410     dispparams.cNamedArgs = 0;
00411     dispparams.rgdispidNamedArgs = NULL;
00412     dispparams.rgvarg = params;
00413 
00414     This->busy = VARIANT_TRUE;
00415 
00416     V_VT(params) = VT_BOOL|VT_BYREF;
00417     V_BOOLREF(params) = cancel;
00418 
00419     V_VT(params+1) = (VT_BYREF|VT_VARIANT);
00420     V_VARIANTREF(params+1) = &var_headers;
00421     V_VT(&var_headers) = VT_BSTR;
00422     V_BSTR(&var_headers) = headers;
00423 
00424     V_VT(params+2) = (VT_BYREF|VT_VARIANT);
00425     V_VARIANTREF(params+2) = &var_post_data2;
00426     V_VT(&var_post_data2) = (VT_BYREF|VT_VARIANT);
00427     V_VARIANTREF(&var_post_data2) = &var_post_data;
00428 
00429     if(post_data) {
00430         V_VT(&var_post_data) = VT_UI1|VT_ARRAY;
00431         V_ARRAY(&var_post_data) = post_data;
00432     }else {
00433         V_VT(&var_post_data) = VT_EMPTY;
00434     }
00435 
00436     V_VT(params+3) = (VT_BYREF|VT_VARIANT);
00437     V_VARIANTREF(params+3) = &var_frame_name;
00438     V_VT(&var_frame_name) = VT_BSTR;
00439     V_BSTR(&var_frame_name) = NULL;
00440 
00441     V_VT(params+4) = (VT_BYREF|VT_VARIANT);
00442     V_VARIANTREF(params+4) = &var_flags;
00443     V_VT(&var_flags) = VT_I4;
00444     V_I4(&var_flags) = 0;
00445 
00446     V_VT(params+5) = (VT_BYREF|VT_VARIANT);
00447     V_VARIANTREF(params+5) = &var_url;
00448     V_VT(&var_url) = VT_BSTR;
00449     V_BSTR(&var_url) = SysAllocString(url);
00450 
00451     V_VT(params+6) = (VT_DISPATCH);
00452     V_DISPATCH(params+6) = This->disp;
00453 
00454     call_sink(This->cps.wbe2, DISPID_BEFORENAVIGATE2, &dispparams);
00455 
00456     SysFreeString(V_BSTR(&var_url));
00457 }
00458 
00459 /* FIXME: urlmon should handle it */
00460 static BOOL try_application_url(LPCWSTR url)
00461 {
00462     SHELLEXECUTEINFOW exec_info;
00463     WCHAR app[64];
00464     HKEY hkey;
00465     DWORD res, type;
00466     HRESULT hres;
00467 
00468     static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
00469 
00470     hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
00471     if(FAILED(hres))
00472         return FALSE;
00473 
00474     res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
00475     if(res != ERROR_SUCCESS)
00476         return FALSE;
00477 
00478     res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
00479     RegCloseKey(hkey);
00480     if(res != ERROR_SUCCESS || type != REG_SZ)
00481         return FALSE;
00482 
00483     TRACE("openning application %s\n", debugstr_w(app));
00484  
00485     memset(&exec_info, 0, sizeof(exec_info));
00486     exec_info.cbSize = sizeof(exec_info);
00487     exec_info.lpFile = url;
00488     exec_info.nShow = SW_SHOW;
00489 
00490     return ShellExecuteExW(&exec_info);
00491 }
00492 
00493 static HRESULT create_moniker(LPCWSTR url, IMoniker **mon)
00494 {
00495     WCHAR new_url[INTERNET_MAX_URL_LENGTH];
00496     DWORD size;
00497     HRESULT hres;
00498 
00499     if(PathIsURLW(url))
00500         return CreateURLMoniker(NULL, url, mon);
00501 
00502     if(url[1] == ':') {
00503         size = sizeof(new_url);
00504         hres = UrlCreateFromPathW(url, new_url, &size, 0);
00505         if(FAILED(hres)) {
00506             WARN("UrlCreateFromPathW failed: %08x\n", hres);
00507             return hres;
00508         }
00509     }else {
00510         size = sizeof(new_url)/sizeof(WCHAR);
00511         hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME);
00512         TRACE("got %s\n", debugstr_w(new_url));
00513         if(FAILED(hres)) {
00514             WARN("UrlApplyScheme failed: %08x\n", hres);
00515             return hres;
00516         }
00517     }
00518 
00519     return CreateURLMoniker(NULL, new_url, mon);
00520 }
00521 
00522 static HRESULT bind_to_object(DocHost *This, IMoniker *mon, LPCWSTR url, IBindCtx *bindctx,
00523                               IBindStatusCallback *callback)
00524 {
00525     IUnknown *unk = NULL;
00526     WCHAR *display_name;
00527     HRESULT hres;
00528 
00529     if(mon) {
00530         IMoniker_AddRef(mon);
00531     }else {
00532         hres = create_moniker(url, &mon);
00533         if(FAILED(hres))
00534             return hres;
00535     }
00536 
00537     hres = IMoniker_GetDisplayName(mon, 0, NULL, &display_name);
00538     if(FAILED(hres)) {
00539         FIXME("GetDisplayName failed: %08x\n", hres);
00540         return hres;
00541     }
00542 
00543     hres = set_dochost_url(This, display_name);
00544     CoTaskMemFree(display_name);
00545     if(FAILED(hres))
00546         return hres;
00547 
00548     IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM,
00549                                  (IUnknown*)CLIENTSITE(This));
00550 
00551     hres = IMoniker_BindToObject(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk);
00552     if(SUCCEEDED(hres)) {
00553         hres = S_OK;
00554         if(unk)
00555             IUnknown_Release(unk);
00556     }else if(try_application_url(url)) {
00557         hres = S_OK;
00558     }else {
00559         FIXME("BindToObject failed: %08x\n", hres);
00560     }
00561 
00562     IMoniker_Release(mon);
00563     return S_OK;
00564 }
00565 
00566 static void html_window_navigate(DocHost *This, IHTMLPrivateWindow *window, BSTR url, BSTR headers, SAFEARRAY *post_data)
00567 {
00568     VARIANT headers_var, post_data_var;
00569     BSTR empty_str;
00570     HRESULT hres;
00571 
00572     hres = set_dochost_url(This, url);
00573     if(FAILED(hres))
00574         return;
00575 
00576     empty_str = SysAllocStringLen(NULL, 0);
00577 
00578     if(headers) {
00579         V_VT(&headers_var) = VT_BSTR;
00580         V_BSTR(&headers_var) = headers;
00581     }else {
00582         V_VT(&headers_var) = VT_EMPTY;
00583     }
00584 
00585     if(post_data) {
00586         V_VT(&post_data_var) = VT_UI1|VT_ARRAY;
00587         V_ARRAY(&post_data_var) = post_data;
00588     }else {
00589         V_VT(&post_data_var) = VT_EMPTY;
00590     }
00591 
00592     set_doc_state(This, READYSTATE_LOADING);
00593     hres = IHTMLPrivateWindow_SuperNavigate(window, url, empty_str, NULL, NULL, &post_data_var, &headers_var, 0);
00594     SysFreeString(empty_str);
00595     if(FAILED(hres))
00596         WARN("SuprtNavigate failed: %08x\n", hres);
00597 }
00598 
00599 typedef struct {
00600     task_header_t header;
00601     BSTR url;
00602     BSTR headers;
00603     SAFEARRAY *post_data;
00604     BOOL async_notif;
00605 } task_doc_navigate_t;
00606 
00607 static HRESULT free_doc_navigate_task(task_doc_navigate_t *task, BOOL free_task)
00608 {
00609     SysFreeString(task->url);
00610     SysFreeString(task->headers);
00611     if(task->post_data)
00612         SafeArrayDestroy(task->post_data);
00613     if(free_task)
00614         heap_free(task);
00615     return E_OUTOFMEMORY;
00616 }
00617 
00618 static void doc_navigate_proc(DocHost *This, task_header_t *t)
00619 {
00620     task_doc_navigate_t *task = (task_doc_navigate_t*)t;
00621     IHTMLPrivateWindow *priv_window;
00622     HRESULT hres;
00623 
00624     if(!This->doc_navigate)
00625         return;
00626 
00627     if(task->async_notif) {
00628         VARIANT_BOOL cancel = VARIANT_FALSE;
00629         on_before_navigate2(This, task->url, task->post_data, task->headers, &cancel);
00630         if(cancel) {
00631             TRACE("Navigation calnceled\n");
00632             free_doc_navigate_task(task, FALSE);
00633             return;
00634         }
00635     }
00636 
00637     hres = IUnknown_QueryInterface(This->doc_navigate, &IID_IHTMLPrivateWindow, (void**)&priv_window);
00638     if(SUCCEEDED(hres)) {
00639         html_window_navigate(This, priv_window, task->url, task->headers, task->post_data);
00640         IHTMLPrivateWindow_Release(priv_window);
00641     }else {
00642         WARN("Could not get IHTMLPrivateWindow iface: %08x\n", hres);
00643     }
00644 
00645     free_doc_navigate_task(task, FALSE);
00646 }
00647 
00648 static HRESULT async_doc_navigate(DocHost *This, LPCWSTR url, LPCWSTR headers, PBYTE post_data, ULONG post_data_size,
00649         BOOL async_notif)
00650 {
00651     task_doc_navigate_t *task;
00652 
00653     task = heap_alloc_zero(sizeof(*task));
00654     if(!task)
00655         return E_OUTOFMEMORY;
00656 
00657     task->url = SysAllocString(url);
00658     if(!task->url)
00659         return free_doc_navigate_task(task, TRUE);
00660 
00661     if(headers) {
00662         task->headers = SysAllocString(headers);
00663         if(!task->headers)
00664             return free_doc_navigate_task(task, TRUE);
00665     }
00666 
00667     if(post_data) {
00668         task->post_data = SafeArrayCreateVector(VT_UI1, 0, post_data_size);
00669         if(!task->post_data)
00670             return free_doc_navigate_task(task, TRUE);
00671         memcpy(task->post_data->pvData, post_data, post_data_size);
00672     }
00673 
00674     if(!async_notif) {
00675         VARIANT_BOOL cancel = VARIANT_FALSE;
00676 
00677         on_before_navigate2(This, task->url, task->post_data, task->headers, &cancel);
00678         if(cancel) {
00679             TRACE("Navigation calnceled\n");
00680             free_doc_navigate_task(task, TRUE);
00681             return S_OK;
00682         }
00683     }
00684 
00685     task->async_notif = async_notif;
00686     push_dochost_task(This, &task->header, doc_navigate_proc, FALSE);
00687     return S_OK;
00688 }
00689 
00690 static HRESULT navigate_bsc(DocHost *This, BindStatusCallback *bsc, IMoniker *mon)
00691 {
00692     VARIANT_BOOL cancel = VARIANT_FALSE;
00693     SAFEARRAY *post_data = NULL;
00694     IBindCtx *bindctx;
00695     HRESULT hres;
00696 
00697     set_doc_state(This, READYSTATE_LOADING);
00698 
00699     if(bsc->post_data) {
00700         post_data = SafeArrayCreateVector(VT_UI1, 0, bsc->post_data_len);
00701         memcpy(post_data->pvData, post_data, bsc->post_data_len);
00702     }
00703 
00704     on_before_navigate2(This, bsc->url, post_data, bsc->headers, &cancel);
00705     if(post_data)
00706         SafeArrayDestroy(post_data);
00707     if(cancel) {
00708         FIXME("Navigation canceled\n");
00709         return S_OK;
00710     }
00711 
00712     if(This->document)
00713         deactivate_document(This);
00714 
00715     CreateAsyncBindCtx(0, BINDSC(bsc), 0, &bindctx);
00716 
00717     if(This->frame)
00718         IOleInPlaceFrame_EnableModeless(This->frame, FALSE);
00719 
00720     hres = bind_to_object(This, mon, bsc->url, bindctx, BINDSC(bsc));
00721 
00722     if(This->frame)
00723         IOleInPlaceFrame_EnableModeless(This->frame, TRUE);
00724 
00725     IBindCtx_Release(bindctx);
00726 
00727     return hres;
00728 }
00729 
00730 typedef struct {
00731     task_header_t header;
00732     BindStatusCallback *bsc;
00733 } task_navigate_bsc_t;
00734 
00735 static void navigate_bsc_proc(DocHost *This, task_header_t *t)
00736 {
00737     task_navigate_bsc_t *task = (task_navigate_bsc_t*)t;
00738 
00739     if(!This->hwnd)
00740         create_doc_view_hwnd(This);
00741 
00742     navigate_bsc(This, task->bsc, NULL);
00743 
00744     IBindStatusCallback_Release(BINDSC(task->bsc));
00745 }
00746 
00747 
00748 HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags,
00749                      const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
00750 {
00751     PBYTE post_data = NULL;
00752     ULONG post_data_len = 0;
00753     LPWSTR headers = NULL;
00754     HRESULT hres = S_OK;
00755 
00756     TRACE("navigating to %s\n", debugstr_w(url));
00757 
00758     if((Flags && V_VT(Flags) != VT_EMPTY) 
00759        || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY))
00760         FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n",
00761                 Flags, Flags ? V_VT(Flags) : -1, TargetFrameName,
00762                 TargetFrameName ? V_VT(TargetFrameName) : -1);
00763 
00764     if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) {
00765         SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data);
00766         post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements;
00767     }
00768 
00769     if(Headers && V_VT(Headers) == VT_BSTR) {
00770         headers = V_BSTR(Headers);
00771         TRACE("Headers: %s\n", debugstr_w(headers));
00772     }
00773 
00774     set_doc_state(This, READYSTATE_LOADING);
00775     This->ready_state = READYSTATE_LOADING;
00776 
00777     if(This->doc_navigate) {
00778         WCHAR new_url[INTERNET_MAX_URL_LENGTH];
00779 
00780         if(PathIsURLW(url)) {
00781             new_url[0] = 0;
00782         }else {
00783             DWORD size;
00784 
00785             size = sizeof(new_url)/sizeof(WCHAR);
00786             hres = UrlApplySchemeW(url, new_url, &size,
00787                     URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT);
00788             if(FAILED(hres)) {
00789                 WARN("UrlApplyScheme failed: %08x\n", hres);
00790                 new_url[0] = 0;
00791             }
00792         }
00793 
00794         hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data,
00795                 post_data_len, TRUE);
00796     }else {
00797         task_navigate_bsc_t *task;
00798 
00799         task = heap_alloc(sizeof(*task));
00800         task->bsc = create_callback(This, url, post_data, post_data_len, headers);
00801         push_dochost_task(This, &task->header, navigate_bsc_proc, This->url == NULL);
00802     }
00803 
00804     if(post_data)
00805         SafeArrayUnaccessData(V_ARRAY(PostData));
00806 
00807     return hres;
00808 }
00809 
00810 static HRESULT navigate_hlink(DocHost *This, IMoniker *mon, IBindCtx *bindctx,
00811                               IBindStatusCallback *callback)
00812 {
00813     IHttpNegotiate *http_negotiate;
00814     BindStatusCallback *bsc;
00815     PBYTE post_data = NULL;
00816     ULONG post_data_len = 0;
00817     LPWSTR headers = NULL, url;
00818     BINDINFO bindinfo;
00819     DWORD bindf = 0;
00820     HRESULT hres;
00821 
00822     hres = IMoniker_GetDisplayName(mon, 0, NULL, &url);
00823     if(FAILED(hres))
00824         FIXME("GetDisplayName failed: %08x\n", hres);
00825 
00826     hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate,
00827                                               (void**)&http_negotiate);
00828     if(SUCCEEDED(hres)) {
00829         static const WCHAR null_string[] = {0};
00830 
00831         IHttpNegotiate_BeginningTransaction(http_negotiate, null_string, null_string, 0,
00832                                             &headers);
00833         IHttpNegotiate_Release(http_negotiate);
00834     }
00835 
00836     memset(&bindinfo, 0, sizeof(bindinfo));
00837     bindinfo.cbSize = sizeof(bindinfo);
00838 
00839     hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
00840     dump_BINDINFO(&bindinfo);
00841     if(bindinfo.dwBindVerb == BINDVERB_POST) {
00842         post_data_len = bindinfo.cbstgmedData;
00843         if(post_data_len)
00844             post_data = bindinfo.stgmedData.u.hGlobal;
00845     }
00846 
00847     if(This->doc_navigate) {
00848         hres = async_doc_navigate(This, url, headers, post_data, post_data_len, FALSE);
00849     }else {
00850         bsc = create_callback(This, url, post_data, post_data_len, headers);
00851         hres = navigate_bsc(This, bsc, mon);
00852         IBindStatusCallback_Release(BINDSC(bsc));
00853     }
00854 
00855     CoTaskMemFree(url);
00856     CoTaskMemFree(headers);
00857     ReleaseBindInfo(&bindinfo);
00858 
00859     return hres;
00860 }
00861 
00862 HRESULT go_home(DocHost *This)
00863 {
00864     HKEY hkey;
00865     DWORD res, type, size;
00866     WCHAR wszPageName[MAX_PATH];
00867     static const WCHAR wszAboutBlank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
00868     static const WCHAR wszStartPage[] = {'S','t','a','r','t',' ','P','a','g','e',0};
00869     static const WCHAR wszSubKey[] = {'S','o','f','t','w','a','r','e','\\',
00870                                       'M','i','c','r','o','s','o','f','t','\\',
00871                                       'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
00872                                       'M','a','i','n',0};
00873 
00874     res = RegOpenKeyW(HKEY_CURRENT_USER, wszSubKey, &hkey);
00875     if (res != ERROR_SUCCESS)
00876         return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);
00877 
00878     size = sizeof(wszPageName);
00879     res = RegQueryValueExW(hkey, wszStartPage, NULL, &type, (LPBYTE)wszPageName, &size);
00880     RegCloseKey(hkey);
00881     if (res != ERROR_SUCCESS || type != REG_SZ)
00882         return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);
00883 
00884     return navigate_url(This, wszPageName, NULL, NULL, NULL, NULL);
00885 }
00886 
00887 #define HLINKFRAME_THIS(iface) DEFINE_THIS(HlinkFrame, IHlinkFrame, iface)
00888 
00889 static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
00890 {
00891     HlinkFrame *This = HLINKFRAME_THIS(iface);
00892     return IUnknown_QueryInterface(This->outer, riid, ppv);
00893 }
00894 
00895 static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
00896 {
00897     HlinkFrame *This = HLINKFRAME_THIS(iface);
00898     return IUnknown_AddRef(This->outer);
00899 }
00900 
00901 static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
00902 {
00903     HlinkFrame *This = HLINKFRAME_THIS(iface);
00904     return IUnknown_Release(This->outer);
00905 }
00906 
00907 static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
00908                                                   IHlinkBrowseContext *pihlbc)
00909 {
00910     HlinkFrame *This = HLINKFRAME_THIS(iface);
00911     FIXME("(%p)->(%p)\n", This, pihlbc);
00912     return E_NOTIMPL;
00913 }
00914 
00915 static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
00916                                                   IHlinkBrowseContext **ppihlbc)
00917 {
00918     HlinkFrame *This = HLINKFRAME_THIS(iface);
00919     FIXME("(%p)->(%p)\n", This, ppihlbc);
00920     return E_NOTIMPL;
00921 }
00922 
00923 static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
00924                                           IBindStatusCallback *pibsc, IHlink *pihlNavigate)
00925 {
00926     HlinkFrame *This = HLINKFRAME_THIS(iface);
00927     IMoniker *mon;
00928     LPWSTR location = NULL;
00929 
00930     TRACE("(%p)->(%08x %p %p %p)\n", This, grfHLNF, pbc, pibsc, pihlNavigate);
00931 
00932     if(grfHLNF)
00933         FIXME("unsupported grfHLNF=%08x\n", grfHLNF);
00934 
00935     /* Windows calls GetTargetFrameName here. */
00936 
00937     IHlink_GetMonikerReference(pihlNavigate, 1, &mon, &location);
00938 
00939     if(location) {
00940         FIXME("location = %s\n", debugstr_w(location));
00941         CoTaskMemFree(location);
00942     }
00943 
00944     /* Windows calls GetHlinkSite here */
00945 
00946     if(grfHLNF & HLNF_OPENINNEWWINDOW) {
00947         FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
00948         return E_NOTIMPL;
00949     }
00950 
00951     return navigate_hlink(This->doc_host, mon, pbc, pibsc);
00952 }
00953 
00954 static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
00955         IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
00956 {
00957     HlinkFrame *This = HLINKFRAME_THIS(iface);
00958     FIXME("(%p)->(%08x %p %s %s %d)\n", This, grfHLNF, pimkTarget, debugstr_w(pwzLocation),
00959           debugstr_w(pwzFriendlyName), dwreserved);
00960     return E_NOTIMPL;
00961 }
00962 
00963 static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
00964         IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
00965 {
00966     HlinkFrame *This = HLINKFRAME_THIS(iface);
00967     FIXME("(%p)->(%u %p %s %s)\n", This, uHLID, pimkTarget, debugstr_w(pwzLocation),
00968           debugstr_w(pwzFriendlyName));
00969     return E_NOTIMPL;
00970 }
00971 
00972 #undef HLINKFRAME_THIS
00973 
00974 static const IHlinkFrameVtbl HlinkFrameVtbl = {
00975     HlinkFrame_QueryInterface,
00976     HlinkFrame_AddRef,
00977     HlinkFrame_Release,
00978     HlinkFrame_SetBrowseContext,
00979     HlinkFrame_GetBrowseContext,
00980     HlinkFrame_Navigate,
00981     HlinkFrame_OnNavigate,
00982     HlinkFrame_UpdateHlink
00983 };
00984 
00985 #define TARGETFRAME2_THIS(iface) DEFINE_THIS(HlinkFrame, ITargetFrame2, iface)
00986 
00987 static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv)
00988 {
00989     HlinkFrame *This = TARGETFRAME2_THIS(iface);
00990     return IUnknown_QueryInterface(This->outer, riid, ppv);
00991 }
00992 
00993 static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface)
00994 {
00995     HlinkFrame *This = TARGETFRAME2_THIS(iface);
00996     return IUnknown_AddRef(This->outer);
00997 }
00998 
00999 static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface)
01000 {
01001     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01002     return IUnknown_Release(This->outer);
01003 }
01004 
01005 static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName)
01006 {
01007     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01008     FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName));
01009     return E_NOTIMPL;
01010 }
01011 
01012 static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName)
01013 {
01014     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01015     FIXME("(%p)->(%p)\n", This, ppszFrameName);
01016     return E_NOTIMPL;
01017 }
01018 
01019 static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent)
01020 {
01021     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01022     FIXME("(%p)->(%p)\n", This, ppunkParent);
01023     return E_NOTIMPL;
01024 }
01025 
01026 static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc)
01027 {
01028     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01029     FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc));
01030     return E_NOTIMPL;
01031 }
01032 
01033 static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc)
01034 {
01035     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01036     FIXME("(%p)->()\n", This);
01037     return E_NOTIMPL;
01038 }
01039 
01040 static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer)
01041 {
01042     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01043     FIXME("(%p)->(%p)\n", This, ppContainer);
01044     return E_NOTIMPL;
01045 }
01046 
01047 static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags)
01048 {
01049     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01050     FIXME("(%p)->(%x)\n", This, dwFlags);
01051     return E_NOTIMPL;
01052 }
01053 
01054 static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags)
01055 {
01056     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01057     FIXME("(%p)->(%p)\n", This, pdwFlags);
01058     return E_NOTIMPL;
01059 }
01060 
01061 static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight)
01062 {
01063     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01064     FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight);
01065     return E_NOTIMPL;
01066 }
01067 
01068 static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight)
01069 {
01070     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01071     FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight);
01072     return E_NOTIMPL;
01073 }
01074 
01075 static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
01076 {
01077     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01078     FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
01079     return E_NOTIMPL;
01080 }
01081 
01082 static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias)
01083 {
01084     HlinkFrame *This = TARGETFRAME2_THIS(iface);
01085     FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias);
01086     return E_NOTIMPL;
01087 }
01088 
01089 #undef TARGETFRAME2_THIS
01090 
01091 static const ITargetFrame2Vtbl TargetFrame2Vtbl = {
01092     TargetFrame2_QueryInterface,
01093     TargetFrame2_AddRef,
01094     TargetFrame2_Release,
01095     TargetFrame2_SetFrameName,
01096     TargetFrame2_GetFrameName,
01097     TargetFrame2_GetParentFrame,
01098     TargetFrame2_SetFrameSrc,
01099     TargetFrame2_GetFrameSrc,
01100     TargetFrame2_GetFramesContainer,
01101     TargetFrame2_SetFrameOptions,
01102     TargetFrame2_GetFrameOptions,
01103     TargetFrame2_SetFrameMargins,
01104     TargetFrame2_GetFrameMargins,
01105     TargetFrame2_FindFrame,
01106     TargetFrame2_GetTargetAlias
01107 };
01108 
01109 BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv)
01110 {
01111     if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
01112         TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
01113         *ppv = HLINKFRAME(This);
01114     }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) {
01115         TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv);
01116         *ppv = TARGETFRAME2(This);
01117     }else {
01118         return FALSE;
01119     }
01120 
01121     IUnknown_AddRef((IUnknown*)*ppv);
01122     return TRUE;
01123 }
01124 
01125 void HlinkFrame_Init(HlinkFrame *This, IUnknown *outer, DocHost *doc_host)
01126 {
01127     This->lpIHlinkFrameVtbl   = &HlinkFrameVtbl;
01128     This->lpITargetFrame2Vtbl = &TargetFrame2Vtbl;
01129 
01130     This->outer = outer;
01131     This->doc_host = doc_host;
01132 }

Generated on Sat May 26 2012 04:23:38 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.