#include "SysMain.h"
#include "_Constants.h"
#include "_GlobalVars.h"
#include "_Utils.h"
#include "resource.h"
// Involved workstation name.
TCHAR lpszWkstaName[MAX_COMPUTERNAME_LENGTH + 1];
TCHAR lpszMessage[1024];
// Shutdown thread informations.
extern LPSHUTDOWNSTRUCT lpSS;
// Dialog procedure.
BOOL CALLBACK
Shutdown_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bResult = FALSE;
switch(uMsg)
{
case WM_INITDIALOG:
Shutdown_OnInitDialog(hWnd, wParam, lParam, &bResult);
break;
case WM_CLOSE:
Shutdown_OnClose(hWnd, wParam, lParam, &bResult);
EndDialog(hWnd, IDCANCEL);
DestroyWindow(hWnd);
break;
case WM_COMMAND:
Shutdown_OnCommand(hWnd, wParam, lParam, &bResult);
break;
case WM_NOTIFY:
Shutdown_OnNotify(hWnd, wParam, lParam, &bResult);
break;
default:
break;
}
return bResult;
}
// Main dialog initialization routine.
BOOL*
Shutdown_OnInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
TCHAR lpszText[_MAX_PATH + 1];
// save workstation name
_tcscpy(lpszWkstaName, (LPCTSTR)lParam);
// center window
CenterWindow(hWnd);
// Propose a default message.
Shutdown_OnInitMessage(hWnd, wParam, lParam, pbResult);
// set caption
_stprintf(lpszText, _T("Shutdown computer %s"), lpszWkstaName);
SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)lpszText);
// play sound 'Nuclear Launch Detected' - many thanks to Starcraft team from Blizzard
Shutdown_MCIPlaySound(hWnd, wParam, lParam, pbResult);
// set a default timeout of 3 minutes
SendMessage(GetDlgItem(hWnd, IDE_TIMEOUT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR)_T("180"));
// check "force application close"
SendMessage(GetDlgItem(hWnd, IDK_FORCEAPPSCLOSE), BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
// Set spin range
SendMessage(GetDlgItem(hWnd, IDSPIN_TIMEOUT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(300, 0));
*pbResult = TRUE;
return pbResult;
}
// nuke.wav sound warning
BOOL*
Shutdown_MCIPlaySound(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
TCHAR lpszVFWLibrary[_MAX_PATH + 1];
TCHAR lpszMCIWndRegisterClass[_MAX_PATH + 1];
TCHAR lpszWAVFile[_MAX_PATH + 1];
_UNREFERENCED_PARAMETER_(hWnd);
_UNREFERENCED_PARAMETER_(wParam);
_UNREFERENCED_PARAMETER_(lParam);
// Load strings for library name, routine and sound file. If OK, try to "sing" nuke.wav.
// The file "nuke.wav" is downloaded from "http://battle.net/scc/terran/".
if(LoadString(g_hInstance, IDS_VFW32DLL, lpszVFWLibrary, _MAX_PATH + 1) &&
LoadString(g_hInstance, IDS_MCIWNDREGISTERCLASS, lpszMCIWndRegisterClass, _MAX_PATH + 1) &&
LoadString(g_hInstance, IDS_SHUTDWONWAVFILE, lpszWAVFile, _MAX_PATH + 1))
{
g_hVFW32 = LoadLibrary(lpszVFWLibrary);
if(g_hVFW32) // we have audio support
{
// Find MCIWndRegisterClass exported routine.
lpfnMCIWndRegisterClass = (LPFNMCIWNDREGISTERCLASS)GetProcAddress(g_hVFW32, lpszMCIWndRegisterClass);
if(lpfnMCIWndRegisterClass) // ok, create MCI window, if possible
{
MDICREATESTRUCT mdics;
mdics.szClass = MCIWND_WINDOW_CLASS;
mdics.szTitle = _T("__ZS_InvisibleMCIWindow__");
mdics.hOwner = g_hInstance;
mdics.x = CW_USEDEFAULT;
mdics.y = 0;
mdics.cx = CW_USEDEFAULT;
mdics.cy = 0;
mdics.style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MCIWNDF_SHOWALL;
mdics.lParam = 0;
if((*lpfnMCIWndRegisterClass)()) // registering: success
{
g_hwndMdi = CreateWindow
(
MCIWND_WINDOW_CLASS,
_T("InvisibleMCIWindow"),
WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MCIWNDF_SHOWALL,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
0,
g_hInstance,
(LPVOID)(LPSTR)(LPCTSTR)lpszWAVFile
);
if(g_hwndMdi) // MCI window created: hide and play
{
ShowWindow(g_hwndMdi, SW_HIDE);
UpdateWindow(g_hwndMdi);
SendMessage(g_hwndMdi, MCI_PLAY, 0, 0);
}
}
}
}
}
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnClose(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
_UNREFERENCED_PARAMETER_(hWnd);
_UNREFERENCED_PARAMETER_(wParam);
_UNREFERENCED_PARAMETER_(lParam);
// deal MCI release
if(g_hwndMdi)
{
SendMessage(g_hwndMdi, MCI_STOP, 0, 0);
DestroyWindow(g_hwndMdi);
g_hwndMdi = 0;
UnregisterClass(MCIWND_WINDOW_CLASS, g_hInstance);
}
// free MSVFW32.DLL library
if(g_hVFW32)
{
FreeLibrary(g_hVFW32);
g_hVFW32 = 0;
}
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
switch(HIWORD(wParam))
{
case EN_CHANGE:
Shutdown_OnEditChange(hWnd, wParam, lParam, pbResult);
break;
case BN_CLICKED:
Shutdown_OnButtonClicked(hWnd, wParam, lParam, pbResult);
break;
default:
break;
}
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnButtonClicked(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
HWND hwndBtn = (HWND)lParam;
if(hwndBtn == GetDlgItem(hWnd, IDOK))
Shutdown_OnOK(hWnd, wParam, lParam, pbResult);
else if(hwndBtn == GetDlgItem(hWnd, IDCANCEL))
Shutdown_OnCancel(hWnd, wParam, lParam, pbResult);
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnOK(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
TCHAR lpszTimeout[4];
TCHAR tszEventName[_MAX_PATH + 1];
SafeAllocatePointer(lpSS, LPSHUTDOWNSTRUCT, GPTR, sizeof(SHUTDOWNSTRUCT));
if(lpSS)
{
GetWindowText(GetDlgItem(hWnd, IDE_TIMEOUT), lpszTimeout, 4);
GetWindowText(GetDlgItem(hWnd, IDE_MSG), lpszMessage, 1024);
_stprintf(tszEventName, _T("CancelShutdownThread_%p"), hWnd);
lpSS->fForceApplicationClose = SendMessage(GetDlgItem(hWnd, IDK_FORCEAPPSCLOSE), BM_GETCHECK, 0, 0);
lpSS->fLocalComputer = IsLocalMachine(lpszWkstaName);
lpSS->fReboot = SendMessage(GetDlgItem(hWnd, IDK_REBOOT), BM_GETCHECK, 0, 0);
lpSS->nTimeout = atoi(lpszTimeout);
lpSS->hCancelEvent = CreateEvent(0, TRUE, FALSE, tszEventName);
_tcscpy(lpSS->lpszMessage, lpszMessage);
_tcscpy(lpSS->lpszMachineName, lpszWkstaName);
}
Shutdown_OnClose(hWnd, wParam, lParam, pbResult);
EndDialog(hWnd, IDOK);
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnCancel(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
Shutdown_OnClose(hWnd, wParam, lParam, pbResult);
EndDialog(hWnd, IDCANCEL);
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnEditChange(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
HWND hwndEdit = (HWND)lParam;
if(hwndEdit == GetDlgItem(hWnd, IDE_TIMEOUT))
Shutdown_OnEditChangeTimeout(hWnd, wParam, lParam, pbResult);
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnEditChangeTimeout(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
TCHAR lpszTimeout[4];
TCHAR lpszText[1024];
_UNREFERENCED_PARAMETER_(wParam);
_UNREFERENCED_PARAMETER_(lParam);
GetWindowText(GetDlgItem(hWnd, IDE_TIMEOUT), lpszTimeout, 4);
_stprintf(lpszText, _T("WARNING! You workstation will be shutdown in %s seconds."), lpszTimeout);
// SendMessage(GetDlgItem(hWnd, IDE_MSG), WM_SETTEXT, 0, (LPARAM)(LPCTSTR)lpszText);
*pbResult = TRUE;
return pbResult;
}
BOOL*
Shutdown_OnNotify(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
LPNMHDR lpNMHDR = (LPNMHDR)lParam;
switch(lpNMHDR->code)
{
case UDN_DELTAPOS:
Shutdown_OnDeltaPos(hWnd, wParam, lParam, pbResult);
break;
default:
break;
}
*pbResult = TRUE;
return pbResult;
}
// updown control notification "UDN_DELTAPOS"
BOOL*
Shutdown_OnDeltaPos(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
NMUPDOWN* pNMUpDown = (NMUPDOWN*)lParam;
TCHAR lpszTimeOut[4];
int nTimeOut = 180;
HWND hwndTimeout = GetDlgItem(hWnd, IDE_TIMEOUT);
_UNREFERENCED_PARAMETER_(wParam);
_UNREFERENCED_PARAMETER_(lParam);
GetWindowText(hwndTimeout, lpszTimeOut, 4);
nTimeOut = atoi(lpszTimeOut);
if(nTimeOut > 0)
{
nTimeOut -= pNMUpDown->iDelta;
_stprintf(lpszTimeOut, _T("%d"), nTimeOut);
SetWindowText(hwndTimeout, lpszTimeOut);
}
else
{
if(pNMUpDown->iDelta < 0)
{
nTimeOut -= pNMUpDown->iDelta;
_stprintf(lpszTimeOut, _T("%d"), nTimeOut);
}
SetWindowText(hwndTimeout, lpszTimeOut);
}
*pbResult = TRUE;
return pbResult;
}
// Propose a default message to be shown to affected user.
BOOL*
Shutdown_OnInitMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *pbResult)
{
NET_API_STATUS nas;
LPBYTE buf;
DWORD entriesread, total, hres = 0;
TCHAR lpszInitMsg[1024];
TCHAR lpszFmt[_MAX_PATH + 1];
HMODULE _hNetDLL = 0;
_UNREFERENCED_PARAMETER_(wParam);
_UNREFERENCED_PARAMETER_(lParam);
LoadString(g_hInstance, IDS_NETAPI32DLL, lpszFmt, _MAX_PATH + 1);
_hNetDLL = LoadLibrary(lpszFmt);
if(_hNetDLL)
{
NETWKPROC _procNetWkstaGetInfo = 0;
LoadString(g_hInstance, IDS_NETWKSTAUSERENUM, lpszFmt, _MAX_PATH + 1);
_procNetWkstaGetInfo = (NETWKPROC)GetProcAddress(_hNetDLL, lpszFmt);
if(_procNetWkstaGetInfo)
{
nas = (*_procNetWkstaGetInfo)(
_WCSTR((LPCTSTR)lpszWkstaName), //lpwsrv,
1,
(LPBYTE *)&buf,
MAX_PREFERRED_LENGTH,
&entriesread,
&total,
&hres);
if(nas == NERR_Success)
{
if(entriesread > 0)
{
LoadString(g_hInstance, IDS_SHUTDOWNWARNING, lpszFmt, 256);
_stprintf(lpszInitMsg, lpszFmt, ((WKSTA_USER_INFO_1 *)buf)->wkui1_username, lpszWkstaName);
SetWindowText(GetDlgItem(hWnd, IDE_MSG), lpszInitMsg);
}
else
{
LoadString(g_hInstance, IDS_WKSTACLOSED, lpszFmt, 256);
_stprintf(lpszInitMsg, lpszFmt, lpszWkstaName);
SetWindowText(GetDlgItem(hWnd, IDE_MSG), lpszInitMsg);
}
}
else
{
LoadString(g_hInstance, IDS_WKSTANOTNT, lpszFmt, 256);
_stprintf(lpszInitMsg, lpszFmt, lpszWkstaName);
SetWindowText(GetDlgItem(hWnd, IDE_MSG), lpszInitMsg);
}
if(buf)
{
NETAPIBUFFERFREEPROC lpfnNetApiBufferFree =
(NETAPIBUFFERFREEPROC)GetProcAddress(_hNetDLL, _T("NetApiBufferFree"));
if(lpfnNetApiBufferFree)
{
(*lpfnNetApiBufferFree)(buf);
}
}
}
FreeLibrary(_hNetDLL);
}
*pbResult = TRUE;
return pbResult;
}