hd->last_was_bad = prev_was_bad? 1: 0; hd->use_as_cb = 1; if (hd->flags & 0x01) rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_DEC, GetDesktopWindow (), decrypt_key_dlg_proc, (LPARAM)hd); else rc = DialogBoxParam (glob_hinst, (LPCTSTR)IDD_DEC_EXT, GetDesktopWindow (), decrypt_key_ext_dlg_proc, (LPARAM)hd); if (rc <= 0) { char buf[256];  FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof (buf)-1, NULL);  log_debug ("passphrase_callback_box: dialog failed rc=%d (%s)\n", rc, buf);
1. Standard passphrase requested: "<long main keyid> <long keyid> <keytype> <keylength>" 2. Passphrase for symmetric key requested: "<cipher_algo> <s2k_mode> <s2k_hash>" 3. PIN for a card requested. "<card_type> <chvno>"  For caching we need to use the long keyid from case 1; the main keyid can't be used because a key may have different passphrases on the subkeys.  Caching for symmetrical keys is not possible becuase there is no information on what key(i.e. passphrase) to use.  Caching of of PINs is not yet possible because we don't have information on the card's serial number yet; that must be solved by gpgme.  To detect case 1 we simply check whether the first token consists in its entire of 16 hex digits. */ const char *s; int i;  for (s=pass_info, i=0; *s && strchr (allhexdigits, *s) ; s++, i++) ; if (i == 16) { while (*s == ' ') s++; for (i=0; *s && strchr (allhexdigits, *s) && i < 16; s++, i++) keyidstr[i] = *s; keyidstr[i] = 0; if (*s) s++; if (i != 16 || !strchr (allhexdigits, *s)) { log_debug ("%s: oops: does not look like pass_info\n", __func__); *keyidstr = 0; }
passphrase_callback_box (void *opaque, const char *uid_hint, 			 const char *pass_info,			 int prev_was_bad, int fd){    struct decrypt_key_s *hd = (struct decrypt_key_s *)opaque;    DWORD nwritten = 0;    log_debug ("passphrase_callback_box: enter (uh=`%s',pi=`%s')\n",                uid_hint?uid_hint:"(null)", pass_info?pass_info:"(null)");    if (hd->opts & OPT_FLAG_CANCEL) {	WriteFile ((HANDLE)fd, "\n", 1, &nwritten, NULL);	CloseHandle ((HANDLE)fd);        log_debug ("passphrase_callback_box: leave (due to cancel flag)\n");	return -1;    }    if (prev_was_bad) {        log_debug ("passphrase_callback_box: last passphrase was bad\n");	xfree (hd->pass);	hd->pass = NULL;    }    if (hd && uid_hint && !hd->pass) {	const char * s = uid_hint;	size_t i=0;        int rc;		while (s && *s != ' ')	    hd->keyid[i++] = *s++;	hd->keyid[i] = '\0'; s++;	if (hd->user_id) {	    xfree (hd->user_id);	    hd->user_id = NULL;	}	hd->user_id = (char *)xcalloc (1, strlen (s) + 2);	strcpy (hd->user_id, s);	hd->last_was_bad = prev_was_bad? 1: 0;	hd->use_as_cb = 1;	if (hd->flags & 0x01)	    rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_DEC, GetDesktopWindow (),			    decrypt_key_dlg_proc, (LPARAM)hd);	else	    rc = DialogBoxParam (glob_hinst, (LPCTSTR)IDD_DEC_EXT, GetDesktopWindow (),			    decrypt_key_ext_dlg_proc, 			    (LPARAM)hd);        if (rc <= 0) {            char buf[256];                FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError (),                            MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),                            buf, sizeof (buf)-1, NULL);                        log_debug ("passphrase_callback_box: dialog failed rc=%d (%s)\n",                       rc, buf);        }    }    else         log_debug ("passphrase_callback_box: hd=%p hd->pass=`%s'\n",                   hd, hd && hd->pass? hd->pass: "(null)");            if (hd->pass != NULL) {        log_debug ("passphrase_callback_box: sending passphrase ...\n");	WriteFile ((HANDLE)fd, hd->pass, strlen (hd->pass), &nwritten, NULL);	WriteFile ((HANDLE)fd, "\n", 1, &nwritten, NULL);    }    else	WriteFile((HANDLE)fd, "\n", 1, &nwritten, NULL);    log_debug ("passphrase_callback_box: leave\n");    return 0;}