Commit a083415d authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

hlink: Add link stack to browser context.

parent 3e302776
...@@ -21,15 +21,23 @@ ...@@ -21,15 +21,23 @@
#include "hlink_private.h" #include "hlink_private.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(hlink); WINE_DEFAULT_DEBUG_CHANNEL(hlink);
struct link_entry
{
struct list entry;
IHlink *link;
};
typedef struct typedef struct
{ {
IHlinkBrowseContext IHlinkBrowseContext_iface; IHlinkBrowseContext IHlinkBrowseContext_iface;
LONG ref; LONG ref;
HLBWINFO* BrowseWindowInfo; HLBWINFO* BrowseWindowInfo;
IHlink* CurrentPage; struct link_entry *current;
struct list links;
} HlinkBCImpl; } HlinkBCImpl;
static inline HlinkBCImpl *impl_from_IHlinkBrowseContext(IHlinkBrowseContext *iface) static inline HlinkBCImpl *impl_from_IHlinkBrowseContext(IHlinkBrowseContext *iface)
...@@ -68,18 +76,26 @@ static ULONG WINAPI IHlinkBC_fnAddRef (IHlinkBrowseContext* iface) ...@@ -68,18 +76,26 @@ static ULONG WINAPI IHlinkBC_fnAddRef (IHlinkBrowseContext* iface)
static ULONG WINAPI IHlinkBC_fnRelease (IHlinkBrowseContext* iface) static ULONG WINAPI IHlinkBC_fnRelease (IHlinkBrowseContext* iface)
{ {
HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface); HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
ULONG refCount = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(count=%u)\n", This, refCount + 1); TRACE("(%p)->(count=%u)\n", This, ref + 1);
if (refCount)
return refCount;
TRACE("-- destroying IHlinkBrowseContext (%p)\n", This); if (!ref)
heap_free(This->BrowseWindowInfo); {
if (This->CurrentPage) struct link_entry *link, *link2;
IHlink_Release(This->CurrentPage);
heap_free(This); LIST_FOR_EACH_ENTRY_SAFE(link, link2, &This->links, struct link_entry, entry)
return 0; {
list_remove(&link->entry);
IHlink_Release(link->link);
heap_free(link);
}
heap_free(This->BrowseWindowInfo);
heap_free(This);
}
return ref;
} }
static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface, static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface,
...@@ -165,17 +181,22 @@ static HRESULT WINAPI IHlinkBC_GetBrowseWindowInfo(IHlinkBrowseContext* iface, ...@@ -165,17 +181,22 @@ static HRESULT WINAPI IHlinkBC_GetBrowseWindowInfo(IHlinkBrowseContext* iface,
static HRESULT WINAPI IHlinkBC_SetInitialHlink(IHlinkBrowseContext* iface, static HRESULT WINAPI IHlinkBC_SetInitialHlink(IHlinkBrowseContext* iface,
IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName) IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
{ {
HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface); HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface);
struct link_entry *link;
TRACE("(%p)->(%p %s %s)\n", This, pimkTarget, debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName));
FIXME("(%p)->(%p %s %s)\n", This, pimkTarget, if (!list_empty(&This->links))
debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName)); return CO_E_ALREADYINITIALIZED;
if (This->CurrentPage) link = heap_alloc(sizeof(struct link_entry));
IHlink_Release(This->CurrentPage); if (!link) return E_OUTOFMEMORY;
HlinkCreateFromMoniker(pimkTarget, pwzLocation, pwzFriendlyName, NULL, HlinkCreateFromMoniker(pimkTarget, pwzLocation, pwzFriendlyName, NULL,
0, NULL, &IID_IHlink, (LPVOID*) &This->CurrentPage); 0, NULL, &IID_IHlink, (void**)&link->link);
list_add_head(&This->links, &link->entry);
This->current = LIST_ENTRY(list_head(&This->links), struct link_entry, entry);
return S_OK; return S_OK;
} }
...@@ -225,7 +246,7 @@ static HRESULT WINAPI IHlinkBC_GetHlink( IHlinkBrowseContext* iface, ...@@ -225,7 +246,7 @@ static HRESULT WINAPI IHlinkBC_GetHlink( IHlinkBrowseContext* iface,
return E_NOTIMPL; return E_NOTIMPL;
} }
*ppihl = This->CurrentPage; *ppihl = This->current->link;
IHlink_AddRef(*ppihl); IHlink_AddRef(*ppihl);
return S_OK; return S_OK;
...@@ -289,6 +310,8 @@ HRESULT HLinkBrowseContext_Constructor(IUnknown *pUnkOuter, REFIID riid, void ** ...@@ -289,6 +310,8 @@ HRESULT HLinkBrowseContext_Constructor(IUnknown *pUnkOuter, REFIID riid, void **
hl->ref = 1; hl->ref = 1;
hl->IHlinkBrowseContext_iface.lpVtbl = &hlvt; hl->IHlinkBrowseContext_iface.lpVtbl = &hlvt;
list_init(&hl->links);
hl->current = NULL;
*ppv = hl; *ppv = hl;
return S_OK; return S_OK;
......
...@@ -50,6 +50,12 @@ static void test_SetInitialHlink(void) ...@@ -50,6 +50,12 @@ static void test_SetInitialHlink(void)
hres = IHlinkBrowseContext_SetInitialHlink(bc, dummy, one, NULL); hres = IHlinkBrowseContext_SetInitialHlink(bc, dummy, one, NULL);
ok(hres == S_OK, "SetInitialHlink failed: 0x%08x\n", hres); ok(hres == S_OK, "SetInitialHlink failed: 0x%08x\n", hres);
hres = IHlinkBrowseContext_SetInitialHlink(bc, dummy, one, NULL);
ok(hres == CO_E_ALREADYINITIALIZED, "got 0x%08x\n", hres);
hres = IHlinkBrowseContext_SetInitialHlink(bc, dummy, five, NULL);
ok(hres == CO_E_ALREADYINITIALIZED, "got 0x%08x\n", hres);
hres = IHlinkBrowseContext_GetHlink(bc, HLID_CURRENT, &found_hlink); hres = IHlinkBrowseContext_GetHlink(bc, HLID_CURRENT, &found_hlink);
ok(hres == S_OK, "GetHlink failed: 0x%08x\n", hres); ok(hres == S_OK, "GetHlink failed: 0x%08x\n", hres);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment