📄 yaffsfsd.c
字号:
/* * YAFFS: Yet another FFS. A NAND-flash specific file system. * yaffsfsd.c: FSD interface funtions for WinCE. * * Copyright (C) 2002 Trimble Navigation Ltd. * * Created by Charles Manning <charles.manning@trimble.co.nz> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. You should have received a * copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Acknowledgements: * Various clean-ups and WinCE4 support by Steve Fogle and Lynn Winter * $Id: yaffsfsd.c,v 1.4 2003/01/31 03:30:33 charles Exp $ */#include <windows.h>#include <extfile.h>#include <yaffs_guts.h>#include <ynandif.h>//slf021104b begin#include <diskio.h>//slf021104b end#define MAX_WIN_FILE 200#define YFSD_NAME_LENGTH 128#define YFSD_FULL_PATH_NAME_SIZE 500#define YFSD_DISK_NAME L"Disk"#define YFSD_BOOT_NAME L"Boot"#define PARTITION_START_NUMBER (1280) // if this is defined the there will be a constant message box raised to display status//#define MSGBOX_DISPLAY //#define MSGSTATE 1#define MSGSTATE 0//#define DISABLE_BOOT_PARTITION//slf021105a begin// Define DO_PARTITION_TABLE to cause the partition table // information to be retrieved from the block driver.// Can define this in your sources file.//#define DO_PARTITION_TABLE// How many partitions the disk might have. 2 gives // space for the "Disk" and "Boot" partitions.#define MAXPARTITIONS (2)//slf021105a end//unsigned yaffs_traceMask=0xffffffff;unsigned yaffs_traceMask=0;typedef struct{ yaffs_Device dev; DWORD hdsk; DWORD mgrVolume; // The volume id from the manager issed when we registered it - it is an HVOL BOOL isMounted; BOOL configured;// DWORD guard0[100];// DWORD guard1[100]; SHELLFILECHANGEFUNC_t shellFunction; PWSTR volName;} yfsd_Volume;typedef struct { yaffs_Object *obj; DWORD offset; BOOL isopen; BOOL dirty; WCHAR *fullName; yfsd_Volume *myVolume; BOOL writePermitted; BOOL readPermitted; BOOL shareRead; BOOL shareWrite;} yfsd_WinFile;struct yfsd_FoundObjectStruct{ yaffs_Object *obj; struct yfsd_FoundObjectStruct *next;};typedef struct yfsd_FoundObjectStruct yaffs_FoundObject;typedef struct { yaffs_Object *dir; char pattern[YFSD_NAME_LENGTH+1]; yaffs_FoundObject *foundObjects;} yfsd_WinFind;#define PSEARCH yfsd_WinFind*#define PVOLUME yfsd_Volume*#define PFILE yfsd_WinFile*#define FSD_API YFSD#include <fsdmgr.h>//slf021105a begin//static yfsd_Volume disk_volume;//static yfsd_Volume boot_volume;static yfsd_Volume * disk_volumes[MAXPARTITIONS];//slf021105a end;static CRITICAL_SECTION yaffsLock;static CRITICAL_SECTION winFileLock;static int yaffsLockInited = 0;static yfsd_WinFile yfsd_winFile[MAX_WIN_FILE];#if 0static yfsd_SetGuards(void){ int i; for(i = 0; i < 100; i++) { yfsd_volume.guard0[i] = yfsd_volume.guard1[i] = i; }}static void yfsd_CheckGuards(void){ int i; int found; for(i = found = 0; i < 100 && !found; i++) { if(yfsd_volume.guard0[i] != i) { RETAILMSG (MSGSTATE, (L"YAFFS:: guard 0 %d brocken\r\n",i)); found = 1; } if(yfsd_volume.guard1[i] != i) { RETAILMSG (MSGSTATE, (L"YAFFS:: guard 0 %d brocken\r\n",i)); found = 1; } }}#endif#ifdef MSGBOX_DISPLAYDWORD WINAPI yfsd_MessageThread(LPVOID param){ yaffs_Device *dev = (yaffs_Device *)param; TCHAR dataBuffer[1000]; Sleep(10000); // note : if the device gets free'd from under us, we will cause an exception in the loop while (1) { wsprintf(dataBuffer, L"nShortOpCaches %i\r\n" L"nErasedBlocks %i\r\n" L"allocationBlock %i\r\n" L"allocationPage %i\r\n" L"garbageCollectionRequired %i\r\n" L"nRetiredBlocks %i\r\n" L"cacheHits %i\r\n" L"eccFixed %i\r\n" L"eccUnfixed %i\r\n" L"tagsEccFixed %i\r\n" L"tagsEccUnfixed %i\r\n", dev->nShortOpCaches, dev->nErasedBlocks, dev->allocationBlock, dev->allocationPage, dev->garbageCollectionRequired, dev->nRetiredBlocks, dev->cacheHits, dev->eccFixed, dev->eccUnfixed, dev->tagsEccFixed, dev->tagsEccUnfixed); MessageBox(NULL, dataBuffer, L"YAFFS PROC INFO", MB_OK); Sleep(1); }}#endifvoid yfsd_LockWinFiles(void){ //RETAILMSG (MSGSTATE, (L"YAFFS::LockWinfiles\r\n")); EnterCriticalSection(&winFileLock);}void yfsd_UnlockWinFiles(void){ //RETAILMSG (MSGSTATE, (L"YAFFS::UnlockWinFiles\r\n")); LeaveCriticalSection(&winFileLock);}int lockwaits;void yfsd_LockYAFFS(void){ //yfsd_CheckGuards(); //RETAILMSG (MSGSTATE, (L"YAFFS::LockYAFFS %d ",lockwaits)); lockwaits++; EnterCriticalSection(&yaffsLock); //RETAILMSG (MSGSTATE, (L" locked\r\n"));}void yfsd_UnlockYAFFS(void){ //yfsd_CheckGuards(); //RETAILMSG (MSGSTATE, (L"YAFFS::UnLockYAFFS ")); LeaveCriticalSection(&yaffsLock); lockwaits--; //RETAILMSG (MSGSTATE, (L" unlocked\r\n"));}void yfsd_InitialiseWinFiles(void){ int i; RETAILMSG (MSGSTATE, (L"YAFFS::InitWinFiles\r\n")); InitializeCriticalSection(&winFileLock); yfsd_LockWinFiles(); for(i = 0; i < MAX_WIN_FILE; i++) { yfsd_winFile[i].isopen = 0; } yfsd_UnlockWinFiles();}yfsd_WinFile * yfsd_GetWinFile(void){ int i; RETAILMSG (MSGSTATE, (L"YAFFS::GetWinFiles\r\n")); yfsd_LockWinFiles(); for(i = 0; i < MAX_WIN_FILE; i++) { if(!yfsd_winFile[i].isopen) { yfsd_winFile[i].isopen = 1; yfsd_winFile[i].writePermitted = 0; yfsd_winFile[i].readPermitted = 0; yfsd_winFile[i].shareRead = 0; yfsd_winFile[i].shareWrite = 0; yfsd_winFile[i].dirty = 0; yfsd_winFile[i].fullName = NULL; yfsd_winFile[i].obj = NULL; yfsd_UnlockWinFiles(); return &yfsd_winFile[i]; } } yfsd_UnlockWinFiles(); RETAILMSG (MSGSTATE, (L"YAFFS::GetWinFiles did not find a handle. Too many open.\r\n")); return NULL;}void yfsd_PutWinFile(yfsd_WinFile *f){ RETAILMSG (MSGSTATE, (L"YAFFS::PutWinFile\r\n")); yfsd_LockWinFiles(); f->isopen = 0; f->obj = NULL; if(f->fullName) { free(f->fullName); f->fullName = NULL; } yfsd_UnlockWinFiles();}void yfsd_FlushAllFiles(void){ int i; RETAILMSG (MSGSTATE, (L"YAFFS::FlushAllFiles\r\n")); yfsd_LockYAFFS(); yfsd_LockWinFiles(); for(i = 0; i < MAX_WIN_FILE; i++) { if(yfsd_winFile[i].isopen && yfsd_winFile[i].obj) { yaffs_FlushFile(yfsd_winFile[i].obj,1); } } yfsd_UnlockWinFiles(); yfsd_UnlockYAFFS();}//slf021104d begin//////////////////////////////////////////////////////////////////////// Search through winFiles to see if any are open. BOOL yfsd_FilesOpen(void){ int i; BOOL rval; RETAILMSG (MSGSTATE, (L"YAFFS::FilesOpen?\r\n")); yfsd_LockWinFiles(); for(i = 0, rval = FALSE; i < MAX_WIN_FILE; i++) { if(yfsd_winFile[i].isopen) { rval = TRUE; break; } } yfsd_UnlockWinFiles(); return rval;}//slf021104d endPWSTR yfsd_FullPathName(PVOLUME vol, PWSTR fpn,int slength,PCWSTR pathName){ // todo check for bounds //slf021104b begin //volName already has the initial backslash if it needs it. //wcscpy(fpn,L"\\"); //wcscat(fpn,vol->volName); wcscpy(fpn,vol->volName); //slf021104b end if(pathName[0] != '\\') { wcscat(fpn,L"\\"); } wcscat(fpn,pathName); return fpn;}// FILETIME is a 64-bit value as 100-nanosecond intervals since January 1, 1601.void yfsd_U32sToWinFileTime(__u32 target[2], FILETIME *wft){ wft->dwLowDateTime = target[0]; wft->dwHighDateTime = target[1];}void yfsd_NullWinFileTime(FILETIME *wft){ wft->dwLowDateTime = 0; wft->dwHighDateTime = 0;}void yfsd_WinFileTimeToU32s(const FILETIME *wft, __u32 target[2]){ target[0] = wft->dwLowDateTime; target[1] = wft->dwHighDateTime;}void yfsd_WinFileTimeNow(__u32 target[2]){ SYSTEMTIME st; FILETIME ft; GetSystemTime(&st); SystemTimeToFileTime(&st,&ft); yfsd_WinFileTimeToU32s(&ft,target);}// Cut down the name to the parent directory, then inform the shell of// a change to the directory.void yfsd_ShellDirectoryChanged(PVOLUME pVolume, PWSTR fullPathName){ WCHAR str[500]; int i; wcscpy(str,fullPathName); i = wcslen(str) - 1; if(i > 0) { str[i] = 0; i--; } // Curveball if the name is a directory (ie. we're doing an update of // a directory because we added a directory item). , then it might end in a \ // which we must toss first if(i >= 0 && (str[i] == '\\' || str[i] == '/')) { str[i] = 0; i--; } // Ok, now strip back... while(i >= 0 && str[i] != '\\' && str[i] != '/') { str[i] = 0; i--; } if(pVolume->shellFunction) { FILECHANGEINFO fc; fc.cbSize = sizeof(FILECHANGEINFO); fc.wEventId = SHCNE_UPDATEDIR; fc.uFlags = SHCNF_PATH; fc.dwItem1 = (DWORD)str; fc.dwItem2 = 0; fc.dwAttributes = 0; yfsd_NullWinFileTime(&fc.ftModified); fc.nFileSize = 0; pVolume->shellFunction(&fc); RETAILMSG (MSGSTATE, (L"YAFFS:: directory changed %s\r\n",str)); }}// Minimal name test for nowBOOL yfsd_NameIsValid (const char *name){ int length = strlen(name); return (length > 0 && length <= YFSD_NAME_LENGTH);}// File attributes:// Wince understands the following attributes of any use to YAFFS:// // ARCHIVE// HIDDEN// READONLY// SYSTEM// TEMPORARY//// Also, FILE_ATTRIBUTE_DIRECTORY is used to mark directories.//// It also understands NORMAL. If no other flag is set, then set NORMAL.// If any of the above are set, then NORMAL must **not** be set.// Ignore this and the WinCE Explorer barfs the file.////// in addition, GetAttributes also returns FILE_ATTRIBUTE_DIRECTORY// The following are valid ones we get presented with,// but must filter out the stuff we don't unserstand//#define FILE_ATTRIBUTE_READONLY 0x00000001 //#define FILE_ATTRIBUTE_HIDDEN 0x00000002 //#define FILE_ATTRIBUTE_SYSTEM 0x00000004 //#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 //#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 //#define FILE_ATTRIBUTE_INROM 0x00000040//#define FILE_ATTRIBUTE_ENCRYPTED 0x00000040 //#define FILE_ATTRIBUTE_NORMAL 0x00000080 //#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 //#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 //#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 //#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 //#define FILE_ATTRIBUTE_OFFLINE 0x00001000 //#define FILE_ATTRIBUTE_ROMSTATICREF 0x00001000//#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 //#define FILE_ATTRIBUTE_ROMMODULE 0x00002000BOOL yfsd_CheckValidAttributes(DWORD attribs){ RETAILMSG (MSGSTATE, (L"Attributes:%X\r\n", attribs));#if 0 // If NORMAL, then nothing else if(attribs & FILE_ATTRIBUTE_NORMAL && attribs != FILE_ATTRIBUTE_NORMAL) return FALSE; if(attribs == FILE_ATTRIBUTE_NORMAL) return TRUE;#endif // Check that the bits are in the valid set if(attribs & ~(0x3FE7)) return FALSE; return TRUE;}DWORD yfsd_GetObjectWinAttributes(yaffs_Object *obj){ DWORD result; result = obj->st_mode & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM); if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) result |= FILE_ATTRIBUTE_DIRECTORY; if(result & ~FILE_ATTRIBUTE_NORMAL) { result &= ~FILE_ATTRIBUTE_NORMAL; } else { result = FILE_ATTRIBUTE_NORMAL; } return result;}/** Runs over input until a '\' is found, or '\0' is found, or outSize - 1 is* reached. Characters are copied from input into output until the above stop* condition is reached - output is then given a '\0'. output must be at least* as large as outSize*/static int parseToNextSlash(const unsigned short *input, char *output, int outSize){ int counter = 0; char *t = output; /* strip any starting \'s */ //RETAILMSG(1, (L"\r\nParsing.. ")); while (*input == '\\' || *input == '/') input++, counter++; for (; counter < outSize - 1; counter++) { if (*input == '\0' || ((*input == '\\' || *input == '/') && input[1] == '\0')) // special case: if the string ends in a '\', then toss the '\' { counter = -1; // break & tell people we've run to the end break; } if (*input == '\\' || *input == '/') break; //RETAILMSG(1, (L"%c", *input)); *output = (char) (*input); input++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -