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.
 
 
 
 
 
 

642 lines
16 KiB

// Copyright (c) 1997-1999 Microsoft Corporation
#include "precomp.h"
#include "..\MMFUtil\MsgDlg.h"
#ifdef EXT_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "util.h"
#include "..\Common\ServiceThread.h"
#include "WBEMPageHelper.h"
#include <stdarg.h>
BOOL WBEMPageHelper::g_fRebootRequired = FALSE;
//------------------------------------------------
WBEMPageHelper::WBEMPageHelper(CWbemServices &service)
{
m_service = 0;
m_WbemServices = service;
m_WbemServices.GetServices(&m_service);
m_WbemServices.SetBlanket(m_service);
m_okPressed = false;
m_userCancelled = false;
m_hDlg = NULL;
m_AVIbox = 0;
}
//------------------------------------------------
WBEMPageHelper::WBEMPageHelper(WbemServiceThread *serviceThread)
{
m_serviceThread = serviceThread;
if (m_serviceThread)
m_serviceThread->AddRef();
m_service = 0;
if(m_serviceThread->m_status == WbemServiceThread::ready)
{
m_WbemServices = m_serviceThread->m_WbemServices;
m_WbemServices.GetServices(&m_service);
m_WbemServices.SetBlanket(m_service);
}
m_okPressed = false;
m_userCancelled = false;
m_hDlg = NULL;
m_AVIbox = 0;
}
//------------------------------------------------
WBEMPageHelper::~WBEMPageHelper()
{
// in case ServiceThread still has a ptr to this
// handle. It knows not to use NULL HWNDs.
m_AVIbox = 0;
m_hDlg = NULL;
if(m_service)
{
m_service->Release();
m_service = 0;
}
m_WbemServices.DisconnectServer();
if (m_serviceThread)
m_serviceThread->Release();
}
//------------------------------------------------
CWbemClassObject WBEMPageHelper::ExchangeInstance(IWbemClassObject **ppbadInst)
{
CWbemClassObject inst;
_variant_t v1;
if(SUCCEEDED((*ppbadInst)->Get(bstr_t("__PATH"), 0, &v1, NULL, NULL)))
{
inst = m_WbemServices.GetObject((_bstr_t) v1);
(*ppbadInst)->Release();
*ppbadInst = NULL;
}
return inst;
}
//------------------------------------------------
// get the first instance of the named class.
IWbemClassObject *WBEMPageHelper::FirstInstanceOf(bstr_t className)
{
IWbemClassObject *pInst = NULL;
ULONG uReturned;
IEnumWbemClassObject *Enum = NULL;
// get the class.
if(SUCCEEDED(m_WbemServices.CreateInstanceEnum(className,
WBEM_FLAG_SHALLOW,
&Enum)))
{
// get the first and only instance.
Enum->Next(-1, 1, &pInst, &uReturned);
Enum->Release();
}
return pInst;
}
//---------------------------------------------------
LPTSTR WBEMPageHelper::CloneString( LPTSTR pszSrc )
{
LPTSTR pszDst = NULL;
if (pszSrc != NULL)
{
pszDst = new TCHAR[(lstrlen(pszSrc) + 1)];
if (pszDst)
{
lstrcpy( pszDst, pszSrc );
}
}
return pszDst;
}
//*************************************************************
//
// SetClearBitmap()
//
// Purpose: Sets or clears an image in a static control.
//
// Parameters: control - handle of static control
// resource - resource / filename of bitmap
// fl - SCB_ flags:
// SCB_FROMFILE 'resource' specifies a filename instead of a resource
// SCB_REPLACEONLY only put the new image up if there was an old one
//
//
// Return: (BOOL) TRUE if successful
// FALSE if an error occurs
//
//
// Comments:
//
//
// History: Date Author Comment
// 5/24/95 ericflo Ported
//
//*************************************************************
BOOL WBEMPageHelper::SetClearBitmap( HWND control,
LPCTSTR resource,
UINT fl )
{
HBITMAP hbm = (HBITMAP)SendMessage(control, STM_GETIMAGE, IMAGE_BITMAP, 0);
if( hbm )
{
DeleteObject( hbm );
}
else if( fl & SCB_REPLACEONLY )
{
return FALSE;
}
if( resource )
{
SendMessage(control, STM_SETIMAGE, IMAGE_BITMAP,
(LPARAM)LoadImage( HINST_THISDLL,
resource,
IMAGE_BITMAP,
0, 0,
LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS |
( ( fl & SCB_FROMFILE )? LR_LOADFROMFILE : 0 ) )
);
}
return
((HBITMAP)SendMessage(control, STM_GETIMAGE, IMAGE_BITMAP, 0) != NULL);
}
//------------------------------------------------------------
int WBEMPageHelper::MsgBoxParam(HWND hWnd,
DWORD wText,
DWORD wCaption,
DWORD wType,
LPTSTR var1,
LPTSTR var2)
{
TCHAR szText[ 4 * MAX_PATH ] = {0}, szCaption[ 2 * MAX_PATH ] = {0};
int ival;
if( !LoadString( HINST_THISDLL, wText, szCaption, ARRAYSIZE( szCaption ) ) )
{
return 0;
}
if(var2)
_snwprintf(szText, 4 * MAX_PATH, szCaption, var1, var2);
else if(var1)
_snwprintf(szText, 4 * MAX_PATH, szCaption, var1);
else
_snwprintf(szText, 4 * MAX_PATH, szCaption);
if( !LoadString( HINST_THISDLL, wCaption, szCaption, ARRAYSIZE( szCaption ) ) )
{
return 0;
}
ival = MessageBox( hWnd, szText, szCaption, wType);
return ival;
}
//------------------------------------------------------------
void WBEMPageHelper::HourGlass( bool bOn )
{
if( !GetSystemMetrics( SM_MOUSEPRESENT ) )
ShowCursor( bOn );
SetCursor( LoadCursor( NULL, bOn ? IDC_WAIT : IDC_ARROW ) );
}
////////////////////////////////////////////////////////////////////////////
// SetLBWidthEx
//
// Set the width of the listbox, in pixels, acording to the size of the
// string passed in.
//
// Note: this function is also used by the Virtual Memory dialog
//
// History:
// 11-Jan-1996 JonPa Created from SetGenLBWidth
////////////////////////////////////////////////////////////////////////////
DWORD WBEMPageHelper::SetLBWidthEx( HWND hwndLB,
LPTSTR szBuffer,
DWORD cxCurWidth,
DWORD cxExtra)
{
HDC hDC;
SIZE Size;
HFONT hfont, hfontOld;
// Get the new Win4.0 thin dialog font
hfont = (HFONT)SendMessage(hwndLB, WM_GETFONT, 0, 0);
hDC = GetDC(hwndLB);
// if we got a font back, select it in this clean hDC
if (hfont != NULL)
hfontOld = (HFONT)SelectObject(hDC, hfont);
// If cxExtra is 0, then give our selves a little breathing space.
if (cxExtra == 0)
{
GetTextExtentPoint(hDC, TEXT("1234"), 4 , &Size);
cxExtra = Size.cx;
}
// Set scroll width of listbox
GetTextExtentPoint(hDC, szBuffer, lstrlen(szBuffer), &Size);
Size.cx += cxExtra;
// Get the name length and adjust the longest name
if ((DWORD) Size.cx > cxCurWidth)
{
cxCurWidth = Size.cx;
SendMessage (hwndLB, LB_SETHORIZONTALEXTENT, (DWORD)Size.cx, 0L);
}
// retstore the original font if we changed it.
if (hfont != NULL)
SelectObject(hDC, hfontOld);
ReleaseDC(NULL, hDC);
return cxCurWidth;
return 1; // bs
}
//---------------------------------------------------
void WBEMPageHelper::SetDefButton(HWND hwndDlg,
int idButton)
{
LRESULT lr;
if(HIWORD(lr = SendMessage(hwndDlg, DM_GETDEFID, 0, 0)) == DC_HASDEFID)
{
HWND hwndOldDefButton = GetDlgItem(hwndDlg, LOWORD(lr));
SendMessage (hwndOldDefButton,
BM_SETSTYLE,
MAKEWPARAM(BS_PUSHBUTTON, 0),
MAKELPARAM(TRUE, 0));
}
SendMessage( hwndDlg, DM_SETDEFID, idButton, 0L );
SendMessage( GetDlgItem(hwndDlg, idButton),
BM_SETSTYLE,
MAKEWPARAM( BS_DEFPUSHBUTTON, 0 ),
MAKELPARAM( TRUE, 0 ));
}
//-------------------------------------------------------------------
void WBEMPageHelper::SetDlgItemMB( HWND hDlg,
int idControl,
ULONG dwMBValue )
{
TCHAR szBuf[20] = {0};
wsprintf(szBuf, _T("%u MB"), dwMBValue);
SetDlgItemText(hDlg, idControl, szBuf);
}
//--------------------------------------------------------------
void WBEMPageHelper::SetWbemService(IWbemServices *pServices)
{
m_serviceThread->m_realServices = pServices;
m_serviceThread->m_WbemServices = pServices;
m_WbemServices = pServices;
}
//--------------------------------------------------------------
bool WBEMPageHelper::ServiceIsReady(UINT uCaption /* = 0*/,
UINT uWaitMsg,
UINT uBadMsg)
{
switch(m_serviceThread->m_status)
{
// its already there.
case WbemServiceThread::ready:
{
ATLTRACE(L"start marshal\n");
for(int i = 0; (i < 5); i++)
{
// if "Object is not connected to server"
if(m_serviceThread->m_hr == 0x800401fd)
{
// lost my connection,
ATLTRACE(_T("Reconnecting to cimom!!!!!!!!!!!\n"));
m_serviceThread->ReConnect();
ATLTRACE(_T("new service status: %d\n"), m_serviceThread->m_status);
continue;
}
else if(FAILED(m_serviceThread->m_hr))
{
// some other problem.
m_serviceThread->m_WbemServices = (IWbemServices *)NULL;
m_serviceThread->m_status = WbemServiceThread::error;
}
ATLTRACE(_T("marshalled ok\n"));
break;
} //endfor
if(m_AVIbox)
{
PostMessage(m_AVIbox,
WM_ASYNC_CIMOM_CONNECTED,
0, 0);
m_AVIbox = 0;
}
// it marshaled, must still be connected/useable.
return true;
}
break;
// its coming.
case WbemServiceThread::notStarted:
case WbemServiceThread::locating:
case WbemServiceThread::connecting:
{
// let me know when its there.
m_serviceThread->NotifyWhenDone(m_hDlg);
// also kill the cancel box at that time.
m_AVIbox = 0;
m_serviceThread->NotifyWhenDone(m_AVIbox);
if(uCaption != NO_UI)
{
TCHAR caption[100] = {0}, msg[256] = {0};
::LoadString(HINST_THISDLL, uCaption,
caption, 100);
::LoadString(HINST_THISDLL, uWaitMsg,
msg, 256);
m_userCancelled = false;
if(DisplayAVIBox(m_hDlg, caption, msg, &m_AVIbox) == IDCANCEL)
{
m_serviceThread->Cancel();
m_userCancelled = true;
}
}
}
return false;
break;
case WbemServiceThread::error: // cant connect.
case WbemServiceThread::threadError: // cant start that thread.
default:
if(::IsWindow(m_AVIbox))
{
PostMessage(m_AVIbox,
WM_ASYNC_CIMOM_CONNECTED,
0, 0);
m_AVIbox = 0;
}
if(uCaption != NO_UI)
{
DisplayUserMessage(m_hDlg, HINST_THISDLL,
uCaption, BASED_ON_SRC,
ConnectServer,
m_serviceThread->m_hr,
MB_ICONSTOP);
}
return false;
}; //endswitch
}
//----------------------------------------------------
HRESULT WBEMPageHelper::Reboot(UINT flags,
long *retval)
{
HRESULT hr = WBEM_E_PROVIDER_NOT_FOUND;
bstr_t path;
CWbemClassObject paramCls;
// need to class def to get the method signature.
paramCls = m_WbemServices.GetObject("Win32_OperatingSystem");
if(paramCls)
{
// get the method signature. dummy wont actually be used.
CWbemClassObject dummy, inSig;
hr = paramCls.GetMethod(L"Win32Shutdown",
inSig, dummy);
// if got a good signature....
if((bool)inSig)
{
// find the OperatingSystem for the current service ptr.
IWbemClassObject *pInst = NULL;
pInst = FirstInstanceOf("Win32_OperatingSystem");
if(pInst)
{
// wrap it for convenience.
CWbemClassObject OS(pInst);
path = OS.GetString(_T("__PATH"));
// fill in the values.
inSig.Put(_T("Flags"), (const long)flags);
inSig.Put(_T("Reserved"), (long)0);
// adjust privilege.
m_WbemServices.SetPriv(SE_SHUTDOWN_NAME);
// now call the method.
hr = m_WbemServices.ExecMethod(path, L"Win32Shutdown",
inSig, dummy);
m_WbemServices.ClearPriv();
// did the caller want the ReturnValue.
if(SUCCEEDED(hr) && (bool)dummy && retval)
{
// NOTE: this guy return STATUS codes.
*retval = dummy.GetLong(_T("ReturnValue"));
}
}
}
} //endif paramCls
return hr;
}
//---------------------------------------------------------------
bool WBEMPageHelper::HasPriv(LPCTSTR privName)
{
HANDLE hAccessToken = 0;
bool retval = false;
if (ImpersonateSelf(SecurityImpersonation))
{
if(OpenThreadToken(GetCurrentThread(),
TOKEN_QUERY,
FALSE, &hAccessToken))
{
DWORD dwLen;
//Find out the size.
GetTokenInformation(hAccessToken, TokenPrivileges,
NULL, 0, &dwLen);
BYTE* pBuffer = new BYTE[dwLen];
if(pBuffer != NULL)
{
if(GetTokenInformation(hAccessToken, TokenPrivileges,
pBuffer, dwLen, &dwLen))
{
TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
LUID luidTgt;
LookupPrivilegeValue(NULL, privName, &luidTgt);
for(DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
{
if((pPrivs->Privileges[i].Luid.LowPart == luidTgt.LowPart) &&
(pPrivs->Privileges[i].Luid.HighPart == luidTgt.HighPart))
{
retval = true;
break;
}
}
}
delete [] pBuffer;
}
CloseHandle(hAccessToken);
}
else
{
DWORD err = GetLastError();
}
}
else
{
DWORD err = GetLastError();
}
return retval;
}
//---------------------------------------------------------------
bool WBEMPageHelper::HasPerm(DWORD mask)
{
// call the method..
CWbemClassObject _in;
CWbemClassObject _out;
bool retval = true;
// NOTE: for backwards compability with wmi builds that didn't have this
// method, assume 'true' unless a newer build says you cant do this.
HRESULT hr = m_WbemServices.GetMethodSignatures("__SystemSecurity",
"GetCallerAccessRights",
_in, _out);
if(SUCCEEDED(hr))
{
hr = m_WbemServices.ExecMethod("__SystemSecurity",
"GetCallerAccessRights",
_in, _out);
if(SUCCEEDED(hr) && (bool)_out)
{
hr = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
if(SUCCEEDED(hr))
{
DWORD grantedMask = 0;
grantedMask = (DWORD)_out.GetLong("Rights");
retval = (bool)((mask & (DWORD)grantedMask) != 0);
}
}
}
return retval;
}
//--------------------------------------------------------------
HRESULT WBEMPageHelper::RemoteRegWriteable(const _bstr_t regPath,
BOOL& writable)
{
HRESULT hr = E_FAIL;
// if not even connected yet...
if(!(bool)m_defaultNS)
{
bstr_t defaultName;
// already whacked...
if(wcsncmp((wchar_t *)m_serviceThread->m_machineName, _T("\\"), 1) == 0)
{
// use it.
defaultName = m_serviceThread->m_machineName;
defaultName += "\\root\\default";
}
else if(m_serviceThread->m_machineName.length() > 0) // not whacked but remote...
{
// whack it myself.
defaultName = "\\\\";
defaultName += m_serviceThread->m_machineName;
defaultName += "\\root\\default";
}
else // must be local
{
defaultName = "root\\default";
}
m_defaultNS.ConnectServer(defaultName);
}
// do we need the signatures?
if((bool)m_defaultNS && !(bool)m_checkAccessIn)
{
hr = m_defaultNS.GetMethodSignatures("StdRegProv", "CheckAccess",
m_checkAccessIn,
m_checkAccessOut);
}
// got connection and signatures already?
if((bool)m_defaultNS && (bool)m_checkAccessIn)
{
// fill in the parms.
m_checkAccessIn.Put("sSubKeyName", regPath);
m_checkAccessIn.Put("uRequired", KEY_WRITE);
// call.
hr = m_defaultNS.ExecMethod("StdRegProv", "CheckAccess",
m_checkAccessIn,
m_checkAccessOut);
// ExecMethod() itself worked.
if(SUCCEEDED(hr))
{
// did CheckAccess() work.
HRESULT hr1 = HRESULT_FROM_NT(m_checkAccessOut.GetLong("ReturnValue"));
if(FAILED(hr1))
{
hr = hr1;
}
else
{
writable = m_checkAccessOut.GetBool("bGranted");
}
}
}
return hr;
}