private static unsafe int MustRunInitializeSecurityContext_SECURITY(
ref SafeFreeCredentials inCredentials,
void* inContextPtr,
byte* targetName,
Interop.SspiCli.ContextFlags inFlags,
Interop.SspiCli.Endianness endianness,
Interop.SspiCli.SecBufferDesc* inputBuffer,
SafeDeleteContext outContext,
ref Interop.SspiCli.SecBufferDesc outputBuffer,
ref Interop.SspiCli.ContextFlags attributes,
SafeFreeContextBuffer handleTemplate)
{
int errorCode = (int)Interop.SECURITY_STATUS.InvalidHandle;
try
{
bool ignore = false;
inCredentials.DangerousAddRef(ref ignore);
outContext.DangerousAddRef(ref ignore);
Interop.SspiCli.CredHandle credentialHandle = inCredentials._handle;
long timeStamp;
errorCode = Interop.SspiCli.InitializeSecurityContextW(
ref credentialHandle,
inContextPtr,
targetName,
inFlags,
0,
endianness,
inputBuffer,
0,
ref outContext._handle,
ref outputBuffer,
ref attributes,
out timeStamp);
}
finally
{
//
// When a credential handle is first associated with the context we keep credential
// ref count bumped up to ensure ordered finalization.
// If the credential handle has been changed we de-ref the old one and associate the
// context with the new cred handle but only if the call was successful.
if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0)
{
// Disassociate the previous credential handle
if (outContext._EffectiveCredential != null)
{
outContext._EffectiveCredential.DangerousRelease();
}
outContext._EffectiveCredential = inCredentials;
}
else
{
inCredentials.DangerousRelease();
}
outContext.DangerousRelease();
}
// The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer.
if (handleTemplate != null)
{
//ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes
handleTemplate.Set(((Interop.SspiCli.SecBuffer*)outputBuffer.pBuffers)->pvBuffer);
if (handleTemplate.IsInvalid)
{
handleTemplate.SetHandleAsInvalid();
}
}
if (inContextPtr == null && (errorCode & 0x80000000) != 0)
{
// an error on the first call, need to set the out handle to invalid value
outContext._handle.SetToInvalid();
}
return errorCode;
}