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.
 
 
 
 
 
 

464 lines
11 KiB

#include "precomp.h"
#pragma hdrstop
EnableAssert
int fNoMessages;
int fInter;
int fWindowsQuery;
HWND QueryHWnd = NULL;
// initilize the query code
void
InitQuery(
FLAGS fFlags)
{
DWORD dwIn, dwOut;
fNoMessages = !!(fFlags & flagForce);
fWindowsQuery = !!(fFlags & flagWindowsQuery);
dwIn = GetFileType((HANDLE) _get_osfhandle(0));
dwOut = GetFileType((HANDLE) _get_osfhandle(2));
if (((dwIn == FILE_TYPE_CHAR || dwIn == FILE_TYPE_PIPE) &&
(dwOut == FILE_TYPE_CHAR || dwOut == FILE_TYPE_PIPE))
|| fWindowsQuery)
fInter = TRUE;
else
fInter = FALSE;
}
// return fTrue if we can talk to the user (unaffected by force flag)
F
FInteractive()
{
return fInter;
}
// return fTrue if it is possible to actually prompt the user
F
FCanPrompt()
{
return !fNoMessages && fInter;
}
// Return fTrue if -f flag or 'f' response given.
F
FForce()
{
return fNoMessages;
}
// Return fTrue if -w flag given.
F
FWindowsQuery()
{
return fWindowsQuery;
}
//VARARGS1
// return true if the we should prompt the user for some information. If we are
// not interactive but we can query (i.e. not -f), we print an error message.
//
// szcan == NULL
F
FCanQuery(
const char *sz,
...)
{
va_list ap;
if (fNoMessages)
return fTrue; // assume yes to all questions
else if (!fInter) {
if (sz) {
va_start(ap, sz);
VaError(sz, ap);
va_end(ap);
}
return fFalse;
} else
return fTrue;
}
// szQuery() returns a pointer to a static buffer at most 320 bytes in length.
// 320 is chosen because one log record must fit in 512 bytes.
static char szQueryRet[321];
// helper to center a window within its parent and set title: "SLM - function"
void
CenterWindow(
HWND hwndDlg
)
{
HWND hwndOwner;
RECT rc, rcDlg, rcOwner;
char szTitle[32] = "SLM";
// Get the owner window and dialog box rectangles.
if ((hwndOwner = GetParent(hwndDlg)) == NULL)
hwndOwner = GetDesktopWindow();
GetWindowRect(hwndOwner, &rcOwner);
GetWindowRect(hwndDlg, &rcDlg);
CopyRect(&rc, &rcOwner);
// Offset the owner and dialog box rectangles so that right and bottom
// values represent the width and height, and then offset the owner again
// to discard space taken up by the dialog box.
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
// The new position is the sum of half the remaining space and the owner's
// original position.
SetWindowPos(hwndDlg,
HWND_TOP,
rcOwner.left + (rc.right / 2),
rcOwner.top + (rc.bottom / 2),
0, 0, // ignores size arguments
SWP_NOSIZE);
if ((szOp != 0) && (_stricmp(szOp , "slm")!=0)) {
strcat(szTitle, " - ");
strcat(szTitle, szOp);
}
SetWindowText(hwndDlg, szTitle);
}
BOOL CALLBACK
QueryMsgBoxProc(
HWND hwndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
int cReply;
switch (message) {
case WM_INITDIALOG:
CenterWindow(hwndDlg); // center window and set title
// Set output text
if (lParam) {
SetDlgItemText(hwndDlg, IDC_MSG_TEXT, (LPCTSTR)lParam);
}
SetForegroundWindow(hwndDlg);
MessageBeep(MB_ICONEXCLAMATION);
return TRUE;
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
case IDYES:
cReply = 'y';
break;
case IDNO:
cReply = 'n';
break;
case IDFORCE:
cReply = 'f';
break;
case IDCANCEL:
cReply = IDCANCEL;
break;
default:
return FALSE;
};
EndDialog(hwndDlg, cReply);
return TRUE;
break;
default:
return FALSE; // let Windows handle it
};
}
BOOL CALLBACK
QueryEditBoxProc(
HWND hwndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
switch (message) {
case WM_INITDIALOG:
CenterWindow(hwndDlg); // center window and set title
// Set output text
if (lParam)
SetDlgItemText(hwndDlg, IDC_MSG_TEXT, (LPCTSTR)lParam);
SetDlgItemText(hwndDlg, IDC_EDIT_TEXT, "");
SetForegroundWindow(hwndDlg);
SetFocus(GetDlgItem(hwndDlg, IDC_EDIT_TEXT));
MessageBeep(MB_ICONQUESTION);
return TRUE;
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
GetDlgItemText(hwndDlg, IDC_EDIT_TEXT, szQueryRet, sizeof(szQueryRet)-1);
break;
case IDCANCEL:
szQueryRet[0] = 0;
break;
default:
return FALSE;
};
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
break;
default:
return FALSE; // let Windows handle it
};
}
int
QueryDialog (
const char * szPrompt,
char * szResponse,
int nMode
)
{
int retval;
HANDLE hInst = GetModuleHandle(NULL);
HWND hWnd = NULL;
char szModPrompt[512];
char * pszCurr = szModPrompt;
char c;
// hWnd = GetDesktopWindow();
// eliminate and CRLF from prompt
do {
c = *(szPrompt++);
if ((c != '\n') && (c != '\r'))
*(pszCurr++) = c;
else if ((pszCurr > szModPrompt) && (*(pszCurr-1) > ' '))
*(pszCurr++) = ' ';
} while (c != 0);
if (IsWindow(QueryHWnd))
hWnd = QueryHWnd;
if (nMode==QD_EDIT) {
retval = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SLM_EDITBOX), hWnd, QueryEditBoxProc, (LPARAM)szModPrompt);
} else {
int idd = (nMode==QD_BREAK) ? IDD_SLM_MSGBOX_BRK : IDD_SLM_MSGBOX;
retval = DialogBoxParam(hInst, MAKEINTRESOURCE(idd), hWnd, QueryMsgBoxProc, (LPARAM)szModPrompt);
}
if (retval == -1) {
Warn("Last Error = %d\n", GetLastError());
Warn("Could not open Dialog: hInst = %08x, hWnd = %08x, szModPrompt = \"%s\"\n", hInst, hWnd, szModPrompt);
Warn("DIALOG = %08x aka. %08x\n", IDD_SLM_MSGBOX, MAKEINTRESOURCE(IDD_SLM_MSGBOX));
return FALSE;
} else
if (retval == IDCANCEL) {
FakeCtrlC();
return FALSE;
} else
if (retval == IDOK) {
if (szResponse != szQueryRet)
strcpy(szResponse, szQueryRet);
} else {
// default: return val is y/n/f
*szResponse++ = (char) retval;
*szResponse = 0;
}
return TRUE;
}
//VARARGS1
// as the user a yes/no question; return fTrue for yes, fFalse for no
F
FQueryUser(
char *sz,
...
)
{
char szResp[257]; // tty buffer is usually only 256
va_list ap, apHold;
va_start(ap, sz);
if (fNoMessages) {
// pretend the user answered yes
if (fVerbose) {
VaPrErr(sz, ap);
va_end(ap);
PrErr("Yes\n");
}
return fTrue;
}
AssertF(fInter);
if (fWindowsQuery) {
char buf[512];
VaSzPrint(buf, sz, ap);
// display dialog box and translate response to y/n/f
QueryDialog(buf, szResp, QD_TEXT);
} else
{
do {
apHold = ap; // for portablity, can't assume unchanged
VaPrErr(sz, apHold);
*szResp = '\0'; // in case we do not read anything
CbReadMf(&mfStdin, szResp, 256);
} while (!FValidResp(szResp));
}
va_end(ap);
// 'f' means "answer yes to all future questions"
if (*szResp == 'f')
fNoMessages = fTrue;
return *szResp != 'n';
}
//VARARGS2
// the args can only refer to sz1
F
FQueryApp(
char *sz1,
char *sz2,
...
)
{
va_list ap;
F f;
va_start(ap, sz2);
f = VaFQueryApp(sz1, sz2, ap);
va_end(ap);
return f;
}
F
VaFQueryApp(
char *sz1,
char *sz2,
va_list ap)
{
char szT[cchMsgMax];
VaSzPrint(szT, sz1, ap);
if (!FCanQuery("%s\n", szT))
return fFalse;
return FQueryUser("%s; %s ? ", szT, sz2);
}
//VARARGS1
// returns 0 or answer from user; string was allocated dynamically; user
// may type \ at end of a line to indicate continuation.
char *
SzQuery(
char *sz,
...
)
{
char szResp[257]; // tty buffer is usually only 256
int cbResp; // size of individual response
int cbRet=sizeof(szQueryRet)-1; // amount of return buffer left
int fMore;
va_list ap;
if (fNoMessages)
return ""; // pretend the user did not give an answer
AssertF(fInter);
// clear previous value
*szQueryRet = '\0';
if (fWindowsQuery) {
char buf[512];
va_start(ap, sz);
VaSzPrint(buf, sz, ap);
va_end(ap);
// display dialog box and translate response to y/n/f
QueryDialog(buf, szQueryRet, QD_EDIT);
return szQueryRet;
}
// print prompt
va_start(ap, sz);
VaPrErr(sz, ap);
va_end(ap);
do {
// read one line
cbResp = CbReadMf(&mfStdin, (char far *)szResp, sizeof(szResp)-1);
// strip [cr]lf
if (cbResp > 0 && szResp[cbResp-1] == '\n')
cbResp--;
if (cbResp > 0 && szResp[cbResp-1] == '\r')
cbResp--;
// determine if we should read more (remove \ from end)
fMore = fFalse;
if (cbResp > 0 && szResp[cbResp-1] == '\\')
cbResp--, fMore = fTrue;
// bound response by room left and save
if (cbResp > cbRet)
cbResp = cbRet;
szResp[cbResp] = '\0';
strcat(szQueryRet, szResp);
cbRet -= cbResp;
} while (cbRet > 0 && fMore);
return szQueryRet;
}
F
FQContinue()
{
return FCanPrompt() ? FQueryUser("continue? ") : fTrue;
}
//----------------------------------------------------------------------------
// Name: FValidResp
// Purpose: Decide if the response given is valid
// Assumes:
// Returns: fTrue if "y", "n", "f", "yes", "no", or "force"; fFalse otherwise
//----------------------------------------------------------------------------
private F
FValidResp(
char *sz
)
{
char *pb;
if ((pb = strchr(sz, '\r')) != NULL)
*pb = '\0';
if ((pb = strchr(sz, '\n')) != NULL)
*pb = '\0';
_strlwr(sz);
return ((sz[1] == '\0' && (sz[0] == 'y' || sz[0] == 'n' || sz[0] == 'f')) ||
strcmp(sz, "yes") == 0 ||
strcmp(sz, "no") == 0 ||
strcmp(sz, "force") == 0);
}