📄 yaffsfsd.c
字号:
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 WCHAR szName[MAX_PATH]; DWORD dwAvail; //slf021104b end RETAILMSG (MSGSTATE, (L"YAFFS::InitVolume\r\n")); //slf021104b Begin filled in later. //vol->volName = volName; //slf021104b end yfsd_LockYAFFS(); //slf021220a Begin Cleanup block driver interface#if _WINCEOSVER >= 400 // For Win'CE 4.0 and later pass the hdsk for use by the yandif layer. vol->dev.genericDevice = (PVOID)hdsk;#endif //slf021220a End Cleanup block driver interface //Mount/initialise YAFFs here //slf021127a begin check for error returns! if (ynandif_InitialiseNAND(&vol->dev)) { //slf021127a end check for error returns! vol->dev.writeChunkToNAND = ynandif_WriteChunkToNAND; vol->dev.readChunkFromNAND = ynandif_ReadChunkFromNAND; vol->dev.eraseBlockInNAND = ynandif_EraseBlockInNAND; vol->dev.initialiseNAND = ynandif_InitialiseNAND; vol->dev.startBlock = startBlock; if (endBlock != -1) vol->dev.endBlock = endBlock; vol->dev.nShortOpCaches = 10; // a nice number of caches. vol->dev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; vol->dev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; vol->dev.nReservedBlocks = 5; // a nice reserve size // nBlocks is set the total size of the disk, not the partition // vol->dev.nBlocks = endBlock - startBlock + 1; // qnand_EraseAllBlocks(&vol->dev); //slf021127a begin check for error returns! if (yaffs_GutsInitialise(&vol->dev)) { //slf021127a end check for error returns! RETAILMSG(1, (L"YAFFS::Done yaffs_GutsInitialise\r\n")); RETAILMSG(1, (L"Blocks start %d end %d Group size %d bits %d\r\n", vol->dev.startBlock,vol->dev.endBlock, vol->dev.chunkGroupSize,vol->dev.chunkGroupBits));#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//slf021127a begin check for error returns! vol->isMounted = 1; } }//slf021127a begin check for error returns! yfsd_UnlockYAFFS();//slf021127a begin check for error returns!// vol->isMounted = 1;//slf021127a begin check for error returns! //slf021104b begin //vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,vol->volName,vol); // If the caller passed a volume name use it. if (volName[0]) wcscpy( szName, volName);#if WINCEOSVER >= 400 // The user passed an empty volume name. On CE 4.xx try to get // if from the block driver (which got it from the registry). else if (!FSDMGR_DiskIoControl(hdsk, DISK_IOCTL_GETNAME, NULL, 0, (LPVOID)szName, sizeof(szName), &dwAvail, NULL)) #else else#endif { // Didn't get a volume name so use "Disk" by default. wcscpy( szName, YFSD_DISK_NAME); } vol->mgrVolume = FSDMGR_RegisterVolume(hdsk,szName,vol); //slf021104b end if(vol->mgrVolume) { //slf021104b Begin // Get some space for the volume name. vol->volName = malloc( MAX_PATH * sizeof(WCHAR)); if (vol->volName) {#if WINCEOSVER >= 400 // Get the name we were really mounted under. FSDMGR_GetVolumeName(vol->mgrVolume, vol->volName, MAX_PATH); // If we got mounted as root then throw away the backslash // so we won't get a double backslash when volName is // prepended to the path in the full path name calculation // that is used for shell callbacks. if (0 == wcscmp(vol->volName,L"\\")) vol->volName[0] = 0;#else // Use the name we asked to be mounted under for // our root. wcscpy(vol->volName,L"\\"); wcscat(vol->volName, szName);#endif } //slf021104b end return TRUE; } else { vol->isMounted = 0; SetLastError(ERROR_OUTOFMEMORY); return FALSE; } }BOOL YFSD_MountDisk(HDSK hdsk){//slf021105a begin#ifdef DO_PARTITION_TABLE ynandif_partition PartTable[MAXPARTITIONS]; DWORD dwAvail; int i; BOOL rval = FALSE;#endif//slf021105a end int deadBlox=0,emptyBlox=0,fullBlox=0,allocatingBlox=0,dirtyBlox=0; //int i; // Called to mount a disk. // 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; } //slf021105a begin memset(disk_volumes,0,sizeof(disk_volumes));#ifdef DO_PARTITION_TABLE memset(&PartTable,0,sizeof(PartTable)); // Call the block driver to get the partition table from it. if (FSDMGR_DiskIoControl(hdsk, YNANDIF_GETPARTITIONS, NULL, 0, (LPVOID)&PartTable, sizeof(PartTable), &dwAvail, NULL)) { // Scan throught the table it return. for (i=0; i<MAXPARTITIONS; i++) { // At the very lease check that the end is later than the beginning // and don't let it start at 0. // Probably could do more thorough checking but I trust the block // driver. if (PartTable[i].startBlock && (PartTable[i].endBlock > PartTable[i].startBlock)) { // Found a partion. Get a volume structure to hold it. disk_volumes[i] = malloc(sizeof(yfsd_Volume)); if (disk_volumes[i]) { memset(disk_volumes[i],0,sizeof(yfsd_Volume)); // Go init the volume. Note that if the block driver wants the // name to come from the registry it will have returned an // empty name string. YFSD_InitVolume(hdsk,disk_volumes[i],PartTable[i].startBlock,PartTable[i].endBlock,PartTable[i].volName); if (disk_volumes[i]->isMounted) rval = TRUE; //Hey, we found at least on partition. } } } } return rval;#else#ifdef DISABLE_BOOT_PARTITION // Only want disk volume disk_volumes[0] = malloc(sizeof(yfsd_Volume)); if (disk_volumes[0]) { memset(disk_volumes[0],0,sizeof(yfsd_Volume)); YFSD_InitVolume(hdsk, disk_volumes[0], 1, -1, YFSD_DISK_NAME); if(disk_volumes[0].isMounted) { return TRUE; } } if (disk_volumes[0]) { free(disk_volumes[0]; disk_volumes[0] = NULL; }#else // Want both boot and disk disk_volumes[0] = malloc(sizeof(yfsd_Volume)); disk_volumes[1] = malloc(sizeof(yfsd_Volume)); if (disk_volumes[0] && disk_volumes[1]) { memset(disk_volumes[0],0,sizeof(yfsd_Volume)); memset(disk_volumes[1],0,sizeof(yfsd_Volume)); YFSD_InitVolume(hdsk, disk_volumes[0], PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME); YFSD_InitVolume(hdsk, disk_volumes[1], 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME);#ifdef MSGBOX_DISPLAY // pass the device we are sniffing to the thread CreateThread(NULL, 0, yfsd_MessageThread, (LPVOID)&disk_volumes[0]->dev, 0, NULL);#endif if(disk_volumes[0]->isMounted && disk_volumes[1]->isMounted) { return TRUE; } } // If we got this far something went wrong. Make sure to // free any memory we allocated. if (disk_volumes[0]) { if (disk_volumes[0]->volName) { free(disk_volumes[0]->volName); } free(disk_volumes[0]); disk_volumes[0] = NULL; } if (disk_volumes[1]) { if (disk_volumes[1]->volName) { free(disk_volumes[1]->volName); } free(disk_volumes[1]); disk_volumes[1] = NULL; }#endif return FALSE; // Only want disk volume// YFSD_InitVolume(hdsk, &disk_volume, 1, -1, YFSD_DISK_NAME);//// // if(disk_volume.isMounted)// {// return TRUE;// }//#else// // Want both boot and disk// YFSD_InitVolume(hdsk, &disk_volume, PARTITION_START_NUMBER+1, -1, YFSD_DISK_NAME);// YFSD_InitVolume(hdsk, &boot_volume, 1, PARTITION_START_NUMBER, YFSD_BOOT_NAME);//// // if(disk_volume.isMounted && boot_volume.isMounted)// {// return TRUE;// }//#endif//// return FALSE;#endif//slf021105a end// yfsd_SetGuards(); // todo - get name from registry}BOOL YFSD_UnmountDisk(HDSK hdsk){//slf021105a begin int i;//slf021105a end RETAILMSG (MSGSTATE, (L"YAFFS::UnmountDisk\r\n")); //slf021104d begin // If there are any files open don't let them dismount // it or the system will get very confused. if (yfsd_FilesOpen()) return FALSE; //yfsd_FlushAllFiles(); //slf021104d end yfsd_LockYAFFS();//slf021105a begin// yaffs_Deinitialise(&disk_volume.dev);// yaffs_Deinitialise(&boot_volume.dev);// yfsd_UnlockYAFFS();//// FSDMGR_DeregisterVolume(disk_volume.mgrVolume);// FSDMGR_DeregisterVolume(boot_volume.mgrVolume); // Walk through the partions deinitializing, deregistering // and freeing them. for (i=0; i<MAXPARTITIONS; i++) { if (disk_volumes[i]) { yaffs_Deinitialise(&(disk_volumes[i]->dev));//slf021220a Begin Cleanup block driver interface ynandif_DeinitialiseNAND(&(disk_volumes[i]->dev));//slf021220a end Cleanup block driver interface FSDMGR_DeregisterVolume(disk_volumes[i]->mgrVolume); if (disk_volumes[i]->volName) { free(disk_volumes[i]->volName); } free(disk_volumes[i]); disk_volumes[i] = NULL; } } yfsd_UnlockYAFFS();//slf021105a end return TRUE;}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_RemoveDirectoryW(PVOLUME pVolume, PCWSTR pathName){ int result = FALSE; yaffs_Object *parent = NULL; yaffs_Object *obj; char name[YFSD_NAME_LENGTH+1]; RETAILMSG (MSGSTATE, (L"YAFFS::RemoveDirectory (%s)\r\n", pathName)); yfsd_LockYAFFS(); obj = yfsd_FindObjectByWinPath(&pVolume->dev,pathName); if(!obj) { SetLastError(ERROR_PATH_NOT_FOUND); result = FALSE; } else if (obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) { SetLastError(ERROR_ACCESS_DENIED); result = FALSE; } else if(obj->st_mode & FILE_ATTRIBUTE_READONLY) { 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_DIR_NOT_EMPTY); } } yfsd_UnlockYAFFS(); if(result && pVolume->shellFunction) { FILECHANGEINFO fc; WCHAR fpn[YFSD_FULL_PATH_NAME_SIZE]; fc.cbSize = sizeof(FILECHANGEINFO); fc.wEventId = SHCNE_RMDIR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -