Author: jimtabor
Date: Tue May 20 19:39:34 2014
New Revision: 63386
URL:
http://svn.reactos.org/svn/reactos?rev=63386&view=rev
Log:
[User32]
- Update and sync DDE code with wine. Make name space close to what it should be.
Modified:
trunk/reactos/win32ss/user/user32/misc/dde.c
trunk/reactos/win32ss/user/user32/misc/ddeclient.c
trunk/reactos/win32ss/user/user32/misc/ddeserver.c
Modified: trunk/reactos/win32ss/user/user32/misc/dde.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/d…
==============================================================================
--- trunk/reactos/win32ss/user/user32/misc/dde.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/misc/dde.c [iso-8859-1] Tue May 20 19:39:34 2014
@@ -36,7 +36,7 @@
static WDML_INSTANCE* WDML_InstanceList = NULL;
static LONG WDML_MaxInstanceID = 0; /* OK for present, have to worry about wrap-around
later */
-const WCHAR WDML_szEventClass[] =
{'D','d','e','E','v','e','n','t','C','l','a','s','s',0};
+const WCHAR WDML_szEventClass[] =
{'D','D','E','M','L','E','v','e','n','t',0};
/* protection for instance list */
CRITICAL_SECTION WDML_CritSect;
@@ -91,7 +91,7 @@
return uiHi;
default:
- return MAKELPARAM(uiLo, uiHi);
+ return MAKELONG(uiLo, uiHi);
}
}
@@ -229,11 +229,508 @@
* DdeSetQualityOfService (USER32.@)
*/
-BOOL WINAPI DdeSetQualityOfService(HWND hwndClient, CONST SECURITY_QUALITY_OF_SERVICE
*pqosNew,
+BOOL WINAPI DdeSetQualityOfService(HWND hwndClient, const SECURITY_QUALITY_OF_SERVICE
*pqosNew,
PSECURITY_QUALITY_OF_SERVICE pqosPrev)
{
FIXME("(%p %p %p): stub\n", hwndClient, pqosNew, pqosPrev);
return TRUE;
+}
+
+/* ================================================================
+ *
+ * WDML Error management
+ *
+ * ================================================================ */
+
+/******************************************************************************
+ * DdeGetLastError [USER32.@] Gets most recent error code
+ *
+ * PARAMS
+ * idInst [I] Instance identifier
+ *
+ * RETURNS
+ * Last error code
+ */
+UINT WINAPI DdeGetLastError(DWORD idInst)
+{
+ DWORD error_code;
+ WDML_INSTANCE* pInstance;
+
+ /* First check instance
+ */
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance == NULL)
+ {
+ error_code = DMLERR_INVALIDPARAMETER;
+ }
+ else
+ {
+ error_code = pInstance->lastError;
+ pInstance->lastError = 0;
+ }
+
+ return error_code;
+}
+
+/******************************************************************
+ * WDML_SetAllLastError
+ *
+ *
+ */
+static void WDML_SetAllLastError(DWORD lastError)
+{
+ DWORD threadID;
+ WDML_INSTANCE* pInstance;
+ threadID = GetCurrentThreadId();
+ pInstance = WDML_InstanceList;
+ while (pInstance)
+ {
+ if (pInstance->threadID == threadID)
+ pInstance->lastError = lastError;
+ pInstance = pInstance->next;
+ }
+}
+
+/* ================================================================
+ *
+ * String management
+ *
+ * ================================================================ */
+
+
+/******************************************************************
+ * WDML_FindNode
+ *
+ *
+ */
+static HSZNode* WDML_FindNode(WDML_INSTANCE* pInstance, HSZ hsz)
+{
+ HSZNode* pNode;
+
+ if (pInstance == NULL) return NULL;
+
+ for (pNode = pInstance->nodeList; pNode != NULL; pNode = pNode->next)
+ {
+ if (pNode->hsz == hsz) break;
+ }
+ if (!pNode) WARN("HSZ %p not found\n", hsz);
+ return pNode;
+}
+
+/******************************************************************
+ * WDML_MakeAtomFromHsz
+ *
+ * Creates a global atom from an existing HSZ
+ * Generally used before sending an HSZ as an atom to a remote app
+ */
+ATOM WDML_MakeAtomFromHsz(HSZ hsz)
+{
+ WCHAR nameBuffer[MAX_BUFFER_LEN];
+
+ if (GetAtomNameW(HSZ2ATOM(hsz), nameBuffer, MAX_BUFFER_LEN))
+ return GlobalAddAtomW(nameBuffer);
+ WARN("HSZ %p not found\n", hsz);
+ return 0;
+}
+
+/******************************************************************
+ * WDML_MakeHszFromAtom
+ *
+ * Creates a HSZ from an existing global atom
+ * Generally used while receiving a global atom and transforming it
+ * into an HSZ
+ */
+HSZ WDML_MakeHszFromAtom(const WDML_INSTANCE* pInstance, ATOM atom)
+{
+ WCHAR nameBuffer[MAX_BUFFER_LEN];
+
+ if (!atom) return NULL;
+
+ if (GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN))
+ {
+ TRACE("%x => %s\n", atom, debugstr_w(nameBuffer));
+ return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
+ }
+ WARN("ATOM 0x%x not found\n", atom);
+ return 0;
+}
+
+/******************************************************************
+ * WDML_IncHSZ
+ *
+ *
+ */
+BOOL WDML_IncHSZ(WDML_INSTANCE* pInstance, HSZ hsz)
+{
+ HSZNode* pNode;
+
+ pNode = WDML_FindNode(pInstance, hsz);
+ if (!pNode) return FALSE;
+
+ pNode->refCount++;
+ return TRUE;
+}
+
+/******************************************************************************
+ * WDML_DecHSZ (INTERNAL)
+ *
+ * Decrease the ref count of an HSZ. If it reaches 0, the node is removed from the list
+ * of HSZ nodes
+ * Returns -1 is the HSZ isn't found, otherwise it's the current (after --) of
the ref count
+ */
+BOOL WDML_DecHSZ(WDML_INSTANCE* pInstance, HSZ hsz)
+{
+ HSZNode* pPrev = NULL;
+ HSZNode* pCurrent;
+
+ for (pCurrent = pInstance->nodeList; pCurrent != NULL; pCurrent = (pPrev =
pCurrent)->next)
+ {
+ /* If we found the node we were looking for and its ref count is one,
+ * we can remove it
+ */
+ if (pCurrent->hsz == hsz)
+ {
+ if (--pCurrent->refCount == 0)
+ {
+ if (pCurrent == pInstance->nodeList)
+ {
+ pInstance->nodeList = pCurrent->next;
+ }
+ else
+ {
+ pPrev->next = pCurrent->next;
+ }
+ HeapFree(GetProcessHeap(), 0, pCurrent);
+ DeleteAtom(HSZ2ATOM(hsz));
+ }
+ return TRUE;
+ }
+ }
+ WARN("HSZ %p not found\n", hsz);
+
+ return FALSE;
+}
+
+/******************************************************************************
+ * WDML_FreeAllHSZ (INTERNAL)
+ *
+ * Frees up all the strings still allocated in the list and
+ * remove all the nodes from the list of HSZ nodes.
+ */
+void WDML_FreeAllHSZ(WDML_INSTANCE* pInstance)
+{
+ /* Free any strings created in this instance.
+ */
+ while (pInstance->nodeList != NULL)
+ {
+ DdeFreeStringHandle(pInstance->instanceID, pInstance->nodeList->hsz);
+ }
+}
+
+/******************************************************************************
+ * InsertHSZNode (INTERNAL)
+ *
+ * Insert a node to the head of the list.
+ */
+static void WDML_InsertHSZNode(WDML_INSTANCE* pInstance, HSZ hsz)
+{
+ if (hsz != 0)
+ {
+ HSZNode* pNew = NULL;
+ /* Create a new node for this HSZ.
+ */
+ pNew = HeapAlloc(GetProcessHeap(), 0, sizeof(HSZNode));
+ if (pNew != NULL)
+ {
+ pNew->hsz = hsz;
+ pNew->next = pInstance->nodeList;
+ pNew->refCount = 1;
+ pInstance->nodeList = pNew;
+ }
+ else
+ {
+ ERR("Primary HSZ Node allocation failed - out of memory\n");
+ }
+ }
+}
+
+/******************************************************************
+ * WDML_QueryString
+ *
+ *
+ */
+static int WDML_QueryString(WDML_INSTANCE* pInstance, HSZ hsz, LPVOID ptr, DWORD cchMax,
+ int codepage)
+{
+ WCHAR pString[MAX_BUFFER_LEN];
+ int ret;
+ /* If psz is null, we have to return only the length
+ * of the string.
+ */
+ if (ptr == NULL)
+ {
+ ptr = pString;
+ cchMax = MAX_BUFFER_LEN;
+ }
+
+ /* if there is no input windows returns a NULL string */
+ if (hsz == NULL)
+ {
+ CHAR *t_ptr = ptr;
+ *t_ptr = '\0';
+ return 1;
+ }
+
+ 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("(%d, %p, %p, %d, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
+
+ /* First check instance
+ */
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance != NULL)
+ {
+ if (iCodePage == 0) iCodePage = CP_WINANSI;
+ ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
+ }
+
+ TRACE("returning %d (%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("(%d, %p, %p, %d, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
+
+ /* First check instance
+ */
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance != NULL)
+ {
+ if (iCodePage == 0) iCodePage = CP_WINUNICODE;
+ ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
+ }
+
+ TRACE("returning %d (%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("(%d,%s,%d)\n", idInst, debugstr_a(psz), codepage);
+
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance == NULL)
+ WDML_SetAllLastError(DMLERR_INVALIDPARAMETER);
+ else
+ {
+ if (codepage == 0) codepage = CP_WINANSI;
+ hsz = WDML_CreateString(pInstance, psz, codepage);
+ }
+
+ 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;
+
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance == NULL)
+ WDML_SetAllLastError(DMLERR_INVALIDPARAMETER);
+ else
+ {
+ if (codepage == 0) codepage = CP_WINUNICODE;
+ hsz = WDML_CreateString(pInstance, psz, codepage);
+ }
+
+ return hsz;
+}
+
+/*****************************************************************
+ * DdeFreeStringHandle (USER32.@)
+ * RETURNS
+ * success: nonzero
+ * fail: zero
+ */
+BOOL WINAPI DdeFreeStringHandle(DWORD idInst, HSZ hsz)
+{
+ WDML_INSTANCE* pInstance;
+ BOOL ret = FALSE;
+
+ TRACE("(%d,%p):\n", idInst, hsz);
+
+ /* First check instance
+ */
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance)
+ ret = WDML_DecHSZ(pInstance, hsz);
+
+ return ret;
+}
+
+/*****************************************************************
+ * DdeKeepStringHandle (USER32.@)
+ *
+ * RETURNS
+ * success: nonzero
+ * fail: zero
+ */
+BOOL WINAPI DdeKeepStringHandle(DWORD idInst, HSZ hsz)
+{
+ WDML_INSTANCE* pInstance;
+ BOOL ret = FALSE;
+
+ TRACE("(%d,%p):\n", idInst, hsz);
+
+ /* First check instance
+ */
+ pInstance = WDML_GetInstance(idInst);
+ if (pInstance)
+ ret = WDML_IncHSZ(pInstance, hsz);
+
+ 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;
}
/* ================================================================
@@ -329,7 +826,7 @@
*
*/
UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
- DWORD afCmd, DWORD ulRes, BOOL bUnicode)
+ DWORD afCmd, DWORD ulRes, BOOL bUnicode)
{
WDML_INSTANCE* pInstance;
WDML_INSTANCE* reference_inst;
@@ -343,7 +840,7 @@
{
ERR("Reserved value not zero? What does this mean?\n");
/* trap this and no more until we know more */
- return DMLERR_NO_ERROR;
+ return DMLERR_INVALIDPARAMETER;
}
/* grab enough heap for one control struct - not really necessary for re-initialise
@@ -386,12 +883,12 @@
(pInstance->CBFflags & CBF_FAIL_ALLSVRXACTIONS) == CBF_FAIL_ALLSVRXACTIONS;
}
- TRACE("instance created - checking validity\n");
+ ERR("instance created - checking validity\n");
if (*pidInst == 0)
{
/* Initialisation of new Instance Identifier */
- TRACE("new instance, callback %p flags %X\n",pfnCallback,afCmd);
+ ERR("new instance, callback %p flags %X\n",pfnCallback,afCmd);
EnterCriticalSection(&WDML_CritSect);
@@ -410,7 +907,7 @@
*/
pInstance->CBFflags = pInstance->CBFflags|APPCMD_FILTERINITS;
- TRACE("First application instance detected OK\n");
+ ERR("First application instance detected OK\n");
/* allocate new instance ID */
WDML_IncrementInstanceId(pInstance);
}
@@ -419,7 +916,7 @@
/* really need to chain the new one in to the latest here, but after checking
conditions
* such as trying to start a conversation from an application trying to monitor */
reference_inst = WDML_InstanceList;
- TRACE("Subsequent application instance - starting checks\n");
+ ERR("Subsequent application instance - starting checks\n");
while (reference_inst->next != NULL)
{
/*
@@ -435,6 +932,7 @@
if (pInstance->clientOnly != reference_inst->clientOnly)
{
+ ERR("WDML_Initialize Mustbe Client-only\n");
ret = DMLERR_DLL_USAGE;
goto theError;
}
@@ -443,6 +941,7 @@
if (pInstance->monitor != reference_inst->monitor)
{
+ ERR("WDML_Initialize cannot use monitor w/any modes\n");
ret = DMLERR_INVALIDPARAMETER;
goto theError;
}
@@ -459,7 +958,7 @@
}
/* All cleared, add to chain */
- TRACE("Application Instance checks finished\n");
+ ERR("Application Instance checks finished\n");
WDML_IncrementInstanceId(pInstance);
reference_inst->next = pInstance;
}
@@ -489,17 +988,18 @@
SetWindowLongPtrW(pInstance->hwndEvent, GWL_WDML_INSTANCE, (ULONG_PTR)pInstance);
- TRACE("New application instance processing finished OK\n");
+ ERR("New application instance processing finished OK\n");
}
else
{
/* Reinitialisation situation --- FIX */
- TRACE("reinitialisation of (%p,%p,0x%x,%d): stub\n", pidInst, pfnCallback,
afCmd, ulRes);
+ ERR("reinitialisation of (%p,%p,0x%x,%d): stub\n", pidInst, pfnCallback,
afCmd, ulRes);
EnterCriticalSection(&WDML_CritSect);
if (WDML_InstanceList == NULL)
{
+ ERR("WDML_Initialize No instance list\n");
ret = DMLERR_INVALIDPARAMETER;
goto theError;
}
@@ -524,6 +1024,7 @@
if (!(afCmd & APPCMD_CLIENTONLY))
{
+ ERR("WDML_Initialize AppCmd Client-only 2\n");
ret = DMLERR_INVALIDPARAMETER;
goto theError;
}
@@ -533,6 +1034,7 @@
if (pInstance->monitor != reference_inst->monitor)
{
+ ERR("WDML_Initialize cannot change monitor modes 2\n");
ret = DMLERR_INVALIDPARAMETER;
goto theError;
}
@@ -541,6 +1043,7 @@
if ((afCmd&APPCMD_CLIENTONLY) && !reference_inst->clientOnly)
{
+ ERR("WDML_Initialize trying to set Client-only via APPCMD\n");
ret = DMLERR_INVALIDPARAMETER;
goto theError;
}
@@ -550,6 +1053,7 @@
}
if (reference_inst->next == NULL)
{
+ ERR("WDML_Initialize Nothing Next\n");
ret = DMLERR_INVALIDPARAMETER;
goto theError;
}
@@ -566,6 +1070,7 @@
return DMLERR_NO_ERROR;
theError:
+ ERR("WDML_Initialize error %x\n",ret);
HeapFree(GetProcessHeap(), 0, pInstance);
LeaveCriticalSection(&WDML_CritSect);
return ret;
@@ -767,497 +1272,6 @@
return (WDML_INSTANCE*)GetWindowLongPtrW(hWnd, GWL_WDML_INSTANCE);
}
-/******************************************************************************
- * DdeGetLastError [USER32.@] Gets most recent error code
- *
- * PARAMS
- * idInst [I] Instance identifier
- *
- * RETURNS
- * Last error code
- */
-UINT WINAPI DdeGetLastError(DWORD idInst)
-{
- DWORD error_code;
- WDML_INSTANCE* pInstance;
-
- /* First check instance
- */
- pInstance = WDML_GetInstance(idInst);
- if (pInstance == NULL)
- {
- error_code = DMLERR_INVALIDPARAMETER;
- }
- else
- {
- error_code = pInstance->lastError;
- pInstance->lastError = 0;
- }
-
- return error_code;
-}
-
-/******************************************************************
- * WDML_SetAllLastError
- *
- *
- */
-static void WDML_SetAllLastError(DWORD lastError)
-{
- DWORD threadID;
- WDML_INSTANCE* pInstance;
- threadID = GetCurrentThreadId();
- pInstance = WDML_InstanceList;
- while (pInstance)
- {
- if (pInstance->threadID == threadID)
- pInstance->lastError = lastError;
- pInstance = pInstance->next;
- }
-}
-
-/* ================================================================
- *
- * String management
- *
- * ================================================================ */
-
-
-/******************************************************************
- * WDML_FindNode
- *
- *
- */
-static HSZNode* WDML_FindNode(WDML_INSTANCE* pInstance, HSZ hsz)
-{
- HSZNode* pNode;
-
- if (pInstance == NULL) return NULL;
-
- for (pNode = pInstance->nodeList; pNode != NULL; pNode = pNode->next)
- {
- if (pNode->hsz == hsz) break;
- }
- if (!pNode) WARN("HSZ %p not found\n", hsz);
- return pNode;
-}
-
-/******************************************************************
- * WDML_MakeAtomFromHsz
- *
- * Creates a global atom from an existing HSZ
- * Generally used before sending an HSZ as an atom to a remote app
- */
-ATOM WDML_MakeAtomFromHsz(HSZ hsz)
-{
- WCHAR nameBuffer[MAX_BUFFER_LEN];
-
- if (GetAtomNameW(HSZ2ATOM(hsz), nameBuffer, MAX_BUFFER_LEN))
- return GlobalAddAtomW(nameBuffer);
- WARN("HSZ %p not found\n", hsz);
- return 0;
-}
-
-/******************************************************************
- * WDML_MakeHszFromAtom
- *
- * Creates a HSZ from an existing global atom
- * Generally used while receiving a global atom and transforming it
- * into an HSZ
- */
-HSZ WDML_MakeHszFromAtom(const WDML_INSTANCE* pInstance, ATOM atom)
-{
- WCHAR nameBuffer[MAX_BUFFER_LEN];
-
- if (!atom) return NULL;
-
- if (GlobalGetAtomNameW(atom, nameBuffer, MAX_BUFFER_LEN))
- {
- TRACE("%x => %s\n", atom, debugstr_w(nameBuffer));
- return DdeCreateStringHandleW(pInstance->instanceID, nameBuffer, CP_WINUNICODE);
- }
- WARN("ATOM 0x%x not found\n", atom);
- return 0;
-}
-
-/******************************************************************
- * WDML_IncHSZ
- *
- *
- */
-BOOL WDML_IncHSZ(WDML_INSTANCE* pInstance, HSZ hsz)
-{
- HSZNode* pNode;
-
- pNode = WDML_FindNode(pInstance, hsz);
- if (!pNode) return FALSE;
-
- pNode->refCount++;
- return TRUE;
-}
-
-/******************************************************************************
- * WDML_DecHSZ (INTERNAL)
- *
- * Decrease the ref count of an HSZ. If it reaches 0, the node is removed from the list
- * of HSZ nodes
- * Returns -1 is the HSZ isn't found, otherwise it's the current (after --) of
the ref count
- */
-BOOL WDML_DecHSZ(WDML_INSTANCE* pInstance, HSZ hsz)
-{
- HSZNode* pPrev = NULL;
- HSZNode* pCurrent;
-
- for (pCurrent = pInstance->nodeList; pCurrent != NULL; pCurrent = (pPrev =
pCurrent)->next)
- {
- /* If we found the node we were looking for and its ref count is one,
- * we can remove it
- */
- if (pCurrent->hsz == hsz)
- {
- if (--pCurrent->refCount == 0)
- {
- if (pCurrent == pInstance->nodeList)
- {
- pInstance->nodeList = pCurrent->next;
- }
- else
- {
- pPrev->next = pCurrent->next;
- }
- HeapFree(GetProcessHeap(), 0, pCurrent);
- DeleteAtom(HSZ2ATOM(hsz));
- }
- return TRUE;
- }
- }
- WARN("HSZ %p not found\n", hsz);
-
- return FALSE;
-}
-
-/******************************************************************************
- * WDML_FreeAllHSZ (INTERNAL)
- *
- * Frees up all the strings still allocated in the list and
- * remove all the nodes from the list of HSZ nodes.
- */
-void WDML_FreeAllHSZ(WDML_INSTANCE* pInstance)
-{
- /* Free any strings created in this instance.
- */
- while (pInstance->nodeList != NULL)
- {
- DdeFreeStringHandle(pInstance->instanceID, pInstance->nodeList->hsz);
- }
-}
-
-/******************************************************************************
- * InsertHSZNode (INTERNAL)
- *
- * Insert a node to the head of the list.
- */
-static void WDML_InsertHSZNode(WDML_INSTANCE* pInstance, HSZ hsz)
-{
- if (hsz != 0)
- {
- HSZNode* pNew = NULL;
- /* Create a new node for this HSZ.
- */
- pNew = HeapAlloc(GetProcessHeap(), 0, sizeof(HSZNode));
- if (pNew != NULL)
- {
- pNew->hsz = hsz;
- pNew->next = pInstance->nodeList;
- pNew->refCount = 1;
- pInstance->nodeList = pNew;
- }
- else
- {
- ERR("Primary HSZ Node allocation failed - out of memory\n");
- }
- }
-}
-
-/******************************************************************
- * WDML_QueryString
- *
- *
- */
-static int WDML_QueryString(WDML_INSTANCE* pInstance, HSZ hsz, LPVOID ptr, DWORD cchMax,
- int codepage)
-{
- WCHAR pString[MAX_BUFFER_LEN];
- int ret;
- /* If psz is null, we have to return only the length
- * of the string.
- */
- if (ptr == NULL)
- {
- ptr = pString;
- cchMax = MAX_BUFFER_LEN;
- }
-
- /* if there is no input windows returns a NULL string */
- if (hsz == NULL)
- {
- CHAR *t_ptr = ptr;
- *t_ptr = '\0';
- return 1;
- }
-
- 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("(%d, %p, %p, %d, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
-
- /* First check instance
- */
- pInstance = WDML_GetInstance(idInst);
- if (pInstance != NULL)
- {
- if (iCodePage == 0) iCodePage = CP_WINANSI;
- ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
- }
-
- TRACE("returning %d (%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("(%d, %p, %p, %d, %d)\n", idInst, hsz, psz, cchMax, iCodePage);
-
- /* First check instance
- */
- pInstance = WDML_GetInstance(idInst);
- if (pInstance != NULL)
- {
- if (iCodePage == 0) iCodePage = CP_WINUNICODE;
- ret = WDML_QueryString(pInstance, hsz, psz, cchMax, iCodePage);
- }
-
- TRACE("returning %d (%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("(%d,%s,%d)\n", idInst, debugstr_a(psz), codepage);
-
- pInstance = WDML_GetInstance(idInst);
- if (pInstance == NULL)
- WDML_SetAllLastError(DMLERR_INVALIDPARAMETER);
- else
- {
- if (codepage == 0) codepage = CP_WINANSI;
- hsz = WDML_CreateString(pInstance, psz, codepage);
- }
-
- 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;
-
- pInstance = WDML_GetInstance(idInst);
- if (pInstance == NULL)
- WDML_SetAllLastError(DMLERR_INVALIDPARAMETER);
- else
- {
- if (codepage == 0) codepage = CP_WINUNICODE;
- hsz = WDML_CreateString(pInstance, psz, codepage);
- }
-
- return hsz;
-}
-
-/*****************************************************************
- * DdeFreeStringHandle (USER32.@)
- * RETURNS
- * success: nonzero
- * fail: zero
- */
-BOOL WINAPI DdeFreeStringHandle(DWORD idInst, HSZ hsz)
-{
- WDML_INSTANCE* pInstance;
- BOOL ret = FALSE;
-
- TRACE("(%d,%p):\n", idInst, hsz);
-
- /* First check instance
- */
- pInstance = WDML_GetInstance(idInst);
- if (pInstance)
- ret = WDML_DecHSZ(pInstance, hsz);
-
- return ret;
-}
-
-/*****************************************************************
- * DdeKeepStringHandle (USER32.@)
- *
- * RETURNS
- * success: nonzero
- * fail: zero
- */
-BOOL WINAPI DdeKeepStringHandle(DWORD idInst, HSZ hsz)
-{
- WDML_INSTANCE* pInstance;
- BOOL ret = FALSE;
-
- TRACE("(%d,%p):\n", idInst, hsz);
-
- /* First check instance
- */
- pInstance = WDML_GetInstance(idInst);
- if (pInstance)
- ret = WDML_IncHSZ(pInstance, hsz);
-
- 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
@@ -1459,7 +1473,7 @@
/* 1 is the handle value returned by an asynchronous operation. */
if (hData == (HDDEDATA)1)
- return TRUE;
+ return TRUE;
return GlobalFree(hData) == 0;
}
@@ -1514,7 +1528,7 @@
default:
FIXME("Unsupported format (%04x) for data %p, passing raw
information\n",
pDd->cfFormat, hMem);
- /* fall thru */
+ /* fall through */
case 0:
case CF_TEXT:
ret = DdeCreateDataHandle(pConv->instance->instanceID,
pDd->Value, size, 0, 0, pDd->cfFormat, 0);
@@ -1573,7 +1587,7 @@
default:
FIXME("Unsupported format (%04x) for data %p, passing raw
information\n",
pDdh->cfFormat, hDdeData);
- /* fall thru */
+ /* fall through */
case 0:
case CF_TEXT:
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(WINE_DDEHEAD) +
dwSize);
@@ -1738,6 +1752,259 @@
/* ================================================================
*
+ * Link (hot & warm) management
+ *
+ * ================================================================ */
+
+/******************************************************************
+ * WDML_AddLink
+ *
+ *
+ */
+void WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
+ UINT wType, HSZ hszItem, UINT wFmt)
+{
+ WDML_LINK* pLink;
+
+ pLink = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_LINK));
+ if (pLink == NULL)
+ {
+ ERR("OOM\n");
+ return;
+ }
+
+ pLink->hConv = hConv;
+ pLink->transactionType = wType;
+ WDML_IncHSZ(pInstance, pLink->hszItem = hszItem);
+ pLink->uFmt = wFmt;
+ pLink->next = pInstance->links[side];
+ pInstance->links[side] = pLink;
+}
+
+/******************************************************************
+ * WDML_RemoveLink
+ *
+ *
+ */
+void WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
+ HSZ hszItem, UINT uFmt)
+{
+ WDML_LINK* pPrev = NULL;
+ WDML_LINK* pCurrent = NULL;
+
+ pCurrent = pInstance->links[side];
+
+ while (pCurrent != NULL)
+ {
+ if (pCurrent->hConv == hConv &&
+ DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
+ pCurrent->uFmt == uFmt)
+ {
+ if (pCurrent == pInstance->links[side])
+ {
+ pInstance->links[side] = pCurrent->next;
+ }
+ else
+ {
+ pPrev->next = pCurrent->next;
+ }
+
+ WDML_DecHSZ(pInstance, pCurrent->hszItem);
+ HeapFree(GetProcessHeap(), 0, pCurrent);
+ break;
+ }
+
+ pPrev = pCurrent;
+ pCurrent = pCurrent->next;
+ }
+}
+
+/* this function is called to remove all links related to the conv.
+ It should be called from both client and server when terminating
+ the conversation.
+*/
+/******************************************************************
+ * WDML_RemoveAllLinks
+ *
+ *
+ */
+void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side)
+{
+ WDML_LINK* pPrev = NULL;
+ WDML_LINK* pCurrent = NULL;
+ WDML_LINK* pNext = NULL;
+
+ pCurrent = pInstance->links[side];
+
+ while (pCurrent != NULL)
+ {
+ if (pCurrent->hConv == (HCONV)pConv)
+ {
+ if (pCurrent == pInstance->links[side])
+ {
+ pInstance->links[side] = pCurrent->next;
+ pNext = pCurrent->next;
+ }
+ else
+ {
+ pPrev->next = pCurrent->next;
+ pNext = pCurrent->next;
+ }
+
+ WDML_DecHSZ(pInstance, pCurrent->hszItem);
+
+ HeapFree(GetProcessHeap(), 0, pCurrent);
+ pCurrent = NULL;
+ }
+
+ if (pCurrent)
+ {
+ pPrev = pCurrent;
+ pCurrent = pCurrent->next;
+ }
+ else
+ {
+ pCurrent = pNext;
+ }
+ }
+}
+
+/******************************************************************
+ * WDML_FindLink
+ *
+ *
+ */
+WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
+ HSZ hszItem, BOOL use_fmt, UINT uFmt)
+{
+ WDML_LINK* pCurrent = NULL;
+
+ for (pCurrent = pInstance->links[side]; pCurrent != NULL; pCurrent =
pCurrent->next)
+ {
+ /* we don't need to check for transaction type as it can be altered */
+
+ if (pCurrent->hConv == hConv &&
+ DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
+ (!use_fmt || pCurrent->uFmt == uFmt))
+ {
+ break;
+ }
+
+ }
+
+ return pCurrent;
+}
+
+/* ================================================================
+ *
+ * Transaction management
+ *
+ * ================================================================ */
+
+/******************************************************************
+ * WDML_AllocTransaction
+ *
+ * Alloc a transaction structure for handling the message ddeMsg
+ */
+WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg,
+ UINT wFmt, HSZ hszItem)
+{
+ WDML_XACT* pXAct;
+ static WORD tid = 1; /* FIXME: wrap around */
+
+ pXAct = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_XACT));
+ if (!pXAct)
+ {
+ pInstance->lastError = DMLERR_MEMORY_ERROR;
+ return NULL;
+ }
+
+ pXAct->xActID = tid++;
+ pXAct->ddeMsg = ddeMsg;
+ pXAct->hDdeData = 0;
+ pXAct->hUser = 0;
+ pXAct->next = NULL;
+ pXAct->wType = 0;
+ pXAct->wFmt = wFmt;
+ if ((pXAct->hszItem = hszItem)) WDML_IncHSZ(pInstance, pXAct->hszItem);
+ pXAct->atom = 0;
+ pXAct->hMem = 0;
+ pXAct->lParam = 0;
+
+ return pXAct;
+}
+
+/******************************************************************
+ * WDML_QueueTransaction
+ *
+ * Adds a transaction to the list of transaction
+ */
+void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct)
+{
+ WDML_XACT** pt;
+
+ /* advance to last in queue */
+ for (pt = &pConv->transactions; *pt != NULL; pt = &(*pt)->next);
+ *pt = pXAct;
+}
+
+/******************************************************************
+ * WDML_UnQueueTransaction
+ *
+ *
+ */
+BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct)
+{
+ WDML_XACT** pt;
+
+ for (pt = &pConv->transactions; *pt; pt = &(*pt)->next)
+ {
+ if (*pt == pXAct)
+ {
+ *pt = pXAct->next;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/******************************************************************
+ * WDML_FreeTransaction
+ *
+ *
+ */
+void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt)
+{
+ /* free pmt(s) in pXAct too. check against one for not deleting TRUE return values
*/
+ if (doFreePmt && (ULONG_PTR)pXAct->hMem > 1)
+ {
+ GlobalFree(pXAct->hMem);
+ }
+ if (pXAct->hszItem) WDML_DecHSZ(pInstance, pXAct->hszItem);
+
+ HeapFree(GetProcessHeap(), 0, pXAct);
+}
+
+/******************************************************************
+ * WDML_FindTransaction
+ *
+ *
+ */
+WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid)
+{
+ WDML_XACT* pXAct;
+
+ tid = HIWORD(tid);
+ for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
+ {
+ if (pXAct->xActID == tid)
+ break;
+ }
+ return pXAct;
+}
+
+/* ================================================================
+ *
* Conversation management
*
* ================================================================ */
@@ -1876,7 +2143,7 @@
}
if (wCmd == EC_QUERYWAITING)
- return pConv->transactions ? TRUE : FALSE;
+ return pConv->transactions != NULL;
if (wCmd != EC_ENABLEALL && wCmd != EC_ENABLEONE)
{
@@ -2203,259 +2470,6 @@
/* ================================================================
*
- * Link (hot & warm) management
- *
- * ================================================================ */
-
-/******************************************************************
- * WDML_AddLink
- *
- *
- */
-void WDML_AddLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
- UINT wType, HSZ hszItem, UINT wFmt)
-{
- WDML_LINK* pLink;
-
- pLink = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_LINK));
- if (pLink == NULL)
- {
- ERR("OOM\n");
- return;
- }
-
- pLink->hConv = hConv;
- pLink->transactionType = wType;
- WDML_IncHSZ(pInstance, pLink->hszItem = hszItem);
- pLink->uFmt = wFmt;
- pLink->next = pInstance->links[side];
- pInstance->links[side] = pLink;
-}
-
-/******************************************************************
- * WDML_RemoveLink
- *
- *
- */
-void WDML_RemoveLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
- HSZ hszItem, UINT uFmt)
-{
- WDML_LINK* pPrev = NULL;
- WDML_LINK* pCurrent = NULL;
-
- pCurrent = pInstance->links[side];
-
- while (pCurrent != NULL)
- {
- if (pCurrent->hConv == hConv &&
- DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
- pCurrent->uFmt == uFmt)
- {
- if (pCurrent == pInstance->links[side])
- {
- pInstance->links[side] = pCurrent->next;
- }
- else
- {
- pPrev->next = pCurrent->next;
- }
-
- WDML_DecHSZ(pInstance, pCurrent->hszItem);
- HeapFree(GetProcessHeap(), 0, pCurrent);
- break;
- }
-
- pPrev = pCurrent;
- pCurrent = pCurrent->next;
- }
-}
-
-/* this function is called to remove all links related to the conv.
- It should be called from both client and server when terminating
- the conversation.
-*/
-/******************************************************************
- * WDML_RemoveAllLinks
- *
- *
- */
-void WDML_RemoveAllLinks(WDML_INSTANCE* pInstance, WDML_CONV* pConv, WDML_SIDE side)
-{
- WDML_LINK* pPrev = NULL;
- WDML_LINK* pCurrent = NULL;
- WDML_LINK* pNext = NULL;
-
- pCurrent = pInstance->links[side];
-
- while (pCurrent != NULL)
- {
- if (pCurrent->hConv == (HCONV)pConv)
- {
- if (pCurrent == pInstance->links[side])
- {
- pInstance->links[side] = pCurrent->next;
- pNext = pCurrent->next;
- }
- else
- {
- pPrev->next = pCurrent->next;
- pNext = pCurrent->next;
- }
-
- WDML_DecHSZ(pInstance, pCurrent->hszItem);
-
- HeapFree(GetProcessHeap(), 0, pCurrent);
- pCurrent = NULL;
- }
-
- if (pCurrent)
- {
- pPrev = pCurrent;
- pCurrent = pCurrent->next;
- }
- else
- {
- pCurrent = pNext;
- }
- }
-}
-
-/******************************************************************
- * WDML_FindLink
- *
- *
- */
-WDML_LINK* WDML_FindLink(WDML_INSTANCE* pInstance, HCONV hConv, WDML_SIDE side,
- HSZ hszItem, BOOL use_fmt, UINT uFmt)
-{
- WDML_LINK* pCurrent = NULL;
-
- for (pCurrent = pInstance->links[side]; pCurrent != NULL; pCurrent =
pCurrent->next)
- {
- /* we don't need to check for transaction type as it can be altered */
-
- if (pCurrent->hConv == hConv &&
- DdeCmpStringHandles(pCurrent->hszItem, hszItem) == 0 &&
- (!use_fmt || pCurrent->uFmt == uFmt))
- {
- break;
- }
-
- }
-
- return pCurrent;
-}
-
-/* ================================================================
- *
- * Transaction management
- *
- * ================================================================ */
-
-/******************************************************************
- * WDML_AllocTransaction
- *
- * Alloc a transaction structure for handling the message ddeMsg
- */
-WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* pInstance, UINT ddeMsg,
- UINT wFmt, HSZ hszItem)
-{
- WDML_XACT* pXAct;
- static WORD tid = 1; /* FIXME: wrap around */
-
- pXAct = HeapAlloc(GetProcessHeap(), 0, sizeof(WDML_XACT));
- if (!pXAct)
- {
- pInstance->lastError = DMLERR_MEMORY_ERROR;
- return NULL;
- }
-
- pXAct->xActID = tid++;
- pXAct->ddeMsg = ddeMsg;
- pXAct->hDdeData = 0;
- pXAct->hUser = 0;
- pXAct->next = NULL;
- pXAct->wType = 0;
- pXAct->wFmt = wFmt;
- if ((pXAct->hszItem = hszItem)) WDML_IncHSZ(pInstance, pXAct->hszItem);
- pXAct->atom = 0;
- pXAct->hMem = 0;
- pXAct->lParam = 0;
-
- return pXAct;
-}
-
-/******************************************************************
- * WDML_QueueTransaction
- *
- * Adds a transaction to the list of transaction
- */
-void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct)
-{
- WDML_XACT** pt;
-
- /* advance to last in queue */
- for (pt = &pConv->transactions; *pt != NULL; pt = &(*pt)->next);
- *pt = pXAct;
-}
-
-/******************************************************************
- * WDML_UnQueueTransaction
- *
- *
- */
-BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct)
-{
- WDML_XACT** pt;
-
- for (pt = &pConv->transactions; *pt; pt = &(*pt)->next)
- {
- if (*pt == pXAct)
- {
- *pt = pXAct->next;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/******************************************************************
- * WDML_FreeTransaction
- *
- *
- */
-void WDML_FreeTransaction(WDML_INSTANCE* pInstance, WDML_XACT* pXAct, BOOL doFreePmt)
-{
- /* free pmt(s) in pXAct too. check against one for not deleting TRUE return values
*/
- if (doFreePmt && (ULONG_PTR)pXAct->hMem > 1)
- {
- GlobalFree(pXAct->hMem);
- }
- if (pXAct->hszItem) WDML_DecHSZ(pInstance, pXAct->hszItem);
-
- HeapFree(GetProcessHeap(), 0, pXAct);
-}
-
-/******************************************************************
- * WDML_FindTransaction
- *
- *
- */
-WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid)
-{
- WDML_XACT* pXAct;
-
- tid = HIWORD(tid);
- for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
- {
- if (pXAct->xActID == tid)
- break;
- }
- return pXAct;
-}
-
-/* ================================================================
- *
* Information broadcast across DDEML implementations
*
* ================================================================ */
Modified: trunk/reactos/win32ss/user/user32/misc/ddeclient.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/d…
==============================================================================
--- trunk/reactos/win32ss/user/user32/misc/ddeclient.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/misc/ddeclient.c [iso-8859-1] Tue May 20 19:39:34
2014
@@ -30,8 +30,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
static LRESULT CALLBACK WDML_ClientProc(HWND, UINT, WPARAM, LPARAM); /* only for one
client, not conv list */
-const char WDML_szClientConvClassA[] = "DdeClientAnsi";
-const WCHAR WDML_szClientConvClassW[] =
{'D','d','e','C','l','i','e','n','t','U','n','i','c','o','d','e',0};
+const char WDML_szClientConvClassA[] = "DDEMLAnsiClient";
+const WCHAR WDML_szClientConvClassW[] =
{'D','D','E','M','L','U','n','i','c','o','d','e','C','l','i','e','n','t',0};
/******************************************************************************
* DdeConnectList [USER32.@] Establishes conversation with DDE servers
@@ -91,7 +91,7 @@
WDML_CONV* pConv = NULL;
ATOM aSrv = 0, aTpc = 0;
- TRACE("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
+ ERR("(0x%x,%p,%p,%p)\n", idInst, hszService, hszTopic, pCC);
pInstance = WDML_GetInstance(idInst);
if (!pInstance)
@@ -166,7 +166,7 @@
/* note: sent messages shall not use packing */
SendMessageTimeoutW( HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM)hwndClient,
MAKELPARAM(aSrv, aTpc),
- SMTO_ABORTIFHUNG, 2000, NULL );
+ SMTO_ABORTIFHUNG, 0, NULL );
pInstance = WDML_GetInstance(idInst);
if (!pInstance)
@@ -180,12 +180,12 @@
pConv = WDML_GetConvFromWnd(hwndClient);
if (pConv == NULL || pConv->hwndServer == 0)
{
- WARN("Done with INITIATE, but no Server window available\n");
+ ERR("Done with INITIATE, but no Server window available %p\n", (pConv ?
pConv->hwndServer : NULL));
pConv = NULL;
pInstance->lastError = DMLERR_NO_CONV_ESTABLISHED;
goto theEnd;
}
- TRACE("Connected to Server window (%p)\n", pConv->hwndServer);
+ ERR("Connected to Server window (%p)\n", pConv->hwndServer);
pConv->wConvst = XST_CONNECTED;
/* finish init of pConv */
@@ -312,8 +312,8 @@
/* pack DdeAdvise */
pDdeAdvise = GlobalLock(pXAct->hMem);
- pDdeAdvise->fAckReq = (wType & XTYPF_ACKREQ) ? TRUE : FALSE;
- pDdeAdvise->fDeferUpd = (wType & XTYPF_NODATA) ? TRUE : FALSE;
+ pDdeAdvise->fAckReq = (wType & XTYPF_ACKREQ) != 0;
+ pDdeAdvise->fDeferUpd = (wType & XTYPF_NODATA) != 0;
pDdeAdvise->cfFormat = wFmt;
GlobalUnlock(pXAct->hMem);
@@ -848,7 +848,7 @@
* XTYP_ADVDATA and callback should return the proper status.
*/
pLink = WDML_FindLink(pConv->instance, (HCONV)pConv, WDML_CLIENT_SIDE, hsz,
- uiLo ? TRUE : FALSE, wdh.cfFormat);
+ uiLo != 0, wdh.cfFormat);
if (!pLink)
{
WDML_DecHSZ(pConv->instance, hsz);
@@ -1008,22 +1008,20 @@
*/
static HDDEDATA WDML_SyncWaitTransactionReply(HCONV hConv, DWORD dwTimeout, const
WDML_XACT* pXAct, DWORD *ack)
{
- DWORD dwTime;
+ DWORD start, elapsed;
DWORD err;
WDML_CONV* pConv;
- TRACE("Starting wait for a timeout of %d ms\n", dwTimeout);
-
- /* FIXME: time 32 bit wrap around */
- dwTimeout += GetCurrentTime();
-
- while ((dwTime = GetCurrentTime()) < dwTimeout)
+ ERR("Starting wait for a timeout of %d ms\n", dwTimeout);
+
+ start = GetTickCount();
+ while ((elapsed = GetTickCount() - start) < dwTimeout)
{
/* we cannot be in the crit sect all the time because when client and server run in a
* single process they need to share the access to the internal data
*/
if (MsgWaitForMultipleObjects(0, NULL, FALSE,
- dwTimeout - dwTime, QS_POSTMESSAGE) == WAIT_OBJECT_0)
+ dwTimeout - elapsed, QS_POSTMESSAGE) == WAIT_OBJECT_0)
{
MSG msg;
@@ -1034,16 +1032,18 @@
pConv = WDML_GetConv(hConv, FALSE);
if (pConv == NULL)
{
+ ERR("conversation no longer available\n");
/* conversation no longer available... return failure */
return 0;
}
+ ERR("Msg hWnd %p & Client
%p\n",msg.hwnd,pConv->hwndClient);
if (msg.hwnd == pConv->hwndClient)
{
/* check that either pXAct has been processed or no more xActions are
pending */
BOOL ret = (pConv->transactions == pXAct);
if (WDML_HandleReply(pConv, &msg, &hdd, ack) ==
WDML_QS_HANDLED)
{
- TRACE("WDML_HandleReply returned WDML_QS_HANDLED\n");
+ ERR("WDML_HandleReply returned WDML_QS_HANDLED\n");
ret = TRUE;
}
else
@@ -1057,13 +1057,14 @@
}
else
{
+ ERR("Dispatching message\n");
DispatchMessageW(&msg);
}
}
}
}
- TRACE("Timeout !!\n");
+ ERR("Timeout !!\n");
pConv = WDML_GetConv(hConv, FALSE);
if (pConv != NULL)
@@ -1143,6 +1144,7 @@
if (pConv == NULL)
{
/* cannot set error... cannot get back to DDE instance */
+ ERR("No Conv!\n");
return 0;
}
@@ -1237,14 +1239,18 @@
{
if ((pConv = WDML_GetConv(hConv, TRUE)) && pConv->instance ==
pInstance)
{
- for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
- {
+
+ pXAct = pConv->transactions;
+ while (pXAct) {
+ WDML_XACT *nextXAct = pXAct->next;
+
if (pXAct->dwTimeout == TIMEOUT_ASYNC &&
(idTransaction == 0 || pXAct->xActID == idTransaction))
{
WDML_UnQueueTransaction(pConv, pXAct);
WDML_FreeTransaction(pInstance, pXAct, TRUE);
}
+ pXAct = nextXAct;
}
}
}
@@ -1253,13 +1259,16 @@
for (pConv = pInstance->convs[WDML_CLIENT_SIDE]; pConv; pConv =
pConv->next)
{
if (!(pConv->wStatus & ST_CONNECTED)) continue;
- for (pXAct = pConv->transactions; pXAct; pXAct = pXAct->next)
- {
+ pXAct = pConv->transactions;
+ while (pXAct) {
+ WDML_XACT *nextXAct = pXAct->next;
+
if (pXAct->dwTimeout == TIMEOUT_ASYNC)
{
WDML_UnQueueTransaction(pConv, pXAct);
WDML_FreeTransaction(pInstance, pXAct, TRUE);
}
+ pXAct = nextXAct;
}
}
}
@@ -1278,16 +1287,18 @@
UINT uiLo, uiHi;
WDML_CONV* pConv = NULL;
HSZ hszSrv, hszTpc;
-
- TRACE("%p %04x %08lx %08lx\n", hwnd, iMsg, wParam , lParam);
-
+ char buf[256];
+ WDML_INSTANCE* pInstance;
+
+ ERR("%p %04x %08lx %08lx\n", hwnd, iMsg, wParam , lParam);
+
+ /* in the initial WM_INITIATE sendmessage */
if (iMsg == WM_DDE_ACK &&
- /* in the initial WM_INITIATE sendmessage */
- ((pConv = WDML_GetConvFromWnd(hwnd)) == NULL || pConv->wStatus == XST_INIT1))
- {
+ (!(pConv = WDML_GetConvFromWnd(hwnd)) || pConv->wStatus == XST_INIT1))
+ {
+
+ ERR("WM_DDE_ACK\n");
/* In response to WM_DDE_INITIATE, save server window */
- char buf[256];
- WDML_INSTANCE* pInstance;
/* note: sent messages do not need packing */
uiLo = LOWORD(lParam);
Modified: trunk/reactos/win32ss/user/user32/misc/ddeserver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/misc/d…
==============================================================================
--- trunk/reactos/win32ss/user/user32/misc/ddeserver.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/misc/ddeserver.c [iso-8859-1] Tue May 20 19:39:34
2014
@@ -30,8 +30,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
static const WCHAR szServerNameClass[] =
{'D','d','e','S','e','r','v','e','r','N','a','m','e',0};
-const char WDML_szServerConvClassA[] = "DdeServerConvAnsi";
-const WCHAR WDML_szServerConvClassW[] =
{'D','d','e','S','e','r','v','e','r','C','o','n','v','U','n','i','c','o','d','e',0};
+const char WDML_szServerConvClassA[] = "DdeServerConvA";
+const WCHAR WDML_szServerConvClassW[] =
{'D','d','e','S','e','r','v','e','r','C','o','n','v','W',0};
static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WDML_ServerConvProc(HWND, UINT, WPARAM, LPARAM);
@@ -62,7 +62,7 @@
pInstance = WDML_GetInstance(idInst);
- if (pInstance == NULL || pInstance->links == NULL)
+ if (pInstance == NULL)
return FALSE;
atom = WDML_MakeAtomFromHsz(hszItem);
@@ -135,7 +135,7 @@
return TRUE;
theError:
- if (atom) GlobalDeleteAtom(atom);
+ GlobalDeleteAtom(atom);
return FALSE;
}
@@ -380,12 +380,12 @@
LOWORD(lParam) -- application atom
HIWORD(lParam) -- topic atom */
- TRACE("WM_DDE_INITIATE message received!\n");
+ ERR("WM_DDE_INITIATE message received!\n");
hwndClient = (HWND)wParam;
pInstance = WDML_GetInstanceFromWnd(hwndServer);
- TRACE("idInst=%d, threadID=0x%x\n", pInstance->instanceID,
GetCurrentThreadId());
if (!pInstance) return 0;
+ ERR("idInst=%d, threadID=0x%x\n", pInstance->instanceID,
GetCurrentThreadId());
/* don't free DDEParams, since this is a broadcast */
UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLo, &uiHi);
@@ -708,7 +708,7 @@
pXAct->hszItem, TRUE, pXAct->wFmt);
if (pLink == NULL)
{
- ERR("Couln'd find link for %p, dropping request\n", pXAct->hszItem);
+ ERR("Couldn't find link for %p, dropping request\n", pXAct->hszItem);
FreeDDElParam(WM_DDE_UNADVISE, pXAct->lParam);
return WDML_QS_ERROR;
}
@@ -748,6 +748,54 @@
return pXAct;
}
+static BOOL data_looks_unicode( const WCHAR *data, DWORD size )
+{
+ DWORD i;
+
+ if (size % sizeof(WCHAR)) return FALSE;
+ for (i = 0; i < size / sizeof(WCHAR); i++) if (data[i] > 255) return FALSE;
+ return TRUE;
+}
+
+/* convert data to Unicode, unless it looks like it's already Unicode */
+static HDDEDATA map_A_to_W( DWORD instance, void *ptr, DWORD size )
+{
+ HDDEDATA ret;
+ DWORD len;
+ const char *end;
+
+ if (!data_looks_unicode( ptr, size ))
+ {
+ if ((end = memchr( ptr, 0, size ))) size = end + 1 - (const char *)ptr;
+ len = MultiByteToWideChar( CP_ACP, 0, ptr, size, NULL, 0 );
+ ret = DdeCreateDataHandle( instance, NULL, len * sizeof(WCHAR), 0, 0, CF_TEXT,
0);
+ MultiByteToWideChar( CP_ACP, 0, ptr, size, (WCHAR *)DdeAccessData(ret, NULL), len
);
+ }
+ else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
+
+ return ret;
+}
+
+/* convert data to ASCII, unless it looks like it's not in Unicode format */
+static HDDEDATA map_W_to_A( DWORD instance, void *ptr, DWORD size )
+{
+ HDDEDATA ret;
+ DWORD len;
+ const WCHAR *end;
+
+ if (data_looks_unicode( ptr, size ))
+ {
+ size /= sizeof(WCHAR);
+ if ((end = memchrW( ptr, 0, size ))) size = end + 1 - (const WCHAR *)ptr;
+ len = WideCharToMultiByte( CP_ACP, 0, ptr, size, NULL, 0, NULL, NULL );
+ ret = DdeCreateDataHandle( instance, NULL, len, 0, 0, CF_TEXT, 0);
+ WideCharToMultiByte( CP_ACP, 0, ptr, size, (char *)DdeAccessData(ret, NULL), len,
NULL, NULL );
+ }
+ else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );
+
+ return ret;
+}
+
/******************************************************************
* WDML_ServerHandleExecute
*
@@ -761,11 +809,16 @@
if (!(pConv->instance->CBFflags & CBF_FAIL_EXECUTES))
{
LPVOID ptr = GlobalLock(pXAct->hMem);
+ DWORD size = GlobalSize(pXAct->hMem);
if (ptr)
{
- hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr,
GlobalSize(pXAct->hMem),
- 0, 0, CF_TEXT, 0);
+ if (pConv->instance->unicode) /* Unicode server, try to map A->W
*/
+ hDdeData = map_A_to_W( pConv->instance->instanceID, ptr, size );
+ else if (!IsWindowUnicode( pConv->hwndClient )) /* ASCII server and
client, try to map W->A */
+ hDdeData = map_W_to_A( pConv->instance->instanceID, ptr, size );
+ else
+ hDdeData = DdeCreateDataHandle(pConv->instance->instanceID, ptr,
size, 0, 0, CF_TEXT, 0);
GlobalUnlock(pXAct->hMem);
}
hDdeData = WDML_InvokeCallback(pConv->instance, XTYP_EXECUTE, 0, (HCONV)pConv,