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

Contents of /trunk/TSAdminTool/ProSupport.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (show annotations) (download)
Wed Jul 11 18:48:42 2012 UTC (7 years, 7 months ago) by william
File size: 28218 byte(s)
+ deprecate some File ACL methods

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

  ViewVC Help
Powered by ViewVC 1.1.22