简体   繁体   中英

How to check if a HANDLE is valid or not?

In C++, I have opened a serial port that has a HANDLE . Since the port may close by an external application, how can I verify that the HANDLE is still valid before reading data?

I think it can be done by checking the HANDLE against a suitable API function, but which? Thank you.

Checking to see whether a handle is "valid" is a mistake. You need to have a better way of dealing with this.

The problem is that once a handle has been closed, the same handle value can be generated by a new open of something different, and your test might say the handle is valid, but you are not operating on the file you think you are.

For example, consider this sequence:

  1. Handle is opened, actual value is 0x1234
  2. Handle is used and the value is passed around
  3. Handle is closed.
  4. Some other part of the program opens a file, gets handle value 0x1234
  5. The original handle value is "checked for validity", and passes.
  6. The handle is used, operating on the wrong file.

So, if it is your process, you need to keep track of which handles are valid and which ones are not. If you got the handle from some other process, it will have been put into your process using DuplicateHandle(). In that case, you should manage the lifetime of the handle and the source process shouldn't do that for you. If your handles are being closed from another process, I assume that you are the one doing that, and you need to deal with the book keeping.

Some WinAPI functions return meaningless ERROR_INVALID_PARAMETER even if valid handles are passed to them, so there is a real use case to check handles for validity.

GetHandleInformation function does the job: http://msdn.microsoft.com/en-us/library/ms724329%28v=vs.85%29.aspx

as the port may close by a external application

This is not possible, an external application cannot obtain the proper handle value to pass to CloseHandle(). Once you have the port opened, any other process trying to get a handle to the port will get AccessDenied.

That said, there's crapware out there that hacks around this restriction by having secret knowledge of the undocumented kernel structures that stores handles for a process. You are powerless against them, don't make the mistake of taking on this battle by doing the same. You will lose. If a customer complains about this then give them my doctor's advice: "if it hurts then don't do it".

If you are given a HANDLE and simply want to find out whether it is indeed an open file handle, there is the Windows API function GetFileInformationByHandle for that.

Depending on the permissions your handle grants you for the file, you can also try to move the file pointer using SetFilePointer , read some data from it using ReadFile , or perform a null write operation using WriteFile with nNumberOfBytesToWrite set to 0.

Probably you are under windows and using ReadFile to read the data. The only way to check it is trying to read. If the HANDLE is invalid it'll return an error code (use GetLastEror() to see which one it is) which will probably be ERROR_HANDLE_INVALID .

Try using the IsWindow() function ;-)

IsWindow() is a function of the Windows API since Windows 2000.

I know that it's a little bit late but I had a similar question to you, how to check if a pipe (a pipe I created using CreateFile) is still open (maybe the other end shut down the connection) and can read, and if it is not, to open it again. I did what @Felix Dombek suggested, and I used the WriteFile to check the connection. If it returned 1 it means the pipe is open, else I opened it using the CreateFile again. This implies that your pipe is duplex. Here's the CreateFile:
hPipe2 = CreateFile(lpszPipename2, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);
and here is how I checked for the connection:

while(1)
{   
    bool MessageSent = WriteFile(hPipe2, "Test", 0, &cbWritten, NULL);
    if (!(MessageSent))
    {
        LogsOut("Read pipe has been disconnected");
        //Call method to start the pipe again
        break;
    }
    Sleep(200); // I need this because it is a thread
}

This is working just fine for me :)

In order to check the handle , first we need to know what is our HANDLE for, (for a File/Port/Window, ...), Then find an appropriate function to check it (thanks @janm for help). Note that the function's duty may be specially for this destination or not. In my case that iv'e opened a Serial port by CreateFile() , i can check the COM status by GetCommState() API function that fills our COM info struct. If the port is not open anymore or inaccessible the function returns 0 and if you call GetLastError() immediately, you`ll get the ERROR_INVALID_HANDLE value. Thanks everyone for helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM