/[AnywhereTS-MSSQL]/trunk/TSAdminTool/frmConfigServices.cs
ViewVC logotype

Contents of /trunk/TSAdminTool/frmConfigServices.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 156 - (show annotations) (download)
Sun Jul 15 13:42:48 2012 UTC (7 years, 7 months ago) by william
File size: 28520 byte(s)
don't set access rights on tftpfolder

1 #define DISALLOW_SETTING_OF_TFTP_FOLDER_ACLS // when defined will not allow RDP only acl to be placed on TFTP folder
2 using System;
3 using System.Collections.Generic;
4 using System.ComponentModel;
5 using System.Data;
6 using System.Drawing;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.IO;
10 using System.Security.AccessControl;
11 using System.Security.Principal;
12
13 namespace AnywhereTS
14 {
15 public partial class frmConfigServices : Form
16 {
17 public frmConfigServices()
18 {
19 InitializeComponent();
20 }
21
22 private atsDataSet.TftpServerDataTable datatableTFTP; // TFTP server directories
23 private atsDataSet.TerminalServerDataTable datatableTerminalServer; // terminal servers
24 const string strATSshareName = @"AnywhereTS$"; // The name of the AnywhereTS Win32 file share for the local TFTP server.
25 const string strShareDesc = @"Used by AnywhereTS";
26 private List<string> tftpUncPaths; // List with the corresponding UNC paths for items in lstTFTP.
27
28 private void frmConfigureMode_Load(object sender, EventArgs e)
29 {
30 //this.Cursor = Cursors.WaitCursor;
31
32 tftpUncPaths = new List<string>(); // Create a list for the TFTP UNC paths.
33
34 // Setup database
35 if (ProSupport.tftpServerTableAdapter == null || ProSupport.terminalServerTableAdapter == null) // Is database initiated?
36 {
37 // Databases is not initiated, do it now
38 ProSupport.InitDatabase();
39 }
40
41 datatableTFTP = new atsDataSet.TftpServerDataTable();
42 ProSupport.tftpServerTableAdapter.Fill(datatableTFTP);
43 datatableTerminalServer = new atsDataSet.TerminalServerDataTable();
44 ProSupport.terminalServerTableAdapter.Fill(datatableTerminalServer);
45
46 if (ATSGlobals.configured == 0)
47 { // ATS not configured yet
48 RadTSthisComputer.Checked = true;
49 txtTFTPpath.Text = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\AnywhereTS\TFTP";
50 radTFTPinternal.Checked = true;
51 }
52 else
53 { // ATS already configured.
54 txtTFTPpath.Text = ATSGlobals.strTFTPdir;
55 radTFTPinternal.Checked = (ATSGlobals.tftpConfig == 0);
56 radTFTPexternal.Checked = (ATSGlobals.tftpConfig == 1);
57 if (ATSGlobals.terminalServerConfig == 0)
58 { // This computer is terminal server
59
60 if (datatableTerminalServer.Rows.Count == 0) //Any other terminal servers?
61 { // No other terminal servers
62 RadTSthisComputer.Checked = true;
63 }
64 else
65 { // At least one other
66 radTSboth.Checked = true;
67 }
68 }
69 else
70 { // This computer is not terminal server
71 radTSother.Checked = true;
72 }
73
74 }
75
76
77 // Update terminal server list
78 UpdateTerminalServerList();
79
80 // Update TFTP server directories list
81 if (ATSGlobals.tftpConfig == 1)
82 {
83 UpdateTftpList();
84 }
85
86 helpProvider.HelpNamespace = ATSGlobals.strHelpFilePath; // Initiate helpProvider
87
88 UpdateControls();
89
90 this.Cursor = Cursors.Default;
91 }
92
93
94 private void btnOK_Click(object sender, EventArgs e)
95 {
96 this.Cursor = Cursors.WaitCursor;
97
98 if (RadTSthisComputer.Checked)
99 ATSGlobals.terminalServerConfig = 0;
100 else if (radTSboth.Checked)
101 ATSGlobals.terminalServerConfig = 0;
102 else if (radTSother.Checked)
103 ATSGlobals.terminalServerConfig = 1;
104 else
105 {
106 string error = "Error: Undefined terminal servers config (42001)";
107 using (log4net.NDC.Push(string.Format("terminalServerConfig={0}", ATSGlobals.terminalServerConfig)))
108 {
109 Logging.ATSAdminLog.Error(error);
110 }
111 MessageBox.Show(string.Format("{0} -> {1}", error, string.Format("terminalServerConfig={0}", ATSGlobals.terminalServerConfig)));
112 return;
113 }
114
115
116 string strPath; // The TFTP path
117 strPath = txtTFTPpath.Text.Trim();
118
119 if (radTFTPinternal.Checked)
120 { // We are using the internal TFTP
121 ATSGlobals.tftpConfig = 0; // Use ATS TFTP
122 // Validate TFTP directory
123 if (strPath.Length == 0)
124 {
125 this.Cursor = Cursors.Default;
126 MessageBox.Show("You must specifiy a directory for the AnywhereTS shared network files.");
127 txtTFTPpath.Focus();
128 return;
129 }
130
131 if (strPath.StartsWith(".") || strPath.StartsWith(@"\"))
132 {
133 this.Cursor = Cursors.Default;
134 MessageBox.Show("Invalid path for the AnywhereTS shared network files.");
135 using (log4net.NDC.Push(string.Format("path={0}", strPath)))
136 {
137 Logging.ATSAdminLog.Error("Invalid path for the AnywhereTS shared network files.");
138 }
139 txtTFTPpath.Focus();
140 return;
141 }
142
143 // Create TFTP directory
144 try
145 {
146 Directory.CreateDirectory(strPath);
147 }
148 catch (Exception ex)
149 {
150 this.Cursor = Cursors.Default;
151 MessageBox.Show("Could not create directory '" + strPath + "'. Error: " + ex.Message);
152 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", ex.Message, System.Environment.NewLine, ex.ToString())))
153 {
154 using (log4net.NDC.Push(string.Format("directory={0}", strPath)))
155 {
156 Logging.ATSAdminLog.Error("Could not create directory.");
157 }
158 }
159 txtTFTPpath.Select();
160 return;
161 }
162
163 // Check that the directory is local
164 ShareUtil shUtil = new ShareUtil(); // Create a util class
165 if (shUtil.IsNetworkPath(strPath))
166 { // The path is a network path
167 MessageBox.Show("A network path cannot be used for the local TFTP server. Please enter a local path.");
168 txtTFTPpath.Select();
169 return;
170 }
171 // Save the TFTP directory to registry
172 ATSGlobals.strTFTPdir = strPath; // Set the C# version of TFTP dir
173 Globals.strTFTPdir = strPath; // Set the VB version of TFTP dir
174 ATSGlobals.SetATSRegValue(ATSGlobals.strRegTFTP_root, ATSGlobals.strTFTPdir);
175
176 // Delete all TFTP roots from database
177 foreach (DataRow row in datatableTFTP.Rows)
178 {
179 row.Delete();
180 }
181 ProSupport.tftpServerTableAdapter.Update(datatableTFTP);
182
183 if (!RadTSthisComputer.Checked)
184 { // There are external terminal servers.
185
186 // Create a share, save the UNC path to the database, add rights to TFTP directory
187 AddTFTPpath(ATSGlobals.strTFTPdir);
188 }
189 else
190 { // We are only using this computer as terminal server
191 SetTFTPrights(ATSGlobals.strTFTPdir);
192 }
193 }
194 else
195 {
196 // Use other TFTP
197 ATSGlobals.tftpConfig = 1; // Use other TFTP
198
199 if (lstTFTP.Items.Count == 0)
200 {
201 this.Cursor = Cursors.Default;
202 MessageBox.Show("You must choose at least one TFTP server root directory, where AnywhereTS can place client images and configurations.");
203 btnAddTFTPpath.Focus();
204 return;
205 }
206 }
207
208 // Check if we are using external terminal servers
209 if (RadTSthisComputer.Checked)
210 { // Only this computer is a terminal server. Delete all other terminal servers.
211 foreach (DataRow row in datatableTerminalServer.Rows)
212 {
213 row.Delete();
214 }
215 ProSupport.terminalServerTableAdapter.Update(datatableTerminalServer);
216 }
217 else
218 { // We have external terminal servers
219 if (lstTerminalServer.Items.Count == 0)
220 {
221 this.Cursor = Cursors.Default;
222 MessageBox.Show("You must specify at least one Terminal Server!");
223 btnAddTerminalServer.Focus();
224 return;
225 }
226
227 // Close database connections
228 datatableTFTP.Dispose();
229 datatableTerminalServer.Dispose();
230 ProSupport.clientTableAdapter.Connection.Close();
231 ProSupport.terminalServerTableAdapter.Connection.Close();
232 ProSupport.clientTableAdapter.Dispose();
233 ProSupport.terminalServerTableAdapter.Dispose();
234
235 // Configure SQL browser service (needed for the control panel to be able to access the database).
236
237 bool sqlServerRestarted = DatabaseSupport.EnableNamedPipes(); // Enable named pipes in the SQL server
238 DatabaseSupport.AutostartSQLbrowserService(); // Configure the SQL Browser service to autostart.
239 DatabaseSupport.StartSQLbrowserService(); // Start the SQL Browser service
240
241 if (sqlServerRestarted)
242 {
243 // SQL server was restarted. Try to reconnect to database in order to repair the database connectivity
244 ProSupport.InitDatabase();
245
246 try
247 {
248 datatableTFTP = new atsDataSet.TftpServerDataTable();
249 ProSupport.tftpServerTableAdapter.Fill(datatableTFTP); // This operation causes an error and forces the connectivity to recover.
250 }
251 catch
252 { // Do nothing, just catch the error that will most likely occur here.
253 }
254 finally
255 {
256 System.Threading.Thread.Sleep(5000); // Wait for the SQL connection to recover.
257 }
258 }
259 }
260
261 // Save DHCP options
262 if (radAtsDhcp.Checked)
263 {
264 ATSGlobals.dhcpConfig = 0; // Use the internal DCHP server
265 }
266 else
267 {
268 ATSGlobals.dhcpConfig = 1; // Use the other DCHP server
269 }
270
271 // Save TFTP configuration to registry
272 ATSGlobals.SetATSRegValue(ATSGlobals.strRegTFTPconfig,ATSGlobals.tftpConfig);
273
274 // Save DCHP configuration to registry
275 ATSGlobals.SetATSRegValue(ATSGlobals.strRegDHCPconfig, ATSGlobals.dhcpConfig);
276
277 // Terminate window
278 this.Cursor = Cursors.Default;
279 DialogResult = DialogResult.OK;
280 }
281
282
283 private void AddTFTPpath(string strPath)
284 {
285 string uncPath; // The path in UNC format
286 string strLocalPath = ""; // Local path to save in database for display purposes. Only set if path is local
287
288 ShareUtil shUtil = new ShareUtil(); // Create a util class
289
290 // Check if path is a network path
291 if (shUtil.IsNetworkPath(strPath))
292 { // The path is a network path
293 if (strPath.StartsWith("\\"))
294 { // The network path is a UNC path, no need to convert it
295 uncPath = strPath;
296 }
297 else
298 { // The network path is not a UNC path, convert it
299 uncPath = UNCconverter.ConvertLocalPathToUnc(strPath);
300 }
301 }
302 else
303 { // User is adding a local path
304 strLocalPath = strPath;
305 string strThisComputer = Environment.MachineName; // The name of this computer
306 // Compile the UNC path
307 uncPath = @"\\" + strThisComputer + @"\" + strATSshareName;
308
309 // Delete ATS share if it exists
310 shUtil.DeleteShare(strATSshareName);
311
312 // Delete share from database if it exists
313 ProSupport.tftpServerTableAdapter.Fill(datatableTFTP); // Refresh data table
314 DataRow rowToDelete;
315 rowToDelete = datatableTFTP.Rows.Find(uncPath);
316 if (rowToDelete != null)
317 { // The local TFTP path exists in database, delete it
318 rowToDelete.Delete();
319 ProSupport.tftpServerTableAdapter.Update(datatableTFTP);
320 }
321
322 // Create network share
323
324 uint nRetVal;
325 nRetVal = shUtil.CreateShare(strShareDesc, strATSshareName, strPath);
326 if (nRetVal == 0)
327 {
328 // Share created
329 }
330 else
331 {
332 // Error
333 MessageBox.Show("Could not create a share for the AnywereTS TFTP data. Do you have sufficient rights? (25322)");
334 return;
335 }
336
337 }
338
339 // Add the remote or local directory path to the database
340 if (uncPath.Length <= 255)
341 { // The path will fit in the database
342 atsDataSet.TftpServerRow row = (atsDataSet.TftpServerRow)datatableTFTP.NewRow();
343 row["Path"] = uncPath;
344 row["LocalPath"] = strLocalPath;
345
346 try
347 {
348 datatableTFTP.AddTftpServerRow(row);
349 }
350 catch (ConstraintException)
351 {
352 MessageBox.Show("'" + uncPath + "' is already in the list.");
353 return;
354 }
355
356 ProSupport.tftpServerTableAdapter.Update(datatableTFTP);
357
358 // Ask if we are going to add righs to the TFTP root directory, set rights.
359 SetTFTPrights(row["Path"].ToString());
360 UpdateTftpList(); // Update the list box
361 lstTFTP.Select();
362 }
363 else
364 { // Path is too long
365 MessageBox.Show("The directory path is too long, please use a path that is max 255 character");
366 }
367
368 }
369
370 private void radAtsDhcp_CheckedChanged(object sender, EventArgs e)
371 {
372 UpdateControls(); // Set text "Next >" or "Finish" on the Ok button
373 }
374
375 private void radExternalDhcp_CheckedChanged(object sender, EventArgs e)
376 {
377 UpdateControls(); // Set text "Next >" or "Finish" on the Ok button
378 }
379
380 private void UpdateControls()
381 {
382 if (RadTSthisComputer.Checked)
383 { // Only this computer as terminal server
384 lblTerminalServers.Enabled = false;
385 lstTerminalServer.Enabled = false;
386 btnAddTerminalServer.Enabled = false;
387 btnDeleteTerminalServer.Enabled = false;
388 }
389 else
390 { // Other terminal servers
391 lblTerminalServers.Enabled = true;
392 lstTerminalServer.Enabled = true;
393 btnAddTerminalServer.Enabled = true;
394 if (lstTerminalServer.SelectedIndex == -1)
395 btnDeleteTerminalServer.Enabled = false;
396 else
397 btnDeleteTerminalServer.Enabled = true;
398 }
399
400 if (radTFTPinternal.Checked)
401 {
402 lblTFTPpath.Enabled = true;
403 txtTFTPpath.Enabled = true;
404 btnBrowseTFTP.Enabled = true;
405 lblTFTPdirectories.Enabled = false;
406 lstTFTP.Enabled = false;
407 btnAddTFTPpath.Enabled = false;
408 btnDeleteTFTP.Enabled = false;
409 radAtsDhcp.Enabled = true;
410 lstTFTP.SelectedIndex = -1;
411 btnOK.Text = "Next >";
412 }
413 else
414 {
415 lblTFTPdirectories.Enabled = true;
416 lstTFTP.Enabled = true;
417 btnAddTFTPpath.Enabled = true;
418 if (lstTFTP.SelectedIndex == -1)
419 btnDeleteTFTP.Enabled = false;
420 else
421 btnDeleteTFTP.Enabled = true;
422 lblTFTPpath.Enabled = false;
423 txtTFTPpath.Enabled = false;
424 btnBrowseTFTP.Enabled = false;
425 btnOK.Text = "Finish";
426 radAtsDhcp.Enabled = false;
427 radExternalDhcp.Checked = true;
428 }
429 }
430
431 private void radTFTPinternal_CheckedChanged(object sender, EventArgs e)
432 {
433 UpdateControls();
434 }
435
436 private void radTFTPexternal_CheckedChanged(object sender, EventArgs e)
437 {
438 if (radTFTPexternal.Checked && ATSGlobals.tftpConfig == 0)
439 { // We have just de-selected internal TFTP server
440
441 // Delete all TFTP roots from database
442 foreach (DataRow row in datatableTFTP.Rows)
443 {
444 row.Delete();
445 }
446 ProSupport.tftpServerTableAdapter.Update(datatableTFTP);
447 UpdateTftpList();
448
449 // Delete the file share for the internal TFTP directory if it exists.
450 ShareUtil shUtil = new ShareUtil(); // Create a util class
451 shUtil.DeleteShare("AnywhereTS$");
452
453 // ATS is now in a non configured state
454 ATSGlobals.configured = 0;
455 ATSGlobals.SetATSRegValue(ATSGlobals.strRegConfigured, ATSGlobals.configured);
456 }
457 UpdateControls();
458 }
459
460 // Update the list with TFTP directories from database.
461 private void UpdateTftpList()
462 {
463 lstTFTP.Items.Clear();
464 tftpUncPaths.Clear();
465 ProSupport.tftpServerTableAdapter.Fill(datatableTFTP);
466 foreach (DataRow row in datatableTFTP.Rows)
467 { // Display local path if possible
468
469
470 lstTFTP.Items.Add(ProSupport.GetTftpPath(row));
471 //string gg = row["Path"].ToString();
472 //tftpUncPaths.Add(gg);
473 tftpUncPaths.Add(row["Path"].ToString()); // Add the UNC path to the list.
474 }
475 btnDeleteTFTP.Enabled = false;
476 }
477
478 // Update the list with terminal servers from database.
479 private void UpdateTerminalServerList()
480 {
481 lstTerminalServer.Items.Clear();
482 foreach (DataRow row in datatableTerminalServer.Rows)
483 {
484 lstTerminalServer.Items.Add(row["Path"].ToString());
485 }
486 btnDeleteTerminalServer.Enabled = false;
487 }
488
489 private void lstTFTP_SelectedIndexChanged(object sender, EventArgs e)
490 {
491 if (lstTFTP.SelectedIndex == -1)
492 { // No item selcted in the TFTP directory list
493 btnDeleteTFTP.Enabled = false;
494 }
495 else
496 { // User has selcted an item in the list
497 btnDeleteTFTP.Enabled = true;
498 }
499 }
500
501 // Delete the row selected in the TFTP directory list box.
502 private void btnDeleteTFTP_Click(object sender, EventArgs e)
503 {
504 DataRow rowToDelete;
505 rowToDelete = datatableTFTP.Rows.Find(tftpUncPaths[lstTFTP.SelectedIndex]);
506 rowToDelete.Delete();
507 ProSupport.tftpServerTableAdapter.Update(datatableTFTP);
508 UpdateTftpList(); // Update the list box
509
510 if (datatableTFTP.Rows.Count == 0)
511 { // Last row deleted
512 // ATS is now in a non configured state
513 ATSGlobals.configured = 0;
514 ATSGlobals.SetATSRegValue(ATSGlobals.strRegConfigured, ATSGlobals.configured);
515 }
516 }
517
518 // Set user rights to TFTP directory, all remote desktop users should be able to write files.
519 void SetTFTPrights(string path)
520 {
521 #if DISALLOW_SETTING_OF_TFTP_FOLDER_ACLS
522 return;
523 #else
524 // Ask if we are going to add righs to the TFTP root directory
525 DialogResult resultRights;
526 resultRights = MessageBox.Show(this, "In order for users to use the AnywhereTS control panel, they need rights to write in the TFTP root directory. Do you want AnywhereTS to add these rights now?", "AnywhereTS", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
527 if (resultRights == DialogResult.Yes)
528 {
529 try
530 {
531 // Create a new DirectoryInfo object.
532 DirectoryInfo dInfo = new DirectoryInfo(path);
533 // Get a DirectorySecurity object that represents the
534 // current security settings.
535 DirectorySecurity dSecurity = dInfo.GetAccessControl();
536 // Add a FileSystemAccessRule to the security settings, to allow write.
537 // No general rights to delete files. These rights are set on the individual files.
538 dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinRemoteDesktopUsersSid, null), FileSystemRights.WriteData, AccessControlType.Allow));
539 // Set the new access settings.
540 dInfo.SetAccessControl(dSecurity);
541 }
542 catch (Exception ex)
543 {
544 this.Cursor = Cursors.Default;
545 MessageBox.Show("Could not set user access rights for TFTP directory. Do you have sufficient right? (29991). Error: " + ex.Message);
546 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", ex.Message, System.Environment.NewLine, ex.ToString())))
547 {
548 Logging.ATSAdminLog.Error("Could not set user access rights for TFTP directory.");
549 }
550 return;
551 }
552 }
553 #endif
554 }
555
556 private void btnDeleteTerminalServer_Click(object sender, EventArgs e)
557 {
558 DataRow rowToDelete;
559 rowToDelete = datatableTerminalServer.Rows.Find(lstTerminalServer.SelectedItem);
560 rowToDelete.Delete();
561 ProSupport.terminalServerTableAdapter.Update(datatableTerminalServer);
562 UpdateTerminalServerList(); // Update the list box
563 }
564
565 private void btnAddTerminalServer_Click(object sender, EventArgs e)
566 {
567 // Show dialog
568 frmAddTerminalServer addTSdialog = new frmAddTerminalServer();
569 DialogResult result = addTSdialog.ShowDialog();
570 if (result == DialogResult.OK)
571 {
572 // Add the server to the database
573 if (addTSdialog.inputstring.Trim().Length <= 255)
574 { // The path will fit in the database
575 atsDataSet.TerminalServerRow row = (atsDataSet.TerminalServerRow)datatableTerminalServer.NewRow();
576 row["Path"] = addTSdialog.inputstring.Trim();
577 try
578 {
579 datatableTerminalServer.AddTerminalServerRow(row);
580 }
581 catch (ConstraintException)
582 {
583 MessageBox.Show("'" + row["Path"] + "' is already in the list.");
584 return;
585 }
586
587 ProSupport.terminalServerTableAdapter.Update(datatableTerminalServer);
588
589 UpdateTerminalServerList(); // Update the list box
590 lstTerminalServer.Select();
591 }
592 else
593 { // Path is too long
594 MessageBox.Show("The server path is too long, please use a path that is max 255 character");
595 }
596 }
597 }
598
599 private void lstTerminalServer_SelectedIndexChanged(object sender, EventArgs e)
600 {
601 if (lstTerminalServer.SelectedIndex == -1)
602 { // No item selcted in the TFTP directory list
603 btnDeleteTerminalServer.Enabled = false;
604 }
605 else
606 { // User has selcted an item in the list
607 btnDeleteTerminalServer.Enabled = true;
608 }
609 }
610
611 private void RadTSthisComputer_CheckedChanged(object sender, EventArgs e)
612 {
613 UpdateControls();
614 }
615
616 private void radTSother_CheckedChanged(object sender, EventArgs e)
617 {
618 UpdateControls();
619 }
620
621 private void radTSboth_CheckedChanged(object sender, EventArgs e)
622 {
623 UpdateControls();
624 }
625
626 // Add a TFTP server
627 private void btnAddTFTPpath_Click(object sender, EventArgs e)
628 {
629 // Show dialog
630 frmAddTFTP addTFTPdialog = new frmAddTFTP();
631 DialogResult result = addTFTPdialog.ShowDialog();
632 if (result == DialogResult.OK)
633 {
634 string strPath;
635 strPath = addTFTPdialog.inputstring.Trim();
636
637 if (Directory.Exists(strPath))
638 {
639 // Convert to UNC, share local directory, add directory to database
640 AddTFTPpath(strPath);
641 }
642 else
643 {
644 MessageBox.Show("Error: Cannot find or access the directory. Please check name and rights. (34212)");
645 }
646 UpdateTftpList();
647 }
648 }
649
650 private void btnBrowseTFTP_Click(object sender, EventArgs e)
651 {
652 // Show the FolderBrowserDialog.
653 Rebrowse:
654 DialogResult result = folderBrowserDialog.ShowDialog();
655 if (result == DialogResult.OK)
656 {
657 string strPath=""; // The path provided by the user
658
659 // Browse to a folder by displaying the folder browse Dialog
660 try
661 {
662 strPath = folderBrowserDialog.SelectedPath.Trim();
663 }
664 catch (NotSupportedException)
665 { // User has browsed to a non folder
666 MessageBox.Show("Object is not a file folder.");
667 using (log4net.NDC.Push(string.Format("path={0}", strPath)))
668 {
669 Logging.ATSAdminLog.Error("Object is not a file folder.");
670 }
671 goto Rebrowse;
672 }
673 txtTFTPpath.Text = strPath;
674 txtTFTPpath.Select();
675 }
676 }
677 }
678 }
679

  ViewVC Help
Powered by ViewVC 1.1.22