X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=wince%2Fyaffsfsd.c;h=f9e8bef50620bf40a4c937071ae14c363e06e0e3;hb=f0494eb05c40ce19d74bedc92a020a743fbec08e;hp=dc64c1aa03a792d9a1860824d2c3b607e8ab9d17;hpb=572f34a1cc2b7bddbd8d66f64be95ba158703a2e;p=yaffs%2F.git diff --git a/wince/yaffsfsd.c b/wince/yaffsfsd.c index dc64c1a..f9e8bef 100644 --- a/wince/yaffsfsd.c +++ b/wince/yaffsfsd.c @@ -1,29 +1,34 @@ -/* - * YAFFS: Yet another FFS. A NAND-flash specific file system. - * yaffsfsd.c: The FSD layer for the WinCE version 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. - * - * $Id: yaffsfsd.c,v 1.1 2002-11-08 07:30:00 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 +//slf021104b end #define MAX_WIN_FILE 200 #define YFSD_NAME_LENGTH 128 @@ -33,12 +38,28 @@ #define YFSD_DISK_NAME L"Disk" #define YFSD_BOOT_NAME L"Boot" -#define PARTITION_START_NUMBER (1280) +#define PARTITION_START_NUMBER (1280) + + +// 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. +// 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 -#define MSGSTATE 1 -//#define DISABLE_BOOT_PARTITION - -unsigned yaffs_traceMask=0xffffffff; +//unsigned yaffs_traceMask=0xffffffff; +unsigned yaffs_traceMask=0; typedef struct @@ -59,10 +80,13 @@ typedef struct yaffs_Object *obj; DWORD offset; BOOL isopen; - BOOL writePermitted; BOOL dirty; WCHAR *fullName; yfsd_Volume *myVolume; + BOOL writePermitted; + BOOL readPermitted; + BOOL shareRead; + BOOL shareWrite; } yfsd_WinFile; @@ -92,9 +116,11 @@ typedef struct #include - -static yfsd_Volume disk_volume; -static yfsd_Volume boot_volume; +//slf021105a begin +//static yfsd_Volume disk_volume; +//static yfsd_Volume boot_volume; +static yfsd_Volume * disk_volumes[MAXPARTITIONS]; +//slf021105a end; static CRITICAL_SECTION yaffsLock; static CRITICAL_SECTION winFileLock; @@ -133,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")); @@ -193,6 +262,9 @@ yfsd_WinFile * yfsd_GetWinFile(void) { 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].dirty = 0; yfsd_winFile[i].fullName = NULL; yfsd_winFile[i].obj = NULL; @@ -238,19 +310,47 @@ void yfsd_FlushAllFiles(void) if(yfsd_winFile[i].isopen && yfsd_winFile[i].obj) { - yaffs_FlushFile(yfsd_winFile[i].obj); + yaffs_FlushFile(yfsd_winFile[i].obj,1); } } 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 end + PWSTR yfsd_FullPathName(PVOLUME vol, PWSTR fpn,int slength,PCWSTR pathName) { // todo check for bounds - wcscpy(fpn,L"\\"); - wcscat(fpn,vol->volName); + //slf021104b begin + //volName already has the initial backslash if it needs it. + //wcscpy(fpn,L"\\"); + //wcscat(fpn,vol->volName); + wcscpy(fpn,vol->volName); + //slf021104b end if(pathName[0] != '\\') { wcscat(fpn,L"\\"); @@ -263,7 +363,7 @@ PWSTR yfsd_FullPathName(PVOLUME vol, PWSTR fpn,int slength,PCWSTR pathName) // FILETIME is a 64-bit value as 100-nanosecond intervals since January 1, 1601. - + void yfsd_U32sToWinFileTime(__u32 target[2], FILETIME *wft) { @@ -347,15 +447,15 @@ void yfsd_ShellDirectoryChanged(PVOLUME pVolume, PWSTR fullPathName) } - - -// Minimal name test for now -BOOL yfsd_NameIsValid (const char *name) -{ - int length = strlen(name); - - return (length > 0 && length <= YFSD_NAME_LENGTH); - + + +// Minimal name test for now +BOOL yfsd_NameIsValid (const char *name) +{ + int length = strlen(name); + + return (length > 0 && length <= YFSD_NAME_LENGTH); + } // File attributes: @@ -375,58 +475,58 @@ BOOL yfsd_NameIsValid (const char *name) // // // in addition, GetAttributes also returns FILE_ATTRIBUTE_DIRECTORY - -// The following are valid ones we get presented with, -// but must filter out the stuff we don't unserstand -//#define FILE_ATTRIBUTE_READONLY 0x00000001 -//#define FILE_ATTRIBUTE_HIDDEN 0x00000002 -//#define FILE_ATTRIBUTE_SYSTEM 0x00000004 -//#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 -//#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 -//#define FILE_ATTRIBUTE_INROM 0x00000040 -//#define FILE_ATTRIBUTE_ENCRYPTED 0x00000040 -//#define FILE_ATTRIBUTE_NORMAL 0x00000080 -//#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 -//#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 -//#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 -//#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 -//#define FILE_ATTRIBUTE_OFFLINE 0x00001000 -//#define FILE_ATTRIBUTE_ROMSTATICREF 0x00001000 -//#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 -//#define FILE_ATTRIBUTE_ROMMODULE 0x00002000 - - -BOOL yfsd_CheckValidAttributes(DWORD attribs) -{ - - RETAILMSG (MSGSTATE, (L"Attributes:%X\r\n", attribs)); - -#if 0 - // If NORMAL, then nothing else - if(attribs & FILE_ATTRIBUTE_NORMAL && attribs != FILE_ATTRIBUTE_NORMAL) - return FALSE; - if(attribs == FILE_ATTRIBUTE_NORMAL) - return TRUE; -#endif - // Check that the bits are in the valid set - if(attribs & ~(0x3FE7)) - return FALSE; - - return TRUE; - + +// The following are valid ones we get presented with, +// but must filter out the stuff we don't unserstand +//#define FILE_ATTRIBUTE_READONLY 0x00000001 +//#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +//#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +//#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +//#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +//#define FILE_ATTRIBUTE_INROM 0x00000040 +//#define FILE_ATTRIBUTE_ENCRYPTED 0x00000040 +//#define FILE_ATTRIBUTE_NORMAL 0x00000080 +//#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +//#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +//#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +//#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +//#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +//#define FILE_ATTRIBUTE_ROMSTATICREF 0x00001000 +//#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +//#define FILE_ATTRIBUTE_ROMMODULE 0x00002000 + + +BOOL yfsd_CheckValidAttributes(DWORD attribs) +{ + + RETAILMSG (MSGSTATE, (L"Attributes:%X\r\n", attribs)); + +#if 0 + // If NORMAL, then nothing else + if(attribs & FILE_ATTRIBUTE_NORMAL && attribs != FILE_ATTRIBUTE_NORMAL) + return FALSE; + if(attribs == FILE_ATTRIBUTE_NORMAL) + return TRUE; +#endif + // Check that the bits are in the valid set + if(attribs & ~(0x3FE7)) + return FALSE; + + return TRUE; + } DWORD yfsd_GetObjectWinAttributes(yaffs_Object *obj) { DWORD result; - result = obj->st_mode & - (FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_ARCHIVE | - FILE_ATTRIBUTE_HIDDEN | + result = obj->st_mode & + (FILE_ATTRIBUTE_READONLY | + FILE_ATTRIBUTE_ARCHIVE | + FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM); - - if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) result |= FILE_ATTRIBUTE_DIRECTORY; + + if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) result |= FILE_ATTRIBUTE_DIRECTORY; if(result & ~FILE_ATTRIBUTE_NORMAL) { @@ -436,7 +536,7 @@ DWORD yfsd_GetObjectWinAttributes(yaffs_Object *obj) { result = FILE_ATTRIBUTE_NORMAL; } - + return result; } @@ -496,7 +596,7 @@ yaffs_Object *yfsd_FindDirectoryByWinPath(yaffs_Device *device, const wchar_t *p RETAILMSG (MSGSTATE, (L"YAFFS::FindByWinPath (%s) : ", path)); // start at the root of this device - current = yaffs_Root(device); + current = yaffs_Root(device); *processed = '\0'; do @@ -553,69 +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")); - vol->volName = volName; + //slf021104b Begin filled in later. + //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; - - // 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! - vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,vol->volName,vol); + //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); + //slf021104b end if(vol->mgrVolume) { + //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 return TRUE; } else @@ -629,6 +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 int deadBlox=0,emptyBlox=0,fullBlox=0,allocatingBlox=0,dirtyBlox=0; //int i; // Called to mount a disk. @@ -647,29 +826,129 @@ BOOL YFSD_MountDisk(HDSK hdsk) 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; + +#else #ifdef DISABLE_BOOT_PARTITION // Only want disk volume - YFSD_InitVolume(hdsk, &disk_volume, 1, -1, YFSD_DISK_NAME); + 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_volume.isMounted) + if(disk_volumes[0].isMounted) + { + return TRUE; + } + } + if (disk_volumes[0]) { - return TRUE; + free(disk_volumes[0]; + disk_volumes[0] = NULL; } #else // Want both boot and disk - YFSD_InitVolume(hdsk, &disk_volume, PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME); - YFSD_InitVolume(hdsk, &boot_volume, 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME); + 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_volume.isMounted && boot_volume.isMounted) + 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]) { - return TRUE; + 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); +// +// +// if(disk_volume.isMounted) +// { +// return TRUE; +// } +//#else +// // Want both boot and disk +// YFSD_InitVolume(hdsk, &disk_volume, PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME); +// YFSD_InitVolume(hdsk, &boot_volume, 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME); +// +// +// if(disk_volume.isMounted && boot_volume.isMounted) +// { +// return TRUE; +// } +//#endif +// +// return FALSE; +#endif +//slf021105a end + // yfsd_SetGuards(); // todo - get name from registry @@ -679,17 +958,50 @@ BOOL YFSD_MountDisk(HDSK hdsk) BOOL YFSD_UnmountDisk(HDSK hdsk) { +//slf021105a begin + int i; +//slf021105a end RETAILMSG (MSGSTATE, (L"YAFFS::UnmountDisk\r\n")); - yfsd_FlushAllFiles(); + //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(); - yaffs_Deinitialise(&disk_volume.dev); - yaffs_Deinitialise(&boot_volume.dev); - yfsd_UnlockYAFFS(); +//slf021105a begin +// yaffs_Deinitialise(&disk_volume.dev); +// yaffs_Deinitialise(&boot_volume.dev); +// yfsd_UnlockYAFFS(); +// +// FSDMGR_DeregisterVolume(disk_volume.mgrVolume); +// FSDMGR_DeregisterVolume(boot_volume.mgrVolume); - 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; } @@ -711,22 +1023,35 @@ BOOL YFSD_CreateDirectoryW(PVOLUME pVolume, PCWSTR pathName, PSECURITY_ATTRIBUTE parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pathName,name,YFSD_NAME_LENGTH); - if(parent && yfsd_NameIsValid(name)) - { - newDir = yaffs_MknodDirectory(parent,name,0,0,0); - } - - if(newDir) + //slf021101b begin + if (parent) { - objSize = yaffs_GetObjectFileLength(newDir); - attribs = yfsd_GetObjectWinAttributes(newDir); - modifiedTime[0] = newDir->win_mtime[0]; - modifiedTime[1] = newDir->win_mtime[1]; + if(yfsd_NameIsValid(name)) + { + newDir = yaffs_MknodDirectory(parent,name,0,0,0); + if(newDir) + { + objSize = yaffs_GetObjectFileLength(newDir); + attribs = yfsd_GetObjectWinAttributes(newDir); + modifiedTime[0] = newDir->win_mtime[0]; + modifiedTime[1] = newDir->win_mtime[1]; + } + else + { + if(yaffs_FindObjectByName(parent,name)) + SetLastError(ERROR_ALREADY_EXISTS); + else + SetLastError(ERROR_DISK_FULL); + } + } + else + SetLastError(ERROR_INVALID_NAME); } else { SetLastError(ERROR_PATH_NOT_FOUND); } + //slf021101b end yfsd_UnlockYAFFS(); @@ -752,31 +1077,37 @@ BOOL YFSD_CreateDirectoryW(PVOLUME pVolume, PCWSTR pathName, PSECURITY_ATTRIBUTE } - if(parent && !newDir) - { - SetLastError(ERROR_DISK_FULL); - } +//slf021101b begin +// if(parent && !newDir) +// { +// SetLastError(ERROR_DISK_FULL); +// } +//slf021101b end return newDir ? TRUE : FALSE; } -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) @@ -798,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; @@ -835,8 +1155,7 @@ BOOL YFSD_RemoveDirectoryW(PVOLUME pVolume, PCWSTR pathName) yfsd_ShellDirectoryChanged(pVolume,fpn); } - return result; - + return result ? TRUE : FALSE; } @@ -871,19 +1190,19 @@ DWORD YFSD_GetFileAttributesW(PVOLUME pVolume, PCWSTR pwsFileName ) BOOL YFSD_SetFileAttributesW( PVOLUME pVolume,PCWSTR pwsFileName, DWORD dwFileAttributes ) { - yaffs_Object *obj = NULL; - DWORD mtime[2]; - DWORD attribs; + yaffs_Object *obj = NULL; + DWORD mtime[2]; + DWORD attribs; DWORD objSize; int result = 0; - RETAILMSG (MSGSTATE, (L"YAFFS::SetFileAttributes %X\r\n",dwFileAttributes)); - - if(!yfsd_CheckValidAttributes(dwFileAttributes)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + RETAILMSG (MSGSTATE, (L"YAFFS::SetFileAttributes %X\r\n",dwFileAttributes)); + + if(!yfsd_CheckValidAttributes(dwFileAttributes)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } yfsd_LockYAFFS(); @@ -894,11 +1213,11 @@ BOOL YFSD_SetFileAttributesW( PVOLUME pVolume,PCWSTR pwsFileName, DWORD dwFileAt { obj->st_mode = dwFileAttributes; obj->dirty = 1; - result = yaffs_FlushFile(obj); - attribs = yfsd_GetObjectWinAttributes(obj); - objSize = yaffs_GetObjectFileLength(obj); - mtime[0] = obj->win_mtime[0]; - mtime[1] = obj->win_mtime[1]; + result = yaffs_FlushFile(obj,0); + attribs = yfsd_GetObjectWinAttributes(obj); + objSize = yaffs_GetObjectFileLength(obj); + mtime[0] = obj->win_mtime[0]; + mtime[1] = obj->win_mtime[1]; } else { @@ -934,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; @@ -958,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 ) @@ -971,7 +1331,7 @@ BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName int result = 0; int objIsDir = 0; DWORD attribs; - DWORD objSize; + DWORD objSize; DWORD mtime[2]; RETAILMSG (MSGSTATE, (L"YAFFS::MoveFile\r\n")); @@ -994,9 +1354,9 @@ BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName { objIsDir = (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY); attribs = yfsd_GetObjectWinAttributes(obj); - objSize = yaffs_GetObjectFileLength(obj); - mtime[0] = obj->win_mtime[0]; - mtime[1] = obj->win_mtime[1]; + objSize = yaffs_GetObjectFileLength(obj); + mtime[0] = obj->win_mtime[0]; + mtime[1] = obj->win_mtime[1]; } } else @@ -1036,8 +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")); - return FALSE; + + //slf021104c begin + if (fSuccess = YFSD_DeleteFileW(pVolume, pwsOldFileName)) + fSuccess = YFSD_MoveFileW(pVolume, pwsNewFileName, pwsOldFileName); + return fSuccess; + //return FALSE; + //slf021104c end } BOOL YFSD_GetDiskFreeSpaceW( PVOLUME pVolume, PCWSTR pwsPathName, PDWORD pSectorsPerCluster,PDWORD pBytesPerSector, PDWORD pFreeClusters, PDWORD pClusters ) @@ -1232,8 +1602,8 @@ BOOL yfsd_ObjectAlreadyFound(PSEARCH pSearch, yaffs_Object *l) return found; } - -#if 0 + +#if 0 // slower one BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd) { @@ -1282,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); @@ -1309,77 +1679,77 @@ out_of_here: return found; } - -#else -// faster one -BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd) -{ - - struct list_head *i; - yaffs_Object *l; - BOOL found = 0; - - char name[YAFFS_MAX_NAME_LENGTH+1]; - - if(!pSearch->foundObjects) - { - pSearch->foundObjects = malloc(sizeof(yaffs_FoundObject)); - pSearch->foundObjects->next = NULL; - pSearch->foundObjects->obj = 0; - } - - - yfsd_LockYAFFS(); - - list_for_each(i,&pSearch->dir->variant.directoryVariant.children) - { - - l = list_entry(i, yaffs_Object,siblings); - if(!yfsd_ObjectAlreadyFound(pSearch,l)) - { - // Only look at things we have not looked at already - yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1); - - if(regularMatch(pSearch->pattern,name)) - { - found = 1; - // fill out find data - - pfd->dwFileAttributes = yfsd_GetObjectWinAttributes(l); - - yfsd_U32sToWinFileTime(l->win_ctime,&pfd->ftCreationTime); - yfsd_U32sToWinFileTime(l->win_atime,&pfd->ftLastAccessTime); - yfsd_U32sToWinFileTime(l->win_mtime,&pfd->ftLastWriteTime); - - pfd->nFileSizeHigh = 0; - pfd->nFileSizeLow = yaffs_GetObjectFileLength(l); - pfd->dwOID = 0; // wtf is this??? - - MultiByteToWideChar(CP_ACP,0,name,-1,pfd->cFileName,YFSD_NAME_LENGTH); - - RETAILMSG(MSGSTATE,(L"File %s id %d header %d nDataChunks %d scannedLength %d\r\n", - pfd->cFileName,l->objectId, l->chunkId, l->nDataChunks, - l->variant.fileVariant.scannedFileSize)); - goto out_of_here; - } - - } - - - } - -out_of_here: - yfsd_UnlockYAFFS(); - - - if(!found) - { - SetLastError(ERROR_NO_MORE_FILES); - } - return found; - -} -#endif + +#else +// faster one +BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd) +{ + + struct list_head *i; + yaffs_Object *l; + BOOL found = 0; + + char name[YAFFS_MAX_NAME_LENGTH+1]; + + if(!pSearch->foundObjects) + { + pSearch->foundObjects = malloc(sizeof(yaffs_FoundObject)); + pSearch->foundObjects->next = NULL; + pSearch->foundObjects->obj = 0; + } + + + yfsd_LockYAFFS(); + + list_for_each(i,&pSearch->dir->variant.directoryVariant.children) + { + + l = list_entry(i, yaffs_Object,siblings); + if(!yfsd_ObjectAlreadyFound(pSearch,l)) + { + // Only look at things we have not looked at already + yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1); + + if(regularMatch(pSearch->pattern,name)) + { + found = 1; + // fill out find data + + pfd->dwFileAttributes = yfsd_GetObjectWinAttributes(l); + + yfsd_U32sToWinFileTime(l->win_ctime,&pfd->ftCreationTime); + yfsd_U32sToWinFileTime(l->win_atime,&pfd->ftLastAccessTime); + yfsd_U32sToWinFileTime(l->win_mtime,&pfd->ftLastWriteTime); + + pfd->nFileSizeHigh = 0; + pfd->nFileSizeLow = yaffs_GetObjectFileLength(l); + pfd->dwOID = (CEOID)(INVALID_HANDLE_VALUE); // wtf is this??? + + MultiByteToWideChar(CP_ACP,0,name,-1,pfd->cFileName,YFSD_NAME_LENGTH); + + RETAILMSG(MSGSTATE,(L"File %s id %d header %d nDataChunks %d scannedLength %d\r\n", + pfd->cFileName,l->objectId, l->chunkId, l->nDataChunks, + l->variant.fileVariant.scannedFileSize)); + goto out_of_here; + } + + } + + + } + +out_of_here: + yfsd_UnlockYAFFS(); + + + if(!found) + { + SetLastError(ERROR_NO_MORE_FILES); + } + return found; + +} +#endif HANDLE YFSD_FindFirstFileW(PVOLUME pVolume, HANDLE hProc,PCWSTR pwsFileSpec, PWIN32_FIND_DATAW pfd ) { @@ -1412,6 +1782,7 @@ HANDLE YFSD_FindFirstFileW(PVOLUME pVolume, HANDLE hProc,PCWSTR pwsFileSpec, PWI { free(pSearch); pSearch = NULL; + SetLastError(ERROR_PATH_NOT_FOUND); } } @@ -1422,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; @@ -1485,13 +1863,19 @@ HANDLE YFSD_CreateFileW( 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 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) { @@ -1502,11 +1886,11 @@ HANDLE YFSD_CreateFileW( RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile write not permitted\r\n")); } - if(!yfsd_CheckValidAttributes(mode)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if(!yfsd_CheckValidAttributes(mode)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } yfsd_LockYAFFS(); @@ -1516,28 +1900,48 @@ HANDLE YFSD_CreateFileW( if(parent && yfsd_NameIsValid(name)) { - - - obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName); - if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) - { - // Naughty, naughty. Don't do file ops on directories - SetLastError(ERROR_ACCESS_DENIED); - fileCreated = FALSE; - obj = NULL; - } - else if(dwCreate == CREATE_NEW) + + //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")); - obj = yaffs_MknodFile(parent,name,mode,0,0); + //slf021101c begin + //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_DISK_FULL); - fileCreated = TRUE; + { + obj = yaffs_MknodFile(parent,name,mode,0,0); + if(!obj) + SetLastError(ERROR_DISK_FULL); + fileCreated = TRUE; + } + //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")); @@ -1547,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")); @@ -1555,26 +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; + // } + //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) { @@ -1584,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); + // 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 @@ -1605,6 +2051,42 @@ HANDLE YFSD_CreateFileW( 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 + { + //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) { RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have an object\r\n")); @@ -1623,14 +2105,35 @@ 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; + //slf021220d begin oops typo. + f->readPermitted = readPermitted; + //slf021220d end oops typo. + f->shareRead= shareRead; + f->shareWrite = shareWrite; f->myVolume = pVolume; obj->inUse++; - modifiedTime[0] = obj->win_mtime[0]; - modifiedTime[1] = obj->win_mtime[1]; + modifiedTime[0] = obj->win_mtime[0]; + modifiedTime[1] = obj->win_mtime[1]; objSize = yaffs_GetObjectFileLength(obj); RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - file size %d\r\n",objSize)); } @@ -1737,8 +2240,8 @@ BOOL yfsd_DoReadFile( { nread = yaffs_ReadDataFromFile(obj,pBuffer,pFile->offset,cbRead); if(nread > 0) - { - pFile->offset += nread; + { + pFile->offset += nread; if(pcbRead) { @@ -1748,9 +2251,9 @@ BOOL yfsd_DoReadFile( } else { - if(pcbRead) - { - *pcbRead = maxRead; + if(pcbRead) + { + *pcbRead = maxRead; } } @@ -1794,7 +2297,7 @@ BOOL YFSD_ReadFileWithSeek( DWORD dwLowOffset, DWORD dwHighOffset ) { - BOOL result; + BOOL result; DWORD rememberedOffset; RETAILMSG (MSGSTATE, (L"YAFFS::ReadFileWithSeek %d bytes at %d high %d pcbRead %X\r\n",cbRead,dwLowOffset,dwHighOffset,pcbRead)); @@ -1813,16 +2316,16 @@ BOOL YFSD_ReadFileWithSeek( return FALSE; } - yfsd_LockYAFFS(); - + yfsd_LockYAFFS(); + rememberedOffset = pFile->offset; pFile->offset = dwLowOffset; // ignore high offset for now result = yfsd_DoReadFile(pFile,pBuffer,cbRead,pcbRead); - - //pFile->offset = rememberedOffset; + + //pFile->offset = rememberedOffset; yfsd_UnlockYAFFS(); @@ -1909,7 +2412,7 @@ BOOL YFSD_WriteFileWithSeek( DWORD rememberedOffset; RETAILMSG (MSGSTATE, (L"YAFFS::WriteFileWithSeek %d bytes at %d,%d pcbWritten %X\r\n",cbWrite,dwHighOffset,dwLowOffset,pcbWritten)); - + if(!pFile || !pFile->obj) { @@ -1918,15 +2421,15 @@ BOOL YFSD_WriteFileWithSeek( } yfsd_LockYAFFS(); - - rememberedOffset = pFile->offset; + + rememberedOffset = pFile->offset; pFile->offset = dwLowOffset; // ignore high offset for now result = yfsd_DoWriteFile(pFile,pBuffer,cbWrite,pcbWritten); - - //pFile->offset = rememberedOffset; + + //pFile->offset = rememberedOffset; yfsd_UnlockYAFFS(); @@ -1953,8 +2456,8 @@ DWORD YFSD_SetFilePointer( return offset; } - yfsd_LockYAFFS(); - + yfsd_LockYAFFS(); + oldPos = pFile->offset; @@ -2028,8 +2531,8 @@ DWORD YFSD_GetFileSize( fileSize = yaffs_GetObjectFileLength(pFile->obj); - yfsd_UnlockYAFFS(); - if(pFileSizeHigh) + yfsd_UnlockYAFFS(); + if(pFileSizeHigh) *pFileSizeHigh = 0; return fileSize; @@ -2047,35 +2550,36 @@ BOOL YFSD_GetFileInformationByHandle( { SetLastError(ERROR_INVALID_HANDLE); return FALSE; - } - - yfsd_LockYAFFS(); - - pFileInfo->dwFileAttributes = yfsd_GetObjectWinAttributes(pFile->obj); - yfsd_U32sToWinFileTime(pFile->obj->win_ctime,&pFileInfo->ftCreationTime); - yfsd_U32sToWinFileTime(pFile->obj->win_atime,&pFileInfo->ftLastAccessTime); - yfsd_U32sToWinFileTime(pFile->obj->win_mtime,&pFileInfo->ftLastWriteTime); - pFileInfo->dwVolumeSerialNumber = 0; //todo is this OK? - pFileInfo->nFileSizeHigh = 0; - pFileInfo->nFileSizeLow = yaffs_GetObjectFileLength(pFile->obj); - pFileInfo->nNumberOfLinks = 1; // only primary link supported like FAT - pFileInfo->nFileIndexHigh = 0; - pFileInfo->nFileIndexLow = pFile->obj->objectId; - + } + + yfsd_LockYAFFS(); + + pFileInfo->dwFileAttributes = yfsd_GetObjectWinAttributes(pFile->obj); + yfsd_U32sToWinFileTime(pFile->obj->win_ctime,&pFileInfo->ftCreationTime); + yfsd_U32sToWinFileTime(pFile->obj->win_atime,&pFileInfo->ftLastAccessTime); + yfsd_U32sToWinFileTime(pFile->obj->win_mtime,&pFileInfo->ftLastWriteTime); + pFileInfo->dwVolumeSerialNumber = 0; //todo is this OK? + pFileInfo->nFileSizeHigh = 0; + pFileInfo->nFileSizeLow = yaffs_GetObjectFileLength(pFile->obj); + pFileInfo->nNumberOfLinks = 1; // only primary link supported like FAT + pFileInfo->nFileIndexHigh = 0; + pFileInfo->nFileIndexLow = pFile->obj->objectId; + pFileInfo->dwOID = (CEOID)(INVALID_HANDLE_VALUE); + yfsd_UnlockYAFFS(); return TRUE; } BOOL YFSD_FlushFileBuffers(PFILE pFile ) -{ - WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; - int nameExists = 0; - yfsd_Volume *vol = NULL; - DWORD attribs = 0; - DWORD objSize = 0; - DWORD mtime[2]; - +{ + WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; + int nameExists = 0; + yfsd_Volume *vol = NULL; + DWORD attribs = 0; + DWORD objSize = 0; + DWORD mtime[2]; + RETAILMSG (MSGSTATE, (L"YAFFS::FlushFileBuffers\r\n")); @@ -2085,40 +2589,40 @@ BOOL YFSD_FlushFileBuffers(PFILE pFile ) return FALSE; } - yfsd_LockYAFFS(); - - yaffs_FlushFile(pFile->obj); - attribs = yfsd_GetObjectWinAttributes(pFile->obj); - objSize = yaffs_GetObjectFileLength(pFile->obj); - mtime[0] = pFile->obj->win_mtime[0]; - mtime[1] = pFile->obj->win_mtime[1]; - if(pFile->fullName) - { - wcscpy(fpn,pFile->fullName); - nameExists = 1; - } - vol = pFile->myVolume; - + yfsd_LockYAFFS(); + + yaffs_FlushFile(pFile->obj,1); + attribs = yfsd_GetObjectWinAttributes(pFile->obj); + objSize = yaffs_GetObjectFileLength(pFile->obj); + mtime[0] = pFile->obj->win_mtime[0]; + mtime[1] = pFile->obj->win_mtime[1]; + if(pFile->fullName) + { + wcscpy(fpn,pFile->fullName); + nameExists = 1; + } + vol = pFile->myVolume; + yfsd_UnlockYAFFS(); - - if(vol && vol->shellFunction && nameExists) - { - FILECHANGEINFO fc; - - fc.cbSize = sizeof(FILECHANGEINFO); - fc.wEventId = SHCNE_UPDATEITEM; - fc.uFlags = SHCNF_PATH; - fc.dwItem1 = (DWORD)fpn; - fc.dwItem2 = 0; - fc.dwAttributes = attribs; - yfsd_U32sToWinFileTime(mtime,&fc.ftModified); - fc.nFileSize = objSize; - - vol->shellFunction(&fc); - RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n")); - //yfsd_ShellDirectoryChanged(vol,fpn); - } - + + if(vol && vol->shellFunction && nameExists) + { + FILECHANGEINFO fc; + + fc.cbSize = sizeof(FILECHANGEINFO); + fc.wEventId = SHCNE_UPDATEITEM; + fc.uFlags = SHCNF_PATH; + fc.dwItem1 = (DWORD)fpn; + fc.dwItem2 = 0; + fc.dwAttributes = attribs; + yfsd_U32sToWinFileTime(mtime,&fc.ftModified); + fc.nFileSize = objSize; + + vol->shellFunction(&fc); + RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n")); + //yfsd_ShellDirectoryChanged(vol,fpn); + } + return TRUE; } @@ -2154,15 +2658,15 @@ BOOL YFSD_SetFileTime( CONST FILETIME *pLastAccess, CONST FILETIME *pLastWrite ) { - WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; - int nameExists = 0; + WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; + int nameExists = 0; int result = FALSE; - yfsd_Volume *vol = NULL; - DWORD attribs = 0; - DWORD objSize = 0; - DWORD mtime[2]; - - + yfsd_Volume *vol = NULL; + DWORD attribs = 0; + DWORD objSize = 0; + DWORD mtime[2]; + + RETAILMSG (MSGSTATE, (L"YAFFS::SetFileTime\r\n")); if(!pFile || !pFile->obj) @@ -2174,60 +2678,60 @@ BOOL YFSD_SetFileTime( yfsd_LockYAFFS(); - if(pCreation) - { - yfsd_WinFileTimeToU32s(pCreation,pFile->obj->win_ctime); - pFile->obj->dirty = 1; + if(pCreation) + { + yfsd_WinFileTimeToU32s(pCreation,pFile->obj->win_ctime); + pFile->obj->dirty = 1; } - if(pLastAccess) - { - yfsd_WinFileTimeToU32s(pLastAccess,pFile->obj->win_atime); - pFile->obj->dirty = 1; + if(pLastAccess) + { + yfsd_WinFileTimeToU32s(pLastAccess,pFile->obj->win_atime); + pFile->obj->dirty = 1; } - if(pLastWrite) - { - yfsd_WinFileTimeToU32s(pLastWrite,pFile->obj->win_mtime); + if(pLastWrite) + { + yfsd_WinFileTimeToU32s(pLastWrite,pFile->obj->win_mtime); pFile->obj->dirty = 1; } if(pCreation || pLastAccess || pLastWrite) { - result = yaffs_FlushFile(pFile->obj); - } - - if(result) - { - attribs = yfsd_GetObjectWinAttributes(pFile->obj); - objSize = yaffs_GetObjectFileLength(pFile->obj); - mtime[0] = pFile->obj->win_mtime[0]; - mtime[1] = pFile->obj->win_mtime[1]; - if(pFile->fullName) - { - wcscpy(fpn,pFile->fullName); - nameExists = 1; - } - vol = pFile->myVolume; - } - + result = yaffs_FlushFile(pFile->obj,0); + } + + if(result) + { + attribs = yfsd_GetObjectWinAttributes(pFile->obj); + objSize = yaffs_GetObjectFileLength(pFile->obj); + mtime[0] = pFile->obj->win_mtime[0]; + mtime[1] = pFile->obj->win_mtime[1]; + if(pFile->fullName) + { + wcscpy(fpn,pFile->fullName); + nameExists = 1; + } + vol = pFile->myVolume; + } + yfsd_UnlockYAFFS(); // Call shell function - if(nameExists && result && vol && vol->shellFunction) - { - FILECHANGEINFO fc; - - fc.cbSize = sizeof(FILECHANGEINFO); - fc.wEventId = SHCNE_UPDATEITEM; - fc.uFlags = SHCNF_PATH; - fc.dwItem1 = (DWORD)fpn; - fc.dwItem2 = 0; - fc.dwAttributes = attribs; - yfsd_U32sToWinFileTime(mtime,&fc.ftModified); - fc.nFileSize = objSize; - - vol->shellFunction(&fc); - RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n")); - //yfsd_ShellDirectoryChanged(vol,fpn); - } + if(nameExists && result && vol && vol->shellFunction) + { + FILECHANGEINFO fc; + + fc.cbSize = sizeof(FILECHANGEINFO); + fc.wEventId = SHCNE_UPDATEITEM; + fc.uFlags = SHCNF_PATH; + fc.dwItem1 = (DWORD)fpn; + fc.dwItem2 = 0; + fc.dwAttributes = attribs; + yfsd_U32sToWinFileTime(mtime,&fc.ftModified); + fc.nFileSize = objSize; + + vol->shellFunction(&fc); + RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n")); + //yfsd_ShellDirectoryChanged(vol,fpn); + } return TRUE; } @@ -2236,12 +2740,12 @@ BOOL YFSD_SetEndOfFile( PFILE pFile ) { - WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; - int nameExists = 0; - yfsd_Volume *vol = NULL; - DWORD attribs = 0; - DWORD objSize = 0; - DWORD mtime[2]; + WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; + int nameExists = 0; + yfsd_Volume *vol = NULL; + DWORD attribs = 0; + DWORD objSize = 0; + DWORD mtime[2]; static unsigned char zeros[512]; int result; @@ -2303,40 +2807,40 @@ PFILE pFile ) { retVal = TRUE; } - if(retVal) - { - attribs = yfsd_GetObjectWinAttributes(pFile->obj); - objSize = yaffs_GetObjectFileLength(pFile->obj); - mtime[0] = pFile->obj->win_mtime[0]; - mtime[1] = pFile->obj->win_mtime[1]; - if(pFile->fullName) - { - wcscpy(fpn,pFile->fullName); - nameExists = 1; - } - vol = pFile->myVolume; - } - - - yfsd_UnlockYAFFS(); - - if(nameExists && retVal && vol && vol->shellFunction) - { - FILECHANGEINFO fc; - - fc.cbSize = sizeof(FILECHANGEINFO); - fc.wEventId = SHCNE_UPDATEITEM; - fc.uFlags = SHCNF_PATH; - fc.dwItem1 = (DWORD)fpn; - fc.dwItem2 = 0; - fc.dwAttributes = attribs; - yfsd_U32sToWinFileTime(mtime,&fc.ftModified); - fc.nFileSize = objSize; - - vol->shellFunction(&fc); - RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n")); - //yfsd_ShellDirectoryChanged(vol,fpn); - } + if(retVal) + { + attribs = yfsd_GetObjectWinAttributes(pFile->obj); + objSize = yaffs_GetObjectFileLength(pFile->obj); + mtime[0] = pFile->obj->win_mtime[0]; + mtime[1] = pFile->obj->win_mtime[1]; + if(pFile->fullName) + { + wcscpy(fpn,pFile->fullName); + nameExists = 1; + } + vol = pFile->myVolume; + } + + + yfsd_UnlockYAFFS(); + + if(nameExists && retVal && vol && vol->shellFunction) + { + FILECHANGEINFO fc; + + fc.cbSize = sizeof(FILECHANGEINFO); + fc.wEventId = SHCNE_UPDATEITEM; + fc.uFlags = SHCNF_PATH; + fc.dwItem1 = (DWORD)fpn; + fc.dwItem2 = 0; + fc.dwAttributes = attribs; + yfsd_U32sToWinFileTime(mtime,&fc.ftModified); + fc.nFileSize = objSize; + + vol->shellFunction(&fc); + RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n")); + //yfsd_ShellDirectoryChanged(vol,fpn); + } RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF file size %d\r\n",yaffs_GetObjectFileLength(pFile->obj))); @@ -2367,7 +2871,7 @@ BOOL YFSD_CloseFile( PFILE pFile ) yfsd_Volume *vol = NULL; DWORD attribs = 0; DWORD objSize = 0; - DWORD mtime[2]; + DWORD mtime[2]; RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile %X\r\n",pFile)); @@ -2383,11 +2887,11 @@ BOOL YFSD_CloseFile( PFILE pFile ) { pFile->obj->inUse--; RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile on obj\r\n")); - yaffs_FlushFile(pFile->obj); + yaffs_FlushFile(pFile->obj,1); attribs = yfsd_GetObjectWinAttributes(pFile->obj); objSize = yaffs_GetObjectFileLength(pFile->obj); - mtime[0] = pFile->obj->win_mtime[0]; - mtime[1] = pFile->obj->win_mtime[1]; + mtime[0] = pFile->obj->win_mtime[0]; + mtime[1] = pFile->obj->win_mtime[1]; RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile on obj done, size is %d\r\n",objSize)); if(pFile->fullName) {