diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-10-28 19:36:34 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-10-28 19:36:34 (GMT) |
| commit | 1f6c360968fab22aa02a30a72c196a8f8eb19c0c (patch) | |
| tree | c490d9cba824ba803b713fe06b6ccfb7f98caca3 /win/tclWinDde.c | |
| parent | 63b8d1466dca7693cf0f6b61d39fada6fd1e0e7f (diff) | |
| parent | ccb97d88ffefe602e7eb5a9610bd356d66bc2f20 (diff) | |
| download | tcl-1f6c360968fab22aa02a30a72c196a8f8eb19c0c.zip tcl-1f6c360968fab22aa02a30a72c196a8f8eb19c0c.tar.gz tcl-1f6c360968fab22aa02a30a72c196a8f8eb19c0c.tar.bz2 | |
Merge tip-468 branch
Diffstat (limited to 'win/tclWinDde.c')
| -rw-r--r-- | win/tclWinDde.c | 276 |
1 files changed, 156 insertions, 120 deletions
diff --git a/win/tclWinDde.c b/win/tclWinDde.c index 2589630..38f1d88 100644 --- a/win/tclWinDde.c +++ b/win/tclWinDde.c @@ -17,15 +17,7 @@ #include "tclInt.h" #include <dde.h> #include <ddeml.h> - -#ifndef UNICODE -# undef CP_WINUNICODE -# define CP_WINUNICODE CP_WINANSI -# undef Tcl_WinTCharToUtf -# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) -# undef Tcl_WinUtfToTChar -# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) -#endif +#include <tchar.h> #if !defined(NDEBUG) /* test POKE server Implemented for debug mode only */ @@ -59,13 +51,13 @@ typedef struct Conversation { Tcl_Obj *returnPackagePtr; /* The result package for this conversation. */ } Conversation; -struct DdeEnumServices { +typedef struct { Tcl_Interp *interp; int result; ATOM service; ATOM topic; HWND hwnd; -}; +} DdeEnumServices; typedef struct { Conversation *currentConversations; @@ -87,7 +79,7 @@ static DWORD ddeInstance; /* The application instance handle given to us * by DdeInitialize. */ static int ddeIsServer = 0; -#define TCL_DDE_VERSION "1.4.0" +#define TCL_DDE_VERSION "1.4.1" #define TCL_DDE_PACKAGE_NAME "dde" #define TCL_DDE_SERVICE_NAME TEXT("TclEval") #define TCL_DDE_EXECUTE_RESULT TEXT("$TCLEVAL$EXECUTE$RESULT") @@ -104,7 +96,7 @@ TCL_DECLARE_MUTEX(ddeMutex) static LRESULT CALLBACK DdeClientWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -static int DdeCreateClient(struct DdeEnumServices *es); +static int DdeCreateClient(DdeEnumServices *es); static BOOL CALLBACK DdeEnumWindowsCallback(HWND hwndTarget, LPARAM lParam); static void DdeExitProc(ClientData clientData); @@ -125,8 +117,9 @@ static int DdeObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -DLLEXPORT int Dde_Init(Tcl_Interp *interp); -DLLEXPORT int Dde_SafeInit(Tcl_Interp *interp); + +DLLEXPORT int Dde_Init(Tcl_Interp *interp); +DLLEXPORT int Dde_SafeInit(Tcl_Interp *interp); /* *---------------------------------------------------------------------- @@ -152,13 +145,6 @@ Dde_Init( return TCL_ERROR; } -#ifdef UNICODE - if (TclWinGetPlatformId() < VER_PLATFORM_WIN32_NT) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "Win32s and Windows 9x are not supported platforms", -1)); - return TCL_ERROR; - } -#endif Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, NULL, NULL); Tcl_CreateExitHandler(DdeExitProc, NULL); return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION); @@ -404,9 +390,9 @@ DdeSetServerName( * We have found a unique name. Now add it to the registry. */ - riPtr = ckalloc(sizeof(RegisteredInterp)); + riPtr = (RegisteredInterp *) Tcl_Alloc(sizeof(RegisteredInterp)); riPtr->interp = interp; - riPtr->name = ckalloc((_tcslen(actualName) + 1) * sizeof(TCHAR)); + riPtr->name = (TCHAR *) Tcl_Alloc((_tcslen(actualName) + 1) * sizeof(TCHAR)); riPtr->nextPtr = tsdPtr->interpListPtr; riPtr->handlerPtr = handlerPtr; if (riPtr->handlerPtr != NULL) { @@ -507,7 +493,7 @@ DeleteProc( prevPtr->nextPtr = searchPtr->nextPtr; } } - ckfree(riPtr->name); + Tcl_Free((char *) riPtr->name); if (riPtr->handlerPtr) { Tcl_DecrRefCount(riPtr->handlerPtr); } @@ -545,7 +531,7 @@ ExecuteRemoteObject( Tcl_Obj *returnPackagePtr; int result = TCL_OK; - if (riPtr->handlerPtr == NULL && Tcl_IsSafe(riPtr->interp)) { + if ((riPtr->handlerPtr == NULL) && Tcl_IsSafe(riPtr->interp)) { Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj("permission denied: " "a handler procedure must be defined for use in a safe " "interp", -1)); @@ -627,7 +613,7 @@ DdeServerProc( /* Transaction-dependent data. */ { Tcl_DString dString; - int len; + size_t len; DWORD dlen; TCHAR *utilString; Tcl_Obj *ddeObjectPtr; @@ -677,7 +663,7 @@ DdeServerProc( for (riPtr = tsdPtr->interpListPtr; riPtr != NULL; riPtr = riPtr->nextPtr) { if (_tcsicmp(riPtr->name, utilString) == 0) { - convPtr = ckalloc(sizeof(Conversation)); + convPtr = (Conversation *) Tcl_Alloc(sizeof(Conversation)); convPtr->nextPtr = tsdPtr->currentConversations; convPtr->returnPackagePtr = NULL; convPtr->hConv = hConv; @@ -707,7 +693,7 @@ DdeServerProc( if (convPtr->returnPackagePtr != NULL) { Tcl_DecrRefCount(convPtr->returnPackagePtr); } - ckfree(convPtr); + Tcl_Free((char *) convPtr); break; } } @@ -733,22 +719,24 @@ DdeServerProc( } if (convPtr != NULL) { + Tcl_DString dsBuf; char *returnString; len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE); Tcl_DStringInit(&dString); + Tcl_DStringInit(&dsBuf); Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1); utilString = (TCHAR *) Tcl_DStringValue(&dString); DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1, CP_WINUNICODE); if (_tcsicmp(utilString, TCL_DDE_EXECUTE_RESULT) == 0) { - if (uFmt == CF_TEXT) { - returnString = - Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len); - } else { - returnString = (char *) - Tcl_GetUnicodeFromObj(convPtr->returnPackagePtr, &len); - len = sizeof(TCHAR) * len + 1; + returnString = + Tcl_GetString(convPtr->returnPackagePtr); + len = convPtr->returnPackagePtr->length; + if (uFmt != CF_TEXT) { + Tcl_WinUtfToTChar(returnString, len, &dsBuf); + returnString = Tcl_DStringValue(&dsBuf); + len = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR) - 1; } ddeReturn = DdeCreateDataHandle(ddeInstance, (BYTE *)returnString, (DWORD) len+1, 0, ddeItem, uFmt, 0); @@ -758,18 +746,18 @@ DdeServerProc( } else { Tcl_DString ds; Tcl_Obj *variableObjPtr; + Tcl_WinTCharToUtf(utilString, -1, &ds); variableObjPtr = Tcl_GetVar2Ex( convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL, TCL_GLOBAL_ONLY); if (variableObjPtr != NULL) { - if (uFmt == CF_TEXT) { - returnString = Tcl_GetStringFromObj( - variableObjPtr, &len); - } else { - returnString = (char *) Tcl_GetUnicodeFromObj( - variableObjPtr, &len); - len = sizeof(TCHAR) * len + 1; + returnString = Tcl_GetString(variableObjPtr); + len = variableObjPtr->length; + if (uFmt != CF_TEXT) { + Tcl_WinUtfToTChar(returnString, len, &dsBuf); + returnString = Tcl_DStringValue(&dsBuf); + len = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR) - 1; } ddeReturn = DdeCreateDataHandle(ddeInstance, (BYTE *)returnString, (DWORD) len+1, 0, ddeItem, @@ -780,6 +768,7 @@ DdeServerProc( Tcl_DStringFree(&ds); } } + Tcl_DStringFree(&dsBuf); Tcl_DStringFree(&dString); } return ddeReturn; @@ -804,26 +793,30 @@ DdeServerProc( } if (convPtr && !Tcl_IsSafe(convPtr->riPtr->interp)) { - Tcl_DString ds; + Tcl_DString ds, ds2; Tcl_Obj *variableObjPtr; + DWORD len2; - len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE); Tcl_DStringInit(&dString); + Tcl_DStringInit(&ds2); + len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE); Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1); utilString = (TCHAR *) Tcl_DStringValue(&dString); DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1, CP_WINUNICODE); Tcl_WinTCharToUtf(utilString, -1, &ds); - utilString = (TCHAR *) DdeAccessData(hData, &dlen); - if (uFmt == CF_TEXT) { - variableObjPtr = Tcl_NewStringObj((char *)utilString, -1); - } else { - variableObjPtr = Tcl_NewUnicodeObj(utilString, -1); + utilString = (TCHAR *) DdeAccessData(hData, &len2); + len = len2; + if (uFmt != CF_TEXT) { + Tcl_WinTCharToUtf(utilString, -1, &ds2); + utilString = (TCHAR *) Tcl_DStringValue(&ds2); } + variableObjPtr = Tcl_NewStringObj((char *)utilString, -1); Tcl_SetVar2Ex(convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL, variableObjPtr, TCL_GLOBAL_ONLY); + Tcl_DStringFree(&ds2); Tcl_DStringFree(&ds); Tcl_DStringFree(&dString); ddeReturn = (HDDEDATA) DDE_FACK; @@ -864,8 +857,12 @@ DdeServerProc( ddeObjectPtr = Tcl_NewStringObj(string, dlen); } else { /* unicode */ - dlen >>= 1; - ddeObjectPtr = Tcl_NewUnicodeObj((Tcl_UniChar *)utilString, dlen - 1); + Tcl_DString dsBuf; + + Tcl_WinTCharToUtf(utilString, dlen - sizeof(TCHAR), &dsBuf); + ddeObjectPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsBuf), + Tcl_DStringLength(&dsBuf)); + Tcl_DStringFree(&dsBuf); } Tcl_IncrRefCount(ddeObjectPtr); DdeUnaccessData(hData); @@ -1030,7 +1027,7 @@ MakeDdeConnection( static int DdeCreateClient( - struct DdeEnumServices *es) + DdeEnumServices *es) { WNDCLASSEX wc; static const TCHAR *szDdeClientClassName = TEXT("TclEval client class"); @@ -1040,7 +1037,7 @@ DdeCreateClient( wc.cbSize = sizeof(wc); wc.lpfnWndProc = DdeClientWindowProc; wc.lpszClassName = szDdeClientClassName; - wc.cbWndExtra = sizeof(struct DdeEnumServices *); + wc.cbWndExtra = sizeof(DdeEnumServices *); /* * Register and create the callback window. @@ -1062,8 +1059,8 @@ DdeClientWindowProc( switch (uMsg) { case WM_CREATE: { LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam; - struct DdeEnumServices *es = - (struct DdeEnumServices *) lpcs->lpCreateParams; + DdeEnumServices *es = + (DdeEnumServices *) lpcs->lpCreateParams; #ifdef _WIN64 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) es); @@ -1088,18 +1085,18 @@ DdeServicesOnAck( HWND hwndRemote = (HWND)wParam; ATOM service = (ATOM)LOWORD(lParam); ATOM topic = (ATOM)HIWORD(lParam); - struct DdeEnumServices *es; + DdeEnumServices *es; TCHAR sz[255]; Tcl_DString dString; #ifdef _WIN64 - es = (struct DdeEnumServices *) GetWindowLongPtr(hwnd, GWLP_USERDATA); + es = (DdeEnumServices *) GetWindowLongPtr(hwnd, GWLP_USERDATA); #else - es = (struct DdeEnumServices *) GetWindowLong(hwnd, GWL_USERDATA); + es = (DdeEnumServices *) GetWindowLong(hwnd, GWL_USERDATA); #endif - if ((es->service == (ATOM)0 || es->service == service) - && (es->topic == (ATOM)0 || es->topic == topic)) { + if (((es->service == (ATOM)0) || (es->service == service)) + && ((es->topic == (ATOM)0) || (es->topic == topic))) { Tcl_Obj *matchPtr = Tcl_NewListObj(0, NULL); Tcl_Obj *resultPtr = Tcl_GetObjResult(es->interp); @@ -1146,7 +1143,7 @@ DdeEnumWindowsCallback( LPARAM lParam) { DWORD_PTR dwResult = 0; - struct DdeEnumServices *es = (struct DdeEnumServices *) lParam; + DdeEnumServices *es = (DdeEnumServices *) lParam; SendMessageTimeout(hwndTarget, WM_DDE_INITIATE, (WPARAM)es->hwnd, MAKELONG(es->service, es->topic), SMTO_ABORTIFHUNG, 1000, @@ -1160,7 +1157,7 @@ DdeGetServicesList( const TCHAR *serviceName, const TCHAR *topicName) { - struct DdeEnumServices es; + DdeEnumServices es; es.interp = interp; es.result = TCL_OK; @@ -1281,7 +1278,8 @@ DdeObjCmd( "-binary", NULL }; - int index, i, length, argIndex; + int index, i, argIndex; + int length; int flags = 0, result = TCL_OK, firstArg = 0; HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL; HDDEDATA ddeData = NULL, ddeItemData = NULL, ddeReturn; @@ -1290,6 +1288,7 @@ DdeObjCmd( const char *string; DWORD ddeResult; Tcl_Obj *objPtr, *handlerPtr = NULL; + Tcl_DString serviceBuf, topicBuf, itemBuf; /* * Initialize DDE server/client @@ -1305,6 +1304,9 @@ DdeObjCmd( return TCL_ERROR; } + Tcl_DStringInit(&serviceBuf); + Tcl_DStringInit(&topicBuf); + Tcl_DStringInit(&itemBuf); switch ((enum DdeSubcommands) index) { case DDE_SERVERNAME: for (i = 2; i < objc; i++) { @@ -1354,7 +1356,7 @@ DdeObjCmd( if (objc == 5) { firstArg = 2; break; - } else if (objc >= 6 && objc <= 7) { + } else if ((objc >= 6) && (objc <= 7)) { firstArg = objc - 3; for (i = 2; i < firstArg; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], ddeExecOptions, @@ -1439,11 +1441,12 @@ DdeObjCmd( Initialize(); if (firstArg != 1) { -#ifdef UNICODE - serviceName = Tcl_GetUnicodeFromObj(objv[firstArg], &length); -#else - serviceName = Tcl_GetStringFromObj(objv[firstArg], &length); -#endif + const char *src = Tcl_GetString(objv[firstArg]); + + length = objv[firstArg]->length; + Tcl_WinUtfToTChar(src, length, &serviceBuf); + serviceName = (TCHAR *) Tcl_DStringValue(&serviceBuf); + length = Tcl_DStringLength(&serviceBuf) / sizeof(TCHAR); } else { length = 0; } @@ -1456,11 +1459,11 @@ DdeObjCmd( } if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { -#ifdef UNICODE - topicName = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 1], &length); -#else - topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length); -#endif + const char *src = Tcl_GetString(objv[firstArg + 1]); + + length = objv[firstArg + 1]->length; + topicName = Tcl_WinUtfToTChar(src, length, &topicBuf); + length = Tcl_DStringLength(&topicBuf) / sizeof(TCHAR); if (length == 0) { topicName = NULL; } else { @@ -1474,11 +1477,12 @@ DdeObjCmd( serviceName = DdeSetServerName(interp, serviceName, flags, handlerPtr); if (serviceName != NULL) { -#ifdef UNICODE - Tcl_SetObjResult(interp, Tcl_NewUnicodeObj((Tcl_UniChar *) serviceName, -1)); -#else - Tcl_SetObjResult(interp, Tcl_NewStringObj(serviceName, -1)); -#endif + Tcl_DString dsBuf; + + Tcl_WinTCharToUtf(serviceName, -1, &dsBuf); + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_DStringValue(&dsBuf), + Tcl_DStringLength(&dsBuf))); + Tcl_DStringFree(&dsBuf); } else { Tcl_ResetResult(interp); } @@ -1486,20 +1490,27 @@ DdeObjCmd( case DDE_EXECUTE: { int dataLength; - const Tcl_UniChar *dataString; + const void *dataString; + Tcl_DString dsBuf; + Tcl_DStringInit(&dsBuf); if (flags & DDE_FLAG_BINARY) { - dataString = (const Tcl_UniChar *) + dataString = Tcl_GetByteArrayFromObj(objv[firstArg + 2], &dataLength); } else { - dataString = - Tcl_GetUnicodeFromObj(objv[firstArg + 2], &dataLength); - dataLength = (dataLength + 1) * sizeof(Tcl_UniChar); + const char *src; + + src = Tcl_GetString(objv[firstArg + 2]); + dataLength = objv[firstArg + 2]->length; + dataString = (const TCHAR *) + Tcl_WinUtfToTChar(src, dataLength, &dsBuf); + dataLength = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR); } - if (dataLength <= 0) { + if (dataLength + 1 < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot execute null data", -1)); + Tcl_DStringFree(&dsBuf); Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL); result = TCL_ERROR; break; @@ -1509,6 +1520,7 @@ DdeObjCmd( DdeFreeStringHandle(ddeInstance, ddeTopic); if (hConv == NULL) { + Tcl_DStringFree(&dsBuf); SetDdeError(interp); result = TCL_ERROR; break; @@ -1534,16 +1546,17 @@ DdeObjCmd( SetDdeError(interp); result = TCL_ERROR; } + Tcl_DStringFree(&dsBuf); break; } case DDE_REQUEST: { -#ifdef UNICODE - const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2], - &length); -#else - const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], - &length); -#endif + const TCHAR *itemString; + const char *src; + + src = Tcl_GetString(objv[firstArg + 2]); + length = objv[firstArg + 2]->length; + itemString = Tcl_WinUtfToTChar(src, length, &itemBuf); + length = Tcl_DStringLength(&itemBuf) / sizeof(TCHAR); if (length == 0) { Tcl_SetObjResult(interp, @@ -1571,18 +1584,23 @@ DdeObjCmd( result = TCL_ERROR; } else { DWORD tmp; - const Tcl_UniChar *dataString = (const Tcl_UniChar *) DdeAccessData(ddeData, &tmp); + TCHAR *dataString = (TCHAR *) DdeAccessData(ddeData, &tmp); if (flags & DDE_FLAG_BINARY) { returnObjPtr = - Tcl_NewByteArrayObj((BYTE *) dataString, (int) tmp); + Tcl_NewByteArrayObj((BYTE *) dataString, tmp); } else { - tmp >>= 1; - if (tmp && !dataString[(tmp-1)]) { - --tmp; + Tcl_DString dsBuf; + + if ((tmp >= sizeof(TCHAR)) + && !dataString[tmp / sizeof(TCHAR) - 1]) { + tmp -= sizeof(TCHAR); } - returnObjPtr = Tcl_NewUnicodeObj(dataString, - (int) tmp); + Tcl_WinTCharToUtf(dataString, tmp, &dsBuf); + returnObjPtr = + Tcl_NewStringObj(Tcl_DStringValue(&dsBuf), + Tcl_DStringLength(&dsBuf)); + Tcl_DStringFree(&dsBuf); } DdeUnaccessData(ddeData); DdeFreeDataHandle(ddeData); @@ -1593,19 +1611,18 @@ DdeObjCmd( result = TCL_ERROR; } } - break; } case DDE_POKE: { -#ifdef UNICODE - const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2], - &length); -#else - const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], - &length); -#endif + Tcl_DString dsBuf; + const TCHAR *itemString; BYTE *dataString; + const char *src; + src = Tcl_GetString(objv[firstArg + 2]); + length = objv[firstArg + 2]->length; + itemString = Tcl_WinUtfToTChar(src, length, &itemBuf); + length = Tcl_DStringLength(&itemBuf) / sizeof(TCHAR); if (length == 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot have a null item", -1)); @@ -1613,13 +1630,17 @@ DdeObjCmd( result = TCL_ERROR; goto cleanup; } + Tcl_DStringInit(&dsBuf); if (flags & DDE_FLAG_BINARY) { dataString = (BYTE *) Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length); } else { + const char *data = + Tcl_GetString(objv[firstArg + 3]); + length = objv[firstArg + 3]->length; dataString = (BYTE *) - Tcl_GetUnicodeFromObj(objv[firstArg + 3], &length); - length = 2 * length + 1; + Tcl_WinUtfToTChar(data, length, &dsBuf); + length = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR); } hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL); @@ -1644,6 +1665,7 @@ DdeObjCmd( result = TCL_ERROR; } } + Tcl_DStringFree(&dsBuf); break; } @@ -1702,7 +1724,7 @@ DdeObjCmd( * referring to deallocated objects. */ - if (Tcl_IsSafe(riPtr->interp) && riPtr->handlerPtr == NULL) { + if (Tcl_IsSafe(riPtr->interp) && (riPtr->handlerPtr == NULL)) { Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj( "permission denied: a handler procedure must be" " defined for use in a safe interp", -1)); @@ -1761,6 +1783,8 @@ DdeObjCmd( Tcl_Release(riPtr); Tcl_Release(sendInterp); } else { + Tcl_DString dsBuf; + /* * This is a non-local request. Send the script to the server and * poll it for a result. @@ -1776,9 +1800,14 @@ DdeObjCmd( } objPtr = Tcl_ConcatObj(objc, objv); - string = (const char *) Tcl_GetUnicodeFromObj(objPtr, &length); - ddeItemData = DdeCreateDataHandle(ddeInstance, - (BYTE *) string, (DWORD) 2*length+2, 0, 0, CF_UNICODETEXT, 0); + string = Tcl_GetString(objPtr); + length = objPtr->length; + Tcl_WinUtfToTChar(string, length, &dsBuf); + string = Tcl_DStringValue(&dsBuf); + length = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR); + ddeItemData = DdeCreateDataHandle(ddeInstance, (BYTE *) string, + (DWORD) length, 0, 0, CF_UNICODETEXT, 0); + Tcl_DStringFree(&dsBuf); if (flags & DDE_FLAG_ASYNC) { ddeData = DdeClientTransaction((LPBYTE) ddeItemData, @@ -1807,7 +1836,7 @@ DdeObjCmd( if (!(flags & DDE_FLAG_ASYNC)) { Tcl_Obj *resultPtr; - Tcl_UniChar *ddeDataString; + TCHAR *ddeDataString; /* * The return handle has a two or four element list in it. The @@ -1818,13 +1847,17 @@ DdeObjCmd( * variable "errorInfo". */ - resultPtr = Tcl_NewObj(); length = DdeGetData(ddeData, NULL, 0, 0); - ddeDataString = ckalloc(length); + ddeDataString = (TCHAR *) Tcl_Alloc(length); DdeGetData(ddeData, (BYTE *) ddeDataString, (DWORD) length, 0); - length = (length >> 1) - 1; - resultPtr = Tcl_NewUnicodeObj(ddeDataString, length); - ckfree(ddeDataString); + if (length > sizeof(TCHAR)) { + length -= sizeof(TCHAR); + } + Tcl_WinTCharToUtf(ddeDataString, length, &dsBuf); + resultPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsBuf), + Tcl_DStringLength(&dsBuf)); + Tcl_DStringFree(&dsBuf); + Tcl_Free((char *) ddeDataString); if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) { Tcl_DecrRefCount(resultPtr); @@ -1874,6 +1907,9 @@ DdeObjCmd( if (hConv != NULL) { DdeDisconnect(hConv); } + Tcl_DStringFree(&itemBuf); + Tcl_DStringFree(&topicBuf); + Tcl_DStringFree(&serviceBuf); return result; } |
