strsafe.hの使い方Ex編

ExありとExなしでははたらきそのものは同じなようですが、出力してくるものが増えてくるようです。ふだんの業務ではExなしで十分なようですが、さらなるセキュリティに配慮するとなるとExありバージョンを使うとよいようです。

StringCchCatEx()

/*
	strsafe.hの使い方の練習
	StringCchCatEx()
	2005/May/18
*/

#define	STRICT
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* using strsafe.h */
#define STRSAFE_LIB
#include <strsafe.h>

#define MAXLENGTH 1024

int main(int argc, char *argv)
{
	int i;
	HRESULT hr;
	
	LPTSTR pszDest;
	size_t cchDest;
	LPCTSTR pszSrc = TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
	LPTSTR ppszDestEnd;
	size_t pcchRemaining;
	DWORD dwFlags = 0;
	
	size_t pszDest_length;
	size_t pszSrc_length;
	
	pszDest = malloc(sizeof(TCHAR) * MAXLENGTH);
	if (pszDest == NULL) {
		MessageBox(NULL, TEXT("Error"), TEXT("malloc() Error"), MB_OK);
		exit(EXIT_FAILURE);
	}
	// 確保したヒープを文字列 "" にする。
	*pszDest = '\0';
	
	StringCchLength(pszDest, STRSAFE_MAX_CCH, &pszDest_length);
	StringCchLength(pszSrc, STRSAFE_MAX_CCH, &pszSrc_length);
	
	// This value must equal the length of pszSrc plus the length of pszDest plus 1
	cchDest = pszDest_length + pszSrc_length + sizeof(TCHAR);
	
	dwFlags = STRSAFE_FILL_BEHIND_NULL
			 | STRSAFE_IGNORE_NULLS
			 | STRSAFE_FILL_ON_FAILURE
			 | STRSAFE_NULL_ON_FAILURE
			 | STRSAFE_NO_TRUNCATION;
	
	ppszDestEnd = pszDest + MAXLENGTH;

	printf("%d\n", sizeof(TCHAR));

	printf("pszSrc = %s\n", pszSrc);
	printf("pszDest = %s\n", pszDest);

	printf("pszSrc = %p\n", pszSrc);
	printf("pszDest = %p\n", pszDest);

/*
HRESULT StringCchCatEx(
    LPTSTR pszDest,
    size_t cchDest,
    LPCTSTR pszSrc,
    LPTSTR *ppszDestEnd,
    size_t *pcchRemaining,
    DWORD dwFlags
);
*/
	hr = StringCchCatEx(
				pszDest,
				cchDest,
				pszSrc,
				&ppszDestEnd,
				&pcchRemaining,
				dwFlags);
	puts("StringCchCatEx()");
	
	printf("ppszDestEnd = %p\n", ppszDestEnd);
	printf("pcchRemaining = %p\n", pcchRemaining);
	
	printf("pszSrc = %s\n", pszSrc);
	printf("pszDest = %s\n", pszDest);

	printf("pszSrc = %p\n", pszSrc);
	printf("pszDest = %p\n", pszDest);

	printf("ppszDestEnd - pszDest = %d\n", ppszDestEnd - pszDest);
	
	// メモリ上で文字列がどうなっているかチェック
	for (i = pszDest; i <= ppszDestEnd; i++) {
		printf("%x: %c\n", i, *pszDest++);
	}
	
	// StringCchCatExの返り値チェック
	switch (hr) {
		case S_OK:
			puts("S_OK");
			break;
		case STRSAFE_E_INVALID_PARAMETER:
			puts("STRSAFE_E_INVALID_PARAMETER");
			break;
		case STRSAFE_E_INSUFFICIENT_BUFFER:
			puts("STRSAFE_E_INSUFFICIENT_BUFFER");
			break;
	}
	
	exit(EXIT_SUCCESS);
}