static int iso_unmount(FileSystem *fs) { ISOFileSystem *isofs = (ISOFileSystem*) fs->fsdata; semWait(&isofs->sem); if (isofs->numOpenInodes != 0) { kprintf_debug("isofs: cannot unmount because %d inodes are open\n", isofs->numOpenInodes); semSignal(&isofs->sem); return -1; }; vfsClose(isofs->fp); kfree(isofs); spinlockAcquire(&isoMountLock); isoMountCount--; spinlockRelease(&isoMountLock); return 0; };
static void spawnProc(void *stack) { kprintf("%$\x02" "Done%#\n"); initInterp(); kprintf("Allocating memory for bootstrap... "); FrameList *fl = palloc(2); AddSegment(getCurrentThread()->pm, 1, fl, PROT_READ | PROT_WRITE | PROT_EXEC); pdownref(fl); SetProcessMemory(getCurrentThread()->pm); kprintf("%$\x02" "Done%#\n"); kprintf("Setting up the terminal... "); setupTerminal(getCurrentThread()->ftab); kprintf("%$\x02" "Done%#\n"); kprintf("Loading /initrd/usbs... "); int err; File *file = vfsOpen("/initrd/usbs", VFS_CHECK_ACCESS, &err); if (file == NULL) { kprintf("%$\x04" "Failed%#\n"); panic("failed to open /initrd/usbs"); }; ssize_t count = vfsRead(file, (void*) 0x1000, 0x1000); if (count < 1) { kprintf("%$\x04" "Failed%#\n"); panic("read() /initrd/usbs: %d\n", count); }; vfsClose(file); kprintf("%$\x02" "%d bytes%#\n", count); kprintf("Control will be transferred to usbs now.\n"); _jmp_usbs(stack); };
int elfExec(Regs *regs, const char *path, const char *pars, size_t parsz) { //getCurrentThread()->therrno = ENOEXEC; vfsLockCreation(); struct stat st; int error = vfsStat(path, &st); if (error != 0) { vfsUnlockCreation(); return sysOpenErrno(error); }; if (!vfsCanCurrentThread(&st, 1)) { vfsUnlockCreation(); getCurrentThread()->therrno = EPERM; return -1; }; File *fp = vfsOpen(path, VFS_CHECK_ACCESS, &error); if (fp == NULL) { vfsUnlockCreation(); return sysOpenErrno(error); }; vfsUnlockCreation(); if (fp->seek == NULL) { vfsClose(fp); getCurrentThread()->therrno = EIO; return -1; }; if (fp->dup == NULL) { vfsClose(fp); getCurrentThread()->therrno = EIO; return -1; }; Elf64_Ehdr elfHeader; if (vfsRead(fp, &elfHeader, sizeof(Elf64_Ehdr)) < sizeof(Elf64_Ehdr)) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (memcmp(elfHeader.e_ident, "\x7f" "ELF", 4) != 0) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (elfHeader.e_ident[EI_CLASS] != ELFCLASS64) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (elfHeader.e_ident[EI_DATA] != ELFDATA2LSB) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (elfHeader.e_ident[EI_VERSION] != 1) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (elfHeader.e_type != ET_EXEC) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (elfHeader.e_phentsize < sizeof(Elf64_Phdr)) { vfsClose(fp); getCurrentThread()->therrno = ENOEXEC; return -1; }; ProgramSegment *segments = (ProgramSegment*) kmalloc(sizeof(ProgramSegment)*(elfHeader.e_phnum)); memset(segments, 0, sizeof(ProgramSegment) * elfHeader.e_phnum); int interpNeeded = 0; Elf64_Dyn *dynamic; unsigned int i; for (i=0; i<elfHeader.e_phnum; i++) { fp->seek(fp, elfHeader.e_phoff + i * elfHeader.e_phentsize, SEEK_SET); Elf64_Phdr proghead; if (vfsRead(fp, &proghead, sizeof(Elf64_Phdr)) < sizeof(Elf64_Phdr)) { kfree(segments); getCurrentThread()->therrno = ENOEXEC; return -1; }; if (proghead.p_type == PT_PHDR) { continue; } else if (proghead.p_type == PT_NULL) { continue; } else if (proghead.p_type == PT_LOAD) { if (proghead.p_vaddr < 0x1000) { vfsClose(fp); kfree(segments); getCurrentThread()->therrno = ENOEXEC; return -1; }; if ((proghead.p_vaddr+proghead.p_memsz) > 0x8000000000) { vfsClose(fp); kfree(segments); return -1; }; uint64_t start = proghead.p_vaddr; segments[i].index = (start)/0x1000; uint64_t end = proghead.p_vaddr + proghead.p_memsz; uint64_t size = end - start; uint64_t numPages = ((start + size) / 0x1000) - segments[i].index + 1; //if (size % 0x1000) numPages++; segments[i].count = (int) numPages; segments[i].fileOffset = proghead.p_offset; segments[i].memorySize = proghead.p_memsz; segments[i].fileSize = proghead.p_filesz; segments[i].loadAddr = proghead.p_vaddr; segments[i].flags = 0; if (proghead.p_flags & PF_R) { segments[i].flags |= PROT_READ; }; if (proghead.p_flags & PF_W) { segments[i].flags |= PROT_WRITE; }; if (proghead.p_flags & PF_X) { segments[i].flags |= PROT_EXEC; }; } else if (proghead.p_type == PT_INTERP) { interpNeeded = 1; } else if (proghead.p_type == PT_DYNAMIC) { dynamic = (Elf64_Dyn*) proghead.p_vaddr; } else { kfree(segments); getCurrentThread()->therrno = ENOEXEC; return -1; }; }; // set the signal handler to default. getCurrentThread()->rootSigHandler = 0; // thread name strcpy(getCurrentThread()->name, path); // set the execPars Thread *thread = getCurrentThread(); if (thread->execPars != NULL) kfree(thread->execPars); thread->execPars = (char*) kmalloc(parsz); thread->szExecPars = parsz; memcpy(thread->execPars, pars, parsz); // create a new address space ProcMem *pm = CreateProcessMemory(); // switch the address space, so that AddSegment() can optimize mapping lockSched(); ProcMem *oldPM = thread->pm; thread->pm = pm; unlockSched(); SetProcessMemory(pm); DownrefProcessMemory(oldPM); // pass 1: allocate the frames and map them for (i=0; i<(elfHeader.e_phnum); i++) { if (segments[i].count > 0) { FrameList *fl = palloc_later(segments[i].count, segments[i].fileOffset, segments[i].fileSize); if (AddSegment(pm, segments[i].index, fl, segments[i].flags) != 0) { getCurrentThread()->therrno = ENOEXEC; pdownref(fl); DownrefProcessMemory(pm); break; }; pdownref(fl); }; }; // change the fpexec if (thread->fpexec != NULL) { if (thread->fpexec->close != NULL) thread->fpexec->close(thread->fpexec); kfree(thread->fpexec); }; thread->fpexec = fp; // make sure we jump to the entry upon return regs->rip = elfHeader.e_entry; // the errnoptr is now invalid thread->errnoptr = NULL; // close all files marked with O_CLOEXEC (on glidx a.k.a. FD_CLOEXEC) spinlockAcquire(&getCurrentThread()->ftab->spinlock); for (i=0; i<MAX_OPEN_FILES; i++) { File *fp = getCurrentThread()->ftab->entries[i]; if (fp != NULL) { if (fp->oflag & O_CLOEXEC) { getCurrentThread()->ftab->entries[i] = NULL; vfsClose(fp); }; }; }; spinlockRelease(&getCurrentThread()->ftab->spinlock); // suid/sgid stuff if (st.st_mode & VFS_MODE_SETUID) { thread->euid = st.st_uid; //thread->ruid = st.st_uid; //thread->suid = st.st_uid; thread->flags |= THREAD_REBEL; }; if (st.st_mode & VFS_MODE_SETGID) { thread->egid = st.st_gid; //thread->rgid = st.st_gid; //thread->sgid = st.st_gid; thread->flags |= THREAD_REBEL; }; if (interpNeeded) { linkInterp(regs, dynamic, pm); }; return 0; };
s64int loadElfProgram(const char *path, struct Program *prog, struct VM *vm) { struct VNode node; Elf64_Ehdr *ehdr; Elf64_Phdr *phdr; s64int ret, n; u64int len, i, j, size, remain; char *buffer; ret = vfsOpen(path, 0, &node); if (ret!=0) return ret; ehdr = (Elf64_Ehdr *)kMalloc(sizeof(Elf64_Ehdr)); if (!ehdr) return -1; //buffer = (char*)kMallocEx(PAGE_SIZE, 1, 0); buffer = (char*)kMalloc(PAGE_SIZE); n = vfsRead(&node, sizeof(Elf64_Ehdr), ehdr); if ((n == sizeof(Elf64_Ehdr)) && isValidElfHeader(ehdr)) { prog->entry = ehdr->e_entry; len = ehdr->e_phentsize * ehdr->e_phnum; phdr = (Elf64_Phdr*)kMalloc(len); vfsSeek(&node, ehdr->e_phoff, SEEK_SET); n = vfsRead(&node, len, phdr); if (n==len) { for (i=0; i<ehdr->e_phnum; i++) { if (phdr[i].p_type == PT_LOAD) { ret = vmAddArea(vm, phdr[i].p_vaddr, phdr[i].p_memsz, VMA_TYPE_HEAP | VMA_OWNER_USER | VMA_STATUS_USED); if (ret!=0) { break; } size = phdr[i].p_filesz; remain = size & 0xfff; size -= remain; vfsSeek(&node, phdr[i].p_offset, SEEK_SET); for (j=0; j<size; j+=PAGE_SIZE) { len = vfsRead(&node, PAGE_SIZE, buffer); if (len!=PAGE_SIZE) { ret = -1; break; } //DBG("%x,%x",vm,currentTask->vm); vmemcpy(vm, (void*)(phdr[i].p_vaddr+j), currentTask->vm, buffer, PAGE_SIZE); } if (remain) { len = vfsRead(&node, remain, buffer); if (len == remain) vmemcpy(vm, (void*)(phdr[i].p_vaddr+size), currentTask->vm, buffer, remain); else ret = -1; } if (ret!=0) break; } } } // setup stack if (ret == 0) { ret = vmAddArea(vm, USER_STACK_TOP-USER_STACK_SIZE, USER_STACK_SIZE, VMA_TYPE_STACK | VMA_OWNER_USER | VMA_STATUS_USED); } kFree(phdr); } else ret = -1; kFree(buffer); kFree(ehdr); vfsClose(&node); return ret; }
static int isoMount(const char *image, FileSystem *fs, size_t szfs) { spinlockAcquire(&isoMountLock); int error; File *fp = vfsOpen(image, 0, &error); if (fp == NULL) { spinlockRelease(&isoMountLock); kprintf_debug("isofs: could not open %s\n", image); return -1; }; if (fp->seek == NULL) { spinlockRelease(&isoMountLock); kprintf_debug("isofs: %s cannot seek\n", image); vfsClose(fp); return -1; }; fp->seek(fp, 0x8000, SEEK_SET); ISOPrimaryVolumeDescriptor primary; if (vfsRead(fp, &primary, sizeof(ISOPrimaryVolumeDescriptor)) != sizeof(ISOPrimaryVolumeDescriptor)) { spinlockRelease(&isoMountLock); kprintf_debug("isofs: cannot read the whole ISOPrimaryVolumeDescriptor (EOF)\n"); vfsClose(fp); return -1; }; if (!checkPVD(&primary)) { spinlockRelease(&isoMountLock); kprintf_debug("isofs: the Primary Volume Descriptor is invalid\n"); vfsClose(fp); return -1; }; kprintf_debug("isofs: PVD validated\n"); ISOFileSystem *isofs = (ISOFileSystem*) kmalloc(sizeof(ISOFileSystem)); isofs->fp = fp; semInit(&isofs->sem); ISODirentHeader *rootDir = (ISODirentHeader*) &primary.rootDir; isofs->rootStart = (uint64_t)rootDir->startLBA * (uint64_t)primary.blockSize; isofs->rootEnd = isofs->rootStart + (uint64_t)rootDir->fileSize; isofs->blockSize = (uint64_t)primary.blockSize; isofs->numOpenInodes = 0; kprintf_debug("isofs: root directory start LBA is %a, block size is %d\n", rootDir->startLBA, primary.blockSize); fs->fsdata = isofs; fs->fsname = "isofs"; fs->openroot = iso_openroot; fs->unmount = iso_unmount; isoMountCount++; spinlockRelease(&isoMountLock); return 0; };
void initInterp() { kprintf("Loading the ELF interpreter... "); int error; File *fp = vfsOpen("/initrd/lib/libc.so", 0, &error); if (fp == NULL) { FAILED(); panic("failed to open /initrd/lib/libc.so (error %d)", error); }; Elf64_Ehdr elfHeader; if (vfsRead(fp, &elfHeader, sizeof(Elf64_Ehdr)) < sizeof(Elf64_Ehdr)) { FAILED(); panic("/initrd/lib/libc.so: ELF header too short"); }; if (memcmp(elfHeader.e_ident, "\x7f" "ELF", 4) != 0) { FAILED(); panic("/initrd/lib/libc.so: invalid ELF magic"); }; if (elfHeader.e_ident[EI_CLASS] != ELFCLASS64) { FAILED(); panic("/initrd/lib/libc.so: this is ELF32, not ELF64"); }; if (elfHeader.e_ident[EI_DATA] != ELFDATA2LSB) { FAILED(); panic("/initrd/lib/libc.so: ELF data not little-endian"); }; if (elfHeader.e_ident[EI_VERSION] != 1) { FAILED(); panic("/initrd/lib/libc.so: ELF version not 1"); }; if (elfHeader.e_type != ET_DYN) { FAILED(); panic("/initrd/lib/libc.so: not a dynamic library"); }; size_t progSize = elfHeader.e_phentsize * elfHeader.e_phnum; Elf64_Phdr *progHeads = (Elf64_Phdr*) kmalloc(progSize); fp->seek(fp, elfHeader.e_phoff, SEEK_SET); if (vfsRead(fp, progHeads, progSize) < progSize) { FAILED(); panic("/initrd/lib/libc.so: failed to read all program headers"); }; Elf64_Phdr *hdrText = NULL; Elf64_Phdr *hdrData = NULL; Elf64_Phdr *hdrDynamic = NULL; size_t i; for (i=0; i<elfHeader.e_phnum; i++) { Elf64_Phdr *phdr = &progHeads[i]; if ((phdr->p_type == PT_LOAD) && (phdr->p_flags & PF_W)) { hdrData = phdr; } else if (phdr->p_type == PT_LOAD) { hdrText = phdr; } else if (phdr->p_type == PT_DYNAMIC) { hdrDynamic = phdr; }; }; if ((hdrText == NULL) || (hdrData == NULL) || (hdrDynamic == NULL)) { FAILED(); panic("/initrd/lib/libc.so: expected text, data and dynamic program headers"); }; libcDynamicOffset = hdrDynamic->p_vaddr - hdrData->p_vaddr; libcDataOffset = hdrData->p_vaddr; libcDataSection = kmalloc(hdrData->p_memsz); memset(libcDataSection, 0, hdrData->p_memsz); // we must temporarily buffer all sections, with the correct layout, so that we can perform // relocations on the data sections while reading all the tables from the text section. char *tmpBuffer = (char*) kmalloc(hdrData->p_vaddr + hdrData->p_memsz); memset(tmpBuffer, 0, hdrData->p_vaddr + hdrData->p_memsz); fp->seek(fp, hdrText->p_offset, SEEK_SET); vfsRead(fp, &tmpBuffer[hdrText->p_vaddr], hdrText->p_filesz); fp->seek(fp, hdrData->p_offset, SEEK_SET); vfsRead(fp, &tmpBuffer[hdrData->p_vaddr], hdrData->p_filesz); // now perform all relocations Elf64_Rela *rela = NULL; Elf64_Rela *pltRela = NULL; Elf64_Word *hashtab; size_t szRela = 0; size_t szRelaEntry = 0; size_t pltRelaSize = 0; Elf64_Sym *symtab; char *strtab; Elf64_Dyn *dyn = (Elf64_Dyn*) ((uint64_t)tmpBuffer + hdrDynamic->p_vaddr); while (dyn->d_tag != DT_NULL) { if (dyn->d_tag == DT_RELA) { rela = (Elf64_Rela*) (tmpBuffer + dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_RELASZ) { szRela = dyn->d_un.d_val; } else if (dyn->d_tag == DT_RELAENT) { szRelaEntry = dyn->d_un.d_val; } else if (dyn->d_tag == DT_JMPREL) { pltRela = (Elf64_Rela*) (tmpBuffer + dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_PLTRELSZ) { pltRelaSize = dyn->d_un.d_val; } else if (dyn->d_tag == DT_STRTAB) { strtab = (char*) (tmpBuffer + dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_SYMTAB) { symtab = (Elf64_Sym*) (tmpBuffer + dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_HASH) { hashtab = (Elf64_Word*) (tmpBuffer + dyn->d_un.d_ptr); } else if (dyn->d_tag == DT_SYMENT) { if (dyn->d_un.d_val != sizeof(Elf64_Sym)) { FAILED(); panic("/initrd/lib/libc.so: symbol size mismatch"); }; } else if (dyn->d_tag == DT_NEEDED) { FAILED(); panic("/initrd/lib/libc.so: requesting additional libraries"); }; dyn++; }; if (rela != NULL) relocate(tmpBuffer, strtab, symtab, rela, szRela / szRelaEntry); if (pltRela != NULL) relocate(tmpBuffer, strtab, symtab, pltRela, pltRelaSize / sizeof(Elf64_Rela)); libcInterpMain = 0; libcInterpStack = 0; if ((symtab == NULL) || (hashtab == NULL) || (strtab == NULL)) { FAILED(); panic("/initrd/lib/libc.so: missing tables"); }; size_t numSymbols = hashtab[1]; libcSymbolCount = numSymbols; for (i=0; i<numSymbols; i++) { Elf64_Sym *sym = &symtab[i]; const char *name = &strtab[sym->st_name]; if (strcmp(name, "__interp_stack") == 0) { libcInterpStack = LIBC_BASE + sym->st_value + 4090; } else if (strcmp(name, "__interp_main") == 0) { libcInterpMain = LIBC_BASE + sym->st_value; }; }; if (libcInterpMain == 0) { FAILED(); panic("/initrd/lib/libc.so: could not find symbol __interp_main"); }; if (libcInterpStack == 0) { FAILED(); panic("/initrd/lib/libc.so: could not find symbol __interp_stack"); }; // copy the data into the data section memcpy(libcDataSection, &tmpBuffer[hdrData->p_vaddr], hdrData->p_memsz); // calculate the number of data pages libcDataPages = ((hdrData->p_vaddr + hdrData->p_memsz) / 0x1000) - (hdrData->p_vaddr / 0x1000) + 1; // make the text pages uint64_t textPages = ((hdrText->p_vaddr + hdrText->p_memsz) / 0x1000) - (hdrText->p_vaddr / 0x1000) + 1; libcTextFrames = palloc(textPages); libcTextFrames->flags = FL_SHARED; ispLock(); for (i=0; i<textPages; i++) { ispSetFrame(libcTextFrames->frames[i]); memcpy(ispGetPointer(), &tmpBuffer[hdrText->p_vaddr + i * 0x1000], 0x1000); }; ispUnlock(); // OK, cleanup time. libcDataSize = hdrData->p_memsz; libcNextLoadAddr = LIBC_BASE + hdrData->p_vaddr + hdrData->p_memsz; libcSymbolTable = (Elf64_Sym*) ((uint64_t)symtab - (uint64_t)tmpBuffer + LIBC_BASE); libcStringTable = strtab - tmpBuffer + (char*)LIBC_BASE; kfree(progHeads); kfree(tmpBuffer); vfsClose(fp); DONE(); };
UINT32 myXdcfCopyDisk(UINT32 ui32dstDirPos) { UINT8 filename[20]; UINT32 temp,temp1; UINT32 err = SUCCESS; UINT32 ui32FileIdx; UINT32 ui32FileCnt; UINT32 ui32DirCnt; UINT32 ui32DirIdx; UINT32 ui32DirPos; UINT32 ui32DirPos2; UINT32 ui32FileSize; UINT32 *pui32SavePage = NULL; SINT32 fd,fd2; xdcfAttrElm_t xdcfFileAttr; xdcfAttrElm_t xdcfDirAttr; xdcfCurDirPosGet(&ui32DirPos); xdcfFileCountGet(&ui32FileCnt); #if C_FILE_DEBUG printf("fine counter=%d,%d ",ui32DirPos,ui32FileCnt); #endif if(!ui32FileCnt) goto copyFileOver; pui32SavePage = osMemAlloc(C_READ_SECTION); if(!pui32SavePage) { #if C_FILE_DEBUG printf("alloc 100k fail "); #endif goto copyFileOver; } ui32FileIdx = 1; for(;ui32FileIdx<=ui32FileCnt;ui32FileIdx++) { xdcfActiveDevIdSet(DRIVE_NAND); xdcfCurDirByPosSet(ui32DirPos); xdcfCurFileByPosSet(ui32FileIdx); xdcfCurFileAttrGet(&xdcfFileAttr); myReadFilename(filename, xdcfFileAttr.name); fd = vfsOpen(xdcfFileAttr.name, O_BINARY, S_IREAD); ui32FileSize = vfsFileSizeGet(fd); xdcfActiveDevIdSet(DRIVE_SD); xdcfCurDirByPosSet(ui32dstDirPos); #if C_FILE_DEBUG printf("file %s=%d ",filename,ui32FileSize); #endif fd2 = vfsOpen(filename, O_CREATE, 0); while(ui32FileSize) { if(ui32FileSize>=C_READ_SECTION) temp = C_READ_SECTION; else temp = ui32FileSize; ui32FileSize -= temp; xdcfActiveDevIdSet(DRIVE_NAND); vfsRead(fd, pui32SavePage, temp); xdcfActiveDevIdSet(DRIVE_SD); temp1 = vfsWrite(fd2, pui32SavePage, temp); if(temp!=temp1) err |= FAIL; } vfsClose(fd); vfsClose(fd2); } copyFileOver: #if 0 #if C_FILE_DEBUG printf("dircnt=%d ",ui32DirCnt); #endif if(!ui32DirCnt) goto copyDirOver; ui32DirIdx = 1; xdcfActiveDevIdSet(DRIVE_NAND); err |= xdcfCurDirByPosSet(ui32DirPos); vfsCurrDirReset(); #if C_FILE_DEBUG printf("dir0=%s ",vfsGetCurrDirName()); #endif xdcfDirCountGet(&ui32DirCnt); xdcfCurDirAttrGet(&xdcfDirAttr); #if C_FILE_DEBUG printf("dir=%s ",xdcfDirAttr.name); #endif while((err|=xdcfCurDirByDirectSet(xDCF_MOVE_NEXT))==SUCCESS) { xdcfCurDirAttrGet(&xdcfDirAttr); #if C_FILE_DEBUG printf("dir=%s ",xdcfDirAttr.name); #endif } #if 0 for(;ui32DirIdx<=ui32DirCnt;ui32DirIdx++) { xdcfActiveDevIdSet(DRIVE_SD); err |= xdcfCurDirByPosSet(ui32dstDirPos); vfsMkdir(xdcfDirAttr.name); vfsChdir(xdcfDirAttr.name); xdcfCurDirPosGet(&ui32DirPos2); xdcfActiveDevIdSet(DRIVE_NAND); err |= xdcfCurDirByPosSet(ui32DirPos); myXdcfCopyDisk(ui32DirPos2); } #endif copyDirOver: #endif if(pui32SavePage) { osMemFree(pui32SavePage); pui32SavePage = NULL; } xdcfActiveDevIdSet(DRIVE_NAND); xdcfCurDirByPosSet(ui32DirPos); return err; }
void myGetSingleDayDL(UINT32 pos, UINT32 *ui32Data) { UINT8 *pStr; UINT8 *ui32Addr[32]; UINT32 j,k,len; UINT32 err = SUCCESS; UINT32 filesize; SINT32 i32DLfd; xdcfAttrElm_t xdcfFileAttr1; ui32Data[0] = 0; if((pos==0)||(ui8TimeFlag==0)) return; xdcfCurFileByPosSet(pos); err = xdcfCurFileAttrGet(&xdcfFileAttr1); i32DLfd = vfsOpen(xdcfFileAttr1.name, O_RDWR, 0); if(!i32DLfd) { #if C_FILE_DEBUG printf("open %s error ",xdcfFileAttr1.name); #endif return; } else { filesize = xdcfFileSizeGet(i32DLfd); j = strlen(ui8DLHeader1)+7+sizeof(ui8DLHeader2); for(k=0;k<C_DL_HEADER_3_LEN;k++) { j += strlen(ui8DLHeader3[k]); } j += 2; #if C_FILE_DEBUG printf("file header=%d ",j); #endif if(filesize<=j) return; len = filesize-j; pStr = osMemAlloc(len); if(!pStr) { #if C_FILE_DEBUG printf("alloc memory fail=%d ",len+1); #endif return; } vfsLseek(i32DLfd, j, SEEK_SET); vfsRead(i32DLfd, pStr, len); pStr[len] = '\0'; k = 0; while(k<len) { for(j=1;(pStr[k]!='\n')&&(pStr[k]!='\0');k++) { /*if(pStr[k]==',') { pStr[k] = '\0'; ui32Addr[j++] = &pStr[k+1]; }*/ } if(pStr[k]=='\0') return; k++; ui32Data[0]++; } vfsClose(i32DLfd); osMemFree(pStr); } }
void uiebook() { UINT32 key = UI_KEY_MODE_EBOOK; UINT8 ui8EBookEXPName[4] = "TXT" ; UINT8 ui8EBooKTempExp1[4]= "tmp"; UINT8 ui8EBookTempExp2[4]="emx"; UINT32 err; semApp = osEventFindByName("APP_SEM"); uiKeyMsgQ = osEventFindByName("UI_KEY"); pbDispStart = 1; ui32DirIdx = 0; ui32FileIdx = 0; while ( ( uiState & UI_MODE_MASK ) ==UI_MODE_EBOOK) { hisIconDisp(); hisTimeDisp(); if (ui32NextState != uiState) { break; } switch(key) { case UI_KEY_DIR_UP: if( ui8DispType == PB_DISP_FOUR ) { if(ui32FileIdx >1) ui32FileIdx --; else ui32FileIdx = ui32FileCnt; pbEBookRefresh(); } else if ( ui8DispType == PB_DISP_ONE ) { pbEBookPrePage();//上一页 } break; case UI_KEY_DIR_DOWN: if( ui8DispType == PB_DISP_FOUR ) { if(ui32FileIdx < ui32FileCnt) ui32FileIdx ++; else ui32FileIdx = 1; pbEBookRefresh(); } else if (ui8DispType == PB_DISP_ONE) { pbEBookNextPage ();//下一页 } break; case UI_KEY_ACCIDENT: osTimeDly(20); if (pui8ReadBuf) { osMemFree (pui8ReadBuf); pui8ReadBuf = NULL; } if ( pui32SavePage ) { osMemFree (pui32SavePage); pui32SavePage = NULL; } if (handle) { vfsClose(handle); handle = 0; } if (ui8DispType == PB_DISP_ONE) { ui8DispType = PB_DISP_FOUR; ui8EBookReadNow = 0; pbEBookRefresh(); //fqdao_modify for bug 23 06.4.29 osQuePost(uiKeyMsgQ, &keyButton[UI_KEY_ACCIDENT]); } break; case UI_KEY_FUNC_B: if( ui8DispType == PB_DISP_FOUR ) //fqdao_add 06.5.16 { buttonAudio(1) ; paEBookMenuFunc(); } break ; case UI_KEY_DIR_LEFT: break; case UI_KEY_DIR_RIGHT: break; /* case UI_KEY_FUNC_ZOOMIN: break ; case UI_KEY_FUNC_ZOOMOUT: break ; */ case UI_KEY_FUNC_MENU: if( ui8DispType == PB_DISP_FOUR ) { if ( pui8ReadBuf ) { osMemFree( pui8ReadBuf ); pui8ReadBuf = NULL; } if ( pui32SavePage ) { osMemFree( pui32SavePage ); pui32SavePage = NULL; } if ( handle ) { vfsClose(handle); handle = 0; } sub_menu_acc = 0; // UI_OSQFlush(uiKeyMsgQ); menuReturn(UI_MAINMENU, 0); osTimeDly(40); return; break; // UI_OSQFlush(uiKeyMsgQ); } else if ( ui8DispType == PB_DISP_ONE ) { /* Paul@2006/05/29 add start */ IsSaveBookmark(); /* Paul@2006/05/29 add end */ #if 1 ui8DispType = PB_DISP_FOUR; if ( pui8ReadBuf ) { osMemFree(pui8ReadBuf); pui8ReadBuf = NULL; } if ( pui32SavePage ) { osMemFree( pui32SavePage ); pui32SavePage = NULL; } ui8EBookReadNow = 0; if ( handle ) { vfsClose(handle); handle = 0; } //UI_OSQFlush(uiKeyMsgQ); pbInit(); osdClearScreen(0); //fqdao_add 06.5.19 pbEBookShow(EBOOK_DRAW_BG ,0 ); pbEBookRefresh(); #endif } break ; // case UI_KEY_FUNC_MODE: // break; case UI_KEY_FUNC_OK: if (ui32FileCnt != 0 && ui8DispType == PB_DISP_FOUR ) { if(pui32SavePage==NULL) { pui32SavePage = osMemAlloc(4096); if ( !pui32SavePage ) { break; } } handle = vfsOpen( xdcfFileAttr.name, O_RDONLY, S_IREAD); if ( !handle ) { break; } ui32FileSize= vfsFileSizeGet(handle); if ( ui32FileSize == 0 ) { osdStrDisp(160, 60, UserFont10x20, 0xd0, GetBookString(EmptyFile)); osTimeDly(100); //vfsClose(handle); break; } #if 0 if ( ui32FileSize < 1024*400 ) { pui8ReadBuf = osMemAlloc( ui32FileSize ); if ( pui8ReadBuf == NULL ) { osMemFree(pui32SavePage); vfsClose(handle); break; } ui32ReadSize = vfsRead(handle, pui8ReadBuf, ui32FileSize ); } else { pui8ReadBuf = osMemAlloc( 1024*400 );/*最大400k*/ if ( pui8ReadBuf == NULL ) { osMemFree(pui32SavePage); vfsClose(handle); break; } ui32ReadSize = vfsRead(handle, pui8ReadBuf, 1024*400); } #endif ui8EBookReadNow = 1; //vfsClose(handle); ui8DispType = PB_DISP_ONE; *pui32SavePage = 0; /*第一页指向的0(开始位置)*/ ui32FileIsEnd = 0; ui32CurPageFlag = 0; ui32PrePageFlag = 0; /* Paul@2006/05/29 add start */ CheckCurBookmark(); /* Paul@2006/05/29 add end */ osdClearScreen(0); pbEBookRefresh(); osTimeDly(50); } break; // case UI_KEY_FUNC_DISP: // break; case UI_KEY_MODE_EBOOK: if ( ui8FirstInEBook ) { xdcfFileTypeAdd(ui8EBooKTempExp1); // 128 xdcfFileTypeAdd(ui8EBookTempExp2); //256 xdcfFileTypeAdd(ui8EBookEXPName);//512 相当于 1<<9 ( xDCF_FILETYPE_RESERVE2) ui8FirstInEBook = 0; } osTaskSuspend(osTaskFindByName("AAA")); sysgMemDispAddrGet(&ui32gPB); if ( pui32SavePage ) { osMemFree( pui32SavePage ); pui32SavePage = NULL; } if ( pui8ReadBuf ) { osMemFree(pui8ReadBuf); pui8ReadBuf = NULL; } //添加目录名 xdcfInit(imageDirNameStr, imageRootNameStr, xDCF_CONFIG_KEY_MIN | xDCF_CONFIG_SORT_IDX/* | xDCF_CONFIG_DCF_ONLY*/); xdcfCurRootDirSet(otherRootNameStr); xdcfFilterSet( ui32FileFilter ); //ui32FileFilter = xDCF_FILETYPE_RESERVE2; hwWait(0,100); xdcfDirCountGet(&ui32DirCnt); xdcfCurDirAttrGet(&xdcfDirAttr); xdcfFileCountGet(&ui32FileCnt); ui32FileIdx = 1; if(ui32FileCnt == 0) { ui32FileIdx = 0; } ui8DispType = PB_DISP_FOUR ; pbInit(); pbEBookShow(EBOOK_DRAW_BG ,0 ); pbEBookRefresh(); break; default: break; } EBookkeyGet(&key); } if ( pui8ReadBuf ) { osMemFree(pui8ReadBuf); pui8ReadBuf = NULL; } if ( pui32SavePage ) { osMemFree( pui32SavePage ); pui32SavePage = NULL; } if ( handle ) { vfsClose(handle); handle = 0; } uiState = ui32NextState; }