/*
1. EProcess 의 포인터가 Process Enviroment Block을 가리키고 있다.
PEB(Process Enviroment Block)에는 현재 디렉토리, 환경변수,command line argument을 가지고 있다.
2. Eprocess에는 프로세스 ID를 가지고 있다.
*/
#include<stdio.h>
#include<windows.h>
/*
void main()
{
//현재 프로세스의 ID얻기 -> EPROCESS 에서 꺼내오는 함수.
DWORD pid = GetCurrentProcessId();
printf("프로세스 ID : %d\n",pid);
//현재 디렉토리 얻기,
char dir[MAX_PATH];
GetCurrentDirectory(MAX_PATH, dir);
printf("현재 디렉토리 : %s\n",dir);
//command line argument 얻기
char *p = GetCommandLine();
printf("Command Line Argument : %s\n\n", p);
//환경 변수 꺼내기
char temp[1024];
GetEnvironmentVariable("PATH",temp, 1024);
printf("PATH라는 환경 변수 : %s\n",temp);
}
*/
/*3. entry
mainCRTStartup()이 먼저 실행후 main()이 실행된다. <~ 모든 C언어에서 그렇다.
하지만 제일 먼저 실행되는 것은 Start of Process 라고 불리는 함수가 있다.(정식명칭은 아니다. MS가 오픈을 안했으므로)
OS - call -> Start of Process - call ->mainCRTStartup() - call ->main()
Start of Process는 커널32.dll에 있다. <~ 항상 같은 주소에 있다.
4. 프로세스 생성
1. WinExec()
2. CreateProcess()
WinExec()가 CreateProcess()를 부른다.
C에선 system()으로 다른 프로세스를 실행 시켰다.
//TerminateProcess는 비동기 함수
//비동기함수 : 함수가 완전히 종료되지 않고 중간에 돌아오는 시점에 해당하는 함수가
// 종료 되었느지 확신할 수 없다. -> 확인해야한다.
//PKO는 살아있을때 nonsinal 죽었을때 signal
//Wait for SingleIbject) <~ 매우중요
*/
/*
1. 자식의 핸들을 닫는다.- 그 이유
2. 종료 코드
Eproces 안에는 종료 코드가 있다. 프로그램이 실행중일경우는 STILL_ACTIVE로 있다가 종료 되었을때 main()함수의 리턴값을 받는다.
*/
/*
void main()
{
//표준 C함수 사용
//system("freecell.exe");//프리셀에 떠있는동안은 다음줄이 실행이 안된다.
WinExec("freecell.exe",SW_SHOW); //다른프로그램이 실행되어도 다음 코드가 실행된다.
printf("Bye~~\n");
}
*/
void main()
{
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
BOOL b = CreateProcess("C:\\WINDOWS\\system32\\freecell.exe", //APP이름 < ~ 절대 경로를 줘야 한다.
0,//"freecell.exe", //APP이름 + command line args <~ 그냥 써도 된다.
0,0, //PKO,TKO 보안
//PKO 보안을 설정하면 작업관리자에서 죽일수 없는 프로그램을 만들수 있다.
FALSE, // KOHT의 상속여부->부모의 테이블 상속여부
NORMAL_PRIORITY_CLASS,//우선순위 | 플래그
0,0, //환경변수 , 현재 디렉토리
&si, //startup info정보
&pi); //생성된 프로세스,스레듸 핸들과 ID를 담을 변수
if(b)
{
//자식의; 핸들을 닫는 이유를 반드시 알아야 한다.
//자식의 핸들을 닫지 않으면 자식이 종료 되어도 자식을 관라하던
//PKO,TKO는 파괴 되지 않고 있다가 (참조개수 1)부모가 자식의핸들을
//닫거나 부모가 종료(자동으로 핸들 닫힘)되어야 PKO,TKO 파괴된다.
// CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
// int cmd;
while(1)
{
//scanf("%d",&cmd);
//if(cmd == 2)
//{
//프로세스 가제로 종료하기
//자식프로세스를 강제로 죽이면 종료코드를 메인의 끝까지 갈 수 없다.
//그래서 종료 코드를 100으로 넣고 종료한다.
//TerminateProcess(pi.hProcess,100); //100은 종료 코드
//TerminateProcess는 비동기 함수이다. 즉 .. 이순간
//정말로 죽었다고 생각할 수는 없다.
//모든 프로세스는 죽을때 PKO가 Signal된다.
//특정 KO가 시그널 될때까지 현재 실행흐름(스레드)를 대기 시킨다.
//이제 정말로 자식 프로세스는 죽었다.
// cmd =1;
//}
// if(cmd == 1)
// {
DWORD code;
GetExitCodeProcess(pi.hProcess, &code);//프로세스의 종료 코드얻기
if(WaitForSingleObject(pi.hProcess,INFINITE))//code == STILL_ACTIVE )//0x103으로 정의된 상수
{
//printf("아직 자식이 살아 있습니다.\n");
break;
}
else
{
printf("자식 종료 : %d\n",code);
CloseHandle(pi.hProcess);
b = CreateProcess("C:\\WINDOWS\\system32\\freecell.exe", //APP이름 < ~ 절대 경로를 줘야 한다.
0,//"freecell.exe", //APP이름 + command line args <~ 그냥 써도 된다.
0,0, //PKO,TKO 보안
//PKO 보안을 설정하면 작업관리자에서 죽일수 없는 프로그램을 만들수 있다.
FALSE, // KOHT의 상속여부->부모의 테이블 상속여부
NORMAL_PRIORITY_CLASS,//우선순위 | 플래그
0,0, //환경변수 , 현재 디렉토리
&si, //startup info정보
&pi); //생성된 프로세스,스레듸 핸들과 ID를 담을 변수
}
// }
}
}