Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

282 lines
9.1 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
request.c
Abstract:
Implements WMI requests to different data providers
Author:
16-Jan-1997 AlanWar
Revision History:
--*/
#include <nt.h>
#include "wmiump.h"
#include "trcapi.h"
#include "wmiumkm.h"
#include "request.h"
//
// This is the handle to the WMI kernel mode device
extern HANDLE EtwpKMHandle;
//
// This is the one-deep Win32 event queue used to supply events for
// overlapped I/O to the WMI device.
extern HANDLE EtwpWin32Event;
ULONG EtwpSendRegisterKMRequest(
HANDLE DeviceHandle,
ULONG Ioctl,
PVOID InBuffer,
ULONG InBufferSize,
PVOID OutBuffer,
ULONG MaxBufferSize,
ULONG *ReturnSize,
LPOVERLAPPED Overlapped
)
/*+++
Routine Description:
This is a special SendKMRequest routine for RegisterTraceGuids.
We will reject MofResource from the RegisterTraceGuids call if it
did not come from Admin or LocalSystem. To determine that we need
to attempt to send the Ioctl through WMIAdminDevice first. If that
fails, we send the request the normal way, ie., through WMI data device.
Arguments:
Ioctl is the IOCTL code to send to the WMI device
Buffer is the input buffer for the call to the WMI device
InBufferSize is the size of the buffer passed to the device
OutBuffer is the output buffer for the call to the WMI device
MaxBufferSize is the maximum number of bytes that can be written
into the buffer
*ReturnSize on return has the actual number of bytes written in buffer
Overlapped is an option OVERLAPPED struct that is used to make the
call async
Return Value:
ERROR_SUCCESS or an error code
---*/
{
ULONG Status;
HANDLE KMHandle;
//
// First, we try to open the WMI Admin device
//
KMHandle = EtwpCreateFileW(WMIAdminDeviceName_W,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED,
NULL);
if ( (KMHandle == INVALID_HANDLE_VALUE) || (KMHandle == NULL))
{
//
// Send the Request through WMI Data Device
//
Status = EtwpSendWmiKMRequest( DeviceHandle,
Ioctl,
InBuffer,
InBufferSize,
OutBuffer,
MaxBufferSize,
ReturnSize,
Overlapped
);
}
else
{
Status = EtwpSendWmiKMRequest( KMHandle,
Ioctl,
InBuffer,
InBufferSize,
OutBuffer,
MaxBufferSize,
ReturnSize,
Overlapped
);
EtwpCloseHandle(KMHandle);
}
return(Status);
}
ULONG EtwpRegisterGuids(
IN LPGUID MasterGuid,
IN LPGUID ControlGuid,
IN LPCWSTR MofImagePath,
IN LPCWSTR MofResourceName,
OUT ULONG64 *LoggerContext,
OUT HANDLE *RegistrationHandle
)
{
ULONG Status, StringPos, StringSize, WmiRegSize;
ULONG SizeNeeded, InSizeNeeded, OutSizeNeeded;
WCHAR GuidObjectName[WmiGuidObjectNameLength+1];
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING GuidString;
PWMIREGREQUEST WmiRegRequest;
PUCHAR Buffer;
PUCHAR RegInfoBuffer;
PWMIREGRESULTS WmiRegResults;
ULONG ReturnSize;
PWMIREGINFOW pWmiRegInfo;
PWMIREGGUID WmiRegGuidPtr;
LPGUID pGuid;
PWCHAR StringPtr;
//
// Allocate a buffer large enough for all in and out parameters
//
// Allocate space to call IOCTL_WMI_REGISTER_GUIDS
//
InSizeNeeded = sizeof(WMIREGREQUEST) +
sizeof(WMIREGINFOW) +
sizeof(WMIREGGUIDW);
if (MofImagePath == NULL) {
MofImagePath = L"";
}
if (MofResourceName != NULL) {
InSizeNeeded += (wcslen(MofResourceName) + 2) * sizeof(WCHAR);
}
InSizeNeeded += (wcslen(MofImagePath) + 2) * sizeof(WCHAR);
InSizeNeeded = (InSizeNeeded + 7) & ~7;
OutSizeNeeded = sizeof(WMIREGRESULTS);
if (InSizeNeeded > OutSizeNeeded)
{
SizeNeeded = InSizeNeeded;
} else {
SizeNeeded = OutSizeNeeded;
}
Buffer = EtwpAlloc(SizeNeeded);
if (Buffer != NULL)
{
RtlZeroMemory(Buffer, SizeNeeded);
//
// Build the object attributes
//
WmiRegRequest = (PWMIREGREQUEST)Buffer;
WmiRegRequest->ObjectAttributes = &ObjectAttributes;
WmiRegRequest->WmiRegInfo32Size = sizeof(WMIREGINFOW);
WmiRegRequest->WmiRegGuid32Size = sizeof(WMIREGGUIDW);
RegInfoBuffer = Buffer + sizeof(WMIREGREQUEST);
Status = EtwpBuildGuidObjectAttributes(MasterGuid,
&ObjectAttributes,
&GuidString,
GuidObjectName);
if (Status == ERROR_SUCCESS)
{
WmiRegRequest->Cookie = 0;
pWmiRegInfo = (PWMIREGINFOW) (Buffer + sizeof(WMIREGREQUEST));
WmiRegSize = SizeNeeded - sizeof(WMIREGREQUEST);
StringPos = sizeof(WMIREGINFOW) + sizeof(WMIREGGUIDW);
pWmiRegInfo->BufferSize = WmiRegSize;
pWmiRegInfo->GuidCount = 1;
WmiRegGuidPtr = &pWmiRegInfo->WmiRegGuid[0];
WmiRegGuidPtr->Flags = (WMIREG_FLAG_TRACED_GUID |
WMIREG_FLAG_TRACE_CONTROL_GUID);
WmiRegGuidPtr->Guid = *ControlGuid;
// Copy MOF resource path and name into WmiRegInfo
if (MofResourceName != NULL) {
pWmiRegInfo->MofResourceName = StringPos;
StringPtr = (PWCHAR)OffsetToPtr(pWmiRegInfo, StringPos);
Status = EtwpCopyStringToCountedUnicode(MofResourceName,
StringPtr,
&StringSize,
FALSE);
if (Status != ERROR_SUCCESS) {
EtwpFree(Buffer);
EtwpSetLastError(Status);
return Status;
}
StringPos += StringSize;
#if DBG
EtwpAssert(StringPos <= WmiRegSize);
#endif
}
if (MofImagePath != NULL) {
pWmiRegInfo->RegistryPath = StringPos;
StringPtr = (PWCHAR)OffsetToPtr(pWmiRegInfo, StringPos);
Status = EtwpCopyStringToCountedUnicode(MofImagePath,
StringPtr,
&StringSize,
FALSE);
if (Status != ERROR_SUCCESS) {
EtwpFree(Buffer);
EtwpSetLastError(Status);
return Status;
}
StringPos += StringSize;
#if DBG
EtwpAssert(StringPos <= WmiRegSize);
#endif
}
Status = EtwpSendRegisterKMRequest (NULL,
IOCTL_WMI_REGISTER_GUIDS,
Buffer,
InSizeNeeded,
Buffer,
OutSizeNeeded,
&ReturnSize,
NULL);
if (Status == ERROR_SUCCESS)
{
//
// Successful call, return the out parameters
//
WmiRegResults = (PWMIREGRESULTS)Buffer;
*RegistrationHandle = WmiRegResults->RequestHandle.Handle;
*LoggerContext = WmiRegResults->LoggerContext;
#if DBG
if ( (WmiRegResults->MofIgnored) && (MofResourceName != NULL)
&& (MofImagePath != NULL))
{
EtwpDebugPrint(("ETW: Mof %ws from %ws ignored\n",
MofImagePath, MofResourceName));
}
#endif
}
}
EtwpFree(Buffer);
} else {
Status = ERROR_NOT_ENOUGH_MEMORY;
}
return(Status);
}