/*\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
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
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
//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
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
}\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;
-}
-