Partial implementation for the following DDE APIs:

DdeCmpStringHandles, DdeCreateStringHandle, DdeFreeStringHandle,
DdeQueryString, DdeUninitialize.
oldstable
Jean-Claude Cote 1998-12-25 08:46:42 +00:00 committed by Alexandre Julliard
parent 9c7c8a4a36
commit c65f4a4757
3 changed files with 352 additions and 21 deletions

View File

@ -10,6 +10,11 @@
#include "wintypes.h"
/* Codepage Constants
*/
#define CP_WINANSI 1004
#define CP_WINUNICODE 1200
#define MSGF_DDEMGR 0x8001
typedef DWORD HCONVLIST;
@ -61,7 +66,7 @@ HCONV WINAPI DdeQueryNextServer32(HCONVLIST, HCONV);
#define DdeQueryNextServer WINELIB_NAME(DdeQueryNextServer)
DWORD WINAPI DdeQueryString32A(DWORD, HSZ, LPSTR, DWORD, INT32);
DWORD WINAPI DdeQueryString32W(DWORD, HSZ, LPWSTR, DWORD, INT32);
#define DdeQueryString WINELIB_NAME(DdeQueryString)
#define DdeQueryString WINELIB_NAME_AW(DdeQueryString)
BOOL16 WINAPI DdeDisconnectList16(HCONVLIST);
BOOL32 WINAPI DdeDisconnectList32(HCONVLIST);
#define DdeDisConnectList WINELIB_NAME(DdeDisconnectList)
@ -110,9 +115,9 @@ BOOL16 WINAPI DdeEnableCallback16(DWORD,HCONV,UINT16);
BOOL32 WINAPI DdeEnableCallback32(DWORD,HCONV,UINT32);
#define DdeEnableCallback WINELIB_NAME(DdeEnableCallback)
int WINAPI DdeCmpStringHandles16(HSZ,HSZ);
int WINAPI DdeCmpStringHandles32(HSZ,HSZ);
#define DdeCmpStringHandles WINELIB_NAME(DdeCmpStringHandles)
int WINAPI DdeCmpStringHandles32A(HSZ,HSZ);
int WINAPI DdeCmpStringHandles32W(HSZ,HSZ);
#define DdeCmpStringHandles WINELIB_NAME_AW(DdeCmpStringHandles)
HDDEDATA WINAPI DdeNameService16(DWORD,HSZ,HSZ,UINT16);
HDDEDATA WINAPI DdeNameService32(DWORD,HSZ,HSZ,UINT32);

View File

@ -7,15 +7,142 @@
/* Only empty stubs for now */
#include <stdlib.h>
#include <strings.h>
#include "ddeml.h"
#include "debug.h"
#include "windows.h"
#include "heap.h"
/* FIXME: What are these values? */
#define DMLERR_NO_ERROR 0
/* Has defined in atom.c file.
*/
#define MAX_ATOM_LEN 255
/* Maximum buffer size ( including the '\0' ).
*/
#define MAX_BUFFER_LEN (MAX_ATOM_LEN + 1)
static LONG DDE_current_handle;
/* This is a simple list to keep track of the strings created
* by DdeCreateStringHandle. The list is used to free
* the strings whenever DdeUninitialize is called.
* This mechanism is not complete and does not handle multiple instances.
* Most of the DDE API use a DWORD parameter indicating witch instance
* of a given program is calling them. The API are supposed to
* associate the data to the instance that created it.
*/
typedef struct tagHSZNode HSZNode;
struct tagHSZNode
{
HSZNode* next;
HSZ hsz;
};
/* Start off the list pointer with a NULL.
*/
static HSZNode* pHSZNodes = NULL;
/******************************************************************************
* RemoveHSZNodes (INTERNAL)
*
* Remove a node from the list of HSZ nodes.
*/
static void RemoveHSZNode( DWORD idInst, HSZ hsz )
{
HSZNode* pPrev = NULL;
HSZNode* pCurrent = NULL;
/* Set the current node at the start of the list.
*/
pCurrent = pHSZNodes;
/* While we have more nodes.
*/
while( pCurrent != NULL )
{
/* If we found the node we were looking for.
*/
if( pCurrent->hsz == hsz )
{
/* Remove the node.
*/
/* If the first node in the list is to to be removed.
* Set the global list pointer to the next node.
*/
if( pCurrent == pHSZNodes )
{
pHSZNodes = pCurrent->next;
}
/* Just fix the pointers has to skip the current
* node so we can delete it.
*/
else
{
pPrev->next = pCurrent->next;
}
/* Destroy this node.
*/
free( pCurrent );
break;
}
/* Save the previous node pointer.
*/
pPrev = pCurrent;
/* Move on to the next node.
*/
pCurrent = pCurrent->next;
}
}
/******************************************************************************
* FreeAndRemoveHSZNodes (INTERNAL)
*
* Frees up all the strings still allocated in the list and
* remove all the nodes from the list of HSZ nodes.
*/
static void FreeAndRemoveHSZNodes( DWORD idInst )
{
/* Free any strings created in this instance.
*/
while( pHSZNodes != NULL )
{
DdeFreeStringHandle32( idInst, pHSZNodes->hsz );
}
}
/******************************************************************************
* InsertHSZNode (INTERNAL)
*
* Insert a node to the head of the list.
*/
static void InsertHSZNode( DWORD idInst, HSZ hsz )
{
if( hsz != 0 )
{
HSZNode* pNew = NULL;
/* Create a new node for this HSZ.
*/
pNew = (HSZNode*) malloc( sizeof( HSZNode ) );
if( pNew != NULL )
{
/* Set the handle value.
*/
pNew->hsz = hsz;
/* Attach the node to the head of the list.
*/
pNew->next = pHSZNodes;
/* The new node is now at the head of the list
* so set the global list pointer to it.
*/
pHSZNodes = pNew;
}
}
}
/******************************************************************************
* DdeInitialize16 (DDEML.2)
@ -88,7 +215,14 @@ BOOL16 WINAPI DdeUninitialize16( DWORD idInst )
*/
BOOL32 WINAPI DdeUninitialize32( DWORD idInst )
{
FIXME(ddeml, "(%ld): stub\n", idInst);
/* Free the nodes that were not freed by this instance
* and remove the nodes from the list of HSZ nodes.
*/
FreeAndRemoveHSZNodes( idInst );
return TRUE;
}
@ -150,6 +284,9 @@ HCONV WINAPI DdeQueryNextServer32( HCONVLIST hConvList, HCONV hConvPrev )
*/
DWORD WINAPI DdeQueryString32A(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, INT32 iCodePage)
{
DWORD ret = 0;
CHAR pString[MAX_BUFFER_LEN];
FIXME(ddeml,
"(%ld, 0x%lx, %p, %ld, %d): stub\n",
idInst,
@ -158,7 +295,21 @@ DWORD WINAPI DdeQueryString32A(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, I
cchMax,
iCodePage);
return 0;
if( iCodePage == CP_WINANSI )
{
/* If psz is null, we have to return only the length
* of the string.
*/
if( psz == NULL )
{
psz = pString;
cchMax = MAX_BUFFER_LEN;
}
ret = GlobalGetAtomName32A( hsz, (LPSTR)psz, cchMax );
}
return ret;
}
/*****************************************************************
@ -166,6 +317,10 @@ DWORD WINAPI DdeQueryString32A(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, I
*/
DWORD WINAPI DdeQueryString32W(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, INT32 iCodePage)
{
DWORD ret = 0;
WCHAR pString[MAX_BUFFER_LEN];
int factor = 1;
FIXME(ddeml,
"(%ld, 0x%lx, %p, %ld, %d): stub\n",
idInst,
@ -174,7 +329,23 @@ DWORD WINAPI DdeQueryString32W(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax,
cchMax,
iCodePage);
return 0;
if( iCodePage == CP_WINUNICODE )
{
/* If psz is null, we have to return only the length
* of the string.
*/
if( psz == NULL )
{
psz = pString;
cchMax = MAX_BUFFER_LEN;
/* Note: According to documentation if the psz parameter
* was NULL this API must return the length of the string in bytes.
*/
factor = (int) sizeof(WCHAR)/sizeof(BYTE);
}
ret = GlobalGetAtomName32W( hsz, (LPWSTR)psz, cchMax ) * factor;
}
return ret;
}
@ -315,11 +486,19 @@ HSZ WINAPI DdeCreateStringHandle16( DWORD idInst, LPCSTR str, INT16 codepage )
* Failure: 0
*/
HSZ WINAPI DdeCreateStringHandle32A( DWORD idInst, LPCSTR psz, INT32 codepage )
{ TRACE(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_a(psz),codepage);
{
HSZ hsz = 0;
TRACE(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_a(psz),codepage);
if (codepage==1004) /*fixme: should be CP_WINANSI*/
return GlobalAddAtom32A (psz);
else
if (codepage==CP_WINANSI)
{
hsz = GlobalAddAtom32A (psz);
/* Save the handle so we know to clean it when
* uninitialize is called.
*/
InsertHSZNode( idInst, hsz );
return hsz;
}
return 0;
}
@ -336,9 +515,20 @@ HSZ WINAPI DdeCreateStringHandle32W(
LPCWSTR psz, /* [in] Pointer to string */
INT32 codepage) /* [in] Code page identifier */
{
HSZ hsz = 0;
FIXME(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_w(psz),codepage);
DDE_current_handle++;
return DDE_current_handle;
if (codepage==CP_WINUNICODE)
{
hsz = GlobalAddAtom32W (psz);
/* Save the handle so we know to clean it when
* uninitialize is called.
*/
InsertHSZNode( idInst, hsz );
return hsz;
}
return 0;
}
@ -357,8 +547,14 @@ BOOL16 WINAPI DdeFreeStringHandle16( DWORD idInst, HSZ hsz )
* fail: zero
*/
BOOL32 WINAPI DdeFreeStringHandle32( DWORD idInst, HSZ hsz )
{ TRACE( ddeml, "(%ld,%ld): stub\n",idInst, hsz );
return GlobalDeleteAtom (hsz) ? hsz : 0;
{
TRACE( ddeml, "(%ld,%ld): stub\n",idInst, hsz );
/* Remove the node associated with this HSZ.
*/
RemoveHSZNode( idInst, hsz );
/* Free the string associated with this HSZ.
*/
return GlobalDeleteAtom (hsz) ? 0 : hsz;
}
@ -381,6 +577,8 @@ BOOL32 WINAPI DdeFreeDataHandle32( HDDEDATA hData )
}
/*****************************************************************
* DdeKeepStringHandle16 (DDEML.24)
*/
@ -617,16 +815,144 @@ UINT32 WINAPI DdeGetLastError32( DWORD idInst )
*/
int WINAPI DdeCmpStringHandles16( HSZ hsz1, HSZ hsz2 )
{
return DdeCmpStringHandles32(hsz1, hsz2);
return DdeCmpStringHandles32A(hsz1, hsz2);
}
/*****************************************************************
* DdeCmpStringHandles32 (USER32.91)
* DdeCmpStringHandles32A (USER32.91)
*
* Compares the value of two string handles. This comparison is
* not case sensitive.
*
* Returns:
* -1 The value of hsz1 is zero or less than hsz2
* 0 The values of hsz 1 and 2 are the same or both zero.
* 1 The value of hsz2 is zero of less than hsz1
*/
int WINAPI DdeCmpStringHandles32( HSZ hsz1, HSZ hsz2 )
int WINAPI DdeCmpStringHandles32A( HSZ hsz1, HSZ hsz2 )
{
FIXME( ddeml, "(0x%lx, 0x%lx): stub\n", hsz1, hsz2 );
return 0;
CHAR psz1[MAX_BUFFER_LEN];
CHAR psz2[MAX_BUFFER_LEN];
int ret = 0;
int ret1, ret2;
TRACE( ddeml, "handle 1, handle 2\n" );
ret1 = GlobalGetAtomName32A( hsz1, psz1, MAX_BUFFER_LEN );
ret2 = GlobalGetAtomName32A( hsz2, psz2, MAX_BUFFER_LEN );
/* Make sure we found both strings.
*/
if( ret1 == 0 && ret2 == 0 )
{
/* If both are not found, return both "zero strings".
*/
ret = 0;
}
else if( ret1 == 0 )
{
/* If hsz1 is a not found, return hsz1 is "zero string".
*/
ret = -1;
}
else if( ret2 == 0 )
{
/* If hsz2 is a not found, return hsz2 is "zero string".
*/
ret = 1;
}
else
{
/* Compare the two strings we got ( case insensitive ).
*/
ret = strcasecmp( psz1, psz2 );
/* Since strcmp returns any number smaller than
* 0 when the first string is found to be less than
* the second one we must make sure we are returning
* the proper values.
*/
if( ret < 0 )
{
ret = -1;
}
else if( ret > 0 )
{
ret = 1;
}
}
return ret;
}
/*****************************************************************
* DdeCmpStringHandles32W (USER32.623)
*
* Compares the value of two string handles. This comparison is
* not case sensitive.
*
* Returns:
* -1 The value of hsz1 is zero or less than hsz2
* 0 The values of hsz 1 and 2 are the same or both zero.
* 1 The value of hsz2 is zero of less than hsz1
*/
int WINAPI DdeCmpStringHandles32W( HSZ hsz1, HSZ hsz2 )
{
WCHAR pwsz1[MAX_BUFFER_LEN];
WCHAR pwsz2[MAX_BUFFER_LEN];
int ret = 0;
int ret1, ret2;
TRACE( ddeml, "handle 1, handle 2\n" );
ret1 = GlobalGetAtomName32W( hsz1, pwsz1, MAX_BUFFER_LEN );
ret2 = GlobalGetAtomName32W( hsz2, pwsz2, MAX_BUFFER_LEN );
/* Make sure we found both strings.
*/
if( ret1 == 0 && ret2 == 0 )
{
/* If both are not found, return both "zero strings".
*/
ret = 0;
}
else if( ret1 == 0 )
{
/* If hsz1 is a not found, return hsz1 is "zero string".
*/
ret = -1;
}
else if( ret2 == 0 )
{
/* If hsz2 is a not found, return hsz2 is "zero string".
*/
ret = 1;
}
else
{
LPSTR psz1, psz2;
psz1 = HEAP_strdupWtoA( GetProcessHeap(), 0, pwsz1 );
psz2 = HEAP_strdupWtoA( GetProcessHeap(), 0, pwsz2 );
if( psz1 != NULL && psz2 != NULL )
{
/* Compare the two strings we got ( case insensitive ).
*/
ret = strcasecmp( psz1, psz2 );
/* Since strcmp returns any number smaller than
* 0 when the first string is found to be less than
* the second one we must make sure we are returning
* the proper values.
*/
if( ret < 0 )
{
ret = -1;
}
else if( ret > 0 )
{
ret = 1;
}
}
HeapFree( GetProcessHeap(), 0, psz1 );
HeapFree( GetProcessHeap(), 0, psz2 );
}
return ret;
}

View File

@ -92,7 +92,7 @@ init MAIN_UserInit
88 stdcall DdeAccessData(long ptr) DdeAccessData32
89 stub DdeAddData
90 stdcall DdeClientTransaction(ptr long long long long long long ptr) DdeClientTransaction32
91 stdcall DdeCmpStringHandles(long long) DdeCmpStringHandles32
91 stdcall DdeCmpStringHandlesA(long long) DdeCmpStringHandles32A
92 stdcall DdeConnect(long long long ptr) DdeConnect32
93 stdcall DdeConnectList(long long long long ptr) DdeConnectList32
94 stdcall DdeCreateDataHandle(long ptr long long long long long) DdeCreateDataHandle32
@ -615,7 +615,6 @@ init MAIN_UserInit
610 stdcall MonitorFromRect(ptr long) MonitorFromRect
611 stdcall MonitorFromPoint(long long long) MonitorFromPoint
612 stdcall EnumDisplayMonitors(long ptr ptr long) EnumDisplayMonitors
613 stdcall PrivateExtractIconExA (long long long long long) PrivateExtractIconExA
614 stdcall PrivateExtractIconExW (long long long long long) PrivateExtractIconExW
615 stdcall PrivateExtractIconsW (long long long long long long long long) PrivateExtractIconsW
@ -626,3 +625,4 @@ init MAIN_UserInit
620 stdcall GetTaskmanWindow () GetTaskmanWindow
621 stdcall SetTaskmanWindow (long) SetTaskmanWindow
622 stdcall GetProgmanWindow () GetProgmanWindow
623 stdcall DdeCmpStringHandlesW(long long) DdeCmpStringHandles32W