void internal_watcher_Renamed(object sender, RenamedEventArgs e) { int change_index = -1; int new_index = -1; int[] affected_interval = new int[2]; WIN32_FIND_DATA new_data = new WIN32_FIND_DATA(); if (WinAPiFSwrapper.GetFileInfo(e.Name, ref new_data)) { change_index = internal_find_name(e.OldName); if (change_index == -1) { return; } internal_list.RemoveAt(change_index); internal_list.Add(new_data, null); new_index = internal_list.IndexOfKey(new_data); if (new_index == change_index) { OnItemUpdate(new_index); } else { affected_interval[0] = Math.Min(change_index, new_index); affected_interval[1] = Math.Max(change_index, new_index); for (int i = affected_interval[0]; i <= affected_interval[1]; i++) { OnItemUpdate(i); } } } }
void internal_watcher_Created(object sender, FileSystemEventArgs e) { int new_index = -1; WIN32_FIND_DATA new_data = new WIN32_FIND_DATA(); //new file or folder if (WinAPiFSwrapper.GetFileInfo(e.FullPath, ref new_data)) { internal_list.Add(new_data, null); new_index = internal_list.IndexOfKey(new_data); //we updates all items from new_index to end for (int i = new_index; i < internal_list.Count; i++) { OnItemUpdate(i); } if ((new_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { cache_directory_count++; } else { cache_files_count++; cache_size += new_data.FileSize; } OnAfterSummaryUpdate(); } }
private void FillStandardPage(string file_name) { IntPtr file_handle = IntPtr.Zero; string nt_file_name = IOhelper.GetUnicodePath(file_name); try { textBoxName.Text = string.Format ("{0}", Path.GetFileName(file_name)); // find data -------------------------------------- WIN32_FIND_DATA f_data = new WIN32_FIND_DATA(); WinAPiFSwrapper.GetFileInfo(file_name, ref f_data); textBoxAttributes.Text = f_data.dwFileAttributes.ToString(); textBoxAltname.Text = f_data.cAlternateFileName; textBoxReaprseTag.Text = f_data.ReparseTag.ToString(); //-------------------------------------------------- fileSystemSecurityViewer1.FillContains(file_name); try { fill_basic_info(); //fill_device(); fill_standard_info(); //fill_volume_attr(); //fill_volume_info(); fill_links(f_data.ReparseTag); fill_dir_size(); } catch (Exception ex) { Messages.ShowException(ex); } try { streamViewer1.FillContents(file_name); } catch (Exception) { } } catch (Exception ex) { Messages.ShowException(ex); } finally { if ((file_handle != IntPtr.Zero) && (file_handle.ToInt32() != WinApiFS.INVALID_HANDLE_VALUE)) { WinApiFS.CloseHandle(file_handle); } } }
void internal_watcher_Changed(object sender, FileSystemEventArgs e) { //find affected DATA item int change_index = -1; int new_index = -1; int[] affected_interval = new int[2]; WIN32_FIND_DATA new_data = new WIN32_FIND_DATA(); WIN32_FIND_DATA old_data = new WIN32_FIND_DATA(); if (WinAPiFSwrapper.GetFileInfo(e.FullPath, ref new_data)) { change_index = internal_find_name(e.Name); if (change_index == -1) { //not found - does not occur, but... return; } old_data = internal_list.Keys[change_index]; internal_list.RemoveAt(change_index); internal_list.Add(new_data, null); new_index = internal_list.IndexOfKey(new_data); if (new_index == change_index) { //updated item in same order - update only one item OnItemUpdate(new_index); } else { //updated item change its index //in this case affected items is within new_index and change_index inclusive affected_interval[0] = Math.Min(change_index, new_index); affected_interval[1] = Math.Max(change_index, new_index); for (int i = affected_interval[0]; i <= affected_interval[1]; i++) { OnItemUpdate(i); } } //summary update cache_size = cache_size - old_data.FileSize + new_data.FileSize; OnAfterSummaryUpdate(); } }
/// <summary> /// create new empty dir, copy security attr if needed /// </summary> /// <param name="source_dir">may be empty string</param> /// <param name="destination_dir"></param> private void create_empty_dir(string source_dir, string destination_dir) { var dest_dir_data = new WIN32_FIND_DATA(); if (WinAPiFSwrapper.GetFileInfo(destination_dir, ref dest_dir_data)) { //already exists return; } else { if ((!string.IsNullOrEmpty(source_dir)) && ((options & CopyEngineOptions.CopySecurityAttributes) == CopyEngineOptions.CopySecurityAttributes)) { Directory.CreateDirectory(destination_dir, Directory.GetAccessControl(source_dir)); } else { Directory.CreateDirectory(destination_dir); } } }
private long calc_source_size() { ulong ret = 0; var f_count = 0; var d_count = 0; var data = new WIN32_FIND_DATA(); for (var i = 0; i < initial_source.Length; i++) { if (WinAPiFSwrapper.GetFileInfo(initial_source[i], ref data)) { if ((data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { ret += WinAPiFSwrapper.GetDirectoryStat (initial_source[i], true, false, true, ref f_count, ref d_count, null); } else { ret += data.FileSize; } } } return((long)ret); }
protected override void internal_command_proc() { QueryPanelInfoEventArgs e = new QueryPanelInfoEventArgs(); OnQueryCurrentPanel(e); if (e.FocusedIndex == -1) { return; } bool group_mode = false; int[] sel_indices = e.SelectedIndices; //we not need cache selection //becouse e.ItemsCollection must not change (DirectoryList not sort on attributes) group_mode = (sel_indices.Length > 1); DirectoryList dl = (DirectoryList)e.ItemCollection; WIN32_FIND_DATA f_data = new WIN32_FIND_DATA(); string target_file = string.Empty; if (!group_mode) { if (sel_indices.Length == 0) { target_file = Path.Combine(dl.DirectoryPath, dl.GetItemDisplayNameLong(e.FocusedIndex)); } else { target_file = Path.Combine(dl.DirectoryPath, dl.GetItemDisplayNameLong(sel_indices[0])); } if (target_file.EndsWith("..")) { target_file = dl.DirectoryPath; } if (!WinAPiFSwrapper.GetFileInfo(target_file, ref f_data)) { return; } } FileAttributesEditDialog dialog = new FileAttributesEditDialog(); if (!group_mode) { dialog.buttonClear.Enabled = false; set_attributes_to_dialog(dialog, f_data.dwFileAttributes); dialog.Text = String.Format (Options.GetLiteral(Options.LANG_FILE_ATTRIBUTES) + " [{0}]", target_file); } else { dialog.buttonClear.Enabled = true; dialog.buttonOK.Text = Options.GetLiteral(Options.LANG_ADD); dialog.Text = string.Format (Options.GetLiteral(Options.LANG_FILE_ATTRIBUTES) + " [{0} " + Options.GetLiteral(Options.LANG_ENTRIES) + "]", sel_indices.Length); } set_readonly_attributes(dialog); DialogResult d_res = dialog.ShowDialog(); switch (d_res) { case DialogResult.OK: //group mode = add attributes //single mode = set attributes if (!group_mode) { try { set_attributes_file(target_file, get_attributes_from_dialog(dialog)); } catch (Exception ex) { Messages.ShowException(ex); } } else { //group mode FileAttributes add_fa = get_attributes_from_dialog(dialog); foreach (int one_index in sel_indices) { target_file = Path.Combine(dl.DirectoryPath, dl.GetItemDisplayNameLong(one_index)); try { add_attributes_file(target_file, add_fa); OnItemProcessDone(new ItemEventArs(one_index)); } catch (Exception ex) { Messages.ShowException(ex); } } } break; case DialogResult.Yes: //group mode only = clear attributes FileAttributes clear_fa = get_attributes_from_dialog(dialog); foreach (int one_index in sel_indices) { target_file = Path.Combine(dl.DirectoryPath, dl.GetItemDisplayNameLong(one_index)); try { clear_attributes_file(target_file, clear_fa); OnItemProcessDone(new ItemEventArs(one_index)); } catch (Exception ex) { Messages.ShowException(ex); } } break; } }
/// <summary> /// show error window if needed and returns do second take or no, if no caller must continue to next source /// </summary> /// <param name="source"></param> /// <param name="src_data"></param> /// <param name="destination"></param> /// <param name="win_error"></param> /// <returns></returns> private bool process_CopyFileEx_errors(FileInfoEx source_info, string destination, int win_error, ref CopyFileExOptions temp_options) { var dst_data = new WIN32_FIND_DATA(); switch (win_error) { case WinApiFS.ERROR_PATH_NOT_FOUND: //ERROR_PATH_NOT_FOUND //there is no target directory, create it var src_dir_3 = Path.GetDirectoryName(source_info.FullName); var dst_dir_3 = Path.GetDirectoryName(destination); try { create_empty_dir(src_dir_3, dst_dir_3); } catch (Exception ex_3) { if (process_error (string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_DIRECTORY_0), dst_dir_3), ex_3)) { return(false); } else { stop(); return(false); } } return(true); case WinApiFS.ERROR_FILE_EXISTS: //ERROR_FILE_EXISTS if ((options & CopyEngineOptions.RewriteIfSourceNewer) == CopyEngineOptions.RewriteIfSourceNewer) { //overwrite enable if source newer WinAPiFSwrapper.GetFileInfo(destination, ref dst_data); if (source_info.WriteFileTime > dst_data.ftLastWriteTime) { temp_options = ~((~temp_options) | CopyFileExOptions.FAIL_IF_EXISTS); return(clear_dest_attributes(destination, dst_data)); } else { if (process_error (string.Format (Options.GetLiteral(Options.LANG_DESTINATION_0_NEWER_THEN_SOURCE_1_OVERWRITING_PROHIBITED), destination, source_info.FullName), null)) { return(false); } else { stop(); return(false); } } } //destination exists and overwrite prohibited if (process_error (string.Format (Options.GetLiteral(Options.LANG_DESTINATION_0_EXIST_OVERWRITING_PROHIBITED), destination), null)) { return(false); } else { stop(); return(false); } case 5: //ERROR_ACCESS_DENIED //destination file have readonly or hidden attribute //clear attributes WinAPiFSwrapper.GetFileInfo(destination, ref dst_data); return(clear_dest_attributes(destination, dst_data)); } //end switch //default: var ex = new Win32Exception(win_error); if (process_error (string.Format (Options.GetLiteral(Options.LANG_CANNOT_COPY_0_ARROW_1), source_info.FullName, destination), ex)) { return(false); } else { stop(); return(false); } }
private void download_one_file(FtpEntryInfo source_info, string dest_file) { var dest_handle = IntPtr.Zero; FileStream dest_stream = null; var update_args = new UpdateProgressArgs(); count_bytes_current_transferred = 0; if (progress != null) { try { AbortSafe = progress.CancelPressedSafe; } catch { } } if (AbortSafe) { return; } try { //time to notify about begin download file update_args.DestinationFile = dest_file; update_args.EnableTotalProgress = opts.ShowTotalProgress; update_args.FilesCopied = count_files_processed; update_args.KBytesPerSec = (ulong)calc_speed(); update_args.Reason = UpdateProgressReason.StreamSwitch; update_args.SourceFile = FtpPath.Combine(source_info.DirectoryPath, source_info.EntryName); update_args.StreamSize = (ulong)source_info.Size; update_args.StreamTransferred = 0; update_args.TotalSize = (ulong)total_source_size; update_args.TotalTransferred = (ulong)count_bytes_total_transferred; update_progress_safe(update_args); //destination file exist? var dest_data = new WIN32_FIND_DATA(); var dest_exist = WinAPiFSwrapper.GetFileInfo(dest_file, ref dest_data); var source_date = connection.GetStamp(FtpPath.Combine(source_info.DirectoryPath, source_info.EntryName)); if (dest_exist) { switch (opts.Overwrite) { case OverwriteExisting.No: //overwrite prohibited AbortSafe = !process_error (string.Format (Options.GetLiteral(Options.LANG_DESTINATION_0_EXIST_OVERWRITING_PROHIBITED), dest_file), null); //and return return; case OverwriteExisting.IfSourceNewer: //check file date //get datetime from server if (source_date <= DateTime.FromFileTime(dest_data.ftLastWriteTime)) { //source older AbortSafe = !process_error (string.Format (Options.GetLiteral(Options.LANG_DESTINATION_0_NEWER_THEN_SOURCE_1_OVERWRITING_PROHIBITED), dest_file, source_info.EntryName), null); //return return; } break; } } //now we can overwrite destination if it exists //create destination directory WinAPiFSwrapper.CreateDirectoryTree(Path.GetDirectoryName(dest_file), string.Empty); //open dest file (handle will be close at finally block with stream.close()) dest_handle = WinAPiFSwrapper.CreateFileHandle (dest_file, Win32FileAccess.GENERIC_WRITE, FileShare.Read, FileMode.Create, CreateFileOptions.None); //create destination stream dest_stream = new FileStream (dest_handle, FileAccess.Write, true); //set destinstion length dest_stream.SetLength(source_info.Size); //and call download var transferred = connection.DownloadFile (FtpPath.Combine(source_info.DirectoryPath, source_info.EntryName), dest_stream, transfer_progress_delegate_holder, new TransferStateObject(FtpPath.Combine(source_info.DirectoryPath, source_info.EntryName), dest_file, source_info.Size), opts.BufferSize); dest_stream.Close(); //and set attributes File.SetLastWriteTime(dest_file, source_date); //now time to update count count_files_processed++; count_bytes_total_transferred += count_bytes_current_transferred; } catch (Exception ex) { AbortSafe = !process_error (string.Format(Options.GetLiteral(Options.LANG_CANNOT_DOWNLOAD_0), source_info.EntryName), ex); } finally { if (dest_stream != null) { dest_stream.Close(); } } }
private void internal_do() { start_tick = Environment.TickCount; var update_args = new UpdateProgressArgs(); update_args.EnableTotalProgress = opts.ShowTotalProgress; update_args.FilesCopied = 0; update_args.KBytesPerSec = 0; update_args.Reason = UpdateProgressReason.JobBegin; update_args.StreamTransferred = 0; update_progress_safe(update_args); if (opts.ShowTotalProgress) { total_source_size = calc_source_size(); } var dest_data = new WIN32_FIND_DATA(); //bool dest_exist = WinAPiFSwrapper.GetFileInfo(initial_destination, ref dest_data); foreach (var info in initial_source) { if (AbortSafe) { break; } var dest_exist = WinAPiFSwrapper.GetFileInfo(initial_destination, ref dest_data); if (info.Directory) { if (dest_exist) { if ((dest_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { //download source directory into directory=initial_destination/info.ENtryName download_directory(info, Path.Combine(initial_destination, info.EntryName)); } else { //show error AbortSafe = !process_error (string.Format (Options.GetLiteral(Options.LANG_WRONG_DESTINATION_SOURCE_0_DIRECTORY_DESTINATION_1_FILE), info.EntryName, initial_destination), null); continue; } } else { //dest not exist if (initial_source.Length == 1) { //that is download one directory to directory with new name download_directory(info, initial_destination); } else { //download driectory INTO initial_destination download_directory(info, Path.Combine(initial_destination, info.EntryName)); } } } else { //info is file if (dest_exist) { if ((dest_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { //dest existing dir //download one file into initial destination download_one_file(info, Path.Combine(initial_destination, info.EntryName)); } else { //dest is file if (initial_source.Length != 1) { //cannot download many entries into one file AbortSafe = !process_error (Options.GetLiteral(Options.LANG_WRONG_DESTINATION_CANNOT_DOWNLOAD_MANY_ENTRIES_INTO_ONE_FILE), null); continue; } else { //overwrite existing download_one_file(info, initial_destination); } } } else { //dest not exist and info is file if (initial_source.Length == 1) { //assume that dest is new file name download_one_file(info, initial_destination); } else { //assume that dest is new dir download_one_file(info, Path.Combine(initial_destination, info.EntryName)); } } } if (DownloadItemDone != null) { DownloadItemDone(this, new ItemEventArs(info.EntryName)); } } count_bytes_current_transferred = 0; //time to notify about job completed update_args.EnableTotalProgress = opts.ShowTotalProgress; update_args.FilesCopied = count_files_processed; update_args.KBytesPerSec = (ulong)calc_speed(); update_args.Reason = UpdateProgressReason.JobDone; update_args.TotalSize = (ulong)total_source_size; update_args.TotalTransferred = (ulong)count_bytes_total_transferred; update_progress_safe(update_args); if (Done != null) { Done(this, new EventArgs()); } }
private void internal_do() { start_tick = Environment.TickCount; var update_args = new UpdateProgressArgs(); update_args.EnableTotalProgress = opts.ShowTotalProgress; update_args.FilesCopied = 0; update_args.KBytesPerSec = 0; update_args.Reason = UpdateProgressReason.JobBegin; update_args.StreamTransferred = 0; update_progress_safe(update_args); if (opts.ShowTotalProgress) { total_source_size = calc_source_size(); } var source_data = new WIN32_FIND_DATA(); var dest_info = new FtpEntryInfo(); //bool dest_exists = connection.GetEntryInfo(initial_destination, ref dest_info, false); for (var i = 0; i < initial_source.Length; i++) { if (AbortSafe) { break; } if (!WinAPiFSwrapper.GetFileInfo(initial_source[i], ref source_data)) { AbortSafe = !process_error (string.Format (Options.GetLiteral(Options.LANG_SOURCE_FILE_0_NOT_FOUND), initial_source[i]), null); continue; } var dest_exists = connection.GetEntryInfo(initial_destination, ref dest_info, false); if ((source_data.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) { if (dest_exists) { if (dest_info.Directory) { upload_directory_recurse (initial_source[i], FtpPath.Combine (initial_destination, source_data.cFileName)); }//end of dest is dir else { AbortSafe = !process_error (string.Format (Options.GetLiteral(Options.LANG_WRONG_DESTINATION_SOURCE_0_DIRECTORY_DESTINATION_1_FILE), initial_destination[i], initial_destination), null); continue; } }//end of dest_exists else { if (initial_source.Length == 1) { upload_directory_recurse (initial_source[i], initial_destination); } else { upload_directory_recurse (initial_source[i], FtpPath.Combine(initial_destination, source_data.cFileName)); } } //end of dest not exists } //end source is dir else { //source is file if (dest_exists) { if (dest_info.Directory) { upload_one_file (initial_source[i], FtpPath.Combine(initial_destination, source_data.cFileName)); }//end of dest is dir else { if (initial_source.Length != 1) { //cannot upload many entries into one file AbortSafe = !process_error (Options.GetLiteral(Options.LANG_WRONG_DESTINATION_CANNOT_UPLOAD_MANY_ENTRIES_INTO_ONE_FILE), null); continue; } else { //try overwrite existing upload_one_file(initial_source[i], initial_destination); } } }//end of dest exists else { //dest not exists and source is file if (initial_source.Length == 1) { //assume that dest is new file name upload_one_file(initial_source[i], initial_destination); } else { //assume that dest is new dir upload_one_file (initial_source[i], FtpPath.Combine(initial_destination, source_data.cFileName)); } } }//end of source is file if (UploadItemDone != null) { UploadItemDone(this, new ItemEventArs(source_data.cFileName)); } }//end for count_bytes_current_transferred = 0; //time to notify about job completed update_args.EnableTotalProgress = opts.ShowTotalProgress; update_args.FilesCopied = count_files_processed; update_args.KBytesPerSec = (ulong)calc_speed(); update_args.Reason = UpdateProgressReason.JobDone; update_args.TotalSize = (ulong)total_source_size; update_args.TotalTransferred = (ulong)count_bytes_total_transferred; update_progress_safe(update_args); connection.ClearCache(); connection.NotifyUpdateNeeded(); if (Done != null) { Done(this, new EventArgs()); } }//end proc
protected override void internal_command_proc() { var e_current = new QueryPanelInfoEventArgs(); var e_other = new QueryPanelInfoEventArgs(); OnQueryCurrentPanel(e_current); OnQueryOtherPanel(e_other); if (!(e_current.ItemCollection is DirectoryList)) { return; } if (!(e_other.ItemCollection is DirectoryList)) { Messages.ShowMessage(Options.GetLiteral(Options.LANG_WRONG_DESTINATION)); return; } if (e_current.FocusedIndex == -1) { return; } var dl_current = (DirectoryList)e_current.ItemCollection; var dl_other = (DirectoryList)e_other.ItemCollection; var group_mode = e_current.SelectedIndices.Length > 1; var link_type = Options.LinkType; var sels = new List <FileInfoEx>(); if (e_current.SelectedIndices.Length > 0) { for (var i = 0; i < e_current.SelectedIndices.Length; i++) { sels.Add(dl_current[e_current.SelectedIndices[i]]); } } else { sels.Add(dl_current[e_current.FocusedIndex]); } //show dialog var dialog = new CreateLinkDialog(); dialog.Text = Options.GetLiteral(Options.LANG_LINK_CREATE); dialog.LinkType = link_type; dialog.textBoxLinkname.Text = string.Empty; if (group_mode) { dialog.textBoxLinkname.ReadOnly = true; dialog.textBoxLinktarget.Text = string.Format ("{0} " + Options.GetLiteral(Options.LANG_ENTRIES), sels.Count); } else { dialog.textBoxLinktarget.Text = sels[0].FileName; } if (dialog.ShowDialog() != DialogResult.OK) { return; } link_type = dialog.LinkType; Options.LinkType = link_type; foreach (var entry in sels) { var link_handle = IntPtr.Zero; //combine link name var link_name = string.Empty; if (dialog.textBoxLinkname.Text == string.Empty) { //use target file name link_name = Path.Combine(dl_other.DirectoryPath, entry.FileName); } else { link_name = Path.Combine(dl_other.DirectoryPath, dialog.textBoxLinkname.Text); } try { if ((entry.Directory) && (link_type == NTFSlinkType.Hard)) { Messages.ShowMessage (string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_HARD_LINK_DIR_0), entry.FullName)); continue; } if (link_type == NTFSlinkType.Hard) { var res = WinApiFS.CreateHardLink (link_name, entry.FullName, IntPtr.Zero); if (res == 0) { Messages.ShowException (new Win32Exception(Marshal.GetLastWin32Error()), string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_LINK_0_ARROW_1), entry.FullName, link_name)); } else { OnItemProcessDone(new ItemEventArs(entry.FileName)); } continue; } if (link_type == NTFSlinkType.Symbolic) { try { WinAPiFSwrapper.CreateSymbolicLink(link_name, entry.FullName, entry.Directory); OnItemProcessDone(new ItemEventArs(entry.FileName)); } catch (Exception) { Messages.ShowException (new Win32Exception(Marshal.GetLastWin32Error()), string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_LINK_0_ARROW_1), entry.FullName, link_name)); } continue; } //link type is junction var link_data = new WIN32_FIND_DATA(); var link_exist = WinAPiFSwrapper.GetFileInfo(link_name, ref link_data); if (link_exist) { Messages.ShowMessage(string.Format(Options.GetLiteral(Options.LANG_DESTINATION_0_EXIST_OVERWRITING_PROHIBITED), link_name)); continue; } //jumction target must be directory, create directory Directory.CreateDirectory(link_name); //and retrieve handle link_handle = WinApiFS.CreateFile_intptr (link_name, Win32FileAccess.WRITE_ATTRIBUTES | Win32FileAccess.WRITE_EA, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, CreateFileOptions.OPEN_REPARSE_POINT | CreateFileOptions.BACKUP_SEMANTICS, IntPtr.Zero); if (link_handle.ToInt64() == WinApiFS.INVALID_HANDLE_VALUE) { var win_ex = new Win32Exception(Marshal.GetLastWin32Error()); Messages.ShowException (win_ex, string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_LINK_0_ARROW_1), link_name, entry.FullName)); if (Directory.Exists(link_name)) { Directory.Delete(link_name); } continue; } //now handle to link open WinAPiFSwrapper.SetMountpoint(link_handle, entry.FullName, entry.FullName); OnItemProcessDone(new ItemEventArs(entry.FileName)); }//end try catch (Exception ex) { Messages.ShowException (ex, string.Format (Options.GetLiteral(Options.LANG_CANNOT_CREATE_LINK_0_ARROW_1), entry.FullName, link_name)); } finally { //close handle if ((link_handle.ToInt64() != WinApiFS.INVALID_HANDLE_VALUE) && (link_handle != IntPtr.Zero)) { WinApiFS.CloseHandle(link_handle); } } }//end foreach }