Leaked source code of windows server 2003
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.

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