Windows_/Windows_Source

Windows :: 환경변수와 환경변수 상속

sosal 2014. 7. 24. 10:05
반응형

/*

 * http://sosal.kr/

 * made by so_Sal

 */



환경변수 :: 시스템의 속성을 기록하고 있는 변수.
                변수의 이름과 의미가 대부분 미리 정해져 있고,
                사용자가 의도적으로 변경, 생성 가능하다.

유닉스, 리눅스 운영체제에서는 환경변수를 설정하면
모든 프로세스가 동시에 접근 가능합니다.
따라서 '상속' 과정에 상관 없이, 환경변수라는 공유 메모리 영역을 통해
서로 정보를 주고 받을 수 있습니다.
(사실 환경변수로 정보를 주고받게 끔 프로그래밍 하는건 흔하지 않음)

윈도우에서는 시스템 환경변수를 제외한
(Path, OS,TMP 등 컴퓨터 환경설정 고급탭에서 설정가능한 환경변수)
환경변수는 각 프로세스마다 테이블이 따로 주어져
공유하지 않게끔 되어있습니다.

환경변수로 정보를 주고받는 과정에서
다른 프로세스의 접근에 의한 정보 손실, 레이스컨디션 취약점 등
취약한 부분이 존재하지만, 실제 정보를 숨기는 차원에서 (특히 웹에서)
환경변수를 통해 변수를 변환하는 경우도 많습니다.

====== 함수 분석 ======

환경변수 설정하기
BOOL SetEnvironmentVariable(
    LPCWSTR lpName,
    LPCWSTR lpValue)

lpName :: 환경변수로 등록할 변수 이름
lpValue  :: 환경변수가 가지는 정보 (보통 Message buffer)

환경변수 반환하기
DWORD GetEnvironmentVariable(
    LPCWSTR lpName,
    LPWSTR lpBuffer,
    DWORD nSize);

lpName ::  환경변수 이름 // 이름을 알아야 반환이 가능z
lpBuffer ::  환경변수가 가지고 있는 정보를 반환하여 저장되어질 버퍼
nSize    ::  버퍼에 들어갈 수 있는 최대 크기

SetEnvironmentVariable( _T("나는"), _T("sosal"));
이렇게 선언시, "나는" 이라는 환경변수가 등록되며
GetEnvironmentVariable( _T("나는"), buffer, sizeof(buffer));
buffer에다가 "나는" 이라는 환경변수의 값을 반환하여 저장합니다.


앞에서 환경변수를 통해서 통신한다는 말을 언급했는데,
윈도우에서 부모프로세스와 자식프로세스처럼
직접적인 관계가 있는 프로세스들만이 통신이 가능합니다.
(리눅스에서는 모든 프로세스가 함께 공유)

자식프로세스 생성시에 < CreateProcess > 매개변수중
LPVOID lpEnvironment 이란 변수가 있는데,
NULL을 넣어주면 환경변수를 상속처리하게 됩니다.


Set/GetEnvironmentVariable, CreateProcess,
그리고 상속 모두를 사용한 예제를 보겠습니다.


========= 환경변수 상속 부모 프로세스 =========

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<tchar.h>

int _tmain( int argc, TCHAR* argv[]){

 SetEnvironmentVariable(_T("sosal"), _T("winner"));
 SetEnvironmentVariable(_T("limsy"), _T("lo-ser"));
 //sosal, limsy라는 환경변수 2개를 지정합니다.
 //각각의 값은 차례대로 winner, lo-ser


 _tprintf( _T("Set EnvironmentVariables \n"));
 _tprintf( _T("sosal -> winner \n"));
 _tprintf( _T("limsy -> lo-ser \n"));

 STARTUPINFO si = {0,};
 PROCESS_INFORMATION pi = {0,};
 
 si.cb = sizeof(si);
 TCHAR Command[] = _T("EnvChild.exe");
  //Command는 자식프로세스 실행파일의 이름인데,
  //자식프로세스의 프로젝트 이름을 넣어주시면 됩니다.

 
  CreateProcess(
  NULL, Command, NULL, NULL, FALSE,
  CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
  NULL, //NULL일 경우 프로세스의 환경변수를 상속합니다.
  NULL,&si,&pi);

 Sleep(330000);
 return 0;
 
}

========= 환경변수 상속 자식 프로세스 =========

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<tchar.h>


#define BUFSIZE 1024

int _tmain(int argc, TCHAR *argv[]){

 TCHAR value[BUFSIZE];

 if(GetEnvironmentVariable( _T("sosal"), value, BUFSIZE) > 0)
  _tprintf( _T("%s = %s \n"), _T("sosal"), value);
 //부모프로세스가 지정한 환경변수를 가져와서 출력합니다.

 if(GetEnvironmentVariable( _T("limsy"), value, BUFSIZE) > 0)
  _tprintf( _T("%s = %s \n"), _T("limsy"), value);
 //부모프로세스가 지정한 환경변수를 가져와서 출력합니다.

 Sleep(90000);

 return 0;
}