Title:  Web Method To Display Server Logical Disks Remotely on Mobile Device
Author:      Greg Dubinovskiy 
Email:       [email protected]
Environment: VB.NET
Keywords:    Web Service, WMI, WriteXML(), Dataset, GetType(), ReadXml(), ManagementScope(), ManagementObjectSearcher()
Level:       Intermediate
Description: Web Method To Display Server Logical Disks Remotely on Mobile Device
Section      Miscellaneous
SubSection   General

Introduction

One of the features available in Siccolo - Management Tool For SQL Server - ability to backup a SQL Server database from a Windows Mobile device (see my previous article at Web Method to Backup Database Remotely at Siccolo Articles). To make backup process experience friendlier and more similiar to Microsoft SQL Server Enterprise Manager, I needed to allow user select where - which directory - actual database backup file is to be saved. But first, users needs to select disk:



In the code presented, client (mobile device) retrieves list of disks from a web service.
So, as we can see Web Services is quickly finding its way into major system integration development efforts. In back office and legacy systems alike, Web Servicess has become a main focus in providing mechanisms to make data move more freely between and across long-closed boundaries. An entire industry has joined forces and pushes forward in overcoming both technical hurdles such as security and market specific hurdles such as the need of standardized message formats. While these efforts continue, an entirely different market is rapidly maturing: the mobile devices, software and services market. Very interesting solution options arise in the cross section, where Web Services meets mobility. The Microsoft® Windows® .NET Compact Framework opens up the world of Web Services to Pocket PCs, and the wireless nature of Pocket PCs opens up the world of mobility to Web Services. This means that new fuel is added to the expansion of the XML-based Web Services provider market. In this article, we will see a sample Pocket PC project that uses Web Services to manage remote machine from Windows Mobile device!

1. Server Code - Retrieve List of Disks

First, web method to allow client to retrieve list of logical disks on the server:

	  Public Function LocalDisksList(ByVal ServerAddress As String, _
                                                            ByRef ErrorInfo As String) As String

            Try

                Dim DiskList_XML As String = ""

                If DirectoryTree.GetFixedLocalDisks_XML(CType(User, WindowsPrincipal), _
                                                        ServerAddress, _
                                                        ToDebug, _
                                                        DiskList_XML, _
                                                        ErrorInfo) Then

                    ErrorInfo = ""

                    Return DiskList_XML

                Else
                    Return ""

                End If

            Catch ex As Exception
                ErrorInfo = ex.Message
                Return ""
            End Try

        End Function
where GetFixedLocalDisks_XML() creates XML String from list of disks:
   Public Shared Function GetFixedLocalDisks_XML(ByVal WebServiceUser As WindowsPrincipal, _
                                                ByVal ServerName As String, _
                                                ByVal ToDebug As String, _
                                                ByRef ServerLocalDisksList_XML As String, _
                                                ByRef ErrorInfo As String) As Boolean

        Dim collection As ManagementObjectCollection

        Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext = _
                CType(WebServiceUser.Identity, System.Security.Principal.WindowsIdentity).Impersonate()


        If Not GetFixedLocalDisks(ServerName, _
                                    ToDebug, _
                                    collection, _
                                    ErrorInfo) Then
            ServerLocalDisksList_XML = ""
            impersonationContext.Undo()
            Return False
        Else
            Dim objDisks As DataSet = New DataSet("QueryResults")
            objDisks.Tables.Add("LocalDisks")
            objDisks.Tables(0).Columns.Add("disk_path", System.Type.GetType("System.String"))
            Dim management_object As ManagementObject
            For Each management_object In collection
                Dim r As Object = New Object() {management_object("deviceID")}
                objDisks.Tables(0).Rows.Add(r)
            Next

            Dim objStringWriter As New System.IO.StringWriter()
            objDisks.WriteXml(objStringWriter, XmlWriteMode.WriteSchema)
            ServerLocalDisksList_XML = "" & objStringWriter.ToString()
            impersonationContext.Undo()

            Return True
        End If
    End Function
As you can notice, I'm using impersonationContext, because web service needs to "assume" an identity of authenticated user to be able to access resources on the machine other than web service host. On the server side, to retrieve authenticated user, we need to use System.Web.Services.WebService.User and then "impersonate" - Impersonate() - to "Impersonate the user represented by the WindowsIdentity object."

In this method, GetFixedLocalDisks_XML(), I'm using Dataset class to create XML string using WriteXML() method:
		...
	Dim objDisks As DataSet = New DataSet("QueryResults")
		...	
		...
	Dim objStringWriter As New System.IO.StringWriter()
        objDisks.WriteXml(objStringWriter, XmlWriteMode.WriteSchema)
		...
where WriteXml() Writes the current data, and the schema, for the DataSet using the specified System.IO.Stream and XmlWriteMode. XmlWriteMode.WriteSchema tells application to Write the current contents of the DataSet as XML data with the relational structure as inline XSD schema.

To add/create columns in Dataset:
	...
	objDisks.Tables(0).Columns.Add("disk_path", System.Type.GetType("System.String"))
	...
Columns.Add() - Creates and adds a DataColumn object to the DataColumnCollection. Here, Add() creates a DataColumn object with the specified name and type to the DataColumnCollection. To let Add() know type of column, we need to pass a parameter of type DataColumn.DataType. To do that, we can use GetType() method which gets Type with the specified name - System.Type.GetType("System.String")

and GetFixedLocalDisks():
   Private Shared Function GetFixedLocalDisks(ByVal ServerName As String, _
                                                ByVal ToDebug As String, _
                                                ByRef ServerLocalDisks As ManagementObjectCollection, _
                                                ByRef ErrorInfo As String) As Boolean
        Try
            Dim query As ManagementObjectSearcher
            Dim queryCollection As ManagementObjectCollection

            Dim msc As ManagementScope = New ManagementScope("\\" & ServerName & "\root\cimv2")
            Dim query_command As String = "SELECT * FROM Win32_LogicalDisk where MediaType=12 "

            Dim select_query As SelectQuery = New SelectQuery(query_command)

            query = New ManagementObjectSearcher(msc, select_query)
            ServerLocalDisks = query.Get()

            Return True
        Catch ex As Exception
            ServerLocalDisks = Nothing
            ErrorInfo = ex.Message
            Return False
        End Try

    End Function
(more on what can be done with Windows WMI - see at Siccolo Articles)

2. Client Code - Display List of Disks

   Friend Function PopulateLocalDiskList(ByVal cboListControl As Windows.Forms.ComboBox, _
                                   ByVal SelectedDatabase As String, _
                                   ByRef ErrorInfo As String) As Boolean

        Try
            ErrorInfo = ""

            Dim DiskList_XML As String = ""
            DiskList_XML = objSQLWebServiceManager.LocalDisksList(objLoginInfo.ServerAddress, _
                                                                    ErrorInfo)
            If ErrorInfo <> "" Or DiskList_XML = "" Then Return False

            Dim objResponse As New DataSet()
            Dim Reader As New System.IO.StringReader(DiskList_XML.ToString())

            Dim XMLReader As New System.Xml.XmlTextReader(Reader)
            XMLReader.Read()

            objResponse.ReadXml(XMLReader, XmlReadMode.Auto)

            objResponse.AcceptChanges()

            XMLReader.Close()
            cboListControl.DataSource = objResponse.Tables(0)
            cboListControl.DisplayMember = "disk_path"

            Return True

        Catch ex As Exception
            ErrorInfo = ex.Message
            Me.SoundError()

            If m_LogErrorToFile Then LogError("PopulateLocalDiskList():" & ex.ToString)
            Return False
        End Try
    End Function
and on the screen:

Points of Interest

If you would like to read more on this story - please take a look at Siccolo - Free Mobile Management Tool For SQL Server and more articles at Siccolo Articles


Article keywords: Backup command, Backup database, web method, web service, asynchronous method, XML, WMI, GetLocalDisks(), WriteXML(), Dataset, GetType(), ReadXml(), ManagementScope(), ManagementObjectSearcher()


Back To Articles Page

Free Mobile Management For SQL Server(s!) - Siccolo - SQL Management ToolQuestions? Suggestions? Concerns? - email me to [email protected]    Greg Dubinovsky © 2006
or share your thoughts at Siccolo Blog

web sponsor - siccolo.com. well being sponsor - Enabling clinical and operational value across the continuum of care.