Thursday, March 3, 2011

HttpWebRequest AddRange with Long values

HttpWebRequest contains a method called AddRange which is very useful when we want to download a file in segments or want to resume the download from where it was stopped previously. But HttpWebRequest.AddRange has one drawback, the parameters for range of bytes is in integer which means only range upto approximately 2 GB is allowed. So we cannot use this method if we want to use it for downloading files in Range greater than 2 GB. If we try to add value greater than “2147483647”  we will get following exception.

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.

So the solution for this problem is to extend the AddRange method with support for long parameters. HttpWebRequest has a private function AddRange which have three string parameters which we can use with Reflection classes.

Private Function AddRange(ByVal rangeSpecifier As String, ByVal fromValue As String, ByVal toValue As String) As Boolean

So now we can use Reflection and add two method with parameter in Long to allow larger value.

Imports System.Reflection
Imports System.Net
Imports System.Runtime.CompilerServices 

Public Module MyModule
#Region "HttpWebRequest AddRange"

    <Extension()> _
    Public Sub AddRange(ByVal request As HttpWebRequest, ByVal from As Long, ByVal [to] As Long)
        Dim info As MethodInfo = Nothing
        Dim methods() As MethodInfo = GetType(Net.HttpWebRequest).GetMethods(BindingFlags.Instance Or BindingFlags.NonPublic)

        For Each mi As MethodInfo In methods
            If mi.Name = "AddRange" Then
                info = mi
                Exit For
            End If
        Next
        If info IsNot Nothing Then
            Dim parameters(2) As Object
            parameters(0) = "bytes"
            parameters(1) = from.ToString
            parameters(2) = [to].ToString
            info.Invoke(request, parameters)
        End If
    End Sub

    <Extension()> _
    Public Sub AddRange(ByVal request As HttpWebRequest, ByVal from As Long)
        Dim info As MethodInfo = Nothing
        Dim methods() As MethodInfo = GetType(Net.HttpWebRequest).GetMethods(BindingFlags.Instance Or BindingFlags.NonPublic)
        For Each mi As MethodInfo In methods
            If mi.Name = "AddRange" Then
                info = mi
                Exit For
            End If
        Next

        If info IsNot Nothing Then
            Dim parameters(2) As Object
            parameters(0) = "bytes"
            parameters(1) = from.ToString
            parameters(2) = String.Empty
            info.Invoke(request, parameters)
        End If
    End Sub
#End Region
End Module

After adding above code in the project, two new HttpWebRequest.AddRange method will get added with long parameter.

HttpWebRequest.AddRange(byval from as Long)
HttpWebRequest.AddRange(byval from as Long,byval to as Long)

Now you can use this methods as shown in following code

Dim startPosition As Long = Integer.MaxValue
Dim endPosition As Long = startPosition + 1000
Dim request As HttpWebRequest = WebRequest.Create("Url")
request.AddRange(startPosition, endPosition)

Tuesday, March 1, 2011

Review: Crypto Obfuscator for .NET 2011

All .NET codes written in .Net language when compiled are converted to MSIL. But there are many decompilers available through which we can reverse engineer the code, which means software licensing code, copy protection mechanisms, proprietary business logic, passwords, etc. get accessible to everyone. So to protect from code from misuse Obfuscator are available that provides for seamless renaming of symbols in assemblies as well as other tricks to foil decompilers. Properly applied obfuscation can increase the protection against decompilation by many orders of magnitude, while leaving the application intact.
There are many .NET obfuscators available today. Crypto Obfuscator For .Net is one of the great obfuscator which supports all versions of the .Net framework from v1.0 to v4.0. It also supports the .Net Compact Framework, Silverlight and XNA. It can protect assemblies created with any .Net language including C#, VB.Net, Managed C++, J#, etc.
Following are few key features available in “Crypto Obfuscator for .NET 2011”
Symbol Renaming – Crypto Obfuscator renames all your class, field, method, properties, methods, parameter and generic parameter names to totally different strings. It is impossible to determine the original names from the new names. This makes it impossible for someone to try to determine the purpose or functionality of the renamed entity from its name.
String Encryption – Literal strings often contain sensitive information such as login information, passwords, SQL queries, algorithm parameters. They also facilitate reverse-engineering of your .Net code. Crypto Obfuscator solves all these issues by encrypting all literal strings in your .Net code.
Anti-Reflection Protection – Many decompilers, dissassemblers and memory dumpers use Reflection to extract information about a .Net assembly. Crypto Obfuscator can modify the assembly in such a way that such tools will fail when trying to work on your assembly.
Anti-Decompiler Protection – Advanced decompilers such as the freely available .Net Reflector are your enemy in the battle against the hackers, crackers and competitors. Crypto Obfuscator can modify your assembly in such a way that such tools fail to work on your assembly – many times they are not even able to open your assembly, let alone examine it.
Advanced Tamper Detection – Crypto Obfuscator can perform strong name verification of the assembly itself even if strong-name verification has been turned OFF on the machine on which the assembly is running or if the assembly has been registered in the verification ’skip-list’ – this is typically done by hackers or crackers. Furthermore, the strong name verification is done using the original key used to sign the assembly when it was processed by Crypto Obfuscator. Thus, strong name verification fails even if the key is removed or replaced – again something typically done by hackers or crackers.
Advanced Anti-Debug + Anti-Tracer Protection – Crypto Obfuscator’s performs more than 10 advanced heuristic tests to detect if your software is running under a debugger or tracer. If detected, an exception is throw and your software will terminate. Both managed as well as native/unmanaged debuggers (including advanced debuggers such as OllyDbg) are detected. This provides a strong defense against crackers and hackers trying to debug or trace your software for various malicious purposes.
Advanced Overload Renaming – Crypto Obfuscator can also rename fields or methods with different signatures to the same name. For example two fields having types int and boolean will be given the same name. Similarly two methods will different parameters will be given the same name. In the case of methods, the method return type is also used in the signature even though high-level languages such as C# and VB.Net do not support overloading by return type. The .Net runtime is able to differentiate between the fields/methods without any problem since the signatures are different. Needless to say, this scheme makes it even harder to reverse-engineer your code.
Control Flow Obfuscation – Many advanced decompilers can reconstruct the code in your methods including the exact structure of your loops, if-else statements, method calls, try-catch blocks, etc. This makes it very easy to revere-engineer your code. Crypto Obfuscator changes the structure of your code into spaghetti code while maintaining 100% the logic and output of the code. The result is that decompilers are unable to reconstruct the code structure and most of the times they crash while trying to do so.
Watermarking – Crypto Obfuscator can embed watermark strings into your deployed assemblies. This can be used to track each assembly instance – this is commonly used for licensing by embedding user name and license codes as watermarks to deter license violations. The watermarks embedded in the assembly can be used in literal strings and constants to be used in your UI, message boxes, etc.
ILDASM Protection – ILDASM (Microsoft IL Dissassembler) is a free tool to disassembly any .Net assembly into MSIL (Microsoft Intermediate Language). Crypto Obfuscator can modify the assembly in such a way that ILDASM refuses to disassemble the assembly.
Metadata Reduction – Crypto Obfuscator can remove unnecessary or redundant information such as parameter names, property/event placeholders, etc from your .Net assembly . During symbol-renaming, Crypto Obfuscator will often assign extremely short (often single-character names) to your classes, fields, methods, etc. All these features can reduce the size of your .Net assembly considerably.

Sunday, January 30, 2011

Nested menuitem in WPF ToolBar

One of the most common question asked on various WPF Forums is “How can we have Submenu or nested menuitems in WPF Toolbar”. Toolbar in WPF doesn’t show sub menuitems on mouseover or click event. So following code for Toolbar doesn’t work.

        <ToolBar Name="ToolBar1" Height="25">
           
<!-- Regular Items -->
           
<Button Content="Item A"/>
            <
Button Content="Item B"/>
           
<!-- SubItems Menu For Special Items -->
           
<MenuItem Header="Special Items">
                <
MenuItem Header="Special Item A" />
                <
MenuItem Header="Special Item B" />
            </
MenuItem>
        </
ToolBar>

So I decide to create my own custom control which Inherits MenuItem and can handle mouseover or click event. MenuItem has a property IsSubMenuOpen which we can use to open submenu for MenuItem. Another useful property is StayOpenOnClick, which if we set to False then whenever user click outside of MenuItem, submenu will automatically get closed.

Imports System.Windows.Controls.Primitives

Public Class ToolBarMenuItem
Inherits System.Windows.Controls.MenuItem

Shared Sub New()
'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
'This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(GetType(ToolBarMenuItem), New FrameworkPropertyMetadata(GetType(ToolBarMenuItem)))
End Sub

Public Enum
PlacementMode
Bottom = 0
Top = 1
Right = 2
Left = 3
End Enum

Public Shared ReadOnly
SubMenuPlacementModeProperty As DependencyProperty = DependencyProperty.Register("SubMenuPlacementMode", GetType(PlacementMode), GetType(ToolBarMenuItem), New FrameworkPropertyMetadata(PlacementMode.Bottom))
Public Property SubMenuPlacementMode As PlacementMode
Get
Return
GetValue(SubMenuPlacementModeProperty)
End Get
Set
(ByVal value As PlacementMode)
SetValue(SubMenuPlacementModeProperty, value)
End Set
End Property

Private Sub
ToolBarMenuItem_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Click
Me.IsSubmenuOpen = False
End Sub

Private Sub
ToolBarMenuItem_MouseLeave(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Me.MouseLeave
Me.IsSubmenuOpen = False
End Sub

Private Sub
ToolBarMenuItem_PreviewMouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
If Me.IsSubmenuOpen = False Then
Me
.IsSubmenuOpen = True
Me
.StaysOpenOnClick = False
End If
End Sub
End Class

We also need to add a XAML Code which contain Style for our custom control which is available in the source at the end of the article.

We can use the above custom control in following way.


<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:ToolBarMenuItemDemo"
Title="NestedToolBarItem Demo" Height="350" Width="525" Background="Aquamarine">
<
Grid VerticalAlignment="Top">
<
ToolBar Name="ToolBar1" Height="25" >
<!--Regular Items-->
<Button Content="Item A"/>
<
Button Content="Item B"/>
<!--SubItems Menu For Special Items-->
<my:ToolBarMenuItem Header="Special Items" VerticalContentAlignment="Center" SubMenuPlacementMode="Bottom">
<
MenuItem Header="Special Item 1" />
<
MenuItem Header="Special Item 2" />
</
my:ToolBarMenuItem>
</
ToolBar>
</
Grid>
</
Window>

Download Source Code

Thursday, October 28, 2010

Comparing two Images

Few days back I was looking to compare two image and find difference between them in WPF. After searching and reading few articles I realized that comparing two image and find difference is much easier using methods of Graphics Class (i.e. using GDI+).  So I decide to compare and find difference between two images using GDI+ and then convert into a BitmapImage. For faster comparing we have to use pointer and write code in unsafe block. As pointer and unsafe block are not supported in VB.NET so comparing code has to be in C# or C++.

CompareImage1

CompareImage2

Code

public static Bitmap BitmapDifference(Bitmap first, Bitmap second)
{
BitmapData data1 = first.LockBits(new Rectangle(0, 0, first.Width, first.Height), ImageLockMode.ReadWrite, first.PixelFormat);
BitmapData data2 = second.LockBits(new Rectangle(0, 0, second.Width, second.Height), ImageLockMode.ReadWrite, second.PixelFormat);
Bitmap bmpresult = new Bitmap(first.Width, first.Height);

BitmapData data3 = bmpresult.LockBits(new Rectangle(0, 0, bmpresult.Width, bmpresult.Height), ImageLockMode.ReadWrite, first.PixelFormat);

unsafe
{
int remain1 = data1.Stride - data1.Width * 3;
int remain2 = data2.Stride - data2.Width * 3;
int remain3 = data3.Stride - data3.Width * 3;

byte* ptr1 = (byte*)data1.Scan0;
byte* ptr2 = (byte*)data2.Scan0;
byte* ptr3 = (byte*)data3.Scan0;

for (int i = 0; i < first.Height; i++)
{
for (int j = 0; j < first.Width * 3; j++)
{
byte ac = (byte)(Math.Abs(ptr1[0] - ptr2[0]));
if (ac < 15)
{
//Change Pixel Color to Black for all the pixel whose value is
ptr3[0] = 0;
}
else
{
ptr3[0] = ac;
}
ptr1++;
ptr2++;
ptr3++;
}
ptr1 += remain1;
ptr2 += remain2;
ptr3 += remain3;
}
}
first.UnlockBits(data1);
second.UnlockBits(data2);
bmpresult.UnlockBits(data3);

bmpresult.MakeTransparent(Color.Black);
return bmpresult;
}
Above function will return the difference between two images using following code 

public void GetDifference()
{
Bitmap bmp1 = new Bitmap(@"C:\1.jpg");
Bitmap bmp2 = new Bitmap(@"C:\2.jpg");
Bitmap result = BitmapDifference(bmp1, bmp2);
result.Save(@"C:\new.jpg");
}

Sunday, August 22, 2010

Sender Property of MailMessage

Many of the time we need to send email on behalf of someone else. For Example, all the employees in the company sending email on behalf of the company. Another common example is invitation email send to the friends by the website on behalf of its user. We have two properties available in MailMessage Class in .NET which are From and Sender which by definition looks very similar but they are different.

When sending a email From Property will contain the Email Address on behalf of whom we are sending the email and Sender property will be the person who is sending the email. Sender is an optional property and is used when we need to send email on behalf of someone else. When we are sending an email  which require authentication (i.e. Credentials) and our MailMessage has Sender property assigned, then Username of NetworkCredential will be same as Sender Email Address.  Below is the code of how we can use it.

Dim msg As New MailMessage
msg.From = New MailAddress("from@domain.com")
msg.Sender = New MailAddress("sender@domain.com")
msg.Subject = "Test Email"
msg.Body = "Hello World. This is a Test Email"

Dim client As New SmtpClient("Host Address", "Port Number")
client.Credentials = New NetworkCredential(msg.Sender.Address, "Password")
client.Send(msg)

Note: Although I have not tested on other SSL Enabled email provider but Sender Property doesn’t work with Gmail. So I think if Smtp Server requires SSL then Sender Property might not work.

Saturday, February 6, 2010

Print Multiple-layered column header in datagridview

Recently someone had asked a question on a forum of “How to create multiple-layered column header in datagridview and also have a print preview of it in vb.net”. Creating multiple-layered column header is available on “Windows Forms Data Controls and Data Binding Forum FAQ” on MSDN Forum but the code is provided in VC#. So I have created a code in VB.NET through which multiple-layered column header can be created as well we can have print preview of it.

Multiple-layered Column Header DatagridView

Datagridview1

To create a datagridview with multiple column header we have to handle the DataGridView.Painting and DataGridView.CellPainting events, so that we can draw header as we want. We can use PrintPage event of PrintDocument to build the page for printing.

Print Preview of Multi-layered Column Datagridview

Datagridview2

Code for Datagridview

Imports System.Drawing.Printing
Public Class DemoForm
Dim names() As String = {"Microsoft", "Adobe", "SUN"}
Dim WithEvents MyPrintDocument As New PrintDocument
Private Sub DemoForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.DataGridView1.Columns.Add("clmProduct1", "Product")
Me.DataGridView1.Columns.Add("clmPrice1", "Price")
Me.DataGridView1.Columns.Add("clmProduct2", "Product")
Me.DataGridView1.Columns.Add("clmPrice2", "Price")
Me.DataGridView1.Columns.Add("clmProduct3", "Product")
Me.DataGridView1.Columns.Add("clmPrice3", "Price")
DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
DataGridView1.ColumnHeadersHeight = DataGridView1.ColumnHeadersHeight * 2
DataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter
End Sub
Private Sub
DataGridView1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles DataGridView1.Paint
For i As Integer = 0 To 5 Step 2
Dim rec As Rectangle = DataGridView1.GetCellDisplayRectangle(i, -1, True)
rec.X += 1
rec.Y += 1
rec.Width = rec.Width * 2 - 2
rec.Height = rec.Height / 2 - 2
e.Graphics.FillRectangle(New SolidBrush(Me.DataGridView1.ColumnHeadersDefaultCellStyle.BackColor), rec)
Dim format As New StringFormat
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(names(i / 2), DataGridView1.ColumnHeadersDefaultCellStyle.Font, New SolidBrush(DataGridView1.ColumnHeadersDefaultCellStyle.ForeColor), rec, format)
Next
End Sub
Private Sub
DataGridView1_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
If e.RowIndex = -1 And e.ColumnIndex <> -1 Then
e.PaintBackground(e.CellBounds, False)
Dim rec As Rectangle = e.CellBounds
rec.Y += e.CellBounds.Height / 2
rec.Height = e.CellBounds.Height / 2
e.PaintContent(rec)
e.Handled = True
End If
End Sub

Private Sub
btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Dim dg As New PrintPreviewDialog
dg.Document = MyPrintDocument
dg.ShowDialog()
End Sub

Private Sub
PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles MyPrintDocument.PrintPage
Dim leftMargin As Integer = 10
Dim position As Integer = leftMargin
Dim yPosition As Integer
Dim
height As Integer = DataGridView1.ColumnHeadersHeight / 2
yPosition = 0
For i As Integer = 0 To 5 Step 2
Dim totalWidth As Double = DataGridView1.Columns(i).Width + DataGridView1.Columns(i + 1).Width
e.Graphics.FillRectangle(New SolidBrush(Color.LightGray), New Rectangle(position, yPosition, totalWidth, height))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(position, yPosition, totalWidth, height))
Dim format As New StringFormat
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(names(i / 2), New Font("Arial", 12, FontStyle.Bold), Brushes.Black, position, yPosition)
position = position + totalWidth
Next

position = leftMargin
yPosition = DataGridView1.ColumnHeadersHeight / 2
For Each dr As DataGridViewColumn In DataGridView1.Columns
Dim totalWidth As Double = dr.Width
e.Graphics.FillRectangle(New SolidBrush(Color.LightGray), New Rectangle(position, yPosition, totalWidth, height))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(position, yPosition, totalWidth, height))
e.Graphics.DrawString(dr.HeaderText, New Font("Arial", 12, FontStyle.Bold), Brushes.Black, position, yPosition)
position = position + totalWidth
Next

For Each
dr As DataGridViewRow In DataGridView1.Rows
position = leftMargin
yPosition = yPosition + DataGridView1.ColumnHeadersHeight / 2
For Each dc As DataGridViewCell In dr.Cells
Dim totalWidth As Double = dc.OwningColumn.Width
e.Graphics.FillRectangle(New SolidBrush(Color.White), New Rectangle(position, yPosition, totalWidth, height))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(position, yPosition, dc.OwningColumn.Width, height))
e.Graphics.DrawString(dc.Value, New Font("Arial", 12, FontStyle.Regular), Brushes.Black, position, yPosition)
position = position + totalWidth
Next
Next
End Sub

End Class

Sunday, January 3, 2010

Gaurav Khanna – Microsoft MVP 2010

I am proud to announce that I am awarded Microsoft MVP on January 01, 2010 for providing technical expertise in Visual Basic technical communities for past one year.

About the MVP Award Program (As described by microsoft)

Since the early 1990s, Microsoft has recognized the inspiring activities of MVPs around the world with the MVP Award. MVPs freely share their deep knowledge, real-world experience, and impartial, objective feedback to help people enhance the way they use technology. Of more than 100 million users who participate in technology communities, around 4,000 are recognized as Microsoft MVPs.

MVPs make exceptional contributions to technical communities, sharing their passion, knowledge, and know-how. Meanwhile, because MVPs hear the opinions and needs of many others in the technical community, they are well-placed to share highly focused feedback with Microsoft.

MVPs are independent experts who are offered a close connection with people at Microsoft. To acknowledge MVPs’ leadership and provide a platform to help support their efforts, Microsoft often gives MVPs early access to Microsoft products, as well as the opportunity to pass on their highly targeted feedback and recommendations about product design, development, and support.

Email from Microsoft

Dear Gaurav Khanna,

Congratulations! We are pleased to present you with the 2010 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Visual Basic technical communities during the past year.

The Microsoft MVP Award provides us the unique opportunity to celebrate and honor your significant contributions and say “Thank you for your technical leadership.”

Toby Richards
General Manager
Community & Online Support

List of MVPs announced from South Asia in January 2010 can be found on following link

http://blogs.technet.com/southasiamvp/archive/2010/01/03/new-mvps-announced-january-2010.aspx