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