Retrouver le nom d'un fichier avec un FILE*

Retrouver le nom d'un fichier avec un FILE* - C - Programmation

Marsh Posté le 04-01-2007 à 20:38:48    

Bonjour,
 
J'aurai voulu savoir s'il était possible de retrouver le nom d'un fichier à partir d'un FILE*, après avoir ouvert le fichier avec un fopen ?
 
 
Merci.

Reply

Marsh Posté le 04-01-2007 à 20:38:48   

Reply

Marsh Posté le 05-01-2007 à 00:33:21    

sangohan001 a écrit :

J'aurai voulu savoir s'il était possible de retrouver le nom d'un fichier à partir d'un FILE*, après avoir ouvert le fichier avec un fopen ?


 
Pas à ma connaissance... ce qui est à mon avis plutôt normal. En général, celui qui fait du "fopen()" est sensé savoir ce qu'il y a dans les parenthèses... :D  


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 05-01-2007 à 00:45:07    

sangohan001 a écrit :

J'aurai voulu savoir s'il était possible de retrouver le nom d'un fichier à partir d'un FILE*, après avoir ouvert le fichier avec un fopen ?


Non. On est censé savoir ce qu'on fait ou prendre des notes...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2007 à 01:24:53    

et non personne ne le sait!!! meme le systeme lui meme ne le sait pas  
dailleurs qd tu fait fwrite il va ecrire un peu nimporte ou et par hasard c sur ton fichier!
 
bravo tu doit ecouter tout c gens!
 

Reply

Marsh Posté le 05-01-2007 à 08:53:36    

red faction a écrit :

et non personne ne le sait!!! meme le systeme lui meme ne le sait pas  
dailleurs qd tu fait fwrite il va ecrire un peu nimporte ou et par hasard c sur ton fichier!
 
bravo tu doit ecouter tout c gens!


 
[:kiki]
 
Le "système" n'a pas besoin du nom d'un fichier, son emplacement lui suffit. [:itm]

Reply

Marsh Posté le 05-01-2007 à 09:56:53    

Et ca renverrait quoi pour stdin / stdout / stderr ?

Reply

Marsh Posté le 05-01-2007 à 10:00:56    

Tu veux dire quoi, par "renvoyer" ?  
Tu es dans l'hypothèse où une méthode existerait pour retourner le nom d'un fichier à partir d'un FILE* ?
 
Si oui, sous Unix ça renverrait /dev/stdin, /dev/stderr et /dev/stdout [:o_doc]

Reply

Marsh Posté le 05-01-2007 à 10:08:21    

Ace17 a écrit :

Et ca renverrait quoi pour stdin / stdout / stderr ?


Sous DOS/Windows :

  • stdin : "con" en mode "r"
  • stdout : "con" en mode "w"
  • stderr : euh...


Mais comme les 2 premiers, au moins, sont redirigeables soit sur la ligne de commande avec < ou >, soit avec freopen(), ben, c'est pas si simple...


Message édité par Emmanuel Delahaye le 05-01-2007 à 10:12:31

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2007 à 10:10:52    

Et si la sortie du programme est redirigee vers l'entree d'un autre (pipe) ?  :D
 
edit : grilled par edition


Message édité par Ace17 le 05-01-2007 à 10:11:24
Reply

Marsh Posté le 05-01-2007 à 10:56:59    

Emmanuel Delahaye a écrit :

Non. On est censé savoir ce qu'on fait ou prendre des notes...


[:rofl]
 

red faction a écrit :

dailleurs qd tu fait fwrite il va ecrire un peu nimporte ou et par hasard c sur ton fichier!


[:rofl][:rofl]
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 05-01-2007 à 10:56:59   

Reply

Marsh Posté le 05-01-2007 à 12:48:02    

red faction a écrit :

et non personne ne le sait!!! meme le systeme lui meme ne le sait pas  
dailleurs qd tu fait fwrite il va ecrire un peu nimporte ou et par hasard c sur ton fichier!
bravo tu doit ecouter tout c gens!


 :ange:  c'est pas parce que le systeme le sait qu'il y a forcement un moyen pour ton programme de le savoir, encore moins si tu veux recuperer cette information de maniere standard...

Reply

Marsh Posté le 07-01-2007 à 03:47:07    

Ace17 a écrit :

:ange:  c'est pas parce que le systeme le sait qu'il y a forcement un moyen pour ton programme de le savoir


 
Bien sûr que si.
Surtout en ring 0 sous Windows.
 
Pour la queston, oui, on peut (sous Windows toujours, linked list des handles)

Reply

Marsh Posté le 07-01-2007 à 04:37:56    

Suffit de générer une chaine aléatoire assez grande, de l'écrire dans le fichier et de scanner tout le disque dur à sa recherche :o


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 07-01-2007 à 13:41:10    

marctes a écrit :

Bien sûr que si.
Surtout en ring 0 sous Windows.


Ce que je voulais dire c'est justement qu'en fonction de la couche dans laquelle tu te trouves il y a des choses auxquelles tu n'accedes qu'indirectement. Et il ne suffit pas d'avoir acces a toute la mémoire pour récuperer n'importe quelle information.

Reply

Marsh Posté le 07-01-2007 à 18:56:34    

Bonsoir,
Sous Windows, il existe la fonction getFullPathName(HANDLE,...) qui permet de retrouver le nom du fichier. Reste a voir si HANDLE et FILE sont compatible...

Reply

Marsh Posté le 07-01-2007 à 21:25:40    

marctes a écrit :

Bien sûr que si.
Surtout en ring 0 sous Windows.
 
Pour la queston, oui, on peut (sous Windows toujours, linked list des handles)


 
Peux-tu expliquer, en gros, comment cela fonctionne, s'il te plait ?
 
Edit02 :
 
Parce qu'apparemment, même les gars de SysInternals ne savent pas faire. Et pourtant, FileMon utilise un driver.  
http://www.microsoft.com/technet/s [...] n.mspx#EBE
 

Citation :


How FileMon Works
...
On Windows NT the heart of FileMon is a file system driver that creates and attaches filter device objects to target file system device objects so that FileMon will see all IRPs and FastIO requests directed at drives. When FileMon sees an open, create or close call, it updates an internal hash table that serves as the mapping between internal file handles and file path names. Whenever it sees calls that are handle based, it looks up the handle in the hash table to obtain the full name for display. If a handle-based access references a file opened before FileMon started, FileMon will fail to find the mapping in its hash table and will simply present the handle's value instead.


 
Traduction :
Le coeur de FileMon est un driver. Une table de hash est utilisée pour faire le lien entre le handle du fichier et son nom. Si un fichier a été ouvert avant que FileMon ne démarre, il ne pourra pas le retrouver dans sa table de hash et ne pourra pas afficher son chemin mais seulement son handle.
 
Sans être sûr à 100% que cela ne soit pas possible, je pense que s'il existait un moyen, ces gars l'aurait utilisé. Donc, marctes, si tu connais une façon d'y arriver, je te serais infiniment reconnaissant de nous l'expliquer.  :jap:  
 
***********
 

breizhbugs a écrit :

Bonsoir,
Sous Windows, il existe la fonction getFullPathName(HANDLE,...) qui permet de retrouver le nom du fichier. Reste a voir si HANDLE et FILE sont compatible...


Hmmm... D'après la MSDN, le premier argument n'est pas un handle mais le nom du fichier dont on veut retrouver le chemin. :)

Code :
  1. DWORD GetFullPathName(
  2.   LPCTSTR lpFileName,
  3.   DWORD nBufferLength,
  4.   LPTSTR lpBuffer,
  5.   LPTSTR* lpFilePart
  6. );


 
Edit01 :
 
Et pour répondre à ta question, un HANDLE est un numéro identifiant un "objet" ouvert par windows (Fichier, contexte d'affichage, adresse de dll, fenêtre, etc.). Alors qu'un FILE est une structure utilisée par la lib C. Cela n'a donc rien à voir. :)


Message édité par anordem le 07-01-2007 à 22:22:31
Reply

Marsh Posté le 08-01-2007 à 14:06:02    

Citation :


Hmmm... D'après la MSDN, le premier argument n'est pas un handle mais le nom du fichier dont on veut retrouver le chemin. :)

Code :
  1. DWORD GetFullPathName(
  2.   LPCTSTR lpFileName,
  3.   DWORD nBufferLength,
  4.   LPTSTR lpBuffer,
  5.   LPTSTR* lpFilePart
  6. );


 
Edit01 :
 
Et pour répondre à ta question, un HANDLE est un numéro identifiant un "objet" ouvert par windows (Fichier, contexte d'affichage, adresse de dll, fenêtre, etc.). Alors qu'un FILE est une structure utilisée par la lib C. Cela n'a donc rien à voir. :)


 
Argh j'ai du mal des fois!!
 
en fouillant mon stdio.h, voici la definition de FILE (issus de VC 2005 express):

Code :
  1. #ifndef _FILE_DEFINED
  2. struct _iobuf {
  3.         char *_ptr;
  4.         int   _cnt;
  5.         char *_base;
  6.         int   _flag;
  7.         int   _file;
  8.         int   _charbuf;
  9.         int   _bufsiz;
  10.         char *_tmpfname;
  11.         };
  12. typedef struct _iobuf FILE;
  13. #define _FILE_DEFINED
  14. #endif


The question is: _tmpfname contient quoi?
EDIT: bon apres investigation sur google, ca marche pas non plus:
http://www.experts-exchange.com/Pr [...] 78041.html

Message cité 2 fois
Message édité par breizhbugs le 08-01-2007 à 14:10:46
Reply

Marsh Posté le 08-01-2007 à 14:38:19    

breizhbugs a écrit :

en fouillant mon stdio.h, voici la definition de FILE (issus de VC 2005 express):


Bzzt ! Il n'y a pas de "la définition de FILE". FILE n'est pas définit par le langage C autrement que comme un type opaque. Chaque implémentation fait ce qu'elle veut.

 

Tu as montré une implémentation de FILE, je pourrais t'en montrer d'autres...
MinGW :

Code :
  1. /*
  2. * The structure underlying the FILE type.
  3. *
  4. * Some believe that nobody in their right mind should make use of the
  5. * internals of this structure. Provided by Pedro A. Aranda Gutiirrez
  6. * <paag@tid.es>.
  7. */
  8. #ifndef _FILE_DEFINED
  9. #define _FILE_DEFINED
  10. typedef struct _iobuf
  11. {
  12. char* _ptr;
  13. int _cnt;
  14. char* _base;
  15. int _flag;
  16. int _file;
  17. int _charbuf;
  18. int _bufsiz;
  19. char* _tmpfname;
  20. } FILE;
  21. #endif /* Not _FILE_DEFINED */


(qui ressemble étrangement à ta version 'visual C++ express', tu es sûr de ton coup ?)

  


Message édité par Emmanuel Delahaye le 08-01-2007 à 14:39:04

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 08-01-2007 à 14:55:13    

Il faudrait dessasembler fread pour voir ce quil fait de FILE* pour retrouver le HANDLE windows (il doit forcement aller le chercher qqpart avant de la passe a lapi windows) .  Apres un coup de GetFullPathName() et le tour est joué (bien sur c pas portable mais bon)

Message cité 1 fois
Message édité par red faction le 08-01-2007 à 14:56:20
Reply

Marsh Posté le 08-01-2007 à 15:52:53    

Citation :

Bzzt ! Il n'y a pas de "la définition de FILE". FILE n'est pas définit par le langage C autrement que comme un type opaque. Chaque implémentation fait ce qu'elle veut.


Je sais, c'est pourquoi j'ai preciser qu'elle venait de vc2005 express
 
 

Reply

Marsh Posté le 08-01-2007 à 16:40:41    

Salut.
Le systeme fait forcement la liaison entre un nom et un filedesc, pour linux ça sera filedesc inode, inode nom de lien donc fichier.
Voir fstat pour l'inode.
Sous windows je sais pas par ou on passe.
Le problème est que trouver le nom du fichier revient à ecrire un petit programme.

Reply

Marsh Posté le 08-01-2007 à 16:47:09    

Le problème de fstat() c'est qu'il utilise un descripteur de fichier posix, obtenu avec open().
 
Les autres fonctions stat() et lstat() fonctionnent avec un chemin.

Reply

Marsh Posté le 08-01-2007 à 18:03:41    

yolas22 a écrit :

Salut.
Le systeme fait forcement la liaison entre un nom et un filedesc, pour linux ça sera filedesc inode, inode nom de lien donc fichier.
Voir fstat pour l'inode.
Sous windows je sais pas par ou on passe.
Le problème est que trouver le nom du fichier revient à ecrire un petit programme.


 
Ce n'est pas parce qu'on peut retrouver une info à partir d'une première que l'inverse est "forcément" vrai. Le système n'a pas besoin de connaitre le nom du fichier pour travailler dessus, par contre, l'utilisateur oui. Donc le système doit savoir retrouver l'adresse du fichier à partir de son nom mais il n'a pas besoin de retrouver le nom à partir de l'adresse. Rien n'indique que sela soit possible.
 
Exemple :
 
Un programme (win32) utilise la fonction GetLastError exporté par la bibliothèque Kernel32.dll. Pour retrouver son adresse, c'est très simple, il suffit d'appeler GetProcAddress(Kernel32_hModule, "GetLastError" ). Mais là, surprise ! L'adresse renvoyée est celle de la fonction RtlGetLastWin32Error exportée par NTDLL.dll. Ca s'appelle les fonctions Forward, déclarées dans Kernel32 mais dont le code se trouve dans NTDLL (l'utilité de cette méthode est de fournir une api uniforme sous NT comme sous 9x). En fait, dans la table d'export de Kernel32, là où il devrait y avoir l'adresse de la fonction, il y a l'adresse d'une chaîne de la forme "ntdll.RtlGetLastWin32Error" pour indiquer que c'est une fonction forward.
 
Le truc, c'est qu'à partir de l'adresse, on ne pourra pas retrouver le nom kernel32.GetLastError qui est le vrai nom de la fonction utilisée par le programme, présent dans sa table d'imports.
 

Reply

Marsh Posté le 08-01-2007 à 18:05:36    

Accessoirement un n° d'inode peut ne correspondre à aucun fichier [:spamafote]


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 08-01-2007 à 19:01:47    

breizhbugs a écrit :

En fouillant mon stdio.h, voici la definition de FILE (issus de VC 2005 express):

Code :
  1. #ifndef _FILE_DEFINED
  2. struct _iobuf {
  3.         char *_ptr;
  4.         int   _cnt;
  5.         char *_base;
  6.         int   _flag;
  7.         int   _file;
  8.         int   _charbuf;
  9.         int   _bufsiz;
  10.         char *_tmpfname;
  11.         };
  12. typedef struct _iobuf FILE;
  13. #define _FILE_DEFINED
  14. #endif


The question is: _tmpfname contient quoi?


 
Ben fait un printf("%s", fp->_tmpfname)...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 08-01-2007 à 20:35:10    

Accessoirement, c'est quoi l'interet de la manip?  
Et pour red faction, je rappelle la declaration de GetFullPathName :

Code :
  1. DWORD GetFullPathName(
  2.   LPCTSTR lpFileName,
  3.   DWORD nBufferLength,
  4.   LPTSTR lpBuffer,
  5.   LPTSTR* lpFilePart
  6. );


 
Il est ou le handle dans l'histoire ?
 

Reply

Marsh Posté le 09-01-2007 à 06:24:46    

breizhbugs a écrit :

Bonsoir,
Sous Windows, il existe la fonction getFullPathName(HANDLE,...) qui permet de retrouver le nom du fichier. Reste a voir si HANDLE et FILE sont compatible...


jmettais fié a ce post, ...

Reply

Marsh Posté le 09-01-2007 à 10:10:25    

Je suis d'accord avec toi Anordem le système n'en a pas besoin ( du nom de fichier), mais il en donne la possibilité à l'utilisateur.  
Le système est capable de fournir à l'utilisateur ce type de données, aprés par ou il faut passer c'est autre chose.
Mais le raisonnement et tout de même logique si il peut nous fournir nom et filedesc lié l'un et l'autre peuvent être retrouvés à partir d'un seul.
C'est une opinion mais je doute que la manip soit impossible.

Reply

Marsh Posté le 09-01-2007 à 12:57:43    

ou alors tu capte tout les CreateFile et tu fait une table handle<->fichier,  
 
apres obtient le handle dapres le file* puis le nom
mais
-cest compliqué
-cest pas portable
-tu ne peut avoir le nom du fichier que si tu as intercepté le createfile avant

Reply

Marsh Posté le 09-01-2007 à 18:27:56    

red faction a écrit :

ou alors tu capte tout les CreateFile et tu fait une table handle<->fichier,  
 
apres obtient le handle dapres le file* puis le nom
mais
-cest compliqué
-cest pas portable
-tu ne peut avoir le nom du fichier que si tu as intercepté le createfile avant


Ou alors tu as un cerveau qui dépasse le cap des 2mn non volatile et t'arrives à te souvenir du nom que t'as mis dans les parenthèses...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 09-01-2007 à 18:42:25    

heu c pas moi qui veut ca  
rien a foutre de connaitre le nom fichier ouvert avec FILE*

Reply

Marsh Posté le 09-01-2007 à 19:09:32    

red faction a écrit :

heu c pas moi qui veut ca


Oui oui, désolé du quiproquo. J'ai juste renchéri sur ton post pour répondre à sangohan001 (qui, soit dit en passant, n'a jamais plus rien dit ici).
Si ça se trouve, il doit modifier un programme C mono source et mono fonction complètement moisi où il y a écrit "fopen(toto, ...)" en ligne 12680 et comme il ne veut pas se casser le c... à essayer de remonter l'origine de "toto" dans le fatras de son code tout pourri il cherche à rajouter cette verrue supplémentaire...


Message édité par Sve@r le 10-01-2007 à 17:01:43

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 14-01-2007 à 23:07:17    

Sve@r a écrit :

Ou alors tu as un cerveau qui dépasse le cap des 2mn non volatile et t'arrives à te souvenir du nom que t'as mis dans les parenthèses...


Et pourtant! mais sous Windows. Sans compter que « vista » implémente une méthode qui le fait : GetFileInformationByHandleEx.

Message cité 1 fois
Message édité par videaste95 le 14-01-2007 à 23:17:11
Reply

Marsh Posté le 14-01-2007 à 23:43:12    

Quel rapport avec le FILE* ? S'il n'a pas un HANDLE, c'est crâmé [:spamafote]

Reply

Marsh Posté le 15-01-2007 à 17:06:45    

videaste95 a écrit :

Et pourtant! mais sous Windows. Sans compter que « vista » implémente une méthode qui le fait : GetFileInformationByHandleEx.


 
Merci pour l'info.  :jap:  
A noter cependant que GetMappedFileName n'est disponible que sous système NT dans la bibliothèque Psapi.dll. Mais c'est déjà pas mal.  
 
D'après mes quelques tests, un indice permettant de retrouver le HANDLE renvoyé par CreateFile est stocké dans FILE._file. Cependant, il n'est pas du tout sûr que cela soit toujours le cas (du moins, qu'il soit toujours à la même place). Ensuite, il faut manipuler un tableau de structures pointé par __pioinfo (exportée par msvcrt.dll). Je n'ai pas trouvé la définition de cette structure (je n'ai pas beaucoup cherché) mais il est fort possible qu'elle change d'une version à l'autre. D'après le code désassemblé, la structure fait 36 octets, soit 9 DWORDs. Le code suivant permet de retrouver un HANDLE à partir d'un FILE mais comme il utilise des structures internes non documentées, il peut ne pas fonctionner sur d'autres machines. Et ça n'est valable que pour windows.
 

Code :
  1. typedef struct {
  2.     HANDLE  hFile;
  3.     DWORD   reserved[8];
  4. } tfile;
  5. // __pioinfo exportée par msvcrt.dll contient l'adresse  
  6. // d'un tableau de structures tfile.
  7. tfile** __pioinfo;
  8. FILE* pFile;
  9. ...
  10. // Récupère l'adresse du pointeur.
  11. __pioinfo = (tfile**)GetProcAddress(GetModuleHandle("msvcrt" ), "__pioinfo" );
  12. // Ouvre le fichier en lecture.
  13. pFile = fopen(Path, "r" );
  14. // Récupère sa taille avec l'api windows à partir de son FILE.
  15. taille = GetFileSize( (*__pioinfo)[pFile->_file].hFile , 0);


 
Donc tout ceci reste plutôt bancal. :)

Reply

Marsh Posté le 15-01-2007 à 19:20:39    

Prochain concours : comment retrouver l'addresse d'un int a partir de sa valeur. Stay tuned ...

Reply

Marsh Posté le 15-01-2007 à 20:04:24    

anordem a écrit :

Ensuite, il faut manipuler un tableau de structures pointé par __pioinfo (exportée par msvcrt.dll). Je n'ai pas trouvé la définition de cette structure (je n'ai pas beaucoup cherché) mais il est fort possible qu'elle change d'une version à l'autre.


 
"pioinfo" c'est franchement pas tellement loin de "pipoinfo"...  :whistle:  
 
 

Ace17 a écrit :

Prochain concours : comment retrouver l'addresse d'un int a partir de sa valeur. Stay tuned ...


Euh... ça compte si on arrive à faire le contraire (trouver la valeur à partir de l'adresse) ??? [:petrus75]


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 15-01-2007 à 20:27:37    

Sve@r a écrit :

Euh... ça compte si on arrive à faire le contraire (trouver la valeur à partir de l'adresse) ??? [:petrus75]


C'est comme si tu me demandais "et si j'arrive a trouver un FILE* a partir d'un nom de fichier, est-ce que c'est bon?"  :D  

Reply

Marsh Posté le 15-01-2007 à 20:31:30    

Bah j'aime bien regarder ce qu'il se passe sous le capot... :spamafote: Et voir comment tout ça fonctionne. Mais je comprend que ça n'intéresse pas grand monde...  
N'empêche qu'une question a été posée et ceux que ça intéresse ont une réponse. :)

Reply

Marsh Posté le 15-01-2007 à 21:35:20    

anordem a écrit :

Bah j'aime bien regarder ce qu'il se passe sous le capot...
Oui, c'est parfois intéressant d'aller voir...


 

anordem a écrit :

N'empêche qu'une question a été posée et ceux que ça intéresse ont une réponse. :)


N'empêche que tous ceux qui savent utiliser un FILE* n'ont jamais eu besoin d'avoir de réponse à cette question... [:spamafote]


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed