Windows CE: Formatting TFAT

Windows CE: Formatting TFAT
Created by samphung on 11/20/2010 10:54:27 PM

Programmatically format Windows CE TFAT partition  


A customer came to me for assistance in formatting an SD card with TFAT. I did a quick look in the control panel code to find how it formats disks as TFAT and told the customer to use FormatVolume() and set the FORMAT_OPTIONS dwFlags FATUTIL_FORMAT_TFAT flag.   

I assumed that it was that easy and left the customer to write the code. A few weeks later the customer came back to me and said that they just couldn’t get FormatVolume() to work, let alone format the disk as TFAT. So this time I dug deeper and write some code to test it out before getting back to the customer. The following is what I figured out including the code to format a disk as TFAT.

What went wrong? When I first looked at how to format TFAT, I looked to see what happens when the Format button is selected. What I didn’t look for is what has to happen before the Format button is selectable. It turns out that before the Format button is selectable, the partition must first be dismounted.

__declspec(dllexport) BOOL APIENTRY FormatDiskTFAT( TCHAR *StoreName, TCHAR *PartitionName )

{

                HANDLE hStore;

                HANDLE hPartition;

 

                hStore = OpenStore(StoreName);          

 

                if( INVALID_HANDLE_VALUE != hStore )

                {

                                hPartition = OpenPartition( hStore, PartitionName );

                                if( INVALID_HANDLE_VALUE != hPartition )

                                {

                                                if( DismountPartition(hPartition) )

                                                {   

                                                                FORMAT_OPTIONS fo;

 

                                                                // Get formating options

                                                                fo.dwClusSize = 4 * 1024;

                                                                fo.dwFatVersion = 32;

                                                                fo.dwNumFats = 2;

                                                                fo.dwRootEntries = 512;

 

                                                                fo.dwFlags = 0;

                                                                //fo.dwFlags |= FATUTIL_FULL_FORMAT;

                                                                fo.dwFlags |= FATUTIL_FORMAT_TFAT;

 

                                                                if( ERROR_SUCCESS != pfnFormatVolume( hPartition, NULL, &fo, HandleProgress, HandleMessage ))

                                                                                RETAILMSG( 1, (TEXT("Format Failed\n")));

                                                                MountPartition(hPartition);

                                                }

                                                else

                                                                RETAILMSG( 1, (TEXT("Failed to dismount Partition\n")));

 

                                                CloseHandle( hPartition );

                                }

                                else

                                                RETAILMSG(1, (TEXT("OpenPartition failed\n")));

 

                                CloseHandle(hStore);

                }

                else

                                RETAILMSG(1, (TEXT("OpenSelectedStore failed\n")));

 

                return TRUE;

}

FormatDiskTFAT() takes two strings as arguments:

·         StoreName which is the szDeviceName in the STOREINFO structure returned from FindFirstStore()/FindNextStore() or the szStoreName in the CE_VOLUME_INFO structure returned from CeGetVolumeInfo(). The value of the string will be somethings like “DSK1:”.

·         PartitionName which is the szPartionName in PARTINFO and CE_VOLUME_INFO returned by FindFirstPartition()/FindNextPartition() and CeGetVolumeInfo(). The value of the string will be something like “PART00”.

FormatDiskTFAT() uses the strings to open the store and the partition. Then it dismounts the partition, formats the disk and re-mounts the partition.

I choose the function signature because I was thinking about using FindFirstStore()/FindNextStore(), so the device name and the partition name would be readily available. As an afterthought, I decided that it might be handy to have a function that simply takes the folder name of the disk, so I came up with FormatDiskTFATEx():

__declspec(dllexport) BOOL APIENTRY FormatDiskTFATEx( TCHAR *FolderName )

{

                CE_VOLUME_INFO VolInfo;

                VolInfo.cbSize = sizeof( CE_VOLUME_INFO );

 

                CeGetVolumeInfo(FolderName, CeVolumeInfoLevelStandard, &VolInfo );

                return FormatDiskTFAT( VolInfo.szStoreName, VolInfo.szPartitionName );

}

FormatDiskTFATEx() takes one string as an argument which is the name of the disk folder. This will be something like “Storage Card” or “\Storage Card” depending on how you obtain the string.

One of the interesting problems that I ran into is that building this for Windows CE 5.0 (I have not tested yet with CE 6.0) the call to CeGetVolumeInfo() causes a linker error because CeGetVolumeInfoW() does not exist. The solution to this problem is to undefine CeGetVolumeInfo(). So I added:

#ifdef CeGetVolumeInfo

#undef CeGetVolumeInfo

#endif

Then next problem that I needed to solve is that while I can easily compile this code using Platform Builder, my customer who is using an SDK that I provided cannot. The problem is that FATUTIL.DLL is included in the OS, but FATUTIL.LIB is not included in the SDK and FormatVolume() is in FATUTIL. It would be easy enough to create a new SDK and release it, but that may be overkill for one function. So the solution that I came up with is to use LoadLibrary() and GetProcAddress().   I am including these functions in a DLL, so I did the mapping in DllEntry():

HMODULE hFatUtil = NULL;

DWORD (*pfnFormatVolume)(HANDLE hVolume,void *pdi,FORMAT_OPTIONS *pfo,void *pfnProgress,void *pfnMessage);

 

static void *GetFormatVolume(HMODULE *hFatUtil);

 

 

BOOL APIENTRY DllMain( HANDLE hModule,

                       DWORD ul_reason_for_call,

                       LPVOID lpReserved

                                                                                 )

{

                switch( ul_reason_for_call )

                {

                                case DLL_PROCESS_ATTACH:

                                                pfnFormatVolume = GetFormatVolume(&hFatUtil);

                                                break;

                                case DLL_PROCESS_DETACH:

                                                FreeLibrary(hFatUtil);

                                                break;

                }

    return TRUE;

}

The last problem is that FORMAT_OPTIONS needed by FormatVolume() is also not available in the SDK, or more accuratly the header file that they are included in doesn’t compile cleanly, so I included them in the C code:

#define FATUTIL_FULL_FORMAT                 0x1

#define FATUTIL_FORMAT_TFAT                 0x2

 

typedef struct _FORMAT_OPTIONS {

    DWORD   dwClusSize;

    DWORD   dwRootEntries;

    DWORD   dwFatVersion;

    DWORD   dwNumFats;

    DWORD   dwFlags;

} FORMAT_OPTIONS;

In my next article (see Windows CE: C# Application to Format TFAT), I will show how to use these functions from C#. As for using them from C/C++, you may want to review Windows CE: Displaying Disk Information for example code that uses FindFirstStore()/FindNextStore() and FindFirstPartition()/FindNextPartition() to enumerate the mounted disks.

NOTE 1: In FormatDiskTFAT() I have commented out the line “//fo.dwFlags |= FATUTIL_FULL_FORMAT;” because in my testing with both this code and the Storage Manager control panel applet, the full format would not complete.

NOTE 2: I made a conscious choice to hardcode the formatting options in FormatDiskTFAT() because while these options are interesting, they just shouldn’t be user options in an embedded system. I could have pushed them up to the caller function, but that opens the door for a confusing user interface.

 

 

Note:  This article is written by Bruce Eitman, and is posted to the Embedded101 site with Bruce’s permission.

Copyright © 2010 – Bruce Eitman – All Rights Reserved

http://geekswithblogs.net/BruceEitman/

Embedded101 Articles

Click to Expand/Collapse Groups
Skip Navigation Links.
Collapse Windows Embedded Compact (CE)Windows Embedded Compact (CE)
Collapse Compact 7Compact 7
Build A Windows Network Projector wi...
Filter Device Drivers
Asynchronous I/O request support
Configure Flash Storage to Launch Co...
CEDriverWiz V2.00: About this releas...
Installing CEDriverWiz for Visual St...
Collapse CE 6.0CE 6.0
Stream Driver with CEDriverWiz rev 0...
Connecting Visual Studio IDE to CE 6...
Windows CE: Save and Restore the Re...
Windows CE: Stream Interface Driver...
Windows CE: Persisting Registry Chan...
Windows CE: Enhanced BusEnum
Windows CE: Soft Reset
Windows CE: Reading a String from th...
Windows CE: Displaying Disk Informa...
Windows CE: Formatting TFAT
Windows CE: C# Application to Format...
Hive-Based Registry for CE 6.0
AutoLaunch for CE 6.0
Configure Flash Storage to Launch Co...
CEDriverWiz V2.00: About this releas...
Installing CEDriverWiz for Visual St...
Collapse CE 5.0CE 5.0
Configure Flash Storage to Launch Co...
Collapse Platform Builder & OS DesignPlatform Builder & OS Design
Platform Builder: Automatically Flus...
Windows CE: Enhanced BusEnum
Windows CE: Soft Reset
Windows CE: Displaying Disk Informa...
Build A Windows Network Projector wi...
CEDriverWiz V2.00: About this releas...
Installing CEDriverWiz for Visual St...
Collapse BSP, OAL & BootloaderBSP, OAL & Bootloader
Windows CE 6.0: User Mode KernelIoC...
Windows CE: Displaying Disk Informa...
Collapse RegistryRegistry
Platform Builder: Automatically Flus...
Windows CE: Save and Restore the Re...
Windows CE: Stream Interface Driver...
Windows CE: Persisting Registry Chan...
Windows CE: Reading a String from th...
Hive-Based Registry for CE 6.0
Collapse Device DriverDevice Driver
Stream Driver with CEDriverWiz rev 0...
Windows CE: Stream Interface Driver...
Windows CE: Enhanced BusEnum
CEDriverWiz V2.00: About this releas...
Installing CEDriverWiz for Visual St...
Collapse File SystemFile System
Windows CE: Formatting TFAT
Windows CE: C# Application to Format...
Collapse Application DevelopmentApplication Development
Connecting Visual Studio IDE to CE 6...
Windows CE: Persisting Registry Chan...
Windows CE: Reading a String from th...
Windows CE: Formatting TFAT
Windows CE: C# Application to Format...
AutoLaunch for CE 6.0
Windows CE: Stream Interface Driver ...
IBW & ICE
Stream Driver with CEDriverWiz rev 0...
Connecting Visual Studio IDE to CE 6...
Platform Builder: Automatically Flus...
Windows CE: Save and Restore the Re...
Windows CE: Stream Interface Driver...
Windows CE: Persisting Registry Chan...
Windows CE: Enhanced BusEnum
Windows CE: Reading a String from th...
Windows CE: Displaying Disk Informa...
Windows CE: Formatting TFAT
Windows CE: C# Application to Format...
Build A Windows Network Projector wi...
Hive-Based Registry for CE 6.0
AutoLaunch for CE 6.0
Hello all
Filter Device Drivers
Asynchronous I/O request support
Configure Flash Storage to Launch Co...
CEDriverWiz Version 2.00 User Manual
CEDriverWiz V2.00: About this releas...
Installing CEDriverWiz for Visual St...
CEDriverWiz Version 2.00: An Example
CEDriverWiz Version 2.00: Using the ...
Collapse Windows Embedded StandardWindows Embedded Standard
WES7
WES-2009
Windows XP Embedded
Target Designer
Enhanced Write Filter
Collapse NET Compact FrameworkNET Compact Framework
Windows CE: C# Application to Format...
Windows Phone 7
Misc.
Turkish porno izle video site in rokettubeporno izle