public static bool CreateDirectory(string path, bool isRecursive = false) { if (!isRecursive) { return(Win32Native.CreateDirectory(string.Concat(@"\\?\", path), null)); } var tmpDir = new DirectoryInfo(path); if (Directory.Exists(tmpDir.Parent.FullName)) { return(Win32Native.CreateDirectory(string.Concat(@"\\?\", path), null)); } else { return(CreateDirectory(tmpDir.Parent.FullName)); } }
internal static void InternalCreateDirectory(String fullPath, String path) { int length = fullPath.Length; // We need to trim the trailing slash or the code will try to create 2 directories of the same name. if (length >= 2 && Path.IsDirectorySeparator(fullPath[length - 1])) { length--; } int i = Path.GetRootLength(fullPath); #if !PLATFORM_UNIX // For UNC paths that are only // or /// if (length == 2 && Path.IsDirectorySeparator(fullPath[1])) { throw new IOException(String.Format(Environment.GetResourceString("IO.IO_CannotCreateDirectory"), path)); } #endif // !PLATFORM_UNIX ArrayList list = new ArrayList(); while (i < length) { i++; while (i < length && fullPath[i] != Path.DirectorySeparatorChar && fullPath[i] != Path.AltDirectorySeparatorChar) { i++; } String dir = fullPath.Substring(0, i); if (!InternalExists(dir)) // Create only the ones missing { list.Add(dir); } } if (list.Count != 0) { String [] securityList = (String[])list.ToArray(typeof(String)); for (int j = 0; j < securityList.Length; j++) { securityList[j] += "\\."; // leafs will never has a slash at the end } // Security check for all directories not present only. new FileIOPermission(FileIOPermissionAccess.Write, securityList, false, false).Demand(); } // We need this check to mask OS differences // Handle CreateDirectory("X:\\") when X: doesn't exist. Similarly for n/w paths. String root = InternalGetDirectoryRoot(fullPath); if (!InternalExists(root)) { __Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, root); } // If all the security checks succeeded create all the directories for (int j = 0; j < list.Count; j++) { String name = (String)list[j]; if (name.Length > Path.MAX_DIRECTORY_PATH) { throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); } bool r = Win32Native.CreateDirectory(name, 0); if (!r) { __Error.WinIOError(Marshal.GetLastWin32Error(), Path.GetDirectoryName(name)); } } }
public static bool CreateDirectory(string path) { return(Win32Native.CreateDirectory(String.Concat(@"\\?\", path), null)); }
private static unsafe void InternalCreateDirectory(string fullPath, string path, object dirSecurityObj) { DirectorySecurity security = (DirectorySecurity)dirSecurityObj; int length = fullPath.Length; if ((length >= 2) && Path.IsDirectorySeparator(fullPath[length - 1])) { length--; } int rootLength = LongPath.GetRootLength(fullPath); if ((length == 2) && Path.IsDirectorySeparator(fullPath[1])) { throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", new object[] { path })); } List <string> list = new List <string>(); bool flag = false; if (length > rootLength) { for (int i = length - 1; (i >= rootLength) && !flag; i--) { string str = fullPath.Substring(0, i + 1); if (!InternalExists(str)) { list.Add(str); } else { flag = true; } while (((i > rootLength) && (fullPath[i] != Path.DirectorySeparatorChar)) && (fullPath[i] != Path.AltDirectorySeparatorChar)) { i--; } } } int count = list.Count; if (list.Count != 0) { string[] array = new string[list.Count]; list.CopyTo(array, 0); for (int j = 0; j < array.Length; j++) { string[] strArray2; IntPtr ptr; (strArray2 = array)[(int)(ptr = (IntPtr)j)] = strArray2[(int)ptr] + @"\."; } AccessControlActions control = (security == null) ? AccessControlActions.None : AccessControlActions.Change; new FileIOPermission(FileIOPermissionAccess.Write, control, array, false, false).Demand(); } Win32Native.SECURITY_ATTRIBUTES structure = null; if (security != null) { structure = new Win32Native.SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(structure) }; byte[] securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm(); byte * pDest = stackalloc byte[(IntPtr)securityDescriptorBinaryForm.Length]; Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length); structure.pSecurityDescriptor = pDest; } bool flag2 = true; int errorCode = 0; string maybeFullPath = path; while (list.Count > 0) { string str3 = list[list.Count - 1]; list.RemoveAt(list.Count - 1); if (str3.Length >= Path.MaxLongPath) { throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); } flag2 = Win32Native.CreateDirectory(Path.AddLongPathPrefix(str3), structure); if (!flag2 && (errorCode == 0)) { int lastError = Marshal.GetLastWin32Error(); if (lastError != 0xb7) { errorCode = lastError; } else if (LongPathFile.InternalExists(str3) || (!InternalExists(str3, out lastError) && (lastError == 5))) { errorCode = lastError; try { new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new string[] { GetDemandDir(str3, true) }, false, false).Demand(); maybeFullPath = str3; continue; } catch (SecurityException) { continue; } } } } if ((count == 0) && !flag) { if (!InternalExists(InternalGetDirectoryRoot(fullPath))) { __Error.WinIOError(3, InternalGetDirectoryRoot(path)); } } else if (!flag2 && (errorCode != 0)) { __Error.WinIOError(errorCode, maybeFullPath); } }
private unsafe static void InternalCreateDirectory(string fullPath, string path, object dirSecurityObj) { DirectorySecurity directorySecurity = (DirectorySecurity)dirSecurityObj; int num = fullPath.Length; if (num >= 2 && Path.IsDirectorySeparator(fullPath[num - 1])) { num--; } int rootLength = LongPath.GetRootLength(fullPath); if (num == 2 && Path.IsDirectorySeparator(fullPath[1])) { throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", new object[] { path })); } List <string> list = new List <string>(); bool flag = false; if (num > rootLength) { int num2 = num - 1; while (num2 >= rootLength && !flag) { string text = fullPath.Substring(0, num2 + 1); if (!LongPathDirectory.InternalExists(text)) { list.Add(text); } else { flag = true; } while (num2 > rootLength && fullPath[num2] != Path.DirectorySeparatorChar && fullPath[num2] != Path.AltDirectorySeparatorChar) { num2--; } num2--; } } int count = list.Count; if (list.Count != 0 && !CodeAccessSecurityEngine.QuickCheckForAllDemands()) { string[] array = new string[list.Count]; list.CopyTo(array, 0); for (int i = 0; i < array.Length; i++) { string[] array2 = array; int num3 = i; array2[num3] += "\\."; } AccessControlActions control = (directorySecurity == null) ? AccessControlActions.None : AccessControlActions.Change; FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, control, array, false, false); } Win32Native.SECURITY_ATTRIBUTES security_ATTRIBUTES = null; if (directorySecurity != null) { security_ATTRIBUTES = new Win32Native.SECURITY_ATTRIBUTES(); security_ATTRIBUTES.nLength = Marshal.SizeOf <Win32Native.SECURITY_ATTRIBUTES>(security_ATTRIBUTES); byte[] securityDescriptorBinaryForm = directorySecurity.GetSecurityDescriptorBinaryForm(); byte * ptr = stackalloc byte[checked (unchecked ((UIntPtr)securityDescriptorBinaryForm.Length) * 1)]; Buffer.Memcpy(ptr, 0, securityDescriptorBinaryForm, 0, securityDescriptorBinaryForm.Length); security_ATTRIBUTES.pSecurityDescriptor = ptr; } bool flag2 = true; int num4 = 0; string maybeFullPath = path; while (list.Count > 0) { string text2 = list[list.Count - 1]; list.RemoveAt(list.Count - 1); if (text2.Length >= 32767) { throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); } flag2 = Win32Native.CreateDirectory(PathInternal.EnsureExtendedPrefix(text2), security_ATTRIBUTES); if (!flag2 && num4 == 0) { int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != 183) { num4 = lastWin32Error; } else if (LongPathFile.InternalExists(text2) || (!LongPathDirectory.InternalExists(text2, out lastWin32Error) && lastWin32Error == 5)) { num4 = lastWin32Error; try { FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, LongPathDirectory.GetDemandDir(text2, true), false, false); maybeFullPath = text2; } catch (SecurityException) { } } } } if (count == 0 && !flag) { string path2 = LongPathDirectory.InternalGetDirectoryRoot(fullPath); if (!LongPathDirectory.InternalExists(path2)) { __Error.WinIOError(3, LongPathDirectory.InternalGetDirectoryRoot(path)); } return; } if (!flag2 && num4 != 0) { __Error.WinIOError(num4, maybeFullPath); } }
internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj) { int length = fullPath.Length; // We need to trim the trailing slash or the code will try to create 2 directories of the same name. if (length >= 2 && PathInternal.IsDirectorySeparator(fullPath[length - 1])) { length--; } int lengthRoot = PathInternal.GetRootLength(fullPath); // For UNC paths that are only // or /// if (length == 2 && PathInternal.IsDirectorySeparator(fullPath[1])) { throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", path)); } // We can save a bunch of work if the directory we want to create already exists. This also // saves us in the case where sub paths are inaccessible (due to ERROR_ACCESS_DENIED) but the // final path is accessable and the directory already exists. For example, consider trying // to create c:\Foo\Bar\Baz, where everything already exists but ACLS prevent access to c:\Foo // and c:\Foo\Bar. In that case, this code will think it needs to create c:\Foo, and c:\Foo\Bar // and fail to due so, causing an exception to be thrown. This is not what we want. if (InternalExists(fullPath)) { return; } List <string> stackDir = new List <string>(); // Attempt to figure out which directories don't exist, and only // create the ones we need. Note that InternalExists may fail due // to Win32 ACL's preventing us from seeing a directory, and this // isn't threadsafe. bool somepathexists = false; if (length > lengthRoot) // Special case root (fullpath = X:\\) { int i = length - 1; while (i >= lengthRoot && !somepathexists) { String dir = fullPath.Substring(0, i + 1); if (!InternalExists(dir)) // Create only the ones missing { stackDir.Add(dir); } else { somepathexists = true; } while (i > lengthRoot && fullPath[i] != Path.DirectorySeparatorChar && fullPath[i] != Path.AltDirectorySeparatorChar) { i--; } i--; } } int count = stackDir.Count; // If we were passed a DirectorySecurity, convert it to a security // descriptor and set it in he call to CreateDirectory. Win32Native.SECURITY_ATTRIBUTES secAttrs = null; bool r = true; int firstError = 0; String errorString = path; // If all the security checks succeeded create all the directories while (stackDir.Count > 0) { String name = stackDir[stackDir.Count - 1]; stackDir.RemoveAt(stackDir.Count - 1); if (PathInternal.IsDirectoryTooLong(name)) { throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong")); } r = Win32Native.CreateDirectory(name, secAttrs); if (!r && (firstError == 0)) { int currentError = Marshal.GetLastWin32Error(); // While we tried to avoid creating directories that don't // exist above, there are at least two cases that will // cause us to see ERROR_ALREADY_EXISTS here. InternalExists // can fail because we didn't have permission to the // directory. Secondly, another thread or process could // create the directory between the time we check and the // time we try using the directory. Thirdly, it could // fail because the target does exist, but is a file. if (currentError != Win32Native.ERROR_ALREADY_EXISTS) { firstError = currentError; } else { // If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw. if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) { firstError = currentError; errorString = name; } } } } // We need this check to mask OS differences // Handle CreateDirectory("X:\\foo") when X: doesn't exist. Similarly for n/w paths. if ((count == 0) && !somepathexists) { String root = InternalGetDirectoryRoot(fullPath); if (!InternalExists(root)) { // Extract the root from the passed in path again for security. __Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, InternalGetDirectoryRoot(path)); } return; } // Only throw an exception if creating the exact directory we // wanted failed to work correctly. if (!r && (firstError != 0)) { __Error.WinIOError(firstError, errorString); } }