(Firstly, let me say that I am new to Mac OS development, but have nearly 24 years' experience of software development, including some Unix.)
I am writing an application which needs to do low-level reads and writes to devices such as USB memory sticks and compact flash drives (devices which appear as mounted volumes, all of which happen to be FAT formatted). Most of my application works fine, but I am having problems with parts of the application that write to the devices and I need some help in finding the right way to do this.
When the application wants to write to these devices, it opens them using the open() function. If I specify O_EXLOCK, to gain exclusive access to the device, I get a "resource busy" error. If I open the device without an exclusive lock (either specifying O_SHLOCK or not specifying any locking), the device seems to get corrupted after I have finished writing to it.
I am confident that the problem is not with the algorithm I am using to write to the device, as I have a Windows version of the software that works fine (and that I am porting to Mac OS). The problem seems to be that Mac OS writes to the device after I've done what I need (which is why I think I need to open it for exclusive access). I have tried dismounting the device immediately on completing the operation, but this does not resolve the corruption.
I have spent about a week ploughing through documentation, searching for every term I can think of, but I can find nothing that addresses the specific issue I am having. I therefore need help to answer the following:
1. Am I right in thinking that opening the device for exclusive access would resolve the problem, or is there anything else (or anything different) that I need to do? For example, it has been suggested to me that I might need to use IOKit, rather than the BSD open() call that I am currently using. Is this correct? (And if so, how the hell do I find out what keys I'm supposed to use to locate resources? The documentation for IOKit seems replete with detailed examples but not much high-level explanation, and I've already run across a few things that do not appear to work very well from Cocoa.)
2. Do I need to dismount the device before I write to it? If so, how do I get around the fact that its BSD node (/dev/rdisk1 or whatever) disappears when I do that, meaning that I no longer have a valid filename to open?
3. Having dismounted/ejected a USB memory stick, is there any way to tell the system to remount it when I've finished? I have found no tools, even within the UI, that will do this automatically. The only solution I can find is to manually unplug and then reconnect the device.
I am using Mac OS X 10.4.8 on a Mac Mini.
David Hazel |