+ 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