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/dd... ============================================================================== --- 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/dd... ============================================================================== --- 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/dd... ============================================================================== --- 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,