Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Horricreu en 18 Junio 2010, 22:36 pm



Título: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 18 Junio 2010, 22:36 pm
Bueno, tengo este código que compila perfectamente y no crashea, pero siempre me termina al MessageBox() de error:

Código
  1. #include <windows.h>
  2.  
  3. int main()
  4. {
  5.        HANDLE hHeap = GetProcessHeap();
  6.  
  7.        LPSTR lpBuffer = "Escribe la ruta del fichero: ";
  8.        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer, lstrlen(lpBuffer), 0, 0);
  9.  
  10.        LPSTR lpFileName = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH);
  11.        DWORD nNumberOfCharsRead = 0;
  12. ReadConsole(GetStdHandle(STD_INPUT_HANDLE), lpFileName, &nNumberOfCharsRead, 0, 0);
  13.  
  14. HANDLE hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  15.  
  16. if(hFile == INVALID_HANDLE_VALUE) MessageBox(0, "Error", "Error", 0);
  17.  
  18. else MessageBox(0, "Funciona", "Funciona", 0);
  19.  
  20. return 0;
  21. }

El caso es que al escribir la ruta del fichero, me dice error aunque exista. ¿Alguna solución? Seguramente se tiene que recurrir al debuggeo pero aun no sé.

Muchas gracias y saludos :P


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Littlehorse en 19 Junio 2010, 00:49 am
Si tenes la base de la ruta en lpBuffer, cuando leas el nombre del archivo, debes concatenar esos datos en un solo buffer a la hora de llamar a CreateFile, de lo contrario no tiene mucho sentido tener una base de ruta en un buffer y el nombre del archivo en otro.

También cabe remarcar que lstrlen(lpFilename) va a devolver 0, y ademas uno de los parámetros de ReadConsole es incorrecto, debería ser un LPDWORD (DWORD &charsread por ejemplo) de lo contrario te debería dar un error. No recuerdo si dicho parámetro es opcional o no, revisalo en la MSDN pero creo que no lo es.

Seguramente CreateFile te devuelve ERROR_PATH_NOT_FOUND por lo antes mencionado, así que procura llamar a GetLastError para encontrar el problema.

Algo así:

Código
  1. HANDLE hFile = CreateFile(lpFileName,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
  2.    if(hFile==INVALID_HANDLE_VALUE)
  3.      printf("CreateFile error: %d\n",GetLastError());

Y luego buscas en la MSDN los códigos de error.

Saludos!


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 12:30 pm
Ok, vamos por partes:

  • lpBuffer es sólo para que se muestre esta cadena de texto en la consola. lpFileName es la ruta del fichero que vamos a esciribir, ¿entiendes?
  • No entiendo lo de lstrlen(). ¿No está bien? Por cierto, es verdad, el parámetro 4 de ReadConsole() NO es opcional, me lo deje. Muchas gracias ;)
  • Exacto, CreateFile() me devuelve error 3, por lo tanto como dijiste me devuelve ERROR_PATH_NOT_FOUND.

No puede ser que CreateFile() me devuelva ERROR_PATH_NOT_FOUND porque escribo la ruta tal y como está :-\

Littlehorse, muchas gracias por tu ayuda. Saludos :P


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Eternal Idol en 19 Junio 2010, 15:15 pm
Si reservas memoria para la cadena haciendo que esta este inicializada a 0 (HEAP_ZERO_MEMORY) entonces lstrlen obviamente devolvera como resultado 0, esa funcion devuelve el numero de caracteres y estas cadenas estan terminadas por 0, es dcir no hay ningun caracter, en lugar de lstren deberias usar MAX_PATH - 1 por ejemplo.


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 16:18 pm
Si hago esto que me dices:

Código
  1. ReadConsole(GetStdHandle(STD_INPUT_HANDLE), lpFileName, MAX_PATH - 1, &lpNumberOfCharsRead, 0);

No me funciona :-\ Es esto lo que me dices que haga, ¿no?

Saludos :P

EDITO: muestro el código con las correcciones que me habéis dado (sigue sin funcionar :-\):

Código
  1. #include <windows.h>
  2.  
  3. int main()
  4. {
  5. LPSTR lpBuffer = "Escribe la ruta del fichero: ";
  6. DWORD nNumberOfCharsRead = 0;
  7.  
  8. LPSTR lpFileName = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH);
  9.  
  10. WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer, lstrlen(lpBuffer), 0, 0);
  11.  
  12. ReadConsole(GetStdHandle(STD_INPUT_HANDLE), lpFileName, MAX_PATH - 1, &nNumberOfCharsRead, 0);
  13.  
  14. HANDLE hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  15.  
  16. if(hFile == INVALID_HANDLE_VALUE) MessageBox(0, "Error", "Error", 0);
  17.  
  18. else MessageBox(0, "Funciona", "Funciona", 0);
  19.  
  20. return 0;
  21. }


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Eternal Idol en 19 Junio 2010, 17:04 pm
La lectura es correcta, si lo depuras lo vas a ver, el tema es que eso incluye el salto de linea (\r\n) y para el nombre del archivo no es correcto. Ahora lo que tenes que hacer es terminar la cadena antes (hacelo con cuidado y teniendo en cuenta que el usuario puede escribir cualquier cosa).


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 20:02 pm
La lectura es correcta, si lo depuras lo vas a ver, el tema es que eso incluye el salto de linea (\r\n) y para el nombre del archivo no es correcto. Ahora lo que tenes que hacer es terminar la cadena antes (hacelo con cuidado y teniendo en cuenta que el usuario puede escribir cualquier cosa).

Ok, ya tengo codificada esta parte según lo que me dijiste de \r\n, pero aun así el programa tampoco va:

Código
  1. if (lpNumberOfCharsRead > 2)
  2. {
  3. LPSTR lpRealFile = (LPSTR)lpFileName + lpNumberOfCharsRead - 2;
  4. *lpRealFile = 0;
  5. }

Pero, como sabes que incluye \r\n. ¿En la MSDN sale? Te agradecería si me pasaras el enlace donde encontraste esta información :)

Saludos :P


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Eternal Idol en 19 Junio 2010, 20:16 pm
Estaras poniendo mal el path  :rolleyes: Depuralo, si lo hubieras hecho ya sabrias que el \r\n estaba en la cadena, no hace falta nada mas.
Igualmente el modo de lectura por defecto implica que ReadConsole no devuelva hasta que el usuario aprete ENTER:

"High-Level Console Modes
The behavior of the high-level console functions is affected by the console input and output modes. All of the following console input modes are enabled for a console's input buffer when a console is created:



Line input mode
Processed input mode
Echo input mode

...
ENABLE_LINE_INPUT Used with a console input handle to cause the ReadFile and ReadConsole functions to return when the ENTER key is pressed. If line input mode is disabled, the functions return when one or more characters are available in the input buffer."


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 20:37 pm
Es verdad, acabo de depurar y lo dice. Ahora no sé porque aun no va. Escribo la ruta del fichero bien :-\

Saludos :P


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Littlehorse en 19 Junio 2010, 20:52 pm
Lo que haces dentro del if no es lo mas adecuado ya que implica utilizar un puntero extra.

Basta con usar la notación de arreglos luego de tu if:

Código
  1. lpFileName[lstrlen(lpFileName)-2]=0;


Por otro lado ten en cuenta que \r\n no son los únicos caracteres inválidos para una ruta, por lo tanto el buffer que la contiene requiere una validación antes de ser procesada.

Un consejo, cuando tengas un error que no puedes encontrar, revisa los parámetros de las funciones que no hacen lo que deben porque en este caso esos han sido el problema principal desde el principio.

En cuanto al código, a mi me funciona y CreateFile me devuelve el handle correcto. En todo caso estarás poniendo mal la ruta.

Saludos


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 21:09 pm
Gracias, ya puse esto pero continua sin ir. Vamos a ver, voy a ponerlo con imágenes y todo para que me creáis de que pongo bien la ruta y todo:

Código
  1. #include <windows.h>
  2.  
  3. int main()
  4. {
  5.        HANDLE hHeap = GetProcessHeap();
  6.  
  7.        LPSTR lpBuffer = "Escribe la ruta del fichero: ";
  8.        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer, lstrlen(lpBuffer), 0, 0);
  9.  
  10.        LPSTR lpFileName = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH);
  11.        DWORD nNumberOfCharsRead = 0;
  12. ReadConsole(GetStdHandle(STD_INPUT_HANDLE), lpFileName, MAX_PATH - 1, &nNumberOfCharsRead, 0);
  13.  
  14. HANDLE hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  15.  
  16. if(hFile == INVALID_HANDLE_VALUE)
  17. {
  18. MessageBox(0, "Error", "Error", 0);
  19.  
  20. lpFileName[lstrlen(lpFileName) - 2] = 0;
  21. }
  22.  
  23. else MessageBox(0, "Funciona", "Funciona", 0);
  24.  
  25. return 0;
  26. }

Escribo la ruta:

(http://r.i.elhacker.net/cache?url=http://img31.imageshack.us/img31/706/paintrm.jpg)

Y para comprobar que existe:

(http://r.i.elhacker.net/cache?url=http://img194.imageshack.us/img194/4340/paint2q.jpg)

Luego no es culpa de la ruta :-\ :o

Saludos :P


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Littlehorse en 19 Junio 2010, 21:14 pm
 :D, revisa lo que has hecho:

Código
  1. if(hFile == INVALID_HANDLE_VALUE)//Si CreateFile me devuelve error porque la ruta esta mal
  2. {                                                      
  3.   MessageBox(0,"Error","Error",0); //Imprimo mensaje de error
  4.  
  5.   lpFileName[lstrlen(lpFileName) - 2] = 0;// Y ahora si arreglo la ruta
  6. }
  7. //Termina el programa

Luego la culpa es de CreateFile  ;D

Saludos!


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 21:19 pm
:D, revisa lo que has hecho:

Código
  1. if(hFile == INVALID_HANDLE_VALUE)//Si CreateFile me devuelve error porque la ruta esta mal
  2. {                                                      
  3.   MessageBox(0,"Error","Error",0); //Imprimo mensaje de error
  4.  
  5.   lpFileName[lstrlen(lpFileName) - 2] = 0;// Y ahora si arreglo la ruta
  6. }
  7. //Termina el programa

Luego la culpa es de CreateFile  ;D

Saludos!

Ya lo sé, pero los parámetros están bien :)

Saludos :P


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Littlehorse en 19 Junio 2010, 21:23 pm
No horricreu, no están bien. Vuelve a leer el hilo completo y analiza todo lo que te he dicho yo y todo lo que te ha dicho Eternal Idol. Estas intentando pasarle a CreateFile una ruta incorrecta y la finalizas correctamente solamente si CreateFile te da un error pero jamas vuelves a llamar a CreateFile nuevamente.

No seria mejor finalizar correctamente la cadena antes de llamar a CreateFile?

Saludos!


Título: Re: [C++][?] Error en ReadConsole()
Publicado por: Horricreu en 19 Junio 2010, 21:38 pm
No horricreu, no están bien. Vuelve a leer el hilo completo y analiza todo lo que te he dicho yo y todo lo que te ha dicho Eternal Idol. Estas intentando pasarle a CreateFile una ruta incorrecta y la finalizas correctamente solamente si CreateFile te da un error pero jamas vuelves a llamar a CreateFile nuevamente.

No seria mejor finalizar correctamente la cadena antes de llamar a CreateFile?

Saludos!


¡Ya está solucionado! Gracias Eternal Idol y Littlehorse por vuestra ayuda, he aprendido algo nuevo ;) :xD

Saludos :P

PD:

Código
  1. #include <windows.h>
  2.  
  3. int main()
  4. {
  5.        HANDLE hHeap = GetProcessHeap();
  6.  
  7.        LPSTR lpBuffer = "Escribe la ruta del fichero: ";
  8.        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuffer, lstrlen(lpBuffer), 0, 0);
  9.  
  10.        LPSTR lpFileName = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH);
  11.        DWORD nNumberOfCharsRead = 0;
  12. ReadConsole(GetStdHandle(STD_INPUT_HANDLE), lpFileName, MAX_PATH - 1, &nNumberOfCharsRead, 0);
  13.  
  14.        lpFileName[lstrlen(lpFileName) - 2] = 0;
  15.  
  16. HANDLE hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  17.  
  18. if(hFile == INVALID_HANDLE_VALUE) MessageBox(0, "Error", "Error", 0);
  19.  
  20. else MessageBox(0, "Funciona", "Funciona", 0);
  21.  
  22. return 0;
  23. }