You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
4.6 KiB
182 lines
4.6 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: ddemlsvr.C
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* DDE Manager main module - Contains all server side ddeml functions.
|
|
*
|
|
* 27-Aug-1991 Sanford Staab Created
|
|
* 21-Jan-1992 IanJa ANSI/Unicode neutralized
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
// globals
|
|
|
|
PSVR_INSTANCE_INFO psiiList;
|
|
|
|
DWORD xxxCsDdeInitialize(
|
|
PHANDLE phInst,
|
|
HWND *phwndEvent,
|
|
LPDWORD pMonitorFlags,
|
|
DWORD afCmd,
|
|
PVOID pcii)
|
|
{
|
|
PSVR_INSTANCE_INFO psii;
|
|
PTHREADINFO ptiCurrent = PtiCurrent();
|
|
|
|
CheckCritIn();
|
|
|
|
psii = (PSVR_INSTANCE_INFO)HMAllocObject(PtiCurrent(), NULL,
|
|
TYPE_DDEACCESS, sizeof(SVR_INSTANCE_INFO));
|
|
if (psii == NULL) {
|
|
return DMLERR_SYS_ERROR;
|
|
}
|
|
|
|
/*
|
|
* We have to tell CreateWindow that window is not created for the same
|
|
* module has the app, (CW_FLAGS_DIFFHMOD), so CreateWindow doesn't
|
|
* assign a hotkey to this window. Other window are done in the
|
|
* client-server thunk
|
|
*/
|
|
Lock(&(psii->spwndEvent), xxxNVCreateWindowEx(
|
|
0,
|
|
(PLARGE_STRING)gpsi->atomSysClass[ICLS_DDEMLEVENT],
|
|
NULL,
|
|
WS_POPUP | WS_CHILD,
|
|
0, 0, 0, 0,
|
|
(PWND)NULL,
|
|
(PMENU)NULL,
|
|
hModuleWin,
|
|
NULL,
|
|
CW_FLAGS_DIFFHMOD | VER31));
|
|
|
|
if (psii->spwndEvent == NULL) {
|
|
HMFreeObject((PVOID)psii);
|
|
return DMLERR_SYS_ERROR;
|
|
}
|
|
/*
|
|
* This GWL offset does NOT leave the critical section!
|
|
*/
|
|
xxxSetWindowLongPtr(psii->spwndEvent, GWLP_PSII, (LONG_PTR)PtoH(psii), FALSE);
|
|
psii->afCmd = 0;
|
|
psii->pcii = pcii;
|
|
//
|
|
// Link into global list
|
|
//
|
|
psii->next = psiiList;
|
|
psiiList = psii;
|
|
|
|
//
|
|
// Link into per-process list
|
|
//
|
|
psii->nextInThisThread = ptiCurrent->psiiList;
|
|
ptiCurrent->psiiList = psii;
|
|
|
|
*phInst = PtoH(psii);
|
|
*phwndEvent = PtoH(psii->spwndEvent);
|
|
xxxChangeMonitorFlags(psii, afCmd); // sets psii->afCmd;
|
|
*pMonitorFlags = MonitorFlags;
|
|
return DMLERR_NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DWORD _CsUpdateInstance(
|
|
HANDLE hInst,
|
|
LPDWORD pMonitorFlags,
|
|
DWORD afCmd)
|
|
{
|
|
PSVR_INSTANCE_INFO psii;
|
|
|
|
CheckCritIn();
|
|
|
|
psii = (PSVR_INSTANCE_INFO)HMValidateHandleNoRip(hInst, TYPE_DDEACCESS);
|
|
if (psii == NULL) {
|
|
return DMLERR_INVALIDPARAMETER;
|
|
}
|
|
xxxChangeMonitorFlags(psii, afCmd);
|
|
*pMonitorFlags = MonitorFlags;
|
|
return DMLERR_NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL _CsDdeUninitialize(
|
|
HANDLE hInst)
|
|
{
|
|
PSVR_INSTANCE_INFO psii;
|
|
|
|
CheckCritIn();
|
|
|
|
psii = HMValidateHandleNoRip(hInst, TYPE_DDEACCESS);
|
|
if (psii == NULL) {
|
|
return TRUE;
|
|
}
|
|
|
|
xxxDestroyThreadDDEObject(PtiCurrent(), psii);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID xxxDestroyThreadDDEObject(
|
|
PTHREADINFO pti,
|
|
PSVR_INSTANCE_INFO psii)
|
|
{
|
|
PSVR_INSTANCE_INFO psiiT;
|
|
|
|
CheckCritIn();
|
|
|
|
if (HMIsMarkDestroy(psii)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Unlink psii from the global list.
|
|
//
|
|
if (psii == psiiList) {
|
|
psiiList = psii->next;
|
|
} else {
|
|
for (psiiT = psiiList; psiiT->next != psii; psiiT = psiiT->next) {
|
|
UserAssert(psiiT->next != NULL);
|
|
}
|
|
psiiT->next = psii->next;
|
|
}
|
|
// psii->next = NULL;
|
|
|
|
//
|
|
// Unlink psii from the per-process list.
|
|
//
|
|
if (psii == pti->psiiList) {
|
|
pti->psiiList = psii->nextInThisThread;
|
|
} else {
|
|
for (psiiT = pti->psiiList; psiiT->nextInThisThread != psii; psiiT = psiiT->nextInThisThread) {
|
|
UserAssert(psiiT->nextInThisThread != NULL);
|
|
}
|
|
psiiT->nextInThisThread = psii->nextInThisThread;
|
|
}
|
|
// psii->nextInThisThread = NULL;
|
|
|
|
if (HMMarkObjectDestroy(psii)) {
|
|
PWND pwnd = psii->spwndEvent;
|
|
/*
|
|
* We already removed psii from the linked list. This means that it
|
|
* will not get another chance to be cleaned up in
|
|
* xxxDestroyThreadInfo(), Since xxxDestroyWindow might leave
|
|
* the critical section the cleanup needs to be done in the below
|
|
* sequence else we will leak pssi and pwnd might be locked for good.
|
|
* [msadek - 03/12/2002]
|
|
*/
|
|
if (Unlock(&(psii->spwndEvent))) {
|
|
HMFreeObject(psii);
|
|
xxxDestroyWindow(pwnd);
|
|
} else {
|
|
HMFreeObject(psii);
|
|
}
|
|
}
|
|
}
|