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

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include <base/strings.h>
  26           #include <base/messages.h>
  27           #include <base/log.h>
  28           #include <base/strings.h>
  29           #include <base/paths.h>
  30           #include <base/io.h>
  31 mike  1.2 #include <base/hashtable.h>
  32 mike  1.1 #include <wql/wql.h>
  33           #include "disp.h"
  34           
  35           #define T MI_T
  36           
  37           /*
  38           **==============================================================================
  39           **
  40 mike  1.2 ** ClassName hash implementation
  41           **
  42           **==============================================================================
  43           */
  44           
  45           typedef struct _ClassNameBucket /* derives from HashBucket */
  46           {
  47               struct _ClassNameBucket* next;
  48               char* key;
  49           }
  50           ClassNameBucket;
  51           
  52           static size_t ClassNameHash(
  53               const HashBucket* bucket_)
  54           {
  55               /* Note: this algorithm has a poor distribution */
  56               ClassNameBucket* bucket = (ClassNameBucket*)bucket_;
  57               size_t h = 0;
  58               char* key = bucket->key;
  59           
  60               while (*key)
  61 mike  1.2     {
  62                   h += 5 * *key++;
  63               }
  64           
  65               return h;
  66           }
  67           
  68           static int ClassNameEqual(
  69               const HashBucket* bucket1_,
  70               const HashBucket* bucket2_)
  71           {
  72               ClassNameBucket* bucket1 = (ClassNameBucket*)bucket1_;
  73               ClassNameBucket* bucket2 = (ClassNameBucket*)bucket2_;
  74               return Strcasecmp(bucket1->key, bucket2->key) == 0;
  75           }
  76           
  77           static void ClassNameRelease(
  78               HashBucket* bucket_)
  79           {
  80               ClassNameBucket* bucket = (ClassNameBucket*)bucket_;
  81           
  82 mike  1.2     free(bucket->key);
  83               free(bucket);
  84           }
  85           
  86           /*
  87           **==============================================================================
  88           **
  89 mike  1.1 ** Data structures
  90           **
  91           **==============================================================================
  92           */
  93           
  94           /*
  95               subscription item - represents single subscription;
  96           */
  97           typedef struct _DispSubscriptionItem
  98           {
  99               struct _DispSubscriptionItem* next;
 100               struct _DispSubscriptionItem* prev;
 101           
 102               /* The batch this context was allocated from */
 103               Batch batch;
 104           
 105               /* filter */
 106               MI_ConstString  filter;
 107               MI_ConstString  language;
 108           
 109               /* unique id of the sub */
 110 mike  1.1     MI_Uint64       subscriptionID;
 111           
 112               /* Client identifier if supported */
 113               MI_Uint64 clientID;
 114           
 115           }
 116           DispSubscriptionItem;
 117           
 118           
 119           /* subscriptions context -
 120               used to track indicaiton providers
 121               and store indications for 'pull' operation
 122               one context per ns/cn pair
 123           */
 124           typedef struct _DispIndicationContext
 125           {
 126               struct _DispIndicationContext* next;
 127               struct _DispIndicationContext* prev;
 128           
 129               /* The batch this context was allocated from */
 130               Batch batch;
 131 mike  1.1 
 132               /* namespace/cn */
 133               MI_ConstString  nameSpace;
 134               MI_ConstString  className;
 135           
 136               /* unique id of the context (used by ProvMgr) */
 137               MI_Uint64       ctxID;
 138           
 139               /* provider info */
 140               const ProvRegEntry* provEntry;
 141           
 142               /* exisitng subscriptions */
 143               DispSubscriptionItem* headSubscriptions;
 144               DispSubscriptionItem* tailSubscriptions;
 145           }
 146           DispIndicationContext;
 147           
 148           
 149           /*
 150           **==============================================================================
 151           **
 152 mike  1.1 ** Local definitions
 153           **
 154           **==============================================================================
 155           */
 156           static MI_Result _SendErrorResponse(
 157               Message* req,
 158               MI_Result r);
 159           
 160           static DispIndicationContext* _FindIndCtxByNScn(
 161               Disp* self,
 162               MI_ConstString  nameSpace,
 163               MI_ConstString  className)
 164           {
 165               DispIndicationContext* current = (DispIndicationContext*)self->headIndCtx;
 166           
 167               while (current)
 168               {
 169                   if (0 == Zcasecmp(nameSpace, current->nameSpace) &&
 170                       0 == Zcasecmp(className, current->className))
 171                       break;
 172           
 173 mike  1.1         current = current->next;
 174               }
 175               return current;
 176           }
 177           
 178           static DispIndicationContext* _FindIndCtxByID(
 179               Disp* self,
 180               MI_Uint64 id)
 181           {
 182               DispIndicationContext* current = (DispIndicationContext*)self->headIndCtx;
 183           
 184               while (current)
 185               {
 186                   if (id == current->ctxID)
 187                       break;
 188           
 189                   current = current->next;
 190               }
 191               return current;
 192           }
 193           
 194 mike  1.1 static DispSubscriptionItem* _FindSubscriptionItem(
 195               DispIndicationContext* ctx,
 196               MI_Uint64 subscriptionID)
 197           {
 198               DispSubscriptionItem* item = ctx->headSubscriptions;
 199           
 200               while (item)
 201               {
 202                   if (item->subscriptionID == subscriptionID)
 203                       break;
 204           
 205                   item = item->next;
 206               }
 207               return item;
 208           }
 209           
 210           
 211           static void _DestroySubscriptionItem(
 212               DispSubscriptionItem* item)
 213           {
 214               Batch_Destroy(&item->batch);
 215 mike  1.1 }
 216           static void _DestroyIndCtx(
 217               DispIndicationContext* ctx)
 218           {
 219               DispSubscriptionItem* item = ctx->headSubscriptions;
 220           
 221               while (item)
 222               {
 223                   DispSubscriptionItem* next = item->next;
 224           
 225                   _DestroySubscriptionItem(item);
 226                   item = next;
 227               }
 228               Batch_Destroy(&ctx->batch);
 229           }
 230           
 231           
 232           static MI_Result _FindCreateIndCtx(
 233               Disp* self,
 234               SubscribeReq* req,
 235               ProvRegEntry const** reg)
 236 mike  1.1 {
 237               /* look for exisiting first */
 238               DispIndicationContext* ctx = _FindIndCtxByNScn( self, req->nameSpace, req->className );
 239           
 240               if (!ctx)
 241               {
 242                   Batch batch = BATCH_INITIALIZER;
 243           
 244                   /* Allocate heap space for message */
 245                   ctx = (DispIndicationContext*) Batch_GetClear(&batch, sizeof(DispIndicationContext) );
 246           
 247                   if (!ctx)
 248                       return MI_RESULT_FAILED;
 249           
 250                   /* Copy batch into context (released by _Destroy method) */
 251                   memcpy(&ctx->batch, &batch, sizeof(batch));
 252           
 253                   ctx->className = Batch_Zdup(&batch, req->className);
 254                   ctx->nameSpace = Batch_Zdup(&batch, req->nameSpace);
 255           
 256                   if (!ctx->className || !ctx->nameSpace)
 257 mike  1.1         {
 258                       _DestroyIndCtx(ctx);
 259                       return MI_RESULT_FAILED;
 260                   }
 261                   ctx->ctxID = ++self->nextID;
 262           
 263                   /* Look for provider info */
 264                   ctx->provEntry = ProvReg_FindProviderForClass(&self->provreg, 
 265                       req->nameSpace, req->className);
 266           
 267                   if (!ctx->provEntry)
 268                   {
 269                       _DestroyIndCtx(ctx);
 270                       return MI_RESULT_INVALID_NAMESPACE;
 271                   }
 272           
 273                   /* add context to the list */
 274                   List_Append(&self->headIndCtx, &self->tailIndCtx, (ListElem*)ctx);
 275               }
 276           
 277               /* Update request with correct IDs */
 278 mike  1.1     req->ctxID = ctx->ctxID;
 279               req->subscriptionID = ++self->nextID;
 280           
 281               /* Set out parameter */
 282               *reg = ctx->provEntry;
 283           
 284               return MI_RESULT_OK;
 285           }
 286           
 287           static MI_Result _UpdateIndicationCtxWithSub(
 288               Disp* self,
 289               SubscribeReq* dispReq)
 290           {
 291               DispIndicationContext* ctx;
 292               DispSubscriptionItem* subItem;
 293           
 294               ctx = _FindIndCtxByID( self, dispReq->ctxID );
 295           
 296               /* unlikely, but it can be removed by other operation */
 297               if (!ctx)
 298                   return MI_RESULT_FAILED;
 299 mike  1.1 
 300               /* */
 301               subItem = _FindSubscriptionItem(ctx, dispReq->subscriptionID);
 302           
 303               if (subItem)
 304                   return MI_RESULT_ALREADY_EXISTS;
 305           
 306               {
 307                   Batch batch = BATCH_INITIALIZER;
 308           
 309                   /* Allocate heap space for message */
 310                   subItem = (DispSubscriptionItem*) Batch_GetClear(&batch, sizeof(DispSubscriptionItem) );
 311           
 312                   if (!subItem)
 313                       return MI_RESULT_FAILED;
 314           
 315                   /* Copy batch into context (released by _Destroy method) */
 316                   memcpy(&subItem->batch, &batch, sizeof(batch));
 317           
 318                   subItem->filter = Batch_Zdup(&batch, dispReq->filter);
 319                   subItem->language = Batch_Zdup(&batch, dispReq->language);
 320 mike  1.1 
 321                   if (!subItem->filter || !subItem->language)
 322                   {
 323                       _DestroySubscriptionItem(subItem);
 324                       return MI_RESULT_FAILED;
 325                   }
 326                   subItem->subscriptionID = dispReq->subscriptionID;
 327                   subItem->clientID = dispReq->base.request->clientID;
 328           
 329                   /* add item to the context */
 330                   List_Append(
 331                       (ListElem**)&ctx->headSubscriptions, 
 332                       (ListElem**)&ctx->tailSubscriptions, 
 333                       (ListElem*)subItem);
 334               }
 335               
 336               return MI_RESULT_OK;
 337           }
 338           
 339           static void _ProcessSubscribeResponse(
 340               Disp* self,
 341 mike  1.1     PostResultMsg* rsp)
 342           {
 343               MI_Result r;
 344               SubscribeReq* dispReq = (SubscribeReq*)rsp->base.request;
 345           
 346           
 347               /* Find context, create subscription struct */
 348               Mutex_Lock(&self->mt);
 349           
 350               r = _UpdateIndicationCtxWithSub( self, dispReq );
 351           
 352               Mutex_Unlock(&self->mt);
 353           
 354               /* check if error was detected */
 355               if (MI_RESULT_OK != r)
 356               {
 357                   _SendErrorResponse(rsp->base.request->request, r);
 358               }
 359           
 360               /* send subscription response */
 361               {
 362 mike  1.1         SubscribeRes* resp;
 363                   char s[50];
 364           
 365                   resp = SubscribeRes_New( rsp->base.request->request->msgID );
 366           
 367                   if (!resp)
 368                       return ;
 369           
 370                   Snprintf(s, MI_COUNT(s), UINT64_FMT "," UINT64_FMT, 
 371                       dispReq->ctxID,
 372                       dispReq->subscriptionID);
 373           
 374                   resp->subscriptionID = Batch_Strdup2(resp->base.batch, s);
 375           
 376                   Message_SetRequest(&resp->base,rsp->base.request->request);
 377                   (*rsp->base.request->request->callback)(&resp->base, rsp->base.request->request->callbackData);
 378           
 379                   SubscribeRes_Release(resp);
 380               }
 381           
 382           }
 383 mike  1.1 
 384           static void _ProviderToDispatcherCallback(
 385               Message* msg, 
 386               void* callbackData)
 387           {
 388               switch ( msg->tag )
 389               {
 390                   case PostResultMsgTag:
 391                   {
 392                       PostResultMsg* rsp = (PostResultMsg*)msg;
 393           
 394                       if (msg->request && msg->request->request &&  msg->request->request->tag == DispResultMsgTag)
 395                       {
 396                           DispResultMsg* dispStateMsg = (DispResultMsg*)msg->request->request;
 397           
 398                           if (rsp->result != MI_RESULT_OK && dispStateMsg->result == MI_RESULT_OK)
 399                           {
 400                               dispStateMsg->result = rsp->result;
 401                           }
 402           
 403                           if ( AtomicDec(&dispStateMsg->requestCounter) )
 404 mike  1.1                 {   /* last result - forward it to the net stack */
 405                               rsp->result = dispStateMsg->result;
 406                           }
 407                           else    /* not the last result - skip it */
 408                               return;
 409           
 410                       }
 411                       else if (msg->request && msg->request->tag == SubscribeReqTag)
 412                       {
 413                           /* process subscription response */
 414                           if (MI_RESULT_OK != rsp->result )
 415                               break;
 416           
 417                           /* 
 418                               validate parameter msg->request->request is a parameter received from network transport;
 419                               msg->request is a message created by disp for provmgr
 420                           */
 421                           if (msg->request->request)
 422                           {
 423                               _ProcessSubscribeResponse((Disp*)callbackData, rsp);
 424                               return;
 425 mike  1.1                 }
 426                       }
 427                   }
 428                   break;
 429           
 430                   default:
 431                       break;
 432               }
 433           
 434               /* forward message to the other side */
 435               if (msg->request && msg->request->request)
 436               {
 437                   /* delegate message to protocol stack */
 438                   msg->clientID = msg->request->request->clientID;
 439                   (*msg->request->request->callback)(msg, msg->request->request->callbackData);
 440               } 
 441               else if (msg->request)
 442               {
 443                   /* delegate message to protocol stack */
 444                   msg->clientID = msg->request->clientID;
 445                   (*msg->request->callback)(msg, msg->request->callbackData);
 446 mike  1.1     } 
 447               else 
 448               {
 449                   (*msg->callback)(msg, msg->callbackData);
 450               }
 451           }
 452           
 453           static MI_Boolean _DispatchEnumerateInstancesReq(
 454               Disp* self,
 455               const MI_Char* className, 
 456               const EnumerateInstancesReq* req,
 457               DispResultMsg* dispStateMsg)
 458           {
 459               const ProvRegEntry* entry;
 460               EnumerateInstancesReq* msg;
 461               MI_Result r;
 462           
 463               /* Attempt to find a provider for this class */
 464               {
 465                   entry = ProvReg_FindProviderForClass(&self->provreg, 
 466                       req->nameSpace, className);
 467 mike  1.1 
 468                   if (!entry)
 469                       return MI_FALSE;
 470               }
 471           
 472               /* Create new request to send to provider */
 473               msg = EnumerateInstancesReq_New(req->base.msgID, req->base.flags);
 474               msg->base.clientID = req->base.clientID;
 475               msg->base.uid = req->base.uid;
 476               msg->base.gid = req->base.gid;
 477               msg->nameSpace = Batch_Zdup(msg->base.batch, req->nameSpace);
 478               msg->className = Batch_Zdup(msg->base.batch, className);
 479           
 480               /* Clone the query fields (if any) */
 481               if (req->queryLanguage)
 482                   msg->queryLanguage = Batch_Zdup(msg->base.batch, req->queryLanguage);
 483           
 484               if (req->queryExpression)
 485                   msg->queryExpression = Batch_Zdup(msg->base.batch,req->queryExpression);
 486           
 487               if (req->wql)
 488 mike  1.1         msg->wql = WQL_Clone(req->wql, msg->base.batch);
 489           
 490               /* Save request's class name to allow porvmgr pack back only base properties */
 491               if (req->basePropertiesOnly)
 492                   msg->requestClassName = Batch_Zdup(msg->base.batch, req->className);
 493           
 494               AtomicInc(&dispStateMsg->requestCounter);
 495               Message_SetRequest(&msg->base, &dispStateMsg->base);
 496           
 497               /* Setup callback */
 498               msg->base.callback = _ProviderToDispatcherCallback;
 499               msg->base.callbackData = self;
 500           
 501               /* Send the request to provider manager */
 502               r = AgentMgr_HandleRequest(&self->agentmgr, &msg->base, entry);
 503           
 504               /* Release the original message */
 505               EnumerateInstancesReq_Release(msg);
 506           
 507               /* Log failure */
 508               if (r != MI_RESULT_OK)
 509 mike  1.1     {
 510                   LOGW((T("AgentMgr_HandleRequest() failed: %u: %s"), r, 
 511                       Result_ToString(r)));
 512                   
 513                   AtomicDec(&dispStateMsg->requestCounter);
 514                   return MI_FALSE;
 515               }
 516           
 517           
 518               return MI_TRUE;
 519           }
 520           
 521           static MI_Boolean _DispatchAssocReq(
 522               Disp* self,
 523               const MI_Char* className, 
 524               const AssociatorsOfReq* req,
 525               DispResultMsg* dispStateMsg)
 526           {
 527               const ProvRegEntry* entry;
 528               AssociatorsOfReq* msg;
 529               MI_Result r;
 530 mike  1.2 
 531 mike  1.1     /* Attempt to find a provider for this class */
 532               {
 533                   entry = ProvReg_FindProviderForClass(&self->provreg, 
 534                       req->nameSpace, className);
 535           
 536                   if (!entry)
 537                       return MI_FALSE;
 538               }
 539           
 540               /* Create new request to send to provider */
 541               msg = AssociatorsOfReq_New(req->base.msgID, req->base.flags);
 542               msg->base.clientID = req->base.clientID;
 543               msg->base.uid = req->base.uid;
 544               msg->base.gid = req->base.gid;
 545               /* original request will be kept for the request duration, so perform shallow copy only */
 546               /*ATTN! perform full copy*/
 547               msg->nameSpace = req->nameSpace;
 548               msg->assocClass = req->assocClass;
 549               msg->resultClass = req->resultClass;
 550               msg->role = req->role;
 551               msg->resultRole = req->resultRole;
 552 mike  1.1     msg->instance = req->instance;
 553               msg->packedInstancePtr = req->packedInstancePtr;
 554               msg->packedInstanceSize = req->packedInstanceSize;
 555           
 556               msg->className = className;
 557           
 558               AtomicInc(&dispStateMsg->requestCounter);
 559               Message_SetRequest(&msg->base, &dispStateMsg->base);
 560           
 561               /* Setup callback */
 562               msg->base.callback = _ProviderToDispatcherCallback;
 563               msg->base.callbackData = self;
 564           
 565               /* Send the request to provider manager */
 566               r = AgentMgr_HandleRequest(&self->agentmgr, &msg->base, entry);
 567           
 568               /* Release the original message */
 569               AssociatorsOfReq_Release(msg);
 570           
 571               /* Log failure */
 572               if (r != MI_RESULT_OK)
 573 mike  1.1     {
 574                   LOGW((T("AgentMgr_HandleRequest() failed: %u: %s"), r, 
 575                       Result_ToString(r)));
 576                   
 577                   AtomicDec(&dispStateMsg->requestCounter);
 578                   return MI_FALSE;
 579               }
 580           
 581               return MI_TRUE;
 582           }
 583           
 584           static MI_Boolean _DispatchRefReq(
 585               Disp* self,
 586               const MI_Char* className, 
 587               const ReferencesOfReq* req,
 588               DispResultMsg* dispStateMsg)
 589           {
 590               const ProvRegEntry* entry;
 591               ReferencesOfReq* msg;
 592               MI_Result r;
 593               
 594 mike  1.1     /* Attempt to find a provider for this class */
 595               {
 596                   entry = ProvReg_FindProviderForClass(&self->provreg, 
 597                       req->nameSpace, className);
 598           
 599                   if (!entry)
 600                       return MI_FALSE;
 601               }
 602           
 603               /* Create new request to send to provider */
 604               msg = ReferencesOfReq_New(req->base.msgID, req->base.flags);
 605               msg->base.clientID = req->base.clientID;
 606               msg->base.uid = req->base.uid;
 607               msg->base.gid = req->base.gid;
 608               /* original request will be kept for the request duration, so perform shallow copy only */
 609               /*ATTN! perform full copy*/
 610               msg->nameSpace = req->nameSpace;
 611               msg->assocClass = req->assocClass;
 612               msg->role = req->role;
 613               msg->instance = req->instance;
 614               msg->packedInstancePtr = req->packedInstancePtr;
 615 mike  1.1     msg->packedInstanceSize = req->packedInstanceSize;
 616           
 617               msg->className = className;
 618           
 619               AtomicInc(&dispStateMsg->requestCounter);
 620               Message_SetRequest(&msg->base, &dispStateMsg->base);
 621           
 622               /* Setup callback */
 623               msg->base.callback = _ProviderToDispatcherCallback;
 624               msg->base.callbackData = self;
 625           
 626               /* Send the request to provider manager */
 627               r = AgentMgr_HandleRequest(&self->agentmgr, &msg->base, entry);
 628           
 629               /* Release the original message */
 630               ReferencesOfReq_Release(msg);
 631           
 632               /* Log failure */
 633               if (r != MI_RESULT_OK)
 634               {
 635                   LOGW((T("AgentMgr_HandleRequest() failed: %u: %s"), r, 
 636 mike  1.1             Result_ToString(r)));
 637                   
 638                   AtomicDec(&dispStateMsg->requestCounter);
 639                   return MI_FALSE;
 640               }
 641           
 642               return MI_TRUE;
 643           }
 644           
 645           static MI_Result _SendErrorResponse(
 646               Message* req,
 647               MI_Result r
 648               )
 649           {
 650               PostResultMsg* resp;
 651           
 652               resp = PostResultMsg_New( req->msgID );
 653           
 654               if (!resp)
 655                   return MI_RESULT_FAILED;
 656           
 657 mike  1.1     resp->result = r;
 658               Message_SetRequest(&resp->base,req);
 659               (*req->callback)(&resp->base, req->callbackData);
 660           
 661               PostResultMsg_Release(resp);
 662           
 663               return MI_RESULT_OK;
 664           }
 665           
 666           static MI_Result _HandleEnumerateInstancesReq(
 667               Disp* self,
 668               EnumerateInstancesReq* req)
 669           {
 670               ProvRegPosition pos;
 671               MI_Result r;
 672               MI_Boolean sentOk = MI_FALSE;
 673               DispResultMsg* dispStateMsg;
 674           
 675               /* Validate input parameters */
 676               if (!req->className || !req->nameSpace)
 677                   return MI_RESULT_INVALID_PARAMETER;
 678 mike  1.1 
 679               /* create a state message that will keep track of results from providers */
 680               dispStateMsg = DispResultMsg_New(req->base.msgID);
 681               if (!dispStateMsg)
 682                   return MI_RESULT_FAILED;
 683           
 684               /* add one for sending thread so first 'fast' provider will not send its response all the way */
 685               AtomicInc(&dispStateMsg->requestCounter);
 686               
 687               dispStateMsg->base.clientID = req->base.clientID;
 688               /* Setup callback */
 689               dispStateMsg->base.callback = req->base.callback;
 690               dispStateMsg->base.callbackData = req->base.callbackData;
 691           
 692               /* Precompile the query */
 693               if (req->queryLanguage || req->queryExpression)
 694               {
 695                   /* Fail if either query language or expression is missing */
 696                   if (!req->queryLanguage || !req->queryExpression)
 697                   {
 698                       LOGW((T("queryLanguage or queryExpression is missing")));
 699 mike  1.1             r = MI_RESULT_INVALID_QUERY;
 700                       goto sendErrorBack;
 701                   }
 702           
 703                   /* Reject non-WQL queries */
 704                   if (Zcmp(req->queryLanguage, T("WQL")) != 0)
 705                   {
 706                       LOGW((T("unknown query language: %s"), req->queryLanguage));
 707                       r = MI_RESULT_QUERY_LANGUAGE_NOT_SUPPORTED;
 708                       goto sendErrorBack;
 709                   }
 710           
 711                   /* Compile the query */
 712                   {
 713                       req->wql = WQL_Parse(req->queryExpression, req->base.batch);
 714           
 715                       if (!req->wql)
 716                       {
 717                           LOGW((T("invalid query expression: %s"), req->queryExpression));
 718                           r = MI_RESULT_INVALID_QUERY;
 719                           goto sendErrorBack;
 720 mike  1.1             }
 721                   }
 722           
 723                   /* Verify that the query classname matches the enumeration classname */
 724                   if (Zcmp(req->wql->className, req->className) != 0)
 725                   {
 726                       LOGW((T("query/enumeration class name mismatch: %s/%s"), 
 727                           req->className, req->className));
 728                       r = MI_RESULT_INVALID_QUERY;
 729                       goto sendErrorBack;
 730                   }
 731               }
 732           
 733               /* Send to direct name */
 734               if (_DispatchEnumerateInstancesReq(self, req->className, req, dispStateMsg))
 735                   sentOk = MI_TRUE;
 736           
 737               if (req->deepInheritance)
 738               {
 739                   /* Begin enumeration of classes for this request */
 740                   {
 741 mike  1.1             r = ProvReg_BeginClasses(&self->provreg, req->nameSpace, 
 742                           req->className, MI_TRUE, &pos);
 743           
 744                       if (MI_RESULT_OK != r)
 745                       {
 746                           LOGD((T("ProvReg_BeginClasses() failed: %u: %s"), 
 747                               r, Result_ToString(r)));
 748           
 749                           LOGI((T("unknown class in enumerate request: %s:%s"), 
 750                               req->nameSpace, req->className));
 751           
 752                           /* send error back to caller */
 753                           goto sendErrorBack;
 754                       }
 755                   }
 756           
 757                   /* While more classes */
 758                   for (;;)
 759                   {
 760                       const MI_Char* derived = NULL;
 761                       MI_Boolean done;
 762 mike  1.1 
 763                       r = ProvReg_NextClass(&pos, &derived, &done);
 764           
 765                       if (done)
 766                           break;
 767           
 768                       if (MI_RESULT_OK != r)
 769                       {
 770                           LOGD((T("ProvReg_NextClass() failed: %u: %s"), 
 771                               r, Result_ToString(r)));
 772           
 773                           LOGI((T("unknown class in enumerate request: %s:%s"), 
 774                               req->nameSpace, req->className));
 775           
 776                           /* send error back to caller */
 777                           goto sendErrorBack;
 778                       }
 779           
 780                       if (_DispatchEnumerateInstancesReq(self, derived, req, dispStateMsg))
 781                           sentOk = MI_TRUE;
 782                   }
 783 mike  1.1 
 784                   /* Finalize enumeration */
 785                   {
 786                       r = ProvReg_EndClasses(&pos);
 787           
 788                       if (MI_RESULT_OK != r)
 789                       {
 790                           LOGD((T("ProvReg_EndClasses() failed: %u: %s"), 
 791                               r, Result_ToString(r)));
 792                           /* send error back to caller */
 793                           goto sendErrorBack;
 794                       }
 795                   }
 796               } /* if deep*/
 797           
 798               /* Fail if no provider was found for request */
 799               if (!sentOk)
 800               {
 801                   LOGD((T("found no providers for class: %s"), MI_GET_SAFE_PRINTF_STRING(req->className)));
 802                   r = MI_RESULT_NOT_FOUND;
 803                   goto sendErrorBack;
 804 mike  1.1     }
 805           
 806               if ( AtomicDec(&dispStateMsg->requestCounter) )
 807               {   /* last result - forward it to the net stack */
 808                   r = dispStateMsg->result;
 809                   goto sendErrorBack;
 810               }
 811           
 812               DispResultMsg_Release(dispStateMsg);
 813               return MI_RESULT_OK;
 814           
 815           sendErrorBack:
 816               DispResultMsg_Release(dispStateMsg);
 817               return _SendErrorResponse(&req->base,r);
 818           }
 819           
 820           
 821           static MI_Result _HandleGetInstanceReq(
 822               Disp* self,
 823               GetInstanceReq* req)
 824           {
 825 mike  1.1     MI_Result r;
 826               const ProvRegEntry* reg;
 827           
 828               /* Validate input parameters */
 829               if (!req->instanceName || !req->nameSpace)
 830                   return MI_RESULT_INVALID_PARAMETER;
 831           
 832               // Find a provider for this class.
 833               reg = ProvReg_FindProviderForClass(&self->provreg, req->nameSpace, 
 834                   req->instanceName->classDecl->name );
 835           
 836               if (!reg)
 837               {
 838                   r = MI_RESULT_INVALID_NAMESPACE; /*ATTN! or class?*/
 839                   LOGD((T("cannot find provider for class: %s/%s"), 
 840                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace), 
 841                       MI_GET_SAFE_PRINTF_STRING(req->instanceName->classDecl->name)));
 842                   goto sendErrorBack;
 843               }
 844           
 845               // Send the request to provider manager.
 846 mike  1.1     r = AgentMgr_HandleRequest(&self->agentmgr, &req->base, reg);
 847           
 848               if (r != MI_RESULT_OK)
 849               {
 850                   LOGD((T("AgentMgr_HandleRequest for namespace: %s"), 
 851                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace)));
 852                   goto sendErrorBack;
 853               }
 854           
 855               return MI_RESULT_OK;
 856           
 857           sendErrorBack:
 858               return _SendErrorResponse(&req->base,r);
 859           }
 860           
 861           static MI_Result _HandleCreateInstanceReq(
 862               Disp* self,
 863               CreateInstanceReq* req)
 864           {
 865               MI_Result r;
 866               const ProvRegEntry* reg;
 867 mike  1.1 
 868               /* Validate input parameters */
 869               if (!req->instance || !req->nameSpace)
 870                   return MI_RESULT_INVALID_PARAMETER;
 871           
 872               // Find a provider for this class.
 873               reg = ProvReg_FindProviderForClass(&self->provreg, req->nameSpace, 
 874                   req->instance->classDecl->name );
 875           
 876               if (!reg)
 877               {
 878                   r = MI_RESULT_INVALID_NAMESPACE; /*ATTN! or class?*/
 879                   LOGD((T("cannot find provider for class: %s/%s"), 
 880                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace), 
 881                       MI_GET_SAFE_PRINTF_STRING(req->instance->classDecl->name)));
 882                   goto sendErrorBack;
 883               }
 884           
 885               // Send the request to provider manager.
 886               r = AgentMgr_HandleRequest(&self->agentmgr, &req->base, reg);
 887           
 888 mike  1.1     if (r != MI_RESULT_OK)
 889               {
 890                   LOGD((T("AgentMgr_HandleRequest for namespace: %s"), 
 891                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace)));
 892                   goto sendErrorBack;
 893               }
 894           
 895               return MI_RESULT_OK;
 896           
 897           sendErrorBack:
 898               return _SendErrorResponse(&req->base,r);
 899           }
 900           
 901           static MI_Result _HandleModifyInstanceReq(
 902               Disp* self,
 903               ModifyInstanceReq* req)
 904           {
 905               MI_Result r;
 906               const ProvRegEntry* reg;
 907           
 908               /* Validate input parameters */
 909 mike  1.1     if (!req->instance || !req->nameSpace)
 910                   return MI_RESULT_INVALID_PARAMETER;
 911           
 912               // Find a provider for this class.
 913               reg = ProvReg_FindProviderForClass(&self->provreg, req->nameSpace, 
 914                   req->instance->classDecl->name );
 915           
 916               if (!reg)
 917               {
 918                   r = MI_RESULT_INVALID_NAMESPACE; /*ATTN! or class?*/
 919                   LOGD((T("cannot find provider for class: %s/%s"), 
 920                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace), 
 921                       MI_GET_SAFE_PRINTF_STRING(req->instance->classDecl->name)));
 922                   goto sendErrorBack;
 923               }
 924           
 925               // Send the request to provider manager.
 926               r = AgentMgr_HandleRequest(&self->agentmgr, &req->base, reg);
 927           
 928               if (r != MI_RESULT_OK)
 929               {
 930 mike  1.1         LOGD((T("AgentMgr_HandleRequest for namespace: %s"), 
 931                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace)));
 932                   goto sendErrorBack;
 933               }
 934           
 935               return MI_RESULT_OK;
 936           
 937           sendErrorBack:
 938               return _SendErrorResponse(&req->base,r);
 939           }
 940           
 941           static MI_Result _HandleDeleteInstanceReq(
 942               Disp* self,
 943               DeleteInstanceReq* req)
 944           {
 945               MI_Result r;
 946               const ProvRegEntry* reg;
 947           
 948               /* Validate input parameters */
 949               if (!req->instanceName || !req->nameSpace)
 950                   return MI_RESULT_INVALID_PARAMETER;
 951 mike  1.1 
 952               // Find a provider for this class.
 953               reg = ProvReg_FindProviderForClass(&self->provreg, req->nameSpace, 
 954                   req->instanceName->classDecl->name);
 955           
 956               if (!reg)
 957               {
 958                   r = MI_RESULT_INVALID_NAMESPACE; /*ATTN! or class?*/
 959                   LOGD((T("cannot find provider for class: %s/%s"), 
 960                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace), 
 961                       MI_GET_SAFE_PRINTF_STRING(req->instanceName->classDecl->name)));
 962                   goto sendErrorBack;
 963               }
 964           
 965               // Send the request to provider manager.
 966               r = AgentMgr_HandleRequest(&self->agentmgr, &req->base, reg);
 967           
 968               if (r != MI_RESULT_OK)
 969               {
 970                   LOGD((T("AgentMgr_HandleRequest for namespace: %s"), 
 971                       MI_GET_SAFE_PRINTF_STRING(req->nameSpace)));
 972 mike  1.1         goto sendErrorBack;
 973               }
 974           
 975               return MI_RESULT_OK;
 976           
 977           sendErrorBack:
 978               return _SendErrorResponse(&req->base,r);
 979           }
 980           
 981           static MI_Result _HandleSubscribeReq(
 982               Disp* self,
 983               SubscribeReq* req)
 984           {
 985               MI_Result r;
 986               const ProvRegEntry* reg = 0;
 987               SubscribeReq* msg = 0;
 988           
 989               /* Validate input parameters */
 990               if (!req->className || !req->nameSpace || !req->language || !req->filter)
 991                   return MI_RESULT_INVALID_PARAMETER;
 992           
 993 mike  1.1     // Duplicate incoming request to substitute callback pointer
 994               msg = SubscribeReq_New(req->base.msgID, req->base.flags);
 995           
 996               msg->base.uid = req->base.uid;
 997               msg->base.gid = req->base.gid;
 998               msg->nameSpace = Batch_Zdup(msg->base.batch, req->nameSpace);
 999               msg->className = Batch_Zdup(msg->base.batch, req->className);
1000               msg->filter = Batch_Zdup(msg->base.batch, req->filter);
1001               msg->language = Batch_Zdup(msg->base.batch, req->language);
1002           
1003               msg->base.clientID = req->base.clientID;
1004           
1005               Message_SetRequest(&msg->base, &req->base);
1006           
1007               /* Setup callback */
1008               msg->base.callback = _ProviderToDispatcherCallback;
1009               msg->base.callbackData = self;
1010           
1011               // Find a indication context by ns/cn
1012               Mutex_Lock(&self->mt);
1013           
1014 mike  1.1     r = _FindCreateIndCtx( self, msg, &reg );
1015           
1016               Mutex_Unlock(&self->mt);
1017           
1018               /* check if error was detected */
1019               if (MI_RESULT_OK != r)
1020                   goto sendErrorBack;
1021           
1022               /* empty reg with OK means context is being initialized;
1023                   sub command will be processed later, once EnableIndicaitons is processed */
1024               if (!reg)
1025                   return MI_RESULT_OK;
1026           
1027               // Send the request to provider manager.
1028               r = AgentMgr_HandleRequest(&self->agentmgr, &msg->base, reg);
1029           
1030               if (r != MI_RESULT_OK)
1031               {
1032                   LOGD((T("AgentMgr_HandleRequest for namespace: %s"), MI_GET_SAFE_PRINTF_STRING(req->nameSpace)));
1033                   goto sendErrorBack;
1034               }
1035 mike  1.1 
1036               if (msg)
1037                   SubscribeReq_Release(msg);
1038           
1039               return MI_RESULT_OK;
1040           
1041           sendErrorBack:
1042               if (msg)
1043                   SubscribeReq_Release(msg);
1044           
1045               return _SendErrorResponse(&req->base,r);
1046           }
1047           
1048           static MI_Result _HandleInvokeReq(
1049               Disp* self,
1050               InvokeReq* req)
1051           {
1052               MI_Result r;
1053               const ProvRegEntry* reg;
1054               MI_ConstString cn = 0;
1055           
1056 mike  1.1     /* Validate input parameters */
1057               if (!req->nameSpace)
1058                   return MI_RESULT_INVALID_PARAMETER;
1059           
1060               if (req->className)
1061                   cn = req->className;
1062               else if (req->instance)
1063                   cn = req->instance->classDecl->name;
1064           
1065               if (!cn)
1066               {
1067                   r = MI_RESULT_INVALID_CLASS;
1068                   LOGD((T("class name is expected for invoke\n")));
1069                   goto sendErrorBack;
1070               }
1071           
1072           
1073               // Find a provider for this class.
1074               reg = ProvReg_FindProviderForClass(&self->provreg, req->nameSpace, cn);
1075           
1076               if (!reg)
1077 mike  1.1     {
1078                   r = MI_RESULT_INVALID_NAMESPACE; /*ATTN! or class?*/
1079                   LOGD((T("cannot find provider for class: %s"), MI_GET_SAFE_PRINTF_STRING(cn)));
1080                   goto sendErrorBack;
1081               }
1082           
1083               // Send the request to provider manager.
1084               r = AgentMgr_HandleRequest(&self->agentmgr, &req->base, reg);
1085           
1086               if (r != MI_RESULT_OK)
1087               {
1088                   LOGD((T("AgentMgr_HandleRequest for namespace: %s"), MI_GET_SAFE_PRINTF_STRING(req->nameSpace)));
1089                   goto sendErrorBack;
1090               }
1091           
1092               return MI_RESULT_OK;
1093           
1094           sendErrorBack:
1095               return _SendErrorResponse(&req->base,r);
1096           }
1097           
1098 mike  1.1 
1099           static MI_Result _HandleAssociatorsOfReq(
1100               Disp* self,
1101               AssociatorsOfReq* req)
1102           {
1103               MI_Result r;
1104               MI_ConstString cn = 0;
1105               DispResultMsg* dispStateMsg;
1106               ProvRegAssocPosition pos;
1107               MI_Boolean sentOk = MI_FALSE;
1108 mike  1.2     HashTable classNames;
1109           
1110               /* Create a hash table of class names */
1111           
1112               r = HashTable_Init(
1113                   &classNames, 
1114                   64, 
1115                   ClassNameHash, 
1116                   ClassNameEqual, 
1117                   ClassNameRelease);
1118           
1119               if (r != 0)
1120                   return MI_RESULT_FAILED;
1121 mike  1.1 
1122               /* Validate input parameters */
1123               if (!req->instance || !req->nameSpace)
1124                   return MI_RESULT_INVALID_PARAMETER;
1125           
1126               /* create a state message that will keep track of results from providers */
1127               dispStateMsg = DispResultMsg_New(req->base.msgID);
1128               if (!dispStateMsg)
1129                   return MI_RESULT_FAILED;
1130           
1131               /* add one for sending thread so first 'fast' provider will not send its response all the way */
1132               AtomicInc(&dispStateMsg->requestCounter);
1133               
1134               dispStateMsg->base.clientID = req->base.clientID;
1135               /* Setup callback */
1136               dispStateMsg->base.callback = req->base.callback;
1137               dispStateMsg->base.callbackData = req->base.callbackData;
1138               Message_SetRequest(&dispStateMsg->base, &req->base);
1139           
1140               r = ProvReg_BeginAssocClasses(&self->provreg, req->nameSpace, 
1141                   req->instance->classDecl->name,
1142 mike  1.1         req->assocClass, req->resultClass, &pos);
1143           
1144               if (MI_RESULT_OK != r)
1145               {
1146                   LOGD((T("ProvReg_BeginAssocClasses() failed: %u: %s"), 
1147                       r, Result_ToString(r)));
1148           
1149                   /* send error back to caller */
1150                   goto sendErrorBack;
1151               }
1152           
1153 mike  1.2     /* ATTN: there is a bug in the provider registration tree causing
1154                * the association provider to be called twice. To avoid this for now,
1155                * we maintain a hash table of already dispatched classes.
1156                */
1157           
1158 mike  1.1     /* While more classes */
1159               for (;;)
1160               {
1161                   MI_Boolean done;
1162                   r = ProvReg_NextAssocClass(&pos, &cn, &done);
1163           
1164                   if (done)
1165                       break;
1166           
1167                   if (MI_RESULT_OK != r)
1168                   {
1169                       LOGD((T("ProvReg_NextAssocClass() failed: %u: %s"), 
1170                           r, Result_ToString(r)));
1171                       /* send error back to caller */
1172                       goto sendErrorBack;
1173                   }
1174           
1175 mike  1.2         /* Check whether this class has been dispatched */
1176                   {
1177                       ClassNameBucket bucket;
1178                       bucket.key = (char*)cn;
1179           
1180                       if (!HashTable_Find(&classNames, (const HashBucket*)&bucket))
1181                       {
1182                           if (_DispatchAssocReq(self, cn, req, dispStateMsg))
1183                               sentOk = MI_TRUE;
1184           
1185                           {
1186                               ClassNameBucket* bucket = (ClassNameBucket*)calloc(
1187                                   1, sizeof(ClassNameBucket));
1188           
1189                               if (!bucket)
1190                               {
1191                                   r = MI_RESULT_FAILED;
1192                                   goto sendErrorBack;
1193                               }
1194           
1195                               bucket->key = strdup(cn);
1196 mike  1.2 
1197                               if (HashTable_Insert(&classNames, (HashBucket*)bucket) != 0)
1198                               {
1199                                   r = MI_RESULT_FAILED;
1200                                   goto sendErrorBack;
1201                               }
1202                           }
1203                       }
1204                   }
1205 mike  1.1     }
1206           
1207               /* Finalize enumeration */
1208               {
1209                   r = ProvReg_EndAssocClasses(&pos);
1210           
1211                   if (MI_RESULT_OK != r)
1212                   {
1213                       LOGD((T("ProvReg_EndAssocClasses() failed: %u: %s"), 
1214                           r, Result_ToString(r)));
1215                       /* send error back to caller */
1216                       goto sendErrorBack;
1217                   }
1218               }
1219           
1220               /* Fail if no provider was found for request */
1221               if (!sentOk)
1222               {
1223                   LOGD((T("found no providers for class: %s"), req->instance->classDecl->name));
1224                   r = MI_RESULT_NOT_FOUND;
1225                   goto sendErrorBack;
1226 mike  1.1     }
1227           
1228               if ( AtomicDec(&dispStateMsg->requestCounter) )
1229               {   /* last result - forward it to the net stack */
1230                   r = dispStateMsg->result;
1231                   goto sendErrorBack;
1232               }
1233           
1234 mike  1.2     HashTable_Destroy(&classNames);
1235 mike  1.1     DispResultMsg_Release(dispStateMsg);
1236               return MI_RESULT_OK;
1237           
1238           sendErrorBack:
1239               DispResultMsg_Release(dispStateMsg);
1240 mike  1.2     HashTable_Destroy(&classNames);
1241 mike  1.1     return _SendErrorResponse(&req->base,r);
1242           }
1243           
1244           static MI_Result _HandleReferencesOfReq(
1245               Disp* self,
1246               ReferencesOfReq* req)
1247           {
1248               MI_Result r;
1249               MI_ConstString cn = 0;
1250               DispResultMsg* dispStateMsg;
1251               ProvRegAssocPosition pos;
1252               MI_Boolean sentOk = MI_FALSE;
1253           
1254               /* Validate input parameters */
1255               if (!req->instance || !req->nameSpace)
1256                   return MI_RESULT_INVALID_PARAMETER;
1257           
1258               /* create a state message that will keep track of results from providers */
1259               dispStateMsg = DispResultMsg_New(req->base.msgID);
1260               if (!dispStateMsg)
1261                   return MI_RESULT_FAILED;
1262 mike  1.1 
1263               /* add one for sending thread so first 'fast' provider will not send its response all the way */
1264               AtomicInc(&dispStateMsg->requestCounter);
1265               
1266               dispStateMsg->base.clientID = req->base.clientID;
1267               /* Setup callback */
1268               dispStateMsg->base.callback = req->base.callback;
1269               dispStateMsg->base.callbackData = req->base.callbackData;
1270               Message_SetRequest(&dispStateMsg->base, &req->base);
1271           
1272               r = ProvReg_BeginAssocClasses(&self->provreg, req->nameSpace, 
1273                   req->instance->classDecl->name,
1274                   req->assocClass, 0, &pos);
1275           
1276               if (MI_RESULT_OK != r)
1277               {
1278                   LOGD((T("ProvReg_BeginAssocClasses() failed: %u: %s"), 
1279                       r, Result_ToString(r)));
1280           
1281                   /* send error back to caller */
1282                   goto sendErrorBack;
1283 mike  1.1     }
1284           
1285               /* While more classes */
1286               for (;;)
1287               {
1288                   MI_Boolean done;
1289                   r = ProvReg_NextAssocClass(&pos, &cn, &done);
1290           
1291                   if (done)
1292                       break;
1293           
1294                   if (MI_RESULT_OK != r)
1295                   {
1296                       LOGD((T("ProvReg_NextAssocClass() failed: %u: %s"), 
1297                           r, Result_ToString(r)));
1298                       /* send error back to caller */
1299                       goto sendErrorBack;
1300                   }
1301           
1302                   if (_DispatchRefReq(self, cn, req, dispStateMsg))
1303                       sentOk = MI_TRUE;
1304 mike  1.1     }
1305           
1306               /* Finalize enumeration */
1307               {
1308                   r = ProvReg_EndAssocClasses(&pos);
1309           
1310                   if (MI_RESULT_OK != r)
1311                   {
1312                       LOGD((T("ProvReg_EndAssocClasses() failed: %u: %s"), 
1313                           r, Result_ToString(r)));
1314                       /* send error back to caller */
1315                       goto sendErrorBack;
1316                   }
1317               }
1318           
1319               /* Fail if no provider was found for request */
1320               if (!sentOk)
1321               {
1322                   LOGD((T("found no providers for class: %s"), req->instance->classDecl->name));
1323                   r = MI_RESULT_NOT_FOUND;
1324                   goto sendErrorBack;
1325 mike  1.1     }
1326           
1327               if ( AtomicDec(&dispStateMsg->requestCounter) )
1328               {   /* last result - forward it to the net stack */
1329                   r = dispStateMsg->result;
1330                   goto sendErrorBack;
1331               }
1332           
1333               DispResultMsg_Release(dispStateMsg);
1334               return MI_RESULT_OK;
1335           
1336           sendErrorBack:
1337               DispResultMsg_Release(dispStateMsg);
1338               return _SendErrorResponse(&req->base,r);
1339           }
1340           
1341           /*
1342           **==============================================================================
1343           **
1344           ** Public definitions
1345           **
1346 mike  1.1 **==============================================================================
1347           */
1348           
1349           MI_Result Disp_Init(Disp* self, Selector* selector)
1350           {
1351               /* Check parameters */
1352               if (!self)
1353                   return MI_RESULT_INVALID_PARAMETER;
1354           
1355               memset(self, 0, sizeof(Disp));
1356           
1357           #if 0
1358               /* Initialize the provider registry */
1359               MI_RETURN_ERR(ProvReg_Init(&self->provreg, GetPath(ID_REGISTERFILE)));
1360           #else
1361               MI_RETURN_ERR(ProvReg_Init2(&self->provreg));
1362           #endif
1363           
1364               /* Initialize the provider manager */
1365               MI_RETURN_ERR(AgentMgr_Init(&self->agentmgr, selector));
1366           
1367 mike  1.1     /* Initialize indications part */
1368               MI_RETURN_ERR(Mutex_Init(&self->mt));
1369           
1370               return MI_RESULT_OK;
1371           }
1372           
1373           MI_Result Disp_Destroy(Disp* self)
1374           {
1375               MI_RETURN_ERR(AgentMgr_Destroy(&self->agentmgr));
1376               ProvReg_Destroy(&self->provreg);
1377           
1378               /*ATTN! remove indication contexts! */
1379               Mutex_Destroy(&self->mt);
1380               return MI_RESULT_OK;
1381           }
1382           
1383           MI_Result Disp_HandleRequest(
1384               Disp* self,
1385               Message* msg)
1386           {
1387               switch (msg->tag)
1388 mike  1.1     {
1389                   case EnumerateInstancesReqTag:
1390                   {
1391                       EnumerateInstancesReq* req = (EnumerateInstancesReq*)msg;
1392                       return _HandleEnumerateInstancesReq(self, req);
1393                   }
1394           
1395                   case GetInstanceReqTag:
1396                   {
1397                       GetInstanceReq* req = (GetInstanceReq*)msg;
1398                       return _HandleGetInstanceReq(self, req);
1399                   }
1400           
1401                   case CreateInstanceReqTag:
1402                   {
1403                       CreateInstanceReq* req = (CreateInstanceReq*)msg;
1404                       return _HandleCreateInstanceReq(self, req);
1405                   }
1406           
1407                   case ModifyInstanceReqTag:
1408                   {
1409 mike  1.1             ModifyInstanceReq* req = (ModifyInstanceReq*)msg;
1410                       return _HandleModifyInstanceReq(self, req);
1411                   }
1412           
1413                   case DeleteInstanceReqTag:
1414                   {
1415                       DeleteInstanceReq* req = (DeleteInstanceReq*)msg;
1416                       return _HandleDeleteInstanceReq(self, req);
1417                   }
1418           
1419                   case InvokeReqTag:
1420                   {
1421                       InvokeReq* req = (InvokeReq*)msg;
1422                       return _HandleInvokeReq(self, req);
1423                   }
1424           
1425                   case AssociatorsOfReqTag:
1426                   {
1427                       AssociatorsOfReq* req = (AssociatorsOfReq*)msg;
1428                       return _HandleAssociatorsOfReq(self, req);
1429                   }
1430 mike  1.1 
1431                   case ReferencesOfReqTag:
1432                   {
1433                       ReferencesOfReq* req = (ReferencesOfReq*)msg;
1434                       return _HandleReferencesOfReq(self, req);
1435                   }
1436           
1437                   case SubscribeReqTag:
1438                   {
1439                       SubscribeReq* req = (SubscribeReq*)msg;
1440                       return _HandleSubscribeReq(self, req);
1441                   }
1442           
1443                   default:
1444                   {
1445                       /* Unsupported mesage type */
1446                       return _SendErrorResponse(msg,MI_RESULT_NOT_SUPPORTED);
1447                   }
1448               }
1449           }

ViewCVS 0.9.2