Click to See Complete Forum and Search --> : database problems on CF card after suspend/resume


majoob
June 12th, 2003, 03:18 PM
I'm developing a CE data entry program using eVC++ 3.0 with MFC. It uses a memory-mapped database. The database file can reside pretty much anywhere on the CE device, but I've been recommending that users (testers) keep it in non-volatile memory such as a CF card for data safety. Well that sure backfired!

Here's the problem: If the device (Pocket PC 2002 tested so far) is suspended then resumed while the program is running, all of the pointers to the database on the CF card seem to get scrambled, and point to garbage within the database. This does NOT happen if the database resides in the device's onboard memory, even after multiple suspend/restarts.

Anyone know what's going on with the CF card? Right now the only work-around I can think of is to detect when the device is being suspended, and clean up/close the database, then re-initialize everything when the device is resumed. However, I can't find how to detect either suspend or resume.

Aaaaaaaaaargh!

alex_gusev
June 18th, 2003, 02:05 AM
Hi, majoob,

it takes some time for device to reestablish all open handles to CF resources, so that's exactly what's happening - you're trying to use them while they're not alive yet. even if you will open some file and then try to work with it after suspend/resume too quickly without timeout - you'll get the same result.

you may catch the moment of suspending/resuming, but in such case you should write simple 'stream interface driver' which will receive all notifications you need to. It should export following functions:


// DLL exports (required for stream interface drivers)
extern "C" {
PWRDLL_API BOOL PWR_Close(DWORD hOpenContext);
PWRDLL_API BOOL PWR_Deinit(DWORD hDeviceContext);
PWRDLL_API DWORD PWR_Init(DWORD dwContext);
PWRDLL_API BOOL PWR_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);
PWRDLL_API DWORD PWR_Open(DWORD hDeviceConext, DWORD dwAccessCode, DWORD dwShareMode);
PWRDLL_API void PWR_PowerDown(DWORD hDeviceContext);
PWRDLL_API void PWR_PowerUp(DWORD hDeviceContext);
PWRDLL_API DWORD PWR_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD dwCount);
PWRDLL_API DWORD PWR_Seek(DWORD hOpenContext, long lAmount, WORD wType);
PWRDLL_API DWORD PWR_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD dwNumberOfBytes);
}


Unfortunately I can't send you source code, but as you may see above they all are XXX_Init etc. functions, where XXX will be your device prefix, e.g. PWR1: in this case. You should register this driver with RegisterDevice call:


g_hPwrDevice = RegisterDevice(
TEXT("PWR"), // device identifier prefix
1, // device identifier index
PATH + TEXT("PWRDLL.DLL"), // device driver name
0);


and then use CreateFile to open it with "PWR1:" name.

Also try to search for PWRDLL on CodeGuru or CodeProject, I remember that I've found some basic project there a while ago.

majoob
June 23rd, 2003, 03:30 PM
Thanks Alex, After doing a little research I discovered that its not
that the pointers are getting permanently "scrambled" as I first
thought, but that it takes the WinCE operating system a few
seconds after a resume to reinitialize the card (handles and
pointers to the files that were open on the card).

It probably depends on the make and model of the card, but my
Kingston CF card took right around 5 seconds after a resume to
kick in. If I waited those five seconds before entering data then
all was well. So, here's what I did in the data entry loop:

CWaitCursor wait;
m_cFile.GetStatus(m_sFileName, m_rStatus);
wait.~CWaitCursor();

Execution stops for 5+/- seconds on the GetStatus line until the
card is initialized, then the waitcursor goes away and the user
can continue. Once the card is initialized there is no perceptible
delay in execution and the user doesn't see the waitcursor.

Seems a little kludgy but it works. Anyone see a danger in doing
this?

alex_gusev
June 23rd, 2003, 04:37 PM
I meant exactly what you're saying - CF needs some time to wake up after suspend/resume, depends on device and CF. Such behavior I has observed all WinCE lifetime, nothing was changed :)
I suggest that that code sample you've provided may take more than 5 seconds, better try to search for PWRDLL on the forums