1 krisbash 1.1 /*============================================================================
|
2 krisbash 1.2 * Copyright (C) Microsoft Corporation, All rights reserved.
|
3 krisbash 1.1 *============================================================================
4 */
5 #include <MI.h>
6 #include "InteractionProtocolHandler.h"
7 #include "Options.h"
8 #include <pal/atomic.h>
|
9 krisbash 1.2 #include <pal/intsafe.h>
|
10 krisbash 1.1 #include <pal/thread.h>
11 #include <pal/format.h>
12 #include <pal/strings.h>
13 #include <pal/lock.h>
14 #include <pal/sleep.h>
15 #include <base/Strand.h>
16 #include <base/messages.h>
17 #include <base/packing.h>
18 #include <base/paths.h>
19 #include <base/result.h>
20 #include <base/log.h>
21 #include <protocol/protocol.h>
22 #include <stdlib.h>
23
24 //#define LOGD(a) {Tprintf a;Tprintf(MI_T("\n"));}
25 //#define LOGD(...)
26
27 extern const MI_ApplicationFT g_interactionProtocolHandler_ApplicationFT;
28 extern const MI_SessionFT g_interactionProtocolHandler_SessionFT;
29 extern const MI_OperationFT g_interactionProtocolHandler_OperationFT;
30 extern const MI_SessionFT g_interactionProtocolHandler_SessionFT_Dummy;
31 krisbash 1.1
32 typedef struct _ApplicationThread
33 {
34 struct _ApplicationThread *next;
35 Thread thread;
36 } ApplicationThread;
37
38 typedef struct _InteractionProtocolHandler_Application
39 {
40 MI_Char *applicationID;
41 MI_Application myMiApplication;
42 ptrdiff_t threadCount;
43 Lock listOfThreadsLock;
44 ApplicationThread *listOfThreads;
45 Thread safeShutdownThread;
46 } InteractionProtocolHandler_Application;
47
48 typedef void * SessionCloseCompletionContext;
49 typedef void (MI_CALL * SessionCloseCompletionCallback)(_In_opt_ SessionCloseCompletionContext);
50
51 typedef struct _SessionCloseCompletion
52 krisbash 1.1 {
53 // count indicating who many protocool run thread are running
54 // so who ever finish last session close or the last protocol run thread
55 // will take care of releasing this completion and calling the callback (if necessary)
|
56 krisbash 1.2 volatile ptrdiff_t count;
|
57 krisbash 1.1 SessionCloseCompletionCallback completionCallback;
58 SessionCloseCompletionContext completionContext;
59 } SessionCloseCompletion;
60
61 typedef struct _InteractionProtocolHandler_Session
62 {
63 InteractionProtocolHandler_Application * parentApplication;
64 MI_DestinationOptions destinationOptions;
65 MI_Session myMiSession;
66 // released by either session close or the protocol run thread, whoever finishes last
|
67 krisbash 1.2 SessionCloseCompletion * sessionCloseCompletion;
|
68 krisbash 1.1 } InteractionProtocolHandler_Session;
69
70 typedef enum _InteractionProtocolHandler_Operation_CurrentState
71 {
72 InteractionProtocolHandler_Operation_CurrentState_NotConnected = 0,
73 InteractionProtocolHandler_Operation_CurrentState_WaitingForConnect,
74 InteractionProtocolHandler_Operation_CurrentState_WaitingForClientResultAck,
75 InteractionProtocolHandler_Operation_CurrentState_WaitingForResult,
76 InteractionProtocolHandler_Operation_CurrentState_ConnectionFailed,
77 InteractionProtocolHandler_Operation_CurrentState_Disconnected,
78 InteractionProtocolHandler_Operation_CurrentState_Closed
79
80 } InteractionProtocolHandler_Operation_CurrentState;
81
82 typedef enum _InteractionProtocolHandler_Operation_OperationType
83 {
84 InteractionProtocolHandler_Operation_OperationType_Instance,
85 InteractionProtocolHandler_Operation_OperationType_Indication,
86 InteractionProtocolHandler_Operation_OperationType_Class
87 } InteractionProtocolHandler_Operation_OperationType;
88
89 krisbash 1.1
90 typedef struct _InteractionProtocolHandler_Operation
91 {
92 InteractionProtocolHandler_Session *parentSession;
93 MI_Operation myMiOperation;
94 MI_OperationCallbacks asyncOperationCallbacks;
95 Strand strand; /* To manage interaction with ProtocolSocket */
96 RequestMsg* req; /* Base pointer of full operation request message */
97 ProtocolSocketAndBase* protocol;
98 ApplicationThread *protocolRunThread;
99 volatile ptrdiff_t currentState; /* InteractionProtocolHandler_Operation_CurrentState */
100 MI_Boolean deliveredFinalResult;
101 InteractionProtocolHandler_Operation_OperationType operationType;
102 Message* cachedResultRequest;
103 MI_Boolean callingFinalResult;
104 Message* currentObjectMessage;
105 Message* currentResultMessage;
106 MI_Class currentClassResult;
107
108 } InteractionProtocolHandler_Operation;
109
110 krisbash 1.1 STRAND_DEBUGNAME(ProtocolHandler);
111
112 MI_Result InteractionProtocolHandler_Application_IncrementThreadCount(
113 _In_ InteractionProtocolHandler_Application *application);
114 MI_Result InteractionProtocolHandler_Application_DecrementThreadCount(
115 _In_ InteractionProtocolHandler_Application *application);
116 MI_Result InteractionProtocolHandler_Application_SafeCloseThread(
|
117 krisbash 1.2 _In_ InteractionProtocolHandler_Application *application,
|
118 krisbash 1.1 _In_ ApplicationThread *operationThread);
119
120
121 MI_Result MI_CALL InteractionProtocolHandler_Session_New(
|
122 krisbash 1.2 _In_ MI_Application *miApplication,
|
123 krisbash 1.1 _In_opt_z_ const MI_Char *protocol,
|
124 krisbash 1.2 _In_opt_z_ const MI_Char *destination,
125 _In_opt_ MI_DestinationOptions *options,
|
126 krisbash 1.1 _In_opt_ MI_SessionCallbacks *callbacks,
127 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
128 _Out_ MI_Session *session);
129
130 MI_Result MI_CALL InteractionProtocolHandler_Client_Ack_PostToInteraction(_In_ MI_Operation *_operation)
131 {
132 InteractionProtocolHandler_Operation* operation = (InteractionProtocolHandler_Operation *)_operation->reserved2;
133
134 trace_InteractionProtocolHandler_Client_Ack_Post(operation);
135
136 /* Clean up all the result data for this iteration of results */
137 if (operation->currentObjectMessage)
138 {
139 Message_Release(operation->currentObjectMessage);
140 operation->currentObjectMessage = NULL;
141 }
142 if (operation->currentResultMessage)
143 {
144 Message_Release(operation->currentResultMessage);
145 operation->currentResultMessage = NULL;
146 }
147 krisbash 1.1 if (operation->currentClassResult.ft)
148 {
149 MI_Class_Delete(&operation->currentClassResult);
150 memset(&operation->currentClassResult, 0, sizeof(operation->currentClassResult));
151 }
152
153 Strand_ScheduleAck(&operation->strand);
154
155 return MI_RESULT_OK;
156 }
157 MI_Result MI_CALL InteractionProtocolHandler_Client_Ack_NoPostToInteraction(_In_ MI_Operation *_operation)
158 {
159 InteractionProtocolHandler_Operation* operation = (InteractionProtocolHandler_Operation *)_operation->reserved2;
|
160 krisbash 1.2
|
161 krisbash 1.1 /* Processing an ack that requires no ack to the interaction interface */
162 trace_InteractionProtocolHandler_Client_Ack_NoPost(operation);
163 return MI_RESULT_OK;
164 }
165
166 static MI_Uint64 _NextOperationId()
167 {
168 static ptrdiff_t _operationId = 10000;
169 return (MI_Uint64) Atomic_Inc(&_operationId);
170 }
171
172 static char* _StringToStr(const MI_Char* str)
173 {
174 MI_Uint32 n = Tcslen(str);
175 MI_Uint32 i;
176 char* r = PAL_Malloc(sizeof(char)* (n + 1));
177
178 if (!r)
179 return NULL;
180
181 for (i = 0; i < n; i++)
182 krisbash 1.1 {
183 r[i] = (char)str[i];
184 }
185
186 r[n] = '\0';
187
188 return r;
189 }
190
191
192 /* ===================================================================================
193 * ===================================================================================
194 * ===================================================================================
195 * ===================================================================================
196 * ===================================================================================
197 * ===================================================================================
198 */
199
200 static void InteractionProtocolHandler_Operation_Strand_Post( _In_ Strand* self_, _In_ Message* msg)
201 {
202 InteractionProtocolHandler_Operation *operation = FromOffset(InteractionProtocolHandler_Operation, strand, self_);
203 krisbash 1.1 trace_InteractionProtocolHandler_Operation_StrandPost(
|
204 krisbash 1.2 operation,
|
205 krisbash 1.1 msg,
206 msg->tag,
207 MessageName(msg->tag),
208 msg->operationId );
209
210 switch(msg->tag)
211 {
212 case PostInstanceMsgTag:
213 {
214 MI_Boolean needToAck = MI_FALSE;
215
216 //If we have a previous item we need to send it
217 if (operation->cachedResultRequest)
218 {
219 PostInstanceMsg* rsp = (PostInstanceMsg*)operation->cachedResultRequest;
220
221 operation->currentObjectMessage = operation->cachedResultRequest; /* Needs releasing in Ack */
222 operation->cachedResultRequest = NULL;
223
224 #ifdef _PREFAST_
225 #pragma prefast(push)
|
226 krisbash 1.2 #pragma prefast(disable:26001)
|
227 krisbash 1.1 #endif
228
229 operation->asyncOperationCallbacks.instanceResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, rsp->instance, MI_TRUE, MI_RESULT_OK, NULL, NULL, InteractionProtocolHandler_Client_Ack_PostToInteraction);
230
231 #ifdef _PREFAST_
232 #pragma prefast(pop)
233 #endif
234 }
235 else
236 needToAck = MI_TRUE;
237
238 {
239 PostInstanceMsg* rsp = (PostInstanceMsg*)msg;
240 if (rsp->instance)
241 {
242 /* if we have an instance we need to cache it */
243 Message_AddRef(msg);
244 operation->cachedResultRequest = msg; /* This will be used next time around or when we deliver final result */
245 }
246 }
247
248 krisbash 1.1 if (needToAck)
249 {
250 Strand_ScheduleAck(&operation->strand);
251 return;
252 }
253
254 break;
255 }
256 case PostIndicationMsgTag:
257 {
258 PostIndicationMsg* indication = (PostIndicationMsg*)msg;
259 trace_InteractionProtocolHandler_Operation_Strand_Post(
260 operation,
261 indication->base.instance);
262 Message_AddRef(msg);
263 operation->currentObjectMessage = msg; /* Needs releasing in Ack */
264 operation->asyncOperationCallbacks.indicationResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, indication->base.instance, indication->bookmark, indication->machineID, MI_TRUE, MI_RESULT_OK, NULL, NULL, InteractionProtocolHandler_Client_Ack_PostToInteraction);
265
266 break;
267 }
268 case PostResultMsgTag:
269 krisbash 1.1 {
270 PostResultMsg* resp = (PostResultMsg*)msg;
271
272 trace_MIResult( Result_ToString(resp->result) );
273
274 operation->callingFinalResult = 1;
275
276 Message_AddRef(msg);
277 operation->currentResultMessage = msg; /* Released in Ack() */
278
279 if (operation->req->base.tag == SubscribeReqTag)
280 {
281 PostInstanceMsg* previousResp = (PostInstanceMsg*)operation->cachedResultRequest;
282 MI_Instance *previousInstance = NULL;
283
284 if (previousResp)
285 previousInstance = previousResp->instance;
286
287 /* Need to get bookmark from message that doesn't yet exist */
288 operation->asyncOperationCallbacks.indicationResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, previousInstance, NULL, NULL, MI_FALSE, resp->result, resp->errorMessage, resp->cimError, InteractionProtocolHandler_Client_Ack_PostToInteraction);
289 operation->deliveredFinalResult = MI_TRUE;
290 krisbash 1.1 }
291 else if (operation->req->base.tag == GetClassReqTag)
292 {
293 PostSchemaMsg* previousResp = (PostSchemaMsg*)operation->cachedResultRequest;
294 MI_Class *classItem = NULL;
295
296 if (previousResp)
297 {
298 MI_Instance_GetClassExt(previousResp->schemaInstance, &operation->currentClassResult);/* Needs deleting in Ack() */
299 classItem = &operation->currentClassResult;
300 }
301
302 operation->currentObjectMessage = operation->cachedResultRequest; /* Needs releasing in Ack() */
303
304 operation->asyncOperationCallbacks.classResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, classItem, MI_FALSE, resp->result, resp->errorMessage, resp->cimError, InteractionProtocolHandler_Client_Ack_PostToInteraction);
305 }
306 else
307 {
308 PostInstanceMsg* previousResp = (PostInstanceMsg*)operation->cachedResultRequest;
309 MI_Instance *previousInstance = NULL;
310
311 krisbash 1.1 if (previousResp)
312 previousInstance = previousResp->instance;
313
314 operation->currentObjectMessage = operation->cachedResultRequest; /* Needs releasing in Ack() */
315
316 operation->asyncOperationCallbacks.instanceResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, previousInstance, MI_FALSE, resp->result, resp->errorMessage, resp->cimError, InteractionProtocolHandler_Client_Ack_PostToInteraction);
317 }
318
319
320 break;
321 }
322 case NoOpRspTag:
323 {
324 //NoOpRsp* resp = (NoOpRsp*)msg;
325 /* If we have an existing result then we need to send that along with the result.
326 * Note that the Strand_Ack will be done in the Ack we get back from the client.
327 */
328 trace_InteractionProtocolHandler_NoopRspTag();
329 operation->callingFinalResult = 1;
330 operation->asyncOperationCallbacks.instanceResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, NULL, MI_FALSE, MI_RESULT_OK, NULL, NULL, InteractionProtocolHandler_Client_Ack_PostToInteraction);
331 operation->deliveredFinalResult = MI_TRUE;
332 krisbash 1.1 break;
333 }
334 case PostSchemaMsgTag:
335 {
336 MI_Boolean needToAck = MI_FALSE;
337
338 //If we have a previous item we need to send it
339 if (operation->cachedResultRequest)
340 {
341 PostSchemaMsg* rsp = (PostSchemaMsg*)operation->cachedResultRequest;
342
343 operation->currentObjectMessage = operation->cachedResultRequest; /* Needs releasing in Ack */
344 operation->cachedResultRequest = NULL;
345
346 MI_Instance_GetClassExt(rsp->schemaInstance, &operation->currentClassResult);/* Needs deleting in Ack() */
347
348 #ifdef _PREFAST_
349 #pragma prefast(push)
|
350 krisbash 1.2 #pragma prefast(disable:26001)
|
351 krisbash 1.1 #endif
352 operation->asyncOperationCallbacks.classResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, &operation->currentClassResult, MI_TRUE, MI_RESULT_OK, NULL, NULL, InteractionProtocolHandler_Client_Ack_PostToInteraction);
353
354 #ifdef _PREFAST_
355 #pragma prefast(pop)
356 #endif
357 }
358 else
359 needToAck = MI_TRUE;
360
361 {
362 PostSchemaMsg* rsp = (PostSchemaMsg*)msg;
363 if (rsp->schemaInstance)
364 {
365 /* if we have an instance we need to cache it */
366 Message_AddRef(msg);
367 operation->cachedResultRequest = msg; /* This will be used next time around or when we deliver final result */
368 }
369 }
370
371 if (needToAck)
372 krisbash 1.1 {
373 Strand_ScheduleAck(&operation->strand);
374 return;
375 }
376
377 break;
378 }
379 case BinProtocolNotificationTag:
380 {
381 /* Don't support these responses yet so just Ack them */
|
382 krisbash 1.2 Strand_Ack(self_);
|
383 krisbash 1.1 return;
384 }
385 case SubscribeResTag:
386 {
387 /* Subscribe succeeded */
388 Strand_Ack(self_);
389 return;
390 }
391 case GetInstanceReqTag:
392 case EnumerateInstancesReqTag:
393 case NoOpReqTag:
394 case InvokeReqTag:
395 case AssociatorsOfReqTag:
396 case ReferencesOfReqTag:
397 case SubscribeReqTag:
398 case DeleteInstanceReqTag:
399 case CreateInstanceReqTag:
400 case ModifyInstanceReqTag:
401 case GetClassReqTag:
402 case UnsubscribeReqTag:
403 default:
404 krisbash 1.1 {
405 /* We should not get any of these messages as they are the requests. We should only get the responses. Ack anyway for now. */
406 DEBUG_ASSERT( MI_FALSE );
407 Strand_Ack(self_);
408 return;
409 }
410 }
411
412 }
413
414 #ifdef _PREFAST_
415 #pragma prefast (push)
416 #pragma prefast (disable: 26001) // bogus "we know the strand points to the middle of the InteractionProtocolHandler_Operation struct" and Linux sal parser doesnt recognize something like _Readable_elements_(_Inexpressible_(InteractionProtocolHandler_Operation))
417 #endif /* _PREFAST_ */
418
419 static void InteractionProtocolHandler_Operation_Strand_PostControl( _In_ Strand* self_, _In_ Message* msg)
420 {
421 InteractionProtocolHandler_Operation *operation = FromOffset(InteractionProtocolHandler_Operation, strand, self_);
422 ProtocolEventConnect* eventMsg = (ProtocolEventConnect*)msg;
423
424 trace_InteractionProtocolHandler_Operation_Strand_PostControl( operation );
425 krisbash 1.1 DEBUG_ASSERT( ProtocolEventConnectTag == msg->tag );
426
427 if( eventMsg->success )
428 {
429 trace_InteractionProtocolHandler_Session_ProtocolConnecting();
|
430 krisbash 1.2
|
431 krisbash 1.1 /* Posting the operation message so set the state to waiting for a result message */
432 operation->currentState = InteractionProtocolHandler_Operation_CurrentState_WaitingForResult;
433 Strand_Post(&operation->strand, &operation->req->base);
434 }
435 else
436 {
437 trace_InteractionProtocolHandler_Session_ConnectFailed();
438
439 }
440 }
441
442 static void InteractionProtocolHandler_Operation_Strand_Ack( _In_ Strand* self_ )
443 {
444 InteractionProtocolHandler_Operation *operation = FromOffset(InteractionProtocolHandler_Operation, strand, self_);
445 trace_InteractionProtocolHandler_Operation_Strand_Ack(operation);
446 // We are not streaming any results, so no need to manage flow control on Ack
447 }
448
449 static void InteractionProtocolHandler_Operation_Strand_Cancel( _In_ Strand* self_ )
450 {
451 InteractionProtocolHandler_Operation *operation = FromOffset(InteractionProtocolHandler_Operation, strand, self_);
452 krisbash 1.1 trace_InteractionProtocolHandler_Operation_Strand_Cancel(operation);
453 // DEBUG_ASSERT( MI_FALSE ); // not used in this direction
454 }
455
456 static void _Operation_SendFinalResult_Internal(InteractionProtocolHandler_Operation *operation)
457 {
458 operation->currentState = InteractionProtocolHandler_Operation_CurrentState_NotConnected;
459 operation->callingFinalResult = MI_TRUE;
460 if (operation->operationType == InteractionProtocolHandler_Operation_OperationType_Class)
461 {
462 operation->asyncOperationCallbacks.classResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, NULL, MI_FALSE, MI_RESULT_FAILED, NULL, NULL, InteractionProtocolHandler_Client_Ack_NoPostToInteraction);
463 }
464 else if (operation->operationType == InteractionProtocolHandler_Operation_OperationType_Indication)
465 {
466 operation->asyncOperationCallbacks.indicationResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, NULL, NULL, NULL, MI_FALSE, MI_RESULT_FAILED, NULL, NULL, InteractionProtocolHandler_Client_Ack_NoPostToInteraction);
467 }
468 else
469 {
470 operation->asyncOperationCallbacks.instanceResult(&operation->myMiOperation, operation->asyncOperationCallbacks.callbackContext, NULL, MI_FALSE, MI_RESULT_FAILED, NULL, NULL, InteractionProtocolHandler_Client_Ack_NoPostToInteraction);
471 }
472 operation->deliveredFinalResult = MI_TRUE;
473 krisbash 1.1 }
474
475 static void InteractionProtocolHandler_Operation_Strand_Close( _In_ Strand* self_ )
476 {
477 InteractionProtocolHandler_Operation *operation = FromOffset(InteractionProtocolHandler_Operation, strand, self_);
|
478 krisbash 1.2
|
479 krisbash 1.1 trace_InteractionProtocolHandler_Operation_Strand_Close(operation);
480
481 if (!operation->callingFinalResult)
482 {
483 _Operation_SendFinalResult_Internal(operation);
484 }
485 }
486
487 static void InteractionProtocolHandler_Operation_Strand_Finish( _In_ Strand* self_ )
488 {
489 InteractionProtocolHandler_Operation *operation = FromOffset(InteractionProtocolHandler_Operation, strand, self_);
490 // MI_Uint32 returnCode;
491
492 trace_InteractionProtocolHandler_Operation_Strand_Finish(operation);
493
494 //TODO: At some point we need to make sure the thread is shutdown properly without causing deadlocks
495 // Thread_Join(&operation->protocolRunThread, &returnCode);
496
497 Message_Release(&operation->req->base);
498 PAL_Free(operation);
499 }
500 krisbash 1.1
501 #ifdef _PREFAST_
502 #pragma prefast (pop)
503 #endif /* _PREFAST_ */
504
505 /*
|
506 krisbash 1.2 Object that implements the MI Protocol Handler as an Interaction Interface
|
507 krisbash 1.1 over the binary protocol.
508
509 Behavior:
510 - Post implementes different behaviour depending on the type of message
511 being posted
|
512 krisbash 1.2 * For PostInstanceMsg stores the instance in a cache var, and if there is
|
513 krisbash 1.1 previous cached instance not yet delivered will deliver that one first
514 (waiting if necessary).
515 * For PostIndicationMsg always delivers it to the client asynchronously.
516 * For PostResultMsg it will delivered it thru the proper callback and
517 set callingFinalResult to 1 to indicate final result already sent.
518 Also note that NoOpRsp is another case of inal result.
519 * PostSchemaMsg is treated the same as PostInstanceMsg with the same
520 cached var mechanism.
521 * SubscribeRes is just acked immediately as nothing is needed there
522 * All other message types are not expected
523 just passed the operation to tries to ClientRep::MessageCallback
524 if that fails it sends the Ack immediately
|
525 krisbash 1.2 - Ack does nothing as there are no secondary messages to be sent to the
|
526 krisbash 1.1 protocol
527 - Post control notified when the connect has succeeded (or failed). If succeeded
528 the request corresponding to the operartion is send there.
529 - Cancel does nothing at this point.
|
530 krisbash 1.2 - Close sends the final result if not being sent already
|
531 krisbash 1.1 (as indicated by callingFinalResult set on Post)
532 if not it triggers a timeout that will close it
|
533 krisbash 1.2 - Shutdown:
|
534 krisbash 1.1 The InteractionProtocolHandler objects are shutdown/deleted thru the normal
535 Strand logic (once the interaction is closed both ways).
536 */
537 StrandFT InteractionProtocolHandler_Operation_Strand_FT =
538 {
|
539 krisbash 1.2 InteractionProtocolHandler_Operation_Strand_Post,
540 InteractionProtocolHandler_Operation_Strand_PostControl,
|
541 krisbash 1.1 InteractionProtocolHandler_Operation_Strand_Ack,
|
542 krisbash 1.2 InteractionProtocolHandler_Operation_Strand_Cancel,
|
543 krisbash 1.1 InteractionProtocolHandler_Operation_Strand_Close,
544 InteractionProtocolHandler_Operation_Strand_Finish,
545 NULL,
546 NULL,
547 NULL,
|
548 krisbash 1.2 NULL
|
549 krisbash 1.1 };
550
551
552 /* ===================================================================================
553 * ===================================================================================
554 * ===================================================================================
555 * ===================================================================================
556 * ===================================================================================
557 * ===================================================================================
558 */
559
560 MI_Result MI_CALL InteractionProtocolHandler_Operation_Close(
561 _Inout_ MI_Operation *_operation)
562 {
563 InteractionProtocolHandler_Operation* operation = (InteractionProtocolHandler_Operation *)_operation->reserved2;
564 trace_InteractionProtocolHandler_Operation_Close(operation);
565
566 Strand_ScheduleClose(&operation->strand);
567
568 return MI_RESULT_OK;
569 }
570 krisbash 1.1
571 MI_Result MI_CALL InteractionProtocolHandler_Operation_Cancel(
572 _Inout_ MI_Operation *_operation,
573 MI_CancellationReason reason)
574 {
575 InteractionProtocolHandler_Operation* operation = (InteractionProtocolHandler_Operation *)_operation->reserved2;
576
577 if (!operation->callingFinalResult)
578 {
579 /*
580 * Send unsubscribe if and only if not received FinalResult;
581 * Cancellation is not implemented yet in protocol layer
582 * For subscribe operation, sending UnsubscribeReq to server,
583 * which will cleanup the subscribe operation;
584 * TODO Upon end to end cancellation implemented, following 'if'
585 * clause should be removed;
586 */
587 if (operation->req->base.tag == SubscribeReqTag)
588 {
589 UnsubscribeReq *req = UnsubscribeReq_New(operation->req->base.operationId, BinaryProtocolFlag);
590 if (req)
591 krisbash 1.1 {
592 trace_InteractionProtocolHandler_Operation_Cancel_PostUnsubscribeReq(operation);
593 Strand_SchedulePost(&operation->strand, &req->base.base);
594 }
595 else
596 {
597 trace_InteractionProtocolHandler_Operation_Cancel_OutOfMemory(operation);
598 }
599 }
600
601 trace_InteractionProtocolHandler_Operation_Cancel(operation);
602 Strand_ScheduleCancel(&operation->strand);
603 }
604 else
605 {
606 trace_InteractionProtocolHandler_Operation_CancelAfterFinal(operation);
607 }
608 return MI_RESULT_OK;
609 }
610
611 MI_Result MI_CALL InteractionProtocolHandler_Operation_GetSession(
612 krisbash 1.1 _In_ MI_Operation *_operation,
613 _Out_ MI_Session *session)
614 {
615 InteractionProtocolHandler_Operation *operation;
616 if (_operation)
617 {
618 operation = (InteractionProtocolHandler_Operation *)_operation->reserved2;
619 if (operation->parentSession)
620 {
621 memcpy(session, &operation->parentSession->myMiSession, sizeof(*session));
622 return MI_RESULT_OK;
623 }
624 else
625 return MI_RESULT_INVALID_PARAMETER;
626 }
627 else
628 return MI_RESULT_INVALID_PARAMETER;
629 }
630
631 const MI_OperationFT g_interactionProtocolHandler_OperationFT =
632 {
633 krisbash 1.1 InteractionProtocolHandler_Operation_Close,
634 InteractionProtocolHandler_Operation_Cancel,
635 InteractionProtocolHandler_Operation_GetSession,
636 NULL, /* GetInstance, only async supported in protocol handlers */
637 NULL, /* GetIndication, only async supported in protocol handlers */
638 NULL /* GetClass, only async supported in protocol handlers */
639 };
640
641 MI_Result MI_CALL InteractionProtocolHandler_Operation_Close_Error(
642 _Inout_ MI_Operation *operation)
643 {
644 return MI_RESULT_OK;
645 }
646
647 MI_Result MI_CALL InteractionProtocolHandler_Operation_Cancel_Error(
648 _Inout_ MI_Operation *operation,
649 MI_CancellationReason reason)
650 {
651 return MI_RESULT_OK;
652 }
653
654 krisbash 1.1 MI_Result MI_CALL InteractionProtocolHandler_Operation_GetSession_Error(
655 _In_ MI_Operation *operation,
656 _Out_ MI_Session *session)
657 {
658 if (session)
659 memset(session, 0, sizeof(*session));
660 return MI_RESULT_FAILED;
661 }
662
663
664 MI_Result MI_CALL InteractionProtocolHandler_Operation_GetInstance_Error(
665 _In_ MI_Operation *operation,
666 _Outptr_result_maybenull_ const MI_Instance **instance,
667 _Out_opt_ MI_Boolean *moreResults,
668 _Out_opt_ MI_Result *result,
669 _Outptr_opt_result_maybenull_z_ const MI_Char **errorMessage,
670 _Outptr_opt_result_maybenull_ const MI_Instance **completionDetails)
671 {
672 if (instance)
673 *instance = NULL;
674 if (moreResults)
675 krisbash 1.1 *moreResults = MI_FALSE;
676 if (result)
677 *result = MI_RESULT_FAILED;
678 if (errorMessage)
679 *errorMessage = NULL;
680 if (completionDetails)
681 *completionDetails = NULL;
682 return MI_RESULT_FAILED;
683 }
684 MI_Result MI_CALL InteractionProtocolHandler_Operation_GetIndication_Error(
685 _In_ MI_Operation *operation,
686 _Outptr_result_maybenull_ const MI_Instance **instance,
687 _Outptr_opt_result_maybenull_z_ const MI_Char **bookmark,
688 _Outptr_opt_result_maybenull_z_ const MI_Char **machineID,
689 _Out_opt_ MI_Boolean *moreResults,
690 _Out_opt_ MI_Result *result,
691 _Outptr_opt_result_maybenull_z_ const MI_Char **errorMessage,
692 _Outptr_opt_result_maybenull_ const MI_Instance **completionDetails)
693 {
694 if (instance)
695 *instance = NULL;
696 krisbash 1.1 if (bookmark)
697 *bookmark = NULL;
698 if (machineID)
699 *machineID = NULL;
700 if (moreResults)
701 *moreResults = MI_FALSE;
702 if (result)
703 *result = MI_RESULT_FAILED;
704 if (errorMessage)
705 *errorMessage = NULL;
706 if (completionDetails)
707 *completionDetails = NULL;
708 return MI_RESULT_FAILED;
709 }
710
711 MI_Result MI_CALL InteractionProtocolHandler_Operation_GetClass_Error(
712 _In_ MI_Operation *operation,
713 _Outptr_result_maybenull_ const MI_Class **classResult,
714 _Out_opt_ MI_Boolean *moreResults,
715 _Out_opt_ MI_Result *result,
716 _Outptr_opt_result_maybenull_z_ const MI_Char **errorMessage,
717 krisbash 1.1 _Outptr_opt_result_maybenull_ const MI_Instance **completionDetails)
718 {
719 if (classResult)
720 *classResult = NULL;
721 if (moreResults)
722 *moreResults = MI_FALSE;
723 if (result)
724 *result = MI_RESULT_FAILED;
725 if (errorMessage)
726 *errorMessage = NULL;
727 if (completionDetails)
728 *completionDetails = NULL;
729 return MI_RESULT_FAILED;
730 }
731
732
733 const MI_OperationFT g_interactionProtocolHandler_OperationFT_Dummy =
734 {
735 InteractionProtocolHandler_Operation_Close_Error,
736 InteractionProtocolHandler_Operation_Cancel_Error,
737 InteractionProtocolHandler_Operation_GetSession_Error,
738 krisbash 1.1 InteractionProtocolHandler_Operation_GetInstance_Error,
739 InteractionProtocolHandler_Operation_GetIndication_Error,
740 InteractionProtocolHandler_Operation_GetClass_Error
741 };
742
743
744
745 /* ===================================================================================
746 * ===================================================================================
747 * ===================================================================================
748 * ===================================================================================
749 * ===================================================================================
750 * ===================================================================================
751 */
752
753 void SessionCloseCompletion_Release( _In_ SessionCloseCompletion* sessionCloseCompletion )
754 {
755 ptrdiff_t count = Atomic_Dec( &sessionCloseCompletion->count );
756 if( 0 == count )
757 {
758 SessionCloseCompletionCallback completionCallback;
759 krisbash 1.1 SessionCloseCompletionContext completionContext;
|
760 krisbash 1.2
|
761 krisbash 1.1 // That means that this is the final release
|
762 krisbash 1.2 // so we call the completion callback (if necessary)
|
763 krisbash 1.1 // and delete the sessionCloseCompletion
764 completionCallback = sessionCloseCompletion->completionCallback;
765 completionContext = sessionCloseCompletion->completionContext;
766 trace_SessionCloseCompletion_Release_CompletionCallback(sessionCloseCompletion, (void *)completionCallback);
767 PAL_Free(sessionCloseCompletion);
768 if( completionCallback )
769 {
770 completionCallback(completionContext);
771 }
772 }
773 else
774 {
|
775 krisbash 1.2 trace_SessionCloseCompletion_Release_Count(sessionCloseCompletion, (int)count );
|
776 krisbash 1.1 }
777 }
778
779 MI_Result MI_CALL InteractionProtocolHandler_Session_New(
|
780 krisbash 1.2 _In_ MI_Application *miApplication,
|
781 krisbash 1.1 _In_opt_z_ const MI_Char *protocol,
|
782 krisbash 1.2 _In_opt_z_ const MI_Char *destination,
783 _In_opt_ MI_DestinationOptions *options,
|
784 krisbash 1.1 _In_opt_ MI_SessionCallbacks *callbacks,
785 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
786 _Out_ MI_Session *_session)
787 {
788 InteractionProtocolHandler_Session *session = NULL;
789 MI_Result result = MI_RESULT_OK;
790
791 if (extendedError)
792 *extendedError = NULL;
793
794 memset(_session, 0, sizeof(*_session));
795
796 session = PAL_Calloc(1, sizeof(InteractionProtocolHandler_Session));
797 if (session == NULL)
798 {
799 result = MI_RESULT_SERVER_LIMITS_EXCEEDED;
800 goto done;
801 }
802 session->sessionCloseCompletion = (SessionCloseCompletion*)PAL_Calloc(1, sizeof(SessionCloseCompletion));
803 if (session->sessionCloseCompletion == NULL)
804 {
805 krisbash 1.1 result = MI_RESULT_SERVER_LIMITS_EXCEEDED;
806 goto done;
807 }
808 memset( session->sessionCloseCompletion, 0, sizeof(SessionCloseCompletion) );
809 session->sessionCloseCompletion->count = 1; // The session itself, released on session close
|
810 krisbash 1.2
|
811 krisbash 1.1 if (options)
812 {
813 result = MI_DestinationOptions_Clone(options, &session->destinationOptions);
814 if (result != MI_RESULT_OK)
815 goto done;
816 }
817
818 done:
819 if (result == MI_RESULT_OK)
820 {
821 session->parentApplication = (InteractionProtocolHandler_Application*) miApplication->reserved2;
822 _session->ft = &g_interactionProtocolHandler_SessionFT;
823 _session->reserved1 = 0;
824 _session->reserved2 = (ptrdiff_t) session;
825 memcpy(&session->myMiSession, _session, sizeof(session->myMiSession));
826 }
827 else
828 {
829 _session->ft = &g_interactionProtocolHandler_SessionFT_Dummy;
830 _session->reserved1 = 0;
831 _session->reserved2 = 0;
832 krisbash 1.1 if (session)
833 PAL_Free(session);
834
835 }
836
837 return result;
838 }
839
840 MI_Result MI_CALL InteractionProtocolHandler_Session_Close(
841 _Inout_ MI_Session *_session,
842 _In_opt_ void *completionContext,
843 _In_opt_ void (MI_CALL *completionCallback)(_In_opt_ void *completionContext))
844 {
845 InteractionProtocolHandler_Session *session = (InteractionProtocolHandler_Session *)_session->reserved2;
846 if (session)
847 {
848 SessionCloseCompletion* sessionCloseCompletion = session->sessionCloseCompletion;
849 trace_InteractionProtocolHandler_Session_Close(session, (void *)completionCallback);
|
850 krisbash 1.2
|
851 krisbash 1.1 if (session->destinationOptions.ft)
852 {
853 MI_DestinationOptions_Delete(&session->destinationOptions);
854 }
855
856 DEBUG_ASSERT( NULL != sessionCloseCompletion );
857
858 sessionCloseCompletion->completionContext = completionContext;
859 sessionCloseCompletion->completionCallback = completionCallback;
860
861 PAL_Free(session);
862 SessionCloseCompletion_Release( sessionCloseCompletion );
863 }
864 else if (completionCallback)
865 {
866 completionCallback(completionContext);
867 }
|
868 krisbash 1.2
|
869 krisbash 1.1 return MI_RESULT_OK;
870 }
871
872 MI_Result MI_CALL InteractionProtocolHandler_Session_GetApplication(
873 _In_ MI_Session *_session,
874 _Out_ MI_Application *application)
875 {
876 InteractionProtocolHandler_Session *session;
877 if (_session)
878 {
879 session = (InteractionProtocolHandler_Session*)_session->reserved2;
880 if (session)
881 {
882 memcpy(application, &session->parentApplication->myMiApplication, sizeof(*application));
883 return MI_RESULT_OK;
884 }
885 else
886 return MI_RESULT_INVALID_PARAMETER;
887 }
888 else
889 {
890 krisbash 1.1 return MI_RESULT_INVALID_PARAMETER;
891 }
892 }
893
894 static void* MI_CALL InteractionProtocolHandler_Protocol_RunThread(void* _operation)
895 {
896 InteractionProtocolHandler_Operation *operation = (InteractionProtocolHandler_Operation*) _operation;
897 MI_Result miResult;
898 ProtocolSocketAndBase* protocol = operation->protocol;
899 SessionCloseCompletion* sessionCloseCompletion = NULL;
900 ApplicationThread *operationThread = NULL;
901 InteractionProtocolHandler_Application *application = NULL;
902
903 trace_InteractionProtocolHandler_Protocol_RunThread();
904
905 // Since for now we create this thread for each operation (instead of per each session)
906 // we need to release the refcount when finishing
907 sessionCloseCompletion = operation->parentSession->sessionCloseCompletion;
908
909 operationThread = operation->protocolRunThread;
910
911 krisbash 1.1 application = operation->parentSession->parentApplication;
|
912 krisbash 1.2
|
913 krisbash 1.1 //printf("InteractionProtocolHandler_Protocol_RunThread starting - application=%p, thread=%p\n", application, operationThread);
914
915 miResult = Protocol_Run( &protocol->internalProtocolBase, TIME_NEVER);
916
917 trace_InteractionProtocolHandler_Protocol_RunThread_WithResult(miResult);
918 ProtocolSocketAndBase_ReadyToFinish( protocol );
919
920 if( sessionCloseCompletion )
921 {
922 SessionCloseCompletion_Release( sessionCloseCompletion );
923 }
|
924 krisbash 1.2
|
925 krisbash 1.1 InteractionProtocolHandler_Application_SafeCloseThread(application, operationThread);
926 //printf("InteractionProtocolHandler_Protocol_RunThread - exiting, application=%p, thread=%p\n", application, operationThread);
|
927 krisbash 1.2
|
928 krisbash 1.1 return 0;
929 }
930
931 MI_Result InteractionProtocolHandler_Session_Connect(
932 InteractionProtocolHandler_Operation *operation,
933 const MI_Char *locatorIn,
934 const MI_Char * user,
935 const MI_Char * password)
936 {
937 MI_Result r = MI_RESULT_SERVER_LIMITS_EXCEEDED;
938 int res;
939 const char* locator_ = NULL;
940 char* user_ = NULL;
941 char* password_ = NULL;
942 SessionCloseCompletion* sessionCloseCompletion = NULL;
943
944 // Fail if already connected:
945 if (operation->protocol)
946 {
947 trace_MI_SessionAlreadyConnected(operation);
948 r = MI_RESULT_FAILED;
949 krisbash 1.1 goto done;
950 }
951
952 // Locator defaults to SOCKETFILE:
953 if (locatorIn == 0)
954 {
955 #ifdef CONFIG_POSIX
956 locator_ = OMI_GetPath(ID_SOCKETFILE);
957 #else
958 locator_ = "localhost:7777";
959 #endif
960 }
961 else
962 {
963 locator_ = _StringToStr(locatorIn);
964 if (!locator_)
965 {
966 trace_MI_OutOfMemoryInOperation(operation);
967 goto done;
968 }
969 }
970 krisbash 1.1
971 // Convert host to 'char' type:
972 if (user)
973 {
974 user_ = _StringToStr(user);
975 if (!user_)
976 {
977 trace_MI_OutOfMemoryInOperation(operation);
978 goto done;
979 }
980 }
981 if (password)
982 {
983 password_ = _StringToStr(password);
984 if (!password_)
985 {
986 trace_MI_OutOfMemoryInOperation(operation);
987 goto done;
988 }
989 }
990
991 krisbash 1.1 // Set connection state to pending.
992 operation->currentState = InteractionProtocolHandler_Operation_CurrentState_WaitingForConnect;
993
994 // this is the one that Opens the interaction (not the one that receives the open)
|
995 krisbash 1.2 Strand_Init( STRAND_DEBUG(ProtocolHandler) &operation->strand, &InteractionProtocolHandler_Operation_Strand_FT, STRAND_FLAG_ENTERSTRAND, NULL );
|
996 krisbash 1.1
997 // Establish connection with server:
998 {
999 InteractionOpenParams interactionParams;
1000 ProtocolSocketAndBase* protocol = NULL;
1001
1002 Strand_OpenPrepare( &operation->strand, &interactionParams, NULL, NULL, MI_TRUE );
1003
1004 r = ProtocolSocketAndBase_New_Connector(
|
1005 krisbash 1.2 &protocol,
|
1006 krisbash 1.1 NULL,
1007 locator_,
|
1008 krisbash 1.2 &interactionParams,
|
1009 krisbash 1.1 user_,
1010 password_);
1011
1012 if (r != MI_RESULT_OK)
1013 {
1014 trace_MI_SocketConnectorFailed(operation, r);
1015 goto done;
1016 }
1017
1018 operation->protocol = protocol;
|
1019 krisbash 1.2
|
1020 krisbash 1.1 if (operation->parentSession)
1021 {
1022 ptrdiff_t count;
|
1023 krisbash 1.2
|
1024 krisbash 1.1 sessionCloseCompletion = operation->parentSession->sessionCloseCompletion;
1025 // we just assign a non-zero value to flag indicating if we got here first
1026 count = Atomic_Inc( &sessionCloseCompletion->count );
1027 DEBUG_ASSERT( count > 0 );
1028 }
|
1029 krisbash 1.2
|
1030 krisbash 1.1 operation->protocolRunThread = PAL_Calloc(1, sizeof(ApplicationThread));
1031 if (operation->protocolRunThread == NULL)
1032 {
1033 if (NULL != sessionCloseCompletion)
1034 {
1035 SessionCloseCompletion_Release(sessionCloseCompletion);
1036 }
1037 trace_MI_OutOfMemoryInOperation(operation);
1038 goto done;
1039 }
|
1040 krisbash 1.2
|
1041 krisbash 1.1 InteractionProtocolHandler_Application_IncrementThreadCount(operation->parentSession->parentApplication);
1042 //printf("InteractionProtocolHandler_Session_Connect - creating protocol thread, application=%p, thread=%p\n", operation->parentSession->parentApplication, operation->protocolRunThread);
1043 res = Thread_CreateJoinable(
1044 &operation->protocolRunThread->thread,
1045 (ThreadProc)InteractionProtocolHandler_Protocol_RunThread,
1046 NULL,
1047 operation);
|
1048 krisbash 1.2
|
1049 krisbash 1.1 if (res != 0)
1050 {
1051 trace_MI_FailedToStartRunThread(operation);
1052
1053 InteractionProtocolHandler_Application_DecrementThreadCount(operation->parentSession->parentApplication);
1054 if( NULL != sessionCloseCompletion )
1055 {
1056 SessionCloseCompletion_Release( sessionCloseCompletion );
1057 }
1058 r = MI_RESULT_FAILED;
1059 goto done1;
1060 }
1061 }
1062
1063 done1:
1064 if (r)
1065 {
1066 PAL_Free(operation->protocolRunThread);
1067 operation->protocolRunThread = NULL;
1068 }
1069
1070 krisbash 1.1 done:
1071 if (locatorIn && locator_)
1072 PAL_Free((void*)locator_);
1073 if (user_)
1074 PAL_Free(user_);
1075 if (password_)
1076 PAL_Free(password_);
|
1077 krisbash 1.2
|
1078 krisbash 1.1 return r;
1079 }
1080
1081 MI_Result InteractionProtocolHandler_Session_CommonInstanceCode(
1082 _In_ MI_Session *_session,
1083 MI_Uint32 flags,
1084 _In_opt_ MI_OperationOptions *options,
1085 _In_opt_ MI_OperationCallbacks *callbacks,
1086 _In_opt_ RequestMsg *req,
1087 _Out_ MI_Operation *_operation)
1088 {
1089 MI_Result miResult = MI_RESULT_OK;
1090 InteractionProtocolHandler_Operation *operation = NULL;
1091 const MI_Char *user = NULL;
1092 MI_Char *password = NULL;
1093 MI_Uint32 passwordLength = 0;
1094 InteractionProtocolHandler_Session *session = (InteractionProtocolHandler_Session *)_session->reserved2;
1095
1096 if (req == NULL)
1097 {
1098 /* Means caller failed to allocate this */
1099 krisbash 1.1 miResult = MI_RESULT_SERVER_LIMITS_EXCEEDED;
1100 trace_MI_SessionFailed(session, miResult);
1101 goto done;
1102 }
1103
1104 DEBUG_ASSERT( Message_IsRequest( &req->base ) );
1105
1106 if (callbacks == NULL)
1107 {
1108 miResult = MI_RESULT_INVALID_PARAMETER;
1109 trace_MI_SessionFailed(session, miResult);
1110 goto done;
1111 }
1112
1113 memset(_operation, 0, sizeof(*_operation));
1114
1115 //Create actual operation object that holds all the state of the operation
1116 {
1117 operation = PAL_Calloc(1, sizeof(InteractionProtocolHandler_Operation));
1118 if (operation == NULL)
1119 {
1120 krisbash 1.1 trace_MI_OutOfMemoryInSession(session);
1121 miResult = MI_RESULT_SERVER_LIMITS_EXCEEDED;
1122 goto done;
1123 }
1124 }
1125
1126 {
1127 operation->parentSession = session;
|
1128 krisbash 1.2
|
1129 krisbash 1.1 if (session->destinationOptions.ft)
1130 {
1131 MI_UserCredentials credentials;
1132 const MI_Char *optionName;
1133 miResult = MI_DestinationOptions_GetCredentialsAt(&session->destinationOptions, 0, &optionName, &credentials, &flags);
1134 if ((miResult == MI_RESULT_NOT_FOUND) || (miResult == MI_RESULT_INVALID_PARAMETER))
1135 miResult = MI_RESULT_OK;
1136 else if (miResult != MI_RESULT_OK)
1137 goto done;
1138 else
1139 {
1140 if ((Tcscmp(credentials.authenticationType, MI_AUTH_TYPE_CLIENT_CERTS) != 0) && (Tcscmp(credentials.authenticationType, MI_AUTH_TYPE_ISSUER_CERT) != 0))
1141 {
1142 user = credentials.credentials.usernamePassword.username;
1143 miResult = MI_DestinationOptions_GetCredentialsPasswordAt(&session->destinationOptions, 0, &optionName, NULL, 0, &passwordLength, &flags);
1144 if ((miResult != MI_RESULT_NOT_FOUND) && (miResult != MI_RESULT_SERVER_LIMITS_EXCEEDED))
1145 {
|
1146 krisbash 1.2 size_t allocSize = 0;
1147 if (SizeTMult(passwordLength, sizeof(MI_Char), &allocSize) == S_OK)
1148 password = PAL_Malloc(allocSize);
1149
|
1150 krisbash 1.1 if (password == NULL)
1151 {
1152 miResult = MI_RESULT_SERVER_LIMITS_EXCEEDED;
1153 trace_MI_SessionFailed(session, miResult);
1154 goto done;
1155 }
1156 miResult = MI_DestinationOptions_GetCredentialsPasswordAt(&session->destinationOptions, 0, &optionName, password, passwordLength, &passwordLength, &flags);
1157 if (miResult != MI_RESULT_OK)
1158 goto done;
1159 }
1160 else if (miResult != MI_RESULT_OK)
1161 goto done;
1162 }
1163 }
1164 }
1165 }
1166
1167 if (options)
1168 {
1169 struct _GenericOptions_Handle *genericOptions = (struct _GenericOptions_Handle*) options;
1170
1171 krisbash 1.1 if (genericOptions->genericOptions && genericOptions->genericOptions->optionsInstance)
1172 {
1173 miResult = InstanceToBatch(
|
1174 krisbash 1.2 genericOptions->genericOptions->optionsInstance,
|
1175 krisbash 1.1 NULL,
1176 NULL,
1177 req->base.batch,
|
1178 krisbash 1.2 &req->packedOptionsPtr,
|
1179 krisbash 1.1 &req->packedOptionsSize);
1180
1181 if (miResult != MI_RESULT_OK)
1182 {
1183 trace_MI_InstanceToBatch_Failed(session, miResult);
1184 goto done;
1185 }
1186 req->options = genericOptions->genericOptions->optionsInstance;
1187 }
1188 }
1189 operation->asyncOperationCallbacks = *callbacks;
1190 _operation->ft = &g_interactionProtocolHandler_OperationFT;
1191 _operation->reserved2 = (ptrdiff_t) operation;
1192 operation->myMiOperation = *_operation;
1193 if (req->base.tag == SubscribeReqTag)
1194 {
1195 operation->operationType = InteractionProtocolHandler_Operation_OperationType_Indication;
1196 }
1197 else if (req->base.tag == GetClassReqTag)
1198 {
1199 operation->operationType = InteractionProtocolHandler_Operation_OperationType_Class;
1200 krisbash 1.1 }
1201 else
1202 {
1203 operation->operationType = InteractionProtocolHandler_Operation_OperationType_Instance;
1204 }
1205 operation->req = req;
1206
1207 /* Kick off protocol initialization */
1208 miResult = InteractionProtocolHandler_Session_Connect(operation, NULL, user, password);
1209 if (miResult != MI_RESULT_OK)
1210 {
1211 trace_MI_SessionConnectFailed(session, miResult);
1212 goto done;
1213 }
1214
1215 trace_InteractionProtocolHandler_SessionConnect_Passed();
1216
1217 /* Everything is asynchronous from this point onwards if we were successful */
1218
1219 done:
1220 if (password)
1221 krisbash 1.1 {
1222 #if defined(_MSC_VER)
1223 SecureZeroMemory(password, passwordLength * sizeof(MI_Char));
1224 #else
1225 memset(password, 0, passwordLength * sizeof(MI_Char));
1226 #endif
1227 PAL_Free(password);
1228 }
1229
1230 if (miResult != MI_RESULT_OK)
1231 {
1232 trace_MI_SessionFailed(session, miResult);
1233
1234 if (operation)
1235 {
1236 _Operation_SendFinalResult_Internal(operation);
1237 PAL_Free(operation);
1238 }
1239
1240 memset(_operation, 0, sizeof(_operation));
1241 _operation->ft = &g_interactionProtocolHandler_OperationFT_Dummy;
1242 krisbash 1.1 }
1243
1244 return miResult;
1245 }
1246
1247
1248 void MI_CALL InteractionProtocolHandler_Session_GetInstance(
1249 _In_ MI_Session *_session,
1250 MI_Uint32 flags,
1251 _In_opt_ MI_OperationOptions *options,
1252 _In_opt_z_ const MI_Char *namespaceName,
1253 _In_ const MI_Instance *inboundInstance,
1254 _In_opt_ MI_OperationCallbacks *callbacks,
1255 _Out_ MI_Operation *_operation)
1256 {
1257 MI_Result miResult = MI_RESULT_OK;
1258 GetInstanceReq *req = NULL;
1259
1260 memset(_operation, 0, sizeof(*_operation));
1261
1262
1263 krisbash 1.1 // Create the request message:
1264 {
1265 req = GetInstanceReq_New(_NextOperationId(), BinaryProtocolFlag);
1266 }
1267 // Set nameSpace:
1268 if (req && namespaceName)
1269 {
1270 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1271 if (!req->nameSpace)
1272 {
1273 GetInstanceReq_Release(req);
1274 req = NULL;
1275 }
1276 }
1277 // Pack the instance name into the message's batch.
1278 if (req)
1279 {
1280 miResult = InstanceToBatch(
|
1281 krisbash 1.2 inboundInstance,
|
1282 krisbash 1.1 NULL,
1283 NULL,
1284 req->base.base.batch,
|
1285 krisbash 1.2 &req->packedInstanceNamePtr,
|
1286 krisbash 1.1 &req->packedInstanceNameSize);
1287
1288 if (miResult != MI_RESULT_OK)
1289 {
1290 GetInstanceReq_Release(req);
1291 req = NULL;
1292 }
1293 }
1294
1295 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1296
1297 if ((miResult != MI_RESULT_OK) && req)
1298 {
1299 GetInstanceReq_Release(req);
1300 }
1301 }
1302
1303 void MI_CALL InteractionProtocolHandler_Session_ModifyInstance(
1304 _In_ MI_Session *_session,
1305 MI_Uint32 flags,
1306 _In_opt_ MI_OperationOptions *options,
1307 krisbash 1.1 _In_opt_z_ const MI_Char *namespaceName,
1308 _In_ const MI_Instance *inboundInstance,
1309 _In_opt_ MI_OperationCallbacks *callbacks,
1310 _Out_ MI_Operation *_operation)
1311 {
1312 MI_Result miResult = MI_RESULT_OK;
1313 ModifyInstanceReq *req = NULL;
1314
1315 memset(_operation, 0, sizeof(*_operation));
1316
1317
1318 // Create the request message:
1319 {
1320 req = ModifyInstanceReq_New(_NextOperationId(), BinaryProtocolFlag);
1321 }
1322 // Set nameSpace:
1323 if (req && namespaceName)
1324 {
1325 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1326 if (!req->nameSpace)
1327 {
1328 krisbash 1.1 ModifyInstanceReq_Release(req);
1329 req = NULL;
1330 }
1331 }
1332 // Pack the instance name into the message's batch.
1333 if (req)
1334 {
1335 miResult = InstanceToBatch(
|
1336 krisbash 1.2 inboundInstance,
|
1337 krisbash 1.1 NULL,
1338 NULL,
1339 req->base.base.batch,
|
1340 krisbash 1.2 &req->packedInstancePtr,
|
1341 krisbash 1.1 &req->packedInstanceSize);
1342
1343 if (miResult != MI_RESULT_OK)
1344 {
1345 ModifyInstanceReq_Release(req);
1346 req = NULL;
1347 }
1348 }
1349
1350 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1351
1352 if ((miResult != MI_RESULT_OK) && req)
1353 {
1354 ModifyInstanceReq_Release(req);
1355 }
1356 }
1357
1358 void MI_CALL InteractionProtocolHandler_Session_CreateInstance(
1359 _In_ MI_Session *_session,
1360 MI_Uint32 flags,
1361 _In_opt_ MI_OperationOptions *options,
1362 krisbash 1.1 _In_opt_z_ const MI_Char *namespaceName,
1363 _In_ const MI_Instance *inboundInstance,
1364 _In_opt_ MI_OperationCallbacks *callbacks,
1365 _Out_ MI_Operation *_operation)
1366 {
1367 MI_Result miResult = MI_RESULT_OK;
1368 CreateInstanceReq *req = NULL;
1369
1370 memset(_operation, 0, sizeof(*_operation));
1371
1372
1373 // Create the request message:
1374 {
1375 req = CreateInstanceReq_New(_NextOperationId(), BinaryProtocolFlag);
1376 }
1377 // Set nameSpace:
1378 if (req && namespaceName)
1379 {
1380 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1381 if (!req->nameSpace)
1382 {
1383 krisbash 1.1 CreateInstanceReq_Release(req);
1384 req = NULL;
1385 }
1386 }
1387 // Pack the instance name into the message's batch.
1388 if (req)
1389 {
1390 miResult = InstanceToBatch(
|
1391 krisbash 1.2 inboundInstance,
|
1392 krisbash 1.1 NULL,
1393 NULL,
1394 req->base.base.batch,
|
1395 krisbash 1.2 &req->packedInstancePtr,
|
1396 krisbash 1.1 &req->packedInstanceSize);
1397
1398 if (miResult != MI_RESULT_OK)
1399 {
1400 CreateInstanceReq_Release(req);
1401 req = NULL;
1402 }
1403 }
1404
1405 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1406
1407 if ((miResult != MI_RESULT_OK) && req)
1408 {
1409 CreateInstanceReq_Release(req);
1410 }
1411 }
1412
1413 void MI_CALL InteractionProtocolHandler_Session_DeleteInstance(
1414 _In_ MI_Session *_session,
1415 MI_Uint32 flags,
1416 _In_opt_ MI_OperationOptions *options,
1417 krisbash 1.1 _In_opt_z_ const MI_Char *namespaceName,
1418 _In_ const MI_Instance *inboundInstance,
1419 _In_opt_ MI_OperationCallbacks *callbacks,
1420 _Out_ MI_Operation *_operation)
1421 {
1422 MI_Result miResult = MI_RESULT_OK;
1423 DeleteInstanceReq *req = NULL;
1424
1425 memset(_operation, 0, sizeof(*_operation));
1426
1427
1428 // Create the request message:
1429 {
1430 req = DeleteInstanceReq_New(_NextOperationId(), BinaryProtocolFlag);
1431 }
1432 // Set nameSpace:
1433 if (req && namespaceName)
1434 {
1435 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1436 if (!req->nameSpace)
1437 {
1438 krisbash 1.1 DeleteInstanceReq_Release(req);
1439 req = NULL;
1440 }
1441 }
1442 // Pack the instance name into the message's batch.
1443 if (req)
1444 {
1445 miResult = InstanceToBatch(
|
1446 krisbash 1.2 inboundInstance,
|
1447 krisbash 1.1 NULL,
1448 NULL,
1449 req->base.base.batch,
|
1450 krisbash 1.2 &req->packedInstanceNamePtr,
|
1451 krisbash 1.1 &req->packedInstanceNameSize);
1452
1453 if (miResult != MI_RESULT_OK)
1454 {
1455 DeleteInstanceReq_Release(req);
1456 req = NULL;
1457 }
1458 }
1459
1460 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1461
1462 if ((miResult != MI_RESULT_OK) && req)
1463 {
1464 DeleteInstanceReq_Release(req);
1465 }
1466 }
1467
1468 void MI_CALL InteractionProtocolHandler_Session_Invoke(
1469 _In_ MI_Session *_session,
1470 MI_Uint32 flags,
1471 _In_opt_ MI_OperationOptions *options,
1472 krisbash 1.1 _In_opt_z_ const MI_Char *namespaceName,
1473 _In_opt_z_ const MI_Char *className,
1474 _In_z_ const MI_Char *methodName,
1475 _In_opt_ const MI_Instance *inboundInstance,
1476 _In_opt_ const MI_Instance *inboundProperties,
1477 _In_opt_ MI_OperationCallbacks *callbacks,
1478 _Out_ MI_Operation *_operation)
1479 {
1480 MI_Result miResult = MI_RESULT_OK;
1481 InvokeReq *req = NULL;
1482
1483 memset(_operation, 0, sizeof(*_operation));
1484
1485
1486 // Create the request message:
1487 {
1488 req = InvokeReq_New(_NextOperationId(), BinaryProtocolFlag);
1489 }
1490 // Set nameSpace:
1491 if (req && namespaceName)
1492 {
1493 krisbash 1.1 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1494 if (!req->nameSpace)
1495 {
1496 InvokeReq_Release(req);
1497 req = NULL;
1498 }
1499 }
1500 // Set method name:
1501 if (req && methodName)
1502 {
1503 req->function = Batch_Tcsdup(req->base.base.batch, methodName);
1504 if (!req->function)
1505 {
1506 InvokeReq_Release(req);
1507 req = NULL;
1508 }
1509 }
1510 // Pack the instance into the message's batch.
1511 if (req && inboundInstance)
1512 {
1513 miResult = InstanceToBatch(
|
1514 krisbash 1.2 inboundInstance,
|
1515 krisbash 1.1 NULL,
1516 NULL,
1517 req->base.base.batch,
|
1518 krisbash 1.2 &req->packedInstancePtr,
|
1519 krisbash 1.1 &req->packedInstanceSize);
1520
1521 if (miResult != MI_RESULT_OK)
1522 {
1523 InvokeReq_Release(req);
1524 req = NULL;
1525 }
1526 }
1527 else if (req && className)
1528 {
1529 req->className = Batch_Tcsdup(req->base.base.batch, className);
1530 if (!req->className)
1531 {
1532 InvokeReq_Release(req);
1533 req = NULL;
1534 }
1535 }
1536 if (req && inboundProperties)
1537 {
1538 miResult = InstanceToBatch(
|
1539 krisbash 1.2 inboundProperties,
|
1540 krisbash 1.1 NULL,
1541 NULL,
1542 req->base.base.batch,
|
1543 krisbash 1.2 &req->packedInstanceParamsPtr,
|
1544 krisbash 1.1 &req->packedInstanceParamsSize);
1545
1546 if (miResult != MI_RESULT_OK)
1547 {
1548 InvokeReq_Release(req);
1549 req = NULL;
1550 }
1551 }
1552
1553 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1554
1555 if ((miResult != MI_RESULT_OK) && req)
1556 {
1557 InvokeReq_Release(req);
1558 }
1559 }
1560
1561 void MI_CALL InteractionProtocolHandler_Session_EnumerateInstances(
1562 _In_ MI_Session *_session,
1563 MI_Uint32 flags,
1564 _In_opt_ MI_OperationOptions *options,
1565 krisbash 1.1 _In_opt_z_ const MI_Char *namespaceName,
1566 _In_opt_z_ const MI_Char *className,
1567 MI_Boolean keysOnly,
1568 _In_opt_ MI_OperationCallbacks *callbacks,
1569 _Out_ MI_Operation *_operation)
1570 {
1571 MI_Result miResult = MI_RESULT_OK;
1572 EnumerateInstancesReq *req = NULL;
1573
1574 memset(_operation, 0, sizeof(*_operation));
1575
1576
1577 // Create the request message:
1578 {
1579 req = EnumerateInstancesReq_New(_NextOperationId(), BinaryProtocolFlag);
1580 }
1581
1582 // If no shallow flag, use deep inheritance.
1583 if (req && !(flags & MI_OPERATIONFLAGS_POLYMORPHISM_SHALLOW))
|
1584 krisbash 1.2 {
|
1585 krisbash 1.1 req->deepInheritance = MI_TRUE;
1586 }
1587
1588 // Set nameSpace:
1589 if (req && namespaceName)
1590 {
1591 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1592 if (!req->nameSpace)
1593 {
1594 EnumerateInstancesReq_Release(req);
1595 req = NULL;
1596 }
1597 }
1598 if (req && className)
1599 {
1600 req->className = Batch_Tcsdup(req->base.base.batch, className);
1601 if (!req->className)
1602 {
1603 EnumerateInstancesReq_Release(req);
1604 req = NULL;
1605 }
1606 krisbash 1.1 }
1607
1608 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1609
1610 if ((miResult != MI_RESULT_OK) && req)
1611 {
1612 EnumerateInstancesReq_Release(req);
1613 }
1614 }
1615
1616 void MI_CALL InteractionProtocolHandler_Session_QueryInstances(
1617 _In_ MI_Session *_session,
1618 MI_Uint32 flags,
1619 _In_opt_ MI_OperationOptions *options,
1620 _In_opt_z_ const MI_Char *namespaceName,
1621 _In_opt_z_ const MI_Char *queryDialect,
1622 _In_opt_z_ const MI_Char *queryExpression,
1623 _In_opt_ MI_OperationCallbacks *callbacks,
1624 _Out_ MI_Operation *_operation)
1625 {
1626 {
1627 krisbash 1.1 MI_Result miResult = MI_RESULT_OK;
1628 EnumerateInstancesReq *req = NULL;
1629
1630 memset(_operation, 0, sizeof(*_operation));
1631
1632
1633 // Create the request message:
1634 {
1635 req = EnumerateInstancesReq_New(_NextOperationId(), BinaryProtocolFlag);
1636 }
1637 // Set nameSpace:
1638 if (req && namespaceName)
1639 {
1640 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1641 if (!req->nameSpace)
1642 {
1643 EnumerateInstancesReq_Release(req);
1644 req = NULL;
1645 }
1646 }
1647 if (req && queryDialect)
1648 krisbash 1.1 {
1649 req->queryLanguage = Batch_Tcsdup(req->base.base.batch, queryDialect);
1650 if (!req->queryLanguage)
1651 {
1652 EnumerateInstancesReq_Release(req);
1653 req = NULL;
1654 }
1655 }
1656 if (req && queryExpression)
1657 {
1658 req->queryExpression = Batch_Tcsdup(req->base.base.batch, queryExpression);
1659 if (!req->queryExpression)
1660 {
1661 EnumerateInstancesReq_Release(req);
1662 req = NULL;
1663 }
1664 }
1665 // If no shallow flag, use deep inheritance.
1666 if (req && !(flags & MI_OPERATIONFLAGS_POLYMORPHISM_SHALLOW))
|
1667 krisbash 1.2 {
|
1668 krisbash 1.1 req->deepInheritance = MI_TRUE;
1669 }
1670
1671 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1672
1673 if ((miResult != MI_RESULT_OK) && req)
1674 {
1675 EnumerateInstancesReq_Release(req);
1676 }
1677 }}
1678
1679 void MI_CALL InteractionProtocolHandler_Session_AssociatorInstances(
1680 _In_ MI_Session *_session,
1681 MI_Uint32 flags,
1682 _In_opt_ MI_OperationOptions *options,
1683 _In_opt_z_ const MI_Char *namespaceName,
1684 _In_ const MI_Instance *instanceKeys,
1685 _In_opt_z_ const MI_Char *assocClass,
1686 _In_opt_z_ const MI_Char *resultClass,
1687 _In_opt_z_ const MI_Char *role,
1688 _In_opt_z_ const MI_Char *resultRole,
1689 krisbash 1.1 MI_Boolean keysOnly,
1690 _In_opt_ MI_OperationCallbacks *callbacks,
1691 _Out_ MI_Operation *_operation)
1692 {
1693 MI_Result miResult = MI_RESULT_OK;
1694 AssociationsOfReq *req = NULL;
1695
1696 memset(_operation, 0, sizeof(*_operation));
1697
1698
1699 // Create the request message:
1700 {
1701 req = AssociationsOfReq_New(_NextOperationId(), BinaryProtocolFlag, AssociatorsOfReqTag);
1702 }
1703 // Set nameSpace:
1704 if (req && namespaceName)
1705 {
1706 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1707 if (!req->nameSpace)
1708 {
1709 AssociationsOfReq_Release(req);
1710 krisbash 1.1 req = NULL;
1711 }
1712 }
1713 if (req && assocClass)
1714 {
1715 req->assocClass = Batch_Tcsdup(req->base.base.batch, assocClass);
1716 if (!req->assocClass)
1717 {
1718 AssociationsOfReq_Release(req);
1719 req = NULL;
1720 }
1721 }
1722 if (req && resultClass)
1723 {
1724 req->resultClass = Batch_Tcsdup(req->base.base.batch, resultClass);
1725 if (!req->resultClass)
1726 {
1727 AssociationsOfReq_Release(req);
1728 req = NULL;
1729 }
1730 }
1731 krisbash 1.1 if (req && role)
1732 {
1733 req->role = Batch_Tcsdup(req->base.base.batch, role);
1734 if (!req->role)
1735 {
1736 AssociationsOfReq_Release(req);
1737 req = NULL;
1738 }
1739 }
1740 if (req && resultRole)
1741 {
1742 req->resultRole = Batch_Tcsdup(req->base.base.batch, resultRole);
1743 if (!req->resultRole)
1744 {
1745 AssociationsOfReq_Release(req);
1746 req = NULL;
1747 }
1748 }
1749 // Pack the instance into the message's batch.
1750 if (req && instanceKeys)
1751 {
1752 krisbash 1.1 miResult = InstanceToBatch(
|
1753 krisbash 1.2 instanceKeys,
|
1754 krisbash 1.1 NULL,
1755 NULL,
1756 req->base.base.batch,
|
1757 krisbash 1.2 &req->packedInstancePtr,
|
1758 krisbash 1.1 &req->packedInstanceSize);
1759
1760 if (miResult != MI_RESULT_OK)
1761 {
1762 AssociationsOfReq_Release(req);
1763 req = NULL;
1764 }
1765 }
1766
1767 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1768
1769 if ((miResult != MI_RESULT_OK) && req)
1770 {
1771 AssociationsOfReq_Release(req);
1772 }
1773 }
1774
1775 void MI_CALL InteractionProtocolHandler_Session_ReferenceInstances(
1776 _In_ MI_Session *_session,
1777 MI_Uint32 flags,
1778 _In_opt_ MI_OperationOptions *options,
1779 krisbash 1.1 _In_opt_z_ const MI_Char *namespaceName,
1780 _In_ const MI_Instance *instanceKeys,
1781 _In_opt_z_ const MI_Char *resultClass,
1782 _In_opt_z_ const MI_Char *role,
1783 MI_Boolean keysOnly,
1784 _In_opt_ MI_OperationCallbacks *callbacks,
1785 _Out_ MI_Operation *_operation)
1786 {
1787 MI_Result miResult = MI_RESULT_OK;
1788 AssociationsOfReq *req = NULL;
1789
1790 memset(_operation, 0, sizeof(*_operation));
1791
1792
1793 // Create the request message:
1794 {
1795 req = AssociationsOfReq_New(_NextOperationId(), BinaryProtocolFlag, ReferencesOfReqTag);
1796 }
1797 // Set nameSpace:
1798 if (req && namespaceName)
1799 {
1800 krisbash 1.1 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1801 if (!req->nameSpace)
1802 {
1803 AssociationsOfReq_Release(req);
1804 req = NULL;
1805 }
1806 }
1807 if (req && resultClass)
1808 {
1809 req->resultClass = Batch_Tcsdup(req->base.base.batch, resultClass);
1810 if (!req->resultClass)
1811 {
1812 AssociationsOfReq_Release(req);
1813 req = NULL;
1814 }
1815 }
1816 if (req && role)
1817 {
1818 req->role = Batch_Tcsdup(req->base.base.batch, role);
1819 if (!req->role)
1820 {
1821 krisbash 1.1 AssociationsOfReq_Release(req);
1822 req = NULL;
1823 }
1824 }
1825 // Pack the instance into the message's batch.
1826 if (req && instanceKeys)
1827 {
1828 miResult = InstanceToBatch(
|
1829 krisbash 1.2 instanceKeys,
|
1830 krisbash 1.1 NULL,
1831 NULL,
1832 req->base.base.batch,
|
1833 krisbash 1.2 &req->packedInstancePtr,
|
1834 krisbash 1.1 &req->packedInstanceSize);
1835
1836 if (miResult != MI_RESULT_OK)
1837 {
1838 AssociationsOfReq_Release(req);
1839 req = NULL;
1840 }
1841 }
1842
1843 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1844
1845 if ((miResult != MI_RESULT_OK) && req)
1846 {
1847 AssociationsOfReq_Release(req);
1848 }
1849 }
1850
1851 void MI_CALL InteractionProtocolHandler_Session_Subscribe(
1852 _In_ MI_Session *_session,
1853 MI_Uint32 flags,
1854 _In_opt_ MI_OperationOptions *options,
|
1855 krisbash 1.2 _In_opt_z_ const MI_Char *namespaceName,
|
1856 krisbash 1.1 _In_opt_z_ const MI_Char *queryDialect,
1857 _In_opt_z_ const MI_Char *queryExpression,
1858 _In_opt_ const MI_SubscriptionDeliveryOptions *deliverOptions,
1859 _In_opt_ MI_OperationCallbacks *callbacks,
1860 _Out_ MI_Operation *_operation)
1861 {
1862 MI_Result miResult = MI_RESULT_OK;
1863 SubscribeReq *req = NULL;
1864
1865 memset(_operation, 0, sizeof(*_operation));
1866
1867
1868 // Create the request message:
1869 {
1870 req = SubscribeReq_New(_NextOperationId(), BinaryProtocolFlag);
1871 }
1872 // Set nameSpace:
1873 if (req && namespaceName)
1874 {
1875 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1876 if (!req->nameSpace)
1877 krisbash 1.1 {
1878 SubscribeReq_Release(req);
1879 req = NULL;
1880 }
1881 }
1882 if (req && queryDialect)
1883 {
1884 req->language = Batch_Tcsdup(req->base.base.batch, queryDialect);
1885 if (!req->language)
1886 {
1887 SubscribeReq_Release(req);
1888 req = NULL;
1889 }
1890 }
1891 if (req && queryExpression)
1892 {
1893 req->filter = Batch_Tcsdup(req->base.base.batch, queryExpression);
1894 if (!req->filter)
1895 {
1896 SubscribeReq_Release(req);
1897 req = NULL;
1898 krisbash 1.1 }
1899 }
1900
1901 /* TODO: Attach options */
1902
1903 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1904
1905 if ((miResult != MI_RESULT_OK) && req)
1906 {
1907 SubscribeReq_Release(req);
1908 }
1909 }
1910
1911 void MI_CALL InteractionProtocolHandler_Session_GetClass(
1912 _In_ MI_Session *_session,
|
1913 krisbash 1.2 MI_Uint32 flags,
|
1914 krisbash 1.1 _In_opt_ MI_OperationOptions *options,
1915 _In_opt_z_ const MI_Char *namespaceName,
1916 _In_opt_z_ const MI_Char *className,
1917 _In_opt_ MI_OperationCallbacks *callbacks,
1918 _Out_ MI_Operation *_operation)
1919 {
1920 MI_Result miResult = MI_RESULT_OK;
1921 GetClassReq *req = NULL;
1922
1923 memset(_operation, 0, sizeof(*_operation));
1924
1925
1926 // Create the request message:
1927 {
1928 req = GetClassReq_New(_NextOperationId(), BinaryProtocolFlag);
1929 }
1930 // Set nameSpace:
1931 if (req && namespaceName)
1932 {
1933 req->nameSpace = Batch_Tcsdup(req->base.base.batch, namespaceName);
1934 if (!req->nameSpace)
1935 krisbash 1.1 {
1936 GetClassReq_Release(req);
1937 req = NULL;
1938 }
1939 }
1940 if (req && className)
1941 {
1942 req->className = Batch_Tcsdup(req->base.base.batch, className);
1943 if (!req->className)
1944 {
1945 GetClassReq_Release(req);
1946 req = NULL;
1947 }
1948 }
1949
1950 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, options, callbacks, (RequestMsg*)req, _operation);
1951
1952 if ((miResult != MI_RESULT_OK) && req)
1953 {
1954 GetClassReq_Release(req);
1955 }
1956 krisbash 1.1 }
1957
1958 void MI_CALL InteractionProtocolHandler_Session_EnumerateClasses(
1959 _In_ MI_Session *session,
1960 MI_Uint32 flags,
1961 _In_opt_ MI_OperationOptions *options,
1962 _In_opt_z_ const MI_Char *namespaceName,
1963 _In_opt_z_ const MI_Char *className,
1964 MI_Boolean classNamesOnly,
1965 _In_opt_ MI_OperationCallbacks *callbacks,
1966 _Out_ MI_Operation *operation)
1967 {
1968 memset(operation, 0, sizeof(*operation));
1969 operation->ft = &g_interactionProtocolHandler_OperationFT;
1970 if (callbacks && callbacks->classResult)
1971 callbacks->classResult(operation, callbacks->callbackContext, NULL, MI_FALSE, MI_RESULT_NOT_SUPPORTED, NULL, NULL, InteractionProtocolHandler_Client_Ack_PostToInteraction);
1972 }
1973
1974 void MI_CALL InteractionProtocolHandler_Session_TestConnection(
1975 _In_ MI_Session *_session,
1976 MI_Uint32 flags,
1977 krisbash 1.1 _In_opt_ MI_OperationCallbacks *callbacks,
1978 _Out_ MI_Operation *_operation
1979 )
1980 {
1981
1982 MI_Result miResult = MI_RESULT_OK;
1983 NoOpReq *req = NULL;
1984
1985 memset(_operation, 0, sizeof(*_operation));
1986
1987
1988 // Create the request message:
1989 {
1990 req = NoOpReq_New(_NextOperationId());
1991 }
1992
1993 miResult = InteractionProtocolHandler_Session_CommonInstanceCode(_session, flags, NULL, callbacks, (RequestMsg*)req, _operation);
1994
1995 if ((miResult != MI_RESULT_OK) && req)
1996 {
1997 NoOpReq_Release(req);
1998 krisbash 1.1 }
1999 }
2000
2001
2002 const MI_SessionFT g_interactionProtocolHandler_SessionFT =
2003 {
2004 InteractionProtocolHandler_Session_Close,
2005 InteractionProtocolHandler_Session_GetApplication,
2006 InteractionProtocolHandler_Session_GetInstance,
2007 InteractionProtocolHandler_Session_ModifyInstance,
2008 InteractionProtocolHandler_Session_CreateInstance,
2009 InteractionProtocolHandler_Session_DeleteInstance,
2010 InteractionProtocolHandler_Session_Invoke,
2011 InteractionProtocolHandler_Session_EnumerateInstances,
2012 InteractionProtocolHandler_Session_QueryInstances,
2013 InteractionProtocolHandler_Session_AssociatorInstances,
2014 InteractionProtocolHandler_Session_ReferenceInstances,
2015 InteractionProtocolHandler_Session_Subscribe,
2016 InteractionProtocolHandler_Session_GetClass,
2017 InteractionProtocolHandler_Session_EnumerateClasses,
2018 InteractionProtocolHandler_Session_TestConnection
2019 krisbash 1.1 };
2020
2021 MI_Result MI_CALL InteractionProtocolHandler_Session_Close_Dummy(
2022 _Inout_ MI_Session *session,
2023 _In_opt_ void *completionContext,
2024 _In_opt_ void (MI_CALL *completionCallback)(_In_opt_ void *completionContext))
2025 {
2026 if (completionCallback)
2027 completionCallback(completionContext);
2028
2029 return MI_RESULT_OK;
2030 }
2031 const MI_SessionFT g_interactionProtocolHandler_SessionFT_Dummy =
2032 {
2033 InteractionProtocolHandler_Session_Close_Dummy
2034 };
2035
2036
2037 /* ===================================================================================
2038 * ===================================================================================
2039 * ===================================================================================
2040 krisbash 1.1 * ===================================================================================
2041 * ===================================================================================
2042 * ===================================================================================
2043 */
2044
2045 PAL_Uint32 THREAD_API InteractionProtocolHandler_ThreadShutdown(void *_application)
2046 {
2047 InteractionProtocolHandler_Application *application = (InteractionProtocolHandler_Application*) _application;
2048 ApplicationThread *nextThread;
2049 PAL_Uint32 returnValue;
2050 //printf("InteractionProtocolHandler_ThreadShutdown start - application = %p\n", application);
2051 do
2052 {
2053 ptrdiff_t notification = (ptrdiff_t) Atomic_Read((ptrdiff_t*) &application->listOfThreads);
2054 while (notification == 0)
2055 {
2056 CondLock_Wait((ptrdiff_t)application, (ptrdiff_t*) &application->listOfThreads, notification, CONDLOCK_DEFAULT_SPINCOUNT);
|
2057 krisbash 1.2
|
2058 krisbash 1.1 notification = (ptrdiff_t) application->listOfThreads;
2059 }
2060 //printf("InteractionProtocolHandler_ThreadShutdown Got something to do - application = %p\n", application);
2061
|
2062 krisbash 1.2 do
|
2063 krisbash 1.1 {
2064 Lock_Acquire(&application->listOfThreadsLock);
2065
2066 nextThread = application->listOfThreads;
2067 if ((application->listOfThreads != NULL) && (application->listOfThreads != (ApplicationThread*)-1))
2068 {
2069 application->listOfThreads = nextThread->next;
2070 }
2071
2072 Lock_Release(&application->listOfThreadsLock);
|
2073 krisbash 1.2
|
2074 krisbash 1.1 if ((nextThread == NULL) || (nextThread == (ApplicationThread*)-1))
2075 {
2076 //printf("InteractionProtocolHandler_ThreadShutdown - Finished iteration, application=%p, nextThread=%p\n", application, nextThread);
2077 break;
2078 }
|
2079 krisbash 1.2
|
2080 krisbash 1.1 //printf("InteractionProtocolHandler_ThreadShutdown - shutting down thread, application=%p, thread=%p\n", application, nextThread);
2081 Thread_Join(&nextThread->thread, &returnValue);
2082 Thread_Destroy(&nextThread->thread);
2083 PAL_Free(nextThread);
2084 InteractionProtocolHandler_Application_DecrementThreadCount(application);
2085 }
2086 while (1);
2087 }
2088 while (application->listOfThreads != (ApplicationThread*) -1);
2089
2090 //printf("InteractionProtocolHandler_ThreadShutdown shutdown - application = %p\n", application);
2091
2092 return 0;
2093 }
2094
|
2095 krisbash 1.2 MI_Result MI_MAIN_CALL InteractionProtocolHandler_Application_Initialize(MI_Uint32 flags,
|
2096 krisbash 1.1 _In_opt_z_ const MI_Char * applicationID,
2097 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
2098 _Out_ MI_Application *miApplication)
2099 {
2100 InteractionProtocolHandler_Application *application;
2101
2102 memset(miApplication, 0, sizeof(*miApplication));
2103
2104 application = PAL_Calloc(1, sizeof(InteractionProtocolHandler_Application));
2105 if (application == 0)
2106 {
2107 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
2108 }
2109
2110 if (applicationID)
2111 {
2112 application->applicationID = PAL_Tcsdup(applicationID);
2113 if (application->applicationID == NULL)
2114 {
2115 PAL_Free(application);
2116 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
2117 krisbash 1.1 }
2118 }
2119
2120 if (Thread_CreateJoinable(&application->safeShutdownThread, InteractionProtocolHandler_ThreadShutdown, NULL, application) != 0)
2121 {
2122 if (application->applicationID)
2123 PAL_Free(application->applicationID);
2124 PAL_Free(application);
2125 return MI_RESULT_SERVER_LIMITS_EXCEEDED;
2126 }
2127
2128 miApplication->reserved2 = (ptrdiff_t) application;
2129 miApplication->ft = &g_interactionProtocolHandler_ApplicationFT;
2130 memcpy(&application->myMiApplication, miApplication, sizeof(application->myMiApplication));
2131 if (extendedError)
2132 *extendedError = NULL;
2133 return MI_RESULT_OK;
2134 }
2135
2136 MI_Result MI_CALL InteractionProtocolHandler_Application_Close(
2137 _Inout_ MI_Application *miApplication)
2138 krisbash 1.1 {
2139 InteractionProtocolHandler_Application *application = (InteractionProtocolHandler_Application *)miApplication->reserved2;
2140 if (application)
2141 {
2142 PAL_Uint32 threadValue;
2143 ApplicationThread **lastThreadPtr = &application->listOfThreads;
2144 int didBroadcast = 0;
2145
2146 /* Wait for all other threads to shutdown. Possible some notification got missed */
2147 while (Atomic_Read(&application->threadCount))
2148 {
2149 //printf("InteractionProtocolHandler_Application_Close - thread count is not zero - application = %p, threadcount=%p, first thread left=%p\n", application, (void*)Atomic_Read(&application->threadCount), (void*)application->listOfThreads);
2150 Sleep_Milliseconds(100);
2151 if (didBroadcast == 0)
2152 {
2153 /* Only broadcast the first time */
2154 CondLock_Broadcast((ptrdiff_t) application);
2155 didBroadcast = 1;
2156 }
2157 }
2158
2159 krisbash 1.1 //printf("InteractionProtocolHandler_Application_Close - Notifying ThreadShutdown to finish - application = %p\n", application);
2160 Lock_Acquire(&application->listOfThreadsLock);
2161 while (*lastThreadPtr != 0)
2162 {
2163 lastThreadPtr = &(*lastThreadPtr)->next;
2164 }
2165 *lastThreadPtr = (ApplicationThread*) -1;
2166 Lock_Release(&application->listOfThreadsLock);
|
2167 krisbash 1.2
|
2168 krisbash 1.1 CondLock_Broadcast((ptrdiff_t) application);
2169
2170 //printf("InteractionProtocolHandler_Application_Close - Closing down main shutdown thread - application = %p, threadcount=%p\n", application, (void*)Atomic_Read(&application->threadCount));
2171 Thread_Join(&application->safeShutdownThread, &threadValue);
2172 Thread_Destroy(&application->safeShutdownThread);
2173
2174 //printf("InteractionProtocolHandler_Application_Close - shutdown thread gone - application = %p, threadcount=%p\n", application, (void*)Atomic_Read(&application->threadCount));
2175
2176 if (application->applicationID)
2177 PAL_Free(application->applicationID);
2178 PAL_Free(application);
2179 }
2180 memset(miApplication, 0, sizeof(miApplication));
2181 return MI_RESULT_OK;
2182 }
2183
2184 MI_Result InteractionProtocolHandler_Application_IncrementThreadCount(
2185 _In_ InteractionProtocolHandler_Application *application)
2186 {
|
2187 krisbash 1.2 //ptrdiff_t a =
|
2188 krisbash 1.1 Atomic_Inc(&application->threadCount);
2189 //printf("InteractionProtocolHandler_Application_IncrementThreadCount - application = %p, new count=%p\n", application, (void*)a);
2190 return MI_RESULT_OK;
2191 }
2192 MI_Result InteractionProtocolHandler_Application_DecrementThreadCount(
2193 _In_ InteractionProtocolHandler_Application *application)
2194 {
|
2195 krisbash 1.2 //ptrdiff_t a =
|
2196 krisbash 1.1 Atomic_Dec(&application->threadCount);
2197 //printf("InteractionProtocolHandler_Application_DecrementThreadCount - application = %p, new count=%p\n", application, (void*)a);
2198 return MI_RESULT_OK;
2199 }
2200 MI_Result InteractionProtocolHandler_Application_SafeCloseThread(
|
2201 krisbash 1.2 _In_ InteractionProtocolHandler_Application *application,
|
2202 krisbash 1.1 _In_ ApplicationThread *operationThread)
2203 {
2204 //printf("InteractionProtocolHandler_Application_SafeCloseThread - queueing up handle to close - application = %p, thread=%p\n", application, operationThread);
2205 Lock_Acquire(&application->listOfThreadsLock);
2206 operationThread->next = application->listOfThreads;
2207 application->listOfThreads = operationThread;
2208 Lock_Release(&application->listOfThreadsLock);
|
2209 krisbash 1.2
|
2210 krisbash 1.1 CondLock_Broadcast((ptrdiff_t) application);
2211 return MI_RESULT_OK;
2212 }
2213
2214 MI_Result MI_CALL InteractionProtocolHandler_Application_NewDestinationOptions(
2215 _In_ MI_Application *miApplication,
2216 _Out_ MI_DestinationOptions *options)
2217 {
2218 return DestinationOptions_Create(miApplication, options);
2219 }
2220
2221 MI_Result MI_CALL InteractionProtocolHandler_Application_NewOperationOptions(
2222 _In_ MI_Application *miApplication,
2223 _In_ MI_Boolean customOptionsMustUnderstand,
2224 _Out_ MI_OperationOptions *options)
2225 {
2226 return OperationOptions_Create(miApplication, customOptionsMustUnderstand, options);
2227 }
2228
2229 MI_Result MI_CALL InteractionProtocolHandler_Application_NewSubscriptionDeliveryOptions(
2230 _In_ MI_Application *miApplication,
2231 krisbash 1.1 _In_ MI_SubscriptionDeliveryType deliveryType,
2232 _Out_ MI_SubscriptionDeliveryOptions *deliveryOptions)
2233 {
2234 return SubscriptionDeliveryOptions_Create(miApplication, deliveryType, deliveryOptions);
2235 }
2236
2237 _Success_(return == MI_RESULT_OK)
2238 MI_Result MI_CALL InteractionProtocolHandler_Application_NewHostedProvider(
2239 _In_ MI_Application *application,
2240 _In_z_ const MI_Char * namespaceName,
2241 _In_z_ const MI_Char * providerName,
2242 _In_ MI_MainFunction mi_Main,
2243 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
2244 _Out_ MI_HostedProvider *hostedProvider)
2245 {
|
2246 krisbash 1.2 if ((application == NULL) || (application->ft == NULL) ||
|
2247 krisbash 1.1 (application->reserved2 == 0) || (application->reserved1 != 1))
2248 {
2249 /* Probably already deleted or failed to initialize */
2250 return MI_RESULT_INVALID_PARAMETER;
2251 }
2252
2253 return MI_RESULT_NOT_SUPPORTED;
2254 }
2255
2256
2257
|
2258 krisbash 1.2 const MI_ApplicationFT g_interactionProtocolHandler_ApplicationFT =
|
2259 krisbash 1.1 {
2260 InteractionProtocolHandler_Application_Close,
2261 InteractionProtocolHandler_Session_New,
|
2262 krisbash 1.2 InteractionProtocolHandler_Application_NewHostedProvider,
|
2263 krisbash 1.1 NULL, /* NewInstance, not needed in protocol handler */
2264 InteractionProtocolHandler_Application_NewDestinationOptions,
2265 InteractionProtocolHandler_Application_NewOperationOptions,
2266 InteractionProtocolHandler_Application_NewSubscriptionDeliveryOptions,
2267 NULL, /* NewSerializer, not needed in protocol handler */
2268 NULL, /* NewDeserializer, not needed in protocol handler */
2269 NULL /* NewInstanceFromClass, not needed in protocol handler */
2270 };
|