Powershell [ComponentModel.Win32Exception] casting inconsistencies


I am trying to get my head around windows errors, especially the relationship between Win32 errors and HRESULT errors.

So, as an example I know 3010 is

"The requested operation is successful. Changes will not be effective until the system is rebooted"

And I can get that by casting to ComponentModel.Win32Exception thus: [ComponentModel.Win32Exception]3010.

Also, I know that 3010 is expressed in hex as 0x00000BC2 or 0x0BC2, and I can cast both of those as well. But it can also be expressed as 0x80070bc2, and this will cast properly. And it can even be expressed as 0xFFFFFFFF80070BC2. Here, as a 64 bit hex value it won't cast. But, 0xFFFFFFFF80070BC2 is -2147021886 in decimal, and that will cast. And it's a return value that can be expected, as documented here.

Similarly 0 decimal can be expressed in hex as 0x0000 and 0x00000000 and those cast fine and return

"The operation completed successfully"

But 0xFFFFFFFF00000000 and the decimal equivalent -4294967296 won't cast, they both return the decimal value. But I have gotten that decimal value returned from an installer, and the website referenced above also includes that decimal value.

So, at times when running installers from various vendors I have seen 0, -4294967296, 3010 & -2147021886 returned, and in three of the four situations I can cast to get a meaningful message for the user, and in one I can't.

So, to sum up, why are these BAD values bad, and why are they inconsistent, and what is the best way to deal with values like -4294967296 or -2147945410, the latter of which may never show up, but the former of which I have seen.

[ComponentModel.Win32Exception]3010 # Good
[ComponentModel.Win32Exception]0x0BC2 # Good

[ComponentModel.Win32Exception]-2147021886 # Good
[ComponentModel.Win32Exception]0x00000BC2 # Good
[ComponentModel.Win32Exception]0x0000000000000BC2 # Good

[ComponentModel.Win32Exception]-2147945410 # BAD
[ComponentModel.Win32Exception]0x80070BC2 # Good
[ComponentModel.Win32Exception]0x0000000080070BC2 # Good

[ComponentModel.Win32Exception]0 # Good
[ComponentModel.Win32Exception]0x0000 # Good

[ComponentModel.Win32Exception]0x00000000 # Good
[ComponentModel.Win32Exception]0x0000000000000000 # Good

[ComponentModel.Win32Exception]0xFFFFFFFF00000000 # BAD
[ComponentModel.Win32Exception]-4294967296 # BAD

EDIT: So, I have dug around a bit, and I THINK this might work.

foreach ($errCode in @(0, 3010, -2147021886, -4294967296)) {
    [int]$intCode = $errCode -band 0xFFFF

For the four values in question it does, but I'll need to test with a bunch of others too. Still just don't understand why Microsoft Autodesk and the rest will return values that can't be used easily. Why not just use nothing but the damn Win32 codes and be done with it? And why is 0x80070BC2 treated the same as 0x00000BC2 and both work, but their decimal equivalents are treated differently and only one works?

asked on Stack Overflow Jul 29, 2019 by Gordon • edited Jul 29, 2019 by Gordon

0 Answers

Nobody has answered this question yet.

User contributions licensed under CC BY-SA 3.0