Blog Archives

.NET Map Drive in C# (WPF)

Complete class reference updated for WPF (not yet tested). For backwards compatibility, previous Win32 code maintained in code comments (and just replace ‘Window’ with ‘Form’).

    /// <summary>
    /// Network drive interface from original application slightly modified to handle WPF windows.
    /// </summary>
    public class NetworkDrive
    {

        #region API
        [DllImport("mpr.dll")]
        private static extern int WNetAddConnection2A(ref structNetResource pstNetRes, string psPassword, string psUsername, int piFlags);
        [DllImport("mpr.dll")]
        private static extern int WNetCancelConnection2A(string psName, int piFlags, int pfForce);
        [DllImport("mpr.dll")]
        private static extern int WNetConnectionDialog(int phWnd, int piType);
        [DllImport("mpr.dll")]
        private static extern int WNetDisconnectDialog(int phWnd, int piType);
        [DllImport("mpr.dll")]
        private static extern int WNetRestoreConnectionW(int phWnd, string psLocalDrive);

        [StructLayout(LayoutKind.Sequential)]
        private struct structNetResource
        {
            public int iScope;
            public int iType;
            public int iDisplayType;
            public int iUsage;
            public string sLocalName;
            public string sRemoteName;
            public string sComment;
            public string sProvider;
        }

        private const int RESOURCETYPE_DISK = 0x1;

        //Standard	
        private const int CONNECT_INTERACTIVE = 0x00000008;
        private const int CONNECT_PROMPT = 0x00000010;
        private const int CONNECT_UPDATE_PROFILE = 0x00000001;
        //IE4+
        private const int CONNECT_REDIRECT = 0x00000080;
        //NT5 only
        private const int CONNECT_COMMANDLINE = 0x00000800;
        private const int CONNECT_CMD_SAVECRED = 0x00001000;

        #endregion

        #region Propertys and options
        private bool lf_SaveCredentials = false;
        /// <summary>
        /// Option to save credentials are reconnection...
        /// </summary>
        public bool SaveCredentials
        {
            get { return (lf_SaveCredentials); }
            set { lf_SaveCredentials = value; }
        }
        private bool lf_Persistent = false;
        /// <summary>
        /// Option to reconnect drive after log off / reboot ...
        /// </summary>
        public bool Persistent
        {
            get { return (lf_Persistent); }
            set { lf_Persistent = value; }
        }
        private bool lf_Force = false;
        /// <summary>
        /// Option to force connection if drive is already mapped...
        /// or force disconnection if network path is not responding...
        /// </summary>
        public bool Force
        {
            get { return (lf_Force); }
            set { lf_Force = value; }
        }
        private bool ls_PromptForCredentials = false;
        /// <summary>
        /// Option to prompt for user credintals when mapping a drive
        /// </summary>
        public bool PromptForCredentials
        {
            get { return (ls_PromptForCredentials); }
            set { ls_PromptForCredentials = value; }
        }

        private string ls_Drive = "s:";
        /// <summary>
        /// Drive to be used in mapping / unmapping...
        /// </summary>
        public string LocalDrive
        {
            get { return (ls_Drive); }
            set
            {
                if (value.Length >= 1)
                {
                    ls_Drive = value.Substring(0, 1) + ":";
                }
                else
                {
                    ls_Drive = "";
                }
            }
        }
        private string ls_ShareName = "\\\\Computer\\C$";
        /// <summary>
        /// Share address to map drive to.
        /// </summary>
        public string ShareName
        {
            get { return (ls_ShareName); }
            set { ls_ShareName = value; }
        }
        #endregion

        #region Function mapping
        /// <summary>
        /// Map network drive
        /// </summary>
        public void MapDrive() { zMapDrive(null, null); }
        /// <summary>
        /// Map network drive (using supplied Password)
        /// </summary>
        public void MapDrive(string Password) { zMapDrive(null, Password); }
        /// <summary>
        /// Map network drive (using supplied Username and Password)
        /// </summary>
        public void MapDrive(string Username, string Password) { zMapDrive(Username, Password); }
        /// <summary>
        /// Unmap network drive
        /// </summary>
        public void UnMapDrive() { zUnMapDrive(this.lf_Force); }
        /// <summary>
        /// Check / restore persistent network drive
        /// </summary>
        public void RestoreDrives() { zRestoreDrive(); }
        /// <summary>
        /// Display windows dialog for mapping a network drive
        /// </summary>
        public void ShowConnectDialog(Window ParentForm) { zDisplayDialog(ParentForm, 1); }
        /// <summary>
        /// Display windows dialog for disconnecting a network drive
        /// </summary>
        public void ShowDisconnectDialog(Window ParentForm) { zDisplayDialog(ParentForm, 2); }


        #endregion

        #region Core functions

        // Map network drive
        private void zMapDrive(string psUsername, string psPassword)
        {
            //create struct data
            structNetResource stNetRes = new structNetResource();
            stNetRes.iScope = 2;
            stNetRes.iType = RESOURCETYPE_DISK;
            stNetRes.iDisplayType = 3;
            stNetRes.iUsage = 1;
            stNetRes.sRemoteName = ls_ShareName;
            stNetRes.sLocalName = ls_Drive;
            //prepare params
            int iFlags = 0;
            if (lf_SaveCredentials) { iFlags += CONNECT_CMD_SAVECRED; }
            if (lf_Persistent) { iFlags += CONNECT_UPDATE_PROFILE; }
            if (ls_PromptForCredentials) { iFlags += CONNECT_INTERACTIVE + CONNECT_PROMPT; }
            if (psUsername == "") { psUsername = null; }
            if (psPassword == "") { psPassword = null; }
            //if force, unmap ready for new connection
            if (lf_Force)
            {
                try { zUnMapDrive(true); }
                catch { }
            }
            //call and return
            int i = WNetAddConnection2A(ref stNetRes, psPassword, psUsername, iFlags);
            if (i > 0) { throw new System.ComponentModel.Win32Exception(i); }
        }


        // Unmap network drive	
        private void zUnMapDrive(bool pfForce)
        {
            //call unmap and return
            int iFlags = 0;
            if (lf_Persistent) { iFlags += CONNECT_UPDATE_PROFILE; }
            int i = WNetCancelConnection2A(ls_Drive, iFlags, Convert.ToInt32(pfForce));
            if (i != 0) i = WNetCancelConnection2A(ls_ShareName, iFlags, Convert.ToInt32(pfForce));  //disconnect if localname was null
            if (i > 0) { throw new System.ComponentModel.Win32Exception(i); }
        }


        // Check / Restore a network drive
        private void zRestoreDrive()
        {
            //call restore and return
            int i = WNetRestoreConnectionW(0, null);
            if (i > 0) { throw new System.ComponentModel.Win32Exception(i); }
        }

        // Display windows dialog
        private void zDisplayDialog(Window poParentForm, int piDialog)
        {
            int i = -1;
            int iHandle = 0;
            //get parent handle
            if (poParentForm != null)
            {

                IntPtr hwnd = (new WindowInteropHelper(poParentForm)).Handle;
                iHandle = hwnd.ToInt32(); //poParentForm.Handle.ToInt32();
            }
            //show dialog
            if (piDialog == 1)
            {
                i = WNetConnectionDialog(iHandle, RESOURCETYPE_DISK);
            }
            else if (piDialog == 2)
            {
                i = WNetDisconnectDialog(iHandle, RESOURCETYPE_DISK);
            }
            if (i > 0) { throw new System.ComponentModel.Win32Exception(i); }
            //set focus on parent form
            //poParentForm.BringToFront();
            poParentForm.Activate();
            poParentForm.Topmost = true;
        }
        #endregion

    }

References
StackOverflow (blog), http://stackoverflow.com/questions/3465182/how-to-map-a-drive-using-c
PINVOKE (code references and snippets), http://pinvoke.net/default.aspx/Structures/NETRESOURCE.html
MSDN (info on class types and structures), http://msdn.microsoft.com/en-us/library/windows/desktop/aa385341%28v=vs.85%29.aspx

Facebook IPO and the Future of Social Networking

Just in case the recent FB IPO has your wallet itchy, lets take a look at some interesting facts.

http://diasporaproject.org/

^ Zuckerberg himself invested in this project..

I’m not trying to sell you a product, but to give you a quick understanding, Diaspora is an example of a distributed social network.

A distributed social network is a really just Decentralized Computing, opposite of Facebook which is centralized.

Diaspora is just one example, you will see on the Wiki link above there are many attempting the same thing, just as there are many centralized social networks competing with Facebook.

Just a Fad?

I do not believe social networking is a Fad.

However, like all software systems it will be potentially subject to lackluster modules, stymied growth once it’s exceptionally large, and software evolution.

Now I’m not big on evolution in general.. but.. software does evolve.

If you try to think of a single example of a software system which has not evolved over time, you will find this list is very small..

What is it evolving into?

The answer to that question at best is an educated guess. But certain patterns in software systems, as well as the donation of Mark Zuckerberg to Diaspora (which is a direct competitor), hints the company may move in a more distributed direction – if not – it could risk getting left behind.

Let’s take a quick look at why Facebook is no different than these other systems.

Evolution of the Internet

Evolution of the Internet

Birth of Napster

Birth of Napster

Cloud Data

Cloud Data

High-Performance Computing

High-Performance Computing

These diagrams are obviously highly simplified, and don’t due justice to the rich history behind the growth of these systems, but they serve to illustrate a very strong theme in computing of growth through networking.

Every system that starts centralized eventually becomes decentralized and distributed. History does show that over expansion and distribution too rapidly spreads things thin, but in moderation it is a model for success.

To IPO, or not to IPO?

To summarize my overall assumption – centralized social networks will be replaced with decentralized ad hoc networks and/or the survival of social networks will be dependent on much tighter integration at the operating system level (which we are already seeing, look at the newest flavor of Fedora or Windows 8).

In investment terminology this means there may be very good long term profit to be made if FB makes the right decisions and continues to evolve at the same pace as society. This can easily be assessed over time, but is uncertain right now.

FB press releases do not seem to hint much at a distributed system or leaning heavier on tighter OS integration, and I believe these two key points to be critical to their long term growth.

Basic Risk Assessment

Stock predictions are guesses, with no promise of accuracy, but my estimation is a large majority of well funded shareholders already see the valuation of FB as a high volatility and high risk simply by considering FB’s reported revenue versus it’s valuation.

Many people are not aware that alot of these shareholders get a stake on the price of the IPO much earlier than the average joe, and in fact they inflate the price so once it is out the door it is already much higher than the stated “IPO price” you will see on the news, but never had the opportunity to get.

By the time you get to purchase, the majority % of these shareholders will be selling for short term gain. Even though brokerages and firms openly discourage this and it is frowned upon it still seems to mysteriously happen.. (look up LinkedIn’s graph on first day of trading)

In some cases this will happen so quickly that you won’t even notice, and you could quickly get pulled under the waves the second you jump in the water.

So if you want to risk holding for the long term and following FB’s growth, go for it, but if you’re trying to get rich quick, it is not likely.

References
Distributed Social Network (Wiki), http://en.wikipedia.org/wiki/Distributed_social_network
Fedora Project, http://www.fedoraproject.org
WebSequenceDiagrams, http://www.websequencediagrams.com/
Zuckerberg Diaspora Investment, http://www.wired.com/epicenter/2010/05/zuckerberg-interview/all/1
Windows 8, http://en.wikipedia.org/wiki/Windows_8
FB’s reported revenue, http://www.bloomberg.com/news/2011-09-20/facebook-revenue-will-reach-4-27-billion-emarketer-says-1-.html
FB’s estimated valuation, http://www.forbes.com/sites/ciocentral/2012/02/02/facebook-valuation-we-dont-know-what-we-dont-know/

Follow

Get every new post delivered to your Inbox.