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.

1231 lines
34 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1994-2000 Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. registry.cxx
  5. Abstract:
  6. Registers the interfaces contained in the proxy DLL.
  7. Public Functions:
  8. DllRegisterServer
  9. NdrDllRegisterProxy
  10. NdrDllUnregisterProxy
  11. Private Functions:
  12. NdrpGetClassID
  13. NdrpRegisterClass
  14. NdrpRegisterInterface
  15. NdrpUnregisterClass
  16. NdrpUnregisterInterface
  17. Author:
  18. ShannonC 12-Oct-1994
  19. Environment:
  20. Windows NT and Windows 95.
  21. Revision History:
  22. RyszardK Nov 1997 Changes for async registration.
  23. --------------------------------------------------------------------*/
  24. #define USE_STUBLESS_PROXY
  25. #define CINTERFACE
  26. #include <ndrp.h>
  27. #include <ndrole.h>
  28. #include <rpcproxy.h>
  29. #include <stdlib.h>
  30. EXTERN_C HINSTANCE g_hRpcrt4 = 0;
  31. HRESULT NdrpGetClassID(
  32. OUT LPSTR pszClassID,
  33. IN const CLSID * pclsid,
  34. IN const ProxyFileInfo ** pProxyFileList);
  35. HRESULT NdrpRegisterClass(
  36. IN LPCSTR pszClassID,
  37. IN LPCTSTR pszClassName,
  38. IN LPCTSTR pszDllFileName,
  39. IN LPCTSTR pszThreadingModel);
  40. HRESULT NdrpRegisterInterface(
  41. IN HKEY hKeyInterface,
  42. IN REFIID riid,
  43. IN LPCSTR pszInterfaceName,
  44. IN LPCSTR pszClassID,
  45. IN long NumMethods,
  46. IN const IID * riidAsync
  47. );
  48. HRESULT NdrpRegisterAsyncInterface(
  49. IN HKEY hKeyInterface,
  50. IN REFIID riid,
  51. IN LPCSTR pszSyncInterfaceName,
  52. IN long SyncNumMethods,
  53. IN REFIID riidAsync
  54. );
  55. HRESULT NdrpUnregisterClass(
  56. IN LPCSTR pszClassID,
  57. IN LPCTSTR pszDllFileName);
  58. HRESULT NdrpUnregisterInterface(
  59. IN HKEY hKeyInterface,
  60. IN REFIID riid,
  61. IN LPCSTR pszClassID,
  62. IN const IID * riidAsync );
  63. HRESULT RPC_ENTRY NdrDllRegisterProxy (
  64. IN HMODULE hDll,
  65. IN const ProxyFileInfo ** pProxyFileList,
  66. IN const CLSID * pclsid OPTIONAL)
  67. /*++
  68. Routine Description:
  69. Creates registry entries for the interfaces contained in the proxy DLL.
  70. Arguments:
  71. hDll - Supplies a handle to the proxy DLL.
  72. pProxyFileList - Supplies a list of proxy files to be registered.
  73. pclsid - Supplies the classid for the proxy DLL. May be zero.
  74. Return Value:
  75. S_OK
  76. See Also:
  77. DllRegisterServer
  78. NdrDllUnregisterProxy
  79. --*/
  80. {
  81. HRESULT hr;
  82. long i, j;
  83. HKEY hKeyInterface;
  84. DWORD dwDisposition;
  85. TCHAR szDllFileName[MAX_PATH];
  86. long error;
  87. ULONG length;
  88. char szClassID[39];
  89. if(hDll != 0)
  90. {
  91. //Get the proxy dll name.
  92. length = GetModuleFileName(hDll,
  93. szDllFileName,
  94. sizeof(szDllFileName));
  95. if(length > 0)
  96. {
  97. hr = S_OK;
  98. }
  99. else
  100. {
  101. hr = HRESULT_FROM_WIN32(GetLastError());
  102. }
  103. }
  104. else
  105. {
  106. //The proxy DLL's DLL_PROCESS_ATTACH did not initialize hProxyDll.
  107. hr = E_HANDLE;
  108. }
  109. if(SUCCEEDED(hr))
  110. {
  111. //Convert the class ID to to a registry key name.
  112. hr = NdrpGetClassID(szClassID, pclsid, pProxyFileList);
  113. }
  114. if(SUCCEEDED(hr))
  115. {
  116. //Register the class
  117. hr = NdrpRegisterClass(szClassID,
  118. TEXT("PSFactoryBuffer"),
  119. szDllFileName,
  120. TEXT("Both"));
  121. }
  122. if(SUCCEEDED(hr))
  123. {
  124. //Create the Interface key.
  125. error = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  126. TEXT("Interface"),
  127. 0,
  128. TEXT("REG_SZ"),
  129. REG_OPTION_NON_VOLATILE,
  130. KEY_WRITE,
  131. 0,
  132. &hKeyInterface,
  133. &dwDisposition);
  134. if(!error)
  135. {
  136. HRESULT hr2;
  137. //iterate over the list of proxy files in the proxy DLL.
  138. for(i = 0;
  139. pProxyFileList[i] != 0;
  140. i++)
  141. {
  142. if ( pProxyFileList[i]->TableVersion & NDR_PROXY_FILE_ASYNC_UUID)
  143. {
  144. // Iterate through sync and async interfaces.
  145. for(j = 0;
  146. pProxyFileList[i]->pProxyVtblList[j] != 0;
  147. j++)
  148. {
  149. if ( pProxyFileList[i]->pAsyncIIDLookup[j] == 0)
  150. {
  151. // just a sync interface, no async counterpart.
  152. hr2 = NdrpRegisterInterface(hKeyInterface,
  153. *pProxyFileList[i]->pStubVtblList[j]->header.piid,
  154. pProxyFileList[i]->pNamesArray[j],
  155. szClassID,
  156. pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
  157. 0 /* no async */);
  158. if(FAILED(hr2) && SUCCEEDED(hr))
  159. hr = hr2;
  160. }
  161. else if ( (ULONG_PTR) pProxyFileList[i]->pAsyncIIDLookup[j] != -1 )
  162. {
  163. // Register an sync-async pair of interfaces.
  164. hr2 = NdrpRegisterInterface(hKeyInterface,
  165. *pProxyFileList[i]->pStubVtblList[j]->header.piid,
  166. pProxyFileList[i]->pNamesArray[j],
  167. szClassID,
  168. pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
  169. pProxyFileList[i]->pAsyncIIDLookup[j]);
  170. if(FAILED(hr2) && SUCCEEDED(hr))
  171. hr = hr2;
  172. hr2 = NdrpRegisterAsyncInterface(hKeyInterface,
  173. *pProxyFileList[i]->pStubVtblList[j]->header.piid,
  174. pProxyFileList[i]->pNamesArray[j],
  175. pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
  176. *pProxyFileList[i]->pAsyncIIDLookup[j] );
  177. if(FAILED(hr2) && SUCCEEDED(hr))
  178. hr = hr2;
  179. }
  180. }
  181. }
  182. else
  183. {
  184. // Plain old style sync interfaces only.
  185. // iterate over the list of interfaces in the proxy file.
  186. for(j = 0;
  187. pProxyFileList[i]->pProxyVtblList[j] != 0;
  188. j++)
  189. {
  190. hr2 = NdrpRegisterInterface(hKeyInterface,
  191. *pProxyFileList[i]->pStubVtblList[j]->header.piid,
  192. pProxyFileList[i]->pNamesArray[j],
  193. szClassID,
  194. pProxyFileList[i]->pStubVtblList[j]->header.DispatchTableCount,
  195. 0 /* no async */);
  196. if(FAILED(hr2) && SUCCEEDED(hr))
  197. hr = hr2;
  198. }
  199. }
  200. }
  201. RegCloseKey(hKeyInterface);
  202. }
  203. else
  204. {
  205. hr = HRESULT_FROM_WIN32(error);
  206. }
  207. }
  208. return hr;
  209. }
  210. HRESULT CheckInprocServer32(
  211. IN HKEY hKeyIID,
  212. IN LPCTSTR pszDllFileName)
  213. {
  214. HRESULT hr;
  215. HKEY hKey;
  216. TCHAR szDll[MAX_PATH];
  217. long cbData = sizeof(szDll);
  218. long error;
  219. DWORD dwType;
  220. //Open the InprocServer32 key.
  221. error = RegOpenKeyEx(hKeyIID,
  222. TEXT("InprocServer32"),
  223. 0,
  224. KEY_READ,
  225. &hKey);
  226. if(!error)
  227. {
  228. error = RegQueryValueEx(hKey,
  229. TEXT(""),
  230. 0,
  231. &dwType,
  232. (BYTE*)szDll,
  233. (ulong*)&cbData);
  234. if(!error)
  235. {
  236. if(0 == lstrcmpi(pszDllFileName,
  237. szDll))
  238. hr = S_OK;
  239. else
  240. hr = REGDB_E_INVALIDVALUE;
  241. }
  242. else
  243. {
  244. hr = HRESULT_FROM_WIN32(error);
  245. }
  246. RegCloseKey(hKey);
  247. }
  248. else
  249. {
  250. hr = HRESULT_FROM_WIN32(error);
  251. }
  252. return hr;
  253. }
  254. HRESULT NdrpCheckClass(
  255. IN LPCSTR pszClassID,
  256. IN LPCTSTR pszDllFileName)
  257. {
  258. HRESULT hr;
  259. long error;
  260. HKEY hKeyCLSID;
  261. //open the CLSID key
  262. error = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  263. TEXT("CLSID"),
  264. 0,
  265. KEY_WRITE,
  266. &hKeyCLSID);
  267. if(!error)
  268. {
  269. HKEY hKeyClassID;
  270. //open registry key for class ID string
  271. error = RegOpenKeyExA(hKeyCLSID,
  272. pszClassID,
  273. 0,
  274. KEY_WRITE,
  275. &hKeyClassID);
  276. if(!error)
  277. {
  278. hr = CheckInprocServer32(hKeyClassID,
  279. pszDllFileName);
  280. RegCloseKey(hKeyClassID);
  281. }
  282. else
  283. {
  284. hr = HRESULT_FROM_WIN32(error);
  285. }
  286. RegCloseKey(hKeyCLSID);
  287. }
  288. else
  289. {
  290. hr = HRESULT_FROM_WIN32(error);
  291. }
  292. return hr;
  293. }
  294. HRESULT RPC_ENTRY NdrDllUnregisterProxy (
  295. IN HMODULE hDll,
  296. IN const ProxyFileInfo ** pProxyFileList,
  297. IN const CLSID * pclsid OPTIONAL)
  298. /*++
  299. Routine Description:
  300. Removes registry entries for the interfaces contained in the proxy DLL.
  301. Arguments:
  302. hDll - Supplies a handle to the proxy DLL.
  303. pProxyFileList - Supplies a list of proxy files to be unregistered.
  304. pclsid - Supplies the classid for the proxy DLL. May be zero.
  305. Return Value:
  306. S_OK
  307. See Also:
  308. DllUnregisterServer
  309. NdrDllRegisterProxy
  310. --*/
  311. {
  312. HRESULT hr;
  313. HKEY hKeyInterface;
  314. long i, j;
  315. long error;
  316. TCHAR szDllFileName[MAX_PATH];
  317. ULONG length;
  318. char szClassID[39];
  319. if(hDll != 0)
  320. {
  321. //Get the proxy dll name.
  322. length = GetModuleFileName(hDll, szDllFileName, sizeof(szDllFileName));
  323. if(length > 0)
  324. {
  325. hr = S_OK;
  326. }
  327. else
  328. {
  329. hr = HRESULT_FROM_WIN32(GetLastError());
  330. }
  331. }
  332. else
  333. {
  334. //The DLL_PROCESS_ATTACH in the proxy DLL failed to initialize hProxyDll.
  335. hr = E_HANDLE;
  336. }
  337. if(SUCCEEDED(hr))
  338. {
  339. //Convert the class ID to a registry key name.
  340. hr = NdrpGetClassID(szClassID, pclsid, pProxyFileList);
  341. }
  342. if(SUCCEEDED(hr))
  343. {
  344. //Check the class
  345. hr = NdrpCheckClass(szClassID, szDllFileName);
  346. }
  347. if(SUCCEEDED(hr))
  348. {
  349. HRESULT hr2;
  350. //Open the Interface key.
  351. error = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  352. TEXT("Interface"),
  353. 0,
  354. KEY_WRITE,
  355. &hKeyInterface);
  356. if (!error)
  357. {
  358. //iterate over the list of proxy files in the proxy DLL.
  359. for(i = 0;
  360. pProxyFileList[i] != 0;
  361. i++)
  362. {
  363. if ( pProxyFileList[i]->TableVersion & NDR_PROXY_FILE_ASYNC_UUID)
  364. {
  365. // Iterate through sync and async interfaces.
  366. for(j = 0;
  367. pProxyFileList[i]->pProxyVtblList[j] != 0;
  368. j++)
  369. {
  370. if ( (ULONG_PTR) pProxyFileList[i]->pAsyncIIDLookup[j] != -1 )
  371. {
  372. // Unegister a single sync only interface or an sync-async
  373. // pair of interfaces. Skip async interfaces.
  374. NdrpUnregisterInterface( hKeyInterface,
  375. *pProxyFileList[i]->pStubVtblList[j]->header.piid,
  376. szClassID,
  377. pProxyFileList[i]->pAsyncIIDLookup[j]);
  378. }
  379. }
  380. }
  381. else
  382. {
  383. //iterate over the list of interfaces in the proxy file.
  384. for(j = 0;
  385. pProxyFileList[i]->pProxyVtblList[j] != 0;
  386. j++)
  387. {
  388. NdrpUnregisterInterface(hKeyInterface,
  389. *pProxyFileList[i]->pStubVtblList[j]->header.piid,
  390. szClassID,
  391. 0 /* no async */);
  392. }
  393. }
  394. }
  395. RegCloseKey(hKeyInterface);
  396. }
  397. else
  398. {
  399. hr = HRESULT_FROM_WIN32(error);
  400. }
  401. //Unregister the class
  402. hr2 = NdrpUnregisterClass(szClassID, szDllFileName);
  403. if(FAILED(hr2) && SUCCEEDED(hr))
  404. hr = hr2;
  405. }
  406. return hr;
  407. }
  408. HRESULT NdrpGetClassID(
  409. OUT LPSTR pszClassID,
  410. IN const CLSID * pclsid,
  411. IN const ProxyFileInfo ** pProxyFileList)
  412. /*++
  413. Routine Description:
  414. Gets a string specifying the Class ID for the PSFactoryBuffer.
  415. If pclsid is NULL, then this function will use the IID of the
  416. first interface as the class ID.
  417. Arguments:
  418. pszClassID - The Class ID string is returned in this buffer.
  419. pclsid - Specifies the class ID. May be zero.
  420. pProxyFileList - Points to a list of ProxyFiles.
  421. Return Value:
  422. S_OK
  423. E_NOINTERFACE
  424. --*/
  425. {
  426. HRESULT hr;
  427. long i, j;
  428. //If necessary, use the IID of the first interface as the CLSID.
  429. for(i = 0;
  430. (pProxyFileList[i] != 0) && (!pclsid);
  431. i++)
  432. {
  433. for(j = 0;
  434. (pProxyFileList[i]->pProxyVtblList[j] != 0) && (!pclsid);
  435. j++)
  436. {
  437. pclsid = pProxyFileList[i]->pStubVtblList[j]->header.piid;
  438. }
  439. }
  440. if(pclsid != 0)
  441. {
  442. hr = NdrStringFromIID( *pclsid, pszClassID );
  443. }
  444. else
  445. {
  446. hr = E_NOINTERFACE;
  447. }
  448. return hr;
  449. }
  450. HRESULT NdrpRegisterClass(
  451. IN LPCSTR pszClassID,
  452. IN LPCTSTR pszClassName OPTIONAL,
  453. IN LPCTSTR pszDllFileName,
  454. IN LPCTSTR pszThreadingModel OPTIONAL)
  455. /*++
  456. Routine Description:
  457. Creates a registry entry for an in-process server class.
  458. Arguments:
  459. pszClassID - Supplies the class ID.
  460. pszClassName - Supplies the class name. May be NULL.
  461. pszDllFileName - Supplies the DLL file name.
  462. pszThreadingModel - Supplies the threading model. May be NULL.
  463. The threading model should be one of the following:
  464. "Apartment", "Both", "Free".
  465. Return Value:
  466. S_OK
  467. See Also:
  468. NdrDllRegisterProxy
  469. NdrpUnregisterClass
  470. --*/
  471. {
  472. HRESULT hr;
  473. long error;
  474. HKEY hKeyCLSID;
  475. HKEY hKeyClassID;
  476. HKEY hKey;
  477. DWORD dwDisposition;
  478. //create the CLSID key
  479. error = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  480. TEXT("CLSID"),
  481. 0,
  482. TEXT("REG_SZ"),
  483. REG_OPTION_NON_VOLATILE,
  484. KEY_WRITE,
  485. 0,
  486. &hKeyCLSID,
  487. &dwDisposition);
  488. if(!error)
  489. {
  490. //Create registry key for class ID
  491. error = RegCreateKeyExA(hKeyCLSID,
  492. pszClassID,
  493. 0,
  494. "REG_SZ",
  495. REG_OPTION_NON_VOLATILE,
  496. KEY_WRITE,
  497. 0,
  498. &hKeyClassID,
  499. &dwDisposition);
  500. if(!error)
  501. {
  502. //Create InProcServer32 key for the proxy dll
  503. error = RegCreateKeyEx(hKeyClassID,
  504. TEXT("InProcServer32"),
  505. 0,
  506. TEXT("REG_SZ"),
  507. REG_OPTION_NON_VOLATILE,
  508. KEY_WRITE,
  509. 0,
  510. &hKey,
  511. &dwDisposition);
  512. if(!error)
  513. {
  514. //register the proxy DLL filename
  515. error = RegSetValueEx(hKey,
  516. TEXT(""),
  517. 0,
  518. REG_SZ,
  519. (BYTE*)pszDllFileName,
  520. strlen(pszDllFileName) + 1);
  521. if((!error) && (pszThreadingModel != 0))
  522. {
  523. //register the threading model for the proxy DLL.
  524. error = RegSetValueEx(hKey,
  525. TEXT("ThreadingModel"),
  526. 0,
  527. REG_SZ,
  528. (BYTE*)pszThreadingModel,
  529. strlen(pszThreadingModel) + 1);
  530. }
  531. RegCloseKey(hKey);
  532. }
  533. if((!error) && (pszClassName != 0))
  534. {
  535. // put the class name in an unnamed value
  536. error = RegSetValueEx(hKeyClassID,
  537. TEXT(""),
  538. 0,
  539. REG_SZ,
  540. (BYTE*)pszClassName,
  541. strlen(pszClassName) + 1);
  542. }
  543. RegCloseKey(hKeyClassID);
  544. }
  545. RegCloseKey(hKeyCLSID);
  546. }
  547. if(!error)
  548. hr = S_OK;
  549. else
  550. hr = HRESULT_FROM_WIN32(error);
  551. return hr;
  552. }
  553. HRESULT NdrpRegisterInterface(
  554. IN HKEY hKeyInterface,
  555. IN REFIID riid,
  556. IN LPCSTR pszInterfaceName,
  557. IN LPCSTR pszClassID,
  558. IN long NumMethods,
  559. IN const IID * riidAsync )
  560. /*++
  561. Routine Description:
  562. Creates a registry entry for an interface proxy.
  563. Arguments:
  564. hKeyInterface
  565. riid
  566. pszInterfaceName
  567. pszClassID
  568. NumMethods
  569. riidAsync - async iid, may be null.
  570. Return Value:
  571. S_OK
  572. See Also:
  573. NdrDllRegisterProxy
  574. NdrpUnregisterInterface
  575. --*/
  576. {
  577. HRESULT hr;
  578. long error;
  579. char szIID[39];
  580. char szNumMethods[6];
  581. DWORD dwDisposition;
  582. HKEY hKey;
  583. HKEY hKeyIID;
  584. //convert the IID to a registry key name.
  585. NdrStringFromIID( riid, szIID );
  586. //create registry key for the interface
  587. error = RegCreateKeyExA(hKeyInterface,
  588. szIID,
  589. 0,
  590. "REG_SZ",
  591. REG_OPTION_NON_VOLATILE,
  592. KEY_WRITE,
  593. 0,
  594. &hKeyIID,
  595. &dwDisposition);
  596. if (!error)
  597. {
  598. //create ProxyStubClsid32 key.
  599. error = RegCreateKeyEx(hKeyIID,
  600. TEXT("ProxyStubClsid32"),
  601. 0,
  602. TEXT("REG_SZ"),
  603. REG_OPTION_NON_VOLATILE,
  604. KEY_WRITE,
  605. 0,
  606. &hKey,
  607. &dwDisposition);
  608. if (!error)
  609. {
  610. //Set the class id for the PSFactoryBuffer.
  611. error = RegSetValueExA(hKey,
  612. "",
  613. 0,
  614. REG_SZ,
  615. (BYTE*)pszClassID,
  616. strlen(pszClassID) + 1);
  617. RegCloseKey(hKey);
  618. }
  619. // put the interface name in the unnamed value
  620. if(!error)
  621. {
  622. error = RegSetValueExA(hKeyIID,
  623. "",
  624. 0,
  625. REG_SZ,
  626. (BYTE*)pszInterfaceName,
  627. strlen(pszInterfaceName) + 1);
  628. }
  629. //create NumMethods key.
  630. if(!error)
  631. {
  632. error = RegCreateKeyEx(hKeyIID,
  633. TEXT("NumMethods"),
  634. 0,
  635. TEXT("REG_SZ"),
  636. REG_OPTION_NON_VOLATILE,
  637. KEY_WRITE,
  638. 0,
  639. &hKey,
  640. &dwDisposition);
  641. if(!error)
  642. {
  643. //Set the number of methods
  644. RpcItoa( NumMethods, szNumMethods, 10 );
  645. error = RegSetValueExA(hKey,
  646. "",
  647. 0,
  648. REG_SZ,
  649. (UCHAR *) szNumMethods,
  650. strlen(szNumMethods) + 1);
  651. RegCloseKey(hKey);
  652. }
  653. }
  654. if ( riidAsync )
  655. {
  656. //create AsynchronousInterface key under the interface.
  657. if(!error)
  658. {
  659. error = RegCreateKeyEx( hKeyIID,
  660. TEXT("AsynchronousInterface"),
  661. 0,
  662. TEXT("REG_SZ"),
  663. REG_OPTION_NON_VOLATILE,
  664. KEY_WRITE,
  665. 0,
  666. &hKey,
  667. &dwDisposition);
  668. if(!error)
  669. {
  670. // Set the iid as value for the string.
  671. NdrStringFromIID( *riidAsync, szIID );
  672. error = RegSetValueExA( hKey,
  673. "",
  674. 0,
  675. REG_SZ,
  676. (UCHAR *) szIID,
  677. strlen(szIID) + 1);
  678. RegCloseKey(hKey);
  679. }
  680. }
  681. }
  682. RegCloseKey(hKeyIID);
  683. }
  684. if(!error)
  685. hr = S_OK;
  686. else
  687. hr = HRESULT_FROM_WIN32(error);
  688. return hr;
  689. }
  690. HRESULT NdrpRegisterAsyncInterface(
  691. IN HKEY hKeyInterface,
  692. IN REFIID riid,
  693. IN LPCSTR pszSyncInterfaceName,
  694. IN long SyncNumMethods,
  695. IN REFIID riidAsync )
  696. /*++
  697. Routine Description:
  698. Creates a registry entry for an async interface proxy.
  699. Arguments:
  700. hKeyInterface
  701. riid
  702. pszInterfaceName
  703. pszClassID
  704. NumMethods
  705. riidAsync
  706. Return Value:
  707. S_OK
  708. See Also:
  709. NdrDllRegisterProxy
  710. NdrpUnregisterInterface
  711. --*/
  712. {
  713. HRESULT hr;
  714. long error;
  715. char szIID[39];
  716. char szNumMethods[6];
  717. DWORD dwDisposition;
  718. HKEY hKey;
  719. HKEY hKeyIID;
  720. //convert the IID to a registry key name.
  721. NdrStringFromIID( riidAsync, szIID );
  722. //create registry key for the interface
  723. error = RegCreateKeyExA(hKeyInterface,
  724. szIID,
  725. 0,
  726. "REG_SZ",
  727. REG_OPTION_NON_VOLATILE,
  728. KEY_WRITE,
  729. 0,
  730. &hKeyIID,
  731. &dwDisposition);
  732. // By definition, for async interfaces do not create Clsid32 key.
  733. // put the interface name in the unnamed value
  734. if(!error)
  735. {
  736. char * pszAsyncInterfaceName;
  737. int len;
  738. len = 5 + strlen(pszSyncInterfaceName) + 1; /* 5 is strlen("Async") */
  739. pszAsyncInterfaceName = (char*)alloca(len);
  740. RpcpMemoryCopy( pszAsyncInterfaceName, "Async", 5 );
  741. RpcpMemoryCopy( pszAsyncInterfaceName + 5, pszSyncInterfaceName, len - 5 );
  742. error = RegSetValueExA(hKeyIID,
  743. "",
  744. 0,
  745. REG_SZ,
  746. (BYTE*)pszAsyncInterfaceName,
  747. len);
  748. //create NumMethods key.
  749. if(!error)
  750. {
  751. long AsyncNumMethods = 2 * SyncNumMethods - 3;
  752. error = RegCreateKeyEx(hKeyIID,
  753. TEXT("NumMethods"),
  754. 0,
  755. TEXT("REG_SZ"),
  756. REG_OPTION_NON_VOLATILE,
  757. KEY_WRITE,
  758. 0,
  759. &hKey,
  760. &dwDisposition);
  761. if(!error)
  762. {
  763. //Set the number of methods
  764. RpcItoa( AsyncNumMethods, szNumMethods, 10 );
  765. error = RegSetValueExA(hKey,
  766. "",
  767. 0,
  768. REG_SZ,
  769. (UCHAR *) szNumMethods,
  770. strlen(szNumMethods) + 1);
  771. RegCloseKey(hKey);
  772. }
  773. }
  774. //create SynchronousInterface key under the interface.
  775. if(!error)
  776. {
  777. error = RegCreateKeyEx( hKeyIID,
  778. TEXT("SynchronousInterface"),
  779. 0,
  780. TEXT("REG_SZ"),
  781. REG_OPTION_NON_VOLATILE,
  782. KEY_WRITE,
  783. 0,
  784. &hKey,
  785. &dwDisposition);
  786. if(!error)
  787. {
  788. // Set the iid as value for the string.
  789. NdrStringFromIID( riid, szIID );
  790. error = RegSetValueExA( hKey,
  791. "",
  792. 0,
  793. REG_SZ,
  794. (UCHAR *) szIID,
  795. strlen(szIID) + 1);
  796. RegCloseKey(hKey);
  797. }
  798. }
  799. RegCloseKey(hKeyIID);
  800. }
  801. if(!error)
  802. hr = S_OK;
  803. else
  804. hr = HRESULT_FROM_WIN32(error);
  805. return hr;
  806. }
  807. HRESULT NdrpUnregisterClass(
  808. IN LPCSTR pszClassID,
  809. IN LPCTSTR pszDllFileName)
  810. /*++
  811. Routine Description:
  812. Removes an in-process server class from the registry.
  813. Arguments:
  814. pszClassID - Supplies the class ID.
  815. Return Value:
  816. S_OK
  817. See Also:
  818. NdrDllUnregisterProxy
  819. NdrpRegisterClass
  820. --*/
  821. {
  822. HRESULT hr;
  823. HKEY hKeyCLSID;
  824. HKEY hKeyClassID;
  825. long error;
  826. //open the CLSID key
  827. error = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  828. TEXT("CLSID"),
  829. 0,
  830. KEY_WRITE,
  831. &hKeyCLSID);
  832. if(!error)
  833. {
  834. //open registry key for class ID string
  835. error = RegOpenKeyExA(hKeyCLSID,
  836. pszClassID,
  837. 0,
  838. KEY_WRITE,
  839. &hKeyClassID);
  840. if(!error)
  841. {
  842. hr = CheckInprocServer32(hKeyClassID,
  843. pszDllFileName);
  844. if(SUCCEEDED(hr))
  845. {
  846. //delete InProcServer32 key.
  847. error = RegDeleteKey(hKeyClassID,
  848. TEXT("InProcServer32"));
  849. if(error != 0)
  850. {
  851. hr = HRESULT_FROM_WIN32(error);
  852. }
  853. }
  854. RegCloseKey(hKeyClassID);
  855. }
  856. else
  857. {
  858. hr = HRESULT_FROM_WIN32(error);
  859. }
  860. if(SUCCEEDED(hr))
  861. {
  862. error = RegDeleteKeyA(hKeyCLSID, pszClassID);
  863. if(error != 0)
  864. {
  865. hr = HRESULT_FROM_WIN32(error);
  866. }
  867. }
  868. RegCloseKey(hKeyCLSID);
  869. }
  870. else
  871. {
  872. hr = HRESULT_FROM_WIN32(error);
  873. }
  874. return hr;
  875. }
  876. HRESULT CheckProxyStubClsid32(
  877. IN HKEY hKeyIID,
  878. IN LPCSTR pszClassID)
  879. {
  880. HRESULT hr;
  881. HKEY hKey;
  882. char szClassID[39];
  883. long cbData = sizeof(szClassID);
  884. long error;
  885. DWORD dwType;
  886. //Open the ProxyStubClsid32 key.
  887. error = RegOpenKeyEx(hKeyIID,
  888. TEXT("ProxyStubClsid32"),
  889. 0,
  890. KEY_READ,
  891. &hKey);
  892. if(!error)
  893. {
  894. error = RegQueryValueExA(hKey,
  895. "",
  896. 0,
  897. &dwType,
  898. (BYTE*)szClassID,
  899. (ulong*)&cbData);
  900. if(!error)
  901. {
  902. if(0 == memcmp(szClassID, pszClassID, cbData))
  903. hr = S_OK;
  904. else
  905. hr = REGDB_E_INVALIDVALUE;
  906. }
  907. else
  908. {
  909. hr = HRESULT_FROM_WIN32(error);
  910. }
  911. RegCloseKey(hKey);
  912. }
  913. else
  914. {
  915. hr = HRESULT_FROM_WIN32(error);
  916. }
  917. return hr;
  918. }
  919. HRESULT NdrpUnregisterInterface(
  920. IN HKEY hKeyInterface,
  921. IN REFIID riid,
  922. IN LPCSTR pszClassID,
  923. IN const IID * riidAsync )
  924. /*++
  925. Routine Description:
  926. Unregisters an interface proxy.
  927. Arguments:
  928. hKeyInterface
  929. riid
  930. Return Value:
  931. S_OK
  932. See Also:
  933. NdrDllUnregisterProxy
  934. NdrpRegisterInterface
  935. --*/
  936. {
  937. HRESULT hr = S_OK;
  938. long error;
  939. char szIID[39];
  940. HKEY hKeyIID;
  941. //convert the IID to a registry key name.
  942. NdrStringFromIID( riid, szIID );
  943. //Open the IID key.
  944. error = RegOpenKeyExA(hKeyInterface,
  945. szIID,
  946. 0,
  947. KEY_WRITE,
  948. &hKeyIID);
  949. if (!error)
  950. {
  951. // As we call for sync singles or sync pairs (sync-async),
  952. // we always have the class id.
  953. hr = CheckProxyStubClsid32(hKeyIID, pszClassID);
  954. if(SUCCEEDED(hr))
  955. {
  956. // Once the class id matches, just attempt to delete
  957. // every possible key that may happen under the sync entry.
  958. // Note that additional key may be present due to oleauto
  959. // registering a TLB.
  960. RegDeleteKey(hKeyIID, TEXT("NumMethods"));
  961. RegDeleteKey(hKeyIID, TEXT("ProxyStubClsid32"));
  962. RegDeleteKey(hKeyIID, TEXT("AsynchronousInterface"));
  963. // Now remove the matching async interface entry, if there is one.
  964. if ( riidAsync )
  965. {
  966. char szAsyncIID[39];
  967. HKEY hKeyAsyncIID;
  968. //convert the IID to a registry key name.
  969. NdrStringFromIID( *riidAsync, szAsyncIID );
  970. //Open the IID key.
  971. error = RegOpenKeyExA(hKeyInterface,
  972. szAsyncIID,
  973. 0,
  974. KEY_WRITE,
  975. &hKeyAsyncIID);
  976. if ( !error )
  977. {
  978. RegDeleteKey( hKeyAsyncIID, TEXT("NumMethods"));
  979. RegDeleteKey( hKeyAsyncIID, TEXT("SynchronousInterface"));
  980. RegCloseKey(hKeyAsyncIID);
  981. RegDeleteKeyA(hKeyInterface, szAsyncIID);
  982. }
  983. }
  984. }
  985. else
  986. hr = S_FALSE;
  987. //Close the IID key.
  988. RegCloseKey(hKeyIID);
  989. RegDeleteKeyA(hKeyInterface, szIID);
  990. }
  991. return hr;
  992. }
  993. STDAPI DllRegisterServer(void)
  994. /*++
  995. Routine Description:
  996. Creates registry entries for the classes contained in rpcrt4.dll.
  997. Return Value:
  998. S_OK
  999. --*/
  1000. {
  1001. HRESULT hr;
  1002. TCHAR szDllFileName[MAX_PATH];
  1003. ULONG length;
  1004. if(!g_hRpcrt4)
  1005. return E_HANDLE;
  1006. //Get the proxy dll name.
  1007. length = GetModuleFileName(g_hRpcrt4,
  1008. szDllFileName,
  1009. sizeof(szDllFileName));
  1010. if(length > 0)
  1011. {
  1012. //Register the class
  1013. hr = NdrpRegisterClass(TEXT("{b5866878-bd99-11d0-b04b-00c04fd91550}"),
  1014. TEXT("TypeFactory"),
  1015. szDllFileName,
  1016. TEXT("Both"));
  1017. }
  1018. else
  1019. {
  1020. hr = HRESULT_FROM_WIN32(GetLastError());
  1021. }
  1022. return hr;
  1023. }