shlwapi/tests: ChrCmpI* is not present on Win95B (winetestbot).
[wine] / dlls / ole32 / bindctx.c
index d83ffab..f7561bd 100644 (file)
 
 #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{
@@ -47,7 +46,7 @@ typedef struct BindCtxObject{
 
 } BindCtxObject;
 
-/* BindCtx data strucrture */
+/* BindCtx data structure */
 typedef struct BindCtxImpl{
 
     const IBindCtxVtbl *lpVtbl; /* VTable relative to the IBindCtx interface.*/
@@ -65,6 +64,7 @@ typedef struct BindCtxImpl{
 /* IBindCtx prototype functions : */
 static HRESULT WINAPI BindCtxImpl_ReleaseBoundObjects(IBindCtx*);
 static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl*, IUnknown*, LPOLESTR, DWORD *);
+static HRESULT BindCtxImpl_ExpandTable(BindCtxImpl *);
 
 /*******************************************************************************
  *        BindCtx_QueryInterface
@@ -74,11 +74,11 @@ BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
 {
     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;
@@ -87,7 +87,7 @@ BindCtxImpl_QueryInterface(IBindCtx* iface,REFIID riid,void** ppvObject)
     if (IsEqualIID(&IID_IUnknown, riid) ||
         IsEqualIID(&IID_IBindCtx, riid))
     {
-        *ppvObject = (IBindCtx*)This;
+        *ppvObject = This;
         IBindCtx_AddRef(iface);
         return S_OK;
     }
@@ -157,7 +157,14 @@ BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
     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);
 
@@ -167,20 +174,6 @@ BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* 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;
 }
 
@@ -196,6 +189,9 @@ BindCtxImpl_RevokeObjectBound(IBindCtx* iface, IUnknown* punk)
 
     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;
@@ -266,18 +262,20 @@ static HRESULT WINAPI
 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;
 }
 
@@ -324,6 +322,14 @@ BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
        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;
 
@@ -344,21 +350,6 @@ BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
 
     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;
 }
@@ -424,7 +415,11 @@ BindCtxImpl_RevokeObjectParam(IBindCtx* iface,LPOLESTR ppenum)
 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;
 }
 
@@ -473,6 +468,29 @@ static HRESULT BindCtxImpl_GetObjectIndex(BindCtxImpl* This,
     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 =
 {
@@ -510,31 +528,48 @@ static HRESULT BindCtxImpl_Construct(BindCtxImpl* This)
 
     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)
@@ -552,15 +587,33 @@ HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC * ppbc)
     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;
 }