private void addUser_Click(object sender, EventArgs e)
        {
            if (userID.Text.Length == 0)
            {
                MessageBox.Show("Enter user ID first", "Error");
                return;
            }

            uint ID = 0;

            try
            {
                ID = UInt32.Parse(userID.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Invalid ID", "Error");
                return;
            }

            int result          = 0;
            int fingerChecksum1 = 0;
            int fingerChecksum2 = 0;

            byte[] templateData = new byte[TEMPLATE_SIZE];

            int numOfFinger = 0;

            if (finger1.Checked)
            {
                numOfFinger++;

                Cursor.Current = Cursors.WaitCursor;
                result         = BSSDK.BS_ScanTemplate(m_Handle, templateData);
                Cursor.Current = Cursors.Default;

                if (result != BSSDK.BS_SUCCESS)
                {
                    MessageBox.Show("Cannot scan the finger", "Error");
                    return;
                }

                Buffer.BlockCopy(templateData, 0, m_TemplateData, 0, TEMPLATE_SIZE);

                Cursor.Current = Cursors.WaitCursor;
                result         = BSSDK.BS_ScanTemplate(m_Handle, templateData);
                Cursor.Current = Cursors.Default;

                if (result != BSSDK.BS_SUCCESS)
                {
                    MessageBox.Show("Cannot scan the finger", "Error");
                    return;
                }

                Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE, TEMPLATE_SIZE);

                for (int i = 0; i < TEMPLATE_SIZE * 2; i++)
                {
                    fingerChecksum1 += m_TemplateData[i];
                }

                checksum1.Text = fingerChecksum1.ToString();

                if (finger2.Checked)
                {
                    numOfFinger++;

                    Cursor.Current = Cursors.WaitCursor;
                    result         = BSSDK.BS_ScanTemplate(m_Handle, templateData);
                    Cursor.Current = Cursors.Default;

                    if (result != BSSDK.BS_SUCCESS)
                    {
                        MessageBox.Show("Cannot scan the finger", "Error");
                        return;
                    }

                    Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE * 2, TEMPLATE_SIZE);

                    Cursor.Current = Cursors.WaitCursor;
                    result         = BSSDK.BS_ScanTemplate(m_Handle, templateData);
                    Cursor.Current = Cursors.Default;

                    if (result != BSSDK.BS_SUCCESS)
                    {
                        MessageBox.Show("Cannot scan the finger", "Error");
                        return;
                    }

                    Buffer.BlockCopy(templateData, 0, m_TemplateData, TEMPLATE_SIZE * 3, TEMPLATE_SIZE);

                    for (int i = 0; i < TEMPLATE_SIZE * 2; i++)
                    {
                        fingerChecksum2 += m_TemplateData[TEMPLATE_SIZE * 2 + i];
                    }

                    checksum2.Text = fingerChecksum2.ToString();
                }
            }

            if (m_DeviceType == BSSDK.BS_DEVICE_BEPLUS || m_DeviceType == BSSDK.BS_DEVICE_BIOLITE)
            {
                BSSDK.BEUserHdr userHdr = new BSSDK.BEUserHdr();
                userHdr.fingerChecksum = new ushort[2];
                userHdr.isDuress       = new byte[2];
                userHdr.numOfFinger    = (ushort)numOfFinger;

                userHdr.fingerChecksum[0] = (ushort)fingerChecksum1;
                userHdr.fingerChecksum[1] = (ushort)fingerChecksum2;

                userHdr.userID        = ID;
                userHdr.adminLevel    = (ushort)userLevel.SelectedIndex;
                userHdr.securityLevel = (ushort)securityLevel.SelectedIndex;
                userHdr.cardFlag      = (byte)cardType.SelectedIndex;
                userHdr.startTime     = (int)((startDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                userHdr.expiryTime    = (int)((expiryDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                userHdr.isDuress[0]   = (duress1.Checked) ? (byte)1 : (byte)0;
                userHdr.isDuress[1]   = (duress2.Checked) ? (byte)1 : (byte)0;
                userHdr.opMode        = (ushort)authMode.SelectedIndex;

                try
                {
                    userHdr.cardID = UInt32.Parse(userCardID.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.cardID = 0;
                }

                try
                {
                    userHdr.cardCustomID = (byte)Int32.Parse(cardCustomID.Text);
                }
                catch (Exception)
                {
                    userHdr.cardCustomID = 0;
                }

                userHdr.cardVersion = BSSDK.BE_CARD_VERSION_1;
                userHdr.disabled    = 0;
                userHdr.dualMode    = 0;

                try
                {
                    userHdr.accessGroupMask = UInt32.Parse(accessGroup.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.accessGroupMask = 0xffffffff;
                }

                IntPtr userInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BSSDK.BEUserHdr)));
                Marshal.StructureToPtr(userHdr, userInfo, true);

                Cursor.Current = Cursors.WaitCursor;

                result = BSSDK.BS_EnrollUserBEPlus(m_Handle, userInfo, m_TemplateData);

                Cursor.Current = Cursors.Default;

                Marshal.FreeHGlobal(userInfo);

                if (result != BSSDK.BS_SUCCESS)
                {
                    MessageBox.Show("Cannot enroll the user", "Error");
                    return;
                }

                ReadUserInfo();
            }
            else if (m_DeviceType == BSSDK.BS_DEVICE_BIOSTATION)
            {
                BSSDK.BSUserHdrEx userHdr = new BSSDK.BSUserHdrEx();

                userHdr.checksum   = new ushort[5];
                userHdr.name       = new byte[33];
                userHdr.department = new byte[33];
                userHdr.password   = new byte[17];

                userHdr.authLimitCount    = 0;
                userHdr.timedAntiPassback = 0;
                userHdr.disabled          = 0;

                userHdr.numOfFinger = (ushort)numOfFinger;

                userHdr.checksum[0] = (ushort)fingerChecksum1;
                userHdr.checksum[1] = (ushort)fingerChecksum2;

                userHdr.ID            = ID;
                userHdr.adminLevel    = (ushort)((userLevel.SelectedIndex == 1) ? BSSDK.BS_USER_ADMIN : BSSDK.BS_USER_NORMAL);
                userHdr.securityLevel = (ushort)(securityLevel.SelectedIndex + BSSDK.BS_USER_SECURITY_DEFAULT);

                userHdr.bypassCard     = (byte)cardType.SelectedIndex;
                userHdr.startDateTime  = (uint)((startDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                userHdr.expireDateTime = (uint)((expiryDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);

                userHdr.duressMask = 0;
                if (duress1.Checked)
                {
                    userHdr.duressMask |= 0x01;
                }
                if (duress2.Checked)
                {
                    userHdr.duressMask |= 0x02;
                }

                if (authMode.SelectedIndex == 0)
                {
                    userHdr.authMode = 0;
                }
                else
                {
                    userHdr.authMode = (ushort)(authMode.SelectedIndex + BSSDK.BS_AUTH_FINGER_ONLY - 1);
                }

                try
                {
                    userHdr.cardID = UInt32.Parse(userCardID.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.cardID = 0;
                }

                try
                {
                    userHdr.customID = (byte)Int32.Parse(cardCustomID.Text);
                }
                catch (Exception)
                {
                    userHdr.customID = 0;
                }

                userHdr.version = BSSDK.BE_CARD_VERSION_1;

                try
                {
                    userHdr.accessGroupMask = UInt32.Parse(accessGroup.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.accessGroupMask = 0xffffffff;
                }

                IntPtr userInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BSSDK.BSUserHdrEx)));
                Marshal.StructureToPtr(userHdr, userInfo, true);

                Cursor.Current = Cursors.WaitCursor;

                result = BSSDK.BS_EnrollUserEx(m_Handle, userInfo, m_TemplateData);

                Cursor.Current = Cursors.Default;

                Marshal.FreeHGlobal(userInfo);

                if (result != BSSDK.BS_SUCCESS)
                {
                    MessageBox.Show("Cannot enroll the user", "Error");
                    return;
                }

                ReadUserInfo();
            }
        }
        private void updateUser_Click(object sender, EventArgs e)
        {
            if (userList.SelectedItems.Count == 0)
            {
                MessageBox.Show("Please select a user first", "Error");
                return;
            }

            uint ID = 0;

            try
            {
                ID = UInt32.Parse(userList.SelectedItems[0].Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Invalid ID", "Error");
                return;
            }

            if (m_DeviceType == BSSDK.BS_DEVICE_BEPLUS || m_DeviceType == BSSDK.BS_DEVICE_BIOLITE)
            {
                IntPtr userInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BSSDK.BEUserHdr)));

                Cursor.Current = Cursors.WaitCursor;

                int result = BSSDK.BS_GetUserBEPlus(m_Handle, ID, userInfo, m_TemplateData);

                Cursor.Current = Cursors.Default;

                if (result != BSSDK.BS_SUCCESS)
                {
                    Marshal.FreeHGlobal(userInfo);

                    MessageBox.Show("Cannot get the user", "Error");
                    return;
                }

                BSSDK.BEUserHdr userHdr = (BSSDK.BEUserHdr)Marshal.PtrToStructure(userInfo, typeof(BSSDK.BEUserHdr));

                userHdr.adminLevel    = (ushort)userLevel.SelectedIndex;
                userHdr.securityLevel = (ushort)securityLevel.SelectedIndex;
                userHdr.cardFlag      = (byte)cardType.SelectedIndex;
                userHdr.startTime     = (int)((startDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                userHdr.expiryTime    = (int)((expiryDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                userHdr.isDuress[0]   = (duress1.Checked) ? (byte)1 : (byte)0;
                userHdr.isDuress[1]   = (duress2.Checked) ? (byte)1 : (byte)0;
                userHdr.opMode        = (ushort)authMode.SelectedIndex;

                try
                {
                    userHdr.cardID = UInt32.Parse(userCardID.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.cardID = 0;
                }

                try
                {
                    userHdr.cardCustomID = (byte)Int32.Parse(cardCustomID.Text);
                }
                catch (Exception)
                {
                    userHdr.cardCustomID = 0;
                }

                try
                {
                    userHdr.accessGroupMask = UInt32.Parse(accessGroup.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.accessGroupMask = 0xffffffff;
                }

                Marshal.StructureToPtr(userHdr, userInfo, true);

                Cursor.Current = Cursors.WaitCursor;

                result = BSSDK.BS_EnrollUserBEPlus(m_Handle, userInfo, m_TemplateData);

                Cursor.Current = Cursors.Default;

                Marshal.FreeHGlobal(userInfo);

                if (result != BSSDK.BS_SUCCESS)
                {
                    MessageBox.Show("Cannot enroll the user", "Error");
                }
            }
            else if (m_DeviceType == BSSDK.BS_DEVICE_BIOSTATION)
            {
                IntPtr userInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(BSSDK.BSUserHdrEx)));

                Cursor.Current = Cursors.WaitCursor;

                int result = BSSDK.BS_GetUserEx(m_Handle, ID, userInfo, m_TemplateData);

                Cursor.Current = Cursors.Default;

                if (result != BSSDK.BS_SUCCESS)
                {
                    Marshal.FreeHGlobal(userInfo);

                    MessageBox.Show("Cannot get the user", "Error");
                    return;
                }

                BSSDK.BSUserHdrEx userHdr = (BSSDK.BSUserHdrEx)Marshal.PtrToStructure(userInfo, typeof(BSSDK.BSUserHdrEx));


                userHdr.adminLevel    = (ushort)((userLevel.SelectedIndex == 1) ? BSSDK.BS_USER_ADMIN : BSSDK.BS_USER_NORMAL);
                userHdr.securityLevel = (ushort)(securityLevel.SelectedIndex + BSSDK.BS_USER_SECURITY_DEFAULT);

                userHdr.bypassCard     = (byte)cardType.SelectedIndex;
                userHdr.startDateTime  = (uint)((startDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);
                userHdr.expireDateTime = (uint)((expiryDate.Value.Ticks - new DateTime(1970, 1, 1).Ticks) / 10000000);

                if (authMode.SelectedIndex == 0)
                {
                    userHdr.authMode = 0;
                }
                else
                {
                    userHdr.authMode = (ushort)(authMode.SelectedIndex + BSSDK.BS_AUTH_FINGER_ONLY - 1);
                }

                try
                {
                    userHdr.cardID = UInt32.Parse(userCardID.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.cardID = 0;
                }

                try
                {
                    userHdr.customID = (byte)Int32.Parse(cardCustomID.Text);
                }
                catch (Exception)
                {
                    userHdr.customID = 0;
                }

                try
                {
                    userHdr.accessGroupMask = UInt32.Parse(accessGroup.Text, System.Globalization.NumberStyles.HexNumber);
                }
                catch (Exception)
                {
                    userHdr.accessGroupMask = 0xffffffff;
                }

                Marshal.StructureToPtr(userHdr, userInfo, true);

                Cursor.Current = Cursors.WaitCursor;

                result = BSSDK.BS_EnrollUserEx(m_Handle, userInfo, m_TemplateData);

                Cursor.Current = Cursors.Default;

                Marshal.FreeHGlobal(userInfo);

                if (result != BSSDK.BS_SUCCESS)
                {
                    MessageBox.Show("Cannot enroll the user", "Error");
                }
            }
        }