Retired Microsoft Blog disclaimer

This directory is a mirror of retired "Decrypt My World" MSDN blog and is provided as is. All posting authorship and copyrights belong to respective authors.

Posts on this page:

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/10/20/get-wmiobject-the-type-initializer-for-system-management-mtahelper-threw-an-exception/
Post name: Get-WmiObject : The type initializer for ‘System.Management.MTAHelper’ threw an exception
Original author: Alejandro Campos Magencio
Posting date: 2010-10-20T06:31:00+00:00


Hi all,

 

Sometime ago a customer of mine had some problems in his x64 machine when running WMI queries in Powershell.

Take for instance the following query:

"

Get-WMIObject Win32_LogicalDisk

"

 

It failed with the following error:

"

Get-WmiObject : The type initializer for 'System.Management.MTAHelper' threw an exception.

At line:1 char:14

+ Get-WMIObject <<<< Win32_LogicalDisk

+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], TypeInitializationException

+ FullyQualifiedErrorId : System.TypeInitializationException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

 

"

 

But doing the same query withWBEMTest.exeworked just fine.

 

So I debugged PowerShell.exe with Windbg.exe and its SOS extension (at the end, Powershell is just another .NET process), and saw the following internal exceptions and errors when the issue happened:

"

0:003> !pe

Exception object: 0000000002dfb820

Exception type: System.TypeInitializationException

Message: The type initializer for 'System.Management.MTAHelper' threw an exception.

InnerException: System.BadImageFormatException, use !PrintException 0000000002dfb520 to see more

StackTrace (generated):

<none>

StackTraceString: <none>

HResult: 80131534

 

0:003> !pe 0000000002dfb520

Exception object: 0000000002dfb520

Exception type: System.BadImageFormatException

Message: Retrieving the COM class factory for component with CLSID {A8F03BE3-EDB7-4972-821F-AF6F8EA34884} failed due to the following error: 800700c1.

InnerException: <none>

StackTrace (generated):

SP IP Function

000000001C34D310 000006424EAFCEA4 System.Management.MTAHelper..cctor()

 

StackTraceString: <none>

HResult: 800700c1

 

0:003> !error 800700c1

Error code: (HRESULT) 0x800700c1 (2147942593) - %1 is not a valid Win32 application.

"

 

I looked for "{A8F03BE3-EDB7-4972-821F-AF6F8EA34884}" in the Registry of my own Windows 7environment, and itcorresponds to:

"

InprocServer32>2.0.50727 : C:\Windows\system32\mscoree.dll

ProgID : WMINet_Utils.WmiSecurityHelper.1

Server : WMINet_Utils.dll

VersionIndependentProgID: WMINet_Utils.WmiSecurityHelper

"

 

So somehow we failed to load mscoree.dll into PowerShell process. (Note: if you want to know more about .NET debugging with Windbg, please checkthisout.)

 

To continue troubleshooting this, we got some Process Monitor logs from problematic machine to see how PowerShell was loading mscoree.dll.

In those logs we could see howPowershell successfully loads mscoree.dll from here first:

"

35 21124 powershell.exe Load Image 10:32:49,0969791 C:\WINDOWS\system32\mscoree.dll SUCCESS Image Base: 0x6427ee50000, Image Size: 0x66000 Domain\user

"

 

And then it tries to load it again from here:

"

3312 21124 powershell.exe RegQueryValue 10:33:33,9734478 HKCR\CLSID\{A8F03BE3-EDB7-4972-821F-AF6F8EA34884}\InprocServer32\(Default) SUCCESS Type: REG_SZ, Length: 64, Data: C:\WINDOWS\SysWOW64\mscoree.dll Domain\user

"

 

But fails, as we cannot see a "Load Image" record in the logs just after that.

So I went toHKCR\CLSID\{A8F03BE3-EDB7-4972-821F-AF6F8EA34884}\InprocServer32\(Default)in my x64 environment, and saw the following path:C:\Windows\system32\mscoree.dll.

Customer changed theC:\WINDOWS\SysWOW64\mscoree.dll path he found in there to the right one, and he didn't get the error again.

 

I hope this helps.

Regards,

 

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/10/15/system-directoryservices-accountmanagement-userprincipal-ismemberof-returns-false-negatives/
Post name: System.DirectoryServices.AccountManagement.UserPrincipal.IsMemberOf returns false negatives
Original author: Alejandro Campos Magencio
Posting date: 2010-10-15T03:04:13+00:00


Hi all,

Sometime ago a customer of mine faced the following issue on his .NET Framework 3.5 app:System.DirectoryServices.AccountManagement.UserPrincipal.IsMemberOfreturned false negativeswhen the group had more than 1500 members. This means that the function returned false when the user was actually in the group. But everything worked properly with VBScript and ADSI.

This turned out to be a limitation on .NET 3.5, which doesn't implement range retrieval for big AD groups (more than 1000/1500 members depending on server version).

My customer ended up applying this really simple workaround: get all groups for a user (around 100 or so in his case), and look for the desired group in that array of groups.

Note that this is not an issue on.NET Framework 4.0, which implementsrange retrievalnow.

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/10/14/global-hooks-getting-lost-on-windows-7/
Post name: Global hooks getting lost on Windows 7
Original author: Alejandro Campos Magencio
Posting date: 2010-10-14T00:23:23+00:00


Hi all,

Some time ago a customer of mine reported the following issue withSetWindowsHookExAPI:

Their application had global hooks to monitor for both keyboard and mouse input. On Windows 7, and under high CPU usage, those hooks were getting lost. They tried several things to solve the issue, without success: adjust registry setting "Control Panel\Desktop\LowLevelKeyboardProc" to 10000 (10sec), restart the hooks every X minutes (withUnhookWindowsHookExandSetWindowsHookEx), etc.At the end, they had to restart the app to reactivate the hooks.

After some research I found out the following:

On Windows 7 we have to make sure that the callback function of the hook can return in less than LowLevelHooksTimeout, which is 300 ms. And weallow for the application to be timed out 10 times when processing the hook callback message. If it times out an 11th time, Windows will unhook the application from the hook chain. This is a by design feature and it was added in Win7 RTM.

My recommendation is that low level hooks should be avoided whenever possible. If you are monitoring keystrokes (and not trying to block them), you can get the keyboard input via Raw Input. This is lighter weight than hooks, won’t affect other apps’ responsiveness, and won’t be turned off if the app isn’t responsive.

My customer got rid of the hooks and used Raw Input instead with success.I hope this helps you too.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/10/13/how-does-cryptoapi-order-the-certificates-in-the-stores/
Post name: How does CryptoAPI order the certificates in the stores?
Original author: Alejandro Campos Magencio
Posting date: 2010-10-13T03:27:38+00:00


Hi all,

The other day a customer of mine was trying to use OWA to sign an email with a specific certificate, with no success.

To put you in situation, he had two certificates with very similar properties, but slightlydifferent. When he accessed OWA, the mime control picked upthe wrong cert, instead of giving them the option to choose between the valid certs in his Personal store.

We debugged the issue and saw that this is by design in OWA: it calls CryptoAPI and goes through the list of available certs until it finds the one that matches certain conditions (valid email address and usage), and uses that one. It doesn't care if there are more valid certs in the list.

So this customer asked us how CryptoAPI orders the certs in the Personal/MY store, in case he could change some property when issuing the certs so they were ordered in a way that the first valid cert that OWA gets is the one he needs.

This is what I found when I debugged the CryptoAPI calls that OWA makes behind the scenes (Disclaimer: The following info is not documented so it may change at any time without warning):

We call CertOpenStore to access the Personal/MY certificate store. There we create an internal list with all available certs. To create that list we go through the available certs by thumbprint (normally a SHA1 hash of the cert). This is an example of the order on which we will read the certs:

0046EA83C83F13336353423F4ED54DA2D118D8AD
19D00F25CAA644C3C41D46BF628EB62B3539BC87 (The one we want OWA to use)
C08025194F09B03C16AB87EA2BCD5D31DBE7738F (The one OWA uses)

In the list we create, the first element of the list is the last one that gets inserted. So the list for the above certs will look like this:

C08025194F09B03C16AB87EA2BCD5D31DBE7738F--> 19D00F25CAA644C3C41D46BF628EB62B3539BC87--> 0046EA83C83F13336353423F4ED54DA2D118D8AD

Now, when we go through it with CertEnumCertificatesInStore, the first cert we get is C08025194F09B03C16AB87EA2BCD5D31DBE7738F. The properties of this cert match what OWA expects, so OWA won't keep looking and we won't get to the next cert in the list, 19D00F25CAA644C3C41D46BF628EB62B3539BC87, the one we wanted to use.

If we are lucky, the cert we want will be the first one on the list. But there is no way for us to affect this behavior by e.g. changing the properties of the cert, as we have no idea which hash will get generated for our cert.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2010/10/13/how-to-read-mstsprofilepath-mstshomedrive-and-mstshomedirectory-properties-from-ad-vb-net/
Post name: How to read msTSProfilePath, msTSHomeDrive and msTSHomeDirectory properties from AD (VB.NET)
Original author: Alejandro Campos Magencio
Posting date: 2010-10-13T02:45:00+00:00


Hi all,

If you used to query Active Directory properties like TerminalServicesProfilePath, TerminalServicesHomeDrive and TerminalServicesHomeDirectory on Windows Server 2003, you may have realized already that those properties are not available on Windows Server 2008 and later. If you investigate a bit, you may find some properties which are supposed to be their substitutes: msTSProfilePath, msTSHomeDrive and msTSHomeDirectory. But if you try to query them with a code like the following, it won’t work. You will get empty strings for those properties.

Dim myUser = New DirectoryEntry(myPath)

' This works fine on Win2003, but fails on Win2008, as expected
'
Try
MsgBox(myUser.InvokeGet("TerminalServicesHomeDirectory").ToString)
Catch ex As Exception
MsgBox(ex.Message)
End Try

' This fails on Win2003 as expected, but returns an empty string on Win2008
'
Try
MsgBox(myUser.InvokeGet("msTSHomeDirectory").ToString)
Catch ex As Exception
MsgBox(ex.Message)
End Try

It turns out that those properties are implemented and meant to be used to store that information, but we neither use them nor do we store the info in those properties (yet).

That information is written into the userParameters datablob which is readable through Tsuserex.dll exports.The recommended approach would be to build an app that will cover future scenarios: check for the new properties as shown above, and if empty, useTsuserex.dllexports.

This is the interface we need to use:

IADsTSUserEx Interface

And some info on the Tsuserex.dll library that implements it:

Using the ADSI Extension for Remote Desktop Services User Configuration

ADSI Extension for Remote Desktop Services User Configuration

These are the properties which correspond to msTSProfilePath, msTSHomeDrive or msTSHomeDirectory:

IADsTSUserEx::TerminalServicesProfilePath Property

IADsTSUserEx::TerminalServicesHomeDrive Property

IADsTSUserEx::TerminalServicesHomeDirectory Property

Now, I couldn’t find any official sample from MS, only this C++ sample copied from MSDN (note I couldn’t find the original web page where they copied this from, so the info is likely to be a bit old):

ADSI Terminal Server Extensions (IADsTSUserEx)

And here is the translation of that sample to C#:

Configuring Terminal Services attributes using .NET

Converting this sample to VB.NET should be quite straightforward.

Now, I tried to create a VB.NET sample on my Windows 7, but I couldn’t find the Tsuserex.dll library. But I found that that library is in the server versions of Windows.

using IADsTSUserEx on Windows 7

So I copied the dll from my Windows Server 2008 R2 to my Windows 7, I registered with regsvr32, and added it as a reference to my sample project.

Then I created this sample code:

Imports System.DirectoryServices
Imports TSUSEREXLib


Dim rootLDAPpath As String = "LDAP://OU=...,DC=com"
Dim root As DirectoryEntry = New DirectoryEntry(rootLDAPpath)
Dim searcher As New DirectorySearcher(root)
Dim adUser As SearchResult

searcher.Filter() = "(&(objectCategory=user)(samAccountName=alejacma))"
adUser = searcher.FindOne

Dim myUser = New DirectoryEntry(adUser.Path)

' Get the properties
Dim tsUser = CType(myUser.NativeObject, IADsTSUserEx)
MsgBox(tsUser.TerminalServicesProfilePath)
MsgBox(tsUser.TerminalServicesHomeDrive)
MsgBox(tsUser.TerminalServicesHomeDirectory)

' Set the properties
tsUser.TerminalServicesHomeDirectory = ...
...
myUser.CommitChanges()

Taking this code as a base we werer able to both read and modify those properties.

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)