/// <summary> /// This converts the managed version to the unmanaged version of the structure. /// </summary> /// <returns></returns> internal LINEFORWARD ConvertToTapiStructure(ref int pos) { var lf = new LINEFORWARD { dwForwardMode = (int)ForwardMode, dwCallerAddressType = (int)CallerAddressType }; if (!String.IsNullOrEmpty(CallerAddress)) { lf.dwCallerAddressOffset = pos; lf.dwCallerAddressSize = Encoding.Unicode.GetByteCount(CallerAddress); pos += lf.dwCallerAddressSize; } lf.dwDestCountryCode = DestinationCountryCode; lf.dwDestAddressType = (int)DestinationAddressType; if (!String.IsNullOrEmpty(DestinationAddress)) { lf.dwDestAddressOffset = pos; lf.dwDestAddressSize = Encoding.Unicode.GetByteCount(DestinationAddress); pos += lf.dwDestAddressSize; } return(lf); }
/// <summary> /// This method converts an array of forwarding information instructions to a LINEFORWARDLIST array /// </summary> /// <param name="forwardInstructions">Input array</param> /// <returns></returns> internal static IntPtr ProcessForwardList(ForwardInfo[] forwardInstructions) { if (forwardInstructions == null) { throw new ArgumentNullException("forwardInstructions"); } if (forwardInstructions.Length == 0) { throw new ArgumentException("forwardInstructions must contain at least one entry"); } var lfl = new LINEFORWARDLIST { dwNumEntries = forwardInstructions.Length }; lfl.dwTotalSize = Marshal.SizeOf(lfl) + (Marshal.SizeOf(typeof(LINEFORWARD)) * lfl.dwNumEntries); int pos = lfl.dwTotalSize; var arrBuff = new List <LINEFORWARD>(); for (int i = 0; i < forwardInstructions.Length; i++) { LINEFORWARD lf = forwardInstructions[i].ConvertToTapiStructure(ref pos); arrBuff.Add(lf); lfl.dwTotalSize += (lf.dwCallerAddressSize + lf.dwDestAddressSize); } // Create a buffer to hold our entire block. IntPtr lpFl = Marshal.AllocHGlobal(lfl.dwTotalSize); var buff = new byte[lfl.dwTotalSize]; // Alloc temp blocks int lfs = Marshal.SizeOf(typeof(LINEFORWARD)); IntPtr ip = Marshal.AllocHGlobal(lfs); var ipBuff = new byte[lfs]; // Copy in the header and move it to our working buffer. Marshal.StructureToPtr(lfl, lpFl, false); Marshal.Copy(lpFl, buff, 0, lfl.dwTotalSize); // Copy each of the structures over. pos = Marshal.SizeOf(lfl); foreach (LINEFORWARD lf in arrBuff) { Marshal.StructureToPtr(lf, ip, true); Marshal.Copy(ip, ipBuff, 0, lfs); Array.Copy(ipBuff, 0, buff, pos, lfs); pos += lfs; } Marshal.FreeHGlobal(ip); // Go back through and add each of the string values. for (int i = 0; i < arrBuff.Count; i++) { if (!String.IsNullOrEmpty(forwardInstructions[i].CallerAddress)) { System.Diagnostics.Debug.Assert(pos == arrBuff[i].dwCallerAddressOffset); Array.Copy(Encoding.Unicode.GetBytes(forwardInstructions[i].CallerAddress), 0, buff, pos, arrBuff[i].dwCallerAddressSize); pos += arrBuff[i].dwCallerAddressSize; } if (!String.IsNullOrEmpty(forwardInstructions[i].DestinationAddress)) { System.Diagnostics.Debug.Assert(pos == arrBuff[i].dwDestAddressOffset); Array.Copy(Encoding.Unicode.GetBytes(forwardInstructions[i].DestinationAddress), 0, buff, pos, arrBuff[i].dwDestAddressSize); pos += arrBuff[i].dwDestAddressSize; } } // Finally, move it back to our IntPtr Marshal.Copy(buff, 0, lpFl, lfl.dwTotalSize); return(lpFl); }