X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;ds=sidebyside;f=wince%2Fyaffsfsd.c;h=f9e8bef50620bf40a4c937071ae14c363e06e0e3;hb=f0494eb05c40ce19d74bedc92a020a743fbec08e;hp=7e202bfe17e60ab44912a09b6ec8b0af253b4830;hpb=d3a46536d1812c81e1c494235ce8f7e25ebb0e1b;p=yaffs%2F.git diff --git a/wince/yaffsfsd.c b/wince/yaffsfsd.c index 7e202bf..f9e8bef 100644 --- a/wince/yaffsfsd.c +++ b/wince/yaffsfsd.c @@ -1,59 +1,65 @@ -/* - * YAFFS: Yet another FFS. A NAND-flash specific file system. - * ynandif.c: NAND interface functions for the WinCE port of YAFFS. - * - * Copyright (C) 2002 Trimble Navigation Ltd. - * - * Created by Charles Manning - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. You should have received a - * copy of the GNU General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Acknowledgements: - * Various clean-ups and WinCE4 support by Steve Fogle - * $Id: yaffsfsd.c,v 1.2 2003-01-14 23:15:41 charles Exp $ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffsfsd.c: FSD interface funtions for WinCE. + * + * Copyright (C) 2002 Trimble Navigation Ltd. + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. You should have received a + * copy of the GNU General Public License along with this program; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Acknowledgements: + * Various clean-ups and WinCE4 support by Steve Fogle and Lynn Winter + * $Id: yaffsfsd.c,v 1.4 2003-01-31 03:30:33 charles Exp $ */ #include #include #include -#include -//slf021104b begin -#include +#include +//slf021104b begin +#include //slf021104b end #define MAX_WIN_FILE 200 #define YFSD_NAME_LENGTH 128 #define YFSD_FULL_PATH_NAME_SIZE 500 - + #define YFSD_DISK_NAME L"Disk" -#define YFSD_BOOT_NAME L"Boot" +#define YFSD_BOOT_NAME L"Boot" + +#define PARTITION_START_NUMBER (1280) -#define PARTITION_START_NUMBER (1280) -//#define MSGSTATE 1 +// if this is defined the there will be a constant message box raised to display status +//#define MSGBOX_DISPLAY + + +//#define MSGSTATE 1 #define MSGSTATE 0 -//#define DISABLE_BOOT_PARTITION -//slf021105a begin -// Define DO_PARTITION_TABLE to cause the partition table -// information to be retrieved from the block driver. -//#define DO_PARTITION_TABLE -// How many partitions the disk might have. 2 gives -// space for the "Disk" and "Boot" partitions. -#define MAXPARTITIONS (2) +//#define DISABLE_BOOT_PARTITION +//slf021105a begin +// Define DO_PARTITION_TABLE to cause the partition table +// information to be retrieved from the block driver. +// Can define this in your sources file. +//#define DO_PARTITION_TABLE +// How many partitions the disk might have. 2 gives +// space for the "Disk" and "Boot" partitions. +#define MAXPARTITIONS (2) //slf021105a end //unsigned yaffs_traceMask=0xffffffff; -unsigned yaffs_traceMask=0; +unsigned yaffs_traceMask=0; typedef struct @@ -77,10 +83,10 @@ typedef struct BOOL dirty; WCHAR *fullName; yfsd_Volume *myVolume; - BOOL writePermitted; - BOOL readPermitted; - BOOL shareRead; - BOOL shareWrite; + BOOL writePermitted; + BOOL readPermitted; + BOOL shareRead; + BOOL shareWrite; } yfsd_WinFile; @@ -110,10 +116,10 @@ typedef struct #include -//slf021105a begin +//slf021105a begin //static yfsd_Volume disk_volume; -//static yfsd_Volume boot_volume; -static yfsd_Volume * disk_volumes[MAXPARTITIONS]; +//static yfsd_Volume boot_volume; +static yfsd_Volume * disk_volumes[MAXPARTITIONS]; //slf021105a end; static CRITICAL_SECTION yaffsLock; @@ -153,6 +159,49 @@ static void yfsd_CheckGuards(void) } #endif + +#ifdef MSGBOX_DISPLAY +DWORD WINAPI yfsd_MessageThread(LPVOID param) +{ + yaffs_Device *dev = (yaffs_Device *)param; + TCHAR dataBuffer[1000]; + Sleep(10000); + + // note : if the device gets free'd from under us, we will cause an exception in the loop + while (1) + { + wsprintf(dataBuffer, L"nShortOpCaches %i\r\n" + L"nErasedBlocks %i\r\n" + L"allocationBlock %i\r\n" + L"allocationPage %i\r\n" + L"garbageCollectionRequired %i\r\n" + L"nRetiredBlocks %i\r\n" + L"cacheHits %i\r\n" + L"eccFixed %i\r\n" + L"eccUnfixed %i\r\n" + L"tagsEccFixed %i\r\n" + L"tagsEccUnfixed %i\r\n", + dev->nShortOpCaches, + dev->nErasedBlocks, + dev->allocationBlock, + dev->allocationPage, + dev->garbageCollectionRequired, + dev->nRetiredBlocks, + dev->cacheHits, + dev->eccFixed, + dev->eccUnfixed, + dev->tagsEccFixed, + dev->tagsEccUnfixed); + + MessageBox(NULL, + dataBuffer, + L"YAFFS PROC INFO", + MB_OK); + Sleep(1); + } +} +#endif + void yfsd_LockWinFiles(void) { //RETAILMSG (MSGSTATE, (L"YAFFS::LockWinfiles\r\n")); @@ -212,10 +261,10 @@ yfsd_WinFile * yfsd_GetWinFile(void) if(!yfsd_winFile[i].isopen) { yfsd_winFile[i].isopen = 1; - yfsd_winFile[i].writePermitted = 0; - yfsd_winFile[i].readPermitted = 0; - yfsd_winFile[i].shareRead = 0; - yfsd_winFile[i].shareWrite = 0; + yfsd_winFile[i].writePermitted = 0; + yfsd_winFile[i].readPermitted = 0; + yfsd_winFile[i].shareRead = 0; + yfsd_winFile[i].shareWrite = 0; yfsd_winFile[i].dirty = 0; yfsd_winFile[i].fullName = NULL; yfsd_winFile[i].obj = NULL; @@ -266,42 +315,42 @@ void yfsd_FlushAllFiles(void) } yfsd_UnlockWinFiles(); yfsd_UnlockYAFFS(); -} - -//slf021104d begin -////////////////////////////////////////////////////////////////////// -// Search through winFiles to see if any are open. - -BOOL yfsd_FilesOpen(void) -{ - int i; - BOOL rval; - RETAILMSG (MSGSTATE, (L"YAFFS::FilesOpen?\r\n")); - - yfsd_LockWinFiles(); - for(i = 0, rval = FALSE; i < MAX_WIN_FILE; i++) - { - if(yfsd_winFile[i].isopen) - { - rval = TRUE; - break; - } - } - yfsd_UnlockWinFiles(); - return rval; -} +} + +//slf021104d begin +////////////////////////////////////////////////////////////////////// +// Search through winFiles to see if any are open. + +BOOL yfsd_FilesOpen(void) +{ + int i; + BOOL rval; + RETAILMSG (MSGSTATE, (L"YAFFS::FilesOpen?\r\n")); + + yfsd_LockWinFiles(); + for(i = 0, rval = FALSE; i < MAX_WIN_FILE; i++) + { + if(yfsd_winFile[i].isopen) + { + rval = TRUE; + break; + } + } + yfsd_UnlockWinFiles(); + return rval; +} //slf021104d end PWSTR yfsd_FullPathName(PVOLUME vol, PWSTR fpn,int slength,PCWSTR pathName) { - // todo check for bounds - //slf021104b begin + // todo check for bounds + //slf021104b begin //volName already has the initial backslash if it needs it. - //wcscpy(fpn,L"\\"); + //wcscpy(fpn,L"\\"); //wcscat(fpn,vol->volName); - wcscpy(fpn,vol->volName); - //slf021104b end + wcscpy(fpn,vol->volName); + //slf021104b end if(pathName[0] != '\\') { wcscat(fpn,L"\\"); @@ -604,116 +653,140 @@ yaffs_Object *yfsd_FindObjectByWinPath(yaffs_Device *dev, PCWSTR pwsFileName ) BOOL YFSD_InitVolume(HDSK hdsk, yfsd_Volume *vol, int startBlock, int endBlock, PWSTR volName) { - //slf021104b Begin - WCHAR szName[MAX_PATH]; - DWORD dwAvail; - //slf021104b end - RETAILMSG (MSGSTATE, (L"YAFFS::InitVolume\r\n")); + //slf021104b Begin + WCHAR szName[MAX_PATH]; + DWORD dwAvail; + //slf021104b end + RETAILMSG (MSGSTATE, (L"YAFFS::InitVolume\r\n")); //slf021104b Begin filled in later. - //vol->volName = volName; + //vol->volName = volName; //slf021104b end yfsd_LockYAFFS(); - //Mount/initialise YAFFs here - ynandif_InitialiseNAND(&vol->dev); - - vol->dev.writeChunkToNAND = ynandif_WriteChunkToNAND; - vol->dev.readChunkFromNAND = ynandif_ReadChunkFromNAND; - vol->dev.eraseBlockInNAND = ynandif_EraseBlockInNAND; - vol->dev.initialiseNAND = ynandif_InitialiseNAND; - vol->dev.startBlock = startBlock; - if (endBlock != -1) - vol->dev.endBlock = endBlock; - vol->dev.nShortOpCaches = 10; // a nice number of caches. - - // nBlocks is set the total size of the disk, not the partition -// vol->dev.nBlocks = endBlock - startBlock + 1; - -// qnand_EraseAllBlocks(&vol->dev); + //slf021220a Begin Cleanup block driver interface +#if _WINCEOSVER >= 400 + // For Win'CE 4.0 and later pass the hdsk for use by the yandif layer. + vol->dev.genericDevice = (PVOID)hdsk; +#endif + //slf021220a End Cleanup block driver interface - yaffs_GutsInitialise(&vol->dev); - RETAILMSG(1, (L"YAFFS::Done yaffs_GutsInitialise\r\n")); + //Mount/initialise YAFFs here + //slf021127a begin check for error returns! + if (ynandif_InitialiseNAND(&vol->dev)) + { + //slf021127a end check for error returns! + vol->dev.writeChunkToNAND = ynandif_WriteChunkToNAND; + vol->dev.readChunkFromNAND = ynandif_ReadChunkFromNAND; + vol->dev.eraseBlockInNAND = ynandif_EraseBlockInNAND; + vol->dev.initialiseNAND = ynandif_InitialiseNAND; + vol->dev.startBlock = startBlock; + if (endBlock != -1) + vol->dev.endBlock = endBlock; + vol->dev.nShortOpCaches = 10; // a nice number of caches. + vol->dev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; + vol->dev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; + vol->dev.nReservedBlocks = 5; // a nice reserve size + + + // nBlocks is set the total size of the disk, not the partition + // vol->dev.nBlocks = endBlock - startBlock + 1; + + // qnand_EraseAllBlocks(&vol->dev); + + //slf021127a begin check for error returns! + if (yaffs_GutsInitialise(&vol->dev)) + { + //slf021127a end check for error returns! + RETAILMSG(1, (L"YAFFS::Done yaffs_GutsInitialise\r\n")); - RETAILMSG(1, (L"Blocks start %d end %d Group size %d bits %d\r\n", - vol->dev.startBlock,vol->dev.endBlock, - vol->dev.chunkGroupSize,vol->dev.chunkGroupBits)); + RETAILMSG(1, (L"Blocks start %d end %d Group size %d bits %d\r\n", + vol->dev.startBlock,vol->dev.endBlock, + vol->dev.chunkGroupSize,vol->dev.chunkGroupBits)); #if 0 - for(i = vol->dev.startBlock; i <= vol->dev.endBlock; i++) - { - switch(vol->dev.blockInfo[i].blockState) + for(i = vol->dev.startBlock; i <= vol->dev.endBlock; i++) { - case YAFFS_BLOCK_STATE_DEAD: - - RETAILMSG(1, (L"YAFFS::Dead block %d\r\n",i)); - deadBlox++; - break; - case YAFFS_BLOCK_STATE_EMPTY: emptyBlox++; break; - case YAFFS_BLOCK_STATE_FULL: fullBlox++; break; - case YAFFS_BLOCK_STATE_ALLOCATING: allocatingBlox++; break; - case YAFFS_BLOCK_STATE_DIRTY: dirtyBlox++; break; - default: - RETAILMSG(1, (L"YAFFS::Block %d has goofus state %d\r\n",i,vol->dev.blockInfo[i].blockState)); - break; + switch(vol->dev.blockInfo[i].blockState) + { + case YAFFS_BLOCK_STATE_DEAD: + + RETAILMSG(1, (L"YAFFS::Dead block %d\r\n",i)); + deadBlox++; + break; + case YAFFS_BLOCK_STATE_EMPTY: emptyBlox++; break; + case YAFFS_BLOCK_STATE_FULL: fullBlox++; break; + case YAFFS_BLOCK_STATE_ALLOCATING: allocatingBlox++; break; + case YAFFS_BLOCK_STATE_DIRTY: dirtyBlox++; break; + default: + RETAILMSG(1, (L"YAFFS::Block %d has goofus state %d\r\n",i,vol->dev.blockInfo[i].blockState)); + break; + } } - } - RETAILMSG(1, (L"Blocks dead %d empty %d full %d allocating %d dirty %d\r\n", - deadBlox,emptyBlox,fullBlox,allocatingBlox,dirtyBlox)); + RETAILMSG(1, (L"Blocks dead %d empty %d full %d allocating %d dirty %d\r\n", + deadBlox,emptyBlox,fullBlox,allocatingBlox,dirtyBlox)); #endif +//slf021127a begin check for error returns! + vol->isMounted = 1; + } + } +//slf021127a begin check for error returns! + yfsd_UnlockYAFFS(); - vol->isMounted = 1; - +//slf021127a begin check for error returns! +// vol->isMounted = 1; +//slf021127a begin check for error returns! + //slf021104b begin - //vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,vol->volName,vol); - // If the caller passed a volume name use it. - if (volName[0]) - wcscpy( szName, volName); -#if WINCEOSVER >= 400 - // The user passed an empty volume name. On CE 4.xx try to get - // if from the block driver (which got it from the registry). - else if (!FSDMGR_DiskIoControl(hdsk, DISK_IOCTL_GETNAME, NULL, 0, (LPVOID)szName, sizeof(szName), &dwAvail, NULL)) -#else - else -#endif - { - // Didn't get a volume name so use "Disk" by default. - wcscpy( szName, YFSD_DISK_NAME); - } - vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,szName,vol); + //vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,vol->volName,vol); + // If the caller passed a volume name use it. + if (volName[0]) + wcscpy( szName, volName); +#if WINCEOSVER >= 400 + // The user passed an empty volume name. On CE 4.xx try to get + // if from the block driver (which got it from the registry). + else if (!FSDMGR_DiskIoControl(hdsk, DISK_IOCTL_GETNAME, NULL, 0, (LPVOID)szName, sizeof(szName), &dwAvail, NULL)) +#else + else +#endif + { + // Didn't get a volume name so use "Disk" by default. + wcscpy( szName, YFSD_DISK_NAME); + } + vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,szName,vol); //slf021104b end if(vol->mgrVolume) - { - //slf021104b Begin + { + //slf021104b Begin // Get some space for the volume name. - vol->volName = malloc( MAX_PATH * sizeof(WCHAR)); - if (vol->volName) - { -#if WINCEOSVER >= 400 - // Get the name we were really mounted under. - FSDMGR_GetVolumeName(vol->mgrVolume, vol->volName, MAX_PATH); - - // If we got mounted as root then throw away the backslash - // so we won't get a double backslash when volName is - // prepended to the path in the full path name calculation - // that is used for shell callbacks. - if (0 == wcscmp(vol->volName,L"\\")) - vol->volName[0] = 0; -#else - // Use the name we asked to be mounted under for - // our root. - wcscpy(vol->volName,L"\\"); - wcscat(vol->volName, szName); -#endif - } - //slf021104b end + vol->volName = malloc( MAX_PATH * sizeof(WCHAR)); + if (vol->volName) + { +#if WINCEOSVER >= 400 + // Get the name we were really mounted under. + FSDMGR_GetVolumeName(vol->mgrVolume, vol->volName, MAX_PATH); + + // If we got mounted as root then throw away the backslash + // so we won't get a double backslash when volName is + // prepended to the path in the full path name calculation + // that is used for shell callbacks. + if (0 == wcscmp(vol->volName,L"\\")) + vol->volName[0] = 0; +#else + // Use the name we asked to be mounted under for + // our root. + wcscpy(vol->volName,L"\\"); + wcscat(vol->volName, szName); +#endif + } + //slf021104b end return TRUE; } else @@ -727,14 +800,14 @@ BOOL YFSD_InitVolume(HDSK hdsk, yfsd_Volume *vol, int startBlock, int endBlock, BOOL YFSD_MountDisk(HDSK hdsk) { -//slf021105a begin -#ifdef DO_PARTITION_TABLE - ynandif_partition PartTable[MAXPARTITIONS]; - DWORD dwAvail; - int i; - BOOL rval = FALSE; -#endif -//slf021105a end +//slf021105a begin +#ifdef DO_PARTITION_TABLE + ynandif_partition PartTable[MAXPARTITIONS]; + DWORD dwAvail; + int i; + BOOL rval = FALSE; +#endif +//slf021105a end int deadBlox=0,emptyBlox=0,fullBlox=0,allocatingBlox=0,dirtyBlox=0; //int i; // Called to mount a disk. @@ -752,102 +825,107 @@ BOOL YFSD_MountDisk(HDSK hdsk) yfsd_InitialiseWinFiles(); yaffsLockInited = 1; } - - //slf021105a begin - memset(disk_volumes,0,sizeof(disk_volumes)); -#ifdef DO_PARTITION_TABLE - memset(&PartTable,0,sizeof(PartTable)); - // Call the block driver to get the partition table from it. - if (FSDMGR_DiskIoControl(hdsk, YNANDIF_GETPARTITIONS, NULL, 0, (LPVOID)&PartTable, sizeof(PartTable), &dwAvail, NULL)) - { - // Scan throught the table it return. - for (i=0; i PartTable[i].startBlock)) - { - // Found a partion. Get a volume structure to hold it. - disk_volumes[i] = malloc(sizeof(yfsd_Volume)); - if (disk_volumes[i]) - { - memset(disk_volumes[i],0,sizeof(yfsd_Volume)); - // Go init the volume. Note that if the block driver wants the - // name to come from the registry it will have returned an - // empty name string. - YFSD_InitVolume(hdsk,disk_volumes[i],PartTable[i].startBlock,PartTable[i].endBlock,PartTable[i].volName); - if (disk_volumes[i]->isMounted) - rval = TRUE; //Hey, we found at least on partition. - } - } - } - } - - return rval; - + + //slf021105a begin + memset(disk_volumes,0,sizeof(disk_volumes)); +#ifdef DO_PARTITION_TABLE + memset(&PartTable,0,sizeof(PartTable)); + // Call the block driver to get the partition table from it. + if (FSDMGR_DiskIoControl(hdsk, YNANDIF_GETPARTITIONS, NULL, 0, (LPVOID)&PartTable, sizeof(PartTable), &dwAvail, NULL)) + { + // Scan throught the table it return. + for (i=0; i PartTable[i].startBlock)) + { + // Found a partion. Get a volume structure to hold it. + disk_volumes[i] = malloc(sizeof(yfsd_Volume)); + if (disk_volumes[i]) + { + memset(disk_volumes[i],0,sizeof(yfsd_Volume)); + // Go init the volume. Note that if the block driver wants the + // name to come from the registry it will have returned an + // empty name string. + YFSD_InitVolume(hdsk,disk_volumes[i],PartTable[i].startBlock,PartTable[i].endBlock,PartTable[i].volName); + if (disk_volumes[i]->isMounted) + rval = TRUE; //Hey, we found at least on partition. + } + } + } + } + + return rval; + #else #ifdef DISABLE_BOOT_PARTITION - // Only want disk volume - disk_volumes[0] = malloc(sizeof(yfsd_Volume)); - if (disk_volumes[0]) - { - memset(disk_volumes[0],0,sizeof(yfsd_Volume)); - YFSD_InitVolume(hdsk, disk_volumes[0], 1, -1, YFSD_DISK_NAME); - - if(disk_volumes[0].isMounted) - { - return TRUE; - } - } - if (disk_volumes[0]) - { - free(disk_volumes[0]; - disk_volumes[0] = NULL; - } -#else - // Want both boot and disk - disk_volumes[0] = malloc(sizeof(yfsd_Volume)); - disk_volumes[1] = malloc(sizeof(yfsd_Volume)); - if (disk_volumes[0] && disk_volumes[1]) - { - memset(disk_volumes[0],0,sizeof(yfsd_Volume)); - memset(disk_volumes[1],0,sizeof(yfsd_Volume)); - YFSD_InitVolume(hdsk, disk_volumes[0], PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME); - YFSD_InitVolume(hdsk, disk_volumes[1], 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME); - - if(disk_volumes[0]->isMounted && disk_volumes[1]->isMounted) - { - return TRUE; - } - } - - // If we got this far something went wrong. Make sure to - // free any memory we allocated. - if (disk_volumes[0]) - { - if (disk_volumes[0]->volName) - { - free(disk_volumes[0]->volName); - } - free(disk_volumes[0]); - disk_volumes[0] = NULL; - } - if (disk_volumes[1]) - { - if (disk_volumes[1]->volName) - { - free(disk_volumes[1]->volName); - } - free(disk_volumes[1]); - disk_volumes[1] = NULL; - } -#endif - - return FALSE; - - // Only want disk volume + // Only want disk volume + disk_volumes[0] = malloc(sizeof(yfsd_Volume)); + if (disk_volumes[0]) + { + memset(disk_volumes[0],0,sizeof(yfsd_Volume)); + YFSD_InitVolume(hdsk, disk_volumes[0], 1, -1, YFSD_DISK_NAME); + + if(disk_volumes[0].isMounted) + { + return TRUE; + } + } + if (disk_volumes[0]) + { + free(disk_volumes[0]; + disk_volumes[0] = NULL; + } +#else + // Want both boot and disk + disk_volumes[0] = malloc(sizeof(yfsd_Volume)); + disk_volumes[1] = malloc(sizeof(yfsd_Volume)); + if (disk_volumes[0] && disk_volumes[1]) + { + memset(disk_volumes[0],0,sizeof(yfsd_Volume)); + memset(disk_volumes[1],0,sizeof(yfsd_Volume)); + YFSD_InitVolume(hdsk, disk_volumes[0], PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME); + YFSD_InitVolume(hdsk, disk_volumes[1], 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME); + +#ifdef MSGBOX_DISPLAY + // pass the device we are sniffing to the thread + CreateThread(NULL, 0, yfsd_MessageThread, (LPVOID)&disk_volumes[0]->dev, 0, NULL); +#endif + + if(disk_volumes[0]->isMounted && disk_volumes[1]->isMounted) + { + return TRUE; + } + } + + // If we got this far something went wrong. Make sure to + // free any memory we allocated. + if (disk_volumes[0]) + { + if (disk_volumes[0]->volName) + { + free(disk_volumes[0]->volName); + } + free(disk_volumes[0]); + disk_volumes[0] = NULL; + } + if (disk_volumes[1]) + { + if (disk_volumes[1]->volName) + { + free(disk_volumes[1]->volName); + } + free(disk_volumes[1]); + disk_volumes[1] = NULL; + } +#endif + + return FALSE; + + // Only want disk volume // YFSD_InitVolume(hdsk, &disk_volume, 1, -1, YFSD_DISK_NAME); // // @@ -865,11 +943,11 @@ BOOL YFSD_MountDisk(HDSK hdsk) // { // return TRUE; // } -//#endif +//#endif // // return FALSE; -#endif -//slf021105a end +#endif +//slf021105a end // yfsd_SetGuards(); @@ -880,46 +958,49 @@ BOOL YFSD_MountDisk(HDSK hdsk) BOOL YFSD_UnmountDisk(HDSK hdsk) { -//slf021105a begin - int i; -//slf021105a end +//slf021105a begin + int i; +//slf021105a end RETAILMSG (MSGSTATE, (L"YAFFS::UnmountDisk\r\n")); - //slf021104d begin - // If there are any files open don't let them dismount - // it or the system will get very confused. - if (yfsd_FilesOpen()) - return FALSE; - - //yfsd_FlushAllFiles(); - //slf021104d end - - yfsd_LockYAFFS(); -//slf021105a begin -// yaffs_Deinitialise(&disk_volume.dev); -// yaffs_Deinitialise(&boot_volume.dev); + //slf021104d begin + // If there are any files open don't let them dismount + // it or the system will get very confused. + if (yfsd_FilesOpen()) + return FALSE; + + //yfsd_FlushAllFiles(); + //slf021104d end + + yfsd_LockYAFFS(); +//slf021105a begin +// yaffs_Deinitialise(&disk_volume.dev); +// yaffs_Deinitialise(&boot_volume.dev); // yfsd_UnlockYAFFS(); // -// FSDMGR_DeregisterVolume(disk_volume.mgrVolume); -// FSDMGR_DeregisterVolume(boot_volume.mgrVolume); - - // Walk through the partions deinitializing, deregistering - // and freeing them. - for (i=0; idev)); - FSDMGR_DeregisterVolume(disk_volumes[i]->mgrVolume); - if (disk_volumes[i]->volName) - { - free(disk_volumes[i]->volName); - } - free(disk_volumes[i]); - disk_volumes[i] = NULL; - } - } - yfsd_UnlockYAFFS(); +// FSDMGR_DeregisterVolume(disk_volume.mgrVolume); +// FSDMGR_DeregisterVolume(boot_volume.mgrVolume); + + // Walk through the partions deinitializing, deregistering + // and freeing them. + for (i=0; idev)); +//slf021220a Begin Cleanup block driver interface + ynandif_DeinitialiseNAND(&(disk_volumes[i]->dev)); +//slf021220a end Cleanup block driver interface + FSDMGR_DeregisterVolume(disk_volumes[i]->mgrVolume); + if (disk_volumes[i]->volName) + { + free(disk_volumes[i]->volName); + } + free(disk_volumes[i]); + disk_volumes[i] = NULL; + } + } + yfsd_UnlockYAFFS(); //slf021105a end return TRUE; } @@ -1007,22 +1088,26 @@ BOOL YFSD_CreateDirectoryW(PVOLUME pVolume, PCWSTR pathName, PSECURITY_ATTRIBUTE } -BOOL yfsd_RemoveObjectW(PVOLUME pVolume, PCWSTR pathName) +BOOL YFSD_RemoveDirectoryW(PVOLUME pVolume, PCWSTR pathName) { - // Fails if directory is not empty int result = FALSE; yaffs_Object *parent = NULL; yaffs_Object *obj; char name[YFSD_NAME_LENGTH+1]; - RETAILMSG (MSGSTATE, (L"YAFFS::RemoveObjectW (%s)\r\n", pathName)); - + RETAILMSG (MSGSTATE, (L"YAFFS::RemoveDirectory (%s)\r\n", pathName)); + yfsd_LockYAFFS(); obj = yfsd_FindObjectByWinPath(&pVolume->dev,pathName); if(!obj) { - SetLastError(ERROR_FILE_NOT_FOUND); + SetLastError(ERROR_PATH_NOT_FOUND); + result = FALSE; + } + else if (obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) + { + SetLastError(ERROR_ACCESS_DENIED); result = FALSE; } else if(obj->st_mode & FILE_ATTRIBUTE_READONLY) @@ -1044,23 +1129,12 @@ BOOL yfsd_RemoveObjectW(PVOLUME pVolume, PCWSTR pathName) { result = yaffs_Unlink(parent,name); if(!result) - SetLastError(ERROR_ACCESS_DENIED); + SetLastError(ERROR_DIR_NOT_EMPTY); } } yfsd_UnlockYAFFS(); - return result ? TRUE : FALSE; -} - - -BOOL YFSD_RemoveDirectoryW(PVOLUME pVolume, PCWSTR pathName) -{ - BOOL result; - RETAILMSG (MSGSTATE, (L"YAFFS::RemoveDirectory\r\n")); - - result = yfsd_RemoveObjectW(pVolume, pathName); - if(result && pVolume->shellFunction) { FILECHANGEINFO fc; @@ -1081,8 +1155,7 @@ BOOL YFSD_RemoveDirectoryW(PVOLUME pVolume, PCWSTR pathName) yfsd_ShellDirectoryChanged(pVolume,fpn); } - return result; - + return result ? TRUE : FALSE; } @@ -1180,10 +1253,51 @@ BOOL YFSD_SetFileAttributesW( PVOLUME pVolume,PCWSTR pwsFileName, DWORD dwFileAt BOOL YFSD_DeleteFileW( PVOLUME pVolume, PCWSTR pwsFileName ) { - BOOL result; + int result = FALSE; + yaffs_Object *parent = NULL; + yaffs_Object *obj; + char name[YFSD_NAME_LENGTH+1]; + RETAILMSG (MSGSTATE, (L"YAFFS::DeleteFileW (%s)\r\n", pwsFileName)); - result = yfsd_RemoveObjectW(pVolume, pwsFileName); + yfsd_LockYAFFS(); + + obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + if(!obj) + { + SetLastError(ERROR_FILE_NOT_FOUND); + result = FALSE; + } + else if (obj->variantType != YAFFS_OBJECT_TYPE_FILE) + { + SetLastError(ERROR_ACCESS_DENIED); + result = FALSE; + } + else if(obj->st_mode & FILE_ATTRIBUTE_READONLY) + { + SetLastError(ERROR_ACCESS_DENIED); + result = FALSE; + } + else if(obj->inUse) + { + SetLastError(ERROR_ACCESS_DENIED); + result = FALSE; + } + else + { + + parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsFileName,name,YFSD_NAME_LENGTH); + + if(parent && yfsd_NameIsValid(name)) + { + result = yaffs_Unlink(parent,name); + if(!result) + SetLastError(ERROR_ACCESS_DENIED); + } + } + + yfsd_UnlockYAFFS(); + if(result && pVolume->shellFunction) { FILECHANGEINFO fc; @@ -1204,7 +1318,7 @@ BOOL YFSD_DeleteFileW( PVOLUME pVolume, PCWSTR pwsFileName ) yfsd_ShellDirectoryChanged(pVolume,fpn); } - return result; + return result ? TRUE : FALSE; } BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName ) @@ -1282,18 +1396,18 @@ BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName BOOL YFSD_DeleteAndRenameFileW(PVOLUME pVolume, PCWSTR pwsOldFileName, PCWSTR pwsNewFileName ) { - //slf021104c begin - BOOL fSuccess; - //slf021104c end - - RETAILMSG (MSGSTATE, (L"YAFFS::DeleteAndRename\r\n")); - //slf021104c begin - if (fSuccess = YFSD_DeleteFileW(pVolume, pwsOldFileName)) - fSuccess = YFSD_MoveFileW(pVolume, pwsNewFileName, pwsOldFileName); - return fSuccess; + BOOL fSuccess; + //slf021104c end + + RETAILMSG (MSGSTATE, (L"YAFFS::DeleteAndRename\r\n")); + + //slf021104c begin + if (fSuccess = YFSD_DeleteFileW(pVolume, pwsOldFileName)) + fSuccess = YFSD_MoveFileW(pVolume, pwsNewFileName, pwsOldFileName); + return fSuccess; //return FALSE; - //slf021104c end + //slf021104c end } BOOL YFSD_GetDiskFreeSpaceW( PVOLUME pVolume, PCWSTR pwsPathName, PDWORD pSectorsPerCluster,PDWORD pBytesPerSector, PDWORD pFreeClusters, PDWORD pClusters ) @@ -1538,7 +1652,7 @@ BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd) pfd->nFileSizeHigh = 0; pfd->nFileSizeLow = yaffs_GetObjectFileLength(l); - pfd->dwOID = 0; // wtf is this??? + pfd->dwOID = (CEOID)(INVALID_HANDLE_VALUE); // wtf is this??? MultiByteToWideChar(CP_ACP,0,name,-1,pfd->cFileName,YFSD_NAME_LENGTH); @@ -1609,7 +1723,7 @@ BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd) pfd->nFileSizeHigh = 0; pfd->nFileSizeLow = yaffs_GetObjectFileLength(l); - pfd->dwOID = 0; // wtf is this??? + pfd->dwOID = (CEOID)(INVALID_HANDLE_VALUE); // wtf is this??? MultiByteToWideChar(CP_ACP,0,name,-1,pfd->cFileName,YFSD_NAME_LENGTH); @@ -1668,6 +1782,7 @@ HANDLE YFSD_FindFirstFileW(PVOLUME pVolume, HANDLE hProc,PCWSTR pwsFileSpec, PWI { free(pSearch); pSearch = NULL; + SetLastError(ERROR_PATH_NOT_FOUND); } } @@ -1678,19 +1793,26 @@ HANDLE YFSD_FindFirstFileW(PVOLUME pVolume, HANDLE hProc,PCWSTR pwsFileSpec, PWI if(pSearch) { found = yfsd_DoFindFile(pSearch,pfd); - } - if(found) - { - h = FSDMGR_CreateSearchHandle(pVolume->mgrVolume,hProc,pSearch); - } + if(found) + { + h = FSDMGR_CreateSearchHandle(pVolume->mgrVolume,hProc,pSearch); + if(h == INVALID_HANDLE_VALUE) + { + SetLastError(ERROR_NO_MORE_SEARCH_HANDLES); + } + } + else + { + SetLastError(ERROR_FILE_NOT_FOUND); + } - if(h == INVALID_HANDLE_VALUE && pSearch) - { - yfsd_DeleteFinder(pSearch); - SetLastError(ERROR_NO_MORE_SEARCH_HANDLES); - } + if(h == INVALID_HANDLE_VALUE) + { + yfsd_DeleteFinder(pSearch); + } + } return h; @@ -1740,19 +1862,20 @@ HANDLE YFSD_CreateFileW( unsigned modifiedTime[2]; unsigned objSize; - BOOL writePermitted = (dwAccess & GENERIC_WRITE) ? TRUE : FALSE; - BOOL readPermitted = (dwAccess & GENERIC_READ) ? TRUE : FALSE; - BOOL shareRead = (dwShareMode & FILE_SHARE_READ) ? TRUE : FALSE; - BOOL shareWrite = (dwShareMode & FILE_SHARE_WRITE) ? TRUE : FALSE; - - BOOL openRead, openWrite, openReadAllowed, openWriteAllowed; + BOOL writePermitted = (dwAccess & GENERIC_WRITE) ? TRUE : FALSE; + BOOL readPermitted = (dwAccess & GENERIC_READ) ? TRUE : FALSE; + BOOL shareRead = (dwShareMode & FILE_SHARE_READ) ? TRUE : FALSE; + BOOL shareWrite = (dwShareMode & FILE_SHARE_WRITE) ? TRUE : FALSE; + + BOOL openRead, openWrite, openReadAllowed, openWriteAllowed; BOOL fileCreated = FALSE; + + BOOL fAlwaysCreateOnExistingFile = FALSE; + BOOL fTruncateExistingFile = FALSE; mode = dwFlagsAndAttributes & 0x00FFFFFF; // ding off the flags - - RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile (%s) flags %X mode %X\r\n", pwsFileName,dwFlagsAndAttributes,mode)); if(writePermitted) { @@ -1778,12 +1901,18 @@ HANDLE YFSD_CreateFileW( if(parent && yfsd_NameIsValid(name)) { + //slf021220b begin Fix still more bugs in CreateFile. + // Get the object for this file if it exists (only once). + obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b end Fix still more bugs in CreateFile. if(dwCreate == CREATE_NEW) { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file in CREATE_NEW\r\n")); //slf021101c begin - obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b begin Fix still more bugs in CreateFile. + // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b end Fix still more bugs in CreateFile. if(!obj) { obj = yaffs_MknodFile(parent,name,mode,0,0); @@ -1791,16 +1920,28 @@ HANDLE YFSD_CreateFileW( SetLastError(ERROR_DISK_FULL); fileCreated = TRUE; } - else + //slf021220b begin Fix still more bugs in CreateFile. + else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) { obj = NULL; SetLastError(ERROR_ALREADY_EXISTS); - } + } + //slf021220b end Fix still more bugs in CreateFile. + else + { + obj = NULL; + //slf021220b begin Fix still more bugs in CreateFile. + //Match CE FAT error return SetLastError(ERROR_ALREADY_EXISTS); + SetLastError(ERROR_FILE_EXISTS); + //slf021220b begin Fix still more bugs in CreateFile. + } //slf021101c end } else if( dwCreate == OPEN_ALWAYS) { - obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b begin Fix still more bugs in CreateFile. + // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b end Fix still more bugs in CreateFile. if(!obj) { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file in OPEN_ALWAYS\r\n")); @@ -1810,6 +1951,13 @@ HANDLE YFSD_CreateFileW( fileCreated = TRUE; } + //slf021220b begin Fix still more bugs in CreateFile. + else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) + { + obj = NULL; + SetLastError(ERROR_ACCESS_DENIED); + } + //slf021220b end Fix still more bugs in CreateFile. else { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile opening existing file in OPEN_ALWAYS\r\n")); @@ -1818,34 +1966,55 @@ HANDLE YFSD_CreateFileW( else if(dwCreate == OPEN_EXISTING) { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile opening file in OPEN_EXISTING\r\n")); - obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b begin Fix still more bugs in CreateFile. + // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b end Fix still more bugs in CreateFile. if(!obj) SetLastError(ERROR_FILE_NOT_FOUND); + //slf021220b begin Fix still more bugs in CreateFile. //slf021101c begin - else - if (yfsd_GetObjectWinAttributes(obj) & FILE_ATTRIBUTE_DIRECTORY) - { - SetLastError(ERROR_ACCESS_DENIED); - obj = NULL; - } + // else + // if (yfsd_GetObjectWinAttributes(obj) & FILE_ATTRIBUTE_DIRECTORY) + // { + // SetLastError(ERROR_ACCESS_DENIED); + // obj = NULL; + // } //slf021101c end + else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) + { + SetLastError(ERROR_ACCESS_DENIED); + obj = NULL; + } + //slf021220b end Fix still more bugs in CreateFile. } else if(dwCreate == TRUNCATE_EXISTING) { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile opening file in TRUNCATE_EXISTING\r\n")); - obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); - if(obj) + //slf021220b begin Fix still more bugs in CreateFile. + // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //if(obj) + if (!writePermitted || (obj && (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY))) { - yaffs_ResizeFile(obj,0); + obj = NULL; + SetLastError(ERROR_ACCESS_DENIED); } - else + else if(obj) + //slf021220b end Fix still more bugs in CreateFile. + { + // Indicate that file is to be truncated. This will happen later on assuming + // that a sharing violation does not occur and that we can get a file handle. + fTruncateExistingFile = TRUE; + } + else { SetLastError(ERROR_FILE_NOT_FOUND); } } else if(dwCreate == CREATE_ALWAYS) { - obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b begin Fix still more bugs in CreateFile. + // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); + //slf021220b end Fix still more bugs in CreateFile. if(!obj) { @@ -1855,13 +2024,19 @@ HANDLE YFSD_CreateFileW( SetLastError(ERROR_DISK_FULL); fileCreated = TRUE; } - else + //slf021220b begin Fix still more bugs in CreateFile. + else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) { + obj = NULL; + SetLastError(ERROR_ACCESS_DENIED); + } + //slf021220b end Fix still more bugs in CreateFile. + else + { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile in CREATE_ALWAYS (already exists)\r\n")); - obj->st_mode = mode; - obj->dirty = 1; - yaffs_ResizeFile(obj,0); - yaffs_FlushFile(obj,1); + // Indicate that file is to be recreated. This will happen later on assuming + // that a sharing violation does not occur and that we can get a file handle. + fAlwaysCreateOnExistingFile = TRUE; } } else @@ -1875,40 +2050,42 @@ HANDLE YFSD_CreateFileW( RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile unable to get parent node\r\n")); SetLastError(ERROR_PATH_NOT_FOUND); } - - if(obj) - { - int i; - yfsd_WinFile *p; - openRead = openWrite =0; - openReadAllowed = openWriteAllowed = 1; - - for(i = 0; i < MAX_WIN_FILE; i++) - { - p = &yfsd_winFile[i]; - - if(p->obj == obj) - { - if (p->readPermitted) openRead = 1; - if (p->writePermitted) openWrite = 1; - if (!p->shareRead) openReadAllowed = 0; - if (!p->shareWrite) openWriteAllowed = 0; - } - - } - - // Now we test if the share works out. - - if((openRead && !shareRead) || // already open for read, but we are not prepared to share it for read - (openWrite && !shareWrite) || // already open for write, but we are not prepared to share it for write - (!openReadAllowed && readPermitted) || // already open with read sharing not permitted - (!openWriteAllowed && writePermitted)) // same... write - { - SetLastError(ERROR_ACCESS_DENIED); - obj = NULL; - } - - + + if(obj) + { + int i; + yfsd_WinFile *p; + openRead = openWrite =0; + openReadAllowed = openWriteAllowed = 1; + + for(i = 0; i < MAX_WIN_FILE; i++) + { + p = &yfsd_winFile[i]; + + if(p->obj == obj) + { + if (p->readPermitted) openRead = 1; + if (p->writePermitted) openWrite = 1; + if (!p->shareRead) openReadAllowed = 0; + if (!p->shareWrite) openWriteAllowed = 0; + } + + } + + // Now we test if the share works out. + + if((openRead && !shareRead) || // already open for read, but we are not prepared to share it for read + (openWrite && !shareWrite) || // already open for write, but we are not prepared to share it for write + (!openReadAllowed && readPermitted) || // already open with read sharing not permitted + (!openWriteAllowed && writePermitted)) // same... write + { + //slf021220c begin Fix error code for new sharing mode check code. + SetLastError(ERROR_SHARING_VIOLATION); + //slf021220c end Fix error code for new sharing mode check code. + obj = NULL; + } + + } if(obj) { @@ -1928,12 +2105,30 @@ HANDLE YFSD_CreateFileW( if(handle != INVALID_HANDLE_VALUE) { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have an fsdmgr handle\r\n")); + + if (fTruncateExistingFile) + { + RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - TRUNCATE_EXISTING - truncating existing file\r\n")); + yaffs_ResizeFile(obj,0); + } + + if (fAlwaysCreateOnExistingFile) + { + RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - CREATE_ALWAYS - zapping existing file\r\n")); + obj->st_mode = mode; + obj->dirty = 1; + yaffs_ResizeFile(obj,0); + yaffs_FlushFile(obj,1); + } + f->obj = obj; f->offset = 0; - f->writePermitted = writePermitted; - f->readPermitted = writePermitted; - f->shareRead= shareRead; - f->shareWrite = shareWrite; + f->writePermitted = writePermitted; + //slf021220d begin oops typo. + f->readPermitted = readPermitted; + //slf021220d end oops typo. + f->shareRead= shareRead; + f->shareWrite = shareWrite; f->myVolume = pVolume; obj->inUse++; @@ -2368,12 +2563,8 @@ BOOL YFSD_GetFileInformationByHandle( pFileInfo->nFileSizeLow = yaffs_GetObjectFileLength(pFile->obj); pFileInfo->nNumberOfLinks = 1; // only primary link supported like FAT pFileInfo->nFileIndexHigh = 0; - pFileInfo->nFileIndexLow = pFile->obj->objectId; -//slf021104a Begin Window CE 4.0 added an additional field. -#if _WINCEOSVER >= 400 - pFileInfo->dwOID = (CEOID)(INVALID_HANDLE_VALUE); -#endif -//slf021104a end + pFileInfo->nFileIndexLow = pFile->obj->objectId; + pFileInfo->dwOID = (CEOID)(INVALID_HANDLE_VALUE); yfsd_UnlockYAFFS();