- SetLastError(ERROR_INVALID_PARAMETER);\r
- return FALSE;\r
- }
-
- yfsd_LockYAFFS();
-
- obj = yfsd_FindObjectByWinPath(&pVolume->dev,pwsFileName);
-
- if(obj)
- {
- obj->st_mode = dwFileAttributes;
- obj->dirty = 1;
- result = yaffs_FlushFile(obj);\r
- attribs = yfsd_GetObjectWinAttributes(obj);\r
- objSize = yaffs_GetObjectFileLength(obj);\r
- mtime[0] = obj->win_mtime[0];\r
- mtime[1] = obj->win_mtime[1];\r
- }
- 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;\r
- 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);\r
- mtime[0] = obj->win_mtime[0];\r
- mtime[1] = obj->win_mtime[1];\r
- }
- }
- 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 )
-{
- RETAILMSG (MSGSTATE, (L"YAFFS::DeleteAndRename\r\n"));
- return FALSE;
-}
-
-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;
-}
+ 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
+ {\r
+ free(disk_volumes[0]->volName);\r
+ }\r
+ free(disk_volumes[0]);\r
+ disk_volumes[0] = NULL;\r
+ }\r
+ if (disk_volumes[1])\r
+ {\r
+ if (disk_volumes[1]->volName)\r
+ {\r
+ free(disk_volumes[1]->volName);\r
+ }\r
+ free(disk_volumes[1]);\r
+ disk_volumes[1] = NULL;\r
+ }\r
+#endif\r
+\r
+ return FALSE;\r
+\r
+ // Only want disk volume\r
+// 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
+//\r
+// return FALSE;\r
+#endif\r
+//slf021105a end\r
+\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"));\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
+ if (yfsd_FilesOpen())\r
+ return FALSE;\r
+\r
+ //yfsd_FlushAllFiles();\r
+ //slf021104d end\r
+\r
+ yfsd_LockYAFFS();\r
+//slf021105a begin\r
+// yaffs_Deinitialise(&disk_volume.dev);\r
+// yaffs_Deinitialise(&boot_volume.dev);\r
+// yfsd_UnlockYAFFS();\r
+//\r
+// FSDMGR_DeregisterVolume(disk_volume.mgrVolume);\r
+// FSDMGR_DeregisterVolume(boot_volume.mgrVolume);\r
+\r
+ // Walk through the partions deinitializing, deregistering\r
+ // and freeing them.\r
+ for (i=0; i<MAXPARTITIONS; i++)\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
+ free(disk_volumes[i]->volName);\r
+ }\r
+ free(disk_volumes[i]);\r
+ disk_volumes[i] = NULL;\r
+ }\r
+ }\r
+ yfsd_UnlockYAFFS();\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\r
+ if (fSuccess = YFSD_DeleteFileW(pVolume, pwsOldFileName))\r
+ fSuccess = YFSD_MoveFileW(pVolume, pwsNewFileName, pwsOldFileName);\r
+ return fSuccess;\r
+ //return FALSE;\r
+ //slf021104c end\r
+}\r
+\r
+BOOL YFSD_GetDiskFreeSpaceW( PVOLUME pVolume, PCWSTR pwsPathName, PDWORD pSectorsPerCluster,PDWORD pBytesPerSector, PDWORD pFreeClusters, PDWORD pClusters )\r
+{\r
+\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
+ // 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
+ return (nChunks >= 0)? TRUE : FALSE;\r
+\r
+\r
+\r
+}\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