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.

1182 lines
35 KiB

  1. ////////////////////////////////////////////////////////////////////////
  2. //
  3. // regcode.cpp
  4. //
  5. // Module:
  6. //
  7. // History:
  8. // ivanbrug 17-09-2000 Create
  9. //
  10. //
  11. // Copyright (c) 1997-2001 Microsoft Corporation, All rights reserved
  12. //
  13. ////////////////////////////////////////////////////////////////////////
  14. #include "precomp.h"
  15. #include <winmgmt.h>
  16. #include <strings.h> // for LoadString
  17. #include <malloc.h>
  18. #include <winntsec.h>
  19. #include <autoptr.h>
  20. #include <helper.h>
  21. #include <tchar.h>
  22. #define SVCHOST_HOME _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost")
  23. #define SERVICE_PATH _T("System\\CurrentControlSet\\Services\\")
  24. #define DLL_PATH _T("%SystemRoot%\\system32\\wbem\\WMIsvc.dll")
  25. #define ENTRY_POINT _T("ServiceMain")
  26. #define COM_APPID _T("Software\\classes\\AppID\\{8BC3F05E-D86B-11D0-A075-00C04FB68820}")
  27. //= Windows Management Instrumentation
  28. //LocalService = WinMgmt
  29. #define COM_APPID_NAME _T("Software\\classes\\AppID\\winmgmt")
  30. //AppID = {8BC3F05E-D86B-11D0-A075-00C04FB68820}
  31. #define SERVICE_CLSID _T("{8BC3F05E-D86B-11D0-A075-00C04FB68820}")
  32. #define SERVICE_NAME_GROUP_ALONE _T("winmgmt")
  33. #define SERVICE_NAME_GROUP _T("netsvcs")
  34. #define SERVICE_NAME_GROUP_TOGETHER _T("netsvcs")
  35. // see winmgmt.h
  36. //#define SERVICE_NAME _T("winmgmt")
  37. #define VALUE_AUTH _T("AuthenticationCapabilities")
  38. #define VALUE_COINIT _T("CoInitializeSecurityParam")
  39. #define VALUE_AUTZN _T("AuthenticationLevel")
  40. #define VALUE_IMPER _T("ImpersonationLevel")
  41. #define ACCOUNT_NAME _T("LocalService") // unused, for now
  42. #define DISPLAY_CLSID _T("Windows Management and Instrumentation")
  43. #define DISPLAY_BACKUP_CLSID _T("Windows Management Instrumentation Backup and Recovery")
  44. //
  45. // how verbose can PMs be ?
  46. //
  47. #define MAX_BUFF 2048
  48. //
  49. //
  50. // this is the rundll32 interface
  51. //
  52. //
  53. //////////////////////////////////////////////////////////////////
  54. void CALLBACK
  55. MoveToAlone(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) //RPC_C_AUTHN_LEVEL_CONNECT
  56. {
  57. BOOL bRet = TRUE;
  58. LONG lRet;
  59. HKEY hKey;
  60. DWORD dwLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  61. if (lpszCmdLine)
  62. {
  63. dwLevel = atoi(lpszCmdLine);
  64. if (0 == dwLevel) // in case of error
  65. {
  66. dwLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  67. }
  68. }
  69. // create the new group key under svchost
  70. if (bRet)
  71. {
  72. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  73. SVCHOST_HOME,
  74. 0,
  75. KEY_ALL_ACCESS,
  76. &hKey);
  77. if (ERROR_SUCCESS == lRet)
  78. {
  79. // add the group
  80. LONG lRet2;
  81. DWORD dwCurrSize;
  82. DWORD dwType;
  83. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,NULL,&dwCurrSize);
  84. if (ERROR_SUCCESS == lRet2)
  85. {
  86. // the key is there, append to the multistring
  87. BYTE * pMulti = new BYTE[(dwCurrSize+sizeof(SERVICE_NAME)+4)];
  88. wmilib::auto_buffer<BYTE> rm_(pMulti);
  89. if (pMulti)
  90. {
  91. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,pMulti,&dwCurrSize);
  92. if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check
  93. {
  94. TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR));
  95. // verify the multisz
  96. TCHAR *pEnd = (TCHAR *)pMulti;
  97. BOOL bIsThere = FALSE;
  98. while (*pEnd)
  99. {
  100. if (0 == _tcsicmp(pEnd,SERVICE_NAME))
  101. {
  102. bIsThere = TRUE;
  103. }
  104. while (*pEnd){
  105. pEnd++;
  106. }
  107. pEnd++; // past the zero who terminates the string
  108. }
  109. if (!bIsThere)
  110. {
  111. if ((ULONG_PTR)pEnd == (ULONG_PTR)pInsertPoint)
  112. {
  113. _tcsncpy(pEnd,SERVICE_NAME _T("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1);
  114. DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME);
  115. RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMulti,dwNowSize);
  116. }
  117. else
  118. {
  119. bRet = FALSE;
  120. }
  121. }
  122. }
  123. }
  124. }
  125. else if (ERROR_FILE_NOT_FOUND == lRet2)
  126. {
  127. BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP_ALONE _T("\0");
  128. RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(_T("")));
  129. }
  130. else
  131. {
  132. // what to do ?
  133. }
  134. HKEY hKey2;
  135. DWORD dwDisposistion;
  136. lRet = RegCreateKeyEx(hKey,
  137. SERVICE_NAME_GROUP_ALONE,
  138. 0,NULL,
  139. REG_OPTION_NON_VOLATILE,
  140. KEY_ALL_ACCESS,
  141. NULL,
  142. &hKey2,
  143. &dwDisposistion);
  144. if (ERROR_SUCCESS == lRet)
  145. {
  146. // any value non NULL will work
  147. DWORD dwVal = 1;
  148. RegSetValueEx(hKey2,VALUE_COINIT,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  149. // from packet to connect
  150. dwVal = dwLevel; //RPC_C_AUTHN_LEVEL_CONNECT;
  151. RegSetValueEx(hKey2,VALUE_AUTZN,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  152. dwVal = RPC_C_IMP_LEVEL_IDENTIFY;
  153. RegSetValueEx(hKey2,VALUE_IMPER,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  154. dwVal = EOAC_DISABLE_AAA | EOAC_NO_CUSTOM_MARSHAL | EOAC_STATIC_CLOAKING ;
  155. RegSetValueEx(hKey2,VALUE_AUTH,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  156. RegCloseKey(hKey2);
  157. bRet = TRUE;
  158. }
  159. }
  160. }
  161. if (bRet)
  162. {
  163. SC_HANDLE scHandle;
  164. scHandle = OpenSCManager(NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS);
  165. if (scHandle)
  166. {
  167. SC_HANDLE scService;
  168. scService = OpenService(scHandle,SERVICE_NAME,SERVICE_ALL_ACCESS);
  169. if (scService)
  170. {
  171. DWORD dwNeeded = 0;
  172. bRet = QueryServiceConfig(scService,NULL,0,&dwNeeded);
  173. if (!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
  174. {
  175. BYTE * pByte = new BYTE[dwNeeded];
  176. wmilib::auto_buffer<BYTE> rm_(pByte);
  177. QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG *)pByte;
  178. if (pConfig)
  179. {
  180. bRet = QueryServiceConfig(scService,pConfig,dwNeeded,&dwNeeded);
  181. if (bRet)
  182. {
  183. TCHAR BinPath[MAX_PATH];
  184. wsprintf(BinPath,_T("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP_ALONE);
  185. bRet = ChangeServiceConfig(scService,
  186. pConfig->dwServiceType,
  187. pConfig->dwStartType,
  188. pConfig->dwErrorControl,
  189. BinPath,
  190. pConfig->lpLoadOrderGroup,
  191. NULL, //&pConfig->dwTagId,
  192. pConfig->lpDependencies,
  193. pConfig->lpServiceStartName,
  194. NULL,
  195. pConfig->lpDisplayName);
  196. if (!bRet)
  197. {
  198. DBG_PRINTFA((pBuff,"ChangeServiceConfig %d\n",GetLastError()));
  199. }
  200. }
  201. }
  202. else
  203. {
  204. bRet = FALSE;
  205. }
  206. }
  207. CloseServiceHandle(scService);
  208. }
  209. else
  210. {
  211. // the service was not there or other error
  212. DBG_PRINTFA((pBuff,"MoveToStandalone OpenService %d\n",GetLastError()));
  213. bRet = FALSE;
  214. }
  215. CloseServiceHandle(scHandle);
  216. }
  217. else
  218. {
  219. DBG_PRINTFA((pBuff,"MoveToStandalone OpenSCManager %d\n",GetLastError()));
  220. bRet = FALSE;
  221. }
  222. }
  223. if (bRet)
  224. {
  225. //
  226. // remove the winmgmt string from the multi-sz of winmgmt
  227. //
  228. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  229. SVCHOST_HOME,
  230. 0,
  231. KEY_ALL_ACCESS,
  232. &hKey);
  233. if (ERROR_SUCCESS == lRet)
  234. {
  235. // add the group
  236. LONG lRet2;
  237. DWORD dwCurrSize;
  238. DWORD dwType;
  239. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,NULL,&dwCurrSize);
  240. if (ERROR_SUCCESS == lRet2)
  241. {
  242. // the key is there, append to the multistring
  243. BYTE * pMulti = new BYTE[dwCurrSize+4];
  244. wmilib::auto_buffer<BYTE> rm1_(pMulti);
  245. BYTE * pMultiNew = new BYTE[dwCurrSize+4];
  246. wmilib::auto_buffer<BYTE> rm2_(pMultiNew);
  247. TCHAR * pMultiNewCopy = (TCHAR *)pMultiNew;
  248. if (pMulti && pMultiNew)
  249. {
  250. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,pMulti,&dwCurrSize);
  251. if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check
  252. {
  253. // verify the multisz
  254. TCHAR *pEnd = (TCHAR *)pMulti;
  255. BOOL bIsThere = FALSE;
  256. while (*pEnd)
  257. {
  258. if (0 == _tcsicmp(pEnd,SERVICE_NAME))
  259. {
  260. bIsThere = TRUE;
  261. while (*pEnd){
  262. pEnd++;
  263. }
  264. pEnd++; // past the zero who terminates the string
  265. }
  266. else // copy
  267. {
  268. while (*pEnd){
  269. *pMultiNewCopy++ = *pEnd++;
  270. }
  271. pEnd++; // past the zero who terminates the string
  272. *pMultiNewCopy++ = 0;
  273. }
  274. }
  275. *pMultiNewCopy++ = 0; // put the double terminator
  276. if (bIsThere)
  277. {
  278. DWORD dwNowSize = dwCurrSize-sizeof(SERVICE_NAME);
  279. RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMultiNew,dwNowSize);
  280. }
  281. }
  282. }
  283. else
  284. {
  285. bRet = FALSE;
  286. }
  287. }
  288. else
  289. {
  290. //
  291. // the netsvcs multi sz MUST be there !!!!
  292. //
  293. bRet = TRUE;
  294. }
  295. }
  296. else
  297. {
  298. bRet = FALSE;
  299. }
  300. }
  301. return;
  302. }
  303. //
  304. //
  305. // this is the rundll32 interface
  306. //
  307. //
  308. //////////////////////////////////////////////////////////////////
  309. void CALLBACK
  310. MoveToShared(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) //RPC_C_AUTHN_LEVEL_CONNECT
  311. {
  312. //
  313. BOOL bRet = TRUE;
  314. LONG lRet;
  315. HKEY hKey;
  316. DWORD dwLevel = RPC_C_PROTECT_LEVEL_PKT;
  317. if (lpszCmdLine)
  318. {
  319. dwLevel = atoi(lpszCmdLine);
  320. if (0 == dwLevel) // in case of error
  321. {
  322. dwLevel = RPC_C_PROTECT_LEVEL_PKT;
  323. }
  324. }
  325. // create the new group key under svchost
  326. if (bRet)
  327. {
  328. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  329. SVCHOST_HOME,
  330. 0,
  331. KEY_ALL_ACCESS,
  332. &hKey);
  333. if (ERROR_SUCCESS == lRet)
  334. {
  335. // add the group
  336. LONG lRet2;
  337. DWORD dwCurrSize;
  338. DWORD dwType;
  339. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,NULL,&dwCurrSize);
  340. if (ERROR_SUCCESS == lRet2)
  341. {
  342. // the key is there, append to the multistring
  343. BYTE * pMulti = new BYTE[(dwCurrSize+sizeof(SERVICE_NAME)+4)];
  344. wmilib::auto_buffer<BYTE> rm_(pMulti);
  345. if (pMulti)
  346. {
  347. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,&dwType,pMulti,&dwCurrSize);
  348. if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check
  349. {
  350. TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR));
  351. // verify the multisz
  352. TCHAR *pEnd = (TCHAR *)pMulti;
  353. BOOL bIsThere = FALSE;
  354. while (*pEnd)
  355. {
  356. if (0 == _tcsicmp(pEnd,SERVICE_NAME))
  357. {
  358. bIsThere = TRUE;
  359. }
  360. while (*pEnd){
  361. pEnd++;
  362. }
  363. pEnd++; // past the zero who terminates the string
  364. }
  365. if (!bIsThere)
  366. {
  367. if ((ULONG_PTR)pEnd == (ULONG_PTR)pInsertPoint)
  368. {
  369. _tcsncpy(pEnd,SERVICE_NAME _T("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1);
  370. DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME);
  371. RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMulti,dwNowSize);
  372. }
  373. else
  374. {
  375. bRet = FALSE;
  376. DebugBreak();
  377. }
  378. }
  379. }
  380. }
  381. else
  382. {
  383. bRet = FALSE;
  384. }
  385. }
  386. else if (ERROR_FILE_NOT_FOUND == lRet2)
  387. {
  388. BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP_TOGETHER _T("\0");
  389. RegSetValueEx(hKey,SERVICE_NAME_GROUP_TOGETHER,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(_T("")));
  390. }
  391. else
  392. {
  393. // what to do ?
  394. }
  395. HKEY hKey2;
  396. DWORD dwDisposistion;
  397. lRet = RegCreateKeyEx(hKey,
  398. SERVICE_NAME_GROUP_TOGETHER,
  399. 0,NULL,
  400. REG_OPTION_NON_VOLATILE,
  401. KEY_ALL_ACCESS,
  402. NULL,
  403. &hKey2,
  404. &dwDisposistion);
  405. if (ERROR_SUCCESS == lRet)
  406. {
  407. // any value non NULL will work
  408. DWORD dwVal = 1;
  409. RegSetValueEx(hKey2,VALUE_COINIT,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  410. // from packet to connect
  411. dwVal = dwLevel; //RPC_C_AUTHN_LEVEL_CONNECT;
  412. RegSetValueEx(hKey2,VALUE_AUTZN,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  413. dwVal = RPC_C_IMP_LEVEL_IDENTIFY;
  414. RegSetValueEx(hKey2,VALUE_IMPER,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  415. dwVal = EOAC_DISABLE_AAA | EOAC_NO_CUSTOM_MARSHAL | EOAC_STATIC_CLOAKING ;
  416. RegSetValueEx(hKey2,VALUE_AUTH,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  417. RegCloseKey(hKey2);
  418. bRet = TRUE;
  419. }
  420. else
  421. {
  422. DebugBreak();
  423. }
  424. }
  425. }
  426. //
  427. // changes the SCM database
  428. //
  429. if (bRet)
  430. {
  431. SC_HANDLE scHandle;
  432. scHandle = OpenSCManager(NULL,SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS);
  433. if (scHandle)
  434. {
  435. SC_HANDLE scService;
  436. scService = OpenService(scHandle,SERVICE_NAME,SERVICE_ALL_ACCESS);
  437. if (scService)
  438. {
  439. DWORD dwNeeded = 0;
  440. bRet = QueryServiceConfig(scService,NULL,0,&dwNeeded);
  441. if (!bRet && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
  442. {
  443. BYTE * pByte = new BYTE[dwNeeded];
  444. wmilib::auto_buffer<BYTE> rm1_(pByte);
  445. QUERY_SERVICE_CONFIG* pConfig = (QUERY_SERVICE_CONFIG *)pByte;
  446. if (pConfig)
  447. {
  448. bRet = QueryServiceConfig(scService,pConfig,dwNeeded,&dwNeeded);
  449. if (bRet)
  450. {
  451. TCHAR BinPath[MAX_PATH];
  452. wsprintf(BinPath,_T("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP_TOGETHER);
  453. bRet = ChangeServiceConfig(scService,
  454. pConfig->dwServiceType,
  455. pConfig->dwStartType,
  456. pConfig->dwErrorControl,
  457. BinPath,
  458. pConfig->lpLoadOrderGroup,
  459. NULL, //&pConfig->dwTagId,
  460. pConfig->lpDependencies,
  461. pConfig->lpServiceStartName,
  462. NULL,
  463. pConfig->lpDisplayName);
  464. if (!bRet)
  465. {
  466. DBG_PRINTFA((pBuff,"ChangeServiceConfig %d\n",GetLastError()));
  467. }
  468. }
  469. }
  470. else
  471. {
  472. bRet = FALSE;
  473. }
  474. }
  475. CloseServiceHandle(scService);
  476. }
  477. else
  478. {
  479. // the service was not there or other error
  480. DBG_PRINTFA((pBuff,"MoveToShared OpenService %d\n",GetLastError()));
  481. bRet = FALSE;
  482. }
  483. CloseServiceHandle(scHandle);
  484. }
  485. else
  486. {
  487. DBG_PRINTFA((pBuff,"MoveToStandalone OpenSCManager %d\n",GetLastError()));
  488. bRet = FALSE;
  489. }
  490. }
  491. if (bRet)
  492. {
  493. //
  494. // remove the winmgmt string from the multi-sz of winmgmt
  495. //
  496. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  497. SVCHOST_HOME,
  498. 0,
  499. KEY_ALL_ACCESS,
  500. &hKey);
  501. if (ERROR_SUCCESS == lRet)
  502. {
  503. // add the group
  504. LONG lRet2;
  505. DWORD dwCurrSize;
  506. DWORD dwType;
  507. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,NULL,&dwCurrSize);
  508. if (ERROR_SUCCESS == lRet2)
  509. {
  510. // the key is there, append to the multistring
  511. BYTE * pMulti = new BYTE[dwCurrSize+4];
  512. wmilib::auto_buffer<BYTE> rm2_(pMulti);
  513. BYTE * pMultiNew = new BYTE[dwCurrSize+4];
  514. wmilib::auto_buffer<BYTE> rm3_(pMultiNew);
  515. TCHAR * pMultiNewCopy = (TCHAR *)pMultiNew;
  516. if (pMulti && pMultiNew)
  517. {
  518. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,&dwType,pMulti,&dwCurrSize);
  519. if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check
  520. {
  521. // verify the multisz
  522. TCHAR *pEnd = (TCHAR *)pMulti;
  523. BOOL bIsThere = FALSE;
  524. while (*pEnd)
  525. {
  526. if (0 == _tcsicmp(pEnd,SERVICE_NAME))
  527. {
  528. bIsThere = TRUE;
  529. while (*pEnd){
  530. pEnd++;
  531. }
  532. pEnd++; // past the zero who terminates the string
  533. }
  534. else // copy
  535. {
  536. while (*pEnd){
  537. *pMultiNewCopy++ = *pEnd++;
  538. }
  539. pEnd++; // past the zero who terminates the string
  540. *pMultiNewCopy++ = 0;
  541. }
  542. }
  543. *pMultiNewCopy++ = 0; // put the double terminator
  544. if (bIsThere)
  545. {
  546. DWORD dwNowSize = dwCurrSize-sizeof(SERVICE_NAME);
  547. RegSetValueEx(hKey,SERVICE_NAME_GROUP_ALONE,0,REG_MULTI_SZ,pMultiNew,dwNowSize);
  548. }
  549. }
  550. }
  551. else
  552. {
  553. bRet = FALSE;
  554. }
  555. }
  556. else
  557. {
  558. //
  559. // the netsvcs multi sz MUST be there !!!!
  560. //
  561. bRet = TRUE;
  562. }
  563. }
  564. else
  565. {
  566. bRet = FALSE;
  567. }
  568. }
  569. }
  570. //***************************************************************************
  571. //
  572. // void InitializeLaunchPermissions()
  573. //
  574. // DESCRIPTION:
  575. //
  576. // Sets the DCOM Launch permissions.
  577. //
  578. //***************************************************************************
  579. void InitializeLaunchPermissions()
  580. {
  581. Registry reg(__TEXT("SOFTWARE\\CLASSES\\APPID\\{8bc3f05e-d86b-11d0-a075-00c04fb68820}"));
  582. if(reg.GetLastError() != 0)
  583. return;
  584. // If there already is a SD, then dont overwrite
  585. BYTE * pData = NULL;
  586. DWORD dwDataSize = 0;
  587. int iRet = reg.GetBinary(__TEXT("LaunchPermission"), &pData, &dwDataSize);
  588. if(iRet == 0)
  589. {
  590. delete [] pData;
  591. return; // it's already there
  592. }
  593. PSID pEveryoneSid;
  594. SID_IDENTIFIER_AUTHORITY id_World = SECURITY_WORLD_SID_AUTHORITY;
  595. if(!AllocateAndInitializeSid( &id_World, 1,
  596. SECURITY_WORLD_RID,
  597. 0,0,0,0,0,0,0,
  598. &pEveryoneSid)) return;
  599. OnDelete<PSID,PVOID(*)(PSID),FreeSid> freeSid1(pEveryoneSid);
  600. SID_IDENTIFIER_AUTHORITY id_NT = SECURITY_NT_AUTHORITY;
  601. PSID pAdministratorsSid = NULL;
  602. if (!AllocateAndInitializeSid(&id_NT,
  603. 2,
  604. SECURITY_BUILTIN_DOMAIN_RID,
  605. DOMAIN_ALIAS_RID_ADMINS,
  606. 0, 0, 0, 0, 0, 0,
  607. &pAdministratorsSid)) return;
  608. OnDelete<PSID,PVOID(*)(PSID),FreeSid> freeSid2(pAdministratorsSid);
  609. // Create the class sids for everyone and administrators
  610. CNtSid SidEveryone(pEveryoneSid);
  611. CNtSid SidAdmins(pAdministratorsSid);
  612. if(SidEveryone.GetStatus() != 0 || SidAdmins.GetStatus() != 0)
  613. return;
  614. // Create a single ACE, and add it to the ACL
  615. CNtAcl DestAcl;
  616. CNtAce Users(1, ACCESS_ALLOWED_ACE_TYPE, 0, SidEveryone);
  617. if(Users.GetStatus() != 0)
  618. return;
  619. DestAcl.AddAce(&Users);
  620. if(DestAcl.GetStatus() != 0)
  621. return;
  622. // Set the descresionary acl, and the owner and group sids
  623. // Create a sd with a single entry for launch permissions.
  624. CNtSecurityDescriptor LaunchPermSD;
  625. LaunchPermSD.SetDacl(&DestAcl);
  626. LaunchPermSD.SetOwner(&SidAdmins);
  627. LaunchPermSD.SetGroup(&SidAdmins);
  628. if(LaunchPermSD.GetStatus() != 0) return;
  629. // Write it out
  630. reg.SetBinary(__TEXT("LaunchPermission"), (BYTE *)LaunchPermSD.GetPtr(), LaunchPermSD.GetSize());
  631. }
  632. //***************************************************************************
  633. //
  634. // DllRegisterServer
  635. //
  636. // Standard OLE entry point for registering the server.
  637. //
  638. // RETURN VALUES:
  639. //
  640. // S_OK Registration was successful
  641. // E_FAIL Registration failed.
  642. //
  643. //***************************************************************************
  644. STDAPI DllRegisterServer(void)
  645. {
  646. // set the group
  647. HKEY hKey;
  648. LONG lRet;
  649. BOOL bRet = TRUE;
  650. if (bRet)
  651. {
  652. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  653. SVCHOST_HOME,
  654. 0,
  655. KEY_ALL_ACCESS,
  656. &hKey);
  657. if (ERROR_SUCCESS == lRet)
  658. {
  659. // add the group
  660. LONG lRet2;
  661. DWORD dwCurrSize;
  662. DWORD dwType;
  663. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP,0,&dwType,NULL,&dwCurrSize);
  664. if (ERROR_SUCCESS == lRet2)
  665. {
  666. // the key is there, append to the multistring
  667. BYTE * pMulti = new BYTE[(dwCurrSize+sizeof(SERVICE_NAME)+4)];
  668. wmilib::auto_buffer<BYTE> rm4_(pMulti);
  669. if (pMulti)
  670. {
  671. lRet2 = RegQueryValueEx(hKey,SERVICE_NAME_GROUP,0,&dwType,pMulti,&dwCurrSize);
  672. if (ERROR_SUCCESS == lRet2) // add REG_MULITSZ check
  673. {
  674. TCHAR * pInsertPoint = (TCHAR *)(pMulti+dwCurrSize-sizeof(TCHAR));
  675. // verify the multisz
  676. TCHAR *pEnd = (TCHAR *)pMulti;
  677. BOOL bIsThere = FALSE;
  678. while (*pEnd)
  679. {
  680. if (0 == _tcsicmp(pEnd,SERVICE_NAME))
  681. {
  682. bIsThere = TRUE;
  683. }
  684. while (*pEnd){
  685. pEnd++;
  686. }
  687. pEnd++; // past the zero who terminates the string
  688. }
  689. if (!bIsThere)
  690. {
  691. if ((ULONG_PTR)pEnd == (ULONG_PTR)pInsertPoint)
  692. {
  693. _tcsncpy(pEnd,SERVICE_NAME _T("\0"),sizeof(SERVICE_NAME)/sizeof(TCHAR)+1);
  694. DWORD dwNowSize = dwCurrSize+sizeof(SERVICE_NAME);
  695. RegSetValueEx(hKey,SERVICE_NAME_GROUP,0,REG_MULTI_SZ,pMulti,dwNowSize);
  696. }
  697. else
  698. {
  699. DebugBreak();
  700. }
  701. }
  702. }
  703. }
  704. else
  705. {
  706. bRet = FALSE;
  707. }
  708. }
  709. else if (ERROR_FILE_NOT_FOUND == lRet2)
  710. {
  711. BYTE * pMulti = (BYTE *)SERVICE_NAME_GROUP _T("\0");
  712. RegSetValueEx(hKey,SERVICE_NAME_GROUP,0,REG_MULTI_SZ,pMulti,sizeof(SERVICE_NAME_GROUP)+sizeof(_T("")));
  713. }
  714. else
  715. {
  716. // what to do ?
  717. }
  718. HKEY hKey2;
  719. DWORD dwDisposistion;
  720. lRet = RegCreateKeyEx(hKey,
  721. SERVICE_NAME_GROUP,
  722. 0,NULL,
  723. REG_OPTION_NON_VOLATILE,
  724. KEY_ALL_ACCESS,
  725. NULL,
  726. &hKey2,
  727. &dwDisposistion);
  728. if (ERROR_SUCCESS == lRet)
  729. {
  730. // any value non NULL will work
  731. DWORD dwVal = 1;
  732. RegSetValueEx(hKey2,VALUE_COINIT,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  733. // servicehost default + static cloaking
  734. dwVal = EOAC_DISABLE_AAA | EOAC_NO_CUSTOM_MARSHAL | EOAC_STATIC_CLOAKING ;
  735. RegSetValueEx(hKey2,VALUE_AUTH,0,REG_DWORD,(BYTE *)&dwVal,sizeof(DWORD));
  736. RegCloseKey(hKey2);
  737. bRet = TRUE;
  738. }
  739. }
  740. }
  741. BOOL bCreated = FALSE;
  742. if (bRet)
  743. {
  744. SC_HANDLE hSCM = NULL;
  745. hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  746. if (hSCM)
  747. {
  748. DWORD dwTag;
  749. TCHAR BinPath[MAX_PATH];
  750. wsprintf(BinPath,_T("%%systemroot%%\\system32\\svchost.exe -k %s"),SERVICE_NAME_GROUP);
  751. TCHAR * pServiceDisplay = new TCHAR[MAX_BUFF];
  752. if (pServiceDisplay)
  753. {
  754. int nRet = LoadString(g_hInstance,ID_WINMGMT_SERVICE,pServiceDisplay,MAX_BUFF);
  755. }
  756. else
  757. {
  758. bRet = FALSE;
  759. }
  760. SC_HANDLE hService = NULL;
  761. if (bRet)
  762. {
  763. hService = OpenService(hSCM,SERVICE_NAME,SERVICE_ALL_ACCESS );
  764. }
  765. SC_ACTION ac[2];
  766. ac[0].Type = SC_ACTION_RESTART;
  767. ac[0].Delay = 60000;
  768. ac[1].Type = SC_ACTION_RESTART;
  769. ac[1].Delay = 60000;
  770. SERVICE_FAILURE_ACTIONS sf;
  771. sf.dwResetPeriod = 86400;
  772. sf.lpRebootMsg = NULL;
  773. sf.lpCommand = NULL;
  774. sf.cActions = 2;
  775. sf.lpsaActions = ac;
  776. if (hService)
  777. {
  778. bRet = ChangeServiceConfig(hService,
  779. SERVICE_WIN32_SHARE_PROCESS,
  780. SERVICE_AUTO_START, //SERVICE_DEMAND_START,
  781. SERVICE_ERROR_IGNORE,
  782. BinPath,
  783. NULL,
  784. NULL,
  785. _T("RPCSS\0Eventlog\0\0\0"),
  786. NULL, //ACCOUNT_NAME,
  787. NULL,
  788. pServiceDisplay);
  789. if (bRet)
  790. {
  791. ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sf);
  792. //
  793. // insert code for description here
  794. TCHAR * pBuff = new TCHAR[MAX_BUFF];
  795. if (pBuff)
  796. {
  797. int nRet = LoadString(g_hInstance,ID_WINMGMT_DESCRIPTION,pBuff,MAX_BUFF);
  798. if (nRet)
  799. {
  800. SERVICE_DESCRIPTION sd;
  801. sd.lpDescription = pBuff;
  802. ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,&sd);
  803. }
  804. delete [] pBuff;
  805. }
  806. //
  807. //
  808. }
  809. else
  810. {
  811. DBG_PRINTFA((pBuff,"ChangeServiceConfig %d\n",GetLastError()));
  812. }
  813. CloseServiceHandle(hService);
  814. }
  815. else
  816. {
  817. // Create it
  818. hService = CreateService(hSCM,
  819. SERVICE_NAME,
  820. pServiceDisplay,
  821. SERVICE_ALL_ACCESS,
  822. SERVICE_WIN32_SHARE_PROCESS,
  823. SERVICE_AUTO_START, //SERVICE_DEMAND_START,
  824. SERVICE_ERROR_IGNORE,
  825. BinPath,
  826. NULL,
  827. NULL,
  828. _T("RPCSS\0Eventlog\0\0\0"),
  829. NULL, //ACCOUNT_NAME,
  830. NULL);
  831. if (hService)
  832. {
  833. ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &sf);
  834. //
  835. // insert code for description here
  836. TCHAR * pBuff = new TCHAR[MAX_BUFF];
  837. if (pBuff)
  838. {
  839. int nRet = LoadString(g_hInstance,ID_WINMGMT_DESCRIPTION,pBuff,MAX_BUFF);
  840. if (nRet)
  841. {
  842. SERVICE_DESCRIPTION sd;
  843. sd.lpDescription = pBuff;
  844. ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,&sd);
  845. }
  846. delete [] pBuff;
  847. }
  848. //
  849. //
  850. CloseServiceHandle(hService);
  851. bRet = TRUE;
  852. };
  853. }
  854. if (pServiceDisplay)
  855. {
  856. delete [] pServiceDisplay;
  857. }
  858. CloseServiceHandle(hSCM);
  859. }
  860. }
  861. if (bRet)
  862. {
  863. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  864. SERVICE_PATH SERVICE_NAME,
  865. 0,
  866. KEY_ALL_ACCESS,
  867. &hKey);
  868. if (ERROR_SUCCESS == lRet)
  869. {
  870. HKEY hKey3;
  871. DWORD dwDisposistion;
  872. lRet = RegCreateKeyEx(hKey,
  873. _T("Parameters"),
  874. 0,NULL,
  875. REG_OPTION_NON_VOLATILE,
  876. KEY_ALL_ACCESS,
  877. NULL,
  878. &hKey3,
  879. &dwDisposistion);
  880. if (ERROR_SUCCESS == lRet)
  881. {
  882. RegSetValueEx(hKey3,_T("ServiceDll"),0,REG_EXPAND_SZ,(BYTE *)DLL_PATH,sizeof(DLL_PATH)-sizeof(TCHAR));
  883. RegSetValueEx(hKey3,_T("ServiceMain"),0,REG_SZ,(BYTE *)ENTRY_POINT,sizeof(ENTRY_POINT)-sizeof(TCHAR));
  884. RegCloseKey(hKey3);
  885. bRet = TRUE;
  886. };
  887. RegCloseKey(hKey);
  888. }
  889. }
  890. if (bRet)
  891. {
  892. HKEY hKey4;
  893. DWORD dwDisposistion;
  894. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  895. COM_APPID,
  896. 0,NULL,
  897. REG_OPTION_NON_VOLATILE,
  898. KEY_ALL_ACCESS,
  899. NULL,
  900. &hKey4,
  901. &dwDisposistion);
  902. if (ERROR_SUCCESS == lRet)
  903. {
  904. RegSetValueEx(hKey4,NULL,0,REG_SZ,(BYTE *)DISPLAY_CLSID,sizeof(DISPLAY_CLSID)-sizeof(TCHAR));
  905. RegSetValueEx(hKey4,_T("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR));
  906. RegCloseKey(hKey4);
  907. }
  908. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  909. COM_APPID_NAME,
  910. 0,NULL,
  911. REG_OPTION_NON_VOLATILE,
  912. KEY_ALL_ACCESS,
  913. NULL,
  914. &hKey4,
  915. &dwDisposistion);
  916. if (ERROR_SUCCESS == lRet)
  917. {
  918. RegSetValueEx(hKey4,_T("AppID"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR));
  919. RegCloseKey(hKey4);
  920. }
  921. InitializeLaunchPermissions();
  922. OLECHAR ClsidBuff[40];
  923. TCHAR * ClsidBuff2;
  924. TCHAR ClsidPath[MAX_PATH];
  925. StringFromGUID2(CLSID_WbemLevel1Login,ClsidBuff,40);
  926. #ifdef UNICODE
  927. ClsidBuff2 = ClsidBuff;
  928. #else
  929. TCHAR pTmp_[40];
  930. ClsidPath2 = pTmp_;
  931. WideCharToMultiByte(CP_ACP,0,ClsidBuff,-1,ClsidBuff2,40,NULL,NULL);
  932. #endif
  933. wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff2);
  934. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  935. ClsidPath,
  936. 0,NULL,
  937. REG_OPTION_NON_VOLATILE,
  938. KEY_ALL_ACCESS,
  939. NULL,
  940. &hKey4,
  941. &dwDisposistion);
  942. if (ERROR_SUCCESS == lRet)
  943. {
  944. RegSetValueEx(hKey4,NULL,0,REG_SZ,(BYTE *)DISPLAY_CLSID,sizeof(DISPLAY_CLSID)-sizeof(TCHAR));
  945. RegSetValueEx(hKey4,_T("AppId"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR));
  946. RegSetValueEx(hKey4,_T("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR));
  947. RegCloseKey(hKey4);
  948. }
  949. StringFromGUID2(CLSID_WbemBackupRestore,ClsidBuff,40);
  950. #ifdef UNICODE
  951. ClsidBuff2 = ClsidBuff;
  952. #else
  953. // already _alloca-ted at this point
  954. //ClsidPath2 = (TCHAR *)_alloca(40*sizeof(TCHAR));
  955. WideCharToMultiByte(CP_ACP,0,ClsidBuff,-1,ClsidBuff2,40,NULL,NULL);
  956. #endif
  957. wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff);
  958. lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  959. ClsidPath,
  960. 0,NULL,
  961. REG_OPTION_NON_VOLATILE,
  962. KEY_ALL_ACCESS,
  963. NULL,
  964. &hKey4,
  965. &dwDisposistion);
  966. if (ERROR_SUCCESS == lRet)
  967. {
  968. RegSetValueEx(hKey4,NULL,0,REG_SZ,(BYTE *)DISPLAY_BACKUP_CLSID,sizeof(DISPLAY_BACKUP_CLSID)-sizeof(TCHAR));
  969. RegSetValueEx(hKey4,_T("AppId"),0,REG_SZ,(BYTE *)SERVICE_CLSID,sizeof(SERVICE_CLSID)-sizeof(TCHAR));
  970. RegSetValueEx(hKey4,_T("LocalService"),0,REG_SZ,(BYTE *)SERVICE_NAME,sizeof(SERVICE_NAME)-sizeof(TCHAR));
  971. RegCloseKey(hKey4);
  972. }
  973. }
  974. return S_OK;
  975. }
  976. //***************************************************************************
  977. //
  978. // DllUnregisterServer
  979. //
  980. // Standard OLE entry point for unregistering the server.
  981. //
  982. // RETURN VALUES:
  983. //
  984. // S_OK Unregistration was successful
  985. // E_FAIL Unregistration failed.
  986. //
  987. //***************************************************************************
  988. STDAPI DllUnregisterServer(void)
  989. {
  990. HKEY hKey;
  991. LONG lRet;
  992. BOOL bRet = TRUE;
  993. if (bRet)
  994. {
  995. TCHAR ClsidBuff[40];
  996. TCHAR ClsidPath[MAX_PATH];
  997. #ifdef UNICODE
  998. StringFromCLSID(CLSID_WbemLevel1Login,(LPOLESTR *)ClsidBuff);
  999. #else
  1000. WCHAR ClsidPath2[40];
  1001. StringFromCLSID(CLSID_WbemLevel1Login,(LPOLESTR *)ClsidBuff2);
  1002. MultiByteToWideChar(CP_ACP,0,ClsidBuff2,-1,ClsidBuff,40);
  1003. #endif
  1004. wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff);
  1005. lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,ClsidPath);
  1006. #ifdef UNICODE
  1007. StringFromCLSID(CLSID_WbemBackupRestore,(LPOLESTR *)ClsidBuff);
  1008. #else
  1009. WCHAR ClsidPath2[40];
  1010. StringFromCLSID(CLSID_WbemBackupRestore,(LPOLESTR *)ClsidBuff2);
  1011. MultiByteToWideChar(CP_ACP,0,ClsidBuff2,-1,ClsidBuff,40);
  1012. #endif
  1013. wsprintf(ClsidPath,_T("software\\classes\\CLSID\\%s"),ClsidBuff);
  1014. lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,ClsidPath);
  1015. lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,COM_APPID);
  1016. lRet = RegDeleteKey(HKEY_LOCAL_MACHINE,COM_APPID_NAME);
  1017. }
  1018. return S_OK;
  1019. }