/// <summary> /// Update length and offset of UPN and DNS Domain. /// </summary> private void UpdateOffsetLength() { int upnOffset = Marshal.SizeOf(NativeUpnDnsInfo.GetType()); NativeUpnDnsInfo.UpnOffset = (ushort)PacUtility.AlignTo(upnOffset, UpnDnsAlignUnit); NativeUpnDnsInfo.UpnLength = (ushort)(Encoding.Unicode.GetByteCount(Upn)); int dnsOffset = NativeUpnDnsInfo.UpnOffset + NativeUpnDnsInfo.UpnLength; NativeUpnDnsInfo.DnsDomainNameOffset = (ushort)PacUtility.AlignTo(dnsOffset, UpnDnsAlignUnit); NativeUpnDnsInfo.DnsDomainNameLength = (ushort)(Encoding.Unicode.GetByteCount(DnsDomain)); }
/// <summary> /// Concatenate specified header buffer and specified body buffers. /// </summary> /// <param name="header">The specified header buffer.</param> /// <param name="bodyReferences">The specified body buffers.</param> /// <returns>The integrated buffer.</returns> private byte[] ConcatenateBuffers(byte[] header, byte[][] bodyReferences) { // calculate total totalLength int totalLength = header.Length; for (int i = 0; i < NativePacType.cBuffers; i++) { if (bodyReferences[i] == null) { continue; } int length = bodyReferences[i].Length; // double check the length // NativePacType.Buffers[index].cbBufferSize has been updated in previous // UpdateInterrelatedFields() method, given by each pacInfoBuffer's // CalculateSize() method. // following evaluation double check whether CalculateSize() method's // result conforms to EncodeBuffer() method's result. // Note: some kind of pacInfoBuffers return EncodeBuffer().Length as the // CalculateSize(), such as NDR encoded structures. But some other // pacInfoBuffers can calculate totalLength without encoding the structure. AssertBufferSize(NativePacType.Buffers, i, length); totalLength += PacUtility.AlignTo(length, PacTypeAlignUnit); } byte[] total = new byte[totalLength]; int offset = 0; Buffer.BlockCopy(header, 0, total, offset, header.Length); offset += header.Length; for (int i = 0; i < bodyReferences.Length; ++i) { if (bodyReferences[i] == null) { continue; } int length = bodyReferences[i].Length; Buffer.BlockCopy(bodyReferences[i], 0, total, offset, length); offset += PacUtility.AlignTo(length, PacTypeAlignUnit); } return(total); }
/// <summary> /// Update cbBufferSize and Offset of all PAC_INFO_BUFFERs /// after the buffers' content updated. /// </summary> public void UpdateInterrelatedFields() { AssertBuffersCount(pacInfoBuffers.Length, NativePacType.Buffers.Length); int offset = CalculateHeaderSize(); for (int i = 0; i < pacInfoBuffers.Length; i++) { NativePacType.Buffers[i].Offset = (ulong)offset; if (pacInfoBuffers[i] == null) { continue; } int size = pacInfoBuffers[i].CalculateSize(); NativePacType.Buffers[i].cbBufferSize = (uint)size; offset += size; //TD section 2.3: "All PAC elements MUST be placed on an 8-byte boundary." offset = PacUtility.AlignTo(offset, PacTypeAlignUnit); } }