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

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. #include "precomp.h"
  3. #include "..\MMFUtil\MsgDlg.h"
  4. #ifdef EXT_DEBUG
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. #include "util.h"
  9. #include "..\Common\ServiceThread.h"
  10. #include "WBEMPageHelper.h"
  11. #include <stdarg.h>
  12. BOOL WBEMPageHelper::g_fRebootRequired = FALSE;
  13. //------------------------------------------------
  14. WBEMPageHelper::WBEMPageHelper(CWbemServices &service)
  15. {
  16. m_service = 0;
  17. m_WbemServices = service;
  18. m_WbemServices.GetServices(&m_service);
  19. m_WbemServices.SetBlanket(m_service);
  20. m_okPressed = false;
  21. m_userCancelled = false;
  22. m_hDlg = NULL;
  23. m_AVIbox = 0;
  24. }
  25. //------------------------------------------------
  26. WBEMPageHelper::WBEMPageHelper(WbemServiceThread *serviceThread)
  27. {
  28. m_serviceThread = serviceThread;
  29. if (m_serviceThread)
  30. m_serviceThread->AddRef();
  31. m_service = 0;
  32. if(m_serviceThread->m_status == WbemServiceThread::ready)
  33. {
  34. m_WbemServices = m_serviceThread->m_WbemServices;
  35. m_WbemServices.GetServices(&m_service);
  36. m_WbemServices.SetBlanket(m_service);
  37. }
  38. m_okPressed = false;
  39. m_userCancelled = false;
  40. m_hDlg = NULL;
  41. m_AVIbox = 0;
  42. }
  43. //------------------------------------------------
  44. WBEMPageHelper::~WBEMPageHelper()
  45. {
  46. // in case ServiceThread still has a ptr to this
  47. // handle. It knows not to use NULL HWNDs.
  48. m_AVIbox = 0;
  49. m_hDlg = NULL;
  50. if(m_service)
  51. {
  52. m_service->Release();
  53. m_service = 0;
  54. }
  55. m_WbemServices.DisconnectServer();
  56. if (m_serviceThread)
  57. m_serviceThread->Release();
  58. }
  59. //------------------------------------------------
  60. CWbemClassObject WBEMPageHelper::ExchangeInstance(IWbemClassObject **ppbadInst)
  61. {
  62. CWbemClassObject inst;
  63. _variant_t v1;
  64. if(SUCCEEDED((*ppbadInst)->Get(bstr_t("__PATH"), 0, &v1, NULL, NULL)))
  65. {
  66. inst = m_WbemServices.GetObject((_bstr_t) v1);
  67. (*ppbadInst)->Release();
  68. *ppbadInst = NULL;
  69. }
  70. return inst;
  71. }
  72. //------------------------------------------------
  73. // get the first instance of the named class.
  74. IWbemClassObject *WBEMPageHelper::FirstInstanceOf(bstr_t className)
  75. {
  76. IWbemClassObject *pInst = NULL;
  77. ULONG uReturned;
  78. IEnumWbemClassObject *Enum = NULL;
  79. // get the class.
  80. if(SUCCEEDED(m_WbemServices.CreateInstanceEnum(className,
  81. WBEM_FLAG_SHALLOW,
  82. &Enum)))
  83. {
  84. // get the first and only instance.
  85. Enum->Next(-1, 1, &pInst, &uReturned);
  86. Enum->Release();
  87. }
  88. return pInst;
  89. }
  90. //---------------------------------------------------
  91. LPTSTR WBEMPageHelper::CloneString( LPTSTR pszSrc )
  92. {
  93. LPTSTR pszDst = NULL;
  94. if (pszSrc != NULL)
  95. {
  96. pszDst = new TCHAR[(lstrlen(pszSrc) + 1)];
  97. if (pszDst)
  98. {
  99. lstrcpy( pszDst, pszSrc );
  100. }
  101. }
  102. return pszDst;
  103. }
  104. //*************************************************************
  105. //
  106. // SetClearBitmap()
  107. //
  108. // Purpose: Sets or clears an image in a static control.
  109. //
  110. // Parameters: control - handle of static control
  111. // resource - resource / filename of bitmap
  112. // fl - SCB_ flags:
  113. // SCB_FROMFILE 'resource' specifies a filename instead of a resource
  114. // SCB_REPLACEONLY only put the new image up if there was an old one
  115. //
  116. //
  117. // Return: (BOOL) TRUE if successful
  118. // FALSE if an error occurs
  119. //
  120. //
  121. // Comments:
  122. //
  123. //
  124. // History: Date Author Comment
  125. // 5/24/95 ericflo Ported
  126. //
  127. //*************************************************************
  128. BOOL WBEMPageHelper::SetClearBitmap( HWND control,
  129. LPCTSTR resource,
  130. UINT fl )
  131. {
  132. HBITMAP hbm = (HBITMAP)SendMessage(control, STM_GETIMAGE, IMAGE_BITMAP, 0);
  133. if( hbm )
  134. {
  135. DeleteObject( hbm );
  136. }
  137. else if( fl & SCB_REPLACEONLY )
  138. {
  139. return FALSE;
  140. }
  141. if( resource )
  142. {
  143. SendMessage(control, STM_SETIMAGE, IMAGE_BITMAP,
  144. (LPARAM)LoadImage( HINST_THISDLL,
  145. resource,
  146. IMAGE_BITMAP,
  147. 0, 0,
  148. LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS |
  149. ( ( fl & SCB_FROMFILE )? LR_LOADFROMFILE : 0 ) )
  150. );
  151. }
  152. return
  153. ((HBITMAP)SendMessage(control, STM_GETIMAGE, IMAGE_BITMAP, 0) != NULL);
  154. }
  155. //------------------------------------------------------------
  156. int WBEMPageHelper::MsgBoxParam(HWND hWnd,
  157. DWORD wText,
  158. DWORD wCaption,
  159. DWORD wType,
  160. LPTSTR var1,
  161. LPTSTR var2)
  162. {
  163. TCHAR szText[ 4 * MAX_PATH ] = {0}, szCaption[ 2 * MAX_PATH ] = {0};
  164. int ival;
  165. if( !LoadString( HINST_THISDLL, wText, szCaption, ARRAYSIZE( szCaption ) ) )
  166. {
  167. return 0;
  168. }
  169. if(var2)
  170. _snwprintf(szText, 4 * MAX_PATH, szCaption, var1, var2);
  171. else if(var1)
  172. _snwprintf(szText, 4 * MAX_PATH, szCaption, var1);
  173. else
  174. _snwprintf(szText, 4 * MAX_PATH, szCaption);
  175. if( !LoadString( HINST_THISDLL, wCaption, szCaption, ARRAYSIZE( szCaption ) ) )
  176. {
  177. return 0;
  178. }
  179. ival = MessageBox( hWnd, szText, szCaption, wType);
  180. return ival;
  181. }
  182. //------------------------------------------------------------
  183. void WBEMPageHelper::HourGlass( bool bOn )
  184. {
  185. if( !GetSystemMetrics( SM_MOUSEPRESENT ) )
  186. ShowCursor( bOn );
  187. SetCursor( LoadCursor( NULL, bOn ? IDC_WAIT : IDC_ARROW ) );
  188. }
  189. ////////////////////////////////////////////////////////////////////////////
  190. // SetLBWidthEx
  191. //
  192. // Set the width of the listbox, in pixels, acording to the size of the
  193. // string passed in.
  194. //
  195. // Note: this function is also used by the Virtual Memory dialog
  196. //
  197. // History:
  198. // 11-Jan-1996 JonPa Created from SetGenLBWidth
  199. ////////////////////////////////////////////////////////////////////////////
  200. DWORD WBEMPageHelper::SetLBWidthEx( HWND hwndLB,
  201. LPTSTR szBuffer,
  202. DWORD cxCurWidth,
  203. DWORD cxExtra)
  204. {
  205. HDC hDC;
  206. SIZE Size;
  207. HFONT hfont, hfontOld;
  208. // Get the new Win4.0 thin dialog font
  209. hfont = (HFONT)SendMessage(hwndLB, WM_GETFONT, 0, 0);
  210. hDC = GetDC(hwndLB);
  211. // if we got a font back, select it in this clean hDC
  212. if (hfont != NULL)
  213. hfontOld = (HFONT)SelectObject(hDC, hfont);
  214. // If cxExtra is 0, then give our selves a little breathing space.
  215. if (cxExtra == 0)
  216. {
  217. GetTextExtentPoint(hDC, TEXT("1234"), 4 , &Size);
  218. cxExtra = Size.cx;
  219. }
  220. // Set scroll width of listbox
  221. GetTextExtentPoint(hDC, szBuffer, lstrlen(szBuffer), &Size);
  222. Size.cx += cxExtra;
  223. // Get the name length and adjust the longest name
  224. if ((DWORD) Size.cx > cxCurWidth)
  225. {
  226. cxCurWidth = Size.cx;
  227. SendMessage (hwndLB, LB_SETHORIZONTALEXTENT, (DWORD)Size.cx, 0L);
  228. }
  229. // retstore the original font if we changed it.
  230. if (hfont != NULL)
  231. SelectObject(hDC, hfontOld);
  232. ReleaseDC(NULL, hDC);
  233. return cxCurWidth;
  234. return 1; // bs
  235. }
  236. //---------------------------------------------------
  237. void WBEMPageHelper::SetDefButton(HWND hwndDlg,
  238. int idButton)
  239. {
  240. LRESULT lr;
  241. if(HIWORD(lr = SendMessage(hwndDlg, DM_GETDEFID, 0, 0)) == DC_HASDEFID)
  242. {
  243. HWND hwndOldDefButton = GetDlgItem(hwndDlg, LOWORD(lr));
  244. SendMessage (hwndOldDefButton,
  245. BM_SETSTYLE,
  246. MAKEWPARAM(BS_PUSHBUTTON, 0),
  247. MAKELPARAM(TRUE, 0));
  248. }
  249. SendMessage( hwndDlg, DM_SETDEFID, idButton, 0L );
  250. SendMessage( GetDlgItem(hwndDlg, idButton),
  251. BM_SETSTYLE,
  252. MAKEWPARAM( BS_DEFPUSHBUTTON, 0 ),
  253. MAKELPARAM( TRUE, 0 ));
  254. }
  255. //-------------------------------------------------------------------
  256. void WBEMPageHelper::SetDlgItemMB( HWND hDlg,
  257. int idControl,
  258. ULONG dwMBValue )
  259. {
  260. TCHAR szBuf[20] = {0};
  261. wsprintf(szBuf, _T("%u MB"), dwMBValue);
  262. SetDlgItemText(hDlg, idControl, szBuf);
  263. }
  264. //--------------------------------------------------------------
  265. void WBEMPageHelper::SetWbemService(IWbemServices *pServices)
  266. {
  267. m_serviceThread->m_realServices = pServices;
  268. m_serviceThread->m_WbemServices = pServices;
  269. m_WbemServices = pServices;
  270. }
  271. //--------------------------------------------------------------
  272. bool WBEMPageHelper::ServiceIsReady(UINT uCaption /* = 0*/,
  273. UINT uWaitMsg,
  274. UINT uBadMsg)
  275. {
  276. switch(m_serviceThread->m_status)
  277. {
  278. // its already there.
  279. case WbemServiceThread::ready:
  280. {
  281. ATLTRACE(L"start marshal\n");
  282. for(int i = 0; (i < 5); i++)
  283. {
  284. // if "Object is not connected to server"
  285. if(m_serviceThread->m_hr == 0x800401fd)
  286. {
  287. // lost my connection,
  288. ATLTRACE(_T("Reconnecting to cimom!!!!!!!!!!!\n"));
  289. m_serviceThread->ReConnect();
  290. ATLTRACE(_T("new service status: %d\n"), m_serviceThread->m_status);
  291. continue;
  292. }
  293. else if(FAILED(m_serviceThread->m_hr))
  294. {
  295. // some other problem.
  296. m_serviceThread->m_WbemServices = (IWbemServices *)NULL;
  297. m_serviceThread->m_status = WbemServiceThread::error;
  298. }
  299. ATLTRACE(_T("marshalled ok\n"));
  300. break;
  301. } //endfor
  302. if(m_AVIbox)
  303. {
  304. PostMessage(m_AVIbox,
  305. WM_ASYNC_CIMOM_CONNECTED,
  306. 0, 0);
  307. m_AVIbox = 0;
  308. }
  309. // it marshaled, must still be connected/useable.
  310. return true;
  311. }
  312. break;
  313. // its coming.
  314. case WbemServiceThread::notStarted:
  315. case WbemServiceThread::locating:
  316. case WbemServiceThread::connecting:
  317. {
  318. // let me know when its there.
  319. m_serviceThread->NotifyWhenDone(m_hDlg);
  320. // also kill the cancel box at that time.
  321. m_AVIbox = 0;
  322. m_serviceThread->NotifyWhenDone(m_AVIbox);
  323. if(uCaption != NO_UI)
  324. {
  325. TCHAR caption[100] = {0}, msg[256] = {0};
  326. ::LoadString(HINST_THISDLL, uCaption,
  327. caption, 100);
  328. ::LoadString(HINST_THISDLL, uWaitMsg,
  329. msg, 256);
  330. m_userCancelled = false;
  331. if(DisplayAVIBox(m_hDlg, caption, msg, &m_AVIbox) == IDCANCEL)
  332. {
  333. m_serviceThread->Cancel();
  334. m_userCancelled = true;
  335. }
  336. }
  337. }
  338. return false;
  339. break;
  340. case WbemServiceThread::error: // cant connect.
  341. case WbemServiceThread::threadError: // cant start that thread.
  342. default:
  343. if(::IsWindow(m_AVIbox))
  344. {
  345. PostMessage(m_AVIbox,
  346. WM_ASYNC_CIMOM_CONNECTED,
  347. 0, 0);
  348. m_AVIbox = 0;
  349. }
  350. if(uCaption != NO_UI)
  351. {
  352. DisplayUserMessage(m_hDlg, HINST_THISDLL,
  353. uCaption, BASED_ON_SRC,
  354. ConnectServer,
  355. m_serviceThread->m_hr,
  356. MB_ICONSTOP);
  357. }
  358. return false;
  359. }; //endswitch
  360. }
  361. //----------------------------------------------------
  362. HRESULT WBEMPageHelper::Reboot(UINT flags,
  363. long *retval)
  364. {
  365. HRESULT hr = WBEM_E_PROVIDER_NOT_FOUND;
  366. bstr_t path;
  367. CWbemClassObject paramCls;
  368. // need to class def to get the method signature.
  369. paramCls = m_WbemServices.GetObject("Win32_OperatingSystem");
  370. if(paramCls)
  371. {
  372. // get the method signature. dummy wont actually be used.
  373. CWbemClassObject dummy, inSig;
  374. hr = paramCls.GetMethod(L"Win32Shutdown",
  375. inSig, dummy);
  376. // if got a good signature....
  377. if((bool)inSig)
  378. {
  379. // find the OperatingSystem for the current service ptr.
  380. IWbemClassObject *pInst = NULL;
  381. pInst = FirstInstanceOf("Win32_OperatingSystem");
  382. if(pInst)
  383. {
  384. // wrap it for convenience.
  385. CWbemClassObject OS(pInst);
  386. path = OS.GetString(_T("__PATH"));
  387. // fill in the values.
  388. inSig.Put(_T("Flags"), (const long)flags);
  389. inSig.Put(_T("Reserved"), (long)0);
  390. // adjust privilege.
  391. m_WbemServices.SetPriv(SE_SHUTDOWN_NAME);
  392. // now call the method.
  393. hr = m_WbemServices.ExecMethod(path, L"Win32Shutdown",
  394. inSig, dummy);
  395. m_WbemServices.ClearPriv();
  396. // did the caller want the ReturnValue.
  397. if(SUCCEEDED(hr) && (bool)dummy && retval)
  398. {
  399. // NOTE: this guy return STATUS codes.
  400. *retval = dummy.GetLong(_T("ReturnValue"));
  401. }
  402. }
  403. }
  404. } //endif paramCls
  405. return hr;
  406. }
  407. //---------------------------------------------------------------
  408. bool WBEMPageHelper::HasPriv(LPCTSTR privName)
  409. {
  410. HANDLE hAccessToken = 0;
  411. bool retval = false;
  412. if (ImpersonateSelf(SecurityImpersonation))
  413. {
  414. if(OpenThreadToken(GetCurrentThread(),
  415. TOKEN_QUERY,
  416. FALSE, &hAccessToken))
  417. {
  418. DWORD dwLen;
  419. //Find out the size.
  420. GetTokenInformation(hAccessToken, TokenPrivileges,
  421. NULL, 0, &dwLen);
  422. BYTE* pBuffer = new BYTE[dwLen];
  423. if(pBuffer != NULL)
  424. {
  425. if(GetTokenInformation(hAccessToken, TokenPrivileges,
  426. pBuffer, dwLen, &dwLen))
  427. {
  428. TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
  429. LUID luidTgt;
  430. LookupPrivilegeValue(NULL, privName, &luidTgt);
  431. for(DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
  432. {
  433. if((pPrivs->Privileges[i].Luid.LowPart == luidTgt.LowPart) &&
  434. (pPrivs->Privileges[i].Luid.HighPart == luidTgt.HighPart))
  435. {
  436. retval = true;
  437. break;
  438. }
  439. }
  440. }
  441. delete [] pBuffer;
  442. }
  443. CloseHandle(hAccessToken);
  444. }
  445. else
  446. {
  447. DWORD err = GetLastError();
  448. }
  449. }
  450. else
  451. {
  452. DWORD err = GetLastError();
  453. }
  454. return retval;
  455. }
  456. //---------------------------------------------------------------
  457. bool WBEMPageHelper::HasPerm(DWORD mask)
  458. {
  459. // call the method..
  460. CWbemClassObject _in;
  461. CWbemClassObject _out;
  462. bool retval = true;
  463. // NOTE: for backwards compability with wmi builds that didn't have this
  464. // method, assume 'true' unless a newer build says you cant do this.
  465. HRESULT hr = m_WbemServices.GetMethodSignatures("__SystemSecurity",
  466. "GetCallerAccessRights",
  467. _in, _out);
  468. if(SUCCEEDED(hr))
  469. {
  470. hr = m_WbemServices.ExecMethod("__SystemSecurity",
  471. "GetCallerAccessRights",
  472. _in, _out);
  473. if(SUCCEEDED(hr) && (bool)_out)
  474. {
  475. hr = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
  476. if(SUCCEEDED(hr))
  477. {
  478. DWORD grantedMask = 0;
  479. grantedMask = (DWORD)_out.GetLong("Rights");
  480. retval = (bool)((mask & (DWORD)grantedMask) != 0);
  481. }
  482. }
  483. }
  484. return retval;
  485. }
  486. //--------------------------------------------------------------
  487. HRESULT WBEMPageHelper::RemoteRegWriteable(const _bstr_t regPath,
  488. BOOL& writable)
  489. {
  490. HRESULT hr = E_FAIL;
  491. // if not even connected yet...
  492. if(!(bool)m_defaultNS)
  493. {
  494. bstr_t defaultName;
  495. // already whacked...
  496. if(wcsncmp((wchar_t *)m_serviceThread->m_machineName, _T("\\"), 1) == 0)
  497. {
  498. // use it.
  499. defaultName = m_serviceThread->m_machineName;
  500. defaultName += "\\root\\default";
  501. }
  502. else if(m_serviceThread->m_machineName.length() > 0) // not whacked but remote...
  503. {
  504. // whack it myself.
  505. defaultName = "\\\\";
  506. defaultName += m_serviceThread->m_machineName;
  507. defaultName += "\\root\\default";
  508. }
  509. else // must be local
  510. {
  511. defaultName = "root\\default";
  512. }
  513. m_defaultNS.ConnectServer(defaultName);
  514. }
  515. // do we need the signatures?
  516. if((bool)m_defaultNS && !(bool)m_checkAccessIn)
  517. {
  518. hr = m_defaultNS.GetMethodSignatures("StdRegProv", "CheckAccess",
  519. m_checkAccessIn,
  520. m_checkAccessOut);
  521. }
  522. // got connection and signatures already?
  523. if((bool)m_defaultNS && (bool)m_checkAccessIn)
  524. {
  525. // fill in the parms.
  526. m_checkAccessIn.Put("sSubKeyName", regPath);
  527. m_checkAccessIn.Put("uRequired", KEY_WRITE);
  528. // call.
  529. hr = m_defaultNS.ExecMethod("StdRegProv", "CheckAccess",
  530. m_checkAccessIn,
  531. m_checkAccessOut);
  532. // ExecMethod() itself worked.
  533. if(SUCCEEDED(hr))
  534. {
  535. // did CheckAccess() work.
  536. HRESULT hr1 = HRESULT_FROM_NT(m_checkAccessOut.GetLong("ReturnValue"));
  537. if(FAILED(hr1))
  538. {
  539. hr = hr1;
  540. }
  541. else
  542. {
  543. writable = m_checkAccessOut.GetBool("bGranted");
  544. }
  545. }
  546. }
  547. return hr;
  548. }