1 krisbash 1.1 /*============================================================================
|
2 krisbash 1.3 * Copyright (C) Microsoft Corporation, All rights reserved.
|
3 krisbash 1.1 *============================================================================
4 */
5
6 #include "miapi_common.h"
7 #include "Application.h"
8 #include "Session.h"
9 #include "Operation.h"
10 #include "HostedProvider.h"
11 #include "SafeHandle.h"
12 #include "ChildList.h"
13 #include "ProtocolHandlerCache.h"
14 #include "Options.h"
15 #include <MI.h>
|
16 krisbash 1.3 #include <pal/intsafe.h>
|
17 krisbash 1.1 #include <pal/atomic.h>
18 #include <pal/lock.h>
19 #include <pal/format.h>
20 #include <base/instance.h>
21 #include <omi_error/OMI_Error.h>
22 #include <omi_error/omierror.h>
23 //#include <common\propertySet.h>
24 //#include "XmlDeserializer.h"
25 //#include "XmlSerializer.h"
26 #include <base/conf.h>
27 #include <base/paths.h>
28 #include <base/log.h>
29
30 //Used for application user ref count
31 #define ActiveBit 0x80000000
32 #define CountMask 0x7fffffff
33
34 /* Component for debug traces */
35 //LPWSTR componentName = L"MI_Client";
36
37
38 krisbash 1.1 /* Define for real at end of file */
39 extern const MI_ApplicationFT g_applicationFT;
40 extern const MI_ApplicationFT g_applicationFT_OOM;
41
42 /* Real back-end MI_Application structure */
43 typedef struct _ApplicationObject
44 {
45 ThunkHandleManager thunkManager; /* Needs to be aligned so always first in this structure */
|
46 krisbash 1.3
|
47 krisbash 1.1 ChildList sessionList; /* Child sessions */
48 ChildList hostedProviderList; /* Child hosted providers */
49 ProtocolHandlerCache protocolHandlerCache; /* Holds active protocol handlers */
50
51 volatile ptrdiff_t callersRefCount;
52
53 //Our copy. May be NULL
54 MI_Char *applicationID;
55 } ApplicationObject;
56
57 /* Reads config file options: loglevel */
58 static MI_Result _GetLogOptionsFromConfigFile()
59 {
60 char path[PAL_MAX_PATH_SIZE];
61 Conf* conf;
62 char logpath[PAL_MAX_PATH_SIZE];
63 char logfile[PAL_MAX_PATH_SIZE];
64
65 /* Form the configuration file path */
66 Strlcpy(path, OMI_GetPath(ID_CONFIGFILE), sizeof(path));
67 Strlcpy(logpath, OMI_GetPath(ID_LOGDIR), PAL_MAX_PATH_SIZE);
68 krisbash 1.1 Strlcat(logpath, "/", PAL_MAX_PATH_SIZE);
69
70 Strlcpy(logfile, "miclient.log", sizeof(logfile));
71
72 /* Open the configuration file */
73 conf = Conf_Open(path);
74 if (!conf)
75 {
76 trace_MIFailedToOpenConfigFile(scs(path));
77 return MI_RESULT_FAILED;
78 }
79
80 /* For each key=value pair in configuration file */
81 for (;;)
82 {
83 const char* key;
84 const char* value;
85 int r = Conf_Read(conf, &key, &value);
86
87 if (r == -1)
88 {
89 krisbash 1.1 trace_MIFailedToReadConfigValue(path, scs(Conf_Error(conf)));
90 goto error;
91 }
92
93 if (r == 1)
94 break;
95
96 if (strcmp(key, "loglevel") == 0)
97 {
98 if (Log_SetLevelFromString(value) != 0)
99 {
100 trace_MIConfig_InvalidValue(scs(path), Conf_Line(conf), scs(key), scs(value));
101 goto error;
102 }
103 }
104 #if defined(OILOGSYSTEM_FILE)
105 else if (strcmp(key, "logpath") == 0)
106 {
107 if (Strlcpy(logpath, value, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE)
108 {
109 trace_MIConfig_InvalidValue(scs(path), Conf_Line(conf), scs(key), scs(value));
110 krisbash 1.1 goto error;
111 }
112 }
113 else if (strcmp(key, "logfile") == 0)
114 {
115 if (Strlcpy(logfile, value, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE)
116 {
117 trace_MIConfig_InvalidValue(scs(path), Conf_Line(conf), scs(key), scs(value));
118 goto error;
119 }
120 }
121 #endif
122 }
123
124 #if defined(OILOGSYSTEM_FILE)
125 {
126 ZChar pathtolog[PAL_MAX_PATH_SIZE];
127 pathtolog[0] = 0;
128 if (TcsStrlcpy(pathtolog, logpath, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE)
129 {
130 trace_MIClient_OutOfMemory();
131 krisbash 1.1 goto error;
132 }
133 if (TcsStrlcat(pathtolog, logfile, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE)
134 {
135 trace_MIClient_OutOfMemory();
136 goto error;
137 }
|
138 krisbash 1.3
|
139 krisbash 1.1 if (Log_Open(pathtolog) != MI_RESULT_OK)
140 goto error;
141 }
142 #endif
143
144 /* Close configuration file */
145 Conf_Close(conf);
146
147 return MI_RESULT_OK;
148
149 error:
150 Conf_Close(conf);
151 return MI_RESULT_INVALID_PARAMETER;
152 }
153
154 /* PUBLIC Application_NewGenericHandle
155 * Retrieve a new generic handler. This is a generic version of MI_Application/MI_Session/etc.
|
156 krisbash 1.3 * To recycle the handler back into the pool do this:
|
157 krisbash 1.1 * ThunkHandle_Shutdown(genericHandle->thunkHandle);
158 * application - top-level application that the handle will be attached to
159 * handle - resultant handler
160 *
161 * Return code: MI_Result code
162 */
163 MI_Result Application_NewGenericHandle(_Inout_ MI_Application *application, _Out_ GenericHandle *handle)
164 {
165 ThunkHandle *thunkHandle = NULL;
166 MI_Result miResult;
167
168 ApplicationObject *applicationObject = (ApplicationObject*) application->reserved2;
169 miResult = ThunkHandleManager_GetHandle(&applicationObject->thunkManager, &thunkHandle);
170 if (miResult == MI_RESULT_OK)
171 {
172 handle->thunkHandle = thunkHandle;
173 handle->version = thunkHandle->version;
174 handle->functionTable = NULL;
175 }
176
177 return miResult;
178 krisbash 1.1 }
179
180 /*=============================================================================================
|
181 krisbash 1.3 * PUBLIC: Create a real application object and have the client point to it. This is the
|
182 krisbash 1.1 * primary DLL export for the client API.
183 *=============================================================================================
184 */
185 #if defined (_MSC_VER)
186 #define MI_LINKAGE
187 #else
188 #define MI_LINKAGE MI_EXPORT
189 #endif
190 MI_LINKAGE MI_Result MI_MAIN_CALL MI_Application_InitializeV1(
|
191 krisbash 1.3 MI_Uint32 flags,
|
192 krisbash 1.1 _In_opt_z_ const MI_Char * applicationID,
193 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
194 _Out_ MI_Application *application)
195 {
196 ApplicationObject *applicationObject;
|
197 krisbash 1.3 size_t applicationIDLength = 0;
|
198 krisbash 1.1 MI_Result miResult;
199
200 /* Before we do anything zap the extended error if it is being asked for */
201 if (extendedError != NULL)
202 {
203 *extendedError = NULL;
204 }
205
206 /* Minimal check of parameters before we zero out the application structure */
207 if (application == NULL)
208 {
209 return MI_RESULT_INVALID_PARAMETER;
210 }
211
212 if(MI_RESULT_OK != _GetLogOptionsFromConfigFile())
|
213 krisbash 1.3 {
|
214 krisbash 1.1 NitsIgnoringError();
215 }
216
|
217 krisbash 1.3 /* Zero out the application structure so if it fails it can still be passed
|
218 krisbash 1.1 * through to the MI_Application_Close function
219 */
220 memset(application, 0, sizeof(MI_Application));
|
221 krisbash 1.3
|
222 krisbash 1.1 /* Rest of parameter validation */
223 if (flags != 0)
224 {
225 application->ft = &g_applicationFT_OOM;
226 return MI_RESULT_INVALID_PARAMETER;
227 }
228
229 /* Allocate the real back-end application object */
230 applicationObject = (ApplicationObject*) _aligned_malloc(sizeof(ApplicationObject), MEMORY_ALLOCATION_ALIGNMENT);
231 if (applicationObject == NULL)
232 {
233 application->ft = &g_applicationFT_OOM;
234 return MI_RESULT_FAILED;
235 }
236
237 memset(applicationObject, 0, sizeof(ApplicationObject));
238
239 applicationObject->callersRefCount = ActiveBit;
240
241 miResult = ChildList_Initialize(&applicationObject->sessionList);
242 if (miResult != MI_RESULT_OK)
243 krisbash 1.1 {
244 application->ft = &g_applicationFT_OOM;
245 _aligned_free(applicationObject);
246 return miResult;
247 }
248
249 miResult = ChildList_Initialize(&applicationObject->hostedProviderList);
250 if (miResult != MI_RESULT_OK)
251 {
252 ChildList_DeInitialize(&applicationObject->sessionList);
253 application->ft = &g_applicationFT_OOM;
254 _aligned_free(applicationObject);
255 return miResult;
256 }
257
258 /* Initialize the free list for all RealHandle objects */
259 ThunkHandleManager_Initialize(&applicationObject->thunkManager);
260
261 if (applicationID)
262 {
|
263 krisbash 1.3 applicationObject->applicationID = NULL;
264
265 if (SizeTAdd(Tcslen(applicationID), 1, &applicationIDLength) == S_OK &&
266 SizeTMult(applicationIDLength, sizeof(MI_Char), &applicationIDLength) == S_OK)
267 {
268 applicationObject->applicationID = (MI_Char*) PAL_Malloc(applicationIDLength);
269 }
270
|
271 krisbash 1.1 if (applicationObject->applicationID == NULL)
272 {
273 ChildList_DeInitialize(&applicationObject->sessionList);
274 ChildList_DeInitialize(&applicationObject->hostedProviderList);
275 _aligned_free(applicationObject);
276 application->ft = &g_applicationFT_OOM;
277 return MI_RESULT_FAILED;
278 }
279 memcpy(applicationObject->applicationID, applicationID, applicationIDLength);
280 }
281
282 miResult = ProtocolHandlerCache_Initialize(applicationObject->applicationID, &applicationObject->protocolHandlerCache);
283 if (miResult != MI_RESULT_OK)
284 {
285 ChildList_DeInitialize(&applicationObject->sessionList);
286 ChildList_DeInitialize(&applicationObject->hostedProviderList);
287 PAL_Free(applicationObject->applicationID);
288 _aligned_free(applicationObject);
289 application->ft = &g_applicationFT_OOM;
290 return miResult;
291 }
292 krisbash 1.1
293 /* Set up the client handle */
294 application->reserved1 = 1;
295 application->reserved2 = (ptrdiff_t) applicationObject;
296 application->ft = &g_applicationFT;
297
298 trace_MIClient_AppInit(application, applicationObject);
299
300 return MI_RESULT_OK;
301 }
302
303 MI_Result Application_RegisterSession(
|
304 krisbash 1.3 _Inout_ MI_Application *application,
|
305 krisbash 1.1 _Inout_ ChildListNode *session)
306 {
307 ApplicationObject *applicationObject = (ApplicationObject*) application->reserved2;
308 return ChildList_AddNode(&applicationObject->sessionList, session);
309 }
310
311 _Check_return_ long Application_AddRef(_Inout_ ApplicationObject *applicationObject)
312 {
313 ptrdiff_t n;
314 for (n = applicationObject->callersRefCount; n & ActiveBit; n = applicationObject->callersRefCount)
315 {
316 if (Atomic_CompareAndSwap(&applicationObject->callersRefCount, n, n + 1) == n)
317 {
318 /*We incremented the count and we weren't cancelled so return success.*/
319 return 1;
320 }
321 }
322 /*Another thread called Shutdown() so return false.*/
323 return 0;
324 }
325
326 krisbash 1.1 long Application_Release(_Inout_ ApplicationObject *applicationObject)
327 {
328 ptrdiff_t n;
329
330 n = Atomic_Dec(&applicationObject->callersRefCount);
331
332 if (n == 0)
333 {
334 //We are done. We now need to trigger the shutdown caller to wake up in case it is blocked on us
335 CondLock_Broadcast((ptrdiff_t) applicationObject);
336 }
337
338 return n & CountMask;
339 }
340
341 long Application_Shutdown(_Inout_ ApplicationObject *applicationObject)
342 {
343 ptrdiff_t n;
344 for (n = applicationObject->callersRefCount; n & ActiveBit; n = applicationObject->callersRefCount)
345 {
346 if (Atomic_CompareAndSwap(&applicationObject->callersRefCount, n, n & CountMask) == n)
347 krisbash 1.1 {
348 //We are done! We were the one who won Now wait until the refcount hits zero
349 ptrdiff_t curCallerCount = applicationObject->callersRefCount;
350 while (curCallerCount)
351 {
352 /* Wait for operations to finish */
353 CondLock_Wait((ptrdiff_t)applicationObject, &applicationObject->callersRefCount, curCallerCount, CONDLOCK_DEFAULT_SPINCOUNT);
354 curCallerCount = applicationObject->callersRefCount;
355 }
356 return 1;
357 }
358 }
359
360 /*Another thread cleared ActiveBit. That is rather worrisom*/
361 return 0;
362 }
363
364 MI_Result Application_UnregisterSession(
|
365 krisbash 1.3 _Inout_ MI_Application *application,
|
366 krisbash 1.1 _Inout_ ChildListNode *session)
367 {
368 ApplicationObject *applicationObject = (ApplicationObject*) application->reserved2;
369 ChildList_RemoveNode(&applicationObject->sessionList, session);
370
371 return MI_RESULT_OK;
372 }
373
374 MI_Result Application_RegisterHostedProvider(
|
375 krisbash 1.3 _Inout_ MI_Application *application,
|
376 krisbash 1.1 _Inout_ ChildListNode *hostedProvider)
377 {
378 ApplicationObject *applicationObject = (ApplicationObject*) application->reserved2;
379 return ChildList_AddNode(&applicationObject->hostedProviderList, hostedProvider);
380 }
381
382 MI_Result Application_UnregisterHostedProvider(
|
383 krisbash 1.3 _Inout_ MI_Application *application,
|
384 krisbash 1.1 _Inout_ ChildListNode *hostedProvider)
385 {
386 ApplicationObject *applicationObject = (ApplicationObject*) application->reserved2;
387 ChildList_RemoveNode(&applicationObject->hostedProviderList, hostedProvider);
388
389 return MI_RESULT_OK;
390 }
391
392 void Application_AllSessionsShutdown(void *context)
393 {
394 ApplicationObject *applicationObject = (ApplicationObject *) context;
395 CondLock_Broadcast((ptrdiff_t)applicationObject);
396 }
397
398 void Application_AllHostedProvidersShutdown(void *context)
399 {
400 ApplicationObject *applicationObject = (ApplicationObject *) context;
401 CondLock_Broadcast((ptrdiff_t)applicationObject);
402 }
403 /* MI_Application_Close implementation for transport API.
404 */
405 krisbash 1.1 _Success_(return == MI_RESULT_OK)
406 MI_Result MI_CALL Application_Close(
407 _In_ MI_Application *application)
408 {
409 /* Copy of client application so we can clear out theirs as soon as possible */
410 ApplicationObject *applicationObject;
|
411 krisbash 1.3
412 if ((application == NULL) || (application->ft == NULL) ||
|
413 krisbash 1.1 (application->reserved2 == 0) || (application->reserved1 != 1))
414 {
415 /* Probably already deleted or failed to initialize */
416 return MI_RESULT_INVALID_PARAMETER;
417 }
418
419 applicationObject = (ApplicationObject*) application->reserved2;
420
421 trace_MIClient_AppClose(application, applicationObject);
422
423 Application_Shutdown(applicationObject);
424
425 /* clear the client handle */
426 memset(application, 0, sizeof(MI_Application));
427
428 /* Checking the application is somewhat pointless as once we are deleted the real handle
429 * will be deleted anyway!
430 */
431
432 /* Signal that all sessions need to shutdown */
433 {
434 krisbash 1.1 ChildListOutstandingHandles _smallBuffer[100];
435 ChildListOutstandingHandles* outstandingSessions = _smallBuffer;
436 ptrdiff_t outstandingSessionsSize = sizeof(_smallBuffer)/sizeof(_smallBuffer[0]);
437 ptrdiff_t outstandingSessionsCount;
438
439 int r = ChildList_Shutdown(&applicationObject->sessionList);
440 if (r)
441 {
442 //We were the winner for doing the shutdown
443
444 r = ChildList_GetCurrentList(&applicationObject->sessionList, outstandingSessions, (MI_Uint32)outstandingSessionsSize, &outstandingSessionsCount);
445 if (r == 0 && (outstandingSessionsCount > outstandingSessionsSize))
446 {
447 outstandingSessions = PAL_Malloc(outstandingSessionsCount*sizeof(ChildListOutstandingHandles));
448 if (outstandingSessions == NULL)
449 {
450 //NitsAssert(outstandingSessions != NULL, MI_T("ignored memory allocation on purpose"));
|
451 krisbash 1.3 //Note that we cannot cancel the sessions.
|
452 krisbash 1.1 //It is completely up to the client to close all sessions in this case and it will cause it to not respond if they do not
453 }
454 else
455 {
456 outstandingSessionsSize = outstandingSessionsCount;
457 r = ChildList_GetCurrentList(&applicationObject->sessionList, outstandingSessions, (MI_Uint32)outstandingSessionsSize, &outstandingSessionsCount);
458 }
459 }
460 /* Cancel all child sessions */
461 if (r)
462 {
463 #ifdef _PREFAST_
464 #pragma prefast(push)
|
465 krisbash 1.3 #pragma prefast(disable:26015)
|
466 krisbash 1.1 #endif
467 while (outstandingSessionsCount)
468 {
469 MI_Session *session = (MI_Session*)&outstandingSessions[outstandingSessionsCount-1].clientHandle;
|
470 krisbash 1.3
|
471 krisbash 1.1 trace_MIClient_AppCloseCancelingAll(application, applicationObject, outstandingSessions[outstandingSessionsCount-1].debugHandlePointer);
472
473 /* Mode to next one as cancel may cause current operation to get deleted */
474 outstandingSessionsCount--;
475
476 Session_CancelAllOperations(session);
477 }
478 #ifdef _PREFAST_
479 #pragma prefast(pop)
480 #endif
481 }
482 if (outstandingSessions != _smallBuffer)
483 {
484 PAL_Free(outstandingSessions);
485 }
486
487 ChildList_RegisterShutdownCallback(&applicationObject->sessionList, Application_AllSessionsShutdown, applicationObject);
488 }
489 }
490
491
492 krisbash 1.1 /* Wait for child sessions to shut down */
493 {
494 ptrdiff_t curChildCount = applicationObject->sessionList.childCount;
495 while (curChildCount)
496 {
497 trace_MIClient_AppCloseWaitingOnSessions(application, applicationObject, curChildCount);
498 /* Wait for child session count to hit 0 */
499 CondLock_Wait((ptrdiff_t)applicationObject, &applicationObject->sessionList.childCount, curChildCount, CONDLOCK_DEFAULT_SPINCOUNT);
500 curChildCount = applicationObject->sessionList.childCount;
501 }
502 }
503
504 ChildList_RegisterShutdownCallback(&applicationObject->hostedProviderList, Application_AllHostedProvidersShutdown, applicationObject);
505 {
506 ptrdiff_t curChildCount = applicationObject->hostedProviderList.childCount;
507 while (curChildCount)
508 {
509 trace_MIClient_AppCloseWaitingOnHostedProviders(application, applicationObject, curChildCount);
510 /* Wait for child hosted provider count to hit 0 */
511 CondLock_Wait((ptrdiff_t)applicationObject, &applicationObject->hostedProviderList.childCount, curChildCount, CONDLOCK_DEFAULT_SPINCOUNT);
512 curChildCount = applicationObject->hostedProviderList.childCount;
513 krisbash 1.1 }
514 }
515
516 /* Deinitialize the handle free-list */
517 ThunkHandleManager_DeInitialize(&applicationObject->thunkManager);
518
519 /* Deinitialize cache manager. All operations are be finished by now */
520 ProtocolHandlerCache_DeInitialize(&applicationObject->protocolHandlerCache);
521
522 /* Free our copy of application ID */
523 PAL_Free(applicationObject->applicationID);
524
525 ChildList_DeInitialize(&applicationObject->sessionList);
526 ChildList_DeInitialize(&applicationObject->hostedProviderList);
527
528
529 /* Delete the real application handle */
530 _aligned_free(applicationObject);
531
532 trace_MIClient_AppCloseCompleted(application, applicationObject);
533
534 krisbash 1.1 #if defined(OILOGSYSTEM_FILE)
535 //TODO: Refactor MI logging as a file can get tramped if someone is using an MI app and then closes after someone else has open a different MI App
536 // For now we just remove closing of the log as that doesnt have any effect (logs are flushed on every trace)
|
537 krisbash 1.2 Log_Close();
|
538 krisbash 1.1 #endif
539
540 return MI_RESULT_OK;
541 }
542
543 _Success_(return == MI_RESULT_OK)
544 MI_Result MI_CALL Application_NewPropertySet(
545 _In_ MI_Application *application,
546 _Out_ MI_PropertySet **propertySet)
547 {
548 if ((application == NULL) || (propertySet == NULL))
549 {
550 return MI_RESULT_INVALID_PARAMETER;
551 }
552 #if 0
553 return PropertySet_New(propertySet);
554 #endif
555 return MI_RESULT_NOT_SUPPORTED;
556 }
557 /* MI_Application_NewInstance implementation */
558 _Success_(return == MI_RESULT_OK)
559 krisbash 1.1 MI_Result MI_CALL Application_NewInstance(
560 _In_ MI_Application *application,
561 _In_opt_z_ const MI_Char * className,
562 _In_opt_ const MI_ClassDecl *classRTTI,
563 _Out_ MI_Instance **instance)
564 {
565 if ((application == NULL) || (instance == NULL))
566 {
567 return MI_RESULT_INVALID_PARAMETER;
568 }
569 if (classRTTI)
570 {
571 return Instance_New(instance, classRTTI, NULL);
572 }
573 else
574 {
575 return Instance_NewDynamic(
576 instance,
577 className,
578 MI_FLAG_CLASS /* TODO: API UPDATE... May be association/indication/etc */,
579 NULL
580 krisbash 1.1 );
581 }
582 }
583
584 _Success_(return == MI_RESULT_OK)
585 MI_Result MI_CALL Application_NewInstanceFromClass(
586 _In_ MI_Application *application,
587 _In_opt_z_ const MI_Char * className,
588 _In_opt_ const MI_Class *classObject,
589 _Out_ MI_Instance **instance)
590 {
591 const MI_ClassDecl *classDecl = NULL;
592 if (classObject)
593 classDecl = classObject->classDecl;
594
595 return Application_NewInstance(application, className, classDecl, instance);
596 }
597
598 _Success_(return == MI_RESULT_OK)
599 MI_Result MI_CALL Application_NewSession(
|
600 krisbash 1.3 _In_ MI_Application *application,
|
601 krisbash 1.1 _In_opt_z_ const MI_Char *protocol,
602 _In_opt_z_ const MI_Char *destination,
603 _In_opt_ MI_DestinationOptions *options,
604 _In_opt_ MI_SessionCallbacks *callbacks,
605 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
606 _Out_ MI_Session *session)
607 {
608 MI_Result result = MI_RESULT_INVALID_PARAMETER;
609 ApplicationObject *applicationObject;
|
610 krisbash 1.3
|
611 krisbash 1.1 trace_MIApplicationEnter(__FUNCTION__, application, protocol, destination, session);
612
|
613 krisbash 1.3 if ((application == NULL) || (application->ft == NULL) ||
|
614 krisbash 1.1 (application->reserved2 == 0) || (application->reserved1 != 1))
615 {
616 /* Probably already deleted or failed to initialize */
617 trace_MILeaveSession(__FUNCTION__, session);
618 return MI_RESULT_INVALID_PARAMETER;
619 }
620
621 if (extendedError)
622 *extendedError = NULL;
623
624 applicationObject = (ApplicationObject*) application->reserved2;
625
626 if (Application_AddRef(applicationObject))
627 {
628 result = Session_Create(application, protocol,destination,options,callbacks,extendedError,session);
629
630 Application_Release(applicationObject);
631 }
632
633 trace_MILeavingSession(__FUNCTION__, session);
634 return result;
635 krisbash 1.1 }
636
637 _Success_(return == MI_RESULT_OK)
638 MI_Result MI_CALL Application_NewHostedProvider(
639 _In_ MI_Application *application,
640 _In_z_ const MI_Char * namespaceName,
641 _In_z_ const MI_Char * providerName,
642 _In_ MI_MainFunction mi_Main,
643 _Outptr_opt_result_maybenull_ MI_Instance **extendedError,
644 _Out_ MI_HostedProvider *hostedProvider)
645 {
|
646 krisbash 1.3 if ((application == NULL) || (application->ft == NULL) ||
|
647 krisbash 1.1 (application->reserved2 == 0) || (application->reserved1 != 1))
648 {
649 /* Probably already deleted or failed to initialize */
650 return MI_RESULT_INVALID_PARAMETER;
651 }
652
653 return HostedProvider_Create(application, namespaceName, providerName, mi_Main, extendedError, hostedProvider);
654 }
655
|
656 krisbash 1.3 /* Used by test infrastructure to set a default protocol handler
|
657 krisbash 1.1 */
658 _Success_(return == MI_RESULT_OK)
659 MI_EXTERN_C MI_Result Application_SetTestTransport(
|
660 krisbash 1.3 _Inout_ MI_Application *clientMiApplication,
|
661 krisbash 1.1 _In_z_ const char *protocolHandlerName,
662 _In_z_ const char *protocolHandlerDLL,
663 _In_z_ const char *protocolHandlerDllEntryPoint,
664 MI_Uint32 protocolHandlerMajorVersion,
665 MI_Uint32 protocolHandlerMinorVersion,
666 MI_Boolean overrideDefaultLocalTransport,
667 MI_Boolean overrideDefaultRemoteTransport)
668 {
669 ApplicationObject *applicationObject = (ApplicationObject*) clientMiApplication->reserved2;
670 ProtocolHandlerCacheItem *cacheItem = NULL;
671 MI_Result miResult;
672
673 /* Set test handler */
674 miResult = ProtocolHandlerCache_InsertProtocolEntries(&applicationObject->protocolHandlerCache, protocolHandlerName, protocolHandlerDLL, protocolHandlerDllEntryPoint, protocolHandlerMajorVersion, protocolHandlerMinorVersion, &cacheItem);
675 if (miResult == MI_RESULT_OK)
676 {
677 if (overrideDefaultLocalTransport)
678 applicationObject->protocolHandlerCache.defaultLocalItem = cacheItem;
679 if (overrideDefaultRemoteTransport)
680 applicationObject->protocolHandlerCache.defaultRemoteItem = cacheItem;
681 }
682 krisbash 1.1 return miResult;
683 }
684
685 /* PUBLIC: Application_GetProtocolHandler
686 * Retrieve the MI_Application of a protocol handler. If protocol handler
687 * is not loaded this function will load it.
688 * It is not valid to have destination and protocolHandler NULL. It needs
689 * one to determine which handler to use.
690 *
691 * application - top-level application that the handler is attached to
692 * destination - For local this should be NULL or empty string. If protocol
|
693 krisbash 1.3 * handler is NULL it will pick the default for local/remote
|
694 krisbash 1.1 * destination.
695 * protocolHandler - If specified is the protocol handler string.
696 * protocolHnadlerApplication - MI_Application for the protocll handler
697 * exposing the function table to the handler.
698 *
699 * Return code: MI_Result code
700 */
701 _Success_(return == MI_RESULT_OK)
702 MI_Result Application_GetProtocolHandler(
|
703 krisbash 1.3 _In_ MI_Application *application,
704 _In_opt_z_ const MI_Char *destination,
705 _In_opt_z_ const MI_Char *protocolHandler,
|
706 krisbash 1.1 _Outptr_ ProtocolHandlerCacheItem **protocolHandlerItem)
707 {
708 ApplicationObject *applicationObject = (ApplicationObject*) application->reserved2;
709
710 if (protocolHandler == NULL)
711 {
712 if (destination == NULL)
713 {
714 if (applicationObject->protocolHandlerCache.defaultLocalItem)
715 protocolHandler = applicationObject->protocolHandlerCache.defaultLocalItem->name;
716 else
717 protocolHandler = MI_T("OMI_SOCKETS");
718 }
719 else
720 {
721 if (applicationObject->protocolHandlerCache.defaultRemoteItem)
722 protocolHandler = applicationObject->protocolHandlerCache.defaultRemoteItem->name;
723 else
724 protocolHandler = MI_T("MI_REMOTE_WSMAN");
725 }
726 }
727 krisbash 1.1
728 /* Load protocol handler */
729 return ProtocolHandlerCache_GetProtocolHandler(&applicationObject->protocolHandlerCache, protocolHandler, protocolHandlerItem);
730 }
731
732 MI_ErrorCategory MI_CALL Utilities_MapErrorToMiErrorCategory(_In_z_ const MI_Char *errorType, MI_Uint32 error)
733 {
734 return ErrorCategoryFromErrorCode(error, errorType);
735 }
736
737 _Success_(return == MI_RESULT_OK)
|
738 krisbash 1.3 MI_Result MI_CALL Utilities_CimErrorFromErrorCode(MI_Uint32 errorCode,_In_z_ const MI_Char *errorType,
|
739 krisbash 1.1 _In_z_ const MI_Char* errorMessage, _Outptr_opt_result_maybenull_ MI_Instance **cimError)
740 {
741 return OMI_ErrorFromErrorCode(NULL, errorCode, errorType, errorMessage, (OMI_Error**)cimError);
742 }
743
744
|
745 krisbash 1.3 const MI_ApplicationFT g_applicationFT = {
746 Application_Close,
747 Application_NewSession,
|
748 krisbash 1.1 Application_NewHostedProvider,
749 Application_NewInstance,
750 DestinationOptions_Create,
751 OperationOptions_Create,
752 SubscriptionDeliveryOptions_Create,
753 NULL, /* XmlSerializer_Create */
754 NULL, /* XmlDeserializer_Create */
755 Application_NewInstanceFromClass
756 };
757
758 /* Out of memory version of table */
|
759 krisbash 1.3 const MI_ApplicationFT g_applicationFT_OOM = {
760 Application_Close,
761 NULL,
|
762 krisbash 1.1 NULL,
763 NULL,
764 NULL,
765 NULL
766 };
767
768
769 const MI_SessionFT _sessionFT =
770 {
771 Session_Close,
772 Session_GetApplication,
773 Operation_Execute_GetInstance,
774 Operation_Execute_ModifyInstance,
775 Operation_Execute_CreateInstance,
776 Operation_Execute_DeleteInstance,
777 Operation_Execute_Invoke,
778 Operation_Execute_EnumerateInstances,
779 Operation_Execute_QueryInstances,
780 Operation_Execute_AssociatorInstances,
781 Operation_Execute_ReferenceInstances,
782 Operation_Execute_Subscribe,
783 krisbash 1.1 Operation_Execute_GetClass,
784 Operation_Execute_EnumerateClasses
785 };
786
787 const MI_OperationFT _operationFT =
788 {
789 Operation_Close,
790 Operation_Cancel,
791 Operation_GetParentSession,
792 Operation_GetInstance_Result,
793 Operation_GetIndication_Result,
794 Operation_GetClass_Result
795 };
796
797 const MI_HostedProviderFT _hostedProviderFT =
798 {
|
799 krisbash 1.3 HostedProvider_Close,
800 HostedProvider_GetApplication
|
801 krisbash 1.1 };
802
803 MI_SerializerFT _serializerFT =
804 {
805 NULL
806 #if 0
807 XmlSerializer_Close,
808 XmlSerializer_SerializeClass,
809 XmlSerializer_SerializeInstance
810 #endif
811 };
812
813 const MI_DeserializerFT _deserializerFT =
814 {
815 NULL
816 #if 0
817 XmlDeserializer_Close,
818 XmlDeserializer_DeserializeClass,
819 XmlDeserializer_Class_GetClassName,
820 XmlDeserializer_Class_GetParentClassName,
821 XmlDeserializer_DeserializeInstance,
822 krisbash 1.1 XmlDeserializer_Instance_GetClassName
823 #endif
824 };
825
826 const MI_UtilitiesFT _utilitiesFT =
827 {
828 Utilities_MapErrorToMiErrorCategory,
829 Utilities_CimErrorFromErrorCode
830 } ;
831
832 const MI_ClientFT_V1 _v1_Functions =
833 {
834 &g_applicationFT,
835 &_sessionFT,
836 &_operationFT,
837 &_hostedProviderFT,
838 &_serializerFT,
839 &_deserializerFT,
840 &g_subscriptionDeliveryOptionsFT,
841 &g_destinationOptionsFT,
842 &g_operationOptionsFT,
843 krisbash 1.1 &_utilitiesFT
844 };
845
846 #if defined (_MSC_VER)
847 const MI_ClientFT_V1 *_mi_clientFT_V1 = &_v1_Functions;
848 #else
849 MI_EXPORT const MI_ClientFT_V1 *mi_clientFT_V1 = &_v1_Functions;
850 #endif
|