Solved

Displaying long file names using C#

Posted on 2009-05-05
3
949 Views
Last Modified: 2013-12-17
I need to list all the files in a shared folder. My file search program is throwing me a message saying that "The file name length must be less than 248 characters long".

But some paths in my UNC shares have more than 2000 characters.

How should I get the long file names using C#?

Do I have any Win32 API function to achieve this?
0
Comment
Question by:sputrevu
3 Comments
 
LVL 8

Expert Comment

by:Haris V
ID: 24302859
0
 
LVL 6

Expert Comment

by:openshac
ID: 24302872
You could run a bat file from C# and then just process the results:

There's an example on how to do this sort of thing here:

http://blogs.msdn.com/csharpfaq/archive/2004/06/01/146375.aspx
0
 

Accepted Solution

by:
sputrevu earned 0 total points
ID: 24334886
I figured it myself.
The code is pasted below.
Compile this program and it generates an executable.

The usage is ACL <machinename> <Sharename>

Example:
ACL VINAYKPM.MYSERVER.COM  MYSHAREFOLDER
ACL VINAYKPM  MYSHAREFOLDER

You need to be a member of Administrators to get permissions of a shared folder in local system, and member of Domain Administrators to check against a network folder.

The only limitation of this program is that the share users added in the shared folder's permission list, need to visit the particular shared folder at-least once, or else the application will show their SID (Security Identifier) instead of the user name.
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

using System.ComponentModel;
 

namespace ACL

{

    class LookUpSidName

    {  

        const int NO_ERROR = 0;

        const int ERROR_INSUFFICIENT_BUFFER = 122;
 

        enum SID_NAME_USE

        {

            SidTypeUser = 1,

            SidTypeGroup,

            SidTypeDomain,

            SidTypeAlias,

            SidTypeWellKnownGroup,

            SidTypeDeletedAccount,

            SidTypeInvalid,

            SidTypeUnknown,

            SidTypeComputer

        }
 

       
 

        [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]

        static extern bool ConvertSidToStringSid(

            [MarshalAs(UnmanagedType.LPArray)] byte[] pSID,

            out IntPtr ptrSid);
 
 

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        static extern bool LookupAccountSid(

          string lpSystemName,

          [MarshalAs(UnmanagedType.LPArray)] byte[] Sid,

          System.Text.StringBuilder lpName,

          ref uint cchName,

          System.Text.StringBuilder ReferencedDomainName,

          ref uint cchReferencedDomainName,

          out SID_NAME_USE peUse);
 

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        private static extern bool LookupAccountSid(

            [In, MarshalAs(UnmanagedType.LPTStr)] string systemName,

            IntPtr sid,

            [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder name,

            ref int cbName,

            StringBuilder referencedDomainName,

            ref int cbReferencedDomainName,

            out int use);
 

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        internal static extern bool ConvertStringSidToSid(

            [In, MarshalAs(UnmanagedType.LPTStr)] string pStringSid,

            ref IntPtr sid);
 

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        internal static extern bool ConvertSidToStringSid(

            IntPtr sid,

            [In, Out, MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);
 

        public void GetAccountNamefromSid(byte[] Sid)

        {

            StringBuilder name = new StringBuilder();

            uint cchName = (uint)name.Capacity;

            StringBuilder referencedDomainName = new StringBuilder();

            uint cchReferencedDomainName = (uint)referencedDomainName.Capacity;

            SID_NAME_USE sidUse;

            // Sid for BUILTIN\Administrators

            //byte[] Sid = new byte[] { 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2 };
 

            int err = NO_ERROR;

            if (!LookupAccountSid(null, Sid, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))

            {

                err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();

                if (err == ERROR_INSUFFICIENT_BUFFER)

                {

                    name.EnsureCapacity((int)cchName);

                    referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);

                    err = NO_ERROR;

                    if (!LookupAccountSid(null, Sid, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))

                        err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();

                }

            }

            if (err == 0)

                Console.WriteLine(@"{0}\{1}", referencedDomainName.ToString(), name.ToString());

            else

            {

                string asid = GetSidString(Sid);

                try

                {

                    Console.WriteLine(GetName(asid));

                }

                catch

                {

                    //Console.WriteLine(@"Error : {0}", err);

                    Console.WriteLine(asid);

                }

                

            }

        }
 

        public static string GetSidString(byte[] sid)

        {

            IntPtr ptrSid;

            string sidString;

            if (!ConvertSidToStringSid(sid, out ptrSid))

                throw new System.ComponentModel.Win32Exception();

            try

            {

                sidString = Marshal.PtrToStringAuto(ptrSid);

            }

            finally

            {

                //LocalFree(ptrSid);

            }

            return sidString;

        }
 

        public static string GetName(string sid)

        {

            IntPtr _sid = IntPtr.Zero;    //pointer to binary form of SID string.

            int _nameLength = 0;        //size of object name buffer

            int _domainLength = 0;        //size of domain name buffer

            int _use;                    //type of object

            StringBuilder _domain = new StringBuilder();    //domain name variable

            int _error = 0;

            StringBuilder _name = new StringBuilder();        //object name variable

            //converts SID string into the binary form

            bool _rc0 = ConvertStringSidToSid(sid, ref _sid);

            if (_rc0 == false)

            {

                _error = Marshal.GetLastWin32Error();

                Marshal.FreeHGlobal(_sid);

                throw (new Exception(new Win32Exception(_error).Message));

            }
 

            //first call of method returns the size of domain name 

            //and object name buffers

            bool _rc = LookupAccountSid(null, _sid, _name, ref _nameLength, _domain,

                             ref _domainLength, out _use);

            _domain = new StringBuilder(_domainLength);    //allocates memory for domain name

            _name = new StringBuilder(_nameLength);        //allocates memory for object name

            _rc = LookupAccountSid(null, _sid, _name, ref _nameLength, _domain,

                             ref _domainLength, out _use);

            if (_rc == false)

            {

                _error = Marshal.GetLastWin32Error();

                Marshal.FreeHGlobal(_sid);

                throw (new Exception(new Win32Exception(_error).Message));

            }

            else

            {

                Marshal.FreeHGlobal(_sid);

                return _domain.ToString() + "\\" + _name.ToString();

            }

        }
 

    }
 

    class Program

    {

        [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        static extern int NetShareGetInfo(

            [MarshalAs(UnmanagedType.LPWStr)] string serverName,

            [MarshalAs(UnmanagedType.LPWStr)] string netName,

            Int32 level,

            out IntPtr bufPtr);
 

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]

        static extern bool GetSecurityDescriptorDacl(

            IntPtr pSecurityDescriptor,

            [MarshalAs(UnmanagedType.Bool)] out bool bDaclPresent,

            ref IntPtr pDacl,

            [MarshalAs(UnmanagedType.Bool)] out bool bDaclDefaulted

            );
 

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]

        static extern bool GetAclInformation(

            IntPtr pAcl,

            ref ACL_SIZE_INFORMATION pAclInformation,

            uint nAclInformationLength,

            ACL_INFORMATION_CLASS dwAclInformationClass

         );
 

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        static extern int GetAce(

            IntPtr aclPtr,

            int aceIndex,

            out IntPtr acePtr

         );
 

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        static extern int GetLengthSid(

            IntPtr pSID

         );
 

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]

        static extern bool ConvertSidToStringSid(

            [MarshalAs(UnmanagedType.LPArray)] byte[] pSID,

            out IntPtr ptrSid

         );
 

        [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

        static extern int NetApiBufferFree(

            IntPtr buffer

         );
 
 
 

        [StructLayout(LayoutKind.Sequential)]

        struct SHARE_INFO_502

        {

            [MarshalAs(UnmanagedType.LPWStr)]

            public string shi502_netname;

            public uint shi502_type;

            [MarshalAs(UnmanagedType.LPWStr)]

            public string shi502_remark;

            public Int32 shi502_permissions;

            public Int32 shi502_max_uses;

            public Int32 shi502_current_uses;

            [MarshalAs(UnmanagedType.LPWStr)]

            public string shi502_path;

            public IntPtr shi502_passwd;

            public Int32 shi502_reserved;

            public IntPtr shi502_security_descriptor;

        }
 

        [StructLayout(LayoutKind.Sequential)]

        struct ACL_SIZE_INFORMATION

        {

            public uint AceCount;

            public uint AclBytesInUse;

            public uint AclBytesFree;

        }
 

        [StructLayout(LayoutKind.Sequential)]

        public struct ACE_HEADER

        {

            public byte AceType;

            public byte AceFlags;

            public short AceSize;

        }
 

        [StructLayout(LayoutKind.Sequential)]

        struct ACCESS_ALLOWED_ACE

        {

            public ACE_HEADER Header;

            public int Mask;

            public int SidStart;

        }
 

        enum ACL_INFORMATION_CLASS

        {

            AclRevisionInformation = 1,

            AclSizeInformation

        }
 

        static void Main(string[] args)

        {

            IntPtr bufptr = IntPtr.Zero;

            int err = NetShareGetInfo(args[0], args[1], 502, out bufptr);

            if (0 == err)

            {

                SHARE_INFO_502 shareInfo = (SHARE_INFO_502)Marshal.PtrToStructure(bufptr, typeof(SHARE_INFO_502));
 

                bool bDaclPresent;

                bool bDaclDefaulted;

                IntPtr pAcl = IntPtr.Zero;

                GetSecurityDescriptorDacl(shareInfo.shi502_security_descriptor, out bDaclPresent, ref pAcl, out bDaclDefaulted);

                if (bDaclPresent)

                {

                    ACL_SIZE_INFORMATION AclSize = new ACL_SIZE_INFORMATION();

                    GetAclInformation(pAcl, ref AclSize, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation);
 

                    LookUpSidName ln = new LookUpSidName();
 

                    for (int i = 0; i < AclSize.AceCount; i++)

                    {

                        IntPtr pAce;

                        err = GetAce(pAcl, i, out pAce);

                        ACCESS_ALLOWED_ACE ace = (ACCESS_ALLOWED_ACE)Marshal.PtrToStructure(pAce, typeof(ACCESS_ALLOWED_ACE));
 

                        IntPtr iter = (IntPtr)((int)pAce + (int)Marshal.OffsetOf(typeof(ACCESS_ALLOWED_ACE), "SidStart"));

                        byte[] bSID = null;

                        int size = (int)GetLengthSid(iter);

                        bSID = new byte[size];

                        Marshal.Copy(iter, bSID, 0, size);

                        IntPtr ptrSid;

                        ConvertSidToStringSid(bSID, out ptrSid);

                        string strSID = Marshal.PtrToStringAuto(ptrSid);
 

                        //Console.WriteLine("{0} : {1}/{2}/{3}", strSID, ace.Header.AceType.ToString(), ace.Mask.ToString(), ace.Header.AceFlags.ToString());

                        ln.GetAccountNamefromSid(bSID);

                    }

                }

                err = NetApiBufferFree(bufptr);

            }

        }

    }

}

Open in new window

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Flash (http://en.wikipedia.org/wiki/Adobe_Flash) has evolved over the years to where it has become a masterful tool for displaying content screen.  It has excellent layout placement, UI precision as well as rendering capabilities. This, along with t…
In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now