source: BMXNET_RPMS_dotNET_UTILITIES-BMX/trunk/cs/bmx_0200scr/BMX2/BMXNet/BMXNetLib.cs@ 822

Last change on this file since 822 was 822, checked in by Sam Habiel, 14 years ago

Support for other encodings besides ASCII. Constructors available in BMXNetLib and and BMXNetConnectInfo.
Comments in several files.

File size: 34.4 KB
Line 
1using System;
2using System.Diagnostics;
3using System.Text;
4using System.IO;
5using System.Net.Sockets;
6using System.Net;
7using System.Security.Cryptography;
8using System.Security.Permissions;
9using System.Security.Principal;
10using System.Threading;
11using System.Timers;
12
13namespace IndianHealthService.BMXNet
14{
15 /// <summary>
16 /// BMXNetLib implements low-level socket connectivity to RPMS databases.
17 /// The VA RPC Broker must be running on the RPMS server in order for
18 /// BMXNetLib to connect.
19 /// </summary>
20 [DnsPermission(SecurityAction.Assert, Unrestricted = true)]
21 public class BMXNetLib
22 {
23 /// <summary>
24 /// Main constructor with default machine encoding
25 /// </summary>
26 public BMXNetLib()
27 {
28 m_sWKID = "BMX";
29 m_sWINH = "";
30 m_sPRCH = "";
31 m_sWISH = "";
32 m_cHDR = ADEBHDR(m_sWKID,m_sWINH,m_sPRCH,m_sWISH);
33
34 }
35
36 /// <summary>
37 /// Constructor specifiying encoding
38 /// </summary>
39 /// <param name="charset">String name of character set</param>
40 public BMXNetLib(string charset) : this()
41 {
42
43 //char[] arabic_nm_ch = arabic_name.ToCharArray();
44 //byte[] arabic_nm_by = cp1256.GetBytes(arabic_nm_ch);
45 //string arabic_name2 = "";
46 //foreach (byte eachbyte in arabic_nm_by)
47 //{
48 // arabic_name2 += ((char)eachbyte);
49 //}
50
51 try
52 {
53 m_Encoding = System.Text.Encoding.GetEncoding(charset);
54 }
55 catch (ArgumentException)
56 {
57 Debug.Write("Invalid Code Page... Falling back to default system encoding");
58 m_Encoding = Encoding.GetEncoding(0);
59 }
60 }
61
62 #region Piece Functions
63
64 /// <summary>
65 /// Corresponds to M's $L(STRING,DELIMITER)
66 /// </summary>
67 /// <param name="sInput"></param>
68 /// <param name="sDelim"></param>
69 /// <returns></returns>
70 public static int PieceLength(string sInput, string sDelim)
71 {
72 char[] cDelim = sDelim.ToCharArray();
73 string [] cSplit = sInput.Split(cDelim);
74 return cSplit.GetLength(0);
75 }
76
77 /// <summary>
78 /// Corresponds to M's $$Piece function
79 /// </summary>
80 /// <param name="sInput"></param>
81 /// <param name="sDelim"></param>
82 /// <param name="nNumber"></param>
83 /// <returns></returns>
84 public static string Piece(string sInput, string sDelim, int nNumber)
85 {
86 try
87 {
88 char[] cDelim = sDelim.ToCharArray();
89 string [] cSplit = sInput.Split(cDelim);
90 int nLength = cSplit.GetLength(0);
91 if ((nLength < nNumber)||(nNumber < 1))
92 return "";
93 return cSplit[nNumber-1];
94 }
95 catch (Exception bmxEx)
96 {
97 string sMessage = bmxEx.Message + bmxEx.StackTrace;
98 throw new BMXNetException(sMessage);
99 }
100
101 }
102
103 public static string Piece(string sInput, string sDelim, int nNumber, int nEnd)
104 {
105 try
106 {
107 if (nNumber < 0)
108 nNumber = 1;
109
110 if (nEnd < nNumber)
111 return "";
112
113 if (nEnd == nNumber)
114 return Piece(sInput, sDelim, nNumber);
115
116 char[] cDelim = sDelim.ToCharArray();
117 string [] cSplit = sInput.Split(cDelim);
118 int nLength = cSplit.GetLength(0);
119 if ((nLength < nNumber)||(nNumber < 1))
120 return "";
121
122 //nNumber = 1-based index of the starting element to return
123 //nLength = count of elements
124 //nEnd = 1-based index of last element to return
125 //nCount = number of elements past nNumber to return
126
127 //convert nNumber to 0-based index:
128 nNumber--;
129
130 //convert nEnd to 0-based index;
131 nEnd--;
132
133 //Calculate nCount;
134 int nCount = nEnd - nNumber + 1;
135
136 //Adjust nCount for number of elements
137 if (nCount + nNumber >= nLength)
138 {
139 nCount = nLength - nNumber;
140 }
141
142 string sRet = string.Join(sDelim, cSplit, nNumber, nCount );
143 return sRet;
144 }
145 catch (Exception bmxEx)
146 {
147 string sMessage = bmxEx.Message + bmxEx.StackTrace;
148 throw new BMXNetException(sMessage);
149 }
150 }
151
152 #endregion Piece Functions
153
154 #region RPX Fields
155
156 private string m_sWKID;
157 private string m_sWISH;
158 private string m_sPRCH;
159 private string m_sWINH;
160 private string m_cHDR;
161 private string m_cAppContext;
162 private bool m_bConnected;
163 private int m_nMServerPort;
164 private string m_cServerAddress;
165 private string m_cDUZ;
166 private string m_cLoginFacility;
167 private TcpClient m_pCommSocket;
168 private string m_sNameSpace = "";
169 private int m_nReceiveTimeout = 30000;
170
171 private Encoding m_Encoding = Encoding.GetEncoding(0);
172
173 #endregion RPX Fields
174
175 #region Encryption Keys
176 private string[] m_sKey = new string[]
177 {
178 @"wkEo-ZJt!dG)49K{nX1BS$vH<&:Myf*>Ae0jQW=;|#PsO`'%+rmb[gpqN,l6/hFC@DcUa ]z~R}""V\iIxu?872.(TYL5_3",
179 @"rKv`R;M/9BqAF%&tSs#Vh)dO1DZP> *fX'u[.4lY=-mg_ci802N7LTG<]!CWo:3?{+,5Q}(@jaExn$~p\IyHwzU""|k6Jeb",
180 @"\pV(ZJk""WQmCn!Y,y@1d+~8s?[lNMxgHEt=uw|X:qSLjAI*}6zoF{T3#;ca)/h5%`P4$r]G'9e2if_>UDKb7<v0&- RBO.",
181 @"depjt3g4W)qD0V~NJar\B ""?OYhcu[<Ms%Z`RIL_6:]AX-zG.#}$@vk7/5x&*m;(yb2Fn+l'PwUof1K{9,|EQi>H=CT8S!",
182 @"NZW:1}K$byP;jk)7'`x90B|cq@iSsEnu,(l-hf.&Y_?J#R]+voQXU8mrV[!p4tg~OMez CAaGFD6H53%L/dT2<*>""{\wI=",
183 @"vCiJ<oZ9|phXVNn)m K`t/SI%]A5qOWe\&?;jT~M!fz1l>[D_0xR32c*4.P""G{r7}E8wUgyudF+6-:B=$(sY,LkbHa#'@Q",
184 @"hvMX,'4Ty;[a8/{6l~F_V""}qLI\!@x(D7bRmUH]W15J%N0BYPkrs&9:$)Zj>u|zwQ=ieC-oGA.#?tfdcO3gp`S+En K2*<",
185 @"jd!W5[];4'<C$/&x|rZ(k{>?ghBzIFN}fAK""#`p_TqtD*1E37XGVs@0nmSe+Y6Qyo-aUu%i8c=H2vJ\) R:MLb.9,wlO~P",
186 @"2ThtjEM+!=xXb)7,ZV{*ci3""8@_l-HS69L>]\AUF/Q%:qD?1~m(yvO0e'<#o$p4dnIzKP|`NrkaGg.ufCRB[; sJYwW}5&",
187 @"vB\5/zl-9y:Pj|=(R'7QJI *&CTX""p0]_3.idcuOefVU#omwNZ`$Fs?L+1Sk<,b)hM4A6[Y%aDrg@~KqEW8t>H};n!2xG{",
188 @"sFz0Bo@_HfnK>LR}qWXV+D6`Y28=4Cm~G/7-5A\b9!a#rP.l&M$hc3ijQk;),TvUd<[:I""u1'NZSOw]*gxtE{eJp|y (?%",
189 @"M@,D}|LJyGO8`$*ZqH .j>c~h<d=fimszv[#-53F!+a;NC'6T91IV?(0x&/{B)w""]Q\YUWprk4:ol%g2nE7teRKbAPuS_X",
190 @".mjY#_0*H<B=Q+FML6]s;r2:e8R}[ic&KA 1w{)vV5d,$u""~xD/Pg?IyfthO@CzWp%!`N4Z'3-(o|J9XUE7k\TlqSb>anG",
191 @"xVa1']_GU<X`|\NgM?LS9{""jT%s$}y[nvtlefB2RKJW~(/cIDCPow4,>#zm+:5b@06O3Ap8=*7ZFY!H-uEQk; .q)i&rhd",
192 @"I]Jz7AG@QX.""%3Lq>METUo{Pp_ |a6<0dYVSv8:b)~W9NK`(r'4fs&wim\kReC2hg=HOj$1B*/nxt,;c#y+![?lFuZ-5D}",
193 @"Rr(Ge6F Hx>q$m&C%M~Tn,:""o'tX/*yP.{lZ!YkiVhuw_<KE5a[;}W0gjsz3]@7cI2\QN?f#4p|vb1OUBD9)=-LJA+d`S8",
194 @"I~k>y|m};d)-7DZ""Fe/Y<B:xwojR,Vh]O0Sc[`$sg8GXE!1&Qrzp._W%TNK(=J 3i*2abuHA4C'?Mv\Pq{n#56LftUl@9+",
195 @"~A*>9 WidFN,1KsmwQ)GJM{I4:C%}#Ep(?HB/r;t.&U8o|l['Lg""2hRDyZ5`nbf]qjc0!zS-TkYO<_=76a\X@$Pe3+xVvu",
196 @"yYgjf""5VdHc#uA,W1i+v'6|@pr{n;DJ!8(btPGaQM.LT3oe?NB/&9>Z`-}02*%x<7lsqz4OS ~E$\R]KI[:UwC_=h)kXmF",
197 @"5:iar.{YU7mBZR@-K|2 ""+~`M%8sq4JhPo<_X\Sg3WC;Tuxz,fvEQ1p9=w}FAI&j/keD0c?)LN6OHV]lGy'$*>nd[(tb!#",
198 };
199
200 #endregion Encryption Keys
201
202 #region RPX Functions
203
204 /// <summary>
205 /// Given strInput = "13" builds "013" if nLength = 3. Default for nLength is 3.
206 /// </summary>
207 /// <param name="strInput"></param>
208 /// <returns></returns>
209 private string ADEBLDPadString(string strInput)
210 {
211 return ADEBLDPadString(strInput, 3);
212 }
213
214 /// <summary>
215 /// Given strInput = "13" builds "013" if nLength = 3 Default for nLength is 3.
216 /// </summary>
217 /// <param name="strInput"></param>
218 /// <param name="nLength">Default = 3</param>
219 /// <returns></returns>
220 private string ADEBLDPadString(string strInput, int nLength /*=3*/)
221 {
222 return strInput.PadLeft(nLength, '0');
223 }
224
225 /// <summary>
226 /// Concatenates zero-padded length of sInput to sInput
227 /// Given "Hello" returns "004Hello"
228 /// If nSize = 5, returns "00004Hello"
229 /// Default for nSize is 3.
230 /// </summary>
231 /// <param name="sInput"></param>
232 /// <returns></returns>
233 private string ADEBLDB(string sInput)
234 {
235 return ADEBLDB(sInput, 3);
236 }
237
238 /// <summary>
239 /// Concatenates zero-padded length of sInput to sInput
240 /// Given "Hello" returns "004Hello"
241 /// If nSize = 5, returns "00004Hello"
242 /// Default for nSize is 3.
243 /// </summary>
244 /// <param name="sInput"></param>
245 /// <param name="nSize"></param>
246 /// <returns></returns>
247 private string ADEBLDB(string sInput, int nSize /*=3*/)
248 {
249 int nLen = sInput.Length;
250 string sLen = this.ADEBLDPadString(nLen.ToString(), nSize);
251 return sLen + sInput;
252 }
253
254 /// <summary>
255 /// Build protocol header
256 /// </summary>
257 /// <param name="sWKID"></param>
258 /// <param name="sWINH"></param>
259 /// <param name="sPRCH"></param>
260 /// <param name="sWISH"></param>
261 /// <returns></returns>
262 private string ADEBHDR(string sWKID, string sWINH, string sPRCH, string sWISH)
263 {
264 string strResult;
265 strResult = sWKID+";"+sWINH+";"+sPRCH+";"+sWISH+";";
266 strResult = ADEBLDB(strResult);
267 return strResult;
268 }
269 private string ADEBLDMsg(string cHDR, string cRPC, string cParam)
270 {
271 string sMult = "";
272 return ADEBLDMsg(cHDR, cRPC, cParam, ref sMult);
273 }
274 private string ADEBLDMsg(string cHDR, string cRPC, string cParam, ref string cMult)
275 {
276 //Builds RPC message
277 //Automatically splits parameters longer than 200 into subscripted array
278 string cMSG;
279 string sBuild = "";
280 string sPiece = "";
281 string sBig = "";
282 int l;
283 int nLength;
284
285 if (cParam == "")
286 {
287 cMSG = "0" + cRPC ;
288 }
289 else
290 {
291 l = PieceLength(cParam, "^");
292 for (int j=1; j <= l; j++)
293 {
294 sPiece = Piece(cParam, "^", j);
295 if ((j == l) && (sPiece.Length > 200))
296 {
297 //Split up long param into array pieces
298 sBig = sPiece;
299 sPiece = ".x";
300 nLength = sPiece.Length + 1;
301 sPiece = ADEBLDPadString(nLength.ToString()) + "2" + sPiece;
302 sBuild = sBuild + sPiece;
303 int nSubscript = 1;
304 string sSubscript ="";
305 int nSubLen = 0;
306 string sSubLen ="";
307 int nBigLen = sBig.Length;
308 string sHunk ="";
309 int nHunkLen = 0;
310 string sHunkLen ="";
311 int nChunk = 0;
312 do
313 {
314 nChunk = (sBig.Length > 200)?200:sBig.Length ;
315 sHunk = sBig.Substring(0, nChunk);
316 sBig = sBig.Remove(0, nChunk);
317 nBigLen = sBig.Length;
318 sSubscript = nSubscript.ToString();
319 nSubLen = sSubscript.Length;
320 sSubLen = nSubLen.ToString();
321 sSubLen = ADEBLDPadString(sSubLen);
322 nHunkLen = sHunk.Length;
323 sHunkLen = nHunkLen.ToString();
324 sHunkLen = ADEBLDPadString(sHunkLen);
325 cMult = cMult + sSubLen + sSubscript + sHunkLen + sHunk;
326 nSubscript++;
327 } while (nBigLen > 0);
328 }
329 else
330 {
331 nLength = sPiece.Length +1;
332 sPiece = ADEBLDPadString(nLength.ToString()) + "0" + sPiece;
333 sBuild = sBuild + sPiece;
334 }
335 }
336 nLength = sBuild.Length;
337 string sTotLen = ADEBLDPadString(nLength.ToString(),5);
338 if (cMult.Length > 0)
339 {
340 cMSG = "1"+ cRPC + "^" +sTotLen + sBuild;
341 }
342 else
343 {
344 cMSG = "0"+ cRPC + "^" +sTotLen + sBuild;
345 }
346 }
347 cMSG = ADEBLDB(cMSG, 5);
348 cMSG = cHDR + cMSG;
349 return cMSG;
350 }
351
352 internal string ADEEncryp(string sInput)
353 {
354 //Encrypt a string
355 string strResult;
356 string strPercent;
357 string strAssoc;
358 string strIdix;
359 int nPercent;
360 int nAssocix;
361 int nIdix;
362 Debug.Assert(sInput != "");
363 System.Random rRand = new Random(DateTime.Now.Second);
364
365 nPercent = rRand.Next(0,10000);
366 nPercent += 72439;
367 nAssocix = nPercent % 20;
368 nAssocix++;
369 Debug.Assert(nAssocix < 21);
370 strPercent = nPercent.ToString();
371 strPercent = strPercent.Substring(1,2);
372 nIdix = Convert.ToInt32(strPercent);
373 nIdix = nIdix % 20;
374 nIdix++;
375 Debug.Assert(nIdix < 21);
376
377 const int nEncryptBase = 101;
378 strAssoc = LoadKey(nEncryptBase + nAssocix);
379 Debug.Assert(strAssoc.Length == 94);
380 strIdix = LoadKey(nEncryptBase + nIdix);
381 Debug.Assert(strIdix.Length == 94);
382 string sEncrypted = "";
383
384 foreach (char c in sInput)
385 {
386 string d = c.ToString();
387 int nFindChar = strIdix.IndexOf(c);
388 if (nFindChar > -1)
389 {
390 d = strAssoc.Substring(nFindChar,1);
391 }
392 sEncrypted += d;
393 }
394
395 strResult = (char) (nIdix + 31) + sEncrypted + (char) (nAssocix + 31);
396
397 return strResult;
398 }
399
400 internal string ADEDecryp(string sInput)
401 {
402 //Encrypt a string
403 string strAssoc;
404 string strIdix;
405 int nAssocix;
406 int nIdix;
407 Debug.Assert(sInput != "");
408
409 //get associator string index
410 char cAssocix = sInput[sInput.Length-1];
411 nAssocix =(int) cAssocix;
412 nAssocix -= 31;
413 Debug.Assert(nAssocix < 21);
414
415 //get identifier string index
416 char cIdix = sInput[0];
417 nIdix = (int) cIdix;
418 nIdix -= 31;
419 Debug.Assert(nIdix < 21);
420
421 //get associator string
422 const int nEncryptBase = 101;
423 strAssoc = LoadKey(nEncryptBase + nAssocix);
424 Debug.Assert(strAssoc.Length == 94);
425
426 //get identifier string
427 strIdix = LoadKey(nEncryptBase + nIdix);
428 Debug.Assert(strIdix.Length == 94);
429
430 //translated result
431 string sDecrypted = "";
432 sInput = sInput.Substring(1, sInput.Length - 2);
433 foreach (char c in sInput)
434 {
435 string d = c.ToString();
436 int nFindChar = strAssoc.IndexOf(c);
437 if (nFindChar > -1)
438 {
439 d = strIdix.Substring(nFindChar,1);
440 }
441 sDecrypted += d;
442 }
443
444 return sDecrypted;
445 }
446
447 internal string BMXEncrypt(string sInput)
448 {
449
450 ASCIIEncoding textConverter = new ASCIIEncoding();
451 RijndaelManaged myRijndael = new RijndaelManaged();
452 byte[] encrypted;
453 byte[] toEncrypt;
454 byte[] key;
455 byte[] IV;
456
457 string sKey="pouphfoz sfdbqjuvmbwft qizmphfoz";
458 string sIV = "Gichin Funakoshi";
459 key = textConverter.GetBytes(sKey);
460 IV = textConverter.GetBytes(sIV);
461
462 //Get an encryptor.
463 ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV);
464
465 //Encrypt the data.
466 MemoryStream msEncrypt = new MemoryStream();
467 CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
468
469 //Convert the input data to a byte array.
470 toEncrypt = textConverter.GetBytes(sInput);
471
472 //Write all data to the crypto stream and flush it.
473 csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
474 csEncrypt.FlushFinalBlock();
475
476 //Get encrypted array of bytes.
477 encrypted = msEncrypt.ToArray();
478
479 //Convert to string to send to RPMS
480 string sEncrypted = "" ;
481 byte bTmp;
482 string sTmp;
483 for (int j =0; j < encrypted.Length; j++)
484 {
485 bTmp = encrypted[j];
486 sTmp = bTmp.ToString();
487 sEncrypted += sTmp;
488 if (j < (encrypted.Length -1))
489 sEncrypted += "~";
490 }
491 return sEncrypted;
492 }
493
494 internal string BMXDecrypt(string sInput)
495 {
496 try
497 {
498 byte[] fromEncrypt;
499 ASCIIEncoding textConverter = new ASCIIEncoding();
500 RijndaelManaged myRijndael = new RijndaelManaged();
501 string sRPMSEncrypted = sInput;
502 string sBar = "~";
503 char[] cBar = sBar.ToCharArray();
504 string[] sArray;
505 sArray = sRPMSEncrypted.Split(cBar);
506 byte[] bRPMSEncrypted = new byte[sArray.GetLength(0)];
507 byte[] key;
508 byte[] IV;
509
510 //Convert the RPMS-stored string to a byte array
511 for (int j = 0; j < sArray.GetLength(0); j++)
512 {
513 bRPMSEncrypted[j] = Byte.Parse(sArray[j]);
514 }
515
516 //Get a decryptor that uses the same key and IV as the encryptor.
517 string sKey="pouphfoz sfdbqjuvmbwft qizmphfoz";
518 string sIV = "Gichin Funakoshi";
519 key = textConverter.GetBytes(sKey);
520 IV = textConverter.GetBytes(sIV);
521 ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV);
522
523 MemoryStream msDecrypt = new MemoryStream(bRPMSEncrypted);
524 CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
525
526 fromEncrypt = new byte[bRPMSEncrypted.Length - 2];
527
528 //Read the data out of the crypto stream.
529 csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
530
531 int nZ = FindChar(fromEncrypt, (char) 0);
532
533 //Convert the byte array back into a string.
534 string sResult;
535 if (nZ < 0)
536 {
537 sResult = textConverter.GetString(fromEncrypt);
538 }
539 else
540 {
541 sResult = textConverter.GetString(fromEncrypt, 0, nZ);
542 }
543 return sResult;
544 }
545 catch (Exception ex)
546 {
547 Debug.Write(ex.Message);
548 return "";
549 }
550 }
551
552 public static int FindChar(byte[] c, char y)
553 {
554 int n = 0;
555 int nRet = -1;
556 for (n=0; n < c.Length; n++)
557 {
558 if (y == (char) c[n])
559 {
560 nRet = n;
561 break;
562 }
563 }
564
565 return nRet;
566 }
567
568 public static int FindChar(string s, char y)
569 {
570 int n = 0;
571 int nRet = -1;
572 foreach (char c in s)
573 {
574 if (y == c)
575 {
576 nRet = n;
577 break;
578 }
579 n++;
580 }
581 return nRet;
582 }
583
584
585 /// <summary>
586 /// Returns index of first instance of sSubString in sString.
587 /// If sSubString not found, returns -1.
588 /// </summary>
589 /// <param name="sString"></param>
590 /// <param name="sSubString"></param>
591 /// <returns></returns>
592 public static int FindSubString(string sString, string sSubString)
593 {
594 int nFound = -1;
595 int nLimit = sString.Length - sSubString.Length + 1;
596 if (nLimit < 0)
597 return -1;
598
599 int nSubLength = sSubString.Length;
600 for (int j=0; j < nLimit; j++)
601 {
602 if (sString.Substring(j, nSubLength) == sSubString)
603 {
604 nFound = j;
605 break;
606 }
607 }
608 return nFound;
609 }
610
611 private string LoadKey(int nID)
612 {
613 nID -= 102;
614 Debug.Assert( nID < 20);
615 return m_sKey[nID];
616 }
617
618 private void OpenConnectionCommon(string sServerAddress)
619 {
620 try
621 {
622 m_cServerAddress = sServerAddress;
623
624 //Connect with the server
625 TcpClient connector = new TcpClient();
626
627 try
628 {
629 connector = new TcpClient();
630 connector.Connect(m_cServerAddress, m_nMServerPort);
631 }
632 catch (SocketException exSocket)
633 {
634 string s = exSocket.Message + exSocket.StackTrace;
635 throw new BMXNetException(s);
636 }
637
638 //Prepare & send the connect message
639 string cSend = "TCPconnect^" + m_sNameSpace + "^^";
640 int nLen = cSend.Length;
641 string sLen = nLen.ToString();
642 sLen = sLen.PadLeft(5, '0');
643 cSend = "{BMX}" + sLen + cSend;
644
645 NetworkStream ns = connector.GetStream();
646 byte[] sendBytes = Encoding.ASCII.GetBytes(cSend);
647 ns.Write(sendBytes,0,sendBytes.Length);
648
649 m_pCommSocket = connector;
650 return;
651
652 }
653 catch (BMXNetException bmxEx)
654 {
655 throw bmxEx;
656 }
657 catch (Exception ex)
658 {
659 string s = ex.Message + ex.StackTrace;
660 throw new BMXNetException(s);
661 }
662 }//End OpenConnectionCommon
663
664 [SocketPermissionAttribute(SecurityAction.Assert,
665 Access="Connect",
666 Host="All",
667 Port="All",
668 Transport="All")]
669 public bool OpenConnection(string sServerAddress, WindowsIdentity winIdentity)
670 {
671 try
672 {
673 OpenConnectionCommon(sServerAddress);
674 bool bSecurity;
675 try
676 {
677 bSecurity = SendSecurityRequest(winIdentity);
678
679 }
680 catch (Exception ex)
681 {
682 //Close the connection
683 SendString(m_pCommSocket, "#BYE#");
684 m_pCommSocket.Close();
685 m_bConnected = false;
686 m_cServerAddress = "";
687 throw ex;
688 }
689
690 m_bConnected = bSecurity;
691 return m_bConnected;
692 }
693 catch (BMXNetException bmxEx)
694 {
695 throw bmxEx;
696 }
697 catch (Exception ex)
698 {
699 string s = ex.Message + ex.StackTrace;
700 throw new BMXNetException(s);
701 }
702 }
703
704 StreamWriter m_LogWriter;
705 bool m_bLogging = false;
706
707 public void StartLog()
708 {
709 try
710 {
711 if (m_bLogging)
712 {
713 throw new Exception("Already logging.");
714 }
715 string sFile = "BMXLog " + DateTime.Now.DayOfYear.ToString() + " " +
716 DateTime.Now.Hour.ToString() + " " + DateTime.Now.Minute.ToString()
717 + " " + DateTime.Now.Second.ToString() + ".log";
718 StartLog(sFile);
719 return;
720 }
721 catch (Exception ex)
722 {
723 throw ex;
724 }
725 }
726
727 public void StartLog(string LogFileName)
728 {
729 try
730 {
731 if (m_bLogging)
732 {
733 throw new Exception("Already logging.");
734 }
735 m_LogWriter = File.AppendText(LogFileName);
736 m_bLogging = true;
737 return;
738 }
739 catch (Exception ex)
740 {
741 throw ex;
742 }
743 }
744
745 public void StopLog()
746 {
747 try
748 {
749 //Close the writer and underlying file.
750 if (m_bLogging == false)
751 {
752 return;
753 }
754 m_LogWriter.Close();
755 m_bLogging = false;
756 return;
757 }
758 catch (Exception ex)
759 {
760 throw ex;
761 }
762 }
763
764 private static void Log(String logMessage, TextWriter w)
765 {
766 w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
767 DateTime.Now.ToLongDateString());
768 w.WriteLine(" :");
769 w.WriteLine(" :{0}", logMessage);
770 w.WriteLine("-------------------------------");
771 // Update the underlying file.
772 w.Flush();
773 }
774
775 [SocketPermissionAttribute(SecurityAction.Assert,
776 Access="Connect",
777 Host="All",
778 Port="All",
779 Transport="All")]
780 public bool OpenConnection(string sServerAddress, string sAccess, string sVerify)
781 {
782 try
783 {
784 this.OpenConnectionCommon(sServerAddress);
785
786 try
787 {
788 bool bSecurity = SendSecurityRequest(sAccess, sVerify);
789 }
790 catch (Exception ex)
791 {
792 //Close the connection
793 SendString(m_pCommSocket, "#BYE#");
794 m_pCommSocket.Close();
795 m_bConnected = false;
796 m_cServerAddress = "";
797 throw ex;
798 }
799
800 m_bConnected = true;
801 return m_bConnected;
802 }
803 catch (BMXNetException bmxEx)
804 {
805 throw bmxEx;
806 }
807 catch (Exception ex)
808 {
809 string s = ex.Message + ex.StackTrace;
810 throw new BMXNetException(s);
811 }
812 }
813
814 private void SendString(TcpClient tcpClient, string cSendString)
815 {
816 string sMult = "";
817 SendString(tcpClient, cSendString, sMult);
818 }
819
820 private void SendString(TcpClient tcpClient, string cSendString, string cMult)
821 {
822 int nLen = cSendString.Length;
823 string sLen = nLen.ToString();
824 sLen = sLen.PadLeft(5, '0');
825 cSendString = sLen + cSendString;
826
827 nLen += 15;
828 sLen = nLen.ToString();
829 sLen = sLen.PadLeft(5, '0');
830
831 cSendString = "{BMX}" + sLen + cSendString;
832 cSendString = cSendString + cMult;
833
834 NetworkStream ns = tcpClient.GetStream();
835 byte[] sendBytes = m_Encoding.GetBytes(cSendString);
836 ns.Write(sendBytes,0,sendBytes.Length);
837 if (this.m_bLogging == true)
838 {
839 Log("Sent: " + cSendString, this.m_LogWriter);
840 }
841 return;
842 }
843
844 private string ReceiveString(TcpClient tcpClient)
845 {
846 NetworkStream ns = tcpClient.GetStream();
847
848 int nTimeOut = this.m_nReceiveTimeout;
849 int nCnt = 0;
850 int nTimeElapsed = 0;
851 while (ns.DataAvailable == false)
852 {
853 if (nCnt > 9999)
854 break;
855 if (nTimeElapsed > nTimeOut)
856 break;
857 nCnt++;
858 nTimeElapsed += 50;
859 Thread.Sleep(50);
860 }
861
862 Debug.Assert(ns.DataAvailable == true);
863 if (ns.DataAvailable == false)
864 {
865 this.CloseConnection();
866 throw new Exception("BMXNetLib.ReceiveString timeout. Connection Closed.");
867 //return "";
868 }
869
870 byte[] bReadBuffer = new byte[1024];
871 string sReadBuffer = "";
872 StringBuilder sbAll = new StringBuilder("", 1024);
873 int numberOfBytesRead = 0;
874
875 // Incoming message may be larger than the buffer size.
876
877 bool bFinished = false;
878 int nFind = -1;
879 bool bStarted = false;
880 int lpBuf = 0;
881 string sError = "";
882 string sAppError = "";
883 do
884 {
885 numberOfBytesRead = ns.Read(bReadBuffer, 0, bReadBuffer.Length);
886 if ((numberOfBytesRead == 1)&&(bStarted == false))
887 {
888 Thread.Sleep(15);
889 numberOfBytesRead += ns.Read(bReadBuffer,1, bReadBuffer.Length-1);
890 //Debug.Write("ReceiveString waiting for data...\n");
891 }
892 if (bStarted == false)
893 {
894 //Process error info at beginning of returned string
895 int nErrLen = bReadBuffer[0];
896 int nAppLen = bReadBuffer[bReadBuffer[0]+1];
897 if ((bReadBuffer[2] == 0)&&(bReadBuffer[3] == 0))
898 { //special case: M error trap invoked in SND^XWBTCPC
899 lpBuf += 2;
900 }
901 sError = m_Encoding.GetString(bReadBuffer, lpBuf + 1, nErrLen);
902 if (sError != "")
903 {
904 throw new BMXNetException(sError);
905 }
906 sAppError = m_Encoding.GetString(bReadBuffer, lpBuf+1+nErrLen+1, nAppLen);
907 lpBuf += (nErrLen + nAppLen + 2);
908 numberOfBytesRead -= (nErrLen + nAppLen + 2);
909 bStarted = true;
910 }
911
912 nFind = FindChar(bReadBuffer, (char) 4);
913 if (nFind > -1)
914 bFinished = true;
915 Debug.Assert(numberOfBytesRead > -1);
916 sReadBuffer = m_Encoding.GetString(bReadBuffer, lpBuf, numberOfBytesRead);
917 lpBuf = 0;
918 if (nFind > -1)
919 {
920 sbAll.Append(sReadBuffer, 0, numberOfBytesRead -1);
921 }
922 else
923 {
924 sbAll.Append(sReadBuffer);
925 }
926 }
927 while(bFinished == false);
928 if (this.m_bLogging == true)
929 {
930 Log("Received: " + sbAll.ToString(), this.m_LogWriter);
931 }
932 return sbAll.ToString();
933
934 }
935 private bool SendSecurityRequest(WindowsIdentity winIdentity)
936 {
937 string strReceive = "";
938 string cMSG;
939 string sTest;
940
941 //Build AV Call
942 cMSG = ADEBLDMsg(m_cHDR, "BMX AV CODE", winIdentity.Name);
943 SendString(m_pCommSocket, cMSG);
944
945 strReceive = ReceiveString(m_pCommSocket);
946 sTest = strReceive.Substring(0,3);
947
948
949 char[] cDelim = {(char) 13,(char) 10,(char) 0};
950 string sDelim = new string(cDelim);
951 int nPiece = 1;
952 m_cDUZ = Piece(strReceive, sDelim , nPiece);
953 if ((m_cDUZ == "0")||(m_cDUZ == ""))
954 {
955 nPiece = 7;
956 string sReason = Piece(strReceive, sDelim, nPiece);
957 throw new Exception(sReason);
958 }
959
960 return true;
961 }
962
963 private bool SendSecurityRequest(string sAccess, string sVerify)
964 {
965 string strReceive = "";
966 string cMSG;
967 sAccess = sAccess.ToUpper();
968 sVerify = sVerify.ToUpper();
969
970 //Build AV Call
971 string strAV = sAccess + ";" + sVerify;
972 strAV = ADEEncryp(strAV);
973 cMSG = ADEBLDMsg(m_cHDR, "XUS AV CODE", strAV);
974 SendString(m_pCommSocket, cMSG);
975
976 strReceive = ReceiveString(m_pCommSocket);
977
978 char[] cDelim = {(char) 13,(char) 10,(char) 0};
979 string sDelim = new string(cDelim);
980 int nPiece = 1;
981 m_cDUZ = Piece(strReceive, sDelim , nPiece);
982 if ((m_cDUZ == "0")||(m_cDUZ == ""))
983 {
984 nPiece = 7;
985 string sReason = Piece(strReceive, sDelim, nPiece);
986 throw new Exception(sReason);
987 }
988
989 return true;
990 }
991
992 public void CloseConnection()
993 {
994 if (!m_bConnected)
995 {
996 return;
997 }
998 SendString(m_pCommSocket, "#BYE#");
999 m_pCommSocket.Close();
1000 m_bConnected = false;
1001 m_cServerAddress = "";
1002 // m_cDUZ2 = "";
1003 m_cDUZ = "";
1004 }
1005
1006 public bool Lock(string Variable)
1007 {
1008 return Lock(Variable, "", "");
1009 }
1010
1011 public bool Lock(string Variable, string Increment)
1012 {
1013 return Lock(Variable, Increment, "");
1014 }
1015
1016 /// <summary>
1017 /// Lock a local or global M variable
1018 /// Returns true if lock is obtained during TimeOut seconds
1019 /// Use + to increment, - to decrement lock.
1020 /// </summary>
1021 /// <param name="Variable"></param>
1022 /// <param name="Increment"></param>
1023 /// <param name="TimeOut"></param>
1024 /// <returns></returns>
1025 public bool Lock(string Variable, string Increment, string TimeOut)
1026 {
1027 try
1028 {
1029 string sContext = this.AppContext;
1030 this.AppContext = "BMXRPC";
1031 Variable = Variable.Replace("^","~");
1032 string sRet = "0";
1033 bool bRet = false;
1034 string sParam = Variable + "^" + Increment + "^" + TimeOut;
1035 sRet = TransmitRPC("BMX LOCK", sParam);
1036 bRet = (sRet == "1")?true:false;
1037 this.AppContext = sContext;
1038 return bRet;
1039 }
1040 catch (Exception ex)
1041 {
1042 string sMsg = ex.Message;
1043 return false;
1044 }
1045 }
1046
1047 static ReaderWriterLock m_rwl = new ReaderWriterLock();
1048 private int m_nRWLTimeout = 30000; //30-second default timeout
1049
1050 /// <summary>
1051 /// Returns a reference to the internal ReaderWriterLock member.
1052 /// </summary>
1053 public ReaderWriterLock BMXRWL
1054 {
1055 get
1056 {
1057 return m_rwl;
1058 }
1059 }
1060
1061 /// <summary>
1062 /// Sets and returns the timeout in milliseconds for locking the transmit port.
1063 /// If the transmit port is unavailable an ApplicationException will be thrown.
1064 /// </summary>
1065 public int RWLTimeout
1066 {
1067 get
1068 {
1069 return m_nRWLTimeout;
1070 }
1071 set
1072 {
1073 m_nRWLTimeout = value;
1074 }
1075 }
1076
1077 public string TransmitRPC(string sRPC, string sParam, int nLockTimeOut)
1078 {
1079 try
1080 {
1081 try
1082 {
1083 if (m_bConnected == false)
1084 {
1085 throw new BMXNetException("BMXNetLib.TransmitRPC failed because BMXNetLib is not connected to RPMS.");
1086 }
1087 Debug.Assert(m_cDUZ != "");
1088 Debug.Assert(m_pCommSocket != null);
1089
1090 string sOldAppContext = "";
1091 if (sRPC.StartsWith("BMX")&&(this.m_cAppContext != "BMXRPC"))
1092 {
1093 sOldAppContext = this.m_cAppContext;
1094 this.AppContext = "BMXRPC";
1095 }
1096 string sMult = "";
1097 string sSend = ADEBLDMsg(m_cHDR, sRPC, sParam, ref sMult);
1098 SendString(m_pCommSocket, sSend, sMult);
1099#if DEBUG
1100 DateTime sendTime = DateTime.Now;
1101 Debug.Write("TransmitRPC Sent: " + sSend + "\n");
1102#endif
1103 string strResult = ReceiveString(m_pCommSocket);
1104#if DEBUG
1105 DateTime receiveTime = DateTime.Now;
1106 Debug.Write("TransmitRPC Received: " + strResult + "\n");
1107 TimeSpan executionTime = receiveTime - sendTime;
1108 Debug.Write("Execution Time: " + executionTime.Milliseconds + " ms.\n");
1109#endif
1110 if (sOldAppContext != "")
1111 {
1112 this.AppContext = sOldAppContext;
1113 }
1114 return strResult;
1115 }
1116 catch (Exception ex)
1117 {
1118 if (ex.Message == "Unable to write data to the transport connection.")
1119 {
1120 m_bConnected = false;
1121 }
1122 throw ex;
1123 }
1124 finally
1125 {
1126 }
1127 }
1128 catch (ApplicationException aex)
1129 {
1130 // The writer lock request timed out.
1131 Debug.Write("TransmitRPC writer lock request timed out.\n");
1132 throw aex;
1133 }
1134 catch (Exception OuterEx)
1135 {
1136 throw OuterEx;
1137 }
1138 }
1139
1140 public string TransmitRPC(string sRPC, string sParam)
1141 {
1142 try
1143 {
1144 return TransmitRPC(sRPC, sParam, m_nRWLTimeout);
1145 }
1146 catch (ApplicationException aex)
1147 {
1148 throw aex;
1149 }
1150 catch (Exception ex)
1151 {
1152 throw ex;
1153 }
1154 }
1155
1156 public string GetLoginFacility()
1157 {
1158 try
1159 {
1160 if (m_bConnected == false)
1161 {
1162 throw new BMXNetException("BMXNetLib is not connected to RPMS");
1163 }
1164
1165 if (m_cLoginFacility != "")
1166 {
1167 return m_cLoginFacility;
1168 }
1169
1170 Debug.Assert(m_pCommSocket != null);
1171 Debug.Assert(m_cDUZ != "");
1172 SendString(m_pCommSocket, ADEBLDMsg(m_cHDR, "BMXGetFac", m_cDUZ));
1173 string sFac = ReceiveString(m_pCommSocket);
1174 m_cLoginFacility = sFac;
1175 return sFac;
1176 }
1177 catch (BMXNetException bmxEx)
1178 {
1179 string sMessage = bmxEx.Message + bmxEx.StackTrace;
1180 throw new BMXNetException(sMessage);
1181 }
1182 catch (Exception ex)
1183 {
1184 throw ex;
1185 }
1186 }
1187
1188 #endregion RPX Functions
1189
1190 #region RPX Properties
1191
1192 /// <summary>
1193 /// Set and retrieve the timeout, in milliseconds, to receive a response from the RPMS server.
1194 /// If the retrieve time exceeds the timeout, an exception will be thrown and the connection will be closed.
1195 /// The default is 30 seconds.
1196 /// </summary>
1197 public int ReceiveTimeout
1198 {
1199 get { return m_nReceiveTimeout; }
1200 set { m_nReceiveTimeout = value; }
1201 }
1202
1203 public string WKID
1204 {
1205 get
1206 {
1207 return m_sWKID;
1208 }
1209 set
1210 {
1211 m_sWKID = value;
1212 }
1213 }
1214
1215 public string PRCH
1216 {
1217 get
1218 {
1219 return m_sPRCH;
1220 }
1221 set
1222 {
1223 m_sPRCH = value;
1224 }
1225 }
1226
1227 public string WINH
1228 {
1229 get
1230 {
1231 return m_sWINH;
1232 }
1233 set
1234 {
1235 m_sWINH = value;
1236 }
1237 }
1238
1239 public string WISH
1240 {
1241 get
1242 {
1243 return m_sWISH;
1244 }
1245 set
1246 {
1247 m_sWISH = value;
1248 }
1249 }
1250
1251 /// <summary>
1252 /// Gets/sets the Kernel Application context
1253 /// Throws an exception if unable to set the context.
1254 /// </summary>
1255 public string AppContext
1256 {
1257 get
1258 {
1259 return m_cAppContext;
1260 }
1261 set
1262 {
1263 //Send the changed context to RPMS
1264 if ((m_bConnected == true) && (value != ""))
1265 {
1266 try
1267 {
1268 string sRPC = ADEEncryp(value);
1269 string sAuthentication = TransmitRPC("XWB CREATE CONTEXT", sRPC);
1270
1271 if (BMXNetLib.FindSubString(sAuthentication, "does not have access to option") > -1)
1272 {
1273 throw new BMXNetException(sAuthentication);
1274 }
1275
1276 }
1277 catch (Exception ex)
1278 {
1279 Debug.Write(ex.Message);
1280 throw ex;
1281 }
1282 }
1283 m_cAppContext = value;
1284 }
1285 }
1286
1287 public bool Connected
1288 {
1289 get
1290 {
1291 return m_bConnected;
1292 }
1293 }
1294
1295 public string DUZ
1296 {
1297 get
1298 {
1299 return m_cDUZ;
1300 }
1301 }
1302
1303 public string MServerAddress
1304 {
1305 get
1306 {
1307 return m_cServerAddress;
1308 }
1309 }
1310
1311 public string MServerNamespace
1312 {
1313 get
1314 {
1315 return m_sNameSpace;
1316 }
1317 set
1318 {
1319 m_sNameSpace = value;
1320 }
1321 }
1322
1323 public int MServerPort
1324 {
1325 get
1326 {
1327 return m_nMServerPort;
1328 }
1329 set
1330 {
1331 m_nMServerPort = value;
1332 }
1333 }
1334
1335 public string NameSpace
1336 {
1337 get
1338 {
1339 return m_sNameSpace;
1340 }
1341 set
1342 {
1343 m_sNameSpace = value;
1344 }
1345 }
1346
1347 /// <summary>
1348 /// Gets or Sets the Default Encoder to use
1349 /// </summary>
1350 public Encoding Encoder
1351 {
1352 get
1353 {
1354 return this.m_Encoding;
1355 }
1356 set
1357 {
1358 this.m_Encoding = Encoder;
1359 }
1360 }
1361
1362 #endregion RPX Properties
1363
1364 }
1365}
Note: See TracBrowser for help on using the repository browser.