;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; FileName: List_Svc2.asm
; Function: Demo the way to list system services and their status
; Author: Purple Endurer
; DevEmv: Win XP SP2, MASM32
;
; LOG
; ---------------------------------------------------
; 2006-11-17 Created!
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.386
.model flat, stdcall
option casemap: none
include /masm32/ include/windows.inc
include /masm32/ include/user32.inc
includelib /masm32/ lib/user32.lib
include /masm32/ include/kernel32.inc
includelib /masm32/ lib/kernel32.lib
include /masm32/ include/advapi32.inc
includelib /masm32/ lib/advapi32.lib
WinMain PROTO : DWORD, : DWORD, : DWORD, : DWORD
ResizeConctrol PROTO
ShowServiceInfo PROTO : dword, : dword, : dword
ShowSvcStatusInfo PROTO : dword
ShowSvcData PROTO : dword, : dword, : dword
;.const
IDC_BtnEnum equ 103
IDC_EdtFileSpec equ 105
IDC_EdtVerInfo equ 107
c_GrpSvcTypeTop equ 5
c_GrpSvcTypeLeft equ 2
c_ChkBtnSvcWin32Top equ c_GrpSvcTypeTop+15
c_ChkBtnSvcWin32Left equ c_GrpSvcTypeLeft+5
c_ChkBtnSvcWin32Width equ 150
c_ChkBtnSvcWin32Height equ 15
c_ChkBtnSvcDrvTop equ c_ChkBtnSvcWin32Top+c_ChkBtnSvcWin32Height+5
c_ChkBtnSvcDrvLeft equ c_ChkBtnSvcWin32Left
c_ChkBtnSvcDrvWidth equ c_ChkBtnSvcWin32Width
c_ChkBtnSvcDrvHeight equ c_ChkBtnSvcWin32Height
c_GrpSvcTypeWidth equ c_ChkBtnSvcWin32Width+10
c_GrpSvcTypeHeight equ c_ChkBtnSvcDrvTop+c_ChkBtnSvcDrvHeight+5
c_GrpSvcStateTop equ c_GrpSvcTypeTop
c_GrpSvcStateLeft equ c_GrpSvcTypeLeft+c_GrpSvcTypeWidth+10
c_ChkBtnSvcActTop equ c_GrpSvcStateTop+15
c_ChkBtnSvcActLeft equ c_GrpSvcStateLeft+5
c_ChkBtnSvcActWidth equ 150
c_ChkBtnSvcActHeight equ 15
c_ChkBtnSvcInActTop equ c_ChkBtnSvcActTop+c_ChkBtnSvcActHeight+5
c_ChkBtnSvcInActLeft equ c_ChkBtnSvcActLeft
c_ChkBtnSvcInActWidth equ c_ChkBtnSvcActWidth
c_ChkBtnSvcInActHeight equ c_ChkBtnSvcActHeight
c_GrpSvcStateWidth equ c_ChkBtnSvcActWidth+10
c_GrpSvcStateHeight equ c_ChkBtnSvcInActTop+c_ChkBtnSvcInActHeight+5
c_BtnShowTop equ c_GrpSvcTypeTop
c_BtnShowLeft equ (c_GrpSvcStateLeft+c_GrpSvcStateWidth+10)
c_BtnShowWidth equ 70
c_BtnShowHeight equ 25
c_EdtSvrInfoLeft equ 2
c_EdtSvrInfoTop equ c_GrpSvcTypeTop+c_GrpSvcTypeHeight+5
c_EdtSvrInfoHeight equ 165
c_WinWidth equ c_BtnShowLeft+c_BtnShowWidth + 10 ;c_EdtSvrInfoLeft + c_EdtSvrInfoWidth + 2
c_WinHeight equ c_EdtSvrInfoTop + c_EdtSvrInfoHeight + 45
c_EdtSvrInfoWidth equ c_WinWidth-8-c_EdtSvrInfoLeft
m_CatStr MACRO szStr: REQ
invoke SendMessage, g_hEditSvrInfo, EM_REPLACESEL, FALSE, szStr
ENDM
m_GoNextLine MACRO
invoke SendMessage, g_hEditSvrInfo, EM_REPLACESEL, FALSE, ADDR g_szCR
ENDM
m_MsgBox MACRO lpszMsg: REQ, dwIcon: REQ
invoke MessageBox, g_hWndMain, lpszMsg, OFFSET g_szAppName_cn, dwIcon
ENDM
.data
g_szClsName db "ListSvrCls", 0
g_szAppName_cn db "系统服务列表", 0
g_szEditCls db "EDIT", 0
g_szBtnCls db "button", 0
g_szBtnEnumSvc_cn db "&E 枚举", 0
g_szSERVICE_WIN32 db "SERVICE_WIN32", 0
g_szSERVICE_DRIVER db "SERVICE_DRIVER", 0
g_szSERVICE_ACTIVE db "SERVICE_ACTIVE", 0
g_szSERVICE_INACTIVE db "SERVICE_INACTIVE", 0
g_szChkSvrTypeFirst_cn db "请先选择要枚举的"
g_szServiceType_cn db "服务类型:", 0
g_szChkSvrStateFirst_cn db "请先选择要枚举的"
g_szServiceState_cn db "服务状态:", 0
.data?
g_hInstance HINSTANCE ?
g_hWndMain HANDLE ?
g_hEditFileSpec HANDLE ?
g_hBtnShow HANDLE ?
g_hEditSvrInfo HANDLE ?
g_szFileSpec db 256 dup (?)
g_hGrpServiceType HANDLE ?
g_hChkBtnSvcWin32 HANDLE ?
g_hChkBtnSvcDrv HANDLE ?
g_hGrpServiceState HANDLE ?
g_hChkBtnSvcAct HANDLE ?
g_hChkBtnSvcInAct HANDLE ?
g_dwServiceType dword ?
g_dwServiceState dword ?
.code
start:
invoke GetModuleHandle, NULL
mov g_hInstance, eax
invoke WinMain, g_hInstance, NULL, NULL, SW_SHOWDEFAULT
invoke ExitProcess, eax
WinMain proc hInst: DWORD, hPrevInst: DWORD, CmdLine: DWORD, CmdShow: DWORD
LOCAL wc: WNDCLASSEX
LOCAL msg: MSG
LOCAL hwnd: HWND
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
mov eax, g_hInstance
mov wc.hInstance, eax
mov wc.hbrBackground, COLOR_APPWORKSPACE
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET g_szClsName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx, WS_EX_TOPMOST, ADDR g_szClsName,/
ADDR g_szAppName_cn, WS_OVERLAPPEDWINDOW+WS_VISIBLE,/
CW_USEDEFAULT, CW_USEDEFAULT, c_WinWidth, c_WinHeight,/
NULL, NULL, hInst, NULL
mov hwnd, eax
.while TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (! eax)
;--- process keystrokes directly in the message loop
.if msg.message == WM_SYSKEYUP
.if msg.wParam == VK_E ; Alt + E
invoke PostMessage, hwnd, WM_COMMAND, IDC_BtnEnum, BM_CLICK
.endif
.endif
; ------------------------------------------------
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax, msg.wParam
ret
WinMain endp
WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM
LOCAL rect: RECT
LOCAL hdc: DWORD
.if uMsg==WM_CREATE
mov eax, hWnd
mov g_hWndMain, eax
;--- Create enum button
invoke CreateWindowEx, NULL, addr g_szBtnCls, addr g_szBtnEnumSvc_cn,/
WS_CHILD+WS_VISIBLE, c_BtnShowLeft, c_BtnShowTop, c_BtnShowWidth, c_BtnShowHeight,/
hWnd, IDC_BtnEnum, g_hInstance, NULL
mov g_hBtnShow, eax
;--- Create group
invoke CreateWindowEx, NULL, addr g_szBtnCls, offset g_szServiceType_cn,/
WS_CHILD+WS_VISIBLE+BS_GROUPBOX, c_GrpSvcTypeLeft, c_GrpSvcTypeTop, /
c_GrpSvcTypeWidth, c_GrpSvcTypeHeight,/
hWnd, NULL, g_hInstance, NULL
mov g_hGrpServiceType, eax
;--- Create autocheck button
invoke CreateWindowEx, NULL, addr g_szBtnCls, offset g_szSERVICE_WIN32,/
WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX, c_ChkBtnSvcWin32Left, c_ChkBtnSvcWin32Top,/
c_ChkBtnSvcWin32Width, c_ChkBtnSvcWin32Height,/
hWnd, NULL, g_hInstance, NULL
mov g_hChkBtnSvcWin32, eax
;--- Create autocheck button
invoke CreateWindowEx, NULL, addr g_szBtnCls, offset g_szSERVICE_DRIVER,/
WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX, c_ChkBtnSvcDrvLeft, c_ChkBtnSvcDrvTop,/
c_ChkBtnSvcDrvWidth, c_ChkBtnSvcDrvHeight,/
hWnd, NULL, g_hInstance, NULL
mov g_hChkBtnSvcDrv, eax
;--- Create group
invoke CreateWindowEx, NULL, addr g_szBtnCls, offset g_szServiceState_cn,/
WS_CHILD+WS_VISIBLE+BS_GROUPBOX, c_GrpSvcStateLeft, c_GrpSvcStateTop,/
c_GrpSvcStateWidth, c_GrpSvcStateHeight,/
hWnd, NULL, g_hInstance, NULL
mov g_hGrpServiceState, eax
;--- Create autocheck button
invoke CreateWindowEx, NULL, addr g_szBtnCls, offset g_szSERVICE_ACTIVE,/
WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX, c_ChkBtnSvcActLeft, c_ChkBtnSvcActTop,/
c_ChkBtnSvcActWidth, c_ChkBtnSvcActHeight,/
hWnd, NULL, g_hInstance, NULL
mov g_hChkBtnSvcAct, eax
;--- Create autocheck button
invoke CreateWindowEx, NULL, addr g_szBtnCls, offset g_szSERVICE_INACTIVE,/
WS_CHILD+WS_VISIBLE+BS_AUTOCHECKBOX, c_ChkBtnSvcInActLeft, c_ChkBtnSvcInActTop,/
c_ChkBtnSvcInActWidth, c_ChkBtnSvcInActHeight,/
hWnd, NULL, g_hInstance, NULL
mov g_hChkBtnSvcInAct, eax
;--- Create services info editbox
invoke CreateWindowEx, NULL, addr g_szEditCls, NULL,/
WS_CHILD+WS_VISIBLE+ES_MULTILINE+WS_HSCROLL+WS_VSCROLL,/
c_EdtSvrInfoLeft, c_EdtSvrInfoTop, c_EdtSvrInfoWidth, c_EdtSvrInfoHeight,/
hWnd, IDC_EdtVerInfo, g_hInstance, NULL
mov g_hEditSvrInfo, eax
.elseif uMsg==WM_COMMAND
.if lParam!=0
mov eax, wParam
.IF ax==IDC_BtnEnum
shr eax, 16
.if ax==BN_CLICKED
xor eax, eax
mov g_dwServiceType, eax
invoke SendMessage, g_hChkBtnSvcWin32, BM_GETCHECK, eax, eax
.if eax==BST_CHECKED
or g_dwServiceType, SERVICE_WIN32
.endif
xor eax, eax
invoke SendMessage, g_hChkBtnSvcDrv, BM_GETCHECK, eax, eax
.if eax==BST_CHECKED
or g_dwServiceType, SERVICE_DRIVER
.endif
cmp g_dwServiceType, 0
jne @F
m_MsgBox OFFSET g_szChkSvrTypeFirst_cn, NULL
xor eax, eax
jz @BtnClkEnd
@@:
xor eax, eax
mov g_dwServiceState, eax
invoke SendMessage, g_hChkBtnSvcAct, BM_GETCHECK, eax, eax
.if eax==BST_CHECKED
or g_dwServiceState, SERVICE_ACTIVE
.endif
xor eax, eax
invoke SendMessage, g_hChkBtnSvcInAct, BM_GETCHECK, eax, eax
.if eax==BST_CHECKED
or g_dwServiceState, SERVICE_INACTIVE
.endif
cmp g_dwServiceState, 0
jne @F
m_MsgBox OFFSET g_szChkSvrStateFirst_cn, NULL
xor eax, eax
jz @BtnClkEnd
@@:
invoke ShowServiceInfo, SC_MANAGER_ENUMERATE_SERVICE, g_dwServiceType, g_dwServiceState
@BtnClkEnd:
.endif
.ENDIF
.endif
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage, NULL
.elseif uMsg==WM_SIZE
invoke ResizeConctrol
xor eax, eax
jz @F
.else
@@:
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
xor eax, eax
ret
WndProc endp
ResizeConctrol PROC
LOCAL st_Rect: RECT
invoke GetClientRect, g_hWndMain, ADDR st_Rect
;--- Resize the Enum button
mov eax, st_Rect.right
sub eax, 5+c_BtnShowWidth
push eax
invoke MoveWindow, g_hBtnShow, eax, c_BtnShowTop, c_BtnShowWidth, c_BtnShowHeight, TRUE
;--- Resize the service editbox
mov eax, st_Rect.right
sub eax, 5
mov edi, st_Rect.bottom
sub edi, 70
invoke MoveWindow, g_hEditSvrInfo, c_EdtSvrInfoLeft, c_EdtSvrInfoTop, eax, edi, TRUE
ret
ResizeConctrol ENDP
ShowServiceInfo PROC dwDesiredAccess: dword, dwServiceType: dword, dwServiceState: dword
LOCAL hSCM, hResume, hMem: HANDLE
LOCAL dwBytesNeeded, dwServiceNum: dword
LOCAL lpstCurSvr: dword
LOCAL Buf1[22]: byte
xor eax, eax
jz @F
g_szERROR_ACCESS_DENIED db "The requested access was denied.", 0
g_szERROR_DATABASE_DOES_NOT_EXIST db "The specified database does not exist.", 0
g_szERROR_INVALID_PARAMETER db "A parameter that was specified is invalid.", 0
g_szERROR_INVALID_HANDLE db "The specified handle is invalid.", 0
g_szERROR_MORE_DATA db "There are more service entries than would fit into the lpServices buffer.", 0
g_szFailGlobalAlloc db "Fail to GlobalAlloc", 0
g_szOpenSCManager db "Call OpenSCManager", 0
g_szEnumServicesStatus db "Call EnumServicesStatus", 0
g_szBlkOK db " OK!"
g_szCR db 0dh, 0ah, 0
g_sz3hyphens db "---", 0
g_szFmtTotal db "Total: %d", 0
@@:
; SC_HANDLE OpenSCManager(
; LPCTSTR lpMachineName, // pointer to machine name string
; LPCTSTR lpDatabaseName, // pointer to database name string
; DWORD dwDesiredAccess // type of access
; );
m_CatStr OFFSET g_szOpenSCManager
invoke OpenSCManager, NULL, NULL, dwDesiredAccess
cmp eax, NULL
jne @F
invoke GetLastError
.if eax==ERROR_ACCESS_DENIED
mov eax, OfFSET g_szERROR_ACCESS_DENIED
.elseif eax==ERROR_DATABASE_DOES_NOT_EXIST
mov eax, OFFSET g_szERROR_DATABASE_DOES_NOT_EXIST
.elseif eax==ERROR_INVALID_PARAMETER
mov eax, OFFSET g_szERROR_INVALID_PARAMETER
.else
mov eax, NULL
.endif
m_CatStr eax
ret
@@:
mov hSCM, eax
m_CatStr OFFSET g_szBlkOK
m_CatStr OFFSET g_szEnumServicesStatus
; BOOL EnumServicesStatus(
; SC_HANDLE hSCManager, // handle to service control manager database
; DWORD dwServiceType, // type of services to enumerate
; DWORD dwServiceState, // state of services to enumerate
; LPENUM_SERVICE_STATUS lpServices, // pointer to service status buffer
; DWORD cbBufSize, // size of service status buffer
; LPDWORD pcbBytesNeeded, // pointer to variable for bytes needed
; LPDWORD lpServicesReturned, // pointer to variable for number returned
; LPDWORD lpResumeHandle // pointer to variable for next entry
; );
mov hResume, 0
invoke EnumServicesStatus, hSCM, dwServiceType, dwServiceState,/
NULL, NULL, ADDR dwBytesNeeded,/
ADDR dwServiceNum, ADDR hResume
invoke GetLastError
cmp eax, ERROR_MORE_DATA
je @F
@EnumServicesStatusErr:
.if eax==ERROR_ACCESS_DENIED
mov eax, OfFSET g_szERROR_ACCESS_DENIED
.elseif eax==ERROR_INVALID_HANDLE
mov eax, OFFSET g_szERROR_INVALID_HANDLE
.elseif eax==ERROR_INVALID_PARAMETER
mov eax, OFFSET g_szERROR_INVALID_PARAMETER
.elseif eax==ERROR_MORE_DATA
mov eax, OFFSET g_szERROR_MORE_DATA
.else
mov eax, NULL
.endif
m_CatStr eax
invoke CloseServiceHandle, hSCM
ret
@@:
m_CatStr OFFSET g_szBlkOK
m_CatStr OFFSET g_szEnumServicesStatus
invoke GlobalAlloc, GMEM_ZEROINIT, dwBytesNeeded
cmp eax, NULL
jnz @F
m_CatStr OFFSET g_szFailGlobalAlloc
invoke CloseServiceHandle, hSCM
ret
@@:
mov hMem, eax
m_CatStr OFFSET g_szBlkOK
mov hResume, 0
invoke EnumServicesStatus, hSCM, dwServiceType, dwServiceState,/
hMem, dwBytesNeeded, ADDR dwBytesNeeded,/
ADDR dwServiceNum, ADDR hResume
or eax, eax
jnz @F
invoke GetLastError
push eax
invoke GlobalFree, hMem
pop eax
jmp @EnumServicesStatusErr
@@:
m_CatStr OFFSET g_sz3hyphens
m_CatStr OFFSET g_szAppName_cn
m_CatStr OFFSET g_sz3hyphens
invoke wsprintf, ADDR Buf1, OFFSET g_szFmtTotal, dwServiceNum
m_CatStr ADDR Buf1
m_GoNextLine
;push edx
mov edx, hMem
xor eax, eax
.while eax < dwServiceNum
push eax
mov lpstCurSvr, edx
m_CatStr (ENUM_SERVICE_STATUS ptr [ edx]).lpServiceName
m_CatStr OFFSET g_sz3hyphens
mov edx, lpstCurSvr
m_CatStr (ENUM_SERVICE_STATUS ptr [ edx]).lpDisplayName
m_GoNextLine
mov edx, lpstCurSvr
lea eax, (ENUM_SERVICE_STATUS ptr [ edx]).ServiceStatus
invoke ShowSvcStatusInfo, eax
m_GoNextLine
mov edx, lpstCurSvr
add edx, SIZEOF ENUM_SERVICE_STATUS
pop eax
inc eax
.endw
;pop edx
invoke GlobalFree, hMem
invoke CloseServiceHandle, hSCM
ret
ShowServiceInfo ENDP
ShowSvcStatusInfo PROC lpstSrvStatus: dword
xor eax, eax
jz @F
;--- type
g_szSERVICE_WIN32_OWN_PROCESS db "SERVICE_WIN32_OWN_PROCESS", 0
g_szSERVICE_WIN32_SHARE_PROCESS db "SERVICE_WIN32_SHARE_PROCESS", 0
g_szSERVICE_KERNEL_DRIVER db "SERVICE_KERNEL_DRIVER", 0
g_szSERVICE_FILE_SYSTEM_DRIVER db "SERVICE_FILE_SYSTEM_DRIVER", 0
g_szSERVICE_INTERACTIVE_PROCESS db "SERVICE_INTERACTIVE_PROCESS", 0
g_szSvcTypeArr dword SERVICE_WIN32_OWN_PROCESS, OFFSET g_szSERVICE_WIN32_OWN_PROCESS
dword SERVICE_WIN32_SHARE_PROCESS, OFFSET g_szSERVICE_WIN32_SHARE_PROCESS
dword SERVICE_KERNEL_DRIVER, OFFSET g_szSERVICE_KERNEL_DRIVER
dword SERVICE_FILE_SYSTEM_DRIVER, OFFSET g_szSERVICE_FILE_SYSTEM_DRIVER
dword SERVICE_INTERACTIVE_PROCESS, OFFSET g_szSERVICE_INTERACTIVE_PROCESS
c_SvcTypeArrLen equ ($ - ( offset g_szSvcTypeArr)) / 8
;--- status
g_szSERVICE_STOPPED db "SERVICE_STOPPED", 0
g_szSERVICE_START_PENDING db "SERVICE_START_PENDING", 0
g_szSERVICE_STOP_PENDING db "SERVICE_STOP_PENDING", 0
g_szSERVICE_RUNNING db "SERVICE_RUNNING", 0
g_szSERVICE_CONTINUE_PENDING db "SERVICE_CONTINUE_PENDING", 0
g_szSERVICE_PAUSE_PENDING db "SERVICE_PAUSE_PENDING", 0
g_szSERVICE_PAUSED db "SERVICE_PAUSED", 0
g_szSvcStatusArr dword SERVICE_STOPPED, OFFSET g_szSERVICE_STOPPED
dword SERVICE_START_PENDING, OFFSET g_szSERVICE_START_PENDING
dword SERVICE_STOP_PENDING, OFFSET g_szSERVICE_STOP_PENDING
dword SERVICE_RUNNING, OFFSET g_szSERVICE_RUNNING
dword SERVICE_CONTINUE_PENDING, OFFSET g_szSERVICE_CONTINUE_PENDING
dword SERVICE_PAUSE_PENDING, OFFSET g_szSERVICE_PAUSE_PENDING
dword SERVICE_PAUSED, OFFSET g_szSERVICE_PAUSED
c_SvcStatusArrLen equ ($ - ( offset g_szSvcStatusArr)) / 8
;---
g_szControlsAccepted_cn db "可受控制:", 0
g_szSERVICE_ACCEPT_STOP db "SERVICE_ACCEPT_STOP", 0
g_szSERVICE_ACCEPT_PAUSE_CONTINUE db "SERVICE_ACCEPT_PAUSE_CONTINUE", 0
g_szSERVICE_ACCEPT_SHUTDOWN db "SERVICE_ACCEPT_SHUTDOWN", 0
g_szSvcAccCtlArr dword SERVICE_ACCEPT_STOP, OFFSET g_szSERVICE_ACCEPT_STOP
dword SERVICE_ACCEPT_PAUSE_CONTINUE, OFFSET g_szSERVICE_ACCEPT_PAUSE_CONTINUE
dword SERVICE_ACCEPT_SHUTDOWN, OFFSET g_szSERVICE_ACCEPT_SHUTDOWN
c_SvcAccCtlArrLen equ ($ - ( offset g_szSvcAccCtlArr)) / 8
@@:
; typedef struct _SERVICE_STATUS { // ss
; DWORD dwServiceType;
; DWORD dwCurrentState;
; DWORD dwControlsAccepted;
; DWORD dwWin32ExitCode;
; DWORD dwServiceSpecificExitCode;
; DWORD dwCheckPoint;
; DWORD dwWaitHint;
; } SERVICE_STATUS, *LPSERVICE_STATUS;
;--- ServiceType
m_CatStr OFFSET g_szServiceType_cn
mov eax, lpstSrvStatus
mov eax, (SERVICE_STATUS ptr [ eax]).dwServiceType
invoke ShowSvcData, eax, OFFSET g_szSvcTypeArr, c_SvcTypeArrLen
m_GoNextLine
;--- Service State
m_CatStr OFFSET g_szServiceState_cn
mov eax, lpstSrvStatus
mov eax, (SERVICE_STATUS ptr [ eax]).dwCurrentState
invoke ShowSvcData, eax, OFFSET g_szSvcStatusArr, c_SvcStatusArrLen
m_GoNextLine
;--- ControlsAccepted
m_CatStr OFFSET g_szControlsAccepted_cn
mov eax, lpstSrvStatus
mov eax, (SERVICE_STATUS ptr [ eax]).dwControlsAccepted
invoke ShowSvcData, eax, OFFSET g_szSvcAccCtlArr, c_SvcAccCtlArrLen
m_GoNextLine
ret
ShowSvcStatusInfo ENDP
ShowSvcData PROC dwSvcData: DWORD, lpSvcDataArr: DWORD, dwDataArrLen: DWORD
LOCAL lpPos: dword
LOCAL dwIndex: dword
mov eax, lpSvcDataArr
mov dwIndex, 0
@ShowSvcDataLoop1:
mov edx, dwIndex
cmp edx, dwDataArrLen
je @ShowSvcDataRet
mov lpPos, eax
mov eax, [ eax]
cmp dwSvcData, eax
jne @F
mov eax, lpPos
add eax, 4
mov eax, [ eax]
or eax, eax
jnz @ShowSvcData
;jmp @ShowSvcData
@@:
inc dwIndex
mov eax, lpPos
add eax, 8
or eax, eax
jnz @ShowSvcDataLoop1
@ShowSvcData:
m_CatStr eax
@ShowSvcDataRet:
ret
ShowSvcData ENDP
end