mscorlib(4.0.0.0) API with additions
Path.cs
1 using Microsoft.Win32;
3 using System.Security;
6 using System.Text;
7 
8 namespace System.IO
9 {
11  [ComVisible(true)]
12  [__DynamicallyInvokable]
13  public static class Path
14  {
16  [__DynamicallyInvokable]
17  public static readonly char DirectorySeparatorChar = '\\';
18 
19  internal const string DirectorySeparatorCharAsString = "\\";
20 
22  [__DynamicallyInvokable]
23  public static readonly char AltDirectorySeparatorChar = '/';
24 
26  [__DynamicallyInvokable]
27  public static readonly char VolumeSeparatorChar = ':';
28 
31  [Obsolete("Please use GetInvalidPathChars or GetInvalidFileNameChars instead.")]
32  public static readonly char[] InvalidPathChars = new char[36]
33  {
34  '"',
35  '<',
36  '>',
37  '|',
38  '\0',
39  '\u0001',
40  '\u0002',
41  '\u0003',
42  '\u0004',
43  '\u0005',
44  '\u0006',
45  '\a',
46  '\b',
47  '\t',
48  '\n',
49  '\v',
50  '\f',
51  '\r',
52  '\u000e',
53  '\u000f',
54  '\u0010',
55  '\u0011',
56  '\u0012',
57  '\u0013',
58  '\u0014',
59  '\u0015',
60  '\u0016',
61  '\u0017',
62  '\u0018',
63  '\u0019',
64  '\u001a',
65  '\u001b',
66  '\u001c',
67  '\u001d',
68  '\u001e',
69  '\u001f'
70  };
71 
72  internal static readonly char[] TrimEndChars = LongPathHelper.s_trimEndChars;
73 
74  private static readonly char[] RealInvalidPathChars = PathInternal.InvalidPathChars;
75 
76  private static readonly char[] InvalidPathCharsWithAdditionalChecks = new char[38]
77  {
78  '"',
79  '<',
80  '>',
81  '|',
82  '\0',
83  '\u0001',
84  '\u0002',
85  '\u0003',
86  '\u0004',
87  '\u0005',
88  '\u0006',
89  '\a',
90  '\b',
91  '\t',
92  '\n',
93  '\v',
94  '\f',
95  '\r',
96  '\u000e',
97  '\u000f',
98  '\u0010',
99  '\u0011',
100  '\u0012',
101  '\u0013',
102  '\u0014',
103  '\u0015',
104  '\u0016',
105  '\u0017',
106  '\u0018',
107  '\u0019',
108  '\u001a',
109  '\u001b',
110  '\u001c',
111  '\u001d',
112  '\u001e',
113  '\u001f',
114  '*',
115  '?'
116  };
117 
118  private static readonly char[] InvalidFileNameChars = new char[41]
119  {
120  '"',
121  '<',
122  '>',
123  '|',
124  '\0',
125  '\u0001',
126  '\u0002',
127  '\u0003',
128  '\u0004',
129  '\u0005',
130  '\u0006',
131  '\a',
132  '\b',
133  '\t',
134  '\n',
135  '\v',
136  '\f',
137  '\r',
138  '\u000e',
139  '\u000f',
140  '\u0010',
141  '\u0011',
142  '\u0012',
143  '\u0013',
144  '\u0014',
145  '\u0015',
146  '\u0016',
147  '\u0017',
148  '\u0018',
149  '\u0019',
150  '\u001a',
151  '\u001b',
152  '\u001c',
153  '\u001d',
154  '\u001e',
155  '\u001f',
156  ':',
157  '*',
158  '?',
159  '\\',
160  '/'
161  };
162 
164  [__DynamicallyInvokable]
165  public static readonly char PathSeparator = ';';
166 
167  internal static readonly int MaxPath = 260;
168 
169  private static readonly int MaxDirectoryLength = PathInternal.MaxComponentLength;
170 
171  internal const int MAX_PATH = 260;
172 
173  internal const int MAX_DIRECTORY_PATH = 248;
174 
175  internal const int MaxLongPath = 32767;
176 
177  private const string LongPathPrefix = "\\\\?\\";
178 
179  private const string UNCPathPrefix = "\\\\";
180 
181  private const string UNCLongPathPrefixToInsert = "?\\UNC\\";
182 
183  private const string UNCLongPathPrefix = "\\\\?\\UNC\\";
184 
185  private static readonly char[] s_Base32Char = new char[32]
186  {
187  'a',
188  'b',
189  'c',
190  'd',
191  'e',
192  'f',
193  'g',
194  'h',
195  'i',
196  'j',
197  'k',
198  'l',
199  'm',
200  'n',
201  'o',
202  'p',
203  'q',
204  'r',
205  's',
206  't',
207  'u',
208  'v',
209  'w',
210  'x',
211  'y',
212  'z',
213  '0',
214  '1',
215  '2',
216  '3',
217  '4',
218  '5'
219  };
220 
227  [__DynamicallyInvokable]
228  public static string ChangeExtension(string path, string extension)
229  {
230  if (path != null)
231  {
232  CheckInvalidPathChars(path);
233  string text = path;
234  int num = path.Length;
235  while (--num >= 0)
236  {
237  char c = path[num];
238  if (c == '.')
239  {
240  text = path.Substring(0, num);
241  break;
242  }
244  {
245  break;
246  }
247  }
248  if (extension != null && path.Length != 0)
249  {
250  if (extension.Length == 0 || extension[0] != '.')
251  {
252  text += ".";
253  }
254  text += extension;
255  }
256  return text;
257  }
258  return null;
259  }
260 
267  [__DynamicallyInvokable]
268  public static string GetDirectoryName(string path)
269  {
270  return InternalGetDirectoryName(path);
271  }
272 
273  [SecuritySafeCritical]
274  private static string InternalGetDirectoryName(string path)
275  {
276  if (path != null)
277  {
278  CheckInvalidPathChars(path);
279  string text = NormalizePath(path, fullCheck: false, AppContextSwitches.UseLegacyPathHandling);
280  if (path.Length > 0 && !CodeAccessSecurityEngine.QuickCheckForAllDemands())
281  {
282  try
283  {
284  string text2 = RemoveLongPathPrefix(path);
285  int i;
286  for (i = 0; i < text2.Length && text2[i] != '?' && text2[i] != '*'; i++)
287  {
288  }
289  if (i > 0)
290  {
291  GetFullPath(text2.Substring(0, i));
292  }
293  }
294  catch (SecurityException)
295  {
296  if (path.IndexOf("~", StringComparison.Ordinal) != -1)
297  {
298  text = NormalizePath(path, fullCheck: false, expandShortPaths: false);
299  }
300  }
301  catch (PathTooLongException)
302  {
303  }
304  catch (NotSupportedException)
305  {
306  }
307  catch (IOException)
308  {
309  }
310  catch (ArgumentException)
311  {
312  }
313  }
314  path = text;
315  int rootLength = GetRootLength(path);
316  int length = path.Length;
317  if (length > rootLength)
318  {
319  length = path.Length;
320  if (length == rootLength)
321  {
322  return null;
323  }
324  while (length > rootLength && path[--length] != DirectorySeparatorChar && path[length] != AltDirectorySeparatorChar)
325  {
326  }
327  return path.Substring(0, length);
328  }
329  }
330  return null;
331  }
332 
333  internal static int GetRootLength(string path)
334  {
335  CheckInvalidPathChars(path);
336  if (AppContextSwitches.UseLegacyPathHandling)
337  {
338  return LegacyGetRootLength(path);
339  }
340  return PathInternal.GetRootLength(path);
341  }
342 
343  private static int LegacyGetRootLength(string path)
344  {
345  int i = 0;
346  int length = path.Length;
347  if (length >= 1 && IsDirectorySeparator(path[0]))
348  {
349  i = 1;
350  if (length >= 2 && IsDirectorySeparator(path[1]))
351  {
352  i = 2;
353  int num = 2;
354  for (; i < length; i++)
355  {
356  if ((path[i] == DirectorySeparatorChar || path[i] == AltDirectorySeparatorChar) && --num <= 0)
357  {
358  break;
359  }
360  }
361  }
362  }
363  else if (length >= 2 && path[1] == VolumeSeparatorChar)
364  {
365  i = 2;
366  if (length >= 3 && IsDirectorySeparator(path[2]))
367  {
368  i++;
369  }
370  }
371  return i;
372  }
373 
374  internal static bool IsDirectorySeparator(char c)
375  {
376  if (c != DirectorySeparatorChar)
377  {
378  return c == AltDirectorySeparatorChar;
379  }
380  return true;
381  }
382 
385  [__DynamicallyInvokable]
386  public static char[] GetInvalidPathChars()
387  {
388  return (char[])RealInvalidPathChars.Clone();
389  }
390 
393  [__DynamicallyInvokable]
394  public static char[] GetInvalidFileNameChars()
395  {
396  return (char[])InvalidFileNameChars.Clone();
397  }
398 
404  [__DynamicallyInvokable]
405  public static string GetExtension(string path)
406  {
407  if (path == null)
408  {
409  return null;
410  }
411  CheckInvalidPathChars(path);
412  int length = path.Length;
413  int num = length;
414  while (--num >= 0)
415  {
416  char c = path[num];
417  if (c == '.')
418  {
419  if (num != length - 1)
420  {
421  return path.Substring(num, length - num);
422  }
423  return string.Empty;
424  }
426  {
427  break;
428  }
429  }
430  return string.Empty;
431  }
432 
444  [SecuritySafeCritical]
445  [__DynamicallyInvokable]
446  public static string GetFullPath(string path)
447  {
448  string fullPathInternal = GetFullPathInternal(path);
449  FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, fullPathInternal, checkForDuplicates: false, needFullPath: false);
450  return fullPathInternal;
451  }
452 
453  [SecurityCritical]
454  internal static string UnsafeGetFullPath(string path)
455  {
456  string fullPathInternal = GetFullPathInternal(path);
457  FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, fullPathInternal, checkForDuplicates: false, needFullPath: false);
458  return fullPathInternal;
459  }
460 
461  internal static string GetFullPathInternal(string path)
462  {
463  if (path == null)
464  {
465  throw new ArgumentNullException("path");
466  }
467  return NormalizePath(path, fullCheck: true);
468  }
469 
470  [SecuritySafeCritical]
471  internal static string NormalizePath(string path, bool fullCheck)
472  {
473  return NormalizePath(path, fullCheck, AppContextSwitches.BlockLongPaths ? 260 : 32767);
474  }
475 
476  [SecuritySafeCritical]
477  internal static string NormalizePath(string path, bool fullCheck, bool expandShortPaths)
478  {
479  return NormalizePath(path, fullCheck, MaxPath, expandShortPaths);
480  }
481 
482  [SecuritySafeCritical]
483  internal static string NormalizePath(string path, bool fullCheck, int maxPathLength)
484  {
485  return NormalizePath(path, fullCheck, maxPathLength, expandShortPaths: true);
486  }
487 
488  [SecuritySafeCritical]
489  internal static string NormalizePath(string path, bool fullCheck, int maxPathLength, bool expandShortPaths)
490  {
491  if (AppContextSwitches.UseLegacyPathHandling)
492  {
493  return LegacyNormalizePath(path, fullCheck, maxPathLength, expandShortPaths);
494  }
495  if (PathInternal.IsExtended(path))
496  {
497  return path;
498  }
499  string text = null;
500  text = (fullCheck ? NewNormalizePath(path, maxPathLength, expandShortPaths: true) : NewNormalizePathLimitedChecks(path, maxPathLength, expandShortPaths));
501  if (string.IsNullOrWhiteSpace(text))
502  {
503  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
504  }
505  return text;
506  }
507 
508  [SecuritySafeCritical]
509  private static string NewNormalizePathLimitedChecks(string path, int maxPathLength, bool expandShortPaths)
510  {
511  string text = PathInternal.NormalizeDirectorySeparators(path);
512  if (PathInternal.IsPathTooLong(text) || PathInternal.AreSegmentsTooLong(text))
513  {
514  throw new PathTooLongException();
515  }
516  if (expandShortPaths && text.IndexOf('~') != -1)
517  {
518  try
519  {
520  return LongPathHelper.GetLongPathName(text);
521  }
522  catch
523  {
524  return text;
525  }
526  }
527  return text;
528  }
529 
530  [SecuritySafeCritical]
531  private static string NewNormalizePath(string path, int maxPathLength, bool expandShortPaths)
532  {
533  if (path.IndexOf('\0') != -1)
534  {
535  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
536  }
537  if (string.IsNullOrWhiteSpace(path))
538  {
539  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
540  }
541  return LongPathHelper.Normalize(path, (uint)maxPathLength, !PathInternal.IsDevice(path), expandShortPaths);
542  }
543 
544  [SecurityCritical]
545  internal unsafe static string LegacyNormalizePath(string path, bool fullCheck, int maxPathLength, bool expandShortPaths)
546  {
547  if (fullCheck)
548  {
549  path = path.TrimEnd(TrimEndChars);
550  if (PathInternal.AnyPathHasIllegalCharacters(path))
551  {
552  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
553  }
554  }
555  int i = 0;
556  PathHelper pathHelper;
557  if (path.Length + 1 > MaxPath)
558  {
559  pathHelper = new PathHelper(path.Length + MaxPath, maxPathLength);
560  }
561  else
562  {
563  char* charArrayPtr = stackalloc char[MaxPath];
564  pathHelper = new PathHelper(charArrayPtr, MaxPath);
565  }
566  uint num = 0u;
567  uint num2 = 0u;
568  bool flag = false;
569  uint num3 = 0u;
570  int num4 = -1;
571  bool flag2 = false;
572  bool flag3 = true;
573  int num5 = 0;
574  bool flag4 = false;
575  if (path.Length > 0 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar))
576  {
577  pathHelper.Append('\\');
578  i++;
579  num4 = 0;
580  }
581  for (; i < path.Length; i++)
582  {
583  char c = path[i];
585  {
586  if (num3 == 0)
587  {
588  if (num2 != 0)
589  {
590  int num6 = num4 + 1;
591  if (path[num6] != '.')
592  {
593  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
594  }
595  if (num2 >= 2)
596  {
597  if (flag2 && num2 > 2)
598  {
599  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
600  }
601  if (path[num6 + 1] == '.')
602  {
603  for (int j = num6 + 2; j < num6 + num2; j++)
604  {
605  if (path[j] != '.')
606  {
607  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
608  }
609  }
610  num2 = 2u;
611  }
612  else
613  {
614  if (num2 > 1)
615  {
616  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
617  }
618  num2 = 1u;
619  }
620  }
621  if (num2 == 2)
622  {
623  pathHelper.Append('.');
624  }
625  pathHelper.Append('.');
626  flag = false;
627  }
628  if (num != 0 && flag3 && i + 1 < path.Length && (path[i + 1] == DirectorySeparatorChar || path[i + 1] == AltDirectorySeparatorChar))
629  {
630  pathHelper.Append(DirectorySeparatorChar);
631  }
632  }
633  num2 = 0u;
634  num = 0u;
635  if (!flag)
636  {
637  flag = true;
638  pathHelper.Append(DirectorySeparatorChar);
639  }
640  num3 = 0u;
641  num4 = i;
642  flag2 = false;
643  flag3 = false;
644  if (flag4)
645  {
646  pathHelper.TryExpandShortFileName();
647  flag4 = false;
648  }
649  int num7 = pathHelper.Length - 1;
650  if (num7 - num5 > MaxDirectoryLength)
651  {
652  throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
653  }
654  num5 = num7;
655  continue;
656  }
657  switch (c)
658  {
659  case '.':
660  num2++;
661  continue;
662  case ' ':
663  num++;
664  continue;
665  }
666  if (c == '~' && expandShortPaths)
667  {
668  flag4 = true;
669  }
670  flag = false;
671  if (flag3 && c == VolumeSeparatorChar)
672  {
673  char c2 = (i > 0) ? path[i - 1] : ' ';
674  if (num2 != 0 || num3 < 1 || c2 == ' ')
675  {
676  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
677  }
678  flag2 = true;
679  if (num3 > 1)
680  {
681  int k;
682  for (k = 0; k < pathHelper.Length && pathHelper[k] == ' '; k++)
683  {
684  }
685  if (num3 - k == 1)
686  {
687  pathHelper.Length = 0;
688  pathHelper.Append(c2);
689  }
690  }
691  num3 = 0u;
692  }
693  else
694  {
695  num3 += 1 + num2 + num;
696  }
697  if (num2 != 0 || num != 0)
698  {
699  int num8 = (num4 >= 0) ? (i - num4 - 1) : i;
700  if (num8 > 0)
701  {
702  for (int l = 0; l < num8; l++)
703  {
704  pathHelper.Append(path[num4 + 1 + l]);
705  }
706  }
707  num2 = 0u;
708  num = 0u;
709  }
710  pathHelper.Append(c);
711  num4 = i;
712  }
713  if (pathHelper.Length - 1 - num5 > MaxDirectoryLength)
714  {
715  throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
716  }
717  if (num3 == 0 && num2 != 0)
718  {
719  int num9 = num4 + 1;
720  if (path[num9] != '.')
721  {
722  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
723  }
724  if (num2 >= 2)
725  {
726  if (flag2 && num2 > 2)
727  {
728  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
729  }
730  if (path[num9 + 1] == '.')
731  {
732  for (int m = num9 + 2; m < num9 + num2; m++)
733  {
734  if (path[m] != '.')
735  {
736  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
737  }
738  }
739  num2 = 2u;
740  }
741  else
742  {
743  if (num2 > 1)
744  {
745  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
746  }
747  num2 = 1u;
748  }
749  }
750  if (num2 == 2)
751  {
752  pathHelper.Append('.');
753  }
754  pathHelper.Append('.');
755  }
756  if (pathHelper.Length == 0)
757  {
758  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
759  }
760  if (fullCheck && (pathHelper.OrdinalStartsWith("http:", ignoreCase: false) || pathHelper.OrdinalStartsWith("file:", ignoreCase: false)))
761  {
762  throw new ArgumentException(Environment.GetResourceString("Argument_PathUriFormatNotSupported"));
763  }
764  if (flag4)
765  {
766  pathHelper.TryExpandShortFileName();
767  }
768  int num10 = 1;
769  if (fullCheck)
770  {
771  num10 = pathHelper.GetFullPathName();
772  flag4 = false;
773  for (int n = 0; n < pathHelper.Length; n++)
774  {
775  if (flag4)
776  {
777  break;
778  }
779  if (pathHelper[n] == '~' && expandShortPaths)
780  {
781  flag4 = true;
782  }
783  }
784  if (flag4 && !pathHelper.TryExpandShortFileName())
785  {
786  int num11 = -1;
787  for (int num12 = pathHelper.Length - 1; num12 >= 0; num12--)
788  {
789  if (pathHelper[num12] == DirectorySeparatorChar)
790  {
791  num11 = num12;
792  break;
793  }
794  }
795  if (num11 >= 0)
796  {
797  if (pathHelper.Length >= maxPathLength)
798  {
799  throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
800  }
801  int lenSavedName = pathHelper.Length - num11 - 1;
802  pathHelper.Fixup(lenSavedName, num11);
803  }
804  }
805  }
806  if (num10 != 0 && pathHelper.Length > 1 && pathHelper[0] == '\\' && pathHelper[1] == '\\')
807  {
808  int num13;
809  for (num13 = 2; num13 < num10; num13++)
810  {
811  if (pathHelper[num13] == '\\')
812  {
813  num13++;
814  break;
815  }
816  }
817  if (num13 == num10)
818  {
819  throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegalUNC"));
820  }
821  if (pathHelper.OrdinalStartsWith("\\\\?\\globalroot", ignoreCase: true))
822  {
823  throw new ArgumentException(Environment.GetResourceString("Arg_PathGlobalRoot"));
824  }
825  }
826  if (pathHelper.Length >= maxPathLength)
827  {
828  throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
829  }
830  if (num10 == 0)
831  {
832  int num14 = Marshal.GetLastWin32Error();
833  if (num14 == 0)
834  {
835  num14 = 161;
836  }
837  __Error.WinIOError(num14, path);
838  return null;
839  }
840  string text = pathHelper.ToString();
841  if (string.Equals(text, path, StringComparison.Ordinal))
842  {
843  text = path;
844  }
845  return text;
846  }
847 
848  internal static bool HasLongPathPrefix(string path)
849  {
850  if (AppContextSwitches.UseLegacyPathHandling)
851  {
852  return path.StartsWith("\\\\?\\", StringComparison.Ordinal);
853  }
854  return PathInternal.IsExtended(path);
855  }
856 
857  internal static string AddLongPathPrefix(string path)
858  {
859  if (AppContextSwitches.UseLegacyPathHandling)
860  {
861  if (path.StartsWith("\\\\?\\", StringComparison.Ordinal))
862  {
863  return path;
864  }
865  if (path.StartsWith("\\\\", StringComparison.Ordinal))
866  {
867  return path.Insert(2, "?\\UNC\\");
868  }
869  return "\\\\?\\" + path;
870  }
871  return PathInternal.EnsureExtendedPrefix(path);
872  }
873 
874  internal static string RemoveLongPathPrefix(string path)
875  {
876  if (AppContextSwitches.UseLegacyPathHandling)
877  {
878  if (!path.StartsWith("\\\\?\\", StringComparison.Ordinal))
879  {
880  return path;
881  }
882  if (path.StartsWith("\\\\?\\UNC\\", StringComparison.OrdinalIgnoreCase))
883  {
884  return path.Remove(2, 6);
885  }
886  return path.Substring(4);
887  }
888  return PathInternal.RemoveExtendedPrefix(path);
889  }
890 
891  internal static StringBuilder RemoveLongPathPrefix(StringBuilder pathSB)
892  {
893  if (AppContextSwitches.UseLegacyPathHandling)
894  {
895  if (!PathInternal.StartsWithOrdinal(pathSB, "\\\\?\\"))
896  {
897  return pathSB;
898  }
899  if (PathInternal.StartsWithOrdinal(pathSB, "\\\\?\\UNC\\", ignoreCase: true))
900  {
901  return pathSB.Remove(2, 6);
902  }
903  return pathSB.Remove(0, 4);
904  }
905  return PathInternal.RemoveExtendedPrefix(pathSB);
906  }
907 
913  [__DynamicallyInvokable]
914  public static string GetFileName(string path)
915  {
916  if (path != null)
917  {
918  CheckInvalidPathChars(path);
919  int length = path.Length;
920  int num = length;
921  while (--num >= 0)
922  {
923  char c = path[num];
925  {
926  return path.Substring(num + 1, length - num - 1);
927  }
928  }
929  }
930  return path;
931  }
932 
938  [__DynamicallyInvokable]
939  public static string GetFileNameWithoutExtension(string path)
940  {
941  path = GetFileName(path);
942  if (path != null)
943  {
944  int length;
945  if ((length = path.LastIndexOf('.')) == -1)
946  {
947  return path;
948  }
949  return path.Substring(0, length);
950  }
951  return null;
952  }
953 
960  [__DynamicallyInvokable]
961  public static string GetPathRoot(string path)
962  {
963  if (path == null)
964  {
965  return null;
966  }
967  path = NormalizePath(path, fullCheck: false, expandShortPaths: false);
968  return path.Substring(0, GetRootLength(path));
969  }
970 
974  [SecuritySafeCritical]
975  [__DynamicallyInvokable]
976  public static string GetTempPath()
977  {
978  new EnvironmentPermission(PermissionState.Unrestricted).Demand();
979  StringBuilder stringBuilder = new StringBuilder(260);
980  uint tempPath = Win32Native.GetTempPath(260, stringBuilder);
981  string path = stringBuilder.ToString();
982  if (tempPath == 0)
983  {
984  __Error.WinIOError();
985  }
986  return GetFullPathInternal(path);
987  }
988 
989  internal static bool IsRelative(string path)
990  {
991  return PathInternal.IsPartiallyQualified(path);
992  }
993 
996  [__DynamicallyInvokable]
997  public static string GetRandomFileName()
998  {
999  byte[] array = new byte[10];
1000  RNGCryptoServiceProvider rNGCryptoServiceProvider = null;
1001  try
1002  {
1003  rNGCryptoServiceProvider = new RNGCryptoServiceProvider();
1004  rNGCryptoServiceProvider.GetBytes(array);
1005  char[] array2 = ToBase32StringSuitableForDirName(array).ToCharArray();
1006  array2[8] = '.';
1007  return new string(array2, 0, 12);
1008  }
1009  finally
1010  {
1011  rNGCryptoServiceProvider?.Dispose();
1012  }
1013  }
1014 
1018  [SecuritySafeCritical]
1019  [__DynamicallyInvokable]
1020  public static string GetTempFileName()
1021  {
1022  return InternalGetTempFileName(checkHost: true);
1023  }
1024 
1025  [SecurityCritical]
1026  internal static string UnsafeGetTempFileName()
1027  {
1028  return InternalGetTempFileName(checkHost: false);
1029  }
1030 
1031  [SecurityCritical]
1032  private static string InternalGetTempFileName(bool checkHost)
1033  {
1034  string tempPath = GetTempPath();
1035  FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, tempPath);
1036  StringBuilder stringBuilder = new StringBuilder(260);
1037  if (Win32Native.GetTempFileName(tempPath, "tmp", 0u, stringBuilder) == 0)
1038  {
1039  __Error.WinIOError();
1040  }
1041  return stringBuilder.ToString();
1042  }
1043 
1050  [__DynamicallyInvokable]
1051  public static bool HasExtension(string path)
1052  {
1053  if (path != null)
1054  {
1055  CheckInvalidPathChars(path);
1056  int num = path.Length;
1057  while (--num >= 0)
1058  {
1059  char c = path[num];
1060  if (c == '.')
1061  {
1062  if (num != path.Length - 1)
1063  {
1064  return true;
1065  }
1066  return false;
1067  }
1069  {
1070  break;
1071  }
1072  }
1073  }
1074  return false;
1075  }
1076 
1083  [__DynamicallyInvokable]
1084  public static bool IsPathRooted(string path)
1085  {
1086  if (path != null)
1087  {
1088  CheckInvalidPathChars(path);
1089  int length = path.Length;
1090  if ((length >= 1 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar)) || (length >= 2 && path[1] == VolumeSeparatorChar))
1091  {
1092  return true;
1093  }
1094  }
1095  return false;
1096  }
1097 
1106  [__DynamicallyInvokable]
1107  public static string Combine(string path1, string path2)
1108  {
1109  if (path1 == null || path2 == null)
1110  {
1111  throw new ArgumentNullException((path1 == null) ? "path1" : "path2");
1112  }
1113  CheckInvalidPathChars(path1);
1114  CheckInvalidPathChars(path2);
1115  return CombineNoChecks(path1, path2);
1116  }
1117 
1127  [__DynamicallyInvokable]
1128  public static string Combine(string path1, string path2, string path3)
1129  {
1130  if (path1 == null || path2 == null || path3 == null)
1131  {
1132  throw new ArgumentNullException((path1 == null) ? "path1" : ((path2 == null) ? "path2" : "path3"));
1133  }
1134  CheckInvalidPathChars(path1);
1135  CheckInvalidPathChars(path2);
1136  CheckInvalidPathChars(path3);
1137  return CombineNoChecks(CombineNoChecks(path1, path2), path3);
1138  }
1139 
1150  public static string Combine(string path1, string path2, string path3, string path4)
1151  {
1152  if (path1 == null || path2 == null || path3 == null || path4 == null)
1153  {
1154  throw new ArgumentNullException((path1 == null) ? "path1" : ((path2 == null) ? "path2" : ((path3 == null) ? "path3" : "path4")));
1155  }
1156  CheckInvalidPathChars(path1);
1157  CheckInvalidPathChars(path2);
1158  CheckInvalidPathChars(path3);
1159  CheckInvalidPathChars(path4);
1160  return CombineNoChecks(CombineNoChecks(CombineNoChecks(path1, path2), path3), path4);
1161  }
1162 
1168  [__DynamicallyInvokable]
1169  public static string Combine(params string[] paths)
1170  {
1171  if (paths == null)
1172  {
1173  throw new ArgumentNullException("paths");
1174  }
1175  int num = 0;
1176  int num2 = 0;
1177  for (int i = 0; i < paths.Length; i++)
1178  {
1179  if (paths[i] == null)
1180  {
1181  throw new ArgumentNullException("paths");
1182  }
1183  if (paths[i].Length != 0)
1184  {
1185  CheckInvalidPathChars(paths[i]);
1186  if (IsPathRooted(paths[i]))
1187  {
1188  num2 = i;
1189  num = paths[i].Length;
1190  }
1191  else
1192  {
1193  num += paths[i].Length;
1194  }
1195  char c = paths[i][paths[i].Length - 1];
1197  {
1198  num++;
1199  }
1200  }
1201  }
1202  StringBuilder stringBuilder = StringBuilderCache.Acquire(num);
1203  for (int j = num2; j < paths.Length; j++)
1204  {
1205  if (paths[j].Length == 0)
1206  {
1207  continue;
1208  }
1209  if (stringBuilder.Length == 0)
1210  {
1211  stringBuilder.Append(paths[j]);
1212  continue;
1213  }
1214  char c2 = stringBuilder[stringBuilder.Length - 1];
1216  {
1217  stringBuilder.Append(DirectorySeparatorChar);
1218  }
1219  stringBuilder.Append(paths[j]);
1220  }
1221  return StringBuilderCache.GetStringAndRelease(stringBuilder);
1222  }
1223 
1224  private static string CombineNoChecks(string path1, string path2)
1225  {
1226  if (path2.Length == 0)
1227  {
1228  return path1;
1229  }
1230  if (path1.Length == 0)
1231  {
1232  return path2;
1233  }
1234  if (IsPathRooted(path2))
1235  {
1236  return path2;
1237  }
1238  char c = path1[path1.Length - 1];
1240  {
1241  return path1 + "\\" + path2;
1242  }
1243  return path1 + path2;
1244  }
1245 
1246  internal static string ToBase32StringSuitableForDirName(byte[] buff)
1247  {
1248  StringBuilder stringBuilder = StringBuilderCache.Acquire();
1249  int num = buff.Length;
1250  int num2 = 0;
1251  do
1252  {
1253  byte b = (byte)((num2 < num) ? buff[num2++] : 0);
1254  byte b2 = (byte)((num2 < num) ? buff[num2++] : 0);
1255  byte b3 = (byte)((num2 < num) ? buff[num2++] : 0);
1256  byte b4 = (byte)((num2 < num) ? buff[num2++] : 0);
1257  byte b5 = (byte)((num2 < num) ? buff[num2++] : 0);
1258  stringBuilder.Append(s_Base32Char[b & 0x1F]);
1259  stringBuilder.Append(s_Base32Char[b2 & 0x1F]);
1260  stringBuilder.Append(s_Base32Char[b3 & 0x1F]);
1261  stringBuilder.Append(s_Base32Char[b4 & 0x1F]);
1262  stringBuilder.Append(s_Base32Char[b5 & 0x1F]);
1263  stringBuilder.Append(s_Base32Char[((b & 0xE0) >> 5) | ((b4 & 0x60) >> 2)]);
1264  stringBuilder.Append(s_Base32Char[((b2 & 0xE0) >> 5) | ((b5 & 0x60) >> 2)]);
1265  b3 = (byte)(b3 >> 5);
1266  if ((b4 & 0x80) != 0)
1267  {
1268  b3 = (byte)(b3 | 8);
1269  }
1270  if ((b5 & 0x80) != 0)
1271  {
1272  b3 = (byte)(b3 | 0x10);
1273  }
1274  stringBuilder.Append(s_Base32Char[b3]);
1275  }
1276  while (num2 < num);
1277  return StringBuilderCache.GetStringAndRelease(stringBuilder);
1278  }
1279 
1280  internal static void CheckSearchPattern(string searchPattern)
1281  {
1282  while (true)
1283  {
1284  int num;
1285  if ((num = searchPattern.IndexOf("..", StringComparison.Ordinal)) != -1)
1286  {
1287  if (num + 2 == searchPattern.Length)
1288  {
1289  throw new ArgumentException(Environment.GetResourceString("Arg_InvalidSearchPattern"));
1290  }
1291  if (searchPattern[num + 2] == DirectorySeparatorChar || searchPattern[num + 2] == AltDirectorySeparatorChar)
1292  {
1293  break;
1294  }
1295  searchPattern = searchPattern.Substring(num + 2);
1296  continue;
1297  }
1298  return;
1299  }
1300  throw new ArgumentException(Environment.GetResourceString("Arg_InvalidSearchPattern"));
1301  }
1302 
1303  internal static void CheckInvalidPathChars(string path, bool checkAdditional = false)
1304  {
1305  if (path == null)
1306  {
1307  throw new ArgumentNullException("path");
1308  }
1309  if (PathInternal.HasIllegalCharacters(path, checkAdditional))
1310  {
1311  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
1312  }
1313  }
1314 
1315  internal static string InternalCombine(string path1, string path2)
1316  {
1317  if (path1 == null || path2 == null)
1318  {
1319  throw new ArgumentNullException((path1 == null) ? "path1" : "path2");
1320  }
1321  CheckInvalidPathChars(path1);
1322  CheckInvalidPathChars(path2);
1323  if (path2.Length == 0)
1324  {
1325  throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), "path2");
1326  }
1327  if (IsPathRooted(path2))
1328  {
1329  throw new ArgumentException(Environment.GetResourceString("Arg_Path2IsRooted"), "path2");
1330  }
1331  int length = path1.Length;
1332  if (length == 0)
1333  {
1334  return path2;
1335  }
1336  char c = path1[length - 1];
1338  {
1339  return path1 + "\\" + path2;
1340  }
1341  return path1 + path2;
1342  }
1343  }
1344 }
static string GetExtension(string path)
Returns the extension of the specified path string.
Definition: Path.cs:405
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
FileIOPermissionAccess
Specifies the type of file access requested.
static char [] GetInvalidPathChars()
Gets an array containing the characters that are not allowed in path names.
Definition: Path.cs:386
unsafe override string ToString()
Converts the value of this instance to a T:System.String.
static string Combine(string path1, string path2)
Combines two strings into a path.
Definition: Path.cs:1107
StringComparison
Specifies the culture, case, and sort rules to be used by certain overloads of the M:System....
Definition: __Canon.cs:3
static readonly char [] InvalidPathChars
Provides a platform-specific array of characters that cannot be specified in path string arguments pa...
Definition: Path.cs:32
static string GetPathRoot(string path)
Gets the root directory information of the specified path.
Definition: Path.cs:961
static readonly char AltDirectorySeparatorChar
Provides a platform-specific alternate character used to separate directory levels in a path string t...
Definition: Path.cs:23
override void GetBytes(byte[] data)
Fills an array of bytes with a cryptographically strong sequence of random values.
static string GetFileName(string path)
Returns the file name and extension of the specified path string.
Definition: Path.cs:914
static readonly char DirectorySeparatorChar
Provides a platform-specific character used to separate directory levels in a path string that reflec...
Definition: Path.cs:17
static string GetTempFileName()
Creates a uniquely named, zero-byte temporary file on disk and returns the full path of that file.
Definition: Path.cs:1020
Implements a cryptographic Random Number Generator (RNG) using the implementation provided by the cry...
override void Dispose(bool disposing)
When overridden in a derived class, releases the unmanaged resources used by the T:System....
static string Combine(string path1, string path2, string path3)
Combines three strings into a path.
Definition: Path.cs:1128
StringBuilder Append(char value, int repeatCount)
Appends a specified number of copies of the string representation of a Unicode character to this inst...
int Length
Gets or sets the length of the current T:System.Text.StringBuilder object.
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
static string GetFullPath(string path)
Returns the absolute path for the specified path string.
Definition: Path.cs:446
static readonly char PathSeparator
A platform-specific separator character used to separate path strings in environment variables.
Definition: Path.cs:165
static char [] GetInvalidFileNameChars()
Gets an array containing the characters that are not allowed in file names.
Definition: Path.cs:394
Represents a mutable string of characters. This class cannot be inherited.To browse the ....
void Demand()
Forces a T:System.Security.SecurityException at run time if all callers higher in the call stack have...
static bool HasExtension(string path)
Determines whether a path includes a file name extension.
Definition: Path.cs:1051
PermissionState
Specifies whether a permission should have all or no access to resources at creation.
static string GetTempPath()
Returns the path of the current user's temporary folder.
Definition: Path.cs:976
Controls access to system and user environment variables. This class cannot be inherited.
static string GetDirectoryName(string path)
Returns the directory information for the specified path string.
Definition: Path.cs:268
Controls the ability to access files and folders. This class cannot be inherited.
static string GetRandomFileName()
Returns a random folder name or file name.
Definition: Path.cs:997
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...
static string Combine(string path1, string path2, string path3, string path4)
Combines four strings into a path.
Definition: Path.cs:1150
static bool IsPathRooted(string path)
Gets a value indicating whether the specified path string contains a root.
Definition: Path.cs:1084
The exception that is thrown when a security error is detected.
Performs operations on T:System.String instances that contain file or directory path information....
Definition: Path.cs:13
static string Combine(params string[] paths)
Combines an array of strings into a path.
Definition: Path.cs:1169
static string GetFileNameWithoutExtension(string path)
Returns the file name of the specified path string without the extension.
Definition: Path.cs:939
static readonly char VolumeSeparatorChar
Provides a platform-specific volume separator character.
Definition: Path.cs:27
StringBuilder Remove(int startIndex, int length)
Removes the specified range of characters from this instance.
static string ChangeExtension(string path, string extension)
Changes the extension of a path string.
Definition: Path.cs:228