Tuesday, August 3, 2010

Process


This lesson we will learn: What is the process? How to generate and terminate a process?

Initial knowledge:

What is the process? Here is my guide in excerpts from the WIN32 API explanation:

"A process is an ongoing process of Yingyong, which includes: private virtual address space, code, data and other operating system resources, Piru access to the pipeline process Ke Yi, Wen Jian Hu Tongbuduixiang Deng Deng."

From the above definition you can see, a process that has several objects: address space, the implementation of the module and the other the implementation of the program to open or create any objects or resources. At a minimum, a process must include the executable module, the private address space and more than one thread. What is the thread then? A thread is actually an implementation unit. When WINDOWS generate a process, it automatically generates a main thread for the process. The thread is usually the first instruction from the module started. If the process needs more threads, which can then be generated explicitly.

When WINDWOS received the news production process, it will be generated for the process private memory address space, then the executable file is mapped to the space. Produced in the process under WIN32 the main process, you can also call the function CreateProcess to create your process more threads.

CreateProcess prototype is as follows:

CreateProcess proto lpApplicationName: DWORD,
lpCommandLine: DWORD, lpProcessAttributes: DWORD,
lpThreadAttributes: DWORD,
bInheritHandles: DWORD,
dwCreationFlags: DWORD,
lpEnvironment: DWORD,
lpCurrentDirectory: DWORD,
lpStartupInfo: DWORD,
lpProcessInformation: DWORD

Do not be intimidated by so many parameters, in fact, most of which you can ignore the parameters (so that they have the default value).

lpApplicationName -> executable file name (with or without path). If this parameter is NULL, it must be passed in the parameter lpCommandLine file name.
lpCommandLine -> For the implementation of the documents passed to the command line parameters. If lpApplicationName is NULL, it must be specified in the parameter, such as: "notepad.exe readme.txt".
lpProcessAttributes and lpthreadAttributes -> specify the process and the main thread of the security attributes. You can set them all as NULL, so set the default security attributes.
bInheritHandles -> flag. Whether the process used to set up a new process created inherits all of the open handles.
dwCreationFlags -> There are several signs here set in order to determine the behavior you want to create the process, for example: You may want to create a process does not want it immediately after the run, so it really can be used before running some tests and revision . You can also set a new course here all the thread priority, usually it is set to NORMAL_PRIOR99vY_CLASS.
lpEnvironment -> point to the environment block pointer, generally, the environment block contains several environmental string. If this parameter is NULL, then the new process created process inherits the environment block.
lpCurrentDirectory -> point to the current directory as well as the child process to set the "current directory" path. If NULL, then the process of succession to create the "current directory" path.
lpStartupInfo -> point to start a new process structure pointer STARTUPINFO. WINDOWS STARTUPINFO tell how to display the appearance of the new process. There are many members of the parameter variable, if you do not want what's special about the new process can call GetStartupInfo function to create a process with the startup parameters to fill STARTUPINFO structure variables.
lpProcessInformation -> pointer to point to PROCESS_INFORMATION structure, the structure variable contains a number of unique identity in the process some member variables:

PROCESS_INFORMATION STRUCT
hProcess HANDLE?; handle to the child process
hThread HANDLE?; handle to the primary thread of the child process
dwProcessId DWORD?; ID of the child process
dwThreadId DWORD?; ID of the primary thread of the child process
PROCESS_INFORMATION ENDS
Process handle and process ID are two different concepts. Process ID is like a unique value, but the process handle is a WINDOWS API calls related to a return value obtained. Can not handle the process to identify the uniqueness of a process, because this value is not unique. Create a new process called CreateProcess after the process was created, and CerateProcess function returns immediately. You can call the function to test whether the process GetExitCodeProcess end. The function prototype is as follows:

GetExitCodeProcess proto hProcess: DWORD, lpExitCode: DWORD

If the call succeeds, lpExitCode contains the query process status code. If you mean STILL_ACTIVE to show that the process still exists. You can call the function TerminateProcess to force a process to terminate. The function prototype is as follows:

TerminateProcess proto hProcess: DWORD, uExitCode: DWORD

You can specify any of the exit value. A process with the end of the function is not good, because the process of loading the dynamic link library, and will not get the news out of the process is.


Examples:
In the following example, when the user selects the menu item "crate process" when we create a new process. It will go to the implementation of "" msgbox.exe ". If the user wants to terminate the new process, you can select the menu item "terminate process". At this time, the application checks whether the process terminated by still, if there are calls TerminateProcess function to terminate it.
.386
. Model flat, stdcall
option casemap: none
WinMain proto: DWORD,: DWORD,: DWORD,: DWORD
include masm32includewindows.inc
include masm32includeuser32.inc
include masm32includekernel32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib

. Const
IDM_CREATE_PROCESS equ 1
IDM_TERMINATE equ 2
IDM_EX99v equ 3

. Data
ClassName db "Win32ASMProcessClass", 0
AppName db "Win32 ASM Process Example", 0
MenuName db "FirstMenu", 0
processInfo PROCESS_INFORMATION <>
programname db "msgbox.exe", 0

. Data?
hInstance HINSTANCE?
CommandLine LPSTR?
hMenu HANDLE?
ExitCode DWORD?; Contains the process exitcode status from GetExitCodeProcess call.

. Code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax

WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, 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
push hInst
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW +1
mov wc.lpszMenuName, OFFSET MenuName
mov wc.lpszClassName, OFFSET ClassName
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_CLIENTEDGE, ADDR ClassName, ADDR AppName,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, 300,200, NULL, NULL,
hInst, NULL
mov hwnd, eax
invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd
invoke GetMenu, hwnd
mov hMenu, eax
. WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0,0
. BREAK. IF (! Eax)
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 startInfo: STARTUPINFO
. IF uMsg == WM_DESTROY
invoke PostQuitMessage, NULL
. ELSEIF uMsg == WM_IN99vMENUPOPUP
invoke GetExitCodeProcess, processInfo.hProcess, ADDR ExitCode
. If eax == TRUE
. If ExitCode == STILL_ACTIVE
invoke EnableMenuItem, hMenu, IDM_CREATE_PROCESS, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_TERMINATE, MF_ENABLED
. Else
invoke EnableMenuItem, hMenu, IDM_CREATE_PROCESS, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_TERMINATE, MF_GRAYED
. Endif
. Else
invoke EnableMenuItem, hMenu, IDM_CREATE_PROCESS, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_TERMINATE, MF_GRAYED
. Endif
. ELSEIF uMsg == WM_COMMAND
mov eax, wParam
. If lParam == 0
. If ax == IDM_CREATE_PROCESS
. If processInfo.hProcess! = 0
invoke CloseHandle, processInfo.hProcess
mov processInfo.hProcess, 0
. Endif
invoke GetStartupInfo, ADDR startInfo
invoke CreateProcess, ADDR programname, NULL, NULL, NULL, FALSE,
NORMAL_PRIOR99vY_CLASS,
NULL, NULL, ADDR startInfo, ADDR processInfo
invoke CloseHandle, processInfo.hThread
. Elseif ax == IDM_TERMINATE
invoke GetExitCodeProcess, processInfo.hProcess, ADDR ExitCode
. If ExitCode == STILL_ACTIVE
invoke TerminateProcess, processInfo.hProcess, 0
. Endif
invoke CloseHandle, processInfo.hProcess
mov processInfo.hProcess, 0
. Else
invoke DestroyWindow, hWnd
. Endif
. Endif
. ELSE
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
. ENDIF
xor eax, eax
ret
WndProc endp
end start

Analysis:
Application creates the main window, save the menu handle for later use. When the user in the main menu, select the "Process" menu item, the message processing received WM_IN99vMENUPOPUP news, we here modify the pop-up menu in the menu item "Enable" and "non-enabled" to the same menu with different display.
. ELSEIF uMsg == WM_IN99vMENUPOPUP
invoke GetExitCodeProcess, processInfo.hProcess, ADDR ExitCode
. If eax == TRUE
. If ExitCode == STILL_ACTIVE
invoke EnableMenuItem, hMenu, IDM_CREATE_PROCESS, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_TERMINATE, MF_ENABLED
. Else
invoke EnableMenuItem, hMenu, IDM_CREATE_PROCESS, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_TERMINATE, MF_GRAYED
. Endif
. Else
invoke EnableMenuItem, hMenu, IDM_CREATE_PROCESS, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_TERMINATE, MF_GRAYED
. Endif

The reason why we deal with the purpose of the message is to make the menu look different when displayed to a user-friendly to use. For example; the new process has not been run, we light up (enable) "menu item" start process ", but grayed out (not enabled) menu item" terminate process ". When the new process is running, the menu's appearance on should be the opposite.
First, we call GetExitCodeProcess function, which handles incoming returned by the CreateProcess. If GetExitCodeProcess returns FALSE, then that process has not been run, we let the menu item "terminate process" grayed out; If you return TRUE, said the new process has started, we re-test is running, which is equal to STILL_ACTIVE by comparing the ExitCode to complete If equal, that process is still running, we let the menu item "start process" grayed out, because in our simple application process does not provide the ability to run multiple processes.

. If ax == IDM_CREATE_PROCESS
. If processInfo.hProcess! = 0
invoke CloseHandle, processInfo.hProcess
mov processInfo.hProcess, 0
. Endif
invoke GetStartupInfo, ADDR startInfo
invoke CreateProcess, ADDR programname, NULL, NULL, NULL, FALSE,
NORMAL_PRIOR99vY_CLASS,
NULL, NULL, ADDR startInfo, ADDR processInfo
invoke CloseHandle, processInfo.hThread

When the user selects the menu item "start process", we first test structure in the member variable hPRocess PROCESS_INFORMATION is turned off. If this is the first time you start the application process, which the variable is 0, because we are. Data section defined structure have been initialized when the value is 0. If the value is not 0, then that the new process has ended, but we have yet to close the process handle (in order to reduce the reference count of the process), we are here to complete the action.
We call GetStartupInfo function to start filling the information structure variables, and the variable will be passed to the CreateProcess function to. Call CreateProcess to generate a new process, we do not check the return value of the function is to simplify the problem, in practice, to do the work. After the call to CreateProcess, we immediately close the structure parameters in the process information returned handle to the main thread to close the thread handle in order to reduce the kernel object reference count, or even if the thread exits, the kernel object is still miserable exist in the kernel is not released, it will cause resource leaks. Process is actually the same reason we do not close the process handle is there because later on we have to use the handle to get some information related to the process and, as threads, our application does not need its information.

. Elseif ax == IDM_TERMINATE
invoke GetExitCodeProcess, processInfo.hProcess, ADDR ExitCode
. If ExitCode == STILL_ACTIVE
invoke TerminateProcess, processInfo.hProcess, 0
. Endif
invoke CloseHandle, processInfo.hProcess
mov processInfo.hProcess, 0

When the user selects the menu item "terminate process", we call the function GetExitCodeProcess to check whether the new process there, if there TerminateProcess we call the function to end it. In addition, we closed off the handle because we no longer have it.






Recommended links:



Audio Players Expert



Kingsoft CEO Lei Jun: calm face of THE new issue of



Comment Inventory And Barcoding



Close contact WITH ASP.Net (3) asp + in the control



The Table Border Css Syntax Order



Fireworks 8 dream trip (5): the new changes in the menu



Converting flac to mp3



Visuanl C # 2005 Quick Start of the while statement (1)



Evolution of a mature framework AND guidelines - CMM Architecture



Gmail Frequently dropped a solution



Catalogs Icon Tools



convert MP4 to avi



Dvd ripper



EMC Announced That Miss Yip Pure Novice To Succeed President, Greater China



avc Converter