Wednesday, March 6, 2019

C Sharp Get Host IP Address and Share a from UNC path

Here's a function that was surprisingly hard to find GetUNCHostIPAddressShare from a directory path. Support Host IP address as either IPv4 or IPv6 formats.

A UNC Share is defined as "\\host-name\share-name[\object-name]

ie \\2001:4860:4860::8888\share\tail\dir1   returns  \\2001:4860:4860::8888\share 


The string extension method returns "\\host-name\share-name.

Code Listing

using System;
     
public static class Program
{
 const string ShareExtUNCFullPrefix = @"\\?\UNC\";  
 const string ShareExtPrefix = @"\\?\";      
 const string SharePrefix = @"\\";           
 const string DIR = @"\";
 const char  cDIR = '\\';
 const string DIRDOUBLE = @"\\";
 const string COLONDIR = @":\";
 const string COLON = @":";
 const char cCOLON = ':';
 const string DIRSPACE = @"\ ";
 const string SPACEDIR = @" \";
 const string SPACE = @" ";

 public static int IndexOfOccurence(this string s, char match, int occurence)
 {
  int i = 1;
  int index = -1;

  while (i <= occurence && (index = s.IndexOf(match, index + 1)) != -1)
  {
   if (i == occurence)
    return index;

   i++;
  }

  return -1;
 }
 
 /// <summary>
 /// Gets UNC Host and Share from a full UNC path. Cuts 4th backslash from start of path, must have least 1 char between or digit between. Support IPv4 and IPv6.
 /// </summary>
 /// <param name="UNCFullPath">\\host\share returns empty, must end in a backslash</param>
 /// <returns>\\host\share from \\host\share\tail\, \\8.8.8.8\DNS\ also \\?\UNC\ and \\?\ work</returns>
 /// <warn>//fails for one case when "\\?\UNC\share\tail\file.txt", UNC Server Name is named "UNC"</warn>
 /// <author>Metadataconsulting.blogspot.com</warn>
    public static string GetUNCHostIPAddressShare(this string UNCFullPath)
 {
  if (UNCFullPath.StartsWith(DIRDOUBLE))
  {
   string p = UNCFullPath; //local working copy
   
   if (p.StartsWith(ShareExtPrefix))
   {
    p = p.Substring(3, p.Length - 3);
    
    if (p.StartsWith(@"\UNC\")) //fails for "\\?\UNC\share\tail\file.txt" one case
     p = DIRDOUBLE + p.Substring(5, p.Length - 5);
    else
     p = DIR + p;
   } 
   
   //starts with \\h\s is min 
   int idx3rd = (p.Length >= 5 ) ? p.IndexOf(cDIR, 3) : -1; //4th position zero index 

   //Console.WriteLine("p = " + p + " idx3rd=" + idx3rd); //DEBUG

   if (p[0]==cDIR && p[1]==cDIR && Char.IsLetterOrDigit(p[2]) && p.Length >= 5 &&idx3rd > -1 && Char.IsLetter(p[idx3rd+1]) && p.IndexOf(cDIR, idx3rd + 2) > -1)
   {
    int i = p.IndexOfOccurence(cDIR, 4);

    if (i > -1)
     return p.Substring(0, i); //returns empty if i=0
    else
     return string.Empty;

   }
   else
    return string.Empty;
   
   

  }
  else
   return string.Empty;

 }

 public static void Main()
 {
   Console.WriteLine(@"\\2001:4860:4860::8888\share\tail\dir1".GetUNCHostIPAddressShare());
   Console.WriteLine(@"\\8.8.8.8\share\tail\dir1".GetUNCHostIPAddressShare());
   Console.WriteLine(@"\\host\share\tail\dir1".GetUNCHostIPAddressShare());
   Console.WriteLine(@"\\host\share\tail\file.txt".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\\?\UNC\share\tail\file.txt".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\h\s\file.txt".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\h\s\".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\\s\".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\h\\".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\\\\\\\".GetUNCHostIPAddressShare());
         Console.WriteLine(@"\\?\UNC\share\tail\file.txt".GetUNCHostIPAddressShare() + ", 1 failed case - UNC is Server Name");
   
 }
}


No comments:

Post a Comment