464 lines
9.9 KiB
C
464 lines
9.9 KiB
C
/*
|
|
* Undocumented functions from COMCTL32.DLL
|
|
*
|
|
* Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
|
|
*
|
|
* NOTES
|
|
* All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
|
|
* Do NOT rely on names or contents of undocumented structures and types!!!
|
|
* These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
|
|
* COMCTL32.DLL (internally).
|
|
*
|
|
* TODO
|
|
* - Fix DSA_InsertItem.
|
|
* - Fix DSA_GetItem.
|
|
* - Write documentation.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "windows.h"
|
|
#include "heap.h"
|
|
#include "debug.h"
|
|
|
|
|
|
typedef struct _DSA_DATA
|
|
{
|
|
DWORD dwEntryCount;
|
|
DWORD dwMaxCount;
|
|
DWORD dwInitial;
|
|
DWORD dwGrow;
|
|
LPSTR *ptrs;
|
|
} DSA_DATA, *LPDSA_DATA;
|
|
|
|
|
|
typedef struct _DPA_DATA
|
|
{
|
|
DWORD dwEntryCount;
|
|
DWORD dwMaxCount;
|
|
DWORD dwGrow;
|
|
LPDWORD ptrs;
|
|
} DPA_DATA, *LPDPA_DATA;
|
|
|
|
|
|
DWORD WINAPI DSA_Create (DWORD, DWORD);
|
|
|
|
|
|
DWORD WINAPI DPA_Create (DWORD);
|
|
DWORD WINAPI DPA_GetPtr (DWORD, DWORD);
|
|
DWORD WINAPI DPA_InsertPtr (DWORD, DWORD, DWORD);
|
|
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
* Alloc [COMCTL32.71]
|
|
*
|
|
*/
|
|
|
|
LPVOID WINAPI
|
|
COMCTL32_Alloc (DWORD dwParam)
|
|
{
|
|
LPVOID lpPtr;
|
|
|
|
lpPtr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, dwParam);
|
|
|
|
TRACE (commctrl, "(0x%08lx) ret=0x%08lx\n", dwParam, (DWORD)lpPtr);
|
|
|
|
return lpPtr;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* ReAlloc [COMCTL32.72]
|
|
*
|
|
*/
|
|
|
|
LPVOID WINAPI
|
|
COMCTL32_ReAlloc (LPVOID dwParam1, DWORD dwParam2)
|
|
{
|
|
LPVOID dwPtr;
|
|
|
|
if (dwParam1 == 0)
|
|
dwPtr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
|
|
dwParam2);
|
|
else
|
|
dwPtr = HeapReAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
|
|
dwParam1, dwParam2);
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n",
|
|
(DWORD)dwParam1, dwParam2, (DWORD)dwPtr);
|
|
|
|
return dwPtr;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* Free [COMCTL32.73]
|
|
*
|
|
*/
|
|
|
|
DWORD WINAPI
|
|
COMCTL32_Free (LPVOID dwParam)
|
|
{
|
|
TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam);
|
|
HeapFree (GetProcessHeap (), 0, dwParam);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* GetSize [COMCTL32.74]
|
|
*
|
|
*/
|
|
|
|
DWORD WINAPI
|
|
COMCTL32_GetSize (LPVOID dwParam)
|
|
{
|
|
TRACE (commctrl, "(0x%08lx)\n", (DWORD)dwParam);
|
|
return (HeapSize (GetProcessHeap (), 0, dwParam));
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* DSA_Create [COMCTL32.320] Creates a dynamic string array
|
|
*
|
|
* PARAMS
|
|
* dwParam1 [I]
|
|
* dwParam2 [I]
|
|
*/
|
|
|
|
DWORD WINAPI
|
|
DSA_Create (DWORD dwParam1, DWORD dwParam2)
|
|
{
|
|
LPDSA_DATA dsaPtr;
|
|
|
|
dsaPtr = (LPDSA_DATA)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
|
|
sizeof(DSA_DATA));
|
|
dsaPtr->dwInitial = dwParam1;
|
|
dsaPtr->dwGrow = dwParam2;
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx) ret=0x%08lx\n",
|
|
dwParam1, dwParam2, (DWORD)dsaPtr);
|
|
|
|
return (DWORD)dsaPtr;
|
|
}
|
|
|
|
|
|
DWORD WINAPI
|
|
DSA_Destroy (DWORD dwParam1)
|
|
{
|
|
LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
|
|
DWORD i;
|
|
|
|
TRACE (commctrl, "(0x%08lx):semi-stub!\n", dwParam1);
|
|
|
|
if (dsaPtr->ptrs) {
|
|
for (i = 0; i < dsaPtr->dwEntryCount; i++) {
|
|
if (dsaPtr->ptrs[i])
|
|
HeapFree (GetProcessHeap (), 0, (LPSTR)dsaPtr->ptrs[i]);
|
|
}
|
|
}
|
|
|
|
HeapFree (GetProcessHeap (), 0, dsaPtr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD WINAPI
|
|
DSA_GetItem (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
|
{
|
|
LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
|
|
|
|
FIXME (commctrl, "(0x%08lx 0x%08lx 0x%08lx): stub!\n",
|
|
dwParam1, dwParam2, dwParam3);
|
|
|
|
if (dsaPtr == NULL)
|
|
return 0;
|
|
if (dsaPtr->ptrs == NULL)
|
|
return 0;
|
|
if ((dwParam2 < 0) || (dwParam2 >= dsaPtr->dwEntryCount))
|
|
return 0;
|
|
|
|
// FIXME (commctrl, "\"%s\"\n", (LPSTR)dsaPtr->ptrs[dwParam2]);
|
|
|
|
return lstrcpy32A ((LPSTR)dwParam3, (LPSTR)dsaPtr->ptrs[dwParam2]);
|
|
|
|
// return 0;
|
|
}
|
|
|
|
|
|
DWORD WINAPI
|
|
DSA_GetItemPtr (DWORD dwParam1, DWORD dwParam2)
|
|
{
|
|
LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2);
|
|
|
|
if (dsaPtr == NULL)
|
|
return 0;
|
|
if (dsaPtr->ptrs == NULL)
|
|
return 0;
|
|
if ((dwParam2 < 0) || (dwParam2 >= dsaPtr->dwEntryCount))
|
|
return 0;
|
|
|
|
TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dsaPtr->ptrs[dwParam2]);
|
|
|
|
return (DWORD)dsaPtr->ptrs[dwParam2];
|
|
}
|
|
|
|
|
|
DWORD WINAPI
|
|
DSA_InsertItem (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
|
{
|
|
LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
|
|
DWORD dwIndex;
|
|
INT32 len;
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx \"%s\"):semi-stub!\n",
|
|
dwParam1, dwParam2, (LPSTR)dwParam3);
|
|
|
|
if (dsaPtr->ptrs == NULL) {
|
|
dsaPtr->ptrs = (LPSTR*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
|
|
dsaPtr->dwInitial * sizeof(LPVOID));
|
|
dsaPtr->dwMaxCount = dsaPtr->dwInitial;
|
|
dwIndex = 0;
|
|
len = lstrlen32A ((LPSTR)dwParam3);
|
|
dsaPtr->ptrs[dwIndex] =
|
|
(LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
|
|
lstrcpy32A (dsaPtr->ptrs[dwIndex], (LPSTR)dwParam3);
|
|
}
|
|
else {
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx)\n",
|
|
dsaPtr->dwEntryCount, dsaPtr->dwMaxCount);
|
|
if (dwParam2 >= dsaPtr->dwEntryCount) {
|
|
if (dsaPtr->dwEntryCount < dsaPtr->dwMaxCount) {
|
|
dwIndex = dsaPtr->dwEntryCount;
|
|
len = lstrlen32A ((LPSTR)dwParam3);
|
|
dsaPtr->ptrs[dwIndex] =
|
|
(LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
|
|
lstrcpy32A (dsaPtr->ptrs[dwIndex], (LPSTR)dwParam3);
|
|
}
|
|
else {
|
|
/* allocate new pointer list and copy all pointers */
|
|
LPSTR *lpOldPtrs = dsaPtr->ptrs;
|
|
dsaPtr->ptrs = (LPSTR*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
|
|
(dsaPtr->dwInitial + dsaPtr->dwGrow) *
|
|
sizeof(LPVOID));
|
|
memcpy (dsaPtr->ptrs, lpOldPtrs,
|
|
dsaPtr->dwMaxCount * sizeof(LPVOID));
|
|
dsaPtr->dwMaxCount += dsaPtr->dwGrow;
|
|
HeapFree (GetProcessHeap (), 0, lpOldPtrs);
|
|
|
|
/* add new string */
|
|
dwIndex = dsaPtr->dwEntryCount;
|
|
len = lstrlen32A ((LPSTR)dwParam3);
|
|
dsaPtr->ptrs[dwIndex] =
|
|
(LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len+1);
|
|
lstrcpy32A (dsaPtr->ptrs[dwIndex], (LPSTR)dwParam3);
|
|
}
|
|
}
|
|
else {
|
|
FIXME (commctrl, "inserting! stub!\n");
|
|
|
|
dwIndex = dwParam2;
|
|
}
|
|
}
|
|
|
|
dsaPtr->dwEntryCount++;
|
|
|
|
TRACE (commctrl, "ret=0x%08lx\n", dwIndex);
|
|
|
|
return (dwIndex);
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI
|
|
DSA_DeleteItem (DWORD dwParam1, DWORD dwParam2)
|
|
{
|
|
LPDSA_DATA dsaPtr = (LPDSA_DATA)dwParam1;
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx):semi-stub!\n",
|
|
dwParam1, dwParam2);
|
|
|
|
if (dsaPtr->ptrs) {
|
|
if (dsaPtr->dwEntryCount == 1) {
|
|
if (dsaPtr->ptrs[dwParam2])
|
|
HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs[dwParam2]);
|
|
dsaPtr->dwEntryCount--;
|
|
}
|
|
else {
|
|
LPSTR *oldPtrs = dsaPtr->ptrs;
|
|
TRACE (commctrl, "complex delete!\n");
|
|
|
|
if (dsaPtr->ptrs[dwParam2])
|
|
HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs[dwParam2]);
|
|
|
|
dsaPtr->dwEntryCount--;
|
|
dsaPtr->ptrs =
|
|
(LPSTR*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
|
|
dsaPtr->dwEntryCount * sizeof(LPVOID));
|
|
if (dwParam2 > 0) {
|
|
memcpy (&dsaPtr->ptrs[0], &oldPtrs[0],
|
|
dwParam2 * sizeof(LPSTR));
|
|
}
|
|
|
|
if (dwParam2 < dsaPtr->dwEntryCount) {
|
|
memcpy (&dsaPtr->ptrs[dwParam2], &oldPtrs[dwParam2+1],
|
|
(dsaPtr->dwEntryCount - dwParam2) * sizeof(LPSTR));
|
|
}
|
|
HeapFree (GetProcessHeap (), 0, oldPtrs);
|
|
}
|
|
|
|
if (dsaPtr->dwEntryCount == 0) {
|
|
HeapFree (GetProcessHeap (), 0, dsaPtr->ptrs);
|
|
dsaPtr->ptrs = NULL;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI
|
|
DPA_Create (DWORD dwParam1)
|
|
{
|
|
LPDPA_DATA dpaPtr;
|
|
|
|
TRACE (commctrl, "(0x%08lx)\n", dwParam1);
|
|
|
|
dpaPtr = (LPDPA_DATA)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY, sizeof(DPA_DATA));
|
|
dpaPtr->dwGrow = dwParam1;
|
|
|
|
TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dpaPtr);
|
|
|
|
return (DWORD)dpaPtr;
|
|
}
|
|
|
|
|
|
|
|
DWORD WINAPI
|
|
DPA_GetPtr (DWORD dwParam1, DWORD dwParam2)
|
|
{
|
|
LPDPA_DATA dpaPtr = (LPDPA_DATA)dwParam1;
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx)\n", dwParam1, dwParam2);
|
|
|
|
if (dpaPtr == NULL)
|
|
return 0;
|
|
if (dpaPtr->ptrs == NULL)
|
|
return 0;
|
|
if ((dwParam2 < 0) || (dwParam2 >= dpaPtr->dwEntryCount))
|
|
return 0;
|
|
|
|
TRACE (commctrl, "ret=0x%08lx\n", (DWORD)dpaPtr->ptrs[dwParam2]);
|
|
|
|
return (DWORD)dpaPtr->ptrs[dwParam2];
|
|
}
|
|
|
|
|
|
|
|
DWORD WINAPI
|
|
DPA_InsertPtr (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
|
{
|
|
LPDPA_DATA dpaPtr = (LPDPA_DATA)dwParam1;
|
|
DWORD dwIndex;
|
|
|
|
TRACE (commctrl, "(0x%08lx 0x%08lx 0x%lx)\n",
|
|
dwParam1, dwParam2, dwParam3);
|
|
|
|
if (dpaPtr->ptrs == NULL) {
|
|
dpaPtr->ptrs = (LPDWORD)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
|
|
dpaPtr->dwGrow * sizeof(LPVOID));
|
|
dpaPtr->dwMaxCount = dpaPtr->dwGrow;
|
|
dwIndex = 0;
|
|
dpaPtr->ptrs[dwIndex] = dwParam3;
|
|
}
|
|
else {
|
|
FIXME (commctrl, "adding to existing array! stub!\n");
|
|
|
|
|
|
dwIndex = dwParam2;
|
|
}
|
|
|
|
dpaPtr->dwEntryCount++;
|
|
|
|
return (dwIndex);
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* DPA_CreateEx [COMCTL32.340]
|
|
*
|
|
*/
|
|
|
|
DWORD WINAPI
|
|
DPA_CreateEx (DWORD dwParam1, DWORD dwParam2)
|
|
{
|
|
FIXME (commctrl, "(0x%08lx 0x%08lx)\n",
|
|
dwParam1, dwParam2);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* SendNotify [COMCTL32.341]
|
|
*
|
|
*/
|
|
|
|
DWORD WINAPI
|
|
COMCTL32_SendNotify (DWORD dw1, DWORD dw2, DWORD dw3, DWORD dw4)
|
|
{
|
|
FIXME (commctrl, "(0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n",
|
|
dw1, dw2, dw3, dw4);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
* StrChrA [COMCTL32.350]
|
|
*
|
|
*/
|
|
|
|
LPSTR WINAPI
|
|
COMCTL32_StrChrA (LPSTR lpString, CHAR cChar)
|
|
{
|
|
return strchr (lpString, cChar);
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* StrStrIA [COMCTL32.350]
|
|
*
|
|
* BUGS
|
|
* This implementation is case sensitive, but it mustn't.
|
|
*/
|
|
|
|
LPSTR WINAPI
|
|
COMCTL32_StrStrIA (LPSTR lpStr1, LPSTR lpStr2)
|
|
{
|
|
return strstr (lpStr1, lpStr2);
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
* StrToIntA [COMCTL32.357]
|
|
*/
|
|
|
|
INT32 WINAPI
|
|
COMCTL32_StrToIntA (LPSTR lpString)
|
|
{
|
|
return atoi(lpString);
|
|
}
|
|
|