DWORD Sm_Shiloh::WriteSync(__in SNI_Packet * pPacket, SNI_ProvInfo * pInfo) { BidxScopeAutoSNI3( SNIAPI_TAG _T("%u#, ") _T("pPacket: %p{SNI_Packet*}, ") _T("pInfo: %p{SNI_ProvInfo*}\n"), GetBidId(), pPacket, pInfo ); DWORD dwRet = ERROR_SUCCESS; // Check that the packetsize does not exceed the max packet size if( MAX_BUFFER_SIZE < SNIPacketGetBufferSize(pPacket) ) { dwRet = ERROR_NOT_SUPPORTED; SNI_SET_LAST_ERROR( SM_PROV, SNIE_SYSTEM, dwRet ); goto Exit; } // Post the transport write LONG Error; if( SNIPacketGetBufferSize(pPacket) != g_rgFuncs.Write( m_pConnObj, SNIPacketGetBufPtr(pPacket), (int)SNIPacketGetBufferSize(pPacket), &Error ) ) { dwRet = Error; SNI_SET_LAST_ERROR( SM_PROV, SNIE_1, dwRet ); } Exit: BidTraceU1( SNI_BID_TRACE_ON, RETURN_TAG _T("%d{WINERR}\n"), dwRet); return dwRet; }
friend void SNIPacketRelease(SNI_Packet * pPacket) { BidTraceU2( SNI_BID_TRACE_ON, SNIAPI_TAG _T("%u#{SNI_Packet}, ") _T("pPacket: %p{SNI_Packet*}\n"), SNIPacketGetBidId(pPacket), pPacket); Assert (pPacket); Assert (pPacket->m_pConn); Assert (pPacket->m_cRef > 0); Assert (pPacket->m_IOType < SNI_Packet_InvalidType); Assert ((pPacket->m_IOType != SNI_Packet_KeyHolderNoBuf) || ( (NULL == pPacket->m_pBuffer) && (0 == pPacket->m_cbBuffer) && (0 == pPacket->m_cBufferSize)) ); Assert (pPacket->m_ConsBuf < SNI_Consumer_Invalid); int iBidId = SNIPacketGetBidId(pPacket); // Only release the packet if it's ref count drops to zero. if ( 0 != InterlockedDecrement( &pPacket->m_cRef ) ) { BidTraceU2( SNI_BID_TRACE_ON, RETURN_TAG _T("%u#!{SNI_Packet}: ") _T("Not final release. ") _T("pPacket: %p{SNI_Packet*}\n"), iBidId, pPacket); return; } #ifndef SNI_BASED_CLIENT if ((SNI_Packet_Read == pPacket->m_IOType) || (SNI_Packet_Write == pPacket->m_IOType)) { Assert(pPacket->m_pBuffer != NULL); BOOL fGlobalZeroingRequired = SOS_OS::GetCommonCriteriaModeEnabled (); if (pPacket->m_fZeroPayloadOnRelease || fGlobalZeroingRequired) { BYTE * pbBuf; DWORD cbBuf; if (fGlobalZeroingRequired) { // If global zeroing is required always zero out the whole buffer // pbBuf = pPacket->m_pBuffer; cbBuf = pPacket->m_cBufferSize; } else { pbBuf = SNIPacketGetBufPtr(pPacket); cbBuf = SNIPacketGetBufferSize(pPacket); // The bytes of memory to zero should never exceed the size // of the packet // If the m_cbBytesToZero is on-zero, we will zero out that // amount, if not, zero out all the bytes // Assert (pPacket->m_cbBytesToZero <= cbBuf); if (pPacket->m_cbBytesToZero != 0) cbBuf = pPacket->m_cbBytesToZero; } SecureZeroMemory(pbBuf, cbBuf); pPacket->m_fZeroPayloadOnRelease = FALSE; pPacket->m_cbBytesToZero= 0; } } else // "Buffer-less" packet like SNI_Packet_KeyHolderNoBuf or SNI_Packet_VaryingBuffer* { pPacket->m_fZeroPayloadOnRelease = FALSE; pPacket->m_cbBytesToZero= 0; } #endif // ifndef SNI_BASED_CLIENT // While SNI_Packet_KeyHolderNoBuf type of packet never gets a buffer assigned to it // the SNI_Packet_VaryingBuffer* packets get their buffers assigned by the Consumer // However, Consumer is fully responsible for releasing the buffers, SNI treats // these types of packets as "buffer-less" and simply removes any reference to // the potential buffers used by the Consumer if ((SNI_Packet_VaryingBufferRead == pPacket->m_IOType) || (SNI_Packet_VaryingBufferWrite == pPacket->m_IOType)) { pPacket->m_pBuffer = NULL; pPacket->m_pNext = NULL; pPacket->m_cBufferSize = 0; pPacket->m_cbBuffer = 0; } pPacket->m_ConsBuf = SNI_Consumer_PacketIsReleased; BidTraceU1( SNI_BID_TRACE_ON, SNI_TAG _T("%u#{SNI_Packet} to pool\n"), SNIPacketGetBidId(pPacket) ); SNI_Conn* pConn = pPacket->m_pConn; if ((SNI_Packet_Read == pPacket->m_IOType) || (SNI_Packet_Write == pPacket->m_IOType)) { pConn->Release( REF_Packet ); } else { pConn->Release( REF_PacketNotOwningBuf ); } #ifdef SNI_BASED_CLIENT // No need to check for [....] or async conn, we just set the Overlapped hEvent to NULL pPacket->RemoveOvlEvent(); #endif pPacket->m_pMemRegion->Push(pPacket); }