Está en la página 1de 110

Universidad de Costa Rica

Facultad de Ingeniera
Escuela de Ingeniera Elctrica

IE 0502 Proyecto Elctrico

Diseo e implementacin de un sistema de registro


de personas mediante la identificacin a partir de
la huella dactilar

Por:
Luis Alfonso Castro Leiva

Ciudad Universitaria Rodrigo Facio


Noviembre del 2009

Diseo e implementacin de un sistema de registro


de personas mediante la identificacin a partir de
la huella digital
Por:
Luis Alfonso Castro Leiva

Sometido a la Escuela de Ingeniera Elctrica


de la Facultad de Ingeniera
de la Universidad de Costa Rica
como requisito parcial para optar por el grado de:
BACHILLER EN INGENIERA ELCTRICA
Aprobado por el Tribunal:

_________________________________
Ing. Rodrigo Garca Len
Profesor Gua

_________________________________
Ing. Lucky Lochi Yu Lo
Profesor lector

_________________________________
Ing. Teodoro Willink Castro
Profesor lector

ii

DEDICATORIA

A Dios,
A mi familia y amigos,
que me han acompaado
en el largo camino

iii

RECONOCIMIENTOS

Un reconocimiento especial a mis padres por su gran ayuda durante toda mi vida.

iv

NDICE GENERAL

NDICE GENERAL ........................................................................................... v


NDICE DE FIGURAS ...................................................................................viii
NOMENCLATURA .......................................................................................... ix
RESUMEN ........................................................................................................... x
CAPTULO 1: Introduccin ............................................................................. 1
1.1

Introduccin ................................................................................................................ 1

1.2

Justificacin ................................................................................................................ 2

1.3

Presentacin del problema a resolver........................................................................ 3

1.4

Objetivos ..................................................................................................................... 4
1.1.1

Objetivo general ................................................................................................. 4

1.1.2

Objetivos especficos ......................................................................................... 4

1.5

Metodologa ................................................................................................................ 5

CAPTULO 2: Desarrollo terico .................................................................... 6


2.1

Principios de reconocimiento biomtrico mediante huellas dactilares ................... 6


2.1.1

Caractersticas Globales..................................................................................... 6

2.1.2

Caractersticas locales........................................................................................ 8

2.2

One Touch for Windows SDK C/C++ Edition .................................................. 9

2.3

El API de DigitalPersona. .......................................................................................... 9

2.4

El IDE de desarrollo Visual C++ 2005 ...................................................................12

2.5

El Software WampServer.........................................................................................13
2.5.1

El servidor HTTP, Apache ..............................................................................13


v

2.5.2

El servidor de Bases de datos, MySQL ..........................................................14

2.5.3

El interpretador PHP ........................................................................................14

2.6

El API C de MySQL ................................................................................................14

2.7

AJAX.........................................................................................................................15

CAPTULO 3: Trabajo previo al desarrollo del software ......................... 18


3.1

El lector de huellas dactilares U.Are.U 4500 de DigitalPersona...........................18

3.2

Eleccin la plataforma de Desarrollo......................................................................19

3.3

Eleccin del entorno integrado de desarrollo .........................................................20

3.4

Visin general del CRB ...........................................................................................21

3.5

Estructura de la base de datos..................................................................................23

CAPTULO 4: Cliente de comunicacin con el lector de huellas digitales


CRB. .................................................................................................................... 25
4.1

Modo de registro de nuevo personal .......................................................................28

4.2

Modo de control de acceso ......................................................................................29

CAPTULO 5: Interfaz para la administracin de bases de datos CRB. 32


CAPTULO 6: Conclusiones y recomendaciones ........................................ 37
6.1

Conclusiones.............................................................................................................37

6.2

Recomendaciones .....................................................................................................38

BIBLIOGRAFA............................................................................................... 40
APNDICE A: Cdigo del cliente de comunicacin con el lector de
huellas dactilares. .............................................................................................. 41
A.1.

Archivo CRB.cpp .....................................................................................................41

A.2.

Archivo Form1.h ......................................................................................................43

A.3.

Archivo Verform.h ...................................................................................................47

A.4.

Archivo Verform.cpp ...............................................................................................52


vi

A.5.

Archivo enroll.h........................................................................................................58

A.6.

Archivo enroll.cpp....................................................................................................66

APNDICE B: Cdigo de la interfaz para administracin de bases de


datos CRB........................................................................................................... 73
B.1.

Archivo cliente.php ..................................................................................................73

B.2.

Archivo ajax.js..........................................................................................................75

B.3.

Archivo query_name.php.........................................................................................77

B.4.

Archivo query_apellido1.php ..................................................................................78

B.5.

Archivo query_apellido2.php ..................................................................................79

B.6.

Archivo query_cedula.php.......................................................................................80

B.7.

Archivo query_marcas.php ......................................................................................81

B.8.

Archivo query_eliminar.php....................................................................................82

Apndice C: Sentencia de SQL para la creacin de la base de datos


crb_db1. .............................................................................................................. 84
Apndice D: Funciones del Dispositivo utilizas. ........................................... 85
2.7.1

Funciones de extraccin...................................................................................89

2.7.2

Funciones de comparacin ..............................................................................91

ANEXOS............................................................................................................. 93

vii

NDICE DE FIGURAS

Figura 2.1 Ejemplo de rea patrn [3]................................................................................... 7


Figura 2.2 Ejemplo de Delta [3]............................................................................................. 7
Figura 2.3 Patrones bsicos de huellas.[3] ............................................................................ 8
Figura 3.1. Lector de huellas digitales U.are.U 4500 .........................................................19
Figura 3.2. Diagrama modular de CRB...............................................................................22
Figura 4.1. Ventana principal del CRB. ..............................................................................25
Figura 4.2. Ventana del modo de registro de nuevo personal ............................................26
Figura 4.3. Diagrama de flujo de CRB.cpp.........................................................................27
Figura 4.4. Niveles de abstraccin del programa CRB. .....................................................28
Figura 4.5. Diagrama de flujo del almacenamiento de informacin. ................................29
Figura 4.6. Ventana del modo de control de acceso ...........................................................30
Figura 5.1. Mdulos de la Interfaz Web..............................................................................32
Figura 5.2. Resultado mostrado por el navegador Web......................................................33
Figura 5.3. Resultados de bsqueda.....................................................................................34
Figura 5.4. Resultados del Registro de marcas de personal ...............................................35
Figura 5.5. Eliminacin de un usuario.................................................................................36

viii

NOMENCLATURA
IDE

Integrated development environment.

SDK

Software developmet ki.t

API

Aplication programming interface.

HTTP

Hypertext Tranfer protocol.

PHP

PHP: Hypertext preprocessor.

GPL

General Public License.

AJAX

Asynchronous JavaSript + XML.

RAD

Rapid Application development.

MingW

Minimalist GNU for Windows

GCC

GNU Compiler Collection.

ix

RESUMEN

En el presente proyecto se aborda la creacin de un sistema que registra las entradas


y salidas de personal en alguna empresa o institucin mediante la identificacin de su
huella dactilar, siguiendo una metodologa de bsqueda de soluciones y eleccin de la de
mejor ajuste a las necesidades y una programacin modular. El resultado obtenido es un
sistema funcional en sus aspectos ms bsicos, con los suficientes requerimientos para ser
una versin alfa y con la necesidad de darle seguimiento para obtener un producto con
mejor acabado. En conclusin, se logr alcanzar la totalidad de los objetivos planteados y
se recomienda seguir con un proceso de mejoramiento de los resultados obtenidos.

CAPTULO 1: Introduccin
1.1

Introduccin
Cuando los seres humanos interactan con otras personas, la identificacin se

realiza por caractersticas como su apariencia fsica. En caso de que una prueba de la
identidad de la persona sea requerida, se recurre a algn tipo de tarjeta de identificacin,
como la cdula de identidad, el pasaporte o incluso la firma. Sin embargo, tcnicas de
identificacin pueden ser fcilmente falsificables. Por este motivo se desarroll la
biometra, ciencia que estudia la identificacin de personas por medio de caractersticas
anatmicas. La gran ventaja de la identificacin biomtrica radica en que las caractersticas
analizadas son prcticamente irrepetibles en diferentes seres humanos y la falsificacin de
las mismas es extremadamente difcil.
Por este motivo, el desarrollo de soluciones biomtricas en el rea digital ha tenido
un enorme desarrollo, especialmente en la identificacin mediante huellas dactilares, palma
de la mano y el iris. Esto trae consigo grandes ventajas en especial en el rea de control de
acceso y seguridad en empresas e instituciones, adems del control de asistencia de
personal.

1.2

Justificacin
Cuando una empresa es de gran tamao y sus empleados son muchos, la prdida de

diez o quince minutos en la hora de entrada de varios de sus empleados puede


contabilizarse en gran cantidad de horas perdidas y retrasos en el inicio de las operaciones
de la empresa, lo cual se traduce al final en grandes prdidas econmicas. Adems la
existencia de ciertos puestos de trabajo que no pueden estar vacantes, ni siquiera por
algunos minutos, motiva al control de entradas y salidas de personal a los puestos de
trabajo.
El desarrollo del pas se sustenta en su capacidad para producir y dar respaldo a esta
produccin, por esto es importante que se motive la creacin de soluciones para las
necesidades del sector productivo del pas por parte del personal calificado existente en
nuestro propio territorio. Las soluciones que se pretenden construir en este proyecto buscan
potencializar las capacidades de las empresas nacionales y contribuir al desarrollo.
Estos motivos son suficientes para justificar el diseo e implementacin de un
sistema de registro de personas mediante huellas dactilares y dar cabida a la elaboracin de
este proyecto.

1.3

Presentacin del problema a resolver


El problema que se aborda en este trabajo es la creacin de un programa de

computadora que permita el control de entradas y salidas de personal a una institucin o


empresa. Este control se realiza por medio de un hardware especializado capaz de registrar
huellas dactilares y realizar comparaciones para determinar si existe concordancia entre
huellas guardadas en una base de datos y el personal que pretende hacer ingreso a las
instalaciones. Por este motivo el programa desarrollado debe ser capaz de interactuar con
este hardware para adquirir la informacin sobre las huellas digitales del personal y
guardarlo junto con la informacin pertinente dentro de una base de datos. Tambin debe
ser capaz de realizar la comparacin y tomar decisiones sobre su resultado, ya sea registrar
la entrada o salida del personal o no. Por ltimo se busca que el personal encargado de los
recursos humanos tenga una forma fcil de accesar a toda la informacin personal, como
nombre o departamento de los trabajadores o de la entrada y salida de los mismos a las
instalaciones, y que la forma en que el personal de recursos humanos pueda realizar estas
consultas sea por la va de Internet.
Por este motivo, se busca que el programa tenga una orientacin modular, y de esta
forma poder enfocarse en sectores especficos del programa por separado, siguiendo el
viejo adagio divide y vencers.

1.4

Objetivos

1.1.1

Objetivo general

Conformar un sistema de registro de personas mediante la identificacin a partir de


la huella dactilar.

1.1.2

Objetivos especficos
Realizar un estudio acerca de las tecnologas existentes en la identificacin de
personas mediante huella dactilar.

Estructurar una solucin persiguiendo la versatilidad y fcil adopcin de empresas o


individuos interesados.

Programar una aplicacin multiplataforma que interacte con el hardware


especializado para la identificacin mediante huella dactilar.

Implementar una interfaz Web para la administracin y consulta del registro de


personas.

Elaborar manuales e instructivos de capacitacin para el uso del sistema.

1.5

Metodologa

Se indagar sobre las opciones que existen en el mercado para soluciones


biomtricas y el hardware existente para tales fines, en miras de la eleccin de la
mejor opcin. Tomando en cuenta precio, factibilidad de uso del hardware para
crear nuevas aplicaciones desde cdigo fuente y disponibilidad de compra desde
Costa Rica.

Se seleccionar y adquirir el hardware requerido junto con las herramientas de


programacin necesarias para la creacin de nuevas aplicaciones.

Se seleccionar la plataforma de operacin (sistema operativo) en la cual se crear


la aplicacin y el IDE sobre el cual se desarrollar la aplicacin.

Se crear una la aplicacin mediante un proceso de pruebas y depuracin de errores


del cdigo elaborado, que cumpla con necesidades planteadas

Se formular un manual del usuario para la aplicacin desarrollada.

CAPTULO 2: Desarrollo terico


2.1

Principios

de

reconocimiento

biomtrico

mediante

huellas

dactilares
Los dedos tienen superficies rugosas que permiten a los seres humanos tener ms
friccin para tomar objetos y sostenerse de superficies sin deslizamientos. Estas
rugosidades forman patrones que son prcticamente nicos e irrepetibles en los seres
humanos. La identificacin de personas se realiza por medio de dos caractersticas en estos
patrones: caractersticas globales y caractersticas locales.
Las caractersticas globales en las huellas dactilares son aquellas que se pueden
observar a simple vista, mientras que las caractersticas locales son llamadas puntos de
minutia. El arreglo bidimensional de la posicin de los puntos de minutia es utilizado en los
algoritmos de reconocimiento debido a que diferentes personas pueden tener caractersticas
globales similares, mientras que es muy poco probable que dos personas tengan arreglos de
puntos de minutia similares, adems de tener la ventaja de que un patrn de este tipo puede
ser cuantificable, lo cual hace esta tcnica candidata ideal para ser implementada de forma
digital.
2.1.1

Caractersticas Globales
Algunos tipos de caractersticas globales son el rea patrn, la delta y el patrn

bsico, aunque existen muchas otras que ayudan a la clasificacin manual de las huellas
digitales. El rea patrn es el rea principal donde se incluyen la mayora de las
caractersticas globales, un ejemplo de esta rea se muestra en la figura 2.1.

Figura 2.1 Ejemplo de rea patrn [3]


La delta es un punto de bifurcacin abrupta o encuentro de lneas digitales donde se
pueden formar puntos o fragmentos cortos de lnea, un ejemplo de una delta se muestra en
la figura 2.2.

Figura 2.2 Ejemplo de Delta [3]


El patrn bsico de las huellas es por as decirlo, la forma adoptan las lneas. Entre
las ms comunes estn el arco, el lazo, y el remolino, los cuales se muestran en la figura 2.3
en ese orden respectivo.

Figura 2.3 Patrones bsicos de huellas.[3]

2.1.2

Caractersticas locales.
Las lneas que conforman una huella digital no son continuas ni rectas, stas

generalmente se rompen, dividen, interrumpen y cambian de direccin. Los puntos donde


las lneas sufren esa clase de cambios y que proveen informacin distinguible, perdurable y,
ms importante an, cuantificable, son los puntos de minutia. Estos puntos tan importantes
para el reconocimiento digital se clasifican segn su tipo, su orientacin, su frecuencia
espacial, su curvatura y su posicin.
Segn su tipo los puntos de minutia pueden ser clasificados como:

Fin de lnea

Bifurcacin de lnea en dos.

Isla o punto. Es una lnea que empieza y acaba en un trayecto muy corto.

Encapsulamiento. Se produce cuando una lnea se divide y rpidamente se


vuelve a juntar.

2.2

One Touch for Windows SDK C/C++ Edition


A continuacin se har un breve resumen del SDK utilizado para el desarrollo del

trabajo, el cual fue escogido por ser la herramienta de software que permite el desarrollo de
aplicaciones con el lector de huellas seleccionado despus del estudio de tecnologas y
posibilidad de implementacin en el trabajo.
El paquete de desarrollo de software SDK, One Touch para Windows C/C++
Edition, versin 1.4, es el paquete que contiene todos los elementos necesarios para el
desarrollo de una aplicacin que interacte con los lectores de huellas digitales de
DigitalPersona, incluida la interfaz de programacin de aplicaciones o API, las libreras
estticas y dinmicas requeridas para comunicarse con el hardware desde un nivel de
abstraccin ms alto (como lo es el lenguaje C++) y los controladores requeridos por el
sistema operativo para el control del hardware. La instalacin de este paquete se encuentra
explicada detalladamente en la gua del desarrollador incluida en el mismo paquete, y es en
este mismo documento donde se explica el manejo de las funciones del API y su adecuado
uso.

2.3

El API de DigitalPersona.
La interfaz de programacin de aplicaciones de DigitalPersona es la que realmente

facilita la interaccin del programador con los lectores de huellas digitales de


DigitalPersona. Est constituida por un conjunto de funciones que, de ser llamadas
adecuadamente, permiten obtener resultados tangibles en el programa desarrollado.

Para hacer uso del API se deben agregar libreras estticas en el linker del
compilador a utilizar, para que las llamadas a estas libreras que se encuentran en los
archivos de encabezado, que tambin deben ser agregados, sean comprendidas por el
compilador
El API se encuentra dividido en dos: el ncleo y un encapsulamiento que crea una
interfaz de usuario del API. Este encapsulamiento (wrapper) consiste en dos funciones
DPEnrollUI y DPVerifyUI. Estas dos funciones son usadas para crear una plantilla con
informacin sobre la huella digital y realizar una verificacin de una huella contra una
plantilla existente. Adems, el encapsulamiento incluye una enumeracin utilizada en las
dos funciones y dos funciones callback. Una funcin callback consiste en un cdigo
ejecutable que es pasado como argumento a otro cdigo, esto permite a una capa inferior de
software llamar una subrutina definida en una capa superior.
Dependiendo del tipo de aplicacin, puede resultar ms fcil hacer uso de este
encapsulamiento. En soluciones como la elaborada en este proyecto no es ese el caso
debido a que se desea tener un alto grado de control sobre el funcionamiento del lector de
huellas digitales, en especial para la comparacin. En la comparacin se debe realizar esta
operacin interactuando con todo un conjunto de elementos presentes en la base de datos a
utilizar y adems tomar decisiones que dependen del tiempo, pues se deben registrar
entradas o salidas. Por este motivo el ncleo del API fue la herramienta utilizada.

10

El ncleo contiene funciones, estructuras, enumeraciones, definiciones de tipos de


variables y constantes. Las funciones contenidas dentro del API pueden ser clasificadas en
las siguientes tres categoras:

Funciones del dispositivo: Son utilizadas para comunicarse establecer y


terminar la comunicacin con el lector de huellas dactilares

Funciones de extraccin: Son utilizadas en el proceso de captura y


procesamiento digital de las imgenes, tanto para el proceso de formacin de
nuevas plantillas como en el proceso de comparacin. Forman el llamado mdulo
de extraccin.

Funciones de comparacin: son las funciones requeridas para la comparacin


de plantillas y determinacin de concordancia entre huellas. Forman el llamado
mdulo de comparacin.

En el apndice D se presenta una explicacin breve de algunas estas funciones,


especialmente las ms relevantes para la creacin de la solucin propuesta.

11

2.4

El IDE de desarrollo Visual C++ 2005


Por motivos que se explican ms adelante en este documento el IDE elegido fue

Visual C++ 2005 es por esto que en este apartado se habla brevemente sobre l, y se
comentan los aspecto bsicos necesarios que se necesitan conocer. Este entorno de
desarrollo permite la rpida creacin de aplicaciones generando grandes cantidades de
cdigo de forma que libera trabajo al programador y le permite centrarse en las necesidades
particulares de su aplicacin. El punto ms importante de mencionar sobre este IDE es el
manejo de Common Language Runtime (CLR), el cual es el motor de la plataforma de
trabajo (Framework) .NET de Microsoft. Esta plataforma es la responsable de acelerar y
simplificar la creacin y el manejo de formularios con los cuales se desarrollan aplicaciones
para Windows. Esto es una gran ventaja pero a la vez genera un problema con el uso del
API de DigitalPersona. Este API est desarrollo en cdigo de C++ estndar, o como lo
llaman en la plataforma de desarrollo .Net, cdigo no manejado o nativo. El cdigo CLR es
llamado cdigo manejado y tiene grandes dificultades con la interaccin de cdigo no
manejado, especialmente por el uso de un componente de Visual C++ 2005, llamado el
recolector de basura (Garbage Collector), este bloque genera dificultades en especial con el
manejo de punteros y pasos por referencia del cdigo nativo. Esto obliga a recurrir a
estrategias que han sido desarrolladas para tal fin como colocar pines a los punteros. Estos
pines fijan los punteros en direcciones de memoria de forma tal que el colector de basura no
generar problemas con el cdigo nativo.

12

2.5

El Software WampServer.
Para implementar la parte Web del proyecto de requiere una estructura que d

soporte a la pgina web, despus de una bsqueda de opciones se seleccion WampServer


y es por esto que en este apartado se habla de forma breve sobre l.
WampServer es un ambiente de desarrollo Web en Windows que permite crear
aplicaciones Web con Apache, PHP y MySQL. Adems incluye phpMyAdmin, un software
para el manejo de bases de datos. Al igual que cada una de las partes que lo conforma
WampServer es un proyecto de cdigo abierto, con licencia GPL. La versin WampServer
2.0i incluye las versiones Apache 2.2.11, MySQL 5.1.36 y PHP 5.3.0.
2.5.1

El servidor HTTP, Apache


Apache es una fundacin de software libre que da cabida a una gran cantidad de

proyectos, entre ellos se encuentra el servidor HTTP Apache. Este proyecto busca el
desarrollo y mantenimiento de un servidor HTTP para sistemas operativos modernos como
UNIX y Windows NT. El objetivo del proyecto es proveer de una alternativa de servidor,
segura, eficiente y extensible que est acorde con los estndares de HTTP.
A travs de la interfaz de WampServer se puede iniciar y detener Apache Server, e
incluso cambiar algunas de sus caractersticas, pero para una configuracin ms profunda
se puede modificar el archivo de configuracin de Apache, httpd.conf y manejarlo desde
lnea de comandos.

13

2.5.2

El servidor de Bases de datos, MySQL


MySQL es un gestor de bases de datos, que se encuentra bajo licencia GPL, aunque

tambin es posible comprar una versin licenciada. MySQL permite estructurar bases de
datos y realizar consultas a travs de lenguaje SQL
2.5.3

El interpretador PHP
PHP es un lenguaje interpretado, por lo cual se requiere un programa interpretador

que convierta el cdigo a lenguaje mquina cada vez que se desea ejecutar. Esto trae
consigo una problemtica para las aplicaciones Web: que el cdigo debe ser ejecutado del
lado del servidor, en el caso de que el cdigo PHP deba ser ejecutado solo bajo ciertas
condiciones o con ciertos parmetros acrecenta la problemtica, por la necesidad de una
comunicacin asincrnica entre cliente y servidor. Para solucionar este problema se ha
desarrollado AJAX.
Se ha decidido utilizar PHP por la enorme facilidad que tiene para establecer
comunicacin con MySQL a travs de un API para tal fin. Este API ya se encuentra
incluido y configurado dentro del paquete WampServer lo cual facilita en gran medida el
trabajo.

2.6

El API C de MySQL
Se debe comentar tambin sobre la estructura que da soporte a la base de datos y la

mejor opcin para esto es MySQL por esto se dedica un apartado para hablar sobre el API
de MySQL, pues es la herramienta de conexin entre el software y la base de datos usada.

14

El API C de MySQL es el encargado de dar conectividad entre aplicaciones escritas


en C o C++ y una base de datos implementada en MySQL. Para hacer uso de ella se deben
incluir un grupo de libreras estticas al Linker del compilador a utilizar y los encabezados
que hacen los llamados a estas libreras estticas. Dentro de las funciones ms relevantes
para este trabajo se encuentran:

mysql_init(NULL); : inicializa el API

mysql_close(connection); : cierra y libera recursos del API

mysql_real_connect(connection,host,username,password,dat
abase,port, NULL,0): establece la conexin con la base de datos.

2.7

mysql_real_query(query): enva una consulta a la base de datos.

mysql_store_result(connection): guarda el resultado de una consulta

mysql_free_result(result): libera el resultado de una consulta

AJAX
AJAX no es una tecnologa, es un conglomerado de tecnologas existentes que ha

permitido lograr grandes avances en el mundo del Internet. La idea detrs de AJAX es
evitar la necesidad de tener que estar cargando una pgina Web cada vez que el usuario
interacta con ella y se deben generar cambios. Una vez cargada y renderizada la pgina,
AJAX permite una comunicacin asincrnica con el servidor, para traer datos que sern
usados solo en una nueva re-renderizacin del sitio, evitando la necesidad de tener que

15

cargar toda la pgina. El mejor ejemplo que se puede dar del uso de AJAX es Google
Maps, donde es claro como es posible dar zoom y ver diferentes puntos de todo el mapa sin
la necesidad de refrescar la pgina. Esto no es de extraar pues Google ha sido uno de los
ms fuertes impulsores de AJAX.
AJAX es realmente muchas tecnologas, cada una floreciendo por su propio
mrito, unindose en poderosas nuevas formas. AJAX incorpora:

presentacin basada en estndares usando XHTML y CSS;

exhibicin e interaccin dinmicas usando el Document Object Model;

Intercambio y manipulacin de datos usando XML and XSLT;

Recuperacin de datos asincrnica usando XMLHttpRequest;

y JavaScript poniendo todo junto. [2]


El modelo de transmisin de informacin queda ejemplificado en la figura 2.4. Aqu

se puede ver claramente las enormes ventajas de AJAX respecto a las nuevas posibilidades
que brinda.

16

Figura 2.4 Modelo de diseo Web con AJAX. [2]


Como se aprecia, en el antiguo modelo cada vez que el cliente requiere nueva
informacin debe realizar una llamada al servidor Web el cual le reenviar toda la
informacin y se deber volver a cargar toda la pgina. En contraposicin utilizando AJAX
se pueden enviar datos sin la necesidad de cargar toda la pgina, esto se traduce en un
aumento de la velocidad pues la cantidad de datos que se transmiten en ambos sentidos se
reduce considerablemente.

17

CAPTULO 3: Trabajo previo al desarrollo del software


3.1

El lector de huellas dactilares U.Are.U 4500 de DigitalPersona.

Para la elaboracin de este proyecto fue sumamente importante la eleccin


adecuada del hardware encargado del escaneo de las huellas digitales. Los parmetros de
seleccin son principalmente las posibilidades reales de desarrollo de nuevas aplicaciones
con l, el factor econmico y la disponibilidad de adquisicin. Existen una gran variedad de
componentes para escaneo de huellas digitales, inclusive muchos incorporan teclados
numricos y mdulos para lectura de tarjetas de tecnologa magntica. Estas capacidades
incrementan en gran medida la seguridad y se usan principalmente en el caso de restriccin
de acceso fsico a algn lugar, pero debido a la inclusin de mayores capacidades, su precio
aumenta en gran medida si se compara con respecto a las soluciones que no incluyen estas
opciones. Entre las empresas que venden soluciones de hardware de este tipo se encuentra:
Microsoft con el DG2-00002, Zvetco con gran variedad de modelos, M2SYS y por
supuesto DigitalPersona. El costo de estos equipos con caractersticas similares era muy
parecido al momento de la eleccin, en donde el factor econmico fue de peso fue en los
paquetes de desarrollo de software para cada uno de los dispositivos. Para muchos de ellos
el costo poda alcanzar hasta los 600 USD.
Por este motivo la opcin del lector U.are.U 4500, mostrado en la figura 3.1, de
DigitalPersona fue elegida sobre gran cantidad de otras opciones. De la misma pgina de
DigitalPersona se pueden descargar paquetes de desarrollo de software de versiones ms

18

antiguas que la que se comercializa en este momento, lo cual permiti el desarrollo del
proyecto a un bajo costo. El contra que posea la eleccin de este dispositivo fue su
disponibilidad, aunque DigitalPersona tiene un socio comercial en Costa Rica, este ya no
comercializa sus productos por lo que tuvo que importarse desde los Estados Unidos, con
todas las implicaciones que esto conlleva. La hoja de datos del U.are.U 4500 se encuentra
en el Apndice A de este documento.

Figura 3.1. Lector de huellas digitales U.are.U 4500

3.2

Eleccin la plataforma de Desarrollo.

Dentro de las opciones de paquetes de desarrollo que se pueden descargar


gratuitamente del sitio Web de DigitalPersona se encuentran un paquete para Linux y otro
para Windows. Las aspiraciones de este proyecto son utilizar al mximo las opciones de
cdigo abierto para la elaboracin de las aplicaciones, por lo cual en un primer momento se

19

trat de utilizar las herramientas orientadas para Linux. A pesar de los intentos de utilizar
los paquetes de desarrollo para Linux, esto no se pudo concretar debido a que a pesar de
haberse logrado actualizar el cdigo fuente de los manejadores de hardware cambiando
funciones obsoleta que se encontraban en los mismos, estos controladores solo funcionan
para modelos de lectores de huellas digitales iguales o anteriores al U.are.U 4000B, que es
anterior al U.are.U 4500 adquirido. Debido a esto se debi utilizar el paquete de desarrollo
para Windows XP, el cual contiene manejadores de hardware actualizados para el U.are.U
4500.
Fuera de los motivos tcnicos, otro fuerte motivo es el mercado meta del software
desarrollado. Este posiblemente utilice Windows a pesar del fuerte crecimiento que han
venido experimentando el uso de Linux en Costa Rica.

3.3

Eleccin del entorno integrado de desarrollo

Para desarrollar el software se probaron tres opciones de RADs, el primero de ellos


wxDev-C++, el cual es una extensin de Dev-C++ utilizando wxWidgets. Este ltimo es un
Framework que permite la creacin de aplicaciones de Windows basadas en formularios.
Esta primera opcin fue descartada por ser un proyecto de software libre con poco
seguimiento y desarrollo, que contiene algunas pulgas an.
La segunda opcin fue CodeBlocks integrado con wxPack. wxPack contiene el
Framework wxWidgets anteriormente mencionado, y con este extra CodeBlocks puede
desarrollar aplicaciones de Windows, orientadas a formularios. Este IDE incluye Mingo, el
20

cual es un puerto del compilador de GCC de GNU, aunque si se encuentran instalados se


puede seleccionar otros compiladores. Esta opcin de IDE fue descartada, porque su
funcionamiento cuando se llaman funciones del API de DigitalPersona no era el adecuado.
Esto se debe a que el API de DigitalPersona fue escrito para el compilador Visual C++ y
hace uso de palabras reservadas para este, cuando se llaman funciones de libreras estticas
y dinmicas. Por este motivo se decidi seguir trabajando con la tercera opcin Visual C++
2005, a pesar de que en CodeBlock uno puede elegir utilizar el compilador Visual C++. Es
preferible usar el compilador desde el entorno de desarrollo para el cual fue creado y no
desde CodeBlocks.

3.4

Visin general del CRB


La aplicacin que se desarroll es llamada Control de Registro Biomtrico (CRB) y

la misma sigue una concepcin modular por lo que est organizada en cuatro bloques
principales:

Un cliente de registro de nuevo personal, y confirmacin de las entradas y salidas de


personal, que se comunica con el lector de huellas digitales.

Un servidor MySQL y una base de datos que cuenta con las tablas y columnas
especficas de la aplicacin CRB.

Un servidor Web Apache que incluye un interpretador PHP y todas las


prerrogativas de comunicacin entre el interpretador PHP y la base de datos.

21

Y por ltimo la interfaz Web por la cual el usuario tiene acceso a la informacin de
la base de datos.

Los bloques anteriormente mencionados se muestran en el diagrama esquemtico de la


figura 3.2.

APACHE y
PHP

Base de Datos
MySQL

Cliente de
comunicacin
con el lector
de huellas

Interfaz Web

Usuario

Figura 3.2. Diagrama modular de CRB.

Los usuarios finales solo tienen acceso a la interfaz Web y al cliente de


comunicacin con el lector de huellas dactilares, el resto de partes son transparentes al
usuario.

22

3.5

Estructura de la base de datos.

Debido a que el sistema desarrollado todava es una versin alfa, se decidi incluir dentro
de la base de datos la informacin bsica que puede necesitar una empresa. As la base de
datos, llamada crb_db1, incluye un tabla principal llamada empleados y una tabla por cada
empleado que lleva como nombre el nmero de cdula correspondiente a cada empleado.
Dentro de la tabla empleados se han creado las siguientes columnas:

Nombre: un espacio tipo char(20).

Apellido1: un espacio tipo char(20).

Apellido2: un espacio tipo char(20).

Cedula: un espacio tipo int.

Departamento: un espacio tipo char(20).

DataTemplate: un espacio tipo BLOB.

cbData: un espacio tipo int.

Los primeros cinco espacios contienen como su nombre lo indica la informacin


elemental del empleado. El espacio DataTemplate no es usado en la versin que ha sido
desarrollada, pero ha sido incluido como una prevista importante, pues en este momento la
informacin sobre las huellas digitales de los usuarios se guarda de forma independiente en
un archivo extensin crbt, aunque lo ptimo sera almacenar la informacin dentro de la
misma base de datos de forma binaria, es por esto que el espacio DataTemplate es tipo

23

BLOB. Por ltimo, el espacio cbData contiene la longitud recomendada para la plantilla de
huella dactilar, este valor es generado por una de las funciones del API de DigitalPersona y
debe ser usado cuando se lee la plantilla, es por esto que fue almacenado en la base de
datos. La sentencia SQL para la generacin de la tabla se encuentra en el apndice C.

24

CAPTULO 4: Cliente de comunicacin con el lector de huellas


digitales CRB.
El software encargado de comunicarse con el lector de huellas digitales y almacenar
nueva informacin sobre el registro de personas en la base de datos fue desarrollado en el
lenguaje C++. El cdigo de este software se encuentra en el apndice A de este documento.
El software se divide en tres ventanas. La ventana principal permite al usuario cambiar
entre accesar a las otras dos ventanas que corresponden a los dos modos de operacin del
software. En la figura 4.1 se muestra la ventana principal. Adems permite al usuario ver la
informacin bsica sobre el software CRB y salir del programa, ya sea mediante la
secuencia Archivo -> Salir o dando click en el botn cerrar de Windows.

Figura 4.1. Ventana principal del CRB.

25

Los dos modos de operacin antes mencionados son el modo de registro de control
de acceso (ver figura 4.6) y el modo de registro de nuevo personal (ver figura 4.2).
Solamente se puede tener uno de ellos activo en un momento dado, esto para independizar
ambos procesos. As el usuario percibe ms fcilmente lo que est haciendo y adems se
facilita la labor de programacin, pues se independizan las tareas de almacenamiento de
plantillas de huellas dactilares y la comparacin de plantillas almacenadas.
Desde el punto de vista de programacin existen 3 clases, una para cada formulario:
la clase Form1 para la ventana principal, la clase Verform para el registro de marcas y la
clase enrrol para el registro de personal nuevo. Adems el programa inicia con la ejecucin
de CRB.cpp, que es el archivo principal donde se inicializa el U.are.U 4500, se establece la
conexin con la base de datos crb_db1 y se llama a la ventana principal. En la figura 4.3 se
muestra el diagrama de flujo que sigue el CRB.cpp.

Figura 4.2. Ventana del modo de registro de nuevo personal

26

Inicio

Error

Inicializar el
hardware.
DPFPInit

Exitoso
Error

Crear un
contexto de
extraccin
FX_init

Exitoso

Crear un
contexto de
comparacin
MC_init

Error

Exitoso
Establecer conexin con MySQL
mysql_real_connect.
Abrir la ventana principal
Continuar con la ejecucin desde ah

Liberar recursos, y cerrar la


conexin con MySQL.
mysql_close, MC_terminate,
FX_terminate, DPFPTerm.

Figura 4.3. Diagrama de flujo de CRB.cpp.


27

Return 0

En general el programa puede ser analizado desde sus diferentes niveles de abstraccin,
(ver figura 4.4), este enfoque permite identificar donde estn los problemas, si son a nivel
de cdigo del programa, a nivel de dependencias de la funciones (encabezados) o a nivel de
libreras dinmicas (problemas en el linker).

Aplicacin desarrollada en C++


API accesado mediante los encabezado
Librerias dinmicas agregadas al linker
OS y controladores se comunican con el hardware

Figura 4.4. Niveles de abstraccin del programa CRB.

4.1

Modo de registro de nuevo personal


En el modo de registro de nuevo personal posee una ventana que contiene tres

lneas de texto sobre el estado actual, espacios para introducir informacin necesaria para el
registro de personal nuevo y dos botones: uno para guardar la informacin y otro para salir
del modo de registro de nuevo personal. La figura 4.1 muestra esta ventana. Es aqu donde
se debe almacenar la informacin sobre la huella digital de la persona en una plantilla. Este
proceso tiene la secuencia que se muestra en la figura 4.5, despus de haberse creado los
contextos de extraccin y comparacin requeridos por el API de DigitalPersona.
28

Obtener una muestra de huella digital a causa del toque de un


dedo en el lector. Este evento es lanzado por el hardware

Procesar la muestra para extraer las caractersticas y


guardarlas en una plantilla de pre-registro en memoria.

Existen suficientes
plantillas de pre-registro?

No

Si
Guardar las caractersticas en una plantilla definitiva y
almacenar la informacin en forma externa al programa

Figura 4.5. Diagrama de flujo del almacenamiento de informacin.


Una vez almacenada la informacin solo queda generar un stream binario para
almacenarla en un archivo con extensin crbt codificado con la huella digital de la persona
y guardar la informacin personal en la base de datos. Por este motivo al dar click en
guardar se revisa que la informacin est completa antes de proceder a guardar todo en
memoria externa al programa.

4.2

Modo de control de acceso


Este es el modo que tiene interaccin directa con todo el personal, aqu deben realizarse

las marcas de entrada o salida a la empresa. La ventana de este modo aparece en la figura

29

4.6. La misma posee tres lneas de informacin, donde se puede ver si el lector de huellas
digitales se encuentra conectado o no, si la marca fue realizada exitosamente y si es posible
realizar marca en el presente momento.

Figura 4.6. Ventana del modo de control de acceso


En lo que respecta a programacin lo ms importante es el algoritmo de bsqueda
que se emplea. Por el momento el algoritmo empleado es muy simple y consiste en una
comparacin uno a uno, principalmente por dos motivos. Primero, se necesita un
conocimiento mucho ms profundo sobre la forma en que opera el lector de huellas
dactilares, aun ms all del manejo del API, para implementar algn tipo de algoritmo ms
complejo y segundo, el corto tiempo que se tiene para desarrolla un proyecto de forma
individual dificulta el concentrar esfuerzos en un punto especfico del sistema como este.
Es claro que el algoritmo es funcional y eficiente para alguna empresa pequea, pero

30

conforme va creciendo la cantidad de usuarios del sistema, el algoritmo se va convirtiendo


cada vez ms ineficiente.

31

CAPTULO 5: Interfaz para la administracin de bases de datos


CRB.
Para ver la informacin sobre entradas y salidas del personal se desarrollo una
interfaz Web. Esta interfaz tiene una estructura modular la cual le permite establecer una
comunicacin asincrnica entre el un servidor Apache y un navegador Web. Los mdulos
tienen la estructura que se muestra en la figura 5.1

query_name

query_apellido1

Cdigo
HTML
cliente.php

query_apellido2

Cdigo
JavaScript
ajax.js

query_cedula

Base de
datos
crb_db1

query_marcas

query_eliminar

Figura 5.1. Mdulos de la Interfaz Web


El primer bloque est formado por el archivo cliente.php. Aunque est conformado
casi completamente por cdigo html, ste debe ser un archivo de extensin php. Esto se
debe a que debe ser preprocesado por el interpretador PHP antes de ser enviado al cliente
que lo est accediendo desde algn navegador Web desde cualquier lugar del mundo para

32

que pueda comunicarse adecuadamente con los otros mdulos. Una vez recibido el
navegador Web lo procesar y se mostrar un resultado como el de la figura 3.2.

Figura 5.2. Resultado mostrado por el navegador Web


Aqu el usuario puede realizar tres acciones diferentes, buscar la informacin de una
persona, por cuatro criterios de bsqueda diferentes: Nombre, Primer Apellido, Segundo
Apellido y Nmero de Cdula. Los resultados se muestran en el mismo espacio de la tabla
por debajo de los criterios de bsqueda como se muestra en la figura 3.3.
La operacin realizada es la siguiente: un objeto AJAX creado mediante el script
ajax.js es usado a travs de una funcin Consulta que se encuentra tambin en el mismo
script. Esta funcin enva informacin a cuatro diferentes cdigos PHP dependiendo de qu
33

tipo de bsqueda se vaya a realizar. Es por esto que existen cuatro bloques query_,
correspondientes a cada una de las bsquedas. Los bloques query_ sea query_name,
query_apellido1, query_apellido2 o query_cedula, son ejecutados del lado del servidor,
debido a que estn escritos en PHP y requieren del interpretador. Una vez procesados, stos
devuelven la informacin mediante la sentencia echo de PHP y son mostrados como se ve
en la figura 3.3. Es importante decir que para versiones posteriores del sistema CRB debe
buscarse otra forma de enviar informacin de regreso a cdigo en JavaScript.
Posteriormente la funcin Consulta se encarga de colocar los resultados en el cdigo
HTML y decirle al navegador Web que debe re-renderizar la pgina.

Figura 5.3. Resultados de bsqueda


Otra de las operaciones que puede realizar el usuario, y tal vez la ms importante, es
ver el registro de entradas y salidas del personal. Para ver los datos de una persona se
necesita conocer el nmero de cdula de ella. La bsqueda, al igual que en el modo
anterior, se realiza mediante un objeto AJAX, pero este se comunicar esta vez con el
bloque de cdigo query_marcas escrito en PHP. La solucin utilizada es la misma y la

34

forma en que se presentan lo resultados se muestra en la figura 3.4. Es en este punto de la


interfaz donde ms se puede avanzar. Deben agregarse bloques que permitan filtrar las
marcas de algn usuario o ver los datos de un da en especfico. Nuevamente, el corto
tiempo de desarrollo fue la principal dificultad.

Figura 5.4. Resultados del Registro de marcas de personal


La ltima de las operaciones que puede realizar la interfaz Web, es la eliminacin
de usuarios va su nmero de cdula. Esta operacin se ha agregado solamente aqu en esta
35

versin alfa, pero en versiones posteriores debe ser agregada tambin en la aplicacin de
escritorio mediante cdigo C++. Se ha agregado aqu principalmente porque la interfaz
Web puede ser accesada prcticamente desde cualquier lugar del mundo y no requiere de
una presencia fsica en el sitio de trabajo, como s sucede con la aplicacin de escritorio. En
lo que a programacin se refiere, se realiza a travs del bloque query_eliminar escrito en
PHP. Este bloque de cdigo difiere en que realiza dos consultas a la base de datos y no
solamente una, como es el caso de todo el resto de bloques query_, pues se debe eliminar
tanto la tabla codificada con el nmero de cdula de la persona como la fila respectiva en la
tabla empleados. Como resultado este enviar solamente una lnea de texto indicando que la
operacin fue realiza con xito, y el cdigo ajax.js en JavaScript se encarga de que la
pgina sea re-renderizada y mostrar un resultado como el que se aprecia en la figura 3.5.

Figura 5.5. Eliminacin de un usuario

El manejo del sistema, en su totalidad por parte del usuario final est documentado
en el manual del usuario.Este manual se encuentra en el Anexo de este documento.

36

CAPTULO 6: Conclusiones y recomendaciones


6.1

Conclusiones
Una bsqueda concienzuda y comparativa fue la que permiti realizar una eleccin

adecuada del hardware a utilizar, lo que a la postre vino a significar facilidades en el


proceso de programacin y el satisfactorio fin de este trabajo.
El seguimiento de una estrategia clara de divisin modular del problema a resolver
fue exitoso y es el responsable del funcionamiento adecuado de un sistema que integra
diferentes frentes de trabajo como lo son una aplicacin de escritorio y una interfaz Web.
De no ser este el enfoque no sera posible manipular la informacin desde rutas tan
diferentes como lo son el Internet y una aplicacin de escritorio.
Durante la elaboracin de este proyecto siempre se busc que la solucin
desarrollada tuviera un enfoque abierto el cual pudiera fcilmente ser adoptado en la gran
mayora de casos donde se requiera una aplicacin similar, y que a partir de la solucin
planteada se pueda seguir trabajando para satisfacer las necesidades especficas del usuario
final. Esto se concret, aunque an se debe seguir trabajando en esta aplicacin,
especialmente en los puntos que se abordan en las recomendaciones.
La interfaz Web desarrollada puede ser accesada desde los mltiples sistemas
operativos existentes, e incluso el cdigo est hecho para preveer diferencias entre los
navegadores Web ms populares del mercado lo cual hace que esta parte del sistema sea
multiplataforma. La aplicacin de escritorio solo pudo ser desarrollada para Windows por
los problemas mencionados en el Captulo 4. A pesar de esto si se pudiera contar

37

principalmente con los manejadores de hardware actualizados, partes importantes del


cdigo desarrollado podra ser exportadas a una aplicacin de Linux, pero mientras no se
cuente con estos manejadores se tendr que esperar.
Por ltimo la meta general planteada se concret y todos los requisitos puestos
inicialmente para la solucin deseada fueron conseguidos, pero es importante recalcar que
en esta clase de aplicaciones siempre debe existir una idea de mejoramiento continuo y an
queda trabajo para obtener un producto final de alta calidad.

6.2

Recomendaciones
La aplicacin desarrollada tiene mucho trabajo por delante antes de poder ser un

versin candidata a definitiva, entre los puntos en los que se debe trabajar para mejor el
sistema CRB se encuentran los siguientes.
Incluir la informacin de las plantillas de huella digital correspondiente a cada
persona dentro de la base de datos como un elemento tipo BLOB pues mejora en gran
medida la portabilidad y adems facilita enormemente la tarea de respaldar la informacin.

Incluir el manejo de excepciones en el cdigo de programa CRB hecho en C++,


para evitar comportamientos inesperados que podran daar valiosa informacin de
la base de datos.

Estandarizar la interfaz Web de manejo de bases de datos CRB, conforme lo


establece la W3C.

38

Buscar una mejor forma de enviar los resultados de la bsqueda en la base de datos
del cdigo PHP a la interfaz Web para presentar la informacin de forma ms
agradable.

Tomar en cuenta todos los posibles fallos del usuario en el ingreso de informacin.
En nmero de cdula, por ejemplo, se debe tomar medidas en caso de que el usuario
del programa no d el nmero completo o incluya letras o espacios dentro de la caja
de texto establecida para ingresar tal nmero.

Mejorar el algoritmo de bsqueda del modo de control de acceso pues resulta


ineficiente conforme crece la cantidad de personal registrado.

Crear un programa instalador para la aplicacin que pueda dejar el programa


funcional sin la intervencin de un programador.

Incluir seguridad en el sistema, principalmente la implementacin de usuarios y la


autenticacin para el uso del programa, y posteriormente la encriptacin de la
informacin que deber viajar por Internet en la interfaz Web.

Debido a que la solucin elaborada representa una versin alfa, el manual del
usuario elaborado deben ser puesto bajo revisin pues apenas cuentan con la
informacin necesaria para explicar al usuario como manejarse en el sistema pero
no prevn los problemas de desarrollo que hayan sido pasados por alto o que
todava no son del conocimiento del desarrollador del sistema CRB.

39

BIBLIOGRAFA
Artculos de revistas:
1. Jimnez, J.M. Marn J.G. Sistema de reconocimiento de huellas dactilares,
Mundo Electrnico, Espaa, N 380, 2006.
2. Zucker, D.F. What does AJAX mean for you?, Interactions, Estados Unidos,
Volumen 14 N 5, 2007.
Libros:
3. DigitalPersona, Inc.. One Touch for Window SDK C/C++ Edition. Developer
Guide, Estados Unidos, 2009.
4. Deitel, H.M. Deitel, P.J. C++ Cmo programar Segunda edicin, Prentice Hall,
Mxico, 1999.
Pginas Web:
5. PHP Manual, http://www.php.net/manual/en/
6. Versin 2.2 de la documentacin del Servidor de HTTP Apache,
http://httpd.apache.org/docs/2.2/
7. Garretr,

J.J.

AJAX:

New

Approach

to

http://adaptivepath.com/ideas/essays/archives/000385.php.

40

Web

Application,

APNDICE A: Cdigo del cliente de comunicacin con el lector


de huellas dactilares.
A.1. Archivo CRB.cpp
/*****************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0502
Proyeto Electrico
Elaborado por: Luis Castro Leiva

A61368

Resumen: CRB.cpp
Este archivo contiene el arranque de CRB, se llama la base de datos
se inicializa el lector U.are.U 4500 y se llama la ventana principal
en caso de error se da aviso y se cierra el programa.
******************************************************************/
#include "stdafx.h"
#include "Form1.h"
#include "enrrol.h"
//Encabezados necesarios para la conexion la base de datos de MySQL
#include <Winsock.h>
#include <mysql.h>
using namespace CRB;
#define
#define
#define
#define

host "localhost"
username "admin"
password "crb"
database "crb_db1"

[STAThreadAttribute]
int main(array<System::String ^> ^args){
//Localiza e inicializa los recursos necesarios para el funcionamiento
del API
if(FAILED(DPFPInit())==TRUE);
else{
// Inicializa el mdulo de extraccin del SDK
if (FT_OK == FX_init())
{
// Inicializa el mdulo de comparacin del SDK
if (FT_OK == MC_init())
{

41

// Habilita los efectos visuales de XP antes de


que los controles sean creados
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
MYSQL *conn = mysql_init(NULL);
int code = 0;
int port = 3306;
//Establece una conexion con MySQL
if
(mysql_real_connect(conn,host,username,password,database,port,NULL,0) ==
NULL){
//En caso de falta de conectividad con crb_db1 se cierra el programa
MessageBox::Show( "Error en la conexin con
la base de datos\nEl programa se cerrar", "Error");
mysql_close(conn);
MC_terminate();
FX_terminate();
DPFPTerm ();
return 0;
}
// Se crea la ventana principal y se ejecuta
Application::Run(gcnew Form1(conn));
// Libera recursos de la conexion con la base de datos
mysql_close(conn);
// Libera recursos del mdulo de comparacin del SDK
MC_terminate();
}
else {
MC_terminate();
FX_terminate();
DPFPTerm ();
return 0;
}
// Libera recursos del mdulo de extraccin del SDK
FX_terminate();
}
else {
FX_terminate();
DPFPTerm ();
return 0;
}
}
DPFPTerm ();
return 0;
}

42

A.2. Archivo Form1.h


/*****************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0502
Proyeto Electrico
Elaborado por: Luis Castro Leiva

A61368

Resumen: Form1.h
Este archivo contiene tanto la declaracin como el contenido de las
funciones de la ventana principal, la cual se encarga de llamar los
dos diferentes modos de operacin y distribuir informacin de
conexin a MySQL.
******************************************************************/
#pragma once
//Encabezados de los modos de operacin
#include "enrrol.h"
#include "Verform.h"
//Encabezados necesarios para la conexion la base de datos de MySQL
#include <Winsock.h>
#include <mysql.h>
//Encabezados para la manipulacion de caracteres
#include <iostream>
#include <fstream>
namespace CRB {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::IO;
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(MYSQL* connlink)
{
InitializeComponent();
ZeroMemory(&m_RegTemplate, sizeof(m_RegTemplate));
conn = connlink;
}
protected:
~Form1()

43

{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::MenuStrip^ menuStrip1;
private: System::Windows::Forms::ToolStripMenuItem^
archivoToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^
salirToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^
toolStripMenuItem1;
private: System::Windows::Forms::ToolStripMenuItem^
cRBToolStripMenuItem;
private: System::Windows::Forms::Button^ button2;
private: System::ComponentModel::IContainer^ components;
private:
DATA_BLOB
MYSQL*

m_RegTemplate;
conn;

#pragma region Windows Form Designer generated code


/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
System::ComponentModel::ComponentResourceManager^ resources
= (gcnew
System::ComponentModel::ComponentResourceManager(Form1::typeid));
this->button1 = (gcnew System::Windows::Forms::Button());
this->menuStrip1 = (gcnew
System::Windows::Forms::MenuStrip());
this->archivoToolStripMenuItem = (gcnew
System::Windows::Forms::ToolStripMenuItem());
this->salirToolStripMenuItem = (gcnew
System::Windows::Forms::ToolStripMenuItem());
this->toolStripMenuItem1 = (gcnew
System::Windows::Forms::ToolStripMenuItem());
this->cRBToolStripMenuItem = (gcnew
System::Windows::Forms::ToolStripMenuItem());
this->button2 = (gcnew System::Windows::Forms::Button());
this->menuStrip1->SuspendLayout();
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(53, 77);

44

this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(184, 26);
this->button1->TabIndex = 0;
this->button1->Text = L"Registrar nuevo personal";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this,
&Form1::button1_Click);
//
// menuStrip1
//
this->menuStrip1->Items->AddRange(gcnew cli::array<
System::Windows::Forms::ToolStripItem^ >(2) {this>archivoToolStripMenuItem,
this->toolStripMenuItem1});
this->menuStrip1->Location = System::Drawing::Point(0, 0);
this->menuStrip1->Name = L"menuStrip1";
this->menuStrip1->Size = System::Drawing::Size(292, 24);
this->menuStrip1->TabIndex = 1;
this->menuStrip1->Text = L"menuStrip1";
//
// archivoToolStripMenuItem
//
this->archivoToolStripMenuItem->DropDownItems->AddRange(gcnew
cli::array< System::Windows::Forms::ToolStripItem^ >(1) {this>salirToolStripMenuItem});
this->archivoToolStripMenuItem->Name =
L"archivoToolStripMenuItem";
this->archivoToolStripMenuItem->Size =
System::Drawing::Size(55, 20);
this->archivoToolStripMenuItem->Text = L"Archivo";
//
// salirToolStripMenuItem
//
this->salirToolStripMenuItem->Name =
L"salirToolStripMenuItem";
this->salirToolStripMenuItem->Size =
System::Drawing::Size(105, 22);
this->salirToolStripMenuItem->Text = L"Salir";
this->salirToolStripMenuItem->Click += gcnew
System::EventHandler(this, &Form1::salirToolStripMenuItem_Click);
//
// toolStripMenuItem1
//
this->toolStripMenuItem1->DropDownItems->AddRange(gcnew
cli::array< System::Windows::Forms::ToolStripItem^ >(1) {this>cRBToolStripMenuItem});
this->toolStripMenuItem1->Name = L"toolStripMenuItem1";
this->toolStripMenuItem1->Size = System::Drawing::Size(67,
20);
this->toolStripMenuItem1->Text = L"Acerca de";
//
// cRBToolStripMenuItem

45

//
this->cRBToolStripMenuItem->Name = L"cRBToolStripMenuItem";
this->cRBToolStripMenuItem->Size = System::Drawing::Size(105,
22);
this->cRBToolStripMenuItem->Text = L"CRB";
this->cRBToolStripMenuItem->Click += gcnew
System::EventHandler(this, &Form1::cRBToolStripMenuItem_Click);
//
// button2
//
this->button2->Location = System::Drawing::Point(53, 141);
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size(184, 26);
this->button2->TabIndex = 2;
this->button2->Text = L"Registrar marcas de personal";
this->button2->UseVisualStyleBackColor = true;
this->button2->Click += gcnew System::EventHandler(this,
&Form1::button2_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode =
System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(292, 266);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Controls->Add(this->menuStrip1);
this->Icon = (cli::safe_cast<System::Drawing::Icon^
>(resources->GetObject(L"$this.Icon")));
this->MaximizeBox = false;
this->MaximumSize = System::Drawing::Size(300, 300);
this->MinimumSize = System::Drawing::Size(300, 300);
this->Name = L"Form1";
this->StartPosition =
System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"Control de Registro Biometrico";
this->menuStrip1->ResumeLayout(false);
this->menuStrip1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void button1_Click(System::Object^
System::EventArgs^ e) {
this->Hide();
enrrol ^form2 = gcnew enrrol();
form2->GetConnetionLinker(conn);
form2->ShowDialog(this);
this->Show();

46

sender,

}
private: System::Void button2_Click(System::Object^ sender,
System::EventArgs^ e) {
this->Hide();
Verform ^form3 = gcnew Verform();
form3->GetConnetionLinker(conn);
form3->ShowDialog(this);
this->Show();
}
private: System::Void salirToolStripMenuItem_Click(System::Object^
sender, System::EventArgs^ e) {
if(MessageBox::Show( "Desea salir de la aplicacin?",
"Salir", MessageBoxButtons::YesNo ) ==
System::Windows::Forms::DialogResult::Yes)
Application::Exit();
}
private: System::Void cRBToolStripMenuItem_Click(System::Object^
sender, System::EventArgs^ e) {
MessageBox::Show( "CRB: Control de Registro
Biomtrico\n2009\nElaborado por: Luis Castro Leiva", "Acerca de CRB");
}
};
}

A.3. Archivo Verform.h


/*****************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0502
Proyeto Electrico
Elaborado por: Luis Castro Leiva

A61368

Resumen: Verform.h
Este archivo contiene declaraciones de las funciones que correponden
a la ventana de registro de control de acceso, (ver Verform.cpp)
y forma parte del cliente de comunicacion con el lector de huellas
digitales U.are.U 4500
******************************************************************/
#pragma once
#pragma warning( disable : 4368)
#include "dpRCodes.h"
#include "dpDefs.h"
#include "DPDevClt.h"

47

#include "dpFtrEx.h"
#include "dpMatch.h"
#include "DpUIApi.h"
//Encabezados necesarios para la manipulacion de caracteres
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
//Encabezados para la conexion con la base de datos
#include <Winsock.h>
#include <mysql.h>
using
using
using
using
using
using
using
using
using
using

namespace
namespace
namespace
namespace
namespace
namespace
namespace
namespace
namespace
namespace

std;
System;
System::ComponentModel;
System::Collections;
System::Windows::Forms;
System::Data;
System::Drawing;
System::Globalization;
System::IO;
System::Runtime::InteropServices;

namespace CRB {
public ref class Verform : public System::Windows::Forms::Form
{
public:
Verform(void){
InitializeComponent();
}
protected:
~Verform(){
if (components){
delete components;
}
delete [] m_RegTemplate.pbData;
m_RegTemplate.cbData = 0;
m_RegTemplate.pbData = NULL;
}
//codificacion para los eventos generados por el lector
private: static const UINT FP_EVENT = (WM_USER+1);
// Variables globales necesarias en el proceso de Verificacion
private:
// Contexto de extraccion
FT_HANDLE
m_fxContext;
// Contexto de comparacion

48

FT_HANDLE
m_mcContext;
// Handle de la operacion
HDPOPERATION
m_hOperationVerify;
// Objetos binarios donde se almacen las plantillas de huellas
dactilares
DATA_BLOB
m_RegTemplate,r_RegTemplate;
// identificador de la comunicacion establecidad con MySQL
MYSQL*
conn;
// Objeto para almacenar los resultados de una consulta a MySQL
MYSQL_RES*
mysql_res;
// Bandera de resultado de comparacion TRUE == huellas
concuerdan. FALSE == no concuerdan
bool
match_flag;
private:
private:
private:
private:
private:

System::Windows::Forms::Label^ label1;
System::Windows::Forms::Button^ button1;
System::Windows::Forms::Label^ label2;
System::Windows::Forms::Label^ label3;
System::Windows::Forms::GroupBox^ groupBox1;

System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void)
{
System::ComponentModel::ComponentResourceManager^

resources
= (gcnew
System::ComponentModel::ComponentResourceManager(Verform::typeid));
this->label1 = (gcnew System::Windows::Forms::Label());
this->button1 = (gcnew System::Windows::Forms::Button());
this->label2 = (gcnew System::Windows::Forms::Label());
this->label3 = (gcnew System::Windows::Forms::Label());
this->groupBox1 = (gcnew System::Windows::Forms::GroupBox());
this->groupBox1->SuspendLayout();
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(46, 54);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(35, 13);
this->label1->TabIndex = 0;
this->label1->Text = L"label1";
//
// button1
//
this->button1->Location = System::Drawing::Point(314, 255);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(92, 28);
this->button1->TabIndex = 1;

49

this->button1->Text = L"Cerrar";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this,
&Verform::button1_Click);
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(46, 89);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(35, 13);
this->label2->TabIndex = 2;
this->label2->Text = L"label2";
//
// label3
//
this->label3->AutoSize = true;
this->label3->Location = System::Drawing::Point(46, 125);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(35, 13);
this->label3->TabIndex = 3;
this->label3->Text = L"label3";
//
// groupBox1
//
this->groupBox1->Controls->Add(this->label2);
this->groupBox1->Controls->Add(this->label1);
this->groupBox1->Controls->Add(this->label3);
this->groupBox1->Location = System::Drawing::Point(12, 37);
this->groupBox1->Name = L"groupBox1";
this->groupBox1->Size = System::Drawing::Size(394, 212);
this->groupBox1->TabIndex = 5;
this->groupBox1->TabStop = false;
this->groupBox1->Text = L"Estado";
//
// Verform
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode =
System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(418, 295);
this->Controls->Add(this->groupBox1);
this->Controls->Add(this->button1);
this->Icon = (cli::safe_cast<System::Drawing::Icon^
>(resources->GetObject(L"$this.Icon")));
this->MaximizeBox = false;
this->MaximumSize = System::Drawing::Size(426, 329);
this->MinimumSize = System::Drawing::Size(426, 329);
this->Name = L"Verform";
this->StartPosition =
System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"Control de entradas y salidas";

50

this->Load += gcnew System::EventHandler(this,


&Verform::Verform_Load);
this->FormClosing += gcnew
System::Windows::Forms::FormClosingEventHandler(this,
&Verform::Verform_FormClosing);
this->groupBox1->ResumeLayout(false);
this->groupBox1->PerformLayout();
this->ResumeLayout(false);
}
#pragma endregion
public: System::Void GetConnetionLinker(MYSQL* connlink);
public: System::Void LoadRegTemplate(const DATA_BLOB% rRegTemplate);
private: System::Void Verform_Load(System::Object^ sender,
System::EventArgs^ e);
private: System::Void button1_Click(System::Object^ sender,
System::EventArgs^ e);
private: System::Void Verificar(FT_IMAGE_PT pFingerprintImage, int
iFingerprintImageSize);
private: System::Void Marca_Personal(int match_cedula);
private: System::Void Cargar_Templates(FT_IMAGE_PT pFingerprintImage,
int iFingerprintImageSize );
private: System::Void Verform_FormClosing(System::Object^ sender,
System::Windows::Forms::FormClosingEventArgs^ e);
protected: virtual void WndProc(Message %m) override{
if (m.Msg == FP_EVENT){
switch((int)m.WParam) {
case WN_COMPLETED: {
this->label3->Text = L"Huella digital capturada";
DATA_BLOB* pImageBlob =
reinterpret_cast<DATA_BLOB*>((int)m.LParam);
//Verificar si hay concordancia
this->Cargar_Templates(pImageBlob->pbData,
pImageBlob->cbData);
break;
}
case WN_ERROR: {
MessageBox::Show( "Existio un error interno del
lector", "Error");
break;
}
case WN_DISCONNECT:
this->label2->Text = L"Lector de huellas
digitales desconectado";
break;
case WN_RECONNECT:
this->label2->Text = L"Lector de huellas
digitales conectado";
break;
case WN_FINGER_TOUCHED:

51

this->label3->Text = L"Huella digital detectada";


break;
case WN_FINGER_GONE:
this->label3->Text = L"Dedo alejado";
break;
case WN_IMAGE_READY:
this->label3->Text = L"Huella digital
capturada";
break;
case WN_OPERATION_STOPPED:
this->label3->Text = L"Operacion detenida
inadecuadamente";
break;
}
}
Form::WndProc(m);
}
};//Fin de la clase Verform
}//Fin del espacio CRB

A.4. Archivo Verform.cpp


/*****************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0502
Proyeto Electrico
Elaborado por: Luis Castro Leiva

A61368

Resumen: Verform.cpp
Este archivo contiene las funciones que correponden a
la ventana de registro de control de acceso, (ver Verform.h)
y forma parte del cliente de comunicacion con el lector de
huellas digitales U.are.U 4500
******************************************************************/
#include "StdAfx.h"
#include "Verform.h"
using namespace CRB;
System::Void Verform::GetConnetionLinker(MYSQL* connlink){
conn = connlink;
}

52

System::Void Verform::LoadRegTemplate(const DATA_BLOB% rRegTemplate) {


// Se eliminan los elementos antiguos que puedan estar en la
plantilla.
delete [] m_RegTemplate.pbData;
m_RegTemplate.pbData = NULL;
m_RegTemplate.cbData = 0;
// Se copian los datos suministrados dentro de la plantilla de
comparacion
m_RegTemplate.pbData = new BYTE[rRegTemplate.cbData];
if (!m_RegTemplate.pbData)
MessageBox::Show( "No hay una plantilla creada", "Error");
::CopyMemory(m_RegTemplate.pbData, rRegTemplate.pbData,
rRegTemplate.cbData);
m_RegTemplate.cbData = rRegTemplate.cbData;
}
System::Void Verform::Verform_Load(System::Object^ sender,
System::EventArgs^ e) {
HRESULT hr = S_OK;
FT_RETCODE rc = FT_OK;
// Se crea un contexto para realizar una extraccion
pin_ptr<FT_HANDLE> pm_fxContext = &m_fxContext;
if (FT_OK != (rc = FX_createContext(pm_fxContext))) {
MessageBox::Show( "Cannot create Feature Extraction Context.",
"Error");
}
// Se crea un contexto para realizar una comparacion
pin_ptr<FT_HANDLE> pm_mcContext = &m_mcContext;
if (FT_OK != (rc = MC_createContext(pm_mcContext))) {
MessageBox::Show( "Error en MC_createContext", "Error");
}
// Iniciar la verificacion
// Se utiliza prioridad baja para que se registren las marcas
// aun si la ventana no se encuentra activa.
DP_ACQUISITION_PRIORITY ePriority = DP_PRIORITY_LOW;
HWND pHandle = (HWND)this->Handle.ToPointer();
pin_ptr<HDPOPERATION> pm_hOperationVerify = &m_hOperationVerify;
if(S_OK == DPFPCreateAcquisition(ePriority,
GUID_NULL,DP_SAMPLE_TYPE_IMAGE,pHandle,FP_EVENT,pm_hOperationVerify)){
if(S_OK == DPFPStartAcquisition(m_hOperationVerify)){
this->label1->Text = L"Inicializacion concluida";
this->label3->Text = L"Puede realizar una marca";
}
}
}
System::Void Verform::button1_Click(System::Object^
System::EventArgs^ e) {

53

sender,

//Se detienen y destruyen los procesos de Adquisicion y se cierran los


contextos de extraccion y comparacion
if (m_hOperationVerify) {
DPFPStopAcquisition(m_hOperationVerify);
DPFPDestroyAcquisition(m_hOperationVerify);
m_hOperationVerify = 0;
}
if (m_fxContext) {
FX_closeContext(m_fxContext);
m_fxContext = 0;
}
if (m_mcContext) {
MC_closeContext(m_mcContext);
m_mcContext = 0;
}
this->Close();
}

System::Void Verform::Verificar(FT_IMAGE_PT pFingerprintImage, int


iFingerprintImageSize) {
HRESULT hr = S_OK;
FT_BYTE* pVerTemplate = NULL;
FT_RETCODE rc = FT_OK;
// Se obtiene el tamao recomendado de las plantillas de
prematricula.
int iRecommendedVerFtrLen = 0;
rc = FX_getFeaturesLen(FT_VER_FTR,
&iRecommendedVerFtrLen,
NULL);
if (FT_OK != rc)
MessageBox::Show( "Error en FX_getFeaturesLen", "Error");
FT_IMG_QUALITY imgQuality;
FT_FTR_QUALITY ftrQuality;
FT_BOOL bEextractOK = FT_FALSE;
if (NULL == (pVerTemplate = new FT_BYTE[iRecommendedVerFtrLen]))
MessageBox::Show( "Error en iRecommendedVerFtrLen", "Error");
rc = FX_extractFeatures(m_fxContext,
extraccion
iFingerprintImageSize,
imagen escaneada
pFingerprintImage,
buffer para contener la imagen
FT_VER_FTR,
Verification Features
iRecommendedVerFtrLen,
que recibe la informacion de la plantilla

54

// Contexto para la
// Tamao de la
// Puntero a algun
// Requested
// Tamao del buffer

pVerTemplate,
donde se almacena la plantilla
&imgQuality,
calidad de la imagen
&ftrQuality,
calidad de las caracteristicas
&bEextractOK);
extraccin

// Puntero al buffer
// Retorna la
// Retorna la
// Resultado de la

if (FT_OK <= rc && bEextractOK == FT_TRUE) {


// Plantilla generada exitosamente
// Ahora se comparan la plantilla generada y la proveniente de
las plantillas almacenadas
double dFalseAcceptProbability = 0.0;
FT_BOOL bVerified = FT_FALSE;
rc = MC_verifyFeaturesEx(m_mcContext,
comparacin
m_RegTemplate.cbData,
la plantilla almacenada
m_RegTemplate.pbData,
la plantilla almacenada
iRecommendedVerFtrLen,
la plantilla a ser verificada
pVerTemplate,
la plantilla a ser verificada
0,
debe ser 0
NULL,
debe ser NULL
NULL,
debe ser NULL
NULL,
debe ser NULL
&dFalseAcceptProbability,
Probabilidad de concordancia falsa
&bVerified);
de la comparacin
if (FT_OK <= rc) {
if (FT_OK != rc) {
WCHAR buffer[101] = {0};
ULONG uSize = 100;
}
if (bVerified == FT_TRUE) {
match_flag = true;
this->label3->Text = L"Scan another finger
verification again.";
WCHAR buffer[101] = {0};
ULONG uSize = 100;
}
else {

55

// Contexto de
// puntero a
// tamao de
// tamao de
// Puntero a
// Obsoleto,
// Reservado,
// Reservado,
// Reservado,
//
// resultado

to run

this->label3->Text = L"Scan another finger to run


verification again.";
WCHAR buffer[101] = {0};
ULONG uSize = 100;
}
}
else {
WCHAR buffer[101] = {0};
ULONG uSize = 100;
MessageBox::Show( "Error en la operacion de verificacion",
"Error");
this->label3->Text = L"Intente nuevamente";
}
}
}
System::Void Verform::Marca_Personal(int match_cedula){
CultureInfo^ MyCI = gcnew CultureInfo( "en-US",false );
DateTimeFormatInfo^ myDTFI = MyCI->DateTimeFormat;
char* cedula = new char[9];
_itoa_s(match_cedula,cedula,10,10);
DateTime Marca = DateTime::Now;
char* Fecha =
(char*)(void*)Marshal::StringToHGlobalAnsi(Marca.Date.ToString("yyyy-MMdd",myDTFI));
char* Hora =
(char*)(void*)Marshal::StringToHGlobalAnsi(Marca.ToString("HH:mm::ss",myD
TFI));
char sql[100];
strcpy_s(sql,100,"INSERT INTO `crb_db1`.`");
strcat_s(sql,100,cedula);
strcat_s(sql,100,"` (`Fecha` ,`Hora` ,`Tipo`)VALUES ('");
strcat_s(sql,100,Fecha);
strcat_s(sql,100,"', '");
strcat_s(sql,100,Hora);
strcat_s(sql,100,"', '');");
if(!mysql_real_query(conn, sql ,strlen(sql))){
this->label2->Text = L"Marca realizada adecuadamente";
}
else{
this->label2->Text = L"Error en la marca, no se pudo realizar";
}
mysql_res = mysql_store_result(conn);
mysql_free_result(mysql_res);
}
System::Void Verform::Cargar_Templates(FT_IMAGE_PT pFingerprintImage, int
iFingerprintImageSize ){
FT_BYTE*

pRegTemplate = NULL;

56

char*
MYSQL_ROW

sql;
row;

String^ solicitud =
String::Format(CultureInfo::CurrentCulture,"SELECT * FROM empleados");
sql = (char*)(void*)Marshal::StringToHGlobalAnsi(solicitud);
int len = 0;
len = strlen(sql);
if(!mysql_real_query(conn, sql ,len)){
this->label2->Text = L"Consulta exitosa";
}
else{
this->label2->Text = L"Error en la consulta";
}
mysql_res = mysql_store_result(conn);
int match_cedula = 0;
while (row = mysql_fetch_row(mysql_res)){
match_flag = false;
int iRecommendedRegFtrLen = atoi(row[6]);
char archivo[40];
strcpy_s(archivo,40,"d:\\CRB\\CRB\\Templates\\");
strcat_s(archivo,40,row[3]);
strcat_s(archivo,40,".crbt");
char* templ = new char[iRecommendedRegFtrLen];
ifstream input(archivo, ios::binary);
input.read(templ, iRecommendedRegFtrLen);
input.close();
//Borrar la informacion antigua del template
delete [] m_RegTemplate.pbData;
m_RegTemplate.pbData = NULL;
m_RegTemplate.cbData = 0;
// Se copian los datos suministrados dentro de la plantilla de
comparacion
m_RegTemplate.pbData = new BYTE[iRecommendedRegFtrLen];
if (!m_RegTemplate.pbData)
MessageBox::Show( "No hay una plantilla creada", "Error");
::CopyMemory(m_RegTemplate.pbData, templ, iRecommendedRegFtrLen);
m_RegTemplate.cbData = iRecommendedRegFtrLen;
Verificar(pFingerprintImage, iFingerprintImageSize);
if(match_flag == true)
match_cedula = atoi(row[3]);
}
mysql_free_result(mysql_res);
if(match_cedula != 0){
Marca_Personal(match_cedula);

57

this->label1->Text
this->label2->Text
exitosamente";
}
else{
this->label1->Text
this->label2->Text
}
}

= L"Puede proceder a realizar otra marca";


= L"Bienvenido. Su marca ha sido registrada

= L"Su huella no se encuentra registrada";


= L"Intente nuevamente por favor";

System::Void Verform::Verform_FormClosing(System::Object^
System::Windows::Forms::FormClosingEventArgs^ e) {
if (m_hOperationVerify) {
DPFPStopAcquisition(m_hOperationVerify);
DPFPDestroyAcquisition(m_hOperationVerify);
m_hOperationVerify = 0;
}
if (m_fxContext) {
FX_closeContext(m_fxContext);
m_fxContext = 0;
}
if (m_mcContext) {
MC_closeContext(m_mcContext);
m_mcContext = 0;
}
}

sender,

A.5. Archivo enroll.h

/*****************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0502
Proyeto Electrico
Elaborado por: Luis Castro Leiva

A61368

Resumen: enrroll.cpp
Este archivo contiene las declaraciones funciones que correponden
a la ventana de registro de nuevo personal, (ver enrrol.cpp)
y forma parte del cliente de comunicacion con el lector de huellas
digitales U.are.U 4500
******************************************************************/

#pragma warning( disable : 4368)

58

#pragma once
//Encabezados para la conexion con la base de datos
#include <Winsock.h>
#include <mysql.h>
//Encabezados de DigitalPersona
#include "resource.h"
#include "dpRCodes.h"
#include "dpDefs.h"
#include "DPDevClt.h"
#include "dpFtrEx.h"
#include "dpMatch.h"
#include "DpUIApi.h"
//Encabezados manejo de cadenas de caracteres
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using
using
using
using
using
using
using
using
using

namespace
namespace
namespace
namespace
namespace
namespace
namespace
namespace
namespace

std;
System;
System::ComponentModel;
System::Collections;
System::Windows::Forms;
System::Data;
System::Runtime::InteropServices;
System::Globalization;
System::IO;

namespace CRB {
public ref class enrrol : public System::Windows::Forms::Form{
public:
enrrol(void){
InitializeComponent();
::ZeroMemory(&m_RegTemplate, sizeof(m_RegTemplate));
}
protected:
~enrrol(){
if (components){
delete components;
}
delete [] m_RegTemplate.pbData;
m_RegTemplate.cbData = 0;
m_RegTemplate.pbData = NULL;
}
private: static const UINT FP_EVENT = (WM_USER+1);

59

private:
// Contexto de extraccion
FT_HANDLE
m_fxContext;
// Contexto de comparacion
FT_HANDLE
m_mcContext;
// Handle de la operacion
HDPOPERATION
m_hOperationEnroll;
// Numero de plantillas de pre-registro
int
m_NumberOfPreRegFeatures;
// Arreglo que contiene las pantillas de pre-registro
FT_BYTE**
m_TemplateArray;
// Indice de la plantilla de pre-registro
int
m_nRegFingerprint;
// Objeto binario donde se almacen las plantillas de huellas
dactilares
DATA_BLOB
m_RegTemplate;
// Link a la conexion con MySQL
MYSQL*
conn;
// Puntero a un objeto encargado de almacenar resultados de una
consulta
MYSQL_RES*
mysql_res;
// cadena de caracteres con una sentencia SQL
CHAR*
sql;
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:
private:

System::Windows::Forms::Label^
System::Windows::Forms::TextBox^
System::Windows::Forms::Label^
System::Windows::Forms::Label^
System::Windows::Forms::TextBox^
System::Windows::Forms::Label^
System::Windows::Forms::TextBox^
System::Windows::Forms::Label^
System::Windows::Forms::Label^
System::Windows::Forms::Button^
System::Windows::Forms::Button^
System::Windows::Forms::TextBox^
System::Windows::Forms::TextBox^
System::Windows::Forms::Label^
System::Windows::Forms::Label^
System::Windows::Forms::GroupBox^

label1;
textBox1;
label2;
label3;
textBox2;
label4;
textBox3;
label5;
label6;
button1;
Guar_button;
textBox4;
textBox5;
label7;
label8;
groupBox1;

System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
void InitializeComponent(void){
System::ComponentModel::ComponentResourceManager^

resources
= (gcnew
System::ComponentModel::ComponentResourceManager(enrrol::typeid));
this->label1 = (gcnew System::Windows::Forms::Label());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->label2 = (gcnew System::Windows::Forms::Label());

60

this->label3 = (gcnew System::Windows::Forms::Label());


this->textBox2 = (gcnew System::Windows::Forms::TextBox());
this->label4 = (gcnew System::Windows::Forms::Label());
this->textBox3 = (gcnew System::Windows::Forms::TextBox());
this->label5 = (gcnew System::Windows::Forms::Label());
this->label6 = (gcnew System::Windows::Forms::Label());
this->button1 = (gcnew System::Windows::Forms::Button());
this->Guar_button = (gcnew System::Windows::Forms::Button());
this->textBox4 = (gcnew System::Windows::Forms::TextBox());
this->textBox5 = (gcnew System::Windows::Forms::TextBox());
this->label7 = (gcnew System::Windows::Forms::Label());
this->label8 = (gcnew System::Windows::Forms::Label());
this->groupBox1 = (gcnew System::Windows::Forms::GroupBox());
this->groupBox1->SuspendLayout();
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(21, 25);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(35, 13);
this->label1->TabIndex = 0;
this->label1->Text = L"label1";
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(54, 193);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(376, 20);
this->textBox1->TabIndex = 1;
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(51, 177);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(44, 13);
this->label2->TabIndex = 2;
this->label2->Text = L"Nombre";
//
// label3
//
this->label3->AutoSize = true;
this->label3->Location = System::Drawing::Point(51, 340);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(95, 13);
this->label3->TabIndex = 3;
this->label3->Text = L"Numero de Cdula";
//
// textBox2
//

61

this->textBox2->Location = System::Drawing::Point(54, 248);


this->textBox2->Name = L"textBox2";
this->textBox2->Size = System::Drawing::Size(376, 20);
this->textBox2->TabIndex = 4;
//
// label4
//
this->label4->AutoSize = true;
this->label4->Location = System::Drawing::Point(51, 391);
this->label4->Name = L"label4";
this->label4->Size = System::Drawing::Size(74, 13);
this->label4->TabIndex = 5;
this->label4->Text = L"Departamento";
//
// textBox3
//
this->textBox3->Location = System::Drawing::Point(54, 303);
this->textBox3->Name = L"textBox3";
this->textBox3->Size = System::Drawing::Size(376, 20);
this->textBox3->TabIndex = 6;
//
// label5
//
this->label5->AutoSize = true;
this->label5->Location = System::Drawing::Point(21, 57);
this->label5->Name = L"label5";
this->label5->Size = System::Drawing::Size(35, 13);
this->label5->TabIndex = 7;
this->label5->Text = L"label5";
//
// label6
//
this->label6->AutoSize = true;
this->label6->Location = System::Drawing::Point(21, 89);
this->label6->Name = L"label6";
this->label6->Size = System::Drawing::Size(35, 13);
this->label6->TabIndex = 8;
this->label6->Text = L"label6";
//
// button1
//
this->button1->Location = System::Drawing::Point(336, 471);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(94, 28);
this->button1->TabIndex = 9;
this->button1->Text = L"Cerrar";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this,
&enrrol::button1_Click);
//
// Guar_button
//

62

this->Guar_button->Location = System::Drawing::Point(231,
472);
this->Guar_button->Name = L"Guar_button";
this->Guar_button->Size = System::Drawing::Size(94, 27);
this->Guar_button->TabIndex = 10;
this->Guar_button->Text = L"Guardar";
this->Guar_button->UseVisualStyleBackColor = true;
this->Guar_button->Click += gcnew System::EventHandler(this,
&enrrol::button2_Click);
//
// textBox4
//
this->textBox4->Location = System::Drawing::Point(54, 356);
this->textBox4->Name = L"textBox4";
this->textBox4->Size = System::Drawing::Size(376, 20);
this->textBox4->TabIndex = 11;
//
// textBox5
//
this->textBox5->Location = System::Drawing::Point(54, 407);
this->textBox5->Name = L"textBox5";
this->textBox5->Size = System::Drawing::Size(376, 20);
this->textBox5->TabIndex = 12;
//
// label7
//
this->label7->AutoSize = true;
this->label7->Location = System::Drawing::Point(54, 232);
this->label7->Name = L"label7";
this->label7->Size = System::Drawing::Size(76, 13);
this->label7->TabIndex = 13;
this->label7->Text = L"Primer Apellido";
//
// label8
//
this->label8->AutoSize = true;
this->label8->Location = System::Drawing::Point(51, 287);
this->label8->Name = L"label8";
this->label8->Size = System::Drawing::Size(90, 13);
this->label8->TabIndex = 14;
this->label8->Text = L"Segundo Apellido";
//
// groupBox1
//
this->groupBox1->Controls->Add(this->label1);
this->groupBox1->Controls->Add(this->label5);
this->groupBox1->Controls->Add(this->label6);
this->groupBox1->Location = System::Drawing::Point(54, 36);
this->groupBox1->Name = L"groupBox1";
this->groupBox1->Size = System::Drawing::Size(376, 122);
this->groupBox1->TabIndex = 15;
this->groupBox1->TabStop = false;

63

this->groupBox1->Text = L"Estado";
//
// enrrol
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode =
System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(473, 541);
this->Controls->Add(this->groupBox1);
this->Controls->Add(this->label8);
this->Controls->Add(this->label7);
this->Controls->Add(this->textBox5);
this->Controls->Add(this->textBox4);
this->Controls->Add(this->Guar_button);
this->Controls->Add(this->button1);
this->Controls->Add(this->textBox3);
this->Controls->Add(this->label4);
this->Controls->Add(this->textBox2);
this->Controls->Add(this->label3);
this->Controls->Add(this->label2);
this->Controls->Add(this->textBox1);
this->Icon = (cli::safe_cast<System::Drawing::Icon^
>(resources->GetObject(L"$this.Icon")));
this->MaximizeBox = false;
this->MaximumSize = System::Drawing::Size(481, 575);
this->MinimumSize = System::Drawing::Size(481, 575);
this->Name = L"enrrol";
this->StartPosition =
System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"Registro de Personal";
this->Load += gcnew System::EventHandler(this,
&enrrol::enrrol_Load);
this->FormClosing += gcnew
System::Windows::Forms::FormClosingEventHandler(this,
&enrrol::enrrol_FormClosing);
this->groupBox1->ResumeLayout(false);
this->groupBox1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
public: System::Void
private: System::Void
System::EventArgs^ e);
private: System::Void
iFingerprintImageSize);
private: System::Void
FT_BYTE* pRegTemplate);
private: System::Void
System::EventArgs^ e);

GetConnetionLinker(MYSQL* connlink);
enrrol_Load(System::Object^ sender,
AddToEnroll(FT_IMAGE_PT pFingerprintImage, int
GuardarArchivo(int iRecommendedRegFtrLen,
button1_Click(System::Object^

64

sender,

private: System::Void enrrol_FormClosing(System::Object^ sender,


System::Windows::Forms::FormClosingEventArgs^ e);
private: System::Void button2_Click(System::Object^ sender,
System::EventArgs^ e);
protected:
virtual void WndProc(Message %m) override{
if (m.Msg == FP_EVENT){
switch((int)m.WParam) {
case WN_COMPLETED: {
this->label5->Text = L"Imagen de la huella
capturada";
DATA_BLOB* pImageBlob =
reinterpret_cast<DATA_BLOB*>((int)m.LParam);
AddToEnroll(pImageBlob->pbData, pImageBlob>cbData);
break;
}
case WN_ERROR: {
MessageBox::Show( "Existio un error interno del
lector", "Error");
break;
}
case WN_DISCONNECT:
this->label6->Text = L"Lector de huellas
digitales desconectado";
break;
case WN_RECONNECT:
this->label6->Text = L"Lector de huellas
digitales conectado";
break;
case WN_FINGER_TOUCHED:
this->label5->Text = L"Huella dactilar
detectada";
break;
case WN_FINGER_GONE:
this->label5->Text = L"Dedo separado del
lector";
break;
case WN_IMAGE_READY:
this->label5->Text = L"Imagen de la huella
dactilar lista";
break;
case WN_OPERATION_STOPPED:
this->label5->Text = L"Fingerprint Enrollment
Operation stopped";
break;
}
}
Form::WndProc(m);
}
};
}

65

A.6. Archivo enroll.cpp

/*****************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0502
Proyeto Electrico
Elaborado por: Luis Castro Leiva

A61368

Resumen: enrrol.cpp
Este archivo contiene las funciones que correponden a
la ventana de registro de nuevo personal, (ver enrrol.h)
y forma parte del cliente de comunicacion con el lector de
huellas digitales U.are.U 4500
******************************************************************/
#include "StdAfx.h"
#include "enrrol.h"
using namespace CRB;
System::Void enrrol::GetConnetionLinker(MYSQL* connlink){
//Almacena el link a la conexion establecida con MySQL
conn = connlink;
}
System::Void enrrol::enrrol_Load(System::Object^
System::EventArgs^ e) {

sender,

FT_RETCODE rc = FT_OK;
HRESULT hr = S_OK;
// Se crea un contexto para realizar una extraccion
pin_ptr<FT_HANDLE> pm_fxContext = &m_fxContext;
if (FT_OK != (rc = FX_createContext(pm_fxContext))) {
MessageBox::Show( "Error en FX_createContext", "Error");
}
// Se crea un contexto para la comparacion
pin_ptr<FT_HANDLE> pm_mcContext = &m_mcContext;
if (FT_OK != (rc = MC_createContext(pm_mcContext))) {
MessageBox::Show( "Error en MC_createContext", "Error");
}
// Se obtiene el numero de pre-plantillas necesarias para la creacion
de una plantilla de huella
// Se asigna memoria a un arreglo que almacena estas pre-plantillas
MC_SETTINGS mcSettings = {0};
if (FT_OK != (rc = MC_getSettings(&mcSettings)))

66

MessageBox::Show( "Error en MC_getSettings", "Error");


m_NumberOfPreRegFeatures = mcSettings.numPreRegFeatures;
if (NULL == (m_TemplateArray = new
FT_BYTE*[m_NumberOfPreRegFeatures]))
MessageBox::Show( "Error en m_TemplateArray", "Error");
::ZeroMemory(m_TemplateArray,
sizeof(FT_BYTE**)*m_NumberOfPreRegFeatures);
// Pone el indice del arreglo en cero, donde sera guardada la primera
pre-plantilla.
m_nRegFingerprint = 0;
// Se usa prioridad Normal para que solo se lean huellas cuando la
// ventana se encuentra activa
DP_ACQUISITION_PRIORITY ePriority = DP_PRIORITY_NORMAL;

HWND pHandle = (HWND)this->Handle.ToPointer();


pin_ptr<HDPOPERATION> pm_hOperationEnroll = &m_hOperationEnroll;
if(S_OK == DPFPCreateAcquisition(ePriority,
GUID_NULL,DP_SAMPLE_TYPE_IMAGE,pHandle,FP_EVENT,pm_hOperationEnroll)){
if(S_OK == DPFPStartAcquisition(m_hOperationEnroll)){
this->label5->Text = L"Inicializacion concluida";
this->label1->Text = L"Coloque el dedo indice derecho para
ser escaneado";
}
}
}

System::Void enrrol::AddToEnroll(FT_IMAGE_PT pFingerprintImage, int


iFingerprintImageSize){
HRESULT hr = S_OK;
FT_BYTE* pPreRegTemplate = NULL;
FT_BYTE* pRegTemplate = NULL;
// No se generan mas pre-plantillas de las necesarias
if (m_nRegFingerprint < m_NumberOfPreRegFeatures) {
FT_RETCODE rc = FT_OK;
// Se obtiene la cantidad recomendada de las plantillas de
pre-registro
int iRecommendedPreRegFtrLen = 0;
rc = FX_getFeaturesLen(FT_PRE_REG_FTR,
&iRecommendedPreRegFtrLen,
NULL);
if (FT_OK != rc)
MessageBox::Show( "Error en FX_getFeaturesLen", "Error");
FT_IMG_QUALITY imgQuality;
FT_FTR_QUALITY ftrQuality;
FT_BOOL bEextractOK = FT_FALSE;

67

if (NULL == (pPreRegTemplate = new


FT_BYTE[iRecommendedPreRegFtrLen]))
MessageBox::Show( "Error en pPreRegTemplate", "Error");
rc = FX_extractFeatures(m_fxContext,
// Contexto
de extraccion
iFingerprintImageSize,
// tamao de la imagen de huella digital
pFingerprintImage,
// Puntero al buffer de imagen
FT_PRE_REG_FTR,
// Solicitud de extraccion de caractersticas
iRecommendedPreRegFtrLen,
// tamao de la plantilla de pre-registro
pPreRegTemplate,
// puntero al buffer que almacena la plantilla de pre-registro
&imgQuality,
// retorna la calidad de imagen
&ftrQuality,
// retorna la calidad de las caractersticas
&bEextractOK);
// retorna el resultado de la extraccion
// Si la extraccin es exitosa se crea una plantilla de preregistro
if (FT_OK <= rc && bEextractOK == FT_TRUE) {
this->label1->Text = L"Pre-Enrollment feature set
generated successfully";
m_TemplateArray[m_nRegFingerprint++] = pPreRegTemplate;
pPreRegTemplate = NULL;
// Se verifica si existen suficientes plantillas de
pre-registro
if (m_nRegFingerprint == m_NumberOfPreRegFeatures) {
int iRecommendedRegFtrLen = 0;
rc = MC_getFeaturesLen(FT_REG_FTR,
0,
&iRecommendedRegFtrLen,
NULL);
if (FT_OK != rc)
MessageBox::Show( "Error en MC_getFeaturesLen",
"Error");
if (NULL == (pRegTemplate = new
FT_BYTE[iRecommendedRegFtrLen]))
MessageBox::Show( "pRegTemplate", "Error");
FT_BOOL bRegSucceeded = FT_FALSE;
rc = MC_generateRegFeatures(m_mcContext,
// Contexto de comparacion
0,
// debe ser 0

68

m_NumberOfPreRegFeatures, // numero de plantillas de pre-registro


iRecommendedPreRegFtrLen, // tamao de una plantilla de preregistro
m_TemplateArray,

// arreglo de plantillas de pre-registro

iRecommendedRegFtrLen,

// tamao de la plantilla

pRegTemplate,
// Pointer to the buffer where the
Enrollment template to be stored
NULL,
// Reservado, debe ser NULL.
&bRegSucceeded);
plantilla

// Resultado de la creacion de la
if (FT_OK <= rc && bRegSucceeded == FT_TRUE) {
// Plantilla generada exitosamente
m_RegTemplate.pbData = pRegTemplate;
m_RegTemplate.cbData =

iRecommendedRegFtrLen;
pRegTemplate = NULL;
this->label1->Text = L"Plantilla de
registro generada exitosamente";
this->label5->Text = L"Close this dialog
and run Verification to verify fingerprint";
}
else {
this->label1->Text = L"La creacion de la
plantilla de registro fallo";
// Existio un error en la creacion de la
plantilla
// entonces se borran las prematriculas realizadas
m_nRegFingerprint = 0;
for (int i=0; i<m_NumberOfPreRegFeatures;
++i)
if(m_TemplateArray[i]) delete []
m_TemplateArray[i], m_TemplateArray[i] = NULL;
}
}
else {
// Continua ejecutandose si no se han terminado
la cantidad de plantilla de
// pre-matricula requeridas
this->label1->Text = L"Coloque el indice derecho
nuevamente";
}
}
else {

69

MessageBox::Show( "Error en la creacin de la plantilla


de pre-registro.", "Error");
}
}
else {
MessageBox::Show( "Una plantilla de registro ya ha sido
creada", "Error");
}
}
System::Void enrrol::GuardarArchivo(int iRecommendedRegFtrLen, FT_BYTE*
pRegTemplate){
if (m_RegTemplate.cbData == 0 || m_RegTemplate.pbData == NULL) {
MessageBox::Show( "Debe crearse una plantilla de huella digital
antes de registrar una persona", "Error");
}
else{
if(this->textBox1->Text != L"" && this->textBox2->Text != L"" &&
this->textBox3->Text != L"" && this->textBox4->Text != L""&& this>textBox5->Text != L""){
//Almacenamiento en el archivo temporal
char archivo[40];
strcpy_s(archivo, 40, "d:\\CRB\\CRB\\Templates\\");
char* cod_ced = new char[9];
cod_ced = (char*)(void*)Marshal::StringToHGlobalAnsi(this>textBox4->Text);
strcat_s(archivo,40,cod_ced);
strcat_s(archivo,40,".crbt");
ofstream out(archivo,ios::binary);
out.write((char*)pRegTemplate,iRecommendedRegFtrLen);
out.close();
//Almacenamiento de la informacio del nuevo empleado en la
base de datos
String^ solicitud =
String::Format(CultureInfo::CurrentCulture,\
"INSERT INTO `crb_db1`.`empleados` (`Nombre` ,`Apellido1`
,`Apellido2` ,`Cedula`,`Departamento` ,`DataTemplate`,`cbData`)VALUES
('{0}', '{1}', '{2}', '{3}' ,'{4}','','{5}');"\
,textBox1->Text,textBox2->Text,textBox3->Text,textBox4>Text,textBox5->Text,iRecommendedRegFtrLen);
sql = (char*)(void*)Marshal::StringToHGlobalAnsi(solicitud);
int len = 0;
len = strlen(sql);
if(!mysql_real_query(conn, sql ,len)){
this->label5->Text = L"Informacion guardada
exitosamente";
}
else{
this->label5->Text = L"Error en la consulta";
}
mysql_res = mysql_store_result(conn);

70

mysql_free_result(mysql_res);
//Creacion de una Tabla en la base de datos para el nuevo
empleado
char nueva_tabla[122];
strcpy_s(nueva_tabla, 122, "CREATE TABLE `crb_db1`.`");
strcat_s(nueva_tabla,122,cod_ced);
strcat_s(nueva_tabla,122,"` (`Fecha` DATE NOT NULL ,`Hora`
TIME NOT NULL ,`Tipo` BOOL NOT NULL) ENGINE = MYISAM ;");
len = strlen(nueva_tabla);
mysql_real_query(conn, nueva_tabla ,len);
mysql_res = mysql_store_result(conn);
mysql_free_result(mysql_res);
}
else{
MessageBox::Show( "Ninguno de los campos de informacion puede
estar vacio", "Error");
}
}
}
System::Void enrrol::button1_Click(System::Object^
System::EventArgs^ e) {
this->Close();
}

sender,

System::Void enrrol::enrrol_FormClosing(System::Object^ sender,


System::Windows::Forms::FormClosingEventArgs^ e) {
//Se detienen los procesos de acquisicion y se eliminan los contextos
//de comparacion y extraccion
if (m_hOperationEnroll) {
DPFPStopAcquisition(m_hOperationEnroll);
DPFPDestroyAcquisition(m_hOperationEnroll);
m_hOperationEnroll = 0;
}
if (m_fxContext) {
FX_closeContext(m_fxContext);
m_fxContext = 0;
}
if (m_mcContext) {
MC_closeContext(m_mcContext);
m_mcContext = 0;
}
if(m_TemplateArray){
//Se eliminan las plantillas de pre-registro
for (int i=0; i<m_NumberOfPreRegFeatures; ++i)
if(m_TemplateArray[i]) delete [] m_TemplateArray[i],
m_TemplateArray[i] = NULL;
delete [] m_TemplateArray;

71

}
}
System::Void enrrol::button2_Click(System::Object^ sender,
System::EventArgs^ e) {
this->GuardarArchivo(m_RegTemplate.cbData, m_RegTemplate.pbData);
}

72

APNDICE B: Cdigo de la interfaz para administracin de


bases de datos CRB
B.1. Archivo cliente.php
<!---------------------------------------------------------Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: cliente.php
Este archivo contiene el codigo HTML de la interfaz de
administracion de Bases de Datos CRB.
----------------------------------------------------------->
<html>
<head>
<script language="JavaScript" type="text/javascript" src="ajax.js"></script>
<title>CRB Data Base Administrator</title>
<style type="text/css">
body {
font-family: Arial, "Times New Roman",
Times, serif;
color: #0174DF;
background-color: #FFFFFF }
h1 {
font-family: Helvetica, Geneva, Arial,
SunSans-Regular, sans-serif }
</style>
</head>
<body>
<h1>Interfaz para administracion de Bases de Datos CRB</h1>
<table align = "center" Border = 0 Cellpadding=4>
<td>
<p>Por medio de esta interfaz se pueden realizar busquedas
de sobre la informacion al almacenada en la base de datos
de CRB</p>
</td>
<td>
<object
type="application/x-shockwave-flash"
data="reloj1.swf"
height="100">
<param name="movie" value="reloj1.swf"></param>
<param name="quality" value="High"></param>
<param name="scale" value="ExactFit"></param>
<param name="wmode" value="transparent"></param>
<param name="loop" value="false"></param>
<param name="menu" value="false"></param>
</object>

73

width="100"

</td>
</table>
<Table align = "center" Border = 1 Cellpadding=4>
<tr>
<td>
<p>Busqueda de personal por Nombre, Primer y Segundo Apellido y Numero de
Cedula</p>
<Form Name="crb_form_busqueda" Action="" Methot="GET">
<Table align = "center" Border Cellpadding=4>
<tr>
<td>Nombre: <INPUT Type="text" Name="nombre" VALUE="" Size=25></td>
<td><Input
Type=button
OnClick="Consultar('query_name.php',this.form);
return
false" Value="Buscar"></td>
</tr>
<tr>
<td>Primer Apellido: <Input Name="apellido1" Value="" Size=16></td>
<td><Input
Type=button
OnClick="Consultar('query_apellido1.php',this.form);
return false" Value="Buscar"></td>
</tr>
<tr>
<td>Segundo Apellido: <Input Name="apellido2" Size=15></td>
<td><Input
Type=button
OnClick="Consultar('query_apellido2.php',this.form);
return false" Value="Buscar"></td>
</tr>
<tr>
<td>Cedula: <Input Name="cedula" Size=27></td>
<td><Input Type=button OnClick="Consultar('query_cedula.php',this.form); return
false" Value="Buscar"></td>
</tr>
</Table>
<p
Align
=
"center"><Input
OnClick="document.getElementById('resultado').innerHTML
=
resultados" Size=27></p>
<div id="resultado"></div>

''"

Type=button
Value="Limpiar

</Form>
</td>
<td rowspan="2">
<p Align = "center">Registro de Marcas de personal por Numero de Cedula</p>
<Form Name="crb_form_marcas" Action="" Methot="GET">
<Table align = "center" Border Cellpadding=4>
<tr>
<td>Cedula: <INPUT Type="text" Name="cedula" VALUE="" Size=25></td>
<td><Input
Type=button
OnClick="ConsultarMarcas('query_marcas.php',this.form);
return false" Value="Buscar"></td>
</tr>
</Table>
</Form>
<p
Align
=
"center"><Input
Type=button
OnClick="document.getElementById('marcas').innerHTML
=
''"
Value="Limpiar
resultados" Size=27></p>
<div id="marcas"></div>
</td>
</tr>

74

<tr>
<td>
<Form>
<p align = "center">Eliminacion de Usuarios por numero de Cedula</p>
<Table align = "center" Border Cellpadding=4>
<tr>
<td>Cedula: <Input Name="cedula_eliminar" Size=27></td>
<td><Input Type=button OnClick="Eliminar('query_eliminar.php',this.form); return
false" Value="Eliminar"></td>
</tr>
</Table>
<p
Align
=
"center"><Input
Type=button
OnClick="document.getElementById('resultado_eliminar').innerHTML
=
''"
Value="Limpiar resultados" Size=27></p>
<div id="resultado_eliminar"></div>
</Form>
</td>
</tr>
</table>
<p Align = "center">2009, Sistema CRB</p>
</body>
</html>

B.2. Archivo ajax.js


/***********************************************************************
Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: ajax.js
Este archivo contiene el codigo JAVASCRIPT necesario por la de la
interfaz de administracion de Bases de Datos CRB. En el se crea un objeto
Ajax para establecer comunicacion asincronica con PHP y este en ultimo
enlaza con MySQL
***********************************************************************/
//La funcion objetoAjax hace que la aplicacin sea transparente al
navegador
//utilizado debido a que independientemente de cual sea, se crea un
objeto ajax
function objetoAjax(){
var xmlhttp=false;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");

75

} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
//La funcin Consultar se encarga de llamar el script de PHP por medio
//del objeto ajax creado al llamar la funcion objetoAjax
function Consultar(datos,form){
var nombre = form.nombre.value;
var apellido1 = form.apellido1.value;
var apellido2 = form.apellido2.value;
var cedula = form.cedula.value;
divResultado = document.getElementById('resultado');
ajax=objetoAjax();
ajax.open("GET",
datos+"?nombre="+nombre+"&apellido1="+apellido1+"&apellido2="+apellido2+"
&cedula="+cedula);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
}
}
ajax.send(null)
}
function Eliminar(datos,form){
var cedula_eliminar = form.cedula_eliminar.value;
divResultado = document.getElementById('resultado_eliminar');
ajax=objetoAjax();
ajax.open("GET", datos+"?cedula="+cedula_eliminar);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
}
}
ajax.send(null)
}
function ConsultarMarcas(datos,form){
var cedula = form.cedula.value;

76

divResultado = document.getElementById('marcas');
ajax=objetoAjax();
ajax.open("GET", datos+"?cedula="+cedula);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
divResultado.innerHTML = ajax.responseText
}
}
ajax.send(null)
}

B.3. Archivo query_name.php


<!--------------------------------------------------------Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: query_name.php
Este archivo contine el codigo en PHP que realiza busquedas
en la base de datos de CRB por el campo nombre y retorna los
resultados de la busqueda.
----------------------------------------------------------->
<?php
//Configuracion de la conexion a base de datos
$host = "localhost";
$usuario = "admin";
$password = "crb";
$base = "crb_db1";
$link = mysql_connect($host, $usuario, $password);
//Seleccin de la base de datos a usar
mysql_select_db($base, $link);
//consulta todos los empleados
if($_GET["nombre"]){
$sql=mysql_query("SELECT * FROM `empleados` WHERE Nombre =
'".$_GET['nombre']."'",$link);
$num_rows = mysql_num_rows($sql);
if($num_rows == NULL)
echo "<p align =\"center\">No hay resultados de la busqueda por
nombre</p>\n";
else
echo "<p align =\"center\">Nombre | Primer Apellido | Cedula </p>
\n";
while($row = mysql_fetch_array($sql)){

77

echo "<p align =\"center\">".$row['Nombre']." |


".$row['Apellido1']." | ".$row['Cedula']."</p> \n";
}
mysql_free_result($sql);
}
else{
echo "<p align =\"center\">No hay nombre elegido para realizar la
busqueda</p>";
}
?>

B.4. Archivo query_apellido1.php


<!--------------------------------------------------------Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: query_apellido1.php
Este archivo contine el codigo en PHP que realiza busquedas
en la base de datos de CRB por el campo apellido1 y retorna
los resultados de la busqueda.
----------------------------------------------------------->
<?php
//Configuracion de la conexion a base de datos
$host = "localhost";
$usuario = "admin";
$password = "crb";
$base = "crb_db1";
$link = mysql_connect($host, $usuario, $password);
//Seleccin de la base de datos a usar
mysql_select_db($base, $link);
//consulta todos los empleados
if($_GET["apellido1"]){
$sql=mysql_query("SELECT * FROM `empleados` WHERE Apellido1 =
'".$_GET['apellido1']."'",$link);
$num_rows = mysql_num_rows($sql);
if($num_rows == NULL)
echo "<p align =\"center\">No hay resultados de la busqueda por
primer apellido</p>\n";
else
echo "<p align =\"center\">Nombre | Primer Apellido | Segundo
Apellido | Cedula </p> \n";
while($row = mysql_fetch_array($sql)){

78

echo "<p align =\"center\">".$row['Nombre']." |


".$row['Apellido1']." | ".$row['Apellido2']." | ".$row['Cedula']."</p> \n";
}
mysql_free_result($sql);
}
else{
echo "<p align =\"center\">No hay un apellido elegido para realizar la
busqueda</p>";
}
?>

B.5. Archivo query_apellido2.php

<!--------------------------------------------------------Universidad de Costa Rica


Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: query_apellido2.php
Este archivo contine el codigo en PHP que realiza busquedas
en la base de datos de CRB por el campo Apellido2 y retorna
los resultados de la busqueda.
----------------------------------------------------------->
<?php
//Configuracion de la conexion a base de datos
$host = "localhost";
$usuario = "admin";
$password = "crb";
$base = "crb_db1";
//Establece la conexion con MySQL
$link = mysql_connect($host, $usuario, $password);
//Seleccin de la base de datos a usar
mysql_select_db($base, $link);
//consulta en la tabla empleados el campo Apellido2
if($_GET["apellido2"]){
$sql=mysql_query("SELECT * FROM `empleados` WHERE Apellido2 =
'".$_GET['apellido2']."'",$link);
$num_rows = mysql_num_rows($sql);
if($num_rows == NULL)
echo "<p align =\"center\">No hay resultados de la busqueda por
segundo apellido</p>\n";
else

79

echo "<p align =\"center\">Nombre | Primer Apellido | Segundo


Apellido | Cedula </p> \n";
while($row = mysql_fetch_array($sql)){
echo "<p align =\"center\">".$row['Nombre']." |
".$row['Apellido1']." | ".$row['Apellido2']." | ".$row['Cedula']."</p> \n";
}
mysql_free_result($sql);
}
else{
echo "<p align =\"center\">No hay un apellido elegido para realizar la
busqueda</p>";
}
?>

B.6. Archivo query_cedula.php


<!--------------------------------------------------------Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: query_cedula.php
Este archivo contine el codigo en PHP que realiza busquedas
en la base de datos de CRB por el campo Cedula y retorna
los resultados de la busqueda.
----------------------------------------------------------->
<?php
//Configuracion de la conexion a base de datos
$host = "localhost";
$usuario = "admin";
$password = "crb";
$base = "crb_db1";
$link = mysql_connect($host, $usuario, $password);
//Seleccin de la base de datos a usar
mysql_select_db($base, $link);
//consulta todos los empleados
if($_GET["cedula"]){
$sql=mysql_query("SELECT * FROM `empleados` WHERE Cedula =
'".$_GET['cedula']."'",$link);
$num_rows = mysql_num_rows($sql);
if($num_rows == NULL)
echo "<p align =\"center\">No hay resultados de la busqueda por
cedula</p>\n";
else

80

echo "<p align =\"center\">Nombre | Primer Apellido | Segundo


Apellido | Cedula </p> \n";
while($row = mysql_fetch_array($sql)){
echo "<p align =\"center\">".$row['Nombre']." |
".$row['Apellido1']." | ".$row['Apellido2']." | ".$row['Cedula']."</p> \n";
}
mysql_free_result($sql);
}
else{
echo "<p align =\"center\">No hay un numero de cedula elegido para realizar
la busqueda</p>";
}
?>

B.7. Archivo query_marcas.php


<!--------------------------------------------------------Universidad de Costa Rica
Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: query_marcas.php
Este archivo contine el codigo en PHP que realiza busquedas
en la base de datos de CRB de las marcas de acceso de personal
y retorna los resultados de la busqueda.
----------------------------------------------------------->
<?php
//Configuracion de la conexion a base de datos
$host = "localhost";
$usuario = "admin";
$password = "crb";
$base = "crb_db1";
$link = mysql_connect($host, $usuario, $password);
//Seleccin de la base de datos a usar
mysql_select_db($base, $link);
//consulta todos los empleados
if($_GET["cedula"]){
$sql=mysql_query("SELECT * FROM `".$_GET['cedula']."`",$link);
if($sql != 0){
$num_rows = mysql_num_rows($sql);
if($num_rows == NULL)
echo "<p align =\"center\">No hay marcas para esta
persona</p>\n";

81

else
echo "<p align =\"center\">Fecha | Hora </p> \n";
while($row = mysql_fetch_array($sql)){
echo "<p align =\"center\">".$row['Fecha']." |
".$row['Hora']."</p> \n";
}
mysql_free_result($sql);
}
else{
echo "<p align =\"center\">No se encuentra registrada una persona
con esta cedula</p>";
}
}
else{
echo "<p align =\"center\">Debe llenar el espacio dado para realizar la
busqueda</p>";
}
?>

B.8. Archivo query_eliminar.php

<!--------------------------------------------------------Universidad de Costa Rica


Escuela de Ingenieria Electrica
II Semestre 2009
IE-0529
Proyecto Electrico
Elaborado por: Luis Castro Leiva A61368
Resumen: query_eliminar.php
Este archivo contine el codigo en PHP que elimina una fila
correspondiente a un numero de cedula suministrado via GET
en la base de datos crb_db1 y la tabla de registro de accesos
correspondiente a ese numero de cedula
----------------------------------------------------------->
<?php
//Configuracion de la conexion a base de datos
$host = "localhost";
$usuario = "admin";
$password = "crb";
$base = "crb_db1";
//establece conexion con la base de datos MySQL
$link = mysql_connect($host, $usuario, $password);
//Seleccin de la base de datos a usar
mysql_select_db($base, $link);

82

if($_GET["cedula"]){
$sql1=mysql_query("DELETE FROM `crb_db1`.`empleados` WHERE
Cedula=".$_GET['cedula'],$link);
$sql2=mysql_query("DROP TABLE `".$_GET['cedula']."`",$link);
if (($sql1 == 1) && ($sql2 == 1)){
echo "<p align =\"center\">Se ha eliminado la persona
adecuadamente</p";
}
}
else{
echo "<p align =\"center\">No se encuentra registrada una persona con esta
cedula</p>";
}
?>

83

Apndice C: Sentencia de SQL para la creacin de la base de


datos crb_db1.
CREATE TABLE `crb_db1`.`empleados` (
`Nombre` CHAR( 20 ) NOT NULL ,
`Apellido1` CHAR( 20 ) NOT NULL ,
`Apellido2` CHAR( 20 ) NOT NULL ,
`Cedula` INT NOT NULL ,
`Departamento` CHAR( 20 ) NOT NULL ,
`DataTemplate` BLOB NOT NULL ,
`cbData` INT NOT NULL
) ENGINE = MYISAM ;

84

Apndice D: Funciones del Dispositivo utilizas.


o HRESULT DPFPInit();
Valores de Retorno

S_OK

operacin exitosa

S_FALSE

librera ya inicializada.

0x800706B3

el servidor RPC no est escuchando, lo que significa que el

Servicio Biomtrico de Inicializacin no ha sido iniciado.

Descripcin: Inicializa los recursos necesarios y hace las asignaciones de memoria


necesarias para empezar la comunicacin con el lector de huellas digitales. Debe ser
llamado antes de cualquier funcin del API, con excepcin de DPFPBufferFree.

o HRESULT DPFPTerm();
Valores de Retorno

S_OK

operacin exitosa

Descripcin: Libera recursos asignados por DPFPInit().

o HRESULT DPFPCreateAcquisition(
DP_ACQUISITION_PRIORITY eAcquisitionPriority,
REFGUID DevUID,
ULONG uSampleType,

85

HWND hWnd,
ULONG uMsg,
HDPOPERATION * phOperation);
Parametros

eAcquisitionPriority: las aplicaciones que se conectan con el lector de huellas digitales


pueden elegir entre tres niveles de prioridad: alto, normal y bajo. En el nivel alto de
prioridad todos los eventos generados por el U.are.U 4500 sern enviados al cliente
suscrito y solo puede existir uno de este tipo. En nivel normal pueden haber varios
clientes suscritos pero la informacin ser enviado a que est como ventana activa. En
el nivel ms bajo toda la informacin ser enviada a l aunque no se encuentre activo.

DevUID: numero de serie del lector a utilizar, GUID_NULL si cualquier lector puede
ser utilizado.

uSampleType: Este parmetro debe ser DP_SAMPLE_TYPE_IMAGE.

hWnd: Handle de la ventana a ser notificada de los eventos.

uMsg: Mensaje a ser enviado como la notificacin del evento

phOperation: puntero al handle de la operacin a ser llenado si la operacin es creada


exitosamente.

Valores de Retorno

S_OK

operacin exitosa

E_ACCESSDENIED

se intenta suscribir una aplicacin como cliente pero

no se tiene permisos para esto

86

E_INVALIDARG

ya existe una aplicacin cliente suscrita con prioridad

alta.
Descripcin: Crea una operacin de adquisicin.

o HRESULT DPFPStartAcquisition(HDPOPERATION hOperation);


Parametros
hOperation: Handle de la operacin.
Valores de Retorno

S_OK

operacin exitosa

Descripcin: Suscribe una aplicacin cliente para recibir notificacin de eventos del
hardware.

o HRESULT DPFPStopAcquisition(HDPOPERATION hOperation);


Parametros
hOperation: Handle de la operacin.
Valores de Retorno

S_OK

operacin exitosa

Descripcin: Se elimina la suscripcin de alguna aplicacin cliente para y se liberan


recursos asignados para esto.

o HRESULT DPFPDestroyAcquisition(HDPOPERATION hOperation);

87

Parametros
hOperation: Handle de la operacin.
Valores de Retorno

S_OK

operacin exitosa

Descripcin: Elimina la operacin creada por DPFPCreateAcquisition y libera los


recursos asociados.

88

2.7.1

Funciones de extraccin

o FX_DLL_INTERFACE FT_RETCODE FX_init(void);


Valores de Retorno

S_OK

operacin exitosa

FT_ERR_NO_MEMORY

no se encontr suficiente memoria para iniciar

el mdulo de extraccin

FT_ERR_BAD_INI_SETTING

la configuracin de inicializacin ha sido

corrompida.
Descripcin: Inicializa el mdulo de extraccin de huellas digitales, inicializa la estructura
MC_SETTINGS y las tablas de bsqueda para comparacin. Debe ser ejecutada antes que
cualquier funcin del mdulo de extraccin.

o FX_DLL_INTERFACE FT_RETCODE FX_Terminate(void);


Valores de Retorno

FT_OK

FT_WRN_NO_INIT

operacin exitosa
el modulo de extraccin no ha sido inicializado.

Descripcin: Cierra el mdulo de extraccin y libera los recursos asociados

89

o FX_DLL_INTERFACE FT_RETCODE FX_createContext(


OUT FT_HANDLE *fxContext);
Parametros
fxContext: Puntero a la direccin de memoria donde se localiza el handle del contexto.
Valores de Retorno

FT_OK

operacin exitosa

FT_ERR_NO_INIT

FX_INIT no ha sido llamada

FT_ERR_INVALID_CONTEXT

no hay suficiente memoria para crear el

contexto.
Descripcin: Crea un contexto de extraccin, si la operacin es exitosa retorna un
HANDLE que apunta al contexto creado.
o FX_DLL_INTERFACE FT_RETCODE FX_closeContext(
OUT FT_HANDLE* fxContext);
Parametros
fxContext: handle del contexto a cerrar.
Valores de Retorno

operacin exitosa

FT_OK

Descripcin: Cierra un contexto de extraccin.

90

2.7.2

Funciones de comparacin

o FX_DLL_INTERFACE FT_RETCODE MC_init(void);


Valores de Retorno

S_OK

operacin exitosa

FT_ERR_NO_MEMORY

no se encontr suficiente memoria para iniciar

el mdulo de comparacin

FT_ERR_BAD_INI_SETTING

la configuracin de inicializacin ha sido

corrompida.
Descripcin: Inicializa el mdulo de comparacin extraccin de huellas digitales,
inicializa. Debe ser ejecutada antes que cualquier funcin del mdulo de extraccin.

o FX_DLL_INTERFACE FT_RETCODE MC_Terminate(void);


Valores de Retorno

FT_OK

FT_WRN_NO_INIT

operacin exitosa
el modulo de comparacin no ha sido inicializado.

Descripcin: Cierra el mdulo de comparacin y libera los recursos asociados.

91

o FX_DLL_INTERFACE FT_RETCODE MC_createContext(


OUT FT_HANDLE* mcContext);
Parametros
mcContext: Puntero a la direccin de memoria donde se localiza el handle del contexto.
Valores de Retorno

FT_OK

operacin exitosa

Descripcin: Crea un contexto de comparacin, si la operacin es exitosa retorna un


HANDLE que apunta al contexto creado.
o FX_DLL_INTERFACE FT_RETCODE MC_closeContext(
OUT FT_HANDLE* mcContext);
Parametros
mcContext: handle del contexto a cerrar.
Valores de Retorno

FT_OK

operacin exitosa

Descripcin: Cierra un contexto de comparacin.

92

ANEXOS

Sistema CRB
Versin Alfa
MANUAL DEL USUARIO

93

Bienvenido a CRB

Bienvenido. Este documento pretende ser una gua para el manejo de la versin
Alfa del sistema CRB. Aqu encontrar toda la informacin sobre las capacidades del
programa y podr adquirir los elementos necesarios para hacer uso del mismo.
CRB es una aplicacin que le permitir estar al tanto de las horas de entrada y salida
del personal a su empresa. Este software cuenta con dos partes fundamentales: una interfaz
Web y el programa CRB que registra las marcas del personal y le permite registrar nuevos
usuarios.

Proceso de Instalacin
Por el momento, por ser esta una versin alfa, el proceso de instalacin no est
automatizado por lo cual se requiere la instalacin de personal capacitado en el tema.

Manejo del Sistema.


El programa CRB.
Para iniciar con el registro de entradas y salidas abra la aplicacin CRB. Una vez
abierta podr ver la ventana principal del programa como se muestra a continuacin. En
esta ventana puede elegir uno de los dos modos de operacin de la aplicacin CRB segn lo
que desee hacer.

94

Figura 1. Ventana principal


Si desea registrar un nuevo empleado en la base de datos del programa haga click en
Registrar nuevo personal, si desea registrar las salidas y entradas de personal a la
empresa haga click en Registrar marcas de personal.

Cmo agregar un nuevo usuario


Una vez que dio click en Registrar nuevo personal ver la siguiente ventana.

95

Figura 2. Ventana de Registro de nuevo personal.


Siga lo siguientes pasos:

Introduzca todos los datos solicitados de la persona

Solicite a la persona a registrar que coloque el dedo sobre el lector y luego lo retire.

Repita el procedimiento anterior tres veces ms o hasta que aparezca en la lnea


superior del rea de estado la sentencia: La plantilla de registro ha sido generada
exitosamente

Haga click en el botn Guardar.

96

Revise que en la segunda lnea del rea de estado se encuentre la sentencia La


informacin ha sido guardada exitosamente, en caso de no ser as salga y vuelva a
intentar todo el procedimiento.

Haga click en el botn salir y vuelva a entrar si se desea registrar un nuevo usuario.

Cmo registrar marcas de personal


Desde la ventana principal, entre al modo de control de acceso haciendo click sobre
el botn Registrar marcas de personal. Podr observar entonces la ventana que se muestra
en la siguiente figura:

Figura 3. Ventana de control de acceso.


Aqu los empleados nada ms deben colocar el dedo que fue registrado y asegurarse
de que en el rea de estado se informe del resultado de la marca. En caso de que se

97

informara de algn error, se debe volver a colocar el dedo hasta que el rea de estado
notifique lo contrario

Interfaz para la administracin de bases de datos CRB


Aqu el encargado de recursos humanos puede realizar las siguientes tres
operaciones:

Realizar bsqueda de la informacin del personal por nombre, apellidos o cdula.

Revisar las marcas de alguna persona.

Eliminar usuario registrado.

Figura 4. Interfaz Web.

98

Solamente se debe acceder al sitio Web habilitado por la empresa para tal fin y llenar
los espacios requeridos para realizar las bsquedas, las consultas o la eliminacin.
Para realizar consultas de las marcas o eliminar usuarios debe conocerse el nmero de
cdula de la persona que se desea sacar del registro principal, y este es el dato que se debe
introducir en los espacios asignados para este fin.

99

100