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.

699 lines
20 KiB

  1. //
  2. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  3. //
  4. //***************************************************************************
  5. //
  6. // MAIND.CPP
  7. //
  8. // Module: WBEM VIEW PROVIDER
  9. //
  10. // Purpose: Contains the global EXE functions
  11. //
  12. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  13. //
  14. //***************************************************************************
  15. #include <tchar.h>
  16. #include <stdio.h>
  17. #include <windows.h>
  18. #include <objbase.h>
  19. #include <olectl.h>
  20. /* WBEM includes */
  21. #include <wbemcli.h>
  22. #include <wbemprov.h>
  23. #include <genlex.h>
  24. #include <opathlex.h>
  25. #include <objpath.h>
  26. #include <sqllex.h>
  27. #include <sql_1.h>
  28. /* ADSI includes */
  29. #include <activeds.h>
  30. /* DS Provider includes */
  31. #include "provlog.h"
  32. #include "maindll.h"
  33. #include "clsname.h"
  34. #include <initguid.h>
  35. #include "dscpguid.h"
  36. #include "dsipguid.h"
  37. #include "refcount.h"
  38. #include "adsiprop.h"
  39. #include "adsiclas.h"
  40. #include "adsiinst.h"
  41. #include "provlog.h"
  42. #include "provexpt.h"
  43. #include "tree.h"
  44. #include "ldapcach.h"
  45. #include "wbemcach.h"
  46. #include "classpro.h"
  47. #include "ldapprov.h"
  48. #include "clsproi.h"
  49. #include "ldapproi.h"
  50. #include "classfac.h"
  51. #include "instprov.h"
  52. #include "instproi.h"
  53. #include "instfac.h"
  54. // Count of locks
  55. long g_lComponents = 0;
  56. // Count of active locks
  57. long g_lServerLocks = 0;
  58. // A critical section to create/delete statics
  59. CRITICAL_SECTION g_StaticsCreationDeletion;
  60. ProvDebugLog *g_pLogObject = NULL;
  61. BOOL s_Exiting = FALSE ;
  62. typedef HRESULT (WINAPI* PFNCOINITIALIZEEX)(void* pvReserved, //Reserved
  63. DWORD dwCoInit //COINIT value
  64. );
  65. typedef HRESULT (WINAPI* PFNCOINITIALIZESECURITY)(
  66. PSECURITY_DESCRIPTOR pSecDesc,
  67. LONG cAuthSvc,
  68. SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
  69. void *pReserved1,
  70. DWORD dwAuthnLevel,
  71. DWORD dwImpLevel,
  72. void *pReserved2,
  73. DWORD dwCapabilities,
  74. void *pReserved3 );
  75. HRESULT COMInit();
  76. STDAPI ExeRegisterServer(void);
  77. STDAPI ExeUnregisterServer(void);
  78. BOOL StartupProvider (DWORD *pdwClassFac)
  79. {
  80. // Initialize the critical section to access the static initializer objects
  81. InitializeCriticalSection(&g_StaticsCreationDeletion);
  82. // Initialize the static Initializer objects. These are destroyed in DllCanUnloadNow
  83. CDSClassProviderClassFactory :: s_pDSClassProviderInitializer = NULL;
  84. CDSClassProviderClassFactory ::s_pLDAPClassProviderInitializer = NULL;
  85. CDSInstanceProviderClassFactory :: s_pDSInstanceProviderInitializer = NULL;
  86. CDSClassProviderClassFactory *lpunk1 = new CDSClassProviderClassFactory;
  87. CDSInstanceProviderClassFactory *lpunk2 = new CDSInstanceProviderClassFactory;
  88. CDSClassAssociationsProviderClassFactory *lpunk3 = new CDSClassAssociationsProviderClassFactory;
  89. lpunk1->AddRef();
  90. lpunk2->AddRef();
  91. lpunk3->AddRef();
  92. HRESULT hr = CoRegisterClassObject(
  93. CLSID_DSProvider, //Class identifier (CLSID) to be registered
  94. (IUnknown *) lpunk1, //Pointer to the class object
  95. CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER, //Context for running executable code
  96. REGCLS_MULTIPLEUSE, //How to connect to the class object
  97. &pdwClassFac[0] //Pointer to the value returned
  98. );
  99. if(SUCCEEDED(hr))
  100. {
  101. hr = CoRegisterClassObject(
  102. CLSID_DSInstanceProvider, //Class identifier (CLSID) to be registered
  103. (IUnknown *) lpunk2, //Pointer to the class object
  104. CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER, //Context for running executable code
  105. REGCLS_MULTIPLEUSE, //How to connect to the class object
  106. &pdwClassFac[1] //Pointer to the value returned
  107. );
  108. }
  109. if(SUCCEEDED(hr))
  110. {
  111. hr = CoRegisterClassObject(
  112. CLSID_DSClassAssocProvider, //Class identifier (CLSID) to be registered
  113. (IUnknown *) lpunk3, //Pointer to the class object
  114. CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER, //Context for running executable code
  115. REGCLS_MULTIPLEUSE, //How to connect to the class object
  116. &pdwClassFac[3] //Pointer to the value returned
  117. );
  118. }
  119. return (SUCCEEDED(hr));
  120. }
  121. void ShutdownProvider(DWORD *pdwClassFac)
  122. {
  123. // Delete the Initializer objects
  124. EnterCriticalSection(&g_StaticsCreationDeletion);
  125. if(g_pLogObject)
  126. g_pLogObject->WriteW(L"DllCanUnloadNow called\r\n");
  127. delete CDSClassProviderClassFactory::s_pDSClassProviderInitializer;
  128. delete CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer;
  129. delete CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer;
  130. delete g_pLogObject;
  131. CDSClassProviderClassFactory::s_pDSClassProviderInitializer = NULL;
  132. CDSClassProviderClassFactory::s_pLDAPClassProviderInitializer = NULL;
  133. CDSInstanceProviderClassFactory::s_pDSInstanceProviderInitializer = NULL;
  134. g_pLogObject = NULL;
  135. LeaveCriticalSection(&g_StaticsCreationDeletion);
  136. CoRevokeClassObject(pdwClassFac[0]);
  137. CoRevokeClassObject(pdwClassFac[1]);
  138. CoRevokeClassObject(pdwClassFac[2]);
  139. DeleteCriticalSection(&g_StaticsCreationDeletion);
  140. }
  141. BOOL ParseCommandLine ()
  142. {
  143. BOOL t_Exit = FALSE ;
  144. LPTSTR t_CommandLine = GetCommandLine () ;
  145. if ( t_CommandLine )
  146. {
  147. TCHAR *t_Arg = NULL ;
  148. TCHAR *t_ApplicationArg = NULL ;
  149. t_ApplicationArg = _tcstok ( t_CommandLine , _TEXT ( " \t" ) ) ;
  150. t_Arg = _tcstok ( NULL , _TEXT ( " \t" ) ) ;
  151. if ( t_Arg )
  152. {
  153. if ( _tcsicmp ( t_Arg , _TEXT ( "/RegServer" ) ) == 0 )
  154. {
  155. t_Exit = TRUE ;
  156. ExeRegisterServer();
  157. }
  158. else if ( _tcsicmp ( t_Arg , _TEXT ( "/UnRegServer" ) ) == 0 )
  159. {
  160. t_Exit = TRUE ;
  161. ExeUnregisterServer();
  162. }
  163. else if(_tcsicmp(t_Arg, _TEXT ( "/EMBEDDING" ) ) == 0)
  164. {
  165. // COM called us, so this is the real thing...
  166. t_Exit = FALSE;
  167. }
  168. }
  169. }
  170. return t_Exit ;
  171. }
  172. LONG CALLBACK WindowsMainProc ( HWND a_hWnd , UINT a_message , WPARAM a_wParam , LPARAM a_lParam )
  173. {
  174. long t_rc = 0 ;
  175. switch ( a_message )
  176. {
  177. case WM_CLOSE:
  178. {
  179. s_Exiting = TRUE ;
  180. }
  181. break ;
  182. case WM_DESTROY:
  183. {
  184. PostMessage ( a_hWnd , WM_QUIT , 0 , 0 ) ;
  185. }
  186. break ;
  187. default:
  188. {
  189. t_rc = DefWindowProc ( a_hWnd , a_message , a_wParam , a_lParam ) ;
  190. }
  191. break ;
  192. }
  193. return ( t_rc ) ;
  194. }
  195. HWND WindowsInit ( HINSTANCE a_HInstance )
  196. {
  197. static wchar_t *t_TemplateCode = L"DS Provider" ;
  198. WNDCLASS t_wc ;
  199. t_wc.style = CS_HREDRAW | CS_VREDRAW ;
  200. t_wc.lpfnWndProc = WindowsMainProc ;
  201. t_wc.cbClsExtra = 0 ;
  202. t_wc.cbWndExtra = 0 ;
  203. t_wc.hInstance = a_HInstance ;
  204. t_wc.hIcon = LoadIcon(NULL, IDI_HAND) ;
  205. t_wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  206. t_wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  207. t_wc.lpszMenuName = NULL ;
  208. t_wc.lpszClassName = t_TemplateCode ;
  209. ATOM t_winClass = RegisterClass ( &t_wc ) ;
  210. HWND t_HWnd = CreateWindow (
  211. t_TemplateCode , // see RegisterClass() call
  212. t_TemplateCode , // text for window title bar
  213. WS_OVERLAPPEDWINDOW , // window style
  214. CW_USEDEFAULT , // default horizontal position
  215. CW_USEDEFAULT , // default vertical position
  216. CW_USEDEFAULT , // default width
  217. CW_USEDEFAULT , // default height
  218. NULL , // overlapped windows have no parent
  219. NULL , // use the window class menu
  220. a_HInstance ,
  221. NULL // pointer not needed
  222. ) ;
  223. if (t_HWnd)
  224. {
  225. ShowWindow ( t_HWnd, SW_SHOW ) ;
  226. }
  227. return t_HWnd ;
  228. }
  229. void WindowsStop ( HWND a_HWnd )
  230. {
  231. DestroyWindow ( a_HWnd ) ;
  232. }
  233. HWND WindowsStart ( HINSTANCE a_Handle )
  234. {
  235. HWND t_HWnd = WindowsInit(a_Handle);
  236. return t_HWnd;
  237. }
  238. void WindowsDispatch ()
  239. {
  240. BOOL t_GetMessage ;
  241. MSG t_lpMsg ;
  242. while ( ( t_GetMessage = GetMessage ( & t_lpMsg , NULL , 0 , 0 ) ) == TRUE )
  243. {
  244. TranslateMessage ( & t_lpMsg ) ;
  245. DispatchMessage ( & t_lpMsg ) ;
  246. if ( s_Exiting )
  247. return ;
  248. }
  249. }
  250. int WINAPI WinMain (
  251. HINSTANCE hInstance, // handle to current instance
  252. HINSTANCE hPrevInstance, // handle to previous instance
  253. LPSTR lpCmdLine, // pointer to command line
  254. int nShowCmd // show state of window
  255. )
  256. {
  257. // Initialize the COM Library.
  258. HRESULT hr = COMInit();
  259. BOOL t_Exit = ParseCommandLine();
  260. if (!t_Exit)
  261. {
  262. HWND hWnd = WindowsStart(hInstance);
  263. if (hWnd)
  264. {
  265. DWORD dwArray[] = {0, 0, 0};
  266. if (StartupProvider(dwArray))
  267. {
  268. WindowsDispatch();
  269. ShutdownProvider(dwArray);
  270. }
  271. WindowsStop(hWnd);
  272. }
  273. }
  274. // Uninitialize the COM Library.
  275. ::CoUninitialize() ;
  276. return 0 ;
  277. }
  278. ////////////////////////////////////////////////////////////////////
  279. // Strings used during self registration
  280. ////////////////////////////////////////////////////////////////////
  281. LPCTSTR THREADING_MODEL_STR = __TEXT("ThreadingModel");
  282. LPCTSTR APARTMENT_STR = __TEXT("Both");
  283. LPCTSTR CLSID_STR = __TEXT("CLSID\\");
  284. // DS Class Provider
  285. LPCTSTR DSPROVIDER_NAME_STR = __TEXT("Microsoft NT DS Class Provider for WBEM");
  286. // DS Class Associations provider
  287. LPCTSTR DS_ASSOC_PROVIDER_NAME_STR = __TEXT("Microsoft NT DS Class Associations Provider for WBEM");
  288. // DS Instance provider
  289. LPCTSTR DS_INSTANCE_PROVIDER_NAME_STR = __TEXT("Microsoft NT DS Instance Provider for WBEM");
  290. #define REG_FORMAT2_STR _T("%s%s")
  291. #define REG_FORMAT3_STR _T("%s%s\\%s")
  292. #define VER_IND_STR _T("VersionIndependentProgID")
  293. #define NOT_INTERT_STR _T("NotInsertable")
  294. #define LOCALSRV32_STR _T("LocalServer32")
  295. #define PROGID_STR _T("ProgID")
  296. #define THREADING_MODULE_STR _T("ThreadingModel")
  297. #define APARTMENT_STR _T("Both")
  298. #define CLSID_STR _T("CLSID\\")
  299. /***************************************************************************
  300. * SetKeyAndValue
  301. *
  302. * Purpose:
  303. * Private helper function for DllRegisterServer that creates
  304. * a key, sets a value, and closes that key.
  305. *
  306. * Parameters:
  307. * pszKey LPTSTR to the ame of the key
  308. * pszSubkey LPTSTR ro the name of a subkey
  309. * pszValue LPTSTR to the value to store
  310. *
  311. * Return Value:
  312. * BOOL TRUE if successful, FALSE otherwise.
  313. ***************************************************************************/
  314. BOOL SetKeyAndValue(LPCTSTR pszKey, LPCTSTR pszSubkey, LPCTSTR pszValueName, LPCTSTR pszValue)
  315. {
  316. HKEY hKey;
  317. TCHAR szKey[256];
  318. _tcscpy(szKey, pszKey);
  319. // If a sub key is mentioned, use it.
  320. if (NULL != pszSubkey)
  321. {
  322. _tcscat(szKey, __TEXT("\\"));
  323. _tcscat(szKey, pszSubkey);
  324. }
  325. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  326. szKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  327. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  328. return FALSE;
  329. if (NULL != pszValue)
  330. {
  331. if (ERROR_SUCCESS != RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (BYTE *)pszValue,
  332. (_tcslen(pszValue)+1)*sizeof(TCHAR)))
  333. return FALSE;
  334. }
  335. RegCloseKey(hKey);
  336. return TRUE;
  337. }
  338. BOOL DeleteKey(LPCTSTR pszKey, LPCTSTR pszSubkey)
  339. {
  340. HKEY hKey;
  341. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  342. pszKey, 0, NULL, REG_OPTION_NON_VOLATILE,
  343. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  344. return FALSE;
  345. if(ERROR_SUCCESS != RegDeleteKey(hKey, pszSubkey))
  346. return FALSE;
  347. RegCloseKey(hKey);
  348. return TRUE;
  349. }
  350. //***************************************************************************
  351. //
  352. // ExeRegisterServer
  353. //
  354. // Purpose: Called when /register is specified on the command line.
  355. //
  356. // Return: NOERROR if registration successful, error otherwise.
  357. //***************************************************************************
  358. STDAPI ExeRegisterServer(void)
  359. {
  360. TCHAR szModule[MAX_PATH + 1];
  361. HINSTANCE hInst = GetModuleHandle(_T("DSPROV"));
  362. GetModuleFileName(hInst,(TCHAR*)szModule, MAX_PATH + 1);
  363. TCHAR szDSProviderClassID[128];
  364. TCHAR szDSProviderCLSIDClassID[128];
  365. #ifdef UNICODE
  366. if(StringFromGUID2(CLSID_DSProvider, szDSProviderClassID, 128) == 0)
  367. return SELFREG_E_CLASS;
  368. #else
  369. WCHAR wszDSProviderClassID[128];
  370. if(StringFromGUID2(CLSID_DSProvider, wszDSProviderClassID, 128) == 0)
  371. return SELFREG_E_CLASS;
  372. WideCharToMultiByte(CP_ACP, 0, wszDSProviderClassID, -1, szDSProviderCLSIDClassID, 128, NULL, NULL);
  373. #endif
  374. _tcscpy(szDSProviderCLSIDClassID, CLSID_STR);
  375. _tcscat(szDSProviderCLSIDClassID, szDSProviderClassID);
  376. //
  377. // Create entries under CLSID for DS Class Provider
  378. //
  379. if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, NULL, NULL, DSPROVIDER_NAME_STR))
  380. return SELFREG_E_CLASS;
  381. if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, LOCALSRV32_STR, NULL, szModule))
  382. return SELFREG_E_CLASS;
  383. if (FALSE == SetKeyAndValue(szDSProviderCLSIDClassID, LOCALSRV32_STR, THREADING_MODEL_STR, APARTMENT_STR))
  384. return SELFREG_E_CLASS;
  385. TCHAR szDSClassAssocProviderClassID[128];
  386. TCHAR szDSClassAssocProviderCLSIDClassID[128];
  387. #ifdef UNICODE
  388. if(StringFromGUID2(CLSID_DSClassAssocProvider, szDSClassAssocProviderClassID, 128) == 0)
  389. return SELFREG_E_CLASS;
  390. #else
  391. WCHAR wszDSClassAssocProviderClassID[128];
  392. if(StringFromGUID2(CLSID_DSClassAssocProvider, wszDSClassAssocProviderClassID, 128) == 0)
  393. return SELFREG_E_CLASS;
  394. WideCharToMultiByte(CP_ACP, 0, wszDSClassAssocProviderClassID, -1, szDSClassAssocProviderCLSIDClassID, 128, NULL, NULL);
  395. #endif
  396. _tcscpy(szDSClassAssocProviderCLSIDClassID, CLSID_STR);
  397. _tcscat(szDSClassAssocProviderCLSIDClassID, szDSClassAssocProviderClassID);
  398. //
  399. // Create entries under CLSID for DS Class Associations Provider
  400. //
  401. if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, NULL, NULL, DS_ASSOC_PROVIDER_NAME_STR))
  402. return SELFREG_E_CLASS;
  403. if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, LOCALSRV32_STR, NULL, szModule))
  404. return SELFREG_E_CLASS;
  405. if (FALSE == SetKeyAndValue(szDSClassAssocProviderCLSIDClassID, LOCALSRV32_STR, THREADING_MODEL_STR, APARTMENT_STR))
  406. return SELFREG_E_CLASS;
  407. TCHAR szDSInstanceProviderClassID[128];
  408. TCHAR szDSInstanceProviderCLSIDClassID[128];
  409. #ifdef UNICODE
  410. if(StringFromGUID2(CLSID_DSInstanceProvider, szDSInstanceProviderClassID, 128) == 0)
  411. return SELFREG_E_CLASS;
  412. #else
  413. WCHAR wszDSInstanceProviderClassID[128];
  414. if(StringFromGUID2(CLSID_DSInstanceProvider, wszDSInstanceProviderClassID, 128) == 0)
  415. return SELFREG_E_CLASS;
  416. WideCharToMultiByte(CP_ACP, 0, wszDSInstanceProviderClassID, -1, szDSInstanceProviderCLSIDClassID, 128, NULL, NULL);
  417. #endif
  418. _tcscpy(szDSInstanceProviderCLSIDClassID, CLSID_STR);
  419. _tcscat(szDSInstanceProviderCLSIDClassID, szDSInstanceProviderClassID);
  420. //
  421. // Create entries under CLSID for DS Instance Provider
  422. //
  423. if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, NULL, NULL, DS_INSTANCE_PROVIDER_NAME_STR))
  424. return SELFREG_E_CLASS;
  425. if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, LOCALSRV32_STR, NULL, szModule))
  426. return SELFREG_E_CLASS;
  427. if (FALSE == SetKeyAndValue(szDSInstanceProviderCLSIDClassID, LOCALSRV32_STR, THREADING_MODEL_STR, APARTMENT_STR))
  428. return SELFREG_E_CLASS;
  429. return S_OK;
  430. }
  431. //***************************************************************************
  432. //
  433. // ExeUnregisterServer
  434. //
  435. // Purpose: Called when /unregister is specified on the command line.
  436. //
  437. // Return: NOERROR if registration successful, error otherwise.
  438. //***************************************************************************
  439. STDAPI ExeUnregisterServer(void)
  440. {
  441. TCHAR szModule[MAX_PATH + 1];
  442. HINSTANCE hInst = GetModuleHandle(_T("DSPROV"));
  443. GetModuleFileName(hInst,(TCHAR*)szModule, MAX_PATH + 1);
  444. TCHAR szDSProviderClassID[128];
  445. TCHAR szDSProviderCLSIDClassID[128];
  446. #ifdef UNICODE
  447. if(StringFromGUID2(CLSID_DSProvider, szDSProviderClassID, 128) == 0)
  448. return SELFREG_E_CLASS;
  449. #else
  450. WCHAR wszDSProviderClassID[128];
  451. if(StringFromGUID2(CLSID_DSProvider, wszDSProviderClassID, 128) == 0)
  452. return SELFREG_E_CLASS;
  453. WideCharToMultiByte(CP_ACP, 0, wszDSProviderClassID, -1, szDSProviderCLSIDClassID, 128, NULL, NULL);
  454. #endif
  455. _tcscpy(szDSProviderCLSIDClassID, CLSID_STR);
  456. _tcscat(szDSProviderCLSIDClassID, szDSProviderClassID);
  457. //
  458. // Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
  459. //
  460. if(FALSE == DeleteKey(szDSProviderCLSIDClassID, LOCALSRV32_STR))
  461. return SELFREG_E_CLASS;
  462. if(FALSE == DeleteKey(CLSID_STR, szDSProviderClassID))
  463. return SELFREG_E_CLASS;
  464. TCHAR szDSClassAssocProviderClassID[128];
  465. TCHAR szDSClassAssocProviderCLSIDClassID[128];
  466. #ifdef UNICODE
  467. if(StringFromGUID2(CLSID_DSClassAssocProvider, szDSClassAssocProviderClassID, 128) == 0)
  468. return SELFREG_E_CLASS;
  469. #else
  470. WCHAR wszDSClassAssocProviderClassID[128];
  471. if(StringFromGUID2(CLSID_DSClassAssocProvider, wszDSClassAssocProviderClassID, 128) == 0)
  472. return SELFREG_E_CLASS;
  473. WideCharToMultiByte(CP_ACP, 0, wszDSClassAssocProviderClassID, -1, szDSClassAssocProviderCLSIDClassID, 128, NULL, NULL);
  474. #endif
  475. _tcscpy(szDSClassAssocProviderCLSIDClassID, CLSID_STR);
  476. _tcscat(szDSClassAssocProviderCLSIDClassID, szDSClassAssocProviderClassID);
  477. //
  478. // Delete the keys for DS Class Provider in the reverse order of creation in DllRegisterServer()
  479. //
  480. if(FALSE == DeleteKey(szDSClassAssocProviderCLSIDClassID, LOCALSRV32_STR))
  481. return SELFREG_E_CLASS;
  482. if(FALSE == DeleteKey(CLSID_STR, szDSClassAssocProviderClassID))
  483. return SELFREG_E_CLASS;
  484. TCHAR szDSInstanceProviderClassID[128];
  485. TCHAR szDSInstanceProviderCLSIDClassID[128];
  486. #ifdef UNICODE
  487. if(StringFromGUID2(CLSID_DSInstanceProvider, szDSInstanceProviderClassID, 128) == 0)
  488. return SELFREG_E_CLASS;
  489. #else
  490. WCHAR wszDSInstanceProviderClassID[128];
  491. if(StringFromGUID2(CLSID_DSInstanceProvider, wszDSInstanceProviderClassID, 128) == 0)
  492. return SELFREG_E_CLASS;
  493. WideCharToMultiByte(CP_ACP, 0, wszDSInstanceProviderClassID, -1, szDSInstanceProviderCLSIDClassID, 128, NULL, NULL);
  494. #endif
  495. _tcscpy(szDSInstanceProviderCLSIDClassID, CLSID_STR);
  496. _tcscat(szDSInstanceProviderCLSIDClassID, szDSInstanceProviderClassID);
  497. //
  498. // Delete the keys in the reverse order of creation in DllRegisterServer()
  499. //
  500. if(FALSE == DeleteKey(szDSInstanceProviderCLSIDClassID, LOCALSRV32_STR))
  501. return SELFREG_E_CLASS;
  502. if(FALSE == DeleteKey(CLSID_STR, szDSInstanceProviderClassID))
  503. return SELFREG_E_CLASS;
  504. return S_OK;
  505. }
  506. /////////////////////////////////////////////////////////////////////////////
  507. HRESULT COMInit()
  508. {
  509. HRESULT hr;
  510. PFNCOINITIALIZESECURITY pfnCoInitializeSecurity = NULL;
  511. PFNCOINITIALIZEEX pfnCoInitializeEx = NULL;
  512. //Get handle to COM library
  513. HMODULE ghOle32 = LoadLibraryEx(_T("ole32.dll"), NULL, 0);
  514. if(ghOle32 != NULL)
  515. {
  516. //Get ptr to functions CoInitialize and CoInitializeSecurity.
  517. pfnCoInitializeEx = (PFNCOINITIALIZEEX) GetProcAddress(ghOle32,
  518. "CoInitializeEx");
  519. pfnCoInitializeSecurity = (PFNCOINITIALIZESECURITY) GetProcAddress(ghOle32,
  520. "CoInitializeSecurity");
  521. //Initialize COM
  522. if (pfnCoInitializeEx)
  523. {
  524. hr = pfnCoInitializeEx(NULL, COINIT_MULTITHREADED);
  525. }
  526. else
  527. {
  528. hr = CoInitialize(NULL);
  529. }
  530. if(FAILED(hr))
  531. {
  532. FreeLibrary(ghOle32);
  533. ghOle32 = NULL;
  534. return E_FAIL;
  535. }
  536. //Initialize Security
  537. if (pfnCoInitializeSecurity)
  538. {
  539. hr = pfnCoInitializeSecurity(NULL, -1, NULL, NULL,
  540. RPC_C_AUTHN_LEVEL_NONE,
  541. RPC_C_IMP_LEVEL_IMPERSONATE,
  542. NULL, EOAC_NONE, 0);
  543. }
  544. if(FAILED(hr))
  545. {
  546. CoUninitialize();
  547. FreeLibrary(ghOle32);
  548. ghOle32 = NULL;
  549. return E_FAIL;
  550. }
  551. }
  552. else
  553. {
  554. return E_FAIL;
  555. }
  556. return S_OK;
  557. }