Bug #71879 [Opn]: Variant type changed with PHP7 x64 with lange values (VT_R8 -> VT_I8)
| From: | markus dot demml at bmlvs dot gv dot at | Date: | Fri, 26 Jan 2018 10:44:47 +0000 |
| Subject: | Bug #71879 [Opn]: Variant type changed with PHP7 x64 with lange values (VT_R8 -> VT_I8) | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-213712@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=71879&edit=1
ID: 71879
User updated by: markus dot demml at bmlvs dot gv dot at
Reported by: markus dot demml at bmlvs dot gv dot at
-Summary: Variant type VT_ARRAY as output parameter invalid
+Summary: Variant type changed with PHP7 x64 with lange values
(VT_R8 -> VT_I8)
Status: Open
Type: Bug
Package: COM related
Operating System: Windows 7 x64
-PHP Version: 7.0.4
+PHP Version: 7.x x64
Block user comment: N
Private report: N
New Comment:
I've tested this problem again with all current released versions, resulting thats only a
problem with PHP 7 x64
ok with:
* php-5.6.33-Win32-VC11-x64
* php-5.6.33-Win32-VC11-x86
* php-7.0.27-Win32-VC14-x86
* php-7.1.13-Win32-VC14-x86
* php-7.2.1-Win32-VC15-x86
error with:
* php-7.0.27-Win32-VC14-x64
* php-7.1.13-Win32-VC14-x64
* php-7.2.1-Win32-VC15-x64
I found that RegRead works properly and GetStringValue doesn't.
$WSH = new COM("WScript.Shell");
$value1 = $WSH->RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion');
$StdRegProv = new COM("WinMgmts://localhost/root/default:StdRegProv");
$value2 = new VARIANT("", VT_BSTR); // 8
$retval = $StdRegProv->GetStringValue(0x80000002, 'SOFTWARE\Microsoft\Windows
NT\CurrentVersion','CurrentVersion' , $sValue);
With some other checks and PHP Source reading I found that the Value 0x80000002 makes the difference
with the function php_com_variant_from_zval
with PHP x86 and PHP 5.6 x64 -> case IS_DOUBLE:
variant_get_type( new VARIANT(0x80000002 /* 2147483650 */)); // 5 = VT_R8
with PHP 7 x64 -> case IS_LONG:
variant_get_type( new VARIANT(0x80000002 /* 2147483650 */)); // 20 = VT_UI8 / VT_I8 ?
-> changed with https://github.com/php/php-src/commit/26e7e54e782d8ba80a7f964f0bfcc3a7920349c2
--
If you pin the types, every version is working properly
// uint32 = GetStringValue(uint32 hDefKey, string sSubKeyName, string sValueName, string
&sValue) // Gets the string data value of a named value.
$sSubKeyName = new VARIANT('SOFTWARE\Microsoft\Windows NT\CurrentVersion', VT_BSTR); // 8
$sValueName = new VARIANT('CurrentVersion', VT_BSTR); // 8
$sValue = new VARIANT("", VT_BSTR); // 8
$hDefKey = new VARIANT(0x80000002 /* 2147483650 */, VT_R8 ); // 5
$StdRegProv = new COM("WinMgmts://localhost/root/default:StdRegProv");
$retval = $StdRegProv->GetStringValue($hDefKey, $sSubKeyName,$sValueName , $sValue);
// $sValue = "6.1" on Win7
---
The posted test scripts works correctly on PHP 7.x x64 if you fix the type to VT_R8
define('HKEY_LOCAL_MACHINE', 0x80000002);
$StdRegProv = new
COM("WinMgmts:{impersonationLevel=impersonate}//localhost/root/default:StdRegProv");
$valueNames = new Variant(array(), VT_ARRAY);
$valueTypes = new Variant(array(), VT_ARRAY);
$hDefKey = new Variant(HKEY_LOCAL_MACHINE, VT_R8); // patch
try {
$StdRegProv->EnumValues($hDefKey, "SOFTWARE\Microsoft\Windows NT\CurrentVersion",
$valueNames, $valueTypes);
foreach($valueNames as $name) {
echo "[" . __LINE__ . "] " . "name: $name \n";
}
foreach($valueTypes as $type) {
echo "[" . __LINE__ . "] " . "type: $type \n";
}
} catch (Exception $e) {
echo "[" . __LINE__ . "] " . "Exception $e\n";
echo "[" . __LINE__ . "] " . "var_dump:\n"; var_dump($e);
echo "[" . __LINE__ . "] " . "print_r:\n"; print_r($e);
}
----
* I don't understand why i can't use VT_UI4 for hDefKey but thats an API and no PHP
problem, isn't?
* VT_UI8 and VT_I8 are not documented http://php.net/manual/en/com.constants.php
* was this change VT_R8 to VT_I8 intended or a side effect ?
Previous Comments:
------------------------------------------------------------------------
[2016-03-22 10:06:48] markus dot demml at bmlvs dot gv dot at
Description:
------------
With PHP 7.0.4 (x64) i get an com_exception "Type mismatch" from the WMI-Functions
EnumValues, EnumKey but this works with 5.6.19 5.5.33 5.5.29 5.5.12.
I used php.ini-development with these changes:
extension_dir = "ext"
extension=php_com_dotnet.dll
Test script:
---------------
define('HKEY_LOCAL_MACHINE', 0x80000002);
$StdRegProv = new
COM("WinMgmts:{impersonationLevel=impersonate}//localhost/root/default:StdRegProv");
$valueNames = new Variant(array(), VT_ARRAY); // also new Variant(array())
$valueTypes = new Variant(array(), VT_ARRAY); // also new Variant(array())
try {
$StdRegProv->EnumValues(HKEY_LOCAL_MACHINE, "SOFTWARE\PhpTestRegEnum", $valueNames,
$valueTypes);
foreach($valueNames as $name) {
echo "[" . __LINE__ . "] " . "name: $name \n";
}
foreach($valueTypes as $type) {
echo "[" . __LINE__ . "] " . "type: $type \n";
}
} catch (Exception $e) {
echo "[" . __LINE__ . "] " . "Exception $e\n";
echo "[" . __LINE__ . "] " . "var_dump:\n"; var_dump($e);
echo "[" . __LINE__ . "] " . "print_r:\n"; print_r($e);
}
Expected result:
----------------
C:\php-5.6.19-Win32-VC11-x64>php ..\test-registry-access-shortversion.php
[9]name: test-reg_sz
[9]name: test-reg_bin
[9]name: test-reg_dword_32
[9]name: test-reg_qword_64
[9]name: test-reg_multi_sz
[12]type: 1
[12]type: 3
[12]type: 4
[12]type: 11
[12]type: 7
Actual result:
--------------
C:\php-7.0.4-Win32-VC14-x64>php ..\test-registry-access-shortversion.php
[15]Exception com_exception: Source: SWbemObjectEx
Description: Type mismatch in C:\test-registry-access-shortversion.php:7
Stack trace:
#0 C:\test-registry-access-shortversion.php(7): com->EnumValues(2147483650,
'SOFTWARE\\PhpTes...', Object(variant), Object(variant))
#1 {main}
[16]var_dump:
...
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=71879&edit=1