Source code of Windows XP (NT5)
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.

609 lines
15 KiB

  1. //***************************************************************************
  2. //
  3. // MAIND.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the global EXE functions
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provtempl.h>
  14. #include <provmt.h>
  15. #include <typeinfo.h>
  16. #include <process.h>
  17. #include <objbase.h>
  18. #include <objidl.h>
  19. #include <olectl.h>
  20. #include <initguid.h>
  21. #ifndef INITGUID
  22. #define INITGUID
  23. #endif
  24. #include <stdio.h>
  25. #include <tchar.h>
  26. #include <wbemidl.h>
  27. #include <provcoll.h>
  28. #include <provcont.h>
  29. #include <provevt.h>
  30. #include <provthrd.h>
  31. #include <provlog.h>
  32. #include <dsgetdc.h>
  33. #include <lmcons.h>
  34. #include <instpath.h>
  35. #include <genlex.h>
  36. #include <sql_1.h>
  37. #include <objpath.h>
  38. #include <vpdefs.h>
  39. #include <vpcfac.h>
  40. #include <vpquals.h>
  41. #include <vpserv.h>
  42. #include <vptasks.h>
  43. //OK we need these globals
  44. ProvDebugLog* CViewProvServ::sm_debugLog = NULL;
  45. IUnsecuredApartment* CViewProvServ::sm_UnsecApp = NULL;
  46. CRITICAL_SECTION g_CriticalSection;
  47. HMODULE ghOle32 = NULL;
  48. BOOL s_Exiting = FALSE;
  49. typedef HRESULT (WINAPI* PFNCOINITIALIZEEX)(void* pvReserved, //Reserved
  50. DWORD dwCoInit //COINIT value
  51. );
  52. typedef HRESULT (WINAPI* PFNCOINITIALIZESECURITY)(
  53. PSECURITY_DESCRIPTOR pSecDesc,
  54. LONG cAuthSvc,
  55. SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
  56. void *pReserved1,
  57. DWORD dwAuthnLevel,
  58. DWORD dwImpLevel,
  59. void *pReserved2,
  60. DWORD dwCapabilities,
  61. void *pReserved3 );
  62. HRESULT COMInit();
  63. STDAPI ExeRegisterServer(void);
  64. STDAPI ExeUnregisterServer(void);
  65. CViewProvClassFactory *g_lpunk;
  66. BOOL StartupVP (DWORD *pdwClassFac)
  67. {
  68. InitializeCriticalSection(&g_CriticalSection);
  69. ProvDebugLog::Startup();
  70. CViewProvServ::sm_debugLog = new ProvDebugLog(_T("ViewProvider"));;
  71. g_lpunk = new CViewProvClassFactory;
  72. g_lpunk->AddRef();
  73. HRESULT hr = CoRegisterClassObject(
  74. CLSID_CViewProviderClassFactory, //Class identifier (CLSID) to be registered
  75. (IUnknown *) g_lpunk, //Pointer to the class object
  76. CLSCTX_LOCAL_SERVER, //Context for running executable code
  77. REGCLS_MULTIPLEUSE, //How to connect to the class object
  78. pdwClassFac //Pointer to the value returned
  79. );
  80. return (SUCCEEDED(hr));
  81. }
  82. void ShutdownVP(DWORD dwClassFac)
  83. {
  84. delete CViewProvServ::sm_debugLog;
  85. CViewProvServ::sm_debugLog = NULL;
  86. ProvDebugLog::Closedown();
  87. if (NULL != CViewProvServ::sm_UnsecApp)
  88. {
  89. CViewProvServ::sm_UnsecApp->Release();
  90. CViewProvServ::sm_UnsecApp = NULL;
  91. }
  92. if (g_lpunk)
  93. {
  94. g_lpunk->Release();
  95. }
  96. CoRevokeClassObject(dwClassFac);
  97. DeleteCriticalSection(&g_CriticalSection);
  98. }
  99. BOOL ParseCommandLine ()
  100. {
  101. BOOL t_Exit = FALSE ;
  102. LPTSTR t_CommandLine = GetCommandLine () ;
  103. if ( t_CommandLine )
  104. {
  105. TCHAR *t_Arg = NULL ;
  106. TCHAR *t_ApplicationArg = NULL ;
  107. t_ApplicationArg = _tcstok ( t_CommandLine , _TEXT ( " \t" ) ) ;
  108. t_Arg = _tcstok ( NULL , _TEXT ( " \t" ) ) ;
  109. if ( t_Arg )
  110. {
  111. if ( _tcsicmp ( t_Arg , _TEXT ( "/RegServer" ) ) == 0 )
  112. {
  113. t_Exit = TRUE ;
  114. ExeRegisterServer();
  115. }
  116. else if ( _tcsicmp ( t_Arg , _TEXT ( "/UnRegServer" ) ) == 0 )
  117. {
  118. t_Exit = TRUE ;
  119. ExeUnregisterServer();
  120. }
  121. else if(_tcsicmp(t_Arg, _TEXT ( "/EMBEDDING" ) ) == 0)
  122. {
  123. // COM called us, so this is the real thing...
  124. t_Exit = FALSE;
  125. }
  126. }
  127. }
  128. return t_Exit ;
  129. }
  130. LONG CALLBACK WindowsMainProc ( HWND a_hWnd , UINT a_message , WPARAM a_wParam , LPARAM a_lParam )
  131. {
  132. long t_rc = 0 ;
  133. switch ( a_message )
  134. {
  135. case WM_CLOSE:
  136. {
  137. s_Exiting = TRUE ;
  138. }
  139. break ;
  140. case WM_DESTROY:
  141. {
  142. PostMessage ( a_hWnd , WM_QUIT , 0 , 0 ) ;
  143. }
  144. break ;
  145. default:
  146. {
  147. t_rc = DefWindowProc ( a_hWnd , a_message , a_wParam , a_lParam ) ;
  148. }
  149. break ;
  150. }
  151. return ( t_rc ) ;
  152. }
  153. HWND WindowsInit ( HINSTANCE a_HInstance )
  154. {
  155. static TCHAR *t_TemplateCode = _TEXT("TemplateCode - View Provider") ;
  156. WNDCLASS t_wc ;
  157. t_wc.style = CS_HREDRAW | CS_VREDRAW ;
  158. t_wc.lpfnWndProc = WindowsMainProc ;
  159. t_wc.cbClsExtra = 0 ;
  160. t_wc.cbWndExtra = 0 ;
  161. t_wc.hInstance = a_HInstance ;
  162. t_wc.hIcon = LoadIcon(NULL, IDI_HAND) ;
  163. t_wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  164. t_wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  165. t_wc.lpszMenuName = NULL ;
  166. t_wc.lpszClassName = t_TemplateCode ;
  167. ATOM t_winClass = RegisterClass ( &t_wc ) ;
  168. HWND t_HWnd = CreateWindow (
  169. t_TemplateCode , // see RegisterClass() call
  170. t_TemplateCode , // text for window title bar
  171. WS_OVERLAPPEDWINDOW , // window style
  172. CW_USEDEFAULT , // default horizontal position
  173. CW_USEDEFAULT , // default vertical position
  174. CW_USEDEFAULT , // default width
  175. CW_USEDEFAULT , // default height
  176. NULL , // overlapped windows have no parent
  177. NULL , // use the window class menu
  178. a_HInstance ,
  179. NULL // pointer not needed
  180. ) ;
  181. if (t_HWnd)
  182. {
  183. ShowWindow ( t_HWnd, SW_SHOW ) ;
  184. }
  185. return t_HWnd ;
  186. }
  187. void WindowsStop ( HWND a_HWnd )
  188. {
  189. DestroyWindow ( a_HWnd ) ;
  190. }
  191. HWND WindowsStart ( HINSTANCE a_Handle )
  192. {
  193. HWND t_HWnd = WindowsInit(a_Handle);
  194. return t_HWnd;
  195. }
  196. void WindowsDispatch ()
  197. {
  198. BOOL t_GetMessage ;
  199. MSG t_lpMsg ;
  200. while ( ( t_GetMessage = GetMessage ( & t_lpMsg , NULL , 0 , 0 ) ) == TRUE )
  201. {
  202. TranslateMessage ( & t_lpMsg ) ;
  203. DispatchMessage ( & t_lpMsg ) ;
  204. if ( s_Exiting )
  205. return ;
  206. }
  207. }
  208. int WINAPI WinMain (
  209. HINSTANCE hInstance, // handle to current instance
  210. HINSTANCE hPrevInstance, // handle to previous instance
  211. LPSTR lpCmdLine, // pointer to command line
  212. int nShowCmd // show state of window
  213. )
  214. {
  215. BOOL t_Exit = ParseCommandLine();
  216. if (!t_Exit)
  217. {
  218. // Initialize the COM Library.
  219. HRESULT hr = COMInit();
  220. HWND hWnd = WindowsStart(hInstance);
  221. if (hWnd)
  222. {
  223. DWORD dw = 0;
  224. if (StartupVP(&dw))
  225. {
  226. WindowsDispatch();
  227. ShutdownVP(dw);
  228. }
  229. WindowsStop(hWnd);
  230. }
  231. // Uninitialize the COM Library.
  232. ::CoUninitialize() ;
  233. }
  234. return 0 ;
  235. }
  236. //Strings used during self registeration
  237. #define REG_FORMAT2_STR _T("%s%s")
  238. #define REG_FORMAT3_STR _T("%s%s\\%s")
  239. #define VER_IND_STR _T("VersionIndependentProgID")
  240. #define NOT_INTERT_STR _T("NotInsertable")
  241. #define LOCALSRV32_STR _T("LocalServer32")
  242. #define PROGID_STR _T("ProgID")
  243. #define THREADING_MODULE_STR _T("ThreadingModel")
  244. #define APARTMENT_STR _T("Both")
  245. #define CLSID_STR _T("CLSID\\")
  246. #define PROVIDER_NAME_STR _T("Microsoft WBEM View Provider")
  247. #define PROVIDER_STR _T("WBEM.VIEW.PROVIDER")
  248. #define PROVIDER_CVER_STR _T("WBEM.VIEW.PROVIDER\\CurVer")
  249. #define PROVIDER_CLSID_STR _T("WBEM.VIEW.PROVIDER\\CLSID")
  250. #define PROVIDER_VER_CLSID_STR _T("WBEM.VIEW.PROVIDER.0\\CLSID")
  251. #define PROVIDER_VER_STR _T("WBEM.VIEW.PROVIDER.0")
  252. /***************************************************************************
  253. * SetKeyAndValue
  254. *
  255. * Purpose:
  256. * Private helper function for DllRegisterServer that creates
  257. * a key, sets a value, and closes that key.
  258. *
  259. * Parameters:
  260. * pszKey LPTSTR to the ame of the key
  261. * pszSubkey LPTSTR ro the name of a subkey
  262. * pszValue LPTSTR to the value to store
  263. *
  264. * Return Value:
  265. * BOOL TRUE if successful, FALSE otherwise.
  266. ***************************************************************************/
  267. BOOL SetKeyAndValue(TCHAR* pszKey, TCHAR* pszSubkey, TCHAR* pszValueName, TCHAR* pszValue)
  268. {
  269. HKEY hKey;
  270. TCHAR szKey[256];
  271. _tcscpy(szKey, HKEYCLASSES);
  272. _tcscat(szKey, pszKey);
  273. if (NULL!=pszSubkey)
  274. {
  275. _tcscat(szKey, _T("\\"));
  276. _tcscat(szKey, pszSubkey);
  277. }
  278. if (ERROR_SUCCESS!=RegCreateKeyEx(HKEY_LOCAL_MACHINE
  279. , szKey, 0, NULL, REG_OPTION_NON_VOLATILE
  280. , KEY_ALL_ACCESS, NULL, &hKey, NULL))
  281. return FALSE;
  282. if (NULL!=pszValue)
  283. {
  284. if (ERROR_SUCCESS != RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (BYTE *)pszValue
  285. , (_tcslen(pszValue)+1)*sizeof(TCHAR)))
  286. return FALSE;
  287. }
  288. RegCloseKey(hKey);
  289. return TRUE;
  290. }
  291. //***************************************************************************
  292. //
  293. // ExeRegisterServer
  294. //
  295. // Purpose: Called when /register is specified on the command line.
  296. //
  297. // Return: NOERROR if registration successful, error otherwise.
  298. //***************************************************************************
  299. STDAPI ExeRegisterServer(void)
  300. {
  301. TCHAR szModule[MAX_PATH + 1];
  302. HINSTANCE hInst = GetModuleHandle(_T("VIEWPROV"));
  303. GetModuleFileName(hInst,(TCHAR*)szModule, MAX_PATH + 1);
  304. TCHAR szProviderClassID[128];
  305. TCHAR szProviderCLSIDClassID[128];
  306. #ifndef UNICODE
  307. wchar_t t_strGUID[128];
  308. if (0 == StringFromGUID2(CLSID_CViewProviderClassFactory, t_strGUID, 128))
  309. {
  310. return SELFREG_E_CLASS;
  311. }
  312. if (0 == WideCharToMultiByte(CP_ACP,
  313. 0,
  314. t_strGUID,
  315. -1,
  316. szProviderClassID,
  317. 128,
  318. NULL,
  319. NULL))
  320. {
  321. return SELFREG_E_CLASS;
  322. }
  323. #else
  324. if (0 == StringFromGUID2(CLSID_CViewProviderClassFactory, szProviderClassID, 128))
  325. {
  326. return SELFREG_E_CLASS;
  327. }
  328. #endif
  329. _tcscpy(szProviderCLSIDClassID,CLSID_STR);
  330. _tcscat(szProviderCLSIDClassID,szProviderClassID);
  331. //Create entries under CLSID
  332. if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, NULL, NULL, PROVIDER_NAME_STR))
  333. return SELFREG_E_CLASS;
  334. if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, PROGID_STR, NULL, PROVIDER_VER_STR))
  335. return SELFREG_E_CLASS;
  336. if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, VER_IND_STR, NULL, PROVIDER_STR))
  337. return SELFREG_E_CLASS;
  338. if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, NOT_INTERT_STR, NULL, NULL))
  339. return SELFREG_E_CLASS;
  340. if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, LOCALSRV32_STR, NULL,szModule))
  341. return SELFREG_E_CLASS;
  342. if (FALSE ==SetKeyAndValue(szProviderCLSIDClassID, LOCALSRV32_STR,THREADING_MODULE_STR, APARTMENT_STR))
  343. return SELFREG_E_CLASS;
  344. return S_OK;
  345. }
  346. //***************************************************************************
  347. //
  348. // ExeUnregisterServer
  349. //
  350. // Purpose: Called when /unregister is specified on the command line.
  351. //
  352. // Return: NOERROR if registration successful, error otherwise.
  353. //***************************************************************************
  354. STDAPI ExeUnregisterServer(void)
  355. {
  356. TCHAR szTemp[128];
  357. TCHAR szProviderClassID[128];
  358. TCHAR szProviderCLSIDClassID[128];
  359. #ifndef UNICODE
  360. wchar_t t_strGUID[128];
  361. if (0 == StringFromGUID2(CLSID_CViewProviderClassFactory, t_strGUID, 128))
  362. {
  363. return SELFREG_E_CLASS;
  364. }
  365. if (0 == WideCharToMultiByte(CP_ACP,
  366. 0,
  367. t_strGUID,
  368. -1,
  369. szProviderClassID,
  370. 128,
  371. NULL,
  372. NULL))
  373. {
  374. return SELFREG_E_CLASS;
  375. }
  376. #else
  377. if (0 == StringFromGUID2(CLSID_CViewProviderClassFactory, szProviderClassID, 128))
  378. {
  379. return SELFREG_E_CLASS;
  380. }
  381. #endif
  382. HRESULT hr = S_OK;
  383. _tcscpy(szProviderCLSIDClassID,CLSID_STR);
  384. _tcscat(szProviderCLSIDClassID,szProviderClassID);
  385. //Delete ProgID keys
  386. _stprintf(szTemp, REG_FORMAT2_STR, HKEYCLASSES, PROVIDER_CVER_STR);
  387. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  388. {
  389. hr = SELFREG_E_CLASS;
  390. }
  391. _stprintf(szTemp, REG_FORMAT2_STR, HKEYCLASSES, PROVIDER_CLSID_STR);
  392. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  393. {
  394. hr = SELFREG_E_CLASS;
  395. }
  396. _stprintf(szTemp, REG_FORMAT2_STR, HKEYCLASSES, PROVIDER_STR);
  397. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  398. {
  399. hr = SELFREG_E_CLASS;
  400. }
  401. //Delete VersionIndependentProgID keys
  402. _stprintf(szTemp, REG_FORMAT2_STR, HKEYCLASSES, PROVIDER_VER_CLSID_STR);
  403. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  404. {
  405. hr = SELFREG_E_CLASS;
  406. }
  407. _stprintf(szTemp, REG_FORMAT2_STR, HKEYCLASSES, PROVIDER_VER_STR);
  408. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  409. {
  410. hr = SELFREG_E_CLASS;
  411. }
  412. //Delete entries under CLSID
  413. _stprintf(szTemp, REG_FORMAT3_STR, HKEYCLASSES, szProviderCLSIDClassID, PROGID_STR);
  414. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  415. {
  416. hr = SELFREG_E_CLASS;
  417. }
  418. _stprintf(szTemp, REG_FORMAT3_STR, HKEYCLASSES, szProviderCLSIDClassID, VER_IND_STR);
  419. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  420. {
  421. hr = SELFREG_E_CLASS;
  422. }
  423. _stprintf(szTemp, REG_FORMAT3_STR, HKEYCLASSES, szProviderCLSIDClassID, NOT_INTERT_STR);
  424. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  425. {
  426. hr = SELFREG_E_CLASS;
  427. }
  428. _stprintf(szTemp, REG_FORMAT3_STR, HKEYCLASSES, szProviderCLSIDClassID, LOCALSRV32_STR);
  429. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  430. {
  431. hr = SELFREG_E_CLASS;
  432. }
  433. _stprintf(szTemp, REG_FORMAT2_STR, HKEYCLASSES, szProviderCLSIDClassID);
  434. if (ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp))
  435. {
  436. hr = SELFREG_E_CLASS;
  437. }
  438. return hr;
  439. }
  440. /////////////////////////////////////////////////////////////////////////////
  441. HRESULT COMInit()
  442. {
  443. HRESULT hr;
  444. PFNCOINITIALIZESECURITY pfnCoInitializeSecurity = NULL;
  445. PFNCOINITIALIZEEX pfnCoInitializeEx = NULL;
  446. //Get handle to COM library
  447. ghOle32 = LoadLibraryEx(_T("ole32.dll"), NULL, 0);
  448. if(ghOle32 != NULL)
  449. {
  450. //Get ptr to functions CoInitialize and CoInitializeSecurity.
  451. pfnCoInitializeEx = (PFNCOINITIALIZEEX) GetProcAddress(ghOle32,
  452. "CoInitializeEx");
  453. pfnCoInitializeSecurity = (PFNCOINITIALIZESECURITY) GetProcAddress(ghOle32,
  454. "CoInitializeSecurity");
  455. //Initialize COM
  456. if (pfnCoInitializeEx)
  457. {
  458. hr = pfnCoInitializeEx(NULL, COINIT_MULTITHREADED);
  459. }
  460. else
  461. {
  462. hr = CoInitialize(NULL);
  463. }
  464. if(FAILED(hr))
  465. {
  466. FreeLibrary(ghOle32);
  467. ghOle32 = NULL;
  468. return E_FAIL;
  469. }
  470. //Initialize Security
  471. if (pfnCoInitializeSecurity)
  472. {
  473. hr = pfnCoInitializeSecurity(NULL, -1, NULL, NULL,
  474. RPC_C_AUTHN_LEVEL_CONNECT,
  475. RPC_C_IMP_LEVEL_IMPERSONATE,
  476. NULL, EOAC_NONE, 0);
  477. }
  478. if(FAILED(hr))
  479. {
  480. CoUninitialize();
  481. FreeLibrary(ghOle32);
  482. ghOle32 = NULL;
  483. return E_FAIL;
  484. }
  485. }
  486. else
  487. {
  488. return E_FAIL;
  489. }
  490. return S_OK;
  491. }