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