Code :
#!/usr/local/bin/perl use strict; use warnings; use Win32; use Win32::API; $Win32::API::DEBUG = 1; my $MultiByteToWideChar = new Win32:: API("KERNEL32", "MultiByteToWideChar", "INPIPI", "I" ) or die "Can't Import OLE32 or find MultiByteToWideChar"; my $CLSIDFromProgID = new Win32:: API("OLE32", "CLSIDFromProgID", "PP", "N" ) or die "Can't Import OLE32 or find CLSIDFromProgID"; my $StringFromCLSID = new Win32:: API("OLE32", "StringFromCLSID", "PP", "N" ) or die "Can't Import OLE32 or find StringFromCLSID"; my $CLSIDFromString = new Win32:: API("OLE32", "CLSIDFromString", "PP", "N" ) || die "Can't find CLSIDFromString: $!\n"; # On va tester avec ce cas trouve dans la base de registres #WMP.DeskBand.1 <= ProgID #HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0A4286EA-E355-44FB-8086-AF3DF7645BD9} <= Windows Media Player my $progid = "WMP.DeskBand.1"; my $oleprogid = COlestr($progid); # translate it to wide chars my $classid = "\0" x 16; # 16 bytes data my $result = $CLSIDFromProgID->Call($oleprogid, $classid ); if ($result) { printf "Error: 0x%x\n", $result; } else { # vérifions que l'appel a marche my ($data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11) = unpack 'LSSC8', $classid; printf "{%x-%x-%x-%x%x-%x%x%x%x%x%x}\n", $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11; # on devrait avoir {0A4286EA-E355-44FB-8086-AF3DF7645BD9} } my $PPV = pack 'P', 0; # au retour, contiendra la OLESTR allouee my $ppv = pack 'P', $PPV; # C'est tordu, fallait le trouver, pour le parametre LPOLESTR * $result = $StringFromCLSID->Call($classid, $ppv); if ($result) { printf "Error: 0x%x\n", $result; } else { # on devrait avoir {0A4286EA-E355-44FB-8086-AF3DF7645BD9} chaque lettre occupant 2 cases } # note: $PPV doit etre desalloué par un appel a OLE si on est un bon petit programmeur # respectueux de la mémoire qui ne lui appartient pas... my $newstring = $PPV . "\0"; # le retour etait un OLESTR, pas un COLESTR et c'etait un piege $classid = "\0" x 16; # 16 bytes data $result = $CLSIDFromString->Call($newstring, $classid); if ($result) { printf "Error: 0x%x\n", $result; } else { my ($data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11) = unpack 'LSSC8', $classid; printf "{%x-%x-%x-%x%x-%x%x%x%x%x%x}\n", $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11; # on devrait avoir {0A4286EA-E355-44FB-8086-AF3DF7645BD9} } #test avec une string en ascii $newstring = '{0A4286EA-E355-44FB-8086-AF3DF7645BD9}'; $oleprogid = COlestr($newstring); $classid = "\0" x 16; # 16 bytes data $result = $CLSIDFromString->Call($oleprogid, $classid); if ($result) { printf "Error: 0x%x\n", $result; } else { my ($data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11) = unpack 'LSSC8', $classid; printf "{%x-%x-%x-%x%x-%x%x%x%x%x%x}\n", $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11; # on devrait avoir {0A4286EA-E355-44FB-8086-AF3DF7645BD9} } # la subroutine perl StringIDToClassID fait aussi bien $newstring = '{0A4286EA-E355-44FB-8086-AF3DF7645BD9}'; my $refclsid = StringIDToClassID($newstring); $result = $StringFromCLSID->Call($refclsid, $ppv); if ($result) { printf "Error: 0x%x\n", $result; } else { # on devrait avoir {0A4286EA-E355-44FB-8086-AF3DF7645BD9} chaque lettre occupant 2 cases } # transforme une chaine en ansi en une en wide chars sub Olestr { my $olestring = "\0" x (2*$lg); $MultiByteToWideChar->Call(0, 0, $ansistr, $lg, $olestring, $lg); } # transforme une chaine en ansi en une en wide chars terminée par un \0 # ne pas l'avoir fait a ete la principale source de bugs qui faisait que # les appels foiraient sub COlestr { my $olestring = "\0" x (2*$lg); $MultiByteToWideChar->Call(0, 0, $ansistr, $lg, $olestring, $lg); $olestring = $olestring . "\0"; } # On peut aussi le faire en perl sans passer par des appels OLE # La chaine en entree est en ansi, pas en wide chars sub StringIDToClassID { my @c = split /-/, $strID; my $classID = pack 'LSSC8', }
|