ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

classwmi.c
Go to the documentation of this file.
00001 /*++
00002 
00003 Copyright (C) Microsoft Corporation, 1991 - 1999
00004 
00005 Module Name:
00006 
00007     classwmi.c
00008 
00009 Abstract:
00010 
00011     SCSI class driver routines
00012 
00013 Environment:
00014 
00015     kernel mode only
00016 
00017 Notes:
00018 
00019 
00020 Revision History:
00021 
00022 --*/
00023 
00024 #include "classp.h"
00025 
00026 NTSTATUS
00027 ClassSystemControl(
00028     IN PDEVICE_OBJECT DeviceObject,
00029     IN PIRP Irp
00030     );
00031 
00032 BOOLEAN
00033 ClassFindGuid(
00034     PGUIDREGINFO GuidList,
00035     ULONG GuidCount,
00036     LPGUID Guid,
00037     PULONG GuidIndex
00038     );
00039 
00040 //
00041 // This is the name for the MOF resource that must be part of all drivers that
00042 // register via this interface.
00043 #define MOFRESOURCENAME L"MofResourceName"
00044 
00045 //
00046 // What can be paged ???
00047 #ifdef ALLOC_PRAGMA
00048 #pragma alloc_text(PAGE, ClassSystemControl)
00049 #pragma alloc_text(PAGE, ClassFindGuid)
00050 #endif
00051 
00052 
00053 /*++////////////////////////////////////////////////////////////////////////////
00054 
00055 ClassFindGuid()
00056 
00057 Routine Description:
00058 
00059     This routine will search the list of guids registered and return
00060     the index for the one that was registered.
00061 
00062 Arguments:
00063 
00064     GuidList is the list of guids to search
00065 
00066     GuidCount is the count of guids in the list
00067 
00068     Guid is the guid being searched for
00069 
00070     *GuidIndex returns the index to the guid
00071 
00072 Return Value:
00073 
00074     TRUE if guid is found else FALSE
00075 
00076 --*/
00077 BOOLEAN
00078 ClassFindGuid(
00079     PGUIDREGINFO GuidList,
00080     ULONG GuidCount,
00081     LPGUID Guid,
00082     PULONG GuidIndex
00083     )
00084 {
00085     ULONG i;
00086 
00087     PAGED_CODE();
00088 
00089     for (i = 0; i < GuidCount; i++)
00090     {
00091         if (IsEqualGUID(Guid, &GuidList[i].Guid))
00092         {
00093             *GuidIndex = i;
00094             return(TRUE);
00095         }
00096     }
00097 
00098     return(FALSE);
00099 } // end ClassFindGuid()
00100 
00101 /*++////////////////////////////////////////////////////////////////////////////
00102 
00103 ClassSystemControl()
00104 
00105 Routine Description:
00106 
00107     Dispatch routine for IRP_MJ_SYSTEM_CONTROL. This routine will process
00108     all wmi requests received, forwarding them if they are not for this
00109     driver or determining if the guid is valid and if so passing it to
00110     the driver specific function for handing wmi requests.
00111 
00112 Arguments:
00113 
00114     DeviceObject - Supplies a pointer to the device object for this request.
00115 
00116     Irp - Supplies the Irp making the request.
00117 
00118 Return Value:
00119 
00120     status
00121 
00122 --*/
00123 NTSTATUS
00124 ClassSystemControl(
00125     IN PDEVICE_OBJECT DeviceObject,
00126     IN PIRP Irp
00127     )
00128 {
00129     PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
00130     PCLASS_DRIVER_EXTENSION driverExtension;
00131     PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
00132     ULONG isRemoved;
00133     ULONG bufferSize;
00134     PUCHAR buffer;
00135     NTSTATUS status;
00136     UCHAR minorFunction;
00137     ULONG guidIndex;
00138     PCLASS_WMI_INFO classWmiInfo;
00139 
00140     PAGED_CODE();
00141 
00142     //
00143     // Make sure device has not been removed
00144     isRemoved = ClassAcquireRemoveLock(DeviceObject, Irp);
00145     if(isRemoved)
00146     {
00147         Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
00148         ClassReleaseRemoveLock(DeviceObject, Irp);
00149         ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
00150         return STATUS_DEVICE_DOES_NOT_EXIST;
00151     }
00152 
00153     //
00154     // If the irp is not a WMI irp or it is not targetted at this device
00155     // or this device has not regstered with WMI then just forward it on.
00156     minorFunction = irpStack->MinorFunction;
00157     if ((minorFunction > IRP_MN_EXECUTE_METHOD) ||
00158         (irpStack->Parameters.WMI.ProviderId != (ULONG_PTR)DeviceObject) ||
00159         ((minorFunction != IRP_MN_REGINFO) &&
00160          (commonExtension->GuidRegInfo == NULL)))
00161     {
00162         //
00163         // CONSIDER: Do I need to hang onto lock until IoCallDriver returns ?
00164         IoSkipCurrentIrpStackLocation(Irp);
00165         ClassReleaseRemoveLock(DeviceObject, Irp);
00166         return(IoCallDriver(commonExtension->LowerDeviceObject, Irp));
00167     }
00168 
00169     buffer = (PUCHAR)irpStack->Parameters.WMI.Buffer;
00170     bufferSize = irpStack->Parameters.WMI.BufferSize;
00171 
00172     if (minorFunction != IRP_MN_REGINFO)
00173     {
00174         //
00175         // For all requests other than query registration info we are passed
00176         // a guid. Determine if the guid is one that is supported by the
00177         // device.
00178         if (ClassFindGuid(commonExtension->GuidRegInfo,
00179                             commonExtension->GuidCount,
00180                             (LPGUID)irpStack->Parameters.WMI.DataPath,
00181                             &guidIndex))
00182         {
00183             status = STATUS_SUCCESS;
00184         } else {
00185             status = STATUS_WMI_GUID_NOT_FOUND;
00186         }
00187 
00188         if (NT_SUCCESS(status) &&
00189             ((minorFunction == IRP_MN_QUERY_SINGLE_INSTANCE) ||
00190              (minorFunction == IRP_MN_CHANGE_SINGLE_INSTANCE) ||
00191              (minorFunction == IRP_MN_CHANGE_SINGLE_ITEM) ||
00192              (minorFunction == IRP_MN_EXECUTE_METHOD)))
00193         {
00194             if ( (((PWNODE_HEADER)buffer)->Flags) &
00195                                           WNODE_FLAG_STATIC_INSTANCE_NAMES)
00196             {
00197                 if ( ((PWNODE_SINGLE_INSTANCE)buffer)->InstanceIndex != 0 )
00198                 {
00199                     status = STATUS_WMI_INSTANCE_NOT_FOUND;
00200                 }
00201             } else {
00202                 status = STATUS_WMI_INSTANCE_NOT_FOUND;
00203             }
00204         }
00205 
00206         if (! NT_SUCCESS(status))
00207         {
00208             Irp->IoStatus.Status = status;
00209             ClassReleaseRemoveLock(DeviceObject, Irp);
00210             ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
00211             return(status);
00212         }
00213     }
00214 
00215     driverExtension = commonExtension->DriverExtension;
00216 
00217     classWmiInfo = commonExtension->IsFdo ?
00218                            &driverExtension->InitData.FdoData.ClassWmiInfo :
00219                            &driverExtension->InitData.PdoData.ClassWmiInfo;
00220     switch(minorFunction)
00221     {
00222         case IRP_MN_REGINFO:
00223         {
00224             ULONG guidCount;
00225             PGUIDREGINFO guidList;
00226             PWMIREGINFOW wmiRegInfo;
00227             PWMIREGGUIDW wmiRegGuid;
00228             PDEVICE_OBJECT pdo;
00229             PUNICODE_STRING regPath;
00230             PWCHAR stringPtr;
00231             ULONG retSize;
00232             ULONG registryPathOffset;
00233             ULONG mofResourceOffset;
00234             ULONG bufferNeeded;
00235             ULONG i;
00236             ULONG_PTR nameInfo;
00237             ULONG nameSize, nameOffset, nameFlags;
00238             UNICODE_STRING name, mofName;
00239             PCLASS_QUERY_WMI_REGINFO_EX ClassQueryWmiRegInfoEx;
00240 
00241             name.Buffer = NULL;
00242             name.Length = 0;
00243             name.MaximumLength = 0;
00244             nameFlags = 0;
00245 
00246             ClassQueryWmiRegInfoEx = commonExtension->IsFdo ?
00247                                driverExtension->ClassFdoQueryWmiRegInfoEx :
00248                                driverExtension->ClassPdoQueryWmiRegInfoEx;
00249         
00250             if (ClassQueryWmiRegInfoEx == NULL)
00251             {
00252                 status = classWmiInfo->ClassQueryWmiRegInfo(
00253                                                         DeviceObject,
00254                                                         &nameFlags,
00255                                                         &name);
00256                 
00257                 RtlInitUnicodeString(&mofName, MOFRESOURCENAME);
00258             } else {
00259                 RtlInitUnicodeString(&mofName, L"");
00260                 status = (*ClassQueryWmiRegInfoEx)(
00261                                                     DeviceObject,
00262                                                     &nameFlags,
00263                                                     &name,
00264                                                     &mofName);
00265             }
00266 
00267             if (NT_SUCCESS(status) &&
00268                 (! (nameFlags &  WMIREG_FLAG_INSTANCE_PDO) &&
00269                 (name.Buffer == NULL)))
00270             {
00271                 //
00272                 // if PDO flag not specified then an instance name must be
00273                 status = STATUS_INVALID_DEVICE_REQUEST;
00274             }
00275 
00276             if (NT_SUCCESS(status))
00277             {
00278                 guidList = classWmiInfo->GuidRegInfo;
00279                 guidCount = classWmiInfo->GuidCount;
00280 
00281                 nameOffset = sizeof(WMIREGINFO) +
00282                                       guidCount * sizeof(WMIREGGUIDW);
00283 
00284                 if (nameFlags & WMIREG_FLAG_INSTANCE_PDO)
00285                 {
00286                     nameSize = 0;
00287                     nameInfo = commonExtension->IsFdo ?
00288                                    (ULONG_PTR)((PFUNCTIONAL_DEVICE_EXTENSION)commonExtension)->LowerPdo :
00289                                    (ULONG_PTR)DeviceObject;
00290                 } else {
00291                     nameFlags |= WMIREG_FLAG_INSTANCE_LIST;
00292                     nameSize = name.Length + sizeof(USHORT);
00293                     nameInfo = nameOffset;
00294                 }
00295 
00296                 mofResourceOffset = nameOffset + nameSize;
00297 
00298                 registryPathOffset = mofResourceOffset +
00299                                   mofName.Length + sizeof(USHORT);
00300 
00301                 regPath = &driverExtension->RegistryPath;
00302                 bufferNeeded = registryPathOffset +
00303                 regPath->Length + sizeof(USHORT);
00304 
00305                 if (bufferNeeded <= bufferSize)
00306                 {
00307                     retSize = bufferNeeded;
00308 
00309                     commonExtension->GuidCount = guidCount;
00310                     commonExtension->GuidRegInfo = guidList;
00311 
00312                     wmiRegInfo = (PWMIREGINFO)buffer;
00313                     wmiRegInfo->BufferSize = bufferNeeded;
00314                     wmiRegInfo->NextWmiRegInfo = 0;
00315                     wmiRegInfo->MofResourceName = mofResourceOffset;
00316                     wmiRegInfo->RegistryPath = registryPathOffset;
00317                     wmiRegInfo->GuidCount = guidCount;
00318 
00319                     for (i = 0; i < guidCount; i++)
00320                     {
00321                         wmiRegGuid = &wmiRegInfo->WmiRegGuid[i];
00322                         wmiRegGuid->Guid = guidList[i].Guid;
00323                         wmiRegGuid->Flags = guidList[i].Flags | nameFlags;
00324                         wmiRegGuid->InstanceInfo = nameInfo;
00325                         wmiRegGuid->InstanceCount = 1;
00326                     }
00327 
00328                     if ( nameFlags &  WMIREG_FLAG_INSTANCE_LIST)
00329                     {
00330                         stringPtr = (PWCHAR)((PUCHAR)buffer + nameOffset);
00331                         *stringPtr++ = name.Length;
00332                         RtlCopyMemory(stringPtr,
00333                                   name.Buffer,
00334                                   name.Length);
00335                     }
00336 
00337                     stringPtr = (PWCHAR)((PUCHAR)buffer + mofResourceOffset);
00338                     *stringPtr++ = mofName.Length;
00339                     RtlCopyMemory(stringPtr,
00340                                   mofName.Buffer,
00341                                   mofName.Length);
00342 
00343                     stringPtr = (PWCHAR)((PUCHAR)buffer + registryPathOffset);
00344                     *stringPtr++ = regPath->Length;
00345                     RtlCopyMemory(stringPtr,
00346                               regPath->Buffer,
00347                               regPath->Length);
00348                 } else {
00349                     *((PULONG)buffer) = bufferNeeded;
00350                     retSize = sizeof(ULONG);
00351                 }
00352             } else {
00353                 retSize = 0;
00354             }
00355 
00356             if (name.Buffer != NULL)
00357             {
00358                 ExFreePool(name.Buffer);
00359             }
00360 
00361             Irp->IoStatus.Status = status;
00362             Irp->IoStatus.Information = retSize;
00363             ClassReleaseRemoveLock(DeviceObject, Irp);
00364             ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
00365             return(status);
00366         }
00367 
00368         case IRP_MN_QUERY_ALL_DATA:
00369         {
00370             PWNODE_ALL_DATA wnode;
00371             ULONG bufferAvail;
00372 
00373             wnode = (PWNODE_ALL_DATA)buffer;
00374 
00375             if (bufferSize < sizeof(WNODE_ALL_DATA))
00376             {
00377                 bufferAvail = 0;
00378             } else {
00379                 bufferAvail = bufferSize - sizeof(WNODE_ALL_DATA);
00380             }
00381 
00382             wnode->DataBlockOffset = sizeof(WNODE_ALL_DATA);
00383 
00384             status = classWmiInfo->ClassQueryWmiDataBlock(
00385                                              DeviceObject,
00386                                              Irp,
00387                                              guidIndex,
00388                                              bufferAvail,
00389                                              buffer + sizeof(WNODE_ALL_DATA));
00390 
00391             break;
00392         }
00393 
00394         case IRP_MN_QUERY_SINGLE_INSTANCE:
00395         {
00396             PWNODE_SINGLE_INSTANCE wnode;
00397             ULONG dataBlockOffset;
00398 
00399             wnode = (PWNODE_SINGLE_INSTANCE)buffer;
00400 
00401             dataBlockOffset = wnode->DataBlockOffset;
00402 
00403             status = classWmiInfo->ClassQueryWmiDataBlock(
00404                                           DeviceObject,
00405                                           Irp,
00406                                           guidIndex,
00407                                           bufferSize - dataBlockOffset,
00408                                           (PUCHAR)wnode + dataBlockOffset);
00409 
00410             break;
00411         }
00412 
00413         case IRP_MN_CHANGE_SINGLE_INSTANCE:
00414         {
00415             PWNODE_SINGLE_INSTANCE wnode;
00416 
00417             wnode = (PWNODE_SINGLE_INSTANCE)buffer;
00418 
00419             status = classWmiInfo->ClassSetWmiDataBlock(
00420                                      DeviceObject,
00421                                      Irp,
00422                                      guidIndex,
00423                                      wnode->SizeDataBlock,
00424                                      (PUCHAR)wnode + wnode->DataBlockOffset);
00425 
00426             break;
00427         }
00428 
00429         case IRP_MN_CHANGE_SINGLE_ITEM:
00430         {
00431             PWNODE_SINGLE_ITEM wnode;
00432 
00433             wnode = (PWNODE_SINGLE_ITEM)buffer;
00434 
00435             status = classWmiInfo->ClassSetWmiDataItem(
00436                                      DeviceObject,
00437                                      Irp,
00438                                      guidIndex,
00439                                      wnode->ItemId,
00440                                      wnode->SizeDataItem,
00441                                      (PUCHAR)wnode + wnode->DataBlockOffset);
00442 
00443             break;
00444         }
00445 
00446         case IRP_MN_EXECUTE_METHOD:
00447         {
00448             PWNODE_METHOD_ITEM wnode;
00449 
00450             wnode = (PWNODE_METHOD_ITEM)buffer;
00451 
00452             status = classWmiInfo->ClassExecuteWmiMethod(
00453                                          DeviceObject,
00454                                          Irp,
00455                                          guidIndex,
00456                                          wnode->MethodId,
00457                                          wnode->SizeDataBlock,
00458                                          bufferSize - wnode->DataBlockOffset,
00459                                          buffer + wnode->DataBlockOffset);
00460 
00461 
00462             break;
00463         }
00464 
00465         case IRP_MN_ENABLE_EVENTS:
00466         {
00467             status = classWmiInfo->ClassWmiFunctionControl(
00468                                                            DeviceObject,
00469                                                            Irp,
00470                                                            guidIndex,
00471                                                            EventGeneration,
00472                                                            TRUE);
00473             break;
00474         }
00475 
00476         case IRP_MN_DISABLE_EVENTS:
00477         {
00478             status = classWmiInfo->ClassWmiFunctionControl(
00479                                                            DeviceObject,
00480                                                            Irp,
00481                                                            guidIndex,
00482                                                            EventGeneration,
00483                                                            FALSE);
00484             break;
00485         }
00486 
00487         case IRP_MN_ENABLE_COLLECTION:
00488         {
00489             status = classWmiInfo->ClassWmiFunctionControl(
00490                                                          DeviceObject,
00491                                                          Irp,
00492                                                          guidIndex,
00493                                                          DataBlockCollection,
00494                                                          TRUE);
00495             break;
00496         }
00497 
00498         case IRP_MN_DISABLE_COLLECTION:
00499         {
00500             status = classWmiInfo->ClassWmiFunctionControl(
00501                                                          DeviceObject,
00502                                                          Irp,
00503                                                          guidIndex,
00504                                                          DataBlockCollection,
00505                                                          FALSE);
00506             break;
00507         }
00508 
00509         default:
00510         {
00511             status = STATUS_INVALID_DEVICE_REQUEST;
00512             break;
00513         }
00514 
00515     }
00516 
00517     return(status);
00518 } // end ClassSystemControl()
00519 
00520 /*++////////////////////////////////////////////////////////////////////////////
00521 
00522 ClassWmiCompleteRequest()
00523 
00524 Routine Description:
00525 
00526 
00527     This routine will do the work of completing a WMI irp. Depending upon the
00528     the WMI request this routine will fixup the returned WNODE appropriately.
00529 
00530     NOTE: This routine assumes that the ClassRemoveLock is held and it will
00531           release it.
00532 
00533 Arguments:
00534 
00535     DeviceObject - Supplies a pointer to the device object for this request.
00536 
00537     Irp - Supplies the Irp making the request.
00538     
00539     Status - Status to complete the irp with.  STATUS_BUFFER_TOO_SMALL is used
00540         to indicate that more buffer is required for the data requested.
00541     
00542     BufferUsed - number of bytes of actual data to return (not including WMI
00543         specific structures)
00544     
00545     PriorityBoost - priority boost to pass to ClassCompleteRequest
00546 
00547 Return Value:
00548 
00549     status
00550 
00551 --*/
00552 SCSIPORTAPI
00553 NTSTATUS
00554 ClassWmiCompleteRequest(
00555     IN PDEVICE_OBJECT DeviceObject,
00556     IN PIRP Irp,
00557     IN NTSTATUS Status,
00558     IN ULONG BufferUsed,
00559     IN CCHAR PriorityBoost
00560     )
00561 {
00562     PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
00563     PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
00564     UCHAR MinorFunction;
00565     PUCHAR buffer;
00566     ULONG retSize;
00567     UCHAR minorFunction;
00568     ULONG bufferSize;
00569 
00570     minorFunction = irpStack->MinorFunction;
00571     buffer = (PUCHAR)irpStack->Parameters.WMI.Buffer;
00572     bufferSize = irpStack->Parameters.WMI.BufferSize;
00573 
00574     switch(minorFunction)
00575     {
00576         case IRP_MN_QUERY_ALL_DATA:
00577         {
00578             PWNODE_ALL_DATA wnode;
00579             PWNODE_TOO_SMALL wnodeTooSmall;
00580             ULONG bufferNeeded;
00581 
00582             wnode = (PWNODE_ALL_DATA)buffer;
00583 
00584             bufferNeeded = sizeof(WNODE_ALL_DATA) + BufferUsed;
00585 
00586             if (NT_SUCCESS(Status))
00587             {
00588                 retSize = bufferNeeded;
00589                 wnode->WnodeHeader.BufferSize = bufferNeeded;
00590                 KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
00591                 wnode->WnodeHeader.Flags |= WNODE_FLAG_FIXED_INSTANCE_SIZE;
00592                 wnode->FixedInstanceSize = BufferUsed;
00593                 wnode->InstanceCount = 1;
00594 
00595             } else if (Status == STATUS_BUFFER_TOO_SMALL) {
00596                 wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
00597 
00598                 wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
00599                 wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
00600                 wnodeTooSmall->SizeNeeded = sizeof(WNODE_ALL_DATA) + BufferUsed;
00601                 retSize = sizeof(WNODE_TOO_SMALL);
00602                 Status = STATUS_SUCCESS;
00603             } else {
00604                 retSize = 0;
00605             }
00606             break;
00607         }
00608 
00609         case IRP_MN_QUERY_SINGLE_INSTANCE:
00610         {
00611             PWNODE_SINGLE_INSTANCE wnode;
00612             PWNODE_TOO_SMALL wnodeTooSmall;
00613             ULONG bufferNeeded;
00614 
00615             wnode = (PWNODE_SINGLE_INSTANCE)buffer;
00616 
00617             bufferNeeded = wnode->DataBlockOffset + BufferUsed;
00618 
00619             if (NT_SUCCESS(Status))
00620             {
00621                 retSize = bufferNeeded;
00622                 wnode->WnodeHeader.BufferSize = bufferNeeded;
00623                 KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
00624                 wnode->SizeDataBlock = BufferUsed;
00625 
00626             } else if (Status == STATUS_BUFFER_TOO_SMALL) {
00627                 wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
00628 
00629                 wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
00630                 wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
00631                 wnodeTooSmall->SizeNeeded = bufferNeeded;
00632                 retSize = sizeof(WNODE_TOO_SMALL);
00633                 Status = STATUS_SUCCESS;
00634             } else {
00635                 retSize = 0;
00636             }
00637             break;
00638         }
00639 
00640         case IRP_MN_EXECUTE_METHOD:
00641         {
00642             PWNODE_METHOD_ITEM wnode;
00643             PWNODE_TOO_SMALL wnodeTooSmall;
00644             ULONG bufferNeeded;
00645 
00646             wnode = (PWNODE_METHOD_ITEM)buffer;
00647 
00648             bufferNeeded = wnode->DataBlockOffset + BufferUsed;
00649 
00650             if (NT_SUCCESS(Status))
00651             {
00652                 retSize = bufferNeeded;
00653                 wnode->WnodeHeader.BufferSize = bufferNeeded;
00654                 KeQuerySystemTime(&wnode->WnodeHeader.TimeStamp);
00655                 wnode->SizeDataBlock = BufferUsed;
00656 
00657             } else if (Status == STATUS_BUFFER_TOO_SMALL) {
00658                 wnodeTooSmall = (PWNODE_TOO_SMALL)wnode;
00659 
00660                 wnodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
00661                 wnodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
00662                 wnodeTooSmall->SizeNeeded = bufferNeeded;
00663                 retSize = sizeof(WNODE_TOO_SMALL);
00664                 Status = STATUS_SUCCESS;
00665             } else {
00666                 retSize = 0;
00667             }
00668             break;
00669         }
00670 
00671         default:
00672         {
00673             //
00674             // All other requests don't return any data
00675             retSize = 0;
00676             break;
00677         }
00678 
00679     }
00680 
00681     Irp->IoStatus.Status = Status;
00682     Irp->IoStatus.Information = retSize;
00683     ClassReleaseRemoveLock(DeviceObject, Irp);
00684     ClassCompleteRequest(DeviceObject, Irp, PriorityBoost);
00685     return(Status);
00686 } // end ClassWmiCompleteRequest()
00687 
00688 /*++////////////////////////////////////////////////////////////////////////////
00689 
00690 ClassWmiFireEvent()
00691 
00692 Routine Description:
00693 
00694     This routine will fire a WMI event using the data buffer passed. This
00695     routine may be called at or below DPC level
00696 
00697 Arguments:
00698 
00699     DeviceObject - Supplies a pointer to the device object for this event
00700 
00701     Guid is pointer to the GUID that represents the event
00702 
00703     InstanceIndex is the index of the instance of the event
00704 
00705     EventDataSize is the number of bytes of data that is being fired with
00706        with the event
00707 
00708     EventData is the data that is fired with the events. This may be NULL
00709         if there is no data associated with the event
00710 
00711 
00712 Return Value:
00713 
00714     status
00715 
00716 --*/
00717 NTSTATUS
00718 ClassWmiFireEvent(
00719     IN PDEVICE_OBJECT DeviceObject,
00720     IN LPGUID Guid,
00721     IN ULONG InstanceIndex,
00722     IN ULONG EventDataSize,
00723     IN PVOID EventData
00724     )
00725 {
00726 
00727     ULONG sizeNeeded;
00728     PWNODE_SINGLE_INSTANCE event;
00729     NTSTATUS status;
00730 
00731     if (EventData == NULL)
00732     {
00733         EventDataSize = 0;
00734     }
00735 
00736     sizeNeeded = sizeof(WNODE_SINGLE_INSTANCE) + EventDataSize;
00737 
00738     event = ExAllocatePoolWithTag(NonPagedPool, sizeNeeded, CLASS_TAG_WMI);
00739     if (event != NULL)
00740     {
00741         event->WnodeHeader.Guid = *Guid;
00742         event->WnodeHeader.ProviderId = IoWMIDeviceObjectToProviderId(DeviceObject);
00743         event->WnodeHeader.BufferSize = sizeNeeded;
00744         event->WnodeHeader.Flags =  WNODE_FLAG_SINGLE_INSTANCE |
00745                                     WNODE_FLAG_EVENT_ITEM |
00746                                     WNODE_FLAG_STATIC_INSTANCE_NAMES;
00747         KeQuerySystemTime(&event->WnodeHeader.TimeStamp);
00748 
00749         event->InstanceIndex = InstanceIndex;
00750         event->SizeDataBlock = EventDataSize;
00751         event->DataBlockOffset = sizeof(WNODE_SINGLE_INSTANCE);
00752         if (EventData != NULL)
00753         {
00754             RtlCopyMemory( &event->VariableData, EventData, EventDataSize);
00755         }
00756 
00757         status = IoWMIWriteEvent(event);
00758         if (! NT_SUCCESS(status))
00759         {
00760             ExFreePool(event);
00761         }
00762     } else {
00763         status = STATUS_INSUFFICIENT_RESOURCES;
00764     }
00765 
00766     return(status);
00767 } // end ClassWmiFireEvent()
00768 

Generated on Sat May 26 2012 04:26:50 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.