Solved

Displaying long file names using C#

Posted on 2009-05-05
3
950 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A basic question.. “What is the Garbage Collector?” The usual answer given back: “Garbage collector is a background thread run by the CLR for freeing up the memory space used by the objects which are no longer used by the program.” I wondered …
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…
I designed this idea while studying technology in the classroom.  This is a semester long project.  Students are asked to take photographs on a specific topic which they find meaningful, it can be a place or situation such as travel or homelessness.…

929 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