(1) Smart card reader support, (2) Tag added to User DB table, (3) Graphs : Y-label fixed, two significant digits, ver. 2.18.893
This commit is contained in:
parent
86601e1ba1
commit
875caf0e28
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,6 +4,8 @@ DeviceTest/bin/
|
||||
DeviceTest/obj/
|
||||
Dirichlet.Numerics/bin
|
||||
Dirichlet.Numerics/obj
|
||||
GemCard/bin
|
||||
GemCard/obj
|
||||
GraphLib/bin
|
||||
GraphLib/obj
|
||||
MonitoringDB/bin
|
||||
|
||||
@ -119,6 +119,7 @@
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Units.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Strings.cs.resx" />
|
||||
|
||||
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.18.891.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.891.0")]
|
||||
[assembly: AssemblyVersion("2.18.893.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.893.0")]
|
||||
|
||||
69
Config/Utils.cs
Normal file
69
Config/Utils.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Config
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
public static string SignificantDigitsToFmt(double value, int sigDigits)
|
||||
{
|
||||
if (sigDigits == 5)
|
||||
{
|
||||
if (value >= 9999.5 || value < -9999.5) return "F0";
|
||||
else if (value >= 999.95 || value < -999.95) return "F1";
|
||||
else if (value >= 99.995 || value < -99.995) return "F2";
|
||||
else if (value >= 9.9995 || value < -9.9995) return "F3";
|
||||
else if (value >= 0.99995 || value < -0.99995) return "F4";
|
||||
else if (value >= 0.099995 || value < -0.099995) return "F5";
|
||||
else if (value >= 0.0099995 || value < -0.0099995) return "F6";
|
||||
else if (value >= 0.00099995 || value < -0.00099995) return "F7";
|
||||
else if (value >= 0.000099995 || value < -0.000099995) return "F8";
|
||||
else return "F9";
|
||||
}
|
||||
else if (sigDigits == 4)
|
||||
{
|
||||
if (value >= 999.5 || value < -999.5) return "F0";
|
||||
else if (value >= 99.95 || value < -99.95) return "F1";
|
||||
else if (value >= 9.995 || value < -9.995) return "F2";
|
||||
else if (value >= 0.9995 || value < -0.9995) return "F3";
|
||||
else if (value >= 0.09995 || value < -0.09995) return "F4";
|
||||
else if (value >= 0.009995 || value < -0.009995) return "F5";
|
||||
else if (value >= 0.0009995 || value < -0.0009995) return "F6";
|
||||
else if (value >= 0.00009995 || value < -0.00009995) return "F7";
|
||||
else return "F8";
|
||||
}
|
||||
else if (sigDigits == 3)
|
||||
{
|
||||
if (value >= 99.5 || value < -99.5) return "F0";
|
||||
else if (value >= 9.95 || value < -9.95) return "F1";
|
||||
else if (value >= 0.995 || value < -0.995) return "F2";
|
||||
else if (value >= 0.0995 || value < -0.0995) return "F3";
|
||||
else if (value >= 0.00995 || value < -0.00995) return "F4";
|
||||
else if (value >= 0.000995 || value < -0.000995) return "F5";
|
||||
else if (value >= 0.0000995 || value < -0.0000995) return "F6";
|
||||
else return "F7";
|
||||
}
|
||||
else if (sigDigits == 2)
|
||||
{
|
||||
if (value >= 9.5 || value < -9.5) return "F0";
|
||||
else if (value >= 0.95 || value < -0.95) return "F1";
|
||||
else if (value >= 0.095 || value < -0.095) return "F2";
|
||||
else if (value >= 0.0095 || value < -0.0095) return "F3";
|
||||
else if (value >= 0.00095 || value < -0.00095) return "F4";
|
||||
else if (value >= 0.000095 || value < -0.000095) return "F5";
|
||||
else return "F6";
|
||||
}
|
||||
else /// if (sigDigits == 1)
|
||||
{
|
||||
if (value >= 0.95 || value < -0.95) return "F0";
|
||||
else if (value >= 0.095 || value < -0.095) return "F1";
|
||||
else if (value >= 0.0095 || value < -0.0095) return "F2";
|
||||
else if (value >= 0.00095 || value < -0.00095) return "F3";
|
||||
else if (value >= 0.000095 || value < -0.000095) return "F4";
|
||||
else return "F5";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
GemCard/APDUCommand.cs
Normal file
94
GemCard/APDUCommand.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a command APDU
|
||||
/// </summary>
|
||||
public class APDUCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimun size of an APDU command in bytes
|
||||
/// </summary>
|
||||
public const int APDU_MIN_LENGTH = 4;
|
||||
|
||||
public byte Class; /// Class byte
|
||||
public byte Ins; /// Instruction byte
|
||||
public byte P1; /// Parameter P1 byte
|
||||
public byte P2; /// Parameter P2 byte
|
||||
public byte[] Data; /// Data to send to the card if any, null if no data to send
|
||||
public byte Le; /// Number of data expected, 0 if none
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="bCla">Class byte</param>
|
||||
/// <param name="bIns">Instruction byte</param>
|
||||
/// <param name="bP1">Parameter P1 byte</param>
|
||||
/// <param name="bP2">Parameter P2 byte</param>
|
||||
/// <param name="baData">Data to send to the card if any, null if no data to send</param>
|
||||
/// <param name="bLe">Number of data expected, 0 if none</param>
|
||||
public APDUCommand(byte bCla, byte bIns, byte bP1, byte bP2, byte[] baData, byte bLe)
|
||||
{
|
||||
this.Class = bCla;
|
||||
this.Ins = bIns;
|
||||
this.P1 = bP1;
|
||||
this.P2 = bP2;
|
||||
this.Data = baData;
|
||||
this.Le = bLe;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Update the current APDU with selected parameters
|
||||
/// </summary>
|
||||
/// <param name="apduParam">APDU parameters</param>
|
||||
public void Update(APDUParam apduParam)
|
||||
{
|
||||
if (apduParam.UseData) Data = apduParam.Data;
|
||||
if (apduParam.UseLe) Le = apduParam.Le;
|
||||
if (apduParam.UseP1) P1 = apduParam.P1;
|
||||
if (apduParam.UseP2) P2 = apduParam.P2;
|
||||
if (apduParam.UseChannel) Class += apduParam.Channel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the ToString method to format to a string the APDUCommand object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string strData = null;
|
||||
byte bLc = 0;
|
||||
byte bP3 = Le;
|
||||
|
||||
if (Data != null)
|
||||
{
|
||||
StringBuilder sData = new StringBuilder(Data.Length * 2);
|
||||
for (int nI = 0; nI < Data.Length; nI++)
|
||||
{
|
||||
sData.AppendFormat("{0:X02}", Data[nI]);
|
||||
}
|
||||
|
||||
strData = "Data=" + sData.ToString();
|
||||
bLc = (byte) Data.Length;
|
||||
bP3 = bLc;
|
||||
}
|
||||
|
||||
//string strApdu = string.Format("Class={0:X02} Ins={1:X02} P1={2:X02} P2={3:X02} Le={4:X02} Lc={5:X02} ",
|
||||
//m_bCla, m_bIns, m_bP1, m_bP2, m_bLe, bLc);
|
||||
StringBuilder strApdu = new StringBuilder();
|
||||
|
||||
strApdu.AppendFormat("Class={0:X02} Ins={1:X02} P1={2:X02} P2={3:X02} P3={4:X02} ",
|
||||
Class, Ins, P1, P2, bP3);
|
||||
|
||||
if (Data != null)
|
||||
{
|
||||
strApdu.Append(strData);
|
||||
}
|
||||
|
||||
return strApdu.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
147
GemCard/APDUParam.cs
Normal file
147
GemCard/APDUParam.cs
Normal file
@ -0,0 +1,147 @@
|
||||
using System;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to update a set of parameters of an APDUCommand object
|
||||
/// </summary>
|
||||
public class APDUParam
|
||||
{
|
||||
byte bClass;
|
||||
byte bChannel;
|
||||
byte bP2;
|
||||
byte bP1;
|
||||
|
||||
byte[] baData;
|
||||
short nLe;
|
||||
|
||||
bool fUseP1;
|
||||
bool fUseP2;
|
||||
bool fChannel;
|
||||
bool fData;
|
||||
bool fClass;
|
||||
bool fLe;
|
||||
|
||||
/// <summary>
|
||||
/// Resets the current instance, all flags are set to false
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
bClass = 0;
|
||||
bChannel = 0;
|
||||
bP2 = 0;
|
||||
bP1 = 0;
|
||||
|
||||
baData = null;
|
||||
nLe = -1;
|
||||
|
||||
fUseP1 = false;
|
||||
fUseP2 = false;
|
||||
fChannel = false;
|
||||
fData = false;
|
||||
fClass = false;
|
||||
fLe = false;
|
||||
}
|
||||
|
||||
#region Constructors
|
||||
|
||||
public APDUParam()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor (used for cloning)
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
public APDUParam(APDUParam param)
|
||||
{
|
||||
// Copy field
|
||||
if (param.baData != null)
|
||||
{
|
||||
param.baData.CopyTo(baData, 0);
|
||||
}
|
||||
|
||||
this.bClass = param.bClass;
|
||||
this.bChannel = param.bChannel;
|
||||
this.bP1 = param.bP1;
|
||||
this.bP2 = param.bP2;
|
||||
this.nLe = param.nLe;
|
||||
|
||||
// Copy flags field
|
||||
this.fChannel = param.fChannel;
|
||||
this.fClass = param.fClass;
|
||||
this.fData = param.fData;
|
||||
this.fLe = param.fLe;
|
||||
this.fUseP1 = param.fUseP1;
|
||||
this.fUseP2 = param.fUseP2;
|
||||
}
|
||||
|
||||
public APDUParam(byte bClass, byte bP1, byte bP2, byte[] baData, short nLe)
|
||||
{
|
||||
this.Class = bClass;
|
||||
this.P1 = bP1;
|
||||
this.P2 = bP2;
|
||||
this.Data = baData;
|
||||
this.Le = (byte)nLe;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Clones the current APDUParam instance
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public APDUParam Clone()
|
||||
{
|
||||
return new APDUParam(this);
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public bool UseClass { get { return fClass; } }
|
||||
public bool UseChannel { get { return fChannel; } }
|
||||
public bool UseLe { get { return fLe; } }
|
||||
public bool UseData { get { return fData; } }
|
||||
public bool UseP1 { get { return fUseP1; } }
|
||||
public bool UseP2 { get { return fUseP2; } }
|
||||
|
||||
public byte P1
|
||||
{
|
||||
get { return bP1; }
|
||||
set { bP1 = value; fUseP1 = true; }
|
||||
}
|
||||
|
||||
public byte P2
|
||||
{
|
||||
get { return bP2; }
|
||||
set { bP2 = value; fUseP2 = true; }
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get { return baData; }
|
||||
set { baData = value; fData = true; }
|
||||
}
|
||||
|
||||
public byte Le
|
||||
{
|
||||
get { return (byte)nLe; }
|
||||
set { nLe = value; fLe = true; }
|
||||
}
|
||||
|
||||
public byte Channel
|
||||
{
|
||||
get { return bChannel; }
|
||||
set { bChannel = value; fChannel = true; }
|
||||
}
|
||||
|
||||
public byte Class
|
||||
{
|
||||
get { return bClass; }
|
||||
set { bClass = value; fClass = true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
74
GemCard/APDUResponse.cs
Normal file
74
GemCard/APDUResponse.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents the APDU response sent by the card
|
||||
/// </summary>
|
||||
public class APDUResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Status bytes length
|
||||
/// </summary>
|
||||
public const int SW_LENGTH = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Response data. Contains the data sent by the card minus the 2 status bytes (SW1, SW2)
|
||||
/// null if no data were sent by the card
|
||||
/// </summary>
|
||||
public byte[] Data;
|
||||
public byte SW1;
|
||||
public byte SW2;
|
||||
|
||||
/// <summary>
|
||||
/// Status get property
|
||||
/// </summary>
|
||||
public ushort Status
|
||||
{
|
||||
get { return (ushort)(((short)SW1 << 8) + (short)SW2); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor from the byte data sent back by the card
|
||||
/// </summary>
|
||||
/// <param name="baData">Buffer of data from the card</param>
|
||||
public APDUResponse(byte[] baData)
|
||||
{
|
||||
if (baData.Length > SW_LENGTH)
|
||||
{
|
||||
Data = new byte[baData.Length - SW_LENGTH];
|
||||
|
||||
for (int nI = 0; nI < baData.Length - SW_LENGTH; nI++)
|
||||
{
|
||||
this.Data[nI] = baData[nI];
|
||||
}
|
||||
}
|
||||
|
||||
this.SW1 = baData[baData.Length - 2];
|
||||
this.SW2 = baData[baData.Length - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the ToString method to format to a string the APDUResponse object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
if (Data != null)
|
||||
{
|
||||
StringBuilder sData = new StringBuilder(Data.Length * 2);
|
||||
for (int nI = 0; nI < Data.Length; nI++)
|
||||
{
|
||||
sData.AppendFormat("{0:X02}", Data[nI]);
|
||||
}
|
||||
|
||||
return sData.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
GemCard/AssemblyInfo.cs
Normal file
58
GemCard/AssemblyInfo.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly: AssemblyTitle("")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
// Microsoft .NET Framework documentation for more information on assembly signing.
|
||||
//
|
||||
// Use the attributes below to control which key is used for signing.
|
||||
//
|
||||
// Notes:
|
||||
// (*) If no key is specified, the assembly is not signed.
|
||||
// (*) KeyName refers to a key that has been installed in the Crypto Service
|
||||
// Provider (CSP) on your machine. KeyFile refers to a file which contains
|
||||
// a key.
|
||||
// (*) If the KeyFile and the KeyName values are both specified, the
|
||||
// following processing occurs:
|
||||
// (1) If the KeyName can be found in the CSP, that key is used.
|
||||
// (2) If the KeyName does not exist and the KeyFile does exist, the key
|
||||
// in the KeyFile is installed into the CSP and used.
|
||||
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
|
||||
// When specifying the KeyFile, the location of the KeyFile should be
|
||||
// relative to the project output directory which is
|
||||
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
|
||||
// located in the project directory, you would specify the AssemblyKeyFile
|
||||
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
|
||||
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
|
||||
// documentation for more information on this.
|
||||
//
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile("")]
|
||||
[assembly: AssemblyKeyName("")]
|
||||
162
GemCard/CardBase.cs
Normal file
162
GemCard/CardBase.cs
Normal file
@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Values for AttrId of SCardGetAttrib
|
||||
/// </summary>
|
||||
public class SCARD_ATTR_VALUE
|
||||
{
|
||||
private const uint
|
||||
SCARD_CLASS_COMMUNICATIONS = 2,
|
||||
SCARD_CLASS_PROTOCOL = 3,
|
||||
SCARD_CLASS_MECHANICAL = 6,
|
||||
SCARD_CLASS_VENDOR_DEFINED = 7,
|
||||
SCARD_CLASS_IFD_PROTOCOL = 8,
|
||||
SCARD_CLASS_ICC_STATE = 9,
|
||||
SCARD_CLASS_SYSTEM = 0x7fff;
|
||||
|
||||
private static UInt32 SCardAttrValue(UInt32 attrClass, UInt32 val)
|
||||
{
|
||||
return (attrClass << 16) | val;
|
||||
}
|
||||
|
||||
public static UInt32 CHANNEL_ID { get { return SCardAttrValue(SCARD_CLASS_COMMUNICATIONS, 0x0110); } }
|
||||
|
||||
public static UInt32 CHARACTERISTICS { get { return SCardAttrValue(SCARD_CLASS_MECHANICAL, 0x0150); } }
|
||||
|
||||
public static UInt32 CURRENT_PROTOCOL_TYPE { get { return SCardAttrValue(SCARD_CLASS_IFD_PROTOCOL, 0x0201); } }
|
||||
|
||||
public static UInt32 DEVICE_UNIT { get { return SCardAttrValue(SCARD_CLASS_SYSTEM, 0x0001); } }
|
||||
public static UInt32 DEVICE_FRIENDLY_NAME { get { return SCardAttrValue(SCARD_CLASS_SYSTEM, 0x0003); } }
|
||||
public UInt32 DEVICE_SYSTEM_NAME { get { return SCardAttrValue(SCARD_CLASS_SYSTEM, 0x0004); } }
|
||||
|
||||
public static UInt32 ICC_PRESENCE { get { return SCardAttrValue(SCARD_CLASS_ICC_STATE, 0x0300); } }
|
||||
public static UInt32 ICC_INTERFACE_STATUS { get { return SCardAttrValue(SCARD_CLASS_ICC_STATE, 0x0301); } }
|
||||
public static UInt32 ATR_STRING { get { return SCardAttrValue(SCARD_CLASS_ICC_STATE, 0x0303); } }
|
||||
public static UInt32 ICC_TYPE_PER_ATR { get { return SCardAttrValue(SCARD_CLASS_ICC_STATE, 0x0304); } }
|
||||
|
||||
public static UInt32 PROTOCOL_TYPES { get { return SCardAttrValue(SCARD_CLASS_PROTOCOL, 0x0120); } }
|
||||
|
||||
public static UInt32 VENDOR_NAME { get { return SCardAttrValue(SCARD_CLASS_VENDOR_DEFINED, 0x0100); } }
|
||||
public static UInt32 VENDOR_IFD_TYPE { get { return SCardAttrValue(SCARD_CLASS_VENDOR_DEFINED, 0x0101); } }
|
||||
public static UInt32 VENDOR_IFD_VERSION { get { return SCardAttrValue(SCARD_CLASS_VENDOR_DEFINED, 0x0102); } }
|
||||
public static UInt32 VENDOR_IFD_SERIAL_NO { get { return SCardAttrValue(SCARD_CLASS_VENDOR_DEFINED, 0x0103); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract class that adds a basic event management to the ICard interface.
|
||||
/// </summary>
|
||||
abstract public class CardBase : ICard
|
||||
{
|
||||
protected const uint INFINITE = 0xFFFFFFFF;
|
||||
protected const uint WAIT_TIME = 250;
|
||||
|
||||
protected bool m_bRunCardDetection = true;
|
||||
protected Thread m_thread = null;
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the card insertion
|
||||
/// </summary>
|
||||
public event EventHandler<CardInsertedEventArgs> OnCardInserted = null;
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for the card removal
|
||||
/// </summary>
|
||||
public event EventHandler<CardRemovedEventArgs> OnCardRemoved = null;
|
||||
|
||||
~CardBase()
|
||||
{
|
||||
// Stop any eventual card detection thread
|
||||
StopCardEvents();
|
||||
}
|
||||
|
||||
#region Abstract method that implement the ICard interface
|
||||
abstract public string[] ListReaders();
|
||||
abstract public void Connect(string Reader, SHARE ShareMode, PROTOCOL PreferredProtocols);
|
||||
abstract public void Disconnect(DISCONNECT Disposition);
|
||||
abstract public APDUResponse Transmit(APDUCommand ApduCmd);
|
||||
abstract public void BeginTransaction();
|
||||
abstract public void EndTransaction(DISCONNECT Disposition);
|
||||
abstract public byte[] GetAttribute(UInt32 AttribId);
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// This method should start a thread that checks for card insertion or removal
|
||||
/// </summary>
|
||||
/// <param name="Reader"></param>
|
||||
public void StartCardEvents(string Reader)
|
||||
{
|
||||
if (m_thread == null)
|
||||
{
|
||||
m_bRunCardDetection = true;
|
||||
|
||||
m_thread = new Thread(new ParameterizedThreadStart(RunCardDetection));
|
||||
m_thread.Start(Reader);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the card events thread
|
||||
/// </summary>
|
||||
public void StopCardEvents()
|
||||
{
|
||||
if (m_thread != null)
|
||||
{
|
||||
int
|
||||
nTimeOut = 10,
|
||||
nCount = 0;
|
||||
bool m_bStop = false;
|
||||
m_bRunCardDetection = false;
|
||||
|
||||
do
|
||||
{
|
||||
if (nCount > nTimeOut)
|
||||
{
|
||||
m_thread.Abort();
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_thread.ThreadState == ThreadState.Aborted)
|
||||
m_bStop = true;
|
||||
|
||||
if (m_thread.ThreadState == ThreadState.Stopped)
|
||||
m_bStop = true;
|
||||
|
||||
Thread.Sleep(200);
|
||||
++nCount; // Manage time out
|
||||
}
|
||||
while (!m_bStop);
|
||||
|
||||
m_thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function must implement a card detection mechanism.
|
||||
///
|
||||
/// When card insertion is detected, it must call the method CardInserted()
|
||||
/// When card removal is detected, it must call the method CardRemoved()
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Reader">Name of the reader to scan for card event</param>
|
||||
abstract protected void RunCardDetection(object Reader);
|
||||
|
||||
#region Event methods
|
||||
|
||||
protected void CardInserted(object sender, CardInsertedEventArgs args)
|
||||
{
|
||||
if (OnCardInserted != null) OnCardInserted(sender, args);
|
||||
}
|
||||
|
||||
protected void CardRemoved(object sender, CardRemovedEventArgs args)
|
||||
{
|
||||
if (OnCardRemoved != null) OnCardRemoved(sender, args);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
173
GemCard/CardCOM.cs
Normal file
173
GemCard/CardCOM.cs
Normal file
@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using SCARDSSPLib;
|
||||
using GemCardExLib;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the ICard interface using the SCard COM objects from Microsoft and SCardDatabaseEx object
|
||||
/// for the ListReaders function.
|
||||
/// </summary>
|
||||
public class CardCOM : CardBase
|
||||
{
|
||||
private ISCard m_itfCard = null;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public CardCOM()
|
||||
{
|
||||
// Create the SCard object
|
||||
m_itfCard = new CSCardClass();
|
||||
}
|
||||
|
||||
#region ICard Members
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardListReaders(SCARDCONTEXT hContext,
|
||||
/// LPCTSTR mszGroups,
|
||||
/// LPTSTR mszReaders,
|
||||
/// LPDWORD pcchReaders
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <returns>A string array of the readers</returns>
|
||||
public override string[] ListReaders()
|
||||
{
|
||||
ISCardDatabaseEx itfCardBase = new SCardDatabaseEx();
|
||||
|
||||
return (string[]) itfCardBase.ListReaders();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardConnect(
|
||||
/// IN SCARDCONTEXT hContext,
|
||||
/// IN LPCTSTR szReader,
|
||||
/// IN DWORD dwShareMode,
|
||||
/// IN DWORD dwPreferredProtocols,
|
||||
/// OUT LPSCARDHANDLE phCard,
|
||||
/// OUT LPDWORD pdwActiveProtocol
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Reader"></param>
|
||||
/// <param name="ShareMode"></param>
|
||||
/// <param name="PreferredProtocols"></param>
|
||||
public override void Connect(string Reader, SHARE ShareMode, PROTOCOL PreferredProtocols)
|
||||
{
|
||||
// Calls AttachReader to connect to the card
|
||||
m_itfCard.AttachByReader(Reader, (SCARD_SHARE_MODES) ShareMode, (SCARD_PROTOCOLS) PreferredProtocols);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardDisconnect(
|
||||
/// IN SCARDHANDLE hCard,
|
||||
/// IN DWORD dwDisposition
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Disposition"></param>
|
||||
public override void Disconnect(DISCONNECT Disposition)
|
||||
{
|
||||
// Off the connection with the card
|
||||
m_itfCard.Detach((SCARD_DISPOSITIONS) Disposition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardTransmit(
|
||||
/// SCARDHANDLE hCard,
|
||||
/// LPCSCARD_I0_REQUEST pioSendPci,
|
||||
/// LPCBYTE pbSendBuffer,
|
||||
/// DWORD cbSendLength,
|
||||
/// LPSCARD_IO_REQUEST pioRecvPci,
|
||||
/// LPBYTE pbRecvBuffer,
|
||||
/// LPDWORD pcbRecvLength
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param>
|
||||
/// <returns>An APDUResponse object with the response from the card</returns>
|
||||
public override APDUResponse Transmit(APDUCommand ApduCmd)
|
||||
{
|
||||
CSCardCmd itfCmd = new CSCardCmdClass();
|
||||
CByteBuffer itfData = new CByteBufferClass();
|
||||
int nLe = ApduCmd.Le;
|
||||
|
||||
if (ApduCmd.Data == null)
|
||||
{
|
||||
itfData.SetSize(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int nWrite = 0;
|
||||
|
||||
itfData.SetSize(ApduCmd.Data.Length);
|
||||
itfData.Write(ref ApduCmd.Data[0], ApduCmd.Data.Length, ref nWrite);
|
||||
}
|
||||
|
||||
// Build the APDU command
|
||||
itfCmd.BuildCmd(ApduCmd.Class, ApduCmd.Ins, ApduCmd.P1, ApduCmd.P2, itfData, ref nLe);
|
||||
|
||||
// Send the command
|
||||
m_itfCard.Transaction(ref itfCmd);
|
||||
|
||||
// Analyse the response
|
||||
int nRead = 0;
|
||||
byte[] pbResp = new byte[itfCmd.ApduReplyLength];
|
||||
|
||||
itfCmd.ApduReply.Read(ref pbResp[0], itfCmd.ApduReplyLength, ref nRead);
|
||||
|
||||
return new APDUResponse(pbResp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PSCS function
|
||||
/// LONG SCardBeginTransaction(
|
||||
/// SCARDHANDLE hCard
|
||||
// );
|
||||
/// This function is not supported in the COM implementation
|
||||
/// </summary>
|
||||
public override void BeginTransaction()
|
||||
{
|
||||
throw new NotImplementedException("BeginTransaction is not supported in the COM implementation");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardEndTransaction(
|
||||
/// SCARDHANDLE hCard,
|
||||
/// DWORD dwDisposition
|
||||
/// );
|
||||
/// This function is not supported in the COM implementation
|
||||
/// </summary>
|
||||
/// <param name="Disposition">A value from DISCONNECT enum</param>
|
||||
public override void EndTransaction(DISCONNECT Disposition)
|
||||
{
|
||||
throw new NotImplementedException("EndTransaction is not supported in the COM implementation");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the attributes of the card
|
||||
/// </summary>
|
||||
/// <param name="AttribId">Identifier for the Attribute to get</param>
|
||||
/// <returns>Attribute content</returns>
|
||||
public override byte[] GetAttribute(UInt32 AttribId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// This function must implement a card detection mechanism.
|
||||
///
|
||||
/// When card insertion is detected, it must call the method CardInserted()
|
||||
/// When card removal is detected, it must call the method CardRemoved()
|
||||
///
|
||||
/// </summary>
|
||||
protected override void RunCardDetection(object Reader)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
9
GemCard/CardInsertedEventArgs.cs
Normal file
9
GemCard/CardInsertedEventArgs.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
public class CardInsertedEventArgs : EventArgs
|
||||
{
|
||||
public CardInsertedEventArgs() { }
|
||||
}
|
||||
}
|
||||
620
GemCard/CardNative.cs
Normal file
620
GemCard/CardNative.cs
Normal file
@ -0,0 +1,620 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// CARD_STATE enumeration, used by the PC/SC function SCardGetStatusChanged
|
||||
/// </summary>
|
||||
enum CARD_STATE
|
||||
{
|
||||
UNAWARE = 0x00000000,
|
||||
IGNORE = 0x00000001,
|
||||
CHANGED = 0x00000002,
|
||||
UNKNOWN = 0x00000004,
|
||||
UNAVAILABLE = 0x00000008,
|
||||
EMPTY = 0x00000010,
|
||||
PRESENT = 0x00000020,
|
||||
ATRMATCH = 0x00000040,
|
||||
EXCLUSIVE = 0x00000080,
|
||||
INUSE = 0x00000100,
|
||||
MUTE = 0x00000200,
|
||||
UNPOWERED = 0x00000400
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the SCARD_IO_STRUCTURE
|
||||
///
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SCard_IO_Request
|
||||
{
|
||||
public UInt32 m_dwProtocol;
|
||||
public UInt32 m_cbPciLength;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wraps theSCARD_READERSTATE structure of PC/SC
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct SCard_ReaderState
|
||||
{
|
||||
public string m_szReader;
|
||||
public IntPtr m_pvUserData;
|
||||
public UInt32 m_dwCurrentState;
|
||||
public UInt32 m_dwEventState;
|
||||
public UInt32 m_cbAtr;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
|
||||
public byte[] m_rgbAtr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of ICard using native (P/Invoke) interoperability for PC/SC
|
||||
/// </summary>
|
||||
public class CardNative : CardBase
|
||||
{
|
||||
private UInt32 m_hContext = 0;
|
||||
private UInt32 m_hCard = 0;
|
||||
private UInt32 m_nProtocol = (uint) PROTOCOL.T0;
|
||||
private int m_nLastError = 0;
|
||||
|
||||
#region PCSC_FUNCTIONS
|
||||
/// <summary>
|
||||
/// Native SCardGetStatusChanged from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hContext"></param>
|
||||
/// <param name="dwTimeout"></param>
|
||||
/// <param name="rgReaderStates"></param>
|
||||
/// <param name="cReaders"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError = true)]
|
||||
internal static extern int SCardGetStatusChange(UInt32 hContext,
|
||||
UInt32 dwTimeout,
|
||||
[In,Out] SCard_ReaderState[] rgReaderStates,
|
||||
UInt32 cReaders);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardListReaders function from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hContext"></param>
|
||||
/// <param name="mszGroups"></param>
|
||||
/// <param name="mszReaders"></param>
|
||||
/// <param name="pcchReaders"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError=true)]
|
||||
internal static extern int SCardListReaders(UInt32 hContext,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string mszGroups,
|
||||
IntPtr mszReaders,
|
||||
out UInt32 pcchReaders);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardEstablishContext function from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="dwScope"></param>
|
||||
/// <param name="pvReserved1"></param>
|
||||
/// <param name="pvReserved2"></param>
|
||||
/// <param name="phContext"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError=true)]
|
||||
internal static extern int SCardEstablishContext(UInt32 dwScope,
|
||||
IntPtr pvReserved1,
|
||||
IntPtr pvReserved2,
|
||||
IntPtr phContext);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardReleaseContext function from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hContext"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError=true)]
|
||||
internal static extern int SCardReleaseContext(UInt32 hContext);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardConnect function from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hContext"></param>
|
||||
/// <param name="szReader"></param>
|
||||
/// <param name="dwShareMode"></param>
|
||||
/// <param name="dwPreferredProtocols"></param>
|
||||
/// <param name="phCard"></param>
|
||||
/// <param name="pdwActiveProtocol"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError=true, CharSet=CharSet.Auto)]
|
||||
internal static extern int SCardConnect(UInt32 hContext,
|
||||
[MarshalAs(UnmanagedType.LPTStr)] string szReader,
|
||||
UInt32 dwShareMode,
|
||||
UInt32 dwPreferredProtocols,
|
||||
IntPtr phCard,
|
||||
IntPtr pdwActiveProtocol);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardDisconnect function from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hCard"></param>
|
||||
/// <param name="dwDisposition"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError=true)]
|
||||
internal static extern int SCardDisconnect(UInt32 hCard,
|
||||
UInt32 dwDisposition);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardTransmit function from winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hCard"></param>
|
||||
/// <param name="pioSendPci"></param>
|
||||
/// <param name="pbSendBuffer"></param>
|
||||
/// <param name="cbSendLength"></param>
|
||||
/// <param name="pioRecvPci"></param>
|
||||
/// <param name="pbRecvBuffer"></param>
|
||||
/// <param name="pcbRecvLength"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError=true)]
|
||||
internal static extern int SCardTransmit(UInt32 hCard,
|
||||
[In] ref SCard_IO_Request pioSendPci,
|
||||
byte[] pbSendBuffer,
|
||||
UInt32 cbSendLength,
|
||||
IntPtr pioRecvPci,
|
||||
[Out] byte[] pbRecvBuffer,
|
||||
out UInt32 pcbRecvLength
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardBeginTransaction function of winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hContext"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError = true)]
|
||||
internal static extern int SCardBeginTransaction(UInt32 hContext);
|
||||
|
||||
/// <summary>
|
||||
/// Native SCardEndTransaction function of winscard.dll
|
||||
/// </summary>
|
||||
/// <param name="hContext"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("winscard.dll", SetLastError = true)]
|
||||
internal static extern int SCardEndTransaction(UInt32 hContext, UInt32 dwDisposition);
|
||||
|
||||
[DllImport("winscard.dll", SetLastError = true)]
|
||||
internal static extern int SCardGetAttrib(UInt32 hCard,
|
||||
UInt32 dwAttribId,
|
||||
[Out] byte[] pbAttr,
|
||||
out UInt32 pcbAttrLen);
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
public CardNative()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Object destruction
|
||||
/// </summary>
|
||||
~CardNative()
|
||||
{
|
||||
Disconnect(DISCONNECT.Unpower);
|
||||
|
||||
ReleaseContext();
|
||||
}
|
||||
|
||||
#region ICard Members
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardListReaders(SCARDCONTEXT hContext,
|
||||
/// LPCTSTR mszGroups,
|
||||
/// LPTSTR mszReaders,
|
||||
/// LPDWORD pcchReaders
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <returns>A string array of the readers</returns>
|
||||
public override string[] ListReaders()
|
||||
{
|
||||
EstablishContext(SCOPE.User);
|
||||
|
||||
string[] sListReaders = null;
|
||||
UInt32 pchReaders = 0;
|
||||
IntPtr szListReaders = IntPtr.Zero;
|
||||
|
||||
m_nLastError = SCardListReaders(m_hContext, null, szListReaders, out pchReaders);
|
||||
if (m_nLastError == 0)
|
||||
{
|
||||
szListReaders = Marshal.AllocHGlobal((int) pchReaders);
|
||||
m_nLastError = SCardListReaders(m_hContext, null, szListReaders, out pchReaders);
|
||||
if (m_nLastError == 0)
|
||||
{
|
||||
char[] caReadersData = new char[pchReaders];
|
||||
int nbReaders = 0;
|
||||
for (int nI = 0; nI < pchReaders; nI++)
|
||||
{
|
||||
caReadersData[nI] = (char) Marshal.ReadByte(szListReaders, nI);
|
||||
|
||||
if (caReadersData[nI] == 0)
|
||||
nbReaders++;
|
||||
}
|
||||
|
||||
// Remove last 0
|
||||
--nbReaders;
|
||||
|
||||
if (nbReaders != 0)
|
||||
{
|
||||
sListReaders = new string[nbReaders];
|
||||
char[] caReader = new char[pchReaders];
|
||||
int nIdx = 0;
|
||||
int nIdy = 0;
|
||||
int nIdz = 0;
|
||||
// Get the nJ string from the multi-string
|
||||
|
||||
while(nIdx < pchReaders - 1)
|
||||
{
|
||||
caReader[nIdy] = caReadersData[nIdx];
|
||||
if (caReader[nIdy] == 0)
|
||||
{
|
||||
sListReaders[nIdz] = new string(caReader, 0, nIdy);
|
||||
++nIdz;
|
||||
nIdy = 0;
|
||||
caReader = new char[pchReaders];
|
||||
}
|
||||
else
|
||||
++nIdy;
|
||||
|
||||
++nIdx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(szListReaders);
|
||||
}
|
||||
|
||||
ReleaseContext();
|
||||
|
||||
return sListReaders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardEstablishContext(
|
||||
/// IN DWORD dwScope,
|
||||
/// IN LPCVOID pvReserved1,
|
||||
/// IN LPCVOID pvReserved2,
|
||||
/// OUT LPSCARDCONTEXT phContext
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Scope"></param>
|
||||
public void EstablishContext(SCOPE Scope)
|
||||
{
|
||||
IntPtr hContext = Marshal.AllocHGlobal(Marshal.SizeOf(m_hContext));
|
||||
|
||||
m_nLastError = SCardEstablishContext((uint) Scope, IntPtr.Zero, IntPtr.Zero, hContext);
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardEstablishContext error: " + m_nLastError;
|
||||
|
||||
Marshal.FreeHGlobal(hContext);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
m_hContext = (uint) Marshal.ReadInt32(hContext);
|
||||
|
||||
Marshal.FreeHGlobal(hContext);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardReleaseContext(
|
||||
/// IN SCARDCONTEXT hContext
|
||||
/// );
|
||||
/// </summary>
|
||||
public void ReleaseContext()
|
||||
{
|
||||
if (m_hContext != 0)
|
||||
{
|
||||
m_nLastError = SCardReleaseContext(m_hContext);
|
||||
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardReleaseContext error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
m_hContext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardConnect(
|
||||
/// IN SCARDCONTEXT hContext,
|
||||
/// IN LPCTSTR szReader,
|
||||
/// IN DWORD dwShareMode,
|
||||
/// IN DWORD dwPreferredProtocols,
|
||||
/// OUT LPSCARDHANDLE phCard,
|
||||
/// OUT LPDWORD pdwActiveProtocol
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Reader"></param>
|
||||
/// <param name="ShareMode"></param>
|
||||
/// <param name="PreferredProtocols"></param>
|
||||
public override void Connect(string Reader, SHARE ShareMode, PROTOCOL PreferredProtocols)
|
||||
{
|
||||
EstablishContext(SCOPE.User);
|
||||
|
||||
IntPtr hCard = Marshal.AllocHGlobal(Marshal.SizeOf(m_hCard));
|
||||
IntPtr pProtocol = Marshal.AllocHGlobal(Marshal.SizeOf(m_nProtocol));
|
||||
|
||||
m_nLastError = SCardConnect(m_hContext,
|
||||
Reader,
|
||||
(uint) ShareMode,
|
||||
(uint) PreferredProtocols,
|
||||
hCard,
|
||||
pProtocol);
|
||||
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardConnect error: " + m_nLastError;
|
||||
|
||||
Marshal.FreeHGlobal(hCard);
|
||||
Marshal.FreeHGlobal(pProtocol);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
m_hCard = (uint) Marshal.ReadInt32(hCard);
|
||||
m_nProtocol = (uint) Marshal.ReadInt32(pProtocol);
|
||||
|
||||
Marshal.FreeHGlobal(hCard);
|
||||
Marshal.FreeHGlobal(pProtocol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardDisconnect(
|
||||
/// IN SCARDHANDLE hCard,
|
||||
/// IN DWORD dwDisposition
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Disposition"></param>
|
||||
public override void Disconnect(DISCONNECT Disposition)
|
||||
{
|
||||
if (m_hCard != 0)
|
||||
{
|
||||
m_nLastError = SCardDisconnect(m_hCard, (uint) Disposition);
|
||||
m_hCard = 0;
|
||||
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardDisconnect error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
ReleaseContext();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardTransmit(
|
||||
/// SCARDHANDLE hCard,
|
||||
/// LPCSCARD_I0_REQUEST pioSendPci,
|
||||
/// LPCBYTE pbSendBuffer,
|
||||
/// DWORD cbSendLength,
|
||||
/// LPSCARD_IO_REQUEST pioRecvPci,
|
||||
/// LPBYTE pbRecvBuffer,
|
||||
/// LPDWORD pcbRecvLength
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param>
|
||||
/// <returns>An APDUResponse object with the response from the card</returns>
|
||||
public override APDUResponse Transmit(APDUCommand ApduCmd)
|
||||
{
|
||||
uint RecvLength = (uint) (ApduCmd.Le + APDUResponse.SW_LENGTH);
|
||||
byte[] ApduBuffer = null;
|
||||
byte[] ApduResponse = new byte[ApduCmd.Le + APDUResponse.SW_LENGTH];
|
||||
SCard_IO_Request ioRequest = new SCard_IO_Request();
|
||||
ioRequest.m_dwProtocol = m_nProtocol;
|
||||
ioRequest.m_cbPciLength = 8;
|
||||
|
||||
// Build the command APDU
|
||||
if (ApduCmd.Data == null)
|
||||
{
|
||||
ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + ((ApduCmd.Le != 0) ? 1 : 0)];
|
||||
|
||||
if (ApduCmd.Le != 0)
|
||||
ApduBuffer[4] = (byte) ApduCmd.Le;
|
||||
}
|
||||
else
|
||||
{
|
||||
ApduBuffer = new byte[APDUCommand.APDU_MIN_LENGTH + 1 + ApduCmd.Data.Length];
|
||||
|
||||
for (int nI = 0; nI < ApduCmd.Data.Length; nI++)
|
||||
ApduBuffer[APDUCommand.APDU_MIN_LENGTH + 1 + nI] = ApduCmd.Data[nI];
|
||||
|
||||
ApduBuffer[APDUCommand.APDU_MIN_LENGTH] = (byte) ApduCmd.Data.Length;
|
||||
}
|
||||
|
||||
ApduBuffer[0] = ApduCmd.Class;
|
||||
ApduBuffer[1] = ApduCmd.Ins;
|
||||
ApduBuffer[2] = ApduCmd.P1;
|
||||
ApduBuffer[3] = ApduCmd.P2;
|
||||
|
||||
m_nLastError = SCardTransmit(m_hCard, ref ioRequest, ApduBuffer, (uint) ApduBuffer.Length, IntPtr.Zero, ApduResponse, out RecvLength);
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardTransmit error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
byte[] ApduData = new byte[RecvLength];
|
||||
|
||||
for (int nI = 0; nI < RecvLength; nI++)
|
||||
ApduData[nI] = ApduResponse[nI];
|
||||
|
||||
return new APDUResponse(ApduData);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PSCS function
|
||||
/// LONG SCardBeginTransaction(
|
||||
/// SCARDHANDLE hCard
|
||||
// );
|
||||
/// </summary>
|
||||
public override void BeginTransaction()
|
||||
{
|
||||
if (m_hCard != 0)
|
||||
{
|
||||
m_nLastError = SCardBeginTransaction(m_hCard);
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardBeginTransaction error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardEndTransaction(
|
||||
/// SCARDHANDLE hCard,
|
||||
/// DWORD dwDisposition
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Disposition">A value from DISCONNECT enum</param>
|
||||
public override void EndTransaction(DISCONNECT Disposition)
|
||||
{
|
||||
if (m_hCard != 0)
|
||||
{
|
||||
m_nLastError = SCardEndTransaction(m_hCard, (UInt32)Disposition);
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardEndTransaction error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the attributes of the card
|
||||
/// </summary>
|
||||
/// <param name="AttribId">Identifier for the Attribute to get</param>
|
||||
/// <returns>Attribute content</returns>
|
||||
public override byte[] GetAttribute(UInt32 AttribId)
|
||||
{
|
||||
byte[] attr = null;
|
||||
UInt32 attrLen = 0;
|
||||
|
||||
m_nLastError = SCardGetAttrib(m_hCard, AttribId, attr, out attrLen);
|
||||
if (m_nLastError == 0)
|
||||
{
|
||||
if (attrLen != 0)
|
||||
{
|
||||
attr = new byte[attrLen];
|
||||
m_nLastError = SCardGetAttrib(m_hCard, AttribId, attr, out attrLen);
|
||||
if (m_nLastError != 0)
|
||||
{
|
||||
string msg = "SCardGetAttr error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string msg = "SCardGetAttr error: " + m_nLastError;
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// This function must implement a card detection mechanism.
|
||||
///
|
||||
/// When card insertion is detected, it must call the method CardInserted()
|
||||
/// When card removal is detected, it must call the method CardRemoved()
|
||||
///
|
||||
/// </summary>
|
||||
protected override void RunCardDetection(object Reader)
|
||||
{
|
||||
bool bFirstLoop = true;
|
||||
UInt32 hContext = 0; // Local context
|
||||
IntPtr phContext;
|
||||
|
||||
phContext = Marshal.AllocHGlobal(Marshal.SizeOf(hContext));
|
||||
|
||||
if (SCardEstablishContext((uint) SCOPE.User, IntPtr.Zero, IntPtr.Zero, phContext) == 0)
|
||||
{
|
||||
hContext = (uint)Marshal.ReadInt32(phContext);
|
||||
Marshal.FreeHGlobal(phContext);
|
||||
|
||||
UInt32 nbReaders = 1;
|
||||
SCard_ReaderState[] readerState = new SCard_ReaderState[nbReaders];
|
||||
|
||||
readerState[0].m_dwCurrentState = (UInt32) CARD_STATE.UNAWARE;
|
||||
readerState[0].m_szReader = (string)Reader;
|
||||
|
||||
UInt32 eventState;
|
||||
UInt32 currentState = readerState[0].m_dwCurrentState;
|
||||
|
||||
// Card detection loop
|
||||
do
|
||||
{
|
||||
if (SCardGetStatusChange(hContext, WAIT_TIME
|
||||
, readerState, nbReaders) == 0)
|
||||
{
|
||||
eventState = readerState[0].m_dwEventState;
|
||||
currentState = readerState[0].m_dwCurrentState;
|
||||
|
||||
// Check state
|
||||
if (((eventState & (uint) CARD_STATE.CHANGED) == (uint) CARD_STATE.CHANGED) && !bFirstLoop)
|
||||
{
|
||||
// State has changed
|
||||
if ((eventState & (uint) CARD_STATE.EMPTY) == (uint) CARD_STATE.EMPTY)
|
||||
{
|
||||
// There is no card, card has been removed -> Fire CardRemoved event
|
||||
CardRemoved(this, new CardRemovedEventArgs());
|
||||
}
|
||||
|
||||
if (((eventState & (uint)CARD_STATE.PRESENT) == (uint)CARD_STATE.PRESENT) &&
|
||||
((eventState & (uint) CARD_STATE.PRESENT) != (currentState & (uint) CARD_STATE.PRESENT)))
|
||||
{
|
||||
// There is a card in the reader -> Fire CardInserted event
|
||||
CardInserted(this, new CardInsertedEventArgs());
|
||||
}
|
||||
|
||||
if ((eventState & (uint) CARD_STATE.ATRMATCH) == (uint) CARD_STATE.ATRMATCH)
|
||||
{
|
||||
// There is a card in the reader and it matches the ATR we were expecting-> Fire CardInserted event
|
||||
CardInserted(this, new CardInsertedEventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
// The current stateis now the event state
|
||||
readerState[0].m_dwCurrentState = eventState;
|
||||
|
||||
bFirstLoop = false;
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
if (m_bRunCardDetection == false)
|
||||
break;
|
||||
}
|
||||
while (true); // Exit on request
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.FreeHGlobal(phContext);
|
||||
throw new Exception("PC/SC error");
|
||||
}
|
||||
|
||||
SCardReleaseContext(hContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
9
GemCard/CardRemovedEventArgs.cs
Normal file
9
GemCard/CardRemovedEventArgs.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
public class CardRemovedEventArgs : EventArgs
|
||||
{
|
||||
public CardRemovedEventArgs() { }
|
||||
}
|
||||
}
|
||||
194
GemCard/GemCard.csproj
Normal file
194
GemCard/GemCard.csproj
Normal file
@ -0,0 +1,194 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>GemCard</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>GemCard</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
|
||||
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
<COMReference Include="GemCardExLib">
|
||||
<Guid>{F1FF634B-BEDF-461C-A409-5B88E05F5117}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
</COMReference>
|
||||
<COMReference Include="SCARDSSPLib">
|
||||
<Guid>{82C38704-19F1-11D3-A11F-00C04F79F800}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
</COMReference>
|
||||
<COMReference Include="stdole">
|
||||
<Guid>{00020430-0000-0000-C000-000000000046}</Guid>
|
||||
<VersionMajor>2</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="APDUCommand.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="APDUParam.cs" />
|
||||
<Compile Include="APDUResponse.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="CardBase.cs" />
|
||||
<Compile Include="CardInsertedEventArgs.cs" />
|
||||
<Compile Include="CardNative.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CardRemovedEventArgs.cs" />
|
||||
<Compile Include="ICard.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SmartCardException.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
70
GemCard/GemCard.csproj.user
Normal file
70
GemCard/GemCard.csproj.user
Normal file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<LastOpenVersion>8.0.50215</LastOpenVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ReferencePath>
|
||||
</ReferencePath>
|
||||
<CopyProjectDestinationFolder>
|
||||
</CopyProjectDestinationFolder>
|
||||
<CopyProjectUncPath>
|
||||
</CopyProjectUncPath>
|
||||
<CopyProjectOption>0</CopyProjectOption>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
<ProjectTrust>0</ProjectTrust>
|
||||
<PublishUrlHistory />
|
||||
<InstallUrlHistory />
|
||||
<SupportUrlHistory />
|
||||
<UpdateUrlHistory />
|
||||
<BootstrapperUrlHistory />
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>en-US</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<EnableASPDebugging>false</EnableASPDebugging>
|
||||
<EnableASPXDebugging>false</EnableASPXDebugging>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<EnableSQLServerDebugging>false</EnableSQLServerDebugging>
|
||||
<RemoteDebugEnabled>false</RemoteDebugEnabled>
|
||||
<RemoteDebugMachine>
|
||||
</RemoteDebugMachine>
|
||||
<StartAction>Project</StartAction>
|
||||
<StartArguments>
|
||||
</StartArguments>
|
||||
<StartPage>
|
||||
</StartPage>
|
||||
<StartProgram>
|
||||
</StartProgram>
|
||||
<StartURL>
|
||||
</StartURL>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartWithIE>false</StartWithIE>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<StartWithIE>true</StartWithIE>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
149
GemCard/ICard.cs
Normal file
149
GemCard/ICard.cs
Normal file
@ -0,0 +1,149 @@
|
||||
using System;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface gives access to the basic card functions. It must be implemented by a class.
|
||||
/// </summary>
|
||||
public interface ICard
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps the PCSC funciton
|
||||
/// LONG SCardListReaders(SCARDCONTEXT hContext,
|
||||
/// LPCTSTR mszGroups,
|
||||
/// LPTSTR mszReaders,
|
||||
/// LPDWORD pcchReaders
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <returns>A string array of the readers</returns>
|
||||
string[] ListReaders();
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardConnect(
|
||||
/// IN SCARDCONTEXT hContext,
|
||||
/// IN LPCTSTR szReader,
|
||||
/// IN DWORD dwShareMode,
|
||||
/// IN DWORD dwPreferredProtocols,
|
||||
/// OUT LPSCARDHANDLE phCard,
|
||||
/// OUT LPDWORD pdwActiveProtocol
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Reader"></param>
|
||||
/// <param name="ShareMode"></param>
|
||||
/// <param name="PreferredProtocols"></param>
|
||||
void Connect(string Reader, SHARE ShareMode, PROTOCOL PreferredProtocols);
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardDisconnect(
|
||||
/// IN SCARDHANDLE hCard,
|
||||
/// IN DWORD dwDisposition
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="Disposition"></param>
|
||||
void Disconnect(DISCONNECT Disposition);
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardTransmit(
|
||||
/// SCARDHANDLE hCard,
|
||||
/// LPCSCARD_I0_REQUEST pioSendPci,
|
||||
/// LPCBYTE pbSendBuffer,
|
||||
/// DWORD cbSendLength,
|
||||
/// LPSCARD_IO_REQUEST pioRecvPci,
|
||||
/// LPBYTE pbRecvBuffer,
|
||||
/// LPDWORD pcbRecvLength
|
||||
/// );
|
||||
/// </summary>
|
||||
/// <param name="ApduCmd">APDUCommand object with the APDU to send to the card</param>
|
||||
/// <returns>An APDUResponse object with the response from the card</returns>
|
||||
APDUResponse Transmit(APDUCommand ApduCmd);
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PSCS function
|
||||
/// LONG SCardBeginTransaction(
|
||||
/// SCARDHANDLE hCard
|
||||
// );
|
||||
/// </summary>
|
||||
void BeginTransaction();
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the PCSC function
|
||||
/// LONG SCardEndTransaction(
|
||||
/// SCARDHANDLE hCard,
|
||||
/// DWORD dwDisposition
|
||||
/// );
|
||||
/// </summary>
|
||||
void EndTransaction(DISCONNECT Disposition);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the attributes of the card
|
||||
/// </summary>
|
||||
/// <param name="AttribId">Identifier for the Attribute to get</param>
|
||||
/// <returns>Attribute content</returns>
|
||||
byte[] GetAttribute(UInt32 AttribId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SCOPE context
|
||||
/// </summary>
|
||||
public enum SCOPE
|
||||
{
|
||||
/// <summary>
|
||||
/// The context is a user context, and any database operations are performed within the
|
||||
/// domain of the user.
|
||||
/// </summary>
|
||||
User,
|
||||
|
||||
/// <summary>
|
||||
/// The context is that of the current terminal, and any database operations are performed
|
||||
/// within the domain of that terminal. (The calling application must have appropriate
|
||||
/// access permissions for any database actions.)
|
||||
/// </summary>
|
||||
Terminal,
|
||||
|
||||
/// <summary>
|
||||
/// The context is the system context, and any database operations are performed within the
|
||||
/// domain of the system. (The calling application must have appropriate access
|
||||
/// permissions for any database actions.)
|
||||
/// </summary>
|
||||
System
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SHARE mode enumeration
|
||||
/// </summary>
|
||||
public enum SHARE
|
||||
{
|
||||
Exclusive = 1, /// This app. is not willing to share this card with other applications.
|
||||
Shared, /// This app. is willing to share this card with other applications.
|
||||
Direct, /// This app. demands direct control of the reader, so it is not available to other applications.
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// PROTOCOL enumeration
|
||||
/// </summary>
|
||||
public enum PROTOCOL
|
||||
{
|
||||
Undefined = 0x00000000, /// There is no active protocol.
|
||||
T0 = 0x00000001, /// T=0 is the active protocol.
|
||||
T1 = 0x00000002, /// T=1 is the active protocol.
|
||||
T0orT1 = T0 | T1, /// T=1 or T=0 can be the active protocol
|
||||
Raw = 0x00010000, /// Raw is the active protocol.
|
||||
Default = unchecked ((int) 0x80000000), /// Use implicit PTS.
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DISCONNECT action enumeration
|
||||
/// </summary>
|
||||
public enum DISCONNECT
|
||||
{
|
||||
Leave, /// Don't do anything special on close
|
||||
Reset, /// Reset the card on close
|
||||
Unpower, /// Power down the card on close
|
||||
Eject, /// Eject(!) the card on close
|
||||
}
|
||||
}
|
||||
40
GemCard/SmartCardException.cs
Normal file
40
GemCard/SmartCardException.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace GemCard
|
||||
{
|
||||
/// <summary>
|
||||
/// Smart card exceptions
|
||||
/// </summary>
|
||||
public class SmartCardException : Exception
|
||||
{
|
||||
|
||||
public SmartCardException() : base("Smart card exception")
|
||||
{
|
||||
}
|
||||
|
||||
public SmartCardException(string Message) : base(Message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ApduCommandException : Exception
|
||||
{
|
||||
public const string
|
||||
NotValidDocument = "The file is not a valid APDU command document",
|
||||
NoSuchCommand = "No such APDU command in the document",
|
||||
ParamLeFormat = "Le parameter format is not correct",
|
||||
ParamP3Format = "P3 parameter format is not correct",
|
||||
NoSuchSequence = "No such APDU sequence in the document",
|
||||
MissingApduOrCommand = "An Apdu or a Sequence is missing in this Sequence";
|
||||
|
||||
public ApduCommandException() : base("APDU command exception")
|
||||
{
|
||||
}
|
||||
|
||||
public ApduCommandException(string Message) : base(Message)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.18.888.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.888.0")]
|
||||
[assembly: AssemblyVersion("2.18.893.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.893.0")]
|
||||
|
||||
107
Results/Utils.cs
107
Results/Utils.cs
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2016 Sensus Metering Systems
|
||||
/// Copyright (c) 2016-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Text;
|
||||
@ -31,110 +31,6 @@ namespace Results
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Converts float number to a string with the specified number of significant digits
|
||||
/// </summary>
|
||||
/// <param name="value">Float value to be converted to a string</param>
|
||||
/// <param name="validDigits">Number of significant digits: 4, 3, or 2 (otherwise a full precision number is printed)</param>
|
||||
/// <returns>String representation of the float number</returns>
|
||||
public static string DoubleToStr(double value, int validDigits)
|
||||
{
|
||||
if (-float.Epsilon <= value && value <= float.Epsilon)
|
||||
{
|
||||
return "0";
|
||||
}
|
||||
else if (validDigits == 4)
|
||||
{
|
||||
if (value >= 999.5 || value < -999.5) return value.ToString("F0");
|
||||
else if (value >= 99.95 || value < -99.95) return value.ToString("F1");
|
||||
else if (value >= 9.995 || value < -9.995) return value.ToString("F2");
|
||||
else if (value >= 0.9995 || value < -0.9995) return value.ToString("F3");
|
||||
else if (value >= 0.09995 || value < -0.09995) return value.ToString("F4");
|
||||
else if (value >= 0.009995 || value < -0.009995) return value.ToString("F5");
|
||||
else return value.ToString("F6");
|
||||
}
|
||||
else if (validDigits == 3)
|
||||
{
|
||||
if (value >= 99.5 || value < -99.5) return value.ToString("F0");
|
||||
else if (value >= 9.95 || value < -9.95) return value.ToString("F1");
|
||||
else if (value >= 0.995 || value < -0.995) return value.ToString("F2");
|
||||
else if (value >= 0.0995 || value < -0.0995) return value.ToString("F3");
|
||||
else if (value >= 0.00995 || value < -0.00995) return value.ToString("F4");
|
||||
else if (value >= 0.000995 || value < -0.000995) return value.ToString("F5");
|
||||
else return value.ToString("F6");
|
||||
}
|
||||
else if (validDigits == 2)
|
||||
{
|
||||
if (value >= 9.5 || value < -9.5) return value.ToString("F0");
|
||||
else if (value >= 0.95 || value < -0.95) return value.ToString("F1");
|
||||
else if (value >= 0.095 || value < -0.095) return value.ToString("F2");
|
||||
else if (value >= 0.0095 || value < -0.0095) return value.ToString("F3");
|
||||
else if (value >= 0.00095 || value < -0.00095) return value.ToString("F4");
|
||||
else return value.ToString("F5");
|
||||
}
|
||||
else return value.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static string SignificantDigitsToFmt(double value, int sigDigits)
|
||||
{
|
||||
if (sigDigits == 5)
|
||||
{
|
||||
if (value >= 9999.5 || value < -9999.5) return "F0";
|
||||
else if (value >= 999.95 || value < -999.95) return "F1";
|
||||
else if (value >= 99.995 || value < -99.995) return "F2";
|
||||
else if (value >= 9.9995 || value < -9.9995) return "F3";
|
||||
else if (value >= 0.99995 || value < -0.99995) return "F4";
|
||||
else if (value >= 0.099995 || value < -0.099995) return "F5";
|
||||
else if (value >= 0.0099995 || value < -0.0099995) return "F6";
|
||||
else if (value >= 0.00099995 || value < -0.00099995) return "F7";
|
||||
else if (value >= 0.000099995 || value < -0.000099995) return "F8";
|
||||
else return "F9";
|
||||
}
|
||||
else if (sigDigits == 4)
|
||||
{
|
||||
if (value >= 999.5 || value < -999.5) return "F0";
|
||||
else if (value >= 99.95 || value < -99.95) return "F1";
|
||||
else if (value >= 9.995 || value < -9.995) return "F2";
|
||||
else if (value >= 0.9995 || value < -0.9995) return "F3";
|
||||
else if (value >= 0.09995 || value < -0.09995) return "F4";
|
||||
else if (value >= 0.009995 || value < -0.009995) return "F5";
|
||||
else if (value >= 0.0009995 || value < -0.0009995) return "F6";
|
||||
else if (value >= 0.00009995 || value < -0.00009995) return "F7";
|
||||
else return "F8";
|
||||
}
|
||||
else if (sigDigits == 3)
|
||||
{
|
||||
if (value >= 99.5 || value < -99.5) return "F0";
|
||||
else if (value >= 9.95 || value < -9.95) return "F1";
|
||||
else if (value >= 0.995 || value < -0.995) return "F2";
|
||||
else if (value >= 0.0995 || value < -0.0995) return "F3";
|
||||
else if (value >= 0.00995 || value < -0.00995) return "F4";
|
||||
else if (value >= 0.000995 || value < -0.000995) return "F5";
|
||||
else if (value >= 0.0000995 || value < -0.0000995) return "F6";
|
||||
else return "F7";
|
||||
}
|
||||
else if (sigDigits == 2)
|
||||
{
|
||||
if (value >= 9.5 || value < -9.5) return "F0";
|
||||
else if (value >= 0.95 || value < -0.95) return "F1";
|
||||
else if (value >= 0.095 || value < -0.095) return "F2";
|
||||
else if (value >= 0.0095 || value < -0.0095) return "F3";
|
||||
else if (value >= 0.00095 || value < -0.00095) return "F4";
|
||||
else if (value >= 0.000095 || value < -0.000095) return "F5";
|
||||
else return "F6";
|
||||
}
|
||||
else /// if (sigDigits == 1)
|
||||
{
|
||||
if (value >= 0.95 || value < -0.95) return "F0";
|
||||
else if (value >= 0.095 || value < -0.095) return "F1";
|
||||
else if (value >= 0.0095 || value < -0.0095) return "F2";
|
||||
else if (value >= 0.00095 || value < -0.00095) return "F3";
|
||||
else if (value >= 0.000095 || value < -0.000095) return "F4";
|
||||
else return "F5";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts ErrorFlags integer to string. Supports up to 31 flags (E1..E31).
|
||||
@ -170,6 +66,5 @@ namespace Results
|
||||
return (useRedGreenColor) ? (passed ? "OK|Green" : "NOK|Red") : (passed ? "OK|White" : "NOK|White");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ namespace Results
|
||||
int significantDigits;
|
||||
if (int.TryParse(precision.Substring(1), out significantDigits))
|
||||
{
|
||||
precision = Utils.SignificantDigitsToFmt(val, significantDigits);
|
||||
precision = Config.Utils.SignificantDigitsToFmt(val, significantDigits);
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,7 +503,7 @@ namespace Results
|
||||
int significantDigits;
|
||||
if (int.TryParse(precision.Substring(1), out significantDigits))
|
||||
{
|
||||
precision = Utils.SignificantDigitsToFmt(val1, significantDigits);
|
||||
precision = Config.Utils.SignificantDigitsToFmt(val1, significantDigits);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
TBF.sln
20
TBF.sln
@ -28,6 +28,9 @@ EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dirichlet.Numerics", "Dirichlet.Numerics\Dirichlet.Numerics.csproj", "{439D0878-C76E-452B-B17D-209A89E91D36}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Users", "Users\Users.csproj", "{6E5CB0E9-E1B6-4E5D-AC6E-B1049E180F2B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697} = {8B10D15A-39DE-4B56-8DD1-710C1EB3A697}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserManagement", "UserManagement\UserManagement.csproj", "{B2CD81B3-AF09-4978-996C-02EDB5F819B7}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@ -35,9 +38,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserManagement", "UserManag
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphLib", "GraphLib\GraphLib.csproj", "{0C0A1F4D-1363-4544-A7C5-196C76D26CCA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{743DF7DB-C7B6-42EB-986D-0F485E5588E4} = {743DF7DB-C7B6-42EB-986D-0F485E5588E4}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonitoringDB", "MonitoringDB\MonitoringDB.csproj", "{EFEC8A31-3022-4DA7-A8F6-16D30A94C3FF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GemCard", "GemCard\GemCard.csproj", "{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -154,6 +162,18 @@ Global
|
||||
{EFEC8A31-3022-4DA7-A8F6-16D30A94C3FF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{EFEC8A31-3022-4DA7-A8F6-16D30A94C3FF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{EFEC8A31-3022-4DA7-A8F6-16D30A94C3FF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Debug|x86.Build.0 = Debug|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Release|x86.ActiveCfg = Release|x86
|
||||
{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2017 Sensus Metering Systems
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Resources;
|
||||
using GemCard;
|
||||
using System.Drawing;
|
||||
|
||||
|
||||
namespace TBF.Forms
|
||||
@ -15,12 +17,19 @@ namespace TBF.Forms
|
||||
/// </summary>
|
||||
public partial class LoginDlgWithBenchSelection : Form
|
||||
{
|
||||
public const string UseTheTagPassword = "UseTheTag0293578";
|
||||
|
||||
/// Private fields
|
||||
string alias;
|
||||
string password;
|
||||
string benchName = null;
|
||||
string legalizator;
|
||||
|
||||
/// Smart card support, card S/N is used as user.Tag
|
||||
GemCard.CardNative card;
|
||||
string[] cardReaders;
|
||||
string smartCardReader;
|
||||
|
||||
/// Readonly public properties to do the authorization.
|
||||
public string Alias { get { return alias; } }
|
||||
public string Password { get { return password; } }
|
||||
@ -87,6 +96,39 @@ namespace TBF.Forms
|
||||
testBenchComboBox.Text = benchName;
|
||||
}
|
||||
}
|
||||
|
||||
smartCardReader = null; /// null = No smart card reader detected
|
||||
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
card = new CardNative();
|
||||
cardReaders = card.ListReaders();
|
||||
foreach (var crd in cardReaders)
|
||||
{
|
||||
if (crd.Contains("NFC"))
|
||||
{
|
||||
smartCardReader = crd; /// NFC smart card reader detected
|
||||
Text += " (NFC)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(smartCardReader))
|
||||
{
|
||||
card.OnCardInserted += delegate(object sndr, CardInsertedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<CardInsertedEventArgs>(OnCardInserted), sndr, args); }
|
||||
else OnCardInserted(sndr, args);
|
||||
};
|
||||
|
||||
card.OnCardRemoved += delegate(object sndr, CardRemovedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<CardRemovedEventArgs>(OnCardRemoved), sndr, args); }
|
||||
else OnCardRemoved(sndr, args);
|
||||
};
|
||||
|
||||
card.StartCardEvents(smartCardReader);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Localize()
|
||||
@ -179,5 +221,53 @@ namespace TBF.Forms
|
||||
Method = 0;
|
||||
aliasLabel.Text = GetAliasLabel();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OnCardInserted(object sender, CardInsertedEventArgs args)
|
||||
{
|
||||
BackColor = Color.Green;
|
||||
card.Connect(smartCardReader, SHARE.Shared, PROTOCOL.T0orT1);
|
||||
|
||||
/// Read the serial number of the card
|
||||
APDUResponse response = card.Transmit(new APDUCommand(0xFF, 0xCA, 0x00, 0x00, null, 7));
|
||||
string tag = response.ToString();
|
||||
|
||||
card.Disconnect(DISCONNECT.Leave);
|
||||
|
||||
if (testBenchComboBox.SelectedItem != null)
|
||||
{
|
||||
alias = tag;
|
||||
password = UseTheTagPassword;
|
||||
benchName = testBenchComboBox.SelectedItem.ToString();
|
||||
if (legalizatorComboBox.Enabled)
|
||||
{
|
||||
legalizator = legalizatorComboBox.Text;
|
||||
Program.LocalSettings.UpdateHistory(legalizator, ref Program.LocalSettings.LastLegalizators);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Strings.PLs_select_testbench, Strings.Warning, MessageBoxButtons.OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnCardRemoved(object sender, CardRemovedEventArgs args)
|
||||
{
|
||||
BackColor = SystemColors.Control;
|
||||
}
|
||||
|
||||
private void LoginDlgWithBenchSelection_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(smartCardReader))
|
||||
{
|
||||
card.StopCardEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
TBF/Forms/LoginDlgWithBenchSelection.designer.cs
generated
1
TBF/Forms/LoginDlgWithBenchSelection.designer.cs
generated
@ -128,6 +128,7 @@ namespace TBF.Forms
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Name = "LoginDlgWithBenchSelection";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LoginDlgWithBenchSelection_FormClosing);
|
||||
this.Load += new System.EventHandler(this.LoginDlgWithBenchSelection_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@ -248,25 +248,32 @@ namespace TBF
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
requiredGroupMembership = Grp.GID.Testers;
|
||||
#endif
|
||||
|
||||
switch (loginDlgBench.Method)
|
||||
{
|
||||
default:
|
||||
case Users.Entities.LoginMethod.UserName:
|
||||
loadedUser = Users.Entities.User.LoadUserByName(loginDlgBench.Alias, db);
|
||||
if (loadedUser != null) authorized = loadedUser.Authorize(loginDlgBench.Alias, loginDlgBench.Password, requiredGroupMembership);
|
||||
break;
|
||||
case Users.Entities.LoginMethod.FullName:
|
||||
loadedUser = Users.Entities.User.LoadUserByFullName(loginDlgBench.Alias, db);
|
||||
if (loadedUser != null) authorized = loadedUser.AuthorizeFullName(loginDlgBench.Alias, loginDlgBench.Password, requiredGroupMembership);
|
||||
break;
|
||||
case Users.Entities.LoginMethod.Number:
|
||||
int number;
|
||||
if (!int.TryParse(loginDlgBench.Alias, out number)) break;
|
||||
loadedUser = Users.Entities.User.LoadUserByNumber(number, db);
|
||||
if (loadedUser != null) authorized = loadedUser.AuthorizeNumber(number, loginDlgBench.Password, requiredGroupMembership);
|
||||
break;
|
||||
}
|
||||
if (loginDlgBench.Password == LoginDlgWithBenchSelection.UseTheTagPassword)
|
||||
{
|
||||
loadedUser = Users.Entities.User.LoadUserByTag(loginDlgBench.Alias, db);
|
||||
if (loadedUser != null) authorized = loadedUser.AuthorizeTag(loginDlgBench.Alias, requiredGroupMembership);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (loginDlgBench.Method)
|
||||
{
|
||||
default:
|
||||
case Users.Entities.LoginMethod.UserName:
|
||||
loadedUser = Users.Entities.User.LoadUserByName(loginDlgBench.Alias, db);
|
||||
if (loadedUser != null) authorized = loadedUser.Authorize(loginDlgBench.Alias, loginDlgBench.Password, requiredGroupMembership);
|
||||
break;
|
||||
case Users.Entities.LoginMethod.FullName:
|
||||
loadedUser = Users.Entities.User.LoadUserByFullName(loginDlgBench.Alias, db);
|
||||
if (loadedUser != null) authorized = loadedUser.AuthorizeFullName(loginDlgBench.Alias, loginDlgBench.Password, requiredGroupMembership);
|
||||
break;
|
||||
case Users.Entities.LoginMethod.Number:
|
||||
int number;
|
||||
if (!int.TryParse(loginDlgBench.Alias, out number)) break;
|
||||
loadedUser = Users.Entities.User.LoadUserByNumber(number, db);
|
||||
if (loadedUser != null) authorized = loadedUser.AuthorizeNumber(number, loginDlgBench.Password, requiredGroupMembership);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("2.18.892.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.892.0")]
|
||||
[assembly: AssemblyVersion("2.18.893.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.893.0")]
|
||||
|
||||
@ -304,7 +304,7 @@ namespace TBF.Screens
|
||||
|
||||
private string RenderYLabel(DataSource s, float value)
|
||||
{
|
||||
return string.Format("{0:0.0}", value);
|
||||
return value.ToString(Config.Utils.SignificantDigitsToFmt(value, 2));
|
||||
}
|
||||
|
||||
private void checkBox1_CheckedChanged(object sender, EventArgs e) { Program.LocalSettings.Graph1_On = checkBox1.Checked; AnyCBChanged(); }
|
||||
|
||||
@ -2877,6 +2877,10 @@
|
||||
<Project>{439D0878-C76E-452B-B17D-209A89E91D36}</Project>
|
||||
<Name>Dirichlet.Numerics</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GemCard\GemCard.csproj">
|
||||
<Project>{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}</Project>
|
||||
<Name>GemCard</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GraphLib\GraphLib.csproj">
|
||||
<Project>{0C0A1F4D-1363-4544-A7C5-196C76D26CCA}</Project>
|
||||
<Name>GraphLib</Name>
|
||||
|
||||
@ -341,7 +341,7 @@ namespace TBF
|
||||
}
|
||||
else if (significantDigits <= 5)
|
||||
{
|
||||
string fmt = Results.Utils.SignificantDigitsToFmt(value, significantDigits);
|
||||
string fmt = Config.Utils.SignificantDigitsToFmt(value, significantDigits);
|
||||
return altCulture ? value.ToString(fmt, Program.AltCulture) : value.ToString(fmt);
|
||||
}
|
||||
else
|
||||
|
||||
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.18.798.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.798.0")]
|
||||
[assembly: AssemblyVersion("2.18.893.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.893.0")]
|
||||
|
||||
@ -16,6 +16,7 @@ namespace Users.Entities
|
||||
public virtual int Id { get; protected set; }
|
||||
public virtual string UserName { get; set; } /// = name, alias, abbreviation
|
||||
public virtual string FullName { get; set; } /// = description
|
||||
public virtual string Tag { get; set; }
|
||||
public virtual int Number { get; set; }
|
||||
public virtual string Password { get; set; }
|
||||
public virtual DateTime LastPwChange { get; set; }
|
||||
@ -33,6 +34,7 @@ namespace Users.Entities
|
||||
this.powerUser = false;
|
||||
Groups = new List<Group>();
|
||||
Number = 0;
|
||||
Tag = string.Empty;
|
||||
}
|
||||
|
||||
public User(string userName, int number, bool powerUser)
|
||||
@ -61,6 +63,7 @@ namespace Users.Entities
|
||||
User newUser = new User(UserName, Number, false);
|
||||
newUser.FullName = FullName;
|
||||
newUser.Number = Number;
|
||||
newUser.Tag = Tag;
|
||||
newUser.Password = Password;
|
||||
newUser.LastPwChange = LastPwChange;
|
||||
return newUser;
|
||||
@ -250,6 +253,44 @@ namespace Users.Entities
|
||||
return AuthorizeFullName(fullName, password, Grp.GID.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The FIRST of TWO possible user authorization method to be used
|
||||
/// when a specific group membership is required (you can use Grp.GID.None).
|
||||
/// If the user is not authorized, the current user remains to be a current user
|
||||
/// (i.e. the access rights were not risen to a higher level).
|
||||
/// If you require different behavior, use Unauthorize() before calling Authorize().
|
||||
/// </summary>
|
||||
/// <param name="tag">Tag (RFID, NFC, ... s/n)</param>
|
||||
/// <param name="requiredGrupMembership"></param>
|
||||
/// <returns>true = authorized</returns>
|
||||
public virtual bool AuthorizeTag(string tag, Grp.GID requiredGroupMembership)
|
||||
{
|
||||
if (Tag == tag)
|
||||
{
|
||||
if (IsMemberOf(requiredGroupMembership))
|
||||
{
|
||||
GlobalData.CurrentUser = this;
|
||||
GlobalData.LastAuthorization = DateTime.Now;
|
||||
log.FatalFormat("User with Tag={0} authorized @level '{1}'", tag, requiredGroupMembership);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The SECOND of TWO possible user authorization method to be used when
|
||||
/// no specific group membership is required.
|
||||
/// </summary>
|
||||
public virtual bool AuthorizeTag(string tag)
|
||||
{
|
||||
return AuthorizeTag(tag, Grp.GID.None);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a 'User' with a given username from a database.
|
||||
@ -371,6 +412,41 @@ namespace Users.Entities
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a 'User' with a given RFID/NFC tag s/n from an ARBITRARY database.
|
||||
/// </summary>
|
||||
/// <param name="tag">Tag of a user for the query</param>
|
||||
/// <returns>reference to a 'User' (if it exists) or null</returns>
|
||||
public static User LoadUserByTag(string tag, DBSettings dbSettings)
|
||||
{
|
||||
if (dbSettings == null || string.IsNullOrEmpty(dbSettings.ConnectionString)) return null;
|
||||
|
||||
DB.DbType = dbSettings.DbType;
|
||||
DB.ConnectionString = dbSettings.ConnectionString;
|
||||
IList<User> listOfUsers = DB.CreateSession()
|
||||
.QueryOver<User>()
|
||||
.Where(x => (x.Tag == tag))
|
||||
.List();
|
||||
if (listOfUsers.Count > 0) return listOfUsers[0];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a 'User' with a given RFID/NFC tag s/n from the users database.
|
||||
/// </summary>
|
||||
/// <param name="tag">Tag of a user for the query</param>
|
||||
/// <returns>reference to a 'User' (if it exists) or null</returns>
|
||||
public static User LoadUserByTag(string tag)
|
||||
{
|
||||
IList<User> listOfUsers = DB.CreateSession()
|
||||
.QueryOver<User>()
|
||||
.Where(x => (x.Tag == tag))
|
||||
.List();
|
||||
if (listOfUsers.Count > 0) return listOfUsers[0];
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// returns an IList of all Users
|
||||
/// </summary>
|
||||
|
||||
49
Users/Forms/EditSelectedUser.Designer.cs
generated
49
Users/Forms/EditSelectedUser.Designer.cs
generated
@ -35,8 +35,8 @@ namespace Users.Forms
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditSelectedUser));
|
||||
this.txtName = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.btnOk = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.okBtn = new System.Windows.Forms.Button();
|
||||
this.cancelBtn = new System.Windows.Forms.Button();
|
||||
this.txtPassword = new System.Windows.Forms.TextBox();
|
||||
this.passwordLabel = new System.Windows.Forms.Label();
|
||||
this.txtDescription = new System.Windows.Forms.TextBox();
|
||||
@ -48,6 +48,8 @@ namespace Users.Forms
|
||||
this.txtRepeatPassword = new System.Windows.Forms.TextBox();
|
||||
this.codeLabel = new System.Windows.Forms.Label();
|
||||
this.txtCode = new System.Windows.Forms.TextBox();
|
||||
this.tagLabel = new System.Windows.Forms.Label();
|
||||
this.txtTag = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// txtName
|
||||
@ -63,19 +65,19 @@ namespace Users.Forms
|
||||
resources.ApplyResources(this.nameLabel, "nameLabel");
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
//
|
||||
// btnOk
|
||||
// okBtn
|
||||
//
|
||||
resources.ApplyResources(this.btnOk, "btnOk");
|
||||
this.btnOk.Name = "btnOk";
|
||||
this.btnOk.UseVisualStyleBackColor = true;
|
||||
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
|
||||
resources.ApplyResources(this.okBtn, "okBtn");
|
||||
this.okBtn.Name = "okBtn";
|
||||
this.okBtn.UseVisualStyleBackColor = true;
|
||||
this.okBtn.Click += new System.EventHandler(this.okBtn_Click);
|
||||
//
|
||||
// btnCancel
|
||||
// cancelBtn
|
||||
//
|
||||
resources.ApplyResources(this.btnCancel, "btnCancel");
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
resources.ApplyResources(this.cancelBtn, "cancelBtn");
|
||||
this.cancelBtn.Name = "cancelBtn";
|
||||
this.cancelBtn.UseVisualStyleBackColor = true;
|
||||
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
|
||||
//
|
||||
// txtPassword
|
||||
//
|
||||
@ -135,18 +137,30 @@ namespace Users.Forms
|
||||
this.txtCode.Name = "txtCode";
|
||||
this.txtCode.TextChanged += new System.EventHandler(this.txtCode_TextChanged);
|
||||
//
|
||||
// tagLabel
|
||||
//
|
||||
resources.ApplyResources(this.tagLabel, "tagLabel");
|
||||
this.tagLabel.Name = "tagLabel";
|
||||
//
|
||||
// txtTag
|
||||
//
|
||||
resources.ApplyResources(this.txtTag, "txtTag");
|
||||
this.txtTag.Name = "txtTag";
|
||||
//
|
||||
// EditSelectedUser
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tagLabel);
|
||||
this.Controls.Add(this.txtTag);
|
||||
this.Controls.Add(this.codeLabel);
|
||||
this.Controls.Add(this.txtCode);
|
||||
this.Controls.Add(this.repeatPasswordLabel);
|
||||
this.Controls.Add(this.txtRepeatPassword);
|
||||
this.Controls.Add(this.groupsLabel);
|
||||
this.Controls.Add(this.checkedListBoxGroups);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.btnOk);
|
||||
this.Controls.Add(this.cancelBtn);
|
||||
this.Controls.Add(this.okBtn);
|
||||
this.Controls.Add(this.descriptionLabel);
|
||||
this.Controls.Add(this.passwordLabel);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
@ -157,6 +171,7 @@ namespace Users.Forms
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "EditSelectedUser";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.EditSelectedUser_FormClosing);
|
||||
this.Load += new System.EventHandler(this.EditSelectedUser_Load);
|
||||
this.Shown += new System.EventHandler(this.EditSelectedUser_Shown);
|
||||
this.ResumeLayout(false);
|
||||
@ -168,8 +183,8 @@ namespace Users.Forms
|
||||
|
||||
private System.Windows.Forms.TextBox txtName;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Button btnOk;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
private System.Windows.Forms.Button okBtn;
|
||||
private System.Windows.Forms.Button cancelBtn;
|
||||
private System.Windows.Forms.TextBox txtPassword;
|
||||
private System.Windows.Forms.Label passwordLabel;
|
||||
private System.Windows.Forms.TextBox txtDescription;
|
||||
@ -181,5 +196,7 @@ namespace Users.Forms
|
||||
private System.Windows.Forms.TextBox txtRepeatPassword;
|
||||
private System.Windows.Forms.Label codeLabel;
|
||||
private System.Windows.Forms.TextBox txtCode;
|
||||
private System.Windows.Forms.Label tagLabel;
|
||||
private System.Windows.Forms.TextBox txtTag;
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,8 @@ using System.Windows.Forms;
|
||||
using NHibernate;
|
||||
using Users.Entities;
|
||||
using Users.Resources;
|
||||
using GemCard;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Users.Forms
|
||||
{
|
||||
@ -18,12 +20,18 @@ namespace Users.Forms
|
||||
bool[] oriGroupMember; /// index is gid, size is Grp.Count
|
||||
|
||||
|
||||
/// Smart card support, card S/N is used as user.Tag
|
||||
GemCard.CardNative card;
|
||||
string[] cardReaders;
|
||||
string smartCardReader;
|
||||
|
||||
|
||||
public EditSelectedUser()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.toolTip1.SetToolTip(this.txtName, string.Format(Strings.max_0_alphanum_chars, 20));
|
||||
oriGroupMember = new bool[Grp.Count];
|
||||
btnOk.Enabled = false;
|
||||
okBtn.Enabled = false;
|
||||
}
|
||||
|
||||
public EditSelectedUser(NHibernate.ISession session, User user)
|
||||
@ -39,10 +47,47 @@ namespace Users.Forms
|
||||
|
||||
txtName.Text = user.UserName;
|
||||
txtCode.Text = user.Number.ToString();
|
||||
txtTag.Text = string.IsNullOrEmpty(user.Tag) ? string.Empty : user.Tag;
|
||||
txtDescription.Text = user.FullName;
|
||||
txtPassword.Text = string.Empty;
|
||||
txtRepeatPassword.Text = string.Empty;
|
||||
|
||||
ShowGroups();
|
||||
|
||||
smartCardReader = null; /// null = No smart card reader detected
|
||||
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
card = new CardNative();
|
||||
cardReaders = card.ListReaders();
|
||||
foreach (var crd in cardReaders)
|
||||
{
|
||||
if (crd.Contains("NFC"))
|
||||
{
|
||||
smartCardReader = crd; /// NFC smart card reader detected
|
||||
Text += " (NFC)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(smartCardReader))
|
||||
{
|
||||
card.OnCardInserted += delegate(object sndr, CardInsertedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<CardInsertedEventArgs>(OnCardInserted), sndr, args); }
|
||||
else OnCardInserted(sndr, args);
|
||||
};
|
||||
|
||||
card.OnCardRemoved += delegate(object sndr, CardRemovedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<CardRemovedEventArgs>(OnCardRemoved), sndr, args); }
|
||||
else OnCardRemoved(sndr, args);
|
||||
};
|
||||
|
||||
card.StartCardEvents(smartCardReader);
|
||||
}
|
||||
|
||||
txtTag.Enabled = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Localize()
|
||||
@ -52,10 +97,11 @@ namespace Users.Forms
|
||||
passwordLabel.Text = Strings.Password;
|
||||
repeatPasswordLabel.Text = Strings.Repeat_password;
|
||||
codeLabel.Text = Strings.User_code;
|
||||
tagLabel.Text = Strings.Tag;
|
||||
descriptionLabel.Text = Strings.DescriptionColHdr;
|
||||
groupsLabel.Text = Strings.Groups;
|
||||
btnOk.Text = Strings.OkBtnText;
|
||||
btnCancel.Text = Strings.CancelBtnText;
|
||||
okBtn.Text = Strings.OkBtnText;
|
||||
cancelBtn.Text = Strings.CancelBtnText;
|
||||
}
|
||||
|
||||
public void ShowGroups()
|
||||
@ -81,12 +127,18 @@ namespace Users.Forms
|
||||
public bool Save()
|
||||
{
|
||||
// todo: check if this name is given to another user
|
||||
if (IsUserNameAllreadyTaken(txtName.Text))
|
||||
if (IsUserNameAlreadyTaken(txtName.Text))
|
||||
{
|
||||
MessageBox.Show(Strings.Username_taken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsTagAlreadyTaken(txtTag.Text))
|
||||
{
|
||||
MessageBox.Show(Strings.Tag_taken);
|
||||
return false;
|
||||
}
|
||||
|
||||
ITransaction transaction = session.BeginTransaction();
|
||||
|
||||
try
|
||||
@ -96,6 +148,7 @@ namespace Users.Forms
|
||||
user.UserName = txtName.Text;
|
||||
user.FullName = txtDescription.Text;
|
||||
user.Number = int.Parse(txtCode.Text);
|
||||
user.Tag = string.IsNullOrEmpty(txtTag.Text) ? null : txtTag.Text;
|
||||
|
||||
if (txtPassword.Text != string.Empty)
|
||||
{
|
||||
@ -146,19 +199,41 @@ namespace Users.Forms
|
||||
/// <summary>
|
||||
/// returns true if the username allready exists for another user
|
||||
/// </summary>
|
||||
private bool IsUserNameAllreadyTaken(string Username)
|
||||
private bool IsUserNameAlreadyTaken(string userName)
|
||||
{
|
||||
// have a look into all other users
|
||||
// Have a look into all other users
|
||||
IList<User> ListOfUsers = User.GetAllUsers();
|
||||
foreach (var person in ListOfUsers)
|
||||
{
|
||||
if (person.Id != user.Id)
|
||||
{
|
||||
// other user
|
||||
if (person.UserName.ToLower() == Username.ToLower())
|
||||
/// Other user then the current one
|
||||
if (person.UserName.ToLower() == userName.ToLower())
|
||||
{
|
||||
// Name is equal, so allready taken
|
||||
return true;
|
||||
return true; // Name is equal = already taken
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if the username allready exists for another user
|
||||
/// </summary>
|
||||
private bool IsTagAlreadyTaken(string tag)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag)) return false; /// No tag
|
||||
|
||||
// Have a look into all other users
|
||||
IList<User> ListOfUsers = User.GetAllUsers();
|
||||
foreach (var person in ListOfUsers)
|
||||
{
|
||||
if (person.Id != user.Id)
|
||||
{
|
||||
// Other user then the current one
|
||||
if (person.Tag == tag)
|
||||
{
|
||||
return true; // Tag is equal = already taken
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,7 +241,7 @@ namespace Users.Forms
|
||||
}
|
||||
|
||||
|
||||
private void btnOk_Click(object sender, EventArgs e)
|
||||
private void okBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Save())
|
||||
{
|
||||
@ -175,7 +250,7 @@ namespace Users.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
private void cancelBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
this.Close();
|
||||
@ -196,9 +271,36 @@ namespace Users.Forms
|
||||
{
|
||||
int userCode;
|
||||
|
||||
btnOk.Enabled = (txtName.Text != string.Empty)
|
||||
okBtn.Enabled = (txtName.Text != string.Empty)
|
||||
&& int.TryParse(txtCode.Text, out userCode)
|
||||
&& (txtPassword.Text == txtRepeatPassword.Text);
|
||||
}
|
||||
|
||||
|
||||
void OnCardInserted(object sender, CardInsertedEventArgs args)
|
||||
{
|
||||
BackColor = Color.Green;
|
||||
card.Connect(smartCardReader, SHARE.Shared, PROTOCOL.T0orT1);
|
||||
|
||||
/// Read the serial number of the card
|
||||
APDUResponse response = card.Transmit(new APDUCommand(0xFF, 0xCA, 0x00, 0x00, null, 7));
|
||||
txtTag.Text = response.ToString();
|
||||
|
||||
card.Disconnect(DISCONNECT.Leave);
|
||||
}
|
||||
|
||||
|
||||
void OnCardRemoved(object sender, CardRemovedEventArgs args)
|
||||
{
|
||||
BackColor = SystemColors.Control;
|
||||
}
|
||||
|
||||
private void EditSelectedUser_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(smartCardReader))
|
||||
{
|
||||
card.StopCardEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtName.ZOrder" xml:space="preserve">
|
||||
<value>13</value>
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name="nameLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
@ -165,58 +165,62 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>nameLabel.ZOrder" xml:space="preserve">
|
||||
<value>10</value>
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name="btnOk.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 356</value>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="okBtn.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="btnOk.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>84, 40</value>
|
||||
<data name="okBtn.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 365</value>
|
||||
</data>
|
||||
<data name="btnOk.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
<data name="okBtn.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>94, 31</value>
|
||||
</data>
|
||||
<data name="btnOk.Text" xml:space="preserve">
|
||||
<data name="okBtn.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name="okBtn.Text" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name=">>btnOk.Name" xml:space="preserve">
|
||||
<value>btnOk</value>
|
||||
<data name=">>okBtn.Name" xml:space="preserve">
|
||||
<value>okBtn</value>
|
||||
</data>
|
||||
<data name=">>btnOk.Type" xml:space="preserve">
|
||||
<data name=">>okBtn.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>btnOk.Parent" xml:space="preserve">
|
||||
<data name=">>okBtn.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>btnOk.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
<data name=">>okBtn.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="btnCancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>253, 356</value>
|
||||
<data name="cancelBtn.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>243, 365</value>
|
||||
</data>
|
||||
<data name="btnCancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>84, 40</value>
|
||||
<data name="cancelBtn.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>94, 31</value>
|
||||
</data>
|
||||
<data name="btnCancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
<data name="cancelBtn.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>16</value>
|
||||
</data>
|
||||
<data name="btnCancel.Text" xml:space="preserve">
|
||||
<data name="cancelBtn.Text" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name=">>btnCancel.Name" xml:space="preserve">
|
||||
<value>btnCancel</value>
|
||||
<data name=">>cancelBtn.Name" xml:space="preserve">
|
||||
<value>cancelBtn</value>
|
||||
</data>
|
||||
<data name=">>btnCancel.Type" xml:space="preserve">
|
||||
<data name=">>cancelBtn.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>btnCancel.Parent" xml:space="preserve">
|
||||
<data name=">>cancelBtn.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>btnCancel.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
<data name=">>cancelBtn.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="txtPassword.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 38</value>
|
||||
<value>137, 35</value>
|
||||
</data>
|
||||
<data name="txtPassword.PasswordChar" type="System.Char, mscorlib" xml:space="preserve">
|
||||
<value>*</value>
|
||||
@ -237,13 +241,13 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtPassword.ZOrder" xml:space="preserve">
|
||||
<value>12</value>
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name="passwordLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="passwordLabel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>9, 41</value>
|
||||
<value>9, 38</value>
|
||||
</data>
|
||||
<data name="passwordLabel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>53, 13</value>
|
||||
@ -264,10 +268,10 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>passwordLabel.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="txtDescription.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 122</value>
|
||||
<value>137, 135</value>
|
||||
</data>
|
||||
<data name="txtDescription.Multiline" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
@ -276,7 +280,7 @@
|
||||
<value>200, 59</value>
|
||||
</data>
|
||||
<data name="txtDescription.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name=">>txtDescription.Name" xml:space="preserve">
|
||||
<value>txtDescription</value>
|
||||
@ -288,19 +292,19 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtDescription.ZOrder" xml:space="preserve">
|
||||
<value>11</value>
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="descriptionLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="descriptionLabel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>9, 125</value>
|
||||
<value>9, 138</value>
|
||||
</data>
|
||||
<data name="descriptionLabel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>60, 13</value>
|
||||
</data>
|
||||
<data name="descriptionLabel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="descriptionLabel.Text" xml:space="preserve">
|
||||
<value>Description</value>
|
||||
@ -315,16 +319,16 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>descriptionLabel.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="checkedListBoxGroups.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 190</value>
|
||||
<value>137, 199</value>
|
||||
</data>
|
||||
<data name="checkedListBoxGroups.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>200, 154</value>
|
||||
</data>
|
||||
<data name="checkedListBoxGroups.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name=">>checkedListBoxGroups.Name" xml:space="preserve">
|
||||
<value>checkedListBoxGroups</value>
|
||||
@ -336,19 +340,19 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>checkedListBoxGroups.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="groupsLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="groupsLabel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>9, 190</value>
|
||||
<value>9, 199</value>
|
||||
</data>
|
||||
<data name="groupsLabel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>41, 13</value>
|
||||
</data>
|
||||
<data name="groupsLabel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="groupsLabel.Text" xml:space="preserve">
|
||||
<value>Groups</value>
|
||||
@ -363,7 +367,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>groupsLabel.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
<value>6</value>
|
||||
</data>
|
||||
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
@ -371,12 +375,11 @@
|
||||
<data name="repeatPasswordLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="repeatPasswordLabel.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="repeatPasswordLabel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>9, 69</value>
|
||||
<value>9, 63</value>
|
||||
</data>
|
||||
<data name="repeatPasswordLabel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>90, 13</value>
|
||||
@ -397,10 +400,10 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>repeatPasswordLabel.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="txtRepeatPassword.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 66</value>
|
||||
<value>137, 60</value>
|
||||
</data>
|
||||
<data name="txtRepeatPassword.PasswordChar" type="System.Char, mscorlib" xml:space="preserve">
|
||||
<value>*</value>
|
||||
@ -421,7 +424,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtRepeatPassword.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="codeLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
@ -430,13 +433,13 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="codeLabel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>9, 97</value>
|
||||
<value>9, 88</value>
|
||||
</data>
|
||||
<data name="codeLabel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>32, 13</value>
|
||||
</data>
|
||||
<data name="codeLabel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="codeLabel.Text" xml:space="preserve">
|
||||
<value>Code</value>
|
||||
@ -451,16 +454,16 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>codeLabel.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="txtCode.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 94</value>
|
||||
<value>137, 85</value>
|
||||
</data>
|
||||
<data name="txtCode.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>66, 20</value>
|
||||
<value>200, 20</value>
|
||||
</data>
|
||||
<data name="txtCode.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name=">>txtCode.Name" xml:space="preserve">
|
||||
<value>txtCode</value>
|
||||
@ -472,6 +475,60 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtCode.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tagLabel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tagLabel.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="tagLabel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>9, 113</value>
|
||||
</data>
|
||||
<data name="tagLabel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>26, 13</value>
|
||||
</data>
|
||||
<data name="tagLabel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="tagLabel.Text" xml:space="preserve">
|
||||
<value>Tag</value>
|
||||
</data>
|
||||
<data name=">>tagLabel.Name" xml:space="preserve">
|
||||
<value>tagLabel</value>
|
||||
</data>
|
||||
<data name=">>tagLabel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tagLabel.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>tagLabel.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="txtTag.Enabled" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="txtTag.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>137, 110</value>
|
||||
</data>
|
||||
<data name="txtTag.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>200, 20</value>
|
||||
</data>
|
||||
<data name="txtTag.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name=">>txtTag.Name" xml:space="preserve">
|
||||
<value>txtTag</value>
|
||||
</data>
|
||||
<data name=">>txtTag.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>txtTag.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>txtTag.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
|
||||
1
Users/Forms/LoginDlg.Designer.cs
generated
1
Users/Forms/LoginDlg.Designer.cs
generated
@ -94,6 +94,7 @@ namespace Users.Forms
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Name = "LoginDlg";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LoginDlg_FormClosing);
|
||||
this.Load += new System.EventHandler(this.LoginDlg_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
///
|
||||
/// Copyright (c) 2017 Sensus Metering Systems
|
||||
/// Copyright (c) 2017-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using GemCard;
|
||||
using Users.Resources;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Users.Forms
|
||||
{
|
||||
@ -19,11 +21,14 @@ namespace Users.Forms
|
||||
Grp.GID requiredGroupMembership = Grp.GID.Invalid;
|
||||
bool noDatabase;
|
||||
|
||||
|
||||
/// Smart card support, card S/N is used as user.Tag
|
||||
GemCard.CardNative card;
|
||||
string[] cardReaders;
|
||||
string smartCardReader;
|
||||
|
||||
public Users.Entities.LoginMethod Method;
|
||||
public string VersionString;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
@ -79,6 +84,39 @@ namespace Users.Forms
|
||||
userNameTextBox.Select();
|
||||
else
|
||||
passwordTextBox.Select();
|
||||
|
||||
smartCardReader = null; /// null = No smart card reader detected
|
||||
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
card = new CardNative();
|
||||
cardReaders = card.ListReaders();
|
||||
foreach (var crd in cardReaders)
|
||||
{
|
||||
if (crd.Contains("NFC"))
|
||||
{
|
||||
smartCardReader = crd; /// NFC smart card reader detected
|
||||
Text += " (NFC)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(smartCardReader))
|
||||
{
|
||||
card.OnCardInserted += delegate(object sndr, CardInsertedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<CardInsertedEventArgs>(OnCardInserted), sndr, args); }
|
||||
else OnCardInserted(sndr, args);
|
||||
};
|
||||
|
||||
card.OnCardRemoved += delegate(object sndr, CardRemovedEventArgs args)
|
||||
{
|
||||
if (InvokeRequired) { Invoke(new EventHandler<CardRemovedEventArgs>(OnCardRemoved), sndr, args); }
|
||||
else OnCardRemoved(sndr, args);
|
||||
};
|
||||
|
||||
card.StartCardEvents(smartCardReader);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Localize()
|
||||
@ -124,27 +162,31 @@ namespace Users.Forms
|
||||
|
||||
foreach (var db in dbs)
|
||||
{
|
||||
Users.Entities.User loadedUser = Users.Entities.User.LoadUserByName(user, db);
|
||||
if (loadedUser != null)
|
||||
{
|
||||
switch (Method)
|
||||
{
|
||||
default:
|
||||
case Entities.LoginMethod.UserName:
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.Authorize(user, password) : loadedUser.Authorize(user, password, requiredGroupMembership);
|
||||
break;
|
||||
case Entities.LoginMethod.FullName:
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.AuthorizeFullName(user, password) : loadedUser.AuthorizeFullName(user, password, requiredGroupMembership);
|
||||
break;
|
||||
case Entities.LoginMethod.Number:
|
||||
int number;
|
||||
if (!int.TryParse(user, out number)) break;
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.AuthorizeNumber(number, password) : loadedUser.AuthorizeNumber(number, password, requiredGroupMembership);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Users.Entities.User loadedUser = Users.Entities.User.LoadUserByName(user, db);
|
||||
if (loadedUser != null)
|
||||
{
|
||||
switch (Method)
|
||||
{
|
||||
default:
|
||||
case Entities.LoginMethod.UserName:
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.Authorize(user, password) : loadedUser.Authorize(user, password, requiredGroupMembership);
|
||||
break;
|
||||
case Entities.LoginMethod.FullName:
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.AuthorizeFullName(user, password) : loadedUser.AuthorizeFullName(user, password, requiredGroupMembership);
|
||||
break;
|
||||
case Entities.LoginMethod.Number:
|
||||
int number;
|
||||
if (!int.TryParse(user, out number)) break;
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.AuthorizeNumber(number, password) : loadedUser.AuthorizeNumber(number, password, requiredGroupMembership);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
if (authorized) break;
|
||||
if (authorized) break;
|
||||
|
||||
authorizedAs = Entities.AuthorizedAs.LocalUser;
|
||||
}
|
||||
@ -200,5 +242,65 @@ namespace Users.Forms
|
||||
okButton_Click(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnCardInserted(object sender, CardInsertedEventArgs args)
|
||||
{
|
||||
BackColor = Color.Green;
|
||||
card.Connect(smartCardReader, SHARE.Shared, PROTOCOL.T0orT1);
|
||||
|
||||
/// Read the serial number of the card
|
||||
APDUResponse response = card.Transmit(new APDUCommand(0xFF, 0xCA, 0x00, 0x00, null, 7));
|
||||
string tag = response.ToString();
|
||||
|
||||
card.Disconnect(DISCONNECT.Leave);
|
||||
|
||||
DBSettings[] dbs = new DBSettings[] { GlobalData.RemoteUsersDB, GlobalData.LocalUsersDB };
|
||||
bool authorized = false;
|
||||
Entities.AuthorizedAs authorizedAs = Entities.AuthorizedAs.RemoteUser;
|
||||
///
|
||||
foreach (var db in dbs)
|
||||
{
|
||||
try
|
||||
{
|
||||
Users.Entities.User loadedUser = Users.Entities.User.LoadUserByTag(tag, db);
|
||||
if (loadedUser != null)
|
||||
{
|
||||
authorized = (requiredGroupMembership == Grp.GID.Invalid) ? loadedUser.AuthorizeTag(tag) : loadedUser.AuthorizeTag(tag, requiredGroupMembership);
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
|
||||
if (authorized) break;
|
||||
|
||||
authorizedAs = Entities.AuthorizedAs.LocalUser;
|
||||
}
|
||||
|
||||
if (authorized)
|
||||
{
|
||||
Users.GlobalData.AuthorizedAs = authorizedAs;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(Strings.Invalid_username_or_password, Strings.Error, MessageBoxButtons.OK);
|
||||
DialogResult = DialogResult.None;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void OnCardRemoved(object sender, CardRemovedEventArgs args)
|
||||
{
|
||||
BackColor = SystemColors.Control;
|
||||
}
|
||||
|
||||
private void LoginDlg_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(smartCardReader))
|
||||
{
|
||||
card.StopCardEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,10 +36,13 @@ namespace Users.Forms
|
||||
deleteButton.Text = Strings.RemoveBtnText;
|
||||
closeButton.Text = Strings.CloseBtnText;
|
||||
|
||||
listViewUsers.Columns.Add(Strings.User_name, 120);
|
||||
listViewUsers.Columns.Add(Strings.User_code, 80);
|
||||
listViewUsers.Columns.Add(Strings.Full_name, 160);
|
||||
listViewUsers.Columns.Add(Strings.Groups, 300);
|
||||
listViewUsers.Columns.Add(Strings.User_name, 100);
|
||||
listViewUsers.Columns.Add(Strings.User_code, 70);
|
||||
listViewUsers.Columns.Add(Strings.Full_name, 150);
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
listViewUsers.Columns.Add(Strings.Tag, 110);
|
||||
#endif
|
||||
listViewUsers.Columns.Add(Strings.Groups, 370);
|
||||
|
||||
try
|
||||
{
|
||||
@ -79,6 +82,9 @@ namespace Users.Forms
|
||||
ListViewItem item = new ListViewItem(u.UserName);
|
||||
item.SubItems.Add(u.Number.ToString());
|
||||
item.SubItems.Add(u.FullName);
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
item.SubItems.Add(string.IsNullOrEmpty(u.Tag) ? string.Empty : u.Tag);
|
||||
#endif
|
||||
item.SubItems.Add(grps);
|
||||
item.Tag = u;
|
||||
this.listViewUsers.Items.Add(item);
|
||||
@ -115,8 +121,11 @@ namespace Users.Forms
|
||||
|
||||
private void editButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
new Forms.EditSelectedUser(session, (User)listViewUsers.SelectedItems[0].Tag).ShowDialog();
|
||||
ListUsers();
|
||||
if (listViewUsers.SelectedItems.Count == 1 && listViewUsers.SelectedItems[0].Tag is User)
|
||||
{
|
||||
new Forms.EditSelectedUser(session, (User)listViewUsers.SelectedItems[0].Tag).ShowDialog();
|
||||
ListUsers();
|
||||
}
|
||||
}
|
||||
|
||||
private void listViewUsers_DoubleClick(object sender, EventArgs e)
|
||||
|
||||
@ -126,7 +126,7 @@
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="listViewUsers.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>480, 502</value>
|
||||
<value>821, 502</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="listViewUsers.TabIndex" type="System.Int32, mscorlib">
|
||||
@ -247,7 +247,7 @@
|
||||
<value>0, 502</value>
|
||||
</data>
|
||||
<data name="statusStrip1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>615, 22</value>
|
||||
<value>956, 22</value>
|
||||
</data>
|
||||
<data name="statusStrip1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
@ -331,10 +331,10 @@
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="splitContainer1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>615, 502</value>
|
||||
<value>956, 502</value>
|
||||
</data>
|
||||
<data name="splitContainer1.SplitterDistance" type="System.Int32, mscorlib">
|
||||
<value>480</value>
|
||||
<value>821</value>
|
||||
</data>
|
||||
<data name="splitContainer1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
@ -358,7 +358,7 @@
|
||||
<value>6, 13</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>615, 524</value>
|
||||
<value>956, 524</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>User Management</value>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2016 Sensus Metering Systems
|
||||
/// Copyright (c) 2016-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using FluentNHibernate.Mapping;
|
||||
|
||||
@ -12,7 +12,10 @@ namespace Users.Mappings
|
||||
Id(x => x.Id);
|
||||
Map(x => x.UserName).Column("Name");
|
||||
Map(x => x.Number);
|
||||
Map(x => x.Password);
|
||||
#if TURA_IPERL || TURA_SPECIAL
|
||||
Map(x => x.Tag);
|
||||
#endif
|
||||
Map(x => x.Password);
|
||||
Map(x => x.FullName).Column("Description");
|
||||
Map(x => x.LastPwChange);
|
||||
HasMany(x => x.Groups)
|
||||
|
||||
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.18.843.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.843.0")]
|
||||
[assembly: AssemblyVersion("2.18.893.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.893.0")]
|
||||
|
||||
18
Users/Resources/Strings.Designer.cs
generated
18
Users/Resources/Strings.Designer.cs
generated
@ -330,6 +330,24 @@ namespace Users.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to NFC Tag.
|
||||
/// </summary>
|
||||
internal static string Tag {
|
||||
get {
|
||||
return ResourceManager.GetString("Tag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This NFC tag has already been taken. Please use another one..
|
||||
/// </summary>
|
||||
internal static string Tag_taken {
|
||||
get {
|
||||
return ResourceManager.GetString("Tag_taken", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to tester.
|
||||
/// </summary>
|
||||
|
||||
@ -216,4 +216,7 @@
|
||||
<data name="invalid" xml:space="preserve">
|
||||
<value>neplatný</value>
|
||||
</data>
|
||||
<data name="Tag_taken" xml:space="preserve">
|
||||
<value>Tento NFC tag již byl použit. Prosím, použite jiný.</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -228,4 +228,10 @@
|
||||
<data name="invalid" xml:space="preserve">
|
||||
<value>invalid</value>
|
||||
</data>
|
||||
<data name="Tag" xml:space="preserve">
|
||||
<value>NFC Tag</value>
|
||||
</data>
|
||||
<data name="Tag_taken" xml:space="preserve">
|
||||
<value>This NFC tag has already been taken. Please use another one.</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -91,7 +91,12 @@
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GemCard\GemCard.csproj">
|
||||
<Project>{8B10D15A-39DE-4B56-8DD1-710C1EB3A697}</Project>
|
||||
<Name>GemCard</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Forms\EditSelectedUser.resx">
|
||||
<DependentUpon>EditSelectedUser.cs</DependentUpon>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user