📄 pgpsdkfrontendthread.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: PGPsdkFrontEndThread.c,v 1.28 2002/08/06 20:11:19 dallen Exp $
____________________________________________________________________________*/
#include <process.h>
#include "pgpRMWOLock.h"
#include "pgpErrors.h"
#include "pgpMem.h"
#include "pgpUtilities.h"
#include "pgpContext.h"
#include "pgpRPCMsg.h"
#include "pgpPassCach.h"
#define PASSPHRASETIME 10000
#define NHANDLES 2
static DWORD sThreadId = 0;
static HANDLE sThreadHandle = NULL;
static HANDLE sEventHandles[NHANDLES]; /* Indexed by PGPNotificationReason */
static void
sCleanupFrontEndThread (void)
{
int i;
for( i=0; i<NHANDLES; i++ )
CloseHandle (sEventHandles[i]);
}
static int __stdcall
sFrontEndThread(void *vptr)
{
MSG msg;
DWORD PGP_WM_SETTIMER = RegisterWindowMessage("PGP_WM_SETTIMER");
int i;
// create Event synchronization objects. We must use these
// instead of thread messages to allow notifications to cross
// sessions under Terminal Services
for( i=0; i<NHANDLES; i++ )
{
sEventHandles[i] = CreateEvent (NULL, FALSE, FALSE, NULL);
}
/*
* Force the system to create the Thread Message Queue.
*/
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
/*
* Pull messages off the Thread Message Queue.
*/
for (;;) {
// wait for either the Event object or an incoming message
DWORD dwReturn = MsgWaitForMultipleObjects (
NHANDLES, sEventHandles, FALSE,
INFINITE, QS_TIMER|QS_POSTMESSAGE);
if (dwReturn == WAIT_OBJECT_0 + kPGPNotification_KeyDBChanged)
{
// the event object was signaled from the backend.
DWORD dwEnd, dwWait;
dwWait = 1000;
dwEnd = GetTickCount() + dwWait;
while ((dwWait > 0) && (dwWait <= 1000))
{
WaitForSingleObject (
sEventHandles[kPGPNotification_KeyDBChanged], dwWait);
dwWait = dwEnd - GetTickCount();
}
pgpCallNotificationCallback ( kPGPNotification_KeyDBChanged, 0, 0 );
}
else if (dwReturn == WAIT_OBJECT_0 + kPGPNotification_PassphraseCacheChanged )
{
pgpCallNotificationCallback (
kPGPNotification_PassphraseCacheChanged, 0, 0 );
}
else
{
// otherwise we may have an incoming message. These
// messages work under Terminal Services because they
// always originate from the frontend.
// first make sure we have a message
if (PeekMessage (&msg, (HWND)0, 0, 0, PM_NOREMOVE))
{
// then actually get the message
DWORD n = GetMessage(&msg, (HWND)0, 0, 0);
if (n == -1)
{
// something is really wrong, exit the thread
sCleanupFrontEndThread ();
return 0;
}
switch(msg.message) {
case WM_QUIT:
// normal way to exit thread
sCleanupFrontEndThread ();
return 0;
case WM_TIMER:
// Timer enabled only when PGPsdkServ is absent.
{
PGPContextRef ctx;
ctx = NULL;
while( IsntNull( ctx = pgpContextNextContext( ctx ) ) )
{
pgpPassphraseCacheAddClient(ctx, (PGPConnectRef)0);
pgpExpirePassphraseCache(ctx);
}
}
break;
default:
if (msg.message == PGP_WM_SETTIMER)
SetTimer((HWND)0, 0, msg.lParam, NULL);
break;
}
}
}
}
}
void
pgpInitFrontEndThread(PGPBoolean ClientSidePwdCache)
{
DWORD n = 0;
sThreadHandle = (HANDLE)_beginthreadex(
NULL, 0, sFrontEndThread, NULL,0, &sThreadId);
// wait for thread to create Event objects
while ((n++ < 5) && (sEventHandles[NHANDLES-1] == NULL))
Sleep (200);
/*
* ClientSidePwdCache is TRUE only when we are not
* running the SDK Service.
*/
if (ClientSidePwdCache) {
pgpSDKFrontEndSetTimer();
}
}
void
pgpKillFrontEndThread()
{
DWORD n = 0;
// If thread doesn't exist, then we're already done.
if (sThreadId == 0)
return;
// PostThreadMessage could fail if the thread has not yet
// finished starting up. Thus, continue to try for a few
// seconds.
while ((n++ < 5) && !PostThreadMessage(sThreadId, WM_QUIT, 0, 0))
Sleep (1000);
// If we successfully posted WM_QUIT, then wait (a little
// while) for thread to die. Otherwise just bail out.
if (n < 5)
WaitForSingleObject(sThreadHandle, 5000);
sThreadId = 0;
sThreadHandle = NULL;
}
void
pgpSDKFrontEndSetTimer()
{
static DWORD PGP_WM_SETTIMER = 0;
if (PGP_WM_SETTIMER == 0)
PGP_WM_SETTIMER = RegisterWindowMessage("PGP_WM_SETTIMER");
PostThreadMessage(sThreadId, PGP_WM_SETTIMER, 0, PASSPHRASETIME);
}
PGPUInt32
pgpSDKGetFrontEndEventHandle( PGPUInt32 n)
{
pgpAssert( n < NHANDLES );
return (PGPUInt32)sEventHandles[n];
}
/*
* pgpNotifyClient -- called by the backend to notify FrontEndThreads
*/
void
pgpNotifyClient(PGPUInt32 connectref, PGPNotificationReason param )
{
HANDLE hEvent;
pgpAssert( param < NHANDLES );
if( connectref == 0 )
{
/* Running in local mode, call directly */
pgpCallNotificationCallback ( param, 0, 0 );
}
else
{
hEvent = (HANDLE)((struct pgpRPCconnection *)
connectref)->EventHandle[param];
if (hEvent)
SetEvent (hEvent);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -