📄 dde.c
字号:
{
ptr = pString;
cchMax = MAX_BUFFER_LEN;
}
switch (codepage)
{
case CP_WINANSI:
ret = GetAtomNameA(HSZ2ATOM(hsz), ptr, cchMax);
break;
case CP_WINUNICODE:
ret = GetAtomNameW(HSZ2ATOM(hsz), ptr, cchMax);
break;
default:
ERR("Unknown code page %d\n", codepage);
ret = 0;
}
return ret;
}
/*****************************************************************
* DdeQueryStringA [USER32.@]
*/
DWORD WINAPI DdeQueryStringA(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, INT iCodePage)
{
DWORD ret = 0;
WDML_INSTANCE* pInstance;
TRACE("(%ld, %p, %p, %ld, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
EnterCriticalSection(&WDML_CritSect);
/* First check instance
*/
pInstance = WDML_GetInstance(idInst);
if (pInstance != NULL)
{
if (iCodePage == 0) iCodePage = CP_WINANSI;
ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
}
LeaveCriticalSection(&WDML_CritSect);
TRACE("returning %ld (%s)\n", ret, debugstr_a(psz));
return ret;
}
/*****************************************************************
* DdeQueryStringW [USER32.@]
*/
DWORD WINAPI DdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, INT iCodePage)
{
DWORD ret = 0;
WDML_INSTANCE* pInstance;
TRACE("(%ld, %p, %p, %ld, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
EnterCriticalSection(&WDML_CritSect);
/* First check instance
*/
pInstance = WDML_GetInstance(idInst);
if (pInstance != NULL)
{
if (iCodePage == 0) iCodePage = CP_WINUNICODE;
ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
}
LeaveCriticalSection(&WDML_CritSect);
TRACE("returning %ld (%s)\n", ret, debugstr_w(psz));
return ret;
}
/******************************************************************
* DML_CreateString
*
*
*/
static HSZ WDML_CreateString(WDML_INSTANCE* pInstance, LPCVOID ptr, int codepage)
{
HSZ hsz;
switch (codepage)
{
case CP_WINANSI:
hsz = ATOM2HSZ(AddAtomA(ptr));
TRACE("added atom %s with HSZ %p,\n", debugstr_a(ptr), hsz);
break;
case CP_WINUNICODE:
hsz = ATOM2HSZ(AddAtomW(ptr));
TRACE("added atom %s with HSZ %p,\n", debugstr_w(ptr), hsz);
break;
default:
ERR("Unknown code page %d\n", codepage);
return 0;
}
WDML_InsertHSZNode(pInstance, hsz);
return hsz;
}
/*****************************************************************
* DdeCreateStringHandleA [USER32.@]
*
* See DdeCreateStringHandleW.
*/
HSZ WINAPI DdeCreateStringHandleA(DWORD idInst, LPCSTR psz, INT codepage)
{
HSZ hsz = 0;
WDML_INSTANCE* pInstance;
TRACE("(%ld,%s,%d)\n", idInst, debugstr_a(psz), codepage);
EnterCriticalSection(&WDML_CritSect);
pInstance = WDML_GetInstance(idInst);
if (pInstance)
{
if (codepage == 0) codepage = CP_WINANSI;
hsz = WDML_CreateString(pInstance, psz, codepage);
}
LeaveCriticalSection(&WDML_CritSect);
return hsz;
}
/******************************************************************************
* DdeCreateStringHandleW [USER32.@] Creates handle to identify string
*
* PARAMS
* idInst [I] Instance identifier
* psz [I] Pointer to string
* codepage [I] Code page identifier
* RETURNS
* Success: String handle
* Failure: 0
*/
HSZ WINAPI DdeCreateStringHandleW(DWORD idInst, LPCWSTR psz, INT codepage)
{
WDML_INSTANCE* pInstance;
HSZ hsz = 0;
TRACE("(%ld,%s,%d)\n", idInst, debugstr_w(psz), codepage);
EnterCriticalSection(&WDML_CritSect);
pInstance = WDML_GetInstance(idInst);
if (pInstance)
{
if (codepage == 0) codepage = CP_WINUNICODE;
hsz = WDML_CreateString(pInstance, psz, codepage);
}
LeaveCriticalSection(&WDML_CritSect);
return hsz;
}
/*****************************************************************
* DdeFreeStringHandle (USER32.@)
* RETURNS
* success: nonzero
* fail: zero
*/
BOOL WINAPI DdeFreeStringHandle(DWORD idInst, HSZ hsz)
{
WDML_INSTANCE* pInstance;
BOOL ret = FALSE;
TRACE("(%ld,%p):\n", idInst, hsz);
EnterCriticalSection(&WDML_CritSect);
/* First check instance
*/
pInstance = WDML_GetInstance(idInst);
if (pInstance)
ret = WDML_DecHSZ(pInstance, hsz);
LeaveCriticalSection(&WDML_CritSect);
return ret;
}
/*****************************************************************
* DdeKeepStringHandle (USER32.@)
*
* RETURNS
* success: nonzero
* fail: zero
*/
BOOL WINAPI DdeKeepStringHandle(DWORD idInst, HSZ hsz)
{
WDML_INSTANCE* pInstance;
BOOL ret = FALSE;
TRACE("(%ld,%p):\n", idInst, hsz);
EnterCriticalSection(&WDML_CritSect);
/* First check instance
*/
pInstance = WDML_GetInstance(idInst);
if (pInstance)
ret = WDML_IncHSZ(pInstance, hsz);
LeaveCriticalSection(&WDML_CritSect);
return ret;
}
/*****************************************************************
* DdeCmpStringHandles (USER32.@)
*
* Compares the value of two string handles. This comparison is
* not case sensitive.
*
* PARAMS
* hsz1 [I] Handle to the first string
* hsz2 [I] Handle to the second string
*
* 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 DdeCmpStringHandles(HSZ hsz1, HSZ hsz2)
{
WCHAR psz1[MAX_BUFFER_LEN];
WCHAR psz2[MAX_BUFFER_LEN];
int ret = 0;
int ret1, ret2;
ret1 = GetAtomNameW(HSZ2ATOM(hsz1), psz1, MAX_BUFFER_LEN);
ret2 = GetAtomNameW(HSZ2ATOM(hsz2), psz2, MAX_BUFFER_LEN);
TRACE("(%p<%s> %p<%s>);\n", hsz1, debugstr_w(psz1), hsz2, debugstr_w(psz2));
/* 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 = lstrcmpiW(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;
}
/* ================================================================
*
* Data handle management
*
* ================================================================ */
/*****************************************************************
* DdeCreateDataHandle (USER32.@)
*/
HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, DWORD cbOff,
HSZ hszItem, UINT wFmt, UINT afCmd)
{
/* For now, we ignore idInst, hszItem.
* The purpose of these arguments still need to be investigated.
*/
HGLOBAL hMem;
LPBYTE pByte;
DDE_DATAHANDLE_HEAD* pDdh;
WCHAR psz[MAX_BUFFER_LEN];
if (!GetAtomNameW(HSZ2ATOM(hszItem), psz, MAX_BUFFER_LEN))
{
psz[0] = HSZ2ATOM(hszItem);
psz[1] = 0;
}
TRACE("(%ld,%p,cb %ld, cbOff %ld,%p <%s>,fmt %04x,%x)\n",
idInst, pSrc, cb, cbOff, hszItem, debugstr_w(psz), wFmt, afCmd);
if (afCmd != 0 && afCmd != HDATA_APPOWNED)
return 0;
/* we use the first 4 bytes to store the size */
if (!(hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cb + cbOff + sizeof(DDE_DATAHANDLE_HEAD))))
{
ERR("GlobalAlloc failed\n");
return 0;
}
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem);
if (!pDdh)
{
GlobalFree(hMem);
return 0;
}
pDdh->cfFormat = wFmt;
pDdh->bAppOwned = (afCmd == HDATA_APPOWNED);
pByte = (LPBYTE)(pDdh + 1);
if (pSrc)
{
memcpy(pByte, pSrc + cbOff, cb);
}
GlobalUnlock(hMem);
TRACE("=> %p\n", hMem);
return (HDDEDATA)hMem;
}
/*****************************************************************
*
* DdeAddData (USER32.@)
*/
HDDEDATA WINAPI DdeAddData(HDDEDATA hData, LPBYTE pSrc, DWORD cb, DWORD cbOff)
{
DWORD old_sz, new_sz;
LPBYTE pDst;
TRACE("(%p,%p,cb %ld, cbOff %ld)\n", hData, pSrc, cb, cbOff);
pDst = DdeAccessData(hData, &old_sz);
if (!pDst) return 0;
new_sz = cb + cbOff;
if (new_sz > old_sz)
{
DdeUnaccessData(hData);
hData = GlobalReAlloc((HGLOBAL)hData, new_sz + sizeof(DDE_DATAHANDLE_HEAD),
GMEM_MOVEABLE | GMEM_DDESHARE);
pDst = DdeAccessData(hData, &old_sz);
}
if (!pDst) return 0;
memcpy(pDst + cbOff, pSrc, cb);
DdeUnaccessData(hData);
return hData;
}
/******************************************************************************
* DdeGetData [USER32.@] Copies data from DDE object to local buffer
*
*
* PARAMS
* hData [I] Handle to DDE object
* pDst [I] Pointer to destination buffer
* cbMax [I] Amount of data to copy
* cbOff [I] Offset to beginning of data
*
* RETURNS
* Size of memory object associated with handle
*/
DWORD WINAPI DdeGetData(HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff)
{
DWORD dwSize, dwRet;
LPBYTE pByte;
TRACE("(%p,%p,%ld,%ld)\n", hData, pDst, cbMax, cbOff);
pByte = DdeAccessData(hData, &dwSize);
if (pByte)
{
if (!pDst)
{
dwRet = dwSize;
}
else if (cbOff + cbMax < dwSize)
{
dwRet = cbMax;
}
else if (cbOff < dwSize)
{
dwRet = dwSize - cbOff;
}
else
{
dwRet = 0;
}
if (pDst && dwRet != 0)
{
memcpy(pDst, pByte + cbOff, dwRet);
}
DdeUnaccessData(hData);
}
else
{
dwRet = 0;
}
return dwRet;
}
/*****************************************************************
* DdeAccessData (USER32.@)
*/
LPBYTE WINAPI DdeAccessData(HDDEDATA hData, LPDWORD pcbDataSize)
{
HGLOBAL hMem = (HGLOBAL)hData;
DDE_DATAHANDLE_HEAD* pDdh;
TRACE("(%p,%p)\n", hData, pcbDataSize);
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock(hMem);
if (pDdh == NULL)
{
ERR("Failed on GlobalLock(%p)\n", hMem);
return 0;
}
if (pcbDataSize != NULL)
{
*pcbDataSize = GlobalSize(hMem) - sizeof(DDE_DATAHANDLE_HEAD);
}
TRACE("=> %p (%lu) fmt %04x\n", pDdh + 1, GlobalSize(hMem) - sizeof(DDE_DATAHANDLE_HEAD), pDdh->cfFormat);
return (LPBYTE)(pDdh + 1);
}
/*****************************************************************
* DdeUnaccessData (USER32.@)
*/
BOOL WINAPI DdeUnaccessData(HDDEDATA hData)
{
HGLOBAL hMem = (HGLOBAL)hData;
TRACE("(%p)\n", hData);
GlobalUnlock(hMem);
return TRUE;
}
/*****************************************************************
* DdeFreeDataHandle (USER32.@)
*/
BOOL WINAPI DdeFreeDataHandle(HDDEDATA hData)
{
TRACE("(%p)\n", hData);
return GlobalFree((HGLOBAL)hData) == 0;
}
/******************************************************************
* WDML_IsAppOwned
*
*
*/
BOOL WDML_IsAppOwned(HDDEDATA hData)
{
DDE_DATAHANDLE_HEAD* pDdh;
BOOL ret = FALSE;
pDdh = (DDE_DATAHANDLE_HEAD*)GlobalLock((HGLOBAL)hData);
if (pDdh != NULL)
{
ret = pDdh->bAppOwned;
GlobalUnlock((HGLOBAL)hData);
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -