362 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			362 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| /*********************************************************************************************
 | |
|  * Copyright 2004 - Volian Enterprises, Inc. All rights reserved.
 | |
|  * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
 | |
|  * ------------------------------------------------------------------------------
 | |
|  * $Workfile: VELock.cs $     $Revision: 2 $
 | |
|  * $Author: Kathy $   $Date: 6/15/06 8:58a $
 | |
|  *
 | |
|  * $History: VELock.cs $
 | |
|  * 
 | |
|  * *****************  Version 2  *****************
 | |
|  * User: Kathy        Date: 6/15/06    Time: 8:58a
 | |
|  * Updated in $/LibSource/VENetwork
 | |
|  * B2006-024 fix - add lock without prompt
 | |
|  * 
 | |
|  * *****************  Version 1  *****************
 | |
|  * User: Kathy        Date: 7/27/04    Time: 8:45a
 | |
|  * Created in $/LibSource/VENetwork
 | |
|  *********************************************************************************************/
 | |
| 
 | |
| using System;
 | |
| using System.IO;
 | |
| using System.Windows;
 | |
| using System.Windows.Forms;
 | |
| using System.ComponentModel;
 | |
| using Utils;
 | |
| using VlnStatus;
 | |
| 
 | |
| namespace VENetwork
 | |
| {
 | |
| 	// The following two enums are used to check lock types & statuses through the users
 | |
| 	// of the VELock class.
 | |
| 
 | |
| 	// LockTypes:
 | |
| 	// no lock at level required (dummy nodes, etc), system, plant & set level, i.e.
 | |
| 	//        None, sprocess.dat, pprocess.dat, process.dat
 | |
| 	public enum LockTypes {None=0, System=1, Plant=2, ProcSet=3};
 | |
| 
 | |
| 	// Status:
 | |
| 	// no lock exists, locked my myself, locked by someelse, I want to lock-but someone else in
 | |
| 	public enum Status {NoLock=0, Locked=1, LockedByOther=2, LockPending=3};
 | |
| 
 | |
| 	// This class manages the locking options for multi-user support, i.e. creation and 
 | |
| 	// removing locks, i.e. lck files at system, plant and procedure set levels.
 | |
| 	public class VELock
 | |
| 	{		
 | |
| 		string [] STypes = {"SPROCESS.LCK", "PPROCESS.LCK", "PROCESS.LCK"};
 | |
| 
 | |
| 		private VENetwork.LockTypes m_Type;	// from type enum (above)
 | |
| 		private string m_Path;
 | |
| 		private VENetwork.Status m_Status;
 | |
| 		private string m_UserNetworkID;		// the 'm_' are all from the lck file. 
 | |
| 		private string m_UserName; 
 | |
| 		private string m_UserPhone1;
 | |
| 		private string m_UserPhone2;
 | |
| 		private string m_UserLoc1;
 | |
| 		private string m_UserLoc2;
 | |
| 		private string m_UserShell;			// 1 - vfw, 2 - 16bit browser, 3 - 32-bit ve-proms
 | |
| 		private String m_UserProcess;
 | |
|         private string m_FailureReason;
 | |
| 		private string m_Why;				// reason for the lock, from user
 | |
| 		private DateTime m_DT;
 | |
| 		private UserData curUserData;		// user data from cfg file
 | |
| 		private bool HasActiveUsers;
 | |
| 
 | |
| 		// this constructor opens the file & reads the data to set the properties
 | |
| 		public VELock(string iloc, UserData iuserdata, VENetwork.LockTypes ityp)
 | |
| 		{
 | |
| 			// HasActiveUsers is used when a lock is created, to determine whether
 | |
| 			// there are active users for the current level. Otherwise, it is not used.
 | |
| 			HasActiveUsers = true;
 | |
| 			m_Type = ityp;			
 | |
| 			// if there is no lock at this level, just return.
 | |
| 			if (ityp==VENetwork.LockTypes.None) return;	
 | |
| 			curUserData = iuserdata;
 | |
| 			m_Path = iloc + "\\" + STypes[(int)ityp-1];
 | |
| 			LoadLockProperties();
 | |
| 		}
 | |
| 	
 | |
| 		// this method creates a lock for the current user. It is used when the user
 | |
| 		// selects to place a lock at a given level.
 | |
| 		public bool CreateLock(VEConnection myconn, bool prompt)
 | |
| 		{
 | |
| 			bool success=false;
 | |
| 			if (!prompt)
 | |
| 				success=CreateLockFileNoPrompt(myconn);
 | |
| 			else
 | |
| 				success=CreateLockFile(myconn);
 | |
| 			if (success)LoadLockProperties();
 | |
| 			return success;
 | |
| 		}
 | |
| 
 | |
| 		[Description("UserName"),Category("LockInfo"),]public string UserName
 | |
| 		{
 | |
| 			get{return m_UserName;}
 | |
| 			set{m_UserName=value;}
 | |
| 		}
 | |
| 		[Description("UserNetworkID"),Category("LockInfo"),]public string UserNetworkID
 | |
| 		{
 | |
| 			get{return m_UserNetworkID;}
 | |
| 			set{m_UserNetworkID=value;}
 | |
| 		}
 | |
| 		[Description("UserProcess"),Category("LockInfo"),]public string UserProcess
 | |
| 		{
 | |
| 			get{return m_UserProcess;}
 | |
| 			set{m_UserProcess=value;}
 | |
| 		}
 | |
| 		[Description("Loc1"),Category("LockInfo"),]public string Loc1
 | |
| 		{
 | |
| 			get{return m_UserLoc1;}
 | |
| 			set{m_UserLoc1=value;}
 | |
| 		}
 | |
| 		[Description("Loc2"),Category("LockInfo"),]public string Loc2
 | |
| 		{
 | |
| 			get{return m_UserLoc2;}
 | |
| 			set{m_UserLoc2=value;}
 | |
| 		}
 | |
| 		[Description("Phone1"),Category("LockInfo"),]public string Phone1
 | |
| 		{
 | |
| 			get{return m_UserPhone1;}
 | |
| 			set{m_UserPhone1=value;}
 | |
| 		}
 | |
| 		[Description("Phone2"),Category("LockInfo"),]public string Phone2
 | |
| 		{
 | |
| 			get{return m_UserPhone2;}
 | |
| 			set{m_UserPhone2=value;}
 | |
| 		}
 | |
| 		[Description("LockPath"),Category("LockInfo"),]public string Path
 | |
| 		{
 | |
| 			get{return m_Path;}
 | |
| 			set{m_Path=value;}
 | |
| 		}
 | |
| 
 | |
| 		[Description("FailureReason"),Category("LockInfo"),]public string FailureReason
 | |
| 		{
 | |
| 			get{return m_FailureReason;}
 | |
| 			set{m_FailureReason=value;}
 | |
| 		}
 | |
| 
 | |
| 		[Description("Why"),Category("Reason"),]public string Why
 | |
| 		{
 | |
| 			get{return m_Why;}
 | |
| 			set{m_Why=value;}
 | |
| 		}
 | |
| 		[Description("WhyDate"),Category("Reason"),]public DateTime WhyDT
 | |
| 		{
 | |
| 			get{return m_DT;}
 | |
| 			set{m_DT=value;}
 | |
| 		}
 | |
| 		[Description("LockStatus"), Category("LockInfo"),]public VENetwork.Status LockStatus
 | |
| 		{
 | |
| 			get{return m_Status;}
 | |
| 			set{m_Status=value;}
 | |
| 		}
 | |
| 		[Description("LockType"),Category("LockInfo"),]public VENetwork.LockTypes LockType
 | |
| 		{
 | |
| 			get{return m_Type;}
 | |
| 			set{m_Type=value;}
 | |
| 		}
 | |
| 
 | |
| 		private bool WriteToLockFile()
 | |
| 		{
 | |
| 			FileStream fs = null;
 | |
| 			BinaryWriter bw = null;
 | |
| 			try
 | |
| 			{
 | |
| 				// set the user data
 | |
| 				m_UserNetworkID = curUserData.UserNetworkID;
 | |
| 				m_UserName = curUserData.UserName;
 | |
| 				m_UserPhone1 = curUserData.UserPhone1;
 | |
| 				m_UserPhone2 = curUserData.UserPhone2;
 | |
| 				m_UserLoc1 = curUserData.UserLoc1;
 | |
| 				m_UserLoc2 = curUserData.UserLoc2;
 | |
| 				m_UserShell = curUserData.UserShell;
 | |
| 				m_UserProcess = curUserData.UserProcess;
 | |
| 				// A reason was entered. Create the file with user's data
 | |
| 				fs = new FileStream(m_Path,FileMode.CreateNew,FileAccess.ReadWrite,FileShare.None);
 | |
| 				bw = new BinaryWriter(fs);					
 | |
| 				byte tmp=(byte)Utils.UserCStatus.PRACTIVE;   // status
 | |
| 				bw.Write(tmp);
 | |
| 				char [] xbuf = new char[9];
 | |
| 				xbuf = m_UserNetworkID.PadRight(9,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[31];
 | |
| 				xbuf = m_UserName.PadRight(31,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[16];
 | |
| 				xbuf = m_UserPhone1.PadRight(16,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[16];
 | |
| 				xbuf = m_UserPhone2.PadRight(16,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[31];
 | |
| 				xbuf = m_UserLoc1.PadRight(31,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[31];
 | |
| 				xbuf = m_UserLoc2.PadRight(31,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[2];
 | |
| 				xbuf = m_UserShell.PadRight(2,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[3];
 | |
| 				xbuf = m_UserProcess.PadRight(3,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				xbuf = new char[60];
 | |
| 				xbuf = m_Why.PadRight(60,'\0').ToCharArray();
 | |
| 				bw.Write(xbuf);
 | |
| 				bw.Close();
 | |
| 				fs.Close();
 | |
| 			}
 | |
| 			catch (Exception e)
 | |
| 			{
 | |
| 				MessageBox.Show(e.Message,"Could not set a lock at this time.");
 | |
| 				if (bw!=null) bw.Close();
 | |
| 				if (fs!=null) fs.Close();
 | |
| 				if (File.Exists(m_Path)) File.Delete(m_Path);
 | |
| 				return false;
 | |
| 			}
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		private bool CreateLockFileNoPrompt(VEConnection veconn)
 | |
| 		{
 | |
| 			HasActiveUsers = veconn.HasActiveUsers();
 | |
| 			if (HasActiveUsers) return false;
 | |
| 			if (File.Exists(m_Path)==true) return false;
 | |
| 			// a string should be passed in with the reason, but this was
 | |
| 			// added to fix an approval bug & will have to do for now.
 | |
| 			m_Why = "Approval";
 | |
| 			WriteToLockFile();
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		// Create the lock file.
 | |
| 		private bool CreateLockFile(VEConnection veconn)
 | |
| 		{		
 | |
| 			// check for active users. if we have them, we can only create a pending lock
 | |
| 			HasActiveUsers = veconn.HasActiveUsers();
 | |
| 			if (HasActiveUsers)
 | |
| 			{
 | |
| 				MessageBoxButtons buttons = MessageBoxButtons.YesNo;
 | |
| 				DialogResult result;
 | |
| 
 | |
| 				// Displays the MessageBox.
 | |
| 
 | |
| 				result = MessageBox.Show("There are other users in the system, a pending lock will be used until other users are no longer in the system. Do you want this type of lock?", "Ve-PROMS Pending Lock", buttons);
 | |
| 				if(result == DialogResult.No)
 | |
| 				{
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			// if one exists, can't do it.
 | |
| 			if (File.Exists(m_Path)==false)
 | |
| 			{
 | |
| 				// Get user's reason for creating lock & make the file based on
 | |
| 				// user's configuration data (UserData read in from the user's environment.)
 | |
| 				LockDlg dlg = new LockDlg(this);
 | |
| 				dlg.ShowDialog();
 | |
| 				if (dlg.DialogResult == DialogResult.OK && (Why != null && Why !=""))
 | |
| 				{
 | |
| 					m_Why = Why;
 | |
| 					WriteToLockFile();
 | |
| 				}
 | |
| 				else if (dlg.DialogResult != DialogResult.Cancel)
 | |
| 				{
 | |
| 					MessageBox.Show("You must enter a message to perform a lock.","VE-PROMS");
 | |
| 					return false;
 | |
| 				}
 | |
| 				return true;
 | |
| 			}
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// Read in lock information & Determine lock status based on information
 | |
| 		private void LoadLockProperties()
 | |
| 		{
 | |
| 			FileStream fs = null;
 | |
| 			BinaryReader br = null;
 | |
| 			if (File.Exists(m_Path))
 | |
| 			{
 | |
| 				VlnSpinner spin = new VlnSpinner(2,25,"- Getting Lock Info for ",m_Path,true,true,false);
 | |
| 				while(spin.SpinnerWait(fs!=null))
 | |
| 				{
 | |
| 					try
 | |
| 					{
 | |
| 						this.m_DT = File.GetCreationTime(m_Path);
 | |
| 						fs = new FileStream(m_Path,FileMode.Open,FileAccess.Read,FileShare.Read);
 | |
| 						br = new BinaryReader(fs);
 | |
| 					
 | |
| 						byte tmp;
 | |
| 						tmp = br.ReadByte();
 | |
| 						m_UserNetworkID = new string(br.ReadChars(9)).Replace('\0',' ').Trim();
 | |
| 						m_UserName = new string(br.ReadChars(31)).Replace('\0',' ').Trim();
 | |
| 						m_UserPhone1 = new string(br.ReadChars(16)).Replace('\0',' ').Trim();
 | |
| 						m_UserPhone2 = new string(br.ReadChars(16)).Replace('\0',' ').Trim();
 | |
| 						m_UserLoc1 = new string(br.ReadChars(31)).Replace('\0',' ').Trim();
 | |
| 						m_UserLoc2 = new string(br.ReadChars(31)).Replace('\0',' ').Trim();
 | |
| 						m_UserShell = new string(br.ReadChars(2)).Replace('\0',' ').Trim();
 | |
| 						m_UserProcess = new string(br.ReadChars(3)).Replace('\0',' ').Trim();
 | |
| 						m_Why = new string(br.ReadChars(60)).Replace('\0',' ').Trim();
 | |
| 						br.Close();
 | |
| 						fs.Close();
 | |
| 					}
 | |
| 					catch (Exception e)
 | |
| 					{
 | |
| 						MessageBox.Show(e.Message, "Could not read locking information");
 | |
| 						br.Close();
 | |
| 						fs.Close();
 | |
| 						fs = null;
 | |
| 					}
 | |
| 
 | |
| 					// if owned by me, it's a pending lock, i.e. I set to lock it, but
 | |
| 					// someone else may be in. This gets reset when the dat file is 
 | |
| 					// connected to (if a lock exists).
 | |
| 					if (curUserData.UserName == m_UserName) 
 | |
| 						m_Status = Status.LockPending;			
 | |
| 					else
 | |
| 						m_Status = Status.LockedByOther;
 | |
| 				}
 | |
| 				spin.Dispose();
 | |
| 			}
 | |
| 			else
 | |
| 				m_Status = Status.NoLock;
 | |
| 		}
 | |
| 
 | |
| 		// this method unlocks by deleting the lock file & reloading properties
 | |
| 		public bool UnLock(bool doprompt)
 | |
| 		{
 | |
| 			if (m_Status!=Status.Locked && m_Status!=Status.LockPending) return true;
 | |
| 			if (doprompt)
 | |
| 			{
 | |
| 				string [] msg = {"System", "Plant", "Procedure Set"};
 | |
| 				MessageBoxButtons buttons = MessageBoxButtons.YesNo;
 | |
| 				DialogResult result;
 | |
| 				result = MessageBox.Show("Are you sure you want to release your "+msg[(int)this.m_Type-1]+ " lock?", "Ve-PROMS Lock Removal", buttons);
 | |
| 				if(result == DialogResult.No)
 | |
| 				{
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 			if (File.Exists(m_Path))
 | |
| 			{
 | |
| 				VlnSpinner spin = new VlnSpinner(2,25,"- Unlinking ",m_Path,true,true,false);
 | |
| 				while(spin.SpinnerWait(!File.Exists(m_Path)))
 | |
| 				{
 | |
| 					File.Delete(m_Path);
 | |
| 				}
 | |
| 				spin.Dispose();
 | |
| 			}
 | |
| 			LoadLockProperties();
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		// refresh reloads the lock properties (if I didn't lock it-if I locked it, they
 | |
| 		// won't change).
 | |
| 		public void Refresh()
 | |
| 		{
 | |
| 			LoadLockProperties();
 | |
| 		}
 | |
| 	}
 | |
| }
 |