Category: Uncategorized

if (strstr(pusrdata, "GET / HTTP/1.1") != NULL) //Display Config request
    {
        char * ResponseToSend = "<!DOCTYPE html><html><body><form action=\"upload\" method=\"post\" enctype=\"multipart/form-data\">Select image to upload:<input type=\"file\" name=\"fileToUpload\" id=\"fileToUpload\"><input type=\"submit\" value=\"Upload Image\" name=\"submit\"></form></body></html>";
        //espconn_send(pespconn, ResponseToSend, os_strlen(ResponseToSend));
        HttpSendWithHeader(pespconn, ResponseToSend);
    }

So Recently I coded this nice little piece for the ESP8266, It sends a Web form asking a User to upload a file to the web server, Now when it does it post the following command back

POST /upload HTTP/1.1
Host: 192.168.1.51
Connection: keep-alive
Content-Length: 1013730
Cache-Control: max-age=0
Origin: http://192.168.1.51
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVD9Qk48AHQFOiDEY
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://192.168.1.51/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9


WebServerConn_recv_callback------WebKitFormBoundaryVD9Qk48AHQFOiDEY
Content-Disposition: form-data; name="fileToUpload"; filename="Chapter 2 Data Files (1).zip"
Content-Type: application/x-zip-compressed

PK
WebServerConn_recv_callbackT�I�V�7��]%j
"�G�z�Z��M��|*�Y�       <
ʠ�%� �Ā��^����  �=wV�t�?�Jj��hA��x
                                  |���Z>        ���ϊf�4�c\�~�c�y��9��A7$
                                                                        ��:�M��������m׾O6|z�������,�Io
�W�>¼H��k)�2������O

We have to parse the data as it comes in

if (RemotePortsOpenedInDownload == pespconn->proto.tcp->remote_port)
    {
        os_printf("Incoming file data gcontentlength = %d\r\n", gContentLength);
        //os_printf(pusrdata);
        char * Ptr = pusrdata;
        if (HeaderRead == false)
        {
            while (!strstarts(Ptr, "\r\n\r\n"))
            {
                Ptr++; //Increment Ptr
                //lengthleft--;
            }
            while (*Ptr == '\n' || *Ptr == '\r')
            {
                Ptr++; //Increment Ptr
                //lengthleft--;
            }
            HeaderRead = true;
        }
        //os_printf("---");
        //os_printf(Ptr);
        os_printf("gcontentlength(%d) - length(%d) = %d\r\n", length, gContentLength, (gContentLength - lengthleft));
        gContentLength -= lengthleft;
        if (gContentLength == 0)
        {
            //espconn_disconnect(&WebServerSocket); //Webservers don't close sockets, clients do
            char * ResponseToSend = "<!DOCTYPE html><html><body>File Uploaded</body></html>";
            HttpSendWithHeader(pespconn, ResponseToSend);

            uint8 id = system_upgrade_userbin_check();
            char *next = id ? "user1.bin" : "user2.bin";
            os_printf("OTA: Next firmware: %s (%d=0x%08x)\n", next, id, system_get_userbin_addr());

            // Information about flash size based on flash memory map as returned by system_get_flash_size_map:
            // 4Mb_256, 2Mb, 8Mb_512, 16Mb_512, 32Mb_512, 16Mb_1024, 32Mb_1024
            static enum flash_size_map flashSizeMap;

            // Start address of user2.bin (address of user1 is always 0x1000)
            static uint32_t flashUser2Addr[] = {
              260*1024, 0, 516*1024, 516*1024, 516*1024, 1028*1024, 1028*1024,
            };

            uint32_t offset;
            // let's see which what flash address we're uploading to
            uint32_t address = id ? 0x1000 : flashUser2Addr[flashSizeMap];
            address += offset;

            // erase next flash block if necessary
            if (address % SPI_FLASH_SEC_SIZE == 0)
            {
                os_printf("OTA Flashing 0x%05lx\n", (long unsigned int) address);
                spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE);
            }
        }
    }

    if (strstr(pusrdata, "POST /upload") != NULL)
    {
        RemotePortsOpenedInDownload = pespconn->proto.tcp->remote_port;
        //os_printf(pusrdata);
        int index = 0;
        char * Ptr = pusrdata;

        while (!strstarts(Ptr, "Content-Length: "))
        {
            Ptr++; //Increment Potr
        }
        while (*Ptr != ' ')
        {
            Ptr++; //Increment Potr
        }
        Ptr++; //Increment to Content String

        char ContentLength[8] = {0};
        index = 0;
        while (*Ptr != '\r' && *Ptr != '\n')
        {
            ContentLength[index] = *Ptr;
            index++;
            Ptr++; //Increment Potr
        }
        os_printf(ContentLength);
        gContentLength = atoi(ContentLength);

        while (!strstarts(Ptr, "Content-Type: multipart/form-data; boundary="))
        {
            Ptr++; //Increment Potr
        }
        while (*Ptr != '=')
        {
            Ptr++; //Increment Potr
        }
        Ptr++; //Increment to Content String
        char Boundary[64] = {0};        
        index = 0;

        while (*Ptr != '\r' && *Ptr != '\n')
        {
            Boundary[index] = *Ptr;
            index++;
            Ptr++; //Increment Potr
        }
        os_printf(Boundary);
        os_printf("\r\n");

        HeaderRead = false; //SetHeader back to false to prep for incoming header to skil

    }

So this is amazing and was very much needed. I adopted our Threading Based Queuing code to integrate with Tesseract OCR to chuck out a HUGE WORKLOAD of processing. With the updated code a User can simply select multiple High Detailed images to render and then walk away, The Images are then all translated at the same time but the data is dumped in the correct order! The newly spawned threads will wait until the previous ones before it are compelted then dump the data that has already been processed! Works like a charm!

Imports Tesseract
Imports System.Threading
Imports System.Runtime.InteropServices
Imports System.IO

Public Class Form1
    Private Delegate Sub MyDelPtr(CurrentInstance As MyThreading)

    Public Const MOD_ALT As Integer = &H1 'Alt key
    Public Const WM_HOTKEY As Integer = &H312

    <DllImport("User32.dll")>
    Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr,
                        ByVal id As Integer, ByVal fsModifiers As Integer,
                        ByVal vk As Integer) As Integer
    End Function

    <DllImport("User32.dll")>
    Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr,
                        ByVal id As Integer) As Integer
    End Function

    <DllImport("dwmapi.dll", PreserveSig:=False)>
    Public Shared Function DwmIsCompositionEnabled() As Boolean
    End Function

    <DllImport("dwmapi.dll", PreserveSig:=False)>
    Public Shared Sub DwmEnableComposition(ByVal bEnable As Boolean)
    End Sub

    <DllImport("user32.dll", EntryPoint:="GetCursorInfo")>
    Public Shared Function GetCursorInfo(ByRef pci As CURSORINFO) As Boolean
    End Function

    <DllImport("user32.dll", EntryPoint:="CopyIcon")>
    Public Shared Function CopyIcon(ByVal hIcon As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll", EntryPoint:="GetIconInfo")>
    Public Shared Function GetIconInfo(ByVal hIcon As IntPtr, ByRef piconinfo As ICONINFO) As Boolean
    End Function

    Dim aeroIsEnabled As Boolean
    Dim b As Bitmap
    Dim graphics As Graphics

    Dim StartPoint As New Point(0, 0)
    Dim ScreenShotSize As Drawing.Size

    Dim ThreadNameIndex As Integer = 0
    Dim MyThreadingClass As MyThreading
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_HOTKEY Then
            Dim id As IntPtr = m.WParam
            Select Case (id.ToString)
                Case "100"
                    Debug.WriteLine("You pressed ALT+S key combination")
                    If StartPoint.IsEmpty Then
                        StartPoint = GetCursorPosition()
                        Debug.WriteLine(StartPoint)
                    Else
                        Dim MyEndPoint As Point = GetCursorPosition()
                        Debug.WriteLine(MyEndPoint)
                        Dim MyTwoPoints As New Point(MyEndPoint.X - StartPoint.X, MyEndPoint.Y - StartPoint.Y)
                        ScreenShotSize = New Size(MyTwoPoints)
                        Debug.WriteLine(ScreenShotSize)
                        'CaptureScreenshot(New Point(0, 0), PictureBox1.Size)
                        'This resizes the Background of the image to scale
                        If True Then
                            b = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
                        Else
                            b = New Bitmap(MyEndPoint.X - StartPoint.X, MyEndPoint.Y - StartPoint.Y)
                        End If
                        'ResizeImage(b, b.Width * 3, b.Height * 3)

                        PictureBox1.Image = b
                        graphics = Graphics.FromImage(b)
                        '
                        graphics.Clear(Color.Transparent)
                        graphics.CopyFromScreen(StartPoint, New Point(0, 0), ScreenShotSize)

                        Dim output As New Bitmap(ScreenShotSize.Width * 2, ScreenShotSize.Height * 2)
                        Using g As Graphics = Graphics.FromImage(output)
                            g.DrawImage(b, 0, 0, PictureBox1.Size.Width * 2, PictureBox1.Size.Height * 2)
                        End Using
                        PictureBox1.Image = output
                        'PictureBox1.Image.Save("./saved.tiff", System.Drawing.Imaging.ImageFormat.Tiff)
                        'ResizeImage(b, b.Width * 3, b.Height * 3)
                        '
                        StartPoint = New Point(0, 0)

                        Application.DoEvents()
                        'translateFromMemory(ConvertToByteArray(output))

                        If IsNothing(MyThreadingClass) Then
                            MyThreadingClass = New MyThreading(ThreadNameIndex, ConvertToByteArray(output), Nothing, Me, New MyDelPtr(AddressOf PostBackFromThread))
                        Else
                            MyThreadingClass = New MyThreading(ThreadNameIndex, ConvertToByteArray(output), MyThreadingClass.MyThreadToStart, Me, New MyDelPtr(AddressOf PostBackFromThread))
                        End If

                        ThreadNameIndex += 1
                        'translateFromFile("./saved.tiff")
                        'translateFromMemory(ConvertToByteArray(New Bitmap(ScreenShotSize.Width, ScreenShotSize.Height, graphics)))
                    End If

                Case "200"
                    MessageBox.Show("You pressed ALT+C key combination")
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Public Sub PostBackFromThread(CurrentInstance As MyThreading)
        Debug.WriteLine("Results (in order) came back to mainthread from:" & CurrentInstance.MyThreadToStart.Name & " Data returned: " & CurrentInstance.DataToReturn)
        TextBox1.Text &= CurrentInstance.DataToReturn
        CurrentInstance = Nothing
    End Sub

    Public Shared Function ConvertToByteArray(ByVal value As Bitmap) As Byte()
        Dim ms = New System.IO.MemoryStream
        value.Save(ms, System.Drawing.Imaging.ImageFormat.Tiff) ' Use appropriate format here
        Dim bytes = ms.ToArray()
        Return bytes
    End Function

#Region " ResizeImage "
    Public Overloads Shared Function ResizeImage(SourceImage As Drawing.Image, TargetWidth As Int32, TargetHeight As Int32) As Drawing.Bitmap
        Dim bmSource = New Drawing.Bitmap(SourceImage)

        Return ResizeImage(bmSource, TargetWidth, TargetHeight)
    End Function

    Public Overloads Shared Function ResizeImage(bmSource As Drawing.Bitmap, TargetWidth As Int32, TargetHeight As Int32) As Drawing.Bitmap
        Dim bmDest As New Drawing.Bitmap(TargetWidth, TargetHeight, Drawing.Imaging.PixelFormat.Format32bppArgb)

        Dim nSourceAspectRatio = bmSource.Width / bmSource.Height
        Dim nDestAspectRatio = bmDest.Width / bmDest.Height

        Dim NewX = 0
        Dim NewY = 0
        Dim NewWidth = bmDest.Width
        Dim NewHeight = bmDest.Height

        If nDestAspectRatio = nSourceAspectRatio Then
            'same ratio
        ElseIf nDestAspectRatio > nSourceAspectRatio Then
            'Source is taller
            NewWidth = Convert.ToInt32(Math.Floor(nSourceAspectRatio * NewHeight))
            NewX = Convert.ToInt32(Math.Floor((bmDest.Width - NewWidth) / 2))
        Else
            'Source is wider
            NewHeight = Convert.ToInt32(Math.Floor((1 / nSourceAspectRatio) * NewWidth))
            NewY = Convert.ToInt32(Math.Floor((bmDest.Height - NewHeight) / 2))
        End If

        Using grDest = Drawing.Graphics.FromImage(bmDest)
            With grDest
                .CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
                .InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
                .PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
                .SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias
                .CompositingMode = Drawing.Drawing2D.CompositingMode.SourceOver

                .DrawImage(bmSource, NewX, NewY, NewWidth, NewHeight)
            End With
        End Using

        Return bmDest
    End Function
#End Region

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Add any initialization after the InitializeComponent() call.
        'b = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
        b = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        PictureBox1.Image = b
        graphics = Graphics.FromImage(b)

        Me.DisableAero()

        RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.S)

        'PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
        'translateFromFile("./saved.tiff")
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As System.Object,
                        ByVal e As System.Windows.Forms.FormClosingEventArgs) _
                        Handles MyBase.FormClosing
        UnregisterHotKey(Me.Handle, 100)
        UnregisterHotKey(Me.Handle, 200)
    End Sub

    Private Sub DisableAero()
        Try
            aeroIsEnabled = DwmIsCompositionEnabled()
            If aeroIsEnabled = True Then
                DwmEnableComposition(False)
            End If
        Catch ex As Exception
        End Try

    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        'Timer1.Stop()
        CaptureScreenshot(New Point(0, 0), PictureBox1.Size)
        'Timer1.Start()
    End Sub

    Private Function CaptureScreenshot(startPoint As Point, DrawingSize As Size) As Boolean
        Try
            If b IsNot Nothing Then

                'graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.Location, New Point(0, 0), Screen.PrimaryScreen.Bounds.Size)
                'Dim newDrawingSize As New System.Drawing.Size(PictureBox1.Size)
                'graphics.CopyFromScreen(New Point(x, y), startPoint, DrawingSize)
                'graphics.CopyFromScreen(startPoint, New Point(0, 0), DrawingSize, CopyPixelOperation.SourceAnd)
                graphics.CopyFromScreen(startPoint, New Point(0, 0), DrawingSize)
                If False Then
                    Dim x As Integer
                    Dim y As Integer
                    Dim cursorBmp As Bitmap = CaptureCursor(x, y)
                    'Draws Cursor on picture
                    graphics.DrawImage(cursorBmp, x, y)
                    cursorBmp.Dispose()
                    'Cursor.Draw(graphics, New Rectangle(Cursor.Position, Cursor.Size))
                End If

                Me.Refresh()
            End If
        Catch ex As Exception

        End Try
    End Function

    Private Shared Function CaptureCursor(ByRef x As Integer, ByRef y As Integer) As Bitmap
        Dim bmp As Bitmap
        Dim hicon As IntPtr
        Dim ci As New CURSORINFO()
        Dim icInfo As ICONINFO
        ci.cbSize = Marshal.SizeOf(ci)
        If GetCursorInfo(ci) Then
            hicon = CopyIcon(ci.hCursor)
            If GetIconInfo(hicon, icInfo) Then
                x = ci.ptScreenPos.X - CInt(icInfo.xHotspot)
                y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot)
                Dim ic As Icon = Icon.FromHandle(hicon)
                bmp = ic.ToBitmap()
                ic.Dispose()
                Return bmp
            End If
        End If
        Return Nothing
    End Function

    Private Shared Function GetCursorPosition() As Point
        Dim hicon As IntPtr
        Dim ci As New CURSORINFO()
        Dim icInfo As ICONINFO
        Dim x, y As Integer
        ci.cbSize = Marshal.SizeOf(ci)
        If GetCursorInfo(ci) Then
            hicon = CopyIcon(ci.hCursor)
            If GetIconInfo(hicon, icInfo) Then
                x = ci.ptScreenPos.X - CInt(icInfo.xHotspot)
                y = ci.ptScreenPos.Y - CInt(icInfo.yHotspot)
                Return New Point(x, y)
            End If
        End If
        Return Nothing
    End Function


    <StructLayout(LayoutKind.Sequential)>
    Public Structure CURSORINFO
        Public cbSize As Int32
        Public flags As Int32
        Public hCursor As IntPtr
        Public ptScreenPos As Point
    End Structure

    <StructLayout(LayoutKind.Sequential)>
    Public Structure ICONINFO
        Public fIcon As Boolean
        Public xHotspot As Int32
        Public yHotspot As Int32
        Public hbmMask As IntPtr
        Public hbmColor As IntPtr
    End Structure

    Public Function translateFromMemory(ByteArray As Byte()) As String
        Try
            Using engine = New TesseractEngine("./tessdata", "eng", EngineMode.Default)

                Using img = Pix.LoadTiffFromMemory(ByteArray)
                    Using page = engine.Process(img)
                        Dim text = page.GetText()
                        Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence())

                        Console.WriteLine("Text (GetText): " & vbCr & vbLf & "{0}", text)
                        Console.WriteLine("Text (iterator):")
                        Using iter = page.GetIterator()
                            iter.Begin()

                            Do
                                Do
                                    Do
                                        Do
                                            If iter.IsAtBeginningOf(PageIteratorLevel.Block) Then
                                                Console.WriteLine("<BLOCK>")
                                            End If

                                            If iter.GetText(PageIteratorLevel.Word).Trim.EndsWith("-") Then
                                                translateFromMemory &= (iter.GetText(PageIteratorLevel.Word).Replace("-", ""))
                                            Else
                                                translateFromMemory &= (iter.GetText(PageIteratorLevel.Word))
                                                translateFromMemory &= (" ")
                                            End If


                                            If iter.IsAtFinalOf(PageIteratorLevel.TextLine, PageIteratorLevel.Word) Then
                                                If Not CheckBox1.Checked AndAlso Not iter.GetText(PageIteratorLevel.Word).EndsWith("-") Then
                                                    translateFromMemory &= vbCrLf
                                                End If
                                            End If
                                        Loop While iter.[Next](PageIteratorLevel.TextLine, PageIteratorLevel.Word)

                                        If iter.IsAtFinalOf(PageIteratorLevel.Para, PageIteratorLevel.TextLine) Then
                                            Console.WriteLine()
                                        End If
                                    Loop While iter.[Next](PageIteratorLevel.Para, PageIteratorLevel.TextLine)
                                Loop While iter.[Next](PageIteratorLevel.Block, PageIteratorLevel.Para)
                            Loop While iter.[Next](PageIteratorLevel.Block)
                        End Using
                    End Using
                End Using
            End Using
        Catch ex As Exception
            Trace.TraceError(ex.ToString())
            Console.WriteLine("Unexpected Error: " + ex.Message)
            Console.WriteLine("Details: ")
            Console.WriteLine(ex.ToString())
        End Try

        translateFromMemory &= vbCrLf & vbCrLf
        Return translateFromMemory
    End Function

    Public Sub translateFromFile(testImagePath As String, sw As IO.StreamWriter)
        Try
            Using engine = New TesseractEngine("./tessdata", "eng", EngineMode.Default)
                Using img = Pix.LoadFromFile(testImagePath)
                    Using page = engine.Process(img)
                        Dim text = page.GetText()
                        Console.WriteLine("Mean confidence: {0}", page.GetMeanConfidence())

                        Console.WriteLine("Text (GetText): " & vbCr & vbLf & "{0}", text)
                        Console.WriteLine("Text (iterator):")
                        Using iter = page.GetIterator()
                            iter.Begin()

                            Do
                                Do
                                    Do
                                        Do
                                            If iter.IsAtBeginningOf(PageIteratorLevel.Block) Then
                                                Console.WriteLine("<BLOCK>")
                                            End If

                                            'TextBox1.Text &= (iter.GetText(PageIteratorLevel.Word))
                                            'TextBox1.Text &= (" ")
                                            If iter.GetText(PageIteratorLevel.Word).Trim.EndsWith("-") Then
                                                sw.Write(iter.GetText(PageIteratorLevel.Word).Replace("-", ""))
                                            Else
                                                sw.Write(iter.GetText(PageIteratorLevel.Word) & (" "))
                                            End If


                                            If iter.IsAtFinalOf(PageIteratorLevel.TextLine, PageIteratorLevel.Word) Then
                                                If Not CheckBox1.Checked AndAlso Not iter.GetText(PageIteratorLevel.Word).EndsWith("-") Then
                                                    sw.WriteLine()
                                                End If
                                            End If
                                        Loop While iter.[Next](PageIteratorLevel.TextLine, PageIteratorLevel.Word)

                                        If iter.IsAtFinalOf(PageIteratorLevel.Para, PageIteratorLevel.TextLine) Then
                                            Console.WriteLine()
                                        End If
                                    Loop While iter.[Next](PageIteratorLevel.Para, PageIteratorLevel.TextLine)
                                Loop While iter.[Next](PageIteratorLevel.Block, PageIteratorLevel.Para)
                            Loop While iter.[Next](PageIteratorLevel.Block)
                        End Using
                    End Using
                End Using
            End Using
        Catch ex As Exception
            Trace.TraceError(ex.ToString())
            Console.WriteLine("Unexpected Error: " + ex.Message)
            Console.WriteLine("Details: ")
            Console.WriteLine(ex.ToString())
        End Try
        Console.Write("Press any key to continue . . . ")
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Timer1.Interval = 1000
        Timer1.Enabled = True
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then
            Using sw As StreamWriter = File.AppendText(FolderBrowserDialog1.SelectedPath & "\Output.txt")
                For Each MyFile As String In IO.Directory.GetFiles(FolderBrowserDialog1.SelectedPath)
                    translateFromFile(MyFile, sw)
                    Application.DoEvents()
                Next
            End Using
        End If
    End Sub

End Class

Public Class MyThreading
    Public DataToPass() As Byte
    Public DataToReturn As String
    Public CallingThreadForm As Form
    Public InvokeFunctionOnCompelte As [Delegate]
    Public MyThreadToStart As Threading.Thread
    Public PreviousThread As System.Threading.Thread

    Public Sub New(ByVal NameOfThread As String, ByVal pDataToPass() As Byte, ByVal pPreviousThread As Threading.Thread, ByVal pCallingThreadForm As Form, ByVal pInvokeFunctionOnCompelte As [Delegate])
        DataToPass = pDataToPass.Clone
        PreviousThread = pPreviousThread
        CallingThreadForm = pCallingThreadForm
        InvokeFunctionOnCompelte = pInvokeFunctionOnCompelte
        MyThreadToStart = New Threading.Thread(AddressOf StartWork)
        MyThreadToStart.Name = NameOfThread
        MyThreadToStart.Start()
    End Sub

    Private Sub StartWork()

        DataToReturn = CType(CallingThreadForm, Form1).translateFromMemory(DataToPass)

        If PreviousThread IsNot Nothing Then
            While PreviousThread.IsAlive
                Debug.WriteLine(MyThreadToStart.Name & ": Sleeping for a Seconds while waiting on " & PreviousThread.Name & " to complete")
                Threading.Thread.Sleep(500)
            End While
        Else
            Debug.WriteLine(MyThreadToStart.Name & "Previous Thread is nothing")
        End If

        Debug.WriteLine(MyThreadToStart.Name & ": Done!")
        CallingThreadForm.Invoke(InvokeFunctionOnCompelte, Me)
    End Sub
End Class

Today I decided to create a custom workflow with Multithreading in such a way that results from a previous thread that was spawned first is required to complete before the results from the thread’s therefor after are rendered. In the example below I created 10 threads, Everytime Mod 3 = 0 is true, that thread will stay alive longer than the rest that are spawned. In this case, Thread 3,6,9 are all active for 5 seconds while the rest are only alive for a second. The outcome of the code results are as follows

Thread 1 Started! 0Previous Thread is nothing 0: Done! Thread 2
Started! Thread 3 Started! Thread 4 Started! Thread 5 Started! Thread
6 Started! Thread 7 Started! Thread 8 Started! Thread 9 Started!
Thread 10 Started! ‘VBMultiThreading.exe’ (CLR v2.0.50727:
VBMultiThreading.exe): Loaded
‘C:\Windows\assembly\GAC_MSIL\Accessibility\2.0.0.0__b03f5f7f11d50a3a\Accessibility.dll’.
Cannot find or open the PDB file. test came back from0 The thread
0x1ee8 has exited with code 0 (0x0). 1: Done! test came back from1 The
thread 0x5c20 has exited with code 0 (0x0). 2: Done! test came back
from2 The thread 0x6cc4 has exited with code 0 (0x0). 3: Done! test
came back from3 The thread 0x49f8 has exited with code 0 (0x0). 4:
Done! test came back from4 The thread 0x302c has exited with code 0
(0x0). 5: Done! test came back from5 The thread 0x4dd0 has exited with
code 0 (0x0). 6: Done! test came back from6 The thread 0x53a0 has
exited with code 0 (0x0). 7: Done! test came back from7 The thread
0x4bc4 has exited with code 0 (0x0). 8: Done! test came back from8 The
thread 0x41e8 has exited with code 0 (0x0). 9: Done! test came back
from9 The thread 0xa1f4 has exited with code 0 (0x0). 10: Done! test
came back from10 The thread 0x32fc has exited with code 0 (0x0). The
program ‘[21476] VBMultiThreading.exe’ has exited with code 0 (0x0).

As you can see regardless of the workflow or even the order they are created as long as the previous thread is attached to the class it will always wait while the previous thread results are in. This workflow increases performance without losing any flexibility when developing multithreaded applications.

Public Class Form1
    Private Delegate Sub MyDelPtr(CurrentInstance As MyThreading)
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim MyThreadingClass As MyThreading

        MyThreadingClass = New MyThreading("0", "1", Nothing, Me, New MyDelPtr(AddressOf Test))

        For i = 1 To 10

            If i Mod 3 = 0 Then
                MyThreadingClass = New MyThreading(i, "5", MyThreadingClass.MyThreadToStart, Me, New MyDelPtr(AddressOf Test))
            Else
                MyThreadingClass = New MyThreading(i, "1", MyThreadingClass.MyThreadToStart, Me, New MyDelPtr(AddressOf Test))
            End If

            Debug.WriteLine("Thread " & i & " Started!")
        Next
    End Sub

    Public Sub Test(CurrentInstance As MyThreading)
        Debug.WriteLine("Results (in order) came back to mainthread from:" & CurrentInstance.MyThreadToStart.Name)
    End Sub

End Class

Public Class MyThreading
    Public DataToPass As String
    Public CallingThreadForm As Form
    Public InvokeFunctionOnCompelte As [Delegate]
    Public MyThreadToStart As Threading.Thread
    Public PreviousThread As System.Threading.Thread

    Public Sub New(ByVal NameOfThread As String, ByVal pDataToPass As String, ByVal pPreviousThread As Threading.Thread, ByVal pCallingThreadForm As Form, ByVal pInvokeFunctionOnCompelte As [Delegate])
        DataToPass = pDataToPass
        PreviousThread = pPreviousThread
        CallingThreadForm = pCallingThreadForm
        InvokeFunctionOnCompelte = pInvokeFunctionOnCompelte
        MyThreadToStart = New Threading.Thread(AddressOf StartWork)
        MyThreadToStart.Name = NameOfThread
        MyThreadToStart.Start()
    End Sub

    Private Sub StartWork()
        If PreviousThread IsNot Nothing Then
            While PreviousThread.IsAlive
                'Debug.WriteLine(MyThreadToStart.Name & ": Sleeping for " & DataToPass & " Seconds")
                Threading.Thread.Sleep(1000 * CInt(DataToPass))
            End While
        Else
            Debug.WriteLine(MyThreadToStart.Name & "Previous Thread is nothing")
        End If

        Debug.WriteLine(MyThreadToStart.Name & ": Done!")
        CallingThreadForm.Invoke(InvokeFunctionOnCompelte, Me)
    End Sub
End Class

Requirements for Patient review of their medical record audit trail

Context: This proposal describes a target for a patient-accessible audit trail for implementation in a 2 to 5 year time frame. It is not expected that any organization would be able to implement this proposal immediately or in the near-term. The near-term impact of this proposal is to (1) stimulate discussion of this subject, (2) provide a benchmark for gap analysis of projects, and (3) provide a basis for policy development within and external to, our organizations.

Background: Many security/privacy breaches are a result of individuals in the covered entity with legitimate access rights who view patient information that they should not be viewing as it is not needed to perform their official duties related to treatment, payment or health care operations or other legal authority to view the information does not exist. Typically, they are viewing information on a personal acquaintance who is not under their care. It is extremely difficult to reliably detect all such security/privacy breaches.

Though the Health Insurance Portability and Accountability Act (HIPAA) Privacy Rule does not mandate that covered entities provide copies of audit trails to patients, the most plausible way to detect the above described security/privacy breaches is to allow patients to review the audit trails of their chart, and they will be able to recognize individuals who they do not believe have a legitimate need to access their chart. Patients will not be able to detect these breaches in an audit trail, unless that audit trail is designed to clearly indicate the who, what, when, where, and why of each individual accessing their chart. If this information is not presented to the patient in a very usable format, it will generate many needless questions and both the patient and the auditor will be frustrated with a very low specificity of the information.

Following are the proposed requirements for the audit trail and processes to support patient viewing of that audit trail:

  1. Patients should be able to review (in-person or online through web access) each of the following elements of the audit trail as it relates to their record: viewing only, editing, or electronically transferring all or part of their record. (Audit trails of these patient-initiated access to their personal audit trails will also be required).
  2. Clear indication of who accessed their record.
    a) Name of the user
    b) Title of the user at the time of access, e.g. MD, RN, medical student, RN, pharmacist, QA, call center agent, etc.
    c) A role description that includes a brief patient friendly summary of the role, e.g. pathologist: studies biopsy results under a microscope
  3. From what location they accessed my record (i.e. which facility)
  4. Which parts of the record they viewed/printed/transferred (in layman’s terms: e.g. “doctors notes”, “lab results”, etc.)
  5. When did the access occur including date and time?
  6. Why the record was viewed/printed/transferred (in layman’s terms: e.g., treatment, payment for services, quality review, training, etc.)
  7. Ability to provide the patient with a digital or paper copy of this audit information
  8. Ability to answer patient requests for further clarification of specific audit events
  9. These audit trails should be retained for a minimum of XX years by all legal record maintenance guardians.
  10. Provide patient with a well documented process to escalate any perceived inappropriate accesses.
  11. Documented policies within the covered entity on how to investigate and mitigate any security/privacy breaches resulting from the patient review of the audit trail.

So these last couple of weeks I’ve been researching Electrical Engineering from a PCB Manufacturing perspective and I have to say, Things are coming along quite nicely. There are some things to keep on the Radar though as you are planning these boards out and a lot of it is Electrical Lane clearance and also the thickness of the traces. I am currently thinking of building this as more of a breakout board than a single project. As I go I’m sure the idea will develop more =].
So a couple features this new computer is going to have is
Radio Communication over 415 and 315HMZ
GPS Abilities
I2C Communcation with a Gyroscope and 1602 LCD
Nextion Touchscreen Interface over UART
One-Wire Thermostats Polling for both Temperature and Humanity
IR Recv, and Mimic at any Modulation thanks to my collection of TSOP98200!
PWM Motor controlling via GPIO!

Stay tuned! 🙂

So recently I came across a reported issue where the end user was getting this error message “The message store has reached its maximum size. to Reduce the amount of data in this message store, select some that you no longer need, permanently (shift + del) delete them.”

After a quick review I found that at the DB level a quota was still in palce so I swiftly removed it to resolve the issue.

[PS] C:\Windows\system32>New-MoveRequest -Identity ‘MyEmail@Email.com’ -TargetDatabase “dbNAME” Mailbox dumpster size 30 GB (32,212,266,090 bytes) exceeds target quota 30 GB (32,212,254,720 bytes). + CategoryInfo : InvalidArgument: (MyEmail@Email.com:MailboxOrMailUserIdParameter) [New-Mov entTaskException + FullyQualifiedErrorId : 7E4E00C3,Microsoft.Exchange.Management.RecipientTasks.NewMoveRequest

[PS] C:\Windows\system32>Get-MailboxDatabase -Identity “dbNAME” | Format-List *

PSComputerName : MyExchange.info.sys RunspaceId : 126bfdd8-485e-87cd-35f810d32d44 JournalRecipient : MailboxRetention : 24855.00:00:00 OfflineAddressBook : \Default Offline Address List OriginalDatabase : PublicFolderDatabase : PF00 ProhibitSendReceiveQuota : unlimited ProhibitSendQuota : unlimited RecoverableItemsQuota : 30 GB (32,212,254,720 bytes) RecoverableItemsWarningQuota : 20 GB (21,474,836,480 bytes) IndexEnabled : True

[PS] C:\Windows\system32>Get-MailboxDatabase -Identity “dbNAME” | Format-List RecoverableItemsQuota,RecoverableItemsWarningQuota

RecoverableItemsQuota : 30 GB (32,212,254,720 bytes) RecoverableItemsWarningQuota : 20 GB (21,474,836,480 bytes)

[PS] C:\Windows\system32>Set-MailboxDatabase -Identity “dbNAME” -RecoverableItemsWarningQuota Unlimited [PS] C:\Windows\system32>Set-MailboxDatabase -Identity “dbNAME” -RecoverableItemsQuota Unlimited

[PS] C:\Windows\system32>Get-MailboxDatabase -Identity “dbNAME” | Format-List RecoverableItemsQuota,RecoverableItemsWarningQuota

RecoverableItemsQuota : unlimited RecoverableItemsWarningQuota : unlimited

So at my place of employment, I am responsible for quite a few task and one of them being the Pharmacy Maintainance window. This window control’s its security patches from Microsoft through a custom web interface with a Login. By using the powershell code below I was able to automate logging into the interface ready to invoke the window. I hope the code below helps someone else post past a ASP.NET page.

Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear(); Clear-Host

$Headers = @{
"accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
"Host"="vm716"
"Cache-Control"="max-age=0"
"Origin"="http://ADMServer"
"Upgrade-Insecure-Requests"="1"
"Referer"="http://ADMServer/ADMConsole/Login.aspx?ReturnUrl=%2fADMConsole%2fdefault.aspx"
"Accept-Encoding"="gzip, deflate"
"Accept-Language"="en-US,en;q=0.9"}

$FormatEnumerationLimit=-1

$userAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome

$LoginResponse = Invoke-WebRequest 'http://ADMServer/ADMConsole/Login.aspx?ReturnUrl=%2fADMConsole%2fDevices%2fdefault.aspx' -SessionVariable 'Session' -UserAgent $userAgent -Headers $Headers


#$LoginResponse.Forms[0] | Format-List -Property *

$addUserForm = $LoginResponse.Forms[0] #Invoke-WebRequest does a lot of auto processing.

#Doing it this will will also send the stateview and other important ASP.NET variables.
$addUserForm.Fields['loginUser$UserName'] = "MyUserName"
$addUserForm.Fields['loginUser$Password'] = "MyPassword"
$addUserForm.Fields['loginUser$LoginButton'] = "Login"

#$LoginResponse.Forms[0] | Format-List -Property *

$LoginResponse = Invoke-WebRequest ('http://ADMServer/ADMConsole/' + $addUserForm.Action) -WebSession $session -Body $addUserForm.Fields -Method 'POST' -UserAgent $userAgent -Headers $Headers

$LoginResponse

write-Host 'http://ADMServer/ADMConsole/' + $addUserForm.Action

$CheckBoxes = $LoginResponse.ParsedHtml.getElementsByTagName("input")

#$LoginResponse = Invoke-WebRequest ('http://ADMServer/ADMConsole/ADMConsole%2fDevices%2fdefault.aspx') -WebSession $session -UserAgent $userAgent -Headers $Headers

#$LoginResponse

foreach ($element in $CheckBoxes)
{
    Write-Host $element.Name $element.value
}
Application.DoEvents();
            /* Create a new SheetMusic Control from the midifile */
            byte[] MyA440 = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x31, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            byte[] MyAPowerChord = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x39, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x00, 0x90, 0x48, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            byte[] MyAChord = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x00, 0x90, 0x48, 0x32, 0x00, 0x90, 0x4c, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0x80, 0x4c, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            byte[] MyA7Chord = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x49, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x00, 0x90, 0x48, 0x32, 0x00, 0x90, 0x4c, 0x32, 0x00, 0x90, 0x4f, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0x80, 0x4c, 0x00, 0x00, 0x80, 0x4f, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            midifile = new MidiFile(MyA7Chord, "My A440");
            DisableMenus();
            EnableMenus();

            instrumentDialog = new InstrumentDialog(midifile);
            playMeasuresDialog = new PlayMeasuresDialog(midifile);

            SaveMidiOptions();
            RedrawSheetMusic();

            sheetmusic = new SheetMusic(midifile, null);
            sheetmusic.SetZoom(zoom);
            sheetmusic.Parent = scrollView;

https://onlinesequencer.net/import2/fedd9ea7da1d866ec760f44f2b155104?title=1.mid http://phpmidiparser.com/reports/2310/ http://phpmidiparser.com/reports/2313/ https://sourceforge.net/projects/midisheetmusic/ https://web.archive.org/web/20141227205754/http://www.sonicspot.com:80/guide/midifiles.html http://subsynth.sourceforge.net/midinote2freq.html

 MIDI                   MIDI                   MIDI
 Note     Frequency      Note   Frequency       Note   Frequency
 C1  0    8.1757989156    12    16.3515978313    24    32.7031956626
 Db  1    8.6619572180    13    17.3239144361    25    34.6478288721
 D   2    9.1770239974    14    18.3540479948    26    36.7080959897
 Eb  3    9.7227182413    15    19.4454364826    27    38.8908729653
 E   4   10.3008611535    16    20.6017223071    28    41.2034446141
 F   5   10.9133822323    17    21.8267644646    29    43.6535289291
 Gb  6   11.5623257097    18    23.1246514195    30    46.2493028390
 G   7   12.2498573744    19    24.4997147489    31    48.9994294977
 Ab  8   12.9782717994    20    25.9565435987    32    51.9130871975
 A   9   13.7500000000    21    27.5000000000    33    55.0000000000
 Bb  10  14.5676175474    22    29.1352350949    34    58.2704701898
 B   11  15.4338531643    23    30.8677063285    35    61.7354126570

 C4  36  65.4063913251    48   130.8127826503    60   261.6255653006
 Db  37  69.2956577442    49   138.5913154884    61   277.1826309769
 D   38  73.4161919794    50   146.8323839587    62   293.6647679174
 Eb  39  77.7817459305    51   155.5634918610    63   311.1269837221
 E   40  82.4068892282    52   164.8137784564    64   329.6275569129
 F   41  87.3070578583    53   174.6141157165    65   349.2282314330
 Gb  42  92.4986056779    54   184.9972113558    66   369.9944227116
 G   43  97.9988589954    55   195.9977179909    67   391.9954359817
 Ab  44  103.8261743950   56   207.6523487900    68   415.3046975799
 A   45  110.0000000000   57   220.0000000000    69   440.0000000000
 Bb  46  116.5409403795   58   233.0818807590    70   466.1637615181
 B   47  123.4708253140   59   246.9416506281    71   493.8833012561

 C7  72  523.2511306012   84  1046.5022612024    96  2093.0045224048
 Db  73  554.3652619537   85  1108.7305239075    97  2217.4610478150
 D   74  587.3295358348   86  1174.6590716696    98  2349.3181433393
 Eb  75  622.2539674442   87  1244.5079348883    99  2489.0158697766
 E   76  659.2551138257   88  1318.5102276515   100  2637.0204553030
 F   77  698.4564628660   89  1396.9129257320   101  2793.8258514640
 Gb  78  739.9888454233   90  1479.9776908465   102  2959.9553816931
 G   79  783.9908719635   91  1567.9817439270   103  3135.9634878540
 Ab  80  830.6093951599   92  1661.2187903198   104  3322.4375806396
 A   81  880.0000000000   93  1760.0000000000   105  3520.0000000000
 Bb  82  932.3275230362   94  1864.6550460724   106  3729.3100921447
 B   83  987.7666025122   95  1975.5332050245   107  3951.0664100490

 C10 108 4186.0090448096  120  8372.0180896192
 Db  109 4434.9220956300  121  8869.8441912599
 D   110 4698.6362866785  122  9397.2725733570
 Eb  111 4978.0317395533  123  9956.0634791066
 E   112 5274.0409106059  124 10548.0818212118
 F   113 5587.6517029281  125 11175.3034058561
 Gb  114 5919.9107633862  126 11839.8215267723
 G   115 6271.9269757080  127 12543.8539514160
 Ab  116 6644.8751612791
 A   117 7040.0000000000
 Bb  118 7458.6201842894
 B   119 7902.1328200980



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MidiFunction
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] MyA440 =        { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x31, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            byte[] MyAPowerChord = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x39, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x00, 0x90, 0x48, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            byte[] MyAChord =      { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x41, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x00, 0x90, 0x48, 0x32, 0x00, 0x90, 0x4c, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0x80, 0x4c, 0x00, 0x00, 0xff, 0x2f, 0x00 };
            byte[] MyA7Chord =     { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x00, 0x49, 0x00, 0xff, 0x58, 0x04, 0x04, 0x02, 0x18, 0x08, 0x00, 0xff, 0x51, 0x03, 0x0b, 0x71, 0xb0, 0x00, 0xff, 0x03, 0x0e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x69, 0x63, 0x20, 0x50, 0x69, 0x61, 0x6e, 0x6f, 0x00, 0xc0, 0x00, 0x00, 0x90, 0x45, 0x32, 0x00, 0x90, 0x48, 0x32, 0x00, 0x90, 0x4c, 0x32, 0x00, 0x90, 0x4f, 0x32, 0x8c, 0x00, 0x80, 0x45, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0x80, 0x4c, 0x00, 0x00, 0x80, 0x4f, 0x00, 0x00, 0xff, 0x2f, 0x00 };

            int Note1 = 60;
            int Note1off = 65;

            int MyAPowerChord1 = 60;
            int MyAPowerChord2 = 64;
            int MyAPowerChord1off = 69;
            int MyAPowerChord2off = 73;

            int MyAChord1 = 60;
            int MyAChord2 = 64;
            int MyAChord3 = 68;
            int MyAChordoff1 = 73;
            int MyAChordoff2 = 77;
            int MyAChordoff3 = 81;

            int MyA7Chord1 = 60;
            int MyA7Chord2 = 64;
            int MyA7Chord3 = 68;
            int MyA7Chord4 = 72;
            int MyA7Chordoff1 = 77;
            int MyA7Chordoff2 = 81;
            int MyA7Chordoff3 = 85;
            int MyA7Chordoff4 = 89;

            System.Diagnostics.Debug.WriteLine(MyA440[Note1]);
            System.Diagnostics.Debug.WriteLine(MyA440[Note1off]);

            System.Diagnostics.Debug.WriteLine(MyAPowerChord[MyAPowerChord1]);
            System.Diagnostics.Debug.WriteLine(MyAPowerChord[MyAPowerChord2]);
            System.Diagnostics.Debug.WriteLine(MyAPowerChord[MyAPowerChord1off]);
            System.Diagnostics.Debug.WriteLine(MyAPowerChord[MyAPowerChord2off]);

            System.Diagnostics.Debug.WriteLine(MyAChord[MyAChord1]);
            System.Diagnostics.Debug.WriteLine(MyAChord[MyAChord2]);
            System.Diagnostics.Debug.WriteLine(MyAChord[MyAChord3]);
            System.Diagnostics.Debug.WriteLine(MyAChord[MyAChordoff1]);
            System.Diagnostics.Debug.WriteLine(MyAChord[MyAChordoff2]);
            System.Diagnostics.Debug.WriteLine(MyAChord[MyAChordoff3]);

            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chord1]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chord2]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chord3]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chord4]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chordoff1]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chordoff2]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chordoff3]);
            System.Diagnostics.Debug.WriteLine(MyA7Chord[MyA7Chordoff4]);
        }
    }
}

A440.Note APowerChord AMajor AMajor7

Imports System.Runtime.InteropServices
Public Class Form1
    'http://social.msdn.microsoft.com/Forums/en-US/512c7fc3-fb32-4081-a8c2-451883abe9fb/dhcpclientinfovq-bclienttype
    Declare Unicode Function DhcpEnumSubnetClients Lib "dhcpsapi" (ByVal ServerIpAddress As String, ByVal SubnetAddress As UInt32, ByRef ResumeHandle As IntPtr, ByVal PreferredMaximum As Integer, ByRef ClientInfo As IntPtr, ByRef ClientsRead As Integer, ByRef ClientsTotal As Integer) As Integer
    <DllImport("dhcpsapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Public Shared Function DhcpSetClientInfo( _
        ByVal ServerIpAddress As String, _
        ByVal ClientInfo As IntPtr) As UInt32
    End Function

    <DllImport("dhcpsapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Public Shared Function DhcpSetClientInfoV4( _
        ByVal ServerIpAddress As String, _
        ByVal ClientInfoV4 As IntPtr) As UInt32
    End Function

    <DllImport("dhcpsapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Public Shared Function DhcpGetClientInfo( _
        ByVal ServerIpAddress As String, _
        ByRef SearchInfo As DHCP_SEARCH_INFO, _
        ByRef ClientInfo As IntPtr) As UInt32
    End Function

    <DllImport("dhcpsapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Public Shared Function DhcpSetClientInfoVQ( _
        ByVal ServerIpAddress As String, _
        ByVal ClientInfo As IntPtr) As UInt32
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure DHCP_IP_ARRAY
        Dim NumElements As Int32
        Dim Elements As IntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure DHCP_CLIENT_INFO_ARRAY
        Dim NumElements As Integer
        Dim Clients As IntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure DHCP_CLIENT_INFO
        Dim ClientIpAddress As UInt32
        Dim SubnetMask As UInt32
        Dim ClientHardwareAddress As DHCP_BINARY_DATA
        <MarshalAs(UnmanagedType.LPWStr)> Dim ClientName As String
        <MarshalAs(UnmanagedType.LPWStr)> Dim ClientComment As String
        Dim ClientLeaseExpires As MyDate_Time
        Dim OwnerHost As DHCP_HOST_INFO
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure DHCP_CLIENT_INFOV4
        Dim ClientIpAddress As UInt32
        Dim SubnetMask As UInt32
        Dim ClientHardwareAddress As DHCP_BINARY_DATA
        <MarshalAs(UnmanagedType.LPWStr)> Dim ClientName As String
        <MarshalAs(UnmanagedType.LPWStr)> Dim ClientComment As String
        Dim ClientLeaseExpires As MyDate_Time
        Dim OwnerHost As DHCP_HOST_INFO
        Dim bClientType As DHCP_CLIENT_TYPE
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure DHCP_CLIENT_INFO_ARRAY_VQ
        Dim NumElements As Integer
        Dim Clients As IntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure DHCP_CLIENT_INFO_VQ
        Dim ClientIpAddress As UInt32
        Dim SubnetMask As UInt32
        Dim ClientHardwareAddress As DHCP_BINARY_DATA
        <MarshalAs(UnmanagedType.LPWStr)> Dim ClientName As String
        <MarshalAs(UnmanagedType.LPWStr)> Dim ClientComment As String
        Dim ClientLeaseExpires As MyDate_Time
        Dim OwnerHost As DHCP_HOST_INFO
        Dim bClientType As DHCP_CLIENT_TYPE
        Dim AddressState As Byte
        Dim Status As DHCP_QuarantineStatus
        Dim ProbationEnds As MyDate_Time
        Dim QuarantineCapable As Boolean
    End Structure

    Enum DHCP_CLIENT_TYPE As Byte
        CLIENT_TYPE_DHCP = 1
        CLIENT_TYPE_BOOTP = 2
        CLIENT_TYPE_BOTH = 3
        CLIENT_TYPE_RESERVATION_FLAG = 4
        CLIENT_TYPE_NONE = &H64
    End Enum

    Enum DHCP_AddressState As Byte
        CLIENT_TYPE_DHCP = 1
        CLIENT_TYPE_BOOTP = 2
        CLIENT_TYPE_BOTH = 3
        CLIENT_TYPE_RESERVATION_FLAG = 4
        CLIENT_TYPE_NONE = &H64
    End Enum

    Enum DHCP_QuarantineStatus As Byte
        NOQUARANTINE = 0
        RESTRICTEDACCESS = 1
        DROPPACKET = 2
        PROBATION = 3
        EXEMPT = 4
        DEFAULTQUARSETTING = 5
        NOQUARINFO = 6
    End Enum

    <StructLayout(LayoutKind.Sequential)> _
    Structure DHCP_DATE_TIME
        Dim dwLowDateTime As Integer
        Dim dwHighDateTime As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Structure DHCP_BINARY_DATA
        Dim DataLength As Int32
        Dim Data As IntPtr
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure MyDate_Time

        <MarshalAs(UnmanagedType.U4)> _
        Dim dwLowDateTime As UInt32

        <MarshalAs(UnmanagedType.U4)> _
        Dim dwHighDateTime As UInt32

        Public Function ConvertIntToDateTime() As DateTime
            If dwHighDateTime = 0 And dwLowDateTime = 0 Then Return DateTime.MinValue
            If dwHighDateTime = Int32.MaxValue And dwLowDateTime = UInt32.MaxValue Then Return DateTime.MaxValue
            Dim value As Long = dwHighDateTime
            value <<= 32
            value += dwLowDateTime
            Return DateTime.FromFileTime(value)
        End Function

        Public Sub SetToReserved()
            dwLowDateTime = 0
            dwHighDateTime = 0
            'Return DateTime.FromFileTime(value)
        End Sub

        Public Sub SetToInfinte()
            dwLowDateTime = 4294967295
            dwHighDateTime = 2147483647
            'Return DateTime.FromFileTime(value)
        End Sub

    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Structure DHCP_HOST_INFO

        Dim IpAddress As Int32

        <MarshalAs(UnmanagedType.LPWStr)> _
        Dim NetBiosName As String

        <MarshalAs(UnmanagedType.LPWStr)> _
        Dim HostName As String

    End Structure
    ''' <summary>
    ''' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''' DHCP SERVER STRUCTS
    ''' </summary>
    ''' <remarks></remarks>
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DHCPDS_SERVER
        Dim Version As UInt32
        Dim ServerName As String
        Dim ServerAddress As UInt32
        Dim Flags As UInt32
        Dim State As UInt32
        Dim DsLocation As String
        Dim DsLocType As UInt32
    End Structure

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DHCPDS_SERVERS
        Dim Flags As UInt32
        Dim NumElements As UInt32
        Dim Servers As IntPtr
    End Structure

    Declare Unicode Function DhcpEnumServers Lib "Dhcpsapi.dll" (ByVal Flags As UInt32, _
      ByVal IdInfo As IntPtr, _
      ByRef Servers As IntPtr, _
      ByVal CallbackFn As IntPtr, _
      ByVal CallbackData As IntPtr) As UInt32


    ''' <summary>
    ''' Sumery
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' 

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DHCP_IP_ADDRESS
        Dim IPAddress As UInteger
    End Structure

    ''' <summary>
    ''' Sumery
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' 

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> Public Structure DHCP_SUBNET_INFO
        Public SubnetAddress As UInteger
        Public SubnetMask As UInteger
        Public SubnetName As String
        Public SubnetComment As String
        'Public PrimaryHost As DHCP_HOST_INFO
        Public SubnetState As DHCP_SUBNET_STATE
    End Structure


    Public Enum DHCP_SUBNET_STATE
        DhcpSubnetEnabled = 0
        DhcpSubnetDisabled = 1
        DhcpSubnetEnabledSwitched = 2
        DhcpSubnetDisabledSwitched = 3
        DhcpSubnetInvalidState = 4
    End Enum

    Public Declare Unicode Function DhcpGetSubnetInfo Lib "Dhcpsapi" (ByVal ServerIpAddress As String, ByVal SubnetAddress As Integer, ByRef SubnetInfo As DHCP_SUBNET_INFO) As Integer
    Public Declare Unicode Function DhcpEnumSubnets Lib "Dhcpsapi" (ByVal ServerIpAddress As String, ByRef ResumeHandle As Integer, ByVal PreferredMaximum As Integer, ByRef EnumInfo As IntPtr, ByRef ElementsRead As Integer, ByRef ElementsTotal As Integer) As Integer

    Dim HowManyClients As Long = 0
    Dim HowManyClientsAreAlreadyReserved As Long = 0
    Dim HowManyClientsAreNeedToBechanged As Long = 0
    Dim HowManyClientsHaveBadAddresses As Long = 0
    Dim MachinesThatWillChange As String = vbNullString
    Dim MachinesThatWillNotChange As String = vbNullString

    Dim ServerIPAddress As String = "10.10.10.10"

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim ts = Stopwatch.StartNew

        ' Your code goes here
        EnumAll()
        Debug.WriteLine("How many clients: " & HowManyClients)
        Debug.WriteLine("How many clients are already reserved: " & HowManyClientsAreAlreadyReserved)
        Debug.WriteLine("How many clients need to be changed: " & (HowManyClientsAreNeedToBechanged - HowManyClientsHaveBadAddresses))
        Debug.WriteLine("How many clients have bad addresses: " & HowManyClientsHaveBadAddresses)
        Debug.WriteLine("-----------------------------------------------------------------------")
        Debug.WriteLine("Machines that will change")
        Debug.WriteLine(MachinesThatWillChange)
        Debug.WriteLine("-----------------------------------------------------------------------")
        Debug.WriteLine("Machines that will NOT change")
        Debug.WriteLine(MachinesThatWillNotChange)

        ' Format and display the TimeSpan value.
        Dim myelapsedTime As String = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Elapsed.Hours, ts.Elapsed.Minutes, ts.Elapsed.Seconds, ts.Elapsed.Milliseconds / 10)
        Debug.WriteLine("RunTime " & myelapsedTime)
        'EnumServers()
        'GetSubnets("10.10.10.10")
        'ListSubnetClients("10.10.10.10", "10.10.10.100")
        'CompareFirewallRules()
        'GetClientInfo("10.10.10.10", "10.10.10.100")
    End Sub

    Public Function GetSubnets(ByVal ServerIp As String) As String()
        Dim StringsToReturn() As String

        Dim ServerIpAddress = ServerIp
        Dim DHCPResult As UInt32 = 0

        Dim IPS As IntPtr
        Dim nr As UInteger = 0
        Dim Total As UInteger = 0
        Dim resumehandle As UInteger = 0

        DHCPResult = DhcpEnumSubnets(ServerIpAddress, resumehandle, 1000, IPS, nr, Total)
        If DHCPResult = 0 Then
            Dim iparray As DHCP_IP_ARRAY = CType(Marshal.PtrToStructure(IPS, GetType(DHCP_IP_ARRAY)), DHCP_IP_ARRAY)

            Dim Size As Integer = iparray.NumElements
            Dim outArray As IntPtr = iparray.Elements
            Dim ipAddressesArray(Size) As DHCP_IP_ADDRESS
            Array.Resize(StringsToReturn, Size + 1)
            Dim current As IntPtr = outArray
            For i = 0 To Size
                ipAddressesArray(i) = New DHCP_IP_ADDRESS
                ipAddressesArray(i) = CType(Marshal.PtrToStructure(current, GetType(DHCP_IP_ADDRESS)), DHCP_IP_ADDRESS)
                Marshal.DestroyStructure(current, GetType(DHCP_IP_ADDRESS))
                current = current + Marshal.SizeOf(ipAddressesArray(i))

                Debug.WriteLine(i & " " & IPConvert(ipAddressesArray(i).IPAddress))
                StringsToReturn(i) = IPConvert(ipAddressesArray(i).IPAddress)
            Next
            Marshal.FreeCoTaskMem(outArray)
            Debug.WriteLine("Elements read " & nr & " out of " & Total)
        Else
            Debug.WriteLine("Failed!")
        End If

        Return StringsToReturn
    End Function

    Public Function getSubNetInfo(ByVal Subnet As Integer) As Integer

        Dim Result As DHCP_SUBNET_INFO
        Dim code As Integer

        Try

            code = DhcpGetSubnetInfo("10.10.10.10", Subnet, Result)
            msgbox(Result.SubnetName)

        Catch

            msgbox(Err.Description)

        End Try

    End Function

    Public Shared Function EnumServers() As DHCPDS_SERVER()

        Dim retVal As UInt32 = 0
        Dim servers As IntPtr

        Try
            DhcpEnumServers(0, Nothing, servers, Nothing, Nothing)
        Catch ex As Exception
            Throw New Exception("Error code:  " & retVal.ToString, ex)
        End Try

        If retVal = 0 And servers <> IntPtr.Zero Then
            Dim serverArray As DHCPDS_SERVERS = _
              CType(Marshal.PtrToStructure(servers, GetType(DHCPDS_SERVERS)), DHCPDS_SERVERS)

            Dim serverList(CType(serverArray.NumElements, Int32)) As DHCPDS_SERVER

            Dim current As IntPtr = serverArray.Servers

            For i As Int32 = 0 To CType(serverArray.NumElements - 1, Int32)
                serverList(i) = CType(Marshal.PtrToStructure(current, GetType(DHCPDS_SERVER)), DHCPDS_SERVER)

                Debug.WriteLine("ServerName: " & serverList(i).ServerName)
                Debug.WriteLine("ServerAddress: " & serverList(i).ServerAddress)
                Debug.WriteLine("ServerState: " & serverList(i).State)
                Debug.WriteLine("ServerVersion: " & serverList(i).Version)
                Debug.WriteLine("ServerDsLocation: " & serverList(i).DsLocation)
                Debug.WriteLine("ServerDsLocType: " & serverList(i).DsLocType)
                Debug.WriteLine("ServerFlags: " & serverList(i).Flags)
                Debug.WriteLine(vbCrLf & vbCrLf)

                Marshal.DestroyStructure(current, GetType(DHCPDS_SERVER))

                current = IntPtr.op_Explicit(current.ToInt64() + Marshal.SizeOf(serverList(i)))
            Next

            Marshal.FreeCoTaskMem(servers)

            Return serverList
        ElseIf retVal = 0 And servers = IntPtr.Zero Then
            Throw New Exception("No servers found.")
        Else
            Throw New Exception("Error code:  " & retVal.ToString)
        End If

    End Function


    Public Sub ListSubnetClients(ByVal ServerIP As String, ByVal SubnetIP As String)

        Dim Client_Array As DHCP_CLIENT_INFO_ARRAY
        Dim DHCP_Clients() As DHCP_CLIENT_INFO

        ' Why would you use int16 for a loop counter and for a pointer offset ?

        Dim i, j As Int16

        Dim pt As IntPtr

        Dim Read_Clients, Total_Clients As Int32
        Dim Error_Code As Int32
        Dim Rem_Handle As IntPtr
        Dim Scope_I As UInt32

        'Scope_I = "10.0.3.0"
        Scope_I = StringIPAddressToUInt32(SubnetIP) ' Dot2LongIP(SubnetIP)

        'Call dhcpsapi
        Error_Code = DhcpEnumSubnetClients(ServerIP, Scope_I, Rem_Handle, 65537, pt, Read_Clients, Total_Clients)

        Client_Array = Marshal.PtrToStructure(pt, GetType(DHCP_CLIENT_INFO_ARRAY))

        ReDim DHCP_Clients(Client_Array.NumElements - 1)

        Dim MacAddr As Net.NetworkInformation.PhysicalAddress
        For i = 0 To Client_Array.NumElements - 1
            pt = Marshal.ReadIntPtr(Client_Array.Clients, j)
            DHCP_Clients(i) = Marshal.PtrToStructure(pt, GetType(DHCP_CLIENT_INFO))

            'MacAddr = Net.NetworkInformation.PhysicalAddress.Parse(DHCP_Clients(i).ClientHardwareAddress.Data)
            'If HardwareAddress = "ec-30-91-d5-f0-a6" Then
            'System.Diagnostics.Debugger.Break()
            'ElseIf HardwareAddress.StartsWith("ec-30-91") Then
            'System.Diagnostics.Debugger.Break()
            'End If

            Dim IsClientReserved As Boolean
            If DHCP_Clients(i).ClientLeaseExpires.dwLowDateTime = 4294967295 And DHCP_Clients(i).ClientLeaseExpires.dwHighDateTime = 2147483647 Then
                IsClientReserved = True
            Else
                IsClientReserved = False
            End If

            Dim IsClientInActivelyReserved As Boolean
            If DHCP_Clients(i).ClientLeaseExpires.dwLowDateTime = 0 And DHCP_Clients(i).ClientLeaseExpires.dwHighDateTime = 0 Then
                IsClientInActivelyReserved = True
            Else
                IsClientInActivelyReserved = False
            End If

            Dim HardwareAddress As String = String.Format("{0:x2}-{1:x2}-{2:x2}-{3:x2}-{4:x2}-{5:x2}", Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 1), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 2), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 3), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 4), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 5))
            Dim NetShHardwareAddress As String = String.Format("{0:x2}{1:x2}{2:x2}{3:x2}{4:x2}{5:x2}", Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 1), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 2), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 3), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 4), Marshal.ReadByte(DHCP_Clients(i).ClientHardwareAddress.Data, 5))

            Debug.WriteLine("ClientComment: " & DHCP_Clients(i).ClientComment)
            Debug.WriteLine("ClientIpAddress: " & IPConvert(DHCP_Clients(i).ClientIpAddress))
            Debug.WriteLine("ClientHardwareAddress: " & HardwareAddress)
            Debug.WriteLine("ClientLeaseExpires: " & DHCP_Clients(i).ClientLeaseExpires.ConvertIntToDateTime)
            Debug.WriteLine("ClientName: " & DHCP_Clients(i).ClientName)
            Debug.WriteLine("OwnerHoost->HostName: " & DHCP_Clients(i).OwnerHost.HostName)
            Debug.WriteLine("OwnerHost->IpAddress: " & IPConvert(DHCP_Clients(i).OwnerHost.IpAddress))
            Debug.WriteLine("OwnerHost->NetBiosName: " & DHCP_Clients(i).OwnerHost.NetBiosName)
            Debug.WriteLine("SubnetMask: " & UInt32IPAddressToString(DHCP_Clients(i).SubnetMask))

            'ConvertTolease

            'IPConvert(DHCP_Clients(i).ClientIpAddress).ToString.Trim = "10.246.36.101" And
            If (Not IsClientReserved And Not IsClientInActivelyReserved) Then
                Dim MyArgs As String = vbNullString
                If Not IsNothing(DHCP_Clients(i).ClientComment) Then
                    Select Case DHCP_Clients(i).ClientComment.Trim
                        Case ""
                            MyArgs = "dhcp server 10.10.10.10 Scope " & SubnetIP.ToString.Trim & " Add reservedip " & IPConvert(DHCP_Clients(i).ClientIpAddress).ToString.Trim & " " & NetShHardwareAddress.ToString & " """ & DHCP_Clients(i).ClientName & """ ""Set for InfoBlox"" DHCP"
                        Case "This address is already in use"
                            HowManyClientsHaveBadAddresses += 1
                        Case Else
                            MyArgs = "dhcp server 10.10.10.10 Scope " & SubnetIP.ToString.Trim & " Add reservedip " & IPConvert(DHCP_Clients(i).ClientIpAddress).ToString.Trim & " " & NetShHardwareAddress.ToString & " """ & DHCP_Clients(i).ClientName & """ """ & DHCP_Clients(i).ClientComment.ToString.Trim & """ DHCP"
                    End Select
                Else
                    MyArgs = "dhcp server 10.10.10.10 Scope " & SubnetIP.ToString.Trim & " Add reservedip " & IPConvert(DHCP_Clients(i).ClientIpAddress).ToString.Trim & " " & NetShHardwareAddress.ToString & " """ & DHCP_Clients(i).ClientName & """ ""Set for InfoBlox"" DHCP"
                End If

                If MyArgs IsNot Nothing Then
                    Debug.WriteLine("netsh " & MyArgs)
                    Dim MyProcess As New Process
                    MyProcess = Process.Start("netsh", MyArgs)
                    MyProcess.WaitForExit()
                    MachinesThatWillChange &= DHCP_Clients(i).ClientName & "," & IPConvert(DHCP_Clients(i).ClientIpAddress) & "," & NetShHardwareAddress & vbCrLf
                    HowManyClientsAreNeedToBechanged += 1
                Else
                    MachinesThatWillNotChange &= DHCP_Clients(i).ClientName & "," & IPConvert(DHCP_Clients(i).ClientIpAddress) & "," & NetShHardwareAddress & "," & DHCP_Clients(i).ClientLeaseExpires.ConvertIntToDateTime & vbCrLf
                    Debug.WriteLine("This unit has a BAD Address - Skipping")
                End If

            Else
                MachinesThatWillNotChange &= DHCP_Clients(i).ClientName & "," & IPConvert(DHCP_Clients(i).ClientIpAddress) & "," & NetShHardwareAddress & "," & DHCP_Clients(i).ClientLeaseExpires.ConvertIntToDateTime & vbCrLf
                Debug.WriteLine("No NETSH command required")
                HowManyClientsAreAlreadyReserved += 1
            End If


            Debug.WriteLine(vbCrLf & vbCrLf)

            pt = IntPtr.Zero
            j = j + 4

            HowManyClients += 1
        Next i

    End Sub

    Private Sub ConvertTolease(ByVal DHCP_Clients() As DHCP_CLIENT_INFO, ByVal I As Integer)
        If IPConvert(DHCP_Clients(i).ClientIpAddress).ToString.Trim = "10.10.10.10" And False Then
            Dim DHCPv4 As New DHCP_CLIENT_INFOV4
            DHCPv4.bClientType = DHCP_CLIENT_TYPE.CLIENT_TYPE_BOTH
            DHCPv4.ClientComment = DHCP_Clients(i).ClientComment
            DHCPv4.ClientHardwareAddress = DHCP_Clients(i).ClientHardwareAddress
            DHCPv4.ClientIpAddress = DHCP_Clients(i).ClientIpAddress
            DHCPv4.ClientLeaseExpires = DHCP_Clients(i).ClientLeaseExpires
            DHCPv4.ClientName = DHCP_Clients(i).ClientName
            DHCPv4.OwnerHost = DHCP_Clients(i).OwnerHost
            DHCPv4.SubnetMask = DHCP_Clients(i).SubnetMask

            'Dim MyPtrr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(New DHCP_CLIENT_INFOV4))
            'DHCPv4.ClientLeaseExpires.SetToReserved()
            'DHCPv4.ClientLeaseExpires.SetToInfinte()
            'Marshal.StructureToPtr(DHCPv4, MyPtrr, False)
            'Debug.WriteLine("Lease Updated: " & DhcpSetClientInfo(ServerIP, MyPtrr))
            'Debug.WriteLine("Lease Updated: " & DhcpSetClientInfoV4(ServerIP, MyPtrr))

        End If
    End Sub

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    '''

    Public Structure DHCP_SEARCH_INFO
        Dim DHCPSearchInfoType As Integer
        Dim DHCPIPAddress As UInt32
    End Structure

    Private Enum DHCP_SEARCH_INFO_TYPE
        DhcpClientIpAddress
        DhcpClientHardwareAddress
        DhcpClientName
    End Enum
    Public Function GetClientInfo(ByVal serverIP As String, ByVal clientIP As String)
        Dim DHCPResult As UInt32 = 0
        Try
            Dim searchInfo As New DHCP_SEARCH_INFO
            Dim searchInfoType As DHCP_SEARCH_INFO_TYPE = DHCP_SEARCH_INFO_TYPE.DhcpClientIpAddress
            searchInfo.DHCPSearchInfoType = searchInfoType
            searchInfo.DHCPIPAddress = Dot2LongIP(clientIP)
            Dim hClientInfo As IntPtr

            DHCPResult = DhcpGetClientInfo(serverIP, searchInfo, hClientInfo)

            If DHCPResult = 0 And Not hClientInfo = IntPtr.Zero Then
                Dim clientInfo As DHCP_CLIENT_INFO = Marshal.PtrToStructure(hClientInfo, GetType(DHCP_CLIENT_INFO))
                Debug.WriteLine("ClientInfo->clientInfo.ClientHardwareAddress " & String.Format("{0:x2}-{1:x2}-{2:x2}-{3:x2}-{4:x2}-{5:x2}", Marshal.ReadByte(clientInfo.ClientHardwareAddress.Data), Marshal.ReadByte(clientInfo.ClientHardwareAddress.Data, 1), Marshal.ReadByte(clientInfo.ClientHardwareAddress.Data, 2), Marshal.ReadByte(clientInfo.ClientHardwareAddress.Data, 3), Marshal.ReadByte(clientInfo.ClientHardwareAddress.Data, 4), Marshal.ReadByte(clientInfo.ClientHardwareAddress.Data, 5)))
                Debug.WriteLine("ClientInfo->clientInfo.ClientIpAddress " & IPConvert(clientInfo.ClientIpAddress))
                Debug.WriteLine("ClientInfo->clientInfo.ClientLeaseExpires " & clientInfo.ClientLeaseExpires.ConvertIntToDateTime)
                Debug.WriteLine("ClientInfo->clientInfo.ClientName " & clientInfo.ClientName)
                Debug.WriteLine("ClientInfo->clientInfo.OwnerHost->HostName " & clientInfo.OwnerHost.HostName)
                Debug.WriteLine("ClientInfo->clientInfo.OwnerHost->IpAddress " & IPConvert(clientInfo.OwnerHost.IpAddress))
                Debug.WriteLine("ClientInfo->clientInfo.OwnerHost->NetBiosName " & clientInfo.OwnerHost.NetBiosName)
                Debug.WriteLine("ClientInfo->clientInfo.SubnetMask " & clientInfo.SubnetMask)
                Debug.WriteLine("ClientInfo->clientInfo.ClientComment " & clientInfo.ClientComment)
                Return (clientInfo)
            End If
            Return Nothing
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Return Nothing
        End Try
    End Function

    Private Sub EnumAll()
        Dim ListOfSubnets As String() = GetSubnets(ServerIPAddress)
        For Each Subnet As String In ListOfSubnets
            If Subnet = "0.0.0.0" Then
                Exit Sub
            End If
            If Subnet = "10.246.10.0" Or True Then
                ListSubnetClients(ServerIPAddress, Subnet)
            End If
        Next

    End Sub

    Public Sub CompareFirewallRules()
        Dim FileContents = GetFileContents("\\fileshare1\ISStaff\Network\KDB\Config\EMC-ASA.txt")
        Dim h As System.Net.IPHostEntry = System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName)

        For Each IPString As System.Net.IPAddress In h.AddressList
            'Debug.WriteLine(IPString.ToString)
            If InStr(FileContents, IPString.ToString) > 0 Then
                'Debug.WriteLine(IPString.ToString & " - IP Found in Firewall Rules")
                TextBox1.Text += IPString.ToString & " - IP Found in Firewall Rules"
            End If
        Next
        If TextBox1.Text = vbNullString Then TextBox1.Text = "No Firewall Rules Found!"
    End Sub

    Public Shared Function StringIPAddressToUInt32(ByVal ip_string As String) As UInteger
        Dim IpA As Net.IPAddress = System.Net.IPAddress.Parse(ip_string)
        Dim ip_bytes As Byte() = IpA.GetAddressBytes()
        Dim ip_uint As UInteger = CUInt(ip_bytes(0)) << 24
        ip_uint += CUInt(ip_bytes(1)) << 16
        ip_uint += CUInt(ip_bytes(2)) << 8
        ip_uint += CUInt(ip_bytes(3))
        Return ip_uint
    End Function

    Public Shared Function UInt32IPAddressToString(ByVal ipAddress As UInteger) As String
        Dim ipA As New Net.IPAddress(ipAddress)
        Dim sIp As String() = ipA.ToString().Split("."c)

        Return sIp(3) & "." & sIp(2) & "." & sIp(1) & "." & sIp(0)
    End Function

    Public Function Dot2LongIP(ByVal DottedIP As String) As Integer
        Dim arrDec() As String
        Dim i As Integer
        Dim intResult As Integer
        If DottedIP = "" Then
            Dot2LongIP = 0
        Else
            arrDec = DottedIP.Split(".")
            For i = arrDec.Length - 1 To 0 Step -1
                intResult = intResult + ((Int(arrDec(i)) Mod 256) * Math.Pow(256, 3 - i))
            Next
            Dot2LongIP = intResult
        End If
    End Function

    Public Function IPConvert(ByVal IPAddress As Object) As Object

        Dim x As Integer
        Dim Pos As Integer
        Dim PrevPos As Integer
        Dim Num As Integer

        If IsNumeric(IPAddress) Then
            IPConvert = "0.0.0.0"
            For x = 1 To 4
                Num = Int(IPAddress / 256 ^ (4 - x))
                IPAddress = IPAddress - (Num * 256 ^ (4 - x))
                If Num > 255 Then
                    IPConvert = "0.0.0.0"
                    Exit Function
                End If

                If x = 1 Then
                    IPConvert = Num
                Else
                    IPConvert = IPConvert & "." & Num
                End If
            Next
        ElseIf UBound(Split(IPAddress, ".")) = 3 Then
            '        On Error Resume Next
            For x = 1 To 4
                Pos = InStr(PrevPos + 1, IPAddress, ".", 1)
                If x = 4 Then Pos = Len(IPAddress) + 1
                Num = Int(Mid(IPAddress, PrevPos + 1, Pos - PrevPos - 1))
                If Num > 255 Then
                    IPConvert = "0"
                    Exit Function
                End If
                PrevPos = Pos
                IPConvert = ((Num Mod 256) * (256 ^ (4 - x))) + IPConvert
            Next
        End If

    End Function

    Public Function GetFileContents(ByVal FullPath As String, Optional ByRef ErrInfo As String = "") As String

        Dim strContents As String
        Dim objReader As System.IO.StreamReader
        Try

            objReader = New System.IO.StreamReader(FullPath)
            strContents = objReader.ReadToEnd()
            objReader.Close()
            Return strContents
        Catch Ex As Exception
            ErrInfo = Ex.Message
        End Try
    End Function
End Class
#include <GuiConstants.au3>
#include <Misc.au3>
#include <GuiconstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListBoxConstants.au3>
#include <SendMessage.au3>

#NoTrayIcon
Opt("GUICloseOnESC", 0)
Opt("GUIOnEventMode", 1)
Opt("WinWaitDelay", 0)

;Global Const $WM_SYSCOMMAND = 0x0112
;Global Const $LBS_NOINTEGRALHEIGHT = 0x1000
Global Const $SC_MOVE = 0xF010
Global Const $SC_SIZE = 0xF000
Global Const $SC_CLOSE = 0xF060

;ShellHook notification codes:
Global Const $HSHELL_WINDOWCREATED = 1;
Global Const $HSHELL_WINDOWDESTROYED = 2;
Global Const $HSHELL_ACTIVATESHELLWINDOW = 3;
Global Const $HSHELL_WINDOWACTIVATED = 4;
Global Const $HSHELL_GETMINRECT = 5;
Global Const $HSHELL_REDRAW = 6;
Global Const $HSHELL_TASKMAN = 7;
Global Const $HSHELL_LANGUAGE = 8;
Global Const $HSHELL_SYSMENU = 9;
Global Const $HSHELL_ENDTASK = 10;
Global Const $HSHELL_ACCESSIBILITYSTATE = 11;
Global Const $HSHELL_APPCOMMAND = 12;
Global Const $HSHELL_WINDOWREPLACED = 13;
Global Const $HSHELL_WINDOWREPLACING = 14;
Global Const $HSHELL_RUDEAPPACTIVATED = 32772;
Global Const $HSHELL_FLASH = 32774;

Global $bHook = 1
;GUI stuff:

Global $iGuiW = 50, $iGuiH = 50, $sTitle = "Jabber Monitor by Nicholas Hall", $aBtnText[2] = ["START", "STOP"]
$hGui = GUICreate($sTitle, $iGuiW, $iGuiH, -1, 0, $WS_POPUP+$WS_BORDER, $WS_EX_TOPMOST)
GUISetOnEvent($GUI_EVENT_CLOSE, "SysEvents")
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "SysEvents")
GUIRegisterMsg($WM_SYSCOMMAND, "On_WM_SYSCOMMAND")
$cBtnMini = GUICtrlCreateButton("v", $iGuiW-$iGuiH, 0, $iGuiH/2, $iGuiH/2)
GUICtrlSetOnEvent(-1, "CtrlEvents")
GUICtrlSetTip(-1, "Minimize")
$cBtnClose = GUICtrlCreateButton("X", $iGuiW-$iGuiH/2, 0, $iGuiH/2, $iGuiH/2)
GUICtrlSetOnEvent(-1, "CtrlEvents")
GUICtrlSetTip(-1, "Exit")
$cBtnHook = GUICtrlCreateButton("", $iGuiW-$iGuiH, $iGuiH/2, $iGuiH, $iGuiH/2)
GUICtrlSetData(-1, $aBtnText[$bHook])
GUICtrlSetTip(-1, "Hook/Unhook Jabber")
GUICtrlSetOnEvent(-1, "CtrlEvents")
;$cList = GUICtrlCreateList("", 0, 0, $iGuiW-$iGuiH-1, $iGuiH, $LBS_NOINTEGRALHEIGHT+$WS_VSCROLL)
GUICtrlSetOnEvent(-1, "CtrlEvents")

;Hook stuff:
GUIRegisterMsg(RegisterWindowMessage("SHELLHOOK"), "HShellWndProc")
ShellHookWindow($hGui, $bHook)


GUISetState()

While 1
    Sleep(1000)
WEnd

Func SysEvents()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_PRIMARYDOWN
            ;CTRL + Left click to drag GUI
            If _IsPressed("11") Then
                DllCall("user32.dll", "int", "ReleaseCapture")
                DllCall("user32.dll", "int", "SendMessage", "hWnd", $hGui, "int", 0xA1, "int", 2, "int", 0)
            EndIf
    EndSwitch
EndFunc
Func CtrlEvents()
    Switch @GUI_CtrlId
        Case $cBtnMini
            GUISetState(@SW_MINIMIZE)
        Case $cBtnClose
            _SendMessage($hGui, $WM_SYSCOMMAND, $SC_CLOSE, 0)
        Case $cBtnHook
            $bHook = BitXOR($bHook, 1)
            ShellHookWindow($hGui, $bHook)
            GUICtrlSetData($cBtnHook, $aBtnText[$bHook])
    EndSwitch   
EndFunc
Func HShellWndProc($hWnd, $Msg, $wParam, $lParam)
    Switch $wParam
        Case $HSHELL_FLASH
            MsgPrint("Window flash: " & $lParam & " (" & WinGetTitle($lParam) & ")")
            MsgPrint(ProcessGetName(WinGetProcess($lParam)))
            if ProcessGetName(WinGetProcess($lParam)) = "CiscoJabber.exe" Then
               WinActivate($lParam)
            endif
            ;if WinGetTitle($lParam) = "Conversations" Then
            ;EndIf
        Case Else
            ;MsgPrint("Unknown ShellHook message: " & $wParam & " , " & $lParam)
    EndSwitch
 EndFunc
 Func ProcessGetName($PId)
    If IsNumber($PId) = 0 Then
        SetError(2)
    ElseIf $PId > 9999 Then
        SetError(1)
    Else
        Local $PList = ProcessList()
        Local $i = 1
        Local $ProcessName = ""

        While $i <= $PList[0][0] And $ProcessName = ""
            If $PList[$i][1] = $PId Then
                $ProcessName = $PList[$i][0]
            Else
                $i = $i + 1
            EndIf
        WEnd
        Return $ProcessName
    EndIf
EndFunc ;==>ProcessGetName
;register/unregister ShellHook
Func ShellHookWindow($hWnd, $bFlag)
    Local $sFunc = 'DeregisterShellHookWindow'
    If $bFlag Then $sFunc = 'RegisterShellHookWindow'
    Local $aRet = DllCall('user32.dll', 'int', $sFunc, 'hwnd', $hWnd)
    MsgPrint($sFunc & ' = ' & $aRet[0])
    Return $aRet[0]
EndFunc
Func MsgPrint($sText)
    ConsoleWrite($sText & @CRLF)
    ;GUICtrlSendMsg($cList, $LB_SETCURSEL, GUICtrlSendMsg($cList, $LB_ADDSTRING, 0, $sText), 0)
EndFunc
;register window message
Func RegisterWindowMessage($sText)
    Local $aRet = DllCall('user32.dll', 'int', 'RegisterWindowMessage', 'str', $sText)
    Return $aRet[0]
EndFunc
Func On_WM_SYSCOMMAND($hWnd, $Msg, $wParam, $lParam)
    Switch BitAND($wParam, 0xFFF0)
        Case $SC_MOVE, $SC_SIZE
        Case $SC_CLOSE
            ShellHookWindow($hGui, 0)
            Return $GUI_RUNDEFMSG
            ;Exit
    EndSwitch
EndFunc