577 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			577 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
/*********************************************************************************************
 | 
						|
 * Copyright 2004 - Volian Enterprises, Inc. All rights reserved.
 | 
						|
 * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
 | 
						|
 * ------------------------------------------------------------------------------
 | 
						|
 * $Workfile: VEConn.cs $     $Revision: 3 $
 | 
						|
 * $Author: Kathy $   $Date: 1/31/05 11:04a $
 | 
						|
 *
 | 
						|
 * $History: VEConn.cs $
 | 
						|
 * 
 | 
						|
 * *****************  Version 3  *****************
 | 
						|
 * User: Kathy        Date: 1/31/05    Time: 11:04a
 | 
						|
 * Updated in $/LibSource/VENetwork
 | 
						|
 * Fix B2005-005 (connection & delete directory errors)
 | 
						|
 * 
 | 
						|
 * *****************  Version 2  *****************
 | 
						|
 * User: Jsj          Date: 11/12/04   Time: 10:34a
 | 
						|
 * Updated in $/LibSource/VENetwork
 | 
						|
 * Save user's Temp dir path
 | 
						|
 * 
 | 
						|
 * *****************  Version 1  *****************
 | 
						|
 * User: Kathy        Date: 7/27/04    Time: 8:44a
 | 
						|
 * Created in $/LibSource/VENetwork
 | 
						|
 *********************************************************************************************/
 | 
						|
 | 
						|
using System;
 | 
						|
using System.IO;
 | 
						|
using System.Collections;
 | 
						|
using System.Windows;
 | 
						|
using System.Windows.Forms;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Text;
 | 
						|
using Utils;
 | 
						|
using VlnStatus;
 | 
						|
 | 
						|
namespace VENetwork
 | 
						|
{
 | 
						|
	// The following enum is used to set/check the mode for which the dat file connection
 | 
						|
	// was made (i.e. when the file was opened.
 | 
						|
	// NWModes:
 | 
						|
	//	exclusive, hold, write
 | 
						|
	public enum NWModes {XCLUDMODE=1, HOLDMODE=2, WRITMODE=3};
 | 
						|
 
 | 
						|
	// This class manages the connection options for multi-user support, i.e. creation, 
 | 
						|
	// connecting to and removing dat files at the system, plant and procedure set levels.
 | 
						|
	public class VEConnection
 | 
						|
	{
 | 
						|
		private VELock m_Lock;
 | 
						|
		private string m_Path;
 | 
						|
		private string CurDir;
 | 
						|
		private long m_Position;
 | 
						|
 | 
						|
		private NWModes m_Mode;
 | 
						|
		private FileStream datFs;
 | 
						|
		private UserRunTime usrRunTime;
 | 
						|
		const int ProcessRecLen = 140;
 | 
						|
		private VETempFile TempFile;
 | 
						|
 | 
						|
		public VEConnection(VELock ilck, UserRunTime iusrRT)
 | 
						|
		{
 | 
						|
			TempFile = null;
 | 
						|
			datFs = null;
 | 
						|
			m_Mode = 0;
 | 
						|
			m_Lock = ilck;
 | 
						|
			usrRunTime = iusrRT;
 | 
						|
			SetUserTempDirPath();
 | 
						|
			if (m_Lock.LockType == LockTypes.None) return;
 | 
						|
			string tmp_path = ilck.Path;
 | 
						|
			CurDir = tmp_path.Substring(0,tmp_path.LastIndexOf("\\")+1);  // save directory
 | 
						|
			// path is same as lock file except extension is dat not lck.
 | 
						|
			m_Path = tmp_path.Substring(0,tmp_path.Length-3) + "dat";
 | 
						|
		}
 | 
						|
 | 
						|
		~ VEConnection()
 | 
						|
		{
 | 
						|
			// update the record as inactive & close the file (this gets called on
 | 
						|
			// exit of the program, rather than changing active data in the tree view).
 | 
						|
			Exit();
 | 
						|
		}
 | 
						|
 | 
						|
		public int GetVfwMode()
 | 
						|
		{
 | 
						|
			//given the current mode, get the required filemode to send back to
 | 
						|
			// vfw. The values were taken from Borland include file
 | 
						|
			// define BASEMODE   (O_NOINHERIT|O_NOCRITERR)
 | 
						|
			//						0x80        0x2000
 | 
						|
			//	define XCLUDMODE  (BASEMODE|O_COMMIT|O_CREAT|O_DENYALL|O_RDWR)
 | 
						|
			//                                0x4000  0x0100  0x10      0x4
 | 
						|
			//	define HOLDMODE   (BASEMODE|O_DENYNONE|O_RDONLY)
 | 
						|
			//                                0x40      0x1
 | 
						|
			//	define WRITMODE   (BASEMODE|O_COMMIT|O_DENYWRITE|O_RDWR)
 | 
						|
			//                                0x4000    0x20      0x4
 | 
						|
			int BASEMODE = 0x80|0x2000;
 | 
						|
			if(m_Mode==NWModes.HOLDMODE)
 | 
						|
				return (BASEMODE|0x40|0x1);
 | 
						|
			else if (m_Mode==NWModes.XCLUDMODE)
 | 
						|
				return (BASEMODE|0x4000|0x0100|0x10|0x4);
 | 
						|
			else if (m_Mode==NWModes.WRITMODE)
 | 
						|
				return (BASEMODE|0x4000|0x20|0x4);
 | 
						|
			else
 | 
						|
				return (0);
 | 
						|
		}
 | 
						|
 | 
						|
		// if file open is done from vfw, need to open file using that mode,
 | 
						|
		// get mode from input.
 | 
						|
		public NWModes GetModeFromVfwMode(int vfwMode)
 | 
						|
		{
 | 
						|
			int BASEMODE = 0x80|0x2000;
 | 
						|
			if (vfwMode==(BASEMODE|0x40|0x1))
 | 
						|
				return NWModes.HOLDMODE;
 | 
						|
			else if (vfwMode==(BASEMODE|0x4000|0x0100|0x10|0x4))
 | 
						|
				return NWModes.XCLUDMODE;
 | 
						|
			else if (vfwMode==(BASEMODE|0x4000|0x20|0x4))
 | 
						|
				return NWModes.WRITMODE;
 | 
						|
			return (NWModes) 0;
 | 
						|
		}
 | 
						|
 | 
						|
		[Description("File offset")]public long FileOffset
 | 
						|
		{
 | 
						|
			get{return m_Position;}
 | 
						|
		}
 | 
						|
 | 
						|
		// reads the dat file for this level, and creates a list of ACTIVE users, i.e.
 | 
						|
		// those users whose record's status is set to active.
 | 
						|
		public ArrayList GetUsers()
 | 
						|
		{
 | 
						|
			ArrayList retval = new ArrayList();
 | 
						|
			if (datFs!=null)
 | 
						|
			{
 | 
						|
				// read records in the .dat file and see if any are active.	
 | 
						|
				long howbig = datFs.Length;
 | 
						|
				int howmany = (int)(howbig/ProcessRecLen) - 1;   // the first record is a dummy
 | 
						|
				for (int rec=1;rec<=howmany;rec++)
 | 
						|
				{
 | 
						|
					UserData usrd = new UserData(datFs, rec);
 | 
						|
					if (usrd.UserStatus==(byte)Utils.UserCStatus.PRACTIVE)
 | 
						|
						retval.Add(usrd);
 | 
						|
					else
 | 
						|
						usrd = null;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return retval;
 | 
						|
		}
 | 
						|
 | 
						|
		// display the monitor users dialog
 | 
						|
		public void MonitorUsers(int lbstr)
 | 
						|
		{
 | 
						|
			ArrayList al = GetUsers();
 | 
						|
			// temporarily do separate dialog. eventually, this will be a pane with a list
 | 
						|
			// on the main window
 | 
						|
			MonUsrDlg dlg = new MonUsrDlg(al,lbstr);
 | 
						|
			dlg.ShowDialog();
 | 
						|
		}
 | 
						|
 | 
						|
		// determines whether there are active users, other than myself, currently in this
 | 
						|
		// level of data
 | 
						|
		public bool HasActiveUsers()
 | 
						|
		{
 | 
						|
			int cntactive=0;
 | 
						|
			// read records in the .dat file and see if any are active.	
 | 
						|
			long howbig = datFs.Length;
 | 
						|
			int howmany = (int)(howbig/ProcessRecLen) - 1;   // the first record is a dummy			
 | 
						|
			for (int rec=1;rec<=howmany;rec++)
 | 
						|
			{
 | 
						|
				UserData usrd = new UserData(datFs, rec);
 | 
						|
				// if active record and it does not match my user name, there is another
 | 
						|
				// user in. return true.
 | 
						|
				if (usrd.UserStatus==(byte)Utils.UserCStatus.PRACTIVE)
 | 
						|
				{
 | 
						|
					cntactive++;
 | 
						|
					if (usrd.UserName.ToUpper()!=usrRunTime.myUserData.UserName.ToUpper())return true;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			// if there is more than one active user that is current user, i.e. multiple
 | 
						|
			// sessions, return true
 | 
						|
			if (cntactive>1)return true;
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
		// This method will attempt to open the *process.dat file in a read/write mode so
 | 
						|
		// that a process record can be added.
 | 
						|
		private bool OpenRW()
 | 
						|
		{
 | 
						|
			bool retval=true;
 | 
						|
			VlnSpinner spn=null;
 | 
						|
			try
 | 
						|
			{
 | 
						|
				spn = new VlnSpinner(2,50,"- Opening Process File ",m_Path,true,true,false);
 | 
						|
				datFs=null;
 | 
						|
				while(spn.SpinnerWait(datFs!=null))
 | 
						|
				{
 | 
						|
					datFs = new FileStream(m_Path,FileMode.Open,FileAccess.ReadWrite,FileShare.Read);
 | 
						|
				}
 | 
						|
				// take this chance to do some cleanup in the procedure set directory
 | 
						|
				if (m_Lock.LockType == LockTypes.ProcSet) DoProcCleanup();
 | 
						|
				datFs.Seek(0L,SeekOrigin.End);
 | 
						|
				m_Position = datFs.Position;
 | 
						|
				usrRunTime.myUserData.UserStatus= (byte)Utils.UserCStatus.PRACTIVE;
 | 
						|
				usrRunTime.myUserData.Write(datFs);
 | 
						|
				m_Mode=NWModes.WRITMODE;
 | 
						|
				datFs.Flush();
 | 
						|
			}
 | 
						|
			catch (Exception e)
 | 
						|
			{
 | 
						|
				//MessageBox.Show(e.Message,"Error on connecting to data - no lock");
 | 
						|
				retval = false;	
 | 
						|
			}
 | 
						|
			spn.Dispose();
 | 
						|
			return retval;
 | 
						|
		}
 | 
						|
 | 
						|
		// used upon expand/select an item in tree - open the connection to the
 | 
						|
		// the dat file. The reenter flag is used when the user is already in at this
 | 
						|
		// level, but a change in lock state may have occurred.
 | 
						|
		public bool Enter(bool reenter)
 | 
						|
		{
 | 
						|
			// for locktype.none, this level has no lock - so just say that
 | 
						|
			// enter succeeded.
 | 
						|
			if (m_Lock.LockType == LockTypes.None) return true;
 | 
						|
 | 
						|
			bool attchtemp = false;
 | 
						|
			bool success=false;
 | 
						|
 | 
						|
			VlnSpinner spin = new VlnSpinner(2,10,"- Connecting to Data ",m_Path,true,true,false);
 | 
						|
			while( spin.SpinnerWait( false ) )	// spin until break or return
 | 
						|
			{
 | 
						|
				// if not reenter refresh the lock. if reenter, the locking logic refreshed
 | 
						|
				// the lock.
 | 
						|
				if (!reenter)m_Lock.Refresh();
 | 
						|
 | 
						|
				// if it's locked, see if it is locked by me and make sure there isn't an 
 | 
						|
				// active connection by another user or by myself from another window or network
 | 
						|
				// process
 | 
						|
				if (m_Lock.LockStatus == Status.Locked || m_Lock.LockStatus == Status.LockPending)
 | 
						|
				{				
 | 
						|
					// if this is a procedure set lock, also check that the correct temp
 | 
						|
					// file is attached, i.e. the one that is from the locking process.
 | 
						|
					if(m_Lock.LockType==LockTypes.ProcSet)
 | 
						|
					{
 | 
						|
						if (TempFile==null)TempFile = new VETempFile(this.CurDir);
 | 
						|
						attchtemp=TempFile.AttachSpecificTemp(usrRunTime.myUserData.UserNetworkID,m_Lock.UserProcess); //usrRunTime.myUserData.UserProcess);
 | 
						|
						// if failed to connect, but a lock was pending, reset the lock type to
 | 
						|
						// locked by other.
 | 
						|
						if(m_Lock.LockStatus == Status.LockPending && !attchtemp) m_Lock.LockStatus = Status.LockedByOther;
 | 
						|
					}
 | 
						|
					if (m_Lock.LockType != LockTypes.ProcSet || attchtemp)
 | 
						|
					{
 | 
						|
						// try to get exclusive access to it (if I don't already have it)
 | 
						|
						// first step is to exit from current connect
 | 
						|
						if (m_Mode !=0 && m_Mode != NWModes.XCLUDMODE) Exit(); 
 | 
						|
						
 | 
						|
						// try to establish a new exclusive connection. If a new exclusive connection
 | 
						|
						// cannot be made, then a connection must exist from another process (either myself,
 | 
						|
						// or another user if pending lock).
 | 
						|
						// If I'm other user, this should be treated like a nolock for me, i.e. I can
 | 
						|
						// view data but not modify it. 
 | 
						|
						if (m_Mode == 0)
 | 
						|
						{
 | 
						|
							try
 | 
						|
							{
 | 
						|
								datFs = new FileStream(m_Path,FileMode.Create,FileAccess.ReadWrite,FileShare.None);
 | 
						|
								if(m_Lock.LockType == LockTypes.ProcSet)
 | 
						|
								{	// these files are only used at the procedure set level
 | 
						|
									DeleteFiles("*.own",0); // Cleanup ownership files
 | 
						|
									DeleteFiles("*.wrq",0); // Cleanup write request files
 | 
						|
								}
 | 
						|
								usrRunTime.myUserData.UserProcess=m_Lock.UserProcess;
 | 
						|
								// truncate file
 | 
						|
								datFs.SetLength(0L);
 | 
						|
								m_Mode=NWModes.XCLUDMODE;
 | 
						|
								// write out a dummy record with the status set to inactive.
 | 
						|
								usrRunTime.myUserData.UserStatus= (byte)Utils.UserCStatus.PRINACTIVE;
 | 
						|
								usrRunTime.myUserData.Write(datFs);
 | 
						|
								m_Position = datFs.Position;
 | 
						|
								usrRunTime.myUserData.UserStatus= (byte)Utils.UserCStatus.PRACTIVE;
 | 
						|
								usrRunTime.myUserData.Write(datFs);
 | 
						|
								success=true;
 | 
						|
								m_Lock.LockStatus = Status.Locked;   // in case it was pending
 | 
						|
								datFs.Flush();
 | 
						|
								break;
 | 
						|
							}
 | 
						|
							// if an ioexception occurs, the connect is open either by me
 | 
						|
							// or another user. Open a non-exlusive connection.
 | 
						|
							catch (IOException)
 | 
						|
							{
 | 
						|
								// if open by another user, reopen as it was. Else return for
 | 
						|
								// view only mode.
 | 
						|
								spin.Dispose();
 | 
						|
								bool opn = OpenRW();
 | 
						|
								if (!opn)
 | 
						|
								{
 | 
						|
									m_Lock.LockStatus = Status.LockedByOther; 
 | 
						|
									return false;
 | 
						|
								}
 | 
						|
								datFs.Close();
 | 
						|
								datFs = new FileStream(m_Path,FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
 | 
						|
								success=true;
 | 
						|
								m_Mode=NWModes.HOLDMODE;
 | 
						|
								break;
 | 
						|
							}
 | 
						|
							catch (Exception e)
 | 
						|
							{
 | 
						|
								spin.Dispose();
 | 
						|
								m_Lock.LockStatus = Status.LockedByOther;
 | 
						|
								MessageBox.Show(e.Message, "Connecting to data failed - lock exists.");
 | 
						|
								return false;
 | 
						|
							}							
 | 
						|
						}
 | 
						|
						else
 | 
						|
						{
 | 
						|
							m_Lock.LockStatus = Status.Locked;
 | 
						|
							success=true;
 | 
						|
							break;		// already connected.
 | 
						|
						}
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{					
 | 
						|
						success = false;	
 | 
						|
						break;
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				// Handle case where there is no lock or the current user is the lock owner,
 | 
						|
				// but they're already connected from another run (either windows session or
 | 
						|
				// network session)
 | 
						|
				if (m_Lock.LockStatus == Status.NoLock)
 | 
						|
				{
 | 
						|
					// check if already connected, i.e. a filestream exists, or that I'm not
 | 
						|
					// changing modes (the mode change occurs when going from locked to unlocked)
 | 
						|
					if (datFs != null && this.m_Mode!=NWModes.XCLUDMODE)
 | 
						|
					{
 | 
						|
						success=true;
 | 
						|
						break;
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
						// if at the procedure set level, need to connect to a temp directory
 | 
						|
						// as well.
 | 
						|
						usrRunTime.myUserData.UserProcess="";
 | 
						|
						if(m_Lock.LockType==LockTypes.ProcSet && TempFile==null)
 | 
						|
						{
 | 
						|
							TempFile = new VETempFile(this.CurDir);
 | 
						|
							bool got_tmp = TempFile.FindAvailableTempDir(usrRunTime.myUserData.UserNetworkID);
 | 
						|
							if (got_tmp==false)
 | 
						|
							{
 | 
						|
								TempFile = null;
 | 
						|
								spin.Dispose();
 | 
						|
								return false;
 | 
						|
							}
 | 
						|
							usrRunTime.myUserData.UserProcess=TempFile.TempNum;
 | 
						|
						}
 | 
						|
						// try to get exclusive access to dat file (see following commentary)
 | 
						|
						try
 | 
						|
						{
 | 
						|
							// if this was open with exclusive, exit (this would be the
 | 
						|
							// case where an unlock occurred.
 | 
						|
							if (reenter || m_Mode == NWModes.XCLUDMODE) Exit();
 | 
						|
 | 
						|
							// if can't get exclusive, an exception is thrown. just continue
 | 
						|
							// on from there, i.e. the file is being used.
 | 
						|
							// if we get exclusive access, cleanup the procset directory (if
 | 
						|
							// this is a procset level enter) and then clean out the dat file
 | 
						|
							datFs = new FileStream(m_Path,FileMode.Create,FileAccess.ReadWrite,FileShare.None);
 | 
						|
							if(m_Lock.LockType == LockTypes.ProcSet)
 | 
						|
							{ // these files are only used at the procedure set level
 | 
						|
								DeleteFiles("*.own",0); // Cleanup ownership files
 | 
						|
								DeleteFiles("*.wrq",0); // Cleanup write request files
 | 
						|
							}
 | 
						|
						
 | 
						|
							// truncate file
 | 
						|
							datFs.SetLength(0L);
 | 
						|
							m_Mode=NWModes.XCLUDMODE;
 | 
						|
							// write out a dummy record with the status set to inactive.
 | 
						|
							usrRunTime.myUserData.UserStatus= (byte)Utils.UserCStatus.PRINACTIVE;
 | 
						|
							usrRunTime.myUserData.Write(datFs);
 | 
						|
							datFs.Close();
 | 
						|
						}
 | 
						|
 | 
						|
						// if it is an IOException, it means the user could not get exclusive access,
 | 
						|
						// just continue on, opening with read/write access to add process record
 | 
						|
						// and then reopen in hold mode.
 | 
						|
						catch (IOException)
 | 
						|
						{
 | 
						|
						}
 | 
						|
 | 
						|
						// Catch a real error.
 | 
						|
						catch (Exception e)
 | 
						|
						{
 | 
						|
							MessageBox.Show(e.Message, "connect->enter failed");
 | 
						|
							spin.Dispose();
 | 
						|
							return false;
 | 
						|
						}
 | 
						|
 | 
						|
						// Attempt to open the file in Read/write mode to add an active process record
 | 
						|
						bool opn = OpenRW();
 | 
						|
						if (!opn)return false;
 | 
						|
 | 
						|
						// now close the process file & open in hold mode.
 | 
						|
						datFs.Close();
 | 
						|
						datFs = new FileStream(m_Path,FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
 | 
						|
						success=true;
 | 
						|
						m_Mode=NWModes.HOLDMODE;
 | 
						|
						break;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				if (m_Lock.LockStatus == Status.LockedByOther)
 | 
						|
				{
 | 
						|
					success = false;
 | 
						|
					if (datFs!=null)Exit();
 | 
						|
					break;
 | 
						|
				}
 | 
						|
			}	
 | 
						|
			spin.Dispose(); // end of spinnerwait while loop
 | 
						|
 | 
						|
			// if successful connection & at the procedure set level, write out number
 | 
						|
			// of bytes to the temp directory file (temps\userid_.p##) to flag which
 | 
						|
			// connection this is associated with. Also, if this is a reenter (locked state change)
 | 
						|
			// then the tempfile is already the correct length, don't write out bytes.
 | 
						|
			if (success==true && m_Lock.LockType==LockTypes.ProcSet && TempFile!=null && !reenter)
 | 
						|
			{
 | 
						|
				TempFile.WriteBytes((int)(m_Position/140));
 | 
						|
			}
 | 
						|
			SetUserTempDirPath();
 | 
						|
			return success;
 | 
						|
		}
 | 
						|
 | 
						|
		// if len is !0, try to delete files of the specified length.
 | 
						|
		// zero length files are normally in transition and will be 
 | 
						|
		// deleted by their owners.
 | 
						|
		public void DeleteFiles(string tmp, int len)
 | 
						|
		{	
 | 
						|
			DirectoryInfo di = new DirectoryInfo(Directory.GetCurrentDirectory());
 | 
						|
			FileInfo [] fis = di.GetFiles(tmp);
 | 
						|
			foreach (FileInfo fi in fis)
 | 
						|
			{
 | 
						|
				if (len==0 || len==fi.Length) fi.Delete();
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// cleanup temp files and active record flags in the dat files.
 | 
						|
		private void DoProcCleanup()
 | 
						|
		{
 | 
						|
			// read records in the .dat file and do check for those that are active.	
 | 
						|
			long howbig = datFs.Length;
 | 
						|
			int howmany = (int)(howbig/ProcessRecLen);
 | 
						|
			for (int rec=1;rec<howmany;rec++)
 | 
						|
			{
 | 
						|
				UserData usrd = new UserData(datFs, rec);				
 | 
						|
				if (usrd.UserStatus==(byte)Utils.UserCStatus.PRACTIVE)
 | 
						|
				{
 | 
						|
					VETempFile tfile = new VETempFile(CurDir);
 | 
						|
					string tfilename = CurDir + "\\" + tfile.MakeTempName(usrd.UserNetworkID,usrd.UserProcess,'P');
 | 
						|
					FileInfo fi = new FileInfo(tfilename);
 | 
						|
					bool tfile_exists = fi.Exists;
 | 
						|
					int len=0;
 | 
						|
					if (tfile_exists) len = (int) fi.Length;
 | 
						|
					// now check if it is an active process (versus an active
 | 
						|
					// record left in dat file by a crashed process).
 | 
						|
					// Do this by checking:
 | 
						|
					//	if the record points to the active process file
 | 
						|
					//	or the process file doesn't exist
 | 
						|
					//	or it's length doesn't match the process number
 | 
						|
					if (usrd.UserStatus == (byte)Utils.UserCStatus.PRACTIVE)
 | 
						|
					{
 | 
						|
						if ((usrd.UserNetworkID.ToUpper()==usrRunTime.myUserData.UserNetworkID.ToUpper() &&
 | 
						|
							usrd.UserProcess==usrRunTime.myUserData.UserProcess) ||
 | 
						|
							!tfile_exists || len!=rec)
 | 
						|
						{
 | 
						|
							datFs.Seek(-ProcessRecLen,SeekOrigin.Current);
 | 
						|
							usrd.UserStatus = (byte)Utils.UserCStatus.PRINACTIVE;
 | 
						|
							usrd.Write(datFs);
 | 
						|
							DeleteFiles("*.own",rec);
 | 
						|
							DeleteFiles("*.wrq",rec);
 | 
						|
						}
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		public long Seek(long offset, int fromwhere)
 | 
						|
		{
 | 
						|
			long skpos = 0L;
 | 
						|
			if(datFs!=null)
 | 
						|
			{
 | 
						|
				// fromwhere: 0=beginning;1=current;2=end. Map these from 16-bit code
 | 
						|
				// to .net 32-bit code.
 | 
						|
				SeekOrigin sorig;
 | 
						|
				if (fromwhere==0)
 | 
						|
					sorig = SeekOrigin.Begin;
 | 
						|
				else if (fromwhere==1)
 | 
						|
					sorig = SeekOrigin.Current;
 | 
						|
				else
 | 
						|
					sorig = SeekOrigin.End;
 | 
						|
				skpos = datFs.Seek(offset, sorig);
 | 
						|
			}
 | 
						|
			return skpos;
 | 
						|
		}
 | 
						|
 | 
						|
		public Int16 GetProcRecBuff(Int16 size, ref byte [] bt)
 | 
						|
		{
 | 
						|
			int retval = datFs.Read(bt,0,(int)size);
 | 
						|
			return (Int16)retval;
 | 
						|
		}
 | 
						|
 | 
						|
		public void Close()
 | 
						|
		{
 | 
						|
			datFs.Close();
 | 
						|
			m_Mode = 0;
 | 
						|
			datFs=null;
 | 
						|
		}
 | 
						|
 | 
						|
		public Int16 Open(Int16 vfwmode)
 | 
						|
		{
 | 
						|
			Int16 retval = 1;
 | 
						|
			try
 | 
						|
			{
 | 
						|
				if (m_Mode!=0) Close();
 | 
						|
				m_Mode = GetModeFromVfwMode(vfwmode);
 | 
						|
				if(m_Mode==NWModes.HOLDMODE)
 | 
						|
					datFs = new FileStream(m_Path,FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
 | 
						|
				else if(m_Mode==NWModes.WRITMODE)
 | 
						|
					datFs = new FileStream(m_Path,FileMode.Open,FileAccess.ReadWrite,FileShare.Read);
 | 
						|
				else if (m_Mode==NWModes.XCLUDMODE)
 | 
						|
					datFs = new FileStream(m_Path,FileMode.Create,FileAccess.ReadWrite,FileShare.None);
 | 
						|
			}
 | 
						|
			catch
 | 
						|
			{
 | 
						|
				retval = -1;
 | 
						|
			}
 | 
						|
			return retval;
 | 
						|
		}
 | 
						|
 | 
						|
		// purpose: close the connection to the dat file.
 | 
						|
		public void Exit()
 | 
						|
		{	
 | 
						|
			// if datFs is null, either we have a lock type of none or the destructor
 | 
						|
			// is being called & an exit may have been done, if collapse occurred
 | 
						|
			if (datFs==null) return;   // datFs not set if lock type was none.
 | 
						|
			byte stat=(byte)Utils.UserCStatus.PRINACTIVE;
 | 
						|
			usrRunTime.myUserData.UserStatus=stat;
 | 
						|
			datFs.Close();
 | 
						|
			datFs=null;
 | 
						|
			VlnSpinner spin = new VlnSpinner(2,25,"- Exiting from Connection ",m_Path,true,true,false);
 | 
						|
			while(spin.SpinnerWait(datFs!=null))
 | 
						|
			{
 | 
						|
				datFs = new FileStream(m_Path,FileMode.Open,FileAccess.ReadWrite,FileShare.Read);
 | 
						|
			}
 | 
						|
			spin.Dispose();
 | 
						|
			datFs.Seek(m_Position,SeekOrigin.Begin);			
 | 
						|
			BinaryWriter bw = new BinaryWriter(datFs);			
 | 
						|
			bw.Write(stat);
 | 
						|
			bw.Close();
 | 
						|
			datFs.Close();
 | 
						|
			if (TempFile!=null)
 | 
						|
			{
 | 
						|
				TempFile.CloseTempProc();
 | 
						|
				TempFile = null;
 | 
						|
			}
 | 
						|
			datFs=null;
 | 
						|
			m_Mode=0;
 | 
						|
		}
 | 
						|
 | 
						|
		public void SetUserTempDirPath()
 | 
						|
		{
 | 
						|
			if (m_Lock.LockStatus == Status.NoLock && TempFile != null)
 | 
						|
			{
 | 
						|
				// no lock set, use temp directory
 | 
						|
				char [] backslash = {'\\'};
 | 
						|
				usrRunTime.TempDirPath = TempFile.TemporaryDirectoryName.TrimEnd(backslash);
 | 
						|
			}
 | 
						|
			else // lock set, don't use temp directory
 | 
						|
				usrRunTime.TempDirPath = null;
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
}
 |