485 lines
12 KiB
C++
485 lines
12 KiB
C++
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// MISCFUNC.CPP / Tuneup
|
|
//
|
|
// Microsoft Confidential
|
|
// Copyright (c) Microsoft Corporation 1998
|
|
// All rights reserved
|
|
//
|
|
// Contains misc. functions used throughout the program. All these functions
|
|
// are externally exported and defined in MISCFUNC.H.
|
|
//
|
|
// 7/98 - Jason Cohen (JCOHEN)
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// Include files.
|
|
//
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <shellapi.h>
|
|
#include "jcohen.h"
|
|
#include "registry.h"
|
|
|
|
|
|
VOID CenterWindow(HWND hWnd, HWND hWndParent, BOOL bRightTop)
|
|
{
|
|
RECT rcWndParent,
|
|
rcWnd;
|
|
|
|
// Get the window rect for the parent window.
|
|
//
|
|
if (hWndParent == NULL)
|
|
GetWindowRect(GetDesktopWindow(), &rcWndParent);
|
|
else
|
|
GetWindowRect(hWndParent, &rcWndParent);
|
|
|
|
// Get the window rect for the window to be centered.
|
|
//
|
|
GetWindowRect(hWnd, &rcWnd);
|
|
|
|
// Now center the window.
|
|
//
|
|
if (bRightTop)
|
|
{
|
|
SetWindowPos(hWnd, HWND_TOPMOST,
|
|
rcWndParent.right - (rcWnd.right - rcWnd.left) - 5,
|
|
GetSystemMetrics(SM_CYCAPTION) * 2,
|
|
0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
|
|
}
|
|
else
|
|
{
|
|
SetWindowPos(hWnd, NULL,
|
|
rcWndParent.left + (rcWndParent.right - rcWndParent.left - (rcWnd.right - rcWnd.left)) / 2,
|
|
rcWndParent.top + (rcWndParent.bottom - rcWndParent.top - (rcWnd.bottom - rcWnd.top)) / 2,
|
|
0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
|
|
}
|
|
}
|
|
|
|
|
|
VOID ShowEnableWindow(HWND hWnd, BOOL bEnable)
|
|
{
|
|
EnableWindow(hWnd, bEnable);
|
|
ShowWindow(hWnd, bEnable ? SW_SHOW : SW_HIDE);
|
|
}
|
|
|
|
|
|
LPTSTR AllocateString(HINSTANCE hInstance, UINT uID)
|
|
{
|
|
TCHAR szBuffer[512];
|
|
LPTSTR lpBuffer = NULL;
|
|
|
|
if ( ( LoadString(hInstance, uID, szBuffer, sizeof(szBuffer) / sizeof(TCHAR)) ) &&
|
|
( lpBuffer = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(szBuffer) + 1)) ) )
|
|
lstrcpy(lpBuffer, szBuffer);
|
|
return lpBuffer;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// EXTERNAL:
|
|
// IsUserAdmin()
|
|
//
|
|
// This routine returns TRUE if the caller's process is a
|
|
// member of the Administrators local group.
|
|
//
|
|
// Caller is NOT expected to be impersonating anyone and IS
|
|
// expected to be able to open their own process and process
|
|
// token.
|
|
//
|
|
// ENTRY:
|
|
// None.
|
|
//
|
|
// EXIT:
|
|
// BOOL
|
|
// TRUE - Caller has Administrators local group.
|
|
// FALSE - Caller does not have Administrators local group.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL IsUserAdmin(VOID)
|
|
{
|
|
HANDLE hToken = INVALID_HANDLE_VALUE;
|
|
PTOKEN_GROUPS pGroups = NULL;
|
|
DWORD dwSize,
|
|
i;
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|
PSID AdministratorsGroup;
|
|
|
|
static DWORD dwReturn = 0;
|
|
|
|
// Save the admin status so that we don't have to
|
|
// do all this work everytime we call this function.
|
|
//
|
|
if (dwReturn)
|
|
return (dwReturn == 1); // 1 = TRUE, 2 = FALSE, 0 = Unknown yet.
|
|
|
|
// Open the process token.
|
|
//
|
|
if ( OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) )
|
|
{
|
|
// Get group information.
|
|
//
|
|
if ( !GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize) &&
|
|
(GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
|
|
(pGroups = (PTOKEN_GROUPS) LocalAlloc(LPTR, dwSize)) &&
|
|
(GetTokenInformation(hToken, TokenGroups, pGroups, dwSize, &dwSize)) )
|
|
{
|
|
|
|
if ( AllocateAndInitializeSid(
|
|
&NtAuthority,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
&AdministratorsGroup)
|
|
)
|
|
{
|
|
// See if the user has the administrator group.
|
|
//
|
|
for(i = 0; (dwReturn != 1) && (i < pGroups->GroupCount); i++)
|
|
if ( EqualSid(pGroups->Groups[i].Sid, AdministratorsGroup) ) dwReturn = 1;
|
|
|
|
// If we didn't find the user in the
|
|
// admin group, set the return option to
|
|
// 2 (meaning we looked already but the
|
|
// user isn't an admin.
|
|
//
|
|
if (dwReturn != 1)
|
|
dwReturn = 2;
|
|
|
|
FreeSid(AdministratorsGroup);
|
|
}
|
|
}
|
|
|
|
// Clean up.
|
|
//
|
|
if (pGroups) {
|
|
LocalFree((HLOCAL) pGroups);
|
|
}
|
|
CloseHandle(hToken);
|
|
}
|
|
|
|
return (dwReturn == 1); // 1 = TRUE, 2 = FALSE, 0 = Unknown yet.
|
|
}
|
|
|
|
|
|
VOID ExecAndWait(HWND hOrgWnd, LPTSTR lpExe, LPTSTR lpCmd, LPTSTR lpDir, BOOL fShowOrgWnd, BOOL fNoWait)
|
|
{
|
|
SHELLEXECUTEINFO sei;
|
|
|
|
ZeroMemory((PVOID) &sei, sizeof(SHELLEXECUTEINFO));
|
|
sei.cbSize = sizeof(SHELLEXECUTEINFO);
|
|
sei.hwnd = hOrgWnd;
|
|
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
|
|
sei.lpFile = (LPCTSTR) lpExe;
|
|
sei.lpDirectory = lpDir;
|
|
sei.lpParameters = lpCmd;
|
|
sei.nShow = SW_SHOW;
|
|
|
|
if (ShellExecuteEx(&sei)) {
|
|
|
|
// Hide/disable Tuneup.
|
|
//
|
|
WaitForInputIdle(sei.hProcess, INFINITE);
|
|
ShowEnableWindow(hOrgWnd, FALSE);
|
|
//ShowEnableWindow(g_hwndMain, FALSE);
|
|
|
|
// Wait until the launched app stop.
|
|
//
|
|
if (!fNoWait)
|
|
WaitForSingleObjectEx(sei.hProcess, INFINITE, FALSE);
|
|
|
|
// Enable Tuneup.
|
|
//
|
|
EnableWindow(hOrgWnd, TRUE);
|
|
//EnableWindow(g_hwndMain, TRUE);
|
|
|
|
// Don't show it?
|
|
//
|
|
if (fShowOrgWnd) {
|
|
ShowWindow(hOrgWnd, SW_SHOW);
|
|
//ShowWindow(g_hwndMain, SW_SHOW);
|
|
SetForegroundWindow(hOrgWnd);
|
|
}
|
|
}
|
|
#ifdef DEBUG
|
|
else {
|
|
LPTSTR lpMsgBuf;
|
|
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
&lpMsgBuf, 0, NULL
|
|
);
|
|
|
|
MessageBox(NULL, (LPCTSTR) lpMsgBuf, (LPCTSTR) _T("GetLastError()"), MB_OK | MB_ICONINFORMATION);
|
|
LocalFree(lpMsgBuf);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
BOOL ErrMsg(HWND hWnd, INT nStringID)
|
|
{
|
|
LPTSTR lpString;
|
|
|
|
// Load the string and display the message box.
|
|
//
|
|
if ( lpString = AllocateString(NULL, nStringID) )
|
|
{
|
|
MessageBox(hWnd, lpString, NULL, MB_OK | MB_ICONEXCLAMATION);
|
|
FREE(lpString);
|
|
}
|
|
|
|
// Always return TRUE.
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD StartScheduler()
|
|
{
|
|
TCHAR szRegKeyServices[] = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServies"),
|
|
szRegValSched[] = _T("SchedulingAgent"),
|
|
szSchedClass[] = _T("SAGEWINDOWCLASS"),
|
|
szSchedTitle[] = _T("SYSTEM AGENT COM WINDOW"),
|
|
szSchedExe[] = _T("MSTASK.EXE");
|
|
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
TCHAR szApp[MAX_PATH] = NULLSTR;
|
|
LPTSTR lpFilePart;
|
|
|
|
// Check to see if it is already running.
|
|
//
|
|
if ( FindWindow(szSchedClass, szSchedTitle) != NULL )
|
|
return ERROR_SUCCESS;
|
|
|
|
// Get the full path to where MSTASK is.
|
|
//
|
|
if ( ( SearchPath(NULL, _T("MSTASK.EXE"), NULL, sizeof(szApp), szApp, &lpFilePart) == 0 ) ||
|
|
( szApp[0] == _T('\0') ) )
|
|
return GetLastError();
|
|
|
|
// Add the key so the Scheduling service will start each time
|
|
// the computer is restarted.
|
|
//
|
|
RegSetString(HKLM, szRegKeyServices, szRegValSched, szApp);
|
|
|
|
// Execute the task scheduler process.
|
|
//
|
|
ZeroMemory(&si, sizeof(STARTUPINFO));
|
|
si.cb = sizeof(STARTUPINFO);
|
|
|
|
if ( !CreateProcess(szApp, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi) )
|
|
return GetLastError();
|
|
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
HFONT GetFont(HWND hWndCtrl, LPTSTR lpFontName, DWORD dwFontSize, LONG lFontWeight, BOOL bSymbol)
|
|
{
|
|
HFONT hFont;
|
|
LOGFONT lFont;
|
|
BOOL bGetFont;
|
|
|
|
|
|
// If the font name is passed in, then try to use that
|
|
// first before getting the font of the control.
|
|
//
|
|
if ( lpFontName )
|
|
{
|
|
// Make sure the font name is not longer than
|
|
// 32 characters (including the NULL terminator).
|
|
//
|
|
if ( lstrlen(lpFontName) >= sizeof(lFont.lfFaceName) )
|
|
return NULL;
|
|
|
|
// Setup the structure to use to get the
|
|
// font we want.
|
|
//
|
|
ZeroMemory(&lFont, sizeof(LOGFONT));
|
|
lstrcpy(lFont.lfFaceName, lpFontName);
|
|
}
|
|
|
|
// First try to get the font that we wanted.
|
|
//
|
|
if ( ( lpFontName == NULL ) ||
|
|
( (hFont = CreateFontIndirect((LPLOGFONT) &lFont)) == NULL ) )
|
|
{
|
|
// Couldn't get the font we wanted, try the font of the control
|
|
// if a valid window handle was passed in.
|
|
//
|
|
if ( ( hWndCtrl == NULL ) ||
|
|
( (hFont = (HFONT) (WORD) SendMessage(hWndCtrl, WM_GETFONT, 0, 0L)) == NULL ) )
|
|
{
|
|
// All atempts to get the font failed. We must return NULL.
|
|
//
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// Return the font we have now if we don't need to
|
|
// change the size or weight.
|
|
//
|
|
if ( (lFontWeight == 0) && (dwFontSize == 0) )
|
|
return hFont;
|
|
|
|
// We must have a valid HFONT now. Fill in the structure
|
|
// and setup the size and weight we wanted for it.
|
|
//
|
|
bGetFont = GetObject(hFont, sizeof(LOGFONT), (LPVOID) &lFont);
|
|
DeleteObject(hFont);
|
|
|
|
if (bGetFont)
|
|
{
|
|
// Set the bold and point size of the font.
|
|
//
|
|
if (lFontWeight)
|
|
lFont.lfWeight = lFontWeight;
|
|
if (dwFontSize)
|
|
lFont.lfHeight = -MulDiv(dwFontSize, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
|
|
if (bSymbol)
|
|
lFont.lfCharSet = SYMBOL_CHARSET;
|
|
|
|
// Create the font.
|
|
//
|
|
hFont = CreateFontIndirect((LPLOGFONT) &lFont);
|
|
}
|
|
else
|
|
hFont = NULL;
|
|
|
|
return hFont;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// EXTERNAL:
|
|
// CreatePath()
|
|
// - Creates the whole path, not just the last directory.
|
|
//
|
|
// ENTRY:
|
|
// lpPath - Path to create.
|
|
//
|
|
// EXIT:
|
|
// VOID
|
|
//
|
|
//***************************************************************************
|
|
|
|
BOOL CreatePath(LPTSTR lpPath) {
|
|
|
|
LPTSTR lpFind = lpPath;
|
|
|
|
while ( lpFind = _tcschr(lpFind + 1, _T('\\')) )
|
|
{
|
|
if ( !( ( lpFind - lpPath <= 2 ) && ( *(lpFind - 1) == _T(':') ) ) )
|
|
{
|
|
*lpFind = _T('\0');
|
|
if (!EXIST(lpPath))
|
|
CreateDirectory(lpPath, NULL);
|
|
*lpFind = _T('\\');
|
|
}
|
|
}
|
|
|
|
if (!EXIST(lpPath))
|
|
return CreateDirectory(lpPath, NULL);
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD GetCommandLineOptions(LPTSTR **lpArgs)
|
|
{
|
|
TCHAR cParse;
|
|
LPTSTR lpSearch,
|
|
lpCommandLine;
|
|
DWORD dwArgs = 0,
|
|
dwMaxArgs = 0xFFFFFFFF;
|
|
|
|
// Make sure we get the command line.
|
|
//
|
|
if ( (lpSearch = lpCommandLine = GetCommandLine()) == NULL )
|
|
return 0;
|
|
|
|
// Get the number of arguments so we can allocate
|
|
// the memory for the array of command line options.
|
|
//
|
|
if ( lpArgs )
|
|
{
|
|
if ( (dwMaxArgs = GetCommandLineOptions(NULL)) == 0 )
|
|
return 0;
|
|
if ( (*lpArgs = (LPTSTR *) MALLOC(sizeof(LPTSTR) * dwMaxArgs)) == NULL )
|
|
return 0;
|
|
}
|
|
|
|
// Now lets parse the arguments.
|
|
//
|
|
while ( *lpSearch && (dwArgs < dwMaxArgs) )
|
|
{
|
|
// Eat all preceeding spaces.
|
|
//
|
|
while ( *lpSearch == _T(' ') )
|
|
lpSearch++;
|
|
|
|
// Check to see if we need to look for a space or a quote
|
|
// to separate the next argument.
|
|
//
|
|
if ( *lpSearch == _T('"') )
|
|
cParse = *lpSearch++;
|
|
else
|
|
cParse = _T(' ');
|
|
|
|
// This is be the beginning of the next argument, but
|
|
// it isn't NULL terminated yet.
|
|
//
|
|
if ( lpArgs )
|
|
*(*lpArgs + dwArgs) = lpSearch;
|
|
dwArgs++;
|
|
|
|
// Go through all the characters until we hit a separator.
|
|
//
|
|
do
|
|
{
|
|
// Once we get to a quote, we just want to keep going
|
|
// until we get to a space.
|
|
//
|
|
if ( *lpSearch == _T('"') )
|
|
cParse = _T(' ');
|
|
|
|
// Only end when we reach the parsing character, which will
|
|
// always be the space by this time (but the space won't trigger
|
|
// the end until we hit a quote, if that is what we were originally
|
|
// looking for). We also need to make sure that we don't increment
|
|
// past the NULL terminator.
|
|
//
|
|
}
|
|
while ( ( *lpSearch != cParse ) && ( *lpSearch ) && ( *lpSearch++ ) );
|
|
|
|
// If the preceeding character is a quote, that is were we want to
|
|
// place the NULL terminator.
|
|
//
|
|
if ( ( lpSearch > lpCommandLine ) &&
|
|
( *(lpSearch - 1) == _T('"') ) )
|
|
lpSearch--;
|
|
|
|
// Set and increment past the NULL terminator only if we aren't already at
|
|
// the end if the string.
|
|
//
|
|
if ( lpArgs && *lpSearch )
|
|
*lpSearch++ = _T('\0');
|
|
else
|
|
if ( *lpSearch ) lpSearch++;
|
|
}
|
|
|
|
return dwArgs;
|
|
} |