mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-20 13:48:38 -05:00

callback function; it may return 0 to indicate that it doesn't have an answer _yet_, in which case it will call the callback later on when it does, or it may return 1 to indicate that it's got an answer right now. The Windows agent_query() implementation is functionally unchanged and still synchronous, but the Unix one is async (since that one was really easy to do via uxsel). ssh.c copes cheerfully with either return value, so other ports are at liberty to be sync or async as they choose. [originally from svn r3153]
98 lines
2.1 KiB
C
98 lines
2.1 KiB
C
/*
|
|
* Pageant client code.
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "puttymem.h"
|
|
|
|
#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
|
|
#define AGENT_MAX_MSGLEN 8192
|
|
|
|
#ifdef TESTMODE
|
|
#define debug(x) (printf x)
|
|
#else
|
|
#define debug(x)
|
|
#endif
|
|
|
|
#define GET_32BIT(cp) \
|
|
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
|
|
((unsigned long)(unsigned char)(cp)[1] << 16) | \
|
|
((unsigned long)(unsigned char)(cp)[2] << 8) | \
|
|
((unsigned long)(unsigned char)(cp)[3]))
|
|
|
|
int agent_exists(void)
|
|
{
|
|
HWND hwnd;
|
|
hwnd = FindWindow("Pageant", "Pageant");
|
|
if (!hwnd)
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
int agent_query(void *in, int inlen, void **out, int *outlen,
|
|
void (*callback)(void *, void *, int), void *callback_ctx)
|
|
{
|
|
HWND hwnd;
|
|
char mapname[64];
|
|
HANDLE filemap;
|
|
unsigned char *p, *ret;
|
|
int id, retlen;
|
|
COPYDATASTRUCT cds;
|
|
|
|
*out = NULL;
|
|
*outlen = 0;
|
|
|
|
hwnd = FindWindow("Pageant", "Pageant");
|
|
debug(("hwnd is %p\n", hwnd));
|
|
if (!hwnd)
|
|
return 1; /* *out == NULL, so failure */
|
|
sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
|
|
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
|
0, AGENT_MAX_MSGLEN, mapname);
|
|
if (!filemap)
|
|
return 1; /* *out == NULL, so failure */
|
|
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
|
|
memcpy(p, in, inlen);
|
|
cds.dwData = AGENT_COPYDATA_ID;
|
|
cds.cbData = 1 + strlen(mapname);
|
|
cds.lpData = mapname;
|
|
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) & cds);
|
|
debug(("return is %d\n", id));
|
|
if (id > 0) {
|
|
retlen = 4 + GET_32BIT(p);
|
|
debug(("len is %d\n", retlen));
|
|
ret = snewn(retlen, unsigned char);
|
|
if (ret) {
|
|
memcpy(ret, p, retlen);
|
|
*out = ret;
|
|
*outlen = retlen;
|
|
}
|
|
}
|
|
UnmapViewOfFile(p);
|
|
CloseHandle(filemap);
|
|
|
|
return 1;
|
|
}
|
|
|
|
#ifdef TESTMODE
|
|
|
|
int main(void)
|
|
{
|
|
void *msg;
|
|
int len;
|
|
int i;
|
|
|
|
agent_query("\0\0\0\1\1", 5, &msg, &len);
|
|
debug(("%d:", len));
|
|
for (i = 0; i < len; i++)
|
|
debug((" %02x", ((unsigned char *) msg)[i]));
|
|
debug(("\n"));
|
|
return 0;
|
|
}
|
|
|
|
#endif
|