(file) Return to Application.c CVS log (file) (dir) Up to [OMI] / omi / miapi

  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

ViewCVS 0.9.2