/* * This is to support SSL under semi trusted environment. * Note that it is only for SSL with no client cert * * Important: safeHandle should not be Disposed during construction of this object. */ internal SecurityPackageInfoClass(SafeHandle safeHandle, int index) { if (safeHandle.IsInvalid) { GlobalLog.Print("SecurityPackageInfoClass::.ctor() the pointer is invalid: " + (safeHandle.DangerousGetHandle()).ToString("x")); return; } IntPtr unmanagedAddress = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index); GlobalLog.Print("SecurityPackageInfoClass::.ctor() unmanagedPointer: " + ((long)unmanagedAddress).ToString("x")); Capabilities = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Capabilities")); Version = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Version")); RPCID = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("RPCID")); MaxToken = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("MaxToken")); IntPtr unmanagedString; unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Name")); if (unmanagedString != IntPtr.Zero) { Name = Marshal.PtrToStringUni(unmanagedString); GlobalLog.Print("Name: " + Name); } unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Comment")); if (unmanagedString != IntPtr.Zero) { Comment = Marshal.PtrToStringUni(unmanagedString); GlobalLog.Print("Comment: " + Comment); } GlobalLog.Print("SecurityPackageInfoClass::.ctor(): " + ToString()); }
internal SecurityPackageInfoClass(SafeHandle safeHandle, int index) { if (!safeHandle.IsInvalid) { IntPtr ptr = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index); this.Capabilities = Marshal.ReadInt32(ptr, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Capabilities")); this.Version = Marshal.ReadInt16(ptr, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Version")); this.RPCID = Marshal.ReadInt16(ptr, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "RPCID")); this.MaxToken = Marshal.ReadInt32(ptr, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "MaxToken")); IntPtr ptr2 = Marshal.ReadIntPtr(ptr, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name")); if (ptr2 != IntPtr.Zero) { if (ComNetOS.IsWin9x) { this.Name = Marshal.PtrToStringAnsi(ptr2); } else { this.Name = Marshal.PtrToStringUni(ptr2); } } ptr2 = Marshal.ReadIntPtr(ptr, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Comment")); if (ptr2 != IntPtr.Zero) { if (ComNetOS.IsWin9x) { this.Comment = Marshal.PtrToStringAnsi(ptr2); } else { this.Comment = Marshal.PtrToStringUni(ptr2); } } } }
/* * This is to support SSL with no client cert. * Important: safeHandle should not be Disposed during construction of this object. * * _SecPkgInfoW in sspi.h */ internal SecurityPackageInfoClass(SafeHandle safeHandle, int index) { if (safeHandle.IsInvalid) { if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"Invalid handle: {safeHandle}"); } return; } IntPtr unmanagedAddress = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"unmanagedAddress: {unmanagedAddress}"); } // TODO (Issue #3114): replace with Marshal.PtrToStructure. Capabilities = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Capabilities")); Version = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Version")); RPCID = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("RPCID")); MaxToken = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("MaxToken")); IntPtr unmanagedString; unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Name")); if (unmanagedString != IntPtr.Zero) { Name = Marshal.PtrToStringUni(unmanagedString); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"Name: {Name}"); } } unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf <SecurityPackageInfo>("Comment")); if (unmanagedString != IntPtr.Zero) { Comment = Marshal.PtrToStringUni(unmanagedString); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"Comment: {Comment}"); } } if (NetEventSource.IsEnabled) { NetEventSource.Info(this, this.ToString()); } }
// // Constructor // internal ListenerAsyncResult(Object userState, AsyncCallback callback) : base(null, userState, callback) { // // we will use this overlapped structure to issue async IO to ul // the event handle will be put in by the BeginXXX() method // m_BufferSize = UlConstants.InitialBufferSize; m_BytesReturned = 0; m_RequestId = 0; m_Retries = 0; m_UnmanagedBlob = Marshal.AllocHGlobal(Win32.OverlappedSize + m_BufferSize); m_Overlapped = m_UnmanagedBlob; m_Buffer = IntPtrHelper.Add(m_UnmanagedBlob, Win32.OverlappedSize); return; } // ListenerAsyncResult()
private static byte[] formatChannelBindingForHash(ChannelBinding binding) { int num = Marshal.ReadInt32(binding.DangerousGetHandle(), InitiatorTypeOffset); int num2 = Marshal.ReadInt32(binding.DangerousGetHandle(), InitiatorLengthOffset); int num3 = Marshal.ReadInt32(binding.DangerousGetHandle(), AcceptorTypeOffset); int num4 = Marshal.ReadInt32(binding.DangerousGetHandle(), AcceptorLengthOffset); int num5 = Marshal.ReadInt32(binding.DangerousGetHandle(), ApplicationDataLengthOffset); byte[] array = new byte[((MinimumFormattedBindingLength + num2) + num4) + num5]; BitConverter.GetBytes(num).CopyTo(array, 0); BitConverter.GetBytes(num2).CopyTo(array, SizeOfInt); int startIndex = 2 * SizeOfInt; if (num2 > 0) { int b = Marshal.ReadInt32(binding.DangerousGetHandle(), InitiatorOffsetOffset); Marshal.Copy(IntPtrHelper.Add(binding.DangerousGetHandle(), b), array, startIndex, num2); startIndex += num2; } BitConverter.GetBytes(num3).CopyTo(array, startIndex); BitConverter.GetBytes(num4).CopyTo(array, (int)(startIndex + SizeOfInt)); startIndex += 2 * SizeOfInt; if (num4 > 0) { int num8 = Marshal.ReadInt32(binding.DangerousGetHandle(), AcceptorOffsetOffset); Marshal.Copy(IntPtrHelper.Add(binding.DangerousGetHandle(), num8), array, startIndex, num4); startIndex += num4; } BitConverter.GetBytes(num5).CopyTo(array, startIndex); startIndex += SizeOfInt; if (num5 > 0) { int num9 = Marshal.ReadInt32(binding.DangerousGetHandle(), ApplicationDataOffsetOffset); Marshal.Copy(IntPtrHelper.Add(binding.DangerousGetHandle(), num9), array, startIndex, num5); } return(array); }
// private static SecurityPackageInfoClass[] m_SecurityPackages; private static SecurityPackageInfoClass[] EnumerateSecurityPackages(SSPIInterface SecModule) { GlobalLog.Enter("EnumerateSecurityPackages"); int moduleCount = 0; IntPtr arrayBase = IntPtr.Zero; int errorCode = SecModule.EnumerateSecurityPackages( out moduleCount, out arrayBase); GlobalLog.Print("SSPIWrapper::arrayBase: " + ((long)arrayBase).ToString()); if (errorCode != 0) { throw new Win32Exception(errorCode); } SecurityPackageInfoClass[] securityPackages = new SecurityPackageInfoClass[moduleCount]; int i; IntPtr unmanagedPointer = arrayBase; for (i = 0; i < moduleCount; i++) { GlobalLog.Print("SSPIWrapper::unmanagedPointer: " + ((long)unmanagedPointer).ToString()); securityPackages[i] = new SecurityPackageInfoClass(SecModule, unmanagedPointer); unmanagedPointer = IntPtrHelper.Add(unmanagedPointer, SecurityPackageInfo.Size); } SecModule.FreeContextBuffer(arrayBase); GlobalLog.Leave("EnumerateSecurityPackages"); return(securityPackages); }
internal static int HackedGetOverlappedResult(IntPtr m_UnmanagedOverlapped) { // // read IO asynchronous stauts from Overlapped structure // int status = Marshal.ReadInt32(IntPtrHelper.Add(m_UnmanagedOverlapped, OverlappedInternalOffset)); if (status == 0) { // // the Async IO call completed asynchronously: // save the bytes read // return(Marshal.ReadInt32(IntPtrHelper.Add(m_UnmanagedOverlapped, OverlappedInternalHighOffset))); } else { // // the Async IO call failed asynchronously: // save the bytes read // return(-1); } } // HackedGetOverlappedResult()
private static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { hostent hostent = (hostent)Marshal.PtrToStructure(nativePointer, typeof(hostent)); IPHostEntry entry = new IPHostEntry(); if (hostent.h_name != IntPtr.Zero) { entry.HostName = Marshal.PtrToStringAnsi(hostent.h_name); } ArrayList list = new ArrayList(); IntPtr ptr = hostent.h_addr_list; nativePointer = Marshal.ReadIntPtr(ptr); while (nativePointer != IntPtr.Zero) { int newAddress = Marshal.ReadInt32(nativePointer); list.Add(new IPAddress(newAddress)); ptr = IntPtrHelper.Add(ptr, IntPtr.Size); nativePointer = Marshal.ReadIntPtr(ptr); } entry.AddressList = new IPAddress[list.Count]; list.CopyTo(entry.AddressList, 0); list.Clear(); ptr = hostent.h_aliases; nativePointer = Marshal.ReadIntPtr(ptr); while (nativePointer != IntPtr.Zero) { string str = Marshal.PtrToStringAnsi(nativePointer); list.Add(str); ptr = IntPtrHelper.Add(ptr, IntPtr.Size); nativePointer = Marshal.ReadIntPtr(ptr); } entry.Aliases = new string[list.Count]; list.CopyTo(entry.Aliases, 0); return(entry); }
/*++ * * Routine Description: * * Takes a native pointer (expressed as an int) to a hostent structure, * and converts the information in their to an IPHostEntry class. This * involves walking through an array of native pointers, and a temporary * ArrayList object is used in doing this. * * Arguments: * * nativePointer - Native pointer to hostent structure. * * * * Return Value: * * An IPHostEntry structure. * * --*/ internal static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { // // marshal pointer to struct // hostent Host = (hostent)Marshal.PtrToStructure(nativePointer, typeof(hostent)); IPHostEntry HostEntry = new IPHostEntry(); if (Host.h_name != IntPtr.Zero) { HostEntry.HostName = Marshal.PtrToStringAnsi(Host.h_name); GlobalLog.Print("HostEntry.HostName: " + HostEntry.HostName); } // decode h_addr_list to ArrayList of IP addresses. // The h_addr_list field is really a pointer to an array of pointers // to IP addresses. Loop through the array, and while the pointer // isn't NULL read the IP address, convert it to an IPAddress class, // and add it to the list. ArrayList TempList = new ArrayList(); int IPAddressToAdd; string AliasToAdd; IntPtr currentArrayElement; // // get the first pointer in the array // currentArrayElement = Host.h_addr_list; nativePointer = Marshal.ReadIntPtr(currentArrayElement); while (nativePointer != IntPtr.Zero) { // // if it's not null it points to an IPAddress, // read it... // IPAddressToAdd = Marshal.ReadInt32(nativePointer); #if BIGENDIAN // IP addresses from native code are always a byte array // converted to int. We need to convert the address into // a uniform integer value. IPAddressToAdd = (int)(((uint)IPAddressToAdd << 24) | (((uint)IPAddressToAdd & 0x0000FF00) << 8) | (((uint)IPAddressToAdd >> 8) & 0x0000FF00) | ((uint)IPAddressToAdd >> 24)); #endif GlobalLog.Print("currentArrayElement: " + currentArrayElement.ToString() + " nativePointer: " + nativePointer.ToString() + " IPAddressToAdd:" + IPAddressToAdd.ToString()); // // ...and add it to the list // TempList.Add(new IPAddress(IPAddressToAdd)); // // now get the next pointer in the array and start over // currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); nativePointer = Marshal.ReadIntPtr(currentArrayElement); } HostEntry.AddressList = new IPAddress[TempList.Count]; TempList.CopyTo(HostEntry.AddressList, 0); // // Now do the same thing for the aliases. // TempList.Clear(); currentArrayElement = Host.h_aliases; nativePointer = Marshal.ReadIntPtr(currentArrayElement); while (nativePointer != IntPtr.Zero) { GlobalLog.Print("currentArrayElement: " + ((long)currentArrayElement).ToString() + "nativePointer: " + ((long)nativePointer).ToString()); // // if it's not null it points to an Alias, // read it... // AliasToAdd = Marshal.PtrToStringAnsi(nativePointer); // // ...and add it to the list // TempList.Add(AliasToAdd); // // now get the next pointer in the array and start over // currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); nativePointer = Marshal.ReadIntPtr(currentArrayElement); } HostEntry.Aliases = new string[TempList.Count]; TempList.CopyTo(HostEntry.Aliases, 0); return(HostEntry); } // NativeToHostEntry
public override void Write(byte[] buffer, int offset, int size) { if (Logging.On) { Logging.Enter(Logging.HttpListener, this, "Write", ""); } GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() buffer.Length:" + buffer.Length + " size:" + size + " offset:" + offset); if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException("size"); } UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = ComputeLeftToWrite(); if (m_Closed || (size == 0 && m_LeftToWrite != 0)) { if (Logging.On) { Logging.Exit(Logging.HttpListener, this, "Write", ""); } return; } if (m_LeftToWrite >= 0 && size > m_LeftToWrite) { throw new ProtocolViolationException(SR.GetString(SR.net_entitytoobig)); } uint statusCode; uint dataToWrite = (uint)size; SafeLocalFree bufferAsIntPtr = null; IntPtr pBufferAsIntPtr = IntPtr.Zero; bool sentHeaders = m_HttpContext.Response.SentHeaders; try { if (size == 0) { statusCode = m_HttpContext.Response.SendHeaders(null, null, flags, false); } else { fixed(byte *pDataBuffer = buffer) { byte *pBuffer = pDataBuffer; if (m_HttpContext.Response.BoundaryType == BoundaryType.Chunked) { // string chunkHeader = size.ToString("x", CultureInfo.InvariantCulture); dataToWrite = dataToWrite + (uint)(chunkHeader.Length + 4); bufferAsIntPtr = SafeLocalFree.LocalAlloc((int)dataToWrite); pBufferAsIntPtr = bufferAsIntPtr.DangerousGetHandle(); for (int i = 0; i < chunkHeader.Length; i++) { Marshal.WriteByte(pBufferAsIntPtr, i, (byte)chunkHeader[i]); } Marshal.WriteInt16(pBufferAsIntPtr, chunkHeader.Length, 0x0A0D); Marshal.Copy(buffer, offset, IntPtrHelper.Add(pBufferAsIntPtr, chunkHeader.Length + 2), size); Marshal.WriteInt16(pBufferAsIntPtr, (int)(dataToWrite - 2), 0x0A0D); pBuffer = (byte *)pBufferAsIntPtr; offset = 0; } UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK dataChunk = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK(); dataChunk.DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory; dataChunk.pBuffer = (byte *)(pBuffer + offset); dataChunk.BufferLength = dataToWrite; flags |= m_LeftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; if (!sentHeaders) { statusCode = m_HttpContext.Response.SendHeaders(&dataChunk, null, flags, false); } else { GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() calling UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody"); statusCode = UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody( m_HttpContext.RequestQueueHandle, m_HttpContext.RequestId, (uint)flags, 1, &dataChunk, null, SafeLocalFree.Zero, 0, null, null); GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() call to UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody returned:" + statusCode); if (m_HttpContext.Listener.IgnoreWriteExceptions) { GlobalLog.Print("HttpResponseStream#" + ValidationHelper.HashString(this) + "::Write() suppressing error"); statusCode = UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS; } } } } } finally { if (bufferAsIntPtr != null) { // free unmanaged buffer bufferAsIntPtr.Close(); } } if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF) { Exception exception = new HttpListenerException((int)statusCode); if (Logging.On) { Logging.Exception(Logging.HttpListener, this, "Write", exception); } m_Closed = true; m_HttpContext.Abort(); throw exception; } UpdateAfterWrite(dataToWrite); if (Logging.On) { Logging.Dump(Logging.HttpListener, this, "Write", buffer, offset, (int)dataToWrite); } if (Logging.On) { Logging.Exit(Logging.HttpListener, this, "Write", ""); } }
/*++ * * Routine Description: * * Takes a native pointer (expressed as an int) to a hostent structure, * and converts the information in their to an IPHostEntry class. This * involves walking through an array of native pointers, and a temporary * ArrayList object is used in doing this. * * Arguments: * * nativePointer - Native pointer to hostent structure. * * * * Return Value: * * An IPHostEntry structure. * * --*/ private static IPHostEntry NativeToHostEntry(IntPtr nativePointer) { // // marshal pointer to struct // hostent Host = Marshal.PtrToStructure <hostent>(nativePointer); IPHostEntry HostEntry = new IPHostEntry(); if (Host.h_name != IntPtr.Zero) { HostEntry.HostName = Marshal.PtrToStringAnsi(Host.h_name); if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"HostEntry.HostName: {HostEntry.HostName}"); } } // decode h_addr_list to ArrayList of IP addresses. // The h_addr_list field is really a pointer to an array of pointers // to IP addresses. Loop through the array, and while the pointer // isn't NULL read the IP address, convert it to an IPAddress class, // and add it to the list. var TempIPAddressList = new List <IPAddress>(); int IPAddressToAdd; string AliasToAdd; IntPtr currentArrayElement; // // get the first pointer in the array // currentArrayElement = Host.h_addr_list; nativePointer = Marshal.ReadIntPtr(currentArrayElement); while (nativePointer != IntPtr.Zero) { // // if it's not null it points to an IPAddress, // read it... // IPAddressToAdd = Marshal.ReadInt32(nativePointer); #if BIGENDIAN // IP addresses from native code are always a byte array // converted to int. We need to convert the address into // a uniform integer value. IPAddressToAdd = (int)(((uint)IPAddressToAdd << 24) | (((uint)IPAddressToAdd & 0x0000FF00) << 8) | (((uint)IPAddressToAdd >> 8) & 0x0000FF00) | ((uint)IPAddressToAdd >> 24)); #endif if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"currentArrayElement:{currentArrayElement} nativePointer:{nativePointer} IPAddressToAdd:{IPAddressToAdd}"); } // // ...and add it to the list // TempIPAddressList.Add(new IPAddress((long)IPAddressToAdd & 0x0FFFFFFFF)); // // now get the next pointer in the array and start over // currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); nativePointer = Marshal.ReadIntPtr(currentArrayElement); } HostEntry.AddressList = TempIPAddressList.ToArray(); // // Now do the same thing for the aliases. // var TempAliasList = new List <string>(); currentArrayElement = Host.h_aliases; nativePointer = Marshal.ReadIntPtr(currentArrayElement); while (nativePointer != IntPtr.Zero) { if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"currentArrayElement:{currentArrayElement} nativePointer:{nativePointer}"); } // // if it's not null it points to an Alias, // read it... // AliasToAdd = Marshal.PtrToStringAnsi(nativePointer); // // ...and add it to the list // TempAliasList.Add(AliasToAdd); // // now get the next pointer in the array and start over // currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size); nativePointer = Marshal.ReadIntPtr(currentArrayElement); } HostEntry.Aliases = TempAliasList.ToArray(); return(HostEntry); } // NativeToHostEntry
public override unsafe void Write(byte[] buffer, int offset, int size) { if (Logging.On) { Logging.Enter(Logging.HttpListener, this, "Write", ""); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if ((offset < 0) || (offset > buffer.Length)) { throw new ArgumentOutOfRangeException("offset"); } if ((size < 0) || (size > (buffer.Length - offset))) { throw new ArgumentOutOfRangeException("size"); } UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags = this.ComputeLeftToWrite(); if (this.m_Closed || ((size == 0) && (this.m_LeftToWrite != 0L))) { if (Logging.On) { Logging.Exit(Logging.HttpListener, this, "Write", ""); } } else { uint num; if ((this.m_LeftToWrite >= 0L) && (size > this.m_LeftToWrite)) { throw new ProtocolViolationException(SR.GetString("net_entitytoobig")); } uint dataWritten = (uint)size; SafeLocalFree free = null; IntPtr zero = IntPtr.Zero; bool sentHeaders = this.m_HttpContext.Response.SentHeaders; try { if (size == 0) { num = this.m_HttpContext.Response.SendHeaders(null, null, flags); } else { try { byte[] buffer2; if (((buffer2 = buffer) == null) || (buffer2.Length == 0)) { numRef = null; goto Label_0109; } fixed(byte *numRef = buffer2) { byte *numPtr; Label_0109: numPtr = numRef; if (this.m_HttpContext.Response.BoundaryType == BoundaryType.Chunked) { string str = size.ToString("x", CultureInfo.InvariantCulture); dataWritten += (uint)(str.Length + 4); free = SafeLocalFree.LocalAlloc((int)dataWritten); zero = free.DangerousGetHandle(); for (int i = 0; i < str.Length; i++) { Marshal.WriteByte(zero, i, (byte)str[i]); } Marshal.WriteInt16(zero, str.Length, (short)0xa0d); Marshal.Copy(buffer, offset, IntPtrHelper.Add(zero, str.Length + 2), size); Marshal.WriteInt16(zero, ((int)dataWritten) - 2, (short)0xa0d); numPtr = (byte *)zero; offset = 0; } UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK pDataChunk = new UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK { DataChunkType = UnsafeNclNativeMethods.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory, pBuffer = numPtr + offset, BufferLength = dataWritten }; flags |= (this.m_LeftToWrite == size) ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; if (!sentHeaders) { num = this.m_HttpContext.Response.SendHeaders(&pDataChunk, null, flags); } else { num = UnsafeNclNativeMethods.HttpApi.HttpSendResponseEntityBody(this.m_HttpContext.RequestQueueHandle, this.m_HttpContext.RequestId, (uint)flags, 1, &pDataChunk, null, SafeLocalFree.Zero, 0, null, null); if (this.m_HttpContext.Listener.IgnoreWriteExceptions) { num = 0; } } } } finally { numRef = null; } } } finally { if (free != null) { free.Close(); } } switch (num) { case 0: case 0x26: this.UpdateAfterWrite(dataWritten); if (Logging.On) { Logging.Dump(Logging.HttpListener, this, "Write", buffer, offset, (int)dataWritten); } if (Logging.On) { Logging.Exit(Logging.HttpListener, this, "Write", ""); } return; } Exception e = new HttpListenerException((int)num); if (Logging.On) { Logging.Exception(Logging.HttpListener, this, "Write", e); } this.m_HttpContext.Abort(); throw e; } }
} // Position // // write a chunk of data to ul // public override void Write( byte[] buffer, int offset, int count) { GlobalLog.Print("ListenerResponseStream.WriteCore() offset: " + Convert.ToString(offset) + " count:" + Convert.ToString(count)); if (m_ContentLength != -1 && m_ContentLength < count) { // // user can't send more data than specified in the ContentLength // throw new ProtocolViolationException(SR.GetString(SR.net_entitytoobig)); } int DataToWrite = count; GCHandle PinnedBuffer = new GCHandle(); IntPtr AddrOfPinnedBuffer = IntPtr.Zero; if (m_SendChunked) { string ChunkHeader = "0x" + Convert.ToString(count, 16); DataToWrite += ChunkHeader.Length + 4; AddrOfPinnedBuffer = Marshal.AllocHGlobal(DataToWrite); Marshal.Copy(ChunkHeader.ToCharArray(), 0, AddrOfPinnedBuffer, ChunkHeader.Length); Marshal.WriteInt16(AddrOfPinnedBuffer, ChunkHeader.Length, 0x0A0D); Marshal.Copy((byte[])buffer, offset, IntPtrHelper.Add(AddrOfPinnedBuffer, ChunkHeader.Length + 2), count); Marshal.WriteInt16(AddrOfPinnedBuffer, DataToWrite - 2, 0x0A0D); } else { // // pin the buffer and make an unmanaged call to the driver to // write more entity body // PinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); AddrOfPinnedBuffer = PinnedBuffer.AddrOfPinnedObject(); } // // set up a UL_DATA_CHUNK structure to pass down to UL with pointers // to data to be written // IntPtr AddrOfPinnedEntityChunks = Marshal.AllocHGlobal(32); // // AddrOfPinnedBuffer and count go into a pEntityChunks structure // Marshal.WriteInt64(AddrOfPinnedEntityChunks, 0, 0); Marshal.WriteIntPtr(AddrOfPinnedEntityChunks, 8, AddrOfPinnedBuffer); Marshal.WriteInt32(AddrOfPinnedEntityChunks, 12, DataToWrite); Marshal.WriteInt64(AddrOfPinnedEntityChunks, 16, 0); Marshal.WriteInt64(AddrOfPinnedEntityChunks, 24, 0); GlobalLog.Print("Calling UlSendHttpResponseEntityBody: AddrOfPinnedEntityChunks:" + Convert.ToString(AddrOfPinnedEntityChunks) + " AddrOfPinnedBuffer:" + Convert.ToString(AddrOfPinnedBuffer) + " DataToWrite:" + Convert.ToString(DataToWrite)); // // issue unmanaged blocking call // int DataWritten = 0; int result = ComNetOS.IsWinNt ? UlSysApi.UlSendEntityBody( m_AppPoolHandle, m_RequestId, UlConstants.UL_SEND_RESPONSE_FLAG_MORE_DATA, 1, AddrOfPinnedEntityChunks, ref DataWritten, IntPtr.Zero) : UlVxdApi.UlSendHttpResponseEntityBody( m_AppPoolHandle, m_RequestId, 0, 1, AddrOfPinnedEntityChunks, ref DataWritten, IntPtr.Zero); if (m_SendChunked) { // // data was copied into an unmanaged buffer, free it // Marshal.FreeHGlobal(AddrOfPinnedBuffer); } else { // // data wasn't copied unpin the pinned buffer // PinnedBuffer.Free(); } Marshal.FreeHGlobal(AddrOfPinnedEntityChunks); GlobalLog.Print("UlSendHttpResponseEntityBody() DataWritten:" + Convert.ToString(DataWritten) + " DataToWrite:" + Convert.ToString(DataToWrite)); if (result != NativeMethods.ERROR_SUCCESS) //Win32.ERROR_CANCELLED || Win32.ERROR_BAD_COMMAND || NativeMethods.ERROR_INVALID_PARAMETER { throw new ProtocolViolationException(SR.GetString(SR.net_connclosed) + Convert.ToString(result)); } // // double check the number of bytes written // if (DataWritten != DataToWrite) { throw new InvalidOperationException("sync UlSendHttpResponseEntityBody() failed to write all the data" + " count:" + Convert.ToString(count) + " DataWritten:" + Convert.ToString(DataWritten) + " DataToWrite:" + Convert.ToString(DataToWrite) + " m_AppPoolHandle:" + Convert.ToString(m_AppPoolHandle) + " m_RequestId:" + Convert.ToString(m_RequestId) + " err#" + Convert.ToString(result)); } if (result != NativeMethods.ERROR_SUCCESS && result != NativeMethods.ERROR_HANDLE_EOF) { // // Consider: move all Exception string to system.txt for localization // throw new InvalidOperationException("sync UlSendHttpResponseEntityBody() failed, err#" + Convert.ToString(result)); } if (m_ContentLength != -1) { // // keep track of the data transferred // m_ContentLength -= count; if (m_ContentLength == 0) { // // I should be able to call Close() at this point // } } return; // DataToWrite; } // Write()
BeginGetRequest( AsyncCallback requestCallback, Object stateObject) { // // Validation // if (m_AppPoolHandle == NativeMethods.INVALID_HANDLE_VALUE) { throw new InvalidOperationException("The AppPool handle is invalid"); } // // prepare the ListenerAsyncResult object ( this will have it's own // event that the user can wait on for IO completion - which means we // need to signal it when IO completes ) // GlobalLog.Print("BeginGetRequest() creating ListenerAsyncResult"); ListenerAsyncResult AResult = new ListenerAsyncResult( stateObject, requestCallback); AutoResetEvent m_Event = new AutoResetEvent(false); Marshal.WriteIntPtr( AResult.m_Overlapped, Win32.OverlappedhEventOffset, m_Event.Handle); // // issue unmanaged call until we read enough data: // usually starting with a InitialBufferSize==4096 bytes we should be // able to get all the headers ( and part of the entity body, if any // is present ), if we don't, if the call didn't fail for othe reasons, // we get indication in BytesReturned, on how big the buffer should be // to receive the data available, so usually the second call will // succeed, but we have to consider the case of two competing calls // for the same RequestId, and that's why we need a loop and not just // a try/retry-expecting-success fashion // int result; for (;;) { // // check if we're in a healthy state // if (AResult.m_Retries++ > m_MaxRetries) { throw new InvalidOperationException("UlReceiveHttpRequest() Too many retries"); } result = ComNetOS.IsWinNt ? UlSysApi.UlReceiveHttpRequest( m_AppPoolHandle, AResult.m_RequestId, UlConstants.UL_RECEIVE_REQUEST_FLAG_COPY_BODY, AResult.m_Buffer, AResult.m_BufferSize, ref AResult.m_BytesReturned, AResult.m_Overlapped) : UlVxdApi.UlReceiveHttpRequestHeaders( m_AppPoolHandle, AResult.m_RequestId, 0, AResult.m_Buffer, AResult.m_BufferSize, ref AResult.m_BytesReturned, AResult.m_Overlapped); GlobalLog.Print("UlReceiveHttpRequest() returns:" + Convert.ToString(result)); if (result == NativeMethods.ERROR_SUCCESS || result == NativeMethods.ERROR_IO_PENDING) { // // synchronous success or successfull pending: we are done // break; } if (result == NativeMethods.ERROR_INVALID_PARAMETER) { // // we might get this if somebody stole our RequestId, // set RequestId to null // AResult.m_RequestId = 0; // // and start all over again with the buffer we // just allocated // continue; } if (result == NativeMethods.ERROR_MORE_DATA) { // // the buffer was not big enough to fit the headers, we need // to read the RequestId returned, grow the buffer, keeping // the data already transferred // AResult.m_RequestId = Marshal.ReadInt64(IntPtrHelper.Add(AResult.m_Buffer, m_RequestIdOffset)); // // allocate a new buffer of the required size // IntPtr NewBuffer = Marshal.AllocHGlobal(AResult.m_BytesReturned); // // copy the data already read from the old buffer into the // new one // NativeMethods.CopyMemory(NewBuffer, AResult.m_Buffer, AResult.m_BufferSize); // // free the old buffer // Marshal.FreeHGlobal(AResult.m_Buffer); // // update buffer pointer and size // AResult.m_Buffer = NewBuffer; AResult.m_BufferSize = AResult.m_BytesReturned; AResult.m_BytesReturned = 0; // // and start all over again with the new buffer // continue; } // // someother bad error, possible( ? ) return values are: // // ERROR_INVALID_HANDLE // ERROR_INSUFFICIENT_BUFFER // ERROR_OPERATION_ABORTED // ERROR_IO_PENDING // throw new InvalidOperationException("UlReceiveHttpRequest() failed, err#" + Convert.ToString(result)); } // // we get here only if a break happens, i.e. // 1) syncronous completion // 2) the IO pended // if (result == NativeMethods.ERROR_SUCCESS) { // // set syncronous completion to true // AResult.Complete(true); // // and call the internal callback // WaitCallback(AResult, false); } else { // // create a new delegate // and spin a new thread from the thread pool to wake up when the // event is signaled and call the delegate // ThreadPool.RegisterWaitForSingleObject( m_Event, new WaitOrTimerCallback(WaitCallback), AResult, -1, true); } GlobalLog.Print("returning AResult"); return(AResult); } // StartListen()
GetRequest() { // // Validation // if (m_AppPoolHandle == NativeMethods.INVALID_HANDLE_VALUE) { throw new InvalidOperationException("The AppPool handle is invalid"); } int result; int retries = 0; // // defined in ulcommonapi.cs // int RcvHeadersBufferSize = UlConstants.InitialBufferSize; // // prepare ( allocate/pin ) buffers and data for the first unmanaged call // GCHandle PinnedBuffer; GCHandle NewPinnedBuffer; IntPtr AddrOfPinnedBuffer = IntPtr.Zero; IntPtr NewAddrOfPinnedBuffer = IntPtr.Zero; int BytesReturned = 0; long RequestId = 0; byte[] RcvHeadersBuffer = new byte[RcvHeadersBufferSize]; // // pin buffers and data for the unmanaged call // PinnedBuffer = GCHandle.Alloc(RcvHeadersBuffer, GCHandleType.Pinned); AddrOfPinnedBuffer = PinnedBuffer.AddrOfPinnedObject(); // // issue unmanaged blocking call until we read enough data: // usually starting with a InitialBufferSize==4096 bytes we should be // able to get all the headers ( and part of the entity body, if any // is present ), if we don't, if the call didn't fail for othe reasons, // we get indication in BytesReturned, on how big the buffer should be // to receive the data available, so usually the second call will // succeed, but we have to consider the case of two competing calls // for the same RequestId, and that's why we need a loop and not just // a try/retry-expecting-success fashion // for (;;) { // // check if we're in a healthy state // if (retries++ > m_MaxRetries) { throw new InvalidOperationException("UlReceiveHttpRequest() Too many retries"); } result = ComNetOS.IsWinNt ? UlSysApi.UlReceiveHttpRequest( m_AppPoolHandle, RequestId, UlConstants.UL_RECEIVE_REQUEST_FLAG_COPY_BODY, AddrOfPinnedBuffer, RcvHeadersBufferSize, ref BytesReturned, IntPtr.Zero) : UlVxdApi.UlReceiveHttpRequestHeaders( m_AppPoolHandle, RequestId, 0, AddrOfPinnedBuffer, RcvHeadersBufferSize, ref BytesReturned, IntPtr.Zero); if (result == NativeMethods.ERROR_SUCCESS) { // // success, we are done. // break; } if (result == NativeMethods.ERROR_INVALID_PARAMETER) { // // we might get this if somebody stole our RequestId, // set RequestId to null // RequestId = 0; // // and start all over again with the buffer we // just allocated // continue; } // // let's check if ul is in good shape: // if (BytesReturned < RcvHeadersBufferSize) { throw new InvalidOperationException("UlReceiveHttpRequest() sent bogus BytesReturned: " + Convert.ToString(BytesReturned)); } if (result == NativeMethods.ERROR_MORE_DATA) { // // the buffer was not big enough to fit the headers, we need // to read the RequestId returned, grow the buffer, keeping // the data already transferred // RequestId = Marshal.ReadInt64(IntPtrHelper.Add(AddrOfPinnedBuffer, m_RequestIdOffset)); // // CODEWORK: wait for the answer from LarrySu // // // if the buffer size was too small, grow the buffer // this reallocation dereferences the old buffer, but since // this was previously pinned, it won't be garbage collected // until we unpin it ( which we do below ) // RcvHeadersBuffer = new byte[BytesReturned]; // // pin the new one // NewPinnedBuffer = GCHandle.Alloc(RcvHeadersBuffer, GCHandleType.Pinned); NewAddrOfPinnedBuffer = NewPinnedBuffer.AddrOfPinnedObject(); // // copy the valid data // Marshal.Copy(AddrOfPinnedBuffer, RcvHeadersBuffer, 0, RcvHeadersBufferSize); RcvHeadersBufferSize = BytesReturned; // // unpin the old buffer, reset pinned/unmanaged pointers // PinnedBuffer.Free(); PinnedBuffer = NewPinnedBuffer; AddrOfPinnedBuffer = NewAddrOfPinnedBuffer; // // and start all over again with the new buffer // continue; } // // someother bad error, possible( ? ) return values are: // // ERROR_INVALID_HANDLE // ERROR_INSUFFICIENT_BUFFER // ERROR_OPERATION_ABORTED // ERROR_IO_PENDING // throw new InvalidOperationException("UlReceiveHttpRequest() failed, err#" + Convert.ToString(result)); } GlobalLog.Print("GetRequest RequestId:" + Convert.ToString(RequestId)); // // translate unmanaged results into a new managed object // HttpListenerWebRequest myWebRequest = new HttpListenerWebRequest(AddrOfPinnedBuffer, RcvHeadersBufferSize, m_AppPoolHandle); // // free the unmanaged buffer ( deallocate/unpin ) after unmanaged call // PinnedBuffer.Free(); return(myWebRequest); } // GetRequest()