cojms1 Posted July 10, 2006 Posted July 10, 2006 Hi, I'm workiong on some code to enumerate the services that are running on a machine. Below is the code I currently have. Thes structure in question is: - typedef struct _ENUM_SERVICE_STATUS { LPTSTR lpServiceName; LPTSTR lpDisplayName; SERVICE_STATUS ServiceStatus; } ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS; lpServiceName The name of a service in the service control manager database. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. A slash (/), backslash (\), comma, and space are invalid service name characters. lpDisplayName A display name that can be used by service control programs, such as Services in Control Panel, to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the service control manager. Display name comparisons are always case-insensitive. The question is which data type do I use to represent LPTSTR? If I currently have the correct type then how do I retrieve the string from the pointer given? expandcollapse popup;********************************************* ; Aim: To retrieve a list of the services ;********************************************* Func EnumerateServices($dwServiceType = 0x30, $dwServiceState = 0x3) $pagResults = 20 $lenStruct = 9 $hndSCM = GetServiceManagerHandle() $cbBufSize = 0 $cbBytesNeeded = DllStructCreate("dword") $pcbBytesNeeded = DllStructGetPtr($cbBytesNeeded) $ServicesReturned = DllStructCreate("dword") $lpServicesReturned = DllStructGetPtr($ServicesReturned) $ResumeHandle = DllStructCreate("dword") $lpResumeHandle = DllStructGetPtr($ResumeHandle) DllStructSetData($lpResumeHandle, 1, 0) $ret = DllCall("advapi32.dll", "int", "EnumServicesStatus", "int", $hndSCM, "int", $dwServiceType, "int", $dwServiceState, "int", 0, "int", 0, "ptr", $pcbBytesNeeded, "ptr", $lpServicesReturned, "int", 0) $ret = DllCall("kernel32.dll", "int", "GetLastError") if $ret[0] = $ERROR_MORE_DATA then $strEnumServiceStatus = "int;int" $strServiceStatus = "dword;dword;dword;dword;dword;dword;dword" $_ENUM_SERVICE_STATUS = DllStructCreate($strEnumServiceStatus & ";" & $strServiceStatus) $size = DllStructGetSize($_ENUM_SERVICE_STATUS) $needed = Round((DllStructGetData($cbBytesNeeded, 1) / $size) + 1) $cbBufSize = $pagResults * $size $strTemp = _StringRepeat($strEnumServiceStatus & ";" & $strServiceStatus & ";", $pagResults) $strTemp = StringTrimRight($strTemp, 1) $_ENUM_SERVICE_STATUS = 0 $_ENUM_SERVICE_STATUS = DllStructCreate($strTemp) ;do $ret = DllCall("advapi32.dll", "int", "EnumServicesStatus", "int", $hndSCM, "int", $dwServiceType, "int", $dwServiceState, "ptr", DllStructGetPtr($_ENUM_SERVICE_STATUS), "int", $cbBufSize, "ptr", $pcbBytesNeeded, "ptr", $lpServicesReturned, "ptr", $lpResumeHandle) $ret = DllCall("kernel32.dll", "int", "GetLastError") $numEntries = DllStructGetData($ServicesReturned, 1) msgbox(0, "", $numEntries) if $numEntries <> 0 then for $i = 1 to $numEntries $strTemp = "" $offset = (($i -1) * $lenStruct) $strServiceName = "" for $j = 1 to $lenStruct $strTemp &= DllStructGetData($_ENUM_SERVICE_STATUS, $offset + $j) & @crlf next msgbox(0, "", $strTemp) next endif ;until $ret[0] <> $ERROR_MORE_DATA endif $_ENUM_SERVICE_STATUS = 0 CloseServiceHandle($hndSCM) EndFunc Any help appreciated.
w0uter Posted July 10, 2006 Posted July 10, 2006 (edited) I think you want DllStructCreate('char[256]', $pointer) Edited July 10, 2006 by w0uter My UDF's:;mem stuff_Mem;ftp stuff_FTP ( OLD );inet stuff_INetGetSource ( OLD )_INetGetImage _INetBrowse ( Collection )_EncodeUrl_NetStat_Google;random stuff_iPixelSearch_DiceRoll
Nomad Posted July 10, 2006 Posted July 10, 2006 It states that it's a string(for the first), which would be a 'char' type. It also states that it has a maximum of 256 characters, so I'd try making the type 'char[257]'. That should also tell you what you should do with the 2nd. Nomad
Valik Posted July 10, 2006 Posted July 10, 2006 Am I missing something? Doesn't the basic DllCall() type "str" do this? Rule number one of using DllCall() is don't over-complicate it by using DllStruct stuff when DllCall() can do it natively.
w0uter Posted July 10, 2006 Posted July 10, 2006 i think you are missing this: typedef struct _ENUM_SERVICE_STATUS { LPTSTR lpServiceName; LPTSTR lpDisplayName; SERVICE_STATUS ServiceStatus; } ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS; My UDF's:;mem stuff_Mem;ftp stuff_FTP ( OLD );inet stuff_INetGetSource ( OLD )_INetGetImage _INetBrowse ( Collection )_EncodeUrl_NetStat_Google;random stuff_iPixelSearch_DiceRoll
Valik Posted July 10, 2006 Posted July 10, 2006 Ahhh, it's part of a structure. My second comment still stands. I see a couple places where a DWORD is created. A DWORD is the same size of an int so that's just redundant (Remember, int_ptr, too).
cojms1 Posted July 11, 2006 Author Posted July 11, 2006 Here's a link to the call definition on MSDN.BOOL WINAPI EnumServicesStatus( SC_HANDLE hSCManager, DWORD dwServiceType, DWORD dwServiceState, LPENUM_SERVICE_STATUS lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned, LPDWORD lpResumeHandle );typedef struct _ENUM_SERVICE_STATUS { LPTSTR lpServiceName; LPTSTR lpDisplayName; SERVICE_STATUS ServiceStatus; } ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;It says that lpServices is a point to an array of ENUM_SERVICE_STATUS.From what I can gather I would define ENUM_SERVICE_STATUS and then use DllStructGetPtr to get the pointer to that structure. How do I create an array of that structure? I do not now how many services will be returned, even after the 1st call that is being used to get the size of the buffer required.If I assign lpServiceName and lpDisplayName as char[257] then the size of the structure cannot be used to to determine the size of the array required.I am working from VB source which can be found hereAny help is greatly appreciated.
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