OK, now that I can debug volume mounding (big thanks to Ben and Henk), I've found the following:
1) The crash of my original code occurs because the resource containing the form I want to display cannot be found. Apparently, for some reason, if the application hasn't been launched normally, it can't go to any of its forms. :-( I don't understand why this is the case - the path taken by my program on sysAppLaunchCmdNormalLaunch and on sysAppLaunchCmdNotify is essentially identical - the same variables are allocated and the same APIs are called in the same order. I guess, the startup code does something different in the two cases - and the difference is not limited to the availability of global/static variables; my current code doesn't use any. :-((
2) My second code - the one that re-launches itself with a custom launch code - I can't figure out why it doesn't work. :-( The debugger shows that the registration for notifications works correctly and returns no errors. When a volume is mounted, my application *does* receive the notification. I've traced it to the point where it does SysUIAppSwitch to itself. The dbID and cardNo are correct - they are that of my application. I've looked at the disassembly - it indeed uses the 0x8001 launch code. I've checked the disassembly of PilotMain too - and the switch statement there indeed checks whether the launch code is 0x8001. Except that once I go past the SysUIAppSwitch point, I no longer receive control. :-((
Help? Is this the correct way for an application to launch itself with a custom launch code and to check whether this is how it has been launched?