/*
 * Dynamic pointer array (DPA) implementation
 *
 * Copyright 1998 Eric Kohl
 *           1998 Juergen Schmied <j.schmied@metronet.de>
 *           2000 Eric Kohl for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES
 *     These functions were involuntarily documented by Microsoft in 2002 as
 *     the outcome of an anti-trust suit brought by various U.S. governments.
 *     As a result the specifications on MSDN are inaccurate, incomplete 
 *     and misleading. A much more complete (unofficial) documentation is
 *     available at:
 *
 *     http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32  
 */

#define COBJMACROS

#include <stdarg.h>
#include <limits.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "commctrl.h"
#include "objbase.h"

#include "comctl32.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dpa);

struct _DPA
{
    INT    nItemCount;
    LPVOID   *ptrs;
    HANDLE hHeap;
    INT    nGrow;
    INT    nMaxCount;
};

typedef struct _STREAMDATA
{
    DWORD dwSize;
    DWORD dwData2;
    DWORD dwItems;
} STREAMDATA, *PSTREAMDATA;

typedef struct _LOADDATA
{
    INT   nCount;
    PVOID ptr;
} LOADDATA, *LPLOADDATA;

typedef HRESULT (CALLBACK *DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);


/**************************************************************************
 * DPA_LoadStream [COMCTL32.9]
 *
 * Loads a dynamic pointer array from a stream
 *
 * PARAMS
 *     phDpa    [O] pointer to a handle to a dynamic pointer array
 *     loadProc [I] pointer to a callback function
 *     pStream  [I] pointer to a stream
 *     lParam   [I] application specific value
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE 
 *
 * NOTES
 *     No more information available yet!
 */
HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc,
                               IStream *pStream, LPARAM lParam)
{
    HRESULT errCode;
    LARGE_INTEGER position;
    ULARGE_INTEGER newPosition;
    STREAMDATA  streamData;
    LOADDATA loadData;
    ULONG ulRead;
    HDPA hDpa;
    PVOID *ptr;

    FIXME ("phDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
           phDpa, loadProc, pStream, lParam);

    if (!phDpa || !loadProc || !pStream)
        return E_INVALIDARG;

    *phDpa = (HDPA)NULL;

    position.QuadPart = 0;

    /*
     * Zero out our streamData
     */
    memset(&streamData,0,sizeof(STREAMDATA));

    errCode = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &newPosition);
    if (errCode != S_OK)
        return errCode;

    errCode = IStream_Read (pStream, &streamData, sizeof(STREAMDATA), &ulRead);
    if (errCode != S_OK)
        return errCode;

    FIXME ("dwSize=%u dwData2=%u dwItems=%u\n",
           streamData.dwSize, streamData.dwData2, streamData.dwItems);

    if ( ulRead < sizeof(STREAMDATA) ||
    lParam < sizeof(STREAMDATA) ||
        streamData.dwSize < sizeof(STREAMDATA) ||
        streamData.dwData2 < 1) {
        errCode = E_FAIL;
    }

    if (streamData.dwItems > (UINT_MAX / 2 / sizeof(VOID*))) /* 536870911 */
        return E_OUTOFMEMORY;

    /* create the dpa */
    hDpa = DPA_Create (streamData.dwItems);
    if (!hDpa)
        return E_OUTOFMEMORY;

    if (!DPA_Grow (hDpa, streamData.dwItems))
        return E_OUTOFMEMORY;

    /* load data from the stream into the dpa */
    ptr = hDpa->ptrs;
    for (loadData.nCount = 0; loadData.nCount < streamData.dwItems; loadData.nCount++) {
        errCode = (loadProc)(&loadData, pStream, lParam);
        if (errCode != S_OK) {
            errCode = S_FALSE;
            break;
        }

        *ptr = loadData.ptr;
        ptr++;
    }

    /* set the number of items */
    hDpa->nItemCount = loadData.nCount;

    /* store the handle to the dpa */
    *phDpa = hDpa;
    FIXME ("new hDpa=%p, errorcode=%x\n", hDpa, errCode);

    return errCode;
}


/**************************************************************************
 * DPA_SaveStream [COMCTL32.10]
 *
 * Saves a dynamic pointer array to a stream
 *
 * PARAMS
 *     hDpa     [I] handle to a dynamic pointer array
 *     loadProc [I] pointer to a callback function
 *     pStream  [I] pointer to a stream
 *     lParam   [I] application specific value
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE 
 *
 * NOTES
 *     No more information available yet!
 */
HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc,
                               IStream *pStream, LPARAM lParam)
{

    FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
           hDpa, loadProc, pStream, lParam);

    return E_FAIL;
}


/**************************************************************************
 * DPA_Merge [COMCTL32.11]
 *
 * Merge two dynamic pointers arrays.
 *
 * PARAMS
 *     hdpa1       [I] handle to a dynamic pointer array
 *     hdpa2       [I] handle to a dynamic pointer array
 *     dwFlags     [I] flags
 *     pfnCompare  [I] pointer to sort function
 *     pfnMerge    [I] pointer to merge function
 *     lParam      [I] application specific value
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE 
 *
 * NOTES
 *     No more information available yet!
 */
BOOL WINAPI DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
                       PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge,
                       LPARAM lParam)
{
    INT nCount;
    LPVOID *pWork1, *pWork2;
    INT nResult, i;
    INT nIndex;

    TRACE("%p %p %08x %p %p %08lx)\n",
           hdpa1, hdpa2, dwFlags, pfnCompare, pfnMerge, lParam);

    if (IsBadWritePtr (hdpa1, sizeof(*hdpa1)))
        return FALSE;

    if (IsBadWritePtr (hdpa2, sizeof(*hdpa2)))
        return FALSE;

    if (IsBadCodePtr ((FARPROC)pfnCompare))
        return FALSE;

    if (IsBadCodePtr ((FARPROC)pfnMerge))
        return FALSE;

    if (!(dwFlags & DPAM_NOSORT)) {
        TRACE("sorting dpa's!\n");
        if (hdpa1->nItemCount > 0)
        DPA_Sort (hdpa1, pfnCompare, lParam);
        TRACE ("dpa 1 sorted!\n");
        if (hdpa2->nItemCount > 0)
        DPA_Sort (hdpa2, pfnCompare, lParam);
        TRACE ("dpa 2 sorted!\n");
    }

    if (hdpa2->nItemCount < 1)
        return TRUE;

    TRACE("hdpa1->nItemCount=%d hdpa2->nItemCount=%d\n",
           hdpa1->nItemCount, hdpa2->nItemCount);


    /* working but untrusted implementation */

    pWork1 = &(hdpa1->ptrs[hdpa1->nItemCount - 1]);
    pWork2 = &(hdpa2->ptrs[hdpa2->nItemCount - 1]);

    nIndex = hdpa1->nItemCount - 1;
    nCount = hdpa2->nItemCount - 1;

    do
    {
        if (nIndex < 0) {
            if ((nCount >= 0) && (dwFlags & DPAM_INSERT)) {
                /* Now insert the remaining new items into DPA 1 */
                TRACE("%d items to be inserted at start of DPA 1\n",
                      nCount+1);
                for (i=nCount; i>=0; i--) {
                    PVOID ptr;

                    ptr = (pfnMerge)(3, *pWork2, NULL, lParam);
                    if (!ptr)
                        return FALSE;
                    DPA_InsertPtr (hdpa1, 0, ptr);
                    pWork2--;
                }
            }
            break;
        }
        nResult = (pfnCompare)(*pWork1, *pWork2, lParam);
        TRACE("compare result=%d, dpa1.cnt=%d, dpa2.cnt=%d\n",
              nResult, nIndex, nCount);

        if (nResult == 0)
        {
            PVOID ptr;

            ptr = (pfnMerge)(1, *pWork1, *pWork2, lParam);
            if (!ptr)
                return FALSE;

            nCount--;
            pWork2--;
            *pWork1 = ptr;
            nIndex--;
            pWork1--;
        }
        else if (nResult > 0)
        {
            /* item in DPA 1 missing from DPA 2 */
            if (dwFlags & DPAM_DELETE)
            {
                /* Now delete the extra item in DPA1 */
                PVOID ptr;

                ptr = DPA_DeletePtr (hdpa1, hdpa1->nItemCount - 1);

                (pfnMerge)(2, ptr, NULL, lParam);
            }
            nIndex--;
            pWork1--;
        }
        else
        {
            /* new item in DPA 2 */
            if (dwFlags & DPAM_INSERT)
            {
                /* Now insert the new item in DPA 1 */
                PVOID ptr;

                ptr = (pfnMerge)(3, *pWork2, NULL, lParam);
                if (!ptr)
                    return FALSE;
                DPA_InsertPtr (hdpa1, nIndex+1, ptr);
            }
            nCount--;
            pWork2--;
        }

    }
    while (nCount >= 0);

    return TRUE;
}


/**************************************************************************
 * DPA_Destroy [COMCTL32.329]
 *
 * Destroys a dynamic pointer array
 *
 * PARAMS
 *     hdpa [I] handle (pointer) to the pointer array
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DPA_Destroy (const HDPA hdpa)
{
    TRACE("(%p)\n", hdpa);

    if (!hdpa)
        return FALSE;

    if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
        return FALSE;

    return HeapFree (hdpa->hHeap, 0, hdpa);
}


/**************************************************************************
 * DPA_Grow [COMCTL32.330]
 *
 * Sets the growth amount.
 *
 * PARAMS
 *     hdpa  [I] handle (pointer) to the existing (source) pointer array
 *     nGrow [I] number of items by which the array grows when it's too small
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DPA_Grow (const HDPA hdpa, INT nGrow)
{
    TRACE("(%p %d)\n", hdpa, nGrow);

    if (!hdpa)
        return FALSE;

    hdpa->nGrow = max(8, nGrow);

    return TRUE;
}


/**************************************************************************
 * DPA_Clone [COMCTL32.331]
 *
 * Copies a pointer array to an other one or creates a copy
 *
 * PARAMS
 *     hdpa    [I] handle (pointer) to the existing (source) pointer array
 *     hdpaNew [O] handle (pointer) to the destination pointer array
 *
 * RETURNS
 *     Success: pointer to the destination pointer array.
 *     Failure: NULL
 *
 * NOTES
 *     - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
 *       array will be created and it's handle (pointer) is returned.
 *     - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
 *       this implementation just returns NULL.
 */
HDPA WINAPI DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
{
    INT nNewItems, nSize;
    HDPA hdpaTemp;

    if (!hdpa)
        return NULL;

    TRACE("(%p %p)\n", hdpa, hdpaNew);

    if (!hdpaNew) {
        /* create a new DPA */
        hdpaTemp = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
                                    sizeof(*hdpaTemp));
        hdpaTemp->hHeap = hdpa->hHeap;
        hdpaTemp->nGrow = hdpa->nGrow;
    }
    else
        hdpaTemp = hdpaNew;

    if (hdpaTemp->ptrs) {
        /* remove old pointer array */
        HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
        hdpaTemp->ptrs = NULL;
        hdpaTemp->nItemCount = 0;
        hdpaTemp->nMaxCount = 0;
    }

    /* create a new pointer array */
    nNewItems = hdpaTemp->nGrow *
                (((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
    nSize = nNewItems * sizeof(LPVOID);
    hdpaTemp->ptrs = HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
    hdpaTemp->nMaxCount = nNewItems;

    /* clone the pointer array */
    hdpaTemp->nItemCount = hdpa->nItemCount;
    memmove (hdpaTemp->ptrs, hdpa->ptrs,
             hdpaTemp->nItemCount * sizeof(LPVOID));

    return hdpaTemp;
}


/**************************************************************************
 * DPA_GetPtr [COMCTL32.332]
 *
 * Retrieves a pointer from a dynamic pointer array
 *
 * PARAMS
 *     hdpa   [I] handle (pointer) to the pointer array
 *     nIndex [I] array index of the desired pointer
 *
 * RETURNS
 *     Success: pointer
 *     Failure: NULL
 */
LPVOID WINAPI DPA_GetPtr (const HDPA hdpa, INT nIndex)
{
    TRACE("(%p %d)\n", hdpa, nIndex);

    if (!hdpa)
        return NULL;
    if (!hdpa->ptrs) {
        WARN("no pointer array.\n");
        return NULL;
    }
    if ((nIndex < 0) || (nIndex >= hdpa->nItemCount)) {
        WARN("not enough pointers in array (%d vs %d).\n",nIndex,hdpa->nItemCount);
        return NULL;
    }

    TRACE("-- %p\n", hdpa->ptrs[nIndex]);

    return hdpa->ptrs[nIndex];
}


/**************************************************************************
 * DPA_GetPtrIndex [COMCTL32.333]
 *
 * Retrieves the index of the specified pointer
 *
 * PARAMS
 *     hdpa   [I] handle (pointer) to the pointer array
 *     p      [I] pointer
 *
 * RETURNS
 *     Success: index of the specified pointer
 *     Failure: -1
 */
INT WINAPI DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
{
    INT i;

    if (!hdpa || !hdpa->ptrs)
        return -1;

    for (i = 0; i < hdpa->nItemCount; i++) {
        if (hdpa->ptrs[i] == p)
            return i;
    }

    return -1;
}


/**************************************************************************
 * DPA_InsertPtr [COMCTL32.334]
 *
 * Inserts a pointer into a dynamic pointer array
 *
 * PARAMS
 *     hdpa [I] handle (pointer) to the array
 *     i    [I] array index
 *     p    [I] pointer to insert
 *
 * RETURNS
 *     Success: index of the inserted pointer
 *     Failure: -1
 */
INT WINAPI DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
{
    TRACE("(%p %d %p)\n", hdpa, i, p);

    if (!hdpa || i < 0) return -1;

    /* append item if index is out of bounds */
    i = min(hdpa->nItemCount, i);

    /* create empty spot at the end */
    if (!DPA_SetPtr(hdpa, hdpa->nItemCount, 0)) return -1;
    
    if (i != hdpa->nItemCount - 1)
        memmove (hdpa->ptrs + i + 1, hdpa->ptrs + i, 
                 (hdpa->nItemCount - i - 1) * sizeof(LPVOID));
    
    hdpa->ptrs[i] = p;
    return i;
}


/**************************************************************************
 * DPA_SetPtr [COMCTL32.335]
 *
 * Sets a pointer in the pointer array
 *
 * PARAMS
 *     hdpa [I] handle (pointer) to the pointer array
 *     i    [I] index of the pointer that will be set
 *     p    [I] pointer to be set
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
{
    LPVOID *lpTemp;

    TRACE("(%p %d %p)\n", hdpa, i, p);

    if (!hdpa || i < 0)
        return FALSE;

    if (hdpa->nItemCount <= i) {
        /* within the old array */
        if (hdpa->nMaxCount <= i) {
            /* resize the block of memory */
            INT nNewItems =
                hdpa->nGrow * ((((i+1) - 1) / hdpa->nGrow) + 1);
            INT nSize = nNewItems * sizeof(LPVOID);

            if (hdpa->ptrs)
                lpTemp = HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, hdpa->ptrs, nSize);
            else
                lpTemp = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, nSize);
            
            if (!lpTemp)
                return FALSE;

            hdpa->nMaxCount = nNewItems;
            hdpa->ptrs = lpTemp;
        }
        hdpa->nItemCount = i+1;
    }

    /* put the new entry in */
    hdpa->ptrs[i] = p;

    return TRUE;
}


/**************************************************************************
 * DPA_DeletePtr [COMCTL32.336]
 *
 * Removes a pointer from the pointer array.
 *
 * PARAMS
 *     hdpa [I] handle (pointer) to the pointer array
 *     i    [I] index of the pointer that will be deleted
 *
 * RETURNS
 *     Success: deleted pointer
 *     Failure: NULL
 */
LPVOID WINAPI DPA_DeletePtr (const HDPA hdpa, INT i)
{
    LPVOID *lpDest, *lpSrc, lpTemp = NULL;
    INT  nSize;

    TRACE("(%p %d)\n", hdpa, i);

    if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
        return NULL;

    lpTemp = hdpa->ptrs[i];

    /* do we need to move ?*/
    if (i < hdpa->nItemCount - 1) {
        lpDest = hdpa->ptrs + i;
        lpSrc = lpDest + 1;
        nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
        TRACE("-- move dest=%p src=%p size=%x\n",
               lpDest, lpSrc, nSize);
        memmove (lpDest, lpSrc, nSize);
    }

    hdpa->nItemCount --;

    /* free memory ?*/
    if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
        INT nNewItems = max(hdpa->nGrow * 2, hdpa->nItemCount);
        nSize = nNewItems * sizeof(LPVOID);
        lpDest = HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
                                      hdpa->ptrs, nSize);
        if (!lpDest)
            return NULL;

        hdpa->nMaxCount = nNewItems;
        hdpa->ptrs = lpDest;
    }

    return lpTemp;
}


/**************************************************************************
 * DPA_DeleteAllPtrs [COMCTL32.337]
 *
 * Removes all pointers and reinitializes the array.
 *
 * PARAMS
 *     hdpa [I] handle (pointer) to the pointer array
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DPA_DeleteAllPtrs (const HDPA hdpa)
{
    TRACE("(%p)\n", hdpa);

    if (!hdpa)
        return FALSE;

    if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
        return FALSE;

    hdpa->nItemCount = 0;
    hdpa->nMaxCount = hdpa->nGrow * 2;
    hdpa->ptrs = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
                                     hdpa->nMaxCount * sizeof(LPVOID));

    return TRUE;
}


/**************************************************************************
 * DPA_QuickSort [Internal]
 *
 * Ordinary quicksort (used by DPA_Sort).
 *
 * PARAMS
 *     lpPtrs     [I] pointer to the pointer array
 *     l          [I] index of the "left border" of the partition
 *     r          [I] index of the "right border" of the partition
 *     pfnCompare [I] pointer to the compare function
 *     lParam     [I] user defined value (3rd parameter in compare function)
 *
 * RETURNS
 *     NONE
 */
static VOID DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
                           PFNDPACOMPARE pfnCompare, LPARAM lParam)
{
    INT m;
    LPVOID t;

    TRACE("l=%i r=%i\n", l, r);

    if (l==r)    /* one element is always sorted */
        return;
    if (r<l)     /* oops, got it in the wrong order */
        {
        DPA_QuickSort(lpPtrs, r, l, pfnCompare, lParam);
        return;
        }
    m = (l+r)/2; /* divide by two */
    DPA_QuickSort(lpPtrs, l, m, pfnCompare, lParam);
    DPA_QuickSort(lpPtrs, m+1, r, pfnCompare, lParam);

    /* join the two sides */
    while( (l<=m) && (m<r) )
    {
        if(pfnCompare(lpPtrs[l],lpPtrs[m+1],lParam)>0)
        {
            t = lpPtrs[m+1];
            memmove(&lpPtrs[l+1],&lpPtrs[l],(m-l+1)*sizeof(lpPtrs[l]));
            lpPtrs[l] = t;

            m++;
        }
        l++;
    }
}


/**************************************************************************
 * DPA_Sort [COMCTL32.338]
 *
 * Sorts a pointer array using a user defined compare function
 *
 * PARAMS
 *     hdpa       [I] handle (pointer) to the pointer array
 *     pfnCompare [I] pointer to the compare function
 *     lParam     [I] user defined value (3rd parameter of compare function)
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */
BOOL WINAPI DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
{
    if (!hdpa || !pfnCompare)
        return FALSE;

    TRACE("(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);

    if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
        DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
                       pfnCompare, lParam);

    return TRUE;
}


/**************************************************************************
 * DPA_Search [COMCTL32.339]
 *
 * Searches a pointer array for a specified pointer
 *
 * PARAMS
 *     hdpa       [I] handle (pointer) to the pointer array
 *     pFind      [I] pointer to search for
 *     nStart     [I] start index
 *     pfnCompare [I] pointer to the compare function
 *     lParam     [I] user defined value (3rd parameter of compare function)
 *     uOptions   [I] search options
 *
 * RETURNS
 *     Success: index of the pointer in the array.
 *     Failure: -1
 */
INT WINAPI DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
                       PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
{
    if (!hdpa || !pfnCompare || !pFind)
        return -1;

    TRACE("(%p %p %d %p 0x%08lx 0x%08x)\n",
           hdpa, pFind, nStart, pfnCompare, lParam, uOptions);

    if (uOptions & DPAS_SORTED) {
        /* array is sorted --> use binary search */
        INT l, r, x, n;
        LPVOID *lpPtr;

        l = (nStart == -1) ? 0 : nStart;
        r = hdpa->nItemCount - 1;
        lpPtr = hdpa->ptrs;
        while (r >= l) {
            x = (l + r) / 2;
            n = (pfnCompare)(pFind, lpPtr[x], lParam);
            if (n == 0)
                return x;
            else if (n < 0)
                r = x - 1;
            else /* (n > 0) */
                l = x + 1;
        }
        if (uOptions & (DPAS_INSERTBEFORE|DPAS_INSERTAFTER)) return l;
    }
    else {
        /* array is not sorted --> use linear search */
        LPVOID *lpPtr;
        INT  nIndex;

        nIndex = (nStart == -1)? 0 : nStart;
        lpPtr = hdpa->ptrs;
        for (; nIndex < hdpa->nItemCount; nIndex++) {
            if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0)
                return nIndex;
        }
    }

    return -1;
}


/**************************************************************************
 * DPA_CreateEx [COMCTL32.340]
 *
 * Creates a dynamic pointer array using the specified size and heap.
 *
 * PARAMS
 *     nGrow [I] number of items by which the array grows when it is filled
 *     hHeap [I] handle to the heap where the array is stored
 *
 * RETURNS
 *     Success: handle (pointer) to the pointer array.
 *     Failure: NULL
 *
 * NOTES
 *     The DPA_ functions can be used to create and manipulate arrays of
 *     pointers.
 */
HDPA WINAPI DPA_CreateEx (INT nGrow, HANDLE hHeap)
{
    HDPA hdpa;

    TRACE("(%d %p)\n", nGrow, hHeap);

    if (hHeap)
        hdpa = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(*hdpa));
    else
        hdpa = Alloc (sizeof(*hdpa));

    if (hdpa) {
        hdpa->nGrow = max(8, nGrow);
        hdpa->hHeap = hHeap ? hHeap : GetProcessHeap();
        hdpa->nMaxCount = hdpa->nGrow * 2;
        hdpa->ptrs = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
                                hdpa->nMaxCount * sizeof(LPVOID));
    }

    TRACE("-- %p\n", hdpa);

    return hdpa;
}


/**************************************************************************
 * DPA_Create [COMCTL32.328]
 *
 * Creates a dynamic pointer array.
 *
 * PARAMS
 *     nGrow [I] number of items by which the array grows when it is filled
 *
 * RETURNS
 *     Success: handle (pointer) to the pointer array.
 *     Failure: NULL
 *
 * NOTES
 *     The DPA_ functions can be used to create and manipulate arrays of
 *     pointers.
 */
HDPA WINAPI DPA_Create (INT nGrow)
{
    return DPA_CreateEx( nGrow, 0 );
}


/**************************************************************************
 * DPA_EnumCallback [COMCTL32.385]
 *
 * Enumerates all items in a dynamic pointer array.
 *
 * PARAMS
 *     hdpa     [I] handle to the dynamic pointer array
 *     enumProc [I]
 *     lParam   [I]
 *
 * RETURNS
 *     none
 */
VOID WINAPI DPA_EnumCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc,
                              LPVOID lParam)
{
    INT i;

    TRACE("(%p %p %p)\n", hdpa, enumProc, lParam);

    if (!hdpa)
        return;
    if (hdpa->nItemCount <= 0)
        return;

    for (i = 0; i < hdpa->nItemCount; i++) {
        if ((enumProc)(hdpa->ptrs[i], lParam) == 0)
            return;
    }

    return;
}


/**************************************************************************
 * DPA_DestroyCallback [COMCTL32.386]
 *
 * Enumerates all items in a dynamic pointer array and destroys it.
 *
 * PARAMS
 *     hdpa     [I] handle to the dynamic pointer array
 *     enumProc [I]
 *     lParam   [I]
 *
 * RETURNS
 *     none
 */
void WINAPI DPA_DestroyCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc,
                                 LPVOID lParam)
{
    TRACE("(%p %p %p)\n", hdpa, enumProc, lParam);

    DPA_EnumCallback (hdpa, enumProc, lParam);
    DPA_Destroy (hdpa);
}
