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.

1095 lines
30 KiB

  1. //---------------------------------------------------------------------
  2. // Copyright (C)1998 Microsoft Corporation, All Rights Reserved.
  3. //
  4. // registry.cpp
  5. //
  6. //---------------------------------------------------------------------
  7. #define UNICODE
  8. #define INITGUID
  9. #include <nt.h>
  10. #include <ntrtl.h>
  11. #include <nturtl.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #ifndef WIN32_LEAN_AND_MEAN
  16. #define WIN32_LEAN_AND_MEAN
  17. #endif
  18. #include <windows.h>
  19. #include <malloc.h>
  20. #include <winsock2.h>
  21. #include <olectl.h> // for: SELFREG_E_CLASS
  22. #include <iadmw.h> // COM Interface header
  23. #include <iiscnfg.h> // MD_ & IIS_MD_ #defines
  24. #include <httpfilt.h>
  25. #include "registry.h"
  26. //----------------------------------------------------------------
  27. // Externals:
  28. //----------------------------------------------------------------
  29. extern "C" void *MemAllocate( DWORD dwSize );
  30. extern "C" void *MemFree( VOID *pMem );
  31. //----------------------------------------------------------------
  32. // Globals:
  33. //----------------------------------------------------------------
  34. // static HINSTANCE g_hInst = 0;
  35. //----------------------------------------------------------------
  36. // AnsiToUnicode()
  37. //
  38. // Convert an ANSI string to a UNICODE string.
  39. //----------------------------------------------------------------
  40. DWORD AnsiToUnicode( IN UCHAR *pszString,
  41. IN ULONG ulStringLen,
  42. OUT WCHAR *pwsString )
  43. {
  44. if (!pszString)
  45. {
  46. if (!pwsString)
  47. {
  48. return NO_ERROR;
  49. }
  50. else
  51. {
  52. pwsString[0] = 0;
  53. return NO_ERROR;
  54. }
  55. }
  56. if (!MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
  57. (char*)pszString, 1+ulStringLen,
  58. pwsString, 1+ulStringLen ))
  59. {
  60. return ERROR_NO_UNICODE_TRANSLATION;
  61. }
  62. return NO_ERROR;
  63. }
  64. //---------------------------------------------------------------------
  65. // RegSetKeyAndValue()
  66. //
  67. // Private helper function for SetupRegistry() that creates
  68. // a key, sets a value, then closes the key.
  69. //
  70. // Parameters:
  71. // pwsKey WCHAR* The name of the key
  72. // pwsSubkey WCHAR* The name of a subkey
  73. // pwsValueName WCHAR* The value name.
  74. // pwsValue WCHAR* The data value to store
  75. // dwType The type for the new registry value.
  76. // dwDataSize The size for non-REG_SZ registry entry types.
  77. //
  78. // Return:
  79. // BOOL TRUE if successful, FALSE otherwise.
  80. //---------------------------------------------------------------------
  81. BOOL RegSetKeyAndValue( const WCHAR *pwsKey,
  82. const WCHAR *pwsSubKey,
  83. const WCHAR *pwsValueName,
  84. const WCHAR *pwsValue,
  85. const DWORD dwType = REG_SZ,
  86. DWORD dwDataSize = 0 )
  87. {
  88. HKEY hKey;
  89. DWORD dwSize = 0;
  90. WCHAR *pwsCompleteKey;
  91. if (pwsKey)
  92. dwSize = wcslen(pwsKey);
  93. if (pwsSubKey)
  94. dwSize += wcslen(pwsSubKey);
  95. dwSize = (1+1+dwSize)*sizeof(WCHAR); // Extra +1 for the backslash...
  96. pwsCompleteKey = (WCHAR*)_alloca(dwSize);
  97. if (!pwsCompleteKey)
  98. {
  99. return FALSE; // Out of stack memory.
  100. }
  101. wcscpy(pwsCompleteKey,pwsKey);
  102. if (NULL!=pwsSubKey)
  103. {
  104. wcscat(pwsCompleteKey, TEXT("\\"));
  105. wcscat(pwsCompleteKey, pwsSubKey);
  106. }
  107. if (ERROR_SUCCESS!=RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  108. pwsCompleteKey,
  109. 0,
  110. NULL,
  111. REG_OPTION_NON_VOLATILE,
  112. KEY_ALL_ACCESS, NULL, &hKey, NULL))
  113. {
  114. return FALSE;
  115. }
  116. if (pwsValue)
  117. {
  118. if ((dwType == REG_SZ)||(dwType == REG_EXPAND_SZ))
  119. dwDataSize = (1+wcslen(pwsValue))*sizeof(WCHAR);
  120. RegSetValueEx( hKey,
  121. pwsValueName, 0, dwType, (BYTE *)pwsValue, dwDataSize );
  122. }
  123. else
  124. {
  125. RegSetValueEx( hKey,
  126. pwsValueName, 0, dwType, (BYTE *)pwsValue, 0 );
  127. }
  128. RegCloseKey(hKey);
  129. return TRUE;
  130. }
  131. //---------------------------------------------------------------------
  132. // SetupRegistry()
  133. //
  134. // Add RPC proxy specific registry entries to contol its operation.
  135. //
  136. // \HKEY_LOCAL_MACHINE
  137. // \Software
  138. // \Microsoft
  139. // \Rpc
  140. // \RpcProxy
  141. // \Enabled:REG_DWORD:0x00000001
  142. // \ValidPorts:REG_SZ:<hostname>:1-5000
  143. //
  144. //---------------------------------------------------------------------
  145. HRESULT SetupRegistry()
  146. {
  147. DWORD dwEnabled = 0x01;
  148. DWORD dwSize;
  149. DWORD dwStatus;
  150. WCHAR *pwsValidPorts = 0;
  151. char szHostName[MAX_TCPIP_HOST_NAME];
  152. // Note that gethostname() is an ANSI (non-unicode) function:
  153. if (SOCKET_ERROR == gethostname(szHostName,sizeof(szHostName)))
  154. {
  155. dwStatus = WSAGetLastError();
  156. return SELFREG_E_CLASS;
  157. }
  158. dwSize = 1 + _mbstrlen(szHostName);
  159. pwsValidPorts = (WCHAR*)MemAllocate( sizeof(WCHAR)
  160. * (dwSize + wcslen(REG_PORT_RANGE)) );
  161. if (!pwsValidPorts)
  162. {
  163. return E_OUTOFMEMORY;
  164. }
  165. dwStatus = AnsiToUnicode((unsigned char*)szHostName,dwSize,pwsValidPorts);
  166. if (dwStatus != NO_ERROR)
  167. {
  168. MemFree(pwsValidPorts);
  169. return SELFREG_E_CLASS;
  170. }
  171. wcscat(pwsValidPorts,REG_PORT_RANGE);
  172. if ( !RegSetKeyAndValue( REG_RPC_PATH,
  173. REG_RPCPROXY,
  174. REG_ENABLED,
  175. (unsigned short *)&dwEnabled,
  176. REG_DWORD,
  177. sizeof(DWORD))
  178. || !RegSetKeyAndValue( REG_RPC_PATH,
  179. REG_RPCPROXY,
  180. REG_VALID_PORTS,
  181. pwsValidPorts,
  182. REG_SZ) )
  183. {
  184. MemFree(pwsValidPorts);
  185. return SELFREG_E_CLASS;
  186. }
  187. MemFree(pwsValidPorts);
  188. return S_OK;
  189. }
  190. //---------------------------------------------------------------------
  191. // CleanupRegistry()
  192. //
  193. // Delete the RpcProxy specific registry entries.
  194. //---------------------------------------------------------------------
  195. HRESULT CleanupRegistry()
  196. {
  197. HRESULT hr;
  198. LONG lStatus;
  199. DWORD dwLength = sizeof(WCHAR) + sizeof(REG_RPC_PATH)
  200. + sizeof(REG_RPCPROXY);
  201. WCHAR *pwsSubKey;
  202. pwsSubKey = (WCHAR*)_alloca(sizeof(WCHAR)*dwLength);
  203. if (pwsSubKey)
  204. {
  205. wcscpy(pwsSubKey,REG_RPC_PATH);
  206. wcscat(pwsSubKey,TEXT("\\"));
  207. wcscat(pwsSubKey,REG_RPCPROXY);
  208. lStatus = RegDeleteKey( HKEY_LOCAL_MACHINE,
  209. pwsSubKey );
  210. }
  211. return S_OK;
  212. }
  213. //---------------------------------------------------------------------
  214. // GetMetaBaseString()
  215. //
  216. // Retrieve a string value from the metabase.
  217. //---------------------------------------------------------------------
  218. HRESULT GetMetaBaseString( IN IMSAdminBase *pIMeta,
  219. IN METADATA_HANDLE hMetaBase,
  220. IN WCHAR *pwsKeyPath,
  221. IN DWORD dwIdent,
  222. OUT WCHAR *pwsBuffer,
  223. IN OUT DWORD *pdwBufferSize )
  224. {
  225. HRESULT hr;
  226. DWORD dwSize;
  227. METADATA_RECORD *pmbRecord;
  228. dwSize = sizeof(METADATA_RECORD);
  229. pmbRecord = (METADATA_RECORD*)MemAllocate(dwSize);
  230. if (!pmbRecord)
  231. {
  232. return ERROR_OUTOFMEMORY;
  233. }
  234. memset(pmbRecord,0,dwSize);
  235. pmbRecord->dwMDIdentifier = dwIdent;
  236. pmbRecord->dwMDAttributes = 0; // METADATA_INHERIT;
  237. pmbRecord->dwMDUserType = IIS_MD_UT_SERVER;
  238. pmbRecord->dwMDDataType = STRING_METADATA;
  239. pmbRecord->dwMDDataLen = *pdwBufferSize;
  240. pmbRecord->pbMDData = (BYTE*)pwsBuffer;
  241. hr = pIMeta->GetData( hMetaBase,
  242. pwsKeyPath,
  243. pmbRecord,
  244. &dwSize );
  245. #ifdef DBG_REG
  246. if (FAILED(hr))
  247. {
  248. DbgPrint("pIMeta->GetData(): Failed: 0x%x\n",hr);
  249. }
  250. #endif
  251. MemFree(pmbRecord);
  252. return hr;
  253. }
  254. //---------------------------------------------------------------------
  255. // SetMetaBaseString()
  256. //
  257. // Store a string value into the metabase.
  258. //---------------------------------------------------------------------
  259. HRESULT SetMetaBaseString( IMSAdminBase *pIMeta,
  260. METADATA_HANDLE hMetaBase,
  261. WCHAR *pwsKeyPath,
  262. DWORD dwIdent,
  263. WCHAR *pwsBuffer,
  264. DWORD dwAttributes,
  265. DWORD dwUserType )
  266. {
  267. HRESULT hr;
  268. METADATA_RECORD MbRecord;
  269. memset(&MbRecord,0,sizeof(MbRecord));
  270. MbRecord.dwMDIdentifier = dwIdent;
  271. MbRecord.dwMDAttributes = dwAttributes;
  272. MbRecord.dwMDUserType = dwUserType;
  273. MbRecord.dwMDDataType = STRING_METADATA;
  274. MbRecord.dwMDDataLen = sizeof(WCHAR) * (1 + wcslen(pwsBuffer));
  275. MbRecord.pbMDData = (BYTE*)pwsBuffer;
  276. hr = pIMeta->SetData( hMetaBase,
  277. pwsKeyPath,
  278. &MbRecord );
  279. return hr;
  280. }
  281. //---------------------------------------------------------------------
  282. // GetMetaBaseDword()
  283. //
  284. // Get a DWORD value from the metabase.
  285. //---------------------------------------------------------------------
  286. HRESULT GetMetaBaseDword( IMSAdminBase *pIMeta,
  287. METADATA_HANDLE hMetaBase,
  288. WCHAR *pwsKeyPath,
  289. DWORD dwIdent,
  290. DWORD *pdwValue )
  291. {
  292. HRESULT hr;
  293. DWORD dwSize;
  294. METADATA_RECORD MbRecord;
  295. memset(&MbRecord,0,sizeof(MbRecord));
  296. *pdwValue = 0;
  297. MbRecord.dwMDIdentifier = dwIdent;
  298. MbRecord.dwMDAttributes = 0;
  299. MbRecord.dwMDUserType = IIS_MD_UT_SERVER;
  300. MbRecord.dwMDDataType = DWORD_METADATA;
  301. MbRecord.dwMDDataLen = sizeof(DWORD);
  302. MbRecord.pbMDData = (unsigned char *)pdwValue;
  303. hr = pIMeta->GetData( hMetaBase,
  304. pwsKeyPath,
  305. &MbRecord,
  306. &dwSize );
  307. return hr;
  308. }
  309. //---------------------------------------------------------------------
  310. // SetMetaBaseDword()
  311. //
  312. // Store a DWORD value into the metabase.
  313. //---------------------------------------------------------------------
  314. HRESULT SetMetaBaseDword( IMSAdminBase *pIMeta,
  315. METADATA_HANDLE hMetaBase,
  316. WCHAR *pwsKeyPath,
  317. DWORD dwIdent,
  318. DWORD dwValue,
  319. DWORD dwAttributes,
  320. DWORD dwUserType )
  321. {
  322. HRESULT hr;
  323. DWORD dwSize;
  324. METADATA_RECORD MbRecord;
  325. memset(&MbRecord,0,sizeof(MbRecord));
  326. MbRecord.dwMDIdentifier = dwIdent;
  327. MbRecord.dwMDAttributes = dwAttributes;
  328. MbRecord.dwMDUserType = dwUserType;
  329. MbRecord.dwMDDataType = DWORD_METADATA;
  330. MbRecord.dwMDDataLen = sizeof(DWORD);
  331. MbRecord.pbMDData = (unsigned char *)&dwValue;
  332. hr = pIMeta->SetData( hMetaBase,
  333. pwsKeyPath,
  334. &MbRecord );
  335. return hr;
  336. }
  337. //---------------------------------------------------------------------
  338. // SetupMetaBase()
  339. //
  340. // Setup entries in the metabase for both the filter and ISAPI parts
  341. // of the RPC proxy. Note that these entries used to be in the registry.
  342. //
  343. // W3Svc/Filters/FilterLoadOrder "...,RpcProxy"
  344. // W3Svc/Filters/RpcProxy/FilterImagePath "%SystemRoot%\System32\RpcProxy"
  345. // W3Svc/Filters/RpcProxy/KeyType "IIsFilter"
  346. // W3Svc/Filters/RpcProxy/FilterDescription "Microsoft RPC Proxy Filter, v1.0"
  347. //
  348. // W3Svc/1/ROOT/Rpc/KeyType "IIsWebVirtualDir"
  349. // W3Svc/1/ROOT/Rpc/VrPath "%SystemRoot%\System32\RpcProxy"
  350. // W3Svc/1/ROOT/Rpc/AccessPerm 0x205
  351. // W3Svc/1/ROOT/Rpc/Win32Error 0x0
  352. // W3Svc/1/ROOT/Rpc/DirectoryBrowsing 0x4000001E
  353. // W3Svc/1/ROOT/Rpc/AppIsolated 0x0
  354. // W3Svc/1/ROOT/Rpc/AppRoot "/LM/W3SVC/1/Root/rpc"
  355. // W3Svc/1/ROOT/Rpc/AppWamClsid "{BF285648-0C5C-11D2-A476-0000F8080B50}"
  356. // W3Svc/1/ROOT/Rpc/AppFriendlyName "rpc"
  357. //
  358. //---------------------------------------------------------------------
  359. HRESULT SetupMetaBase()
  360. {
  361. HRESULT hr = 0;
  362. DWORD dwValue = 0;
  363. DWORD dwSize = 0;
  364. DWORD dwBufferSize = sizeof(WCHAR) * ORIGINAL_BUFFER_SIZE;
  365. WCHAR *pwsBuffer = (WCHAR*)MemAllocate(dwBufferSize);
  366. WCHAR *pwsSystemRoot = _wgetenv(SYSTEM_ROOT);
  367. WCHAR wsPath[METADATA_MAX_NAME_LEN];
  368. IMSAdminBase *pIMeta;
  369. METADATA_HANDLE hMetaBase;
  370. //
  371. // Name of this DLL (and where it is):
  372. //
  373. // WCHAR wszModule[256];
  374. //
  375. // if (!GetModuleFileName( g_hInst, wszModule,
  376. // sizeof(wszModule)/sizeof(WCHAR)))
  377. // {
  378. // return SELFREG_E_CLASS;
  379. // }
  380. if (!pwsBuffer)
  381. {
  382. return E_OUTOFMEMORY;
  383. }
  384. hr = CoCreateInstance( CLSID_MSAdminBase,
  385. NULL,
  386. CLSCTX_ALL,
  387. IID_IMSAdminBase,
  388. (void **)&pIMeta );
  389. if (FAILED(hr))
  390. {
  391. #ifdef DBG_REG
  392. DbgPrint("CoCreateInstance(): Failed: 0x%x\n",hr);
  393. #endif
  394. MemFree(pwsBuffer);
  395. return hr;
  396. }
  397. // Get a handle to the Web service:
  398. hr = pIMeta->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  399. LOCAL_MACHINE_W3SVC,
  400. (METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE),
  401. 20,
  402. &hMetaBase );
  403. if (FAILED(hr))
  404. {
  405. #ifdef DBG_REG
  406. DbgPrint("pIMeta->OpenKey(): Failed: 0x%x\n",hr);
  407. #endif
  408. MemFree(pwsBuffer);
  409. pIMeta->Release();
  410. return hr;
  411. }
  412. //
  413. // IIS Filter: FilterLoadOrder
  414. //
  415. dwSize = dwBufferSize;
  416. hr = GetMetaBaseString( pIMeta,
  417. hMetaBase,
  418. MD_KEY_FILTERS, // See iiscnfg.h
  419. MD_FILTER_LOAD_ORDER, // See iiscnfg.h
  420. pwsBuffer,
  421. &dwSize );
  422. if (FAILED(hr))
  423. {
  424. #ifdef DBG_REG
  425. DbgPrint("GetMetaBaseString(): Failed: 0x%x\n",hr);
  426. #endif
  427. MemFree(pwsBuffer);
  428. pIMeta->Release();
  429. return hr;
  430. }
  431. else
  432. {
  433. if (!wcsstr(pwsBuffer,RPCPROXY))
  434. {
  435. // RpcProxy is not in FilterLoadOrder, so add it:
  436. wcscat(pwsBuffer,TEXT(","));
  437. wcscat(pwsBuffer,RPCPROXY);
  438. hr = SetMetaBaseString( pIMeta,
  439. hMetaBase,
  440. MD_KEY_FILTERS,
  441. MD_FILTER_LOAD_ORDER,
  442. pwsBuffer,
  443. 0,
  444. IIS_MD_UT_SERVER );
  445. }
  446. if (FAILED(hr))
  447. {
  448. MemFree(pwsBuffer);
  449. pIMeta->Release();
  450. return hr;
  451. }
  452. }
  453. //
  454. // IIS Filter: RpcProxy/FilterImagePath
  455. //
  456. hr = pIMeta->AddKey( hMetaBase, MD_KEY_FILTERS_RPCPROXY );
  457. if ( (FAILED(hr)) && (hr != 0x800700b7))
  458. {
  459. MemFree(pwsBuffer);
  460. pIMeta->Release();
  461. return hr;
  462. }
  463. wcscpy(pwsBuffer,pwsSystemRoot);
  464. wcscat(pwsBuffer,RPCPROXY_PATH);
  465. wcscat(pwsBuffer,TEXT("\\"));
  466. wcscat(pwsBuffer,RPCPROXY_DLL);
  467. hr = SetMetaBaseString( pIMeta,
  468. hMetaBase,
  469. MD_KEY_FILTERS_RPCPROXY,
  470. MD_FILTER_IMAGE_PATH,
  471. pwsBuffer,
  472. 0,
  473. IIS_MD_UT_SERVER );
  474. if (FAILED(hr))
  475. {
  476. MemFree(pwsBuffer);
  477. pIMeta->Release();
  478. return hr;
  479. }
  480. //
  481. // IIS Filter: Filters/RpcProxy/KeyType
  482. //
  483. wcscpy(pwsBuffer,IISFILTER);
  484. hr = SetMetaBaseString( pIMeta,
  485. hMetaBase,
  486. MD_KEY_FILTERS_RPCPROXY,
  487. MD_KEY_TYPE,
  488. pwsBuffer,
  489. 0,
  490. IIS_MD_UT_SERVER );
  491. if (FAILED(hr))
  492. {
  493. MemFree(pwsBuffer);
  494. pIMeta->Release();
  495. return hr;
  496. }
  497. wcscpy(pwsBuffer,FILTER_DESCRIPTION);
  498. hr = SetMetaBaseString( pIMeta,
  499. hMetaBase,
  500. MD_KEY_FILTERS_RPCPROXY,
  501. MD_FILTER_DESCRIPTION,
  502. pwsBuffer,
  503. 0,
  504. IIS_MD_UT_SERVER );
  505. if (FAILED(hr))
  506. {
  507. MemFree(pwsBuffer);
  508. pIMeta->Release();
  509. return hr;
  510. }
  511. hr = SetMetaBaseDword( pIMeta,
  512. hMetaBase,
  513. MD_KEY_FILTERS_RPCPROXY,
  514. MD_FILTER_FLAGS,
  515. SF_NOTIFY_ORDER_LOW
  516. | SF_NOTIFY_READ_RAW_DATA
  517. | SF_NOTIFY_END_OF_NET_SESSION
  518. | SF_NOTIFY_PREPROC_HEADERS,
  519. 0,
  520. IIS_MD_UT_SERVER );
  521. if (FAILED(hr))
  522. {
  523. MemFree(pwsBuffer);
  524. pIMeta->Release();
  525. return hr;
  526. }
  527. //
  528. // Set: /W3Svc/1/ROOT/rpc/AccessPerm
  529. //
  530. dwValue = ACCESS_PERM_FLAGS;
  531. hr = SetMetaBaseDword( pIMeta,
  532. hMetaBase,
  533. MD_KEY_ROOT_RPC,
  534. MD_ACCESS_PERM,
  535. dwValue,
  536. METADATA_INHERIT,
  537. IIS_MD_UT_FILE );
  538. if (FAILED(hr))
  539. {
  540. MemFree(pwsBuffer);
  541. pIMeta->Release();
  542. return hr;
  543. }
  544. //
  545. // Disable entity body preload for this ISAPI
  546. //
  547. dwValue = 0;
  548. hr = SetMetaBaseDword( pIMeta,
  549. hMetaBase,
  550. MD_KEY_ROOT_RPC,
  551. MD_UPLOAD_READAHEAD_SIZE,
  552. dwValue,
  553. METADATA_INHERIT,
  554. IIS_MD_UT_FILE );
  555. if (FAILED(hr))
  556. {
  557. MemFree(pwsBuffer);
  558. pIMeta->Release();
  559. return hr;
  560. }
  561. //
  562. // Set: /W3Svc/1/ROOT/rpc/Win32Error
  563. //
  564. dwValue = 0;
  565. hr = SetMetaBaseDword( pIMeta,
  566. hMetaBase,
  567. MD_KEY_ROOT_RPC,
  568. MD_WIN32_ERROR,
  569. dwValue,
  570. METADATA_INHERIT,
  571. IIS_MD_UT_SERVER );
  572. if (FAILED(hr))
  573. {
  574. MemFree(pwsBuffer);
  575. pIMeta->Release();
  576. return hr;
  577. }
  578. //
  579. // Set: /W3Svc/1/ROOT/rpc/DirectroyBrowsing
  580. //
  581. dwValue = DIRECTORY_BROWSING_FLAGS;
  582. hr = SetMetaBaseDword( pIMeta,
  583. hMetaBase,
  584. MD_KEY_ROOT_RPC,
  585. MD_DIRECTORY_BROWSING,
  586. dwValue,
  587. METADATA_INHERIT,
  588. IIS_MD_UT_FILE );
  589. if (FAILED(hr))
  590. {
  591. pIMeta->Release();
  592. CoUninitialize();
  593. return hr;
  594. }
  595. //
  596. // Set: /W3Svc/1/ROOT/rpc/KeyType
  597. //
  598. wcscpy(pwsBuffer,IIS_WEB_VIRTUAL_DIR);
  599. hr = SetMetaBaseString( pIMeta,
  600. hMetaBase,
  601. MD_KEY_ROOT_RPC,
  602. MD_KEY_TYPE,
  603. pwsBuffer,
  604. 0,
  605. IIS_MD_UT_SERVER );
  606. if (FAILED(hr))
  607. {
  608. MemFree(pwsBuffer);
  609. pIMeta->Release();
  610. return hr;
  611. }
  612. //
  613. // Set: /W3Svc/1/ROOT/rpc/VrPath
  614. //
  615. wcscpy(pwsBuffer,pwsSystemRoot);
  616. wcscat(pwsBuffer,RPCPROXY_PATH);
  617. hr = SetMetaBaseString( pIMeta,
  618. hMetaBase,
  619. MD_KEY_ROOT_RPC,
  620. MD_VR_PATH,
  621. pwsBuffer,
  622. METADATA_INHERIT,
  623. IIS_MD_UT_FILE );
  624. if (FAILED(hr))
  625. {
  626. MemFree(pwsBuffer);
  627. pIMeta->Release();
  628. return hr;
  629. }
  630. #if FALSE
  631. //
  632. // Set: /W3Svc/1/ROOT/rpc/AppIsolated
  633. //
  634. dwValue = 0;
  635. hr = SetMetaBaseDword( pIMeta,
  636. hMetaBase,
  637. MD_KEY_ROOT_RPC,
  638. MD_APP_ISOLATED,
  639. dwValue,
  640. METADATA_INHERIT,
  641. IIS_MD_UT_WAM );
  642. if (FAILED(hr))
  643. {
  644. MemFree(pwsBuffer);
  645. pIMeta->Release();
  646. return hr;
  647. }
  648. //
  649. // Set: /W3Svc/1/ROOT/rpc/AppRoot
  650. //
  651. wcscpy(pwsBuffer,APP_ROOT_PATH);
  652. hr = SetMetaBaseString( pIMeta,
  653. hMetaBase,
  654. MD_KEY_ROOT_RPC,
  655. MD_APP_ROOT,
  656. pwsBuffer,
  657. METADATA_INHERIT,
  658. IIS_MD_UT_FILE );
  659. if (FAILED(hr))
  660. {
  661. MemFree(pwsBuffer);
  662. pIMeta->Release();
  663. return hr;
  664. }
  665. //
  666. // Set: /W3Svc/1/ROOT/rpc/AppWamClsid
  667. //
  668. wcscpy(pwsBuffer,APP_WAM_CLSID);
  669. hr = SetMetaBaseString( pIMeta,
  670. hMetaBase,
  671. MD_KEY_ROOT_RPC,
  672. MD_APP_WAM_CLSID,
  673. pwsBuffer,
  674. METADATA_INHERIT,
  675. IIS_MD_UT_WAM );
  676. if (FAILED(hr))
  677. {
  678. MemFree(pwsBuffer);
  679. pIMeta->Release();
  680. return hr;
  681. }
  682. //
  683. // Set: /W3Svc/1/ROOT/rpc/AppFriendlyName
  684. //
  685. wcscpy(pwsBuffer,APP_FRIENDLY_NAME);
  686. hr = SetMetaBaseString( pIMeta,
  687. hMetaBase,
  688. MD_KEY_ROOT_RPC,
  689. MD_APP_FRIENDLY_NAME,
  690. pwsBuffer,
  691. METADATA_INHERIT,
  692. IIS_MD_UT_WAM );
  693. if (FAILED(hr))
  694. {
  695. MemFree(pwsBuffer);
  696. pIMeta->Release();
  697. return hr;
  698. }
  699. #endif
  700. //
  701. // Release the handle and buffer:
  702. //
  703. MemFree(pwsBuffer);
  704. pIMeta->CloseKey(hMetaBase);
  705. pIMeta->Release();
  706. CoUninitialize();
  707. return 0;
  708. }
  709. //---------------------------------------------------------------------
  710. // CleanupMetaBase()
  711. //
  712. //---------------------------------------------------------------------
  713. HRESULT CleanupMetaBase()
  714. {
  715. HRESULT hr = 0;
  716. DWORD dwSize = 0;
  717. WCHAR *pwsRpcProxy;
  718. WCHAR *pws;
  719. DWORD dwBufferSize = sizeof(WCHAR) * ORIGINAL_BUFFER_SIZE;
  720. WCHAR *pwsBuffer = (WCHAR*)MemAllocate(dwBufferSize);
  721. // CComPtr <IMSAdminBase> pIMeta;
  722. IMSAdminBase *pIMeta;
  723. METADATA_HANDLE hMetaBase;
  724. if (!pwsBuffer)
  725. {
  726. return ERROR_OUTOFMEMORY;
  727. }
  728. hr = CoCreateInstance( CLSID_MSAdminBase,
  729. NULL,
  730. CLSCTX_ALL,
  731. IID_IMSAdminBase,
  732. (void **)&pIMeta );
  733. if (FAILED(hr))
  734. {
  735. MemFree(pwsBuffer);
  736. return hr;
  737. }
  738. //
  739. // Get a handle to the Web service:
  740. //
  741. hr = pIMeta->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  742. TEXT("/LM/W3SVC"),
  743. (METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE),
  744. 20,
  745. &hMetaBase );
  746. if (FAILED(hr))
  747. {
  748. MemFree(pwsBuffer);
  749. pIMeta->Release();
  750. return hr;
  751. }
  752. //
  753. // Remove the RpcProxy reference from the FilterLoadOrder value:
  754. //
  755. dwSize = dwBufferSize;
  756. hr = GetMetaBaseString( pIMeta,
  757. hMetaBase,
  758. MD_KEY_FILTERS,
  759. MD_FILTER_LOAD_ORDER,
  760. pwsBuffer,
  761. &dwSize );
  762. if (!FAILED(hr))
  763. {
  764. if (pwsRpcProxy=wcsstr(pwsBuffer,RPCPROXY))
  765. {
  766. // "RpcProxy" is in FilterLoadOrder, so remove it:
  767. // Check to see if RpcProxy is at the start of the list:
  768. if (pwsRpcProxy != pwsBuffer)
  769. {
  770. pwsRpcProxy--; // Want to remove the comma before...
  771. dwSize = sizeof(RPCPROXY);
  772. }
  773. else
  774. {
  775. dwSize = sizeof(RPCPROXY) - 1;
  776. }
  777. pws = pwsRpcProxy + dwSize;
  778. memcpy(pwsRpcProxy,pws,sizeof(WCHAR)*(1+wcslen(pws)));
  779. hr = SetMetaBaseString( pIMeta,
  780. hMetaBase,
  781. MD_KEY_FILTERS,
  782. MD_FILTER_LOAD_ORDER,
  783. pwsBuffer,
  784. 0,
  785. IIS_MD_UT_SERVER );
  786. }
  787. }
  788. //
  789. // Delete: /W3Svc/Filters/RpcProxy
  790. //
  791. hr = pIMeta->DeleteKey( hMetaBase,
  792. MD_KEY_FILTERS_RPCPROXY );
  793. //
  794. // Delete: /W3Svc/1/ROOT/Rpc
  795. //
  796. hr = pIMeta->DeleteKey( hMetaBase,
  797. MD_KEY_FILTERS_RPCPROXY );
  798. //
  799. // Release the handle and buffer:
  800. //
  801. MemFree(pwsBuffer);
  802. pIMeta->CloseKey(hMetaBase);
  803. pIMeta->Release();
  804. return S_OK;
  805. }
  806. //---------------------------------------------------------------------
  807. // DllRegisterServer()
  808. //
  809. // Setup the Registry and MetaBase for the RPC proxy.
  810. //---------------------------------------------------------------------
  811. HRESULT DllRegisterServer()
  812. {
  813. HRESULT hr;
  814. WORD wVersion = MAKEWORD(1,1);
  815. WSADATA wsaData;
  816. #ifdef DBG_REG
  817. DbgPrint("RpcProxy: DllRegisterServer(): Start\n");
  818. #endif
  819. if (WSAStartup(wVersion,&wsaData))
  820. {
  821. return SELFREG_E_CLASS;
  822. }
  823. hr = CoInitializeEx(0,COINIT_MULTITHREADED);
  824. if (FAILED(hr))
  825. {
  826. hr = CoInitializeEx(0,COINIT_APARTMENTTHREADED);
  827. if (FAILED(hr))
  828. {
  829. #ifdef DBG_REG
  830. DbgPrint("RpcProxy: CoInitialize(): Failed: 0x%x\n", hr );
  831. #endif
  832. return hr;
  833. }
  834. }
  835. hr = SetupRegistry();
  836. if (FAILED(hr))
  837. {
  838. #ifdef DBG_REG
  839. DbgPrint("RpcProxy: SetupRegistry(): Failed: 0x%x (%d)\n",
  840. hr, hr );
  841. #endif
  842. return hr;
  843. }
  844. hr = SetupMetaBase();
  845. #ifdef DBG_REG
  846. if (FAILED(hr))
  847. {
  848. DbgPrint("RpcProxy: SetupRegistry(): Failed: 0x%x (%d)\n",
  849. hr, hr );
  850. }
  851. #endif
  852. CoUninitialize();
  853. #ifdef DBG_REG
  854. DbgPrint("RpcProxy: DllRegisterServer(): End: hr: 0x%x\n",hr);
  855. #endif
  856. return hr;
  857. }
  858. //---------------------------------------------------------------------
  859. // DllUnregisterServer()
  860. //
  861. // Uninstall Registry and MetaBase values used by the RPC proxy.
  862. //
  863. // Modified to mostly return S_Ok, even if a problem occurs. This is
  864. // done so that the uninstall will complete even if there is a problem
  865. // in the un-register.
  866. //---------------------------------------------------------------------
  867. HRESULT DllUnregisterServer()
  868. {
  869. HRESULT hr;
  870. WORD wVersion = MAKEWORD(1,1);
  871. WSADATA wsaData;
  872. #ifdef DBG_REG
  873. DbgPrint("RpcProxy: DllUnregisterServer(): Start\n");
  874. #endif
  875. if (WSAStartup(wVersion,&wsaData))
  876. {
  877. return SELFREG_E_CLASS;
  878. }
  879. hr = CoInitializeEx(0,COINIT_MULTITHREADED);
  880. if (FAILED(hr))
  881. {
  882. hr = CoInitializeEx(0,COINIT_APARTMENTTHREADED);
  883. if (FAILED(hr))
  884. {
  885. #ifdef DBG_REG
  886. DbgPrint("RpcProxy: CoInitializeEx() Failed: 0x%x\n",hr);
  887. #endif
  888. return S_OK;
  889. }
  890. }
  891. hr = CleanupRegistry();
  892. if (FAILED(hr))
  893. {
  894. #ifdef DBG_REG
  895. DbgPrint("RpcProxy: CleanupRegistry() Failed: 0x%x (%d)\n",hr,hr);
  896. #endif
  897. return S_OK;
  898. }
  899. hr = CleanupMetaBase();
  900. #ifdef DBG_REG
  901. if (FAILED(hr))
  902. {
  903. DbgPrint("RpcProxy: CleanupRegistry() Failed: 0x%x (%d)\n",hr,hr);
  904. }
  905. #endif
  906. CoUninitialize();
  907. #ifdef DBG_REG
  908. DbgPrint("RpcProxy: DllUnregisterServer(): Start\n");
  909. #endif
  910. return S_OK;
  911. }
  912. #if FALSE
  913. //--------------------------------------------------------------------
  914. // DllMain()
  915. //
  916. //--------------------------------------------------------------------
  917. BOOL WINAPI DllMain( HINSTANCE hInst,
  918. ULONG ulReason,
  919. LPVOID pvReserved )
  920. {
  921. BOOL fInitialized = TRUE;
  922. switch (ulReason)
  923. {
  924. case DLL_PROCESS_ATTACH:
  925. if (!DisableThreadLibraryCalls(hInst))
  926. {
  927. fInitialized = FALSE;
  928. }
  929. else
  930. {
  931. g_hInst = hInst;
  932. }
  933. break;
  934. case DLL_PROCESS_DETACH:
  935. break;
  936. case DLL_THREAD_ATTACH:
  937. // Not used. Disabled.
  938. break;
  939. case DLL_THREAD_DETACH:
  940. // Not used. Disabled.
  941. break;
  942. }
  943. return fInitialized;
  944. }
  945. #endif