I have investigated it a little bit and it looks like it's impossible to figure out whether the password is correct at the file open time. It is even possible sometimes that you are actually able to read the whole file with a wrong password and only when you calculate the CRC you figure out that the password was probably wrong (or maybe the archive itself is corrupt). Other times, reading files because the (incorrectly) decrypted stream is not a valid zlib stream, and this is probably your case.

Note that looping on read() without checking for 0 is a bad idea. It returns 0 when you reach the EOF so you eventually end up in an infinite loop anyway. However, you may check for error by calling getZipError(), which will return something not equal to UNZ_OK if the read failed due to some ZIP error, for example. If you get 0 from read() and UNZ_OK from getZipError(), it would mean that EOF was reached correctly.

Note that read() doesn't check for CRC, but close() does. So it may be possible that you get UNZ_OK after reaching EOF, but then after calling close() you call getZipError() again and get UNZ_CRCERROR, which would mean that the CRC is bad either due to the wrong password or some sort of data corruption.