Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - Littlehorse

#1
Renovamos la encuesta como siempre. Las anteriores encuestas se pueden ver aquí
La cantidad de opciones posibles es 5 como en la anterior encuesta por el mismo motivo: Nadie usa mas de 5 lenguajes en el día a día, en reglas generales se usan 2 o 3 como máximo (obviamente hay excepciones).
En el periodo de los últimos 3 meses, cuales fueron los lenguajes que mas utilizaron? esos son los que deben ir en la votación. :)
Recuerden, no es una competencia para ver quien conoce mas lenguajes, así que traten de ser objetivos con los votos. Que lenguajes utilizan habitualmente?

Compartan sus experiencias con los diferentes lenguajes de programación, quejas y recomendaciones.

Saludos!


#2
Foro Libre / Deadlines!
3 Diciembre 2011, 21:27 PM
 [youtube=425,350]http://www.youtube.com/watch?v=jgvx9OfZKJw&feature=share[/youtube]

Dedicado para todos los que lidiamos con deadlines en el día a día.  :D
#3

Rusty Hearts es un MMORPG desarrollado por Stairway Games y publicado por Windysoft en Korea. PWI ha firmado para sumarlo a su catalogo de juegos y aparentemente lo mostrara en la E3 de este año.

Aparentemente es orientado a acción masiva al estilo Vindictus y por lo que se puede ver por los videos, implementado mediante instancias (sin mundo persistente).

No hay mucha información como requerimientos y demás, pero con el tiempo irán revelando mas detalles.



CitarWINDYSOFT FIRST RUSTY HEARTS LICENSING DEAL WITH PERFECT WORLD ENTERTAINMENT

    FOSTER CITY, Calif. – January 12, 2011 Perfect World Entertainment Inc., a wholly owned US subsidiary of Perfect World Co., Ltd. (NASDAQ: PWRD), announced today that it has signed a licensing agreement with WindySoft to operate "Rusty Hearts" in North America. "Rusty Hearts" is a visual action MORPG developed by Stairway Games, and WindySoft possesses the global publishing right.

    "Rusty Hearts," with its advanced action features and game-play design, has received great attention of players and publishers from North America and Asia even before its closed beta testing. With this first overseas licensing agreement before its open beta testing in Korea, "Rusty Hearts" has shown its high potential in the global market. "Rusty Hearts" is scheduled to be introduced to North American players by Perfect World Entertainment at the Electronic Entertainment Expo 2011 ("E3 2011″).

    "We are very glad to announce this licensing deal with Perfect World Entertainment, one of the most successful publishers based in North America, at the beginning of the New Year," said Chil Hyun Baek, CEO for WindySoft. "Perfect World Entertainment has the solid know-how of the industry and the North American market, and we will be providing them the best support to successfully launch 'Rusty Hearts' to North American players."

    "It's our great pleasure working with WindySoft on the 'Rusty Hearts' title. As 'Rusty Hearts' is an action-based MORPG, which differs from our existing game portfolio in genre, we believe it will help us extend our market penetration while also bringing new and unique online gaming experiences to our players," said Alan Chen, CEO for Perfect World Entertainment Inc. "We will work closely with WindySoft on the localization to provide our North American players another high quality game with excellent service."
#4
Sony ha decidido convertir otro de sus títulos al modelo de negocios "Free to Play". En este caso es un MMORPG con temática pirata. Es un juego bastante pulido, ya que tiene un tiempo considerable de desarrollo a la par que se encontraba en un modelo de pago por suscripción.

El juego tiene una complejidad bastante abultada si se compara con la mayoria de los MMORPG free to play, ya que el juego gira en torno a un sistema político y económico. Esa complejidad puede ser una ventaja para algunos y un defecto para otros, ya que a algunos tipos de usuarios les agradan los juegos mas simples y a otros les gusta tener que lidiar con la dificultad.

Tiene un poco del "Uncharted Waters" y otro poco de "Voyage Century". En mi opinión vale la pena probarlo, sobre todo para los que están un tanto cansados de la temática fantasía al estilo mago/guerrero/sacerdote.

En otros titulos que Sony ha convertido al modelo Free to Play, las restricciones para los usuarios gratuitos eran inmensas. Un ejemplo es el "EverQuest 2", pero en este caso las restricciones entre los tipos de suscripciones son nimias.

Trailer:
[youtube=425,350]http://www.youtube.com/watch?v=EmzGFEbtD54&feature=channel[/youtube]

Gameplay:
[youtube=425,350]http://www.youtube.com/watch?v=ihw0PuudooE&feature=related[/youtube]


No soy de postear mucho por estos lares pero me parece que cuando un titulo de estos se vuelve "gratis" vale la pena darle un vistazo. :D

Web:
http://www.burningsea.com/page/home


Saludos!
#5
El periodo de entrega ha finalizado, dando paso al periodo de votaciones.



Antes que nada quiero decir que me alegra mucho la aceptación que ha tenido el concurso. Gracias a ustedes queda un precedente muy positivo en cuanto a la futura organización de otras ediciones de este concurso, y por que no, de la creación de otros concursos similares.

De mi parte, y de parte de todo el staff de elhacker.net, quiero felicitar a todos los que han participado, ya que independientemente de quienes estén en los primeros puestos, todos son ganadores al participar.
Especiales felicitaciones a las personas que decidieron involucrarse en el concurso a pesar de tener poco tiempo en el mundo de la programación, y a los que no son nuevos pero han tenido complicaciones con sus horarios, y así y todo han sacado tiempo de donde no lo hay para poder estar. Doy fe que se han esforzado bastante para participar y eso vale mucho para todos nosotros.

Espero que se hayan divertido programando y que hayan aprendido algo nuevo en el camino.

Comienzan las votaciones!


Lista de aplicaciones:






Concurso finalizado

Quiero felicitar de parte de todo el staff de elhacker.net, a todos los participantes de este concurso, ya que como siempre dije, gracias a su esfuerzo programando este concurso fue posible.

No puedo expresar mucho mas de lo que ya dije cuando termino la presentación, pero no esta de mas decir que personalmente fue un placer revisar las aplicaciones y analizar los códigos, chequear si utilizaban buenas practicas, revisar las cosas bien hechas, revisar las que estaban mal. Es un poco de lo que se trata una de las áreas de este mundo de la informática y de elhacker.net y creo es lo que a todos nos gusta.

Vamos a lo que todos quieren ver, los resultados, que vienen con algunas sorpresas que no serán del agrado de algunos, pero para ser justos es lo correcto:

Datos del concurso

Votos totales: 140 votos.
Porcentaje de las menciones: 5% cada una, es decir, 7 votos extra por cada mención.
Aplicaciones presentadas: 19 aplicaciones!.




Menciones especiales

Mejor código:
DLL Genius, Neural, TurboTron.

Idea Innovadora:
DLL Genius





Posiciones

Primer puesto:
DLL Genius: 25 votos (11+7+7)

Segundo puesto:
TurboTron: 11 votos (4+7)

Tercer puesto:
Notas por red: 9 votos ()
PyMSE: 9 votos ()





Creo que no me olvido de nada. Los ganadores favor de comunicarse con el-brujo para tratar el tema de los premios.
Nuevamente, felicitaciones a todos y a prepararse para el próximo concurso

Saludos!
#6
Foro Libre / Nadie se anima a banearme :D...
4 Noviembre 2010, 03:44 AM
...mucho menos Skapunky que cuando cumple años se pone mansito  :xD ;D, FELIZ CUMPLEAÑOSSSS SKAA ;-) ;-) ;-) ;-) ;-) ;-) ;-)



#7
Este tema tiene como objetivo recopilar términos de uso frecuente en este apartado del foro y definirlos de forma informal teniendo en cuenta el contexto en el que se encuentran. Es decir, no se trata de una definición de diccionario ni de un artículo de la wikipedia entero, se trata de una breve definición añadiendo datos interesantes relacionándolos con el subforo.

Pueden aportar los términos que quieran con o sin su definición correspondiente, los iremos poniendo en este post y creando el glosario. Los términos pueden estar compuestos por varias palabras y las definiciones se modificaran para crear un conjunto mas o menos uniforme (extensión, registro del lenguaje utilizado...).

Esperamos hacer entre todos un recopilatorio de términos que sea útil y sobre todo ameno a la lectura.

Gracias por participar!




Glosarios creados:
Criptografía
Redes
Programación
Seguridad
Hacking Wireless



Indice alfabético

A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z




Terminos:

A
Acumulador
Algoritmo
Alpha


B
Beta
Bottom-Up
Buffer



C
Camelcase
Compilador
Constante



D


E


F


G


H


I
Interprete



J


K


L


M


N
Nivel de complejidad:


O


P
Pascalcase
Pseudocodigo



Q


R


S


T
Top-Down:


U


V
Variable



W


X


Y


Z




Acumulador: Variable que sirve para llevar una suma o el resultado de un conjunto de operaciones.

Algoritmo: Por definición es un conjunto finito de instrucciones para llevar a cabo una tarea, y de esta forma resolver un problema puntual. Estas instrucciones deben ser precisas y de ser posible, eficientes.
Los algoritmos se implementan en forma de sentencias en el o los lenguajes de programación que se hayan elegido, dependiendo de esto ultimo el paradigma utilizado.
Los algoritmos pueden ser representados en forma gráfica, comúnmente utilizando diagramas de flujo. De esta forma son facilmente comprensibles, sobre todo para personas no relacionadas con la programación.

Alpha: Una versión Alpha es una versión "precoz" de un software. Una versión alpha puede no contener todas las características de la versión final. Normalmente todo software pasa, antes de su lanzamiento, por dos etapas. Esta es la primera etapa (Alpha) y normalmente está disponible solo para usuarios internos y desarrolladores. La segunda etapa, beta, generalmente implica a un número limitado de usuarios pero estos sí pueden o no ser internos. Las versiones alpha en su mayoría de los casos no son estables y no es recomendado su uso para usuarios finales.

Beta Implementa todas las características de los requerimientos iniciales. Posiblemente tenga algunos fallos menores y es usada normalmente para testing y demostraciones. Los usuarios que usan esta versión son llamados [Beta Testers] y normalmente su función es la de reportar los fallos para que sean corregidos en la versión final.

Bottom-Up: Método opuesto al Top-Down. Consiste en afrontar el problema desde los niveles de complejidad más bajos, partiendo desde la base de código a usar, e ir luego construyendo los niveles de complejidad mas altos hasta completar la solución.

Buffer: Porción de memoria que se utiliza para almacenar datos en pos de procesarlos, validarlos u realizar cualquier otro tipo de operación con ellos.

Camelcase: Es similar a PascalCase, salvo que la primera letra de la primera palabra va en minúsculas. Ejemplo: numeroCuenta.

Compilador: Es un programa que se encarga de generar una aplicacion partiendo de un código fuente base, traduciendo este ultimo a un lenguaje que la maquina sea capaz de comprender (Código maquina, o usualmente denominado código nativo). El objetivo principal de los compiladores es permitir a los programadores codificar en un lenguaje de programación mucho mas cercano a como piensa un ser humano.

Constante: Valor o conjunto de valores que permanecen invariables durante la ejecución de la aplicación.

Interprete: Cumple un objetivo similar al del compilador solo que implementado de una manera bastante distinta. El interprete analiza, traduce y ejecuta las sentencias a medida que se van requiriendo, ya sea partiendo de un código fuente base u de un código intermedio. Esto genera un rendimiento menor a un programa compilado, ya que las tareas que se realizan en tiempo de compilación, un lenguaje interpretado debe realizarlas en cada ejecución, no obstante los lenguajes interpretados poseen mayor flexibilidad, dado que no dependen de la maquina en la cual están siendo ejecutados si no del interprete.


Nivel de complejidad: Un nivel de complejidad se entiende como una división de la parte que forma una solución a un problema vista esta como una gran pirámide, donde un conjunto de funcionalidades forman otra o varias otras, que a su vez pueden ser usadas para formar otras tantas.

Top-Down: Método que consiste en afrontar el problema desde los niveles de complejidad mas altos, e ir luego solucionando las partes del problema que permite que el código anterior funcione.

Pascalcase: Es una práctica de programación que consiste en declarar funciones y/o variables mediante varias palabras sin espacios, escribiendo en mayúsculas la primera letra de cada palabra. Ejemplo: CreateRemoteThread.

Pseudocodigo: El pseudocodigo es un falso lenguaje de programación donde sus características mas importantes es su semejanza con el lenguaje humano y la posibilidad de representar soluciones en forma abstracta.
Principalmente utilizado por los aprendices de programación para adentrarse en la lógica y en el desarrollo de algoritmos, dado que el pseudocodigo es una manera abstracta de representarlos sin necesidad de involucrarse con un lenguaje en especifico. No obstante también es utilizado por programadores profesionales para representar en forma simple y comprensible las soluciones que hayan creado en pos que otros programadores puedan comprender mas fácilmente la lógica utilizada, o bien para representar las ideas que se generen en la etapa previa del desarrollo.

Variable: Básicamente es un contenedor, una estructura que contiene los datos que se le hayan asignados hasta que se le asigne otro valor u el programa finalice su ejecución. Por supuesto el escenario puede variar dependiendo de los lenguajes, lo que se este haciendo y como, pero la idea principal es ver a una variable como un espacio en memoria al cual le podemos asignar datos, que dependerán del tipo que sea la variable.

#8

Concurso de desarrollo de aplicaciones

Llego el dia del concurso. Esta es la oportunidad para comenzar a desarrollar lo que gusten en el lenguaje que deseen y demostrar lo que pueden hacer.
Es una competencia, pero la idea principal es divertirse, pasarla bien, y aprender entre todos con los proyectos que se expongan.
Cualquiera, y repito, cualquiera puede participar. No hace falta ser ningún guru en ningún lenguaje, solo tener un poco de imaginación y ganas de programar. :D

Premios


  • Primer puesto:

Directo de la tienda oficial de elhacker.net, una alfombrilla de ratón con la posibilidad de elegir entre dos diseños!



+ una cuenta de @elhacker.net!

  • Segundo puesto:: Una cuenta de @elhacker.net!
  • Tercer puesto:: Una cuenta de @elhacker.net!



  • El resto: Haberse divertido en el desarrollo y de seguro haber aprendido algo nuevo. Y por supuesto, la satisfacción de pasar un buen rato programando y compartiendo sus experiencias con la comunidad.


Bases del concurso:

Para participar hay que desarrollar una herramienta y presentarla junto con su código correspondiente. Tanto el objetivo de la aplicacion como el lenguaje a utilizar son de libre elección, por lo tanto hay basicamente una gran libertad para desarrollar lo que sea respecto del área que mas les agrade a cada uno.

Por supuesto, la aplicacion debe ser open source, ya que de esta forma podemos apreciar el espectro completo de la herramienta al poder ver su codigo completamente.

El post para participar debe tener una estructura similar a esta:

  • Nombre del autor
  • Nombre de la herramienta
  • Lenguaje(s) en los que está diseñado
  • Descripción del trabajo
  • Link de descarga que contendrá el código fuente y el archivo ejecutable
  • Captura de pantalla (en el caso de tener interfaz)

Es altamente recomendable que junto con la descarga del código y del ejecutable haya un archivo readme que contenga las instrucciones que sean necesarias que por motivos de espacio hayan quedado fuera del post de participación.

Plazos de participación:

El periodo de entrega de las aplicaciones comienza el día 23 de noviembre y finalizara el día 30 de noviembre, por lo tanto hasta que comience el periodo de entrega he creado este hilo para que los que tengan dudas respecto del concurso puedan preguntarlas allí.

El dia 23 de noviembre, este hilo sera reabierto y solo la publicación de las aplicaciones sera aceptada. Al finalizar el periodo de entrega, el día 30 de noviembre, comenzaran las votaciones que duraran 2 semanas completas.

Votaciones:

Al comenzar el periodo de votación, los usuarios tendrán la chance de elegir la aplicacion que mas les guste durante el periodo expuesto. Finalizado el periodo, no se podrán emitir mas votos.

Menciones especiales:

Habrá dos menciones especiales:

  • Premio a la innovación.
  • Premio al mejor código.

Cada mención otorga +5% extra calculado mediante los votos totales de la encuesta, pudiendo obtener un +10% extra si se obtienen ambas menciones.

Los moderadores de las secciones de programacion, junto con los miembros del staff, son los que deciden estas dos menciones especiales. Por supuesto nadie podrá votar su propia aplicacion para ninguna mención especial y quien quiera puede abstenerse de votar.

Deberán enviarme un pm con una estructura similar a:

  • Premio a la innovación: Nombre del autor - nombre de la aplicación.
  • Premio al mejor código: Nombre del autor - nombre de la aplicación.

Pudiendo dejar en blanco alguno de los dos campos. En el caso de no decidirse por ningún candidato, simplemente no enviar el pm.

El periodo para enviar los votos para la mención especial finaliza el mismo día que las votaciones generales, ese día haré el recuento y el ganador obtendrá su +5%/+10% sumado a los votos que ya tenga en la encuesta general.


Reglas:


100 reglas:

1) Las aplicaciones al estilo "Hola mundo" con menos de 10/20 lineas de código (dependiendo el lenguaje) serán descalificados. Cualquier duda respecto del criterio a seguir, leer el FAQ en el hilo de dudas

2) Cualquier aplicacion que no contenga su código fuente sera descalificada sin posibilidad de volver a presentarla.

3) Cualquier aplicacion que ya hayas posteado en el foro hace mas de 1 año, no puede ser presentada al menos que esta presente un re-diseño u alguna modificación en sus funciones.

4) Se pueden postear aplicaciones relacionadas con el malware ya sean troyanos, virus etc. Pero esto debe quedar bien en claro en la descripción al postear la aplicacion. Es decir, cualquier intento de engaño para infectar usuarios sera motivo de baneo permanente.


Recomendaciones:


Si tenes alguna duda respecto del concurso, puedes hacer una consulta en el hilo de dudas o enviándome un pm.

Si tenes alguna duda respecto de una aplicacion y su funcionamiento, no dudes en enviarle pm al creador correspondiente.

Ante la duda, puedes subir cualquier aplicacion ya sea a VirusTotal u a NoVirusThanks.

Por supuesto, también puedes usar una maquina virtual para probar las aplicaciones.




Hilo oficial abierto!

Cualquier duda dirigirse al hilo de dudas.





Happy coding. :D





Lista de aplicaciones:


Concurso finalizado

Quiero felicitar de parte de todo el staff de elhacker.net, a todos los participantes de este concurso, ya que como siempre dije, gracias a su esfuerzo programando este concurso fue posible.

No puedo expresar mucho mas de lo que ya dije cuando termino la presentación, pero no esta de mas decir que personalmente fue un placer revisar las aplicaciones y analizar los códigos, chequear si utilizaban buenas practicas, revisar las cosas bien hechas, revisar las que estaban mal. Es un poco de lo que se trata una de las áreas de este mundo de la informática y de elhacker.net y creo es lo que a todos nos gusta.

Vamos a lo que todos quieren ver, los resultados, que vienen con algunas sorpresas que no serán del agrado de algunos, pero para ser justos es lo correcto:

Datos del concurso

Votos totales: 140 votos.
Porcentaje de las menciones: 5% cada una, es decir, 7 votos extra por cada mención.
Aplicaciones presentadas: 19 aplicaciones!.




Menciones especiales

Mejor código:
DLL Genius, Neural, TurboTron.

Idea Innovadora:
DLL Genius





Posiciones

Primer puesto:
DLL Genius: 25 votos (11+7+7)

Segundo puesto:
TurboTron: 11 votos (4+7)

Tercer puesto:
Notas por red: 9 votos ()
PyMSE: 9 votos ()



#9
[Ehn-Dev 2010] Hilo Oficial - Bases del concurso

EhnDev - FAQ

1) Puedo postear un "hola mundo"?

No, no puedes. Se aceptaran códigos de poca complejidad, desde códigos básicos hasta códigos avanzados, pero se requiere un mínimo de esfuerzo en el desarrollo de la aplicacion para que sea divertido para todos.
No es necesario que tenga una interfaz gráfica increíble, de hecho puede ser solo por consola.
Piensa esto, si tu código tiene entre 10 y 20 lineas y solo te llevo 10 minutos, tal vez debas darle un ajuste de tuercas, agregarle alguna otra función, etc.

2) Que lenguaje puedo utilizar?

Cualquiera, el que desees.

3) Puedo usar librerías de terceros?

Siempre que respetes las licencias que estas librerías contengan. Tal vez en algún caso la licencia requiera que hagas mención del creador de la librería, en otros tal vez podrás usarla siempre y cuando la aplicacion no tenga fines comerciales etc.

4) Que pasa si no llego a presentar la aplicacion en el plazo?

Lamentablemente no podrás participar en la votación ni tener acceso a los premios, por una cuestión de respeto a los que si se presentaron en el plazo estipulado. Igualmente puedes presentarla para que forme parte del recopilatorio cuando el concurso termine.

5) Creo que esta aplicacion es un malware, pero en la descripción no dice nada de ello...

Ante la duda, la subes a NoVirusThanks u a VirusTotal, y luego me envías un pm a mi u a algún moderador global junto con el link de la aplicacion.

6) Que buenas practicas de programacion influyen en los votos?

Todas, las que conozcas, y las que no. Recuerda que los que votan son los usuarios por lo tanto no todos medirán con la misma vara, a alguno le puede parecer una nimiedad que tu código no tenga comentarios, y a otro le puede parecer algo imperdonable. Por lo tanto, intenta implementar todas las buenas practicas que conozcas.

7) Mi aplicacion tiene que ser estable para que la pueda postear?

No, puede ser beta, alpha incluso. Por supuesto la estabilidad es un punto a favor y te podría otorgar votos extras respecto de una aplicacion que no sea tan estable.


8) puedo presentar mi código en un repositorio tipo GIT o SVN?

Como poder, podes, pero tal vez quien no tenga experiencia con ese tipo de servicios se pueda marear un poco, por lo tanto recomiendo dejarlo como una opción extra siempre y cuando se desee que otras personas participen en tu proyecto al terminar el concurso.

9) Debo presentar código y ejecutable ya compilados o puedo dejar solo código y makefile?

Código, y ejecutable. Ten en cuenta que muchos no podrán/sabrán/querrán compilar la aplicacion por ende necesitan el ejecutable para poder probarla y poder votar correctamente.

10) Si mi aplicación es de tipo web, sea PHP, asp o cualquier otro, debo de colgarla en algún servidor, ya sea propio o de terceros?

Al igual que con una aplicacion de escritorio, si tenes una aplicacion web y no provees un host para utilizarla, muchos no podrán/querrán tomarse el trabajo de implementarla y eso impactara en la cantidad de votos que puedas obtener, ya que limitas a que solo puedan apreciar tu aplicacion las personas que entiendan el lenguaje que utilizaste.

11) Debe ser multiplataforma o puedo elegir solo hacerlo para unix?

No, no hace falta que sea multiplataforma. Por supuesto, que lo sea te puede garantizar votos extra ya que la portabilidad suele ser algo a valorar dependiendo el caso en especifico. Pero en conclusión, no hace falta que sea multiplataforma.

12) Puedo desarrollar una herramienta que realice o este relacionada con DDOS?

Rotundo no. Al menos que tu herramienta este enfocada a evitar DDOS, pero cualquier aplicacion que sirva para realizar DDOS ya sea porque es su objetivo principal -u porque contiene funciones extra para dicha tarea- sera descalificada.

13) Este FAQ no me ayudo de mucho, no encuentro la respuesta a mi pregunta.

Entonces postea tu duda en este mismo hilo y sera respondida a la brevedad.




Cualquier pregunta frecuente que crean que deba agregar, enviarla por pm!

Para cualquier duda puntual, preguntar en este mismo hilo. :D

Saludos!
#10
Bueno el titulo habla por si solo, ¿Les gustaría?.
La idea principal es plantear una fecha de entrega y cuando llegue esa fecha todos los participantes expongan un código que realice una tarea determinada, el lenguaje a utilizar puede ser cualquiera y el objetivo de la aplicacion seria a elección del usuario. Desde aplicaciones básicas hasta avanzadas, eso no importa ya que todos podrán aportar lo suyo y todas se someterán a votación cuando el plazo de entrega (a definir) termine.

Los que hayan participado en algún "Abril negro" sabrán mas o menos de que se trata, esto es algo similar solo que el motivo es libre y por supuesto también pueden postearse códigos de malware solamente que en este caso no se tratara exclusivamente de eso.

Los detalles del concurso y de su organización tales como fechas y demás todavía no están definidos y todavía estoy pensando que premio se podría otorgar al ganador (y ademas lo tendría que hablar con el-brujo antes).

El objetivo de este post y de esta encuesta es tener una estadística mas o menos realista respecto de la aceptación del futuro concurso. Siéntanse libres de postear y votar ya que esto no representa un compromiso de participación.

Cualquier otra idea y/o duda relacionada al concurso que les parezca conveniente aportar también es bienvenida.

Saludos!

#Chincheta temporal.
#11
Este articulo también se encuentra en wiki.elhacker.net,
http://wiki.elhacker.net/programacion/cc/articulos/principios-basicos-de-desarrollo-de-drivers-en-windows




Introducción

Encontrar información sobre el desarrollo de drivers no siempre es tarea fácil, sin importar el sistema operativo del cual estemos hablando.
Normalmente, lo ideal para entender este tipo de temas correctamente es leer libros especializados en el tema u ir directamente a las fuentes. Suele ser lo correcto ya que el tema es complejo, largo y puede volverse pesado para quien se apure en entender todos los conceptos implicados.

Por ahora, esto no sera mas que una introducción, por lo tanto tratare que sea breve. Es solo un intento de dar una perspectiva general sobre este tema y con esto lograr que mas gente decida a interiorizarse en el, con suerte mas adelante podremos ver técnicas y/o conceptos mas avanzados y que la mayoría los entiendan.




subsystem, ¿que es?

Es ideal conocer a fondo las herramientas que estamos utilizando, y con esto no solo me refiero al lenguaje, si no tambien al entorno de trabajo que utilicemos.

El proceso de compilado y linkeado genera un binario adecuado para que el sistema operativo en el cual estemos pueda comprenderlo. En Windows, este formato es lo que varios conocen como PE (Portable Executable Format)
Alrededor de PE, tenemos un concepto llamado subsystem. Un subsystem, entre otras opciones incluidas en la información del header PE, describe como cargar un ejecutable que también incluye el punto de entrada (Entry Point) en el binario.




Conociendo tus herramientas.

Posiblemente muchos recién se enteran lo que es un subsystem, y esto se debe a que generalmente en la etapa de aprendizaje de lenguajes como C/C++, uno puede simplemente descargar un IDE y ponerse a trabajar. Los errores no causan tantos problemas cuando todavía no salimos del modo usuario.

Por ejemplo, las personas que utilizan Visual C++, habrán hecho ya alguna aplicacion en consola u alguna aplicacion para Windows. Al crear el proyecto, el subsystem viene predefinido, tal como /SUBSYSTEM:CONSOLE o /SUBSYSTEM:WINDOWS.

La novedad en todo esto, es que un driver es linkeado con otro tipo de subsystem, llamado NATIVE.

MSDN /SUBSYSTEM
CitarNATIVE
   Device drivers for Windows NT. If /DRIVER:WDM is specified, NATIVE is the default.




Los drivers también tienen un "main".

Por supuesto, los drivers también tienen un main, un Entry Point.
Si sabemos que es un driver lo que vamos a realizar, basta con que el main reciba los parámetros adecuados y retorne lo esperado para un driver. El sistema se encargara de cargar el driver cuando lo requiramos y darse cuenta que es un driver.

Podemos utilizar cualquier nombre como Entry Point, pero por convención en Windows se utiliza DriverEntry.
Si estas utilizando el DDK, al seleccionar que vas a construir un driver se utilizan una serie de opciones predefinidas. Esta es la razón por la cual DriverEntry se convirtió en algo similar al Entry Point oficial.

Al especificar /DRIVER, tenemos tambien otras opciones, directo de la MSDN:

Use the /DRIVER linker option to build a Windows NT kernel mode driver.

CitarThe UPONLY keyword causes the linker to add the IMAGE_FILE_UP_SYSTEM_ONLY bit to the characteristics in the output header to specify that it is a uniprocessor (UP) driver. The operating system will refuse to load a UP driver on a multiprocessor (MP) system.

The WDM keyword causes the linker to set the IMAGE_DLLCHARACTERISTICS_WDM_DRIVER bit in the optional header's DllCharacteristics field. WDM video capture was designed to resolve the problems inherent in the Video for Windows architecture.

En este caso utilizaremos:

/SUBSYSTEM:NATIVE /DRIVER:WDM -entry:DriverEntry




Conceptos básicos. Lo que debes saber.

Antes de comenzar, hay que cambiar la mentalidad de "Compilar y probar" que todos solemos adquirir mientras aprendemos a programar en modo usuario.
En el mundo de los drivers la situación cambia y lo hace en forma drástica.

Como mínimo podrías ocasionar un BSOD, y si estamos ante un driver que iniciara siempre con el sistema, tenemos un problema.
Igualmente, nada que no puedas revertir entrando en modo seguro u volviendo a configuraciones previas, pero esto solo cabe en las practicas y no en casos reales.

En conclusión, no compiles y pruebes el código de un driver al menos que entiendas a ciencia cierta que es lo que realiza, y mas aun si antes de compilarlo vas a modificar secciones del código.

Cabe recordar, que esta es solo una introducción de los conceptos básicos, por lo tanto quien quiera interiorizarse a fondo no le queda mas alternativa que revisar la MSDN u libros como "Programming the Windows Driver Model".


Interrupt Request Level


Abreviado como IRQL, partamos de la definición del DDK:

CitarThe priority ranking of an interrupt. A processor has an IRQL setting that threads can raise or lower. Interrupts that occur at or below the processor's IRQL setting are masked and will not interfere with the current operation. Interrupts that occur above the processor's IRQL setting take precedence over the current operation.

The particular IRQL at which a piece of kernel-mode code executes determines its hardware priority. Kernel-mode code is always interruptible: an interrupt with a higher IRQL value can occur at any time, thereby causing another piece of kernel-mode code with the system-assigned higher IRQL to be run immediately on that processor. In other words, when a piece of code runs at a given IRQL, the Kernel masks off all interrupt vectors with a lesser or equal IRQL value on the microprocessor.

Si, puede ser difícil de comprender a la primer lectura, por eso vamos a intentar explicarlo en términos mas sencillos.
El IRQL de un procesador ayuda a especificar como un determinado thread puede ser interrumpido. Dicho thread solo puede ser interrumpido mediante código por un nivel mas alto de IRQL en el mismo procesador.
En estas épocas, es normal ver equipos con varios procesadores. En esos casos cada procesador corre en su propio IRQL

Estos 4 niveles serán con los que tendrás que trabajar normalmente.
Normalmente las APIs llevan una pequeña nota aclarando en que nivel de IRQL necesitas estar para poder utilizar determinada API. En reglas generales, a mas alto sea el nivel, menos APIs podes utilizar.

  • Passive
  • APC (Asynchronous Procedure Calls)
  • Dispatch
  • DIRQL




Citar
1) PASSIVE_LEVEL

   Interrupts Masked Off — None.

   Driver Routines Called at PASSIVE_LEVEL — DriverEntry, AddDevice, Reinitialize, Unload routines, most dispatch routines, driver-created threads, worker-thread callbacks.

El nivel mas bajo. En este nivel corre un thread que se ejecute en modo usuario.

Citar2) APC_LEVEL

   Interrupts Masked Off — APC_LEVEL interrupts are masked off.

   Driver Routines Called at APC_LEVEL — Some dispatch routines (see Dispatch Routines and IRQLs).

Este es el nivel donde ocurren las "Asynchronous Procedure Calls". Cuando ocurre una APC, el nivel del procesador se aumenta a APC_LEVEL.

Citar3) DISPATCH_LEVEL

   Interrupts Masked Off — DISPATCH_LEVEL and APC_LEVEL interrupts are masked off. Device, clock, and power failure interrupts can occur.

   Driver Routines Called at DISPATCH_LEVEL — StartIo, AdapterControl, AdapterListControl, ControllerControl, IoTimer, Cancel (while holding the cancel spin lock), DpcForIsr, CustomTimerDpc, CustomDpc routines.

La memoria paginada no es accesible en este nivel, por lo tanto toda la memoria accesible debe ser no-paginada. Esto ocasiona que disminuya en gran parte la cantidad de APIs que podes utilizar.

Citar4) DIRQL

   Interrupts Masked Off — All interrupts at IRQL<= DIRQL of driver's interrupt object. Device interrupts with a higher DIRQL value can occur, along with clock and power failure interrupts.

   Driver Routines Called at DIRQL — InterruptService, SynchCritSection routines.

En este nivel generalmente un driver no lidia con interrupciones. Es mas que nada una forma de conocer que dispositivos tienen prioridad sobre otros.

I/O Request Packet

Abreviado IRP, basicamente es una estructura que permite a diferentes drivers comunicarse entre si y requerir tareas a finalizar.
El manejo de IRPs puede ser muy simple u demasiado complejo dependiendo de cual sea la estructura de los drivers.

El IRP también contendrá "peticiones secundarias", conocido como "IRP Stack Location". Cada driver contendrá sus propias peticiones secundarias respecto de como interpretar el IRP, denominada IO_STACK_LOCATION.

Creando el DriverEntry

Comenzando con un poco de código, el prototipo del DriverEntry:

Código (cpp) [Seleccionar]

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath);


DRIVER_OBJECT es una estructura que representa el driver.  Este objeto contiene un puntero a DEVICE_OBJECT, la cual es otra estructura que representa un dispositivo en particular.
Un solo driver puede manejar múltiples dispositivos, y tal así, DRIVER_OBJETCT mantiene una lista de todos los dispositivos que para los cuales ese driver maneja peticiones.

Registrypath es una cadena que apunta a una ubicacion en el registro donde la informacion para el driver fue guardada. El driver puede utilizar luego esta ubicacion para guardar informacion especifica.

Veamos la primer parte de nuestra rutina de entrada:

Código (cpp) [Seleccionar]

NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject, PUNICODE_STRING  pRegistryPath)
{
   NTSTATUS NtStatus = STATUS_SUCCESS;
   UINT uiIndex = 0;
   PDEVICE_OBJECT pDeviceObject = NULL;
   UNICODE_STRING DriverName, DosDeviceName;

   DbgPrint("DriverEntry!\n");

   RtlInitUnicodeString(&DriverName, L"\\Device\\ehn");
   RtlInitUnicodeString(&DosDeviceName, L"\\DosDevices\\ehn");

   NtStatus = IoCreateDevice(pDriverObject, 0,
                             &DriverName,
                             FILE_DEVICE_UNKNOWN,//No asociado a ningun dispositivo en particular
                             FILE_DEVICE_SECURE_OPEN,
                             FALSE, &pDeviceObject);


Lo primero que se nota es la llamada a DbgPrint, esta funciona como el printf de toda la vida, pero en este caso el output va a parar al kernel debugger. Estos mensajes se pueden ver perfectamente con una herramienta como DbgView de Sysinternals

RtlInitUnicodeString inicializa una estructura del tipo UNICODE_STRING.
Esta estructura esta definida de tal modo que:


Código (cpp) [Seleccionar]
typedef struct _LSA_UNICODE_STRING {
 USHORT Length;
 USHORT MaximumLength;
 PWSTR  Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;


Donde "Lenght" es la longitud actual de la cadena, "MaximunLenght" es el tamaño máximo que la cadena puede tener, y "Buffer" es el puntero a la cadena.
Como podemos ver, esta estructura contiene el tamaño de la cadena por lo tanto no necesitamos verificar si la cadena esta terminada en NULL.

Luego de crear el dispositivo, ahora queda configurar el Driver Object para que llame a nuestro driver cuando ciertas peticiones se realicen. Estas peticiones se denominan IRP Major requests.
Existen tambien las denominadas Minor requests a las cuales nos referimos con anterioridad como peticiones secundarias, se encuentran en el stack location del IRP.

Código (cpp) [Seleccionar]
       for(uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++)
            pDriverObject->MajorFunction[uiIndex] = ehn_UnSupportedFunction;
   
       pDriverObject->MajorFunction[IRP_MJ_CLOSE]             = ehn_Close;
       pDriverObject->MajorFunction[IRP_MJ_CREATE]            = ehn_Create;
       pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    = ehn_DeviceControl;
       pDriverObject->MajorFunction[IRP_MJ_READ]              = ehn_Read;
       pDriverObject->MajorFunction[IRP_MJ_WRITE]             = ehn_Write;


Es decir, cuando una aplicación en modo usuario llame a algunas de estas funciones:

  • CreateFile
  • CloseHandle
  • WriteFile
  • ReadFile
  • DeviceIoControl

se llamara a tu driver.




Rutina Unload

Lo siguiente es la función de descarga del driver:

Código (cpp) [Seleccionar]
pDriverObject->DriverUnload =  ehn_Unload;

En realidad la rutina de descarga solo se necesita si queres descargar tu driver en forma dinámica, en ese caso la rutina debe ser especificada. Si no se especifica una función de descarga, el sistema no dejara que el driver sea descargado.

Esta es, por ejemplo, una forma simple de rutina de descarga:

Código (cpp) [Seleccionar]
void Example_Unload(PDRIVER_OBJECT  DriverObject)
{    
   
   UNICODE_STRING DosDeviceName;
   
   DbgPrint("Unload!!\n");
   
   RtlInitUnicodeString(&DosDeviceName, L"\\DosDevices\\ehn");
   IoDeleteSymbolicLink(&DosDeviceName);

   IoDeleteDevice(DriverObject->DeviceObject);
}


Definir las otras funciones es tarea para el hogar ya que creo es la parte mas divertida de todo esto y la que supongo motivara mas para los que quieran interiorizarse en el tema.
Igualmente este ejemplo es de lo mas básico y es el que se utiliza para comprender estos conceptos por lo tanto probablemente al buscar los conceptos que faltan para definir lo necesario se encuentren con ejemplos conceptualmente similares, por lo tanto la dificultad es casi nula pero si sera bastante divertido de seguro.




Cargar y descargar el driver en forma dinámica.

Código (cpp) [Seleccionar]
int _cdecl main()
{
   HANDLE HSmng,HServ;
   SERVICE_STATUS Sstatus;

   HSmng = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
   
   printf("Cargando el driver!\n");
   
if(HSmng)
   {
       HServ = CreateService(HSmng, "ehn",
                                "ehn driver",
                                 SERVICE_START | DELETE | SERVICE_STOP,
                                 SERVICE_KERNEL_DRIVER,
                                 SERVICE_DEMAND_START,
                                 SERVICE_ERROR_IGNORE,
                                 "C:\\ehn.sys",
                                 NULL, NULL, NULL, NULL, NULL);

       if(!HServ)
       HServ = OpenService(HSmng, "ehn", SERVICE_START | DELETE | SERVICE_STOP);
       

       if(HServ)
       {
           printf("Iniciando servicio\n");

           StartService(HServ, 0, NULL);
           printf("Presione una tecla para cerrar el servicio\n");
           getchar();
           ControlService(HServ, SERVICE_CONTROL_STOP, &Sstatus);

           DeleteService(HServ);

           CloseServiceHandle(HServ);
           
       }

       CloseServiceHandle(HSmng);
   }
   
   return EXIT_SUCESS;
}


Para cualquier detalle respecto de las APIs utilizadas, referirse a la documentación del DDK y de la MSDN.





return EXIT_SUCESS


Luego de definir las funciones correspondientes en el driver, al utilizar las APIs desde modo usuario podrán comprobar que secciones de código se utilizan de su driver, incluso al definir las funciones que restan les basta con poner algunos dbgprint para luego ver con dbgview que es exactamente lo que se esta ejecutando.

Lo que no hay que hacer

Toda área tiene una lista de cosas que NO hay que hacerse, el desarrollo de drivers no es la excepción y Microsoft se encargo de resaltar este tipo de errores.

Como ejemplo, las primeras 10, hay mas en el link:

CitarNever return STATUS_PENDING from a dispatch routine without marking the I/O request packet (IRP) pending (IoMarkIrpPending).
Never call KeSynchronizeExecution from an interrupt service routine (ISR). It will deadlock your system.
Never set DeviceObject->Flags to both DO_BUFFERED_IO and DO_DIRECT_IO. It can confuse the system and eventually lead to fatal error. Also, never set METHOD_BUFFERED, METHOD_NEITHER, METHOD_IN_DIRECT or METHOD_OUT_DIRECT in DeviceObject->Flags, because these values are only used in defining IOCTLs.
Never allocate dispatcher objects from a paged pool. If you do, it will cause occasional system bugchecks.
Never allocate memory from paged pool, or access memory in paged pool, while running at IRQL >= DISPATCH_LEVEL. It is a fatal error.
Never wait on a kernel dispatcher object for a nonzero interval at IRQL >= DISPATCH_LEVEL. It is a fatal error.
Never call any function that causes the calling thread to wait directly or indirectly while executing at IRQL >= DISPATCH_LEVEL. It is a fatal error.
Never lower the interrupt request level (IRQL) below the level at which your top-level routine has been invoked.
Never call KeLowerIrql() if you haven't called KeRaiseIrql().
Never stall a processor (KeStallExecutionProcessor) longer than 50 microseconds.



Referencias

Lectura recomendada para los que quieran interiorizarse y/o iniciarse en este tema.  :)

WDK
Peering Inside the PE: A Tour of the Win32 Portable Executable File Format
Key driver concepts
Getting started: Writing Windows drivers

Libros:
"Programming the windows driver model"

Saludos!
#12
He decidido hacer nuevamente la encuesta respecto de que lenguajes se utilizan habitualmente puesto que las anteriores me parecen que no reflejan con mucha exactitud cuales son los lenguajes mas utilizados en el foro.
Las anteriores encuestas se pueden ver aqui.

Esta también expirara en el termino de 1 año como las anteriores, pero voy a restringir las opciones a votar a un máximo de 5 ya que la anterior permitía un total de 11 siendo 11 las opciones. Creo que todos estamos de acuerdo en que casi nadie utiliza mas de 5 lenguajes en forma habitual al menos que este todos los días probando los ejemplos del "Hola mundo" que aparecen en Wikipedia.  ;D

Por supuesto digo casi, porque puede haber excepciones, pero realmente sera una estadística tan baja que ni siquiera vale la pena contemplar.
El problema creo yo es que "habitual" puede interpretarse de muchas maneras, así que definamos por ejemplo, en el termino de 1 mes, que lenguajes se utilizaron en mayor medida? esos serán los que haya que votar.

Recuerden, no es una competencia para ver quien conoce mas lenguajes, así que traten de ser objetivos con los votos. Que lenguajes utilizan habitualmente?

Saludos!
#13
El primer error se da en las advertencias enviadas mediante cake, no se si en todos los casos pero si por lo menos en varios.

Al enviar una advertencia, el mensaje automatico queda algo asi como:

CitarEl mensaje se ha cerrado por tal
Leer reglas:
:http://linkdereglasundefined

Ese "undefined" se agrega en casi todo mensaje enviado mediante cake. Si por ejemplo se envía una advertencia a todos los participantes del hilo, queda algo así:

CitarNo utilicen el foro como un chatundefined




El segundo error, se da en el "mostrar nuevas respuestas a tus mensajes". Al hacer un post y luego visitarlo por el regreso automático -el que se activa desde el perfil- el post no se marca como visitado. Si luego presionas el "mostrar nuevas..." aparecen los últimos mensajes que hayas hecho sin importar si visitaste todos y las ultimas respuestas son siempre propias. Tienes que volverlos a visitar para que se marquen como leídos y creo que eso antes no sucedía.

Eso solo.

Saludos!
#14
    Si tienes un source interesante y todavía no esta en la lista, ponlo en este mismo post o envíalo por pm y sera agregado. :)





Sources




A:



B:



C:




D:



E:




F:



G:


H:



I:



J:


K:



L:



LL:


M:



N:


O:



P:



Q:



R:



S:



T:



U:


V:


W:



X:


Y:


Z:

[/list]
#15
[youtube=425,350]http://www.youtube.com/watch?v=97U3S57-a9k&feature=player_embedded#![/youtube]

Vamos Argentina! mañana a todo o nada  :D
#16
Requisitos:


En este caso para el ejemplo utilice xchat.




1) Configuración Tor.

  • Abrimos el archivo de configuración, por defecto se encuentra en:

[U]:\Documents and Settings\User\Datos de programa\Vidalia\torrc

o

/etc/tor/torrc

  • Al final del archivo agregamos la linea:

mapaddress  10.40.40.40  p4fsi4ockecnea7l.onion

  • Guardamos el archivo y reiniciamos Tor.


2) Configuración xchat.

  • En la lista de redes, creamos una (pueden llamarla como quieran). En este caso la llamaremos freenode.

  • La editan y en la lista de servidores agregan:

10.40.40.40

  • Vamos a Configuración>Preferencias>Red>Configuración de la red:

Nombre de equipo: localhost.
Puerto: 9050.
Tipo: SOCKS5

3) Login SASL


  • Descargamos cap_sasl.py y lo colocamos en el directorio de instalación

  • Xchat>Cargar complemento>cap_sasl.py (La interfaz de Python debería cargarse automáticamente si reinician xchat)

  • /SASL -set Nombrered(En este caso es freenode) nick pass

  • Conectar





Me preguntaron varios sobre esto por Msn así que preferí hacer un post al respecto. Lo hice lo mas sencillo posible pero si algo queda poco claro no duden en preguntar. :D

Saludos!
#17
Este articulo también se encuentra en wiki.elhacker.net,
http://wiki.elhacker.net/programacion/cc/articulos/lo-que-no-hay-que-hacer-en-c-c

La mayoría que recién esta empezando con C/C++ y viene al foro a sacarse dudas, cometen errores similares. Incluso muchos tienen conceptos erroneos sobre la utilidad o eficiencia de ciertas funciones, probablemente debido a el estudio de textos incorrectos o de libros anticuados.

Pero incluso a veces uno no puede escapar de ciertas cosas. Imaginen a alguien que recién entra en la universidad y el profesor le hace incluir conio para utilizar getch. Seguramente el alumno de por sentado que hacer eso esta perfecto, e incluso el profesor recompense con notas altas a los que programan tal cual se ha enseñado.
Por lo tanto, ciertas cosas son comprensibles y el único consejo que se puede dar es que nunca den por sentado algo, es recomendable informarse antes para ver que es lo que se esta realizando, sobre todo en programación.

Para los que quieran revisar un poco explicaciones mas detalladas del "por que" de ciertas reglas, puede revisar este draft, que aunque puede tornarse bastante técnico para alguien que recién comienza, puede servir bastante:

WG14/N1256 Committee Draft — Septermber 7, 2007 ISO/IEC 9899:TC3
(Gracias Queta)


1)
gets();

La falta de control en un programa es un factor bastante negativo, y también peligroso en caso de programas comerciales o masivos. Ese es el principal problema de gets, no tiene control interno.

¿Que signifca no tener control interno?

Significa que la funcion acarrea como consecuencia el mal comportamiento del programa, resultados inesperados y erroneos, vulnerabilidades entre otras tantas cosas.
Define una cadena de 10 caracteres, y gets va a aceptarte eso y muchisimo mas como entrada.

Veamos este codigo:

#include<stdio.h>

int main()
{

char letra1[]="AAAAA";
char letra2[]="BBBBB";
char letra3[]="CCCCC";

printf("A: %s\nB: %s\nC: %s\n\n",letra1,letra2,letra3);

printf("Ingrese la letra D, 5 veces: ");
gets(letra2);

printf("\nA: %s\nB: %s\nC: %s\n\n",letra1,letra2,letra3);

getchar();
}


A: AAAAA
B: BBBBB
C: CCCCC

Ingrese la letra D, 5 veces: DDDDD

A: AAAAA
B: DDDDD
C: CCCCC


Como vemos nada paso, y los elementos de letra2 se reemplazaron por el input ingresado como debería ser . Ahora en vez de 5 veces, ingresemos la letra 'D' mas veces de lo que el programa nos indica:


A: AAAAA
B: BBBBB
C: CCCCC

Ingrese la letra D, 5 veces: DDDDDDDDDDDDDDDDDDD

A: DDD
B: DDDDD
C: CCCCC


Que paso con letra1? :huh: precisamente lo que no queremos que pase en nuestro programa. gets sobreescribio una zona de memoria que no debia sobreescribir, ya que el input debia ser ingresado en letra2, pero simplemente no le importo que el input sea muchisimo mas grande que el tamaño de la cadena. Razon mas que suficiente para no utilizarla.

Por lo tanto es recomendable utilizar fgets();

fgets(char *string, int length, FILE * stream)

Es decir:

fgets(letra2, 5, stdin);

Con fgets permites que sean ingresados lenght-1 caracteres.
Aunque no todo es color de rosas, y en caso de que se ingresen menos caracteres de los que has definido como tamaño, tendras que lidiar con un salto de linea '\n'. Obviamente es una nimiedad que puedes arreglarla de esta forma:


if (letra2[strlen(letra2)-1] == '\n')//string.h para strlen();
letra2[strlen(letra2)-1] = '\0';


Supongo que con esto queda claro que no tiene sentido utilizar gets();.

Links:
http://en.wikipedia.org/wiki/Fgets
http://www.gidnetwork.com/b-56.html


2) fflush(stdin);

fflush(stdin) es un invitado casi diario. Pocas veces pasa un dia sin que alguien lo recomiende o lo mencione como la solucion! a los malos comportamientos de las pausas en los programas.

STDIN, como su nombre lo indica, significa 'Standard input'. Es decir, el ingreso por teclado.

Acorde al Standard, fflush espera solamente un stream de salida (STDOUT: 'Standard Output) por lo que el comportamiento con streams de entrada como STDIN es indefinido. Por mas que en algunas plataformas funcione, o que en algunos compiladores funcione, no deberia ser utilizado.

Por el otro lado, para evitar esas pausas fastidiosas es necesario evitar las funciones que dejan basura por doquier (como scanf();) y utilizar funciones como la ya mencionada fgets();


http://foro.elhacker.net/programacion_cc/fflushstdin-t91101.0.html
http://foro.elhacker.net/programacion_cc/zanjar_de_una_vez_fflushstdin-t265125.0.html;msg1294511
http://foro.elhacker.net/programacion_cc/error_super_basico_en_c_quien_me_ayuda_soy_nuevo-t262118.0.html;msg1275898
http://foro.elhacker.net/programacion_cc/problema_con_el_compilador_gcc_de_ubuntu-t248582.0.html




3) system("PAUSE");

Otro invitado diario es la pausa utilizando system. Esto incluso me ha tocado en mi universidad. Que el profesor me haga realizar ejercicios exclusivamente utilizando system y la pausa tambien habia que realizarla exclusivamente utilizando system. En fin, seguramente muchos consideren que realizar esto no es un gran problema, y probablemente tengan razon en los codigos que uno realiza como tarea estudiantil. Pero es un habito malo, y como todo, hay que dejarlo algun dia. Claramente no puedes pasarte toda la vida llamando al sistema para hacer una pausa.

*No es portable, solo va a funcionar en sistemas que tengan el comando PAUSE.


*Es una funcion pesada. Llamar al sistema, suspender tu programa, buscar el comando PAUSE, etc etc etc etc.

Por el otro lado si se siguio la norma de no dejar basura en el buffer de entrada, se puede utilizar soluciones mas sencillas como getchar(); (o cin.get(); en C++).


4)
conio.h

Librerias inutiles si las hay, pero por sobre todas las cosas NO standard. No existe problema para el cual sea exclusivamente necesario utilizar conio.h. Y visto que aca la mayoria de los que la incluyen lo hacen para utilizar getch(); supongo que con todo el parrafo anterior habran quedado claras las alternativas.

http://en.wikipedia.org/wiki/Conio.h
http://www.gidforums.com/t-7379.html


5) void main();

Seguramente para justificar esto habría que decir que el estándar dice que void no puede ser el valor de retorno del main, lo cual es verdad, pero no siempre es suficiente. Sobretodo considerando que muchas veces en los libros el void main dice presente.

No voy a extenderme mucho con esto ya que voy a dejar los links necesarios para el que quiera entender porque sucede, pero como base comprendamos esto:

-Devolver un valor void es perder la garantia que un valor de retorno distinto de 0 implica un error, lo cual es malo tanto para el SO como para el determinado programa que pueda estar llamando a tu código.

-Esta mal acorde al estándar.

-Puede que tu programa no funcione correctamente.

Los errores pueden depender de los mecanismos de retorno o la arquitectura especifica en la cual estemos. Pero por supuesto, si elegimos un lenguaje de alto nivel como lo es C o C++, es para no tener que preocuparnos por esos asuntos.

En conclusión, el que quiera entender el " por que", leer los siguientes links.

Links:

http://www.eskimo.com/~scs/readings/voidmain.960823.html
http://home.att.net/~jackklein/ctips01.html#int_main
http://users.aber.ac.uk/auj/voidmain.shtml


6) Procesamiento de cadenas: string.h

La mayoría de las funciones que no tienen la posibilidad de pasar como argumento el tamaño del buffer que debe procesarse, estan completamente expuestas al desbordamiento de buffer. Sobre todo si el contenido del buffer origen es ingresado por el usuario, y por sobre todas las cosas, si no se hicieron las validaciones correspondientes. (Por ejemplo, haber utilizado gets o no haber chequeado el tamaño de la cadena antes de copiar/concatenar o cualquier otra forma de procesar una cadena).
Obviamente no voy a hablar sobre todas las funciones, pero si sobre dos ejemplos que dan la pauta de lo que sucede y de lo que debería hacerse: strcpy y strcat.

a) strcpy ( char * destination, const char * source );

Veamos un ejemplo de un codigo incorrecto:


#include <stdio.h>
#include <string.h>

int main()
{
char cadena1[]={"aaaa"};
char cadena2[100];
char cadena3[]={"0123"};

printf("Ingrese cadena: ");
fgets(cadena2,100,stdin);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s\n\n",cadena1,cadena2,cadena3);
strcpy(cadena1,cadena2);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s",cadena1,cadena2,cadena3);
getchar();
return 0;
}


Ingrese cadena: 1111111111111111111111111111111111111111111111111111

//Antes de strcpy
cadena1: aaaa
cadena2: 111111111111111111111111111111111111
cadena3: 0123

//Despues de strcpy
cadena1: 111111111111111111111111111111111111
cadena2: 111111111111111111111111111111111111
cadena3: 1111111111111111111111111111111111111111111111111111


Como se ve claramente, el problema esta vez no estuvo en la recepción de los datos (en el sentido técnico), si no en el copiado. Ya que strcpy no verifica si el buffer destino es efectivamente capaz de contener los datos del buffer origen, lo cual por supuesto ocasiona perdida de datos y buffers overflows.
Obviamente si el fgets se hubiese utilizado correctamente, esto no hubiese sucedido.

b) strcat ( char * destination, const char * source );

La misma historia sucede aqui. Al no poder especificar el tamaño del buffer destino la funcion es insegura. Veamos un ejemplo incorrecto:

#include <stdio.h>
#include <string.h>

int main()
{
char cadena1[]={"aaaa"};
char cadena2[100];
char cadena3[]={"0123"};

printf("Ingrese cadena: ");
fgets(cadena2,100,stdin);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s\n\n",cadena1,cadena2,cadena3);
strcat(cadena1,cadena2);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s",cadena1,cadena2,cadena3);
getchar();
return 0;
}


Ingrese cadena: 11111111111111111111111111111111111111111111

//Antes de strcat
cadena1: aaaa
cadena2: 1111111111111111111111111111
cadena3: 0123


//Despues de strcat
cadena1: aaaa1111111111111111111111111111
cadena2: 1111111111111111111111111111
cadena3: 11111111111111111111111111111111111111111111


Como pueden ver suceden errores muy similares. Obviamente es un error tonto de programación en el cual el desarrollador pasa un mal argumento a fgets, ya que de haberlo hecho bien el error no sucederia. Pero ese no es el asunto, lo importante es que tanto strcpy o strcat (y toda la familia de funciones) no realizan (o permiten realizar) la validación extra necesaria. Imaginen que creas una cadena para tomar una ruta del sistema operativo para luego concatenar, ¿Y si el atacante se da cuenta de eso y decide explotar el overflow por ese lado? mil variantes pueden existir y probablemente no siempre uno cubra todas ellas.

c) Entonces que se puede utilizar?

strncpy y strncat cumplen su función perfectamente si se utilizan en forma correcta.

c1) strncpy ( char * destination, const char * source, size_t num );

#include <stdio.h>
#include <string.h>

int main()
{
char cadena1[]={"aaaa"};
char cadena2[100];
char cadena3[]={"0123"};

printf("Ingrese cadena: ");
fgets(cadena2,100,stdin);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s\n\n",cadena1,cadena2,cadena3);
strncpy(cadena1,cadena2,1);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s",cadena1,cadena2,cadena3);
getchar();
return 0;
}


Ingrese cadena: 1111111111111111111

//Antes de strncpy
cadena1: aaaa
cadena2: 1111111111111111111
cadena3: 0123

//Despues de strncpy
cadena1: 1aaa
cadena2: 1111111111111111111
cadena3: 0123


c2) strncat ( char * destination, const char * source, size_t num );

#include <stdio.h>
#include <string.h>

int main()
{
char cadena1[]={"aaaa"};
char cadena2[100];
char cadena3[]={"0123"};

printf("Ingrese cadena: ");
fgets(cadena2,100,stdin);
printf("cadena1: %s\ncadena2: %s\ncadena3: %s\n\n",cadena1,cadena2,cadena3);
strncat(cadena1,cadena2,0);//Obviamente esta linea es un absurdo
//Pero queda claro el control que la funcion mantiene
printf("cadena1: %s\ncadena2: %s\ncadena3: %s",cadena1,cadena2,cadena3);
getchar();
return 0;
}


Ingrese cadena: 123123

//Antes de strncat
cadena1: aaaa
cadena2: 123123
cadena3: 0123

//Despues de strncat
cadena1: aaaa
cadena2: 123123
cadena3: 0123


Estas ultimas funciones a pesar de poder utilizarse perfectamente como solucion a lo anterior expuesto, tambien tienen sus contras:

-Tanto strncpy o strncat no proveen un valor de retorno que pueda implicar un error o el exito de la cadena resultante, si no que devuelven un puntero al buffer destino. Por lo tanto requiere un esfuerzo extra por parte del programador.

- strncpy no finaliza la cadena resultante con null si el destino es al menos igual en tamaño que el origen, por lo tanto siempre debe finalizarse la cadena con null después de la llamada a strncpy.

- strncpy tambien tiene un comportamiento que puede afectar el rendimiento del programa en caso que el buffer destino sea considerablemente mas grande que el buffer origen, ya que en este caso se realiza el zero-padding, es decir, llena el resto de la cadena con nulls.

Microsoft tiene una lista de funciones baneadas (lo que en Visual Studio se conoce como deprecated) y obviamente tiene el reemplazo de estas llamandolas funcion_s. Ejemplo: strcpy_s, strcat_s, gets_s y etc.
Pueden ver las funciones catalogadas como inseguras en este header, y su reemplazo en esta lista. (Gracias Vertex por los links)

Tambien existen opciones como strlcpy y strlcat, las cuales pueden ver a fondo en este link.


------------------------------------------------------------------------------------------

Continua





#18
Pues eso, anda alguien viciando ese juego?

Un video para los que no lo conocen

[youtube=425,350]http://www.youtube.com/watch?v=kIgOrFbVi0c[/youtube]
#19
Y otra vez y vaaan, creo que es la cuarta vez que un juego con este motor me da dolores de cabeza (Cod 5, Mirrors Edge etc)

Voy primero con el problema y despues con las cosas que hice y el hardware que tengo.


Problema


Inicio el juego y queda el splash screen como 5 minutos, luego como que quiere iniciar y queda en black screen.


Hardware y SSOO

PC 1

Core 2 Duo e8400
4gb ram 1066mhz
Geforce 9800gt

SO1: Windows XP Pro SP3 x32
SO2: Windows Vista Ultimate x64

Juegos probados con anterioridad en esta pc: Crysis, Crysis warhead, GTA 4 etc

PC 2

Pentium D
2gb ram
Geforce 6200

SO: Windows XP Pro SP3 x32


Intentos fallidos


1*Actualizar graficas
2*Actualizar DX
3*Actualizar Physx
4*Tunear baseengine.ini
5* Desactivar Unimodem (De forma manual, cambiando los valores DevicePresence/Emulated en el registro)
6*Reinstalar
7*Reiniciar muchas veces
8*Ejecutar modo compatibilidad
9*Probar varias medicinas
10*Putear
11*Rezar a Zeus
12* Deshabilitar aceleracion de sonido

Nada de esto funciono, alguien tiene alguna idea? Googlie, bingie y Yahooie y nada.



Un saludo!










#20
Bueno esa es la pregunta.

Un asistente que hable y reconozca la voz, se le pueda poner tareas programadas. No importa si es Windows o Linux.
Para poner un ejemplo sencillo, que pueda tanto despertarte hablando como asi tambien maximizar la pantalla si le das la orden por voz.

Sin tener que utilizar el esclavo o cosas asi porque es muy cutre.

Un abrazo
#21
No se que le paso, de un dia para el otro dejo de refrescar los servers y me tiene loco. Andaba siempre y ahora ya no, y me tira eso del titulo. Estan todos los firewall deshabilitados, la aplicacion desbloqueada por el firewall de windows, los puertos en el comodo e igual lo deshabilito.

No se que mas hacer, todos me dicen que haga eso de agregar a favorites pero a mi no me va porque de un dia para el otro dejo de andar el refresh de la pestaña internet.

Alguien tiene alguna solucion? borre el masterserver.vdf y tampoco, en google le paso a miles pero ninguno una solucion clara para no steam.

Espero la ayuda de los gamers

Un abrazo!
#22
La verdad que me esta volviendo loco este atrevido.

Luego de googlear horas encontre que este error los esta volviendo locos a todos y la verdad no se como solucionarlo. En windows vista modifican el sonido y sale andando, pero en xp la verdad que no vi nada  :-\.

El error en concreto es este

Citar----- Initializing Renderer ----
execing ragdoll.cfg from disk
----- Client Initialization -----
----- Client Initialization Complete -----
Trying SMP acceleration...
...succeeded.
----- R_Init -----
Getting Direct3D 9 interface...
Pixel shader version is 3.0
Vertex shader version is 3.0
Shader model 2.0 code path is available.
Shader model 3.0 code path is available.
Using Shader model 3.0 code path because it is the best available path on this hardware.
Attempting 640 x 480 fullscreen with 32 bpp at 60 hz
Game window successfully created.
Using 2x anti-aliasing
Creating Direct3D device...
Com_TouchMemory: 0 msec. Using sum: 0
Loading fastfile code_post_gfx
Loading fastfile ui
Loading fastfile common
Initializing render targets...
Requested frame buffer to be 24-bit color with 8-bit alpha
DirectX returned a frame buffer that is 24-bit color with 8-bit alpha
Initializing static model cache...
Initializing dynamic buffers...
Loading fastfile 'code_post_gfx'
used 1.13 MB memory in DB alloc
Initializing particle cloud buffer...
Creating Direct3D queries...
Setting initial state...
DirectX reports 256 MB of video memory and 444 MB of available texture memory.
Using video memory size to cap used texture memory at 240 MB.
Texture detail is set automatically.
Using picmip 0 on most textures, 1 on normal maps, and 3 on specular maps
Error: Waited 1258 msec for missing asset "water_droplet".
Error: Could not load material "water_droplet".
Error: Could not load material "water_dynamic_spray".
Loading fastfile 'ui'
used 39.48 MB memory in DB alloc

------- sound system initialization -------
Waiting for $init to finish.  There may be assets missing from
code_post_gfx.


Error during initialization:
Unhandled exception caught


La verdad que estoy tranqui con los requerimientos, ya que han tenido el mismo error gente con mucho mejor Hardware (muchisimo mejor)

Actualize el direxct
Actualize Drivers de video (y de sonido)
Reinstale el juego

Y absolutamente nada.

Estoy en Windows xp (aunque ya lo dije mas arriba) 1 giga de ram y gf de 256mb. Aclaro que el call of duty modern warfare me iba perfecto.


No se la verdad que goglee muchisimo asi que si alguien me tira un link con una solucion y funciona me sorprenderia mucho, asi que apelo mas a que tiren posibles soluciones por su cuenta para esto, o si hay algun informe oficial sobre este tipo de errores y que se me haya pesado. Porque los que solucionan este problema (generalmente en vista) despues tienen problemas con los save...

Un saludo

SOLUCION (Mi caso, no garantizo que le funcione a todo el mundo)

Luego de probar todo lo existente en la red y de que absolutamente nada funcione, estaba a punto de desinstalarlo cuando se me ocurrio ver de nuevo DXdiag. Entonces veo que el la pestaña "Sonido" decia "Emulado". Bueno, luego de eso me acorde de un viejo problema del XP, el cual tuve que googlear un poco.

La solucion es buscar en regedit "Device Presence", es ahi cuando vas a ver que dice "Emulated", "VxD" y "WDM" en mi caso todas con valor 1. Le cambias el valor de "Emulated" de "1" a "0", luego presionas F3 para buscar el siguiente, haces lo mismo hasta que le hayas puesto el valor 0 a cada "Emulated" que encuentres en "Device Presence" y listo, deberia andar ahi =). Ahora a solucionar el tema de los profile, que eso si ya estan las soluciones por todo internet.

:)