Leaked source code of windows server 2003
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.
 
 
 
 
 
 

279 lines
8.0 KiB

//---------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation
//
// File: setupenum.cpp
//
// The current order of enumeration is whatever order we read from the registry
//
// History:
// 6-11-98 by toddb
//------------------------------------------------------------------------
#include "priv.h"
#include <shellp.h> // for IsUserAnAdmin
#include "setupenum.h"
#include "appwizid.h"
#define c_szOCSetupKey TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Setup\\OCManager\\ToDoList")
//-----------------------------------------------------------------------
// OCSetupApp
//-----------------------------------------------------------------------
COCSetupApp::COCSetupApp()
{
// This must be heap alloced so everything should be zero'ed out.
// Make sure this wasn't stack alloced using these asserts:
ASSERT(0 == _szDisplayName[0]);
ASSERT(0 == _szApp[0]);
ASSERT(0 == _szArgs[0]);
}
COCSetupApp::~COCSetupApp()
{
}
//-----------------------------------------------------------------------
// GetAppInfo
//
// Fills in the only valid field in our psuedo APPINFODATA structure.
BOOL COCSetupApp::GetAppInfo(PAPPINFODATA pai)
{
if (pai->cbSize != SIZEOF(APPINFODATA))
return FALSE;
DWORD dwInfoFlags = pai->dwMask;
pai->dwMask = 0;
if (dwInfoFlags & AIM_DISPLAYNAME)
{
if (SUCCEEDED(SHStrDup(_szDisplayName, &pai->pszDisplayName)))
pai->dwMask |= AIM_DISPLAYNAME;
}
return TRUE;
}
//-----------------------------------------------------------------------
// ReadFromKey
//
// This function reads the actual data from the given reg key. It returns
// TRUE if all required fields contained string data.
BOOL COCSetupApp::ReadFromKey( HKEY hkey )
{
DWORD dwType;
DWORD dwSize;
dwSize = sizeof(_szDisplayName);
if ( ERROR_SUCCESS != RegQueryValueEx( hkey, TEXT("Title"), 0, &dwType, (LPBYTE)_szDisplayName, &dwSize ) ||
dwType != REG_SZ )
{
// DisplayName is required
return FALSE;
}
dwSize = sizeof(_szApp);
if ( ERROR_SUCCESS == RegQueryValueEx( hkey, TEXT("ConfigCommand"), 0, &dwType, (LPBYTE)_szApp, &dwSize ) &&
(dwType == REG_SZ || dwType == REG_EXPAND_SZ) )
{
if ( dwType == REG_EXPAND_SZ )
{
TCHAR szBuf[MAX_PATH];
ExpandEnvironmentStrings(_szApp, szBuf, ARRAYSIZE(szBuf));
lstrcpyn(_szApp, szBuf, ARRAYSIZE(_szApp));
}
}
else
{
// ConfigCommand is required
return FALSE;
}
dwSize = sizeof(_szArgs);
if ( ERROR_SUCCESS == RegQueryValueEx( hkey, TEXT("ConfigArgs"), 0, &dwType, (LPBYTE)_szArgs, &dwSize ) &&
(dwType == REG_SZ || dwType == REG_EXPAND_SZ) )
{
if ( dwType == REG_EXPAND_SZ )
{
TCHAR szBuf[MAX_PATH];
ExpandEnvironmentStrings(_szArgs, szBuf, ARRAYSIZE(szBuf));
lstrcpyn(_szArgs, szBuf, ARRAYSIZE(_szArgs));
}
}
else
{
// This is optional so we don't fail. Instead simply insure that _szArgs is an empty string.
_szArgs[0] = 0;
}
return TRUE;
}
BOOL COCSetupApp::Run()
{
// REARCHITECT: (stephstm, 03/17/99) we should probably wait on a job object in case
// the spawned process spawns some other process(es) and then exits before them.
BOOL fRet = FALSE;
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = GetDesktopWindow();
sei.lpFile = _szApp;
sei.lpParameters = _szArgs[0] ? _szArgs : NULL;
sei.nShow = SW_SHOWDEFAULT;
fRet = ShellExecuteEx(&sei);
if (fRet)
{
DWORD dwRet;
do
{
MSG msg;
// Get and process the messages!
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// MsgWaitForMultipleObjects can fail with -1 being returned!
dwRet = MsgWaitForMultipleObjects(1, &sei.hProcess, FALSE, INFINITE, QS_ALLINPUT);
}
while ((WAIT_OBJECT_0 != dwRet) && (-1 != dwRet));
// Did MsgWait... failed?
if (-1 == dwRet)
{
// Yes, kill the process
TerminateProcess(sei.hProcess, 0);
fRet = FALSE;
}
CloseHandle(sei.hProcess);
}
else
{
ShellMessageBox(HINST_THISDLL, sei.hwnd, MAKEINTRESOURCE( IDS_CONFIGURE_FAILED ),
MAKEINTRESOURCE( IDS_NAME ),
MB_OK | MB_ICONEXCLAMATION);
}
return fRet;
}
//-----------------------------------------------------------------------
// OCSetupEnum
//-----------------------------------------------------------------------
COCSetupEnum::COCSetupEnum()
{
_hkeyRoot = 0;
_iRegEnumIndex = -1;
}
COCSetupEnum::~COCSetupEnum()
{
if ( _hkeyRoot )
{
RegCloseKey( _hkeyRoot );
}
}
//-----------------------------------------------------------------------
// s_OCSetupNeeded
//
// This checks for the neccessaary conditions to display the OC Setup portion of the ARP.
// This section is only shown if the current user is a member of the administrators group
// AND there are any items listed in the registry that need to be displayed.
BOOL COCSetupEnum::s_OCSetupNeeded()
{
BOOL fResult = FALSE;
HKEY hkey;
// Temporarily open the reg key to see if it exists and has any sub keys
if ( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szOCSetupKey, 0, KEY_READ, &hkey ) )
{
TCHAR szBuf[MAX_PATH];
if ( ERROR_SUCCESS == RegEnumKey( hkey, 0, szBuf, ARRAYSIZE(szBuf) ) )
{
// Yes, there are OCSetup items, but is the current user an administrator?
if ( IsUserAnAdmin() )
{
fResult = TRUE;
}
}
RegCloseKey( hkey );
}
return fResult;
}
//-----------------------------------------------------------------------
// EnumOCSetupItems
//
// This begins the enumeration by opening the required registry key. This does
// not attempt to read any of the sub items so there is no garentee that the
// first call to Next() will succeed.
BOOL COCSetupEnum::EnumOCSetupItems()
{
ASSERT( NULL == _hkeyRoot );
// Open the reg key, return true if it's open. We leave the key open until
// our destructor is called since we need this key to do the enumeration.
if ( ERROR_SUCCESS == RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
c_szOCSetupKey,
0,
KEY_READ,
&_hkeyRoot ) )
{
return TRUE;
}
return FALSE;
}
//-----------------------------------------------------------------------
// Next
//
// Reads the data from the next sub key of _hkeyRoot and returns the data in the
// out pointer. Returns TRUE if the out pointer is a valid COCSetupApp object.
BOOL COCSetupEnum::Next(COCSetupApp **ppocsa)
{
HKEY hkeySub;
TCHAR szSubKeyName[MAX_PATH];
// We open each subkey of the root key and attempt to read an OCSetup item from the subkey.
if ( ERROR_SUCCESS == RegEnumKey( _hkeyRoot, ++_iRegEnumIndex, szSubKeyName, ARRAYSIZE(szSubKeyName) ) )
{
if ( ERROR_SUCCESS == RegOpenKeyEx( _hkeyRoot, szSubKeyName, 0, KEY_READ, &hkeySub ) )
{
*ppocsa = new COCSetupApp();
if ( *ppocsa )
{
if ( (*ppocsa)->ReadFromKey( hkeySub ) )
{
RegCloseKey( hkeySub );
return TRUE;
}
delete *ppocsa;
}
RegCloseKey( hkeySub );
}
// fall through
}
*ppocsa = NULL;
return FALSE;
}