Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenclasswmi.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
1.7.6.1
|