環境変数の表示と環境変数ブロックの仕組み
環境変数とは?
環境変数はその EXE が実行する環境特有のパラメータを定義するものです。 例えば、C のプログラムをコンパイルするときに特に明示が無い限り、コンパイラは環境変数 INCLUDE に指定されたパスからヘッダファイルを探します。
また CGI など、WEB サーバー上で実行するプログラムは、その EXE の起動時に 環境変数として HTTP プロトコルのヘッダ情報等を明示的にセットしてからプロセスを起動します。 このようにすることによって、CGI から HTTP ヘッダが参照できます。
環境変数ブロックの仕組み
環境変数は 変数名1=値1\0変数名2=値2\0\0 のように、変数名と値のペアとして定義します。 複数のペアは \0 (NULL) で区切り、最後に \0 を続け終了マーカーとします。
さらにカレントディレクトリや ExitCode を保持するための '=' 付き変数名の定義をメモリブロックの先頭に持っています。
環境変数ブロックの表示
環境変数を定義したブロックは GetEnvironmentStrings 関数で取得できます。 取得したメモリ領域は FreeEnvironmentStrings 関数で解放します。
enumenv.cpp として以下を保存します。
#include <windows.h> #include <stdio.h> #include <fcntl.h> #include <io.h> int main ( int argc, char* argv[] ) { char *lpvEnv; lpvEnv = GetEnvironmentStrings(); if ( !lpvEnv ) { printf ("GetEnvironmentStrings failed (%d)", GetLastError()); return 1; } for ( char* pszVar = lpvEnv; *pszVar ; pszVar++) { while ( *pszVar ) { putchar( *pszVar ); pszVar++; } printf("\n"); } FreeEnvironmentStrings ( lpvEnv ); return 0; }
makefile は次の通り。
TARGETNAME=enumenv OUTDIR=.\chk LINK32=link.exe ALL : "$(OUTDIR)\$(TARGETNAME).exe" CPPFLAGS=\ /nologo\ /MT\ /W3\ /Fo"$(OUTDIR)\\"\ /Fd"$(OUTDIR)\\"\ /c\ /Zi\ /DWIN32 LINK32_FLAGS=\ /nologo\ /subsystem:console\ /pdb:"$(OUTDIR)\$(TARGETNAME).pdb"\ /machine:I386\ /out:"$(OUTDIR)\$(TARGETNAME).exe"\ /DEBUG\ /RELEASE LINK32_OBJS= \ "$(OUTDIR)\$(TARGETNAME).obj" "$(OUTDIR)\$(TARGETNAME).exe" : "$(OUTDIR)" $(LINK32_OBJS) $(LINK32) $(LINK32_FLAGS) $(LINK32_OBJS) "$(OUTDIR)" : @if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" .cpp{$(OUTDIR)}.obj: $(CPP) $(CPPFLAGS) $<
上記を nmake すると enumenv.exe が作られます。(バイナリのダウンロード)
enumenv.exe の実行結果は SET コマンドの実行結果とほぼ同様ですが、出力の先頭に = 付き変数を定義した領域が表示されるところが異なります。