Krakatoa Posted August 3, 2014 Share Posted August 3, 2014 (edited) Grrr.No old script!3.3.8.1 = 16-Nov-2012win 8.1, advapi32.dll, OpenServiceOpenService is normal function in Win 8.1 advapi32.dll, no old!Compile 32bit autoit script with service function with autoit version 3.3.8.1 = no bug! Advapi32.dll + OpenService = no error 6Compile 64bit autoit script with service function with autoit version 3.3.8.1 = no bug! Advapi32.dll + OpenService = no error 6Compile 32bit autoit script with service function with autoit version 3.3.10.2 and 3.3.12.0 = no bug! Advapi32.dll + OpenService = no error 6Compile 64bit autoit script with service function with autoit version 3.3.10.2 and 3.3.12.0 = bug! Advapi32.dll + OpenService = error 6! Autoit (3.3.10.2 and 3.3.12.0) compile 64bit exe with bug! Edited August 3, 2014 by Melba23 Resized font Link to comment Share on other sites More sharing options...
wraithdu Posted August 3, 2014 Share Posted August 3, 2014 I hope you're up for learning about DllCall and the Win API. I can almost guarantee that this has to do with improvements and bugfixing in DllCall and DllStruct with respect to parameter sizing and alignment in 64-bit windows. To fix this UDF you're going to have to go through the function calls and correct the parameters by referencing the functions on MSDN. Quick example: OpenService Current implementation (read this as <return: param1, param2, ...> etc) <long: long, str, long> Correct implementation ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms684330(v=vs.85).aspx ) <handle: handle, str, dword> Additionally, for functions that have ANSI and Unicode variants, you should explicitly call one or the other. OpenService really calls either OpenServiceA (ANSI) or OpenServiceW (Unicode). This will change whether your DllCall string parameters are ANSI strings (str) or Unicode strings (wstr). Link to comment Share on other sites More sharing options...
Krakatoa Posted August 4, 2014 Share Posted August 4, 2014 (edited) wraithdu: Added "A" as ANSI. Added handle and dword. Same always: 32bit and 64bit 3.3.8.1 and 32bit 3.3.10.2 and 32bit 3.3.12.0 OK 64bit 3.3.10.2 and 64bit 3.3.12.0 error 6 OpenService. 64bit 3.3.8.1 OK + 64bit 3.3.10.2 and 64bit 3.3.12.0 error 6 OpenService -> 64bit 3.3.10.2 and 64bit 3.3.12.0 bug. expandcollapse popupFunc _StartService($sServiceName) Local $hAdvapi32 Local $hKernel32 Local $arRet Local $hSC Local $hService Local $lError = -1 $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $hKernel32 = DllOpen("kernel32.dll") If $hKernel32 = -1 Then Return 0 $arRet = DllCall($hAdvapi32, "long", "OpenSCManagerA", _ "str", "", _ "str", "ServicesActive", _ "dword", 0x0001) If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "long", "GetLastError") $lError = $arRet[0] MsgBox (0,"error1", $lError) Else $hSC = $arRet[0] MsgBox (0,"$hSC", $hSC) $arRet = DllCall($hAdvapi32, "long", "OpenServiceA", _ "handle", $hSC, _ "str", $sServiceName, _ "dword", 0x0010) If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "long", "GetLastError") $lError = $arRet[0] MsgBox (0,"error2", $lError) Else $hService = $arRet[0] $arRet = DllCall($hAdvapi32, "int", "StartServiceA", _ "long", $hService, _ "long", 0, _ "str", "") If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "long", "GetLastError") $lError = $arRet[0] MsgBox (0,"error3", $lError) EndIf DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService) EndIf DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC) EndIf DllClose($hAdvapi32) DllClose($hKernel32) If $lError <> -1 Then MsgBox (0,"error", $lError) SetError($lError) Return 0 EndIf Return 1 EndFunc Edited August 4, 2014 by Krakatoa Link to comment Share on other sites More sharing options...
BrewManNH Posted August 4, 2014 Share Posted August 4, 2014 What's the return value from the OpenSCManager call? Error 6 means that the handle is invalid and that means that the DLLCall probably failed, because you're not getting a valid handle to pass to StartService. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
wraithdu Posted August 4, 2014 Share Posted August 4, 2014 OpenSCManager and OpenService... a 'long' is not a 'handle'. Your return value is wrong, which I already pointed out. I'm sure your CloseServiceHandle calls are also wrong. Read the help file for DllCall, and consult MSDN for the correct function prototypes. Link to comment Share on other sites More sharing options...
Krakatoa Posted August 4, 2014 Share Posted August 4, 2014 (edited) BrewManNH, wraithdu: Thanks help. Replace type and 64bit 3.3.12.0 no error 6. Valid code (_StartService, _StopService, _ServiceRunning)(ControlService not struct but str (str no problem)). expandcollapse popup;=============================================================================== ; Description: Starts a service ; Parameters: $sServiceName - name of the service to start ; Requirements: None ; Return Values: On Success - 1 ; On Failure - 0 and @error is set to extended Windows error code ; Note: This function does not check to see if the service has started successfully ;=============================================================================== Func _StartService($sServiceName) Local $hAdvapi32 Local $hKernel32 Local $arRet Local $hSC Local $hService Local $lError = -1 $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $hKernel32 = DllOpen("kernel32.dll") If $hKernel32 = -1 Then Return 0 $arRet = DllCall($hAdvapi32, "handle", "OpenSCManagerA", _ "str", "", _ "str", "ServicesActive", _ "dword", 0x0001) If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "dword", "GetLastError") $lError = $arRet[0] Else $hSC = $arRet[0] $arRet = DllCall($hAdvapi32, "handle", "OpenServiceA", _ "handle", $hSC, _ "str", $sServiceName, _ "dword", 0x0010) If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "dword", "GetLastError") $lError = $arRet[0] Else $hService = $arRet[0] $arRet = DllCall($hAdvapi32, "bool", "StartServiceA", _ "handle", $hService, _ "dword", 0x0000, _ "str", "") If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "dword", "GetLastError") $lError = $arRet[0] EndIf DllCall($hAdvapi32, "bool", "CloseServiceHandle", "handle", $hService) EndIf DllCall($hAdvapi32, "bool", "CloseServiceHandle", "handle", $hSC) EndIf DllClose($hAdvapi32) DllClose($hKernel32) If $lError <> -1 Then SetError($lError) Return 0 EndIf Return 1 EndFunc ;=============================================================================== ; Description: Stops a service ; Parameters: $sServiceName - name of the service to stop ; Requirements: None ; Return Values: On Success - 1 ; On Failure - 0 and @error is set to extended Windows error code ; Note: This function does not check to see if the service has stopped successfully ;=============================================================================== Func _StopService($sServiceName) Local $hAdvapi32 Local $hKernel32 Local $arRet Local $hSC Local $hService Local $lError = -1 $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $hKernel32 = DllOpen("kernel32.dll") If $hKernel32 = -1 Then Return 0 $arRet = DllCall($hAdvapi32, "handle", "OpenSCManagerA", _ "str", "", _ "str", "ServicesActive", _ "dword", 0x0001) If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "dword", "GetLastError") $lError = $arRet[0] Else $hSC = $arRet[0] $arRet = DllCall($hAdvapi32, "handle", "OpenServiceA", _ "handle", $hSC, _ "str", $sServiceName, _ "dword", 0x0020) If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "dword", "GetLastError") $lError = $arRet[0] Else $hService = $arRet[0] $arRet = DllCall($hAdvapi32, "bool", "ControlService", _ "handle", $hService, _ "dword", 0x00000001, _ "str", "") If $arRet[0] = 0 Then $arRet = DllCall($hKernel32, "dword", "GetLastError") $lError = $arRet[0] EndIf DllCall($hAdvapi32, "bool", "CloseServiceHandle", "handle", $hService) EndIf DllCall($hAdvapi32, "bool", "CloseServiceHandle", "handle", $hSC) EndIf DllClose($hAdvapi32) DllClose($hKernel32) If $lError <> -1 Then SetError($lError) Return 0 EndIf Return 1 EndFunc ;=============================================================================== ; Description: Checks if a service is running ; Parameters: $sServiceName - name of the service to check ; Requirements: None ; Return Values: On Success - 1 ; On Failure - 0 ; Note: This function relies on the fact that only a running service responds ; to a SERVICE_CONTROL_INTERROGATE control code. Check the ControlService ; page on MSDN for limitations with using this method. ;=============================================================================== Func _ServiceRunning($sServiceName) Local $hAdvapi32 Local $arRet Local $hSC Local $hService Local $bRunning = 0 $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $arRet = DllCall($hAdvapi32, "handle", "OpenSCManagerA", _ "str", "", _ "str", "ServicesActive", _ "dword", 0x0001) If $arRet[0] <> 0 Then $hSC = $arRet[0] $arRet = DllCall($hAdvapi32, "handle", "OpenServiceA", _ "handle", $hSC, _ "str", $sServiceName, _ "dword", 0x0080) If $arRet[0] <> 0 Then $hService = $arRet[0] $arRet = DllCall($hAdvapi32, "bool", "ControlService", _ "handle", $hService, _ "dword", 0x00000004, _ "str", "") $bRunning = $arRet[0] DllCall($hAdvapi32, "bool", "CloseServiceHandle", "handle", $hService) EndIf DllCall($hAdvapi32, "bool", "CloseServiceHandle", "handle", $hSC) EndIf DllClose($hAdvapi32) Return $bRunning EndFunc Edited August 4, 2014 by Krakatoa Link to comment Share on other sites More sharing options...
wraithdu Posted August 4, 2014 Share Posted August 4, 2014 Nicely done. The ControlService function's last parameter is a pointer to a SERVICE_STATUS structure, which it fills in upon error. The correct way to do that would be to create the structure, then pass the pointer to it. The easiest way would be to create an array of 7 dwords, but the best way is to create the actual structure with element names, so you can easily access them later if needed. $tagSERVICE_STATUS = "dword dwServiceType;dword dwCurrentState;dword dwControlsAccepted;dword dwWin32ExitCode; _ dword dwServiceSpecificExitCode;dword dwCheckPoint;dword dwWaitHint" $SERVICE_STATUS = DllStructCreate($tagSERVICE_STATUS) ;; easy way ;$SERVICE_STATUS = DllStructCreate("dword[7]") $ret = DllCall("AdvApi32.dll", "bool", "ControlService", "handle", $hService, "dword", 1, "struct*", $SERVICE_STATUS) Link to comment Share on other sites More sharing options...
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