FindFirstUrlCacheEntryで取得できるURLは文字化けの可能性がある

Internet Explorerのキャッシュ情報を取得するAPIとしてFindFirstUrlCacheEntryやFindNextUrlCacheEntryが用意されている。これらのAPIではキャッシュ内に保存されているURL、アクセスした回数などが取得できて便利だ。

しかしなぜかこれらのAPIはバグ?が潜んでいる。下の画像はこれらのAPIによって取得したURLの例だ。これらはどちらもローカルHDD内にアクセスしたときにキャッシュされた情報だが...日本語名のフォルダが完全に文字化けしている(テスト環境:Windows XP SP2)。
通常のインターネットURLの場合は%xx形式でエンコードされるため問題が生じる可能性は低いだろう。しかし「file://」で始まるURLについては要注意だ。


Test56_01.gif


Test56_02.gif

依存環境:ATL
#include "atlstr.h"

#include "wininet.h"
#pragma	comment(lib,"wininet.lib")

bool	Test(void)
{
	HANDLE	hFind;
	DWORD	dwLen;
	INTERNET_CACHE_ENTRY_INFO*	psInfo;

	dwLen = 0;
	hFind = ::FindFirstUrlCacheEntry(_T("visited:"),NULL,&dwLen);
	if(dwLen == 0)
	{
		if(hFind)
			::FindCloseUrlCache(hFind);
		return	false;
	}
	//サイズ取得せずにdwLen = MAX_CACHE_ENTRY_INFO_SIZE;を利用してnewしてもいい
	psInfo = (INTERNET_CACHE_ENTRY_INFO*) new TCHAR[dwLen];
	hFind = ::FindFirstUrlCacheEntry(_T("visited:"),psInfo,&dwLen);

	delete	psInfo;

	while(1)
	{
		BOOL	ret;

		dwLen = 0;
		ret = ::FindNextUrlCacheEntry(hFind,NULL,&dwLen);
		if(dwLen == 0)
			break;

		//MSDNではchar[dwLen]となっているが…誤記かもしれないのでTCHARを利用
		psInfo = (INTERNET_CACHE_ENTRY_INFO*) new TCHAR[dwLen];

		ret = ::FindNextUrlCacheEntry(hFind,psInfo,&dwLen);

		CAtlString	str = psInfo->lpszSourceUrlName;
		if(str.Find(_T("@file://")) > 0)
			::MessageBox(NULL,str,_T(""),MB_OK);
		else if(str.Find(_T("??")) > 0)
			::MessageBox(NULL,str,_T(""),MB_OK);

		delete	psInfo;
	}

	::FindCloseUrlCache(hFind);

	return	true;
}

プロジェクトファイルをダウンロード


カテゴリー「Internet Explorer」 のエントリー