The PocketTV Team
05-04-2004, 06:58 AM
It appears that MSFT managed to break something in WM2003 and WM2003-SE, and this can cause serious head-haches for developers, as there is no easy workaround.
The problem affects applications that read or write files located on removable storages (SD Cards, CF Cards).
In Pocket PC 2000 and Pocket PC 2002, when the device was turned OFF (i.e. "suspended"), then turned ON again later ("resumed"), all the files handles of files located on removable storages were re-mounted correctly by the filesystem drivers, i.e. basically the suspend/resume operation was totally transparent to all applications, including those that had open file handles to files located on removable storages.
The only caveat was described in this KB article: http://support.microsoft.com/default.aspx?scid=kb;en-us;811693 . Basically ReadFile could return an error when trying to read the file too soon after the power-resume. The workaround was simple: sleep a bit and retry. If it keeps failing after say 4 seconds, then abandon.
Now, in WM2003 and WM2003-SE, it appears that those file handles are not always remounted by the driver upon the power-resume, i.e. all file handles can become un-usable after a power suspend/resume for files located on removable storage (even though the storage card was left in the device while the device was suspended).
You may think: no big deal, the application can just re-open the file.
But think a bit more, and you will realize that by re-opening the file based on its pathname (e.g. "\SD Card\foo.xxx"), you have no guarantee that you are in fact opening the same file! While the device was suspended, the user may have replaced the Storage Card by another one that have a different file with the same name. Only the driver can verify that the Storage Card is the same, based on the filesystem signature, the Card ID etc. That's why the filesystem should be re-mounted by the driver, and all the file handles should remain valid, unless the storage card was changed.
And even if you re-open the file, it is not as simple: You also need to keep track of the current offset in the file (seek position), in order to get a new file handle that points to the same offset.
And your application must now expect each File System call (e.g. GetFileSize, SetFilePointer, ReadFile, WriteFile, GetFileAttributeByHandle, FlushFileBuffer, etc ) to fail since it has become a "normal" thing that will happen each time the user press the POWER OFF button (if your file is on a storage card).
I complained to MSFT that this was a serious bug that will cause problems to a number of apps and reported the issue to several MSFT Engineers at the Mobility Developer Conference. They did not take it seriously enough to file a bug report in the Knowledge Database.
When I insisted, two months later they assigned a contractor to look into the issue, and the feedback I got from the guy was: "it's by design, the product group said it's normal that file handles to files located on removable storages become un-usable after the device is suspended/resumed". This guy told me that "there was many improvements in WinCE 4.2, so some things have changed". That's definitely what I would call a "negative improvement".
I just cannot believe that this new bug is "by design", since it was working (almost) perfectly in Pocket PC 2000 and 2002. And if this was a change "by design", I would expect it to be documented, which is not the case.
Furthermore, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemain4/html/cmconstoragemanagerarchitecture.asp clearly suggests that the storage Card drivers should remount correctly the filesystems on suspend/resume:
[...]This notification forces unmounts of the partition driver and any file systems. During this period, the mount points move into a suspended state and requested I/O access to the mount points fail with ERROR_DEVICE_NOT_AVAILABLE. The primary use for this is during suspend/resume cycles where a block driver might unload and reload on resume. When the Storage Manager receives a load notification, it examines the block device to see if it is identical to the previously unmounted device. If it is identical, the block device remounts under the previous mount points.
The problem affects applications that read or write files located on removable storages (SD Cards, CF Cards).
In Pocket PC 2000 and Pocket PC 2002, when the device was turned OFF (i.e. "suspended"), then turned ON again later ("resumed"), all the files handles of files located on removable storages were re-mounted correctly by the filesystem drivers, i.e. basically the suspend/resume operation was totally transparent to all applications, including those that had open file handles to files located on removable storages.
The only caveat was described in this KB article: http://support.microsoft.com/default.aspx?scid=kb;en-us;811693 . Basically ReadFile could return an error when trying to read the file too soon after the power-resume. The workaround was simple: sleep a bit and retry. If it keeps failing after say 4 seconds, then abandon.
Now, in WM2003 and WM2003-SE, it appears that those file handles are not always remounted by the driver upon the power-resume, i.e. all file handles can become un-usable after a power suspend/resume for files located on removable storage (even though the storage card was left in the device while the device was suspended).
You may think: no big deal, the application can just re-open the file.
But think a bit more, and you will realize that by re-opening the file based on its pathname (e.g. "\SD Card\foo.xxx"), you have no guarantee that you are in fact opening the same file! While the device was suspended, the user may have replaced the Storage Card by another one that have a different file with the same name. Only the driver can verify that the Storage Card is the same, based on the filesystem signature, the Card ID etc. That's why the filesystem should be re-mounted by the driver, and all the file handles should remain valid, unless the storage card was changed.
And even if you re-open the file, it is not as simple: You also need to keep track of the current offset in the file (seek position), in order to get a new file handle that points to the same offset.
And your application must now expect each File System call (e.g. GetFileSize, SetFilePointer, ReadFile, WriteFile, GetFileAttributeByHandle, FlushFileBuffer, etc ) to fail since it has become a "normal" thing that will happen each time the user press the POWER OFF button (if your file is on a storage card).
I complained to MSFT that this was a serious bug that will cause problems to a number of apps and reported the issue to several MSFT Engineers at the Mobility Developer Conference. They did not take it seriously enough to file a bug report in the Knowledge Database.
When I insisted, two months later they assigned a contractor to look into the issue, and the feedback I got from the guy was: "it's by design, the product group said it's normal that file handles to files located on removable storages become un-usable after the device is suspended/resumed". This guy told me that "there was many improvements in WinCE 4.2, so some things have changed". That's definitely what I would call a "negative improvement".
I just cannot believe that this new bug is "by design", since it was working (almost) perfectly in Pocket PC 2000 and 2002. And if this was a change "by design", I would expect it to be documented, which is not the case.
Furthermore, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemain4/html/cmconstoragemanagerarchitecture.asp clearly suggests that the storage Card drivers should remount correctly the filesystems on suspend/resume:
[...]This notification forces unmounts of the partition driver and any file systems. During this period, the mount points move into a suspended state and requested I/O access to the mount points fail with ERROR_DEVICE_NOT_AVAILABLE. The primary use for this is during suspend/resume cycles where a block driver might unload and reload on resume. When the Storage Manager receives a load notification, it examines the block device to see if it is identical to the previously unmounted device. If it is identical, the block device remounts under the previous mount points.