|  | /* Copyright (C) 2004 Juan Lang | 
|  | * | 
|  | * Implements secur32 functions that forward to (wrap) an SSP's implementation. | 
|  | * | 
|  | * 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 "sspi.h" | 
|  | #include "secur32_priv.h" | 
|  |  | 
|  | #include "wine/debug.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(secur32); | 
|  |  | 
|  | /* Tries to allocate a new SecHandle, into which it stores package (in | 
|  | * phSec->dwUpper) and a copy of realHandle (allocated with SECUR32_ALLOC, | 
|  | * and stored in phSec->dwLower).  SecHandle is equivalent to both a | 
|  | * CredHandle and a CtxtHandle. | 
|  | */ | 
|  | static SECURITY_STATUS SECUR32_makeSecHandle(PSecHandle phSec, | 
|  | SecurePackage *package, PSecHandle realHandle) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p %p\n", phSec, package, realHandle); | 
|  |  | 
|  | if (phSec && package && realHandle) | 
|  | { | 
|  | PSecHandle newSec = HeapAlloc(GetProcessHeap(), 0, sizeof(SecHandle)); | 
|  |  | 
|  | if (newSec) | 
|  | { | 
|  | *newSec = *realHandle; | 
|  | phSec->dwUpper = (ULONG_PTR)package; | 
|  | phSec->dwLower = (ULONG_PTR)newSec; | 
|  | ret = SEC_E_OK; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INSUFFICIENT_MEMORY; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		AcquireCredentialsHandleA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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) | 
|  | { | 
|  | SecurePackage *package = SECUR32_findPackageA(pszPackage); | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableA.AcquireCredentialsHandleA) | 
|  | { | 
|  | CredHandle myCred; | 
|  |  | 
|  | ret = package->provider->fnTableA.AcquireCredentialsHandleA( | 
|  | pszPrincipal, pszPackage, fCredentialsUse, pvLogonID, | 
|  | pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred, | 
|  | ptsExpiry); | 
|  | if (ret == SEC_E_OK) | 
|  | { | 
|  | ret = SECUR32_makeSecHandle(phCredential, package, &myCred); | 
|  | if (ret != SEC_E_OK) | 
|  | package->provider->fnTableW.FreeCredentialsHandle( | 
|  | &myCred); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		AcquireCredentialsHandleW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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) | 
|  | { | 
|  | SecurePackage *package = SECUR32_findPackageW(pszPackage); | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.AcquireCredentialsHandleW) | 
|  | { | 
|  | CredHandle myCred; | 
|  |  | 
|  | ret = package->provider->fnTableW.AcquireCredentialsHandleW( | 
|  | pszPrincipal, pszPackage, fCredentialsUse, pvLogonID, | 
|  | pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred, | 
|  | ptsExpiry); | 
|  | if (ret == SEC_E_OK) | 
|  | { | 
|  | ret = SECUR32_makeSecHandle(phCredential, package, &myCred); | 
|  | if (ret != SEC_E_OK) | 
|  | package->provider->fnTableW.FreeCredentialsHandle( | 
|  | &myCred); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		FreeCredentialsHandle (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI FreeCredentialsHandle( | 
|  | PCredHandle phCredential) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p\n", phCredential); | 
|  | if (phCredential) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phCredential->dwUpper; | 
|  | PCredHandle cred = (PCredHandle)phCredential->dwLower; | 
|  |  | 
|  | if (package && package->provider && | 
|  | package->provider->fnTableW.FreeCredentialsHandle) | 
|  | ret = package->provider->fnTableW.FreeCredentialsHandle(cred); | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | HeapFree(GetProcessHeap(), 0, cred); | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QueryCredentialsAttributesA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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->fnTableA.QueryCredentialsAttributesA) | 
|  | ret = package->provider->fnTableA.QueryCredentialsAttributesA( | 
|  | cred, ulAttribute, pBuffer); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QueryCredentialsAttributesW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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->fnTableW.QueryCredentialsAttributesW) | 
|  | ret = package->provider->fnTableW.QueryCredentialsAttributesW( | 
|  | cred, ulAttribute, pBuffer); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		InitializeSecurityContextA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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; | 
|  | SecurePackage *package = NULL; | 
|  | PCredHandle cred = NULL; | 
|  | PCredHandle ctxt = NULL; | 
|  |  | 
|  | 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 (phContext) | 
|  | { | 
|  | package = (SecurePackage *)phContext->dwUpper; | 
|  | ctxt = (PCtxtHandle)phContext->dwLower; | 
|  | } | 
|  | if (phCredential) | 
|  | { | 
|  | package = (SecurePackage *)phCredential->dwUpper; | 
|  | cred = (PCredHandle)phCredential->dwLower; | 
|  | } | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableA.InitializeSecurityContextA) | 
|  | { | 
|  | CtxtHandle myCtxt; | 
|  |  | 
|  | if (phContext) | 
|  | { | 
|  | PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower; | 
|  | myCtxt.dwUpper = realCtxt->dwUpper; | 
|  | myCtxt.dwLower = realCtxt->dwLower; | 
|  | } | 
|  |  | 
|  | ret = package->provider->fnTableA.InitializeSecurityContextA( | 
|  | cred, ctxt, pszTargetName, fContextReq, | 
|  | Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL, | 
|  | pOutput, pfContextAttr, ptsExpiry); | 
|  | if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && | 
|  | phNewContext && phNewContext != phContext) | 
|  | { | 
|  | SECURITY_STATUS ret2; | 
|  | ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt); | 
|  | if (ret2 != SEC_E_OK) | 
|  | package->provider->fnTableA.DeleteSecurityContext(&myCtxt); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		InitializeSecurityContextW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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; | 
|  | SecurePackage *package = NULL; | 
|  | PCredHandle cred = NULL; | 
|  | PCredHandle ctxt = NULL; | 
|  |  | 
|  | 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 (phContext) | 
|  | { | 
|  | package = (SecurePackage *)phContext->dwUpper; | 
|  | ctxt = (PCtxtHandle)phContext->dwLower; | 
|  | } | 
|  | if (phCredential) | 
|  | { | 
|  | package = (SecurePackage *)phCredential->dwUpper; | 
|  | cred = (PCredHandle)phCredential->dwLower; | 
|  | } | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.InitializeSecurityContextW) | 
|  | { | 
|  | CtxtHandle myCtxt; | 
|  |  | 
|  | if (phContext) | 
|  | { | 
|  | PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower; | 
|  | myCtxt.dwUpper = realCtxt->dwUpper; | 
|  | myCtxt.dwLower = realCtxt->dwLower; | 
|  | } | 
|  |  | 
|  | ret = package->provider->fnTableW.InitializeSecurityContextW( | 
|  | cred, ctxt, pszTargetName, fContextReq, | 
|  | Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL, | 
|  | pOutput, pfContextAttr, ptsExpiry); | 
|  | if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && | 
|  | phNewContext && phNewContext != phContext) | 
|  | { | 
|  | SECURITY_STATUS ret2; | 
|  | ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt); | 
|  | if (ret2 != SEC_E_OK) | 
|  | package->provider->fnTableW.DeleteSecurityContext(&myCtxt); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		AcceptSecurityContext (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI AcceptSecurityContext( | 
|  | PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, | 
|  | ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, | 
|  | PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput, | 
|  | fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, | 
|  | ptsExpiry); | 
|  | if (phCredential) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phCredential->dwUpper; | 
|  | PCredHandle cred = (PCredHandle)phCredential->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.AcceptSecurityContext) | 
|  | { | 
|  | CtxtHandle myCtxt; | 
|  |  | 
|  | if(phContext) | 
|  | { | 
|  | PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower; | 
|  | TRACE("realCtx: %p\n", realCtxt); | 
|  | myCtxt.dwUpper = realCtxt->dwUpper; | 
|  | myCtxt.dwLower = realCtxt->dwLower; | 
|  | } | 
|  |  | 
|  | ret = package->provider->fnTableW.AcceptSecurityContext( | 
|  | cred, phContext ? &myCtxt : NULL, pInput, fContextReq, | 
|  | TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry); | 
|  | if (ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) | 
|  | { | 
|  | SECURITY_STATUS ret2; | 
|  | ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt); | 
|  | if (ret2 != SEC_E_OK) | 
|  | package->provider->fnTableW.DeleteSecurityContext( | 
|  | &myCtxt); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		CompleteAuthToken (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext, | 
|  | PSecBufferDesc pToken) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p\n", phContext, pToken); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.CompleteAuthToken) | 
|  | ret = package->provider->fnTableW.CompleteAuthToken(ctxt, | 
|  | pToken); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		DeleteSecurityContext (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p\n", phContext); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider && | 
|  | package->provider->fnTableW.DeleteSecurityContext) | 
|  | ret = package->provider->fnTableW.DeleteSecurityContext(ctxt); | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | HeapFree(GetProcessHeap(), 0, ctxt); | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		ApplyControlToken (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI ApplyControlToken(PCtxtHandle phContext, | 
|  | PSecBufferDesc pInput) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p\n", phContext, pInput); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.ApplyControlToken) | 
|  | ret = package->provider->fnTableW.ApplyControlToken( | 
|  | ctxt, pInput); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QueryContextAttributesA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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->fnTableA.QueryContextAttributesA) | 
|  | ret = package->provider->fnTableA.QueryContextAttributesA( | 
|  | ctxt, ulAttribute, pBuffer); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QueryContextAttributesW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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->fnTableW.QueryContextAttributesW) | 
|  | ret = package->provider->fnTableW.QueryContextAttributesW( | 
|  | ctxt, ulAttribute, pBuffer); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		ImpersonateSecurityContext (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p\n", phContext); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.ImpersonateSecurityContext) | 
|  | ret = package->provider->fnTableW.ImpersonateSecurityContext( | 
|  | ctxt); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		RevertSecurityContext (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p\n", phContext); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.RevertSecurityContext) | 
|  | ret = package->provider->fnTableW.RevertSecurityContext( | 
|  | ctxt); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		MakeSignature (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP, | 
|  | PSecBufferDesc pMessage, ULONG MessageSeqNo) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.MakeSignature) | 
|  | ret = package->provider->fnTableW.MakeSignature( | 
|  | ctxt, fQOP, pMessage, MessageSeqNo); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		VerifySignature (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext, | 
|  | PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.VerifySignature) | 
|  | ret = package->provider->fnTableW.VerifySignature( | 
|  | ctxt, pMessage, MessageSeqNo, pfQOP); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QuerySecurityPackageInfoA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName, | 
|  | PSecPkgInfoA *ppPackageInfo) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo); | 
|  | if (pszPackageName) | 
|  | { | 
|  | SecurePackage *package = SECUR32_findPackageA(pszPackageName); | 
|  |  | 
|  | if (package) | 
|  | { | 
|  | size_t bytesNeeded = sizeof(SecPkgInfoA); | 
|  | int nameLen = 0, commentLen = 0; | 
|  |  | 
|  | if (package->infoW.Name) | 
|  | { | 
|  | nameLen = WideCharToMultiByte(CP_ACP, 0, | 
|  | package->infoW.Name, -1, NULL, 0, NULL, NULL); | 
|  | bytesNeeded += nameLen; | 
|  | } | 
|  | if (package->infoW.Comment) | 
|  | { | 
|  | commentLen = WideCharToMultiByte(CP_ACP, 0, | 
|  | package->infoW.Comment, -1, NULL, 0, NULL, NULL); | 
|  | bytesNeeded += commentLen; | 
|  | } | 
|  | *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); | 
|  | if (*ppPackageInfo) | 
|  | { | 
|  | PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo + | 
|  | sizeof(SecPkgInfoA)); | 
|  |  | 
|  | memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW)); | 
|  | if (package->infoW.Name) | 
|  | { | 
|  | (*ppPackageInfo)->Name = nextString; | 
|  | nextString += WideCharToMultiByte(CP_ACP, 0, | 
|  | package->infoW.Name, -1, nextString, nameLen, NULL, NULL); | 
|  | } | 
|  | else | 
|  | (*ppPackageInfo)->Name = NULL; | 
|  | if (package->infoW.Comment) | 
|  | { | 
|  | (*ppPackageInfo)->Comment = nextString; | 
|  | nextString += WideCharToMultiByte(CP_ACP, 0, | 
|  | package->infoW.Comment, -1, nextString, commentLen, NULL, | 
|  | NULL); | 
|  | } | 
|  | else | 
|  | (*ppPackageInfo)->Comment = NULL; | 
|  | ret = SEC_E_OK; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INSUFFICIENT_MEMORY; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QuerySecurityPackageInfoW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName, | 
|  | PSecPkgInfoW *ppPackageInfo) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  | SecurePackage *package = SECUR32_findPackageW(pszPackageName); | 
|  |  | 
|  | TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo); | 
|  | if (package) | 
|  | { | 
|  | size_t bytesNeeded = sizeof(SecPkgInfoW); | 
|  | int nameLen = 0, commentLen = 0; | 
|  |  | 
|  | if (package->infoW.Name) | 
|  | { | 
|  | nameLen = lstrlenW(package->infoW.Name) + 1; | 
|  | bytesNeeded += nameLen * sizeof(WCHAR); | 
|  | } | 
|  | if (package->infoW.Comment) | 
|  | { | 
|  | commentLen = lstrlenW(package->infoW.Comment) + 1; | 
|  | bytesNeeded += commentLen * sizeof(WCHAR); | 
|  | } | 
|  | *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); | 
|  | if (*ppPackageInfo) | 
|  | { | 
|  | PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo + | 
|  | sizeof(SecPkgInfoW)); | 
|  |  | 
|  | **ppPackageInfo = package->infoW; | 
|  | if (package->infoW.Name) | 
|  | { | 
|  | (*ppPackageInfo)->Name = nextString; | 
|  | lstrcpynW(nextString, package->infoW.Name, nameLen); | 
|  | nextString += nameLen; | 
|  | } | 
|  | else | 
|  | (*ppPackageInfo)->Name = NULL; | 
|  | if (package->infoW.Comment) | 
|  | { | 
|  | (*ppPackageInfo)->Comment = nextString; | 
|  | lstrcpynW(nextString, package->infoW.Comment, commentLen); | 
|  | nextString += commentLen; | 
|  | } | 
|  | else | 
|  | (*ppPackageInfo)->Comment = NULL; | 
|  | ret = SEC_E_OK; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INSUFFICIENT_MEMORY; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		ExportSecurityContext (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI ExportSecurityContext(PCtxtHandle phContext, | 
|  | ULONG fFlags, PSecBuffer pPackedContext, void **pToken) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %d %p %p\n", phContext, fFlags, pPackedContext, pToken); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.ExportSecurityContext) | 
|  | ret = package->provider->fnTableW.ExportSecurityContext( | 
|  | ctxt, fFlags, pPackedContext, pToken); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		ImportSecurityContextA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI ImportSecurityContextA(SEC_CHAR *pszPackage, | 
|  | PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  | SecurePackage *package = SECUR32_findPackageA(pszPackage); | 
|  |  | 
|  | TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token, | 
|  | phContext); | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableA.ImportSecurityContextA) | 
|  | { | 
|  | CtxtHandle myCtxt; | 
|  |  | 
|  | ret = package->provider->fnTableA.ImportSecurityContextA( | 
|  | pszPackage, pPackedContext, Token, &myCtxt); | 
|  | if (ret == SEC_E_OK) | 
|  | { | 
|  | ret = SECUR32_makeSecHandle(phContext, package, &myCtxt); | 
|  | if (ret != SEC_E_OK) | 
|  | package->provider->fnTableW.DeleteSecurityContext(&myCtxt); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | return ret; | 
|  |  | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		ImportSecurityContextW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI ImportSecurityContextW(SEC_WCHAR *pszPackage, | 
|  | PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  | SecurePackage *package = SECUR32_findPackageW(pszPackage); | 
|  |  | 
|  | TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token, | 
|  | phContext); | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.ImportSecurityContextW) | 
|  | { | 
|  | CtxtHandle myCtxt; | 
|  |  | 
|  | ret = package->provider->fnTableW.ImportSecurityContextW( | 
|  | pszPackage, pPackedContext, Token, &myCtxt); | 
|  | if (ret == SEC_E_OK) | 
|  | { | 
|  | ret = SECUR32_makeSecHandle(phContext, package, &myCtxt); | 
|  | if (ret != SEC_E_OK) | 
|  | package->provider->fnTableW.DeleteSecurityContext(&myCtxt); | 
|  | } | 
|  | } | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_SECPKG_NOT_FOUND; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		AddCredentialsA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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->fnTableA.AddCredentialsA) | 
|  | ret = package->provider->fnTableA.AddCredentialsA( | 
|  | cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData, | 
|  | pGetKeyFn, pvGetKeyArgument, ptsExpiry); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		AddCredentialsW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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->fnTableW.AddCredentialsW) | 
|  | ret = package->provider->fnTableW.AddCredentialsW( | 
|  | cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData, | 
|  | pGetKeyFn, pvGetKeyArgument, ptsExpiry); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		QuerySecurityContextToken (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI QuerySecurityContextToken(PCtxtHandle phContext, | 
|  | HANDLE *phToken) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p\n", phContext, phToken); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.QuerySecurityContextToken) | 
|  | ret = package->provider->fnTableW.QuerySecurityContextToken( | 
|  | ctxt, phToken); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		EncryptMessage (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, | 
|  | PSecBufferDesc pMessage, ULONG MessageSeqNo) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.EncryptMessage) | 
|  | ret = package->provider->fnTableW.EncryptMessage( | 
|  | ctxt, fQOP, pMessage, MessageSeqNo); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		DecryptMessage (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, | 
|  | PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) | 
|  | { | 
|  | SECURITY_STATUS ret; | 
|  |  | 
|  | TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP); | 
|  | if (phContext) | 
|  | { | 
|  | SecurePackage *package = (SecurePackage *)phContext->dwUpper; | 
|  | PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; | 
|  |  | 
|  | if (package && package->provider) | 
|  | { | 
|  | if (package->provider->fnTableW.DecryptMessage) | 
|  | ret = package->provider->fnTableW.DecryptMessage( | 
|  | ctxt, pMessage, MessageSeqNo, pfQOP); | 
|  | else | 
|  | ret = SEC_E_UNSUPPORTED_FUNCTION; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | } | 
|  | else | 
|  | ret = SEC_E_INVALID_HANDLE; | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		SetContextAttributesA (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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) | 
|  | { | 
|  | if (package->provider->fnTableA.SetContextAttributesA) | 
|  | 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; | 
|  | } | 
|  |  | 
|  | /*********************************************************************** | 
|  | *		SetContextAttributesW (SECUR32.@) | 
|  | */ | 
|  | SECURITY_STATUS WINAPI 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) | 
|  | { | 
|  | if (package->provider->fnTableW.SetContextAttributesW) | 
|  | 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; | 
|  | } |