source: BMXNET_RPMS_dotNET_UTILITIES-BMX/trunk/cs/bmx_0200scr/BMX2/BMXNet/BMXNetConnectInfo.cs

Last change on this file was 1082, checked in by Sam Habiel, 13 years ago

BMX version bumped to 2.3.
New dll
BMXNetConnectInfo: Event polling from RPMS/VISTA is now async. BMX Writer lock removed.
BMXNetLib:

  1. Application context changes are now suppressed. Developer must make sure that his/her application has all the needed BMX methods. This was done for performance enhancement as application context changes are very expensive in network time.
  2. Locks are implemented at the TransmitRPC with a very simple Lock(this) which works very well.

RPMSDb: See #1 for BMXNetLib. All context changes are now suppressed.

File size: 35.4 KB
Line 
1using System;
2using System.Data;
3using System.Diagnostics;
4using System.IO;
5using System.IO.IsolatedStorage;
6using System.Runtime.Serialization;
7using System.Runtime.Serialization.Formatters;
8using System.Runtime.Serialization.Formatters.Soap;
9using System.Windows.Forms;
10using System.Security.Principal;
11using System.Text;
12using System.Security.Cryptography;
13using System.Timers;
14using System.Threading;
15using System.Runtime.Remoting.Messaging;
16
17
18namespace IndianHealthService.BMXNet
19{
20 public class BMXNetEventArgs : EventArgs
21 {
22 public string BMXParam;
23 public string BMXEvent;
24 }
25
26 /// <summary>
27 /// Contains methods and properties to support RPMS Login for .NET applications
28 /// </summary>
29 public class BMXNetConnectInfo : System.Windows.Forms.Control
30 {
31
32 /// <summary>
33 /// Serializes RPMS server address and port
34 /// </summary>
35 [SerializableAttribute]
36 private class ServerData
37 {
38 public string m_sAddress = "";
39 public int m_nPort = 0;
40 public string m_sNamespace = "";
41
42 public ServerData()
43 {
44 }
45
46 public ServerData(string sAddress, int nPort)
47 {
48 this.m_nPort = nPort;
49 this.m_sAddress = sAddress;
50 this.m_sNamespace = "";
51 }
52 public ServerData(string sAddress, int nPort, string sNamespace)
53 {
54 this.m_nPort = nPort;
55 this.m_sAddress = sAddress;
56 this.m_sNamespace = sNamespace;
57 }
58 }
59
60 /// <summary>
61 /// BMXNetConnector With Default Encoding (invokes BMXNetLib)
62 /// </summary>
63 public BMXNetConnectInfo() : this("") { }
64
65 /// <summary>
66 /// BMXNetConnector with a specific encoding
67 /// </summary>
68 /// <param name="encoding">String representation of encoding (e.g. windows-1256 for arabic).
69 /// If encoding is not found, we fall back to the default windows encoding. A debug message
70 /// is printed to that effect.</param>
71 public BMXNetConnectInfo(string encoding)
72 {
73 if (encoding == String.Empty) m_BMXNetLib = new BMXNetLib();
74 else m_BMXNetLib = new BMXNetLib(encoding);
75
76 m_timerEvent = new System.Timers.Timer();
77 m_timerEvent.Elapsed += new ElapsedEventHandler(OnEventTimer);
78 m_timerEvent.Interval = 10000;
79 m_timerEvent.Enabled = false;
80 }
81
82 #region BMXNetEvent
83
84 private System.Timers.Timer m_timerEvent;
85 public delegate void BMXNetEventDelegate(Object obj, BMXNetEventArgs e);
86 public event BMXNetEventDelegate BMXNetEvent;
87
88 /// <summary>
89 /// Enables and disables event polling for the RPMS connection
90 /// </summary>
91 public bool EventPollingEnabled
92 {
93 get
94 {
95 return m_timerEvent.Enabled;
96 }
97 set
98 {
99 m_timerEvent.Enabled = value;
100 }
101 }
102
103 /// <summary>
104 /// Sets and retrieves the interval in milliseconds for RPMS event polling
105 /// </summary>
106 public double EventPollingInterval
107 {
108 get
109 {
110 return m_timerEvent.Interval;
111 }
112 set
113 {
114 m_timerEvent.Interval = value;
115 }
116 }
117
118 /// <summary>
119 /// Register interest in an RPMS event.
120 /// </summary>
121 /// <param name="EventName"></param>
122 /// <returns></returns>
123 public int SubscribeEvent(string EventName)
124 {
125 try
126 {
127 //System.IntPtr pHandle = this.Handle;
128 DataTable dt;
129 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(RPMSDataTable);
130 if (this.IsHandleCreated == false)
131 {
132 this.CreateHandle();
133 }
134 dt = (DataTable) this.Invoke(rdtd, new object[] {"BMX EVENT REGISTER^" + EventName, "dt"});
135
136// dt = RPMSDataTable("BMX EVENT REGISTER^" + EventName, "dt");
137 DataRow dr = dt.Rows[0];
138 int nRet = (int) dr["ERRORID"];
139 return nRet;
140 }
141 catch (Exception ex)
142 {
143 Debug.Write(ex.Message);
144 return 99;
145 }
146 }
147
148 /// <summary>
149 /// Unregister an RPMS event
150 /// </summary>
151 /// <param name="EventName"></param>
152 /// <returns></returns>
153 public int UnSubscribeEvent(string EventName)
154 {
155 try
156 {
157 DataTable dt;
158 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(RPMSDataTable);
159 if (this.IsHandleCreated == false)
160 {
161 this.CreateHandle();
162 }
163 dt = (DataTable) this.Invoke(rdtd, new object[] {"BMX EVENT UNREGISTER^" + EventName, "dt"});
164
165 DataRow dr = dt.Rows[0];
166 int nRet = (int) dr["ERRORID"];
167 return nRet;
168 }
169 catch (Exception ex)
170 {
171 Debug.Write(ex.Message);
172 return 99;
173 }
174 }
175
176 /// <summary>
177 /// Raise an RPMS event
178 /// </summary>
179 /// <param name="EventName">The name of the event to raise</param>
180 /// <param name="Param">Parameters associated with the event</param>
181 /// <param name="RaiseBack">True if the event should be raised back to the caller</param>
182 /// <returns></returns>
183 public int RaiseEvent(string EventName, string Param, bool RaiseBack)
184 {
185 string sBack = (RaiseBack == true)?"TRUE":"FALSE";
186 try
187 {
188 DataTable dt;
189 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(RPMSDataTable);
190 if (this.IsHandleCreated == false)
191 {
192 this.CreateHandle();
193 }
194 dt = (DataTable) this.Invoke(rdtd, new object[] {"BMX EVENT RAISE^" + EventName + "^" + Param + "^" + sBack + "^", "dt"});
195
196 DataRow dr = dt.Rows[0];
197 int nRet = (int) dr["ERRORID"];
198 return nRet;
199 }
200 catch (Exception ex)
201 {
202 Debug.Write(ex.Message);
203 return 99;
204 }
205 }
206
207 /// <summary>
208 /// Sets and retrieves the number of times that the Event Timer will generage a BMXNet AutoFire event.
209 /// For example, if AutoFire == 3, then every 3rd time the Event Timer fires, it will generate an AutoFire event.
210 /// </summary>
211 public int AutoFire
212 {
213 get
214 {
215 return m_nAutoFireIncrements;
216 }
217 set
218 {
219 m_nAutoFireIncrements = value;
220 }
221 }
222
223 //Retrieve events registered by this session
224 private int m_nAutoFireIncrements = 0;
225 private int m_nAutoFireCount = 0;
226
227 private void OnEventTimer(object source, ElapsedEventArgs e)
228 {
229 try
230 {
231 //this.bmxNetLib.BMXRWL.AcquireWriterLock(5);
232 try
233 {
234 this.m_timerEvent.Enabled = false;
235
236 Object obj = this;
237 BMXNetEventArgs args = new BMXNetEventArgs();
238 m_nAutoFireCount++;
239 if ((m_nAutoFireIncrements > 0)&&(m_nAutoFireCount >= m_nAutoFireIncrements))
240 {
241 m_nAutoFireCount = 0;
242 args.BMXEvent = "BMXNet AutoFire";
243 args.BMXParam = "";
244 if (BMXNetEvent != null)
245 {
246 Debug.Write("BMXNet AutoFire event raised from BMXNetConnectInfo");
247 BMXNetEvent(obj, args);
248 }
249 this.m_timerEvent.Enabled = true;
250 return;
251 }
252
253 if (m_BMXNetLib.Connected == false)
254 {
255 this.m_timerEvent.Enabled = true;
256 return;
257 }
258
259 DataTable dtEvents = new DataTable("BMXNetEvents");
260
261 try
262 {
263 if (this.IsHandleCreated == false)
264 {
265 this.CreateHandle();
266 }
267 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(RPMSDataTable);
268
269 //SMH - 3100110 - BMX EVENT POLL happens in the foreground. It blocks the main thread
270 //until it is done. So I changed it to async so that there would be no jerking
271 //on this thread while it's taking place.
272 //dtEvents = (DataTable) this.Invoke(rdtd, new object[] {"BMX EVENT POLL", "BMXNetEvents"});
273
274 rdtd.BeginInvoke("BMX EVENT POLL", "BMXNetEvents", new AsyncCallback(BMXNetEventsCallback), null);
275 }
276 catch (Exception ex)
277 {
278 string sMsg = ex.Message;
279 this.m_timerEvent.Enabled = true;
280 return;
281 }
282 /*
283 try
284 {
285 if (dtEvents.Rows.Count == 0)
286 {
287 this.m_timerEvent.Enabled = true;
288 return;
289 }
290 }
291 catch(Exception ex)
292 {
293 Debug.Write("upper Exception in BMXNetConnectInfo.OnEventTimer: " + ex.Message + "\n");
294 }
295
296 try
297 {
298 //If events exist, raise BMXNetEvent
299 foreach (DataRow dr in dtEvents.Rows)
300 {
301 args.BMXEvent = dr["EVENT"].ToString();
302 args.BMXParam = dr["PARAM"].ToString();
303 if (BMXNetEvent != null)
304 {
305 BMXNetEvent(obj, args);
306 }
307 }
308 this.m_timerEvent.Enabled = true;
309 return;
310 }
311 catch(Exception ex)
312 {
313 Debug.Write("lower Exception in BMXNetConnectInfo.OnEventTimer: " + ex.Message + "\n");
314 }
315 */
316 }
317 catch(Exception ex)
318 {
319 Debug.Write("Exception in BMXNetConnectInfo.OnEventTimer: " + ex.Message + "\n");
320 }
321 finally
322 {
323 //this.bmxNetLib.BMXRWL.ReleaseWriterLock();
324 //this.m_timerEvent.Enabled = true;
325 }
326
327 }
328 catch
329 {
330 Debug.Write(" OnEventTimer failed to obtain lock.\n");
331 }
332 }
333
334
335 /// <summary>
336 /// Callback for Async operation to get events from RPMS/VISTA server
337 /// </summary>
338 /// <param name="itfAR"></param>
339 void BMXNetEventsCallback(IAsyncResult itfAR)
340 {
341 //Define datatable we will receive results at.
342 DataTable dtEvents;
343 //Get Result
344 AsyncResult ar = (AsyncResult)itfAR;
345 //Get Original Delegate
346 RPMSDataTableDelegate rdtd = (RPMSDataTableDelegate)ar.AsyncDelegate;
347
348 //Complete the call of the delegate. We may lose connection so try catch
349 try
350 {
351 dtEvents = rdtd.EndInvoke(itfAR);
352 }
353 catch (Exception ex)
354 {
355 throw new BMXNetException("Lost connection to Server", ex);
356 }
357
358 BMXNetEventArgs args = new BMXNetEventArgs();
359
360 //Fire off BMXNetEvent to interested subscribers
361 if (dtEvents.Rows.Count != 0)
362 {
363 foreach (DataRow dr in dtEvents.Rows)
364 {
365 args.BMXEvent = dr["EVENT"].ToString();
366 args.BMXParam = dr["PARAM"].ToString();
367 if (BMXNetEvent != null)
368 {
369 BMXNetEvent(this, args);
370 }
371 }
372 }
373
374 //re-enable the timer so it can check again for events
375
376 this.m_timerEvent.Enabled = true;
377 }
378
379 #endregion BMXNetEvent
380
381 #region Fields
382
383 private ServerData m_ServerData;
384 private string m_sServerAddress;
385 private int m_nServerPort;
386 private string m_sServerNamespace;
387 private string m_sDUZ2;
388 private int m_nDivisionCount = 0;
389 private string m_sUserName;
390 private string m_sDivision;
391 private string m_sAppcontext;
392 private BMXNetLib m_BMXNetLib;
393 private bool m_bAutoServer = false;
394 private bool m_bAutoLogin = false;
395
396 #endregion Fields
397
398 #region Properties
399
400// /// <summary>
401// /// Set and retrieve the timeout in milliseconds for locking the transmit port.
402// /// If the transmit port is unavailable an ApplicationException will be thrown.
403// /// </summary>
404// public int TransmitLockTimeout
405// {
406// get
407// {
408// return m_nTransmitLockTimeout;
409// }
410// set
411// {
412// m_nTransmitLockTimeout = value;
413// }
414// }
415
416 /// <summary>
417 /// Set and retrieve the timeout, in milliseconds, to receive a response from the RPMS server.
418 /// If the retrieve time exceeds the timeout, an exception will be thrown and the connection will be closed.
419 /// The default is 30 seconds.
420 /// </summary>
421 public int ReceiveTimeout
422 {
423 get { return m_BMXNetLib.ReceiveTimeout; }
424 set { m_BMXNetLib.ReceiveTimeout = value; }
425 }
426
427 public string MServerNameSpace
428 {
429 get
430 {
431 return m_BMXNetLib.MServerNamespace;
432 }
433 set
434 {
435 m_BMXNetLib.MServerNamespace = value;
436 }
437 }
438
439 public BMXNetLib bmxNetLib
440 {
441 get
442 {
443 return m_BMXNetLib;
444 }
445 }
446
447 public string AppContext
448 {
449 get
450 {
451 return m_sAppcontext;
452 }
453 set
454 {
455 if (m_BMXNetLib.Connected == true)
456 {
457 try
458 {
459 try
460 {
461 m_BMXNetLib.AppContext = value;
462 m_sAppcontext = value;
463 }
464 catch (Exception ex)
465 {
466 Debug.Write(ex.Message);
467 throw ex;
468 }
469 finally
470 {
471 }
472 }
473 catch (ApplicationException aex)
474 {
475 // The writer lock request timed out.
476 Debug.Write("BMXNetConnectInfo.AppContext lock request timed out.\n");
477 throw aex;
478 }
479 }//end if
480 }//end set
481 }
482
483 public bool Connected
484 {
485 get
486 {
487 return m_BMXNetLib.Connected;
488 }
489 }
490
491 public string UserName
492 {
493 get
494 {
495 return this.m_sUserName;
496 }
497 }
498
499 public string DivisionName
500 {
501 get
502 {
503 return this.m_sDivision;
504 }
505 }
506
507 /// <summary>
508 /// Returns a string representation of DUZ
509 /// </summary>
510 public string DUZ
511 {
512 get
513 {
514 return this.bmxNetLib.DUZ;
515 }
516 }
517
518 /// <summary>
519 /// Sets and Returns DUZ(2)
520 /// </summary>
521 public string DUZ2
522 {
523 get
524 {
525 return m_sDUZ2;
526 }
527 set
528 {
529 try
530 {
531 //Set DUZ(2) in M partition
532 DataTable dt = this.RPMSDataTable("BMXSetFac^" + value, "SetDUZ2");
533 Debug.Assert(dt.Rows.Count == 1);
534 DataRow dr = dt.Rows[0];
535 string sDUZ2 = dr["FACILITY_IEN"].ToString();
536 if (sDUZ2 != "0")
537 {
538 m_sDUZ2 = sDUZ2;
539 this.m_sDivision = dr["FACILITY_NAME"].ToString();
540 }
541 }
542 catch (Exception ex)
543 {
544 Debug.Write("DUZ2.Set failed: " + ex.Message + "\n");
545 }
546 }
547 }
548
549 /// <summary>
550 /// Gets the address of the RPMS Server
551 /// </summary>
552 public string MServerAddress
553 {
554 get
555 {
556 return this.m_sServerAddress;
557 }
558 }
559
560 /// <summary>
561 /// Gets the port on which the MServer is connected
562 /// </summary>
563 public int MServerPort
564 {
565 get
566 {
567 return this.m_nServerPort;
568 }
569 }
570
571 public DataTable UserDivisions
572 {
573 get
574 {
575 DataTable dt = this.GetUserDivisions();
576 return dt;
577 }
578 }
579
580 #endregion Properties
581
582 #region Methods
583
584 public void CloseConnection()
585 {
586 //TODO: Make thread safe
587 this.m_bAutoServer = false;
588 this.m_bAutoLogin = false;
589 m_BMXNetLib.CloseConnection();
590 }
591
592 /// <summary>
593 /// For backwards compatibility. Internally calls LoadConnectInfo()
594 /// </summary>
595 public void Login()
596 {
597 LoadConnectInfo();
598 }
599
600 /// <summary>
601 /// Change the internet address and port of the RPMS server
602 /// Throws a BMXNetException if user cancels
603 /// </summary>
604 public void ChangeServerInfo()
605 {
606 //Get existing values from isolated storage
607 ServerData serverData = new ServerData();
608 Stream stStorage = null;
609 try
610 {
611 IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForAssembly();
612 string sFileName = "mserver0200.dat";
613 stStorage = new IsolatedStorageFileStream(sFileName, FileMode.Open, isStore);
614 IFormatter formatter = new SoapFormatter();
615 serverData = (ServerData) formatter.Deserialize(stStorage);
616 stStorage.Close();
617 }
618 catch (Exception ex)
619 {
620 Debug.Write(ex.Message);
621 if (stStorage != null)
622 stStorage.Close();
623 }
624
625 try
626 {
627 DServerInfo dsi = new DServerInfo();
628 dsi.InitializePage(serverData.m_sAddress,serverData.m_nPort, serverData.m_sNamespace);
629 if (dsi.ShowDialog() != DialogResult.OK)
630 {
631 throw new BMXNetException("User cancelled.");
632 }
633 serverData.m_sAddress = dsi.MServerAddress;
634 serverData.m_nPort = dsi.MServerPort;
635 serverData.m_sNamespace = dsi.MServerNamespace;
636
637 this.m_sServerAddress = dsi.MServerAddress;
638 this.m_nServerPort = dsi.MServerPort;
639 this.m_sServerNamespace = dsi.MServerNamespace;
640
641 //Save port and address to isolated storage
642 try
643 {
644 string sFileName = "mserver0200.dat";
645 IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForAssembly();
646 stStorage = new IsolatedStorageFileStream(sFileName, FileMode.Create, isStore);
647 IFormatter formatter = new SoapFormatter();
648 formatter.Serialize(stStorage, serverData);
649 stStorage.Close();
650 }
651 catch (Exception ex)
652 {
653 Debug.Write(ex.Message);
654 if (stStorage != null)
655 stStorage.Close();
656 }
657
658 }
659 catch (Exception ex)
660 {
661 Debug.Write(ex.Message);
662 if (stStorage != null)
663 stStorage.Close();
664 if (ex.Message == "User cancelled.")
665 {
666 throw ex;
667 }
668 }
669
670 }
671
672 private void GetServerInfo(ref int nPort, ref string sAddress, ref string sNamespace)
673 {
674 //Get values from isolated storage
675 bool bLoaded = false;
676 Stream stStorage = null;
677 try
678 {
679 m_ServerData = new ServerData();
680 IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForAssembly();
681 string sFileName = "mserver0200.dat";
682 stStorage = new IsolatedStorageFileStream(sFileName, FileMode.Open, isStore);
683 IFormatter formatter = new SoapFormatter();
684 m_ServerData = (ServerData) formatter.Deserialize(stStorage);
685 stStorage.Close();
686 sAddress = m_ServerData.m_sAddress;
687 nPort = m_ServerData.m_nPort;
688 sNamespace = m_ServerData.m_sNamespace;
689
690 bLoaded = true;
691 return;
692 }
693 catch (Exception ex)
694 {
695 Debug.Write(ex.Message);
696 if (stStorage != null)
697 stStorage.Close();
698 }
699 try
700 {
701 //If unable to deserialize, display dialog to collect values
702 if (bLoaded == false)
703 {
704 DServerInfo dsi = new DServerInfo();
705 dsi.InitializePage("",10501,"");
706 if (dsi.ShowDialog() != DialogResult.OK)
707 {
708 throw new BMXNetException("Unable to get M Server information");
709 }
710 m_ServerData.m_sAddress = dsi.MServerAddress;
711 m_ServerData.m_nPort = dsi.MServerPort;
712 m_ServerData.m_sNamespace = dsi.MServerNamespace;
713 }
714
715 sAddress = m_ServerData.m_sAddress;
716 nPort = m_ServerData.m_nPort;
717 sNamespace = m_ServerData.m_sNamespace;
718
719 //Save port and address to isolated storage
720 try
721 {
722 string sFileName = "mserver0200.dat";
723 IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForAssembly();
724 stStorage = new IsolatedStorageFileStream(sFileName, FileMode.Create, isStore);
725 IFormatter formatter = new SoapFormatter();
726 formatter.Serialize(stStorage, m_ServerData);
727 stStorage.Close();
728 }
729 catch (Exception ex)
730 {
731 Debug.Write(ex.Message);
732 if (stStorage != null)
733 stStorage.Close();
734 }
735
736 return;
737 }
738 catch (Exception ex)
739 {
740 Debug.Write(ex.Message);
741 if (stStorage != null)
742 stStorage.Close();
743 throw ex;
744 }
745
746 }
747
748 /// <summary>
749 /// Called to connect to an M server
750 /// Server address, port, Access and Verify codes will be
751 /// prompted for depending on whether these values are
752 /// cached.
753 /// </summary>
754 public void LoadConnectInfo()
755 {
756 m_bAutoServer = true;
757 m_bAutoLogin = true;
758 LoadConnectInfo("",0,"","");
759 }
760
761 /// <summary>
762 /// Called to connect to the M server specified by
763 /// server address and listener port. The default namespace on the server will be used.
764 /// Access and Verify codes will be prompted if
765 /// valid values for the current Windows Identity are
766 /// not cached on the server.
767 /// </summary>
768 /// <param name="MServerAddress">The IP address or name of the MServer</param>
769 /// <param name="Port">The port on which the BMXNet Monitor is listening</param>
770 public void LoadConnectInfo(string MServerAddress, int Port)
771 {
772 LoadConnectInfo(MServerAddress, Port, "", "", "");
773 }
774
775 /// <summary>
776 /// Called to connect to the M server specified by
777 /// server address, listener port and namespace.
778 /// Access and Verify codes will be prompted if
779 /// valid values for the current Windows Identity are
780 /// not cached on the server.
781 /// </summary>
782 /// <param name="MServerAddress">The IP address or name of the MServer</param>
783 /// <param name="Port">The port on which the BMXNet Monitor is listening</param>
784 /// <param name="Namespace">The namespace in which the BMXNet application will run</param>
785 public void LoadConnectInfo(string MServerAddress, int Port, string Namespace)
786 {
787 m_bAutoServer = false;
788 m_bAutoLogin = true;
789 LoadConnectInfo(MServerAddress, Port,"","", Namespace);
790 }
791
792 /// <summary>
793 /// Called to connect to an M server
794 /// using specific Access and Verify codes.
795 /// Server address and port will be prompted if they
796 /// are not cached in local storage.
797 /// </summary>
798 /// <param name="AccessCode">The user's access code</param>
799 /// <param name="VerifyCode">The user's verify code</param>
800 public void LoadConnectInfo(string AccessCode, string VerifyCode)
801 {
802 m_bAutoServer = true;
803 m_bAutoLogin = false;
804 LoadConnectInfo("", 0,AccessCode,VerifyCode);
805 }
806
807 /// <summary>
808 /// Called to connect to a specific M server
809 /// using specific Access and Verify codes.
810 /// </summary>
811 /// <param name="AccessCode">The user's access code</param>
812 /// <param name="VerifyCode">The user's verify code</param>
813 /// <param name="MServerAddress">The IP address or name of the MServer</param>
814 /// <param name="Port">The port on which the BMXNet Monitor is listening</param>
815 public void LoadConnectInfo(string MServerAddress, int Port,
816 string AccessCode, string VerifyCode)
817 {
818 LoadConnectInfo(MServerAddress, Port, AccessCode, VerifyCode, "");
819 }
820
821 /// <summary>
822 /// Called to connect to a specific namespace on the M server
823 /// using specific Access and Verify codes.
824 /// </summary>
825 /// <param name="AccessCode">The user's access code</param>
826 /// <param name="VerifyCode">The user's verify code</param>
827 /// <param name="MServerAddress">The IP address or name of the MServer</param>
828 /// <param name="Port">The port on which the BMXNet Monitor is listening</param>
829 /// <param name="Namespace">The namespace in which the BMXNet application will run</param>
830 public void LoadConnectInfo(string MServerAddress, int Port,
831 string AccessCode, string VerifyCode, string Namespace)
832 {
833 //Throws exception if unable to connect to RPMS
834
835 /*
836 * Get RPMS Server Address and Port from local storage.
837 * Prompt for them if they're not there.
838 *
839 * Throw exception if unable to get address/port
840 */
841
842 if (m_bAutoServer == true)
843 {
844 string sAddress = "";
845 int nPort = 0;
846 string sNamespace = "";
847 try
848 {
849 GetServerInfo(ref nPort, ref sAddress, ref sNamespace);
850 m_nServerPort = nPort;
851 m_sServerAddress = sAddress;
852 m_sServerNamespace = sNamespace;
853 }
854 catch (Exception ex)
855 {
856 Debug.Write(ex.Message);
857 throw ex;
858 }
859 }
860 else
861 {
862 m_sServerAddress = MServerAddress;
863 m_nServerPort = Port;
864 m_sServerNamespace = Namespace;
865 }
866
867 /*
868 * Connect to RPMS using current windows identity
869 * Execute BMXNetGetCodes(NTDomain/UserName) to get encrypted AV codes
870 *
871 */
872
873 m_BMXNetLib.CloseConnection();
874 m_BMXNetLib.MServerPort = m_nServerPort;
875 m_BMXNetLib.MServerNamespace = m_sServerNamespace;
876
877 string sLoginError = "";
878 WindowsIdentity winIdentity = WindowsIdentity.GetCurrent();
879 string sIdentName = winIdentity.Name;
880 string sIdentType = winIdentity.AuthenticationType;
881 bool bIdentIsAuth = winIdentity.IsAuthenticated;
882 bool bRet = false;
883 if (m_bAutoLogin == true)
884 {
885 try
886 {
887 //Attempt Auto-login using WindowsIdentity
888
889 if (bIdentIsAuth == false)
890 {
891 throw new BMXNetException("Current Windows User is not authenticated");
892 }
893 bRet = m_BMXNetLib.OpenConnection(m_sServerAddress, winIdentity);
894
895 try
896 {
897 string sDuz = m_BMXNetLib.DUZ;
898 int nDuz = Convert.ToInt16(sDuz);
899 }
900 catch (Exception exCV)
901 {
902 Debug.Write("OpenConnection failed: " + exCV.Message);
903 //Debug.Assert(false);
904 throw new Exception(exCV.Message);
905 }
906 }
907 catch (Exception ex)
908 {
909 Debug.Write(ex.Message);
910 sLoginError = ex.Message;
911 }
912 }
913
914 if (m_BMXNetLib.Connected == false) //BMXNET Login failed or m_bAutoLogin == false
915 {
916 try
917 {
918 //If autologin was attempted and
919 //error message anything other than
920 //"invalid AV code pair"
921 // or "User BMXNET,APPLICATION does not have access to option BMXRPC",
922 // or current windows user is not authenticated or is a guest
923 //then rethrow exception.
924 if ((m_bAutoLogin == true)
925 &&(BMXNetLib.FindSubString(sLoginError, "Not a valid ACCESS CODE/VERIFY CODE pair.") == -1)
926 &&(BMXNetLib.FindSubString(sLoginError, "User BMXNET,APPLICATION does not have access to option BMXRPC") == -1)
927 &&(BMXNetLib.FindSubString(sLoginError, "Not a valid Windows Identity map value.") == -1)
928 &&(BMXNetLib.FindSubString(sLoginError, "Current Windows User is not authenticated") == -1)
929 &&(BMXNetLib.FindSubString(sLoginError, "Windows Integrated Security Not Allowed on this port.") == -1)
930 )
931 {
932 throw new BMXNetException(sLoginError);
933 }
934
935 //Display dialog to collect user-input AV
936
937 DLoginInfo dLog = new DLoginInfo();
938 DialogResult bStop = DialogResult.OK;
939 m_BMXNetLib.CloseConnection();
940 if ((AccessCode == "") && (VerifyCode == ""))
941 {
942 //nothing was passed in, so display a dialog to collect AV codes
943 do
944 {
945 dLog.InitializePage("","");
946 bStop = dLog.ShowDialog();
947 if (bStop == DialogResult.Cancel)
948 {
949 throw new BMXNetException("User cancelled login.");
950 }
951 try
952 {
953 string sTempAccess = dLog.AccessCode;
954 string sTempVerify = dLog.VerifyCode;
955 bRet = m_BMXNetLib.OpenConnection(m_sServerAddress, sTempAccess, sTempVerify);
956 }
957 catch (Exception ex)
958 {
959 Debug.Write(ex.Message);
960 //MessageBox.Show(ex.Message, "RPMS Login Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
961 throw ex;
962 }
963 }while ((bStop == DialogResult.OK) && (m_BMXNetLib.Connected == false));
964 }
965 else //caller passed in AV codes
966 {
967 try
968 {
969 //Connect using caller's AV
970 bRet = m_BMXNetLib.OpenConnection(m_sServerAddress, AccessCode, VerifyCode);
971 }
972 catch (Exception ex)
973 {
974 Debug.Write(ex.Message);
975 //MessageBox.Show(ex.Message, "RPMS Login Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
976 throw new BMXNetException(ex.Message);
977 }
978 }
979
980 //Map Windows Identity to logged-in RPMS user
981 if ((bIdentIsAuth == true) && (m_BMXNetLib.Connected == true))
982 {
983 m_BMXNetLib.AppContext = "BMXRPC";
984 string sRes = m_BMXNetLib.TransmitRPC("BMXNetSetUser", sIdentName);
985 Debug.Write("LoadConnectInfo BMXNetSetUser returned " + sRes + "\n");
986 }
987 }
988 catch (Exception ex)
989 {
990 Debug.Write(ex.Message);
991 m_BMXNetLib.CloseConnection();
992 throw ex; //this exception will be caught by the caller.
993 }
994 }//End if (m_BMXNetLib.Connected == false)
995
996 try
997 {
998 Debug.Assert(m_BMXNetLib.Connected == true);
999 m_BMXNetLib.AppContext = "BMXRPC";
1000 string sRpc = "BMX USER";
1001 Debug.Assert(m_BMXNetLib.AppContext == "BMXRPC");
1002
1003 bool bCtxt = false;
1004 int nCtxt = 0;
1005 do
1006 {
1007 try
1008 {
1009 m_sUserName = m_BMXNetLib.TransmitRPC(sRpc, this.DUZ);
1010 bCtxt = true;
1011 Debug.Write("BMXNet::LoadConnectInfo succeeded.\n");
1012 }
1013 catch (Exception ex)
1014 {
1015 Debug.Write("BMXNet::LoadConnectInfo retrying: " + ex.Message + "\n");
1016 m_BMXNetLib.AppContext = "BMXRPC";
1017 nCtxt++;
1018 if (nCtxt > 4)
1019 throw ex;
1020 }
1021 }while (bCtxt == false);
1022
1023
1024 System.Data.DataTable rsDivisions;
1025 rsDivisions = this.GetUserDivisions();
1026 m_nDivisionCount = rsDivisions.Rows.Count;
1027
1028 // Must have at least one division in order for our code to work
1029 // If user has no divisions, M routine will invent one for our sake (get it from kernel).
1030 //
1031 Debug.Assert(m_nDivisionCount > 0, "Must get at least one division from VISTA");
1032
1033 // if more than one division, have user pick
1034 // if just one, get the DUZ(2) and then set it via the property DUZ2.
1035
1036 if (m_nDivisionCount > 1)
1037 {
1038 ChangeDivision(null);
1039 // following true if user cancelled.
1040 if (DUZ2 == null) throw new BMXNetException("No division chosen -- can't log in");
1041 }
1042 // if just one
1043 else DUZ2 = m_sDUZ2 = rsDivisions.Rows[0]["FACILITY_IEN"].ToString();
1044
1045 }
1046 catch(Exception bmxEx)
1047 {
1048 m_BMXNetLib.CloseConnection();
1049 string sMessage = bmxEx.Message + bmxEx.StackTrace;
1050 throw new BMXNetException(sMessage);
1051 }
1052 return;
1053 }
1054
1055 private DataTable GetUserDivisions()
1056 {
1057 try
1058 {
1059 DataTable tb = this.RPMSDataTable("BMXGetFacRS^" + this.DUZ, "DivisionTable");
1060 return tb;
1061 }
1062 catch (Exception bmxEx)
1063 {
1064 string sMessage = bmxEx.Message + bmxEx.StackTrace;
1065 throw new BMXNetException(sMessage);
1066
1067 }
1068 }
1069
1070 public void ChangeDivision(System.Windows.Forms.Form frmCaller)
1071 {
1072 DSelectDivision dsd = new DSelectDivision();
1073 dsd.InitializePage(UserDivisions);
1074
1075 if (dsd.ShowDialog(frmCaller) == DialogResult.Cancel)
1076 return;
1077
1078 if (dsd.DUZ2 != this.DUZ2)
1079 {
1080 DUZ2 = dsd.DUZ2;
1081 }
1082 }
1083
1084 public string GetDSN(string sAppContext)
1085 {
1086 string sDsn = "Data source=";
1087 if (sAppContext == "")
1088 sAppContext = "BMXRPC";
1089
1090 if (m_BMXNetLib.Connected == false)
1091 return sDsn.ToString();
1092
1093 sDsn += this.m_sServerAddress ;
1094 sDsn += ";Location=";
1095 sDsn += this.m_nServerPort.ToString();
1096 sDsn += ";Extended Properties=";
1097 sDsn += sAppContext;
1098
1099 return sDsn;
1100 }
1101
1102
1103 public bool Lock(string sVariable, string sIncrement, string sTimeOut)
1104 {
1105 bool bRet = false;
1106 string sErrorMessage = "";
1107
1108 if (m_BMXNetLib.Connected == false)
1109 {
1110 return bRet;
1111 }
1112 try
1113 {
1114 bRet = this.bmxNetLib.Lock(sVariable, sIncrement, sTimeOut);
1115 return bRet;
1116 }
1117 catch(Exception ex)
1118 {
1119 sErrorMessage = "CGDocumentManager.RPMSDataTable error: " + ex.Message;
1120 throw ex;
1121 }
1122 }
1123
1124 delegate DataTable RPMSDataTableDelegate(string CommandString, string TableName);
1125 delegate DataTable RPMSDataTableDelegate2(string CommandString, string TableName, DataSet dsDataSet);
1126
1127 /// <summary>
1128 /// Creates and names a DataTable using the command in CommandString
1129 /// and the name in TableName.
1130 /// </summary>
1131 /// <param name="CommandString"> The SQL or RPC call</param>
1132 /// <param name="TableName">The name of the resulting table</param>
1133 /// <returns>
1134 /// Returns the resulting DataTable.
1135 /// </returns>
1136 public DataTable RPMSDataTable(string CommandString, string TableName)
1137 {
1138 return this.RPMSDataTable(CommandString, TableName, null);
1139 }
1140
1141 /// <summary>
1142 /// Creates and names a DataTable using the command in CommandString
1143 /// and the name in TableName then adds it to DataSet.
1144 /// </summary>
1145 /// <param name="CommandString">The SQL or RPC call</param>
1146 /// <param name="TableName">The name of the resulting table</param>
1147 /// <param name="dsDataSet">The dataset in which to place the table</param>
1148 /// <returns>
1149 /// Returns the resulting DataTable.
1150 /// </returns>
1151 public DataTable RPMSDataTable(string CommandString, string TableName, DataSet dsDataSet)
1152 {
1153 //Retrieves a recordset from RPMS
1154 //Debug.Assert(this.InvokeRequired == false);
1155 string sErrorMessage = "";
1156 DataTable dtResult = new DataTable(TableName);
1157
1158 if (m_BMXNetLib.Connected == false)
1159 return dtResult;
1160
1161 try
1162 {
1163 BMXNetConnection rpmsConn = new BMXNetConnection(m_BMXNetLib);
1164 BMXNetCommand cmd = (BMXNetCommand) rpmsConn.CreateCommand();
1165 BMXNetDataAdapter da = new BMXNetDataAdapter();
1166
1167 cmd.CommandText = CommandString;
1168 da.SelectCommand = cmd;
1169 if (dsDataSet == null)
1170 {
1171 da.Fill(dtResult);
1172 }
1173 else
1174 {
1175 da.Fill(dsDataSet, TableName);
1176 dtResult = dsDataSet.Tables[TableName];
1177 }
1178 Debug.Write(dtResult.TableName + " DataTable retrieved\n");
1179 return dtResult;
1180 }
1181 catch (Exception ex)
1182 {
1183 sErrorMessage = "CGDocumentManager.RPMSDataTable error: " + ex.Message;
1184 throw ex;
1185 }
1186 }
1187
1188 public int RPMSDataTableAsyncQue(string CommandString, string EventName)
1189 {
1190 try
1191 {
1192 string sCommand = "BMX ASYNC QUEUE^";
1193 //replace ^'s in CommandString with $c(30)'s
1194 char[] cDelim = new char[1];
1195 cDelim[0] = (char) 30;
1196 string sDelim = cDelim[0].ToString();
1197 CommandString = CommandString.Replace("^", sDelim);
1198 sCommand = sCommand + CommandString + "^" + EventName;
1199
1200 DataTable dt = new DataTable();
1201 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(RPMSDataTable);
1202 if (this.IsHandleCreated == false)
1203 {
1204 this.CreateHandle();
1205 }
1206
1207 dt = (DataTable) this.Invoke(rdtd, new object[] {sCommand, "Que"});
1208
1209 DataRow dr = dt.Rows[0];
1210 int nErrorID = Convert.ToInt32(dr["ERRORID"]);
1211 int nParam = Convert.ToInt32(dr["PARAM"]);
1212
1213 if (nErrorID == 0)
1214 {
1215 return 0;
1216 }
1217 else
1218 {
1219 return nParam;
1220 }
1221 }
1222 catch (Exception ex)
1223 {
1224 Debug.Write("RPMSDataTableAsyncQue error: " + ex.Message + "\n");
1225 throw ex;
1226 }
1227 }
1228
1229 public DataTable RPMSDataTableAsyncGet(string AsyncInfo, string TableName)
1230 {
1231 return RPMSDataTableAsyncGet(AsyncInfo, TableName, null);
1232 }
1233
1234 public DataTable RPMSDataTableAsyncGet(string AsyncInfo, string TableName, DataSet dsDataSet)
1235 {
1236 try
1237 {
1238 string sCommand = "BMX ASYNC GET^" + AsyncInfo;
1239
1240 DataTable dt;
1241 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(RPMSDataTable);
1242 RPMSDataTableDelegate2 rdtd2 = new RPMSDataTableDelegate2(RPMSDataTable);
1243 if (this.IsHandleCreated == false)
1244 {
1245 this.CreateHandle();
1246 }
1247
1248 if (dsDataSet == null)
1249 {
1250 dt = (DataTable) this.Invoke(rdtd, new object[] {sCommand, TableName});
1251 }
1252 else
1253 {
1254 dt = (DataTable) this.Invoke(rdtd2, new object[] {sCommand, TableName, dsDataSet});
1255 }
1256 return dt;
1257 }
1258 catch (Exception ex)
1259 {
1260 Debug.Write("RPMSDataTableAsyncGet error: " + ex.Message + "\n");
1261 throw ex;
1262 }
1263 }
1264
1265 #endregion Methods
1266
1267 }
1268}
Note: See TracBrowser for help on using the repository browser.