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.

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