Pixytech

Lead Architect  •  Full Stack Engineer

Author: Pixytech

  • SQL Server Discovery

    The objective of this article is to discover the presence of Microsoft SQL Server  across subnet. There are API’s to enumerate SQL Server instances in single subnet (Win32 API : NetServerEnum ) and Microsoft enterprise manger uses this API to populate the list of SQL server available in current subnet. The API NetServerEnum broadcast UDP packets in the network and SQL server respond the message by sending their details. Since UDP packets can’t cross subnets and hence it will only return the partial list in particular domain.

    I was working on project where I have to find if on given IP or IP range , any sql server exists or not and if sql server exists I need to find the instance names. etc.

    The SQL server discovery module is hosted on web server and will be accessed by Silverlight application via WCF service. The code can be used to determine if SQL server is running or not (Before trying to connect) to build more responsive applications.

    The code sends the UDP packet (point to point access) directly to provide ip address on port 1434 and revived the data back from machines.

    If server is there the another function connects on TCP channel on TCP IP port to extract Sql server Netlib version.

    public class SqlServerInfo
    {
        public string ServerName { get; private set; }
        public string IpAddress { get; private set; }
        public string InstanceName { get; private set; }
        public bool IsClustered { get; private set; }
        public string Version { get; private set; }
        public int tcpPort { get; private set; }
        public string NamedPipe { get; private set; }
        public string Rpc { get; private set; }
        public bool IsActive { get; private set; }
    
        static public List<SqlServerInfo> DiscoverSQLServer(string[] possibleIPs, bool requiredDeepCheck)
        {
            List<SqlServerInfo> servers = new List<SqlServerInfo>();
            foreach (string ip in possibleIPs)
            {
                servers.AddRange(SqlServerInfo.DiscoverSQLServer(ip));
            }
            return servers;
        }
    
        static public List<SqlServerInfo> DiscoverSQLServer(string ip)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.EnableBroadcast = true;
            socket.ReceiveTimeout = 1000;
            List<SqlServerInfo> servers = new List<SqlServerInfo>();
            try
            {
                byte[] msg = new byte[] { 3 };
                IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), 1434);
                socket.SendTo(msg, ep);
                int cnt = 0;
                byte[] bytBuffer = new byte[64000];
                do
                {
                    cnt = socket.Receive(bytBuffer);
                    string s = System.Text.ASCIIEncoding.ASCII.GetString(bytBuffer, 3, BitConverter.ToInt16(bytBuffer, 1));
                    string[] parts = s.Split(new string[] { ";;" }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string s1 in parts)
                    {
                        SqlServerInfo sInfo = new SqlServerInfo(s1);
                        sInfo.IpAddress = ip;
                        if (sInfo.CheckIsActive())
                        {
                            servers.Add(sInfo);
                        }
    
                    }
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 300);
                } while (cnt != 0);
            }
            catch
            {
    
            }
            finally
            {
                socket.Close();
            }
    
            return servers;
        }
    
        private SqlServerInfo()
        {
    
        }
    
        public  string SSNetlibVersion(string remoteIP, int port)
        {
            string str = "";
            try
            {
                TcpClient client = new TcpClient();
                client.SendTimeout = 300;
                client.ReceiveTimeout = 300;
                client.Connect(remoteIP, port);
                NetworkStream stream = client.GetStream();
                byte[] buffer = new byte[] {
                    0x12, 1, 0, 0x34, 0, 0, 0, 0, 0, 0, 0x15, 0, 6, 1, 0, 0x1b,
                    0, 1, 2, 0, 0x1c, 0, 12, 3, 0, 40, 0, 4, 0xff, 8, 0, 1,
                    0x55, 0, 0, 0, 0x4d, 0x53, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0,
                    4, 8, 0, 0};
                stream.Write(buffer, 0, buffer.Length);
                byte[] buffer2 = new byte[0xff];
                string str2 = string.Empty;
                int count = stream.Read(buffer2, 0, buffer2.Length);
                str2 = Encoding.ASCII.GetString(buffer2, 0, count);
                string[] strArray = new string[] { buffer2[0x1d].ToString(), ".", buffer2[30].ToString(), ".", ((buffer2[0x1f] * 0x100) + buffer2[0x20]).ToString() };
                str = string.Concat(strArray);
                if (str.Substring(0, 1) == "0")
                {
                    str = "";
                }
            }
            catch
            {
            }
            return str;
        }
    
        private bool CheckIsActive()
        {
            string version= SSNetlibVersion(this.IpAddress, this.tcpPort);
            if (version.Length == 0)
            {
                this.IsActive = false;
                return false;
            }
            else
            {
                this.IsActive = true;
                this.Version = version;
                return true;
            }
    
        }
    
        private SqlServerInfo(string info)
        {
            string[] nvs = info.Split(';');
            for (int i = 0; i < nvs.Length; i += 2)
            {
                switch (nvs[i].ToLower())
                {
                    case "servername":
                        this.ServerName = nvs[i + 1];
                        break;
    
                    case "instancename":
    
                        this.InstanceName = nvs[i + 1];
                        break;
    
                    case "isclustered":
                        this.IsClustered = (nvs[i + 1].ToLower() == "yes");   //bool.Parse(nvs[i+1]);
                        break;
    
                    case "version":
                        this.Version = nvs[i + 1];
                        break;
    
                    case "tcp":
                        this.tcpPort = int.Parse(nvs[i + 1]);
                        break;
    
                    case "np":
                        this.NamedPipe = nvs[i + 1];
                        break;
    
                    case "rpc":
                        this.Rpc = nvs[i + 1];
                        break;
    
                }
            }
        }
    }

    using the code

    List<SqlServerInfo> sqlSrv = null;
    sqlSrv = SqlServerInfo.DiscoverSQLServer(address);
    //Or
    sqlSrv = SqlServerInfo.DiscoverSQLServer(
                        new string[]{ address+ ".01",
                            address+ ".02",
                            address+ ".03",
                            address+ ".04",
                            address+ ".05",
                            address+ ".06",
                            address+ ".07",
                            address+ ".08",
                            address+ ".09",
                            address+ ".10",
                            address+ ".21",
                            address+ ".51",
                            address+ ".100"},true);
  • Persisting RIA Service Entities to Isolated Storage in Silverlight

    The Silverlight library in this article extends RIA service entities and provides save & load method to save/load entities directly into application storage (Isolation storage). The library supports dynamic quota management for application storage i.e. if an entity requires more space to store it will prompt user to confirm new size of quota store. The saving and loading supports asynchronous processing of entities with inbuilt compression which allows your application to provide non blocking UI. Library can be used to build online-offline mode based Silverlight applications without additional programming overheads.

    Code to save RIA Entities in the storage space

    EmployeeContext context = new EmployeeContext();
    dataGrid.ItemSource = context.Employees;
    Action<LoadOperation<Patient>> completeProcessing = delegate(LoadOperation<Patient> loadOp)
    {
        if (!loadOp.HasError)
            {
                loadOp.Entities.Save();
            }
            else
            {
                LogAndNotify(loadOp.Error);
                loadOp.MarkErrorAsHandled();
            }
    };
    context.Load(context.GetEmployeesQuery(), completeProcessing, null);

    Code to load RIA Entities from storage space

    EmployeeContext context = new EmployeeContext();
    context.Employees.Load();

    You can also use the same library to save and load genric data you need to provide the filename to which the object set is saved whereas with Ria EntitySet the fileName is optional which is calculated based on the data type of entity.
    Code to save List<string> into storge sapce

    List<string> names = new List<string>();
    names.Add("Employee1");
    names.Add("Employee2");
    names.Add("Employee3");
    names.Save("Employee4");
    names.Save("EmployeeesDataSet");

    Code to load List<string> into storge sapce

    List<string> names = new List<string>();
    names.Load("EmployeeesDataSet")

    Note: The Load method supports Asynchronous (default) and Synchronous operation where as Save method only supports Asynchronous operation.You can also override the Quota Management screen globally in your application and if not overrided the library will use in-built screen shown below (right image).

    How it works : diagram is self explanatory..

    Source code is now available here, Because of time constriants i was not able to comlete the code behind for the isolation storage screen above, however the library is now completed and published with silverlight unit test project.

  • Recovering a SQL Server Database from Suspect Mode

    USE Master
    GO

    EXEC sp_configure ‘allow updates’, 1
    RECONFIGURE WITH OVERRIDE
    GO

    BEGIN TRAN
    UPDATE master..sysdatabases SET status = status | 32768 WHERE name = ‘YourDBName’
    IF @@ROWCOUNT = 1
     BEGIN COMMIT TRAN
      RAISERROR(‘Emergency Mode Successfully Set’, 0, 1)
     END
    ELSE
     BEGIN ROLLBACK
     RAISERROR(‘Setting Emergency Mode Failed’, 16, 1)
    END
    GO
    –Stop mssql service

    –Rename the existing LOG file for YourDBName database.

    –Start mssql service

    DBCC REBUILD_LOG(YourDBName,’C:program files….dataYourDBName_log.ldf’)
    GO

    DBCC checkdb (YourDBName)
    GO

    –If DBCC return errors then fix it
    — BEGIN
     ALTER DATABASE YourDBName SET SINGLE_USER
     GO
     –Repair the consistency errors if found by above command
     DBCC checkdb (YourDBName,REPAIR_ALLOW_DATA_LOSS)
     GO
     –OR
     DBCC checkdb (YourDBName,REPAIR_FAST)
     GO
    — END Fix errors finished

    ALTER DATABASE YourDBName SET MULTI_USER

    Article applies to SQL Server 2000

  • Silverlight data grid extensions

    Data Grid Ex Support two new events

    • Commit (An event that indicates that a selection is complete and has been made, effectively commit action.)
    • Cancel (An event that indicates that the selection operation has been canceled)

    Also supports single row double click.

    Event Commit will be raise if user double click on row or press enter while row is selected where as event Cancel is fired if user click on Esc button.

    Class DataGridEx :

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.Windows.Automation.Peers;
    using System.Linq;
    
    namespace XXX.YYY.Controls
    {
        public class DataGridEx : DataGrid
        {
            private DataGridRow _LastDataGridRow = null;
            private DataGridColumn _LastDataGridColumn = null;
            private DataGridCell _LastDataGridCell = null;
            private object _LastObject = null;
            private DateTime _LastClick = DateTime.MinValue;
    
            private double _DoubleClickTime = 1500;
    
            /// 
            /// An event that indicates that a selection is complete and has been
            /// made, effectively a commit action.
            /// 
            public event RoutedEventHandler Commit;
    
            /// 
            /// An event that indicates that the selection operation has been
            /// canceled.
            /// 
            public event RoutedEventHandler Cancel;
    
            /// 
            /// Initializes a new instance of the DataGridEx class.
            /// 
            public DataGridEx()
            {
                MouseLeftButtonUp += OnGridMouseLeftButtonUp;
            }
    
            private void OnGridMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                DateTime clickTime = DateTime.Now;
                DataGridRow currentRowClicked;
                DataGridColumn currentColumnClicked;
                DataGridCell currentCellClicked;
                object currentObject;
    
                //If we've found at least the row,
                if (GetDataGridCellByPosition(e.GetPosition(null), out currentRowClicked, out currentColumnClicked, out currentCellClicked, out currentObject))
                {
                    //And the current row is the same as the last row, and is within the timespan, consider it a double-click
                    bool isDoubleClick = (currentRowClicked == _LastDataGridRow && clickTime.Subtract(_LastClick) <= TimeSpan.FromMilliseconds(_DoubleClickTime));
    
                    _LastDataGridRow = currentRowClicked;
                    _LastDataGridColumn = currentColumnClicked;
                    _LastDataGridCell = currentCellClicked;
                    _LastObject = currentObject;
    
                    if (isDoubleClick)
                    {
                        OnItemDoubleClick(this,null);
                    }
                }
                else
                {
                    _LastDataGridRow = null;
                    _LastDataGridCell = null;
                    _LastDataGridColumn = null;
                    _LastObject = null;
                }
    
                _LastClick = clickTime;
    
            }
    
            private bool GetDataGridCellByPosition(Point pt, out DataGridRow dataGridRow, out DataGridColumn dataGridColumn, out DataGridCell dataGridCell, out object dataGridObject)
            {
                var elements = VisualTreeHelper.FindElementsInHostCoordinates(pt, this);
                dataGridRow = null;
                dataGridCell = null;
                dataGridColumn = null;
                dataGridObject = null;
    
                if (null == elements || elements.Count() == 0)
                {
                    return false;
                }
    
                var rowQuery = from gridRow in elements where gridRow is DataGridRow select gridRow as DataGridRow;
                dataGridRow = rowQuery.FirstOrDefault();
                if (dataGridRow == null)
                {
                    return false;
                }
    
                dataGridObject = dataGridRow.DataContext;
    
                var cellQuery = from gridCell in elements where gridCell is DataGridCell select gridCell as DataGridCell;
                dataGridCell = cellQuery.FirstOrDefault();
    
                if (dataGridCell != null)
                {
                    dataGridColumn = DataGridColumn.GetColumnContainingElement(dataGridCell);
                }
    
                //If we've got the row, return true - sometimes the Column, DataContext could be null
                return dataGridRow != null;
            }
    
            private void OnItemDoubleClick(object sender,RoutedEventArgs e)
            {
                 OnCommit(this, e);
            }
    
            protected override void OnKeyDown(KeyEventArgs e)
            {
                HandleKeyDown(e);
                if (!e.Handled)
                    base.OnKeyDown(e);
            }
    
            /// 
            /// Process a key down event.
            /// 
            /// The key event arguments object.
            public void HandleKeyDown(KeyEventArgs e)
            {
                switch (e.Key)
                {
                    case Key.Enter:
                        OnCommit(this, e);
                        e.Handled = true;
                        break;
    
                    case Key.Escape:
                        OnCancel(this, e);
                        e.Handled = true;
                        break;
    
                    default:
                        break;
                }
            }
    
            /// 
            /// Fires the Commit event.
            /// 
            /// The source object.
            /// The event data.
            private void OnCommit(object sender, RoutedEventArgs e)
            {
                RoutedEventHandler handler = Commit;
                if (handler != null)
                {
                    handler(sender, e);
                }
            }
    
            /// 
            /// Fires the Cancel event.
            /// 
            /// The source object.
            /// The event data.
            private void OnCancel(object sender, RoutedEventArgs e)
            {
                RoutedEventHandler handler = Cancel;
                if (handler != null)
                {
                    handler(sender, e);
                }
            }
    
            /// 
            /// Initializes a new instance of a DataGridAutomationPeer.
            /// 
            /// Returns a new DataGridAutomationPeer.
            public AutomationPeer CreateAutomationPeer()
            {
                return new DataGridAutomationPeer(this);
            }
    
        }
    }
  • 3d Lenticular (3d Without Glasses)

    After Anaglyph 3DPlayer from last month, the next challenge is to create 3d without glasses using lenticular sheet. A lenticular lens is an array of magnifying lenses, designed so that when viewed from slightly different angles, different images are magnified. The most common example is the lenses used in lenticular printing, where the technology is used to give an illusion of depth, or to make images that appear to change or move as the image is viewed from different angles.

    Lenticular imaging is a multi-step process consisting of creating a lenticular image from at least two existing images, and combining it with a lenticular lens. This process can be used to create various frames of animation (for a motion effect), offsetting the various layers at different increments (for a 3d effect).

    To create output from two input images here in this article you will find lenticular shadder effect (WPF).With lenticular effect you can transform image or video into lenticular source within WPF or online Silverlight application. The heart of lenticular effect is HLSL (High Level Shader Language) code

    int pxW =floor (PixelWidth);
    float virtualRow;
    if(Direction ==0)
    virtualRow =round( (uv.y * ImageHeight)/(floor (PixelWidth)));
    else
    virtualRow =round( (uv.x * ImageWidth)/(floor (PixelWidth)));
    
    if (virtualRow % 2 >= 1) //Odd Even Rows
    return tex2D(RightImage, uv);
    else
    return tex2D(input, uv);

    The HLSL code above calculates the pixel position and determines from which source it has to pick the pixel color information to create final output. To create and test HLSL program I have used Shazzam pixel shader utility which is very nice tool to quickly develop shader logic.

    The attached Silverlight project uses lenticular effect to render merged images and to convert it into good looking 3d, you need to precisely align lenticular sheet on top of your laptop.

    Lenticular output from Silverlight project and final look, after you put your lenticular sheet

             .

    xaml behind project is

    <Image Margin="20" Stretch="None" Name="imageSource" Source="/LenticularEffect3D;component/Uta_bar_sm 1.png">
    <Image.Effect>
    <effects:LenticularEffect ImageWidth="{Binding ElementName=imageSource,Path=ActualWidth}" ImageHeight="{Binding ElementName=imageSource,Path=ActualHeight}" x:Name="lenticularEffect"  Direction="1" PixelWidth="1" >
    <effects:LenticularEffect.RightImage>
    <ImageBrush Opacity="1"  ImageSource="/LenticularEffect3D;component/Uta_bar_sm 2.png">
    </ImageBrush>
    </effects:LenticularEffect.RightImage>
    </effects:LenticularEffect>
    </Image.Effect>
    </Image>

    The lenticular sheet has specific ppi (pixel per inch) , since we are trying to produce 3d from laptop screen (TFT DPI 120) and you have to somehow match the picture pixels to screen & screen dpi to lenticular sheet to get desired results. I was not able to achieve very good 3d output as you will need matching ppi lenticular sheet and very high resolution screen to fix at least two pixes under single lenticular lense.

    Download source code