web-dev-qa-db-fra.com

Comment vérifier si un HANDLE est valide ou non?

En C++, j'ai ouvert un port série doté d'une HANDLE. Puisque le port peut fermer par une application externe, comment puis-je vérifier que la HANDLE est toujours valide avant de lire les données?

Je pense que cela peut être fait en vérifiant la HANDLE par rapport à une fonction API appropriée, mais laquelle? Merci.

18
losingsleeep

Vérifier si un descripteur est "valide" est une erreur. Vous devez avoir un meilleur moyen de gérer cela.

Le problème est qu'une fois qu'un descripteur a été fermé, la même valeur peut être générée par une nouvelle ouverture de quelque chose de différent, et votre test peut indiquer que le descripteur est valide, mais vous n'utilisez pas le fichier que vous pensez être.

Par exemple, considérons cette séquence:

  1. La poignée est ouverte, la valeur réelle est 0x1234.
  2. La poignée est utilisée et la valeur est transmise
  3. La poignée est fermée.
  4. Une autre partie du programme ouvre un fichier et obtient la valeur de traitement 0x1234.
  5. La valeur de poignée d'origine est "vérifiée pour sa validité" et passe.
  6. Le handle est utilisé, opérant sur le mauvais fichier.

Donc, si c'est votre processus, vous devez savoir quelles adresses sont valides et lesquelles ne le sont pas. Si vous avez obtenu le descriptif d'un autre processus, celui-ci aura été intégré à votre processus à l'aide de DuplicateHandle (). Dans ce cas, vous devriez gérer la durée de vie du descripteur et le processus source ne devrait pas le faire pour vous. Si vos poignées sont fermées d'un autre processus, je suppose que c'est vous qui le faites et que vous devez vous occuper de la comptabilité.

17
janm

Certaines fonctions WinAPI renvoient ERROR_INVALID_PARAMETER sans signification, même si des descripteurs valides leur sont transmis, donc il y a un cas d'utilisation réel pour vérifier la validité des descripteurs.

La fonction GetHandleInformation fait le travail: http://msdn.Microsoft.com/en-us/library/ms724329%28v=vs.85%29.aspx

6
Krit

comme le port peut fermer par une application externe

Ce n'est pas possible, une application externe ne peut pas obtenir la valeur de descripteur appropriée à transmettre à CloseHandle (). Une fois le port ouvert, tout autre processus essayant d'obtenir un descripteur sur le port obtiendra AccessDenied.

Cela dit, il existe des pièges qui échappent à cette restriction en ayant une connaissance secrète des structures non documentées du noyau stockant les descripteurs de processus. Vous êtes impuissant contre eux, ne commettez pas l'erreur de vous lancer dans cette bataille en faisant de même. Tu vas perdre. Si un client se plaint de cela, donnez-lui le conseil de mon médecin: "si ça vous fait mal, ne le faites pas".

5
Hans Passant

Si une HANDLE vous est donnée et que vous voulez simplement savoir s’il s’agit bien d’un descripteur de fichier ouvert, il existe la fonction API Windows GetFileInformationByHandle pour cela.

En fonction des autorisations accordées par votre handle pour le fichier, vous pouvez également essayer de déplacer le pointeur de fichier à l'aide de SetFilePointer , lire des données à l'aide de ReadFile ou effectuer une opération d'écriture nulle en utilisant WriteFile avec nNumberOfBytesToWrite défini sur 0.

1
Felix Dombek

Vous êtes probablement sous Windows et utilisez ReadFile pour lire les données. La seule façon de vérifier, c'est d'essayer de lire. Si la variable HANDLE est invalide, elle renvoie un code d'erreur (utilisez GetLastEror () pour savoir lequel), ce sera probablement ERROR_HANDLE_INVALID.

1
RedX

Essayez d’utiliser la fonction IsWindow () function ;-)

IsWindow () est une fonction de l'API Windows depuis Windows 2000.

0
Codr

Konuyla ilgili örnek `

// File handle: CreateFile(), GetHandleInformation() and CloseHandle()
#include <windows.h>
#include <stdio.h>

int main(void)
{
// handle to a file
HANDLE hFile;
// file and path, change accordingly. LPCWSTR is a pointer to a constant
// null-terminated string of 16-bit Unicode characters. It is a typedef:
// typedef CONST WCHAR *LPCWSTR. The modifier 'L' is for wide character.
LPCWSTR fname = L"c:\\testfile.txt";
DWORD lpdwFlags[100];
BOOL test;

// Create a file with the given information...
hFile = CreateFile(fname, // file to be opened
GENERIC_WRITE, // open for writing
FILE_SHARE_WRITE, // share for writing
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL |FILE_ATTRIBUTE_ARCHIVE | SECURITY_IMPERSONATION,
// normal file archive and impersonate client
NULL); // no attr. template

if(hFile == INVALID_HANDLE_VALUE)
printf("Could not open %s file, error %d\n", fname, GetLastError());
else
{
printf("File's HANDLE is OK!\n");
test = GetHandleInformation(hFile, lpdwFlags);
printf("The return value is %d, error %d\n", test, GetLastError());
}
// when finished, close the file handle
CloseHandle(hFile);
DeleteFile(fname);
return 0;
}`

par http://www.tenouk.com/cpluscodesnippet/createfilegetclosehandleinfo.html

0
İbrahim Doğan