⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yaffsfsd.c

📁 FAT32文件系统详细介绍
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -