void testCharDeviceIo(const wchar_t *name) { handle_t file; fileop_t op; uint32_t key; file = FsOpen(name, FILE_READ); if (file == NULL) wprintf(L"Failed to open %s\n", name); else { op.event = EvtCreate(false); op.bytes = 0; wprintf(L"op = %p op.event = %u sig = %u\n", &op, op.event, EvtIsSignalled(op.event)); if (op.event != NULL) { while (true) { status_t ret; ret = FsReadAsync(file, &key, 0, sizeof(key), &op); if (ret > 0) break; else if (ret == SIOPENDING) { DbgWrite(L"Wait start\n", 11); /*while (EvtIsSignalled(op.event))*/ ThrWaitHandle(op.event); DbgWrite(L"Wait end\n", 9); ret = op.result; } /*wprintf(L"op.result = %d op.bytes = %u\n", op.result, op.bytes);*/ if (ret == SIOPENDING) wprintf(L"op.result is still SIOPENDING\n"); else { if (ret > 0 || op.bytes == 0) break; wprintf(L"%c", (wchar_t) key); if (key == 27) break; } op.bytes = 0; } DbgWrite(L"Finished\n", 9); wprintf(L"Finished: op.result = %d, op.bytes = %u\n", op.result, op.bytes); HndClose(op.event); } } HndClose(file); }
void testBlockDeviceIo(const wchar_t *name) { handle_t file; unsigned i, j; fileop_t op; wchar_t *ch; file = FsOpen(name, FILE_READ); if (file == NULL) wprintf(L"Failed to open %s\n", name); else { op.event = EvtCreate(false); for (j = 0; j < 1; j++) { status_t ret; wprintf(/*L"\x1b[2J"*/ L"\x1b[%um", (j % 8) + 30); ret = FsReadAsync(file, key, 9 * 512, sizeof(key), &op); if (ret > 0) break; else if (ret == SIOPENDING) { ThrWaitHandle(op.event); ret = op.result; } if (ret == SIOPENDING) wprintf(L"op.result is still SIOPENDING\n"); else if (ret == 0 && op.bytes > 0) { wprintf(L"Read %u bytes\n", op.bytes); ch = str; for (i = 0; i < op.bytes; i++) { swprintf(ch, L"%02X", key[i]); ch += 2; } _cputws(str, op.bytes * 2); /*for (i = 0; i < op.bytes; i++) wprintf(L"%02X", key[i]);*/ } else break; } DbgWrite(L"Finished\n", 9); wprintf(L"Finished: op.result = %d, op.bytes = %u\n", op.result, op.bytes); HndClose(op.event); } HndClose(file); }
void testFileIo(const wchar_t *name) { handle_t file; unsigned i; size_t len; fileop_t op; uint64_t offset; file = FsOpen(name, FILE_READ); if (file == NULL) { wprintf(L"Failed to open %s\n", name); return; } op.event = EvtCreate(false); for (i = 0; i < 16; i++) { offset = 0; wprintf(L"\x1b[%um", (i % 8) + 30); while (true) { status_t ret; ret = FsReadAsync(file, key, offset, sizeof(key), &op); if (ret > 0) break; else if (ret == SIOPENDING) { ThrWaitHandle(op.event); ret = op.result; } len = op.bytes; if (len == 0) break; if (len < sizeof(key)) key[len] = '\0'; len = mbstowcs(str, key, _countof(key) - 1); if (len == -1) wprintf(L"invalid multibyte sequence\n"); else _cputws(str, len); offset += op.bytes; } ThrSleep(5000); } HndClose(op.event); HndClose(file); }
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; }
static void EthHandleBinding(void) { net_binding_t *bind; request_eth_t req_eth; union { uint8_t raw[ETH_FRAME_LEN]; net_ether header; } packet; page_array_t *pages; io_callback_t cb; event_t *event; net_hwaddr_t src, dst; bind = ThrGetCurrent()->info->param; pages = MemCreatePageArray(packet.raw, sizeof(packet.raw)); event = EvtCreate(false); src.type = dst.type = NET_HW_ETHERNET; src.data_size = dst.data_size = 6; while (true) { req_eth.header.code = ETH_RECEIVE; req_eth.header.param = (void*) event; memcpy(req_eth.params.eth_receive.from, bcast, sizeof(bcast)); req_eth.params.eth_receive.type = (uint16_t) (addr_t) bind->hw_cookie; req_eth.params.eth_receive.pages = pages; req_eth.params.eth_receive.length = sizeof(packet.raw); cb.type = IO_CALLBACK_FUNCTION; cb.u.function = EthHandleBindingCompletion; if (!IoRequest(&cb, bind->dev, &req_eth.header)) { wprintf(L"EthHandleBinding: IoRequest error\n"); break; } ThrWaitHandle(ThrGetCurrent(), &event->hdr); KeYield(); memcpy(src.u.ethernet, packet.header.src, sizeof(src.u.ethernet)); memcpy(dst.u.ethernet, packet.header.dst, sizeof(dst.u.ethernet)); if (bind->proto->vtbl->receive_packet != NULL) bind->proto->vtbl->receive_packet(bind->proto, bind, &src, &dst, packet.raw + sizeof(packet.header), req_eth.params.eth_receive.length - sizeof(packet.header)); } HndClose(&event->hdr); ThrExitThread(0); KeYield(); }
bool GmgrInit(void) { params_vid_t params; handle_t device; LmuxInit(&gmgr_draw); LmuxInit(&gmgr_mux_gfxs); atexit(GmgrCleanup); device = FsOpen(SYS_DEVICES L"/Classes/video0", FILE_READ | FILE_WRITE); if (device == NULL) { _wdprintf(SYS_DEVICES L"/Classes/video0" L": %s\n", _wcserror(errno)); goto error0; } memset(¶ms.vid_setmode, 0, sizeof(params.vid_setmode)); if (!FsRequestSync(device, VID_SETMODE, ¶ms, sizeof(params), NULL)) { _wdprintf(L"VID_SETMODE: %s\n", _wcserror(errno)); goto error1; } gmgr_screen = GmgrCreateDeviceSurface(device, ¶ms.vid_setmode); if (gmgr_screen == NULL) { _wdprintf(L"GmgrCreateDeviceSurface: %s\n", _wcserror(errno)); goto error1; } gmgr_font = FontLoad(L"/Mobius/veramono.ttf", 12 * 64, gmgr_screen->mode.bitsPerPixel < 8 ? FB_FONT_MONO : FB_FONT_SMOOTH); if (gmgr_font == NULL) { _wdprintf(L"/Mobius/veramono.ttf: %s\n", _wcserror(errno)); goto error2; } if (!GmgrInitCursor()) goto error3; return true; error3: FontDelete(gmgr_font); gmgr_font = NULL; error2: GmgrCloseSurface(gmgr_screen); gmgr_screen = NULL; error1: HndClose(device); error0: return false; }
gmgr_surface_t *GmgrCreateDeviceSurface(handle_t device, const videomode_t *mode) { gmgr_surface_t *surf; handle_t memory; surf = malloc(sizeof(*surf)); if (surf == NULL) return NULL; surf->refs = 1; surf->device = device; surf->flags = GMGR_SURFACE_SHARED; surf->mode = *mode; if (mode->framebuffer[0] == '\0') { surf->base = NULL; if (!AccelCreateSurface(mode, device, &surf->surf)) { _wdprintf(L"GmgrCreateDeviceSurface: AccelCreateSurface failed\n"); free(surf); return NULL; } } else { memory = HndOpen(mode->framebuffer); surf->base = VmmMapSharedArea(memory, NULL, VM_MEM_USER | VM_MEM_READ | VM_MEM_WRITE); HndClose(memory); if (!FramebufCreateSurface(mode, surf->base, &surf->surf)) { _wdprintf(L"GmgrCreateDeviceSurface: FramebufCreateSurface failed\n"); VmmFree(surf->base); free(surf); return NULL; } } return surf; }
static void DevCallLoader(load_request_t *load) { event_t *evt_done; evt_done = EvtCreate(false); load->evt_done = evt_done; SemDown(mux_load); LIST_ADD(load, load); SemUp(mux_load); wprintf(L"DevCallLoader: submitting request\n"); SemUp(sem_load); ThrWaitHandle(current(), &evt_done->hdr); KeYield(); HndClose(&evt_done->hdr); }
static void DevLoaderThread(void) { load_request_t *load; event_t *evt_done; while (true) { wprintf(L"DevLoaderThread: waiting for request\n"); SemDown(sem_load); wprintf(L"DevLoaderThread: got request\n"); SemDown(mux_load); load = load_first; LIST_REMOVE(load, load); SemUp(mux_load); evt_done = (event_t*) HndCopy(&load->evt_done->hdr); switch (load->action) { case LOAD_ACTION_LOAD_DRIVER: load->status = DevDoLoadDriver(load->u.load_driver.name, &load->u.load_driver.driver); break; case LOAD_ACTION_ADD_DEVICE: load->u.add_device.driver->add_device(load->u.add_device.driver, load->u.add_device.name, load->u.add_device.config); load->status = 0; break; default: wprintf(L"DevLoaderThread: invalid action: %u\n", load->action); assert(load->action == LOAD_ACTION_LOAD_DRIVER || load->action == LOAD_ACTION_ADD_DEVICE); break; } EvtSignal(evt_done, true); HndClose(&evt_done->hdr); } }
void ThrEvaluateWait(thread_t *thr, handle_hdr_t *reason) { unsigned i, handles_set; int last_unset; handles_set = 0; last_unset = -1; for (i = 0; i < thr->num_wait_handles; i++) { if (thr->wait_handles[i] == reason) { HndClose(reason); thr->wait_handles[i] = NULL; } if (thr->wait_handles[i] == NULL) last_unset = i; else handles_set++; } //if (thr->num_wait_handles > 1) //wprintf(L"ThrEvaluateWait: handles_set = %u, num_wait_handles = %u: ", //handles_set, thr->num_wait_handles); if ((thr->wait_all && handles_set == 0) || (!thr->wait_all && handles_set < thr->num_wait_handles)) { //if (thr->num_wait_handles > 1) //wprintf(L"running, last_unset = %d\n", last_unset); if (thr->wait_result != NULL) *thr->wait_result = last_unset; thr->wait_result = NULL; thr->num_wait_handles = 0; ThrRun(thr); ScNeedSchedule(true); } //else if (thr->num_wait_handles > 1) //wprintf(L"not running\n"); }
void GmgrCloseSurface(gmgr_surface_t *surf) { if (SysDecrementAndTest(&surf->refs)) { surf->surf.vtbl->SurfDeleteCookie(&surf->surf); if (surf->base != NULL) { if (surf->flags & GMGR_SURFACE_SHARED) VmmFree(surf->base); else free(surf->base); } if (surf->device != 0) HndClose(surf->device); free(surf); } }
bool OnCreate() { static const wchar_t mouse_prefix[] = L"mouse"; handle_t dir; dirent_t di; wchar_t name[30]; OS::LayoutColumn *column; if (!OS::DialogBox::OnCreate()) return false; column = new OS::LayoutColumn(L"20"); column->AddLayout(new OS::LayoutControl(&m_label)); OS::Rect rect = GetClientArea(); rect.Inflate(-5, -5); rect.bottom = rect.top + rect.Height() / _countof(m_buttons); m_num_buttons = 0; dir = FsOpenDir(SYS_DEVICES L"/Classes"); while (FsReadDir(dir, &di, sizeof(di)) && m_num_buttons < _countof(m_buttons)) { if (wcslen(di.name) >= (_countof(mouse_prefix) - 1) && _wcsnicmp(di.name, mouse_prefix, _countof(mouse_prefix) - 1) == 0) { swprintf(name, L"Press %c: %s", m_num_buttons + 'A', di.name); wcscpy(m_names[m_num_buttons], di.name); //m_buttons[m_num_buttons].Create(&m_container, name, rect); m_buttons[m_num_buttons].Create(&m_container, name, OS::Rect(0, 0, 0, 0)); column->AddLayout(new OS::LayoutControl(m_buttons + m_num_buttons)); rect.Offset(0, rect.Height()); m_num_buttons++; } } HndClose(dir); if (m_num_buttons == 0) { m_label.Create(&m_container, L"No mice found\n" L"Check " SYS_BOOT L"/system.pro\n" L"\n" L"Press Esc to continue", OS::Label::AlignLeft | OS::Label::AlignTop); } else { m_label.Create(&m_container, L"Choose the input device to\n" L"use with The Möbius:", OS::Label::AlignLeft | OS::Label::AlignTop); } m_container.AddLayout(column); m_container.UpdateLayout(); if (m_num_buttons == 1) OnKeyDown('A'); return true; }
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);*/ }
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 LmuxDelete(lmutex_t *mux) { HndClose(mux->mutex); }
int mainCRTStartup(void) { handle_t server, client; unsigned i; params_vid_t params; font_t *font; vid = FsOpen(SYS_DEVICES L"/Classes/video0", FILE_READ | FILE_WRITE); if (vid == NULL) { _wdprintf(L"console: " SYS_DEVICES L"/Classes/video0: %s\n", _wcserror(errno)); return errno; } memset(&mode, 0, sizeof(mode)); params.vid_setmode = mode; if (!FsRequestSync(vid, VID_SETMODE, ¶ms, sizeof(params), NULL)) { _wdprintf(L"console: failed to set video mode: %s\n", _wcserror(errno)); HndClose(vid); return errno; } mode = params.vid_setmode; if (mode.flags & VIDEO_MODE_TEXT) { _wdprintf(L"console: text mode not supported\n"); return 0; } if (mode.bitsPerPixel == 4) { vidmem = NULL; if (!AccelCreateSurface(&mode, vid, &surf)) { _wdprintf(L"console: AccelCreateSurface failed\n"); return errno; } } else { handle_t handle_vidmem; handle_vidmem = HndOpen(mode.framebuffer); if (handle_vidmem == 0) { _wdprintf(L"console: unable to open framebuffer %s\n", mode.framebuffer); return errno; } vidmem = VmmMapSharedArea(handle_vidmem, 0, VM_MEM_USER | VM_MEM_READ | VM_MEM_WRITE); HndClose(handle_vidmem); if (!FramebufCreateSurface(&mode, vidmem, &surf)) { _wdprintf(L"console: video mode not supported: %u bits per pixel\n", mode.bitsPerPixel); return errno; } } FontInit(); font = FontLoad(font_name, 10 * 64, mode.bitsPerPixel < 8 ? FB_FONT_MONO : FB_FONT_SMOOTH); if (font == NULL) { _wdprintf(L"console: failed to load font %s\n", font_name); return errno; } cookies[0] = (void*) 0x12345678; num_buffers = 1; LmuxInit(&lmux_consoles); for (i = 0; i < _countof(consoles); i++) { LmuxInit(&consoles[i].lmux); consoles[i].width = consoles[i].height = 0; consoles[i].fg_colour = consoles[i].default_fg_colour = 0xc0c0c0; consoles[i].bg_colour = consoles[i].default_bg_colour = 0x000000; consoles[i].cookie = cookies[0]; consoles[i].buf_chars = NULL; consoles[i].font = font; FontGetMaxSize(consoles[i].font, &consoles[i].char_width, &consoles[i].char_height); } num_consoles = _countof(consoles); ConTileBuffer(0); num_consoles = 0; current = consoles; for (i = 0; i < _countof(consoles); i++) ConClear(consoles + i); server = FsCreate(server_name, 0); ThrCreateThread(ConKeyboardThread, NULL, 16, L"ConKeyboardThread"); ThrCreateThread(ConCursorThread, NULL, 16, L"ConCursorThread"); ConDisplaySignonMessage(); while ((client = PortAccept(server, FILE_READ | FILE_WRITE))) { if (num_consoles < _countof(consoles)) { consoles[num_consoles].client = client; ThrCreateThread(ConClientThread, consoles + num_consoles, 15, L"ConClientThread"); num_consoles++; } else HndClose(client); } for (i = 0; i < _countof(consoles); i++) { LmuxDelete(&consoles[i].lmux); free(consoles[i].buf_chars); } LmuxDelete(&lmux_consoles); FontDelete(font); HndClose(server); if (vidmem != NULL) VmmFree(vidmem); HndClose(vid); return EXIT_SUCCESS; }
static void ShListDirectory(wchar_t *path, const wchar_t *spec, unsigned indent, bool do_recurse, bool is_full) { handle_t search; file_info_t *entries; wchar_t *end; unsigned num_entries, alloc_entries, i, n, columns; size_t max_len, len; end = path + wcslen(path); if (end[-1] != '/') { wcscpy(end, L"/"); end++; } //end++; //KeLeakBegin(); search = FsOpenDir(path); if (search != NULL) { entries = malloc(sizeof(file_info_t)); num_entries = alloc_entries = 0; max_len = 0; while (FsReadDir(search, &entries[num_entries].dirent, sizeof(dirent_t))) { len = wcslen(entries[num_entries].dirent.name) + 2; if (len > max_len) max_len = len; wcscpy(end, entries[num_entries].dirent.name); if (!FsQueryFile(path, FILE_QUERY_STANDARD, &entries[num_entries].standard, sizeof(dirent_standard_t))) { _pwerror(path); continue; } num_entries++; if (num_entries >= alloc_entries) { alloc_entries = num_entries + 16; //wprintf(L"ShListDirectory: alloc_entries = %u\n", alloc_entries); entries = realloc(entries, sizeof(file_info_t) * (alloc_entries + 1)); } } HndClose(search); qsort(entries, num_entries, sizeof(file_info_t), ShCompareDirent); if (max_len == 0) columns = 1; else columns = (sh_width - 2) / max_len - 1; for (i = n = 0; i < num_entries; i++) { if (do_recurse) { if (entries[i].standard.attributes & FILE_ATTR_DIRECTORY) { printf("%*s+ %S\n", indent * 2, "", entries[i].dirent.name); ShListDirectory(path, spec, indent + 1, true, is_full); } else if (_wcsmatch(spec, entries[i].dirent.name) == 0) printf("%*s %S\n", indent * 2, "", entries[i].dirent.name); } else if (_wcsmatch(spec, entries[i].dirent.name) == 0) { if (is_full) { if (entries[i].standard.attributes & FILE_ATTR_DIRECTORY) printf("[Directory]\t"); else if (entries[i].standard.attributes & FILE_ATTR_DEVICE) printf(" [Device]\t"); else printf("%10lu\t", (uint32_t) entries[i].standard.length); printf("\t%S", entries[i].dirent.name); printf("%*s%S\n", 20 - wcslen(entries[i].dirent.name) + 1, "", entries[i].standard.mimetype); } else { if (entries[i].standard.attributes & FILE_ATTR_DIRECTORY) printf("\x1b[1m"); printf("%S%*s", entries[i].dirent.name, max_len - wcslen(entries[i].dirent.name), ""); if (entries[i].standard.attributes & FILE_ATTR_DIRECTORY) printf("\x1b[m"); if (n == columns) { printf("\n"); n = 0; } else n++; } } } if (!do_recurse && !is_full && (n - 1) != columns) printf("\n"); free(entries); } else _pwerror(path); //KeLeakEnd(); }