/// <summary> /// FS readdir /// </summary> /// <param name="node">The node</param> /// <param name="index">The index</param> /// <returns>The directory entry</returns> private static unsafe DirEntry *rootReadDirImpl(Node node, uint index) { Task current = Tasking.KernelTask; int i = 0; while (i < index && current.NextTask != Tasking.KernelTask) { current = current.NextTask; i++; } // Last task entry reached but index is still not reached? Stop. if (i < index && current.NextTask == Tasking.KernelTask) { return(null); } DirEntry *entry = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); string name = current.PID.ToString(); String.CopyTo(entry->Name, name); Heap.Free(name); return(entry); }
/// <summary> /// Creates a directory entry by its name /// </summary> /// <param name="str">The name</param> /// <returns>The entry</returns> private static unsafe DirEntry *makeByName(string str) { DirEntry *entry = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); String.CopyTo(entry->Name, str); return(entry); }
/// <summary> /// Reads directory entries from the FS /// </summary> /// <param name="node">The node</param> /// <param name="index">The current index</param> /// <returns>The directory entry</returns> private static unsafe DirEntry *readDirImpl(Node node, uint index) { if (index >= NumCommands) { return(null); } DirEntry *entry = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); String.CopyTo(entry->Name, CommandNames[index]); return(entry); }
/// <summary> /// Read next directory entry /// </summary> /// <returns>Next directory entry</returns> public DirEntry Readdir() { DirEntry *read = readdir(m_instance); DirEntry entry = new DirEntry(); if (read != null) { Memory.Memcpy(&entry, read, sizeof(DirEntry)); } return(entry); }
/// <summary> /// FS readdir /// </summary> /// <param name="node">The node</param> /// <param name="index">The index</param> /// <returns>The directory entry</returns> private static unsafe DirEntry *procReadDirImpl(Node node, uint index) { // Check if task still exists IDCookie cookie = (IDCookie)node.Cookie; Task task = Tasking.GetTaskByPID(cookie.ID); if (task == null) { return(null); } DirEntry *entry = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); string name = null; // Index zero is the info file if (index == 0) { name = "info"; } else { int j = 0; Thread current = task.FirstThread; while (j < index - 1 && current.NextThread != task.FirstThread) { current = current.NextThread; j++; } // Last thread entry reached but index is still not reached? Stop. if (j < index - 1 && current.NextThread == task.FirstThread) { return(null); } name = current.TID.ToString(); } String.CopyTo(entry->Name, name); // A new string is only created here when index != 0 if (index != 0) { Heap.Free(name); } return(entry); }
/// <summary> /// FS readdir /// </summary> /// <param name="node">The node</param> /// <param name="index">The index</param> /// <returns>The directory entry</returns> private static unsafe DirEntry *readDirImpl(Node node, uint index) { ContainerCookie cookie = (ContainerCookie)node.Cookie; RootPoint dev = cookie.FS.GetAt(index); if (dev == null) { return(null); } DirEntry *entry = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); String.CopyTo(entry->Name, dev.Name); return(entry); }
/// <summary> /// FS readdir /// </summary> /// <param name="node">The node</param> /// <param name="index">The index</param> /// <returns>The directory entry</returns> private static unsafe DirEntry *readDirImpl(Node node, uint index) { m_mutex.Lock(); PacketFSEntry dev = (PacketFSEntry)m_children.GetAt(index); m_mutex.Unlock(); if (dev == null) { return(null); } DirEntry *entry = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); String.CopyTo(entry->Name, dev.Name); return(entry); }
/// <summary> /// Reads a directory entry /// </summary> /// <param name="descriptor">The descriptor</param> /// <param name="entry">The directory entry</param> /// <param name="index">The index</param> /// <returns>Errorcode</returns> public static unsafe ErrorCode Readdir(int descriptor, DirEntry *entry, uint index) { FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; Node node = descriptors.GetNode(descriptor); if (node == null) { return(ErrorCode.EBADF); } DirEntry *gotEntry = VFS.ReadDir(node, index); if (gotEntry == null) { return(ErrorCode.ENOENT); } Memory.Memcpy(entry, gotEntry, sizeof(DirEntry)); Heap.Free(gotEntry); return(ErrorCode.SUCCESS); }
/// <summary> /// Filesystem read directory implementation /// </summary> /// <param name="node"></param> /// <param name="index"></param> /// <returns></returns> private static DirEntry *readDirImpl(Node node, uint index) { int j = 0; /** * Find cluster number if not root directory */ uint cluster = 0xFFFFFFFF; Fat16Cookie cookie = (Fat16Cookie)node.Cookie; Fat16 fat = cookie.FAT16; if (cookie.DirEntry != null) { FatDirEntry *entry = cookie.DirEntry; cluster = entry->ClusterNumberLo; } /** * Read directory entries */ SubDirectory dir = fat.readDirectory(cluster); for (int i = 0; i < dir.Length; i++) { FatDirEntry entry = dir.DirEntries[i]; /** * Correct attributes? */ if (entry.Name[0] == 0 || entry.Name[0] == (char)0xE5 || entry.Attribs == 0xF || (entry.Attribs & 0x08) > 0) { continue; } /** * Do we need to search further? */ if (j >= index) { DirEntry *outDir = (DirEntry *)Heap.Alloc(sizeof(DirEntry)); outDir->Reclen = (ushort)sizeof(DirEntry); GetName(dir, i, outDir->Name); /** * Directory or file? */ if ((dir.DirEntries[i].Attribs & ATTRIB_SUBDIR) == 0) { outDir->Type = (byte)DT_Type.DT_REG; } else { outDir->Type = (byte)DT_Type.DT_DIR; } return(outDir); } j++; } return(null); }
unsafe byte open_directory(byte *pattern) { int i, j, n, m; byte * p, q; DirEntry *de; byte c; byte * tmppat; // Special treatment for "$0" if (pattern[0] == '0' && pattern[1] == 0) { pattern += 1; } // Skip everything before the ':' in the pattern if ((tmppat = CharFunctions.strchr(pattern, ':')) != null) { pattern = tmppat + 1; } AllocateChannelBuffer(0, 8192); p = buf_ptr[0] = chan_buf[0]; chan_mode[0] = ChannelMode.CHMOD_DIRECTORY; // Create directory title *p++ = 0x01; // Load address $0401 (from PET days :-) *p++ = 0x04; *p++ = 0x01; // Dummy line link *p++ = 0x01; *p++ = 0; // Drive number (0) as line number *p++ = 0; *p++ = 0x12; // RVS ON *p++ = (byte)'\"'; q = bam->disk_name; for (i = 0; i < 23; i++) { if ((c = *q++) == 0xa0) { *p++ = (byte)' '; // Replace 0xa0 by space } else { *p++ = c; } } *(p - 7) = (byte)'\"'; *p++ = 0; // Scan all directory blocks dir.next_track = bam->dir_track; dir.next_sector = bam->dir_sector; fixed(Directory *dd = &dir) { while (dir.next_track != 0x00) { if (!read_sector(dir.next_track, dir.next_sector, &dd->next_track)) { return((byte)C64StatusCode.ST_OK); } DirEntry *ade = (DirEntry *)dd->entry; // Scan all 8 entries of a block for (j = 0; j < 8; j++) { de = &ade[j]; if (de->type != 0 && match(pattern, de->name)) { *p++ = 0x01; // Dummy line link *p++ = 0x01; *p++ = de->num_blocks_l; // Line number *p++ = de->num_blocks_h; *p++ = (byte)' '; n = (de->num_blocks_h << 8) + de->num_blocks_l; if (n < 10) { *p++ = (byte)' '; } if (n < 100) { *p++ = (byte)' '; } *p++ = (byte)'\"'; q = de->name; m = 0; for (i = 0; i < 16; i++) { if ((c = *q++) == 0xa0) { if (m != 0) { *p++ = (byte)' '; // Replace all 0xa0 by spaces } else { m = *p++ = (byte)'\"'; // But the first by a '"' } } else { *p++ = c; } } if (m != 0) { *p++ = (byte)' '; } else { *p++ = (byte)'\"'; // No 0xa0, then append a space } if ((de->type & 0x80) != 0) { *p++ = (byte)' '; } else { *p++ = (byte)'*'; } *p++ = type_char_1[de->type & 0x0f]; *p++ = type_char_2[de->type & 0x0f]; *p++ = type_char_3[de->type & 0x0f]; if ((de->type & 0x40) != 0) { *p++ = (byte)'<'; } else { *p++ = (byte)' '; } *p++ = (byte)' '; if (n >= 10) { *p++ = (byte)' '; } if (n >= 100) { *p++ = (byte)' '; } *p++ = 0; } } } } // Final line q = p; for (i = 0; i < 29; i++) { *q++ = (byte)' '; } n = 0; for (i = 0; i < 35; i++) { n += bam->bitmap[i * 4]; } *p++ = 0x01; // Dummy line link *p++ = 0x01; *p++ = (byte)(n & 0xff); // Number of free blocks as line number *p++ = (byte)((n >> 8) & 0xff); *p++ = (byte)'B'; *p++ = (byte)'L'; *p++ = (byte)'O'; *p++ = (byte)'C'; *p++ = (byte)'K'; *p++ = (byte)'S'; *p++ = (byte)' '; *p++ = (byte)'F'; *p++ = (byte)'R'; *p++ = (byte)'E'; *p++ = (byte)'E'; *p++ = (byte)'.'; p = q; *p++ = 0; *p++ = 0; *p++ = 0; buf_len[0] = (int)(p - chan_buf[0]); return((byte)C64StatusCode.ST_OK); }
unsafe bool find_file(BytePtr filename, ref int track, ref int sector) { int i, j; byte * p, q; DirEntry *de; fixed(Directory *dd = &dir) { // Scan all directory blocks dir.next_track = bam->dir_track; dir.next_sector = bam->dir_sector; while (dir.next_track != 0) { if (!read_sector(dir.next_track, dir.next_sector, &dd->next_track)) { return(false); } DirEntry *ade = (DirEntry *)dd->entry; // Scan all 8 entries of a block for (j = 0; j < 8; j++) { de = &ade[j]; track = de->track; sector = de->sector; if (de->type != 0) { p = (byte *)filename; q = de->name; for (i = 0; i < 16 && (*p != 0); i++, p++, q++) { if (*p == '*') // Wildcard '*' matches all following characters { return(true); } if (*p != *q) { if (*p != '?') { goto next_entry; // Wildcard '?' matches single character } if (*q == 0xa0) { goto next_entry; } } } if (i == 16 || *q == 0xa0) { return(true); } } next_entry :; } } } return(false); }