/*********************************************************************************************
* Copyright 2004 - Volian Enterprises, Inc. All rights reserved.
* Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
* ------------------------------------------------------------------------------
* $Workfile: UsrRunTime.cs $ $Revision: 9 $
* $Author: Jsj $ $Date: 10/31/07 10:11a $
*
* $History: UsrRunTime.cs $
*
* ***************** Version 9 *****************
* User: Jsj Date: 10/31/07 Time: 10:11a
* Updated in $/LibSource/Utils
* Bug fix to ExeAdjust()
*
* ***************** Version 8 *****************
* User: Jsj Date: 7/21/06 Time: 2:57p
* Updated in $/LibSource/Utils
* added comment of logic that might be needed in future.
*
* ***************** Version 7 *****************
* User: Jsj Date: 5/17/05 Time: 11:54a
* Updated in $/LibSource/Utils
* cleanup
*
* ***************** Version 6 *****************
* User: Kathy Date: 4/21/05 Time: 10:17a
* Updated in $/LibSource/Utils
* issingleuser
*
* ***************** Version 5 *****************
* User: Kathy Date: 4/12/05 Time: 1:00p
* Updated in $/LibSource/Utils
* B2004-050: single user needed network info
*
* ***************** Version 4 *****************
* User: Kathy Date: 1/24/05 Time: 2:44p
* Updated in $/LibSource/Utils
* B2005-004 fixes
*
* ***************** Version 3 *****************
* User: Kathy Date: 1/10/05 Time: 12:57p
* Updated in $/LibSource/Utils
* B2004-063 fix
*
* ***************** Version 2 *****************
* User: Jsj Date: 11/12/04 Time: 10:32a
* Updated in $/LibSource/Utils
* Save the user's TEMP dir path ExeAjust() handles TEMP dir and Data Dir
*
* ***************** Version 1 *****************
* User: Kathy Date: 7/27/04 Time: 8:34a
* Created in $/LibSource/Utils
*********************************************************************************************/
using System;
using System.IO;
using System.Windows.Forms;
using System.Text;
using Org.Mentalis.Files;
namespace Utils
{
public enum UserCStatus
{
PRINACTIVE=0, PRACTIVE=1 // process record is NOT active, active respectively
};
public class UserData
{
public byte UserStatus;
public string UserNetworkID;
public string UserName;
public string UserPhone1;
public string UserPhone2;
public string UserLoc1;
public string UserLoc2;
public string UserShell; // 1 - vfw; 2 - browser; 3 - 32-bit browser
public string UserProcess;
// the first constructor loads data from a user's cfg file
public UserData(string ucfgpath)
{
if (File.Exists(ucfgpath)==false) return;
// create an xml node from the [User Data] in the cfg file & transfer
// to this. Note that the UserNetworkID is not set until the serial
// number is read to determine whether in multi-user-mode (B2004-050)
PrivateProfile ppUserData = new PrivateProfile(ucfgpath);
UserName=ppUserData.Attr("User Data","UserName");
UserPhone1=ppUserData.Attr("User Data","UserPhone1");
UserPhone2=ppUserData.Attr("User Data","UserPhone2");
UserLoc1=ppUserData.Attr("User Data","UserLoc1");
UserLoc2=ppUserData.Attr("User Data","UserLoc2");
char tmp = '\x03';
UserShell = tmp.ToString(); // 1 - vfw; 2 - browser; 3 - 32-bit browser
UserProcess="";
ppUserData=null;
}
public void SetNetworkID(string ucfgpath, bool inmultiuser)
{
// create an xml node from the [User Data] in the cfg file & transfer
// to this.
PrivateProfile ppUserData = new PrivateProfile(ucfgpath);
UserNetworkID=ppUserData.Attr("User Data","UserNetworkID");
if (inmultiuser && (UserNetworkID == "" || UserNetworkID==null))
{
MessageBox.Show("Invalid UserNetworkID from " + ucfgpath +", set before reexecuting VE-PROMS.","VE-PROMS Error");
Environment.Exit(-1);
}
ppUserData=null;
}
// the next constructor gets the input 'nth' record from the dat file (dat file is
// passed in via a FileStream
public UserData(FileStream dfs, int n)
{
// seek to the position as defined by n.
long skpos = (long)(n * 140); // 140 is the size of the record from old proms.
dfs.Seek(skpos,SeekOrigin.Begin);
byte [] test = new byte[140];
dfs.Read(test,0,140);
UserStatus = test[0];
string tmp = Encoding.ASCII.GetString(test,0,140);
UserNetworkID = tmp.Substring(1,9).Replace('\0',' ').Trim();
UserName = tmp.Substring(10,31).Replace('\0',' ').Trim();
UserPhone1 = tmp.Substring(41,16).Replace('\0',' ').Trim();
UserPhone2 = tmp.Substring(57,16).Replace('\0',' ').Trim();
UserLoc1 = tmp.Substring(73,31).Replace('\0',' ').Trim();
UserLoc2 = tmp.Substring(104,31).Replace('\0',' ').Trim();
UserShell = tmp.Substring(135,2).Replace('\0',' ').Trim();
UserProcess = tmp.Substring(137,3).Replace('\0',' ').Trim();
}
// write this user data out to the filestream at the current position in file
// defined in dfs
public void Write(FileStream dfs)
{
dfs.WriteByte(UserStatus);
byte[] btmp = Encoding.ASCII.GetBytes(UserNetworkID.PadRight(9,'\0'));
dfs.Write(btmp,0,9);
btmp = Encoding.ASCII.GetBytes(UserName.PadRight(31,'\0'));
dfs.Write(btmp,0,31);
btmp = Encoding.ASCII.GetBytes(UserPhone1.PadRight(16,'\0'));
dfs.Write(btmp,0,16);
btmp = Encoding.ASCII.GetBytes(UserPhone2.PadRight(16,'\0'));
dfs.Write(btmp,0,16);
btmp = Encoding.ASCII.GetBytes(UserLoc1.PadRight(31,'\0'));
dfs.Write(btmp,0,31);
btmp = Encoding.ASCII.GetBytes(UserLoc2.PadRight(31,'\0'));
dfs.Write(btmp,0,31);
btmp = Encoding.ASCII.GetBytes(UserShell.PadRight(2,'\0'));
dfs.Write(btmp,0,2);
btmp = Encoding.ASCII.GetBytes(UserProcess.PadRight(3,'\0'));
dfs.Write(btmp,0,3);
}
};
///
/// Summary description for UserRunTime. This class contains all pertinent information
/// for the runtime for this instance of the program, including cfg, paths, menu file,
/// security, serial number, options, etc.
///
public class UserRunTime
{
public string exepath;
public string syspath;
public string netsyspath;
public string TempDirPath;
public string ucfgpath; // user config file name
public string appcfgpath; // app config file name
public Security sec;
public SerialNo SerialNumber;
public string OptionsFile;
public string initials; // user login name
public string UserID; // cfg name and/or login
public MenuXML menuwinXML;
public MenuXML menuwin2XML;
public string myUserNetworkID;
public UserData myUserData;
public bool InMultiUserMode;
// make some form properties here, such as color. - make need it's own class,
//
public UserRunTime()
{
menuwin2XML = null;
SetExeName();
// load in xml list of plants. Then do exist tests to see if they
// exist on the datapath.
menuwinXML = new MenuXML(syspath + "\\menuwin.xml");
}
public void SetSecurity(Security isec)
{
// set the user's run time security settings. also, flag whether this user is
// running in multi user mode (just so we don't have to keep making this check
// later)
sec = isec;
// Do this separate (SetUserMode()) to remove interdependent logic path between
// security(vesam), user CFG file, and the serial number
// InMultiUserMode = (SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_NETWORK_ON)>0)?true:false;
}
public void SetUserMode()
{
if (SerialNumber.SerialNum != -1)
InMultiUserMode = (SerialNumber.GetSNOption((uint)Utils.SerialNo.SN_Flags.SN_NETWORK_ON)>0)?true:false;
if (InMultiUserMode) myUserData.SetNetworkID(ucfgpath, InMultiUserMode);
}
private bool IsSingleUserMode()
{
// Need to do:
// This needs to check if a lock is currently set as well
// - jsj 7/20/06
return !InMultiUserMode;
}
// Adjust the input file with the required pathname as follows:
// '~': (system path) i.e. c:\VE-PROMS
// '@': (executable path) i.e. c:\VE-PROMS\BIN
// '\342': current data directory i.e. c:\VEHPR1B\PROCS
// '\347': resolve for single user mode, append tempdir onto data dir i.e. TEMPS\JOHN____.D00
public string ExeAdjust(string str)
{
if (exepath==null)SetExeName();
// This logic will allow me to combine the use of our special
// tokens. For example, I needed a user temp directory in the
// VE-PROMS root for the Search Across Procedure Sets option:
// "~\374results" --> C:\VE-PROMS\TEMPS\JOHN____.D00\RESUTLS
StringBuilder exebuff = new StringBuilder();
StringBuilder exetkn = new StringBuilder(str);
string exetkn_str = exetkn.ToString();
int pos = 0;
char[] tchar = "~@\xE7\xE2".ToCharArray();
/** Bug Fix: B2007-015
* If a short file/directory name contained a ~ character, it was
* being processed, when it should not have.
* i.e. we were getting the current directory, then looping back up
* and searching the directory string (finding a ~ char)
*
* I added logic to use a starting position in the IndexOfAny() function
* so that we can skip past the portions already processes.
*/
while ((pos=exetkn_str.IndexOfAny(tchar,pos))>-1)
{
char[] chr;
string curdir = Directory.GetCurrentDirectory(); // for use with '\xE2'
chr = new char[exetkn_str.Length];
chr = exetkn_str.ToCharArray();
exetkn.Remove(pos,1);
switch (chr[0])
{
case '~': exetkn.Insert(pos,syspath+"\\"); // i.e. c:\VE-PROMS
pos += syspath.Length +1;
break;
case '@': exetkn.Insert(pos,exepath+"\\"); // i.e. c:\VE-PROMS\BIN
pos += exepath.Length + 1;
break;
case '\xE2': // case '\342':
exetkn.Insert(pos,curdir+"\\"); // i.e. c:\VEHPR1B\PROCS
pos += curdir.Length + 1;
break;
case '\xE7': // case '\347':
if (!IsSingleUserMode()&& TempDirPath!=null)
{
exetkn.Insert(pos,TempDirPath+"\\"); // i.e. TEMPS\JOHN____.D00
pos += TempDirPath.Length + 1;
}
break;
}
exetkn_str = exetkn.ToString();
}
return exetkn.ToString();
}
private void SetExeName()
{
ShortName sname = new ShortName(System.Environment.CommandLine);
string cmdlinepath = sname.ShortFileName;
string upbuff = cmdlinepath.ToUpper();
string tmp = upbuff.Substring(1,upbuff.LastIndexOf("\\")-1);
int idx = tmp.IndexOf("VE-PROMS.NET");
if (idx > 0)
{
exepath = tmp.Substring(0,idx+8) + tmp.Substring(idx+12);
syspath = exepath.Substring(0,exepath.IndexOf("\\BIN"));
netsyspath = syspath + ".NET";
}
else
{
exepath = tmp;
syspath = exepath.Substring(0,exepath.IndexOf("\\BIN"));
netsyspath = syspath + ".NET";
}
}
public void SetAppConfig(string pth)
{
appcfgpath = pth;
}
public bool SetUserConfig()
{
bool Rtnval = true;
PrivateProfile Veproms_ini = new PrivateProfile(ExeAdjust("~veproms.ini"));
// Find the UserId (not the number, he name/initials)
if (UserID==null || UserID.Equals(""))
{
// see if it's defined via an environment variable
UserID = System.Environment.GetEnvironmentVariable("userid");
if (UserID == null)
{
// Check the VEPROMS.INI file
// UserID = Veproms_ini.Attr("/ini/section[@name='veconfig']/param[@name='userid']/@value");
UserID = Veproms_ini.Attr("veconfig","userid");
}
if (UserID == null || UserID.Equals(""))
{
if (sec.initials != null && !sec.initials.Equals(""))
{
// default to the user's login name
UserID = sec.initials;
}
else
{
// default to VEPROMS.CFG
UserID = "VEPROMS";
}
}
}
// Fing the VECONFIG path
ucfgpath=System.Environment.GetEnvironmentVariable("veconfig");
// If VECONFIG environment variable not set then check the
// VEPROMS.INI file for VECONFIG settings.
if (ucfgpath == null || ucfgpath.Equals(""))
{
// ucfgpath = Veproms_ini.Attr("/ini/section[@name='veconfig']/param[@name='file']/@value");
ucfgpath = Veproms_ini.Attr("veconfig","file");
if (ucfgpath==null || ucfgpath.Equals(""))
{
// still no path, use default cfg file path
ucfgpath = ExeAdjust("~CONFIG");
}
}
if (ucfgpath != null)
{
string tmp_UID="";
// See it the VECONFIG path includes a CFG file name.
// if no CFG file name, then build one based on userid
bool atroot = ucfgpath.EndsWith(":\\");
if (!atroot)
{
if (ucfgpath.EndsWith("\\"))
{
// trim the ending backslash
ucfgpath = ucfgpath.Substring(0,ucfgpath.Length-1);
}
}
//See if we need to build a CFG file name
if (atroot || Directory.Exists(ucfgpath))
{
// use the no more than the first 8 chars of the userid
tmp_UID = (UserID.Length > 8)?UserID.Substring(0,8) : UserID;
// Build the CFG file name and append to the VECONFIG path
ucfgpath = ucfgpath + "\\" + tmp_UID + ".CFG";
}
}
if (File.Exists(ucfgpath))
myUserData = new UserData(ucfgpath);
else
{
// error - cfg file does not exist
Rtnval = false;
MessageBox.Show("Configuration file:\n\n" + ucfgpath + "\n\nDoes not exist","Missing CFG file");
}
return Rtnval;
}
public void FreeMenuWinXML()
{
menuwinXML=null;
}
public void LoadMenuWin2()
{
if (menuwin2XML == null)
menuwin2XML = new MenuXML(syspath + "\\menuwin2.xml");
// menuwin2XML = new MenuXML("e:\\ve-proms\\menuwin2.xml");
}
public void FreeMenuWin2XML()
{
menuwin2XML=null;
}
// The following methods update the cfg file (delete item, add item & mod)
//public bool DeletePathFromCfg(string delpth)
//{
// IniReader in1 = new IniReader(ucfgpath);
// string curpath = in1.ReadString("Menu","DataPath","");
// string modpath = curpath.Replace(delpth,"");
// inifile.WriteINIKeyValueStr("Menu","DataPath",modpath,ucfgpath);
// return true;
//}
//public void AddPathToCfg(string pth)
//{
// string newpath=null;
// INIFile inifile = new INIFile();
// string curpath = inifile.GetINIKeyValueStr("Menu","DataPath","",132,ucfgpath);
// string tmp = curpath.TrimEnd(" \t".ToCharArray());
// // If none exists, just add that entered, if it ends with ';', don't add another
// if (tmp==null||tmp=="")
// newpath = pth;
// else if (tmp.Substring(tmp.Length-1,1)==";")
// newpath = tmp + pth;
// else
// newpath = tmp+";"+pth;
// inifile.WriteINIKeyValueStr("Menu","DataPath",newpath,ucfgpath);
//}
//public void ModTitleToCfg(string oldtitle, string newtitle)
//{
// INIFile inifile = new INIFile();
// string curpath = inifile.GetINIKeyValueStr("Menu","DataPath","",132,ucfgpath);
// string newpath=curpath.Replace(oldtitle,newtitle);
// inifile.WriteINIKeyValueStr("Menu","DataPath",newpath,ucfgpath);
//}
// Check if plant (defined by location) is in the menuwin file. Return 0 if not,
// 1 if in file and -1 if error reading file.
public int IsInMenuWin(string location)
{
// see if this plant is already in the file, check menuwin
// and if there, assume in both.
try
{
// Create an instance of StreamReader to read from a file.
// The using statement also closes the StreamReader.
using (StreamReader sr = new StreamReader(syspath+"\\menuwin"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int indx;
indx = line.ToUpper().IndexOf(location.ToUpper());
if (indx>-1)
{
sr.Close();
return 1;
}
}
}
}
catch (Exception e)
{
// Let the user know what went wrong.
Console.WriteLine("Could not test " + e.Message + " for plant existence in menuwin file");
return -1;
}
return 0;
}
public bool AddToMenuWin(string title,string location)
{
int inmenufile = IsInMenuWin(location);
if (inmenufile==-1)return false; // error checking for it
if (inmenufile==1)return true; // already there.
// make backup files in case of failure.
FileInfo menuwinbak = new FileInfo(syspath+"\\menuwin");
menuwinbak.CopyTo(syspath+"\\menuwin.BAK",true);
menuwinbak=null;
// add the title and location to the menuwin menuwin.xml files.
// menuwin first.
FileStream fs = new FileStream(syspath+"\\menuwin",
FileMode.Open, FileAccess.ReadWrite, FileShare.None);
// if the file couldn't open, give an error.
if (fs == null)
{
MessageBox.Show("Could not add plant to menuwin file.","VE-PROMS");
menuwinbak = new FileInfo(syspath+"\\menuwin.BAK");
menuwinbak.Delete();
return false;
}
// go to last character of file & see if we have a /r/n. There
// needs to be a single newline between plants in the menuwin file
// or an error will occur.
fs.Seek(-2,SeekOrigin.End);
StreamReader tmpReader = new StreamReader(fs);
int tmpi1 = tmpReader.Peek();
bool hasnewline=false;
if (tmpi1==0xD)hasnewline=true;
fs.Seek(0,SeekOrigin.End);
StreamWriter swFromFileStream = new StreamWriter(fs);
if (hasnewline)
swFromFileStream.Write(title);
else
swFromFileStream.Write("\r\n"+title);
string tmpl = "\r\n{t}" + location + " menu ~menu1a\r\n";
swFromFileStream.Write(tmpl);
swFromFileStream.Flush();
swFromFileStream.Close();
fs.Close();
// now add menuwin.xml text, add this before the end tags for
// system attach & menuwin (i.e. that's the seek part of this
// subtracting from end of file the number of characters for
// these two tags.
// make backup files in case of failure.
FileInfo menuwinxbak = new FileInfo(syspath+"\\menuwin");
menuwinxbak.CopyTo(syspath+"\\menuwinx.BAK",true);
menuwinxbak=null;
fs = new FileStream(syspath+"\\menuwin.xml",
FileMode.Open, FileAccess.Write, FileShare.None);
if (fs == null)
{
MessageBox.Show("Could not add plant to menuwin.xml file.","VE-PROMS");
//delete menuwin & rename the bak file.
menuwinbak = new FileInfo(syspath+"\\menuwin");
menuwinbak.Delete();
menuwinbak = null;
menuwinbak = new FileInfo(syspath+"\\menuwin.BAK");
menuwinbak.CopyTo(syspath+"\\menuwin");
menuwinbak.Delete();
menuwinxbak = new FileInfo(syspath+"\\menuwinx.BAK");
menuwinxbak.Delete();
return false;
}
long flen = fs.Length;
fs.SetLength(flen-27); //remove tags.
fs.Seek(0,SeekOrigin.End);
swFromFileStream = new StreamWriter(fs);
swFromFileStream.Write("\r\n");
swFromFileStream.Write(title);
swFromFileStream.Write("\r\n{t}");
swFromFileStream.Write(location);
swFromFileStream.Write(" menu menu1a\r\n\r\n");
swFromFileStream.Write("\r\n");
swFromFileStream.Flush();
swFromFileStream.Close();
fs.Close();
menuwinbak = new FileInfo(syspath+"\\menuwin.BAK");
menuwinbak.Delete();
menuwinxbak = new FileInfo(syspath+"\\menuwinx.BAK");
menuwinxbak.Delete();
// reload so that the new plant node gets added to the xml tree.
menuwinXML = null;
menuwinXML = new MenuXML(syspath + "\\menuwin.xml");
MessageBox.Show("Please send \\ve-proms\\menuwin & \\ve-proms\\menuwin.xml files to Volian.","VE-PROMS");
return true;
}
public bool ModMenuWin(string newtitle, string oldtitle)
{
// replace the oldtitle with the new in both the menuwin file
// and the menuwin.xml file.
FileInfo menuwinbak = new FileInfo(syspath+"\\menuwin");
menuwinbak.CopyTo(syspath+"\\menuwin.BAK",true);
menuwinbak=null;
// read the whole file, replace the plant title string & save the file.
StreamReader sr = File.OpenText(syspath+"\\menuwin");
string input;
if ((input=sr.ReadToEnd())!=null)
{
sr.Close();
string output = input.Replace(oldtitle,newtitle);
StreamWriter sw = new StreamWriter(syspath+"\\menuwin",false);
sw.Write(output);
sw.Close();
}
else
{
sr.Close();
MessageBox.Show("Could not update menuwin file with new plant title","VE-PROMS");
menuwinbak = new FileInfo(syspath+"\\menuwin.BAK");
menuwinbak.CopyTo(syspath+"\\menuwin",true);
menuwinbak.Delete();
return false;
}
// now do the xml file.
menuwinbak = new FileInfo(syspath+"\\menuwin.xml");
menuwinbak.CopyTo(syspath+"\\menuwinx.BAK",true);
menuwinbak=null;
// read the whole file, replace the plant title string & save the file.
sr = File.OpenText(syspath+"\\menuwin.xml");
if ((input=sr.ReadToEnd())!=null)
{
sr.Close();
string output = input.Replace(oldtitle,newtitle);
StreamWriter sw = new StreamWriter(syspath+"\\menuwin.xml",false);
sw.Write(output);
sw.Close();
}
else
{
sr.Close();
MessageBox.Show("Could not update menuwin.xml file with new plant title","VE-PROMS");
menuwinbak = new FileInfo(syspath+"\\menuwin.BAK");
menuwinbak.CopyTo(syspath+"\\menuwin",true);
menuwinbak.Delete();
menuwinbak = new FileInfo(syspath+"\\menuwinx.BAK");
menuwinbak.CopyTo(syspath+"\\menuwin.xml",true);
menuwinbak.Delete();
return false;
}
return true;
}
}
}