-/*\r
- * YAFFS: Yet another FFS. A NAND-flash specific file system.\r
- * yaffsfsd.c: The FSD layer for the WinCE version of YAFFS.\r
- *\r
- * Copyright (C) 2002 Trimble Navigation Ltd.\r
- *\r
- * Created by Charles Manning <charles.manning@trimble.co.nz>\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License version 2 as\r
- * published by the Free Software Foundation.\r
- *\r
- * This program is distributed in the hope that it will be useful, \r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of \r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
- * General Public License for more details. You should have received a \r
- * copy of the GNU General Public License along with this program; \r
- * if not, write to the Free Software Foundation, Inc., \r
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \r
- *\r
- * $Id: yaffsfsd.c,v 1.1 2002-11-08 07:30:00 charles Exp $\r
+/*
+ * 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 <charles.manning@trimble.co.nz>
+ *
+ * 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 <windows.h>
#include <extfile.h>
#include <yaffs_guts.h>
#include <ynandif.h>
+//slf021104b begin
+#include <diskio.h>
+//slf021104b end
#define MAX_WIN_FILE 200
#define YFSD_NAME_LENGTH 128
#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\r
-\r
-unsigned yaffs_traceMask=0xffffffff;
+//unsigned yaffs_traceMask=0xffffffff;
+unsigned yaffs_traceMask=0;
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;
#include <fsdmgr.h>
-
-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;
}
#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"));
{
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;
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"\\");
// FILETIME is a 64-bit value as 100-nanosecond intervals since January 1, 1601.
-\r
+
void yfsd_U32sToWinFileTime(__u32 target[2], FILETIME *wft)
{
}
-\r
-\r
-// Minimal name test for now\r
-BOOL yfsd_NameIsValid (const char *name)\r
-{\r
- int length = strlen(name);\r
-\r
- return (length > 0 && length <= YFSD_NAME_LENGTH);\r
-\r
+
+
+// Minimal name test for now
+BOOL yfsd_NameIsValid (const char *name)
+{
+ int length = strlen(name);
+
+ return (length > 0 && length <= YFSD_NAME_LENGTH);
+
}
// File attributes:
//
//
// in addition, GetAttributes also returns FILE_ATTRIBUTE_DIRECTORY
-\r
-// The following are valid ones we get presented with,\r
-// but must filter out the stuff we don't unserstand\r
-//#define FILE_ATTRIBUTE_READONLY 0x00000001 \r
-//#define FILE_ATTRIBUTE_HIDDEN 0x00000002 \r
-//#define FILE_ATTRIBUTE_SYSTEM 0x00000004 \r
-//#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 \r
-//#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 \r
-//#define FILE_ATTRIBUTE_INROM 0x00000040\r
-//#define FILE_ATTRIBUTE_ENCRYPTED 0x00000040 \r
-//#define FILE_ATTRIBUTE_NORMAL 0x00000080 \r
-//#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 \r
-//#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 \r
-//#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 \r
-//#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 \r
-//#define FILE_ATTRIBUTE_OFFLINE 0x00001000 \r
-//#define FILE_ATTRIBUTE_ROMSTATICREF 0x00001000\r
-//#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 \r
-//#define FILE_ATTRIBUTE_ROMMODULE 0x00002000\r
-\r
-\r
-BOOL yfsd_CheckValidAttributes(DWORD attribs)\r
-{\r
-\r
- RETAILMSG (MSGSTATE, (L"Attributes:%X\r\n", attribs));\r
-\r
-#if 0\r
- // If NORMAL, then nothing else\r
- if(attribs & FILE_ATTRIBUTE_NORMAL && attribs != FILE_ATTRIBUTE_NORMAL)\r
- return FALSE;\r
- if(attribs == FILE_ATTRIBUTE_NORMAL) \r
- return TRUE;\r
-#endif\r
- // Check that the bits are in the valid set\r
- if(attribs & ~(0x3FE7))\r
- return FALSE;\r
-\r
- return TRUE;\r
-\r
+
+// 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 & \r
- (FILE_ATTRIBUTE_READONLY | \r
- FILE_ATTRIBUTE_ARCHIVE | \r
- FILE_ATTRIBUTE_HIDDEN |\r
+ result = obj->st_mode &
+ (FILE_ATTRIBUTE_READONLY |
+ FILE_ATTRIBUTE_ARCHIVE |
+ FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM);
-\r
- if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) result |= FILE_ATTRIBUTE_DIRECTORY;\r
+
+ if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) result |= FILE_ATTRIBUTE_DIRECTORY;
if(result & ~FILE_ATTRIBUTE_NORMAL)
{
{
result = FILE_ATTRIBUTE_NORMAL;
}
-\r
+
return result;
}
RETAILMSG (MSGSTATE, (L"YAFFS::FindByWinPath (%s) : ", path));
// start at the root of this device
- current = yaffs_Root(device);\r
+ current = yaffs_Root(device);
*processed = '\0';
do
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
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.
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<MAXPARTITIONS; i++)
+ {
+ // At the very lease check that the end is later than the beginning
+ // and don't let it start at 0.
+ // Probably could do more thorough checking but I trust the block
+ // driver.
+ if (PartTable[i].startBlock && (PartTable[i].endBlock > 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
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; i<MAXPARTITIONS; i++)
+ {
+ if (disk_volumes[i])
+ {
+ yaffs_Deinitialise(&(disk_volumes[i]->dev));
+//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;
}
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];\r
- modifiedTime[1] = newDir->win_mtime[1];\r
+ 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();
}
- 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)
{
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;
yfsd_ShellDirectoryChanged(pVolume,fpn);
}
- return result;
-
+ return result ? TRUE : FALSE;
}
BOOL YFSD_SetFileAttributesW( PVOLUME pVolume,PCWSTR pwsFileName, DWORD dwFileAttributes )
{
- yaffs_Object *obj = NULL;\r
- DWORD mtime[2];\r
- DWORD attribs;\r
+ yaffs_Object *obj = NULL;
+ DWORD mtime[2];
+ DWORD attribs;
DWORD objSize;
int result = 0;
- RETAILMSG (MSGSTATE, (L"YAFFS::SetFileAttributes %X\r\n",dwFileAttributes));\r
-\r
- if(!yfsd_CheckValidAttributes(dwFileAttributes))\r
- {\r
- SetLastError(ERROR_INVALID_PARAMETER);\r
- return FALSE;\r
+ RETAILMSG (MSGSTATE, (L"YAFFS::SetFileAttributes %X\r\n",dwFileAttributes));
+
+ if(!yfsd_CheckValidAttributes(dwFileAttributes))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
yfsd_LockYAFFS();
{
obj->st_mode = dwFileAttributes;
obj->dirty = 1;
- result = yaffs_FlushFile(obj);\r
- attribs = yfsd_GetObjectWinAttributes(obj);\r
- objSize = yaffs_GetObjectFileLength(obj);\r
- mtime[0] = obj->win_mtime[0];\r
- mtime[1] = obj->win_mtime[1];\r
+ 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
{
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;
yfsd_ShellDirectoryChanged(pVolume,fpn);
}
- return result;
+ return result ? TRUE : FALSE;
}
BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName )
int result = 0;
int objIsDir = 0;
DWORD attribs;
- DWORD objSize;\r
+ DWORD objSize;
DWORD mtime[2];
RETAILMSG (MSGSTATE, (L"YAFFS::MoveFile\r\n"));
{
objIsDir = (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY);
attribs = yfsd_GetObjectWinAttributes(obj);
- objSize = yaffs_GetObjectFileLength(obj);\r
- mtime[0] = obj->win_mtime[0];\r
- mtime[1] = obj->win_mtime[1];\r
+ objSize = yaffs_GetObjectFileLength(obj);
+ mtime[0] = obj->win_mtime[0];
+ mtime[1] = obj->win_mtime[1];
}
}
else
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 )
return found;
}
-\r
-#if 0\r
+
+#if 0
// slower one
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);
return found;
}
-\r
-#else\r
-// faster one\r
-BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd)\r
-{\r
-\r
- struct list_head *i;\r
- yaffs_Object *l;\r
- BOOL found = 0;\r
-\r
- char name[YAFFS_MAX_NAME_LENGTH+1];\r
-\r
- if(!pSearch->foundObjects)\r
- {\r
- pSearch->foundObjects = malloc(sizeof(yaffs_FoundObject));\r
- pSearch->foundObjects->next = NULL;\r
- pSearch->foundObjects->obj = 0;\r
- }\r
-\r
-\r
- yfsd_LockYAFFS();\r
-\r
- list_for_each(i,&pSearch->dir->variant.directoryVariant.children)\r
- {\r
-\r
- l = list_entry(i, yaffs_Object,siblings);\r
- if(!yfsd_ObjectAlreadyFound(pSearch,l))\r
- {\r
- // Only look at things we have not looked at already\r
- yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1);\r
-\r
- if(regularMatch(pSearch->pattern,name))\r
- {\r
- found = 1;\r
- // fill out find data\r
-\r
- pfd->dwFileAttributes = yfsd_GetObjectWinAttributes(l);\r
-\r
- yfsd_U32sToWinFileTime(l->win_ctime,&pfd->ftCreationTime);\r
- yfsd_U32sToWinFileTime(l->win_atime,&pfd->ftLastAccessTime);\r
- yfsd_U32sToWinFileTime(l->win_mtime,&pfd->ftLastWriteTime);\r
-\r
- pfd->nFileSizeHigh = 0;\r
- pfd->nFileSizeLow = yaffs_GetObjectFileLength(l);\r
- pfd->dwOID = 0; // wtf is this???\r
-\r
- MultiByteToWideChar(CP_ACP,0,name,-1,pfd->cFileName,YFSD_NAME_LENGTH);\r
-\r
- RETAILMSG(MSGSTATE,(L"File %s id %d header %d nDataChunks %d scannedLength %d\r\n",\r
- pfd->cFileName,l->objectId, l->chunkId, l->nDataChunks,\r
- l->variant.fileVariant.scannedFileSize));\r
- goto out_of_here;\r
- }\r
-\r
- }\r
-\r
-\r
- }\r
-\r
-out_of_here:\r
- yfsd_UnlockYAFFS();\r
-\r
-\r
- if(!found)\r
- {\r
- SetLastError(ERROR_NO_MORE_FILES);\r
- }\r
- return found;\r
- \r
-}\r
-#endif\r
+
+#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 )
{
{
free(pSearch);
pSearch = NULL;
+ SetLastError(ERROR_PATH_NOT_FOUND);
}
}
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;
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)
{
RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile write not permitted\r\n"));
}
- if(!yfsd_CheckValidAttributes(mode))\r
- {\r
- SetLastError(ERROR_INVALID_PARAMETER);\r
- return FALSE;\r
- }\r
+ if(!yfsd_CheckValidAttributes(mode))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
yfsd_LockYAFFS();
if(parent && yfsd_NameIsValid(name))
{
-\r
-
- obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
- if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)\r
- {\r
- // Naughty, naughty. Don't do file ops on directories\r
- SetLastError(ERROR_ACCESS_DENIED);\r
- fileCreated = FALSE;\r
- obj = NULL;\r
- }\r
- 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"));
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"));
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)
{
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
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"));
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];\r
- modifiedTime[1] = obj->win_mtime[1];\r
+ 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));
}
{
nread = yaffs_ReadDataFromFile(obj,pBuffer,pFile->offset,cbRead);
if(nread > 0)
- {\r
- pFile->offset += nread;\r
+ {
+ pFile->offset += nread;
if(pcbRead)
{
}
else
{
- if(pcbRead) \r
- {\r
- *pcbRead = maxRead;\r
+ if(pcbRead)
+ {
+ *pcbRead = maxRead;
}
}
DWORD dwLowOffset,
DWORD dwHighOffset )
{
- BOOL result;\r
+ BOOL result;
DWORD rememberedOffset;
RETAILMSG (MSGSTATE, (L"YAFFS::ReadFileWithSeek %d bytes at %d high %d pcbRead %X\r\n",cbRead,dwLowOffset,dwHighOffset,pcbRead));
return FALSE;
}
- yfsd_LockYAFFS();\r
-\r
+ yfsd_LockYAFFS();
+
rememberedOffset = pFile->offset;
pFile->offset = dwLowOffset;
// ignore high offset for now
result = yfsd_DoReadFile(pFile,pBuffer,cbRead,pcbRead);
-\r
- //pFile->offset = rememberedOffset;\r
+
+ //pFile->offset = rememberedOffset;
yfsd_UnlockYAFFS();
DWORD rememberedOffset;
RETAILMSG (MSGSTATE, (L"YAFFS::WriteFileWithSeek %d bytes at %d,%d pcbWritten %X\r\n",cbWrite,dwHighOffset,dwLowOffset,pcbWritten));
- \r
+
if(!pFile || !pFile->obj)
{
}
yfsd_LockYAFFS();
-\r
- rememberedOffset = pFile->offset;\r
+
+ rememberedOffset = pFile->offset;
pFile->offset = dwLowOffset;
// ignore high offset for now
result = yfsd_DoWriteFile(pFile,pBuffer,cbWrite,pcbWritten);
-\r
- //pFile->offset = rememberedOffset;\r
+
+ //pFile->offset = rememberedOffset;
yfsd_UnlockYAFFS();
return offset;
}
- yfsd_LockYAFFS();\r
-\r
+ yfsd_LockYAFFS();
+
oldPos = pFile->offset;
fileSize = yaffs_GetObjectFileLength(pFile->obj);
- yfsd_UnlockYAFFS();\r
- if(pFileSizeHigh)\r
+ yfsd_UnlockYAFFS();
+ if(pFileSizeHigh)
*pFileSizeHigh = 0;
return fileSize;
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
- }\r
-\r
- yfsd_LockYAFFS();\r
-\r
- pFileInfo->dwFileAttributes = yfsd_GetObjectWinAttributes(pFile->obj);\r
- yfsd_U32sToWinFileTime(pFile->obj->win_ctime,&pFileInfo->ftCreationTime);\r
- yfsd_U32sToWinFileTime(pFile->obj->win_atime,&pFileInfo->ftLastAccessTime);\r
- yfsd_U32sToWinFileTime(pFile->obj->win_mtime,&pFileInfo->ftLastWriteTime);\r
- pFileInfo->dwVolumeSerialNumber = 0; //todo is this OK? \r
- pFileInfo->nFileSizeHigh = 0;\r
- pFileInfo->nFileSizeLow = yaffs_GetObjectFileLength(pFile->obj); \r
- pFileInfo->nNumberOfLinks = 1; // only primary link supported like FAT\r
- pFileInfo->nFileIndexHigh = 0; \r
- pFileInfo->nFileIndexLow = pFile->obj->objectId; \r
-\r
+ }
+
+ 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 )
-{\r
- WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
- int nameExists = 0;\r
- yfsd_Volume *vol = NULL;\r
- DWORD attribs = 0;\r
- DWORD objSize = 0;\r
- DWORD mtime[2];\r
-\r
+{
+ 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"));
return FALSE;
}
- yfsd_LockYAFFS();\r
-
- yaffs_FlushFile(pFile->obj);\r
- attribs = yfsd_GetObjectWinAttributes(pFile->obj);\r
- objSize = yaffs_GetObjectFileLength(pFile->obj);\r
- mtime[0] = pFile->obj->win_mtime[0];\r
- mtime[1] = pFile->obj->win_mtime[1];\r
- if(pFile->fullName)\r
- {\r
- wcscpy(fpn,pFile->fullName);\r
- nameExists = 1;\r
- }\r
- vol = pFile->myVolume;\r
-\r
+ 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();
- \r
- if(vol && vol->shellFunction && nameExists)\r
- {\r
- FILECHANGEINFO fc;\r
- \r
- fc.cbSize = sizeof(FILECHANGEINFO);\r
- fc.wEventId = SHCNE_UPDATEITEM;\r
- fc.uFlags = SHCNF_PATH;\r
- fc.dwItem1 = (DWORD)fpn;\r
- fc.dwItem2 = 0;\r
- fc.dwAttributes = attribs;\r
- yfsd_U32sToWinFileTime(mtime,&fc.ftModified);\r
- fc.nFileSize = objSize;\r
-\r
- vol->shellFunction(&fc);\r
- RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
- //yfsd_ShellDirectoryChanged(vol,fpn);\r
- }\r
-\r
+
+ 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;
}
CONST FILETIME *pLastAccess,
CONST FILETIME *pLastWrite )
{
- WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
- int nameExists = 0;\r
+ WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
+ int nameExists = 0;
int result = FALSE;
- yfsd_Volume *vol = NULL;\r
- DWORD attribs = 0;\r
- DWORD objSize = 0;\r
- DWORD mtime[2];\r
-\r
- \r
+ yfsd_Volume *vol = NULL;
+ DWORD attribs = 0;
+ DWORD objSize = 0;
+ DWORD mtime[2];
+
+
RETAILMSG (MSGSTATE, (L"YAFFS::SetFileTime\r\n"));
if(!pFile || !pFile->obj)
yfsd_LockYAFFS();
- if(pCreation) \r
- {\r
- yfsd_WinFileTimeToU32s(pCreation,pFile->obj->win_ctime);\r
- pFile->obj->dirty = 1;\r
+ if(pCreation)
+ {
+ yfsd_WinFileTimeToU32s(pCreation,pFile->obj->win_ctime);
+ pFile->obj->dirty = 1;
}
- if(pLastAccess)\r
- {\r
- yfsd_WinFileTimeToU32s(pLastAccess,pFile->obj->win_atime);\r
- pFile->obj->dirty = 1;\r
+ if(pLastAccess)
+ {
+ yfsd_WinFileTimeToU32s(pLastAccess,pFile->obj->win_atime);
+ pFile->obj->dirty = 1;
}
- if(pLastWrite)\r
- {\r
- yfsd_WinFileTimeToU32s(pLastWrite,pFile->obj->win_mtime);\r
+ if(pLastWrite)
+ {
+ yfsd_WinFileTimeToU32s(pLastWrite,pFile->obj->win_mtime);
pFile->obj->dirty = 1;
}
if(pCreation || pLastAccess || pLastWrite)
{
- result = yaffs_FlushFile(pFile->obj);
- }
-\r
- if(result)\r
- {
- attribs = yfsd_GetObjectWinAttributes(pFile->obj);\r
- objSize = yaffs_GetObjectFileLength(pFile->obj);\r
- mtime[0] = pFile->obj->win_mtime[0];\r
- mtime[1] = pFile->obj->win_mtime[1];\r
- if(pFile->fullName)\r
- {\r
- wcscpy(fpn,pFile->fullName);\r
- nameExists = 1;\r
- }\r
- vol = pFile->myVolume;\r
- }\r
-\r
+ 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)\r
- {\r
- FILECHANGEINFO fc;\r
- \r
- fc.cbSize = sizeof(FILECHANGEINFO);\r
- fc.wEventId = SHCNE_UPDATEITEM;\r
- fc.uFlags = SHCNF_PATH;\r
- fc.dwItem1 = (DWORD)fpn;\r
- fc.dwItem2 = 0;\r
- fc.dwAttributes = attribs;\r
- yfsd_U32sToWinFileTime(mtime,&fc.ftModified);\r
- fc.nFileSize = objSize;\r
-\r
- vol->shellFunction(&fc);\r
- RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
- //yfsd_ShellDirectoryChanged(vol,fpn);\r
- }\r
+ 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;
}
PFILE pFile )
{
- WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
- int nameExists = 0;\r
- yfsd_Volume *vol = NULL;\r
- DWORD attribs = 0;\r
- DWORD objSize = 0;\r
- DWORD mtime[2];\r
+ 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;
{
retVal = TRUE;
}
- if(retVal)\r
- {\r
- attribs = yfsd_GetObjectWinAttributes(pFile->obj);\r
- objSize = yaffs_GetObjectFileLength(pFile->obj);\r
- mtime[0] = pFile->obj->win_mtime[0];\r
- mtime[1] = pFile->obj->win_mtime[1];\r
- if(pFile->fullName)\r
- {\r
- wcscpy(fpn,pFile->fullName);\r
- nameExists = 1;\r
- }\r
- vol = pFile->myVolume;\r
- }\r
-\r
-\r
- yfsd_UnlockYAFFS();\r
-\r
- if(nameExists && retVal && vol && vol->shellFunction)\r
- {\r
- FILECHANGEINFO fc;\r
- \r
- fc.cbSize = sizeof(FILECHANGEINFO);\r
- fc.wEventId = SHCNE_UPDATEITEM;\r
- fc.uFlags = SHCNF_PATH;\r
- fc.dwItem1 = (DWORD)fpn;\r
- fc.dwItem2 = 0;\r
- fc.dwAttributes = attribs;\r
- yfsd_U32sToWinFileTime(mtime,&fc.ftModified);\r
- fc.nFileSize = objSize;\r
-\r
- vol->shellFunction(&fc);\r
- RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
- //yfsd_ShellDirectoryChanged(vol,fpn);\r
- }\r
+ 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)));
yfsd_Volume *vol = NULL;
DWORD attribs = 0;
DWORD objSize = 0;
- DWORD mtime[2];\r
+ DWORD mtime[2];
RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile %X\r\n",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];\r
- mtime[1] = pFile->obj->win_mtime[1];\r
+ 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)
{