ReactOS 0.4.16-dev-1946-g52006dd
iso.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for iso.c:

Go to the source code of this file.

Classes

struct  _ISO_VOLUME_INFO
 

Macros

#define SECTORSIZE   2048
 
#define TAG_ISO_VOLUME   'VosI'
 
#define TAG_ISO_BUFFER   'BosI'
 
#define TAG_ISO_FILE   'FosI'
 

Typedefs

typedef struct _ISO_VOLUME_INFO ISO_VOLUME_INFO
 
typedef struct _ISO_VOLUME_INFOPISO_VOLUME_INFO
 

Functions

 DBG_DEFAULT_CHANNEL (FILESYSTEM)
 
static PCSTR IsoLastPathSeparator (_In_ PCSTR Path)
 
static BOOLEAN IsoSearchDirectoryBufferForFile (PVOID DirectoryBuffer, ULONG DirectoryLength, PCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
 
static ARC_STATUS IsoBufferDirectory (ULONG DeviceId, ULONG DirectoryStartSector, ULONG DirectoryLength, PVOID *pDirectoryBuffer)
 
static ARC_STATUS IsoLookupFile (PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfo)
 
static ARC_STATUS IsoClose (ULONG FileId)
 
static ARC_STATUS IsoGetFileInformation (ULONG FileId, FILEINFORMATION *Information)
 
static ARC_STATUS IsoOpen (CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
 
static ARC_STATUS IsoRead (ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
 
static ARC_STATUS IsoSeek (ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
 
ULONGLONG IsoGetVolumeSize (_In_ ULONG DeviceId)
 Returns the size of the ISO-9660 volume laid on the storage media device opened via DeviceId.
 
const DEVVTBLIsoMount (ULONG DeviceId)
 

Variables

static PISO_VOLUME_INFO IsoVolumes [MAX_FDS]
 
static const DEVVTBL Iso9660FuncTable
 

Macro Definition Documentation

◆ SECTORSIZE

#define SECTORSIZE   2048

Definition at line 27 of file iso.c.

◆ TAG_ISO_BUFFER

#define TAG_ISO_BUFFER   'BosI'

Definition at line 29 of file iso.c.

◆ TAG_ISO_FILE

#define TAG_ISO_FILE   'FosI'

Definition at line 30 of file iso.c.

◆ TAG_ISO_VOLUME

#define TAG_ISO_VOLUME   'VosI'

Definition at line 28 of file iso.c.

Typedef Documentation

◆ ISO_VOLUME_INFO

◆ PISO_VOLUME_INFO

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( FILESYSTEM  )

◆ IsoBufferDirectory()

static ARC_STATUS IsoBufferDirectory ( ULONG  DeviceId,
ULONG  DirectoryStartSector,
ULONG  DirectoryLength,
PVOID pDirectoryBuffer 
)
static

Definition at line 128 of file iso.c.

130{
131 PVOID DirectoryBuffer;
134 ULONG Count;
136
137 TRACE("IsoBufferDirectory() DirectoryStartSector = %d DirectoryLength = %d\n", DirectoryStartSector, DirectoryLength);
138
139 SectorCount = ROUND_UP(DirectoryLength, SECTORSIZE) / SECTORSIZE;
140 TRACE("Trying to read (DirectoryCount) %d sectors.\n", SectorCount);
141
142 //
143 // Attempt to allocate memory for directory buffer
144 //
145 TRACE("Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength);
146 DirectoryBuffer = FrLdrTempAlloc(DirectoryLength, TAG_ISO_BUFFER);
147 if (!DirectoryBuffer)
148 return ENOMEM;
149
150 //
151 // Now read directory contents into DirectoryBuffer
152 //
153 Position.HighPart = 0;
154 Position.LowPart = DirectoryStartSector * SECTORSIZE;
155 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
156 if (Status != ESUCCESS)
157 {
158 FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER);
159 return Status;
160 }
161 Status = ArcRead(DeviceId, DirectoryBuffer, SectorCount * SECTORSIZE, &Count);
163 {
164 FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER);
165 return EIO;
166 }
167
168 *pDirectoryBuffer = DirectoryBuffer;
169 return ESUCCESS;
170}
#define ENOMEM
Definition: acclib.h:84
#define EIO
Definition: acclib.h:81
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:455
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:448
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
#define TAG_ISO_BUFFER
Definition: iso.c:29
#define SECTORSIZE
Definition: iso.c:27
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
Status
Definition: gdiplustypes.h:25
int Count
Definition: noreturn.cpp:7
ULONG SectorCount
Definition: part_xbox.c:31
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ SeekAbsolute
Definition: arc.h:59
#define TRACE(s)
Definition: solgame.cpp:4
static COORD Position
Definition: mouse.c:34
uint32_t ULONG
Definition: typedefs.h:59

Referenced by IsoLookupFile().

◆ IsoClose()

static ARC_STATUS IsoClose ( ULONG  FileId)
static

Definition at line 320 of file iso.c.

321{
324 return ESUCCESS;
325}
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:709
#define TAG_ISO_FILE
Definition: iso.c:30
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231

◆ IsoGetFileInformation()

static ARC_STATUS IsoGetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)
static

Definition at line 328 of file iso.c.

329{
331
333 Information->EndingAddress.LowPart = FileHandle->FileSize;
334 Information->CurrentAddress.LowPart = FileHandle->FilePointer;
335
336 /* Set the ARC file attributes */
337 Information->Attributes = FileHandle->Attributes;
338
339 /* Copy the file name, perhaps truncated, and NUL-terminated */
340 Information->FileNameLength = min(FileHandle->FileNameLength, sizeof(Information->FileName) - 1);
341 RtlCopyMemory(Information->FileName, FileHandle->FileName, Information->FileNameLength);
342 Information->FileName[Information->FileNameLength] = ANSI_NULL;
343
344 TRACE("IsoGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
345 FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);
346
347 return ESUCCESS;
348}
#define min(a, b)
Definition: monoChain.cc:55
#define ANSI_NULL
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

◆ IsoGetVolumeSize()

ULONGLONG IsoGetVolumeSize ( _In_ ULONG  DeviceId)

Returns the size of the ISO-9660 volume laid on the storage media device opened via DeviceId.

This routine is in particular used to determine the useful (volume) size of a CD-ROM media.

Definition at line 583 of file iso.c.

585{
587 ASSERT(Volume);
588 return (ULONGLONG)Volume->VolumeSizeLBN * Volume->LogicalBlockSize;
589}
static PISO_VOLUME_INFO IsoVolumes[MAX_FDS]
Definition: iso.c:44
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define ASSERT(a)
Definition: mode.c:44
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by FsGetVolumeSize().

◆ IsoLastPathSeparator()

static PCSTR IsoLastPathSeparator ( _In_ PCSTR  Path)
static

Definition at line 48 of file iso.c.

50{
51 PCSTR Last = NULL;
52
53 ASSERT(Path != NULL);
54
55 while (*Path != ANSI_NULL)
56 {
57 if (*Path == '\\' || *Path == '/')
58 Last = Path;
59
60 ++Path;
61 }
62
63 return Last;
64}
PRTL_UNICODE_STRING_BUFFER Path
#define NULL
Definition: types.h:112
const char * PCSTR
Definition: typedefs.h:52

Referenced by IsoLookupFile().

◆ IsoLookupFile()

static ARC_STATUS IsoLookupFile ( PCSTR  FileName,
ULONG  DeviceId,
PISO_FILE_INFO  IsoFileInfo 
)
static

Definition at line 178 of file iso.c.

179{
180 PCSTR FullPath = FileName;
182 PCSTR FileNameStr;
183 ULONG i, DirectoryPathLength, DirectorySector, DirectoryLength;
184 PVOID DirectoryBuffer;
185 ULONG NumberOfPathParts;
186 CHAR PathBuffer[261];
187 CHAR* PathPart;
189 BOOLEAN DoFullLookup;
191
192 TRACE("IsoLookupFile() FileName = %s\n", FileName);
193
194 Volume = IsoVolumes[DeviceId];
195
196 /*
197 * Extract the file name
198 * '\test.ini' --> 'test.ini'
199 * '\folder\app.exe' --> 'app.exe'
200 */
201 FileNameStr = IsoLastPathSeparator(FileName) + 1;
202
203 /*
204 * Extract the directory path, including trailing slash
205 * '\test.ini' --> '\'
206 * '\folder\app.exe' --> '\folder\'
207 */
208 DirectoryPathLength = FileNameStr - FileName;
209
210 /* See if this directory has been buffered before */
211 DoFullLookup = (DirectoryPathLength != Volume->DirectoryPathLength) ||
212 !RtlEqualMemory(FileName, Volume->DirectoryPath, DirectoryPathLength);
213 if (!DoFullLookup)
214 {
215 PathPart = (CHAR*)FileNameStr;
216 DirectoryBuffer = Volume->DirectoryBuffer;
217 DirectoryLength = Volume->DirectoryLength;
218
219 NumberOfPathParts = 1;
220 }
221 else
222 {
223 PathPart = PathBuffer;
224 DirectorySector = Volume->PvdDirectorySector;
225 DirectoryLength = Volume->PvdDirectoryLength;
226
227 /* Skip leading path separator, if any */
228 if (*FileName == '\\' || *FileName == '/')
229 ++FileName;
230 PathPart[0] = ANSI_NULL;
231
232 /* Figure out how many sub-directories we are nested in */
233 NumberOfPathParts = FsGetNumPathParts(FileName);
234 }
235
236 //
237 // Loop once for each part
238 //
239 for (i=0; i<NumberOfPathParts; i++)
240 {
241 if (DoFullLookup)
242 {
243 /* Get first path part */
245
246 /* Advance to the next part of the path */
247 while ((*FileName != ANSI_NULL) && (*FileName != '\\') && (*FileName != '/'))
248 {
249 FileName++;
250 }
251 FileName++;
252
253 /* Buffer the directory contents */
254 Status = IsoBufferDirectory(DeviceId,
255 DirectorySector,
256 DirectoryLength,
257 &DirectoryBuffer);
258 if (Status != ESUCCESS)
259 return Status;
260
261 /* Save the directory buffer */
262 if ((i + 1) >= NumberOfPathParts)
263 {
264 if (Volume->DirectoryBuffer)
265 FrLdrTempFree(Volume->DirectoryBuffer, TAG_ISO_BUFFER);
266
267 Volume->DirectoryPathLength = DirectoryPathLength;
268 Volume->DirectoryBuffer = DirectoryBuffer;
269 Volume->DirectoryLength = DirectoryLength;
270
271 RtlCopyMemory(Volume->DirectoryPath, FullPath, DirectoryPathLength);
272 }
273 }
274
275 /* Search for file name in directory */
276 if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer,
277 DirectoryLength,
278 PathPart,
279 IsoFileInfo))
280 {
281 /* Free the directory buffer that wasn't cached */
282 if ((i + 1) < NumberOfPathParts)
283 {
284 ASSERT(DirectoryBuffer != Volume->DirectoryBuffer);
285 FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER);
286 }
287 return ENOENT;
288 }
289
290 //
291 // If we have another sub-directory to go then
292 // grab the start sector and file size
293 //
294 if ((i+1) < NumberOfPathParts)
295 {
296 FrLdrTempFree(DirectoryBuffer, TAG_ISO_BUFFER);
297
298 DirectorySector = IsoFileInfo->FileStart;
299 DirectoryLength = IsoFileInfo->FileSize;
300 }
301 }
302
303 /* Re-map the attributes to ARC file attributes */
304 FileAttributes = IsoFileInfo->Attributes;
305 IsoFileInfo->Attributes = ReadOnlyFile;
307 IsoFileInfo->Attributes |= HiddenFile;
309 IsoFileInfo->Attributes |= DirectoryFile;
310
311 /* Copy the file name, perhaps truncated */
312 IsoFileInfo->FileNameLength = (ULONG)strlen(PathPart);
313 IsoFileInfo->FileNameLength = min(IsoFileInfo->FileNameLength, sizeof(IsoFileInfo->FileName) - 1);
314 RtlCopyMemory(IsoFileInfo->FileName, PathPart, IsoFileInfo->FileNameLength);
315
316 return ESUCCESS;
317}
unsigned char BOOLEAN
#define ENOENT
Definition: acclib.h:79
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG FsGetNumPathParts(PCSTR Path)
Definition: fs.c:617
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:645
static PCSTR IsoLastPathSeparator(_In_ PCSTR Path)
Definition: iso.c:48
static ARC_STATUS IsoBufferDirectory(ULONG DeviceId, ULONG DirectoryStartSector, ULONG DirectoryLength, PVOID *pDirectoryBuffer)
Definition: iso.c:128
static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectoryLength, PCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
Definition: iso.c:66
@ DirectoryFile
Definition: fatprocs.h:1047
struct _FileName FileName
Definition: fatprocs.h:897
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ISO_ATTR_HIDDEN
Definition: iso.h:92
#define ISO_ATTR_DIRECTORY
Definition: iso.h:93
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
@ ReadOnlyFile
Definition: arc.h:78
@ HiddenFile
Definition: arc.h:79
ULONG FileNameLength
Definition: iso.h:104
ULONG FileStart
Definition: iso.h:100
ULONG FileSize
Definition: iso.h:101
UCHAR Attributes
Definition: iso.h:105
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)]
Definition: iso.h:106
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175

Referenced by IsoOpen().

◆ IsoMount()

const DEVVTBL * IsoMount ( ULONG  DeviceId)

Definition at line 602 of file iso.c.

603{
605 PPVD Pvd = (PPVD)Buffer;
607 ULONG Count;
610
611 TRACE("Enter IsoMount(%lu)\n", DeviceId);
612
613 /* Read the ISO Primary Volume Descriptor */
614 Position.QuadPart = 16 * SECTORSIZE;
615 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
616 if (Status != ESUCCESS)
617 return NULL;
618 Status = ArcRead(DeviceId, Pvd, SECTORSIZE, &Count);
619 if (Status != ESUCCESS || Count < sizeof(PVD))
620 return NULL;
621
622 /* Check whether the PVD is valid */
623 if (!(Pvd->VdType == 1 && RtlEqualMemory(Pvd->StandardId, "CD001", 5) && Pvd->VdVersion == 1))
624 {
625 WARN("Unrecognized CD-ROM format\n");
626 return NULL;
627 }
628 if (Pvd->LogicalBlockSizeL != SECTORSIZE)
629 {
630 ERR("Unsupported LogicalBlockSize %u\n", Pvd->LogicalBlockSizeL);
631 return NULL;
632 }
633
634 Count = (ULONG)((ULONGLONG)Pvd->VolumeSpaceSizeL * SECTORSIZE / 1024 / 1024);
635 TRACE("Recognized ISO9660 drive, size %lu MB (%lu sectors)\n",
636 Count, Pvd->VolumeSpaceSizeL);
637
639 if (!Volume)
640 return NULL;
641 RtlZeroMemory(Volume, sizeof(*Volume));
642
643 /*
644 * This is equivalent to using the RAW_ISO_VD::VolSpaceI field:
645 * https://github.com/reactos/reactos/blob/435482912c6dc0aaa4371e37b7336b2b1291e65f/drivers/filesystems/cdfs/cd.h#L126
646 * and also what MS CDFS does with the CdRvdVolSz() macro,
647 * in cdfs/strucsup.c!CdUpdateVcbFromVolDescriptor().
648 */
649 Volume->VolumeSizeLBN = Pvd->VolumeSpaceSizeL;
650 Volume->LogicalBlockSize = Pvd->LogicalBlockSizeL;
651
652 /* Cache some useful PVD information */
653 Volume->PvdDirectorySector = Pvd->RootDirRecord.ExtentLocationL;
654 Volume->PvdDirectoryLength = Pvd->RootDirRecord.DataLengthL;
655
656 IsoVolumes[DeviceId] = Volume;
657
658 /* Everything OK, return the ISO9660 function table */
659 return &Iso9660FuncTable;
660}
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define TAG_ISO_VOLUME
Definition: iso.c:28
static const DEVVTBL Iso9660FuncTable
Definition: iso.c:592
Definition: bufpool.h:45
struct _PVD * PPVD
ULONG ExtentLocationL
Definition: iso.h:27
ULONG DataLengthL
Definition: iso.h:29
Definition: iso.h:61
DIR_RECORD RootDirRecord
Definition: iso.h:84
USHORT LogicalBlockSizeL
Definition: iso.h:76
ULONG VolumeSpaceSizeL
Definition: iso.h:69
UCHAR StandardId[5]
Definition: iso.h:63
UCHAR VdType
Definition: iso.h:62
UCHAR VdVersion
Definition: iso.h:64

◆ IsoOpen()

static ARC_STATUS IsoOpen ( CHAR Path,
OPENMODE  OpenMode,
ULONG FileId 
)
static

Definition at line 351 of file iso.c.

352{
354 ULONG DeviceId;
356
357 if (OpenMode != OpenReadOnly)
358 return EACCES;
359
360 DeviceId = FsGetDeviceId(*FileId);
361
362 TRACE("IsoOpen() FileName = %s\n", Path);
363
365 if (!FileHandle)
366 return ENOMEM;
367
368 Status = IsoLookupFile(Path, DeviceId, FileHandle);
369 if (Status != ESUCCESS)
370 {
372 return ENOENT;
373 }
374
376 return ESUCCESS;
377}
#define EACCES
Definition: acclib.h:85
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
Definition: fs.c:702
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:716
static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfo)
Definition: iso.c:178
@ OpenReadOnly
Definition: arc.h:65

◆ IsoRead()

static ARC_STATUS IsoRead ( ULONG  FileId,
VOID Buffer,
ULONG  N,
ULONG Count 
)
static

Definition at line 380 of file iso.c.

381{
384 UCHAR SectorBuffer[SECTORSIZE];
386 ULONG DeviceId;
387 ULONG SectorNumber;
388 ULONG OffsetInSector;
389 ULONG LengthInSector;
390 ULONG NumberOfSectors;
392
393 TRACE("IsoRead() Buffer = %p, N = %lu\n", Buffer, N);
394
395 DeviceId = FsGetDeviceId(FileId);
396 *Count = 0;
397
398 //
399 // If the user is trying to read past the end of
400 // the file then return success with Count == 0.
401 //
402 if (FileHandle->FilePointer >= FileHandle->FileSize)
403 {
404 return ESUCCESS;
405 }
406
407 //
408 // If the user is trying to read more than there is to read
409 // then adjust the amount to read.
410 //
411 if (FileHandle->FilePointer + N > FileHandle->FileSize)
412 {
413 N = FileHandle->FileSize - FileHandle->FilePointer;
414 }
415
416 //
417 // Ok, now we have to perform at most 3 calculations
418 // I'll draw you a picture (using nifty ASCII art):
419 //
420 // CurrentFilePointer -+
421 // |
422 // +----------------+
423 // |
424 // +-----------+-----------+-----------+-----------+
425 // | Sector 1 | Sector 2 | Sector 3 | Sector 4 |
426 // +-----------+-----------+-----------+-----------+
427 // | |
428 // +---------------+--------------------+
429 // |
430 // N -----------------+
431 //
432 // 1 - The first calculation (and read) will align
433 // the file pointer with the next sector
434 // boundary (if we are supposed to read that much)
435 // 2 - The next calculation (and read) will read
436 // in all the full sectors that the requested
437 // amount of data would cover (in this case
438 // sectors 2 & 3).
439 // 3 - The last calculation (and read) would read
440 // in the remainder of the data requested out of
441 // the last sector.
442 //
443
444
445 //
446 // Only do the first read if we
447 // aren't aligned on a cluster boundary
448 //
449 if (FileHandle->FilePointer % SECTORSIZE)
450 {
451 //
452 // Do the math for our first read
453 //
454 SectorNumber = FileHandle->FileStart + (FileHandle->FilePointer / SECTORSIZE);
455 OffsetInSector = FileHandle->FilePointer % SECTORSIZE;
456 LengthInSector = min(N, SECTORSIZE - OffsetInSector);
457
458 //
459 // Now do the read and update Count, N, FilePointer, & Buffer
460 //
461 Position.HighPart = 0;
462 Position.LowPart = SectorNumber * SECTORSIZE;
463 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
464 if (Status != ESUCCESS)
465 {
466 return Status;
467 }
468 Status = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead);
469 if (Status != ESUCCESS || BytesRead != SECTORSIZE)
470 {
471 return EIO;
472 }
473 RtlCopyMemory(Buffer, SectorBuffer + OffsetInSector, LengthInSector);
474 *Count += LengthInSector;
475 N -= LengthInSector;
476 FileHandle->FilePointer += LengthInSector;
477 Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInSector);
478 }
479
480 //
481 // Do the math for our second read (if any data left)
482 //
483 if (N > 0)
484 {
485 //
486 // Determine how many full clusters we need to read
487 //
488 NumberOfSectors = (N / SECTORSIZE);
489
490 SectorNumber = FileHandle->FileStart + (FileHandle->FilePointer / SECTORSIZE);
491
492 //
493 // Now do the read and update Count, N, FilePointer, & Buffer
494 //
495 Position.HighPart = 0;
496 Position.LowPart = SectorNumber * SECTORSIZE;
497 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
498 if (Status != ESUCCESS)
499 {
500 return Status;
501 }
502 Status = ArcRead(DeviceId, Buffer, NumberOfSectors * SECTORSIZE, &BytesRead);
503 if (Status != ESUCCESS || BytesRead != NumberOfSectors * SECTORSIZE)
504 {
505 return EIO;
506 }
507
508 *Count += NumberOfSectors * SECTORSIZE;
509 N -= NumberOfSectors * SECTORSIZE;
510 FileHandle->FilePointer += NumberOfSectors * SECTORSIZE;
511 Buffer = (PVOID)((ULONG_PTR)Buffer + NumberOfSectors * SECTORSIZE);
512 }
513
514 //
515 // Do the math for our third read (if any data left)
516 //
517 if (N > 0)
518 {
519 SectorNumber = FileHandle->FileStart + (FileHandle->FilePointer / SECTORSIZE);
520
521 //
522 // Now do the read and update Count, N, FilePointer, & Buffer
523 //
524 Position.HighPart = 0;
525 Position.LowPart = SectorNumber * SECTORSIZE;
526 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
527 if (Status != ESUCCESS)
528 {
529 return Status;
530 }
531 Status = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead);
532 if (Status != ESUCCESS || BytesRead != SECTORSIZE)
533 {
534 return EIO;
535 }
536 RtlCopyMemory(Buffer, SectorBuffer, N);
537 *Count += N;
538 FileHandle->FilePointer += N;
539 }
540
541 TRACE("IsoRead() done\n");
542
543 return ESUCCESS;
544}
#define N
Definition: crc32.c:57
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870

◆ IsoSearchDirectoryBufferForFile()

static BOOLEAN IsoSearchDirectoryBufferForFile ( PVOID  DirectoryBuffer,
ULONG  DirectoryLength,
PCHAR  FileName,
PISO_FILE_INFO  IsoFileInfoPointer 
)
static

Definition at line 66 of file iso.c.

67{
70 ULONG i;
71 CHAR Name[32];
72
73 TRACE("IsoSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectoryLength = %d FileName = %s\n", DirectoryBuffer, DirectoryLength, FileName);
74
75 Offset = 0;
76 Record = (PDIR_RECORD)DirectoryBuffer;
77 while (TRUE)
78 {
79 Offset = Offset + Record->RecordLength;
80 Record = (PDIR_RECORD)((ULONG_PTR)DirectoryBuffer + Offset);
81
82 if (Record->RecordLength == 0)
83 {
85 Record = (PDIR_RECORD)((ULONG_PTR)DirectoryBuffer + Offset);
86 }
87
88 if (Offset >= DirectoryLength)
89 return FALSE;
90
91 if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
92 {
93 TRACE("Name '.'\n");
94 }
95 else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
96 {
97 TRACE("Name '..'\n");
98 }
99 else
100 {
101 for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
102 Name[i] = Record->FileId[i];
103 Name[i] = ANSI_NULL;
104 TRACE("Name '%s'\n", Name);
105
106 if (_stricmp(FileName, Name) == 0)
107 {
108 IsoFileInfoPointer->FileStart = Record->ExtentLocationL;
109 IsoFileInfoPointer->FileSize = Record->DataLengthL;
110 IsoFileInfoPointer->FilePointer = 0;
111 IsoFileInfoPointer->Attributes = Record->FileFlags;
112 return TRUE;
113 }
114 }
115 }
116
117 return FALSE;
118}
#define _stricmp
Definition: cat.c:22
LPWSTR Name
Definition: desk.c:124
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
struct _DIR_RECORD * PDIR_RECORD
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG FilePointer
Definition: iso.h:102
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:320

Referenced by IsoLookupFile().

◆ IsoSeek()

static ARC_STATUS IsoSeek ( ULONG  FileId,
LARGE_INTEGER Position,
SEEKMODE  SeekMode 
)
static

Definition at line 547 of file iso.c.

548{
550 LARGE_INTEGER NewPosition = *Position;
551
552 switch (SeekMode)
553 {
554 case SeekAbsolute:
555 break;
556 case SeekRelative:
557 NewPosition.QuadPart += (ULONGLONG)FileHandle->FilePointer;
558 break;
559 default:
560 ASSERT(FALSE);
561 return EINVAL;
562 }
563
564 if (NewPosition.HighPart != 0)
565 return EINVAL;
566 if (NewPosition.LowPart >= FileHandle->FileSize)
567 return EINVAL;
568
569 FileHandle->FilePointer = NewPosition.LowPart;
570 return ESUCCESS;
571}
#define EINVAL
Definition: acclib.h:90
@ SeekRelative
Definition: arc.h:60
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106

Variable Documentation

◆ Iso9660FuncTable

const DEVVTBL Iso9660FuncTable
static
Initial value:
=
{
L"cdfs",
}
static ARC_STATUS IsoSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: iso.c:547
static ARC_STATUS IsoGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: iso.c:328
static ARC_STATUS IsoRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: iso.c:380
static ARC_STATUS IsoOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: iso.c:351
static ARC_STATUS IsoClose(ULONG FileId)
Definition: iso.c:320
#define L(x)
Definition: resources.c:13

Definition at line 592 of file iso.c.

Referenced by IsoMount().

◆ IsoVolumes

PISO_VOLUME_INFO IsoVolumes[MAX_FDS]
static

Definition at line 44 of file iso.c.

Referenced by IsoGetVolumeSize(), IsoLookupFile(), and IsoMount().