Internet Explorer の Cookie 操作

ご存じの通り、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 を取得/設定するのかを説明します。
大体、次のような処理になります。

  1. 動作中の IE が保護モードかどうかを判定する
  2. 保護モードであれば、保護モード用の 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 を使い分けることです。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。