ご存じの通り、Windows Vista 以降の IE では保護モードというものが導入されています。
最新の IE8 でも同様になります。
今回は Cookie の設定/取得についてのネタです。
Cookie の設定/取得では、動いている IE がどのモード(保護モードかどうか)で動いているのかを意識する必要があります。
どのモードで動いているのかによって、Cookie ストアの場所が異なるからです。
- 保護モード用の Cookie ストア
Users\"username"\AppData\Roaming\Microsoft\Windows\Cookies\Low
- 通常の Cookie ストア
Users\"username"\AppData\Roaming\Microsoft\Windows\Cookies
では、これらのローカルの Cookie ストアに対して、どのように Cookie を取得/設定するのかを説明します。
大体、次のような処理になります。
- 動作中の IE が保護モードかどうかを判定する
- 保護モードであれば、保護モード用の Cookie 用 API を使い、非保護モードであれば、通常の Cookie 用 API を使う
1) 保護モードかどうかの判定
これには、IEIsProtectedModeProcess() を使います。
使い方は、こんな感じです。API が HRESULT を返すので、ラッパーにしてみました。
// IE が保護モードの場合には、0 を、非保護モードであれば、-1 を返します
int IsIEProtectedMode()
{
BOOL bResult = FALSE;
// IE が保護モードかどうかを確認する
HRESULT hRes = IEIsProtectedModeProcess(&bResult);
if (FAILED(hRes))
{
DWORD dwErr = GetLastError();
// 必要に応じでエラー処理
// エラーが発生したときには、GetLasetError()の値を返します
return dwErr;
}
#ifdef _DEBUG
if (bResult)
{
MessageBox(_T("IE is Protected Mode"), _T("IE 保護モードの確認"), MB_OK | MB_ICONINFORMATION);
}
else
{
MessageBox(_T("IE is Not Protected Mode"), _T("IE 保護モードの確認"), MB_OK | MB_ICONINFORMATION);
}
#endif
return bResult ? 0: -1;
}
このような方法で、事前に IE が保護モードで動いているのかどうかを判定することができます。
2) Cookie の設定/取得
Cookie を操作する API には、以下のものがあります。
Cookie 設定用 API
Cookie 取得用 API
では、使い方です。
Cookie はメモリ内に一時的に保存しておくものと、HDD に Cookie ファイルとして永続化しておく方法の 2 種類があります。
初めは、Cookie の設定です。
[IE が保護モードで動いている]
メモリ上(セッション内)に Cookie を一時的に作成する場合
HRESULT hRes = IESetProtectedModeCookie(szUrl,
_T(“MyValue”), _T("777; expires = Fri,10-Sep-2010 00:00:00 GMT"), INTERNET_COOKIE_THIRD_PARTY);
if (FAILED(hRes))
{
DWORD dwErr = GetLastError();
// エラー
}
HDD の Cookie ストアに Cookie ファイルを永続化する場合(第 2 パラメーターを NULL にします)
HRESULT hRes = IESetProtectedModeCookie(szUrl,
NULL, _T("777; expires = Fri,10-Sep-2010 00:00:00 GMT"), INTERNET_COOKIE_THIRD_PARTY);
if (FAILED(hRes))
{
DWORD dwErr = GetLastError();
// エラー
}
[IE が非保護モードで動いている]
メモリ上(セッション内)に Cookie を一時的に作成する場合
BOOL bRes = InternetSetCookieEx(szUrl,
_T("MyValue"), _T("MyValue = 777; expires = Fri,10-Sep-2010 00:00:00 GMT"),
INTERNET_COOKIE_THIRD_PARTY, NULL);
if (bRes == FALSE)
{
dwErr = GetLastError();
// エラー
}
HDD の Cookie ストアに Cookie ファイルを永続化する場合(第 2 パラメーターを NULL にします)
BOOL bRes = InternetSetCookieEx(szUrl,
NULL, _T("MyValue = 777; expires = Fri,10-Sep-2010 00:00:00 GMT"),
INTERNET_COOKIE_THIRD_PARTY, NULL);
if (bRes == FALSE)
{
dwErr = GetLastError();
// エラー
}
Cookie を使用する際、フォーマットが決められていますので、間違えないようにしてください。
また、Cookie の有効期限を設定する場合ですが、必ず、正しい日時を設定しなければなりません。
上記はコードを簡単にするために、ハードコーディングしていますが、きちんと API で取得した方がよいと思います。
InternetSetCookie() は、InternetSetCookieEx() を参考にしてください(最後の 2 つのパラメーターがないだけです)。
次は、Cookie の取得です。こちらは、少しコーディングっぽくしてみます。
TCHAR * pszCookieHeader = NULL;
__try
{
DWORD dwDataSize = 512;
pszCookieHeader = (TCHAR *)_malloca(dwDataSize);
if (pszCookieHeader == NULL)
{
// メモリがとれない
__leave;
}
SecureZeroMemory(pszCookieHeader, dwDataSize);
TCHAR szUrl[1024];
wsprintf(szUrl, _T("%s"), OLE2T(m_bstrString));
if (IE が保護モード)
{
// HDD の Low Cookie ストアから Cookie を取得
HRESULT hRes = IEGetProtectedModeCookie(szUrl,
NULL, pszCookieHeader, &dwDataSize, INTERNET_COOKIE_THIRD_PARTY);
if (FAILED(hRes))
{
DWORD dwErr = GetLastError();
if (dwErr == ERROR_INSUFFICIENT_BUFFER)
{
// Cookie のサイズが大きかったので、もう一度、バッファを確保する
_freea(pszCookieHeader);
pszCookieHeader = (TCHAR *)_malloca(dwDataSize);
if (pszCookieHeader == NULL)
{
// メモリがとれない
__leave;
}
SecureZeroMemory(pszCookieHeader, dwDataSize);
hRes = IEGetProtectedModeCookie(szUrl,
NULL, pszCookieHeader, &dwDataSize, INTERNET_COOKIE_THIRD_PARTY);
if (FAILED(hRes))
{
dwErr = GetLastError();
// エラー処理
}
else
{
// Cookie を取得できた!
MessageBox(pszCookieHeader, _T("Get Cookie"), MB_OK | MB_ICONINFORMATION);
}
}
else
{
// エラー処理
}
}
else
{
// Cookie を取得できた!
MessageBox(pszCookieHeader, _T("Get Cookie"), MB_OK | MB_ICONINFORMATION);
}
}
else if (IE が非保護モード)
{
// HDD の Cookie ストアから Cookie を取得
BOOL bRes = InternetGetCookieEx(szUrl,
NULL, pszCookieHeader, &dwDataSize, INTERNET_COOKIE_THIRD_PARTY, NULL);
if (bRes == FALSE)
{
DWORD dwErr = GetLastError();
if (dwErr == ERROR_INSUFFICIENT_BUFFER)
{
// Cookie のサイズが大きかったので、もう一度、バッファを確保する
_freea(pszCookieHeader);
pszCookieHeader = (TCHAR *)_malloca(dwDataSize);
if (pszCookieHeader == NULL)
{
// メモリがとれない
__leave;
}
SecureZeroMemory(pszCookieHeader, dwDataSize);
bRes = InternetGetCookieEx(szUrl,
NULL, pszCookieHeader, &dwDataSize, INTERNET_COOKIE_THIRD_PARTY, NULL);
if (bRes == FALSE)
{
dwErr = GetLastError();
// エラー処理
}
else
{
// Cookie を取得できた!
MessageBox(pszCookieHeader, _T("Get Cookie"), MB_OK | MB_ICONINFORMATION);
}
}
else
{
// エラー処理
}
}
else
{
// Cookie を取得できた!
MessageBox(pszCookieHeader, _T("Get Cookie"), MB_OK | MB_ICONINFORMATION);
}
}
}
__finally
{
if (pszCookieHeader)
{
_freea(pszCookieHeader);
}
}
メモリ(セッション)上の Cookie を取得する場合には、IEGetProtectedModeCookie() と InternetGetCookieEx() の第 2 パラメーターを
NULL ではなく、_T("MyValue") みたいに変えてください。
これらの API を使うことで Cookie の操作ができます。
ポイントは、IE が保護モードがどうかで API を使い分けることです。