ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/AnywhereTS-MSSQL/trunk/TSAdminTool/ProSupport.cs
Revision: 47
Committed: Thu Jul 12 14:29:34 2012 UTC (10 years, 10 months ago) by william
File size: 29874 byte(s)
Log Message:
+ fix compilation errors

File Contents

# Content
1
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Text;
6 using System.Windows.Forms;
7 using System.Globalization;
8 using System.Data;
9 using System.Security.AccessControl;
10 using System.Security.Principal;
11 using System.IO;
12 using System.Management;
13 using System.Net;
14 using log4net;
15
16 // Support class for the AnywhereTS version. This file should only be included in the Pro version.
17 namespace AnywhereTS
18 {
19 public static class ProSupport
20 {
21 // File names
22 public const string strHostsFilename = "hosts"; // The name of the thin clients host file.
23 public const string strNetworkConfigFilename = "network"; // Name of the Thinstation common config file in the TFTP root directory.
24 public const string strDatabaseFilename = "ats.mdf"; // Name of the AnywhereTS SQL express database file.
25 public const string strDatabaseFilename2 = "ats_log.ldf"; // Name of the AnywhereTS SQL express database log file.
26
27 // Registry keys
28 public const string strRegTFTP_root = "TFTP_root"; // Reg key for TFTP root directory in database
29 public const string strRegDatabaseDir = "DatabaseDir"; // Reg key for database directory
30 public const string strRegDatabaseServer = "DatabaseServer"; // Reg key for database server
31 public const string strRegDestDir = "DestDir"; // Reg key for Destination directory, used in unmanged mode..
32
33 // Database constants
34 public const string DEFAULT_RECORD_MAC = "Default "; // Phony MAC address (12 chars) used to identify the client record that contains the default settings for all new clients
35
36 // Database variables
37 public static atsDataSetTableAdapters.ClientTableAdapter clientTableAdapter; // The AnywhereTS application data adapter for the clients table. Only this adapter should be used.
38 public static atsDataSetTableAdapters.TftpServerTableAdapter tftpServerTableAdapter; // The AnywhereTS application data adapter for the TFTP servers table. Only this adapter should be used.
39 public static atsDataSetTableAdapters.TerminalServerTableAdapter terminalServerTableAdapter; // The AnywhereTS application data adapter for the terminal servers table. Only this adapter should be used.
40 public static atsDataSetTableAdapters.AppInfoTableAdapter appInfoTableAdapter; // The AnywhereTS application data adapter for the AppInfo table. Only this adapter should be used.
41
42 public static string strDatabaseServer; // If this computer does not contain the database server, this is the name of the database server that contains the ATS database. Used by the Control Panel
43
44 // Directories
45 public static string strDatabasePath; // The directory where the database file is located.
46 public static string strDestDir; // Destination directory for client files in unmanaged mode.
47
48 // Constructor Initializes the global variables
49 static ProSupport()
50 {
51 // Initiate variables from registry
52 strDatabasePath = ATSGlobals.GetATSRegValueString(strRegDatabaseDir);
53 strDestDir = ATSGlobals.GetATSRegValueString(strRegDestDir);
54 strDatabaseServer = ATSGlobals.GetATSRegValueString(strRegDatabaseServer);
55 }
56
57 // Loook up local IP for computer
58 public static void ThisComputerIp (System.Windows.Forms.ComboBox combo, bool bolServerName)
59 {
60 ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
61
62 ManagementObjectCollection queryCollection = query.Get();
63 combo.Items.Clear();
64 if (bolServerName == true) //Add computer name
65 {
66 combo.Items.Add(Dns.GetHostName());
67 }
68 foreach (ManagementObject mo in queryCollection)
69 {
70 string[] addresses = (string[])mo["IPAddress"];
71 foreach (string ipaddress in addresses)
72 {
73 if (ipaddress !="0.0.0.0")
74 combo.Items.Add(ipaddress);
75
76 }
77 }
78 }
79
80 // Compate two DriveInfo arrays and return TRUE if they are equal.
81 public static bool CompareDriveInfoArrays(List<DriveInfo> data1, List<DriveInfo> data2)
82 {
83 // If both are null, they're equal
84 if (data1 == null && data2 == null)
85 {
86 return true;
87 }
88 // If either but not both are null, they're not equal
89 if (data1 == null || data2 == null)
90 {
91 return false;
92 }
93 if (data1.Count != data2.Count)
94 {
95 return false;
96 }
97 for (int i = 0; i < data1.Count; i++)
98 {
99 if (data1[i].Name + data1[i].VolumeLabel != data2[i].Name + data2[i].VolumeLabel)
100 {
101 return false;
102 }
103 }
104 return true;
105 }
106
107 // Get an IP parameter (IP, netmask, gateway) from the local machine
108 // Paramters:
109 // Out: IP address in the format "x.x.x.x"
110 // strNetworkConf = "IPAddress": Get IPAddress
111 // strNetworkConf = "IPSubnet": Get netmask
112 // strNetworkConf = "DefaultIPGateway": Get gateway
113 // strNetworkConf = "Description": Get network card
114 // strNetworkConf = "MACAddress": Get MAC address
115 // strNetworkConf = "DNSServerSearchOrder": Get DNS
116 public static string ThisComputerNetworkConf(string strNetworkConf)
117 {
118 ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
119 ManagementObjectCollection queryCollection = query.Get();
120 foreach (ManagementObject mo in queryCollection)
121 {
122 string[] addresses = (string[])mo[strNetworkConf];
123 return addresses[0];
124 }
125 return ""; // No network adapter found.
126 }
127
128 // Initiate the database
129 public static void InitDatabase()
130 {
131 //// Create and set the connection string
132 //string dataServerName; // The name of the database server in the connection string
133 //if (strDatabaseServer.Length != 0)
134 //{ // We have a database server
135 // dataServerName = strDatabaseServer;
136 //}
137 //else
138 //{ // We do not have an external, data server.
139 // dataServerName = ".";
140 //}
141 //Properties.Settings.Default["atsConnectionString"] = @"Data Source=" + dataServerName + @"\SQLEXPRESS;Database='AnywhereTS';Integrated Security=True;Connect Timeout=30;User Instance=False";
142 //Properties.Settings.Default.Save();
143
144 // Set up table adapters
145 clientTableAdapter = new atsDataSetTableAdapters.ClientTableAdapter();
146 tftpServerTableAdapter = new atsDataSetTableAdapters.TftpServerTableAdapter();
147 terminalServerTableAdapter = new atsDataSetTableAdapters.TerminalServerTableAdapter();
148 appInfoTableAdapter = new atsDataSetTableAdapters.AppInfoTableAdapter();
149 }
150
151 // Adds an ACL entry for RW access on the specified file for Remote desktop users.
152 [Obsolete("GrantRWaccessForRemoteDesktopUsers has been deprecated - define user access rights via SQL Server")]
153 public static void GrantRWaccessForRemoteDesktopUsers(string fileName)
154 {
155 // Get a FileSecurity object that represents the current security settings.
156 FileSecurity fSecurity = File.GetAccessControl(fileName);
157
158 // Add FileSystemAccessRule:s to the security settings.
159 // Remote desktop users can read and write, but not delete
160 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinRemoteDesktopUsersSid, null), FileSystemRights.Read, AccessControlType.Allow));
161 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinRemoteDesktopUsersSid, null), FileSystemRights.Write, AccessControlType.Allow));
162
163 // Set the new access settings.
164 File.SetAccessControl(fileName, fSecurity);
165 }
166
167 // Adds an ACL entry for ReadWriteModify access on the specified file for Remote desktop users.
168 [Obsolete("GrantRWMaccessForRemoteDesktopUsers has been deprecated - define user access rights via SQL Server")]
169 public static void GrantRWMaccessForRemoteDesktopUsers(string fileName)
170 {
171 // Get a FileSecurity object that represents the current security settings.
172 FileSecurity fSecurity = File.GetAccessControl(fileName);
173
174 // Add FileSystemAccessRule:s to the security settings.
175 // Remote desktop users can read and write, but not delete
176 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinRemoteDesktopUsersSid, null), FileSystemRights.Read, AccessControlType.Allow));
177 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinRemoteDesktopUsersSid, null), FileSystemRights.Write, AccessControlType.Allow));
178 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinRemoteDesktopUsersSid, null), FileSystemRights.Modify, AccessControlType.Allow));
179
180 // Set the new access settings.
181 File.SetAccessControl(fileName, fSecurity);
182 }
183
184 // (obsolete)
185 // Adds an ACL entry for to deny modify access on the specified file for all users.
186 [Obsolete("DenyAccessRightModifyForUsers has been deprecated - define user access rights via SQL Server")]
187 public static void DenyAccessRightModifyForUsers(string fileName)
188 {
189 // Get a FileSecurity object that represents the current security settings.
190 FileSecurity fSecurity = File.GetAccessControl(fileName);
191
192 // Add FileSystemAccessRule:s to the security settings.
193 // Remote desktop users can read and write, but not delete
194 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), FileSystemRights.Write, AccessControlType.Deny));
195 fSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), FileSystemRights.Modify, AccessControlType.Deny));
196
197 // Set the new access settings.
198 File.SetAccessControl(fileName, fSecurity);
199 }
200
201
202 // Writes config files to all of the TFTP directories definied in registry and database,
203 // and set rights.
204 public static void WriteConfigFiles(ATSImageRuntimeConfig config, string fileName, bool setRights)
205 { // config: The config that should be written to disk
206 // fileName: Name of the config file to write
207 // setRights: True = Set access rights on the file, so that all remote desktop users can delete the file.
208 // Write client config file
209
210 if (ATSGlobals.tftpConfig == 0)
211 { // Use ATS TFTP
212 WriteConfigFile(config, ATSGlobals.strTFTPdir + @"\" + fileName, setRights);
213 }
214 else if (ATSGlobals.tftpConfig == 1)
215 { // External TFTP
216 // Write the config file to all TFTP directories
217 atsDataSet.TftpServerDataTable datatableTFTP; // TFTP server directories
218 atsDataSetTableAdapters.TftpServerTableAdapter tftpServerTableAdapter; // The AnywhereTS application data adapter for the TFTP servers table. Only this adapter should be used.
219
220 tftpServerTableAdapter = new AnywhereTS.atsDataSetTableAdapters.TftpServerTableAdapter();
221 datatableTFTP = new atsDataSet.TftpServerDataTable();
222
223 tftpServerTableAdapter.Fill(datatableTFTP);
224 foreach (DataRow row in datatableTFTP.Rows)
225 {
226 WriteConfigFile(config, GetTftpPath(row) + @"\" + fileName, setRights);
227 }
228 }
229 else
230 throw new Exception("Unknown TFTP mode 28158");
231 }
232
233 // Copy image file to all external tftp directories/servers
234 public static void CopyImageFile(string path, string sourceFileName, string destFileName)
235 {
236 atsDataSet.TftpServerDataTable datatableTFTP; // TFTP server directories
237 datatableTFTP = new atsDataSet.TftpServerDataTable();
238 atsDataSetTableAdapters.TftpServerTableAdapter tftpServerTableAdapter; // The AnywhereTS application data adapter for the TFTP servers table. Only this adapter should be used.
239 tftpServerTableAdapter = new AnywhereTS.atsDataSetTableAdapters.TftpServerTableAdapter();
240
241 tftpServerTableAdapter.Fill(datatableTFTP);
242 foreach (DataRow row in datatableTFTP.Rows)
243 {
244 // Copy to the TFTP server
245 try
246 {
247 File.Copy(path + @"\" + sourceFileName, GetTftpPath(row) + @"\" + destFileName, true);
248 }
249 catch (Exception e)
250 {
251 MessageBox.Show("Could not update TFTP server '" + GetTftpPath(row) + "' (22181). Error: " + e.Message);
252 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString())))
253 {
254 using (log4net.NDC.Push(string.Format("tftpPath={0}", GetTftpPath(row))))
255 {
256 Logging.ATSAdminLog.Error("Could not update TFTP server");
257 }
258 }
259 }
260
261 // Try to set rights for image the image file
262 // (not implemented)
263 /*
264 try
265 {
266 DenyAccessRightModifyForUsers(row["Path"].ToString() + @"\" + file);
267 }
268 catch (Exception e)
269 {
270 MessageBox.Show("Could not set rights for image file on TFTP server '" + row["Path"].ToString() + "' (22183). Error: " + e.Message);
271 } */
272 }
273 }
274
275 // Create subdirectory in all external tftp directories/servers
276 public static void CreateDirectoryOnTFTP_servers(string directoryName)
277 {
278 atsDataSet.TftpServerDataTable datatableTFTP; // TFTP server directories
279 datatableTFTP = new atsDataSet.TftpServerDataTable();
280 atsDataSetTableAdapters.TftpServerTableAdapter tftpServerTableAdapter; // The AnywhereTS application data adapter for the TFTP servers table. Only this adapter should be used.
281 tftpServerTableAdapter = new AnywhereTS.atsDataSetTableAdapters.TftpServerTableAdapter();
282
283 tftpServerTableAdapter.Fill(datatableTFTP);
284 foreach (DataRow row in datatableTFTP.Rows)
285 {
286 // Create the Directory on the TFTP server
287 try
288 {
289 Directory.CreateDirectory(GetTftpPath(row) + @"\" + directoryName);
290 }
291 catch (Exception e)
292 {
293 MessageBox.Show("Could not update TFTP server '" + GetTftpPath(row) + "' (22381). Error: " + e.Message);
294 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString())))
295 {
296 using (log4net.NDC.Push(string.Format("tftpPath={0}", GetTftpPath(row))))
297 {
298 Logging.ATSAdminLog.Error("Could not update TFTP server");
299 }
300 }
301 }
302 }
303 }
304
305 public static void WriteConfigFile(ATSImageRuntimeConfig config, string path, bool setRights)
306 {
307 config.WriteConfigFile(path);
308
309 if (setRights)
310 {
311 // Set access rights for the config file.
312 try
313 {
314 // Add an access control entry to the config file.
315 ProSupport.GrantRWMaccessForRemoteDesktopUsers(path);
316 }
317 catch (Exception ex)
318 {
319 MessageBox.Show("Cannot set access rights for client configuration. Application will abort. Error: " + ex.Message);
320 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", ex.Message, System.Environment.NewLine, ex.ToString())))
321 {
322 Logging.ATSAdminLog.Error("Cannot set access rights for client configuration");
323 }
324 Application.Exit();
325 return;
326 }
327 }
328 }
329
330
331 // Writes host files to all of the TFTP directories definied in registry and database.
332 public static void WriteHostsFiles()
333 {
334 if (ATSGlobals.tftpConfig == 0)
335 { // Use ATS TFTP
336 WriteHostsFile(ATSGlobals.strTFTPdir + @"\" + strHostsFilename);
337 }
338 else if (ATSGlobals.tftpConfig == 1)
339 { // External TFTP
340 // Write the config file to all TFTP directories
341 atsDataSet.TftpServerDataTable datatableTFTP; // TFTP server directories
342 datatableTFTP = new atsDataSet.TftpServerDataTable();
343 tftpServerTableAdapter.Fill(datatableTFTP);
344 foreach (DataRow row in datatableTFTP.Rows)
345 {
346 WriteHostsFile(GetTftpPath(row) + @"\" + strHostsFilename);
347 }
348 }
349 else
350 throw new Exception("Unknown TFTP mode 48158");
351 }
352
353
354 // Create a (new) encrypted hosts file from data in the database.
355 private static void WriteHostsFile(string path)
356 {
357 atsDataSet datasetClient = new atsDataSet();
358 ProSupport.clientTableAdapter.FillClients(datasetClient.Client);
359
360 // System.IO.StreamWriter writer = null;
361 CryptStream writer = null;
362
363 // Delete old hosts file
364 if (System.IO.File.Exists(path))
365 {
366 System.IO.File.Delete(path);
367 }
368
369 // Write a new hosts file.
370 try
371 {
372 //writer = new System.IO.StreamWriter(path);
373 writer = new CryptStream(path);
374 writer.NewLine = "\n"; // Unix style line terminators
375 writer.WriteLine("# This is a hosts file generated by AnywhereTS. Do not change.");
376 foreach (DataRow row in datasetClient.Client.Rows)
377 {
378 writer.WriteLine(row["ClientName"].ToString() + " " + row["MacAddress"].ToString());
379 }
380 writer.WriteLine("# Detta e slutet."); // Termination string to avoid decryptation bug.
381 }
382 catch (Exception e)
383 {
384 //improve autoretry
385 MessageBox.Show("Error: Could not write configuration data to disk. Possibly the data is being accessed by another component right now or you do not have the sufficient rights. Please retry this operation later (52044). Error details: " + e.Message);
386 using (log4net.NDC.Push(string.Format("SqlException: MESSAGE={0}{1}Diagnostics:{1}{2}", e.Message, System.Environment.NewLine, e.ToString())))
387 {
388 using (log4net.NDC.Push(string.Format("path={0}", path)))
389 {
390 Logging.ATSAdminLog.Error("Could not write configuration data to disk");
391 }
392 }
393 }
394
395 finally
396 {
397 if (writer != null)
398 writer.Close();
399 }
400
401 // DenyAccessRightModifyForUsers(path); // Prevent users from deleting or modifying the hosts file.
402 }
403
404
405 // Check if user is administrator
406 // Returns true if user is administrator
407 public static bool IsAnAdministrator()
408 {
409 WindowsIdentity identity =
410 WindowsIdentity.GetCurrent();
411 WindowsPrincipal principal =
412 new WindowsPrincipal(identity);
413 return principal.IsInRole
414 (WindowsBuiltInRole.Administrator);
415 }
416
417 public static string GetMacAddressFromNameAndDatabase(string strName)
418 {
419 string macAddress;
420 // Try to extract MAC address from client name.
421 macAddress = ATSGlobals.GetMacFromATSname(strName);
422 if (macAddress.Length == 0)
423 { // MAC not in name, try to lookup client name in database
424 atsDataSet datasetClientName = new atsDataSet();
425 // Update dataset with the client row matching the name
426 try
427 {
428 ProSupport.clientTableAdapter.FillOnName(datasetClientName.Client, strName);
429 }
430 catch
431 { // Error when accessing database
432 return "";
433 }
434 if (datasetClientName.Client.Rows.Count > 0)
435 { // Client row found in database
436 macAddress = datasetClientName.Client.Rows[0]["MacAddress"].ToString();
437 }
438 else
439 { // Name not found
440 macAddress = "";
441 }
442 }
443 return macAddress;
444 }
445
446 // Re-writes all config files, so that they will be containing new parameters.
447 // Also creates config files if they have been deleted, i.e by an expired beta.
448 public static void RecreateConfigFiles()
449 {
450 // Re-create all config files
451 if (ATSGlobals.tftpConfig == 0)
452 { // Use ATS TFTP
453 WriteConfigFiles(ATSGlobals.strTFTPdir);
454 }
455 else if (ATSGlobals.tftpConfig == 1)
456 { // External TFTP
457 // Write the config file to all TFTP directories
458 atsDataSet.TftpServerDataTable datatableTFTP; // TFTP server directories
459 datatableTFTP = new atsDataSet.TftpServerDataTable();
460 tftpServerTableAdapter.Fill(datatableTFTP);
461 foreach (DataRow row in datatableTFTP.Rows)
462 {
463 // Write to TFTP path
464 WriteConfigFiles(GetTftpPath(row));
465 }
466 }
467 else
468 throw new Exception("Unknown TFTP mode 88158");
469
470 WriteHostsFiles();
471 ATSImageRuntimeConfig currentConfig = new ATSImageRuntimeConfig();
472 currentConfig.ReadDefaultFromDatabase();
473 ProSupport.WriteConfigFiles(currentConfig, ProSupport.strNetworkConfigFilename, false);
474 }
475
476
477 static void WriteConfigFiles(string strDirectory)
478 {
479 ATSImageRuntimeConfig currentConfig = new ATSImageRuntimeConfig();
480 atsDataSet datasetClient = new atsDataSet();
481 ProSupport.clientTableAdapter.FillClients(datasetClient.Client);
482 string strFilePath;
483 foreach (DataRow row in datasetClient.Client.Rows)
484 {
485 // Write the config file corresponding to the client
486 currentConfig.ReadFromDatabase(row);
487 strFilePath = strDirectory + @"\" + row["MacAddress"];
488 currentConfig.WriteConfigFile(strFilePath);
489 }
490 }
491
492 // Return a local or UNC path for TFTP server, depending on what it best.
493 public static string GetTftpPath(DataRow tftpRow)
494 {
495 // Extract computer name from UNC Path
496 string uncPath = tftpRow["Path"].ToString();
497 string uncComputer = uncPath.Substring(2, uncPath.IndexOf(@"\", 2) - 2);
498 if (uncComputer.ToUpper() == Environment.MachineName)
499 { // The UNC path resides on this computer, use a local path if it is available
500 if (tftpRow["LocalPath"].ToString().Length > 0)
501 { // We have a local path
502 return tftpRow["LocalPath"].ToString();
503 }
504 else
505 { // No local path, we have to go with the UNC path referring to the local machine.
506 return tftpRow["Path"].ToString();
507 }
508 }
509 else
510 { // The UNC path does not reside on this computer, use it as it is.
511 return tftpRow["Path"].ToString();
512 }
513 }
514
515
516 // Sub routines used by wizard for screen resolution
517 //-----------------------------------------------------
518
519 public static void UpdateScreenResolutionControls(int x, int y, TextBox txtScreenResX, TextBox txtScreenResY, TrackBar tbrScreenResolution)
520 {
521 txtScreenResX.Text = x.ToString();
522 txtScreenResY.Text = y.ToString();
523
524 for (int i = 0; i < ATSGlobals.ScreenResolutions.GetLength(0); i++)
525 {
526 if (x == ATSGlobals.ScreenResolutions[i, 0] && y == ATSGlobals.ScreenResolutions[i, 1])
527 {
528 tbrScreenResolution.Value = i + 1;
529 return;
530 }
531
532 }
533 // Values could not be expressed using the track bar. Set it at default.
534 tbrScreenResolution.Value = 4;
535 }
536
537 public static void GetScreenResolutionFromTrackbar(TrackBar tbr, out int x, out int y)
538 {
539 x = ATSGlobals.ScreenResolutions[tbr.Value - 1, 0];
540 y = ATSGlobals.ScreenResolutions[tbr.Value - 1, 1];
541 }
542
543 public static void UpdateResolutionTrackbar(TextBox txtScreenResX, TextBox txtScreenResY, TrackBar tbrScreenResolution)
544 { // Try to convert x, y values to trackbar.
545 int x, y;
546 try
547 {
548 x = Int32.Parse(txtScreenResX.Text.Trim());
549 }
550 catch (Exception)
551 {
552 x = 0;
553 }
554
555 try
556 {
557 y = Int32.Parse(txtScreenResY.Text.Trim());
558 }
559 catch (Exception)
560 {
561 y = 0;
562 }
563
564 UpdateScreenResolutionControls(x, y, txtScreenResX, txtScreenResY, tbrScreenResolution);
565 }
566
567
568
569 public static void copyDirectory(string Src,string Dst)
570 {
571 String[] Files;
572
573 if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar)
574 Dst+=Path.DirectorySeparatorChar;
575 if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
576 Files=Directory.GetFileSystemEntries(Src);
577 foreach(string Element in Files){
578 // Sub directories
579
580 if(Directory.Exists(Element))
581 copyDirectory(Element,Dst+Path.GetFileName(Element));
582 // Files in directory
583
584 else
585 File.Copy(Element,Dst+Path.GetFileName(Element), true);
586 }
587 }
588
589
590
591
592 } // end class Prosupport
593
594
595 public class CryptStream : StreamWriter
596 {
597 BinaryWriter outStream;
598
599 const byte offset1 = 36;
600 const byte offset2 = 0xab;
601 const byte key = 0x36;
602 byte value;
603
604 public CryptStream(string s)
605 : base(s)
606 {
607 // Base constructor has created a stream. Steal it.
608 outStream = new BinaryWriter(base.BaseStream);
609 WriteHeader();
610 }
611
612
613 public CryptStream(Stream s)
614 : base(s)
615 {
616 outStream = new BinaryWriter(s);
617 WriteHeader();
618 }
619
620
621 private void WriteHeader()
622 {
623 outStream.Write((byte)0x41);
624 outStream.Write((byte)0x54);
625 outStream.Write((byte)0x53);
626 outStream.Write((byte)0x78);
627 value = key;
628 }
629
630
631 private byte Crypt(byte ch1)
632 {
633 byte ch2 = (byte)((ch1 + offset1) & 0xFF);
634 byte ch3 = (byte)((ch2 ^ value) & 0xFF);
635 value = (byte)((value + offset2) & 0xFF);
636 return ch3;
637 }
638
639 public override void Write(string s)
640 {
641 for (int i = 0; i < s.Length; i++)
642 outStream.Write(Crypt((byte)s[i]));
643 }
644
645
646 public override void WriteLine(string s)
647 {
648 Write(s);
649 Write("\n");
650 }
651 }
652
653 } //end namespace