I am implementing WMI support in my driver. I am going through the msdn doc and found one statement that "All drivers must support any standard WMI data blocks that WMI defines for their device class. These WMI data blocks are defined in Wmicore.mof."
Ref: https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/introduction-to-wmi-for-kmdf-drivers
Below mof file is enough for me to get all the details. Here what kind of standard WMI data block can I add?
Kindly provide some examples and explain.
Thanks in advance!
This is my mof file:
PRAGMA AUTORECOVER
[Dynamic, Provider("WMIProv"),
WMI,
Description("Sensor driver stability information"),
guid("{c3915401-b2ba-4588-a354-1494d267b987}"),
locale("MS\\0x409")]
class Sensor7887
{
[key, read]
string InstanceName;
[read]
boolean Active;
[WmiDataId(1),
read,
Description("This indicates the number of resets triggered by driver")]
uint32 ResetCount;
[WmiDataId(2),
read,
Description("This indicates the number of crashes")]
uint32 CrashCount;
[WmiDataId(3),
read,
Description("This indicates the number of surprise removals")]
uint32 SurpriseRemovalCount;
[WmiDataId(4),
read,
Description("The Model Name.")]
string ModelName;
};
Related
The AccessCheck function gets a GenericMapping parameter. What is this parameter used for? It is NOT used for the DesiredAccess parameter since MapGenericMask must be applied to DesiredAccess before.
It is also not applied to the DACL contained in the SecurityDescriptor as I found out using a C program doing this:
open the current thread token
create a security descriptor with owner and default group from the token and an DACL granting GENERIC_ALL to the owner "D:(A;;GA;;;ownerSID)"
setup GENERIC_MAPPING, which maps (among others) GenericAll to my OWN_READ | OWN_WRITE (defined as 0x0001 and 0x0002)
call AccessCheck with security descriptor created above, the thread token, OWN_READ as DesiredAccess, the described GENERIC_MAPPING
However, this fails with an access denied error. When I change the security descriptor to "D:(A;;0x0001;;;ownerSID)" access is granted. This shows that AccessCheck is NOT using the GenericMapping parameter to convert generic access flags (GA/GW/GR/GX) in the DACL to the specific access rights. Why? Am I doing something wrong?
https://msdn.microsoft.com/de-de/library/windows/desktop/aa374815(v=vs.85).aspx does not give any hints on how the security descriptor should be set.
you do almost all correct, but you not take in account that when you try assign security descriptor(SD) to kernel object - system not exactly "as is" assigned your SD but apply GenericMapping to ACEs first.
every object - have assosiated _OBJECT_TYPE which containing _OBJECT_TYPE_INITIALIZER and here exist GENERIC_MAPPING GenericMapping; and this GenericMapping (unique for each type of object) used for convert you generic flags in ACCESS_MASK to non-generic.
for test i create file with next SD - "D:P(A;;GA;;;WD)" (10000000 - GenericAll for S-1-1-0 EveryOne). and then i query DACL from created file - and see really 001F01FF for S-1-1-0 but not 10000000.
when i use "D:P(A;;GX;;;WD)" (GenericExecute - 20000000 for S-1-1-0) - in final file i view 001200A0 for S-1-1-0
so real kernel object have no generic bits in ACCESS_MASK and your DACL in exactly form you cannot assign to any object.
Why is AccessCheck NOT applying GenericMapping to the DACL?
AccessCheck assume that ACCESS_MASK in DACL already converted (no generic bits)
i think this is performance optimization - better convert generic bits once (on object creating or assigning SD to it - than every time do this convertation when somebody try open object)
about how GenericMapping parameter used ?
really very weak - only in case when object have no DACL (or if PreviousMode == KernelMode) and you request MAXIMUM_ALLOWED as DesiredAccess - system grant you GenericMapping->GenericAll. this is based on looking source code from WRK (accessck.c)
no DACL and MAXIMUM_ALLOWED this is rare case, but in this case how system can calculate what concrete access need grant to caller ? he not ask concrete access (like read/write/delete) - but "ALL". so system and give him GenericMapping->GenericAll
As illustrated in the picture bellow, by tweaking the registry in windows 10 I was able to change the bios version but not the SMBIOSVersion, which is what i want. Is there any way to alter it? Not necessarily permanently. I don't care if the value is restored after a reboot, i just want the win32_bios containing an SMBIOSVersion that i have specified until shutdown so calls to it will return my specified version.
It's coming from WMI, and the Win32_BIOS provider is defined in c:\Windows\System32\wbem\cimwin32.mof as a dynamic provider calling from cimwin32.dll.
But it does seem to be possible to override it; create a new file somewhere, e.g. c:\user\spkone\test.mof and put this in it:
#pragma namespace ("\\\\.\\root\\CIMv2")
class Win32_BIOS
{
[key]
string SMBIOSBIOSVersion;
};
[DYNPROPS]
instance of Win32_BIOS
{
SMBIOSBIOSVersion = "wow";
};
Run an administrator command prompt or PowerShell, and run mofcomp test.mof.
Before:
After:
I got this far and then stopped, I don't know how far the change reaches, or what the implications are. It does show in another PowerShell process, anyway. I'll leave it to you to fill in the other details ;)
Quoting from the documentation (emphasis mine):
SMBIOSBIOSVersion
Data type: string
Access type: Read-only
Qualifiers: MappingStrings ("SMBIOS|Type 0|BIOS Version")
BIOS version as reported by SMBIOS.
This value comes from the BIOS Version member of the BIOS Information structure in the SMBIOS information.
Basically, this value reports information obtained from the BIOS. To modify the value you'd need to modify the BIOS, i.e. flash the chip with a new firmware.
How do i get the shell IPreviewHandler for a particular file extension?
Background
Windows allows developers to create a preview handler for their custom file types:
Preview handlers are called when an item is selected to show a lightweight, rich, read-only preview of the file's contents in the view's reading pane. This is done without launching the file's associated application.
A preview handler is a hosted application. Hosts include the Windows Explorer in Windows Vista or Microsoft Outlook 2007.
I want to leverage the existing IPreviewHandler infrasturcture to get a thumbnail for a file.
In A Stream
The problem is that my files are not housed in the shell namespace (i.e. they are not sitting on the hard drive). They are sitting in memory, accessable through an IStream. This means i cannot use the legacy IExtractImage interface; as it does not support loading a file from a Stream.
Fortunately, this is why the modern IPreviewHandler supports (recommends, and prefers) loading data from a Stream, and recommends against loading previews from a file:
This method is preferred to Initialize due to its ability to use streams that are not accessible through a Win32 path, such as the contents of a compressed file with a .zip file name extension.
So how do i get it?
There is no documentation on the correct way to get ahold of the IPreviewHandler associated with a particular extension. But if i take the directions of how to register an IPreviewHandler, and read the contract from the other side:
HKEY_CLASSES_ROOT
.xyz
(Default) = xyzfile
HKEY_CLASSES_ROOT
xyzfile
shellex
{8895b1c6-b41f-4c1c-a562-0d564250836f} //IPreviewHandler subkey
(Default) = [clsid of the IPreviewHandler]
I should be able to follow the same route, given that i know the extension. Lets follow that with a real world example, a .jpg file:
Notice that the file has a preview. Notice i included the second screenshot only to reinforce the idea that the preview doesn't come from a file sitting on the hard drive.
Lets get spellunking!
First is the fact that it's a .jpg file:
HKEY_CLASSES_ROOT
.jpg
(Default) = ACDC_JPG
HKEY_CLASSES_ROOT
ACDC_JPG
ShellEx
{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
ContextMenuHandlers
Wait, there is no {8895b1c6-b41f-4c1c-a562-0d564250836f} subkey for a previewhandler. That must mean that we cannot get a thumbnail for .jpg files.
reducto an absurdum
The Real Question
The careful reader will realize that the actual question i'm asking is:
How do i get the preview of an image contained only in a stream?
And while that is a useful question, and the real issue i'm having, having an answer on how to use IPreviewHandler is also a useful question.
So feel free to answer either; or both!
Bonus Reading
MSDN: Preview Handlers and Shell Preview Host
MSDN: How to Register a Preview Handler
MSDN: IInitializeWithStream::Initialize method
IPreviewHandler throws uncatchable exception
Outlook IPreviewHandler for Delphi
#hvd had the right answer.
File types have a ShellEx key, with {guid} subkeys. Each {guid} key represents a particular InterfaceID.
There are a number of standard shell interfaces that can be associated with a file type:
{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1} IExtractImage
{953BB1EE-93B4-11d1-98A3-00C04FB687DA} IExtractImage2
{e357fccd-a995-4576-b01f-234630154e96} IThumbnailProvider
{8895b1c6-b41f-4c1c-a562-0d564250836f} IPreviewHandler
Unsupported spelunking of undocumented registry keys
If i want to find, for example, the clsid of the IPreviewHandler associated with a .jpg file, i would look in:
HKEY_CLASSES_ROOT/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
But that's not the only place i could look. I can also look in:
HKEY_CLASSES_ROOT/.jpg
(default) = jpgfile
HKEY_CLASSES_ROOT/jpgfile/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
But that's not the only place i could look. I can also look in:
HKEY_CLASSES_ROOT/SystemFileAssociations/.jpg/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
But that's not the only place i could look. I can also look in:
HKEY_CLASSES_ROOT/SystemFileAssociations/jpegfile/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
But that's not the only place i could look. If i think the file is an image, i can also look in:
HKEY_CLASSES_ROOT/SystemFileAssociations/image/ShellEx/{8895b1c6-b41f-4c1c-a562-0d564250836f}
(default) = [clsid]
How did i find these locations? Did i only follow documented and supported locations? No, i spied on Explorer using Process Monitor as it went hunting for an IThumbnailProvider.
Don't use undocumented spellunking
So now i want to use a standard shell interface for a file-type myself. This means that i have to crawl the locations. But why crawl these locations in an undocumented, unsupported way. Why incur the wrath from the guy from high atop the thing? Use AssocQueryString:
Guid GetShellClsidForFileType(String fileExtension, Guid interfaceID)
{
//E.g.:
// String fileExtension = ".jpg"
// Guid interfaceID = "{8895b1c6-b41f-4c1c-a562-0d564250836f}"; //IExtractImage
//The interface we're after - in string form
String szInterfaceID := GuidToString(interfaceID);
//Buffer to receive the clsid string
DWORD bufferSize := 1024; //more than enough to hold a 38-character clsid
String buffer;
SetLength(buffer, bufferSize);
HRESULT hr := AssocQueryString(
ASSOCF_INIT_DEFAULTTOSTAR,
ASSOCSTR_SHELLEXTENSION, //for finding shell extensions
fileExtension, //e.g. ".txt"
szInterfaceID, //e.g. "{8895b1c6-b41f-4c1c-a562-0d564250836f}"
buffer, //will receive the clsid string
#bufferSize);
if (hr <> S_OK)
return Guid.Empty;
Guid clsid;
HRESULT hr = CLSIDFromString(buffer, out clsid);
if (hr <> NOERROR)
return Guid.Empty;
return clsid;
}
And so to get the clsid of IPreviewHandler for .xps files:
Guid clsid = GetShellClsidForFileType(".xps", IPreviewHandler);
How to get IPreviewHandler for a file extension?
With all the above, we can now answer the question:
IPreviewHandler GetPreviewHandlerForFileType(String extension)
{
//Extension: the file type to return IPreviewHandler for (e.g. ".xps")
Guid previewHandlerClassID = GetShellClsidForFileType(extension, IPreviewHandler);
//Create the COM object
IUnknown unk = CreateComObject(previewHandlerClassID);
//Return the actual IPreviewHanler interface (not IUnknown)
return (IPreviewhandler)unk;
}
I am debugging though a wcf service. I have a service attached and debugging along with the exe. During the process, I get unsupported format name operation error when initializing queues with strings. However, I am pretty sure and double checked that the strings are of correct syntax, and I have all the permission and access to the queues.
RequestQueue = new System.Messaging.MessageQueue(correctString);
Any ideas are appreciated. Great thanks.
There are a couple of different formats that can be specified in the MessageQueue constructor, that use differing syntax, depending on if they are public/ private queues, dead-letter-queues, journal queues, and so on.
For example:
Public queue: MachineName\QueueName
Private queue: MachineName\Private$\QueueName
Can you post an example of what you are using?
Also, if you are using an Format Name, check the spelling of your format string:
FormatName:DIRECT=OS:YOURMACHINENAME\private$\YourQueueName
Please note that the first part FormatName:DIRECT is case-sensitive. (More in-depth documentation about the syntax can be found in the MSDN here: Direct Format Names)
I am trying to add the facility to burn CD/DVD into my app by using IMAPI2.dll. I am using Microsoft Visual FoxPro 9 SP 2 to devolopment. When I invork the method Write() which is a member of the IMAPI2.MsftDiscFormat2Data class (Last line of the sample code) Visual FoxPro gives the following error message. Error Msg : "OLE error code 0x80004002: No such interface supported."
OS : Windows 7
Please Help.
**--Creating MsftDiscMaster2 object to connect to optical drives.
loDiscMaster = CREATEOBJECT("IMAPI2.MsftDiscMaster2")
**--Creating MsftDiscRecorder2 object for the specified burning device.
loRecorder = CREATEOBJECT("IMAPI2.MsftDiscRecorder2")
lcUniqueId = loDiscMaster.ITEM(0)
loRecorder.InitializeDiscRecorder(lcUniqueId)
**--Create an image stream for the specified directory.
loFileSystem = CREATEOBJECT("IMAPI2FS.MsftFileSystemImage")
loRootDir = loFileSystem.Root
**--Create the new disc format and set the recorder.
loDataWriter = CREATEOBJECT("IMAPI2.MsftDiscFormat2Data")
loDataWriter.Recorder = loRecorder
loDataWriter.ClientName = "IMAPIv2 TEST"
loFileSystem.ChooseImageDefaults(loRecorder)
**--Add the directory and its contents to the file system.
loRootDir.AddTree("F:\VSS",.F.)
**--Create an image from the file system
loResultImage = loFileSystem.CreateResultImage()
loStream = loResultImage.ImageStream
**--Write stream to disc using the specified recorder.
loDataWriter.Write(loStream)
I'm afraid you are out of luck there. FoxPro interacts with COM objects at a fairly high level. In fact, it works in much the same way that VBScript interacts with COM. Normally, if your code works in VBScript, it will also work in FoxPro.
This is actually a common problem with some ActiveX/COM libraries. While the objects implemented in imapi2.dll and imapi2fs.dll all use IDispatch - the highest level and most interoperable form of COM interface - some of the method parameters, method returns, and properties of those objects are not IDispatch.
Specifically, the ImageStream property returns something called an IStream which inherits from IUnknown instead of IDispatch. Because of this, the ImageStream property returns something that FoxPro doesn't know how to deal with. FoxPro knows that it is a COM interface, but it doesn't know how to find or call the methods on that object.