PaulIA Posted December 6, 2006 Posted December 6, 2006 (edited) I have been working for the last couple of days on this and I've reached the point where I need assistance from somebody with better COM skills than I have. The problem appears when I try to convert a byte array returned from a COM call. When I write a VBS wrapper to convert the array, it returns the value correctly. I have included the script below that shows the problem. Any assistance as to what I'm doing wrong would be appreciated. expandcollapse popupOpt("MustDeclareVars", 1) ; ================================================================================================= Global $oError, $aSid, $sUserName ; ================================================================================================= $oError = ObjEvent("AutoIt.Error", "ComError") $sUserName = InputBox("Username", "Please enter a username:", "Administrator") if @Error then Exit $aSid = GetUserSid($sUserName) if @Error then ConsoleWrite($sUserName & " does not exist on local machine") Exit EndIf ; ================================================================================================= GetSidAIT($aSid) ; <-- These two calls should produce the same output? GetSidVBS($aSid) ; <-- ; ================================================================================================= Func GetSidAIT($aSid) Local $rSid, $sSid $rSid = DllStructCreate("byte[28]") DllStructSetData($rSid, 1, $aSID) for $iI = 1 to 28 $sSid = $sSid & Hex(DllStructGetData($rSid, 1, $iI), 2) next ConsoleWrite("AutoIT Sid ...: " & $sSid & @CR) EndFunc ; ================================================================================================= Func GetSidVBS($aSid) Local $sCode, $oVBS $sCode = "Function OctetToHexStr(Octet)" $sCode = $sCode & @CR & "Dim I" $sCode = $sCode & @CR & "For I = 1 To LenB(Octet)" $sCode = $sCode & @CR & " OctetToHexStr = OctetToHexStr & Right(""0"" & Hex(Ascb(Midb(Octet, I, 1))), 2)" $sCode = $sCode & @CR & "Next" $sCode = $sCode & @CR & "end Function" $oVBS = ObjCreate("ScriptControl") $oVBS.Language = "vbscript" $oVBS.AddCode($sCode) ConsoleWrite("VBS Sid ......: " & $oVBS.Run("OctetToHexStr", $aSID) & @CR) EndFunc ; ================================================================================================= Func GetUserSid($sUserName) Local $sCode, $oVBS $sCode = "Function GetUserSid(UserName)" $sCode = $sCode & @CR & 'Set oSid = GetObject("WinNT://./' & $sUserName & '")' $sCode = $sCode & @CR & 'GetUserSid = oSid.objectSID' $sCode = $sCode & @CR & 'end Function' $oVBS = ObjCreate("ScriptControl") $oVBS.Language = "vbscript" $oVBS.AddCode($sCode) Return $oVBS.Run("GetUserSid", $sUserName) EndFunc ; ================================================================================================= Func ComError() if IsObj($oError) then SetError(Hex($oError.Number)) else SetError(1) endif EndFunc Edit: Provided example that doesn't require Active Directory Edited December 9, 2006 by PaulIA Auto3Lib: A library of over 1200 functions for AutoIt
Valik Posted December 6, 2006 Posted December 6, 2006 An example of what you get and what you expect would be useful.
PaulIA Posted December 7, 2006 Author Posted December 7, 2006 (edited) An example of what you get and what you expect would be useful.The demo actually prints these values for you. The GetSidVBS prints what I expect and the GetSidAIT prints what I get when I attempt to duplicate the VBS function in AutoIt. I'm sure I'm just screwing up the transfer of the byte array from the COM object to the AutoIt structure, but I'm tapped as to what I'm doing wrong. Here is the console print out when I run this on my machine: AutoIT Sid ...: 407E4500000000000000000000000000000000000000000000000000 VBS Sid ......: 010500000000000515000000456C8711DC5727E9FEE12033F4010000 Edit: Added example printout values Edited December 7, 2006 by PaulIA Auto3Lib: A library of over 1200 functions for AutoIt
Valik Posted December 7, 2006 Posted December 7, 2006 You're making the assumption I can run the example. I can not, I get the "Username does not exist" error regardless of whether the user actually exists or not.
flyingboz Posted December 7, 2006 Posted December 7, 2006 I get the "Username does not exist" error regardless of whether the user actually exists or not.Ditto. Is your code supposed to handle a user who is not authenticated via a domain controller? Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.
PaulIA Posted December 7, 2006 Author Posted December 7, 2006 Ditto. Is your code supposed to handle a user who is not authenticated via a domain controller?No, it's only suppose to work for AD. I thought all of the references to the Active Directory constants would be a dead give away. Auto3Lib: A library of over 1200 functions for AutoIt
Valik Posted December 7, 2006 Posted December 7, 2006 It is a giveaway, but it does hurt your chances of getting an answer. Presumably you want a developer to help (based on the forum you're posting in). But when you filter down the number of developers with COM knowledge and then further filter that down to those with AD access and finally you take into account that some of us are less active than others, well, that doesn't leave too many people.
PaulIA Posted December 7, 2006 Author Posted December 7, 2006 It is a giveaway, but it does hurt your chances of getting an answer. Presumably you want a developer to help (based on the forum you're posting in). But when you filter down the number of developers with COM knowledge and then further filter that down to those with AD access and finally you take into account that some of us are less active than others, well, that doesn't leave too many people.True. Maybe I can find another COM call that exhibits the same behavior. I'll look around and see if I can find something that returns a byte array and will run on a generic PC. Auto3Lib: A library of over 1200 functions for AutoIt
PaulIA Posted December 9, 2006 Author Posted December 9, 2006 I rewrote the example so that it will return a byte array when used on a local machine. Any help would be appreciated. Auto3Lib: A library of over 1200 functions for AutoIt
Valik Posted December 9, 2006 Posted December 9, 2006 If I understand the code (AutoIt's, not yours) correctly, quite simply, SAFEARRAYs are not implemented. It's implemented for just a couple types but not for bytes. The reason I think VBS works is because while AutoIt doesn't put the SAFEARRAY into a format you can use, it does keep it intact. Thus when you later pass it back to VBS, VBS sees a perfectly valid VARIANT containing a SAFEARRAY of BYTEs. I'll need to get with SvenP to see where his thinking was on this... limitation. It looks somewhat trivial to me to convert a SAFEARRAY into an array in AutoIt (I believe that AutoIt -> SAFEARRAY works already). I'm not sure why Sven didn't go ahead and do this.
/dev/null Posted December 9, 2006 Posted December 9, 2006 I rewrote the example so that it will return a byte array when used on a local machine. Any help would be appreciated.on my system the AutoIT SID always contains the same value (B7D9420....), no matter which user I select. Looks like a memory location to me.....CheersKurt __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *
Valik Posted December 9, 2006 Posted December 9, 2006 I think that's just garbage. I'm not quite sure what AutoIt is returning but whatever it is, it's actually quite lucky it doesn't cause crash. It's CC a bunch of times under the debugger.
/dev/null Posted December 9, 2006 Posted December 9, 2006 I think that's just garbage. I'm not quite sure what AutoIt is returning but whatever it is, it's actually quite lucky it doesn't cause crash. It's CC a bunch of times under the debugger.Could well be garbage. I used "RtlMoveMemory" to copy the memory content of that "pointer" to a DllStruct. But it returns just garbage...CheersKurt __________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *
arcker Posted December 11, 2006 Posted December 11, 2006 i've this problem tooyou know i work a lot on AD functionbut "garbage" is returned :/it would be really useful to make it work because SID are really important (migration, deleted accounts, etc...)i've the same workaround as PaulIA (look in my tokengroup function)=> using vbsit's some binary data to retrieve, then to convert into stringit's really over my knowledge, and i didn't think it was a bug of autoit, but more an autoit implementation that could be too hard to implement, so i didn't tell anythingbut, i you implement it, it would be just too greatthx for support -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
ptrex Posted December 14, 2006 Posted December 14, 2006 @PaulIA A solution to the problem is to embed VbScript in AutoIT using the ObjCreate("ScriptControl"). This is a workaround for the time being. Example script : expandcollapse popup; Here's a function to emulate vbscript; ; I assume you can find the high , low values mentioned; here is example using vbscript object! ; I don't know if native AutoIt can do it! #include<Date.au3> #include<Array.au3> Func _StampDateAdd($lngHigh,$lngLow,$format = "") Local $s_Quotes='"' ;"" $code= "Function Integer8Date(lngHigh,lngLow)" $code = $code & @CRLF & "Dim WshShell, lngBiasKey,lngTZBias" $code = $code & @CRLF & 'Set WshShell = CreateObject("WScript.Shell")' $code = $code & @CRLF & "lngBiasKey=WshShell.RegRead(""HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias"")" $code = $code & @CRLF & "If UCase(TypeName(lngBiasKey)) = ""LONG"" Then" $code = $code & @CRLF & "lngTZBias = lngBiasKey" $code = $code & @CRLF & "ElseIf UCase(TypeName(lngBiasKey)) = ""VARIANT()"" Then" $code = $code & @CRLF & "lngTZBias = 0" $code = $code & @CRLF & "For k = 0 To UBound(lngBiasKey)" $code = $code & @CRLF & "lngTZBias = lngTZBias + (lngBiasKey(k) * 256^k)" $code = $code & @CRLF & "Next" $code = $code & @CRLF & "End If" $code = $code & @CRLF & "lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) + lngLow) / 600000000 - lngTZBias) / 1440" $code = $code & @CRLF & "Integer8Date = CDate(lngDate)" $code = $code & @CRLF & "end Function" $vbs = ObjCreate("ScriptControl") $vbs.language="vbscript" $vbs.addcode($code) $retour = $vbs.run("Integer8Date",$lngHigh,$lngLow) $vbs="" $Year=StringLeft($retour,4) $Month=StringMid($retour,5,2) $Day=StringMid($retour,7,2) $Hour=StringMid($retour,9,2) $Minute=StringMid($retour,11,2) $Second=StringMid($retour,13,2) ;ConsoleWrite($retour) if $format = "date" then $retourstring = $Day&"/"&$Month&"/"&$Year&" "&$Hour&":"&$Minute&":"&$Second Else $retourstring=$Year&"/"&$Month&"/"&$Day&" "&$Hour&":"&$Minute&":"&$Second EndIf return $retourstring EndFunc;==>_StampDateAdd ;$retour=_datetointeger8("03/01/2006 09:02:16") ;msgbox(0,"",$retour) ;$splithigh=StringMid($retour,1,8) ;$splitlow=StringMid($retour,9,8) ;$retour=_StampDateAdd($splithigh,$splitlow,"date") ;msgbox(0,"YEEEES",$retour) Func _datetointeger8($date) ;Obtain local Time Zone bias from machine registry. Local $s_Quotes='"' $code = "function datetointeger8(date)" ;$code = $code & @CRLF & "Option Explicit" $code = $code & @CRLF & "Dim dtmDateValue, dtmAdjusted, lngSeconds" $code = $code & @CRLF & "Dim WshShell, lngBiasKey,lngTZBias" $code = $code & @CRLF & 'Set WshShell = CreateObject("WScript.Shell")' $code = $code & @CRLF & "dtmDateValue = CDate(date)" $code = $code & @CRLF & "lngBiasKey=WshShell.RegRead(""HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias"")" $code = $code & @CRLF & "If UCase(TypeName(lngBiasKey)) = ""LONG"" Then" $code = $code & @CRLF & "lngTZBias = lngBiasKey" $code = $code & @CRLF & "ElseIf UCase(TypeName(lngBiasKey)) = ""VARIANT()"" Then" $code = $code & @CRLF & "lngTZBias = 0" $code = $code & @CRLF & "For k = 0 To UBound(lngBiasKey)" $code = $code & @CRLF & "lngTZBias = lngTZBias + (lngBiasKey(k) * 256^k)" $code = $code & @CRLF & "Next" $code = $code & @CRLF & "End If" ; Convert datetime value to UTC. $code = $code & @CRLF & "dtmAdjusted = DateAdd(""n"", lngBias, dtmDateValue)" ;' Find number of seconds since 1/1/1601. $code = $code & @CRLF & "lngSeconds = DateDiff(""s"", #1/1/1601#, dtmAdjusted)" ;' Convert the number of seconds to a string ;' and convert to 100-nanosecond intervals. $code = $code & @CRLF & "datetointeger8 = CStr(lngSeconds) & ""0000000""" $code = $code & @CRLF & "end Function" msgbox(0,"",$code) $vbs = ObjCreate("ScriptControl") $vbs.language="vbscript" $vbs.addcode($code) $retour = $vbs.run("datetointeger8",$date) return $retour $vbs="" EndFunc func _getinfotime($champ,$cheminldap) Local $s_Quotes='"' $code= "Function Getinfo(champ,cheminldap)" $code = $code & @CRLF & "Dim objConnection, objChild , string" $code = $code & @CRLF & "Set objEntry = GetObject(""LDAP://"" & cheminldap)" $code = $code & @CRLF & 'proplist = array(champ) ' $code = $code & @CRLF & 'objEntry.getinfoex proplist, 0' $code = $code & @CRLF & 'string = objEntry.Get(champ)' $code = $code & @CRLF & 'Getinfo = string' $code = $code & @CRLF & "end Function" ;msgbox(0,"",$code) $vbs = ObjCreate("ScriptControl") $vbs.language="vbscript" $vbs.addcode($code) $retour = $vbs.run("Getinfo",$champ,$cheminldap) $Year=StringLeft($retour,4) $Month=StringMid($retour,5,2) $Day=StringMid($retour,7,2) $Hour=StringMid($retour,9,2) $Minute=StringMid($retour,11,2) $Second=StringMid($retour,13,2) $retour = $Day&"/"&$Month&"/"&$Year&" "&$Hour&":"&$Minute&":"&$Second return $retour $vbs="" endfunc I hope this helps regards ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
PaulIA Posted December 14, 2006 Author Posted December 14, 2006 While I always appreciate a helping hand, you might want to reread the first post in this thread. See that embedded VBS script... Auto3Lib: A library of over 1200 functions for AutoIt
ptrex Posted December 14, 2006 Posted December 14, 2006 While I always appreciate a helping hand, you might want to reread the first post in this thread. See that embedded VBS script... PaulIASorry didn(t read till the end of the script :"> See you aroundregardsptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now