We are using the following function to get the number of processors specified by the current boot configuration. This number is used purely for logging.
The function below works fine on XP, Vista, 7, 2003 and 2008. It, however, fails on the Windows 2012 Server.
// -1 = not implemented or not allowed
// 0 = not limited
// >0 = number of processors in the {current} boot entry
function Internal_GetBCDNumberOfProcessors: integer;
var
objBcdStore : OleVariant;
objElement : OleVariant;
objWBL : OleVariant;
objWMIService: OleVariant;
begin
// for more info, see: http://stackoverflow.com/questions/7517965/accessing-bcdstore-from-delphi/7527164#7527164
Result := -1;
try
objWMIService := GetObject('winmgmts:{(Backup,Restore)}\\.\root\wmi:BcdStore');
if (not VarIsNull(objWMIService)) and
boolean(objWMIService.OpenStore('', objBcdStore)) and
(not VarIsNull(objBcdStore)) and
boolean(objBcdStore.OpenObject('{fa926493-6f1c-4193-a414-58f0b2456d1e}', objWBL)) and
(not VarIsNull(objWBL))
then
if objWBL.GetElement($25000061, objElement) and //<-- fails here on Server 2012
(not VarIsNull(objElement))
then
Result := StrToIntDef(objElement.Integer, 0)
else
Result := 0;
except
on E: EOleSysError do
Result := -1;
end;
end;
If I try to run it on Win2012, the objWBL.GetElement
raises EOleSysError
exception with text OLE error D0000225
. Google doesn't find anything meaningful related to this error code :(
Stack trace says that the exception is triggered in System.Win.ComObj.DispatchInvokeError which is called by the DispatchInvoke which is called by the VarDispInvoke.
All this was reproduced using XE2. I could try to repeat the problem with XE3 but I don't believe Delphi RTL has anything to do with it.
Does anybody has any idea about possible reasons for this behaviour?
The GetElement
part:
if objWBL.GetElement($25000061, objElement) and //<-- fails here on Server 2012
(not VarIsNull(objElement))
then
Result := StrToIntDef(objElement.Integer, 0)
else
Result := 0;
can be replace with EnumerateElements
:
if objWBL.EnumerateElements(objArray) then try
for i := VarArrayLowBound(objArray, 1) to VarArrayHighBound(objArray, 1) do begin
objElement := objArray[i];
if objElement.Type = $25000061 then
Exit(objElement.Integer);
end;
finally VarClear(objArray); end;
This doesn't raise the EOleException
, but sadly also doesn't find the NumberOfProcessors
element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With