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");
                }
            }
        }
        private void ReadUser(uint ID)
        {
            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 user info", "Error");
                    return;
                }

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

                Marshal.FreeHGlobal(userInfo);

                userID.Text                 = userHdr.userID.ToString();
                userCardID.Text             = userHdr.cardID.ToString("X");
                cardCustomID.Text           = userHdr.cardCustomID.ToString();
                userLevel.SelectedIndex     = userHdr.adminLevel;
                securityLevel.SelectedIndex = userHdr.securityLevel;
                cardType.SelectedIndex      = userHdr.cardFlag;
                name.Text = "";

                accessGroup.Text = userHdr.accessGroupMask.ToString("X");

                if (userHdr.opMode >= BSSDK.BS_AUTH_FINGER_ONLY && userHdr.opMode <= BSSDK.BS_AUTH_CARD_ONLY)
                {
                    authMode.SelectedIndex = userHdr.opMode - BSSDK.BS_AUTH_FINGER_ONLY + 1;
                }
                else
                {
                    authMode.SelectedIndex = 0;
                }

                startDate.Value  = new DateTime(1970, 1, 1).AddSeconds(userHdr.startTime);
                expiryDate.Value = new DateTime(1970, 1, 1).AddSeconds(userHdr.expiryTime);

                if (userHdr.numOfFinger > 0)
                {
                    finger1.Checked = true;
                    duress1.Checked = (userHdr.isDuress[0] == 1);
                    checksum1.Text  = userHdr.fingerChecksum[0].ToString();
                }
                else
                {
                    finger1.Checked = false;
                    duress1.Checked = false;
                    checksum1.Text  = "";
                }

                if (userHdr.numOfFinger > 1)
                {
                    finger2.Checked = true;
                    duress2.Checked = (userHdr.isDuress[1] == 1);
                    checksum2.Text  = userHdr.fingerChecksum[1].ToString();
                }
                else
                {
                    finger2.Checked = false;
                    duress2.Checked = false;
                    checksum2.Text  = "";
                }
            }
            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 user info", "Error");
                    return;
                }

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

                Marshal.FreeHGlobal(userInfo);

                userID.Text                 = userHdr.ID.ToString();
                userCardID.Text             = userHdr.cardID.ToString("X");
                cardCustomID.Text           = userHdr.customID.ToString();
                userLevel.SelectedIndex     = (userHdr.adminLevel == BSSDK.BS_USER_ADMIN) ? 1 : 0;
                securityLevel.SelectedIndex = (userHdr.securityLevel >= BSSDK.BS_USER_SECURITY_DEFAULT) ? userHdr.securityLevel - BSSDK.BS_USER_SECURITY_DEFAULT : 0;
                cardType.SelectedIndex      = userHdr.bypassCard;
                name.Text = Encoding.ASCII.GetString(userHdr.name);

                accessGroup.Text = userHdr.accessGroupMask.ToString("X");

                if (userHdr.authMode >= BSSDK.BS_AUTH_FINGER_ONLY && userHdr.authMode <= BSSDK.BS_AUTH_CARD_ONLY)
                {
                    authMode.SelectedIndex = userHdr.authMode - BSSDK.BS_AUTH_FINGER_ONLY + 1;
                }
                else
                {
                    authMode.SelectedIndex = 0;
                }

                startDate.Value  = new DateTime(1970, 1, 1).AddSeconds(userHdr.startDateTime);
                expiryDate.Value = new DateTime(1970, 1, 1).AddSeconds(userHdr.expireDateTime);

                if (userHdr.numOfFinger > 0)
                {
                    finger1.Checked = true;
                    duress1.Checked = (userHdr.duressMask & 0x01) == 0x01;
                    checksum1.Text  = userHdr.checksum[0].ToString();
                }
                else
                {
                    finger1.Checked = false;
                    duress1.Checked = false;
                    checksum1.Text  = "";
                }

                if (userHdr.numOfFinger > 1)
                {
                    finger2.Checked = true;
                    duress2.Checked = (userHdr.duressMask & 0x02) == 0x02;
                    checksum2.Text  = userHdr.checksum[1].ToString();
                }
                else
                {
                    finger2.Checked = false;
                    duress2.Checked = false;
                    checksum2.Text  = "";
                }
            }
        }