Clients complaining that your VFP apps sometimes freeze/corrupt data when both the server and client machines have Vista?
You're not alone.
Windows Vista has a critical locking bug when locking over SMB2 (which, at the moment, means connecting to another Vista computer).
Here's an easy reproduction scenario:
- Get two Vista computers, one acting as the server and the other acting as the client:
- On the server, lock a file, at byte X (say, using RLock()).
- On the client, try to lock the same file, also at byte X (RLock() the same record), with LOCKFILE_FAIL_IMMEDIATELY (or in VFP, SET REPROCESS TO 1).
The client will not fail immediately (which would be the correct behavior), and will in fact block until the server releases the lock (in VFP, this means your app will "freeze").
The kicker for this is that if you do it in the other order, the server seems to sometimes (I haven't narrowed it down when) acquire the lock anyway, even though the client is already holding it -- invalidating the client's lock (and possibly corrupting data, if, say, the lock was on a .dbf header). (Incidentally -- calling Unlock File() after the client's lock was invalidated errors with "The segment is already unlocked." -- possibly a bug in the SMB2 command-joining?)
This is a severe bug if you rely on locking for anything, as VFP does for updating table headers. It can introduce data corruption, easily cause deadlocks, etc.
See KB 935366 to get the hotfix (currently, you cannot redistribute this -- your clients will have to call Microsoft support to get it). Note that the KB does not give a full explanation -- it just mentions VFP.
You can also get some more information on this from the MSDN forums:
Also see Vista Lock Reproduction Program Source, Visual FoxPro On Windows Server 2008 and Opportunistic Locking.
Contributors: Peter Crabtree
Category Three Star Topics
It is worth pointing out that this is not a "Windows Vista File Locking Bug," but a "FoxPro Locking Bug with SMB*."
FoxPro picks what is possibly the worst method ever used to "lock" a file, placing a record at the end of the (now obsolete) 4gb limit, long past the end of the file. Since this is not now, nor has it ever been, a valid or supported method to handle file locking (file locks should be requested from the OS, so that they can be properly invalidated), the server discards the invalid data - the 'lock' isn't located anywhere in the valid address space for the file - and releases the lock.
There is no way to override this behaviour so that FoxPro locks the file properly.
This is all a bit like mounting a deadbolt on your desk, then claiming that locking it means no one will be able to enter your home. After all, a lock somewhere completely random is just as good as a lock on the actual door, right?
(*There IS an issue with SMB, but this ain't it.)
( Topic last updated: 2012.12.14 11:11:53 AM )