Sample Code
Windows Driver Samples/ Windows Filtering Platform Sample/ C++/ svc/ Framework_RPCServerInterface.cpp/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | //////////////////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2012 Microsoft Corporation. All Rights Reserved. // // Module Name: // Framework_RPCServerInterface.cpp // // Abstract: // This module contains functions which implement the RPC server interface. // // Author: // Dusty Harper (DHarper) // // Naming Convention: // // <Scope><Object><Action><Modifier> // // i.e. // // <Scope> // { // - Function is likely visible to other modules. // } // <Object> // { // RPCServerInterface - Function pertains to the RPC Server Interface. // } // <Action> // { // Initialize - Function prepares environment for use. // SecurityCallback - Function enforces RPC security measures. // Terminate - Function cleans up the environment. // } // <Modifier> // { // } // // Private Functions: // // Public Functions: // RPCClientInterfaceInitialize(), // RPCClientInterfaceSecurityCallback(), // RPCClientInterfaceTerminate(), // // Revision History: // // [ Month ][Day] [Year] - [Revision]-[ Comments ] // May 01, 2010 - 1.0 - Creation // //////////////////////////////////////////////////////////////////////////////////////////////////// #include "Framework_WFPSamplerService.h" /// . #include "WFPSamplerRPC_s.c" /// $(OBJ_PATH)\..\idl\$(O) /// Module's Local Structures typedef struct RPC_DATA_ { RPC_IF_HANDLE rpcInterfaceHandle; RPC_BINDING_VECTOR* pBindingVector; UINT32 protocolSequence; RPC_WSTR pProtocolSequence; PWSTR pEndpoint; UINT32 interfaceFlags; BOOLEAN isInterfaceRegistered; BOOLEAN isEndpointRegistered; }RPC_DATA, *PRPC_DATA; /// /// Module's Local Enumerations typedef enum RPC_INITIALIZATION_TASKS_ { RPC_SELECT_PROTOCOL_SEQUENCE = 0, RPC_REGISTER_INTERFACE = 1, RPC_CREATE_BINDING_INFORMATION = 2, RPC_REGISTER_ENDPOINT = 3, RPC_INITIALIZATION_TASKS_MAX }; typedef enum RPC_TERMINATION_TASKS_ { RPC_UNREGISTER_ENDPOINT = 0, RPC_FREE_BINDING_INFORMATION = 1, RPC_UNREGISTER_INTERFACE = 2, RPC_TERMINATION_TASKS_MAX }; /// /// Module's Local Variables RPC_DATA* pRPCData = 0; /// /// Functions implemented in Framework_WFPSamplerSvc.cpp _Success_( return == NO_ERROR) UINT32 ServiceStatusReportToSCM(_In_ UINT32 currentState, _In_ UINT32 exitCode, _In_ UINT32 waitHint); VOID ServiceEventLogError(_In_ PCWSTR pFunctionName, _In_ UINT32 status); /// extern "C" { /** @framework_function="MIDL_user_free" Purpose: RPC stub routine to allocate memory. <br> <br> Notes: <br> <br> */ _Must_inspect_result_ _Ret_maybenull_ _Post_writable_byte_size_(size) VOID * __RPC_USER MIDL_user_allocate( /* _In_ */ size_t size) { BYTE * pBuffer = 0; if (size) { HLPR_NEW_ARRAY(pBuffer, BYTE , size); } return pBuffer; } /** @framework_function="MIDL_user_free" Purpose: RPC stub routine to free allocated memory. <br> <br> Notes: <br> <br> */ VOID __RPC_USER MIDL_user_free( /* _Inout_ */ _Pre_maybenull_ _Post_invalid_ VOID * pBuffer) { HLPR_DELETE_ARRAY(pBuffer); return ; } } /** @framework_function="RPCInterfaceSecurityCallback" Purpose: Callback routine to enforce security measures. <br> <br> Notes: <br> <br> */ _Success_( return == RPC_S_OK) RPC_STATUS RPCServerInterfaceSecurityCallback(_In_ RPC_IF_HANDLE interfaceHandle, _In_ VOID * pContext) { UNREFERENCED_PARAMETER(interfaceHandle); ASSERT(interfaceHandle); ASSERT(pContext); RPC_STATUS status = RPC_S_OK; RPC_CALL_ATTRIBUTES_V2 callAttributes = {0}; callAttributes.Version = 2; callAttributes.Flags = RPC_QUERY_CLIENT_PID; status = RpcServerInqCallAttributes((RPC_BINDING_HANDLE)pContext, /// Binding handle used by the client when making the RPC call &callAttributes); /// Client's call attributes if (status != RPC_S_OK) { ServiceEventLogError(L "RPCServerInterfaceSecurityCallback : RpcServerinqCallAttributes()" , status); HLPR_BAIL; } if (callAttributes.IsClientLocal == rcclRemote || /// make sure this is a local client callAttributes.ProtocolSequence != pRPCData->protocolSequence || /// make sure this is the correct protocol sequence (in our case Local RPC) !HlprGUIDsAreEqual(&(callAttributes.InterfaceUuid), &WFPSAMPLER_INTERFACE) || /// make sure this is the correct interface callAttributes.AuthenticationLevel < RPC_C_AUTHN_LEVEL_PKT_PRIVACY) /// make sure this is highest security { status = RPC_S_ACCESS_DENIED; ServiceEventLogError(L "RPCServerInterfaceSecurityCallback()" , status); } HLPR_BAIL_LABEL: return status; } /** @framework_function="RPCServerInterfaceTerminate" Purpose: Remove the RPC server interface by unregistering the endpoint and interface and freeing the bindings. <br> <br> Notes: <br> <br> */ _Success_( return == RPC_S_OK) RPC_STATUS RPCServerInterfaceTerminate() { RPC_STATUS status = RPC_S_OK; const UINT32 ITERATIONS = RPC_TERMINATION_TASKS_MAX; for ( UINT32 index = 0; index < ITERATIONS; index++) { switch (index) { case RPC_UNREGISTER_ENDPOINT: { if (pRPCData->isEndpointRegistered) { status = RpcEpUnregister(pRPCData->rpcInterfaceHandle, /// Handle genereated by MIDL compiler for Interface pRPCData->pBindingVector, /// Vector of binding Handles 0); /// no object UUIDs if (status != RPC_S_OK) ServiceEventLogError(L "RPCServerInterfaceTerminate : RpcEpUnregister()" , status); } break ; } case RPC_FREE_BINDING_INFORMATION: { if (pRPCData->pBindingVector) { status = RpcBindingVectorFree(&(pRPCData->pBindingVector)); /// Vector of binding Handles to free. 0 on success if (status != RPC_S_OK) ServiceEventLogError(L "RPCServerInterfaceTerminate : RpcBindingVectorFree()" , status); } break ; } case RPC_UNREGISTER_INTERFACE: { if (pRPCData->isInterfaceRegistered) { status = RpcServerUnregisterIf(pRPCData->rpcInterfaceHandle, /// Handle genereated by MIDL compiler for Interface (UUID*)&WFPSAMPLER_INTERFACE, /// GUID for our Interface TRUE); /// Wait for any outstanding calls to finish if (status != RPC_S_OK) ServiceEventLogError(L "RPCServerInterfaceTerminate : RpcServerUnregisterIf()" , status); } break ; } default : { status = RPC_S_INVALID_ARG; break ; } } ServiceStatusReportToSCM(SERVICE_STOP_PENDING, status, 0); } HLPR_DELETE(pRPCData); return status; } /** @framework_function="RPCServerInterfaceInitialize" Purpose: Initialize the RPC server interface by creating the RPC bindings and registering the interface and endpoint. <br> <br> Notes: <br> <br> */ _Success_( return == RPC_S_OK) RPC_STATUS RPCServerInterfaceInitialize() { RPC_STATUS status = RPC_S_OK; const UINT32 ITERATIONS = RPC_INITIALIZATION_TASKS_MAX; HLPR_NEW(pRPCData, RPC_DATA); HLPR_BAIL_ON_ALLOC_FAILURE(pRPCData, status); pRPCData->rpcInterfaceHandle = IWFPSampler_v1_0_s_ifspec; /// MIDL generated Server Interface Handle pRPCData->protocolSequence = RPC_PROTSEQ_LRPC; /// Use Local RPC pRPCData->pProtocolSequence = (RPC_WSTR)g_pRPCProtocolSequence; /// Use Local RPC pRPCData->pEndpoint = ( PWSTR )g_pEndpoint; /// String representation of our endpoint pRPCData->interfaceFlags = RPC_IF_ALLOW_LOCAL_ONLY | /// Reject all non-local RPC calls RPC_IF_AUTOLISTEN | /// Interface will automatically listen RPC_IF_ALLOW_SECURE_ONLY; /// Only allow authorized clients (valid account and credentials) for ( UINT32 index = 0; index < ITERATIONS; index++) { switch (index) { case RPC_SELECT_PROTOCOL_SEQUENCE: { status = RpcServerUseProtseqEp(pRPCData->pProtocolSequence, /// protocolSequence to register. In our case this is Local RPC RPC_C_PROTSEQ_MAX_REQS_DEFAULT, /// Backlog queue length. In our case this is ignored. pRPCData->pEndpoint, /// Use our endpoint information 0); /// We will implement security via a callback routine if (status != RPC_S_OK) { ServiceEventLogError(L "RPCServerInterfaceInitialize : RpcServerUseProtseqEp()" , status); HLPR_BAIL; } break ; } case RPC_REGISTER_INTERFACE: { status = RpcServerRegisterIfEx(pRPCData->rpcInterfaceHandle, /// Handle genereated by MIDL compiler for Interface 0, /// Use default entry point type 0, /// Use default entry point vector pRPCData->interfaceFlags, /// Registration flags RPC_C_LISTEN_MAX_CALLS_DEFAULT, /// Max number of calls that can be accepted concurrently RPCServerInterfaceSecurityCallback); /// Callback routine to implement our security if (status != RPC_S_OK) { ServiceEventLogError(L "RPCServerInterfaceInitialize : RpcServerRegisterIf()" , status); HLPR_BAIL; } break ; } case RPC_CREATE_BINDING_INFORMATION: { status = RpcServerInqBindings(&(pRPCData->pBindingVector)); /// Get vector of binding handles if (status != RPC_S_OK) { ServiceEventLogError(L "RPCServerInterfaceInitialize : RpcServerInqBindings()" , status); HLPR_BAIL; } break ; } case RPC_REGISTER_ENDPOINT: { status = RpcEpRegister(pRPCData->rpcInterfaceHandle, /// Handle genereated by MIDL compiler for Interface pRPCData->pBindingVector, /// Vector of Binding Handles 0, /// No object UUIDs L "WFPSampler Endpoint" ); /// Annotation / Comment if (status != RPC_S_OK) { ServiceEventLogError(L "RPCServerInterfaceInitialize : RpcEpRegister()" , status); HLPR_BAIL; } pRPCData->isEndpointRegistered = TRUE; break ; } default : { status = RPC_S_INVALID_ARG; break ; } } ServiceStatusReportToSCM(SERVICE_START_PENDING, status, 5000); } HLPR_BAIL_LABEL: if (status != RPC_S_OK) ServiceStatusReportToSCM(SERVICE_STOPPED, status, 0); return status; } |
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials