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