using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Sample2_AssemblyEmbedding
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();

            CreateDLLInMemory(
                Application.StartupPath + @"\\ManagedDll1.dll",
                Assembly.GetExecutingAssembly().GetManifestResourceStream("Sample2_AssemblyEmbedding.res.ManagedDll1.bin"));

            CreateDLLInMemory(
                Application.StartupPath + @"\\UnmanagedDll1.dll",
                Assembly.GetExecutingAssembly().GetManifestResourceStream("Sample2_AssemblyEmbedding.res.UnmanagedDll1.bin"));

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());

            BoxedAppSDK.NativeMethods.BoxedAppSDK_Exit();
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll")]
        static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer,
            uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten,
            [In] ref System.Threading.NativeOverlapped lpOverlapped);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string path);

        static void CreateDLLInMemory(string strVirtualPath, Stream stream)
        {
            const int BufferSize = 1024;
            byte[] buffer = new byte[BufferSize];

            IntPtr hHandle =
                BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFile(
                strVirtualPath,
                BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
                BoxedAppSDK.NativeMethods.EFileShare.Read,
                IntPtr.Zero,
                BoxedAppSDK.NativeMethods.ECreationDisposition.New,
                BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
                IntPtr.Zero);
            CloseHandle(hHandle);

            int nReadBytes;

            using (FileStream VirtualFileStream = new FileStream(strVirtualPath, FileMode.Open))
            {
                while ((nReadBytes = stream.Read(buffer, 0, BufferSize)) > 0)
                    VirtualFileStream.Write(buffer, 0, nReadBytes);
            }
        }
    }
}