Changeset 2179


Ignore:
Timestamp:
6/18/2010 6:53:20 AM (20 months ago)
Author:
lowjoel
Message:

Refactor a function which parses null-delimited string arrays.

Location:
trunk/eraser/Eraser.Util
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Util/NativeMethods/Kernel.cs

    r2178 r2179  
    599599                //Do we have enough space for all the text 
    600600                if (written != 0) 
    601                     break; 
     601                    return ParseNullDelimitedArray(buffer, (int)written); 
    602602                else if (Marshal.GetLastWin32Error() == Win32ErrorCode.InsufficientBuffer) 
    603603                    continue; 
     
    605605                    throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
    606606            } 
    607  
    608             List<string> result = new List<string>(); 
    609             for (int lastIndex = 0, i = 0; i != buffer.Length; ++i) 
    610             { 
    611                 if (buffer[i] == '\0') 
    612                 { 
    613                     //If there are no mount points for this volume, the string will only 
    614                     //have one NULL 
    615                     if (i - lastIndex == 0) 
    616                         break; 
    617  
    618                     //Resolve the DOS name to the device name 
    619                     result.Add(new string(buffer, lastIndex, i - lastIndex)); 
    620  
    621                     lastIndex = i + 1; 
    622                     if (buffer[lastIndex] == '\0') 
    623                         break; 
    624                 } 
    625             } 
    626  
    627             return result.ToArray(); 
    628607        } 
    629608 
     
    11671146        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    11681147        [return: MarshalAs(UnmanagedType.Bool)] 
    1169         public static extern bool GetVolumePathNamesForVolumeName(string lpszVolumeName, 
     1148        private static extern bool GetVolumePathNamesForVolumeName(string lpszVolumeName, 
    11701149            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] char[] lpszVolumePathNames, 
    11711150            uint cchBufferLength, out uint lpcchReturnLength); 
     1151 
     1152        /// <summary> 
     1153        /// Retrieves a list of path names for the specified volume name. 
     1154        /// </summary> 
     1155        /// <param name="lpszVolumeName">The volume name.</param> 
     1156        public static string[] GetVolumePathNamesForVolumeName(string lpszVolumeName) 
     1157        { 
     1158            uint returnLength = 0; 
     1159            char[] pathNamesBuffer = new char[NativeMethods.MaxPath]; 
     1160            while (!NativeMethods.GetVolumePathNamesForVolumeName(lpszVolumeName, 
     1161                pathNamesBuffer, (uint)pathNamesBuffer.Length, out returnLength)) 
     1162            { 
     1163                int errorCode = Marshal.GetLastWin32Error(); 
     1164                switch (errorCode) 
     1165                { 
     1166                    case Win32ErrorCode.NotReady: 
     1167                        //The drive isn't ready yet: just return an empty list. 
     1168                        return new string[0]; 
     1169                    case Win32ErrorCode.MoreData: 
     1170                        pathNamesBuffer = new char[pathNamesBuffer.Length * 2]; 
     1171                        break; 
     1172                    default: 
     1173                        throw Win32ErrorCode.GetExceptionForWin32Error(errorCode); 
     1174                } 
     1175            } 
     1176 
     1177            return ParseNullDelimitedArray(pathNamesBuffer, (int)returnLength); 
     1178        } 
    11721179 
    11731180        public const int MaxPath = 260; 
     
    12441251        [DllImport("Kernel32.dll", SetLastError = true)] 
    12451252        public static extern IntPtr LocalFree(IntPtr hMem); 
     1253 
     1254        /// <summary> 
     1255        /// Parses a null-delimited array into a string array. 
     1256        /// </summary> 
     1257        /// <param name="buffer">The buffer to parse.</param> 
     1258        /// <param name="length">The valid length of the array.</param> 
     1259        /// <returns>The array found in the buffer</returns> 
     1260        private static string[] ParseNullDelimitedArray(char[] buffer, int length) 
     1261        { 
     1262            List<string> result = new List<string>(); 
     1263            for (int lastIndex = 0, i = 0; i != length; ++i) 
     1264            { 
     1265                if (buffer[i] == '\0') 
     1266                { 
     1267                    //If the string formed is empty, there are no elements left. 
     1268                    if (i - lastIndex == 0) 
     1269                        break; 
     1270 
     1271                    result.Add(new string(buffer, lastIndex, i - lastIndex)); 
     1272 
     1273                    lastIndex = i + 1; 
     1274                    if (buffer[lastIndex] == '\0') 
     1275                        break; 
     1276                } 
     1277            } 
     1278 
     1279            return result.ToArray(); 
     1280        } 
    12461281    } 
    12471282} 
  • trunk/eraser/Eraser.Util/VolumeInfo.cs

    r2178 r2179  
    9292        private List<string> GetLocalVolumeMountPoints() 
    9393        { 
    94             List<string> result = new List<string>(); 
    95  
    96             //Get the paths of the said volume 
    97             string pathNames; 
    98             { 
    99                 uint returnLength = 0; 
    100                 char[] pathNamesBuffer = new char[NativeMethods.MaxPath]; 
    101                 while (!NativeMethods.GetVolumePathNamesForVolumeName(VolumeId, 
    102                     pathNamesBuffer, (uint)pathNamesBuffer.Length, out returnLength)) 
    103                 { 
    104                     int errorCode = Marshal.GetLastWin32Error(); 
    105                     switch (errorCode) 
    106                     { 
    107                         case Win32ErrorCode.NotReady: 
    108                             //The drive isn't ready yet: just return an empty list. 
    109                             return result; 
    110                         case Win32ErrorCode.MoreData: 
    111                             pathNamesBuffer = new char[pathNamesBuffer.Length * 2]; 
    112                             break; 
    113                         default: 
    114                             throw Win32ErrorCode.GetExceptionForWin32Error(errorCode); 
    115                     } 
    116                 } 
    117  
    118                 pathNames = new string(pathNamesBuffer, 0, (int)returnLength); 
    119             } 
    120  
    121             //OK, the marshalling is complete. Convert the pathNames string into a list 
    122             //of strings containing all of the volumes mountpoints; because the 
    123             //GetVolumePathNamesForVolumeName function returns a convoluted structure 
    124             //containing the path names. 
    125             for (int lastIndex = 0, i = 0; i != pathNames.Length; ++i) 
    126             { 
    127                 if (pathNames[i] == '\0') 
    128                 { 
    129                     //If there are no mount points for this volume, the string will only 
    130                     //have one NULL 
    131                     if (i - lastIndex == 0) 
    132                         break; 
    133  
    134                     result.Add(pathNames.Substring(lastIndex, i - lastIndex)); 
    135  
    136                     lastIndex = i + 1; 
    137                     if (pathNames[lastIndex] == '\0') 
    138                         break; 
    139                 } 
    140             } 
    141  
    142             return result; 
     94            return new List<string>(NativeMethods.GetVolumePathNamesForVolumeName(VolumeId)); 
    14395        } 
    14496 
Note: See TracChangeset for help on using the changeset viewer.