static int unify_hsz(DWORD ddeInst, term_t term, HSZ hsz) { wchar_t buf[FASTBUFSIZE]; int len; if ( !(len=DdeQueryStringW(ddeInst, hsz, buf, sizeof(buf)/sizeof(wchar_t)-1, CP_WINUNICODE)) ) { dde_warning("string handle"); return NULL_ATOM; } if ( len == sizeof(buf)/sizeof(wchar_t)-1 ) { if ( (len=DdeQueryStringW(ddeInst, hsz, NULL, 0, CP_WINUNICODE)) > 0 ) { wchar_t *b2; int rc; if ( !(b2 = malloc((len+1)*sizeof(wchar_t))) ) return PL_no_memory(); DdeQueryStringW(ddeInst, hsz, b2, len+1, CP_WINUNICODE); rc = PL_unify_wchars(term, PL_ATOM, len, b2); free(b2); return rc; } dde_warning("string handle"); } return PL_unify_wchars(term, PL_ATOM, len, buf); }
static void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService) { WCHAR szTopic[MAX_PATH]; WCHAR szService[MAX_PATH]; DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE); TRACE("Dde_OnConnectConfirm: hconv=%p, topic=%S, service=%S\n", hconv, szTopic, szService); }
static HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic, HSZ hszItem) { WCHAR szTopic[MAX_PATH]; WCHAR szItem[MAX_PATH]; DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); DdeQueryStringW(dwDDEInst, hszItem, szItem, _countof(szItem), CP_WINUNICODE); TRACE("Dde_OnRequest: uFmt=%d, hconv=%p, topic=%S, item=%S\n", hconv, szTopic, szItem); return NULL; }
static BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService) { WCHAR szTopic[MAX_PATH]; WCHAR szService[MAX_PATH]; DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); DdeQueryStringW(dwDDEInst, hszService, szService, _countof(szService), CP_WINUNICODE); TRACE("Dde_OnWildConnect: topic=%S, service=%S\n", szTopic, szService); return FALSE; }
static const char *debugstr_hsz( HSZ hsz ) { WCHAR buffer[256]; if (!DdeQueryStringW( dwDDEInst, hsz, buffer, sizeof(buffer)/sizeof(WCHAR), CP_WINUNICODE )) return "<unknown>"; return debugstr_w( buffer ); }
/* Dde callback, save the execute or request string for processing */ static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG_PTR dwData1, ULONG_PTR dwData2) { DWORD size = 0, ret = 0; WINE_TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); switch (uType) { case XTYP_CONNECT: if (!DdeCmpStringHandles(hsz1, hszTopic)) return (HDDEDATA)TRUE; return (HDDEDATA)FALSE; case XTYP_EXECUTE: if (!(size = DdeGetData(hData, NULL, 0, 0))) WINE_ERR("DdeGetData returned zero size of execute string\n"); else if (!(ddeString = HeapAlloc(GetProcessHeap(), 0, size))) WINE_ERR("Out of memory\n"); else if (DdeGetData(hData, (LPBYTE)ddeString, size, 0) != size) WINE_WARN("DdeGetData did not return %d bytes\n", size); DdeFreeDataHandle(hData); return (HDDEDATA)DDE_FACK; case XTYP_REQUEST: ret = -3; /* error */ if (!(size = DdeQueryStringW(ddeInst, hsz2, NULL, 0, CP_WINUNICODE))) WINE_ERR("DdeQueryString returned zero size of request string\n"); else if (!(ddeString = HeapAlloc(GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR)))) WINE_ERR("Out of memory\n"); else if (DdeQueryStringW(ddeInst, hsz2, ddeString, size + 1, CP_WINUNICODE) != size) WINE_WARN("DdeQueryString did not return %d characters\n", size); else ret = -2; /* acknowledgment */ return DdeCreateDataHandle(ddeInst, (LPBYTE)&ret, sizeof(ret), 0, hszReturn, CF_TEXT, 0); default: return NULL; } }
static DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata) { WCHAR szTopic[MAX_PATH]; WCHAR szCommand[MAX_PATH]; WCHAR *pszCommand; DdeQueryStringW(dwDDEInst, hszTopic, szTopic, _countof(szTopic), CP_WINUNICODE); pszCommand = (WCHAR*) DdeAccessData(hdata, NULL); if (!pszCommand) return DDE_FNOTPROCESSED; StringCchCopyW(szCommand, _countof(szCommand), pszCommand); DdeUnaccessData(hdata); TRACE("Dde_OnExecute: hconv=%p, topic=%S, command=%S\n", hconv, szTopic, pszCommand); /* [ViewFolder("%l", %I, %S)] -- Open a folder in standard mode [ExploreFolder("%l", %I, %S)] -- Open a folder in "explore" mode (file tree is shown to the left by default) [FindFolder("%l", %I)] -- Open a folder in "find" mode (search panel is shown to the left by default) [ShellFile("%1","%1",%S)] -- Execute the contents of the specified .SCF file Approximate grammar (Upper names define rules, <lower> names define terminals, single-quotes are literals): Rules Command = ('[' Function ']') | Function Function = <identifier> '(' Parameters ')' Parameters = (<quoted-string> (',' <idlist> (',' <number>)?)?)? Terminals <identifier> = [a-zA-Z]+ <quoted-string> = \"([^\"]|\\.)\" <idlist> = \:[0-9]+\:[0-9]+ <number> = [0-9]+ */ WCHAR Command[MAX_PATH] = L""; WCHAR Path[MAX_PATH] = L""; LPITEMIDLIST IdList = NULL; INT UnknownParameter = 0; // Simplified parsing (assumes the command will not be TOO broken): PWSTR cmd = szCommand; // 1. if starts with [, skip first char if (*cmd == L'[') cmd++; if (*cmd == L']') { ERR("Empty command. Nothing to run.\n"); return DDE_FNOTPROCESSED; } // Read until first (, and take text before ( as command name { PWSTR cmdEnd = StrChrW(cmd, L'('); if (!cmdEnd) { ERR("Could not find '('. Invalid command.\n"); return DDE_FNOTPROCESSED; } *cmdEnd = 0; StringCchCopy(Command, _countof(Command), cmd); cmd = cmdEnd + 1; } // Read first param after (, expecting quoted string if (*cmd != L')') { // Copy unescaped string PWSTR dst = Path; BOOL isQuote = FALSE; PWSTR arg = cmd; while (*arg && (isQuote || *arg != L',')) { if (*arg == L'"') { isQuote = !isQuote; if (isQuote && arg != cmd) // do not copy the " at the beginning of the string { *(dst++) = L'"'; } } else { *(dst++) = *arg; } arg++; } cmd = arg + 1; while (*cmd == L' ') cmd++; } // Read second param, expecting an idlist in shared memory if (*cmd != L')') { if (*cmd != ':') { ERR("Expected ':'. Invalid command.\n"); return DDE_FNOTPROCESSED; } PWSTR idlistEnd = StrChrW(cmd, L','); if (!idlistEnd) idlistEnd = StrChrW(cmd, L')'); if (!idlistEnd) { ERR("Expected ',' or ')'. Invalid command.\n"); return DDE_FNOTPROCESSED; } IdList = _ILReadFromSharedMemory(cmd); cmd = idlistEnd + 1; } // Read third param, expecting an integer if (*cmd != L')') { UnknownParameter = StrToIntW(cmd); } TRACE("Parse end: cmd=%S, S=%d, pidl=%p, path=%S\n", Command, UnknownParameter, IdList, Path); // Find handler in list for (int i = 0; i < HandlerListLength; i++) { DDECommandHandler & handler = HandlerList[i]; if (StrCmpW(handler.Command, Command) == 0) { return handler.Handler(Command, Path, IdList, UnknownParameter); } } // No handler found ERR("Unknown command %S\n", Command); return DDE_FNOTPROCESSED; }