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