Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

617 lines
16 KiB

/***************************************************************************/
/** Microsoft Windows **/
/** Copyright(c) Microsoft Corp., 1991-1994 **/
/***************************************************************************/
/****************************************************************************
ddecb.cpp DDE callback functions for BugBoard
Apr, 94 JimH
Also includes some routines to check whether netdde is available, to
create a netdde share, and some helper routines.
****************************************************************************/
#include "bugboard.h"
//#include <stdlib.h>
#include <time.h>
/****************************************************************************
DdeServerCallBack
****************************************************************************/
HDDEDATA CALLBACK DdeServerCallBack(
WORD wType, // transaction type
WORD wFmt, // clipboard format
HCONV hConv, // handle to conversation
HSZ hsz1, // string handles
HSZ hsz2,
HDDEDATA hData, // handle to a global memory object
DWORD dwData1, // transaction-specific data
DWORD dwData2)
{
DWORD re;
switch(wType)
{
// Server called PostAdvise
case XTYP_ADVREQ:
if (hsz2 == hszNewBug)
{
re = (DWORD) ddeServer->CreateDataHandle(pBugData, sizeof(BUGDATA),
hsz2);
if (re == 0L || re == 0){
//MessageBox(NULL, "Create Data Handle failed", "bugboard.exe error", MB_OK | MB_ICONSTOP);
return (HDDEDATA) NULL;
}
return (HDDEDATA) re;
}
else
return (HDDEDATA) NULL;
// Client has requested advise loop (hot link)
case XTYP_ADVSTART:
if (hsz2 == hszNewBug)
return (HDDEDATA) TRUE;
else
return (HDDEDATA) FALSE;
case XTYP_CONNECT:
if (hsz1 == (ddeServer->Topic()))
{
nConnections++;
SetServerText();
return (HDDEDATA) TRUE; // accept connection
}
else
return (HDDEDATA) FALSE;
case XTYP_CONNECT_CONFIRM:
return (HDDEDATA) TRUE;
case XTYP_DISCONNECT:
nConnections--;
SetServerText();
return (HDDEDATA) TRUE;
// client sending data to server
case XTYP_POKE:
if (hsz2 != hszNewBug){
return (HDDEDATA) DDE_FNOTPROCESSED;
}
// popup first so we can set change selection
if (bRestoreOnUpdate)
{
if (IsIconic(hMainWnd))
ShowWindow(hMainWnd, SW_RESTORE);
else
SetWindowPos(hMainWnd, HWND_TOP, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
// client is sending new bugboard
ddeServer->GetData(hData, (PBYTE)pBugData, sizeof(BUGDATA));
// change to Server's time for consistency
time(&(pBugData->aclock));
SendMessage(hMainWnd, WM_COMMAND, IDC_UPDATE, 0);
//
// post it for others
//
if ( !(ddeServer->PostAdvise(hsz2)) ){
return (HDDEDATA) DDE_FNOTPROCESSED;
}
if (bSoundOnUpdate)
MessageBeep(MB_ICONEXCLAMATION);
return (HDDEDATA) DDE_FACK;
// Client requests old bugboard data or old update time
case XTYP_REQUEST:
if (hsz2 == hszOldBug)
{
HDDEDATA hOldBug = ddeServer->CreateDataHandle(pBugData,
sizeof(BUGDATA), hsz2);
return hOldBug;
}
else if (hsz2 == hszPW)
{
HDDEDATA hPW = ddeServer->CreateDataHandle(szPassword,
lstrlen(szPassword)+1, hsz2);
return hPW;
}
else
{
return (HDDEDATA) NULL;
}
default:
return (HDDEDATA) NULL;
}
}
/****************************************************************************
DdeClientCallBack
****************************************************************************/
HDDEDATA CALLBACK DdeClientCallBack(
WORD wType, // transaction type
WORD wFmt, // clipboard format
HCONV hConv, // handle to conversation
HSZ hsz1, // string handles
HSZ hsz2,
HDDEDATA hData, // handle to a global memory object
DWORD dwData1, // transaction-specific data
DWORD dwData2)
{
UINT delay; // used for timer
switch(wType)
{
//case XTYP_CONNECT_CONFIRM:
// return (HDDEDATA) NULL;
// server has updated data for us
case XTYP_ADVDATA:
ddeClient->GetData(hData, (PBYTE)pBugData, sizeof(BUGDATA));
PostMessage(hMainWnd, WM_COMMAND, IDC_UPDATE, 0);
if (bRestoreOnUpdate)
{
if (IsIconic(hMainWnd))
ShowWindow(hMainWnd, SW_RESTORE);
else
SetWindowPos(hMainWnd, HWND_TOP, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
}
if (bSoundOnUpdate)
MessageBeep(MB_ICONEXCLAMATION);
return (HDDEDATA) DDE_FACK;
// server has gone bye-bye
case XTYP_DISCONNECT:
/*
CONVINFO *pConvInfo;
char szStatus[20];
pConvInfo = (CONVINFO*) malloc(sizeof(CONVINFO));
pConvInfo->cb = sizeof(CONVINFO);
DdeQueryConvInfo(hConv, QID_SYNC, pConvInfo);
itoa(pConvInfo->wConvst, szStatus, 10);
strcat(szStatus, " - disconnect status");
free(pConvInfo);
MessageBox(NULL, szStatus, "bugboard.exe error", MB_OK | MB_ICONSTOP);
*/
bConnected = FALSE;
EnableWindow(GetDlgItem(hMainWnd, IDC_EDIT), FALSE);
SetClientText();
srand((unsigned)time(NULL));
delay = (UINT)65535 - ((UINT)rand() % (UINT)20000);
if (SetTimer(hMainWnd, TIMER_RECONNECT, delay, NULL) == 0)
{
SetFocus(GetDlgItem(hMainWnd, IDC_QUIT));
PostMessage(hMainWnd, WM_CLOSE, 0, 0);
}
return (HDDEDATA) NULL;
// asynch call for old bugboard data has returned
case XTYP_XACT_COMPLETE:
if (hsz2 == hszOldBug)
{
bConnected = TRUE;
//bAuthenticated = FALSE;
// don't mess with password on NT since it allows
// for a security descriptor on the bugboard$ share
bAuthenticated = TRUE;
EnableWindow(GetDlgItem(hMainWnd, IDC_EDIT), TRUE);
SetClientText();
// copy the data associated with the data handle
ddeClient->GetData(hData, (PBYTE)pBugData, sizeof(BUGDATA));
PostMessage(hMainWnd, WM_COMMAND, IDC_UPDATE, 0);
}
// don't bother with password stuff
/*
else if (hsz2 == hszPW)
{
char localbuf[PWLEN];
ddeClient->GetData(hData, (PBYTE)localbuf, PWLEN);
Code(localbuf);
if (0 == lstrcmpi(localbuf, szPassword))
{
bAuthenticated = TRUE;
PostMessage(hMainWnd, WM_COMMAND, IDC_EDIT, 0);
}
}
*/
return (HDDEDATA) NULL;
default:
return (HDDEDATA) NULL;
}
}
/****************************************************************************
CheckNddeShare
Check that NDDE share exists, and add it if not.
****************************************************************************/
// Typedefs for NDdeShareGetInfo (SGIPROC) and NDdeShareAdd (SAPROC)
typedef UINT (WINAPI *SGIPROC)(LPSTR, LPSTR, UINT, LPBYTE, DWORD, LPDWORD, LPWORD);
typedef UINT (WINAPI *SAPROC)(LPSTR, UINT, PSECURITY_DESCRIPTOR, LPBYTE, DWORD );
typedef UINT (WINAPI *SGSPROC)(UINT, LPSTR, DWORD);
typedef UINT (WINAPI *SSTPROC)(LPSTR, LPSTR, DWORD);
void CheckNddeShare()
{
DWORD dwAvail;
WORD wItems=0;
BYTE buffer[200];
//LPBYTE buffer;
CHAR szres[255];
DWORD err=0;
char szerror[16];
char *sztopiclist = {"bugboard|bugboard\0bugboard|bugboard\0bugboard|bugboard\0\0"};
//FARPROC fpNDdeShareGetInfo;
PSID pworldsid;
PACL pacl;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority = SECURITY_WORLD_SID_AUTHORITY;
SECURITY_DESCRIPTOR sd;
//HINSTANCE hinstNDDEAPI=NULL;
SetErrorMode(SEM_FAILCRITICALERRORS); //_NOOPENFILEERRORBOX);
HINSTANCE hinstNDDEAPI = LoadLibrary("NDDEAPI.DLL");
if (NULL == hinstNDDEAPI) // <= HINSTANCE_ERROR)
{
MessageBox(NULL, "NDDEAPI.DLL not found in path", "bugboard.exe", MB_OK | MB_ICONSTOP);
return;
}
SGIPROC fpNDdeShareGetInfo = (SGIPROC) GetProcAddress(hinstNDDEAPI, "NDdeShareGetInfoA");
if (fpNDdeShareGetInfo == NULL)
{
FreeLibrary(hinstNDDEAPI);
return;
}
UINT ret = (*fpNDdeShareGetInfo)(NULL, "bugboard$", 2,
buffer, sizeof(buffer), &dwAvail, &wItems);
if (ret != NDDE_SHARE_NOT_EXIST) {
return;
}
NDDESHAREINFO *pnddeInfo = (NDDESHAREINFO *)buffer;
SAPROC lpfnNDdeShareAdd =
(SAPROC) GetProcAddress(hinstNDDEAPI, "NDdeShareAddA");
if (lpfnNDdeShareAdd == NULL)
{
FreeLibrary(hinstNDDEAPI);
return;
}
/* this is all different for win32 (NT)
lstrcpy(pnddeInfo->szShareName, "bugboard$");
pnddeInfo->lpszTargetApp = "bugboard";
pnddeInfo->lpszTargetTopic = "bugboard";
pnddeInfo->lpbPassword1 = (LPBYTE) "";
pnddeInfo->cbPassword1 = 0;
pnddeInfo->dwPermissions1 = 15;
pnddeInfo->lpbPassword2 = (LPBYTE) "";
pnddeInfo->cbPassword2 = 0;
pnddeInfo->dwPermissions2 = 0;
pnddeInfo->lpszItem = "";
pnddeInfo->cAddItems = 0;
pnddeInfo->lpNDdeShareItemInfo = NULL;
*/
// current structure
pnddeInfo->lRevision = 1L;
pnddeInfo->lpszShareName = _strdup("bugboard$");
pnddeInfo->lShareType = SHARE_TYPE_NEW | SHARE_TYPE_OLD | SHARE_TYPE_STATIC;
pnddeInfo->lpszAppTopicList = (LPTSTR)sztopiclist;
pnddeInfo->fSharedFlag = 1;
pnddeInfo->fService = 0;
pnddeInfo->fStartAppFlag = 0;
pnddeInfo->nCmdShow = SW_SHOWMAXIMIZED;
pnddeInfo->qModifyId[0] = 0;
pnddeInfo->qModifyId[1] = 0;
pnddeInfo->cNumItems = 0;
pnddeInfo->lpszItemList = "\0";
if (!AllocateAndInitializeSid( &IdentifierAuthority,
1,
SECURITY_WORLD_RID,
0,0,0,0,0,0,0,
&pworldsid))
{
FreeLibrary(hinstNDDEAPI);
return;
}
pacl = (ACL*)malloc(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pworldsid) - sizeof(DWORD) ) ;
InitializeAcl(pacl,
sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pworldsid) - sizeof(DWORD),
ACL_REVISION);
if (!IsValidAcl) {
MessageBox(NULL, "ACL not valid", "bugboard.exe", MB_OK | MB_ICONSTOP);
FreeLibrary(hinstNDDEAPI);
return;
}
if (!AddAccessAllowedAce(pacl,
ACL_REVISION,
STANDARD_RIGHTS_ALL | MAXIMUM_ALLOWED | GENERIC_ALL | ACCESS_SYSTEM_SECURITY,
pworldsid)) {
MessageBox(NULL, "Add ACE failed", "bugboard.exe", MB_OK | MB_ICONSTOP);
FreeLibrary(hinstNDDEAPI);
return;
}
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
MessageBox(NULL, "Init sd failed", "bugboard.exe", MB_OK | MB_ICONSTOP);
FreeLibrary(hinstNDDEAPI);
return;
}
if (!SetSecurityDescriptorOwner(&sd, NULL, FALSE))
{
FreeLibrary(hinstNDDEAPI);
return;
}
if (!SetSecurityDescriptorGroup(&sd, NULL, FALSE))
{
FreeLibrary(hinstNDDEAPI);
return;
}
if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE))
{
FreeLibrary(hinstNDDEAPI);
return;
}
if (!IsValidSecurityDescriptor(&sd))
{
MessageBox(NULL, "Invalid sd", "bugboard.exe", MB_OK | MB_ICONSTOP);
FreeLibrary(hinstNDDEAPI);
return;
}
ret = (*lpfnNDdeShareAdd)(NULL, 2, &sd, buffer, sizeof(buffer));
if (ret != NDDE_NO_ERROR && ret != NDDE_SHARE_ALREADY_EXIST) {
SGSPROC lpfnNDdeGetErrorString =
(SGSPROC) GetProcAddress(hinstNDDEAPI, "NDdeGetErrorStringA");
if (lpfnNDdeGetErrorString == NULL)
{
FreeLibrary(hinstNDDEAPI);
return;
}
(*lpfnNDdeGetErrorString)(ret, (LPSTR)szres, 255);
MessageBox(NULL, (LPSTR)szres, "ERROR bugboard.exe", MB_OK | MB_ICONSTOP);
FreeLibrary(hinstNDDEAPI);
return;
}
SSTPROC lpfnNDdeSetTrustedShare =
(SSTPROC) GetProcAddress(hinstNDDEAPI, "NDdeSetTrustedShareA");
if (NDDE_NO_ERROR != ((*lpfnNDdeSetTrustedShare)(NULL, pnddeInfo->lpszShareName, NDDE_TRUST_SHARE_INIT)))
{
MessageBox(NULL, "Unable to set trusted share", "ERROR bugboard.exe", MB_OK | MB_ICONSTOP);
}
FreeLibrary(hinstNDDEAPI);
}
/****************************************************************************
IsNddeActive()
****************************************************************************/
typedef int (CALLBACK* FPROC)(); // a FARPROC that returns int
BOOL IsNddeActive()
{
// see if netdde is an active process
FARPROC fpNDDEGetWindow;
static BOOL bNetDdeActive = -1; // starts as unknown;
if (bNetDdeActive != -1)
return bNetDdeActive;
bNetDdeActive = TRUE; // assume true, then check
SetErrorMode(SEM_NOOPENFILEERRORBOX);
HINSTANCE hinstNDDEAPI = LoadLibrary("NDDEAPI.DLL");
if (NULL == hinstNDDEAPI) // <= HINSTANCE_ERROR)
{
MessageBox(NULL, "NDDEAPI.DLL not found in path", "bugboard.exe", MB_OK | MB_ICONSTOP);
bNetDdeActive = FALSE;
return bNetDdeActive;
}
WinExec("net start NETDDE", SW_HIDE);
// if ((*fpNDDEGetWindow)() == NULL)
// bNetDdeActive = FALSE;
//}
FreeLibrary(hinstNDDEAPI);
return bNetDdeActive;
}
/****************************************************************************
SetServerText()
SetClientText()
Update titlebars
Server shows number of connections
Client shows server name
****************************************************************************/
void SetServerText()
{
char localbuf[80];
wsprintf(localbuf, RS(IDS_BBSERV), nConnections);
SetWindowText(hMainWnd, localbuf);
}
void SetClientText()
{
char localbuf[80];
wsprintf(localbuf, RS(bConnected ? IDS_BBON : IDS_BBOFF),
(LPSTR)szServerName);
SetWindowText(hMainWnd, localbuf);
}
/****************************************************************************
Code(char *pstring)
encodes and decodes string using simple algorithm
****************************************************************************/
void Code(char far *pstring)
{
while (*pstring)
{
*pstring = ~(*pstring);
pstring++;
}
}