//============================================================== void *_MmFileLoadB(const char *file, int area) //-------------------------------------------------------------- // malloc して読み込む // ※ブロックタイプ //-------------------------------------------------------------- // in: file = ファイル名 // area = 読み込みエリア //-------------------------------------------------------------- // out: 読み込みアドレス //============================================================== { sFILE *fp; size_t len; void *p; fp = FsOpen(file); ASSERT(fp); len = FsGetSizeOrig(fp); p = MemMalloc(area, len, GetFileBaseName(file)); ASSERT(p); FsRead(fp, p, len); FsClose(fp); mn_read_size = len; // FIXME:実ファイルサイズを返すべきか? // PRINTF("File '%s' Loaded.(%d bytes)\n", file, len); return p; }
//============================================================== void *MmTextFileLoad(const char *file) //-------------------------------------------------------------- // テキストファイルを読み込む // ※データ終端に '\0' を付加します //-------------------------------------------------------------- // in: file = ファイル名 //-------------------------------------------------------------- // out: 読み込みアドレス //============================================================== { sFILE *fp; size_t len; char *p; fp = FsOpen(file); ASSERT(fp); len = FsGetSizeOrig(fp); p = (char *)fsMalloc(len + 1, "text data"); ASSERT(p); FsRead(fp, p, len); FsClose(fp); *(p + len) = '\0'; return p; }
static void ShInt21(context_v86_t *ctx) { void *ptr; char *ch; uint32_t key; switch ((uint16_t) ctx->regs.eax >> 8) { case 0: ThrExitThread(0); break; case 1: while (!FsRead(ProcGetProcessInfo()->std_in, &key, 0, sizeof(key), NULL)) ; wprintf(L"%c", (uint8_t) key); ctx->regs.eax = (ctx->regs.eax & 0xffffff00) | (uint8_t) key; break; case 2: wprintf(L"%c", ctx->regs.edx & 0xff); break; case 9: ptr = FP_TO_LINEAR(ctx->v86_ds, ctx->regs.edx); ch = strchr(ptr, '$'); fwrite(ptr, 1, ch - (char*) ptr, stdout); break; case 0x4c: ThrExitThread(ctx->regs.eax & 0xff); break; } }
int ConClientThread(void *param) { char buf[80]; console_t *console; size_t bytes, length; wchar_t wbuf[80]; con_mbstate_t state; console = param; LmuxAcquire(&lmux_consoles); if (current == NULL) current = console; LmuxRelease(&lmux_consoles); ConInitMbState(&state); while (FsRead(console->client, buf, 0, sizeof(buf), &bytes)) { length = ConMultiByteToWideChar(wbuf, buf, bytes, &state); if (length > 0) ConPutStr(console, wbuf, length); } HndClose(console->client); LmuxAcquire(&lmux_consoles); if (current == console) current = NULL; LmuxRelease(&lmux_consoles); return 0; }
//============================================================== void MakeBackupFile(const char *fname) //-------------------------------------------------------------- // PATH_BACKUP にバックアップをとる //-------------------------------------------------------------- // in: file = バックアップを取るファイル名 //-------------------------------------------------------------- // out: なし //============================================================== { char d_name[FNAME_MAXLEN]; void *tmp_buf; sFILE *fd_src, *fd_dst; size_t len, size; // オリジナルのファイルを開く //---------------------------- fd_src = FsOpen(fname); if(!fd_src) { return; } // バックアップファイルの作成 //---------------------------- sprintf(d_name, PATH_BACKUP"/%s.%s", GetFileBaseName(fname), StrMakeUniqueName()); fd_dst = FsCreate(d_name); if (!fd_dst) { FsClose(fd_src); return; } // 作業バッファを確保 //-------------------- tmp_buf = devMalloc(TMPBUF_LEN, "MakeBackupFile"); len = FsGetSizeOrig(fd_src); while(len) { size = (len >= TMPBUF_LEN) ? TMPBUF_LEN : len; FsRead(fd_src, tmp_buf, size); FsWrite(fd_dst, tmp_buf, size); len -= size; } FsClose(fd_src); FsClose(fd_dst); Free(tmp_buf); // SYSINFODSP("Make Backup file"); // SYSINFODSP("%s", MSG_FILE(d_name)); // SYSINFO("Make Backup file"); // SYSINFO("%s", MSG_FILE(d_name)); // SYSINFOCNS("Make Backup file"); // SYSINFOCNS("%s", MSG_FILE(d_name)); }
ssize_t read(int fd, void *buf, size_t nbyte) { size_t bytes; if (!FsRead(fd, buf, nbyte, &bytes)) return -1; return bytes; }
void InputRecordRead(sFILE *fp) { gInput[INP_CH0].record = FALSE; gInput[INP_CH0].playback = FALSE; u_int header; FsRead(fp, &header, sizeof(u_int)); record_num = ntohl(header); record_ofs = record_num; FreeWork(record); record = (sInputRecord *)fsMalloc(sizeof(sInputRecord) * record_num, "record"); ASSERT(record); FileBuffer buffer; size_t size = FsGetSize(fp) - 4; void *zptr = fsMalloc(size, "zlib"); ASSERT(zptr); FsRead(fp, zptr, size); buffer.ptr = (u_char *)ZlibDecode(zptr, ZlibEncodeSize(zptr)); buffer.ofs = 0; Free(zptr); sInputRecord *ptr = record; for(int i = 0; i < record_ofs; i += 1) { ptr->x = (int)getIntValue(&buffer); ptr->y = (int)getIntValue(&buffer); ptr->btn_p = getIntValue(&buffer); ptr->btn_td = getIntValue(&buffer); ptr->btn_tu = getIntValue(&buffer); RecKey *recKey = ptr->recKey; for(int h = 0; h < KEY_INPUT_BUFFER * 2; h += 1) { recKey->key = getCharValue(&buffer); recKey->push = (BOOL)getCharValue(&buffer); recKey += 1; } ptr->recNum = getIntValue(&buffer); ptr += 1; } Free(buffer.ptr); }
//---------------------------------------------------------------------- // // ProcessGetCodeSizes // // Get the code sizes (stack & data) for a file. A file descriptor // for the named file is returned. This descriptor MUST be closed // (presumably by the caller) at some point. // //---------------------------------------------------------------------- int ProcessGetCodeInfo (const char *file, uint32 *startAddr, uint32 *codeStart, uint32 *codeSize, uint32 *dataStart, uint32 *dataSize) { int fd; int totalsize; char buf[100]; char *pos; // Open the file for reading. If it returns a negative number, the open // didn't work. if ((fd = FsOpen (file, FS_MODE_READ)) < 0) { dbprintf ('f', "ProcessGetCodeInfo: open of %s failed (%d).\n", file, fd); return (-1); } dbprintf ('f', "File descriptor is now %d.\n", fd); if ((totalsize = FsRead (fd, buf, sizeof (buf))) != sizeof (buf)) { dbprintf ('f', "ProcessGetCodeInfo: read got %d (not %d) bytes from %s\n", totalsize, (int)sizeof (buf), file); FsClose (fd); return (-1); } if (dstrstr (buf, "start:") == NULL) { dbprintf ('f', "ProcessGetCodeInfo: %s missing start line (not a DLX executable?)\n", file); return (-1); } pos = (char *)dindex (buf, ':') + 1; // Get the start address and overall size *startAddr = dstrtol (pos, &pos, 16); totalsize = dstrtol (pos, &pos, 16); // Get code & data section start & sizes *codeStart = dstrtol (pos, &pos, 16); *codeSize = dstrtol (pos, &pos, 16); *dataStart = dstrtol (pos, &pos, 16); *dataSize = dstrtol (pos, &pos, 16); // Seek to start of first real line FsSeek (fd, 1 + dindex (buf, '\n') - buf, 0); return (fd); }
int DiskReadBlock (uint32 blocknum, disk_block *b) { int fsfd = -1; uint32 intrvals = 0; char *filename = NULL; if (blocknum >= DISK_NUMBLOCKS) { printf("DiskReadBlock: cannot read from block larger than filesystem size\n"); return DISK_FAIL; } if (filename[11] == 'X') { printf("DiskReadBlock: you didn't change the filesystem filename in include/os/disk.h. Cowardly refusing to do anything.\n"); GracefulExit(); } intrvals = DisableIntrs(); // Open the hard disk file if ((fsfd = FsOpen(DISK_FILENAME, FS_MODE_READ)) < 0) { printf ("DiskReadBlock: File system %s cannot be opened!\n", DISK_FILENAME); return DISK_FAIL; } /* printf("fsfd = %d\n", fsfd); */ // Read data from virtual disk FsSeek(fsfd, blocknum * DISK_BLOCKSIZE, FS_SEEK_SET); if (FsRead(fsfd, b->data, DISK_BLOCKSIZE) != DISK_BLOCKSIZE) { printf ("DiskReadBlock: Block %d could not be read!\n", blocknum); FsClose (fsfd); return DISK_FAIL; } // Close the hard disk file FsClose (fsfd); RestoreIntrs(intrvals); return DISK_BLOCKSIZE; }
static bool IpcReadFromPipe(handle_t file, void *buf, size_t length) { size_t bytes, total; total = 0; errno = 0; while (total < length) { //printf("FsRead(file=%u, length=%u-%u=%u)\n", //file, length, total, length - total); if (!FsRead(file, (char*) buf + total, 0, length - total, &bytes) || (length > 0 && bytes == 0)) { _wdprintf(L"%s: IpcReadFromPipe(%u): bytes = %u, errno = %d\n", ProcGetProcessInfo()->module_first->name, file, bytes, errno); return false; } total += bytes; } return true; }
//---------------------------------------------------------------------- // // ProcessGetFromFile // // Inputs: // addr - points to an integer that contains the address of // the byte past that previously returned. If this is the // first call to this routine, *addr should be set to 0. // fd - File descriptor from which to read data. The file format // is the same as that used by the DLX simulator. // buf - points to a buffer that will receive data from the input // file. Note that the data is NOT 0-terminated, and may // include any number of 0 bytes. // max - maximum length of data to return. The routine collects data // until either the address changes or it has read max bytes. // // Returns the number of bytes actually stored into buf. In addition, // *addr is updated to point to the byte following the last byte in // the buffer. // // Load a file into memory. The file format consists of a // leading address, followed by a colon, followed by the data // to go at that address. If the address is omitted, the data // follows that from the previous line of the file. // //---------------------------------------------------------------------- int ProcessGetFromFile (int fd, unsigned char *buf, uint32 *addr, int max) { char localbuf[204]; int nbytes; int seekpos; unsigned char *pos = buf; char *lpos = localbuf; // Remember our position at the start of the routine so we can adjust // it later. seekpos = FsSeek (fd, 0, FS_SEEK_CUR); // The maximum number of characters we could read is limited to the // maximum buffer space available to the caller * 2 because each 2 // characters in the input file result in a single byte of program // info being read in. max = max * 2; // If the callers maximum is greater than the available buffer space, // limit the buffer space further. if (max > (sizeof(localbuf)-4)) { max = sizeof(localbuf)-4; } if ((nbytes = FsRead (fd, localbuf, max)) <= 0) { return (0); } // 'Z' is unused in load file, so use it to mark the end of the buffer // Back up until just after the last newline in the data we read. dbprintf ('f', "Got %d bytes at offset %d ...", nbytes, seekpos); while (localbuf[--nbytes] != '\n') { } localbuf[nbytes+1] = 'Z'; localbuf[nbytes+2] = '\0'; dbprintf ('f', " terminated at %d.\n", nbytes); dbprintf ('f', "Buffer is '%s'\n", localbuf); nbytes = 0; while (dindex (lpos, 'Z') != NULL) { if (dindex (lpos, ':') == NULL) { break; } if (*lpos != ':') { // If we're going to go to a new address, we break out of the // loop and return what we've got already. if (nbytes > 0) { break; } *addr = dstrtol (lpos, &lpos, 16); dbprintf ('f', "New address is 0x%x.\n", (int)(*addr)); } if (*lpos != ':') { break; } lpos++; // skip past colon while (1) { while (((*lpos) == ' ') || (*lpos == '\t')) { lpos++; } if (*lpos == '\n') { lpos++; break; } else if (!(isxdigit (*lpos) && isxdigit (*(lpos+1)))) { // Exit loop if at least one digit isn't a hex digit. break; } pos[nbytes++] = (getxvalue(*lpos) * 16) + getxvalue(*(lpos+1)); lpos += 2; (*addr)++; } } // Seek to just past the last line we read. FsSeek (fd, seekpos + lpos - localbuf, FS_SEEK_SET); dbprintf ('f', "Seeking to %d and returning %d bytes!\n", (int)(seekpos + lpos - localbuf), nbytes); return (nbytes); }
status_t CdfsReadDir(fsd_t *fsd, void *dir_cookie, dirent_t *buf) { cdfs_t *cdfs; cdsearch_t *search; entry_t entry; uint32_t sector; size_t bytes_read; unsigned i; char entry_name[MAX_NAME_LENGTH]; wchar_t entry_name_wide[MAX_NAME_LENGTH + 1]; bool found; cdfs = (cdfs_t*) fsd; search = dir_cookie; sector = search->offset / SECTOR_SIZE; found = false; while (!found) { if (!FsRead(search->node->directory, &entry, search->offset, offsetof(entry_t, id), &bytes_read)) return errno; if (bytes_read < offsetof(entry_t, id)) return EHARDWARE; if (entry.struct_size == 0) return EEOF; assert(entry.id_length < _countof(entry_name)); if (search->index >= 2 && entry.id_length > 0) { if (!FsRead(search->node->directory, entry_name, search->offset + offsetof(entry_t, id), min(_countof(entry_name), entry.id_length), &bytes_read)) return errno; if (bytes_read < min(_countof(entry_name) - 1, entry.id_length)) return EHARDWARE; for (i = 0; entry_name[i] != ';' && i < entry.id_length; i++) entry_name_wide[i] = (wchar_t) (unsigned char) tolower(entry_name[i]); entry_name_wide[i] = '\0'; buf->vnode = CdfsGenerateNodeId(cdfs, search->node->id, search->index); wcsncpy(buf->name, entry_name_wide, _countof(buf->name)); found = true; } search->offset += entry.struct_size; if (search->offset / SECTOR_SIZE != sector) { assert(search->offset / SECTOR_SIZE < sector + 1); sector++; search->offset = sector * SECTOR_SIZE; } search->index++; } return 0; }
status_t CdfsParseElement(fsd_t *fsd, const wchar_t *name, wchar_t **new_path, vnode_t *node) { cdfs_t *cdfs; cdnode_t *cdnode; entry_t entry; uint32_t offset, sector; uint8_t entry_name[MAX_NAME_LENGTH]; wchar_t entry_name_wide[MAX_NAME_LENGTH + 1]; unsigned i, index; size_t bytes_read; cdfs = (cdfs_t*) fsd; cdnode = CdfsGetNode(cdfs, node->id); if (cdnode == NULL) { wprintf(L"CdfsParseElement(%x/%s): invalid parent node\n", node->id, name); return ENOTFOUND; } if (cdnode->directory == NULL) { wprintf(L"CdfsParseElement(%x/%s): parent is not a directory\n", node->id, name); return ENOTADIR; } offset = 0; sector = 0; index = 0; while (true) { if (!FsRead(cdnode->directory, &entry, offset, offsetof(entry_t, id), &bytes_read)) return errno; if (bytes_read < offsetof(entry_t, id) || entry.struct_size == 0) break; assert(entry.id_length < _countof(entry_name)); if (index >= 2) { if (!FsRead(cdnode->directory, entry_name, offset + offsetof(entry_t, id), min(_countof(entry_name), entry.id_length), &bytes_read)) return errno; if (bytes_read < min(_countof(entry_name) - 1, entry.id_length)) break; for (i = 0; entry_name[i] != ';' && i < entry.id_length; i++) entry_name_wide[i] = (wchar_t) (unsigned char) tolower(entry_name[i]); entry_name_wide[i] = '\0'; if (_wcsicmp(entry_name_wide, name) == 0) { //cdnode_t *temp; //wprintf(L"CdfsParseElement(%x/%s): ", node->id, name); node->id = CdfsAllocNode(cdfs, node->id, index, &entry, entry_name_wide); CdfsReleaseNode(cdfs, cdnode); //temp = CdfsGetNode(cdfs, node->id); //wprintf(L"%p %x\n", temp->name, node->id); //CdfsReleaseNode(cdfs, temp); return 0; } } offset += entry.struct_size; if (offset / SECTOR_SIZE != sector) { assert(offset / SECTOR_SIZE < sector + 1); sector++; offset = sector * SECTOR_SIZE; } index++; } CdfsReleaseNode(cdfs, cdnode); return ENOTFOUND; }
static void ShDumpFile(const wchar_t *name, void (*fn)(const void*, addr_t, size_t)) { static char buf[16 + 1]; handle_t file; size_t len; addr_t origin; dirent_standard_t di; char *ptr, *dyn; di.length = 0; if (!FsQueryFile(name, FILE_QUERY_STANDARD, &di, sizeof(di)) || di.length == 0) { di.length = sizeof(buf) - 1; ptr = buf; dyn = NULL; } else { dyn = malloc(di.length); ptr = dyn; } printf("ShDumpFile(%S): reading in chunks of %lu\n", name, (uint32_t) di.length); file = FsOpen(name, FILE_READ); if (file == NULL) { _pwerror(name); return; } origin = 0; do { //KeLeakBegin(); //printf("[b]"); if (!FsRead(file, ptr, origin, di.length, &len)) { _pwerror(name); break; } //KeLeakEnd(); if (len == 0) { printf("FSD read zero bytes but didn't report an error\n"); break; } if (len < di.length) ptr[len] = '\0'; /*printf("%u", len);*/ fn(ptr, origin, len); origin += len; if (len < di.length) { printf("FSD hit the end of the file: successful but only %u bytes read\n", len); break; } //printf("[e]"); fflush(stdout); } while (true); free(dyn); HndClose(file); }
void ShCmdV86(const wchar_t *cmd, wchar_t *params) { uint8_t *code; psp_t *psp; FARPTR fp_code, fp_stackend; handle_t thr, file; dirent_standard_t di; bool doWait; wchar_t **names, **values; ShParseParams(params, &names, &values, ¶ms); params = ShPrompt(L" .COM file? ", params); if (*params == '\0') return; doWait = true; if (ShHasParam(names, L"nowait")) doWait = false; free(names); free(values); /*if (!FsQueryFile(params, FILE_QUERY_STANDARD, &di, sizeof(di))) { _pwerror(params); return; }*/ di.length = 0x10000; file = FsOpen(params, FILE_READ); if (file == NULL) { wprintf(L"FsOpen: "); _pwerror(params); return; } code = aligned_alloc(di.length + 0x100); psp = (psp_t*) code; memset(psp, 0, sizeof(*psp)); psp->int20 = 0x20cd; if (!FsRead(file, code + 0x100, 0, di.length, NULL)) { wprintf(L"FsRead: "); _pwerror(params); HndClose(file); return; } HndClose(file); fp_code = i386LinearToFp(code); fp_code = MK_FP(FP_SEG(fp_code), FP_OFF(fp_code) + 0x100); if (sh_v86stack == NULL) sh_v86stack = aligned_alloc(65536); fp_stackend = i386LinearToFp(sh_v86stack); memset(sh_v86stack, 0, 65536); thr = ThrCreateV86Thread(fp_code, fp_stackend, 15, ShV86Handler, params); if (doWait) ThrWaitHandle(thr); /* xxx - need to clean up HndClose() implementation before we can use this */ /*HndClose(thr);*/ }
int ConKeyboardThread(void *param) { uint32_t ch, code; handle_t keyboard; //void *old_buffer; //unsigned i; keyboard = FsOpen(SYS_DEVICES L"/keyboard", FILE_READ); while (FsRead(keyboard, &ch, 0, sizeof(ch), NULL)) { code = ch & ~KBD_BUCKY_ANY; if ((ch & KBD_BUCKY_ALT) != 0 && code >= KEY_F1 && code <= KEY_F12) { /*LmuxAcquire(&lmux_consoles); LmuxAcquire(¤t->lmux); ConDrawCursor(current, false); old_buffer = current->cookie; current = consoles + code - KEY_F1; if (old_buffer != current->buffer) for (i = 0; i < num_consoles; i++) if (consoles[i].buffer == current->buffer) ConRedraw(consoles + i); ConDrawCursor(current, true); LmuxRelease(¤t->lmux); LmuxRelease(&lmux_consoles);*/ } else if (ch == (KBD_BUCKY_CTRL | KBD_BUCKY_ALT | KEY_DEL)) SysShutdown(SHUTDOWN_REBOOT); else if (ch == (KBD_BUCKY_ALT | '\t') || ch == (KBD_BUCKY_ALT | KBD_BUCKY_SHIFT | '\t')) { LmuxAcquire(&lmux_consoles); LmuxAcquire(¤t->lmux); ConDrawCursor(current, false); LmuxRelease(¤t->lmux); if (ch & KBD_BUCKY_SHIFT) { if (current - consoles - 1 < 0) current = consoles + num_consoles - 1; else current--; } else { if (current - consoles + 1 >= num_consoles) current = consoles; else current++; } LmuxAcquire(¤t->lmux); ConDrawCursor(current, true); LmuxRelease(¤t->lmux); LmuxRelease(&lmux_consoles); } else { LmuxAcquire(&lmux_consoles); if (current != NULL && current->client != NULL) FsWrite(current->client, &ch, 0, sizeof(ch), NULL); LmuxRelease(&lmux_consoles); } } _wdprintf(L"console(keyboard): FsRead failed, %s\n", _wcserror(errno)); return errno; }