ReactOS 0.4.16-dev-1946-g52006dd
iso.c
Go to the documentation of this file.
1/*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 * Copyright (C) 2009 Hervé Poussineau <hpoussin@reactos.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef _M_ARM
22#include <freeldr.h>
23
24#include <debug.h>
26
27#define SECTORSIZE 2048
28#define TAG_ISO_VOLUME 'VosI'
29#define TAG_ISO_BUFFER 'BosI'
30#define TAG_ISO_FILE 'FosI'
31
32typedef struct _ISO_VOLUME_INFO
33{
43
45
46static
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}
65
66static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectoryLength, PCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
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}
119
120
121/*
122 * IsoBufferDirectory()
123 * This function allocates a buffer, reads the specified directory
124 * and returns a pointer to that buffer into pDirectoryBuffer. The
125 * function returns an ARC error code. The directory is specified
126 * by its starting sector and length.
127 */
128static ARC_STATUS IsoBufferDirectory(ULONG DeviceId, ULONG DirectoryStartSector, ULONG DirectoryLength,
129 PVOID* pDirectoryBuffer)
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}
171
172/*
173 * IsoLookupFile()
174 * This function searches the file system for the
175 * specified filename and fills in an ISO_FILE_INFO structure
176 * with info describing the file, etc. returns ARC error code
177 */
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}
318
319static
321{
324 return ESUCCESS;
325}
326
327static
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}
349
350static
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}
378
379static
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}
545
546static
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}
572
573
584 _In_ ULONG DeviceId)
585{
587 ASSERT(Volume);
588 return (ULONGLONG)Volume->VolumeSizeLBN * Volume->LogicalBlockSize;
589}
590
591
593{
594 IsoClose,
596 IsoOpen,
597 IsoRead,
598 IsoSeek,
599 L"cdfs",
600};
601
602const DEVVTBL* IsoMount(ULONG DeviceId)
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}
661
662#endif
#define N
Definition: crc32.c:57
unsigned char BOOLEAN
PRTL_UNICODE_STRING_BUFFER Path
#define ENOENT
Definition: acclib.h:79
#define EINVAL
Definition: acclib.h:90
#define ENOMEM
Definition: acclib.h:84
#define EIO
Definition: acclib.h:81
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define EACCES
Definition: acclib.h:85
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:455
PVOID FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:709
ULONG FsGetNumPathParts(PCSTR Path)
Definition: fs.c:617
VOID FsSetDeviceSpecific(ULONG FileId, PVOID Specific)
Definition: fs.c:702
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:716
#define MAX_FDS
Definition: fs.h:34
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:448
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
Definition: fs.c:645
VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: heap.c:553
PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: heap.c:545
const DEVVTBL * IsoMount(ULONG DeviceId)
Definition: iso.c:602
static PCSTR IsoLastPathSeparator(_In_ PCSTR Path)
Definition: iso.c:48
static ARC_STATUS IsoSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: iso.c:547
static PISO_VOLUME_INFO IsoVolumes[MAX_FDS]
Definition: iso.c:44
#define TAG_ISO_BUFFER
Definition: iso.c:29
static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfo)
Definition: iso.c:178
static ARC_STATUS IsoGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: iso.c:328
#define SECTORSIZE
Definition: iso.c:27
static ARC_STATUS IsoBufferDirectory(ULONG DeviceId, ULONG DirectoryStartSector, ULONG DirectoryLength, PVOID *pDirectoryBuffer)
Definition: iso.c:128
#define TAG_ISO_VOLUME
Definition: iso.c:28
static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectoryLength, PCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
Definition: iso.c:66
struct _ISO_VOLUME_INFO ISO_VOLUME_INFO
#define TAG_ISO_FILE
Definition: iso.c:30
static const DEVVTBL Iso9660FuncTable
Definition: iso.c:592
struct _ISO_VOLUME_INFO * PISO_VOLUME_INFO
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
ULONGLONG IsoGetVolumeSize(_In_ ULONG DeviceId)
Returns the size of the ISO-9660 volume laid on the storage media device opened via DeviceId.
Definition: iso.c:583
static ARC_STATUS IsoClose(ULONG FileId)
Definition: iso.c:320
#define _stricmp
Definition: cat.c:22
Definition: bufpool.h:45
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define L(x)
Definition: resources.c:13
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
@ 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
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
Status
Definition: gdiplustypes.h:25
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
struct _DIR_RECORD * PDIR_RECORD
struct _PVD * PPVD
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define ASSERT(a)
Definition: mode.c:44
#define min(a, b)
Definition: monoChain.cc:55
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
#define ANSI_NULL
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG SectorCount
Definition: part_xbox.c:31
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ SeekRelative
Definition: arc.h:60
@ SeekAbsolute
Definition: arc.h:59
enum _OPENMODE OPENMODE
@ ReadOnlyFile
Definition: arc.h:78
@ HiddenFile
Definition: arc.h:79
enum _SEEKMODE SEEKMODE
@ OpenReadOnly
Definition: arc.h:65
#define TRACE(s)
Definition: solgame.cpp:4
ULONG ExtentLocationL
Definition: iso.h:27
ULONG DataLengthL
Definition: iso.h:29
ULONG FilePointer
Definition: iso.h:102
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
PVOID DirectoryBuffer
Definition: iso.c:40
ULONG LogicalBlockSize
Should be SECTORSIZE.
Definition: iso.c:35
UCHAR DirectoryPath[261]
Definition: iso.c:41
ULONG PvdDirectoryLength
Definition: iso.c:37
ULONG DirectoryPathLength
Definition: iso.c:38
ULONG DirectoryLength
Definition: iso.c:39
ULONG VolumeSizeLBN
In Logical Block Numbers (LBN)
Definition: iso.c:34
ULONG PvdDirectorySector
Definition: iso.c:36
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
Definition: fs.h:25
static COORD Position
Definition: mouse.c:34
void * PVOID
Definition: typedefs.h:50
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
char * PCHAR
Definition: typedefs.h:51
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_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
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:320
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175