*** empty log message ***
authorcharles <charles>
Fri, 31 Jan 2003 00:52:53 +0000 (00:52 +0000)
committercharles <charles>
Fri, 31 Jan 2003 00:52:53 +0000 (00:52 +0000)
direct/dtest.c
direct/yaffsfs.c
wince/sources
wince/yaffsfsd.c
wince/ynandif.c
wince/ynandif.h
yaffs_guts.c

index 7360584906bccd30a3511a7aa47221da98308dda..7f6963823aebe1aa1540fe8b3a809fa0d58e682f 100644 (file)
@@ -81,6 +81,78 @@ void fill_disk_and_delete(char *path, int nfiles, int ncycles)
        }
 }
 
+
+void fill_files(char *path,int flags, int maxIterations,int siz)
+{
+       int i;
+       int j;
+       char str[50];
+       int h;
+       
+       i = 0;
+       
+       do{
+               sprintf(str,"%s/%d",path,i);
+               h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
+               yaffs_close(h);
+
+               if(h >= 0)
+               {
+                       for(j = 0; j < siz; j++)
+                       {
+                               yaffs_write(h,str,1);
+                       }
+               }
+               
+               if( flags & 1)
+               {
+                       yaffs_unlink(str);
+               }
+               i++;
+       } while(h >= 0 && i < maxIterations);
+       
+       if(flags & 2)
+       {
+               i = 0;
+               do{
+                       sprintf(str,"%s/%d",path,i);
+                       printf("unlink %s\n",str);
+                       i++;
+               } while(yaffs_unlink(str) >= 0);
+       }
+}
+
+void leave_unlinked_file(char *path,int maxIterations,int siz)
+{
+       int i;
+       char str[50];
+       int h;
+       
+       i = 0;
+       
+       do{
+               sprintf(str,"%s/%d",path,i);
+               printf("create %s\n",str);
+               h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE);
+               if(h >= 0)
+               {
+                       yaffs_unlink(str);
+               }
+               i++;
+       } while(h < 0 && i < maxIterations);
+       
+       if(h >= 0)
+       {
+               for(i = 0; i < siz; i++)
+               {
+                       yaffs_write(h,str,1);
+               }
+       }
+       
+       printf("Leaving file %s open\n",str);
+
+}
+
 void dumpDirFollow(const char *dname)
 {
        yaffs_DIR *d;
@@ -212,9 +284,18 @@ int main(int argc, char *argv[])
        yaffs_StartUp();
        
        yaffs_mount("/boot");
+       yaffs_mount("/data");
+       yaffs_mount("/flash");
        
        printf("\nDirectory look-up of /boot\n");
        dumpDir("/boot");
+       printf("\nDirectory look-up of /data\n");
+       dumpDir("/data");
+       printf("\nDirectory look-up of /flash\n");
+       dumpDir("/flash");
+
+       leave_unlinked_file("/flash",20000,0);
+       leave_unlinked_file("/data",20000,0);
 
        f = yaffs_open("/boot/b1", O_RDONLY,0);
        
@@ -402,6 +483,22 @@ int main(int argc, char *argv[])
        fill_disk_and_delete("/boot",20,20);
        
        yaffs_DumpDevStruct("/boot");
+       
+       fill_files("/boot",1,10000,0);
+       fill_files("/boot",1,10000,5000);
+       fill_files("/boot",2,10000,0);
+       fill_files("/boot",2,10000,5000);
+       
+       leave_unlinked_file("/data",20000,0);
+       leave_unlinked_file("/data",20000,5000);
+       leave_unlinked_file("/data",20000,5000);
+       leave_unlinked_file("/data",20000,5000);
+       leave_unlinked_file("/data",20000,5000);
+       leave_unlinked_file("/data",20000,5000);
+       
+       yaffs_DumpDevStruct("/boot");
+       yaffs_DumpDevStruct("/data");
+       
                
                
        return 0;
index d3eae30e1969d664d96b5923a14887677917536f..8f2f06e82ff7f0cefc71a645fa3a21ee84d528ca 100644 (file)
@@ -25,7 +25,7 @@
 #endif
 
 
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.1 2003-01-21 03:32:17 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.2 2003-01-31 00:57:35 charles Exp $";
 
 // configurationList is the list of devices that are supported
 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
@@ -424,7 +424,13 @@ int yaffs_open(const char *path, int oflag, int mode)
                {
                        // Let's see if we can create this file
                        dir = yaffsfs_FindDirectory(NULL,path,&name,0);
-                       obj = yaffs_MknodFile(dir,name,mode,0,0);       
+                       if(dir)
+                       {
+                               obj = yaffs_MknodFile(dir,name,mode,0,0);       
+                       }
+                       else
+                       {
+                       } yaffsfs_SetError(-ENOTDIR);
                }
                
                if(obj && !openDenied)
index 86ca4d2cbb2a0acc3aa9de359c86c8c5e9a95fbd..2706a6d56302da0667b869733427d8012a095439 100644 (file)
@@ -1,6 +1,25 @@
 !IF 0\r
 \r
-The YAFFS FSD for WinCE\r
+ YAFFS: Yet another FFS. A NAND-flash specific file system.\r
+; SOURCES: The FSD layer for the WinCE version of YAFFS.\r
+;\r
+; Copyright (C) 2002 Trimble Navigation Limited.  All rights reserved.\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
+; This program is distributed in the hope that it will be useful, but \r
+;\r
+; WITHOUT ANY WARRANTY; without even the implied warranty of \r
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General \r
+; Public License for more details. You should have received a copy of the\r
+; GNU General Public License along with this program; if not, write to the \r
+; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+;\r
+; $Id: sources,v 1.2 2003-01-31 00:52:53 charles Exp $\r
+\r
 \r
 \r
 !ENDIF\r
@@ -14,7 +33,7 @@ RELEASETYPE=PLATFORM
 TARGETNAME=YFSD\r
 TARGETTYPE=DYNLINK\r
 TARGETLIBS=                                             \\r
-    C:\WINCE300\PUBLIC\COMMON\OAK\lib\arm\Sa1100\ce\retail\fsdmgr.lib \\r
+    $(_PUBLICROOT)\COMMON\OAK\lib\arm\Sa1100\ce\retail\fsdmgr.lib \\r
     $(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib    \\r
 \r
 CDEFINES=  $(CDEFINES) -DCONFIG_YAFFS_WINCE -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM \r
index 7e202bfe17e60ab44912a09b6ec8b0af253b4830..e7ba9b16814b044fd35e9d525ef91a6dca7f4a2e 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  * YAFFS: Yet another FFS. A NAND-flash specific file system.\r
- * ynandif.c: NAND interface functions for the WinCE port of YAFFS.\r
+ * yaffsfsd.c: FSD interface funtions for WinCE.\r
  *\r
  * Copyright (C) 2002 Trimble Navigation Ltd.\r
  *\r
  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \r
  *\r
  * Acknowledgements:\r
- *  Various clean-ups and WinCE4 support by Steve Fogle\r
- * $Id: yaffsfsd.c,v 1.2 2003-01-14 23:15:41 charles Exp $\r
- */
-#include <windows.h>
-#include <extfile.h>
-#include <yaffs_guts.h>
+ *  Various clean-ups and WinCE4 support by Steve Fogle and Lynn Winter\r
+ * $Id: yaffsfsd.c,v 1.3 2003-01-31 00:52:53 charles Exp $\r
+ */\r
+#include <windows.h>\r
+#include <extfile.h>\r
+#include <yaffs_guts.h>\r
 #include <ynandif.h>\r
 //slf021104b begin\r
 #include <diskio.h>\r
-//slf021104b end
-
-#define MAX_WIN_FILE   200
-#define YFSD_NAME_LENGTH 128
-#define YFSD_FULL_PATH_NAME_SIZE 500
-
-\r
-#define YFSD_DISK_NAME L"Disk"
+//slf021104b end\r
+\r
+#define MAX_WIN_FILE   200\r
+#define YFSD_NAME_LENGTH 128\r
+#define YFSD_FULL_PATH_NAME_SIZE 500\r
+\r
+\r
+#define YFSD_DISK_NAME L"Disk"\r
 #define YFSD_BOOT_NAME L"Boot"\r
-
-#define PARTITION_START_NUMBER (1280)          
-
+\r
+#define PARTITION_START_NUMBER (1280)  \r
+\r
+\r
+// if this is defined the there will be a constant message box raised to display status\r
+//#define MSGBOX_DISPLAY\r
+       \r
+\r
 //#define MSGSTATE 1\r
-#define MSGSTATE 0
+#define MSGSTATE 0\r
 //#define DISABLE_BOOT_PARTITION\r
 //slf021105a begin\r
 // Define DO_PARTITION_TABLE to cause the partition table \r
 // information to be retrieved from the block driver.\r
+// Can define this in your sources file.\r
 //#define DO_PARTITION_TABLE\r
 // How many partitions the disk might have.  2 gives \r
 // space for the "Disk" and "Boot" partitions.\r
 #define MAXPARTITIONS (2)\r
-//slf021105a end
-
-//unsigned yaffs_traceMask=0xffffffff;
+//slf021105a end\r
+\r
+//unsigned yaffs_traceMask=0xffffffff;\r
 unsigned yaffs_traceMask=0;\r
-
-
-typedef struct
-{
-       yaffs_Device dev;
-       DWORD   hdsk;
-       DWORD    mgrVolume; // The volume id from the manager issed when we registered it - it is an HVOL
-       BOOL    isMounted;
-       BOOL    configured;
-//     DWORD   guard0[100];
-//     DWORD   guard1[100];
-       SHELLFILECHANGEFUNC_t shellFunction;
-       PWSTR volName;
-} yfsd_Volume;
-
-typedef struct 
-{
-       yaffs_Object *obj;
-       DWORD offset;
-       BOOL isopen;
-       BOOL dirty;
-       WCHAR *fullName;
-       yfsd_Volume *myVolume;
+\r
+\r
+typedef struct\r
+{\r
+       yaffs_Device dev;\r
+       DWORD   hdsk;\r
+       DWORD    mgrVolume; // The volume id from the manager issed when we registered it - it is an HVOL\r
+       BOOL    isMounted;\r
+       BOOL    configured;\r
+//     DWORD   guard0[100];\r
+//     DWORD   guard1[100];\r
+       SHELLFILECHANGEFUNC_t shellFunction;\r
+       PWSTR volName;\r
+} yfsd_Volume;\r
+\r
+typedef struct \r
+{\r
+       yaffs_Object *obj;\r
+       DWORD offset;\r
+       BOOL isopen;\r
+       BOOL dirty;\r
+       WCHAR *fullName;\r
+       yfsd_Volume *myVolume;\r
        BOOL writePermitted;\r
        BOOL readPermitted;\r
        BOOL shareRead;\r
        BOOL shareWrite;\r
-
-}      yfsd_WinFile;
-
-struct yfsd_FoundObjectStruct
-{
-  yaffs_Object *obj;
-  struct yfsd_FoundObjectStruct *next;
-};
-
-typedef struct yfsd_FoundObjectStruct yaffs_FoundObject;
-
-typedef struct 
-{
-       yaffs_Object *dir;
-       char pattern[YFSD_NAME_LENGTH+1];
-       yaffs_FoundObject *foundObjects;
-}      yfsd_WinFind;
-
-
-
-#define PSEARCH yfsd_WinFind*
-
-#define PVOLUME yfsd_Volume*
-#define PFILE   yfsd_WinFile*
-
-#define FSD_API        YFSD
-
-#include <fsdmgr.h>
-
+\r
+}      yfsd_WinFile;\r
+\r
+struct yfsd_FoundObjectStruct\r
+{\r
+  yaffs_Object *obj;\r
+  struct yfsd_FoundObjectStruct *next;\r
+};\r
+\r
+typedef struct yfsd_FoundObjectStruct yaffs_FoundObject;\r
+\r
+typedef struct \r
+{\r
+       yaffs_Object *dir;\r
+       char pattern[YFSD_NAME_LENGTH+1];\r
+       yaffs_FoundObject *foundObjects;\r
+}      yfsd_WinFind;\r
+\r
+\r
+\r
+#define PSEARCH yfsd_WinFind*\r
+\r
+#define PVOLUME yfsd_Volume*\r
+#define PFILE   yfsd_WinFile*\r
+\r
+#define FSD_API        YFSD\r
+\r
+#include <fsdmgr.h>\r
+\r
 //slf021105a begin\r
-//static yfsd_Volume disk_volume;
+//static yfsd_Volume disk_volume;\r
 //static yfsd_Volume boot_volume;\r
 static yfsd_Volume * disk_volumes[MAXPARTITIONS];\r
-//slf021105a end;
-
-static CRITICAL_SECTION yaffsLock;
-static CRITICAL_SECTION winFileLock;
-
-static int yaffsLockInited = 0;
-
-static yfsd_WinFile yfsd_winFile[MAX_WIN_FILE];
-
-#if 0
-static yfsd_SetGuards(void)
-{
-       int i;
-       for(i = 0; i < 100; i++)
-       {
-               yfsd_volume.guard0[i] = yfsd_volume.guard1[i] = i;
-       }
-}
-
-static void yfsd_CheckGuards(void)
-{
-       int i;
-       int found;
-       for(i = found = 0; i < 100 && !found; i++)
-       {
-                       if(yfsd_volume.guard0[i] != i)
-                       {
-                                       RETAILMSG (MSGSTATE, (L"YAFFS:: guard 0 %d brocken\r\n",i));
-                                       found = 1;
-                       }
-                       if(yfsd_volume.guard1[i] != i)
-                       {
-                                       RETAILMSG (MSGSTATE, (L"YAFFS:: guard 0 %d brocken\r\n",i));
-                                       found = 1;
-                       }
-       }
-}
-#endif
-
-void yfsd_LockWinFiles(void)
-{
-       //RETAILMSG (MSGSTATE, (L"YAFFS::LockWinfiles\r\n"));
-       EnterCriticalSection(&winFileLock);
-}
-void yfsd_UnlockWinFiles(void)
-{
-       //RETAILMSG (MSGSTATE, (L"YAFFS::UnlockWinFiles\r\n"));
-       LeaveCriticalSection(&winFileLock);
-}
-
-int lockwaits;
-
-void yfsd_LockYAFFS(void)
-{
-       //yfsd_CheckGuards();
-       //RETAILMSG (MSGSTATE, (L"YAFFS::LockYAFFS %d ",lockwaits));
-       lockwaits++;
-       EnterCriticalSection(&yaffsLock);
-       //RETAILMSG (MSGSTATE, (L" locked\r\n"));
-}
-void yfsd_UnlockYAFFS(void)
-{
-       //yfsd_CheckGuards();
-       //RETAILMSG (MSGSTATE, (L"YAFFS::UnLockYAFFS "));
-       LeaveCriticalSection(&yaffsLock);
-       lockwaits--;
-       //RETAILMSG (MSGSTATE, (L" unlocked\r\n"));
-}
-
-
-void yfsd_InitialiseWinFiles(void)
-{
-       int i;
-       
-       RETAILMSG (MSGSTATE, (L"YAFFS::InitWinFiles\r\n"));
-
-       InitializeCriticalSection(&winFileLock);
-
-       yfsd_LockWinFiles();
-       for(i = 0; i < MAX_WIN_FILE; i++)
-       {
-                       yfsd_winFile[i].isopen = 0;
-       }
-       yfsd_UnlockWinFiles();
-}
-
-yfsd_WinFile * yfsd_GetWinFile(void)
-{
-       int i;
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetWinFiles\r\n"));
-
-       yfsd_LockWinFiles();
-
-       for(i = 0; i < MAX_WIN_FILE; i++)
-       {
-               if(!yfsd_winFile[i].isopen)
-               {
-                       yfsd_winFile[i].isopen = 1;
+//slf021105a end;\r
+\r
+static CRITICAL_SECTION yaffsLock;\r
+static CRITICAL_SECTION winFileLock;\r
+\r
+static int yaffsLockInited = 0;\r
+\r
+static yfsd_WinFile yfsd_winFile[MAX_WIN_FILE];\r
+\r
+#if 0\r
+static yfsd_SetGuards(void)\r
+{\r
+       int i;\r
+       for(i = 0; i < 100; i++)\r
+       {\r
+               yfsd_volume.guard0[i] = yfsd_volume.guard1[i] = i;\r
+       }\r
+}\r
+\r
+static void yfsd_CheckGuards(void)\r
+{\r
+       int i;\r
+       int found;\r
+       for(i = found = 0; i < 100 && !found; i++)\r
+       {\r
+                       if(yfsd_volume.guard0[i] != i)\r
+                       {\r
+                                       RETAILMSG (MSGSTATE, (L"YAFFS:: guard 0 %d brocken\r\n",i));\r
+                                       found = 1;\r
+                       }\r
+                       if(yfsd_volume.guard1[i] != i)\r
+                       {\r
+                                       RETAILMSG (MSGSTATE, (L"YAFFS:: guard 0 %d brocken\r\n",i));\r
+                                       found = 1;\r
+                       }\r
+       }\r
+}\r
+#endif\r
+\r
+\r
+#ifdef MSGBOX_DISPLAY\r
+DWORD WINAPI yfsd_MessageThread(LPVOID param)\r
+{\r
+    yaffs_Device *dev = (yaffs_Device *)param;\r
+    TCHAR dataBuffer[1000];\r
+    Sleep(10000);\r
+\r
+    // note : if the device gets free'd from under us, we will cause an exception in the loop\r
+    while (1)\r
+    {\r
+        wsprintf(dataBuffer, L"nShortOpCaches %i\r\n"\r
+                             L"nErasedBlocks %i\r\n"\r
+                             L"allocationBlock %i\r\n"\r
+                             L"allocationPage %i\r\n"\r
+                             L"garbageCollectionRequired %i\r\n"\r
+                             L"nRetiredBlocks %i\r\n"\r
+                             L"cacheHits %i\r\n"\r
+                             L"eccFixed %i\r\n"\r
+                             L"eccUnfixed %i\r\n"\r
+                             L"tagsEccFixed %i\r\n"\r
+                             L"tagsEccUnfixed %i\r\n",\r
+                             dev->nShortOpCaches, \r
+                             dev->nErasedBlocks,\r
+                             dev->allocationBlock,\r
+                             dev->allocationPage,\r
+                             dev->garbageCollectionRequired,\r
+                             dev->nRetiredBlocks,\r
+                             dev->cacheHits,\r
+                             dev->eccFixed,\r
+                             dev->eccUnfixed,\r
+                             dev->tagsEccFixed,\r
+                             dev->tagsEccUnfixed);\r
+\r
+        MessageBox(NULL,\r
+                   dataBuffer,\r
+                   L"YAFFS PROC INFO",\r
+                   MB_OK);\r
+        Sleep(1);\r
+    }\r
+}\r
+#endif\r
+\r
+void yfsd_LockWinFiles(void)\r
+{\r
+       //RETAILMSG (MSGSTATE, (L"YAFFS::LockWinfiles\r\n"));\r
+       EnterCriticalSection(&winFileLock);\r
+}\r
+void yfsd_UnlockWinFiles(void)\r
+{\r
+       //RETAILMSG (MSGSTATE, (L"YAFFS::UnlockWinFiles\r\n"));\r
+       LeaveCriticalSection(&winFileLock);\r
+}\r
+\r
+int lockwaits;\r
+\r
+void yfsd_LockYAFFS(void)\r
+{\r
+       //yfsd_CheckGuards();\r
+       //RETAILMSG (MSGSTATE, (L"YAFFS::LockYAFFS %d ",lockwaits));\r
+       lockwaits++;\r
+       EnterCriticalSection(&yaffsLock);\r
+       //RETAILMSG (MSGSTATE, (L" locked\r\n"));\r
+}\r
+void yfsd_UnlockYAFFS(void)\r
+{\r
+       //yfsd_CheckGuards();\r
+       //RETAILMSG (MSGSTATE, (L"YAFFS::UnLockYAFFS "));\r
+       LeaveCriticalSection(&yaffsLock);\r
+       lockwaits--;\r
+       //RETAILMSG (MSGSTATE, (L" unlocked\r\n"));\r
+}\r
+\r
+\r
+void yfsd_InitialiseWinFiles(void)\r
+{\r
+       int i;\r
+       \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::InitWinFiles\r\n"));\r
+\r
+       InitializeCriticalSection(&winFileLock);\r
+\r
+       yfsd_LockWinFiles();\r
+       for(i = 0; i < MAX_WIN_FILE; i++)\r
+       {\r
+                       yfsd_winFile[i].isopen = 0;\r
+       }\r
+       yfsd_UnlockWinFiles();\r
+}\r
+\r
+yfsd_WinFile * yfsd_GetWinFile(void)\r
+{\r
+       int i;\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetWinFiles\r\n"));\r
+\r
+       yfsd_LockWinFiles();\r
+\r
+       for(i = 0; i < MAX_WIN_FILE; i++)\r
+       {\r
+               if(!yfsd_winFile[i].isopen)\r
+               {\r
+                       yfsd_winFile[i].isopen = 1;\r
                        yfsd_winFile[i].writePermitted = 0;\r
                        yfsd_winFile[i].readPermitted = 0;\r
                        yfsd_winFile[i].shareRead = 0;\r
                        yfsd_winFile[i].shareWrite = 0;\r
-                       yfsd_winFile[i].dirty = 0;
-                       yfsd_winFile[i].fullName = NULL;
-                       yfsd_winFile[i].obj = NULL;
-
-                       yfsd_UnlockWinFiles();
-                       return &yfsd_winFile[i];
-               }
-       }
-
-       yfsd_UnlockWinFiles();
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetWinFiles did not find a handle. Too many open.\r\n"));
-
-       return NULL;
-}
-
-void yfsd_PutWinFile(yfsd_WinFile *f)
-{
-       RETAILMSG (MSGSTATE, (L"YAFFS::PutWinFile\r\n"));
-       yfsd_LockWinFiles();
-       f->isopen = 0;
-       f->obj = NULL;
-       if(f->fullName)
-       {
-               free(f->fullName);
-               f->fullName = NULL;
-       }
-
-       yfsd_UnlockWinFiles();
-}
-
-
-
-void yfsd_FlushAllFiles(void)
-{
-       int i;
-       RETAILMSG (MSGSTATE, (L"YAFFS::FlushAllFiles\r\n"));
-
-       yfsd_LockYAFFS();
-       yfsd_LockWinFiles();
-       for(i = 0; i < MAX_WIN_FILE; i++)
-       {
-               if(yfsd_winFile[i].isopen &&
-                  yfsd_winFile[i].obj)
-               {
-                       yaffs_FlushFile(yfsd_winFile[i].obj,1);
-               }
-       }
-       yfsd_UnlockWinFiles();
-       yfsd_UnlockYAFFS();
+                       yfsd_winFile[i].dirty = 0;\r
+                       yfsd_winFile[i].fullName = NULL;\r
+                       yfsd_winFile[i].obj = NULL;\r
+\r
+                       yfsd_UnlockWinFiles();\r
+                       return &yfsd_winFile[i];\r
+               }\r
+       }\r
+\r
+       yfsd_UnlockWinFiles();\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetWinFiles did not find a handle. Too many open.\r\n"));\r
+\r
+       return NULL;\r
+}\r
+\r
+void yfsd_PutWinFile(yfsd_WinFile *f)\r
+{\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::PutWinFile\r\n"));\r
+       yfsd_LockWinFiles();\r
+       f->isopen = 0;\r
+       f->obj = NULL;\r
+       if(f->fullName)\r
+       {\r
+               free(f->fullName);\r
+               f->fullName = NULL;\r
+       }\r
+\r
+       yfsd_UnlockWinFiles();\r
+}\r
+\r
+\r
+\r
+void yfsd_FlushAllFiles(void)\r
+{\r
+       int i;\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FlushAllFiles\r\n"));\r
+\r
+       yfsd_LockYAFFS();\r
+       yfsd_LockWinFiles();\r
+       for(i = 0; i < MAX_WIN_FILE; i++)\r
+       {\r
+               if(yfsd_winFile[i].isopen &&\r
+                  yfsd_winFile[i].obj)\r
+               {\r
+                       yaffs_FlushFile(yfsd_winFile[i].obj,1);\r
+               }\r
+       }\r
+       yfsd_UnlockWinFiles();\r
+       yfsd_UnlockYAFFS();\r
 }\r
 \r
 //slf021104d begin\r
@@ -290,541 +339,569 @@ BOOL yfsd_FilesOpen(void)
        yfsd_UnlockWinFiles();\r
        return rval;\r
 }\r
-//slf021104d end
-
-PWSTR yfsd_FullPathName(PVOLUME vol, PWSTR fpn,int slength,PCWSTR pathName)
-{
-
+//slf021104d end\r
+\r
+PWSTR yfsd_FullPathName(PVOLUME vol, PWSTR fpn,int slength,PCWSTR pathName)\r
+{\r
+\r
        // todo check for bounds\r
        //slf021104b begin\r
-       //volName already has the initial backslash if it needs it.
+       //volName already has the initial backslash if it needs it.\r
        //wcscpy(fpn,L"\\");\r
-       //wcscat(fpn,vol->volName);
+       //wcscat(fpn,vol->volName);\r
        wcscpy(fpn,vol->volName);\r
        //slf021104b end\r
-       if(pathName[0] != '\\')
-       {
-               wcscat(fpn,L"\\");
-       }
-       wcscat(fpn,pathName);
-
-       return fpn;
-
-}
-
-
-// FILETIME is a 64-bit value as 100-nanosecond intervals since January 1, 1601.
-
-void yfsd_U32sToWinFileTime(__u32 target[2], FILETIME *wft)
-{
-       
-       wft->dwLowDateTime = target[0];
-       wft->dwHighDateTime = target[1];
-
-}
-
-void yfsd_NullWinFileTime(FILETIME *wft)
-{
-       wft->dwLowDateTime = 0;
-       wft->dwHighDateTime = 0;
-}
-
-void yfsd_WinFileTimeToU32s(const FILETIME *wft, __u32 target[2])
-{
-       target[0] = wft->dwLowDateTime;
-       target[1] = wft->dwHighDateTime;
-}
-
-void  yfsd_WinFileTimeNow(__u32 target[2])
-{
-       SYSTEMTIME st;
-       FILETIME ft;
-
-       GetSystemTime(&st);
-       SystemTimeToFileTime(&st,&ft);
-       yfsd_WinFileTimeToU32s(&ft,target);
-}
-
-// Cut down the name to the parent directory, then inform the shell of
-// a change to the directory.
-void yfsd_ShellDirectoryChanged(PVOLUME pVolume, PWSTR fullPathName)
-{
-       WCHAR str[500];
-       int i;
-       wcscpy(str,fullPathName);
-
-       i = wcslen(str) - 1;
-       
-       if(i > 0)
-       {
-               str[i] = 0;
-               i--;
-       }
-
-       // Curveball if the name is a directory (ie. we're doing an update of
-       // a directory because we added a directory item). , then it might end in a \
-       // which we must toss first
-       if(i >= 0 && (str[i] == '\\' || str[i] == '/'))
-       {
-               str[i] = 0;
-               i--;
-       }
-
-       // Ok, now strip back...
-
-       while(i >= 0 && str[i] != '\\' && str[i] != '/')
-       {
-               str[i] = 0;
-               i--;
-       }
-
-       if(pVolume->shellFunction)
-       {
-                       FILECHANGEINFO fc;
-                       
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = SHCNE_UPDATEDIR;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)str;
-                       fc.dwItem2 = 0;
-                       fc.dwAttributes = 0;
-                       yfsd_NullWinFileTime(&fc.ftModified);
-                       fc.nFileSize = 0;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS:: directory changed %s\r\n",str));
-
-       }
-
-
-}
-
-
-// Minimal name test for now
-BOOL yfsd_NameIsValid (const char *name)
-{
-       int length = strlen(name);
-
-       return (length > 0 && length <= YFSD_NAME_LENGTH);
-
-}
-
-// File attributes:
-// Wince understands the following attributes of any use to YAFFS:
-//  
-//   ARCHIVE
-//   HIDDEN
-//   READONLY
-//   SYSTEM
-//   TEMPORARY
-//
-//      Also, FILE_ATTRIBUTE_DIRECTORY is used to mark directories.
-//
-//   It also understands NORMAL. If no other flag is set, then set NORMAL.
-//   If any of the above are set, then NORMAL must **not** be set.
-//      Ignore this and the WinCE Explorer barfs the file.
-//
-//
-// 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;
-
-}
-DWORD yfsd_GetObjectWinAttributes(yaffs_Object *obj)
-{
-
-               DWORD result;
-               
-               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(result & ~FILE_ATTRIBUTE_NORMAL)
-               { 
-                       result &= ~FILE_ATTRIBUTE_NORMAL;
-               }
-               else 
-               {
-                       result = FILE_ATTRIBUTE_NORMAL;
-               }
-
-
-               return result;
-}
-
-
-
-/*
-*      Runs over input until a '\' is found, or '\0' is found, or outSize - 1 is
-*      reached.  Characters are copied from input into output until the above stop
-*      condition is reached - output is then given a '\0'.  output must be at least
-*      as large as outSize
-*/
-static int parseToNextSlash(const unsigned short *input, char *output, int outSize)
-{
-       int counter = 0;
-       char *t = output;
-       /* strip any starting \'s */
-       //RETAILMSG(1, (L"\r\nParsing.. "));
-       while (*input == '\\' || *input == '/') input++, counter++;
-
-       for (; counter < outSize - 1; counter++)
-       {
-               if (*input == '\0' ||
-                       ((*input == '\\' || *input == '/') && input[1] == '\0'))   // special case: if the string ends in a '\', then toss the '\'
-               {
-                       counter = -1;   // break & tell people we've run to the end
-                       break;
-               }
-               if (*input == '\\' || *input == '/')
-                       break;
-               //RETAILMSG(1, (L"%c", *input));
-               *output = (char) (*input);
-               input++;
-               output++;
-       }
-       *output++ = '\0';
-       *output  = '\0';
-//     RETAILMSG(1, (L"\r\nOut %a\r\n", t));
-       
-       return counter;
-}
-
-/*
-*      Since the notion of paths as WinCE sees them and as YAFFS sees them
-*      is different, we needed a helper function to search from the root of
-*      device along the string in path.  The processed pointer is set to where
-*      abouts in the string the function was able to search up to.
-*/
-yaffs_Object *yfsd_FindDirectoryByWinPath(yaffs_Device *device, const wchar_t *path, char *processed, int length)
-{
-       // a buffer to keep the current chunk of path we're talking about it
-       char pathChunk[255];
-       int chunkSize;
-       int counter;
-       // the current object we are at
-       yaffs_Object *current;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindByWinPath (%s) : ", path));
-       // start at the root of this device
-       current = yaffs_Root(device);
-       *processed = '\0';
-
-       do
-       {
-       //      parse chunks until we run out
-               chunkSize = parseToNextSlash(path, pathChunk, 255);
-//             RETAILMSG(1, (L"Chunk %a\r\n", pathChunk));
-               if (chunkSize == -1)
-                       break;
-       //      move the path pointer along
-               path += chunkSize;
-       //      try and find the next yaffs object by chunkname 
-               current = yaffs_FindObjectByName(current, pathChunk);
-               if (current == 0)
-               {
-                       processed[0] = '\0';
-                       return 0;
-               }
-       } while (1);
-
-       for (counter = 0; counter < length; counter++)
-       {
-               // Get the rest of the string
-               processed[counter] = pathChunk[counter];
-               if (pathChunk[counter] == '\0')
-                       break;
-       }
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindDirectoryByWinPath parent:%X name:%a\r\n", current,processed));
-
-       return current;
-}
-
-
-yaffs_Object *yfsd_FindObjectByWinPath(yaffs_Device *dev, PCWSTR pwsFileName )
-{
-       yaffs_Object *obj = NULL;
-       yaffs_Object *parent = NULL;
-       char name[YFSD_NAME_LENGTH+1];
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindObjByWinPath\r\n"));
-
-       parent = yfsd_FindDirectoryByWinPath(dev,pwsFileName,name,YFSD_NAME_LENGTH);
-
-       if(parent && yfsd_NameIsValid(name))
-       {
-               obj = yaffs_FindObjectByName(parent,name);
-       }
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindObjectByWinPath parent:%X obj:%X\r\n", parent,obj));
-
-       return obj;
-}
-
-BOOL YFSD_InitVolume(HDSK hdsk, yfsd_Volume *vol, int startBlock, int endBlock, PWSTR volName)
-{
-       //slf021104b Begin\r
-       WCHAR szName[MAX_PATH];\r
-    DWORD dwAvail;\r
-       //slf021104b end\r
-       RETAILMSG (MSGSTATE, (L"YAFFS::InitVolume\r\n"));\r
-       //slf021104b Begin filled in later.
-       //vol->volName = volName;\r
-       //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;\r
-       vol->dev.nShortOpCaches = 10; // a nice number of caches.
-
-       // nBlocks is set the total size of the disk, not the partition
-//     vol->dev.nBlocks = endBlock - startBlock + 1;
-
-//     qnand_EraseAllBlocks(&vol->dev);
-
-       yaffs_GutsInitialise(&vol->dev);
-       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));
-
-
-#if 0
-       for(i = vol->dev.startBlock; i <= vol->dev.endBlock; i++)
-       {
-                       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));
-
-#endif
-
-       yfsd_UnlockYAFFS();
-
-       vol->isMounted = 1;
-       \r
-       //slf021104b begin
-       //vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,vol->volName,vol);\r
-       // If the caller passed a volume name use it.\r
-       if (volName[0])\r
-        wcscpy( szName, volName);\r
-#if WINCEOSVER >= 400\r
-       // The user passed an empty volume name.  On CE 4.xx try to get\r
-       // if from the block driver (which got it from the registry).\r
-       else if (!FSDMGR_DiskIoControl(hdsk, DISK_IOCTL_GETNAME, NULL, 0, (LPVOID)szName, sizeof(szName), &dwAvail, NULL)) \r
-#else\r
-       else\r
-#endif\r
-       { \r
-               // Didn't get a volume name so use "Disk" by default.\r
-        wcscpy( szName, YFSD_DISK_NAME);\r
-    }    \r
-       vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,szName,vol);\r
-       //slf021104b end
-
-       if(vol->mgrVolume)
+       if(pathName[0] != '\\')\r
        {\r
-               //slf021104b Begin\r
-               // Get some space for the volume name.
-        vol->volName = malloc( MAX_PATH * sizeof(WCHAR));\r
-        if (vol->volName) \r
-               {\r
-#if WINCEOSVER >= 400\r
-                       // Get the name we were really mounted under.\r
-            FSDMGR_GetVolumeName(vol->mgrVolume, vol->volName, MAX_PATH);\r
+               wcscat(fpn,L"\\");\r
+       }\r
+       wcscat(fpn,pathName);\r
 \r
-                       // If we got mounted as root then throw away the backslash\r
-                       // so we won't get a double backslash when volName is\r
-                       // prepended to the path in the full path name calculation\r
-                       // that is used for shell callbacks.\r
-                       if (0 == wcscmp(vol->volName,L"\\"))\r
-                               vol->volName[0] = 0;\r
-#else\r
-                       // Use the name we asked to be mounted under for\r
-                       // our root.  \r
-                       wcscpy(vol->volName,L"\\");\r
-                       wcscat(vol->volName, szName);\r
-#endif\r
-               }\r
-               //slf021104b end\r
-               return TRUE;
-       }
-       else
-       {
-               vol->isMounted = 0;
-               SetLastError(ERROR_OUTOFMEMORY);
-               return FALSE;
-       }       
-}
-
-
-BOOL YFSD_MountDisk(HDSK hdsk)
-{
-//slf021105a begin\r
-#ifdef DO_PARTITION_TABLE\r
-       ynandif_partition PartTable[MAXPARTITIONS];\r
-       DWORD dwAvail;\r
+       return fpn;\r
+\r
+}\r
+\r
+\r
+// FILETIME is a 64-bit value as 100-nanosecond intervals since January 1, 1601.\r
+\r
+void yfsd_U32sToWinFileTime(__u32 target[2], FILETIME *wft)\r
+{\r
+       \r
+       wft->dwLowDateTime = target[0];\r
+       wft->dwHighDateTime = target[1];\r
+\r
+}\r
+\r
+void yfsd_NullWinFileTime(FILETIME *wft)\r
+{\r
+       wft->dwLowDateTime = 0;\r
+       wft->dwHighDateTime = 0;\r
+}\r
+\r
+void yfsd_WinFileTimeToU32s(const FILETIME *wft, __u32 target[2])\r
+{\r
+       target[0] = wft->dwLowDateTime;\r
+       target[1] = wft->dwHighDateTime;\r
+}\r
+\r
+void  yfsd_WinFileTimeNow(__u32 target[2])\r
+{\r
+       SYSTEMTIME st;\r
+       FILETIME ft;\r
+\r
+       GetSystemTime(&st);\r
+       SystemTimeToFileTime(&st,&ft);\r
+       yfsd_WinFileTimeToU32s(&ft,target);\r
+}\r
+\r
+// Cut down the name to the parent directory, then inform the shell of\r
+// a change to the directory.\r
+void yfsd_ShellDirectoryChanged(PVOLUME pVolume, PWSTR fullPathName)\r
+{\r
+       WCHAR str[500];\r
        int i;\r
-       BOOL rval = FALSE;\r
-#endif\r
-//slf021105a end\r
-       int deadBlox=0,emptyBlox=0,fullBlox=0,allocatingBlox=0,dirtyBlox=0;
-       //int i;
-       // Called to mount a disk.
-       // NB THis call might happen redundantly.
-       //
-       //
-       // If yaffs is not initialised, then call the 
-       // initialisation function
-       //
-       RETAILMSG (MSGSTATE, (L"YAFFS::MountDisk\r\n"));
-
-       if (!yaffsLockInited)
-       {
-               InitializeCriticalSection(&yaffsLock);
-               yfsd_InitialiseWinFiles();
-               yaffsLockInited = 1;
-       }
+       wcscpy(str,fullPathName);\r
 \r
-       //slf021105a begin\r
-       memset(disk_volumes,0,sizeof(disk_volumes));\r
-#ifdef DO_PARTITION_TABLE\r
-       memset(&PartTable,0,sizeof(PartTable));\r
-       // Call the block driver to get the partition table from it.\r
-    if (FSDMGR_DiskIoControl(hdsk, YNANDIF_GETPARTITIONS, NULL, 0, (LPVOID)&PartTable, sizeof(PartTable), &dwAvail, NULL)) \r
+       i = wcslen(str) - 1;\r
+       \r
+       if(i > 0)\r
        {\r
-               // Scan throught the table it return.\r
-               for (i=0; i<MAXPARTITIONS; i++)\r
-               {\r
-                       // At the very lease check that the end is later than the beginning\r
-                       // and don't let it start at 0.  \r
-                       // Probably could do more thorough checking but I trust the block\r
-                       // driver.\r
-                       if (PartTable[i].startBlock && (PartTable[i].endBlock > PartTable[i].startBlock))\r
-                       {\r
-                               // Found a partion.  Get a volume structure to hold it.\r
-                               disk_volumes[i] = malloc(sizeof(yfsd_Volume));\r
-                               if (disk_volumes[i])\r
-                               {\r
-                                       memset(disk_volumes[i],0,sizeof(yfsd_Volume));\r
-                                       // Go init the volume.  Note that if the block driver wants the\r
-                                       // name to come from the registry it will have returned an\r
-                                       // empty name string.\r
-                                       YFSD_InitVolume(hdsk,disk_volumes[i],PartTable[i].startBlock,PartTable[i].endBlock,PartTable[i].volName);\r
-                                       if (disk_volumes[i]->isMounted)\r
-                                               rval = TRUE; //Hey, we found at least on partition.\r
-                               }\r
-                       }\r
-               }\r
+               str[i] = 0;\r
+               i--;\r
        }\r
 \r
-       return rval;\r
-\r
-#else
-#ifdef DISABLE_BOOT_PARTITION
-       // Only want disk volume\r
-       disk_volumes[0] = malloc(sizeof(yfsd_Volume));\r
-       if (disk_volumes[0])\r
+       // Curveball if the name is a directory (ie. we're doing an update of\r
+       // a directory because we added a directory item). , then it might end in a \\r
+       // which we must toss first\r
+       if(i >= 0 && (str[i] == '\\' || str[i] == '/'))\r
        {\r
-               memset(disk_volumes[0],0,sizeof(yfsd_Volume));\r
-               YFSD_InitVolume(hdsk, disk_volumes[0], 1, -1, YFSD_DISK_NAME);\r
-\r
-               if(disk_volumes[0].isMounted)\r
-               {\r
-                       return TRUE;\r
-               }\r
+               str[i] = 0;\r
+               i--;\r
        }\r
-       if (disk_volumes[0])\r
+\r
+       // Ok, now strip back...\r
+\r
+       while(i >= 0 && str[i] != '\\' && str[i] != '/')\r
        {\r
-               free(disk_volumes[0];\r
-               disk_volumes[0] = NULL;\r
+               str[i] = 0;\r
+               i--;\r
        }\r
-#else\r
-       // Want both boot and disk\r
-       disk_volumes[0] = malloc(sizeof(yfsd_Volume));\r
-       disk_volumes[1] = malloc(sizeof(yfsd_Volume));\r
-       if (disk_volumes[0] && disk_volumes[1])\r
+\r
+       if(pVolume->shellFunction)\r
        {\r
-               memset(disk_volumes[0],0,sizeof(yfsd_Volume));\r
-               memset(disk_volumes[1],0,sizeof(yfsd_Volume));\r
-               YFSD_InitVolume(hdsk, disk_volumes[0], PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME);\r
-               YFSD_InitVolume(hdsk, disk_volumes[1], 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME);\r
+                       FILECHANGEINFO fc;\r
+                       \r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = SHCNE_UPDATEDIR;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)str;\r
+                       fc.dwItem2 = 0;\r
+                       fc.dwAttributes = 0;\r
+                       yfsd_NullWinFileTime(&fc.ftModified);\r
+                       fc.nFileSize = 0;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS:: directory changed %s\r\n",str));\r
 \r
-               if(disk_volumes[0]->isMounted && disk_volumes[1]->isMounted)\r
-               {\r
-                       return TRUE;\r
-               }\r
        }\r
 \r
-       // If we got this far something went wrong.  Make sure to \r
-       // free any memory we allocated.\r
+\r
+}\r
+\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
+}\r
+\r
+// File attributes:\r
+// Wince understands the following attributes of any use to YAFFS:\r
+//  \r
+//   ARCHIVE\r
+//   HIDDEN\r
+//   READONLY\r
+//   SYSTEM\r
+//   TEMPORARY\r
+//\r
+//      Also, FILE_ATTRIBUTE_DIRECTORY is used to mark directories.\r
+//\r
+//   It also understands NORMAL. If no other flag is set, then set NORMAL.\r
+//   If any of the above are set, then NORMAL must **not** be set.\r
+//      Ignore this and the WinCE Explorer barfs the file.\r
+//\r
+//\r
+// in addition, GetAttributes also returns FILE_ATTRIBUTE_DIRECTORY\r
+\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
+}\r
+DWORD yfsd_GetObjectWinAttributes(yaffs_Object *obj)\r
+{\r
+\r
+               DWORD result;\r
+               \r
+               result = obj->st_mode & \r
+                                       (FILE_ATTRIBUTE_READONLY | \r
+                                        FILE_ATTRIBUTE_ARCHIVE | \r
+                                        FILE_ATTRIBUTE_HIDDEN |\r
+                                        FILE_ATTRIBUTE_SYSTEM);\r
+\r
+               if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) result |= FILE_ATTRIBUTE_DIRECTORY;\r
+\r
+               if(result & ~FILE_ATTRIBUTE_NORMAL)\r
+               { \r
+                       result &= ~FILE_ATTRIBUTE_NORMAL;\r
+               }\r
+               else \r
+               {\r
+                       result = FILE_ATTRIBUTE_NORMAL;\r
+               }\r
+\r
+\r
+               return result;\r
+}\r
+\r
+\r
+\r
+/*\r
+*      Runs over input until a '\' is found, or '\0' is found, or outSize - 1 is\r
+*      reached.  Characters are copied from input into output until the above stop\r
+*      condition is reached - output is then given a '\0'.  output must be at least\r
+*      as large as outSize\r
+*/\r
+static int parseToNextSlash(const unsigned short *input, char *output, int outSize)\r
+{\r
+       int counter = 0;\r
+       char *t = output;\r
+       /* strip any starting \'s */\r
+       //RETAILMSG(1, (L"\r\nParsing.. "));\r
+       while (*input == '\\' || *input == '/') input++, counter++;\r
+\r
+       for (; counter < outSize - 1; counter++)\r
+       {\r
+               if (*input == '\0' ||\r
+                       ((*input == '\\' || *input == '/') && input[1] == '\0'))   // special case: if the string ends in a '\', then toss the '\'\r
+               {\r
+                       counter = -1;   // break & tell people we've run to the end\r
+                       break;\r
+               }\r
+               if (*input == '\\' || *input == '/')\r
+                       break;\r
+               //RETAILMSG(1, (L"%c", *input));\r
+               *output = (char) (*input);\r
+               input++;\r
+               output++;\r
+       }\r
+       *output++ = '\0';\r
+       *output  = '\0';\r
+//     RETAILMSG(1, (L"\r\nOut %a\r\n", t));\r
+       \r
+       return counter;\r
+}\r
+\r
+/*\r
+*      Since the notion of paths as WinCE sees them and as YAFFS sees them\r
+*      is different, we needed a helper function to search from the root of\r
+*      device along the string in path.  The processed pointer is set to where\r
+*      abouts in the string the function was able to search up to.\r
+*/\r
+yaffs_Object *yfsd_FindDirectoryByWinPath(yaffs_Device *device, const wchar_t *path, char *processed, int length)\r
+{\r
+       // a buffer to keep the current chunk of path we're talking about it\r
+       char pathChunk[255];\r
+       int chunkSize;\r
+       int counter;\r
+       // the current object we are at\r
+       yaffs_Object *current;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindByWinPath (%s) : ", path));\r
+       // start at the root of this device\r
+       current = yaffs_Root(device);\r
+       *processed = '\0';\r
+\r
+       do\r
+       {\r
+       //      parse chunks until we run out\r
+               chunkSize = parseToNextSlash(path, pathChunk, 255);\r
+//             RETAILMSG(1, (L"Chunk %a\r\n", pathChunk));\r
+               if (chunkSize == -1)\r
+                       break;\r
+       //      move the path pointer along\r
+               path += chunkSize;\r
+       //      try and find the next yaffs object by chunkname \r
+               current = yaffs_FindObjectByName(current, pathChunk);\r
+               if (current == 0)\r
+               {\r
+                       processed[0] = '\0';\r
+                       return 0;\r
+               }\r
+       } while (1);\r
+\r
+       for (counter = 0; counter < length; counter++)\r
+       {\r
+               // Get the rest of the string\r
+               processed[counter] = pathChunk[counter];\r
+               if (pathChunk[counter] == '\0')\r
+                       break;\r
+       }\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindDirectoryByWinPath parent:%X name:%a\r\n", current,processed));\r
+\r
+       return current;\r
+}\r
+\r
+\r
+yaffs_Object *yfsd_FindObjectByWinPath(yaffs_Device *dev, PCWSTR pwsFileName )\r
+{\r
+       yaffs_Object *obj = NULL;\r
+       yaffs_Object *parent = NULL;\r
+       char name[YFSD_NAME_LENGTH+1];\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindObjByWinPath\r\n"));\r
+\r
+       parent = yfsd_FindDirectoryByWinPath(dev,pwsFileName,name,YFSD_NAME_LENGTH);\r
+\r
+       if(parent && yfsd_NameIsValid(name))\r
+       {\r
+               obj = yaffs_FindObjectByName(parent,name);\r
+       }\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindObjectByWinPath parent:%X obj:%X\r\n", parent,obj));\r
+\r
+       return obj;\r
+}\r
+\r
+BOOL YFSD_InitVolume(HDSK hdsk, yfsd_Volume *vol, int startBlock, int endBlock, PWSTR volName)\r
+{\r
+       //slf021104b Begin\r
+       WCHAR szName[MAX_PATH];\r
+    DWORD dwAvail;\r
+       //slf021104b end\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::InitVolume\r\n"));\r
+       //slf021104b Begin filled in later.\r
+       //vol->volName = volName;\r
+       //slf021104b end\r
+\r
+\r
+       yfsd_LockYAFFS();\r
+       \r
+       //slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+       // For Win'CE 4.0 and later pass the hdsk for use by the yandif layer.\r
+       vol->dev.genericDevice = (PVOID)hdsk;\r
+#endif\r
+       //slf021220a End Cleanup block driver interface\r
+\r
+       //Mount/initialise YAFFs here\r
+       //slf021127a begin check for error returns!\r
+       if (ynandif_InitialiseNAND(&vol->dev))  \r
+       {\r
+       //slf021127a end check for error returns!\r
+               vol->dev.writeChunkToNAND = ynandif_WriteChunkToNAND;\r
+               vol->dev.readChunkFromNAND = ynandif_ReadChunkFromNAND;\r
+               vol->dev.eraseBlockInNAND = ynandif_EraseBlockInNAND;\r
+               vol->dev.initialiseNAND = ynandif_InitialiseNAND;\r
+               vol->dev.startBlock = startBlock;\r
+               if (endBlock != -1)\r
+                       vol->dev.endBlock = endBlock;\r
+               vol->dev.nShortOpCaches = 10; // a nice number of caches.\r
+               vol->dev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;\r
+               vol->dev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK;\r
+\r
+\r
+               // nBlocks is set the total size of the disk, not the partition\r
+       //      vol->dev.nBlocks = endBlock - startBlock + 1;\r
+\r
+       //      qnand_EraseAllBlocks(&vol->dev);\r
+\r
+               //slf021127a begin check for error returns!\r
+               if (yaffs_GutsInitialise(&vol->dev))\r
+               {\r
+               //slf021127a end check for error returns!\r
+                       RETAILMSG(1, (L"YAFFS::Done yaffs_GutsInitialise\r\n"));\r
+\r
+                       RETAILMSG(1, (L"Blocks start %d end %d Group size %d bits %d\r\n",\r
+                                                       vol->dev.startBlock,vol->dev.endBlock,\r
+                                                       vol->dev.chunkGroupSize,vol->dev.chunkGroupBits));\r
+\r
+\r
+#if 0\r
+                       for(i = vol->dev.startBlock; i <= vol->dev.endBlock; i++)\r
+                       {\r
+                                       switch(vol->dev.blockInfo[i].blockState)\r
+                                       {\r
+                                               case YAFFS_BLOCK_STATE_DEAD:\r
+                               \r
+                                                       RETAILMSG(1, (L"YAFFS::Dead block %d\r\n",i));\r
+                                                       deadBlox++;\r
+                                                       break;\r
+                                               case YAFFS_BLOCK_STATE_EMPTY: emptyBlox++; break;\r
+                                               case YAFFS_BLOCK_STATE_FULL: fullBlox++; break;\r
+                                               case YAFFS_BLOCK_STATE_ALLOCATING: allocatingBlox++; break;\r
+                                               case YAFFS_BLOCK_STATE_DIRTY: dirtyBlox++; break;\r
+                                               default:\r
+                                                       RETAILMSG(1, (L"YAFFS::Block %d has goofus state %d\r\n",i,vol->dev.blockInfo[i].blockState));\r
+                                                       break;\r
+                                       }\r
+                       }\r
+\r
+                       RETAILMSG(1, (L"Blocks dead  %d empty %d full %d allocating %d dirty %d\r\n",\r
+                                                       deadBlox,emptyBlox,fullBlox,allocatingBlox,dirtyBlox));\r
+\r
+#endif\r
+\r
+//slf021127a begin check for error returns!\r
+                       vol->isMounted = 1;\r
+               }\r
+       }\r
+//slf021127a begin check for error returns!\r
+       \r
+       yfsd_UnlockYAFFS();\r
+\r
+//slf021127a begin check for error returns!\r
+//     vol->isMounted = 1;\r
+//slf021127a begin check for error returns!\r
+       \r
+       //slf021104b begin\r
+       //vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,vol->volName,vol);\r
+       // If the caller passed a volume name use it.\r
+       if (volName[0])\r
+        wcscpy( szName, volName);\r
+#if WINCEOSVER >= 400\r
+       // The user passed an empty volume name.  On CE 4.xx try to get\r
+       // if from the block driver (which got it from the registry).\r
+       else if (!FSDMGR_DiskIoControl(hdsk, DISK_IOCTL_GETNAME, NULL, 0, (LPVOID)szName, sizeof(szName), &dwAvail, NULL)) \r
+#else\r
+       else\r
+#endif\r
+       { \r
+               // Didn't get a volume name so use "Disk" by default.\r
+        wcscpy( szName, YFSD_DISK_NAME);\r
+    }    \r
+       vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,szName,vol);\r
+       //slf021104b end\r
+\r
+       if(vol->mgrVolume)\r
+       {\r
+               //slf021104b Begin\r
+               // Get some space for the volume name.\r
+        vol->volName = malloc( MAX_PATH * sizeof(WCHAR));\r
+        if (vol->volName) \r
+               {\r
+#if WINCEOSVER >= 400\r
+                       // Get the name we were really mounted under.\r
+            FSDMGR_GetVolumeName(vol->mgrVolume, vol->volName, MAX_PATH);\r
+\r
+                       // If we got mounted as root then throw away the backslash\r
+                       // so we won't get a double backslash when volName is\r
+                       // prepended to the path in the full path name calculation\r
+                       // that is used for shell callbacks.\r
+                       if (0 == wcscmp(vol->volName,L"\\"))\r
+                               vol->volName[0] = 0;\r
+#else\r
+                       // Use the name we asked to be mounted under for\r
+                       // our root.  \r
+                       wcscpy(vol->volName,L"\\");\r
+                       wcscat(vol->volName, szName);\r
+#endif\r
+               }\r
+               //slf021104b end\r
+               return TRUE;\r
+       }\r
+       else\r
+       {\r
+               vol->isMounted = 0;\r
+               SetLastError(ERROR_OUTOFMEMORY);\r
+               return FALSE;\r
+       }       \r
+}\r
+\r
+\r
+BOOL YFSD_MountDisk(HDSK hdsk)\r
+{\r
+//slf021105a begin\r
+#ifdef DO_PARTITION_TABLE\r
+       ynandif_partition PartTable[MAXPARTITIONS];\r
+       DWORD dwAvail;\r
+       int i;\r
+       BOOL rval = FALSE;\r
+#endif\r
+//slf021105a end\r
+       int deadBlox=0,emptyBlox=0,fullBlox=0,allocatingBlox=0,dirtyBlox=0;\r
+       //int i;\r
+       // Called to mount a disk.\r
+       // NB THis call might happen redundantly.\r
+       //\r
+       //\r
+       // If yaffs is not initialised, then call the \r
+       // initialisation function\r
+       //\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::MountDisk\r\n"));\r
+\r
+       if (!yaffsLockInited)\r
+       {\r
+               InitializeCriticalSection(&yaffsLock);\r
+               yfsd_InitialiseWinFiles();\r
+               yaffsLockInited = 1;\r
+       }\r
+\r
+       //slf021105a begin\r
+       memset(disk_volumes,0,sizeof(disk_volumes));\r
+#ifdef DO_PARTITION_TABLE\r
+       memset(&PartTable,0,sizeof(PartTable));\r
+       // Call the block driver to get the partition table from it.\r
+    if (FSDMGR_DiskIoControl(hdsk, YNANDIF_GETPARTITIONS, NULL, 0, (LPVOID)&PartTable, sizeof(PartTable), &dwAvail, NULL)) \r
+       {\r
+               // Scan throught the table it return.\r
+               for (i=0; i<MAXPARTITIONS; i++)\r
+               {\r
+                       // At the very lease check that the end is later than the beginning\r
+                       // and don't let it start at 0.  \r
+                       // Probably could do more thorough checking but I trust the block\r
+                       // driver.\r
+                       if (PartTable[i].startBlock && (PartTable[i].endBlock > PartTable[i].startBlock))\r
+                       {\r
+                               // Found a partion.  Get a volume structure to hold it.\r
+                               disk_volumes[i] = malloc(sizeof(yfsd_Volume));\r
+                               if (disk_volumes[i])\r
+                               {\r
+                                       memset(disk_volumes[i],0,sizeof(yfsd_Volume));\r
+                                       // Go init the volume.  Note that if the block driver wants the\r
+                                       // name to come from the registry it will have returned an\r
+                                       // empty name string.\r
+                                       YFSD_InitVolume(hdsk,disk_volumes[i],PartTable[i].startBlock,PartTable[i].endBlock,PartTable[i].volName);\r
+                                       if (disk_volumes[i]->isMounted)\r
+                                               rval = TRUE; //Hey, we found at least on partition.\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       return rval;\r
+\r
+#else\r
+#ifdef DISABLE_BOOT_PARTITION\r
+       // Only want disk volume\r
+       disk_volumes[0] = malloc(sizeof(yfsd_Volume));\r
+       if (disk_volumes[0])\r
+       {\r
+               memset(disk_volumes[0],0,sizeof(yfsd_Volume));\r
+               YFSD_InitVolume(hdsk, disk_volumes[0], 1, -1, YFSD_DISK_NAME);\r
+\r
+               if(disk_volumes[0].isMounted)\r
+               {\r
+                       return TRUE;\r
+               }\r
+       }\r
+       if (disk_volumes[0])\r
+       {\r
+               free(disk_volumes[0];\r
+               disk_volumes[0] = NULL;\r
+       }\r
+#else\r
+       // Want both boot and disk\r
+       disk_volumes[0] = malloc(sizeof(yfsd_Volume));\r
+       disk_volumes[1] = malloc(sizeof(yfsd_Volume));\r
+       if (disk_volumes[0] && disk_volumes[1])\r
+       {\r
+               memset(disk_volumes[0],0,sizeof(yfsd_Volume));\r
+               memset(disk_volumes[1],0,sizeof(yfsd_Volume));\r
+               YFSD_InitVolume(hdsk, disk_volumes[0], PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME);\r
+               YFSD_InitVolume(hdsk, disk_volumes[1], 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME);\r
+\r
+#ifdef MSGBOX_DISPLAY\r
+        // pass the device we are sniffing to the thread\r
+        CreateThread(NULL, 0, yfsd_MessageThread, (LPVOID)&disk_volumes[0]->dev, 0, NULL);\r
+#endif\r
+\r
+               if(disk_volumes[0]->isMounted && disk_volumes[1]->isMounted)\r
+               {\r
+                       return TRUE;\r
+               }\r
+       }\r
+\r
+       // If we got this far something went wrong.  Make sure to \r
+       // free any memory we allocated.\r
        if (disk_volumes[0])\r
        {\r
                if (disk_volumes[0]->volName)\r
@@ -848,43 +925,43 @@ BOOL YFSD_MountDisk(HDSK hdsk)
        return FALSE;\r
 \r
        // Only want disk volume\r
-//     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;
-//     }
+//     YFSD_InitVolume(hdsk, &disk_volume, 1, -1, YFSD_DISK_NAME);\r
+//\r
+//     \r
+//     if(disk_volume.isMounted)\r
+//     {\r
+//             return TRUE;\r
+//     }\r
+//#else\r
+//     // Want both boot and disk\r
+//     YFSD_InitVolume(hdsk, &disk_volume, PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME);\r
+//     YFSD_InitVolume(hdsk, &boot_volume, 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME);\r
+//\r
+//     \r
+//     if(disk_volume.isMounted && boot_volume.isMounted)\r
+//     {\r
+//             return TRUE;\r
+//     }\r
 //#endif\r
-//
-//     return FALSE;
+//\r
+//     return FALSE;\r
 #endif\r
 //slf021105a end\r
-
-//     yfsd_SetGuards();
-
-       // todo - get name from registry
-
-}
-
-
-BOOL YFSD_UnmountDisk(HDSK hdsk)
-{
+\r
+//     yfsd_SetGuards();\r
+\r
+       // todo - get name from registry\r
+\r
+}\r
+\r
+\r
+BOOL YFSD_UnmountDisk(HDSK hdsk)\r
+{\r
 //slf021105a begin\r
        int i;\r
 //slf021105a end\r
-       RETAILMSG (MSGSTATE, (L"YAFFS::UnmountDisk\r\n"));
-       
+       RETAILMSG (MSGSTATE, (L"YAFFS::UnmountDisk\r\n"));\r
+       \r
        //slf021104d begin\r
        // If there are any files open don't let them dismount\r
        // it or the system will get very confused.  \r
@@ -898,8 +975,8 @@ BOOL YFSD_UnmountDisk(HDSK hdsk)
 //slf021105a begin\r
 //     yaffs_Deinitialise(&disk_volume.dev);\r
 //     yaffs_Deinitialise(&boot_volume.dev);\r
-//     yfsd_UnlockYAFFS();
-//
+//     yfsd_UnlockYAFFS();\r
+//\r
 //     FSDMGR_DeregisterVolume(disk_volume.mgrVolume);\r
 //     FSDMGR_DeregisterVolume(boot_volume.mgrVolume);\r
 \r
@@ -910,6 +987,9 @@ BOOL YFSD_UnmountDisk(HDSK hdsk)
                if (disk_volumes[i])\r
                {\r
                        yaffs_Deinitialise(&(disk_volumes[i]->dev));\r
+//slf021220a Begin Cleanup block driver interface\r
+                       ynandif_DeinitialiseNAND(&(disk_volumes[i]->dev));\r
+//slf021220a end Cleanup block driver interface\r
                        FSDMGR_DeregisterVolume(disk_volumes[i]->mgrVolume);\r
                        if (disk_volumes[i]->volName)\r
                        {\r
@@ -920,1836 +1000,1946 @@ BOOL YFSD_UnmountDisk(HDSK hdsk)
                }\r
        }\r
        yfsd_UnlockYAFFS();\r
-//slf021105a end
-       return TRUE;
-}
-
-
-BOOL YFSD_CreateDirectoryW(PVOLUME pVolume, PCWSTR pathName, PSECURITY_ATTRIBUTES pSecurityAttributes)
-{
-       // security attributes are ignored (should be NULL)
-
-       yaffs_Object *newDir = NULL;
-       yaffs_Object *parent = NULL;
-       char name[YFSD_NAME_LENGTH+1];
-       ULONG objSize;
-       DWORD attribs;
-       unsigned modifiedTime[2];
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::CreateDirectory (%s)\r\n", pathName));
-
-       yfsd_LockYAFFS();
-
-       parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pathName,name,YFSD_NAME_LENGTH);
-
-       //slf021101b begin 
-       if (parent)
-       {
-               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();
-
-       // Call shell function to tell of new directory
-       if(newDir && pVolume->shellFunction)
-       {
-                       FILECHANGEINFO fc;
-                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
-
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = SHCNE_MKDIR;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume, fpn,YFSD_FULL_PATH_NAME_SIZE,pathName);
-                       fc.dwItem2 = 0;
-                       fc.dwAttributes = attribs; 
-                       yfsd_U32sToWinFileTime(modifiedTime,&fc.ftModified);
-                       fc.nFileSize = objSize;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));
-
-                       //yfsd_ShellDirectoryChanged(pVolume,fpn);
-
-       }
-
-//slf021101b begin 
-//     if(parent && !newDir)
-//     {
-//                     SetLastError(ERROR_DISK_FULL);
-//     }
-//slf021101b end
-
-       return newDir ? TRUE : FALSE;
-}
-
-
-BOOL yfsd_RemoveObjectW(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));
-
-       yfsd_LockYAFFS();
-
-       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pathName);
-       if(!obj)
-       {
-               SetLastError(ERROR_FILE_NOT_FOUND);
-               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,pathName,name,YFSD_NAME_LENGTH);
-
-               if(parent && yfsd_NameIsValid(name))
-               {
-                       result = yaffs_Unlink(parent,name);
-                       if(!result)
-                               SetLastError(ERROR_ACCESS_DENIED);
-               }
-       }
-
-       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;
-                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
-
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = SHCNE_RMDIR;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pathName);
-                       fc.dwItem2 = 0;
-                       fc.dwAttributes = 0;
-                       yfsd_NullWinFileTime(&fc.ftModified);
-                       fc.nFileSize = 0;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));
-
-                       yfsd_ShellDirectoryChanged(pVolume,fpn);
-       }
-       
-       return result;
-
-}
-
-
-DWORD YFSD_GetFileAttributesW(PVOLUME pVolume, PCWSTR pwsFileName )
-{
-       yaffs_Object *obj = NULL;
-
-       DWORD result = 0xFFFFFFFF;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileAttributes\r\n"));
-
-       yfsd_LockYAFFS();
-
-       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);
-
-       if(obj)
-       {
-               result = yfsd_GetObjectWinAttributes(obj);
-       }
-       else
-       {
-               SetLastError(ERROR_FILE_NOT_FOUND);
-       }
-
-       yfsd_UnlockYAFFS();
-       
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileAttributes for %s returning %X\r\n",pwsFileName,result));
-       return result;
-
-       
-}
-
-BOOL YFSD_SetFileAttributesW( PVOLUME pVolume,PCWSTR pwsFileName, DWORD dwFileAttributes )
-{
-       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;
-       }
-
-       yfsd_LockYAFFS();
-
-       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);
-
-       if(obj)
-       {
-               obj->st_mode = dwFileAttributes;
-               obj->dirty = 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
-       {
-               SetLastError(ERROR_FILE_NOT_FOUND);
-       }
-
-       yfsd_UnlockYAFFS();
-
-       if(result && pVolume->shellFunction)
-       {
-                       FILECHANGEINFO fc;
-                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
-
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = SHCNE_ATTRIBUTES;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);
-                       fc.dwItem2 = 0;
-                       fc.dwAttributes =  attribs;
-                       yfsd_U32sToWinFileTime(mtime,&fc.ftModified);
-                       fc.nFileSize = objSize;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));
-
-                       //yfsd_ShellDirectoryChanged(pVolume,fpn);
-       }
-       
-
-       return result;
-
-}
-
-BOOL YFSD_DeleteFileW( PVOLUME pVolume, PCWSTR pwsFileName )
-{
-       BOOL result;
-       RETAILMSG (MSGSTATE, (L"YAFFS::DeleteFileW (%s)\r\n", pwsFileName));
-
-       result =  yfsd_RemoveObjectW(pVolume, pwsFileName);
-       if(result && pVolume->shellFunction)
-       {
-                       FILECHANGEINFO fc;
-                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
-
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = SHCNE_DELETE;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);
-                       fc.dwItem2 = 0;
-                       fc.dwAttributes = -1;
-                       yfsd_NullWinFileTime(&fc.ftModified);
-                       fc.nFileSize = 0;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));
-
-                       yfsd_ShellDirectoryChanged(pVolume,fpn);
-       }
-
-       return result;
-}
-
-BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName )
-{
-       yaffs_Object *newParent = NULL;
-       yaffs_Object *oldParent = NULL;
-       yaffs_Object *obj = NULL;
-       char oldName[YFSD_NAME_LENGTH+1];
-       char newName[YFSD_NAME_LENGTH+1];
-       int result = 0;
-       int objIsDir = 0;
-       DWORD attribs;
-       DWORD objSize;
-       DWORD mtime[2];
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::MoveFile\r\n"));
-
-       yfsd_LockYAFFS();
-
-       oldParent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsOldFileName,oldName,YFSD_NAME_LENGTH);
-       newParent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsNewFileName,newName,YFSD_NAME_LENGTH);
-
-       if(oldParent  && yfsd_NameIsValid(oldName) && newParent && yfsd_NameIsValid(newName))
-       {
-               result = yaffs_RenameObject(oldParent,oldName,newParent,newName);
-               if(!result)
-               {
-                       SetLastError(ERROR_FILE_NOT_FOUND);
-               }
-
-               obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsNewFileName);
-               if(obj)
-               {
-                       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];
-               }
-       }
-       else
-       {
-               SetLastError(ERROR_PATH_NOT_FOUND);
-       }
-
-       yfsd_UnlockYAFFS();
-
-
-       if(result && pVolume->shellFunction)
-       {
-                       FILECHANGEINFO fc;
-                       WCHAR fpn1[YFSD_FULL_PATH_NAME_SIZE];
-                       WCHAR fpn2[YFSD_FULL_PATH_NAME_SIZE];
-
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = objIsDir ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn1,YFSD_FULL_PATH_NAME_SIZE,pwsOldFileName);
-                       fc.dwItem2 = (DWORD)yfsd_FullPathName(pVolume,fpn2,YFSD_FULL_PATH_NAME_SIZE,pwsNewFileName);
-                       fc.dwAttributes = attribs;
-                       yfsd_U32sToWinFileTime(mtime,&fc.ftModified);
-                       fc.nFileSize = objSize;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));
-
-                       yfsd_ShellDirectoryChanged(pVolume,fpn1);
-                       yfsd_ShellDirectoryChanged(pVolume,fpn2);
-       }
-
-
-       return result ? TRUE : FALSE;
-
-}
-
-BOOL YFSD_DeleteAndRenameFileW(PVOLUME pVolume, PCWSTR pwsOldFileName, PCWSTR pwsNewFileName )
-{
-       //slf021104c begin\r
-    BOOL fSuccess;\r
-       //slf021104c end\r
-\r
+//slf021105a end\r
+       return TRUE;\r
+}\r
+\r
+\r
+BOOL YFSD_CreateDirectoryW(PVOLUME pVolume, PCWSTR pathName, PSECURITY_ATTRIBUTES pSecurityAttributes)\r
+{\r
+       // security attributes are ignored (should be NULL)\r
+\r
+       yaffs_Object *newDir = NULL;\r
+       yaffs_Object *parent = NULL;\r
+       char name[YFSD_NAME_LENGTH+1];\r
+       ULONG objSize;\r
+       DWORD attribs;\r
+       unsigned modifiedTime[2];\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::CreateDirectory (%s)\r\n", pathName));\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pathName,name,YFSD_NAME_LENGTH);\r
+\r
+       //slf021101b begin \r
+       if (parent)\r
+       {\r
+               if(yfsd_NameIsValid(name))\r
+               {\r
+                       newDir = yaffs_MknodDirectory(parent,name,0,0,0);\r
+                       if(newDir)\r
+                       {\r
+                               objSize = yaffs_GetObjectFileLength(newDir);\r
+                               attribs = yfsd_GetObjectWinAttributes(newDir);\r
+                               modifiedTime[0] = newDir->win_mtime[0];\r
+                                modifiedTime[1] = newDir->win_mtime[1];\r
+                       }\r
+                       else\r
+                       {\r
+                               if(yaffs_FindObjectByName(parent,name))\r
+                                       SetLastError(ERROR_ALREADY_EXISTS);\r
+                               else\r
+                                       SetLastError(ERROR_DISK_FULL);\r
+                       }\r
+               }\r
+               else\r
+                       SetLastError(ERROR_INVALID_NAME);\r
+       }\r
+       else\r
+       {\r
+               SetLastError(ERROR_PATH_NOT_FOUND);\r
+       }\r
+    //slf021101b end\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       // Call shell function to tell of new directory\r
+       if(newDir && pVolume->shellFunction)\r
+       {\r
+                       FILECHANGEINFO fc;\r
+                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+\r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = SHCNE_MKDIR;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume, fpn,YFSD_FULL_PATH_NAME_SIZE,pathName);\r
+                       fc.dwItem2 = 0;\r
+                       fc.dwAttributes = attribs; \r
+                       yfsd_U32sToWinFileTime(modifiedTime,&fc.ftModified);\r
+                       fc.nFileSize = objSize;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
+\r
+                       //yfsd_ShellDirectoryChanged(pVolume,fpn);\r
+\r
+       }\r
+\r
+//slf021101b begin \r
+//     if(parent && !newDir)\r
+//     {\r
+//                     SetLastError(ERROR_DISK_FULL);\r
+//     }\r
+//slf021101b end\r
+\r
+       return newDir ? TRUE : FALSE;\r
+}\r
+\r
+\r
+BOOL YFSD_RemoveDirectoryW(PVOLUME pVolume, PCWSTR pathName)\r
+{\r
+       int result = FALSE;\r
+       yaffs_Object *parent = NULL;\r
+       yaffs_Object *obj;\r
+       char name[YFSD_NAME_LENGTH+1];\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::RemoveDirectory (%s)\r\n", pathName));\r
+       \r
+       yfsd_LockYAFFS();\r
+\r
+       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pathName);\r
+       if(!obj)\r
+       {\r
+               SetLastError(ERROR_PATH_NOT_FOUND);\r
+               result = FALSE;\r
+       }\r
+       else if (obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)\r
+       {\r
+               SetLastError(ERROR_ACCESS_DENIED);\r
+               result = FALSE;\r
+       }\r
+       else if(obj->st_mode & FILE_ATTRIBUTE_READONLY)\r
+       {\r
+               SetLastError(ERROR_ACCESS_DENIED);\r
+               result = FALSE;\r
+       }\r
+       else if(obj->inUse)\r
+       {\r
+               SetLastError(ERROR_ACCESS_DENIED);\r
+               result = FALSE;\r
+       }\r
+       else\r
+       {\r
+\r
+               parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pathName,name,YFSD_NAME_LENGTH);\r
+\r
+               if(parent && yfsd_NameIsValid(name))\r
+               {\r
+                       result = yaffs_Unlink(parent,name);\r
+                       if(!result)\r
+                               SetLastError(ERROR_DIR_NOT_EMPTY);\r
+               }\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       if(result && pVolume->shellFunction)\r
+       {\r
+                       FILECHANGEINFO fc;\r
+                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+\r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = SHCNE_RMDIR;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pathName);\r
+                       fc.dwItem2 = 0;\r
+                       fc.dwAttributes = 0;\r
+                       yfsd_NullWinFileTime(&fc.ftModified);\r
+                       fc.nFileSize = 0;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
+\r
+                       yfsd_ShellDirectoryChanged(pVolume,fpn);\r
+       }\r
+       \r
+       return result ? TRUE : FALSE;\r
+}\r
+\r
+\r
+DWORD YFSD_GetFileAttributesW(PVOLUME pVolume, PCWSTR pwsFileName )\r
+{\r
+       yaffs_Object *obj = NULL;\r
+\r
+       DWORD result = 0xFFFFFFFF;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileAttributes\r\n"));\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+\r
+       if(obj)\r
+       {\r
+               result = yfsd_GetObjectWinAttributes(obj);\r
+       }\r
+       else\r
+       {\r
+               SetLastError(ERROR_FILE_NOT_FOUND);\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+       \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileAttributes for %s returning %X\r\n",pwsFileName,result));\r
+       return result;\r
+\r
+       \r
+}\r
+\r
+BOOL YFSD_SetFileAttributesW( PVOLUME pVolume,PCWSTR pwsFileName, DWORD dwFileAttributes )\r
+{\r
+       yaffs_Object *obj = NULL;\r
+       DWORD mtime[2];\r
+       DWORD attribs;\r
+       DWORD objSize;\r
+\r
+       int result = 0;\r
+\r
+       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
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+\r
+       if(obj)\r
+       {\r
+               obj->st_mode = dwFileAttributes;\r
+               obj->dirty = 1;\r
+               result = yaffs_FlushFile(obj,0);\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
+       }\r
+       else\r
+       {\r
+               SetLastError(ERROR_FILE_NOT_FOUND);\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       if(result && pVolume->shellFunction)\r
+       {\r
+                       FILECHANGEINFO fc;\r
+                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+\r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = SHCNE_ATTRIBUTES;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);\r
+                       fc.dwItem2 = 0;\r
+                       fc.dwAttributes =  attribs;\r
+                       yfsd_U32sToWinFileTime(mtime,&fc.ftModified);\r
+                       fc.nFileSize = objSize;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
+\r
+                       //yfsd_ShellDirectoryChanged(pVolume,fpn);\r
+       }\r
+       \r
+\r
+       return result;\r
+\r
+}\r
+\r
+BOOL YFSD_DeleteFileW( PVOLUME pVolume, PCWSTR pwsFileName )\r
+{\r
+       int result = FALSE;\r
+       yaffs_Object *parent = NULL;\r
+       yaffs_Object *obj;\r
+       char name[YFSD_NAME_LENGTH+1];\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::DeleteFileW (%s)\r\n", pwsFileName));\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+       if(!obj)\r
+       {\r
+               SetLastError(ERROR_FILE_NOT_FOUND);\r
+               result = FALSE;\r
+       }\r
+       else if (obj->variantType != YAFFS_OBJECT_TYPE_FILE)\r
+       {\r
+               SetLastError(ERROR_ACCESS_DENIED);\r
+               result = FALSE;\r
+       }\r
+       else if(obj->st_mode & FILE_ATTRIBUTE_READONLY)\r
+       {\r
+               SetLastError(ERROR_ACCESS_DENIED);\r
+               result = FALSE;\r
+       }\r
+       else if(obj->inUse)\r
+       {\r
+               SetLastError(ERROR_ACCESS_DENIED);\r
+               result = FALSE;\r
+       }\r
+       else\r
+       {\r
+\r
+               parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsFileName,name,YFSD_NAME_LENGTH);\r
+\r
+               if(parent && yfsd_NameIsValid(name))\r
+               {\r
+                       result = yaffs_Unlink(parent,name);\r
+                       if(!result)\r
+                               SetLastError(ERROR_ACCESS_DENIED);\r
+               }\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       if(result && pVolume->shellFunction)\r
+       {\r
+                       FILECHANGEINFO fc;\r
+                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+\r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = SHCNE_DELETE;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);\r
+                       fc.dwItem2 = 0;\r
+                       fc.dwAttributes = -1;\r
+                       yfsd_NullWinFileTime(&fc.ftModified);\r
+                       fc.nFileSize = 0;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
+\r
+                       yfsd_ShellDirectoryChanged(pVolume,fpn);\r
+       }\r
+\r
+       return result ? TRUE : FALSE;\r
+}\r
+\r
+BOOL YFSD_MoveFileW(PVOLUME pVolume,PCWSTR pwsOldFileName, PCWSTR pwsNewFileName )\r
+{\r
+       yaffs_Object *newParent = NULL;\r
+       yaffs_Object *oldParent = NULL;\r
+       yaffs_Object *obj = NULL;\r
+       char oldName[YFSD_NAME_LENGTH+1];\r
+       char newName[YFSD_NAME_LENGTH+1];\r
+       int result = 0;\r
+       int objIsDir = 0;\r
+       DWORD attribs;\r
+       DWORD objSize;\r
+       DWORD mtime[2];\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::MoveFile\r\n"));\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       oldParent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsOldFileName,oldName,YFSD_NAME_LENGTH);\r
+       newParent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsNewFileName,newName,YFSD_NAME_LENGTH);\r
+\r
+       if(oldParent  && yfsd_NameIsValid(oldName) && newParent && yfsd_NameIsValid(newName))\r
+       {\r
+               result = yaffs_RenameObject(oldParent,oldName,newParent,newName);\r
+               if(!result)\r
+               {\r
+                       SetLastError(ERROR_FILE_NOT_FOUND);\r
+               }\r
+\r
+               obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsNewFileName);\r
+               if(obj)\r
+               {\r
+                       objIsDir = (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY);\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
+               }\r
+       }\r
+       else\r
+       {\r
+               SetLastError(ERROR_PATH_NOT_FOUND);\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+\r
+       if(result && pVolume->shellFunction)\r
+       {\r
+                       FILECHANGEINFO fc;\r
+                       WCHAR fpn1[YFSD_FULL_PATH_NAME_SIZE];\r
+                       WCHAR fpn2[YFSD_FULL_PATH_NAME_SIZE];\r
+\r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = objIsDir ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn1,YFSD_FULL_PATH_NAME_SIZE,pwsOldFileName);\r
+                       fc.dwItem2 = (DWORD)yfsd_FullPathName(pVolume,fpn2,YFSD_FULL_PATH_NAME_SIZE,pwsNewFileName);\r
+                       fc.dwAttributes = attribs;\r
+                       yfsd_U32sToWinFileTime(mtime,&fc.ftModified);\r
+                       fc.nFileSize = objSize;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
+\r
+                       yfsd_ShellDirectoryChanged(pVolume,fpn1);\r
+                       yfsd_ShellDirectoryChanged(pVolume,fpn2);\r
+       }\r
+\r
+\r
+       return result ? TRUE : FALSE;\r
+\r
+}\r
+\r
+BOOL YFSD_DeleteAndRenameFileW(PVOLUME pVolume, PCWSTR pwsOldFileName, PCWSTR pwsNewFileName )\r
+{\r
+       //slf021104c begin\r
+    BOOL fSuccess;\r
+       //slf021104c end\r
+\r
        RETAILMSG (MSGSTATE, (L"YAFFS::DeleteAndRename\r\n"));\r
 \r
-       //slf021104c begin
+       //slf021104c begin\r
     if (fSuccess = YFSD_DeleteFileW(pVolume, pwsOldFileName))\r
         fSuccess = YFSD_MoveFileW(pVolume, pwsNewFileName, pwsOldFileName);\r
        return fSuccess;\r
-       //return FALSE;
+       //return FALSE;\r
        //slf021104c end\r
-}
-
-BOOL YFSD_GetDiskFreeSpaceW( PVOLUME pVolume, PCWSTR pwsPathName, PDWORD pSectorsPerCluster,PDWORD pBytesPerSector, PDWORD pFreeClusters, PDWORD pClusters )
-{
-
-       int nChunks;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetFreeSpace\r\n"));
-
-       yfsd_LockYAFFS();
-       nChunks = yaffs_GetNumberOfFreeChunks(&pVolume->dev);
-       yfsd_UnlockYAFFS();
-
-       if(nChunks >= 0)
-       {
-               // Let's pretentd our clusters are the same size as eraseable blocks...
-               *pBytesPerSector = 512;
-               *pSectorsPerCluster  =32;
-               *pFreeClusters = nChunks/32;
-               *pClusters = pVolume->dev.endBlock - pVolume->dev.startBlock + 1;
-       }
-
-       return (nChunks >= 0)? TRUE : FALSE;
-
-
-
-}
-
-void YFSD_Notify(PVOLUME pVolume, DWORD dwFlags )
-{
-       // Flags can be one of:
-       // FSNOTIFY_POWER_ON: no action required
-       // FSNOTIFY_POWER_OFF: flush all files
-       // FSNOTIFY_DEVICE_ON: no action required
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::Notify\r\n"));
-       if(dwFlags == FSNOTIFY_POWER_OFF)
-       {
-               yfsd_FlushAllFiles();
-       }
-
-}
-
-
-BOOL YFSD_RegisterFileSystemFunction(PVOLUME pVolume,SHELLFILECHANGEFUNC_t pfn )
-{
-       RETAILMSG (MSGSTATE, (L"YAFFS::RegisterFileSysFunction\r\n"));
-       
-       pVolume->shellFunction = pfn;
-
-       return TRUE;
-}
-
-
-
-
-
-int iMatch(const char a, const char b)
-{
-       if (a == '?' || b == '?')
-               return 1;
-       return (toupper(a) == toupper(b));
-}
-
-void pString(const char *inp)
-{
-       while (*inp) RETAILMSG(1, (L"%c", *inp++));
-}
-
-int regularMatch(const char *regexp, const char *str)
-{
-//     pString(regexp);
-//     RETAILMSG(1, (L" "));
-//     pString(str);
-//     RETAILMSG(1, (L"\r\n"));
-
-       if (*regexp == 0 && *str == 0)
-       {
-               //RETAILMSG(1, (L"Match!\r\n"));
-               return 1;
-       }
-       if (*regexp == '*')                     
-       {
-               regexp++;
-               if (*regexp == 0)   // end of the expression is a *, we must match
-               {
-                       //RETAILMSG(1, (L"Match!\r\n"));
-                       return 1;
-               }
-               while (!iMatch(*regexp, *str)) // throw away chars from str until we match
-               {
-                       if (*str == 0)  // if we're not at the end
-                       {
-                               // if we have .* left to match, but the str is finished then match it OK
-                               if (regexp[0] == '.' && regexp[1] == '*')
-                               {
-                                       //RETAILMSG(1, (L"Match!\r\n"));
-                                       return 1;
-                               }
-                               else
-                               {
-                               // the extension failed the match
-                                       //RETAILMSG(1, (L"No Match!\r\n"));
-                                       return 0;
-                               }
-                       }
-                       str++;
-               } 
-               // right now we should either eat more characters, or try to match
-               return (regularMatch(regexp, str) || regularMatch(--regexp, ++str));
-       }
-//  compare chars until we hit another *, or we fail
-       while (iMatch(*regexp, *str))
-       {
-               if (*regexp == 0 && *str == 0)
-               {
-                       //RETAILMSG(1, (L"Match!\r\n"));
-                       return 1;
-               }
-               regexp++;
-               str++;
-       }
-
-       if (*regexp == 0 && *str == 0)
-       {
-               //RETAILMSG(1, (L"Match!\r\n"));
-               return 1;
-       }
-
-       if (*regexp == '*')
-               return regularMatch(regexp, str);
-
-       //RETAILMSG(1, (L"No Match!\r\n"));
-       return 0;
-}
-
-
-void yfsd_DeleteFinder(PSEARCH pSearch)
-{
-  if(pSearch->foundObjects) //If we found some objects we must clean up the cached linked list.
-  {
-    yaffs_FoundObject *it;
-    yaffs_FoundObject *temp;
-
-    it = pSearch->foundObjects;
-
-    while(it != NULL)
-    {
-      temp = it;
-      it = it->next;
-      
-      free(temp);
-    }
-
-    pSearch->foundObjects = NULL;
-  }
-
-               pSearch->dir->inUse--;
-               free(pSearch);
-}
-
-BOOL yfsd_ObjectAlreadyFound(PSEARCH pSearch, yaffs_Object *l)
-{
-  //Iterate through the current list of objs already found and return true if already exists.
-  //If the object hasn't already been found then add it to the list (SIDE-EFFECT alert) and return false.
-  BOOL found = FALSE;
-
-  yaffs_FoundObject *it;
-  it = pSearch->foundObjects;
-
-  
-  while(it->next != NULL) //iterate through singly linked list.
-  {
-    if(it->obj == l)
-    {
-      found = TRUE;
-      break;
-    }
-    it = it->next;
-  }
-
-  if(!found)
-  {
-    //Add the item to the list.
-    //'it' will currently be pointing to the last of the list nodes. i.e node->next == NULL
-    it->next = malloc(sizeof(yaffs_FoundObject));
-    it->next->next = NULL;
-    it->next->obj = 0;
-
-    it->obj = l;
-  }
-
-  return found;
-}
-
-#if 0
-// slower one
-BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd)
-{
-
-       struct list_head *i;
-       int pos;
-       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();
-
-       pos = 0;
-       list_for_each(i,&pSearch->dir->variant.directoryVariant.children)
-       {
-
-               l = list_entry(i, yaffs_Object,siblings);
-
-               yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1);
-
-               if(regularMatch(pSearch->pattern,name))
-               {
-                       if(!yfsd_ObjectAlreadyFound(pSearch, l))//pos == pSearch->currentPos)
-                       {               
-
-                               
-                               found = 1;
-                               //pSearch->currentPos++;
-
-                               // 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;
-                       }
-                       else
-                       {
-                               pos++;
-                       }
-               }
-       }
-
-out_of_here:
-       yfsd_UnlockYAFFS();
-
-
-       if(!found)
-       {
-               SetLastError(ERROR_NO_MORE_FILES);
-       }
-       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
-
-HANDLE YFSD_FindFirstFileW(PVOLUME pVolume, HANDLE hProc,PCWSTR pwsFileSpec, PWIN32_FIND_DATAW pfd )
-{
-
-       // Create a search context, register it, and do the first search
-
-       PSEARCH pSearch;
-       HANDLE h = INVALID_HANDLE_VALUE;
-       BOOL found = 0;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindFirst\r\n"));
-
-       pSearch = malloc(sizeof(yfsd_WinFind));
-       if(!pSearch)
-       {
-               SetLastError(ERROR_OUTOFMEMORY);
-       }
-
-       yfsd_LockYAFFS();
-
-       if(pSearch)
-       {
-               pSearch->foundObjects = NULL; //pSearch->currentPos = 0;
-               pSearch->dir = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsFileSpec,pSearch->pattern,YFSD_NAME_LENGTH);
-               if(pSearch->dir)
-               {
-                               pSearch->dir->inUse++;
-               }
-               else
-               {
-                       free(pSearch);
-                       pSearch = NULL;
-               }
-       }
-
-       yfsd_UnlockYAFFS();
-
-
-
-       if(pSearch)
-       {
-               found = yfsd_DoFindFile(pSearch,pfd);
-       }
-
-       if(found)
-       {
-               h = FSDMGR_CreateSearchHandle(pVolume->mgrVolume,hProc,pSearch);
-       }
-
-       if(h == INVALID_HANDLE_VALUE && pSearch)
-       {
-               yfsd_DeleteFinder(pSearch);
-               SetLastError(ERROR_NO_MORE_SEARCH_HANDLES);
-       }
-
-
-
-       return h;
-}
-
-BOOL YFSD_FindNextFileW(PSEARCH pSearch, PWIN32_FIND_DATAW pfd )
-{
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindNext\r\n"));
-       if(!pSearch)
-       {
-               return FALSE;
-       }
-       return yfsd_DoFindFile(pSearch,pfd);
-}
-
-BOOL YFSD_FindClose( PSEARCH pSearch )
-{      
-       RETAILMSG (MSGSTATE, (L"YAFFS::FindClose\r\n"));
-       if(!pSearch)
-       {
-               return FALSE;
-       }
-       yfsd_DeleteFinder(pSearch);
-       return TRUE;
-}
-
-
-HANDLE YFSD_CreateFileW( 
-       PVOLUME pVolume, 
-       HANDLE hProc, 
-       PCWSTR pwsFileName, 
-       DWORD dwAccess, 
-       DWORD dwShareMode,
-       PSECURITY_ATTRIBUTES pSecurityAttributes, // ignore
-       DWORD dwCreate,
-       DWORD dwFlagsAndAttributes, 
-       HANDLE hTemplateFile ) // ignore
-{
-
-
-       yaffs_Object *parent = NULL;
-       yaffs_Object *obj = NULL;
-       char name[YFSD_NAME_LENGTH+1];
-       int mode;
-       yfsd_WinFile *f = NULL;
-       HANDLE handle = INVALID_HANDLE_VALUE;
-       unsigned modifiedTime[2];
-       unsigned objSize;
-
-       BOOL writePermitted = (dwAccess & GENERIC_WRITE) ? TRUE : FALSE;\r
-       BOOL readPermitted = (dwAccess & GENERIC_READ) ? TRUE : FALSE;\r
-       BOOL shareRead = (dwShareMode & FILE_SHARE_READ) ? TRUE : FALSE;\r
-       BOOL shareWrite = (dwShareMode & FILE_SHARE_WRITE) ? TRUE : FALSE;\r
+}\r
 \r
-       BOOL openRead, openWrite, openReadAllowed, openWriteAllowed;\r
-
-       BOOL fileCreated = 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 permitted\r\n"));
-       }
-       else
-       {
-               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile write not permitted\r\n"));
-       }
-
-       if(!yfsd_CheckValidAttributes(mode))
-       {
-                       SetLastError(ERROR_INVALID_PARAMETER);
-                       return FALSE;
-       }
-
-       yfsd_LockYAFFS();
-
-
-       parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsFileName,name,YFSD_NAME_LENGTH);
-
-
-       if(parent && yfsd_NameIsValid(name))
-       {
-
-               if(dwCreate == CREATE_NEW)
-               {
-                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file in CREATE_NEW\r\n"));
-
-                       //slf021101c begin
-                       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);
-                       if(!obj)
-                       {
-                               obj = yaffs_MknodFile(parent,name,mode,0,0);
-                               if(!obj)
-                                       SetLastError(ERROR_DISK_FULL);
-                               fileCreated = TRUE;
-                       }
-                       else
-                       {
-                               obj = NULL;
-                               SetLastError(ERROR_ALREADY_EXISTS);
-                       }\r
-                       //slf021101c end
-               }
-               else if( dwCreate == OPEN_ALWAYS)
-               {
-                       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);
-                       if(!obj)
-                       {
-                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file in OPEN_ALWAYS\r\n"));
-                               obj = yaffs_MknodFile(parent,name,mode,0,0);
-                               if(!obj)
-                                       SetLastError(ERROR_DISK_FULL);
-                               fileCreated = TRUE;
-
-                       }
-                       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);
-                       if(!obj)
-                               SetLastError(ERROR_FILE_NOT_FOUND);
-            //slf021101c begin
-                       else
-                               if (yfsd_GetObjectWinAttributes(obj) & FILE_ATTRIBUTE_DIRECTORY)
-                               {
-                                       SetLastError(ERROR_ACCESS_DENIED);
-                                       obj = NULL;
-                               }
-            //slf021101c end
-               }
-               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)
-                       {
-                               yaffs_ResizeFile(obj,0);
-                       }
-                       else
-                       {
-                               SetLastError(ERROR_FILE_NOT_FOUND);
-                       }
-               }
-               else if(dwCreate == CREATE_ALWAYS)
-               {
-                       obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);
-
-                       if(!obj)
-                       {
-                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file parent %X, name %a in CREATE_ALWAYS\r\n",parent,name));
-                               obj = yaffs_MknodFile(parent,name,mode,0,0);
-                               if(!obj)
-                                       SetLastError(ERROR_DISK_FULL);
-                               fileCreated = TRUE;
-                       }
-                       else
-                       {
-                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile in CREATE_ALWAYS (already exists)\r\n"));
-                               obj->st_mode = mode;
-                               obj->dirty = 1;
-                               yaffs_ResizeFile(obj,0);
-                               yaffs_FlushFile(obj,1);
-                       }
-               }
-               else
-               {
-                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile called with unknown flags %x\r\n", dwCreate));
-                               SetLastError(ERROR_INVALID_PARAMETER);
-               }
-       }
-       else
-       {
-               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile unable to get parent node\r\n"));
-               SetLastError(ERROR_PATH_NOT_FOUND);
-       }
+BOOL YFSD_GetDiskFreeSpaceW( PVOLUME pVolume, PCWSTR pwsPathName, PDWORD pSectorsPerCluster,PDWORD pBytesPerSector, PDWORD pFreeClusters, PDWORD pClusters )\r
+{\r
 \r
-       if(obj)\r
+       int nChunks;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetFreeSpace\r\n"));\r
+\r
+       yfsd_LockYAFFS();\r
+       nChunks = yaffs_GetNumberOfFreeChunks(&pVolume->dev);\r
+       yfsd_UnlockYAFFS();\r
+\r
+       if(nChunks >= 0)\r
        {\r
-                       int i;\r
-                       yfsd_WinFile *p;\r
-                       openRead = openWrite =0;\r
-                       openReadAllowed = openWriteAllowed = 1;\r
+               // Let's pretentd our clusters are the same size as eraseable blocks...\r
+               *pBytesPerSector = 512;\r
+               *pSectorsPerCluster  =32;\r
+               *pFreeClusters = nChunks/32;\r
+               *pClusters = pVolume->dev.endBlock - pVolume->dev.startBlock + 1;\r
+       }\r
 \r
-                       for(i = 0; i < MAX_WIN_FILE; i++)\r
-                       {\r
-                                       p = &yfsd_winFile[i];\r
+       return (nChunks >= 0)? TRUE : FALSE;\r
 \r
-                                       if(p->obj == obj)\r
-                                       {\r
-                                               if (p->readPermitted) openRead = 1;\r
-                                               if (p->writePermitted) openWrite = 1;\r
-                                               if (!p->shareRead) openReadAllowed = 0;\r
-                                               if (!p->shareWrite) openWriteAllowed = 0;\r
-                                       }\r
 \r
-                       }\r
 \r
-                       // Now we test if the share works out.\r
+}\r
 \r
-                       if((openRead && !shareRead) ||   // already open for read, but we are not prepared to share it for read\r
-                          (openWrite && !shareWrite) || // already open for write, but we are not prepared to share it for write\r
-                          (!openReadAllowed && readPermitted) || // already open with read sharing not permitted\r
-                          (!openWriteAllowed && writePermitted)) // same... write\r
-                       {\r
-                               SetLastError(ERROR_ACCESS_DENIED);\r
-                               obj = NULL;\r
-                       }\r
+void YFSD_Notify(PVOLUME pVolume, DWORD dwFlags )\r
+{\r
+       // Flags can be one of:\r
+       // FSNOTIFY_POWER_ON: no action required\r
+       // FSNOTIFY_POWER_OFF: flush all files\r
+       // FSNOTIFY_DEVICE_ON: no action required\r
 \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::Notify\r\n"));\r
+       if(dwFlags == FSNOTIFY_POWER_OFF)\r
+       {\r
+               yfsd_FlushAllFiles();\r
+       }\r
+\r
+}\r
+\r
+\r
+BOOL YFSD_RegisterFileSystemFunction(PVOLUME pVolume,SHELLFILECHANGEFUNC_t pfn )\r
+{\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::RegisterFileSysFunction\r\n"));\r
+       \r
+       pVolume->shellFunction = pfn;\r
+\r
+       return TRUE;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+int iMatch(const char a, const char b)\r
+{\r
+       if (a == '?' || b == '?')\r
+               return 1;\r
+       return (toupper(a) == toupper(b));\r
+}\r
+\r
+void pString(const char *inp)\r
+{\r
+       while (*inp) RETAILMSG(1, (L"%c", *inp++));\r
+}\r
+\r
+int regularMatch(const char *regexp, const char *str)\r
+{\r
+//     pString(regexp);\r
+//     RETAILMSG(1, (L" "));\r
+//     pString(str);\r
+//     RETAILMSG(1, (L"\r\n"));\r
+\r
+       if (*regexp == 0 && *str == 0)\r
+       {\r
+               //RETAILMSG(1, (L"Match!\r\n"));\r
+               return 1;\r
+       }\r
+       if (*regexp == '*')                     \r
+       {\r
+               regexp++;\r
+               if (*regexp == 0)   // end of the expression is a *, we must match\r
+               {\r
+                       //RETAILMSG(1, (L"Match!\r\n"));\r
+                       return 1;\r
+               }\r
+               while (!iMatch(*regexp, *str)) // throw away chars from str until we match\r
+               {\r
+                       if (*str == 0)  // if we're not at the end\r
+                       {\r
+                               // if we have .* left to match, but the str is finished then match it OK\r
+                               if (regexp[0] == '.' && regexp[1] == '*')\r
+                               {\r
+                                       //RETAILMSG(1, (L"Match!\r\n"));\r
+                                       return 1;\r
+                               }\r
+                               else\r
+                               {\r
+                               // the extension failed the match\r
+                                       //RETAILMSG(1, (L"No Match!\r\n"));\r
+                                       return 0;\r
+                               }\r
+                       }\r
+                       str++;\r
+               } \r
+               // right now we should either eat more characters, or try to match\r
+               return (regularMatch(regexp, str) || regularMatch(--regexp, ++str));\r
+       }\r
+//  compare chars until we hit another *, or we fail\r
+       while (iMatch(*regexp, *str))\r
+       {\r
+               if (*regexp == 0 && *str == 0)\r
+               {\r
+                       //RETAILMSG(1, (L"Match!\r\n"));\r
+                       return 1;\r
+               }\r
+               regexp++;\r
+               str++;\r
+       }\r
+\r
+       if (*regexp == 0 && *str == 0)\r
+       {\r
+               //RETAILMSG(1, (L"Match!\r\n"));\r
+               return 1;\r
+       }\r
+\r
+       if (*regexp == '*')\r
+               return regularMatch(regexp, str);\r
+\r
+       //RETAILMSG(1, (L"No Match!\r\n"));\r
+       return 0;\r
+}\r
+\r
+\r
+void yfsd_DeleteFinder(PSEARCH pSearch)\r
+{\r
+  if(pSearch->foundObjects) //If we found some objects we must clean up the cached linked list.\r
+  {\r
+    yaffs_FoundObject *it;\r
+    yaffs_FoundObject *temp;\r
+\r
+    it = pSearch->foundObjects;\r
+\r
+    while(it != NULL)\r
+    {\r
+      temp = it;\r
+      it = it->next;\r
+      \r
+      free(temp);\r
+    }\r
+\r
+    pSearch->foundObjects = NULL;\r
+  }\r
+\r
+               pSearch->dir->inUse--;\r
+               free(pSearch);\r
+}\r
+\r
+BOOL yfsd_ObjectAlreadyFound(PSEARCH pSearch, yaffs_Object *l)\r
+{\r
+  //Iterate through the current list of objs already found and return true if already exists.\r
+  //If the object hasn't already been found then add it to the list (SIDE-EFFECT alert) and return false.\r
+  BOOL found = FALSE;\r
+\r
+  yaffs_FoundObject *it;\r
+  it = pSearch->foundObjects;\r
+\r
+  \r
+  while(it->next != NULL) //iterate through singly linked list.\r
+  {\r
+    if(it->obj == l)\r
+    {\r
+      found = TRUE;\r
+      break;\r
+    }\r
+    it = it->next;\r
+  }\r
+\r
+  if(!found)\r
+  {\r
+    //Add the item to the list.\r
+    //'it' will currently be pointing to the last of the list nodes. i.e node->next == NULL\r
+    it->next = malloc(sizeof(yaffs_FoundObject));\r
+    it->next->next = NULL;\r
+    it->next->obj = 0;\r
+\r
+    it->obj = l;\r
+  }\r
+\r
+  return found;\r
+}\r
+\r
+#if 0\r
+// slower one\r
+BOOL yfsd_DoFindFile(PSEARCH pSearch, PWIN32_FIND_DATAW pfd)\r
+{\r
+\r
+       struct list_head *i;\r
+       int pos;\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
+       pos = 0;\r
+       list_for_each(i,&pSearch->dir->variant.directoryVariant.children)\r
+       {\r
+\r
+               l = list_entry(i, yaffs_Object,siblings);\r
+\r
+               yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1);\r
+\r
+               if(regularMatch(pSearch->pattern,name))\r
+               {\r
+                       if(!yfsd_ObjectAlreadyFound(pSearch, l))//pos == pSearch->currentPos)\r
+                       {               \r
+\r
+                               \r
+                               found = 1;\r
+                               //pSearch->currentPos++;\r
+\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 = (CEOID)(INVALID_HANDLE_VALUE); // 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
+                       else\r
+                       {\r
+                               pos++;\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
+\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 = (CEOID)(INVALID_HANDLE_VALUE); // 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
+\r
+HANDLE YFSD_FindFirstFileW(PVOLUME pVolume, HANDLE hProc,PCWSTR pwsFileSpec, PWIN32_FIND_DATAW pfd )\r
+{\r
+\r
+       // Create a search context, register it, and do the first search\r
+\r
+       PSEARCH pSearch;\r
+       HANDLE h = INVALID_HANDLE_VALUE;\r
+       BOOL found = 0;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindFirst\r\n"));\r
+\r
+       pSearch = malloc(sizeof(yfsd_WinFind));\r
+       if(!pSearch)\r
+       {\r
+               SetLastError(ERROR_OUTOFMEMORY);\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       if(pSearch)\r
+       {\r
+               pSearch->foundObjects = NULL; //pSearch->currentPos = 0;\r
+               pSearch->dir = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsFileSpec,pSearch->pattern,YFSD_NAME_LENGTH);\r
+               if(pSearch->dir)\r
+               {\r
+                               pSearch->dir->inUse++;\r
+               }\r
+               else\r
+               {\r
+                       free(pSearch);\r
+                       pSearch = NULL;\r
+                       SetLastError(ERROR_PATH_NOT_FOUND);\r
+               }\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+\r
+\r
+       if(pSearch)\r
+       {\r
+               found = yfsd_DoFindFile(pSearch,pfd);\r
+\r
+               if(found)\r
+               {\r
+                       h = FSDMGR_CreateSearchHandle(pVolume->mgrVolume,hProc,pSearch);\r
+                       if(h == INVALID_HANDLE_VALUE)\r
+                       {\r
+                               SetLastError(ERROR_NO_MORE_SEARCH_HANDLES);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       SetLastError(ERROR_FILE_NOT_FOUND);\r
+               }\r
+\r
+               if(h == INVALID_HANDLE_VALUE)\r
+               {\r
+                       yfsd_DeleteFinder(pSearch);\r
+               }\r
+\r
+       }\r
+\r
+\r
+       return h;\r
+}\r
+\r
+BOOL YFSD_FindNextFileW(PSEARCH pSearch, PWIN32_FIND_DATAW pfd )\r
+{\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindNext\r\n"));\r
+       if(!pSearch)\r
+       {\r
+               return FALSE;\r
+       }\r
+       return yfsd_DoFindFile(pSearch,pfd);\r
+}\r
+\r
+BOOL YFSD_FindClose( PSEARCH pSearch )\r
+{      \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FindClose\r\n"));\r
+       if(!pSearch)\r
+       {\r
+               return FALSE;\r
+       }\r
+       yfsd_DeleteFinder(pSearch);\r
+       return TRUE;\r
+}\r
+\r
+\r
+HANDLE YFSD_CreateFileW( \r
+       PVOLUME pVolume, \r
+       HANDLE hProc, \r
+       PCWSTR pwsFileName, \r
+       DWORD dwAccess, \r
+       DWORD dwShareMode,\r
+       PSECURITY_ATTRIBUTES pSecurityAttributes, // ignore\r
+       DWORD dwCreate,\r
+       DWORD dwFlagsAndAttributes, \r
+       HANDLE hTemplateFile ) // ignore\r
+{\r
+\r
+\r
+       yaffs_Object *parent = NULL;\r
+       yaffs_Object *obj = NULL;\r
+       char name[YFSD_NAME_LENGTH+1];\r
+       int mode;\r
+       yfsd_WinFile *f = NULL;\r
+       HANDLE handle = INVALID_HANDLE_VALUE;\r
+       unsigned modifiedTime[2];\r
+       unsigned objSize;\r
+\r
+       BOOL writePermitted = (dwAccess & GENERIC_WRITE) ? TRUE : FALSE;\r
+       BOOL readPermitted = (dwAccess & GENERIC_READ) ? TRUE : FALSE;\r
+       BOOL shareRead = (dwShareMode & FILE_SHARE_READ) ? TRUE : FALSE;\r
+       BOOL shareWrite = (dwShareMode & FILE_SHARE_WRITE) ? TRUE : FALSE;\r
+\r
+       BOOL openRead, openWrite, openReadAllowed, openWriteAllowed;\r
+\r
+       BOOL fileCreated = FALSE;\r
+       \r
+       BOOL fAlwaysCreateOnExistingFile = FALSE;\r
+       BOOL fTruncateExistingFile = FALSE;\r
+\r
+\r
+       mode = dwFlagsAndAttributes & 0x00FFFFFF;  // ding off the flags\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile (%s) flags %X mode %X\r\n", pwsFileName,dwFlagsAndAttributes,mode));\r
+       if(writePermitted)\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile write permitted\r\n"));\r
+       }\r
+       else\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile write not permitted\r\n"));\r
+       }\r
+\r
+       if(!yfsd_CheckValidAttributes(mode))\r
+       {\r
+                       SetLastError(ERROR_INVALID_PARAMETER);\r
+                       return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+\r
+       parent = yfsd_FindDirectoryByWinPath(&pVolume->dev,pwsFileName,name,YFSD_NAME_LENGTH);\r
+\r
+\r
+       if(parent && yfsd_NameIsValid(name))\r
+       {\r
+\r
+               //slf021220b begin Fix still more bugs in CreateFile.\r
+               // Get the object for this file if it exists (only once).\r
+               obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+               //slf021220b end Fix still more bugs in CreateFile.\r
+               if(dwCreate == CREATE_NEW)\r
+               {\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file in CREATE_NEW\r\n"));\r
+\r
+                       //slf021101c begin\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       if(!obj)\r
+                       {\r
+                               obj = yaffs_MknodFile(parent,name,mode,0,0);\r
+                               if(!obj)\r
+                                       SetLastError(ERROR_DISK_FULL);\r
+                               fileCreated = TRUE;\r
+                       }\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)\r
+                       {\r
+                               obj = NULL;\r
+                               SetLastError(ERROR_ALREADY_EXISTS);\r
+                       }\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       else\r
+                       {\r
+                               obj = NULL;\r
+                               //slf021220b begin Fix still more bugs in CreateFile.\r
+                               //Match CE FAT error return SetLastError(ERROR_ALREADY_EXISTS);\r
+                               SetLastError(ERROR_FILE_EXISTS);\r
+                               //slf021220b begin Fix still more bugs in CreateFile.\r
+                       }\r
+                       //slf021101c end\r
+               }\r
+               else if( dwCreate == OPEN_ALWAYS)\r
+               {\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       if(!obj)\r
+                       {\r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file in OPEN_ALWAYS\r\n"));\r
+                               obj = yaffs_MknodFile(parent,name,mode,0,0);\r
+                               if(!obj)\r
+                                       SetLastError(ERROR_DISK_FULL);\r
+                               fileCreated = TRUE;\r
+\r
+                       }\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)\r
+                       {\r
+                               obj = NULL;\r
+                               SetLastError(ERROR_ACCESS_DENIED);\r
+                       }\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       else\r
+                       {\r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile opening existing file in OPEN_ALWAYS\r\n"));\r
+                       }\r
+               }\r
+               else if(dwCreate == OPEN_EXISTING)\r
+               {\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile opening file in OPEN_EXISTING\r\n"));\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       if(!obj)\r
+                               SetLastError(ERROR_FILE_NOT_FOUND);\r
+               //slf021220b begin Fix still more bugs in CreateFile.\r
+            //slf021101c begin\r
+           //                  else\r
+           //                          if (yfsd_GetObjectWinAttributes(obj) & FILE_ATTRIBUTE_DIRECTORY)\r
+           //                          {\r
+           //                                  SetLastError(ERROR_ACCESS_DENIED);\r
+           //                                  obj = NULL;\r
+           //                          }\r
+            //slf021101c end\r
+                       else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)\r
+                       {\r
+                               SetLastError(ERROR_ACCESS_DENIED);\r
+                               obj = NULL;\r
+                       }\r
+               //slf021220b end Fix still more bugs in CreateFile.\r
+               }\r
+               else if(dwCreate == TRUNCATE_EXISTING)\r
+               {\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile opening file in TRUNCATE_EXISTING\r\n"));\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+                       //if(obj)\r
+                       if (!writePermitted || (obj  && (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)))\r
+                       {\r
+                               obj = NULL;\r
+                               SetLastError(ERROR_ACCESS_DENIED);\r
+                       }\r
+                       else if(obj)\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       {\r
+                               // Indicate that file is to be truncated.  This will happen later on assuming\r
+                               // that a sharing violation does not occur and that we can get a file handle.\r
+                               fTruncateExistingFile = TRUE;\r
+                       }\r
+                       else \r
+                       {\r
+                               SetLastError(ERROR_FILE_NOT_FOUND);\r
+                       }\r
+               }\r
+               else if(dwCreate == CREATE_ALWAYS)\r
+               {\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       // got above. obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+\r
+                       if(!obj)\r
+                       {\r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile creating file parent %X, name %a in CREATE_ALWAYS\r\n",parent,name));\r
+                               obj = yaffs_MknodFile(parent,name,mode,0,0);\r
+                               if(!obj)\r
+                                       SetLastError(ERROR_DISK_FULL);\r
+                               fileCreated = TRUE;\r
+                       }\r
+                       //slf021220b begin Fix still more bugs in CreateFile.\r
+                       else if (obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)\r
+                       {\r
+                               obj = NULL;\r
+                               SetLastError(ERROR_ACCESS_DENIED);\r
+                       }\r
+                       //slf021220b end Fix still more bugs in CreateFile.\r
+                       else\r
+                       {                       \r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile in CREATE_ALWAYS (already exists)\r\n"));\r
+                               // Indicate that file is to be recreated.  This will happen later on assuming\r
+                               // that a sharing violation does not occur and that we can get a file handle.\r
+                               fAlwaysCreateOnExistingFile = TRUE;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile called with unknown flags %x\r\n", dwCreate));\r
+                               SetLastError(ERROR_INVALID_PARAMETER);\r
+               }\r
+       }\r
+       else\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile unable to get parent node\r\n"));\r
+               SetLastError(ERROR_PATH_NOT_FOUND);\r
+       }\r
+\r
+       if(obj)\r
+       {\r
+                       int i;\r
+                       yfsd_WinFile *p;\r
+                       openRead = openWrite =0;\r
+                       openReadAllowed = openWriteAllowed = 1;\r
+\r
+                       for(i = 0; i < MAX_WIN_FILE; i++)\r
+                       {\r
+                                       p = &yfsd_winFile[i];\r
+\r
+                                       if(p->obj == obj)\r
+                                       {\r
+                                               if (p->readPermitted) openRead = 1;\r
+                                               if (p->writePermitted) openWrite = 1;\r
+                                               if (!p->shareRead) openReadAllowed = 0;\r
+                                               if (!p->shareWrite) openWriteAllowed = 0;\r
+                                       }\r
+\r
+                       }\r
+\r
+                       // Now we test if the share works out.\r
+\r
+                       if((openRead && !shareRead) ||   // already open for read, but we are not prepared to share it for read\r
+                          (openWrite && !shareWrite) || // already open for write, but we are not prepared to share it for write\r
+                          (!openReadAllowed && readPermitted) || // already open with read sharing not permitted\r
+                          (!openWriteAllowed && writePermitted)) // same... write\r
+                       {\r
+                               //slf021220c begin Fix error code for new sharing mode check code.\r
+                               SetLastError(ERROR_SHARING_VIOLATION);\r
+                               //slf021220c end Fix error code for new sharing mode check code.\r
+                               obj = NULL;\r
+                       }\r
+\r
+\r
+       }\r
+       if(obj)\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have an object\r\n"));\r
+               f = yfsd_GetWinFile();\r
+       }\r
+       else\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::Creatfile - no object\r\n"));\r
+       }\r
+\r
+       if(f)\r
+       {\r
+\r
+               handle = FSDMGR_CreateFileHandle(pVolume->mgrVolume,hProc,f);\r
+\r
+               if(handle != INVALID_HANDLE_VALUE)\r
+               {\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have an fsdmgr handle\r\n"));\r
+\r
+                       if (fTruncateExistingFile)\r
+                       {\r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - TRUNCATE_EXISTING - truncating existing file\r\n"));\r
+                               yaffs_ResizeFile(obj,0);\r
+                       }\r
+                       \r
+                       if (fAlwaysCreateOnExistingFile)\r
+                       {\r
+                               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - CREATE_ALWAYS - zapping existing file\r\n"));\r
+                               obj->st_mode = mode;\r
+                               obj->dirty = 1;\r
+                               yaffs_ResizeFile(obj,0);\r
+                               yaffs_FlushFile(obj,1);\r
+                       }\r
+                                               \r
+                       f->obj = obj;\r
+                       f->offset = 0;\r
+                       f->writePermitted = writePermitted;\r
+                       //slf021220d begin oops typo.\r
+                       f->readPermitted = readPermitted;\r
+                       //slf021220d end oops typo.\r
+                       f->shareRead= shareRead;\r
+                       f->shareWrite = shareWrite;\r
+                       f->myVolume = pVolume;\r
+                       obj->inUse++;\r
+\r
+                       modifiedTime[0] = obj->win_mtime[0];\r
+                       modifiedTime[1] = obj->win_mtime[1];\r
+                       objSize = yaffs_GetObjectFileLength(obj);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - file size %d\r\n",objSize));\r
+               }\r
+               else\r
+               {\r
+                       yfsd_PutWinFile(f);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have no fsdmgr handle\r\n"));\r
+               }\r
+\r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       if(handle != INVALID_HANDLE_VALUE && \r
+          fileCreated &&\r
+          pVolume->shellFunction)\r
+       {\r
+                       FILECHANGEINFO fc;\r
+                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+\r
+                       fc.cbSize = sizeof(FILECHANGEINFO);\r
+                       fc.wEventId = SHCNE_CREATE;\r
+                       fc.uFlags = SHCNF_PATH;\r
+                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);\r
+                       fc.dwItem2 = 0;\r
+                       fc.dwAttributes = mode;\r
+                       yfsd_U32sToWinFileTime(modifiedTime,&fc.ftModified);\r
+                       fc.nFileSize = objSize;\r
+\r
+                       pVolume->shellFunction(&fc);\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));\r
+\r
+                       yfsd_ShellDirectoryChanged(pVolume,fpn);\r
+       }\r
+\r
+       if(handle != INVALID_HANDLE_VALUE && (fileCreated || writePermitted))\r
+       {\r
+                       // Remember the name\r
+\r
+                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+                       int slen;\r
+\r
+                       yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);\r
+                       slen = wcslen(fpn);\r
+                       f->fullName = malloc((slen+1)* sizeof(WCHAR));\r
+                       if(f->fullName)\r
+                       {\r
+                               wcscpy(f->fullName,fpn);\r
+                       }\r
+\r
+       }\r
+\r
+\r
+       return handle;\r
+\r
+}\r
+\r
+BOOL yfsd_DoReadFile( \r
+       PFILE pFile, \r
+       PVOID pBuffer, \r
+       DWORD cbRead, \r
+       PDWORD pcbRead)\r
+{\r
+       \r
+       DWORD maxRead;\r
+       int nread = 0;\r
+       yaffs_Object *obj = NULL;\r
+\r
+\r
+       if(pcbRead)\r
+       {\r
+               *pcbRead = 0;\r
+       }\r
+       else\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::DoReadFile pcbRead was NULL. naughty.\r\n"));\r
+       }\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::DoReadFile %d bytes\r\n",cbRead));\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+       \r
+       obj = pFile->obj;\r
+\r
+       if(yaffs_GetObjectFileLength(obj) > pFile->offset)\r
+       {\r
+               maxRead = yaffs_GetObjectFileLength(obj) - pFile->offset;\r
+       }\r
+       else\r
+       {\r
+               maxRead = 0;\r
+       }\r
+\r
+       if(cbRead > maxRead)\r
+       {\r
+               cbRead = maxRead;\r
+       }\r
+       \r
+       if(maxRead > 0)\r
+       {\r
+               nread = yaffs_ReadDataFromFile(obj,pBuffer,pFile->offset,cbRead);\r
+               if(nread > 0)\r
+               {\r
+                       pFile->offset += nread;\r
+\r
+                       if(pcbRead)\r
+                       {\r
+                               *pcbRead = nread;\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if(pcbRead) \r
+               {\r
+                       *pcbRead = maxRead;\r
+               }\r
+       }\r
+\r
+\r
+       return nread < 0? FALSE : TRUE; \r
+\r
+}\r
+\r
+BOOL YFSD_ReadFile( \r
+       PFILE pFile, \r
+       PVOID pBuffer, \r
+       DWORD cbRead, \r
+       PDWORD pcbRead, \r
+       OVERLAPPED *pOverlapped ) //ignore\r
+{\r
+       BOOL result;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::ReadFile\r\n"));\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       result = yfsd_DoReadFile(pFile,pBuffer,cbRead,pcbRead);\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       return result;\r
+}\r
+\r
+BOOL YFSD_ReadFileWithSeek( \r
+       PFILE pFile, \r
+       PVOID pBuffer, \r
+       DWORD cbRead, \r
+       PDWORD pcbRead, \r
+       OVERLAPPED *pOverlapped, \r
+       DWORD dwLowOffset, \r
+       DWORD dwHighOffset )\r
+{\r
+       BOOL result;\r
+       DWORD rememberedOffset;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::ReadFileWithSeek %d bytes at %d high %d pcbRead %X\r\n",cbRead,dwLowOffset,dwHighOffset,pcbRead));\r
+\r
+       // To determine if paging is supported, the kernel calls this with all parameters except pFile\r
+       // being zero.\r
+       if(!pBuffer && !cbRead && !pcbRead && !pOverlapped && !dwLowOffset && !dwHighOffset)\r
+       {\r
+               return TRUE; // paging suppported\r
+               //return FALSE; // paging not supported\r
+       }\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       rememberedOffset = pFile->offset;\r
+\r
+       pFile->offset = dwLowOffset;\r
+       // ignore high offset for now\r
+\r
+       result = yfsd_DoReadFile(pFile,pBuffer,cbRead,pcbRead);\r
+\r
+       //pFile->offset = rememberedOffset;\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       return result;\r
+\r
+\r
+}\r
+\r
+\r
+BOOL yfsd_DoWriteFile( \r
+       PFILE pFile, \r
+       PCVOID pBuffer, \r
+       DWORD cbWrite, \r
+       PDWORD pcbWritten)\r
+{\r
+       int nwritten = 0;\r
+       yaffs_Object *obj = NULL;\r
+       \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::DoWriteFile size %d\r\n",cbWrite));\r
+       \r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       if(!pFile->writePermitted)\r
+       {\r
+                       *pcbWritten = 0;\r
+                       SetLastError(ERROR_ACCESS_DENIED);\r
+                       return FALSE;\r
+       }\r
+\r
+       obj = pFile->obj;\r
+\r
+       *pcbWritten = 0;\r
+\r
+\r
+               nwritten = yaffs_WriteDataToFile(obj,pBuffer,pFile->offset,cbWrite);\r
+               if(nwritten >= 0)\r
+               {\r
+                       pFile->offset += nwritten;\r
+                       *pcbWritten = nwritten;\r
+               }\r
+               if(nwritten != cbWrite)\r
+               {\r
+                       SetLastError(ERROR_DISK_FULL);\r
+               }\r
+\r
+\r
+       return nwritten != cbWrite? FALSE : TRUE; \r
+}\r
+\r
+\r
+BOOL YFSD_WriteFile( \r
+       PFILE pFile, \r
+       PCVOID pBuffer, \r
+       DWORD cbWrite, \r
+       PDWORD pcbWritten, \r
+       OVERLAPPED *pOverlapped )\r
+{\r
+       BOOL result;\r
+\r
+       yfsd_LockYAFFS();\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::WriteFile\r\n"));\r
+\r
+       result = yfsd_DoWriteFile(pFile,pBuffer,cbWrite,pcbWritten);\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       return result;\r
+}\r
+\r
+BOOL YFSD_WriteFileWithSeek( \r
+       PFILE pFile, \r
+       PCVOID pBuffer, \r
+       DWORD cbWrite, \r
+       PDWORD pcbWritten, \r
+       OVERLAPPED *pOverlapped,\r
+       DWORD dwLowOffset, \r
+       DWORD dwHighOffset )\r
+{\r
+       BOOL result;\r
+       DWORD rememberedOffset;\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::WriteFileWithSeek %d bytes at %d,%d pcbWritten %X\r\n",cbWrite,dwHighOffset,dwLowOffset,pcbWritten));\r
+\r
+       \r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       rememberedOffset = pFile->offset;\r
+\r
+       pFile->offset = dwLowOffset;\r
+       // ignore high offset for now\r
+\r
+       result = yfsd_DoWriteFile(pFile,pBuffer,cbWrite,pcbWritten);\r
+\r
+       //pFile->offset = rememberedOffset;\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       return result;\r
+}\r
+\r
+DWORD YFSD_SetFilePointer( \r
+       PFILE pFile, \r
+       LONG lDistanceToMove, \r
+       PLONG pDistanceToMoveHigh, \r
+       DWORD dwMoveMethod )\r
+{\r
+       // ignore high offset for now\r
+\r
+       DWORD offset = 0xFFFFFFFF;\r
+       DWORD oldPos;\r
+       int fileSize;\r
+       int seekNegative = 0;\r
+\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return offset;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+\r
+       oldPos = pFile->offset;\r
+\r
+       if(dwMoveMethod == FILE_BEGIN)\r
+       {\r
+               if(lDistanceToMove >= 0)\r
+               {       \r
+                       offset = pFile->offset = lDistanceToMove;\r
+               }\r
+               else\r
+               {\r
+                       seekNegative = 1;\r
+               }\r
+       }\r
+       else if(dwMoveMethod == FILE_END)\r
+       {\r
+               fileSize = yaffs_GetObjectFileLength(pFile->obj);\r
+               if(fileSize >= 0 &&\r
+                  (fileSize + lDistanceToMove) >= 0)\r
+               {\r
+                       offset = pFile->offset = fileSize + lDistanceToMove;\r
+               }\r
+               else\r
+               {\r
+                       seekNegative = 1;\r
+               }\r
+       }\r
+       else if(dwMoveMethod == FILE_CURRENT)\r
+       {\r
+               if(pFile->offset + lDistanceToMove >= 0)\r
+               {\r
+                       offset = pFile->offset = pFile->offset + lDistanceToMove;               \r
+               }\r
+               else\r
+               {\r
+                               seekNegative = 1;\r
+               }\r
+       }\r
+\r
+       if(seekNegative)\r
+       {\r
+                       SetLastError(ERROR_NEGATIVE_SEEK);\r
+                       \r
+       }\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::SetFilePtr method %d distance %d high %X oldpos %d newpos %d\r\n",\r
+                                 dwMoveMethod,lDistanceToMove,pDistanceToMoveHigh,oldPos,offset));\r
+\r
+       return offset;\r
+\r
+}\r
+\r
+DWORD YFSD_GetFileSize( \r
+       PFILE pFile, \r
+       PDWORD pFileSizeHigh )\r
+{\r
+       int fileSize;\r
+       \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileSize high %X\r\n",pFileSizeHigh));\r
+       \r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return -1;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       fileSize = yaffs_GetObjectFileLength(pFile->obj);\r
+\r
+       yfsd_UnlockYAFFS();\r
+       if(pFileSizeHigh)\r
+                *pFileSizeHigh = 0;\r
+\r
+       return fileSize;\r
+\r
+}\r
+\r
+\r
+BOOL YFSD_GetFileInformationByHandle( \r
+       PFILE pFile,\r
+       PBY_HANDLE_FILE_INFORMATION pFileInfo )\r
+{\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileInfoByHandle\r\n"));\r
+\r
+       if(!pFile || !pFile->obj || !pFileInfo)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\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
+       pFileInfo->dwOID = (CEOID)(INVALID_HANDLE_VALUE);\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       return TRUE;\r
+}\r
+\r
+BOOL YFSD_FlushFileBuffers(PFILE pFile )\r
+{\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
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::FlushFileBuffers\r\n"));\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       yaffs_FlushFile(pFile->obj,1);\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_UnlockYAFFS();\r
+       \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
+       \r
+       return TRUE;\r
+}\r
+\r
+BOOL YFSD_GetFileTime( \r
+       PFILE pFile, \r
+       FILETIME *pCreation, \r
+       FILETIME *pLastAccess, \r
+       FILETIME *pLastWrite )\r
+{\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileTime\r\n"));\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       if(pCreation) yfsd_U32sToWinFileTime(pFile->obj->win_ctime,pCreation);\r
+       if(pLastAccess) yfsd_U32sToWinFileTime(pFile->obj->win_atime,pLastAccess);\r
+       if(pLastWrite) yfsd_U32sToWinFileTime(pFile->obj->win_mtime,pLastWrite);\r
+\r
+       yfsd_UnlockYAFFS();\r
+\r
+       return TRUE;\r
+}\r
+\r
+BOOL YFSD_SetFileTime( \r
+       PFILE pFile, \r
+       CONST FILETIME *pCreation, \r
+       CONST FILETIME *pLastAccess, \r
+       CONST FILETIME *pLastWrite )\r
+{\r
+       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];\r
+       int nameExists = 0;\r
+       int result = FALSE;\r
+       yfsd_Volume *vol = NULL;\r
+       DWORD attribs = 0;\r
+       DWORD objSize = 0;\r
+       DWORD mtime[2];\r
+\r
+       \r
+       RETAILMSG (MSGSTATE, (L"YAFFS::SetFileTime\r\n"));\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+       \r
+       \r
+       yfsd_LockYAFFS();\r
+\r
+       if(pCreation) \r
+       {\r
+                yfsd_WinFileTimeToU32s(pCreation,pFile->obj->win_ctime);\r
+               pFile->obj->dirty = 1;\r
+       }\r
+       if(pLastAccess)\r
+       {\r
+               yfsd_WinFileTimeToU32s(pLastAccess,pFile->obj->win_atime);\r
+               pFile->obj->dirty = 1;\r
+       }\r
+       if(pLastWrite)\r
+       {\r
+               yfsd_WinFileTimeToU32s(pLastWrite,pFile->obj->win_mtime);\r
+               pFile->obj->dirty = 1;\r
+       }\r
+       if(pCreation || pLastAccess || pLastWrite)\r
+       {\r
+               result = yaffs_FlushFile(pFile->obj,0);\r
+       }\r
+\r
+       if(result)\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
+       yfsd_UnlockYAFFS();\r
+\r
+       // Call shell function\r
+       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
+\r
+       return TRUE;\r
+}\r
+   \r
+BOOL YFSD_SetEndOfFile( \r
+PFILE pFile )\r
+{\r
+\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
+       static unsigned char zeros[512];\r
+\r
+       int result;\r
+       BOOL retVal = FALSE;\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF\r\n"));\r
+\r
+       if(!pFile || !pFile->obj)\r
+       {\r
+               SetLastError(ERROR_INVALID_HANDLE);\r
+               return FALSE;\r
+       }\r
+\r
+       yfsd_LockYAFFS();\r
+       result = yaffs_ResizeFile(pFile->obj,pFile->offset);\r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF resizing to %d, result %d\r\n",pFile->offset,result));\r
+\r
+       // Resize only works if we're shortening the file.\r
+       // If the result is shorter than the offset, then we need to write zeros....\r
+       // \r
+       if(result != pFile->offset)\r
+       {\r
+               if(result < pFile->offset)\r
+               {\r
+\r
+                       int nBytes = pFile->offset - result;\r
+                       int thisWriteSize;\r
+                       int written;\r
+                       BOOL ok = TRUE;\r
+\r
+                       memset(zeros,0,512);\r
+\r
+                       pFile->offset = result;\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF expanding file by %d bytes\r\n",nBytes));\r
+                       while(nBytes > 0 && ok)\r
+                       {\r
+                               thisWriteSize = (nBytes > 512) ? 512  : nBytes;\r
+\r
+                               ok = yfsd_DoWriteFile(pFile,zeros,thisWriteSize,&written);      \r
+                               if(written != thisWriteSize)\r
+                               {\r
+                                       ok = FALSE;\r
+                               }\r
+\r
+                               nBytes -= thisWriteSize;\r
+                       }\r
+\r
+                       retVal = ok;\r
+               }\r
+               else\r
+               {\r
+\r
+                       SetLastError(ERROR_ACCESS_DENIED);\r
+                       retVal = FALSE;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               retVal = TRUE;\r
+       }\r
+       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
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF file size %d\r\n",yaffs_GetObjectFileLength(pFile->obj)));\r
+\r
+\r
+       \r
+       return retVal;\r
+}\r
+\r
+BOOL YFSD_DeviceIoControl( \r
+       PFILE pFile, \r
+       DWORD dwIoControlCode, \r
+       PVOID pInBuf, \r
+       DWORD nInBufSize, \r
+       PVOID pOutBuf, \r
+       DWORD nOutBufSize, \r
+       PDWORD pBytesReturned, \r
+       OVERLAPPED *pOverlapped )\r
+{\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::DeviceIoControl\r\n"));\r
+\r
+       return FALSE;\r
+}\r
+\r
+BOOL YFSD_CloseFile( PFILE pFile )\r
+{\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
+       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile %X\r\n",pFile));\r
+\r
+       yfsd_LockYAFFS();\r
+\r
+       if(!pFile)\r
+       {\r
+               RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile null pFile\r\n"));\r
+       }\r
+       else\r
+       {\r
+               if(pFile->obj)\r
+               {\r
+                       pFile->obj->inUse--;\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile on obj\r\n"));\r
+                       yaffs_FlushFile(pFile->obj,1);\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
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile on obj done, size is %d\r\n",objSize));\r
+                       if(pFile->fullName)\r
+                       {\r
+                               wcscpy(fpn,pFile->fullName);\r
+                               nameExists = 1;\r
+                       }\r
+                       vol = pFile->myVolume;\r
+                       yfsd_PutWinFile(pFile);\r
+               }\r
+               else\r
+               {\r
+                       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile null obj\r\n"));\r
+               }\r
+\r
+       }\r
+       yfsd_UnlockYAFFS();\r
+\r
+\r
+       if(nameExists && 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
+\r
+       \r
+\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile done\r\n"));\r
+\r
+       return TRUE;\r
+\r
+}\r
+\r
+\r
+BOOL YFSD_CloseVolume(PVOLUME pVolume )\r
+{\r
+       RETAILMSG (MSGSTATE, (L"YAFFS::CloseVolume\r\n"));\r
+       yfsd_FlushAllFiles();\r
+       return TRUE;\r
+}\r
 \r
-       }
-       if(obj)
-       {
-               RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have an object\r\n"));
-               f = yfsd_GetWinFile();
-       }
-       else
-       {
-               RETAILMSG (MSGSTATE, (L"YAFFS::Creatfile - no object\r\n"));
-       }
-
-       if(f)
-       {
-
-               handle = FSDMGR_CreateFileHandle(pVolume->mgrVolume,hProc,f);
-
-               if(handle != INVALID_HANDLE_VALUE)
-               {
-                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have an fsdmgr handle\r\n"));
-                       f->obj = obj;
-                       f->offset = 0;
-                       f->writePermitted = writePermitted;\r
-                       f->readPermitted = writePermitted;\r
-                       f->shareRead= shareRead;\r
-                       f->shareWrite = shareWrite;\r
-                       f->myVolume = pVolume;
-                       obj->inUse++;
-
-                       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));
-               }
-               else
-               {
-                       yfsd_PutWinFile(f);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::CreateFile - we have no fsdmgr handle\r\n"));
-               }
-
-       }
-
-       yfsd_UnlockYAFFS();
-
-       if(handle != INVALID_HANDLE_VALUE && 
-          fileCreated &&
-          pVolume->shellFunction)
-       {
-                       FILECHANGEINFO fc;
-                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
-
-                       fc.cbSize = sizeof(FILECHANGEINFO);
-                       fc.wEventId = SHCNE_CREATE;
-                       fc.uFlags = SHCNF_PATH;
-                       fc.dwItem1 = (DWORD)yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);
-                       fc.dwItem2 = 0;
-                       fc.dwAttributes = mode;
-                       yfsd_U32sToWinFileTime(modifiedTime,&fc.ftModified);
-                       fc.nFileSize = objSize;
-
-                       pVolume->shellFunction(&fc);
-                       RETAILMSG (MSGSTATE, (L"YAFFS::shell function called\r\n"));
-
-                       yfsd_ShellDirectoryChanged(pVolume,fpn);
-       }
-
-       if(handle != INVALID_HANDLE_VALUE && (fileCreated || writePermitted))
-       {
-                       // Remember the name
-
-                       WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE];
-                       int slen;
-
-                       yfsd_FullPathName(pVolume,fpn,YFSD_FULL_PATH_NAME_SIZE,pwsFileName);
-                       slen = wcslen(fpn);
-                       f->fullName = malloc((slen+1)* sizeof(WCHAR));
-                       if(f->fullName)
-                       {
-                               wcscpy(f->fullName,fpn);
-                       }
-
-       }
-
-
-       return handle;
-
-}
-
-BOOL yfsd_DoReadFile( 
-       PFILE pFile, 
-       PVOID pBuffer, 
-       DWORD cbRead, 
-       PDWORD pcbRead)
-{
-       
-       DWORD maxRead;
-       int nread = 0;
-       yaffs_Object *obj = NULL;
-
-
-       if(pcbRead)
-       {
-               *pcbRead = 0;
-       }
-       else
-       {
-               RETAILMSG (MSGSTATE, (L"YAFFS::DoReadFile pcbRead was NULL. naughty.\r\n"));
-       }
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::DoReadFile %d bytes\r\n",cbRead));
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-       
-       obj = pFile->obj;
-
-       if(yaffs_GetObjectFileLength(obj) > pFile->offset)
-       {
-               maxRead = yaffs_GetObjectFileLength(obj) - pFile->offset;
-       }
-       else
-       {
-               maxRead = 0;
-       }
-
-       if(cbRead > maxRead)
-       {
-               cbRead = maxRead;
-       }
-       
-       if(maxRead > 0)
-       {
-               nread = yaffs_ReadDataFromFile(obj,pBuffer,pFile->offset,cbRead);
-               if(nread > 0)
-               {
-                       pFile->offset += nread;
-
-                       if(pcbRead)
-                       {
-                               *pcbRead = nread;
-                       }
-               }
-       }
-       else
-       {
-               if(pcbRead) 
-               {
-                       *pcbRead = maxRead;
-               }
-       }
-
-
-       return nread < 0? FALSE : TRUE; 
-
-}
-
-BOOL YFSD_ReadFile( 
-       PFILE pFile, 
-       PVOID pBuffer, 
-       DWORD cbRead, 
-       PDWORD pcbRead, 
-       OVERLAPPED *pOverlapped ) //ignore
-{
-       BOOL result;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::ReadFile\r\n"));
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       yfsd_LockYAFFS();
-
-       result = yfsd_DoReadFile(pFile,pBuffer,cbRead,pcbRead);
-
-       yfsd_UnlockYAFFS();
-
-       return result;
-}
-
-BOOL YFSD_ReadFileWithSeek( 
-       PFILE pFile, 
-       PVOID pBuffer, 
-       DWORD cbRead, 
-       PDWORD pcbRead, 
-       OVERLAPPED *pOverlapped, 
-       DWORD dwLowOffset, 
-       DWORD dwHighOffset )
-{
-       BOOL result;
-       DWORD rememberedOffset;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::ReadFileWithSeek %d bytes at %d high %d pcbRead %X\r\n",cbRead,dwLowOffset,dwHighOffset,pcbRead));
-
-       // To determine if paging is supported, the kernel calls this with all parameters except pFile
-       // being zero.
-       if(!pBuffer && !cbRead && !pcbRead && !pOverlapped && !dwLowOffset && !dwHighOffset)
-       {
-               return TRUE; // paging suppported
-               //return FALSE; // paging not supported
-       }
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       yfsd_LockYAFFS();
-
-       rememberedOffset = pFile->offset;
-
-       pFile->offset = dwLowOffset;
-       // ignore high offset for now
-
-       result = yfsd_DoReadFile(pFile,pBuffer,cbRead,pcbRead);
-
-       //pFile->offset = rememberedOffset;
-
-       yfsd_UnlockYAFFS();
-
-       return result;
-
-
-}
-
-
-BOOL yfsd_DoWriteFile( 
-       PFILE pFile, 
-       PCVOID pBuffer, 
-       DWORD cbWrite, 
-       PDWORD pcbWritten)
-{
-       int nwritten = 0;
-       yaffs_Object *obj = NULL;
-       
-       RETAILMSG (MSGSTATE, (L"YAFFS::DoWriteFile size %d\r\n",cbWrite));
-       
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       if(!pFile->writePermitted)
-       {
-                       *pcbWritten = 0;
-                       SetLastError(ERROR_ACCESS_DENIED);
-                       return FALSE;
-       }
-
-       obj = pFile->obj;
-
-       *pcbWritten = 0;
-
-
-               nwritten = yaffs_WriteDataToFile(obj,pBuffer,pFile->offset,cbWrite);
-               if(nwritten >= 0)
-               {
-                       pFile->offset += nwritten;
-                       *pcbWritten = nwritten;
-               }
-               if(nwritten != cbWrite)
-               {
-                       SetLastError(ERROR_DISK_FULL);
-               }
-
-
-       return nwritten != cbWrite? FALSE : TRUE; 
-}
-
-
-BOOL YFSD_WriteFile( 
-       PFILE pFile, 
-       PCVOID pBuffer, 
-       DWORD cbWrite, 
-       PDWORD pcbWritten, 
-       OVERLAPPED *pOverlapped )
-{
-       BOOL result;
-
-       yfsd_LockYAFFS();
-       RETAILMSG (MSGSTATE, (L"YAFFS::WriteFile\r\n"));
-
-       result = yfsd_DoWriteFile(pFile,pBuffer,cbWrite,pcbWritten);
-
-       yfsd_UnlockYAFFS();
-
-       return result;
-}
-
-BOOL YFSD_WriteFileWithSeek( 
-       PFILE pFile, 
-       PCVOID pBuffer, 
-       DWORD cbWrite, 
-       PDWORD pcbWritten, 
-       OVERLAPPED *pOverlapped,
-       DWORD dwLowOffset, 
-       DWORD dwHighOffset )
-{
-       BOOL result;
-       DWORD rememberedOffset;
-       RETAILMSG (MSGSTATE, (L"YAFFS::WriteFileWithSeek %d bytes at %d,%d pcbWritten %X\r\n",cbWrite,dwHighOffset,dwLowOffset,pcbWritten));
-
-       
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       yfsd_LockYAFFS();
-
-       rememberedOffset = pFile->offset;
-
-       pFile->offset = dwLowOffset;
-       // ignore high offset for now
-
-       result = yfsd_DoWriteFile(pFile,pBuffer,cbWrite,pcbWritten);
-
-       //pFile->offset = rememberedOffset;
-
-       yfsd_UnlockYAFFS();
-
-       return result;
-}
-
-DWORD YFSD_SetFilePointer( 
-       PFILE pFile, 
-       LONG lDistanceToMove, 
-       PLONG pDistanceToMoveHigh, 
-       DWORD dwMoveMethod )
-{
-       // ignore high offset for now
-
-       DWORD offset = 0xFFFFFFFF;
-       DWORD oldPos;
-       int fileSize;
-       int seekNegative = 0;
-
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return offset;
-       }
-
-       yfsd_LockYAFFS();
-
-
-       oldPos = pFile->offset;
-
-       if(dwMoveMethod == FILE_BEGIN)
-       {
-               if(lDistanceToMove >= 0)
-               {       
-                       offset = pFile->offset = lDistanceToMove;
-               }
-               else
-               {
-                       seekNegative = 1;
-               }
-       }
-       else if(dwMoveMethod == FILE_END)
-       {
-               fileSize = yaffs_GetObjectFileLength(pFile->obj);
-               if(fileSize >= 0 &&
-                  (fileSize + lDistanceToMove) >= 0)
-               {
-                       offset = pFile->offset = fileSize + lDistanceToMove;
-               }
-               else
-               {
-                       seekNegative = 1;
-               }
-       }
-       else if(dwMoveMethod == FILE_CURRENT)
-       {
-               if(pFile->offset + lDistanceToMove >= 0)
-               {
-                       offset = pFile->offset = pFile->offset + lDistanceToMove;               
-               }
-               else
-               {
-                               seekNegative = 1;
-               }
-       }
-
-       if(seekNegative)
-       {
-                       SetLastError(ERROR_NEGATIVE_SEEK);
-                       
-       }
-
-       yfsd_UnlockYAFFS();
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::SetFilePtr method %d distance %d high %X oldpos %d newpos %d\r\n",
-                                 dwMoveMethod,lDistanceToMove,pDistanceToMoveHigh,oldPos,offset));
-
-       return offset;
-
-}
-
-DWORD YFSD_GetFileSize( 
-       PFILE pFile, 
-       PDWORD pFileSizeHigh )
-{
-       int fileSize;
-       
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileSize high %X\r\n",pFileSizeHigh));
-       
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return -1;
-       }
-
-       yfsd_LockYAFFS();
-
-       fileSize = yaffs_GetObjectFileLength(pFile->obj);
-
-       yfsd_UnlockYAFFS();
-       if(pFileSizeHigh)
-                *pFileSizeHigh = 0;
-
-       return fileSize;
-
-}
-
-
-BOOL YFSD_GetFileInformationByHandle( 
-       PFILE pFile,
-       PBY_HANDLE_FILE_INFORMATION pFileInfo )
-{
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileInfoByHandle\r\n"));
-
-       if(!pFile || !pFile->obj || !pFileInfo)
-       {
-               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;\r
-//slf021104a Begin Window CE 4.0 added an additional field.\r
-#if _WINCEOSVER >= 400
-       pFileInfo->dwOID = (CEOID)(INVALID_HANDLE_VALUE);\r
-#endif\r
-//slf021104a end\r
-
-       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];
-
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::FlushFileBuffers\r\n"));
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       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);
-       }
-
-       
-       return TRUE;
-}
-
-BOOL YFSD_GetFileTime( 
-       PFILE pFile, 
-       FILETIME *pCreation, 
-       FILETIME *pLastAccess, 
-       FILETIME *pLastWrite )
-{
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::GetFileTime\r\n"));
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       yfsd_LockYAFFS();
-
-       if(pCreation) yfsd_U32sToWinFileTime(pFile->obj->win_ctime,pCreation);
-       if(pLastAccess) yfsd_U32sToWinFileTime(pFile->obj->win_atime,pLastAccess);
-       if(pLastWrite) yfsd_U32sToWinFileTime(pFile->obj->win_mtime,pLastWrite);
-
-       yfsd_UnlockYAFFS();
-
-       return TRUE;
-}
-
-BOOL YFSD_SetFileTime( 
-       PFILE pFile, 
-       CONST FILETIME *pCreation, 
-       CONST FILETIME *pLastAccess, 
-       CONST FILETIME *pLastWrite )
-{
-       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];
-
-       
-       RETAILMSG (MSGSTATE, (L"YAFFS::SetFileTime\r\n"));
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-       
-       
-       yfsd_LockYAFFS();
-
-       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(pLastWrite)
-       {
-               yfsd_WinFileTimeToU32s(pLastWrite,pFile->obj->win_mtime);
-               pFile->obj->dirty = 1;
-       }
-       if(pCreation || pLastAccess || pLastWrite)
-       {
-               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);
-       }
-
-       return TRUE;
-}
-   
-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];
-       static unsigned char zeros[512];
-
-       int result;
-       BOOL retVal = FALSE;
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF\r\n"));
-
-       if(!pFile || !pFile->obj)
-       {
-               SetLastError(ERROR_INVALID_HANDLE);
-               return FALSE;
-       }
-
-       yfsd_LockYAFFS();
-       result = yaffs_ResizeFile(pFile->obj,pFile->offset);
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF resizing to %d, result %d\r\n",pFile->offset,result));
-
-       // Resize only works if we're shortening the file.
-       // If the result is shorter than the offset, then we need to write zeros....
-       // 
-       if(result != pFile->offset)
-       {
-               if(result < pFile->offset)
-               {
-
-                       int nBytes = pFile->offset - result;
-                       int thisWriteSize;
-                       int written;
-                       BOOL ok = TRUE;
-
-                       memset(zeros,0,512);
-
-                       pFile->offset = result;
-                       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF expanding file by %d bytes\r\n",nBytes));
-                       while(nBytes > 0 && ok)
-                       {
-                               thisWriteSize = (nBytes > 512) ? 512  : nBytes;
-
-                               ok = yfsd_DoWriteFile(pFile,zeros,thisWriteSize,&written);      
-                               if(written != thisWriteSize)
-                               {
-                                       ok = FALSE;
-                               }
-
-                               nBytes -= thisWriteSize;
-                       }
-
-                       retVal = ok;
-               }
-               else
-               {
-
-                       SetLastError(ERROR_ACCESS_DENIED);
-                       retVal = FALSE;
-               }
-       }
-       else
-       {
-               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);
-       }
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::SetEOF file size %d\r\n",yaffs_GetObjectFileLength(pFile->obj)));
-
-
-       
-       return retVal;
-}
-
-BOOL YFSD_DeviceIoControl( 
-       PFILE pFile, 
-       DWORD dwIoControlCode, 
-       PVOID pInBuf, 
-       DWORD nInBufSize, 
-       PVOID pOutBuf, 
-       DWORD nOutBufSize, 
-       PDWORD pBytesReturned, 
-       OVERLAPPED *pOverlapped )
-{
-       RETAILMSG (MSGSTATE, (L"YAFFS::DeviceIoControl\r\n"));
-
-       return FALSE;
-}
-
-BOOL YFSD_CloseFile( 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];
-
-       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile %X\r\n",pFile));
-
-       yfsd_LockYAFFS();
-
-       if(!pFile)
-       {
-               RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile null pFile\r\n"));
-       }
-       else
-       {
-               if(pFile->obj)
-               {
-                       pFile->obj->inUse--;
-                       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile on obj\r\n"));
-                       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];
-                       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile on obj done, size is %d\r\n",objSize));
-                       if(pFile->fullName)
-                       {
-                               wcscpy(fpn,pFile->fullName);
-                               nameExists = 1;
-                       }
-                       vol = pFile->myVolume;
-                       yfsd_PutWinFile(pFile);
-               }
-               else
-               {
-                       RETAILMSG (MSGSTATE, (L"YAFFS::CloseFile null obj\r\n"));
-               }
-
-       }
-       yfsd_UnlockYAFFS();
-
-
-       if(nameExists && 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::CloseFile done\r\n"));
-
-       return TRUE;
-
-}
-
-
-BOOL YFSD_CloseVolume(PVOLUME pVolume )
-{
-       RETAILMSG (MSGSTATE, (L"YAFFS::CloseVolume\r\n"));
-       yfsd_FlushAllFiles();
-       return TRUE;
-}
-
index 5e982b502ae7755c9ca19047d5ccf5a5a3eeaadb..2812549ac37b42dcf8e9a75faee77f4fc81a26a1 100644 (file)
@@ -2,9 +2,10 @@
  * YAFFS: Yet another FFS. A NAND-flash specific file system.\r
  * ynandif.c: NAND interface functions for the WinCE port of YAFFS.\r
  *\r
- * Copyright (C) 2002 Trimble Navigation Ltd.\r
+ * Copyright (C) 2002-2003 Trimble Navigation Ltd.\r
  *\r
  * Created by Brad Beveridge <brad.beveridge@trimble.co.nz>\r
+ * Modified for CE 4.x by Steve Fogle <stevef@atworkcom.com>\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
  * if not, write to the Free Software Foundation, Inc., \r
  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \r
  *\r
- * $Id: ynandif.c,v 1.1 2002-11-08 07:30:00 charles Exp $\r
+ * $Id: ynandif.c,v 1.2 2003-01-31 00:52:53 charles Exp $\r
  */\r
-#include "ynandif.h"\r
 #include <windows.h>\r
+#include <fsdmgr.h>\r
+#include "ynandif.h"\r
 \r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER < 400\r
+// For Win'CE 4.0 FSDMGR instead of direct access.\r
 HANDLE devHandle = 0;\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
 \r
 /*\r
 *      Functions that need to be provided for YAFFS\r
 */\r
 int ynandif_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,const __u8 *data, yaffs_Spare *spare)\r
 {\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+       if (dev)\r
+#else\r
        if (devHandle)\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
        {\r
                ynandif_data writeData;\r
                int result;\r
@@ -39,7 +52,13 @@ int ynandif_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,const __u8 *data
                writeData.data = (__u8 *)data;\r
                writeData.spare = (char *)spare;\r
                \r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+               if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
+#else\r
                if (!DeviceIoControl(devHandle,\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
                                                     YNANDIF_WRITE,\r
                                                     &writeData,\r
                                                     sizeof(ynandif_data),\r
@@ -57,7 +76,13 @@ int ynandif_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,const __u8 *data
 \r
 int ynandif_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)\r
 {\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+       if (dev)\r
+#else\r
        if (devHandle)\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
        {\r
                ynandif_data readData;\r
                int result;\r
@@ -66,7 +91,13 @@ int ynandif_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf
                readData.data = data;\r
                readData.spare = (char *)spare;\r
                \r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+               if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
+#else\r
                if (!DeviceIoControl(devHandle,\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
                                                     YNANDIF_READ,\r
                                                     &readData,\r
                                                     sizeof(ynandif_data),\r
@@ -84,11 +115,23 @@ int ynandif_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf
 \r
 int ynandif_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)\r
 {\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+       if (dev)\r
+#else\r
        if (devHandle)\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
        {\r
                int result;\r
                \r
-               if (!DeviceIoControl(devHandle,\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+               if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
+#else\r
+       if (!DeviceIoControl(devHandle,\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
                                                     YNANDIF_ERASE,\r
                                                     &blockNumber,\r
                                                     sizeof(int),\r
@@ -108,6 +151,10 @@ int ynandif_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
 \r
 int ynandif_InitialiseNAND(yaffs_Device *dev)\r
 {\r
+\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER < 400\r
+// For Win'CE 4.0 FSDMGR instead of direct access.\r
        RETAILMSG(1, (L"ynandif_InitialiseNAND\r\n"));\r
        devHandle = CreateFile(L"YND1:",\r
                                                   GENERIC_READ|GENERIC_WRITE,\r
@@ -117,13 +164,30 @@ int ynandif_InitialiseNAND(yaffs_Device *dev)
                                                   0,\r
                                                   0);\r
 \r
-       if (!devHandle)\r
+//slf021220d Begin CreateFile returns INVALID_HANDLE_VALUE not null fix.\r
+       if (INVALID_HANDLE_VALUE == devHandle)\r
+       {\r
+               devHandle = NULL;\r
                return 0;\r
+       }\r
+//     if (!devHandle)\r
+//             return 0;\r
+//slf021220d end CreateFile returns INVALID_HANDLE_VALUE not null fix.\r
 \r
        RETAILMSG(1, (L"devhandle open\r\n"));\r
+#endif\r
+//slf021220a Begin Cleanup block driver interface\r
 \r
        RETAILMSG(1, (L"DeviceIo INIT\r\n"));\r
-       if (!DeviceIoControl(devHandle,\r
+//slf021220a Begin Cleanup block driver interface\r
+       if (dev)\r
+       {\r
+#if _WINCEOSVER >= 400\r
+               if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
+#else\r
+               if (!DeviceIoControl(devHandle,\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
                                                 YNANDIF_INIT,\r
                                                 NULL,\r
                                                 0,\r
@@ -131,12 +195,17 @@ int ynandif_InitialiseNAND(yaffs_Device *dev)
                                                 0,\r
                                                 NULL,\r
                                                 NULL))\r
-               return 0;\r
-\r
+                       return 0;\r
+//slf021220a Begin Cleanup block driver interface\r
+       }\r
+//slf021220a end Cleanup block driver interface\r
 \r
        if (dev)\r
        {\r
-               int nBlocks = ynandif_GetChipSize(0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
+//slf021220a Begin Cleanup block driver interface\r
+//             int nBlocks = ynandif_GetChipSize(0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
+               int nBlocks = ynandif_GetChipSize(dev,0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
+//slf021220a end Cleanup block driver interface\r
                dev->startBlock = 1;  // Don't use block 0\r
                dev->endBlock = nBlocks - 1;\r
        }\r
@@ -144,10 +213,27 @@ int ynandif_InitialiseNAND(yaffs_Device *dev)
        return 1;\r
 }\r
 \r
+//slf021220a Begin Cleanup block driver interface\r
+void ynandif_DeinitialiseNAND(yaffs_Device *dev)\r
+{\r
+       RETAILMSG(1, (L"ynandif_DeinitialiseNAND\r\n"));\r
+#if _WINCEOSVER < 400\r
+       if (devHandle)\r
+       {\r
+               CloseHandle(devHandle);\r
+               devHandle = NULL;\r
+       }\r
+#endif\r
+}\r
+//slf021220a end Cleanup block driver interface\r
+\r
 int ynandif_EraseAllBlocks(yaffs_Device *dev)\r
 {\r
        int numBlocks, counter;\r
-       numBlocks = ynandif_GetChipSize(0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
+//slf021220a Begin Cleanup block driver interface\r
+//     numBlocks = ynandif_GetChipSize(0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
+       numBlocks = ynandif_GetChipSize(dev,0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
+//slf021220a end Cleanup block driver interface\r
        for (counter = 0; counter < numBlocks; counter++)\r
        {\r
                ynandif_EraseBlockInNAND(dev, counter);\r
@@ -155,14 +241,29 @@ int ynandif_EraseAllBlocks(yaffs_Device *dev)
        return YAFFS_OK;\r
 }\r
 \r
-int ynandif_GetChipSize(unsigned char chipNumber)\r
+//slf021220a Begin Cleanup block driver interface\r
+//int ynandif_GetChipSize(unsigned char chipNumber)\r
+int ynandif_GetChipSize(yaffs_Device *dev, unsigned char chipNumber)\r
+//slf021220a end Cleanup block driver interface\r
 {\r
        int ret = 0;\r
        RETAILMSG(1, (L"DeviceIo GETSIZE\r\n"));\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+       if (dev)\r
+#else\r
        if (devHandle)\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
        {\r
                RETAILMSG(1, (L"DeviceIo GETSIZE - getting ret\r\n"));\r
+//slf021220a Begin Cleanup block driver interface\r
+#if _WINCEOSVER >= 400\r
+               FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
+#else\r
                DeviceIoControl(devHandle,\r
+#endif\r
+//slf021220a end Cleanup block driver interface\r
                                        YNANDIF_GETSIZE,\r
                                        NULL,\r
                                        0,\r
index 3ae1e8ac0fb0ed093d6345975b10045f6ac9a40f..ab5f35e8f9fc6fcb494aea0c775aad8cf51c4ddb 100644 (file)
@@ -2,9 +2,10 @@
  * YAFFS: Yet another FFS. A NAND-flash specific file system. \r
  * ynandif.h: Nand interface routines for WinCE version of YAFFS.\r
  *\r
- * Copyright (C) 2002 Trimble Navigaion Ltd.\r
+ * Copyright (C) 2002-2003 Trimble Navigaion Ltd.\r
  *\r
  * Created by Brad Beveridge <brad.beveridge@trimble.co.nz>\r
+ * Modified for CE 4.x by Steve Fogle <stevef@atworkcom.com>\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
  * it under the terms of the GNU Lesser General Public License version 2.1 as\r
@@ -21,8 +22,8 @@
  *\r
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.\r
  *\r
- * $Id: ynandif.h,v 1.1 2002-11-08 07:30:00 charles Exp $\r
- */\r
+ * $Id: ynandif.h,v 1.2 2003-01-31 00:52:53 charles Exp $\r
+*/\r
 \r
 #ifndef YNANDIF_H\r
 #define YNANDIF_H\r
@@ -43,8 +44,19 @@ typedef enum
        YNANDIF_ERASE,\r
        YNANDIF_INIT,\r
        YNANDIF_GETSIZE,\r
+       //slf021105a begin\r
+       YNANDIF_GETPARTITIONS,\r
+       //slf021105a end\r
 } ynandif_commands;\r
 \r
+//slf021105a begin\r
+typedef struct\r
+{\r
+       int startBlock;\r
+       int endBlock;\r
+       unsigned short volName[12];\r
+} ynandif_partition;\r
+//slf021105a end\r
 \r
 /*\r
 *      Functions that need to be provided for YAFFS\r
@@ -53,12 +65,18 @@ int ynandif_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,const __u8 *data
 int ynandif_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare);\r
 int ynandif_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);\r
 int ynandif_InitialiseNAND(yaffs_Device *dev);\r
+//slf021220a begin Cleanup block driver interface\r
+void ynandif_DeinitialiseNAND(yaffs_Device *dev);\r
+//slf021220a end Cleanup block driver interface\r
 \r
 /*\r
 *      Additional optional functions\r
 */\r
 \r
 int ynandif_EraseAllBlocks(yaffs_Device *dev);\r
-int ynandif_GetChipSize(unsigned char chipNumber);\r
+//slf021220a begin Cleanup block driver interface\r
+//int ynandif_GetChipSize(unsigned char chipNumber);\r
+int ynandif_GetChipSize(yaffs_Device *dev, unsigned char chipNumber);\r
+//slf021220a end Cleanup block driver interface\r
 \r
 #endif // end of file
\ No newline at end of file
index bf504e92a761862b5a4de00601bee2472d125d60..8198e419f0da720bd2fac3fd76534d2a1ed9d17b 100644 (file)
@@ -14,7 +14,7 @@
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.18 2003-01-21 20:42:27 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.19 2003-01-31 00:57:34 charles Exp $";
 
 #include "yportenv.h"
 
@@ -1149,8 +1149,10 @@ static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level
                        {
                            if(tn->level0[i])
                        {
-                                       
                                        theChunk =  (tn->level0[i] << in->myDev->chunkGroupBits);
+                                       T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR),
+                                               tn->level0[i],in->myDev->chunkGroupBits,theChunk));
+                                               
                                        theBlock =      yaffs_GetBlockInfo(in->myDev,  theChunk/in->myDev->nChunksPerBlock);
                                        if(theBlock)
                                        {