/********************************************************************************************* * 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(); } } }