#include <stdarg.h>
#include <string.h>
-#include <assert.h>
#define COBJMACROS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
+#include "winnls.h"
#include "objbase.h"
+
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-/* represent the first size table and it's increment block size */
-#define BLOCK_TAB_SIZE 10
-#define MAX_TAB_SIZE 0xFFFFFFFF
+#define BINDCTX_FIRST_TABLE_SIZE 4
/* data structure of the BindCtx table elements */
typedef struct BindCtxObject{
} BindCtxObject;
-/* BindCtx data strucrture */
+/* BindCtx data structure */
typedef struct BindCtxImpl{
const IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/
/* IBindCtx prototype functions : */
static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx*);
static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl*, IUnknown*, LPOLESTR, DWORD *);
+static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *);
/*******************************************************************************
* BindCtx_QueryInterface
{
BindCtxImpl *This = (BindCtxImpl *)iface;
- TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
+ TRACE("(%p %s %p)\n",This, debugstr_guid(riid), ppvObject);
/* Perform a sanity check on the parameters.*/
- if ( (This==0) || (ppvObject==0) )
- return E_INVALIDARG;
+ if (!ppvObject)
+ return E_POINTER;
/* Initialize the return parameter.*/
*ppvObject = 0;
if (IsEqualIID(&IID_IUnknown, riid) ||
IsEqualIID(&IID_IBindCtx, riid))
{
- *ppvObject = (IBindCtx*)This;
+ *ppvObject = This;
IBindCtx_AddRef(iface);
return S_OK;
}
TRACE("(%p,%p)\n",This,punk);
if (punk==NULL)
- return E_POINTER;
+ return S_OK;
+
+ if (lastIndex == This->bindCtxTableSize)
+ {
+ HRESULT hr = BindCtxImpl_ExpandTable(This);
+ if (FAILED(hr))
+ return hr;
+ }
IUnknown_AddRef(punk);
This->bindCtxTable[lastIndex].regType = 0;
lastIndex= ++This->bindCtxTableLastIndex;
- if (lastIndex == This->bindCtxTableSize){ /* the table is full so it must be resized */
-
- if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
- FIXME("This->bindCtxTableSize: %ld is out of data limite\n", This->bindCtxTableSize);
- return E_FAIL;
- }
-
- This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
-
- This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
- This->bindCtxTableSize * sizeof(BindCtxObject));
- if (!This->bindCtxTable)
- return E_OUTOFMEMORY;
- }
return S_OK;
}
TRACE("(%p,%p)\n",This,punk);
+ if (!punk)
+ return E_INVALIDARG;
+
/* check if the object was registered or not */
if (BindCtxImpl_GetObjectIndex(This,punk,NULL,&index)==S_FALSE)
return MK_E_NOTBOUND;
BindCtxImpl_GetBindOptions(IBindCtx* iface,BIND_OPTS *pbindopts)
{
BindCtxImpl *This = (BindCtxImpl *)iface;
+ ULONG cbStruct;
TRACE("(%p,%p)\n",This,pbindopts);
if (pbindopts==NULL)
return E_POINTER;
- if (pbindopts->cbStruct > sizeof(BIND_OPTS2))
- {
- WARN("invalid size\n");
- return E_INVALIDARG; /* FIXME : not verified */
- }
- memcpy(pbindopts, &This->bindOption2, pbindopts->cbStruct);
+ cbStruct = pbindopts->cbStruct;
+ if (cbStruct > sizeof(BIND_OPTS2))
+ cbStruct = sizeof(BIND_OPTS2);
+
+ memcpy(pbindopts, &This->bindOption2, cbStruct);
+ pbindopts->cbStruct = cbStruct;
+
return S_OK;
}
IUnknown_AddRef(punk);
return S_OK;
}
+
+ if (This->bindCtxTableLastIndex == This->bindCtxTableSize)
+ {
+ HRESULT hr = BindCtxImpl_ExpandTable(This);
+ if (FAILED(hr))
+ return hr;
+ }
+
This->bindCtxTable[This->bindCtxTableLastIndex].pObj = punk;
This->bindCtxTable[This->bindCtxTableLastIndex].regType = 1;
This->bindCtxTableLastIndex++;
- if (This->bindCtxTableLastIndex == This->bindCtxTableSize)
- {
- /* table is full ! must be resized */
-
- This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
- if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE))
- {
- FIXME("This->bindCtxTableSize: %ld is out of data limite\n", This->bindCtxTableSize);
- return E_FAIL;
- }
- This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
- This->bindCtxTableSize * sizeof(BindCtxObject));
- if (!This->bindCtxTable)
- return E_OUTOFMEMORY;
- }
IUnknown_AddRef(punk);
return S_OK;
}
static HRESULT WINAPI
BindCtxImpl_EnumObjectParam(IBindCtx* iface,IEnumString** pszkey)
{
- FIXME("(%p,%p),stub!\n",iface,pszkey);
+ TRACE("(%p,%p)\n",iface,pszkey);
+
+ *pszkey = NULL;
+
+ /* not implemented in native either */
return E_NOTIMPL;
}
return S_FALSE;
}
+static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *This)
+{
+ if (!This->bindCtxTableSize)
+ {
+ This->bindCtxTableSize = BINDCTX_FIRST_TABLE_SIZE;
+ This->bindCtxTable = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ This->bindCtxTableSize * sizeof(BindCtxObject));
+ }
+ else
+ {
+ This->bindCtxTableSize *= 2;
+
+ This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
+ This->bindCtxTableSize * sizeof(BindCtxObject));
+ }
+
+ if (!This->bindCtxTable)
+ return E_OUTOFMEMORY;
+
+ return S_OK;
+}
+
+
/* Virtual function table for the BindCtx class. */
static const IBindCtxVtbl VT_BindCtxImpl =
{
This->bindOption2.dwTrackFlags = 0;
This->bindOption2.dwClassContext = CLSCTX_SERVER;
- This->bindOption2.locale = 1033;
+ This->bindOption2.locale = GetThreadLocale();
This->bindOption2.pServerInfo = 0;
/* Initialize the bindctx table */
- This->bindCtxTableSize=BLOCK_TAB_SIZE;
+ This->bindCtxTableSize=0;
This->bindCtxTableLastIndex=0;
- This->bindCtxTable = HeapAlloc(GetProcessHeap(), 0,
- This->bindCtxTableSize*sizeof(BindCtxObject));
-
- if (This->bindCtxTable==NULL)
- return E_OUTOFMEMORY;
+ This->bindCtxTable = NULL;
return S_OK;
}
/******************************************************************************
* CreateBindCtx (OLE32.@)
- ******************************************************************************/
+ *
+ * Creates a bind context. A bind context encompasses information and options
+ * used when binding to a moniker.
+ *
+ * PARAMS
+ * reserved [I] Reserved. Set to 0.
+ * ppbc [O] Address that receives the bind context object.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: Any HRESULT code.
+ */
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
{
BindCtxImpl* newBindCtx = 0;
HRESULT hr;
IID riid=IID_IBindCtx;
- TRACE("(%ld,%p)\n",reserved,ppbc);
+ TRACE("(%d,%p)\n",reserved,ppbc);
+
+ if (!ppbc) return E_INVALIDARG;
+
+ *ppbc = NULL;
+
+ if (reserved != 0)
+ {
+ ERR("reserved should be 0, not 0x%x\n", reserved);
+ return E_INVALIDARG;
+ }
newBindCtx = HeapAlloc(GetProcessHeap(), 0, sizeof(BindCtxImpl));
if (newBindCtx == 0)
return hr;
}
+/******************************************************************************
+ * BindMoniker [OLE32.@]
+ *
+ * Binds to a moniker.
+ *
+ * PARAMS
+ * pmk [I] Moniker to bind to.
+ * grfOpt [I] Reserved option flags. Set to 0.
+ * riid [I] ID of the interface to bind to.
+ * pvResult [O] Address that receives the interface of the object that was bound to.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: Any HRESULT code.
+ */
HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID riid, LPVOID * ppvResult)
{
HRESULT res;
IBindCtx * pbc;
- TRACE("(%p, %lx, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
+ TRACE("(%p, %x, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult);
res = CreateBindCtx(grfOpt, &pbc);
if (SUCCEEDED(res))
+ {
res = IMoniker_BindToObject(pmk, pbc, NULL, riid, ppvResult);
+ IBindCtx_Release(pbc);
+ }
return res;
}