static bool ShNormalizePath(wchar_t *path) { wchar_t *ch, *prev; dirent_standard_t standard; dirent_t dirent; bool isEnd; if (*path == '/') { ch = path; prev = path + 1; } else { ch = path - 1; prev = path; } isEnd = false; while (!isEnd) { ch = wcschr(ch + 1, '/'); if (ch == NULL) { ch = path + wcslen(path); isEnd = true; } *ch = '\0'; if (!FsQueryFile(path, FILE_QUERY_STANDARD, &standard, sizeof(standard))) return false; if ((standard.attributes & FILE_ATTR_DIRECTORY) == 0) { errno = ENOTADIR; return false; } if (!FsQueryFile(path, FILE_QUERY_DIRENT, &dirent, sizeof(dirent))) return false; wcscpy(prev, dirent.name); prev = ch + 1; *ch = '/'; } *ch = '\0'; return true; }
int stat(const char *path, struct stat *buf) { wchar_t *wc; dirent_standard_t di; wc = _towc(path); if (wc == NULL) return -1; if (!FsQueryFile(wc, FILE_QUERY_STANDARD, &di, sizeof(di))) { free(wc); return -1; } free(wc); buf->st_atime = 0; buf->st_ctime = 0; buf->st_dev = 0; buf->st_gid = 0; buf->st_ino = 0; buf->st_mode = 0; buf->st_mtime = 0; buf->st_nlink = 1; buf->st_size = di.length; buf->st_blksize = 0; buf->st_uid = 0; return 0; }
char * tmpnam(char *s) { static char static_buf[L_tmpnam]; static wchar_t wcs_buf[L_tmpnam]; static char tmpcount[] = "dj000000"; int i; size_t len; /*if (tmp_bss_count != __bss_count) { tmp_bss_count = __bss_count;*/ /*if (tmp_dir == 0) try("TMPDIR"); if (tmp_dir == 0) try("TEMP"); if (tmp_dir == 0) try("TMP");*/ if (tmp_dir == 0) { static char def[] = "c:/"; tmp_dir = def; tmp_len = 3; } /*}*/ if (!s) s = static_buf; strcpy(s, tmp_dir); do { /* increment the "count" starting at the first digit (backwards order) */ for (i=2; tmpcount[i] == '9' && i < 8; tmpcount[i] = '0', i++); if (i < 8) tmpcount[i]++; strcpy(s+tmp_len, tmpcount); len = mbstowcs(wcs_buf, s, _countof(wcs_buf) - 1); if (len == -1) len = 0; wcs_buf[len] = '\0'; } while (!FsQueryFile(wcs_buf, FILE_QUERY_NONE, NULL, 0)); /* until file doesn't exist */ return s; }
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(); }
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); }