天天看點

Windows核心程式設計學習五:程序的環境變量1.程序的環境變量2.調用GetEnvironmentStrings擷取完整的環境塊3.通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作

注:源碼為學習《Windows核心程式設計》的一些嘗試,非原創。若能有助于一二訪客,幸甚。

1.程序的環境變量

每個程序都有一個與它關聯的環境塊(environment block),這是在程序位址空間内配置設定的一塊記憶體,其中包含字元串類似于:

=::=::\...

VarName=VarValue\0...

\0

除第一個=::=::\外,塊中可能還有其他字元串是以等号開頭的,這種字元串不作為環境變量使用。

通路環境塊的兩種方式:

1)調用GetEnvironmentStrings擷取完整的環境塊

2)CUI程式專用,通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作

2.調用GetEnvironmentStrings擷取完整的環境塊

1)不論是不是環境變量,暫且都列印出來

void DumpEnvStrings()
{
	PTSTR pEnvBlock = GetEnvironmentStrings();

	PTSTR pszCurrent = pEnvBlock;
	int current = 0;

	while (pszCurrent != NULL)
	{
		// 不論是不是環境變量,暫且都列印
		_tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);

		current++;

		// 指針移動到字元串末尾
		while (*pszCurrent != TEXT('\0'))
			pszCurrent++;
		pszCurrent++;

		// 是否是最後一個字元串
		if (*pszCurrent == TEXT('\0'))
			break;
	}

	// 釋放記憶體
	FreeEnvironmentStrings(pEnvBlock);
}
           
Windows核心程式設計學習五:程式的環境變量1.程式的環境變量2.調用GetEnvironmentStrings擷取完整的環境塊3.通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作

2)去除無意義的串

void DumpEnvStrings()
{
	PTSTR pEnvBlock = GetEnvironmentStrings();
	
	TCHAR szName[MAX_PATH];
	TCHAR szValue[MAX_PATH];
	PTSTR pszCurrent = pEnvBlock;
	HRESULT hr = S_OK;
	PCTSTR pszPos = NULL;
	int current = 0;

	while (pszCurrent != NULL)
	{
		// 去除無意義的串(以'='開頭,如"=::=::\","=C:=C:Windows\System32")
		if (*pszCurrent != TEXT('='))
		{
			// 查找'=',然後指針指向'='後一個字元,即值的第一個字元
			pszPos = _tcschr(pszCurrent, TEXT('='));
			pszPos++;

			// 将變量名拷貝到szName
			size_t cbNameLength = (size_t)pszPos - (size_t)pszCurrent - sizeof(TCHAR);
			hr = StringCbCopyN(szName, MAX_PATH, pszCurrent, cbNameLength);
			if (FAILED(hr)) {
				break;
			}

			// 擷取值
			hr = StringCbCopyN(szValue, MAX_PATH, pszPos, _tcslen(pszPos)+1);
			if (SUCCEEDED(hr)) {
				_tprintf(TEXT("[%u] %s=%s\r\n"), current, szName, szValue);
			}
			else if (hr == STRSAFE_E_INSUFFICIENT_BUFFER){
				// 發生錯誤,檢查截斷
				_tprintf(TEXT("[%u] %s=%s...\r\n"), current, szName, szValue);
			}
			else {
				// 這裡應該不能發生
				_tprintf(TEXT("[%u] %s=???\r\n"), current, szName);
				break;
			}
		}
		else {
			_tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);
		}

		current++;

		// 指針移動到字元串末尾
		while (*pszCurrent != TEXT('\0'))
			pszCurrent++;
		pszCurrent++;

		// 是否是最後一個字元串
		if (*pszCurrent == TEXT('\0'))
			break;
	}

	// 釋放記憶體
	FreeEnvironmentStrings(pEnvBlock);
}
           
Windows核心程式設計學習五:程式的環境變量1.程式的環境變量2.調用GetEnvironmentStrings擷取完整的環境塊3.通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作

3.通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作

void DumpEnvVariables(PTSTR pEnvBlock[])
{
	int current = 0;
	PTSTR* pElement = (PTSTR*)pEnvBlock;
	PTSTR pCurrent = NULL;
	while (pElement != NULL)
	{
		pCurrent = (PTSTR)(*pElement);
		if (pCurrent == NULL)
		{
			// 沒有更多環境變量了
			pElement = NULL;
		}
		else
		{
			_tprintf(TEXT("[%u] %s\r\n"), current, pCurrent);
			current++;
			pElement++;
		}
	}
}

int _tmain()
{
	DumpEnvVariables(_wenviron);
	return 0;
}
           
Windows核心程式設計學習五:程式的環境變量1.程式的環境變量2.調用GetEnvironmentStrings擷取完整的環境塊3.通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作

繼續閱讀