/* Copyright (C) 2004 Juan Lang
 *
 * This file implements thunks between wide char and multibyte functions for
 * SSPs that only provide one or the other.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winternl.h"
#include "sspi.h"
#include "secur32_priv.h"
#include "thunks.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(secur32);

SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleA(
 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
 PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
 PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
     debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
     pvGetKeyArgument, phCredential, ptsExpiry);
    if (pszPackage)
    {
        UNICODE_STRING principal, package;

        RtlCreateUnicodeStringFromAsciiz(&principal, pszPrincipal);
        RtlCreateUnicodeStringFromAsciiz(&package, pszPackage);
        ret = AcquireCredentialsHandleW(principal.Buffer, package.Buffer,
         fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
         phCredential, ptsExpiry);
        RtlFreeUnicodeString(&principal);
        RtlFreeUnicodeString(&package);
    }
    else
        ret = SEC_E_SECPKG_NOT_FOUND;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW(
 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
 PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
 PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
     debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
     pvGetKeyArgument, phCredential, ptsExpiry);
    if (pszPackage)
    {
        PSTR principal, package;

        principal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
        package = SECUR32_AllocMultiByteFromWide(pszPackage);
        ret = AcquireCredentialsHandleA(principal, package, fCredentialsUse,
         pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
         ptsExpiry);
        HeapFree(GetProcessHeap(), 0, principal);
        HeapFree(GetProcessHeap(), 0, package);
    }
    else
        ret = SEC_E_SECPKG_NOT_FOUND;
    return ret;
}

/* thunking is pretty dicey for these--the output type depends on ulAttribute,
 * so we have to know about every type the caller does
 */
SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesA(
 PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
{
    SECURITY_STATUS ret;

    TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
    if (phCredential)
    {
        SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
        PCredHandle cred = (PCredHandle)phCredential->dwLower;

        if (package && package->provider)
        {
            if (package->provider->fnTableW.QueryCredentialsAttributesW)
            {
                ret = package->provider->fnTableW.QueryCredentialsAttributesW(
                 cred, ulAttribute, pBuffer);
                if (ret == SEC_E_OK)
                {
                    switch (ulAttribute)
                    {
                        case SECPKG_CRED_ATTR_NAMES:
                        {
                            PSecPkgCredentials_NamesW names =
                             (PSecPkgCredentials_NamesW)pBuffer;
                            SEC_WCHAR *oldUser = names->sUserName;

                            if (oldUser)
                            {
                                names->sUserName =
                                 (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser);
                                package->provider->fnTableW.FreeContextBuffer(
                                 oldUser);
                            }
                            break;
                        }
                        default:
                            WARN("attribute type %d unknown\n", ulAttribute);
                            ret = SEC_E_INTERNAL_ERROR;
                    }
                }
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesW(
 PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
{
    SECURITY_STATUS ret;

    TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
    if (phCredential)
    {
        SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
        PCredHandle cred = (PCredHandle)phCredential->dwLower;

        if (package && package->provider)
        {
            if (package->provider->fnTableA.QueryCredentialsAttributesA)
            {
                ret = package->provider->fnTableA.QueryCredentialsAttributesA(
                 cred, ulAttribute, pBuffer);
                if (ret == SEC_E_OK)
                {
                    switch (ulAttribute)
                    {
                        case SECPKG_CRED_ATTR_NAMES:
                        {
                            PSecPkgCredentials_NamesA names =
                             (PSecPkgCredentials_NamesA)pBuffer;
                            SEC_CHAR *oldUser = names->sUserName;

                            if (oldUser)
                            {
                                names->sUserName =
                                 (PSTR)SECUR32_AllocWideFromMultiByte(oldUser);
                                package->provider->fnTableA.FreeContextBuffer(
                                 oldUser);
                            }
                            break;
                        }
                        default:
                            WARN("attribute type %d unknown\n", ulAttribute);
                            ret = SEC_E_INTERNAL_ERROR;
                    }
                }
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextA(
 PCredHandle phCredential, PCtxtHandle phContext,
 SEC_CHAR *pszTargetName, ULONG fContextReq,
 ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
 ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
 ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
     debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
     Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
    if (phCredential)
    {
        SecurePackage *package = (SecurePackage *)phCredential->dwUpper;

        if (package && package->provider)
        {
            if (package->provider->fnTableW.InitializeSecurityContextW)
            {
                UNICODE_STRING target;

                RtlCreateUnicodeStringFromAsciiz(&target, pszTargetName);
                ret = package->provider->fnTableW.InitializeSecurityContextW(
                 phCredential, phContext, target.Buffer, fContextReq, Reserved1,
                 TargetDataRep, pInput, Reserved2, phNewContext, pOutput,
                 pfContextAttr, ptsExpiry);
                RtlFreeUnicodeString(&target);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextW(
 PCredHandle phCredential, PCtxtHandle phContext,
 SEC_WCHAR *pszTargetName, ULONG fContextReq,
 ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
 ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
 ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
     debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
     Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
    if (phCredential)
    {
        SecurePackage *package = (SecurePackage *)phCredential->dwUpper;

        if (package && package->provider)
        {
            if (package->provider->fnTableA.InitializeSecurityContextA)
            {
                PSTR target = SECUR32_AllocMultiByteFromWide(pszTargetName);

                ret = package->provider->fnTableA.InitializeSecurityContextA(
                 phCredential, phContext, target, fContextReq, Reserved1,
                 TargetDataRep, pInput, Reserved2, phNewContext, pOutput,
                 pfContextAttr, ptsExpiry);
                HeapFree(GetProcessHeap(), 0, target);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsA(PCredHandle hCredentials,
 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
 void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
 PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
     debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
     pvGetKeyArgument, ptsExpiry);
    if (hCredentials)
    {
        SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
        PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;

        if (package && package->provider)
        {
            if (package->provider->fnTableW.AddCredentialsW)
            {
                UNICODE_STRING szPrincipal, szPackage;

                RtlCreateUnicodeStringFromAsciiz(&szPrincipal, pszPrincipal);
                RtlCreateUnicodeStringFromAsciiz(&szPackage, pszPackage);
                ret = package->provider->fnTableW.AddCredentialsW(
                 cred, szPrincipal.Buffer, szPackage.Buffer, fCredentialUse,
                 pAuthData, pGetKeyFn, pvGetKeyArgument, ptsExpiry);
                RtlFreeUnicodeString(&szPrincipal);
                RtlFreeUnicodeString(&szPackage);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsW(PCredHandle hCredentials,
 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
 void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
 PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;

    TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
     debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
     pvGetKeyArgument, ptsExpiry);
    if (hCredentials)
    {
        SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
        PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;

        if (package && package->provider)
        {
            if (package->provider->fnTableA.AddCredentialsA)
            {
                PSTR szPrincipal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
                PSTR szPackage = SECUR32_AllocMultiByteFromWide(pszPackage);

                ret = package->provider->fnTableA.AddCredentialsA(
                 cred, szPrincipal, szPackage, fCredentialUse, pAuthData,
                 pGetKeyFn, pvGetKeyArgument, ptsExpiry);
                HeapFree(GetProcessHeap(), 0, szPrincipal);
                HeapFree(GetProcessHeap(), 0, szPackage);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

static PSecPkgInfoA _copyPackageInfoFlatWToA(const SecPkgInfoW *infoW)
{
    PSecPkgInfoA ret;

    if (infoW)
    {
        size_t bytesNeeded = sizeof(SecPkgInfoA);
        int nameLen = 0, commentLen = 0;

        if (infoW->Name)
        {
            nameLen = WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1,
             NULL, 0, NULL, NULL);
            bytesNeeded += nameLen;
        }
        if (infoW->Comment)
        {
            commentLen = WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1,
             NULL, 0, NULL, NULL);
            bytesNeeded += commentLen;
        }
        ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
        if (ret)
        {
            PSTR nextString = (PSTR)((PBYTE)ret + sizeof(SecPkgInfoA));

            memcpy(ret, infoW, sizeof(SecPkgInfoA));
            if (infoW->Name)
            {
                ret->Name = nextString;
                WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, nextString,
                 nameLen, NULL, NULL);
                nextString += nameLen;
            }
            else
                ret->Name = NULL;
            if (infoW->Comment)
            {
                ret->Comment = nextString;
                WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, nextString,
                 nameLen, NULL, NULL);
            }
            else
                ret->Comment = NULL;
        }
    }
    else
        ret = NULL;
    return ret;
}

static SECURITY_STATUS thunk_ContextAttributesWToA(SecurePackage *package,
 ULONG ulAttribute, void *pBuffer)
{
    SECURITY_STATUS ret = SEC_E_OK;

    if (package && pBuffer)
    {
        switch (ulAttribute)
        {
            case SECPKG_ATTR_NAMES:
            {
                PSecPkgContext_NamesW names = (PSecPkgContext_NamesW)pBuffer;
                SEC_WCHAR *oldUser = names->sUserName;

                if (oldUser)
                {
                    names->sUserName =
                     (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser);
                    package->provider->fnTableW.FreeContextBuffer(oldUser);
                }
                break;
            }
            case SECPKG_ATTR_AUTHORITY:
            {
                PSecPkgContext_AuthorityW names =
                 (PSecPkgContext_AuthorityW)pBuffer;
                SEC_WCHAR *oldAuth = names->sAuthorityName;

                if (oldAuth)
                {
                    names->sAuthorityName =
                     (PWSTR)SECUR32_AllocMultiByteFromWide(oldAuth);
                    package->provider->fnTableW.FreeContextBuffer(oldAuth);
                }
                break;
            }
            case SECPKG_ATTR_KEY_INFO:
            {
                PSecPkgContext_KeyInfoW info = (PSecPkgContext_KeyInfoW)pBuffer;
                SEC_WCHAR *oldSigAlgName = info->sSignatureAlgorithmName;
                SEC_WCHAR *oldEncAlgName = info->sEncryptAlgorithmName;

                if (oldSigAlgName)
                {
                    info->sSignatureAlgorithmName =
                     (PWSTR)SECUR32_AllocMultiByteFromWide(oldSigAlgName);
                    package->provider->fnTableW.FreeContextBuffer(
                     oldSigAlgName);
                }
                if (oldEncAlgName)
                {
                    info->sEncryptAlgorithmName =
                     (PWSTR)SECUR32_AllocMultiByteFromWide(oldEncAlgName);
                    package->provider->fnTableW.FreeContextBuffer(
                     oldEncAlgName);
                }
                break;
            }
            case SECPKG_ATTR_PACKAGE_INFO:
            {
                PSecPkgContext_PackageInfoW info =
                 (PSecPkgContext_PackageInfoW)pBuffer;
                PSecPkgInfoW oldPkgInfo = info->PackageInfo;

                if (oldPkgInfo)
                {
                    info->PackageInfo = (PSecPkgInfoW)
                     _copyPackageInfoFlatWToA(oldPkgInfo);
                    package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
                }
                break;
            }
            case SECPKG_ATTR_NEGOTIATION_INFO:
            {
                PSecPkgContext_NegotiationInfoW info =
                 (PSecPkgContext_NegotiationInfoW)pBuffer;
                PSecPkgInfoW oldPkgInfo = info->PackageInfo;

                if (oldPkgInfo)
                {
                    info->PackageInfo = (PSecPkgInfoW)
                     _copyPackageInfoFlatWToA(oldPkgInfo);
                    package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
                }
                break;
            }
            case SECPKG_ATTR_NATIVE_NAMES:
            {
                PSecPkgContext_NativeNamesW names =
                 (PSecPkgContext_NativeNamesW)pBuffer;
                PWSTR oldClient = names->sClientName;
                PWSTR oldServer = names->sServerName;

                if (oldClient)
                {
                    names->sClientName = (PWSTR)SECUR32_AllocMultiByteFromWide(
                     oldClient);
                    package->provider->fnTableW.FreeContextBuffer(oldClient);
                }
                if (oldServer)
                {
                    names->sServerName = (PWSTR)SECUR32_AllocMultiByteFromWide(
                     oldServer);
                    package->provider->fnTableW.FreeContextBuffer(oldServer);
                }
                break;
            }
            case SECPKG_ATTR_CREDENTIAL_NAME:
            {
                PSecPkgContext_CredentialNameW name =
                 (PSecPkgContext_CredentialNameW)pBuffer;
                PWSTR oldCred = name->sCredentialName;

                if (oldCred)
                {
                    name->sCredentialName =
                     (PWSTR)SECUR32_AllocMultiByteFromWide(oldCred);
                    package->provider->fnTableW.FreeContextBuffer(oldCred);
                }
                break;
            }
            /* no thunking needed: */
            case SECPKG_ATTR_ACCESS_TOKEN:
            case SECPKG_ATTR_DCE_INFO:
            case SECPKG_ATTR_FLAGS:
            case SECPKG_ATTR_LIFESPAN:
            case SECPKG_ATTR_PASSWORD_EXPIRY:
            case SECPKG_ATTR_SESSION_KEY:
            case SECPKG_ATTR_SIZES:
            case SECPKG_ATTR_STREAM_SIZES:
            case SECPKG_ATTR_TARGET_INFORMATION:
                break;
            default:
                WARN("attribute type %d unknown\n", ulAttribute);
                ret = SEC_E_INTERNAL_ERROR;
        }
    }
    else
        ret = SEC_E_INVALID_TOKEN;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesA(PCtxtHandle phContext,
 ULONG ulAttribute, void *pBuffer)
{
    SECURITY_STATUS ret;

    TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
    if (phContext)
    {
        SecurePackage *package = (SecurePackage *)phContext->dwUpper;
        PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;

        if (package && package->provider)
        {
            if (package->provider->fnTableW.QueryContextAttributesW)
            {
                ret = package->provider->fnTableW.QueryContextAttributesW(
                 ctxt, ulAttribute, pBuffer);
                if (ret == SEC_E_OK)
                    ret = thunk_ContextAttributesWToA(package, ulAttribute,
                     pBuffer);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

static PSecPkgInfoW _copyPackageInfoFlatAToW(const SecPkgInfoA *infoA)
{
    PSecPkgInfoW ret;

    if (infoA)
    {
        size_t bytesNeeded = sizeof(SecPkgInfoW);
        int nameLen = 0, commentLen = 0;

        if (infoA->Name)
        {
            nameLen = MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1,
             NULL, 0);
            bytesNeeded += nameLen * sizeof(WCHAR);
        }
        if (infoA->Comment)
        {
            commentLen = MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1,
             NULL, 0);
            bytesNeeded += commentLen * sizeof(WCHAR);
        }
        ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
        if (ret)
        {
            PWSTR nextString = (PWSTR)((PBYTE)ret + sizeof(SecPkgInfoW));

            memcpy(ret, infoA, sizeof(SecPkgInfoA));
            if (infoA->Name)
            {
                ret->Name = nextString;
                MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, nextString,
                 nameLen);
                nextString += nameLen;
            }
            else
                ret->Name = NULL;
            if (infoA->Comment)
            {
                ret->Comment = nextString;
                MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, nextString,
                 commentLen);
            }
            else
                ret->Comment = NULL;
        }
    }
    else
        ret = NULL;
    return ret;
}

static SECURITY_STATUS thunk_ContextAttributesAToW(SecurePackage *package,
 ULONG ulAttribute, void *pBuffer)
{
    SECURITY_STATUS ret = SEC_E_OK;

    if (package && pBuffer)
    {
        switch (ulAttribute)
        {
            case SECPKG_ATTR_NAMES:
            {
                PSecPkgContext_NamesA names = (PSecPkgContext_NamesA)pBuffer;
                SEC_CHAR *oldUser = names->sUserName;

                if (oldUser)
                {
                    names->sUserName =
                     (PSTR)SECUR32_AllocWideFromMultiByte(oldUser);
                    package->provider->fnTableW.FreeContextBuffer(oldUser);
                }
                break;
            }
            case SECPKG_ATTR_AUTHORITY:
            {
                PSecPkgContext_AuthorityA names =
                 (PSecPkgContext_AuthorityA)pBuffer;
                SEC_CHAR *oldAuth = names->sAuthorityName;

                if (oldAuth)
                {
                    names->sAuthorityName =
                     (PSTR)SECUR32_AllocWideFromMultiByte(oldAuth);
                    package->provider->fnTableW.FreeContextBuffer(oldAuth);
                }
                break;
            }
            case SECPKG_ATTR_KEY_INFO:
            {
                PSecPkgContext_KeyInfoA info = (PSecPkgContext_KeyInfoA)pBuffer;
                SEC_CHAR *oldSigAlgName = info->sSignatureAlgorithmName;
                SEC_CHAR *oldEncAlgName = info->sEncryptAlgorithmName;

                if (oldSigAlgName)
                {
                    info->sSignatureAlgorithmName =
                     (PSTR)SECUR32_AllocWideFromMultiByte(oldSigAlgName);
                    package->provider->fnTableW.FreeContextBuffer(
                     oldSigAlgName);
                }
                if (oldEncAlgName)
                {
                    info->sEncryptAlgorithmName =
                     (PSTR)SECUR32_AllocWideFromMultiByte(
                     oldEncAlgName);
                    package->provider->fnTableW.FreeContextBuffer(
                     oldEncAlgName);
                }
                break;
            }
            case SECPKG_ATTR_PACKAGE_INFO:
            {
                PSecPkgContext_PackageInfoA info =
                 (PSecPkgContext_PackageInfoA)pBuffer;
                PSecPkgInfoA oldPkgInfo = info->PackageInfo;

                if (oldPkgInfo)
                {
                    info->PackageInfo = (PSecPkgInfoA)
                     _copyPackageInfoFlatAToW(oldPkgInfo);
                    package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
                }
                break;
            }
            case SECPKG_ATTR_NEGOTIATION_INFO:
            {
                PSecPkgContext_NegotiationInfoA info =
                 (PSecPkgContext_NegotiationInfoA)pBuffer;
                PSecPkgInfoA oldPkgInfo = info->PackageInfo;

                if (oldPkgInfo)
                {
                    info->PackageInfo = (PSecPkgInfoA)
                     _copyPackageInfoFlatAToW(oldPkgInfo);
                    package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
                }
                break;
            }
            case SECPKG_ATTR_NATIVE_NAMES:
            {
                PSecPkgContext_NativeNamesA names =
                 (PSecPkgContext_NativeNamesA)pBuffer;
                PSTR oldClient = names->sClientName;
                PSTR oldServer = names->sServerName;

                if (oldClient)
                {
                    names->sClientName = (PSTR)SECUR32_AllocWideFromMultiByte(
                     oldClient);
                    package->provider->fnTableW.FreeContextBuffer(oldClient);
                }
                if (oldServer)
                {
                    names->sServerName = (PSTR)SECUR32_AllocWideFromMultiByte(
                     oldServer);
                    package->provider->fnTableW.FreeContextBuffer(oldServer);
                }
                break;
            }
            case SECPKG_ATTR_CREDENTIAL_NAME:
            {
                PSecPkgContext_CredentialNameA name =
                 (PSecPkgContext_CredentialNameA)pBuffer;
                PSTR oldCred = name->sCredentialName;

                if (oldCred)
                {
                    name->sCredentialName =
                     (PSTR)SECUR32_AllocWideFromMultiByte(oldCred);
                    package->provider->fnTableW.FreeContextBuffer(oldCred);
                }
                break;
            }
            /* no thunking needed: */
            case SECPKG_ATTR_ACCESS_TOKEN:
            case SECPKG_ATTR_DCE_INFO:
            case SECPKG_ATTR_FLAGS:
            case SECPKG_ATTR_LIFESPAN:
            case SECPKG_ATTR_PASSWORD_EXPIRY:
            case SECPKG_ATTR_SESSION_KEY:
            case SECPKG_ATTR_SIZES:
            case SECPKG_ATTR_STREAM_SIZES:
            case SECPKG_ATTR_TARGET_INFORMATION:
                break;
            default:
                WARN("attribute type %d unknown\n", ulAttribute);
                ret = SEC_E_INTERNAL_ERROR;
        }
    }
    else
        ret = SEC_E_INVALID_TOKEN;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesW(PCtxtHandle phContext,
 ULONG ulAttribute, void *pBuffer)
{
    SECURITY_STATUS ret;

    TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
    if (phContext)
    {
        SecurePackage *package = (SecurePackage *)phContext->dwUpper;
        PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;

        if (package && package->provider)
        {
            if (package->provider->fnTableA.QueryContextAttributesA)
            {
                ret = package->provider->fnTableA.QueryContextAttributesA(
                 ctxt, ulAttribute, pBuffer);
                if (ret == SEC_E_OK)
                    ret = thunk_ContextAttributesAToW(package, ulAttribute,
                     pBuffer);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesA(PCtxtHandle phContext,
 ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
{
    SECURITY_STATUS ret;

    TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
    if (phContext)
    {
        SecurePackage *package = (SecurePackage *)phContext->dwUpper;
        PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;

        if (package && package->provider && pBuffer && cbBuffer)
        {
            if (package->provider->fnTableW.SetContextAttributesW)
            {
                /* TODO: gotta validate size too! */
                ret = thunk_ContextAttributesWToA(package, ulAttribute,
                 pBuffer);
                if (ret == SEC_E_OK)
                    ret = package->provider->fnTableW.SetContextAttributesW(
                     ctxt, ulAttribute, pBuffer, cbBuffer);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesW(PCtxtHandle phContext,
 ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
{
    SECURITY_STATUS ret;

    TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
    if (phContext)
    {
        SecurePackage *package = (SecurePackage *)phContext->dwUpper;
        PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;

        if (package && package->provider && pBuffer && cbBuffer)
        {
            if (package->provider->fnTableA.SetContextAttributesA)
            {
                /* TODO: gotta validate size too! */
                ret = thunk_ContextAttributesAToW(package, ulAttribute,
                 pBuffer);
                if (ret == SEC_E_OK)
                    ret = package->provider->fnTableA.SetContextAttributesA(
                     ctxt, ulAttribute, pBuffer, cbBuffer);
            }
            else
                ret = SEC_E_UNSUPPORTED_FUNCTION;
        }
        else
            ret = SEC_E_INVALID_HANDLE;
    }
    else
        ret = SEC_E_INVALID_HANDLE;
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextA(
 SEC_CHAR *pszPackage, PSecBuffer pPackedContext, void *Token,
 PCtxtHandle phContext)
{
    SECURITY_STATUS ret;
    UNICODE_STRING package;

    TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
     phContext);
    RtlCreateUnicodeStringFromAsciiz(&package, pszPackage);
    ret = ImportSecurityContextW(package.Buffer, pPackedContext, Token,
     phContext);
    RtlFreeUnicodeString(&package);
    return ret;
}

SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextW(
 SEC_WCHAR *pszPackage, PSecBuffer pPackedContext, void *Token,
 PCtxtHandle phContext)
{
    SECURITY_STATUS ret;
    PSTR package = SECUR32_AllocMultiByteFromWide(pszPackage);

    TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
     phContext);
    ret = ImportSecurityContextA(package, pPackedContext, Token, phContext);
    HeapFree(GetProcessHeap(), 0, package);
    return ret;
}
