Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-12-2003
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Obtener nombre de objeto Windows a partir de un handle

¡Buen día a todos!

Mi pregunta es la siguiente:

¿De qué manera puedo obtener el nombre que tiene asociado un objeto Windows, a partir de su identificador (handle)?

Me refiero a los objetos eventos, mutex, memorias compartidas, semáforos, etc., que el sistema operativo guarda internamente.

Por ejemplo, si ejecuto el código:
Código:
Var
  Identificador :THandle;

Begin
  Identificador := CreateFileMapping (Invalid_Handle_Value, Nil,
Page_ReadWrite, 0, 10, 'Prueba');
para crear un objeto de memoria compartida (file mapping). ¿Más tarde puedo obtener el nombre que le dí ('Prueba'), a partir del valor guardado en la variable Identificador? Es decir, como si existiera una función llamada GetHandleName:
Código:
Var
  Nombre :String;
Begin
  Nombre := GetHandleName (Identificador);
Se que Windows guarda y administra la información de todos los objetos creados y sus identificadores abiertos (handles). Pero ¿habrá una forma de tener acceso a los detalles de dicha información, o por lo menos a los nombres de los objetos?

¿Se necesita una API adicional? ¿Es una dura restricción del sistema?

Les agradezco todas sus aportaciones al respecto. Seguimos en contacto.

Al González .

Última edición por Al González fecha: 22-12-2003 a las 22:32:18.
Responder Con Cita
  #2  
Antiguo 22-12-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Windows internamente maneja tres tipos genéricos de objetos: Que son los del User, GDI y Kernler. Todos estos objetos se identifican con un Handle y no necesariamente pertenecen a la misma lista, mismo si comparas un Handle de un objeto del Kernler con uno del GDI notarás que el del Kernler es mucho mas bajo que el del GDI, esto se debe a que el handle del GDI normalmente es el valor del un puntero, en cambio el del Kernler es una referencia al indice de la tabla interna del proceso.
En tu caso estas mezclando objetos del User (Objeto Window) con objetos del Kernler (FileMapping), y si hay forma de obtener información sobre estos objetos, pero hay funciones muy diferentes para cada tipo de objeto.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 23-12-2003
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Buen día a todos!

Delphi.com.ar:

Agradezco tus valiosos comentarios.

Aprovecho para actualizarles los resultados de mi investigación.

Después de leer varios documentos y estudiar algunas aplicaciones, he encontrado que Windows guarda una estructura de tipo EPROCESS por cada proceso activo en el sistema. Que dicha estructura contiene un campo llamado ObjectTable de tipo _HANDLE_TABLE, el cual es un arreglo que contiene las direcciones de memoria de todos los objetos pertenecientes al proceso (mutex, eventos, mapeos de archivo, etc.).

Dichos objetos se encuentran dentro del espacio de memoria del nucleo (kernel) del sistema. Cada uno tiene su propia estructura, pero con una cabecera de datos común de tipo _OBJECT_HEADER. La estructura _OBJECT_HEADER, tiene un campo llamado NameOffset, que es un desplazamiento negativo para encontrar el nombre del objeto.

Cuando creo un objeto de memoria compartida con la función CreateFileMapping, por ejemplo, ésta me regresa un valor de tipo HANDLE. Este valor entero es el índice o desplazamiento que tiene la entrada correspondiente en el campo ObjectTable de la estructura EPROCESS del programa en ejecución.

Esto quiere decir, que para obtener el nombre de un objeto mutex, evento, mapeo de archivo, etc. de un proceso, a partir de su identificador HANDLE, primero hay que localizar la estructura EPROCESS del proceso, enseguida usar el identificador HANDLE como índice en el campo ObjectTable; de ahí tomar el puntero que señala la dirección de memoria del objeto. Estos punteros señalan el comienzo del cuerpo (body) del objeto, así que hay que hacer un desplazamiento negativo del tamaño de _OBJECT_HEADER, para tener acceso a los campos de la cabecera (header). De ahí se toma el valor del campo NameOffset, para hacer otro desplazamiento negativo hacia el lugar donde se encuentra una estructura de tipo OBJECT_NAME, la cual contiene una cadena Unicode con el nombre del objeto.

Bien, en teoría esto no parece tan difícil: sólo hay que saber obtener la dirección de memoria de la estructura EPROCESS de un proceso, para tener acceso a su tabla de objetos (ObjectTable).

Existe una función llamada PsLookupProcessByProcessId, cuyo propósito es precisamente obtener la dirección de memoria de la estructura EPROCESS de un proceso dado. Esta función se localiza en el archivo estándar NTOSKRNL.EXE, el cual contiene las funciones API nativas el sistema operativo. Según he visto, este archivo y sus funciones sólo pueden ser utilizados en modo kernel, es decir, en ese modo especial en el que trabajan ciertos programas como los controladores de dispositivos, entres otros.

Sinceramente creo que debe existir otra manera de acceder a la estructura EPROCESS, bajo el modo de ejecución normal (user mode). No he encontrado otra función que sirva para obtener de forma directa y explícita la dirección de memoria de dicha estructura. Sin embargo creo que se podrían utilizar algunas de las funciones existentes en Kernel32.dll para lograr este objetivo.

Baso mi argumento en lo que descubrí con los programas Process Explorer 8.1 y PE Explorer 1.94. El primero muestra un listado de todos los objetos mutex, eventos, mapeos de archivo (sections), de cada proceso activo en el sistema. Con el segundo analizo las dependencias que tiene Process Explorer.

Según la información arrojada por PE Explorer, Process Explorer no utiliza ninguna función de NTOSKRNL.EXE (ni directa ni indirectamente). Es decir, no accede a la estructura EPROCESS de cada proceso con la función PsLookupProcessByProcessId. Process Explorer sólo utiliza unas cuantas DLLs estándares y muy comunes de Windows, entre ellas Kernel32.dll y ADVAPI32.dll, e indirectamente NTDLL.dll, que según he leído es la interfaz que existe para acceder a elementos del nucleo en modo normal de usuario.

Estoy seguro de que Process Explorer utiliza alguna técnica de mapeo de memoria para acceder a la estructura EPROCESS y su lista ObjectTable de cada programa en ejecución, y así poder mostrar los nombres de todos los objetos mutex, eventos y mapeos de archivo creados por los procesos. Es decir, Process Explorer, sin usar la API nativa NTOSKRNL.EXE ni la función PsLookupProcessByProcessId, y aparentemente sin entrar de forma explícita en modo kernel, localiza la estructura EPROCESS, lee su arreglo ObjectTable, accede a la memoria de cada objeto y lee sus nombres.

Es decir, si es viable en modo de usuario obtener el nombre de un objeto kernel, a partir de uno de sus identificadores HANDLE. Aparentemente sólo me falta saber localizar la estructura EPROCESS. De última hora me viene a la mente que tal vez esa estructura ocupa los primeros bytes de la memoria virtual del proceso.

Agradezco cualquier aportación que se haga a este tema. Pienso que éste puede ser un hilo valioso, ya que existe poca literatura gratuita en español que hable de las estructuras internas de Windows.

Anexo algunos enlaces importantes que encontré durante mi investigación:

http://www.alkor.ru/~00077500/kb/ntfiles.htm
http://msdn.microsoft.com/library/de...e&hidetoc=true
http://www.sysinternals.com/index.shtml
http://www.theparticle.com/files/txt...k/p59-0x10.txt
http://www.linuxgazette.com/issue23/flower/page1.html
http://www.ntkernel.com/resources.shtml
http://www.informit.com/content/inde...-302DF1E029E7}

Espero esto sea de utilidad. Seguimos en contacto.

Al González .
Responder Con Cita
  #4  
Antiguo 23-12-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
En concreto... ¿Que es lo que quieres lograr?.. algo similar al panel inferior del ProcessExplorer??...
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #5  
Antiguo 23-12-2003
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Buen día a todos!

Delphi.com.ar:

Agradezco tu interés en este caso.

En términos generales, mi respuesta a tu pregunta es . Deseo localizar los nombres de los objetos que pertenecen a un proceso a partir de sus identificadores HANDLE.

Más concretamente, si en un programa creo varios objetos y guardo sus identificadores (HANDLEs) en una lista, más tarde deseo poder obtener el nombre que se le dio a cada uno. Esto es para una bilioteca de funciones, donde sólo el programador final sabrá cuántos objetos crea y con qué nombres. Quiero evitar el uso de una lista alterna de nombres relacionados con los identificadores, bajo el conocimiento de que esa relación ya existe en las estructuras internas de Windows (¿para qué ocupar más memoria?).

Además, pretendo facilitar el camino a otros desarrolladores Delphi interesados en el aprovechamiento de los recursos internos de Windows.

Muchas gracias por sus aportaciones.

Atentamente,

Al González .
Responder Con Cita
  #6  
Antiguo 23-12-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Ok.. Basándonos en toda la teoría que has escrito en el mensaje anterior, podríamos recorrer todos los procesos con la "ToolHelp" (CreateToolhelp32Snapshot, Process32First...), abrir los procesos (OpenProcess) y acceder a la memoria de estos procesos con ReadProcessMemory.
El problema, es que seguramente estas estructuras que has nombrado difieran entre las plataformas, por eso siempre es mejor utilizar las funciones indicadas para cada caso. En este caso, he buscado funciones para listar los objetos de un proceso, y a simple vista no encontré nada.

Espero que te sirvan mis comentarios, y no olvides tenernos al tanto de la investigación, y contá conmigo para las inquietudes!
Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 08:21:34.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi