private void DoBeginSendFile(
string fileName,
byte[] preBuffer,
byte[] postBuffer,
TransmitFileOptions flags,
TransmitFileOverlappedAsyncResult asyncResult)
{
if(s_LoggingEnabled)Logging.Enter(Logging.Sockets, this, "BeginSendFile", "");
if (CleanedUp) {
throw new ObjectDisposedException(this.GetType().FullName);
}
if (CleanedUp) {
throw new ObjectDisposedException(this.GetType().FullName);
}
#if FEATURE_PAL
throw new PlatformNotSupportedException(SR.GetString(SR.WinNTRequired));
#endif // FEATURE_PAL
if (!Connected) {
throw new NotSupportedException(SR.GetString(SR.net_notconnected));
}
GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::DoBeginSendFile() SRC:" + ValidationHelper.ToString(LocalEndPoint) + " DST:" + ValidationHelper.ToString(RemoteEndPoint) + " fileName:" + fileName);
FileStream fileStream = null;
if (fileName != null && fileName.Length>0) {
fileStream = new FileStream(fileName,FileMode.Open,FileAccess.Read,FileShare.Read);
}
SafeHandle fileHandle = null;
if (fileStream != null) {
ExceptionHelper.UnmanagedPermission.Assert();
try {
fileHandle = fileStream.SafeFileHandle;
}
finally {
SecurityPermission.RevertAssert();
}
}
// Guarantee to call CheckAsyncCallOverlappedResult if we call SetUnamangedStructures with a cache in order to
// avoid a Socket leak in case of error.
SocketError errorCode = SocketError.SocketError;
try
{
asyncResult.SetUnmanagedStructures(preBuffer, postBuffer, fileStream, flags, ref Caches.SendOverlappedCache);
bool result = false;
// This can throw ObjectDisposedException.
if (fileHandle != null){
result = UnsafeNclNativeMethods.OSSOCK.TransmitFile(m_Handle,fileHandle,0,0,asyncResult.OverlappedHandle,asyncResult.TransmitFileBuffers,flags);
}
else{
result = UnsafeNclNativeMethods.OSSOCK.TransmitFile2(m_Handle,IntPtr.Zero,0,0,asyncResult.OverlappedHandle,asyncResult.TransmitFileBuffers,flags);
}
if(!result)
{
errorCode = (SocketError)Marshal.GetLastWin32Error();
}
else
{
errorCode = SocketError.Success;
}
}
finally
{
errorCode = asyncResult.CheckAsyncCallOverlappedResult(errorCode);
}
//
// if the native call fails we'll throw a SocketException
//
if (errorCode!=SocketError.Success) {
//
// update our internal state after this socket error and throw
//
asyncResult.ExtractCache(ref Caches.SendOverlappedCache);
SocketException socketException = new SocketException(errorCode);
UpdateStatusAfterSocketError(socketException);
if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "BeginSendFile", socketException);
throw socketException;
}
GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::DoBeginSendFile() UnsafeNclNativeMethods.OSSOCK.send returns:" + errorCode.ToString());
if(s_LoggingEnabled)Logging.Exit(Logging.Sockets, this, "BeginSendFile", errorCode);
}