The Pedigree Project  0.1
Iso9660Directory.h
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef ISO9660DIRECTORY_H
21 #define ISO9660DIRECTORY_H
22 
23 #include "Iso9660File.h"
24 #include "Iso9660Filesystem.h"
25 #include "iso9660.h"
26 #include "modules/system/vfs/Directory.h"
27 #include "pedigree/kernel/Log.h"
28 #include "pedigree/kernel/machine/Disk.h"
29 #include "pedigree/kernel/processor/types.h"
30 #include "pedigree/kernel/time/Time.h"
31 #include "pedigree/kernel/utilities/String.h"
32 #include "pedigree/kernel/utilities/utility.h"
33 
34 class File;
35 
37 {
38  friend class Iso9660File;
39 
40  private:
42  Iso9660Directory &operator=(const Iso9660Directory &);
43 
44  public:
46  String name, size_t inode, class Iso9660Filesystem *pFs, File *pParent,
47  Iso9660DirRecord &dirRec, Time::Timestamp accessedTime = 0,
48  Time::Timestamp modifiedTime = 0, Time::Timestamp creationTime = 0)
49  : Directory(
50  name, accessedTime, modifiedTime, creationTime, inode, pFs, 0,
51  pParent),
52  m_pFs(pFs), m_Dir(dirRec)
53  {
54  }
55  virtual ~Iso9660Directory();
56 
57  virtual void cacheDirectoryContents()
58  {
59  if (!m_pFs)
60  {
61  ERROR("ISO9660: m_pFs is null!");
62  return;
63  }
64 
65  Disk *myDisk = m_pFs->getDisk();
66 
67  // Grab our parent (will always be a directory)
68  Iso9660Directory *pParentDir =
69  reinterpret_cast<Iso9660Directory *>(m_pParent);
70  if (pParentDir == 0)
71  {
72  // Root directory, . and .. should redirect to this directory
74  String("."), m_Inode, m_pFs, m_pParent, m_Dir, m_AccessedTime,
75  m_ModifiedTime, m_CreationTime);
76  Iso9660Directory *dotdot = new Iso9660Directory(
77  String(".."), m_Inode, m_pFs, m_pParent, m_Dir, m_AccessedTime,
78  m_ModifiedTime, m_CreationTime);
79  addDirectoryEntry(String("."), dot);
80  addDirectoryEntry(String(".."), dotdot);
81  }
82  else
83  {
84  // Non-root, . and .. should point to the correct locations
86  String("."), m_Inode, m_pFs, m_pParent, m_Dir, m_AccessedTime,
87  m_ModifiedTime, m_CreationTime);
88  addDirectoryEntry(String("."), dot);
89 
90  Iso9660Directory *dotdot = new Iso9660Directory(
91  String(".."), pParentDir->getInode(), pParentDir->m_pFs,
92  pParentDir->getParent(), pParentDir->getDirRecord(),
93  pParentDir->getAccessedTime(), pParentDir->getModifiedTime(),
94  pParentDir->getCreationTime());
95  addDirectoryEntry(String(".."), dotdot);
96  }
97 
98  // How big is the directory?
99  size_t dirSize = LITTLE_TO_HOST32(m_Dir.DataLen_LE);
100  size_t dirLoc = LITTLE_TO_HOST32(m_Dir.ExtentLocation_LE);
101 
102  // Read the directory, block by block
103  size_t numBlocks = (dirSize > 2048) ? dirSize / 2048 : 1;
104  size_t i;
105  for (i = 0; i < numBlocks; i++)
106  {
107  // Read the block
108  uintptr_t block = myDisk->read((dirLoc + i) * 2048);
109 
110  // Complete, so start reading entries
111  size_t offset = 0;
112  bool bLastHit = false;
113  while (offset < 2048)
114  {
115  Iso9660DirRecord *record =
116  reinterpret_cast<Iso9660DirRecord *>(block + offset);
117  offset += record->RecLen;
118  uint8_t *fileIdent = reinterpret_cast<uint8_t *>(
119  adjust_pointer(record, sizeof(*record)));
120 
121  if (record->RecLen == 0)
122  {
123  bLastHit = true;
124  break;
125  }
126  else if (record->FileFlags & (1 << 0))
127  continue;
128  else if (
129  record->FileFlags & (1 << 1) && record->FileIdentLen == 1)
130  {
131  if (fileIdent[0] == 0 || fileIdent[0] == 1)
132  continue;
133  }
134 
135  String fileName = m_pFs->parseName(*record);
136 
137  // Grab the UNIX timestamp
138  Time::Timestamp unixTime = m_pFs->timeToUnix(record->Time);
139  if (record->FileFlags & (1 << 1))
140  {
142  fileName, 0, m_pFs, this, *record, unixTime, unixTime,
143  unixTime);
144  addDirectoryEntry(fileName, dir);
145  }
146  else
147  {
148  Iso9660File *file = new Iso9660File(
149  fileName, unixTime, unixTime, unixTime, 0, m_pFs,
150  LITTLE_TO_HOST32(record->DataLen_LE), *record, this);
151  addDirectoryEntry(fileName, file);
152  }
153  }
154 
155  // Last in the block, but are there still blocks to read?
156  if (bLastHit && ((i + 1) == numBlocks))
157  break;
158  }
159 
161  }
162 
163  virtual bool addEntry(String filename, File *pFile, size_t type)
164  {
165  return false;
166  }
167 
168  virtual bool removeEntry(File *pFile)
169  {
170  return false;
171  }
172 
173  void fileAttributeChanged()
174  {
175  }
176 
177  inline Iso9660DirRecord &getDirRecord()
178  {
179  return m_Dir;
180  }
181 
182  private:
183  // Filesystem object
184  Iso9660Filesystem *m_pFs;
185 
186  // Our internal directory information (info about *this* directory, not the
187  // child)
188  Iso9660DirRecord m_Dir;
189 };
190 
191 #endif
virtual void cacheDirectoryContents()
Iso9660File(const Iso9660File &)
Time::Timestamp getAccessedTime()
Definition: File.cc:389
Definition: String.h:49
Definition: Disk.h:32
Time::Timestamp getCreationTime()
Definition: File.cc:378
void addDirectoryEntry(const String &name, File *pTarget)
Definition: Directory.cc:114
virtual uintptr_t read(uint64_t location)
Definition: Disk.cc:56
Time::Timestamp getModifiedTime()
Definition: File.cc:400
#define ERROR(text)
Definition: Log.h:82
Definition: File.h:66
void markCachePopulated()
Definition: Directory.h:187