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.

241 lines
8.8 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. //+============================================================================
  3. //
  4. // rpcsvr.cxx
  5. //
  6. // Implementation of CRpcServer, with the common code to support
  7. // trkwks & trksvr RPC servers.
  8. //
  9. //+============================================================================
  10. #include <pch.cxx>
  11. #pragma hdrstop
  12. #include "trklib.hxx"
  13. #define THIS_FILE_NUMBER RPCSVR_CXX_FILE_NO
  14. //+----------------------------------------------------------------------------
  15. //
  16. // CRpcServer::Initialize
  17. //
  18. // Initialize the CRpcServer base class. Before calling this
  19. // method, a derivation should perform all of its necessary
  20. // RpcUseProtseq calls.
  21. //
  22. // If a ptszProtSeqForEpRegistration is specified, find the
  23. // binding handle for that protocol and register this interface
  24. // just with that binding.
  25. //
  26. //+----------------------------------------------------------------------------
  27. void
  28. CRpcServer::Initialize(RPC_IF_HANDLE ifspec,
  29. ULONG grfRpcServerRegisterInterfaceEx,
  30. UINT cMaxCalls,
  31. BOOL fSetAuthInfo,
  32. const TCHAR *ptszProtSeqForEpRegistration )
  33. {
  34. RPC_STATUS rpcstatus;
  35. RPC_BINDING_VECTOR *pBindingVector = NULL;
  36. TCHAR *ptszStringBinding = NULL;
  37. TCHAR *ptszProtSeq = NULL;
  38. _ifspec = ifspec;
  39. _fEpRegister = NULL != ptszProtSeqForEpRegistration;
  40. __try
  41. {
  42. // If required, set authentication information
  43. if( RpcSecurityEnabled() && fSetAuthInfo )
  44. {
  45. RPC_TCHAR tszAuthName[MAX_COMPUTERNAME_LENGTH * 2 + 2 + 1]; // slash and $ and NUL
  46. CMachineId mcid(MCID_LOCAL);
  47. // Get the authentiation name, e.g. domain\machine$
  48. mcid.GetLocalAuthName(tszAuthName, sizeof(tszAuthName)/sizeof(tszAuthName[0]));
  49. // Set the auth info. We set it to negotiate, but we'll always get Kerberos.
  50. rpcstatus = RpcServerRegisterAuthInfo(
  51. tszAuthName,
  52. RPC_C_AUTHN_GSS_NEGOTIATE,
  53. NULL, // RPC_AUTH_KEY_RETRIEVAL_FN,
  54. NULL ); // Arg );
  55. if (rpcstatus)
  56. {
  57. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
  58. HRESULT_FROM_WIN32(rpcstatus), tszAuthName );
  59. TrkRaiseWin32Error(rpcstatus);
  60. }
  61. }
  62. // If using dynamic enpoints, register in the endpoint mapper
  63. // for the first binding handle for the specified protocol sequence.
  64. if( _fEpRegister )
  65. {
  66. // Query for the currently active binding handles
  67. rpcstatus = RpcServerInqBindings(&pBindingVector);
  68. if (rpcstatus)
  69. {
  70. TrkLog((TRKDBG_ERROR, TEXT("RpcServerInqBindings %08x"), rpcstatus));
  71. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
  72. HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
  73. TrkRaiseWin32Error(rpcstatus);
  74. }
  75. // Loop through the binding handles, looking for the first one with
  76. // the required protocol sequence.
  77. for( ULONG i = 0; i < pBindingVector->Count; i++ )
  78. {
  79. // Stringize the binding handle.
  80. rpcstatus = RpcBindingToStringBinding( pBindingVector->BindingH[i],
  81. &ptszStringBinding );
  82. if( RPC_S_OK != rpcstatus )
  83. {
  84. TrkLog(( TRKDBG_ERROR, TEXT("RpcBindingToStringBinding %08x"), rpcstatus ));
  85. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
  86. TrkRaiseWin32Error(rpcstatus);
  87. }
  88. // Parse the binding string for the protseq
  89. rpcstatus = RpcStringBindingParse( ptszStringBinding, NULL,
  90. &ptszProtSeq,
  91. NULL, NULL, NULL );
  92. if( RPC_S_OK != rpcstatus )
  93. {
  94. TrkLog(( TRKDBG_ERROR, TEXT("RpcStringBindingParse %08x"), rpcstatus ));
  95. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
  96. TrkRaiseWin32Error(rpcstatus);
  97. }
  98. // See if this protseq is that which we seek
  99. if( 0 == _tcscmp( ptszProtSeq, ptszProtSeqForEpRegistration ))
  100. {
  101. // We have a match. Register against this binding handle.
  102. RPC_BINDING_VECTOR PartialBindingVector;
  103. PartialBindingVector.Count = 1;
  104. PartialBindingVector.BindingH[0] = pBindingVector->BindingH[i];
  105. rpcstatus = RpcEpRegister(ifspec, &PartialBindingVector, NULL, NULL);
  106. if( RPC_S_OK != rpcstatus )
  107. {
  108. TrkLog((TRKDBG_ERROR, TEXT("RpcEpRegister %08x"), rpcstatus));
  109. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
  110. TrkRaiseWin32Error(rpcstatus);
  111. }
  112. else
  113. TrkLog(( TRKDBG_MISC, TEXT("RpcEpRegister on %s"), ptszStringBinding ));
  114. break;
  115. }
  116. RpcStringFree( &ptszStringBinding );
  117. ptszStringBinding = NULL;
  118. RpcStringFree( &ptszProtSeq );
  119. ptszProtSeq = NULL;
  120. }
  121. if( i == pBindingVector->Count )
  122. {
  123. TrkLog((TRKDBG_ERROR, TEXT("Couldn't find protseq %s in binding vector"),
  124. ptszProtSeqForEpRegistration ));
  125. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__, HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
  126. TrkRaiseWin32Error( HRESULT_FROM_WIN32(RPC_S_NO_PROTSEQS_REGISTERED) );
  127. }
  128. } // if( _fEpRegister )
  129. // Finally, register the server interface
  130. rpcstatus = RpcServerRegisterIfEx(ifspec, NULL, NULL,
  131. grfRpcServerRegisterInterfaceEx,
  132. cMaxCalls, NULL );
  133. if (rpcstatus != RPC_S_OK && rpcstatus != RPC_S_TYPE_ALREADY_REGISTERED)
  134. {
  135. TrkLog((TRKDBG_ERROR, TEXT("RpcServerRegisterIf %08x"), rpcstatus));
  136. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
  137. HRESULT_FROM_WIN32(rpcstatus), TRKREPORT_LAST_PARAM );
  138. TrkRaiseWin32Error(rpcstatus);
  139. }
  140. }
  141. __finally
  142. {
  143. if( NULL != pBindingVector )
  144. RpcBindingVectorFree( &pBindingVector );
  145. if( NULL != ptszStringBinding )
  146. RpcStringFree( &ptszStringBinding );
  147. if( NULL != ptszProtSeq )
  148. RpcStringFree( &ptszProtSeq );
  149. }
  150. }
  151. //+----------------------------------------------------------------------------
  152. //
  153. // CRpcServer::UnInitialize
  154. //
  155. // Unregister the interface, and if necessary unregister the endpoints.
  156. //
  157. //+----------------------------------------------------------------------------
  158. void
  159. CRpcServer::UnInitialize()
  160. {
  161. RPC_STATUS rpcstatus;
  162. RPC_BINDING_VECTOR *pBindingVector = NULL;
  163. if (_ifspec == NULL)
  164. return;
  165. // If we registered with the endpoint mapper, unreg now.
  166. if( _fEpRegister )
  167. {
  168. // Ignore any errors; we should still unregister the interface
  169. // no matter what.
  170. rpcstatus = RpcServerInqBindings(&pBindingVector);
  171. if (rpcstatus)
  172. {
  173. TrkLog((TRKDBG_ERROR, TEXT("RpcServerInqBindings %08x"), rpcstatus));
  174. }
  175. else
  176. {
  177. rpcstatus = RpcEpUnregister(_ifspec, pBindingVector, NULL);
  178. RpcBindingVectorFree( &pBindingVector );
  179. if( RPC_S_OK != rpcstatus && EPT_S_NOT_REGISTERED != rpcstatus )
  180. {
  181. TrkLog((TRKDBG_ERROR, TEXT("RpcEpUnregister %08x"), rpcstatus));
  182. }
  183. }
  184. }
  185. // Unregister the interface
  186. rpcstatus = RpcServerUnregisterIf(_ifspec, NULL, 1 /* wait for calls */);
  187. if (rpcstatus != RPC_S_OK)
  188. {
  189. TrkLog((TRKDBG_ERROR, TEXT("RpcServerUnregisterIf %08x"), rpcstatus));
  190. //TrkRaiseWin32Error(rpcstatus);
  191. }
  192. CTrkRpcConfig::UnInitialize();
  193. _ifspec = NULL;
  194. _fEpRegister = FALSE;
  195. }