mirror of
https://github.com/reactos/reactos.git
synced 2024-11-27 05:23:33 +08:00
[FFS] Remove the FFS/UFS driver
The upstream driver is not maintained and the file system itself
is in a semi-abandoned state.
Originally imported at 3a3ef631d1
The driver is written by Lee Jae-Hong, updated by Bo Brantén.
ReactOS porting made by Peter Hater and Pierre Schweitzer.
Follow updates at http://www.acc.umu.se/~bosse/
FS Recognizer code is left to keep the FS support as an
installable driver.
CORE-11040
This commit is contained in:
parent
2e2190df57
commit
49cfac17c5
@ -267,7 +267,6 @@
|
||||
/drivers/filesystems/cdfs/ @HeisSpiter
|
||||
/drivers/filesystems/ext2/ @HeisSpiter
|
||||
/drivers/filesystems/fastfat_new/ @HeisSpiter
|
||||
/drivers/filesystems/ffs/ @HeisSpiter
|
||||
/drivers/filesystems/nfs/ @HeisSpiter
|
||||
/media/doc/README.FSD @HeisSpiter
|
||||
/sdk/lib/fslib/btrfslib/ @HeisSpiter
|
||||
|
@ -1260,8 +1260,7 @@ InstallVBRToPartition(
|
||||
/*
|
||||
else if (wcsicmp(FileSystemName, L"EXT2") == 0 ||
|
||||
wcsicmp(FileSystemName, L"EXT3") == 0 ||
|
||||
wcsicmp(FileSystemName, L"EXT4") == 0 ||
|
||||
wcsicmp(FileSystemName, L"FFS") == 0)
|
||||
wcsicmp(FileSystemName, L"EXT4") == 0)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -142,7 +142,6 @@ static FILE_SYSTEM RegisteredFileSystems[] =
|
||||
{ L"EXT2" , Ext2Format, Ext2Chkdsk },
|
||||
{ L"EXT3" , Ext2Format, Ext2Chkdsk },
|
||||
{ L"EXT4" , Ext2Format, Ext2Chkdsk },
|
||||
{ L"FFS" , FfsFormat , FfsChkdsk },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -392,8 +392,7 @@ FileSystemToMBRPartitionType(
|
||||
else if (wcsicmp(FileSystem, L"BTRFS") == 0 ||
|
||||
wcsicmp(FileSystem, L"EXT2") == 0 ||
|
||||
wcsicmp(FileSystem, L"EXT3") == 0 ||
|
||||
wcsicmp(FileSystem, L"EXT4") == 0 ||
|
||||
wcsicmp(FileSystem, L"FFS") == 0)
|
||||
wcsicmp(FileSystem, L"EXT4") == 0)
|
||||
{
|
||||
return PARTITION_LINUX;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
add_executable(autochk WIN32 autochk.c autochk.rc)
|
||||
set_module_type(autochk nativecui)
|
||||
target_link_libraries(autochk nt vfatlib vfatxlib ntfslib btrfslib ext2lib ffslib cdfslib)
|
||||
target_link_libraries(autochk nt vfatlib vfatxlib ntfslib btrfslib ext2lib cdfslib)
|
||||
add_importlibs(autochk ntdll)
|
||||
add_cd_file(TARGET autochk DESTINATION reactos/system32 FOR all)
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <fslib/ntfslib.h>
|
||||
#include <fslib/btrfslib.h>
|
||||
#include <fslib/ext2lib.h>
|
||||
#include <fslib/ffslib.h>
|
||||
#include <fslib/cdfslib.h>
|
||||
|
||||
#define NDEBUG
|
||||
@ -55,7 +54,6 @@ FILESYSTEM_CHKDSK FileSystems[] =
|
||||
{ L"EXT2", Ext2Chkdsk },
|
||||
{ L"EXT3", Ext2Chkdsk },
|
||||
{ L"EXT4", Ext2Chkdsk },
|
||||
{ L"FFS", FfsChkdsk },
|
||||
{ L"CDFS", CdfsChkdsk },
|
||||
};
|
||||
|
||||
|
@ -2197,13 +2197,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\btrfs","ImagePath",0x00020000,"system32\
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\btrfs","Start",0x00010001,0x00000003
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\btrfs","Type",0x00010001,0x00000002
|
||||
|
||||
; FFS Filesystem driver
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\ffs","ErrorControl",0x00010001,0x00000000
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\ffs","Group",0x00000000,"Boot File System"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\ffs","ImagePath",0x00020000,"system32\drivers\ffs.sys"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\ffs","Start",0x00010001,0x00000003
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\ffs","Type",0x00010001,0x00000002
|
||||
|
||||
; NFS Filesystem driver
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\nfs41_driver","ErrorControl",0x00010001,0x00000000
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\nfs41_driver","Group",0x00000000,"Network"
|
||||
|
@ -214,7 +214,6 @@ add_subdirectory(ucdfs)
|
||||
add_subdirectory(uext2)
|
||||
add_subdirectory(ufat)
|
||||
add_subdirectory(ufatx)
|
||||
add_subdirectory(uffs)
|
||||
add_subdirectory(untfs)
|
||||
add_subdirectory(updspapi)
|
||||
add_subdirectory(url)
|
||||
|
@ -1,13 +0,0 @@
|
||||
|
||||
spec2def(uffs.dll uffs.spec)
|
||||
|
||||
list(APPEND SOURCE
|
||||
uffs.c
|
||||
uffs.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/uffs.def)
|
||||
|
||||
add_library(uffs MODULE ${SOURCE})
|
||||
set_module_type(uffs nativedll)
|
||||
target_link_libraries(uffs ffslib)
|
||||
add_importlibs(uffs ntdll)
|
||||
add_cd_file(TARGET uffs DESTINATION reactos/system32 FOR all)
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: FFS File System Management
|
||||
* FILE: dll/win32/uffs/uffs.c
|
||||
* PURPOSE: uffs DLL initialisation
|
||||
* PROGRAMMERS: Pierre Schweitzer
|
||||
*/
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
INT WINAPI
|
||||
DllMain(
|
||||
IN HINSTANCE hinstDLL,
|
||||
IN DWORD dwReason,
|
||||
IN LPVOID lpvReserved)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hinstDLL);
|
||||
UNREFERENCED_PARAMETER(dwReason);
|
||||
UNREFERENCED_PARAMETER(lpvReserved);
|
||||
|
||||
return TRUE;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "FFS File System Management"
|
||||
#define REACTOS_STR_INTERNAL_NAME "uffs"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "uffs.dll"
|
||||
#include <reactos/version.rc>
|
@ -1,2 +0,0 @@
|
||||
@ stdcall Chkdsk(ptr ptr long long long long ptr ptr ptr ptr ptr) FfsChkdsk
|
||||
@ stdcall Format(ptr ptr long long long ptr long) FfsFormat
|
@ -4,7 +4,6 @@ add_subdirectory(cdfs)
|
||||
add_subdirectory(ext2)
|
||||
#add_subdirectory(fastfat)
|
||||
add_subdirectory(fastfat_new)
|
||||
add_subdirectory(ffs)
|
||||
add_subdirectory(fs_rec)
|
||||
add_subdirectory(msfs)
|
||||
add_subdirectory(mup)
|
||||
|
@ -1,51 +0,0 @@
|
||||
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/drivers
|
||||
inc)
|
||||
|
||||
list(APPEND SOURCE
|
||||
src/block.c
|
||||
src/cleanup.c
|
||||
src/close.c
|
||||
src/cmcb.c
|
||||
src/create.c
|
||||
src/debug.c
|
||||
src/devctl.c
|
||||
src/dirctl.c
|
||||
src/dispatch.c
|
||||
src/except.c
|
||||
src/fastio.c
|
||||
src/ffs.c
|
||||
src/fileinfo.c
|
||||
src/flush.c
|
||||
src/fsctl.c
|
||||
src/init.c
|
||||
src/lock.c
|
||||
src/memory.c
|
||||
src/misc.c
|
||||
src/pnp.c
|
||||
src/read.c
|
||||
src/shutdown.c
|
||||
src/volinfo.c
|
||||
src/write.c
|
||||
inc/ffsdrv.h)
|
||||
|
||||
add_library(ffs MODULE ${SOURCE} src/ffsdrv.rc)
|
||||
|
||||
if(USE_CLANG_CL OR (NOT MSVC))
|
||||
target_compile_options(ffs PRIVATE -Wno-pointer-sign -Wno-unused-function)
|
||||
target_compile_options(ffs PRIVATE -Wno-unused-variable -Wno-missing-braces)
|
||||
if(USE_CLANG_CL)
|
||||
target_compile_options(ffs PRIVATE -Wno-empty-body)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_compile_options(ffs PRIVATE -Wno-unused-but-set-variable)
|
||||
endif()
|
||||
|
||||
add_definitions(-D__KERNEL__)
|
||||
set_module_type(ffs kernelmodedriver)
|
||||
target_link_libraries(ffs memcmp ${PSEH_LIB})
|
||||
add_importlibs(ffs ntoskrnl hal)
|
||||
add_pch(ffs inc/ffsdrv.h SOURCE)
|
||||
add_cd_file(TARGET ffs DESTINATION reactos/system32/drivers FOR all)
|
||||
|
@ -1,892 +0,0 @@
|
||||
/* $NetBSD: bootblock.h,v 1.24 2004/03/22 07:11:00 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
* Michael L. Finch, Bradley A. Grantham, and
|
||||
* Lawrence A. Kesteloot
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Alice Group.
|
||||
* 4. The names of the Alice Group or any of its members may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1994, 1999 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Christopher G. Demetriou
|
||||
* for the NetBSD Project.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1994 Rolf Grossmann
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Rolf Grossmann.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_BOOTBLOCK_H
|
||||
#define _SYS_BOOTBLOCK_H
|
||||
|
||||
#include "type.h"
|
||||
|
||||
#if 0 /* XXX ffsdrv */
|
||||
#if !defined(__ASSEMBLER__)
|
||||
#if defined(_KERNEL) || defined(_STANDALONE)
|
||||
#include <sys/stdint.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif /* !defined(__ASSEMBLER__) */
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------
|
||||
* MBR (Master Boot Record) --
|
||||
* definitions for systems that use MBRs
|
||||
*/
|
||||
|
||||
/*
|
||||
* Layout of boot records:
|
||||
*
|
||||
* Byte range Use Description
|
||||
* ---------- --- -----------
|
||||
*
|
||||
* 0 - 2 FMP JMP xxx, NOP
|
||||
* 3 - 10 FP OEM Name
|
||||
*
|
||||
* 11 - 61 FMP FAT12/16 BPB
|
||||
* Whilst not strictly necessary for MBR,
|
||||
* GRUB reserves this area
|
||||
*
|
||||
* 11 - 89 P FAT32 BPB
|
||||
* (are we ever going to boot off this?)
|
||||
*
|
||||
*
|
||||
* 62 - 217 FMP Boot code
|
||||
*
|
||||
* 90 - 217 P FAT32 boot code
|
||||
*
|
||||
* 218 - 223 M Win95b/98/me "drive time"
|
||||
* http://www.geocities.com/thestarman3/asm/mbr/95BMEMBR.htm#MYST
|
||||
* only changed if all 6 bytes are 0
|
||||
*
|
||||
* 224 - 436 FMP boot code (continued)
|
||||
*
|
||||
* 437 - 439 M WinNT/2K/XP MBR "boot language"
|
||||
* http://www.geocities.com/thestarman3/asm/mbr/Win2kmbr.htm
|
||||
* not needed by us
|
||||
*
|
||||
* 400 - 439 MP NetBSD: mbr_bootsel
|
||||
*
|
||||
* 440 - 443 M WinNT/2K/XP Drive Serial Number (NT DSN)
|
||||
* http://www.geocities.com/thestarman3/asm/mbr/Win2kmbr.htm
|
||||
*
|
||||
* 444 - 445 FMP bootcode or unused
|
||||
* NetBSD: mbr_bootsel_magic
|
||||
*
|
||||
* 446 - 509 M partition table
|
||||
*
|
||||
* 510 - 511 FMP magic number (0xAA55)
|
||||
*
|
||||
* Use:
|
||||
* ----
|
||||
* F Floppy boot sector
|
||||
* M Master Boot Record
|
||||
* P Partition Boot record
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* MBR (Master Boot Record)
|
||||
*/
|
||||
#define MBR_BBSECTOR 0 /* MBR relative sector # */
|
||||
#define MBR_BPB_OFFSET 11 /* offsetof(mbr_sector, mbr_bpb) */
|
||||
#define MBR_BOOTCODE_OFFSET 90 /* offsetof(mbr_sector, mbr_bootcode) */
|
||||
#define MBR_BS_OFFSET 400 /* offsetof(mbr_sector, mbr_bootsel) */
|
||||
#define MBR_DSN_OFFSET 440 /* offsetof(mbr_sector, mbr_dsn) */
|
||||
#define MBR_BS_MAGIC_OFFSET 444 /* offsetof(mbr_sector, mbr_bootsel_magic) */
|
||||
#define MBR_PART_OFFSET 446 /* offsetof(mbr_sector, mbr_part[0]) */
|
||||
#define MBR_MAGIC_OFFSET 510 /* offsetof(mbr_sector, mbr_magic) */
|
||||
#define MBR_MAGIC 0xaa55 /* MBR magic number */
|
||||
#define MBR_BS_MAGIC 0xb5e1 /* mbr_bootsel magic number */
|
||||
#define MBR_PART_COUNT 4 /* Number of partitions in MBR */
|
||||
#define MBR_BS_PARTNAMESIZE 8 /* Size of name mbr_bootsel nametab */
|
||||
/* (excluding trailing NUL) */
|
||||
|
||||
/* values for mbr_partition.mbrp_flag */
|
||||
#define MBR_PFLAG_ACTIVE 0x80 /* The active partition */
|
||||
|
||||
/* values for mbr_partition.mbrp_type */
|
||||
#define MBR_PTYPE_FAT12 0x01 /* 12-bit FAT */
|
||||
#define MBR_PTYPE_FAT16S 0x04 /* 16-bit FAT, less than 32M */
|
||||
#define MBR_PTYPE_EXT 0x05 /* extended partition */
|
||||
#define MBR_PTYPE_FAT16B 0x06 /* 16-bit FAT, more than 32M */
|
||||
#define MBR_PTYPE_NTFS 0x07 /* OS/2 HPFS, NTFS, QNX2, Adv. UNIX */
|
||||
#define MBR_PTYPE_FAT32 0x0b /* 32-bit FAT */
|
||||
#define MBR_PTYPE_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
|
||||
#define MBR_PTYPE_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
|
||||
#define MBR_PTYPE_EXT_LBA 0x0f /* extended partition, LBA-mapped */
|
||||
#define MBR_PTYPE_ONTRACK 0x54
|
||||
#define MBR_PTYPE_LNXSWAP 0x82 /* Linux swap or Solaris */
|
||||
#define MBR_PTYPE_LNXEXT2 0x83 /* Linux native */
|
||||
#define MBR_PTYPE_EXT_LNX 0x85 /* Linux extended partition */
|
||||
#define MBR_PTYPE_NTFSVOL 0x87 /* NTFS volume set or HPFS mirrored */
|
||||
#define MBR_PTYPE_PREP 0x41 /* PReP */
|
||||
#define MBR_PTYPE_386BSD 0xa5 /* 386BSD partition type */
|
||||
#define MBR_PTYPE_APPLEUFS 0xa8 /* Apple UFS */
|
||||
#define MBR_PTYPE_NETBSD 0xa9 /* NetBSD partition type */
|
||||
#define MBR_PTYPE_OPENBSD 0xa6 /* OpenBSD partition type */
|
||||
|
||||
#define MBR_PSECT(s) ((s) & 0x3f)
|
||||
#define MBR_PCYL(c, s) ((c) + (((s) & 0xc0) << 2))
|
||||
|
||||
#define MBR_IS_EXTENDED(x) ((x) == MBR_PTYPE_EXT || \
|
||||
(x) == MBR_PTYPE_EXT_LBA || \
|
||||
(x) == MBR_PTYPE_EXT_LNX)
|
||||
|
||||
/* values for mbr_bootsel.mbrbs_flags */
|
||||
#define MBR_BS_ACTIVE 0x01 /* Bootselector active (or code present) */
|
||||
#define MBR_BS_EXTINT13 0x02 /* Set by fdisk if LBA needed (deprecated) */
|
||||
#define MBR_BS_READ_LBA 0x04 /* Force LBA reads - even for low numbers */
|
||||
#define MBR_BS_EXTLBA 0x08 /* Extended ptn capable (LBA reads) */
|
||||
#define MBR_BS_NEWMBR 0x80 /* New bootsel at offset 440 */
|
||||
|
||||
#if !defined(__ASSEMBLER__) /* { */
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* (x86) BIOS Parameter Block for FAT12
|
||||
*/
|
||||
struct mbr_bpbFAT12 {
|
||||
uint16_t bpbBytesPerSec; /* bytes per sector */
|
||||
uint8_t bpbSecPerClust; /* sectors per cluster */
|
||||
uint16_t bpbResSectors; /* number of reserved sectors */
|
||||
uint8_t bpbFATs; /* number of FATs */
|
||||
uint16_t bpbRootDirEnts; /* number of root directory entries */
|
||||
uint16_t bpbSectors; /* total number of sectors */
|
||||
uint8_t bpbMedia; /* media descriptor */
|
||||
uint16_t bpbFATsecs; /* number of sectors per FAT */
|
||||
uint16_t bpbSecPerTrack; /* sectors per track */
|
||||
uint16_t bpbHeads; /* number of heads */
|
||||
uint16_t bpbHiddenSecs; /* # of hidden sectors */
|
||||
}; /* __attribute__((__packed__)); */
|
||||
|
||||
/*
|
||||
* (x86) BIOS Parameter Block for FAT16
|
||||
*/
|
||||
struct mbr_bpbFAT16 {
|
||||
uint16_t bpbBytesPerSec; /* bytes per sector */
|
||||
uint8_t bpbSecPerClust; /* sectors per cluster */
|
||||
uint16_t bpbResSectors; /* number of reserved sectors */
|
||||
uint8_t bpbFATs; /* number of FATs */
|
||||
uint16_t bpbRootDirEnts; /* number of root directory entries */
|
||||
uint16_t bpbSectors; /* total number of sectors */
|
||||
uint8_t bpbMedia; /* media descriptor */
|
||||
uint16_t bpbFATsecs; /* number of sectors per FAT */
|
||||
uint16_t bpbSecPerTrack; /* sectors per track */
|
||||
uint16_t bpbHeads; /* number of heads */
|
||||
uint32_t bpbHiddenSecs; /* # of hidden sectors */
|
||||
uint32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
|
||||
uint8_t bsDrvNum; /* Int 0x13 drive number (e.g. 0x80) */
|
||||
uint8_t bsReserved1; /* Reserved; set to 0 */
|
||||
uint8_t bsBootSig; /* 0x29 if next 3 fields are present */
|
||||
uint8_t bsVolID[4]; /* Volume serial number */
|
||||
uint8_t bsVolLab[11]; /* Volume label */
|
||||
uint8_t bsFileSysType[8];
|
||||
/* "FAT12 ", "FAT16 ", "FAT " */
|
||||
}; /* __attribute__((__packed__)); */
|
||||
|
||||
/*
|
||||
* (x86) BIOS Parameter Block for FAT32
|
||||
*/
|
||||
struct mbr_bpbFAT32 {
|
||||
uint16_t bpbBytesPerSec; /* bytes per sector */
|
||||
uint8_t bpbSecPerClust; /* sectors per cluster */
|
||||
uint16_t bpbResSectors; /* number of reserved sectors */
|
||||
uint8_t bpbFATs; /* number of FATs */
|
||||
uint16_t bpbRootDirEnts; /* number of root directory entries */
|
||||
uint16_t bpbSectors; /* total number of sectors */
|
||||
uint8_t bpbMedia; /* media descriptor */
|
||||
uint16_t bpbFATsecs; /* number of sectors per FAT */
|
||||
uint16_t bpbSecPerTrack; /* sectors per track */
|
||||
uint16_t bpbHeads; /* number of heads */
|
||||
uint32_t bpbHiddenSecs; /* # of hidden sectors */
|
||||
uint32_t bpbHugeSectors; /* # of sectors if bpbSectors == 0 */
|
||||
uint32_t bpbBigFATsecs; /* like bpbFATsecs for FAT32 */
|
||||
uint16_t bpbExtFlags; /* extended flags: */
|
||||
#define MBR_FAT32_FATNUM 0x0F /* mask for numbering active FAT */
|
||||
#define MBR_FAT32_FATMIRROR 0x80 /* FAT is mirrored (as previously) */
|
||||
uint16_t bpbFSVers; /* filesystem version */
|
||||
#define MBR_FAT32_FSVERS 0 /* currently only 0 is understood */
|
||||
uint32_t bpbRootClust; /* start cluster for root directory */
|
||||
uint16_t bpbFSInfo; /* filesystem info structure sector */
|
||||
uint16_t bpbBackup; /* backup boot sector */
|
||||
uint8_t bsReserved[12]; /* Reserved for future expansion */
|
||||
uint8_t bsDrvNum; /* Int 0x13 drive number (e.g. 0x80) */
|
||||
uint8_t bsReserved1; /* Reserved; set to 0 */
|
||||
uint8_t bsBootSig; /* 0x29 if next 3 fields are present */
|
||||
uint8_t bsVolID[4]; /* Volume serial number */
|
||||
uint8_t bsVolLab[11]; /* Volume label */
|
||||
uint8_t bsFileSysType[8]; /* "FAT32 " */
|
||||
}; /* __attribute__((__packed__)); */
|
||||
|
||||
/*
|
||||
* (x86) MBR boot selector
|
||||
*/
|
||||
struct mbr_bootsel {
|
||||
uint8_t mbrbs_defkey;
|
||||
uint8_t mbrbs_flags;
|
||||
uint16_t mbrbs_timeo;
|
||||
uint8_t mbrbs_nametab[MBR_PART_COUNT][MBR_BS_PARTNAMESIZE + 1];
|
||||
}; /* __attribute__((__packed__)); */
|
||||
|
||||
/*
|
||||
* MBR partition
|
||||
*/
|
||||
struct mbr_partition {
|
||||
uint8_t mbrp_flag; /* MBR partition flags */
|
||||
uint8_t mbrp_shd; /* Starting head */
|
||||
uint8_t mbrp_ssect; /* Starting sector */
|
||||
uint8_t mbrp_scyl; /* Starting cylinder */
|
||||
uint8_t mbrp_type; /* Partition type (see below) */
|
||||
uint8_t mbrp_ehd; /* End head */
|
||||
uint8_t mbrp_esect; /* End sector */
|
||||
uint8_t mbrp_ecyl; /* End cylinder */
|
||||
uint32_t mbrp_start; /* Absolute starting sector number */
|
||||
uint32_t mbrp_size; /* Partition size in sectors */
|
||||
}; /* __attribute__((__packed__)); */
|
||||
|
||||
int xlat_mbr_fstype(int); /* in sys/lib/libkern/xlat_mbr_fstype.c */
|
||||
|
||||
/*
|
||||
* MBR boot sector.
|
||||
* This is used by both the MBR (Master Boot Record) in sector 0 of the disk
|
||||
* and the PBR (Partition Boot Record) in sector 0 of an MBR partition.
|
||||
*/
|
||||
struct mbr_sector {
|
||||
/* Jump instruction to boot code. */
|
||||
/* Usually 0xE9nnnn or 0xEBnn90 */
|
||||
uint8_t mbr_jmpboot[3];
|
||||
/* OEM name and version */
|
||||
uint8_t mbr_oemname[8];
|
||||
union { /* BIOS Parameter Block */
|
||||
struct mbr_bpbFAT12 bpb12;
|
||||
struct mbr_bpbFAT16 bpb16;
|
||||
struct mbr_bpbFAT32 bpb32;
|
||||
} mbr_bpb;
|
||||
/* Boot code */
|
||||
uint8_t mbr_bootcode[310];
|
||||
/* Config for /usr/mdec/mbr_bootsel */
|
||||
struct mbr_bootsel mbr_bootsel;
|
||||
/* NT Drive Serial Number */
|
||||
uint32_t mbr_dsn;
|
||||
/* mbr_bootsel magic */
|
||||
uint16_t mbr_bootsel_magic;
|
||||
/* MBR partition table */
|
||||
struct mbr_partition mbr_parts[MBR_PART_COUNT];
|
||||
/* MBR magic (0xaa55) */
|
||||
uint16_t mbr_magic;
|
||||
}; /* __attribute__((__packed__)); */
|
||||
|
||||
#endif /* !defined(__ASSEMBLER__) */ /* } */
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
/* ------------------------------------------
|
||||
* shared --
|
||||
* definitions shared by many platforms
|
||||
*/
|
||||
|
||||
#if !defined(__ASSEMBLER__) /* { */
|
||||
|
||||
/* Maximum # of blocks in bbi_block_table, each bbi_block_size long */
|
||||
#define SHARED_BBINFO_MAXBLOCKS 118 /* so sizeof(shared_bbinfo) == 512 */
|
||||
|
||||
struct shared_bbinfo {
|
||||
uint8_t bbi_magic[32];
|
||||
int32_t bbi_block_size;
|
||||
int32_t bbi_block_count;
|
||||
int32_t bbi_block_table[SHARED_BBINFO_MAXBLOCKS];
|
||||
};
|
||||
|
||||
#if 0 /* XXX ffsdrv */
|
||||
|
||||
/* ------------------------------------------
|
||||
* alpha --
|
||||
* Alpha (disk, but also tape) Boot Block.
|
||||
*
|
||||
* See Section (III) 3.6.1 of the Alpha Architecture Reference Manual.
|
||||
*/
|
||||
|
||||
struct alpha_boot_block {
|
||||
uint64_t bb_data[63]; /* data (disklabel, also as below) */
|
||||
uint64_t bb_cksum; /* checksum of the boot block,
|
||||
* taken as uint64_t's
|
||||
*/
|
||||
};
|
||||
#define bb_secsize bb_data[60] /* secondary size (blocks) */
|
||||
#define bb_secstart bb_data[61] /* secondary start (blocks) */
|
||||
#define bb_flags bb_data[62] /* unknown flags (set to zero) */
|
||||
|
||||
#define ALPHA_BOOT_BLOCK_OFFSET 0 /* offset of boot block. */
|
||||
#define ALPHA_BOOT_BLOCK_BLOCKSIZE 512 /* block size for sector
|
||||
* size/start, and for boot
|
||||
* block itself.
|
||||
*/
|
||||
|
||||
#define ALPHA_BOOT_BLOCK_CKSUM(bb,cksum) \
|
||||
do { \
|
||||
const struct alpha_boot_block *_bb = (bb); \
|
||||
uint64_t _cksum; \
|
||||
int _i; \
|
||||
\
|
||||
_cksum = 0; \
|
||||
for (_i = 0; \
|
||||
_i < (sizeof _bb->bb_data / sizeof _bb->bb_data[0]); \
|
||||
_i++) \
|
||||
_cksum += _bb->bb_data[_i]; \
|
||||
*(cksum) = _cksum; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* ------------------------------------------
|
||||
* apple --
|
||||
* Apple computers boot block related information
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver Descriptor Map, from Inside Macintosh: Devices, SCSI Manager
|
||||
* pp 12-13. The driver descriptor map always resides on physical block 0.
|
||||
*/
|
||||
struct apple_drvr_descriptor {
|
||||
uint32_t descBlock; /* first block of driver */
|
||||
uint16_t descSize; /* driver size in blocks */
|
||||
uint16_t descType; /* system type */
|
||||
};
|
||||
|
||||
/*
|
||||
* system types; Apple reserves 0-15
|
||||
*/
|
||||
#define APPLE_DRVR_TYPE_MACINTOSH 1
|
||||
|
||||
#define APPLE_DRVR_MAP_MAGIC 0x4552
|
||||
#define APPLE_DRVR_MAP_MAX_DESCRIPTORS 61
|
||||
|
||||
struct apple_drvr_map {
|
||||
uint16_t sbSig; /* map signature */
|
||||
uint16_t sbBlockSize; /* block size of device */
|
||||
uint32_t sbBlkCount; /* number of blocks on device */
|
||||
uint16_t sbDevType; /* (used internally by ROM) */
|
||||
uint16_t sbDevID; /* (used internally by ROM) */
|
||||
uint32_t sbData; /* (used internally by ROM) */
|
||||
uint16_t sbDrvrCount; /* number of driver descriptors */
|
||||
struct apple_drvr_descriptor sb_dd[APPLE_DRVR_MAP_MAX_DESCRIPTORS];
|
||||
uint16_t pad[3];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/*
|
||||
* Partition map structure from Inside Macintosh: Devices, SCSI Manager
|
||||
* pp. 13-14. The partition map always begins on physical block 1.
|
||||
*
|
||||
* With the exception of block 0, all blocks on the disk must belong to
|
||||
* exactly one partition. The partition map itself belongs to a partition
|
||||
* of type `APPLE_PARTITION_MAP', and is not limited in size by anything
|
||||
* other than available disk space. The partition map is not necessarily
|
||||
* the first partition listed.
|
||||
*/
|
||||
#define APPLE_PART_MAP_ENTRY_MAGIC 0x504d
|
||||
|
||||
struct apple_part_map_entry {
|
||||
uint16_t pmSig; /* partition signature */
|
||||
uint16_t pmSigPad; /* (reserved) */
|
||||
uint32_t pmMapBlkCnt; /* number of blocks in partition map */
|
||||
uint32_t pmPyPartStart; /* first physical block of partition */
|
||||
uint32_t pmPartBlkCnt; /* number of blocks in partition */
|
||||
uint8_t pmPartName[32]; /* partition name */
|
||||
uint8_t pmPartType[32]; /* partition type */
|
||||
uint32_t pmLgDataStart; /* first logical block of data area */
|
||||
uint32_t pmDataCnt; /* number of blocks in data area */
|
||||
uint32_t pmPartStatus; /* partition status information */
|
||||
uint32_t pmLgBootStart; /* first logical block of boot code */
|
||||
uint32_t pmBootSize; /* size of boot code, in bytes */
|
||||
uint32_t pmBootLoad; /* boot code load address */
|
||||
uint32_t pmBootLoad2; /* (reserved) */
|
||||
uint32_t pmBootEntry; /* boot code entry point */
|
||||
uint32_t pmBootEntry2; /* (reserved) */
|
||||
uint32_t pmBootCksum; /* boot code checksum */
|
||||
int8_t pmProcessor[16]; /* processor type (e.g. "68020") */
|
||||
uint8_t pmBootArgs[128]; /* A/UX boot arguments */
|
||||
uint8_t pad[248]; /* pad to end of block */
|
||||
};
|
||||
|
||||
#define APPLE_PART_TYPE_DRIVER "APPLE_DRIVER"
|
||||
#define APPLE_PART_TYPE_DRIVER43 "APPLE_DRIVER43"
|
||||
#define APPLE_PART_TYPE_DRIVERATA "APPLE_DRIVER_ATA"
|
||||
#define APPLE_PART_TYPE_DRIVERIOKIT "APPLE_DRIVER_IOKIT"
|
||||
#define APPLE_PART_TYPE_FWDRIVER "APPLE_FWDRIVER"
|
||||
#define APPLE_PART_TYPE_FWB_COMPONENT "FWB DRIVER COMPONENTS"
|
||||
#define APPLE_PART_TYPE_FREE "APPLE_FREE"
|
||||
#define APPLE_PART_TYPE_MAC "APPLE_HFS"
|
||||
#define APPLE_PART_TYPE_NETBSD "NETBSD"
|
||||
#define APPLE_PART_TYPE_NBSD_PPCBOOT "NETBSD/MACPPC"
|
||||
#define APPLE_PART_TYPE_NBSD_68KBOOT "NETBSD/MAC68K"
|
||||
#define APPLE_PART_TYPE_PATCHES "APPLE_PATCHES"
|
||||
#define APPLE_PART_TYPE_PARTMAP "APPLE_PARTITION_MAP"
|
||||
#define APPLE_PART_TYPE_PATCHES "APPLE_PATCHES"
|
||||
#define APPLE_PART_TYPE_SCRATCH "APPLE_SCRATCH"
|
||||
#define APPLE_PART_TYPE_UNIX "APPLE_UNIX_SVR2"
|
||||
|
||||
/*
|
||||
* "pmBootArgs" for APPLE_UNIX_SVR2 partition.
|
||||
* NetBSD/mac68k only uses Magic, Cluster, Type, and Flags.
|
||||
*/
|
||||
struct apple_blockzeroblock {
|
||||
uint32_t bzbMagic;
|
||||
uint8_t bzbCluster;
|
||||
uint8_t bzbType;
|
||||
uint16_t bzbBadBlockInode;
|
||||
uint16_t bzbFlags;
|
||||
uint16_t bzbReserved;
|
||||
uint32_t bzbCreationTime;
|
||||
uint32_t bzbMountTime;
|
||||
uint32_t bzbUMountTime;
|
||||
};
|
||||
|
||||
#define APPLE_BZB_MAGIC 0xABADBABE
|
||||
#define APPLE_BZB_TYPEFS 1
|
||||
#define APPLE_BZB_TYPESWAP 3
|
||||
#define APPLE_BZB_ROOTFS 0x8000
|
||||
#define APPLE_BZB_USRFS 0x4000
|
||||
|
||||
/* ------------------------------------------
|
||||
* hp300
|
||||
*
|
||||
*/
|
||||
|
||||
/* volume header for "LIF" format volumes */
|
||||
|
||||
struct hp300_lifvol {
|
||||
int16_t vol_id;
|
||||
char vol_label[6];
|
||||
int32_t vol_addr;
|
||||
int16_t vol_oct;
|
||||
int16_t vol_dummy;
|
||||
int32_t vol_dirsize;
|
||||
int16_t vol_version;
|
||||
int16_t vol_zero;
|
||||
int32_t vol_huh1;
|
||||
int32_t vol_huh2;
|
||||
int32_t vol_length;
|
||||
};
|
||||
|
||||
/* LIF directory entry format */
|
||||
|
||||
struct hp300_lifdir {
|
||||
char dir_name[10];
|
||||
int16_t dir_type;
|
||||
int32_t dir_addr;
|
||||
int32_t dir_length;
|
||||
char dir_toc[6];
|
||||
int16_t dir_flag;
|
||||
int32_t dir_exec;
|
||||
};
|
||||
|
||||
/* load header for boot rom */
|
||||
struct hp300_load {
|
||||
int32_t address;
|
||||
int32_t count;
|
||||
};
|
||||
|
||||
#define HP300_VOL_ID -32768
|
||||
#define HP300_VOL_OCT 4096
|
||||
#define HP300_DIR_TYPE -5822
|
||||
#define HP300_DIR_FLAG 0x8001 /* dont ask me! */
|
||||
#define HP300_SECTSIZE 256
|
||||
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------
|
||||
* x86
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parameters for NetBSD /boot written to start of pbr code by installboot
|
||||
*/
|
||||
|
||||
struct x86_boot_params {
|
||||
uint32_t bp_length; /* length of patchable data */
|
||||
uint32_t bp_flags;
|
||||
uint32_t bp_timeout; /* boot timeout in seconds */
|
||||
uint32_t bp_consdev;
|
||||
uint32_t bp_conspeed;
|
||||
uint8_t bp_password[16]; /* md5 hash of password */
|
||||
char bp_keymap[16]; /* keyboard traslation map */
|
||||
};
|
||||
|
||||
#endif /* !defined(__ASSEMBLER__) */ /* } */
|
||||
|
||||
#define X86_BOOT_MAGIC(n) ('x' << 24 | 0x86b << 12 | 'm' << 4 | (n))
|
||||
#define X86_BOOT_MAGIC_1 X86_BOOT_MAGIC(1) /* pbr.S */
|
||||
#define X86_BOOT_MAGIC_2 X86_BOOT_MAGIC(2) /* bootxx.S */
|
||||
#define X86_BOOT_MAGIC_PXE X86_BOOT_MAGIC(3) /* start_pxe.S */
|
||||
|
||||
/* values for bp_flags */
|
||||
#define X86_BP_FLAGS_RESET_VIDEO 1
|
||||
#define X86_BP_FLAGS_PASSWORD 2
|
||||
|
||||
/* values for bp_consdev */
|
||||
#define X86_BP_CONSDEV_PC 0
|
||||
#define X86_BP_CONSDEV_COM0 1
|
||||
#define X86_BP_CONSDEV_COM1 2
|
||||
#define X86_BP_CONSDEV_COM2 3
|
||||
#define X86_BP_CONSDEV_COM3 4
|
||||
#define X86_BP_CONSDEV_COM0KBD 5
|
||||
#define X86_BP_CONSDEV_COM1KBD 6
|
||||
#define X86_BP_CONSDEV_COM2KBD 7
|
||||
#define X86_BP_CONSDEV_COM3KBD 8
|
||||
|
||||
#if !defined(__ASSEMBLER__) /* { */
|
||||
|
||||
#if 0 /* XXX ffsdrv */
|
||||
/* ------------------------------------------
|
||||
* macppc
|
||||
*/
|
||||
|
||||
#define MACPPC_BOOT_BLOCK_OFFSET 2048
|
||||
#define MACPPC_BOOT_BLOCK_BLOCKSIZE 512
|
||||
#define MACPPC_BOOT_BLOCK_MAX_SIZE 2048 /* XXX: could be up to 6144 */
|
||||
/* Magic string -- 32 bytes long (including the NUL) */
|
||||
#define MACPPC_BBINFO_MAGIC "NetBSD/macppc bootxx 20020515"
|
||||
|
||||
/* ------------------------------------------
|
||||
* news68k, newsmips
|
||||
*/
|
||||
|
||||
#define NEWS_BOOT_BLOCK_LABELOFFSET 64 /* XXX from <machine/disklabel.h> */
|
||||
#define NEWS_BOOT_BLOCK_OFFSET 0
|
||||
#define NEWS_BOOT_BLOCK_BLOCKSIZE 512
|
||||
#define NEWS_BOOT_BLOCK_MAX_SIZE (512 * 16)
|
||||
|
||||
/* Magic string -- 32 bytes long (including the NUL) */
|
||||
#define NEWS68K_BBINFO_MAGIC "NetBSD/news68k bootxx 20020518"
|
||||
#define NEWSMIPS_BBINFO_MAGIC "NetBSD/newsmips bootxx 20020518"
|
||||
|
||||
/* ------------------------------------------
|
||||
* next68k
|
||||
*/
|
||||
|
||||
#define NEXT68K_LABEL_MAXPARTITIONS 8 /* number of partitions in next68k_disklabel */
|
||||
#define NEXT68K_LABEL_CPULBLLEN 24
|
||||
#define NEXT68K_LABEL_MAXDNMLEN 24
|
||||
#define NEXT68K_LABEL_MAXTYPLEN 24
|
||||
#define NEXT68K_LABEL_MAXBFLEN 24
|
||||
#define NEXT68K_LABEL_MAXHNLEN 32
|
||||
#define NEXT68K_LABEL_MAXMPTLEN 16
|
||||
#define NEXT68K_LABEL_MAXFSTLEN 8
|
||||
#define NEXT68K_LABEL_NBAD 1670 /* sized to make label ~= 8KB */
|
||||
|
||||
struct next68k_partition {
|
||||
int32_t cp_offset; /* starting sector */
|
||||
int32_t cp_size; /* number of sectors in partition */
|
||||
int16_t cp_bsize; /* block size in bytes */
|
||||
int16_t cp_fsize; /* filesystem basic fragment size */
|
||||
char cp_opt; /* optimization type: 's'pace/'t'ime */
|
||||
char cp_pad1;
|
||||
int16_t cp_cpg; /* filesystem cylinders per group */
|
||||
int16_t cp_density; /* bytes per inode density */
|
||||
int8_t cp_minfree; /* minfree (%) */
|
||||
int8_t cp_newfs; /* run newfs during init */
|
||||
char cp_mountpt[NEXT68K_LABEL_MAXMPTLEN];
|
||||
/* default/standard mount point */
|
||||
int8_t cp_automnt; /* auto-mount when inserted */
|
||||
char cp_type[NEXT68K_LABEL_MAXFSTLEN]; /* file system type name */
|
||||
char cp_pad2;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* The disklabel the way it is on the disk */
|
||||
struct next68k_disklabel {
|
||||
int32_t cd_version; /* label version */
|
||||
int32_t cd_label_blkno; /* block # of this label */
|
||||
int32_t cd_size; /* size of media area (sectors) */
|
||||
char cd_label[NEXT68K_LABEL_CPULBLLEN]; /* disk name (label) */
|
||||
uint32_t cd_flags; /* flags */
|
||||
uint32_t cd_tag; /* volume tag */
|
||||
char cd_name[NEXT68K_LABEL_MAXDNMLEN]; /* drive (hardware) name */
|
||||
char cd_type[NEXT68K_LABEL_MAXTYPLEN]; /* drive type */
|
||||
int32_t cd_secsize; /* # of bytes per sector */
|
||||
int32_t cd_ntracks; /* # of tracks per cylinder */
|
||||
int32_t cd_nsectors; /* # of data sectors per track */
|
||||
int32_t cd_ncylinders; /* # of data cylinders per unit */
|
||||
int32_t cd_rpm; /* rotational speed */
|
||||
int16_t cd_front; /* # of sectors in "front porch" */
|
||||
int16_t cd_back; /* # of sectors in "back porch" */
|
||||
int16_t cd_ngroups; /* # of alt groups */
|
||||
int16_t cd_ag_size; /* alt group size (sectors) */
|
||||
int16_t cd_ag_alts; /* alternate sectors / alt group */
|
||||
int16_t cd_ag_off; /* sector offset to first alternate */
|
||||
int32_t cd_boot_blkno[2]; /* boot program locations */
|
||||
char cd_kernel[NEXT68K_LABEL_MAXBFLEN]; /* default kernel name */
|
||||
char cd_hostname[NEXT68K_LABEL_MAXHNLEN];
|
||||
/* host name (usu. where disk was labeled) */
|
||||
char cd_rootpartition; /* root partition letter e.g. 'a' */
|
||||
char cd_rwpartition; /* r/w partition letter e.g. 'b' */
|
||||
struct next68k_partition cd_partitions[NEXT68K_LABEL_MAXPARTITIONS];
|
||||
|
||||
union {
|
||||
uint16_t CD_v3_checksum; /* label version 3 checksum */
|
||||
int32_t CD_bad[NEXT68K_LABEL_NBAD];
|
||||
/* block number that is bad */
|
||||
} cd_un;
|
||||
uint16_t cd_checksum; /* label version 1 or 2 checksum */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define NEXT68K_LABEL_cd_checksum cd_checksum
|
||||
#define NEXT68K_LABEL_cd_v3_checksum cd_un.CD_v3_checksum
|
||||
#define NEXT68K_LABEL_cd_bad cd_un.CD_bad
|
||||
|
||||
#define NEXT68K_LABEL_SECTOR 0 /* sector containing label */
|
||||
#define NEXT68K_LABEL_OFFSET 0 /* offset of label in sector */
|
||||
#define NEXT68K_LABEL_SIZE 8192 /* size of label */
|
||||
#define NEXT68K_LABEL_CD_V1 0x4e655854 /* version #1: "NeXT" */
|
||||
#define NEXT68K_LABEL_CD_V2 0x646c5632 /* version #2: "dlV2" */
|
||||
#define NEXT68K_LABEL_CD_V3 0x646c5633 /* version #3: "dlV3" */
|
||||
#define NEXT68K_LABEL_DEFAULTFRONTPORCH (160 * 2)
|
||||
#define NEXT68K_LABEL_DEFAULTBOOT0_1 (32 * 2)
|
||||
#define NEXT68K_LABEL_DEFAULTBOOT0_2 (96 * 2)
|
||||
|
||||
/* ------------------------------------------
|
||||
* pmax --
|
||||
* PMAX (DECstation / MIPS) boot block information
|
||||
*/
|
||||
|
||||
/*
|
||||
* If mode is 0, there is just one sequence of blocks and one Dec_BootMap
|
||||
* is used. If mode is 1, there are multiple sequences of blocks
|
||||
* and multiple Dec_BootMaps are used, the last with numBlocks = 0.
|
||||
*/
|
||||
struct pmax_boot_map {
|
||||
int32_t num_blocks; /* Number of blocks to read. */
|
||||
int32_t start_block; /* Starting block on disk. */
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the structure of a disk or tape boot block. The boot_map
|
||||
* can either be a single boot count and start block (contiguous mode)
|
||||
* or a list of up to 61 (to fill a 512 byte sector) block count and
|
||||
* start block pairs. Under NetBSD, contiguous mode is always used.
|
||||
*/
|
||||
struct pmax_boot_block {
|
||||
uint8_t pad[8];
|
||||
int32_t magic; /* PMAX_BOOT_MAGIC */
|
||||
int32_t mode; /* Mode for boot info. */
|
||||
uint32_t load_addr; /* Address to start loading. */
|
||||
uint32_t exec_addr; /* Address to start execing. */
|
||||
struct pmax_boot_map map[61]; /* boot program section(s). */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define PMAX_BOOT_MAGIC 0x0002757a
|
||||
#define PMAX_BOOTMODE_CONTIGUOUS 0
|
||||
#define PMAX_BOOTMODE_SCATTERED 1
|
||||
|
||||
#define PMAX_BOOT_BLOCK_OFFSET 0
|
||||
#define PMAX_BOOT_BLOCK_BLOCKSIZE 512
|
||||
|
||||
|
||||
/* ------------------------------------------
|
||||
* sparc
|
||||
*/
|
||||
|
||||
#define SPARC_BOOT_BLOCK_OFFSET 512
|
||||
#define SPARC_BOOT_BLOCK_BLOCKSIZE 512
|
||||
#define SPARC_BOOT_BLOCK_MAX_SIZE (512 * 15)
|
||||
/* Magic string -- 32 bytes long (including the NUL) */
|
||||
#define SPARC_BBINFO_MAGIC "NetBSD/sparc bootxx 20020515"
|
||||
|
||||
|
||||
/* ------------------------------------------
|
||||
* sparc64
|
||||
*/
|
||||
|
||||
#define SPARC64_BOOT_BLOCK_OFFSET 512
|
||||
#define SPARC64_BOOT_BLOCK_BLOCKSIZE 512
|
||||
#define SPARC64_BOOT_BLOCK_MAX_SIZE (512 * 15)
|
||||
|
||||
|
||||
/* ------------------------------------------
|
||||
* sun68k (sun2, sun3)
|
||||
*/
|
||||
|
||||
#define SUN68K_BOOT_BLOCK_OFFSET 512
|
||||
#define SUN68K_BOOT_BLOCK_BLOCKSIZE 512
|
||||
#define SUN68K_BOOT_BLOCK_MAX_SIZE (512 * 15)
|
||||
/* Magic string -- 32 bytes long (including the NUL) */
|
||||
#define SUN68K_BBINFO_MAGIC "NetBSD/sun68k bootxx 20020515"
|
||||
|
||||
|
||||
/* ------------------------------------------
|
||||
* vax --
|
||||
* VAX boot block information
|
||||
*/
|
||||
|
||||
struct vax_boot_block {
|
||||
/* Note that these don't overlap any of the pmax boot block */
|
||||
uint8_t pad0[2];
|
||||
uint8_t bb_id_offset; /* offset in words to id (magic1)*/
|
||||
uint8_t bb_mbone; /* must be one */
|
||||
uint16_t bb_lbn_hi; /* lbn (hi word) of bootstrap */
|
||||
uint16_t bb_lbn_low; /* lbn (low word) of bootstrap */
|
||||
uint8_t pad1[332];
|
||||
|
||||
/* The rest of these fields are identification area and describe
|
||||
* the secondary block for uVAX VMB.
|
||||
*/
|
||||
uint8_t bb_magic1; /* magic number */
|
||||
uint8_t bb_mbz1; /* must be zero */
|
||||
uint8_t bb_pad1; /* any value */
|
||||
uint8_t bb_sum1; /* ~(magic1 + mbz1 + pad1) */
|
||||
|
||||
uint8_t bb_mbz2; /* must be zero */
|
||||
uint8_t bb_volinfo; /* volinfo */
|
||||
uint8_t bb_pad2a; /* any value */
|
||||
uint8_t bb_pad2b; /* any value */
|
||||
|
||||
uint32_t bb_size; /* size in blocks of bootstrap */
|
||||
uint32_t bb_load; /* load offset to bootstrap */
|
||||
uint32_t bb_entry; /* byte offset in bootstrap */
|
||||
uint32_t bb_sum3; /* sum of previous 3 fields */
|
||||
|
||||
/* The rest is unused.
|
||||
*/
|
||||
uint8_t pad2[148];
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define VAX_BOOT_MAGIC1 0x18 /* size of BB info? */
|
||||
#define VAX_BOOT_VOLINFO_NONE 0x00 /* no special info */
|
||||
#define VAX_BOOT_VOLINFO_SS 0x01 /* single sided */
|
||||
#define VAX_BOOT_VOLINFO_DS 0x81 /* double sided */
|
||||
|
||||
#define VAX_BOOT_SIZE 15 /* 15 blocks */
|
||||
#define VAX_BOOT_LOAD 0 /* no load offset */
|
||||
#define VAX_BOOT_ENTRY 0x200 /* one block in */
|
||||
|
||||
#define VAX_BOOT_BLOCK_OFFSET 0
|
||||
#define VAX_BOOT_BLOCK_BLOCKSIZE 512
|
||||
|
||||
|
||||
/* ------------------------------------------
|
||||
* x68k
|
||||
*/
|
||||
|
||||
#define X68K_BOOT_BLOCK_OFFSET 0
|
||||
#define X68K_BOOT_BLOCK_BLOCKSIZE 512
|
||||
#define X68K_BOOT_BLOCK_MAX_SIZE (512 * 16)
|
||||
/* Magic string -- 32 bytes long (including the NUL) */
|
||||
#define X68K_BBINFO_MAGIC "NetBSD/x68k bootxx 20020601"
|
||||
|
||||
#endif /* !defined(__ASSEMBLER__) */ /* } */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_BOOTBLOCK_H */
|
@ -1,177 +0,0 @@
|
||||
/* $NetBSD: dinode.h,v 1.18 2003/08/07 16:34:42 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by Marshall
|
||||
* Kirk McKusick and Network Associates Laboratories, the Security
|
||||
* Research Division of Network Associates, Inc. under DARPA/SPAWAR
|
||||
* contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
|
||||
* research program
|
||||
*
|
||||
* Copyright (c) 1982, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dinode.h 8.9 (Berkeley) 3/29/95
|
||||
*/
|
||||
|
||||
#ifndef _UFS_UFS_DINODE_H_
|
||||
#define _UFS_UFS_DINODE_H_
|
||||
|
||||
#include "type.h"
|
||||
|
||||
/*
|
||||
* The root inode is the root of the file system. Inode 0 can't be used for
|
||||
* normal purposes and historically bad blocks were linked to inode 1, thus
|
||||
* the root inode is 2. (Inode 1 is no longer used for this purpose, however
|
||||
* numerous dump tapes make this assumption, so we are stuck with it).
|
||||
*/
|
||||
#define ROOTINO ((ino_t)2)
|
||||
|
||||
/*
|
||||
* The Whiteout inode# is a dummy non-zero inode number which will
|
||||
* never be allocated to a real file. It is used as a place holder
|
||||
* in the directory entry which has been tagged as a DT_W entry.
|
||||
* See the comments about ROOTINO above.
|
||||
*/
|
||||
#define WINO ((ino_t)1)
|
||||
|
||||
/*
|
||||
* A dinode contains all the meta-data associated with a UFS file.
|
||||
* This structure defines the on-disk format of a dinode. Since
|
||||
* this structure describes an on-disk structure, all its fields
|
||||
* are defined by types with precise widths.
|
||||
*/
|
||||
|
||||
#define NXADDR 2
|
||||
#define NDADDR 12 /* Direct addresses in inode. */
|
||||
#define NIADDR 3 /* Indirect addresses in inode. */
|
||||
|
||||
struct ufs1_dinode {
|
||||
u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
|
||||
int16_t di_nlink; /* 2: File link count. */
|
||||
union {
|
||||
u_int16_t oldids[2]; /* 4: Ffs: old user and group ids. */
|
||||
u_int32_t inumber; /* 4: Lfs: inode number. */
|
||||
} di_u;
|
||||
u_int64_t di_size; /* 8: File byte count. */
|
||||
int32_t di_atime; /* 16: Last access time. */
|
||||
int32_t di_atimensec; /* 20: Last access time. */
|
||||
int32_t di_mtime; /* 24: Last modified time. */
|
||||
int32_t di_mtimensec; /* 28: Last modified time. */
|
||||
int32_t di_ctime; /* 32: Last inode change time. */
|
||||
int32_t di_ctimensec; /* 36: Last inode change time. */
|
||||
int32_t di_db[NDADDR]; /* 40: Direct disk blocks. */
|
||||
int32_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */
|
||||
u_int32_t di_flags; /* 100: Status flags (chflags). */
|
||||
u_int32_t di_blocks; /* 104: Blocks actually held. */
|
||||
int32_t di_gen; /* 108: Generation number. */
|
||||
u_int32_t di_uid; /* 112: File owner. */
|
||||
u_int32_t di_gid; /* 116: File group. */
|
||||
int32_t di_spare[2]; /* 120: Reserved; currently unused */
|
||||
};
|
||||
|
||||
struct ufs2_dinode {
|
||||
u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
|
||||
int16_t di_nlink; /* 2: File link count. */
|
||||
u_int32_t di_uid; /* 4: File owner. */
|
||||
u_int32_t di_gid; /* 8: File group. */
|
||||
u_int32_t di_blksize; /* 12: Inode blocksize. */
|
||||
u_int64_t di_size; /* 16: File byte count. */
|
||||
u_int64_t di_blocks; /* 24: Bytes actually held. */
|
||||
int64_t di_atime; /* 32: Last access time. */
|
||||
int64_t di_mtime; /* 40: Last modified time. */
|
||||
int64_t di_ctime; /* 48: Last inode change time. */
|
||||
int64_t di_birthtime; /* 56: Inode creation time. */
|
||||
int32_t di_mtimensec; /* 64: Last modified time. */
|
||||
int32_t di_atimensec; /* 68: Last access time. */
|
||||
int32_t di_ctimensec; /* 72: Last inode change time. */
|
||||
int32_t di_birthnsec; /* 76: Inode creation time. */
|
||||
int32_t di_gen; /* 80: Generation number. */
|
||||
u_int32_t di_kernflags; /* 84: Kernel flags. */
|
||||
u_int32_t di_flags; /* 88: Status flags (chflags). */
|
||||
int32_t di_extsize; /* 92: External attributes block. */
|
||||
int64_t di_extb[NXADDR];/* 96: External attributes block. */
|
||||
int64_t di_db[NDADDR]; /* 112: Direct disk blocks. */
|
||||
int64_t di_ib[NIADDR]; /* 208: Indirect disk blocks. */
|
||||
int64_t di_spare[3]; /* 232: Reserved; currently unused */
|
||||
};
|
||||
|
||||
/*
|
||||
* The di_db fields may be overlaid with other information for
|
||||
* file types that do not have associated disk storage. Block
|
||||
* and character devices overlay the first data block with their
|
||||
* dev_t value. Short symbolic links place their path in the
|
||||
* di_db area.
|
||||
*/
|
||||
#define di_inumber di_u.inumber
|
||||
#define di_ogid di_u.oldids[1]
|
||||
#define di_ouid di_u.oldids[0]
|
||||
#define di_rdev di_db[0]
|
||||
#define MAXSYMLINKLEN_UFS1 ((NDADDR + NIADDR) * sizeof(int32_t))
|
||||
#define MAXSYMLINKLEN_UFS2 ((NDADDR + NIADDR) * sizeof(int64_t))
|
||||
|
||||
#define MAXSYMLINKLEN(ip) \
|
||||
((ip)->i_ump->um_fstype == UFS1) ? \
|
||||
MAXSYMLINKLEN_UFS1 : MAXSYMLINKLEN_UFS2
|
||||
|
||||
/* NeXT used to keep short symlinks in the inode even when using
|
||||
* FS_42INODEFMT. In that case fs->fs_maxsymlinklen is probably -1,
|
||||
* but short symlinks were stored in inodes shorter than this:
|
||||
*/
|
||||
#define APPLEUFS_MAXSYMLINKLEN 60
|
||||
|
||||
/* File permissions. */
|
||||
#define IEXEC 0000100 /* Executable. */
|
||||
#define IWRITE 0000200 /* Writable. */
|
||||
#define IREAD 0000400 /* Readable. */
|
||||
#define ISVTX 0001000 /* Sticky bit. */
|
||||
#define ISGID 0002000 /* Set-gid. */
|
||||
#define ISUID 0004000 /* Set-uid. */
|
||||
|
||||
/* File types. */
|
||||
#define IFMT 0170000 /* Mask of file type. */
|
||||
#define IFIFO 0010000 /* Named pipe (fifo). */
|
||||
#define IFCHR 0020000 /* Character device. */
|
||||
#define IFDIR 0040000 /* Directory file. */
|
||||
#define IFBLK 0060000 /* Block device. */
|
||||
#define IFREG 0100000 /* Regular file. */
|
||||
#define IFLNK 0120000 /* Symbolic link. */
|
||||
#define IFSOCK 0140000 /* UNIX domain socket. */
|
||||
#define IFWHT 0160000 /* Whiteout. */
|
||||
|
||||
/* Size of the on-disk inode. */
|
||||
#define DINODE1_SIZE (sizeof(struct ufs1_dinode)) /* 128 */
|
||||
#define DINODE2_SIZE (sizeof(struct ufs2_dinode))
|
||||
|
||||
#endif /* !_UFS_UFS_DINODE_H_ */
|
@ -1,162 +0,0 @@
|
||||
/* $NetBSD: dir.h,v 1.17 2003/08/07 16:34:42 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)dir.h 8.5 (Berkeley) 4/27/95
|
||||
*/
|
||||
|
||||
#ifndef _UFS_UFS_DIR_H_
|
||||
#define _UFS_UFS_DIR_H_
|
||||
|
||||
#include "type.h"
|
||||
|
||||
/*
|
||||
* Theoretically, directories can be more than 2Gb in length, however, in
|
||||
* practice this seems unlikely. So, we define the type doff_t as a 32-bit
|
||||
* quantity to keep down the cost of doing lookup on a 32-bit machine.
|
||||
*/
|
||||
#define doff_t int32_t
|
||||
#define MAXDIRSIZE (0x7fffffff)
|
||||
|
||||
/*
|
||||
* A directory consists of some number of blocks of DIRBLKSIZ
|
||||
* bytes, where DIRBLKSIZ is chosen such that it can be transferred
|
||||
* to disk in a single atomic operation (e.g. 512 bytes on most machines).
|
||||
*
|
||||
* Each DIRBLKSIZ byte block contains some number of directory entry
|
||||
* structures, which are of variable length. Each directory entry has
|
||||
* a struct direct at the front of it, containing its inode number,
|
||||
* the length of the entry, and the length of the name contained in
|
||||
* the entry. These are followed by the name padded to a 4 byte boundary.
|
||||
* All names are guaranteed null terminated.
|
||||
* The maximum length of a name in a directory is MAXNAMLEN.
|
||||
*
|
||||
* The macro DIRSIZ(fmt, dp) gives the amount of space required to represent
|
||||
* a directory entry. Free space in a directory is represented by
|
||||
* entries which have dp->d_reclen > DIRSIZ(fmt, dp). All DIRBLKSIZ bytes
|
||||
* in a directory block are claimed by the directory entries. This
|
||||
* usually results in the last entry in a directory having a large
|
||||
* dp->d_reclen. When entries are deleted from a directory, the
|
||||
* space is returned to the previous entry in the same directory
|
||||
* block by increasing its dp->d_reclen. If the first entry of
|
||||
* a directory block is free, then its dp->d_ino is set to 0.
|
||||
* Entries other than the first in a directory do not normally have
|
||||
* dp->d_ino set to 0.
|
||||
*/
|
||||
#undef DIRBLKSIZ
|
||||
#define DIRBLKSIZ DEV_BSIZE
|
||||
#undef MAXNAMLEN
|
||||
#define MAXNAMLEN 255
|
||||
#define APPLEUFS_DIRBLKSIZ 1024
|
||||
|
||||
struct direct {
|
||||
u_int32_t d_ino; /* inode number of entry */
|
||||
u_int16_t d_reclen; /* length of this record */
|
||||
u_int8_t d_type; /* file type, see below */
|
||||
u_int8_t d_namlen; /* length of string in d_name */
|
||||
char d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
|
||||
};
|
||||
|
||||
/*
|
||||
* File types
|
||||
*/
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_FIFO 1
|
||||
#define DT_CHR 2
|
||||
#define DT_DIR 4
|
||||
#define DT_BLK 6
|
||||
#define DT_REG 8
|
||||
#define DT_LNK 10
|
||||
#define DT_SOCK 12
|
||||
#define DT_WHT 14
|
||||
|
||||
/*
|
||||
* Convert between stat structure types and directory types.
|
||||
*/
|
||||
#define IFTODT(mode) (((mode) & 0170000) >> 12)
|
||||
#define DTTOIF(dirtype) ((dirtype) << 12)
|
||||
|
||||
/*
|
||||
* The DIRSIZ macro gives the minimum record length which will hold
|
||||
* the directory entry. This requires the amount of space in struct direct
|
||||
* without the d_name field, plus enough space for the name with a terminating
|
||||
* null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
|
||||
*/
|
||||
#define DIRECTSIZ(namlen) \
|
||||
((sizeof(struct direct) - (MAXNAMLEN+1)) + (((namlen)+1 + 3) &~ 3))
|
||||
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
#define DIRSIZ(oldfmt, dp, needswap) \
|
||||
(((oldfmt) && !(needswap)) ? \
|
||||
DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
|
||||
#else
|
||||
#define DIRSIZ(oldfmt, dp, needswap) \
|
||||
(((oldfmt) && (needswap)) ? \
|
||||
DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
|
||||
#endif
|
||||
|
||||
#define OLDDIRFMT 1
|
||||
#define NEWDIRFMT 0
|
||||
|
||||
/*
|
||||
* Template for manipulating directories. Should use struct direct's,
|
||||
* but the name field is MAXNAMLEN - 1, and this just won't do.
|
||||
*/
|
||||
struct dirtemplate {
|
||||
u_int32_t dot_ino;
|
||||
int16_t dot_reclen;
|
||||
u_int8_t dot_type;
|
||||
u_int8_t dot_namlen;
|
||||
char dot_name[4]; /* must be multiple of 4 */
|
||||
u_int32_t dotdot_ino;
|
||||
int16_t dotdot_reclen;
|
||||
u_int8_t dotdot_type;
|
||||
u_int8_t dotdot_namlen;
|
||||
char dotdot_name[4]; /* ditto */
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the old format of directories, sanz type element.
|
||||
*/
|
||||
struct odirtemplate {
|
||||
u_int32_t dot_ino;
|
||||
int16_t dot_reclen;
|
||||
u_int16_t dot_namlen;
|
||||
char dot_name[4]; /* must be multiple of 4 */
|
||||
u_int32_t dotdot_ino;
|
||||
int16_t dotdot_reclen;
|
||||
u_int16_t dotdot_namlen;
|
||||
char dotdot_name[4]; /* ditto */
|
||||
};
|
||||
#endif /* !_UFS_UFS_DIR_H_ */
|
@ -1,555 +0,0 @@
|
||||
/* $NetBSD: disklabel.h,v 1.88 2003/11/14 12:07:42 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)disklabel.h 8.2 (Berkeley) 7/10/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_DISKLABEL_H_
|
||||
#define _SYS_DISKLABEL_H_
|
||||
|
||||
#include "type.h"
|
||||
|
||||
/*
|
||||
* We need <machine/types.h> for __HAVE_OLD_DISKLABEL
|
||||
*/
|
||||
#if 0 /* XXX ffsdrv */
|
||||
#ifndef _LOCORE
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* sys/arch/i386/include/type.h XXX ffsdrv */
|
||||
#define __HAVE_OLD_DISKLABEL
|
||||
|
||||
/*
|
||||
* Each disk has a label which includes information about the hardware
|
||||
* disk geometry, filesystem partitions, and drive specific information.
|
||||
* The location of the label, as well as the number of partitions the
|
||||
* label can describe and the number of the "whole disk" (raw)
|
||||
* paritition are machine dependent.
|
||||
*/
|
||||
#if 0 /* XXX ffsdrv */
|
||||
#include <machine/disklabel.h>
|
||||
#endif
|
||||
|
||||
/* arch/i386/include/disklabel.h */
|
||||
#define LABELSECTOR 1 /* sector containing label */
|
||||
#define LABELOFFSET 0 /* offset of label in sector */
|
||||
#define MAXPARTITIONS 16 /* number of partitions */
|
||||
#define OLDMAXPARTITIONS 8 /* number of partitions before 1.6 */
|
||||
#define RAW_PART 3 /* raw partition: XX?d (XXX) */
|
||||
|
||||
/*
|
||||
* We use the highest bit of the minor number for the partition number.
|
||||
* This maintains backward compatibility with device nodes created before
|
||||
* MAXPARTITIONS was increased.
|
||||
*/
|
||||
#define __I386_MAXDISKS ((1 << 20) / MAXPARTITIONS)
|
||||
#define DISKUNIT(dev) ((minor(dev) / OLDMAXPARTITIONS) % __I386_MAXDISKS)
|
||||
#define DISKPART(dev) ((minor(dev) % OLDMAXPARTITIONS) + \
|
||||
((minor(dev) / (__I386_MAXDISKS * OLDMAXPARTITIONS)) * OLDMAXPARTITIONS))
|
||||
#define DISKMINOR(unit, part) \
|
||||
(((unit) * OLDMAXPARTITIONS) + ((part) % OLDMAXPARTITIONS) + \
|
||||
((part) / OLDMAXPARTITIONS) * (__I386_MAXDISKS * OLDMAXPARTITIONS))
|
||||
|
||||
/* Pull in MBR partition definitions. */
|
||||
#include "bootblock.h"
|
||||
|
||||
/* end of arch/i386/include/disklabel.h */
|
||||
|
||||
|
||||
/*
|
||||
* The absolute maximum number of disk partitions allowed.
|
||||
* This is the maximum value of MAXPARTITIONS for which 'struct disklabel'
|
||||
* is <= DEV_BSIZE bytes long. If MAXPARTITIONS is greater than this, beware.
|
||||
*/
|
||||
#define MAXMAXPARTITIONS 22
|
||||
#if MAXPARTITIONS > MAXMAXPARTITIONS
|
||||
#warning beware: MAXPARTITIONS bigger than MAXMAXPARTITIONS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ports can switch their MAXPARTITIONS once, as follows:
|
||||
*
|
||||
* - define OLDMAXPARTITIONS in <machine/disklabel.h> as the old number
|
||||
* - define MAXPARTITIONS as the new number
|
||||
* - define DISKUNIT, DISKPART and DISKMINOR macros in <machine/disklabel.h>
|
||||
* as appropriate for the port (see the i386 one for an example).
|
||||
* - define __HAVE_OLD_DISKLABEL in <machine/types.h>
|
||||
*/
|
||||
|
||||
#if defined(_KERNEL) && defined(__HAVE_OLD_DISKLABEL) && \
|
||||
(MAXPARTITIONS < OLDMAXPARTITIONS)
|
||||
#error "can only grow disklabel size"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Translate between device numbers and major/disk unit/disk partition.
|
||||
*/
|
||||
#ifndef __HAVE_OLD_DISKLABEL
|
||||
#define DISKUNIT(dev) (minor(dev) / MAXPARTITIONS)
|
||||
#define DISKPART(dev) (minor(dev) % MAXPARTITIONS)
|
||||
#define DISKMINOR(unit, part) \
|
||||
(((unit) * MAXPARTITIONS) + (part))
|
||||
#endif
|
||||
#define MAKEDISKDEV(maj, unit, part) \
|
||||
(makedev((maj), DISKMINOR((unit), (part))))
|
||||
|
||||
#define DISKMAGIC ((u_int32_t)0x82564557) /* The disk magic number */
|
||||
|
||||
#ifndef _LOCORE
|
||||
struct disklabel {
|
||||
u_int32_t d_magic; /* the magic number */
|
||||
u_int16_t d_type; /* drive type */
|
||||
u_int16_t d_subtype; /* controller/d_type specific */
|
||||
char d_typename[16]; /* type name, e.g. "eagle" */
|
||||
|
||||
/*
|
||||
* d_packname contains the pack identifier and is returned when
|
||||
* the disklabel is read off the disk or in-core copy.
|
||||
* d_boot0 and d_boot1 are the (optional) names of the
|
||||
* primary (block 0) and secondary (block 1-15) bootstraps
|
||||
* as found in /usr/mdec. These are returned when using
|
||||
* getdiskbyname(3) to retrieve the values from /etc/disktab.
|
||||
*/
|
||||
union {
|
||||
char un_d_packname[16]; /* pack identifier */
|
||||
struct {
|
||||
char *un_d_boot0; /* primary bootstrap name */
|
||||
char *un_d_boot1; /* secondary bootstrap name */
|
||||
} un_b;
|
||||
} d_un;
|
||||
#define d_packname d_un.un_d_packname
|
||||
#define d_boot0 d_un.un_b.un_d_boot0
|
||||
#define d_boot1 d_un.un_b.un_d_boot1
|
||||
|
||||
/* disk geometry: */
|
||||
u_int32_t d_secsize; /* # of bytes per sector */
|
||||
u_int32_t d_nsectors; /* # of data sectors per track */
|
||||
u_int32_t d_ntracks; /* # of tracks per cylinder */
|
||||
u_int32_t d_ncylinders; /* # of data cylinders per unit */
|
||||
u_int32_t d_secpercyl; /* # of data sectors per cylinder */
|
||||
u_int32_t d_secperunit; /* # of data sectors per unit */
|
||||
|
||||
/*
|
||||
* Spares (bad sector replacements) below are not counted in
|
||||
* d_nsectors or d_secpercyl. Spare sectors are assumed to
|
||||
* be physical sectors which occupy space at the end of each
|
||||
* track and/or cylinder.
|
||||
*/
|
||||
u_int16_t d_sparespertrack; /* # of spare sectors per track */
|
||||
u_int16_t d_sparespercyl; /* # of spare sectors per cylinder */
|
||||
/*
|
||||
* Alternative cylinders include maintenance, replacement,
|
||||
* configuration description areas, etc.
|
||||
*/
|
||||
u_int32_t d_acylinders; /* # of alt. cylinders per unit */
|
||||
|
||||
/* hardware characteristics: */
|
||||
/*
|
||||
* d_interleave, d_trackskew and d_cylskew describe perturbations
|
||||
* in the media format used to compensate for a slow controller.
|
||||
* Interleave is physical sector interleave, set up by the
|
||||
* formatter or controller when formatting. When interleaving is
|
||||
* in use, logically adjacent sectors are not physically
|
||||
* contiguous, but instead are separated by some number of
|
||||
* sectors. It is specified as the ratio of physical sectors
|
||||
* traversed per logical sector. Thus an interleave of 1:1
|
||||
* implies contiguous layout, while 2:1 implies that logical
|
||||
* sector 0 is separated by one sector from logical sector 1.
|
||||
* d_trackskew is the offset of sector 0 on track N relative to
|
||||
* sector 0 on track N-1 on the same cylinder. Finally, d_cylskew
|
||||
* is the offset of sector 0 on cylinder N relative to sector 0
|
||||
* on cylinder N-1.
|
||||
*/
|
||||
u_int16_t d_rpm; /* rotational speed */
|
||||
u_int16_t d_interleave; /* hardware sector interleave */
|
||||
u_int16_t d_trackskew; /* sector 0 skew, per track */
|
||||
u_int16_t d_cylskew; /* sector 0 skew, per cylinder */
|
||||
u_int32_t d_headswitch; /* head switch time, usec */
|
||||
u_int32_t d_trkseek; /* track-to-track seek, usec */
|
||||
u_int32_t d_flags; /* generic flags */
|
||||
#define NDDATA 5
|
||||
u_int32_t d_drivedata[NDDATA]; /* drive-type specific information */
|
||||
#define NSPARE 5
|
||||
u_int32_t d_spare[NSPARE]; /* reserved for future use */
|
||||
u_int32_t d_magic2; /* the magic number (again) */
|
||||
u_int16_t d_checksum; /* xor of data incl. partitions */
|
||||
|
||||
/* filesystem and partition information: */
|
||||
u_int16_t d_npartitions; /* number of partitions in following */
|
||||
u_int32_t d_bbsize; /* size of boot area at sn0, bytes */
|
||||
u_int32_t d_sbsize; /* max size of fs superblock, bytes */
|
||||
struct partition { /* the partition table */
|
||||
u_int32_t p_size; /* number of sectors in partition */
|
||||
u_int32_t p_offset; /* starting sector */
|
||||
union {
|
||||
u_int32_t fsize; /* FFS, ADOS:
|
||||
filesystem basic fragment size */
|
||||
u_int32_t cdsession; /* ISO9660: session offset */
|
||||
} __partition_u2;
|
||||
#define p_fsize __partition_u2.fsize
|
||||
#define p_cdsession __partition_u2.cdsession
|
||||
u_int8_t p_fstype; /* filesystem type, see below */
|
||||
u_int8_t p_frag; /* filesystem fragments per block */
|
||||
union {
|
||||
u_int16_t cpg; /* UFS: FS cylinders per group */
|
||||
u_int16_t sgs; /* LFS: FS segment shift */
|
||||
} __partition_u1;
|
||||
#define p_cpg __partition_u1.cpg
|
||||
#define p_sgs __partition_u1.sgs
|
||||
} d_partitions[MAXPARTITIONS]; /* actually may be more */
|
||||
};
|
||||
|
||||
#ifdef __HAVE_OLD_DISKLABEL
|
||||
/*
|
||||
* Same as above, but with OLDMAXPARTITIONS partitions. For use in
|
||||
* the old DIOC* ioctl calls.
|
||||
*/
|
||||
struct olddisklabel {
|
||||
u_int32_t d_magic;
|
||||
u_int16_t d_type;
|
||||
u_int16_t d_subtype;
|
||||
char d_typename[16];
|
||||
union {
|
||||
char un_d_packname[16];
|
||||
struct {
|
||||
char *un_d_boot0;
|
||||
char *un_d_boot1;
|
||||
} un_b;
|
||||
} d_un;
|
||||
u_int32_t d_secsize;
|
||||
u_int32_t d_nsectors;
|
||||
u_int32_t d_ntracks;
|
||||
u_int32_t d_ncylinders;
|
||||
u_int32_t d_secpercyl;
|
||||
u_int32_t d_secperunit;
|
||||
u_int16_t d_sparespertrack;
|
||||
u_int16_t d_sparespercyl;
|
||||
u_int32_t d_acylinders;
|
||||
u_int16_t d_rpm;
|
||||
u_int16_t d_interleave;
|
||||
u_int16_t d_trackskew;
|
||||
u_int16_t d_cylskew;
|
||||
u_int32_t d_headswitch;
|
||||
u_int32_t d_trkseek;
|
||||
u_int32_t d_flags;
|
||||
u_int32_t d_drivedata[NDDATA];
|
||||
u_int32_t d_spare[NSPARE];
|
||||
u_int32_t d_magic2;
|
||||
u_int16_t d_checksum;
|
||||
u_int16_t d_npartitions;
|
||||
u_int32_t d_bbsize;
|
||||
u_int32_t d_sbsize;
|
||||
struct opartition {
|
||||
u_int32_t p_size;
|
||||
u_int32_t p_offset;
|
||||
union {
|
||||
u_int32_t fsize;
|
||||
u_int32_t cdsession;
|
||||
} __partition_u2;
|
||||
u_int8_t p_fstype;
|
||||
u_int8_t p_frag;
|
||||
union {
|
||||
u_int16_t cpg;
|
||||
u_int16_t sgs;
|
||||
} __partition_u1;
|
||||
} d_partitions[OLDMAXPARTITIONS];
|
||||
};
|
||||
#endif /* __HAVE_OLD_DISKLABEL */
|
||||
#else /* _LOCORE */
|
||||
/*
|
||||
* offsets for asm boot files.
|
||||
*/
|
||||
.set d_secsize,40
|
||||
.set d_nsectors,44
|
||||
.set d_ntracks,48
|
||||
.set d_ncylinders,52
|
||||
.set d_secpercyl,56
|
||||
.set d_secperunit,60
|
||||
.set d_end_,276 /* size of disk label */
|
||||
#endif /* _LOCORE */
|
||||
|
||||
/* d_type values: */
|
||||
#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
|
||||
#define DTYPE_MSCP 2 /* MSCP */
|
||||
#define DTYPE_DEC 3 /* other DEC (rk, rl) */
|
||||
#define DTYPE_SCSI 4 /* SCSI */
|
||||
#define DTYPE_ESDI 5 /* ESDI interface */
|
||||
#define DTYPE_ST506 6 /* ST506 etc. */
|
||||
#define DTYPE_HPIB 7 /* CS/80 on HP-IB */
|
||||
#define DTYPE_HPFL 8 /* HP Fiber-link */
|
||||
#define DTYPE_FLOPPY 10 /* floppy */
|
||||
#define DTYPE_CCD 11 /* concatenated disk device */
|
||||
#define DTYPE_VND 12 /* vnode pseudo-disk */
|
||||
#define DTYPE_ATAPI 13 /* ATAPI */
|
||||
#define DTYPE_RAID 14 /* RAIDframe */
|
||||
#define DTYPE_LD 15 /* logical disk */
|
||||
#define DTYPE_JFS2 16 /* IBM JFS2 */
|
||||
#define DTYPE_CGD 17 /* cryptographic pseudo-disk */
|
||||
#define DTYPE_VINUM 18 /* vinum volume */
|
||||
|
||||
#ifdef DKTYPENAMES
|
||||
static const char *const dktypenames[] = {
|
||||
"unknown",
|
||||
"SMD",
|
||||
"MSCP",
|
||||
"old DEC",
|
||||
"SCSI",
|
||||
"ESDI",
|
||||
"ST506",
|
||||
"HP-IB",
|
||||
"HP-FL",
|
||||
"type 9",
|
||||
"floppy",
|
||||
"ccd",
|
||||
"vnd",
|
||||
"ATAPI",
|
||||
"RAID",
|
||||
"ld",
|
||||
"jfs",
|
||||
"cgd",
|
||||
"vinum",
|
||||
NULL
|
||||
};
|
||||
#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Filesystem type and version.
|
||||
* Used to interpret other filesystem-specific
|
||||
* per-partition information.
|
||||
*
|
||||
* These are used only for COMPAT_09 support.
|
||||
*/
|
||||
#define FS_UNUSED 0 /* unused */
|
||||
#define FS_SWAP 1 /* swap */
|
||||
#define FS_V6 2 /* Sixth Edition */
|
||||
#define FS_V7 3 /* Seventh Edition */
|
||||
#define FS_SYSV 4 /* System V */
|
||||
#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
|
||||
#define FS_V8 6 /* Eighth Edition, 4K blocks */
|
||||
#define FS_BSDFFS 7 /* 4.2BSD fast file system */
|
||||
#define FS_MSDOS 8 /* MSDOS file system */
|
||||
#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */
|
||||
#define FS_OTHER 10 /* in use, but unknown/unsupported */
|
||||
#define FS_HPFS 11 /* OS/2 high-performance file system */
|
||||
#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */
|
||||
#define FS_BOOT 13 /* partition contains bootstrap */
|
||||
#define FS_ADOS 14 /* AmigaDOS fast file system */
|
||||
#define FS_HFS 15 /* Macintosh HFS */
|
||||
#define FS_FILECORE 16 /* Acorn Filecore Filing System */
|
||||
#define FS_EX2FS 17 /* Linux Extended 2 file system */
|
||||
#define FS_NTFS 18 /* Windows/NT file system */
|
||||
#define FS_RAID 19 /* RAIDframe component */
|
||||
#define FS_CCD 20 /* concatenated disk component */
|
||||
#define FS_JFS2 21 /* IBM JFS2 */
|
||||
#define FS_APPLEUFS 22 /* Apple UFS */
|
||||
/* XXX this is not the same as FreeBSD. How to solve? */
|
||||
#define FS_VINUM 23 /* Vinum */
|
||||
|
||||
/* Adjust the FSMAXTYPES def below if you add something after APPLEUFS */
|
||||
|
||||
#ifdef FSTYPENAMES
|
||||
static const char *const fstypenames[] = {
|
||||
"unused",
|
||||
"swap",
|
||||
"Version 6",
|
||||
"Version 7",
|
||||
"System V",
|
||||
"4.1BSD",
|
||||
"Eighth Edition",
|
||||
"4.2BSD",
|
||||
"MSDOS",
|
||||
"4.4LFS",
|
||||
"unknown",
|
||||
"HPFS",
|
||||
"ISO9660",
|
||||
"boot",
|
||||
"ADOS",
|
||||
"HFS",
|
||||
"FILECORE",
|
||||
"Linux Ext2",
|
||||
"NTFS",
|
||||
"RAID",
|
||||
"ccd",
|
||||
"jfs",
|
||||
"Apple UFS",
|
||||
"vinum",
|
||||
NULL
|
||||
};
|
||||
#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
|
||||
#else
|
||||
#define FSMAXTYPES (FS_VINUM + 1)
|
||||
#endif
|
||||
|
||||
#ifdef FSCKNAMES
|
||||
/* These are the names MOUNT_XXX from <sys/mount.h> */
|
||||
static const char *const fscknames[] = {
|
||||
NULL, /* unused */
|
||||
NULL, /* swap */
|
||||
NULL, /* Version 6 */
|
||||
NULL, /* Version 7 */
|
||||
NULL, /* System V */
|
||||
NULL, /* 4.1BSD */
|
||||
NULL, /* Eighth edition */
|
||||
"ffs", /* 4.2BSD */
|
||||
"msdos", /* MSDOS */
|
||||
"lfs", /* 4.4LFS */
|
||||
NULL, /* unknown */
|
||||
NULL, /* HPFS */
|
||||
NULL, /* ISO9660 */
|
||||
NULL, /* boot */
|
||||
NULL, /* ADOS */
|
||||
NULL, /* HFS */
|
||||
NULL, /* FILECORE */
|
||||
"ext2fs", /* Linux Ext2 */
|
||||
NULL, /* Windows/NT */
|
||||
NULL, /* RAID Component */
|
||||
NULL, /* concatenated disk component */
|
||||
NULL, /* IBM JFS2 */
|
||||
"ffs", /* Apple UFS */
|
||||
NULL /* NULL */
|
||||
};
|
||||
#define FSMAXNAMES (sizeof(fscknames) / sizeof(fscknames[0]) - 1)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MOUNTNAMES
|
||||
/* These are the names MOUNT_XXX from <sys/mount.h> */
|
||||
static const char *const mountnames[] = {
|
||||
NULL, /* unused */
|
||||
NULL, /* swap */
|
||||
NULL, /* Version 6 */
|
||||
NULL, /* Version 7 */
|
||||
NULL, /* System V */
|
||||
NULL, /* 4.1BSD */
|
||||
NULL, /* Eighth edition */
|
||||
"ffs", /* 4.2BSD */
|
||||
"msdos", /* MSDOS */
|
||||
"lfs", /* 4.4LFS */
|
||||
NULL, /* unknown */
|
||||
NULL, /* HPFS */
|
||||
"cd9660", /* ISO9660 */
|
||||
NULL, /* boot */
|
||||
"ados", /* ADOS */
|
||||
NULL, /* HFS */
|
||||
"filecore", /* FILECORE */
|
||||
"ext2fs", /* Linux Ext2 */
|
||||
"ntfs", /* Windows/NT */
|
||||
NULL, /* RAID Component */
|
||||
NULL, /* concatenated disk component */
|
||||
NULL, /* IBM JFS2 */
|
||||
"ffs", /* Apple UFS */
|
||||
NULL /* NULL */
|
||||
};
|
||||
#define FSMAXMOUNTNAMES (sizeof(mountnames) / sizeof(mountnames[0]) - 1)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* flags shared by various drives:
|
||||
*/
|
||||
#define D_REMOVABLE 0x01 /* removable media */
|
||||
#define D_ECC 0x02 /* supports ECC */
|
||||
#define D_BADSECT 0x04 /* supports bad sector forw. */
|
||||
#define D_RAMDISK 0x08 /* disk emulator */
|
||||
#define D_CHAIN 0x10 /* can do back-back transfers */
|
||||
|
||||
/*
|
||||
* Drive data for SMD.
|
||||
*/
|
||||
#define d_smdflags d_drivedata[0]
|
||||
#define D_SSE 0x1 /* supports skip sectoring */
|
||||
#define d_mindist d_drivedata[1]
|
||||
#define d_maxdist d_drivedata[2]
|
||||
#define d_sdist d_drivedata[3]
|
||||
|
||||
/*
|
||||
* Drive data for ST506.
|
||||
*/
|
||||
#define d_precompcyl d_drivedata[0]
|
||||
#define d_gap3 d_drivedata[1] /* used only when formatting */
|
||||
|
||||
/*
|
||||
* Drive data for SCSI.
|
||||
*/
|
||||
#define d_blind d_drivedata[0]
|
||||
|
||||
#ifndef _LOCORE
|
||||
/*
|
||||
* Structure used to perform a format or other raw operation,
|
||||
* returning data and/or register values. Register identification
|
||||
* and format are device- and driver-dependent. Currently unused.
|
||||
*/
|
||||
struct format_op {
|
||||
char *df_buf;
|
||||
int df_count; /* value-result */
|
||||
daddr_t df_startblk;
|
||||
int df_reg[8]; /* result */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used internally to retrieve information about a partition
|
||||
* on a disk.
|
||||
*/
|
||||
struct partinfo {
|
||||
struct disklabel *disklab;
|
||||
struct partition *part;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct disk;
|
||||
|
||||
void diskerr __P((const struct buf *, const char *, const char *, int,
|
||||
int, const struct disklabel *));
|
||||
u_int dkcksum __P((struct disklabel *));
|
||||
int setdisklabel __P((struct disklabel *, struct disklabel *, u_long,
|
||||
struct cpu_disklabel *));
|
||||
const char *readdisklabel __P((dev_t, void (*)(struct buf *),
|
||||
struct disklabel *, struct cpu_disklabel *));
|
||||
int writedisklabel __P((dev_t, void (*)(struct buf *), struct disklabel *,
|
||||
struct cpu_disklabel *));
|
||||
int bounds_check_with_label __P((struct disk *, struct buf *, int));
|
||||
int bounds_check_with_mediasize __P((struct buf *, int, u_int64_t));
|
||||
#endif
|
||||
#endif /* _LOCORE */
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_LOCORE)
|
||||
|
||||
#if 0 /* XXX ffsdrv */
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_DISKLABEL_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,697 +0,0 @@
|
||||
/* $NetBSD: fs.h,v 1.43 2004/03/21 18:48:24 dsl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)fs.h 8.13 (Berkeley) 3/21/95
|
||||
*/
|
||||
|
||||
#ifndef _UFS_FFS_FS_H_
|
||||
#define _UFS_FFS_FS_H_
|
||||
|
||||
#include "type.h"
|
||||
|
||||
/*
|
||||
* Each disk drive contains some number of file systems.
|
||||
* A file system consists of a number of cylinder groups.
|
||||
* Each cylinder group has inodes and data.
|
||||
*
|
||||
* A file system is described by its super-block, which in turn
|
||||
* describes the cylinder groups. The super-block is critical
|
||||
* data and is replicated in each cylinder group to protect against
|
||||
* catastrophic loss. This is done at `newfs' time and the critical
|
||||
* super-block data does not change, so the copies need not be
|
||||
* referenced further unless disaster strikes.
|
||||
*
|
||||
* For file system fs, the offsets of the various blocks of interest
|
||||
* are given in the super block as:
|
||||
* [fs->fs_sblkno] Super-block
|
||||
* [fs->fs_cblkno] Cylinder group block
|
||||
* [fs->fs_iblkno] Inode blocks
|
||||
* [fs->fs_dblkno] Data blocks
|
||||
* The beginning of cylinder group cg in fs, is given by
|
||||
* the ``cgbase(fs, cg)'' macro.
|
||||
*
|
||||
* Depending on the architecture and the media, the superblock may
|
||||
* reside in any one of four places. For tiny media where every block
|
||||
* counts, it is placed at the very front of the partition. Historically,
|
||||
* UFS1 placed it 8K from the front to leave room for the disk label and
|
||||
* a small bootstrap. For UFS2 it got moved to 64K from the front to leave
|
||||
* room for the disk label and a bigger bootstrap, and for really piggy
|
||||
* systems we check at 256K from the front if the first three fail. In
|
||||
* all cases the size of the superblock will be SBLOCKSIZE. All values are
|
||||
* given in byte-offset form, so they do not imply a sector size. The
|
||||
* SBLOCKSEARCH specifies the order in which the locations should be searched.
|
||||
*
|
||||
* Unfortunately the UFS2/FFSv2 change was done without adequate consideration
|
||||
* of backward compatibility. In particular 'newfs' for a FFSv2 partition
|
||||
* must overwrite any old FFSv1 superblock at 8k, and preferrably as many
|
||||
* of the alternates as it can find - otherwise attempting to mount on a
|
||||
* system that only supports FFSv1 is likely to succeed!.
|
||||
* For a small FFSv1 filesystem, an old FFSv2 superblock can be left on
|
||||
* the disk, and a system that tries to find an FFSv2 filesystem in preference
|
||||
* to and FFSv1 one (as NetBSD does) can mount the old FFSv2 filesystem.
|
||||
* As a added bonus, the 'first alternate' superblock of a FFSv1 filesystem
|
||||
* with 64k blocks is at 64k - just where the code looks first when playing
|
||||
* 'hunt the superblock'.
|
||||
*
|
||||
* The ffsv2 superblock layout (which might contain an ffsv1 filesystem)
|
||||
* can be detected by checking for sb->fs_old_flags & FS_FLAGS_UPDATED.
|
||||
* This is the default suberblock type for NetBSD since ffsv2 support was added.
|
||||
*/
|
||||
#define BBSIZE 8192
|
||||
#define BBOFF ((off_t)(0))
|
||||
#define BBLOCK ((daddr_t)(0))
|
||||
|
||||
#define SBLOCK_FLOPPY 0
|
||||
#define SBLOCK_UFS1 8192
|
||||
#define SBLOCK_UFS2 65536
|
||||
#define SBLOCK_PIGGY 262144
|
||||
#define SBLOCKSIZE 8192
|
||||
/*
|
||||
* NB: Do not, under any circumstances, look for an ffsv1 filesystem at
|
||||
* SBLOCK_UFS2. Doing so will find the wrong superblock for filesystems
|
||||
* with a 64k block size.
|
||||
*/
|
||||
#define SBLOCKSEARCH \
|
||||
{ SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
|
||||
|
||||
/*
|
||||
* Max number of fragments per block. This value is NOT tweakable.
|
||||
*/
|
||||
#define MAXFRAG 8
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Addresses stored in inodes are capable of addressing fragments
|
||||
* of `blocks'. File system blocks of at most size MAXBSIZE can
|
||||
* be optionally broken into 2, 4, or 8 pieces, each of which is
|
||||
* addressable; these pieces may be DEV_BSIZE, or some multiple of
|
||||
* a DEV_BSIZE unit.
|
||||
*
|
||||
* Large files consist of exclusively large data blocks. To avoid
|
||||
* undue wasted disk space, the last data block of a small file may be
|
||||
* allocated as only as many fragments of a large block as are
|
||||
* necessary. The file system format retains only a single pointer
|
||||
* to such a fragment, which is a piece of a single large block that
|
||||
* has been divided. The size of such a fragment is determinable from
|
||||
* information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
|
||||
*
|
||||
* The file system records space availability at the fragment level;
|
||||
* to determine block availability, aligned fragments are examined.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MINBSIZE is the smallest allowable block size.
|
||||
* In order to insure that it is possible to create files of size
|
||||
* 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
|
||||
* MINBSIZE must be big enough to hold a cylinder group block,
|
||||
* thus changes to (struct cg) must keep its size within MINBSIZE.
|
||||
* Note that super blocks are always of size SBSIZE,
|
||||
* and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
|
||||
*/
|
||||
#define MINBSIZE 4096
|
||||
|
||||
/*
|
||||
* The path name on which the file system is mounted is maintained
|
||||
* in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
|
||||
* the super block for this name.
|
||||
*/
|
||||
#define MAXMNTLEN 468
|
||||
|
||||
/*
|
||||
* The volume name for this filesystem is maintained in fs_volname.
|
||||
* MAXVOLLEN defines the length of the buffer allocated.
|
||||
* This space used to be part of of fs_fsmnt.
|
||||
*/
|
||||
#define MAXVOLLEN 32
|
||||
|
||||
/*
|
||||
* There is a 128-byte region in the superblock reserved for in-core
|
||||
* pointers to summary information. Originally this included an array
|
||||
* of pointers to blocks of struct csum; now there are just four
|
||||
* pointers and the remaining space is padded with fs_ocsp[].
|
||||
* NOCSPTRS determines the size of this padding. One pointer (fs_csp)
|
||||
* is taken away to point to a contiguous array of struct csum for
|
||||
* all cylinder groups; a second (fs_maxcluster) points to an array
|
||||
* of cluster sizes that is computed as cylinder groups are inspected;
|
||||
* the third (fs_contigdirs) points to an array that tracks the
|
||||
* creation of new directories; and the fourth (fs_active) is used
|
||||
* by snapshots.
|
||||
*/
|
||||
#define NOCSPTRS ((128 / sizeof(void *)) - 4)
|
||||
|
||||
/*
|
||||
* A summary of contiguous blocks of various sizes is maintained
|
||||
* in each cylinder group. Normally this is set by the initial
|
||||
* value of fs_maxcontig. To conserve space, a maximum summary size
|
||||
* is set by FS_MAXCONTIG.
|
||||
*/
|
||||
#define FS_MAXCONTIG 16
|
||||
|
||||
/*
|
||||
* Unused value currently, FreeBSD compat.
|
||||
*/
|
||||
#define FSMAXSNAP 20
|
||||
|
||||
/*
|
||||
* MINFREE gives the minimum acceptable percentage of file system
|
||||
* blocks which may be free. If the freelist drops below this level
|
||||
* only the superuser may continue to allocate blocks. This may
|
||||
* be set to 0 if no reserve of free blocks is deemed necessary,
|
||||
* however throughput drops by fifty percent if the file system
|
||||
* is run at between 95% and 100% full; thus the minimum default
|
||||
* value of fs_minfree is 5%. However, to get good clustering
|
||||
* performance, 10% is a better choice. hence we use 10% as our
|
||||
* default value. With 10% free space, fragmentation is not a
|
||||
* problem, so we choose to optimize for time.
|
||||
*/
|
||||
#define MINFREE 5
|
||||
#define DEFAULTOPT FS_OPTTIME
|
||||
|
||||
/*
|
||||
* Grigoriy Orlov <gluk@ptci.ru> has done some extensive work to fine
|
||||
* tune the layout preferences for directories within a filesystem.
|
||||
* His algorithm can be tuned by adjusting the following parameters
|
||||
* which tell the system the average file size and the average number
|
||||
* of files per directory. These defaults are well selected for typical
|
||||
* filesystems, but may need to be tuned for odd cases like filesystems
|
||||
* being used for squid caches or news spools.
|
||||
*/
|
||||
#define AVFILESIZ 16384 /* expected average file size */
|
||||
#define AFPDIR 64 /* expected number of files per directory */
|
||||
|
||||
/*
|
||||
* Per cylinder group information; summarized in blocks allocated
|
||||
* from first cylinder group data blocks. These blocks have to be
|
||||
* read in from fs_csaddr (size fs_cssize) in addition to the
|
||||
* super block.
|
||||
*/
|
||||
struct csum {
|
||||
int32_t cs_ndir; /* number of directories */
|
||||
int32_t cs_nbfree; /* number of free blocks */
|
||||
int32_t cs_nifree; /* number of free inodes */
|
||||
int32_t cs_nffree; /* number of free frags */
|
||||
};
|
||||
|
||||
struct csum_total {
|
||||
int64_t cs_ndir; /* number of directories */
|
||||
int64_t cs_nbfree; /* number of free blocks */
|
||||
int64_t cs_nifree; /* number of free inodes */
|
||||
int64_t cs_nffree; /* number of free frags */
|
||||
int64_t cs_spare[4]; /* future expansion */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Super block for an FFS file system in memory.
|
||||
*/
|
||||
struct fs {
|
||||
int32_t fs_firstfield; /* historic file system linked list, */
|
||||
int32_t fs_unused_1; /* used for incore super blocks */
|
||||
int32_t fs_sblkno; /* addr of super-block in filesys */
|
||||
int32_t fs_cblkno; /* offset of cyl-block in filesys */
|
||||
int32_t fs_iblkno; /* offset of inode-blocks in filesys */
|
||||
int32_t fs_dblkno; /* offset of first data after cg */
|
||||
int32_t fs_old_cgoffset; /* cylinder group offset in cylinder */
|
||||
int32_t fs_old_cgmask; /* used to calc mod fs_ntrak */
|
||||
int32_t fs_old_time; /* last time written */
|
||||
int32_t fs_old_size; /* number of blocks in fs */
|
||||
int32_t fs_old_dsize; /* number of data blocks in fs */
|
||||
int32_t fs_ncg; /* number of cylinder groups */
|
||||
int32_t fs_bsize; /* size of basic blocks in fs */
|
||||
int32_t fs_fsize; /* size of frag blocks in fs */
|
||||
int32_t fs_frag; /* number of frags in a block in fs */
|
||||
/* these are configuration parameters */
|
||||
int32_t fs_minfree; /* minimum percentage of free blocks */
|
||||
int32_t fs_old_rotdelay; /* num of ms for optimal next block */
|
||||
int32_t fs_old_rps; /* disk revolutions per second */
|
||||
/* these fields can be computed from the others */
|
||||
int32_t fs_bmask; /* ``blkoff'' calc of blk offsets */
|
||||
int32_t fs_fmask; /* ``fragoff'' calc of frag offsets */
|
||||
int32_t fs_bshift; /* ``lblkno'' calc of logical blkno */
|
||||
int32_t fs_fshift; /* ``numfrags'' calc number of frags */
|
||||
/* these are configuration parameters */
|
||||
int32_t fs_maxcontig; /* max number of contiguous blks */
|
||||
int32_t fs_maxbpg; /* max number of blks per cyl group */
|
||||
/* these fields can be computed from the others */
|
||||
int32_t fs_fragshift; /* block to frag shift */
|
||||
int32_t fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
|
||||
int32_t fs_sbsize; /* actual size of super block */
|
||||
int32_t fs_spare1[2]; /* old fs_csmask */
|
||||
/* old fs_csshift */
|
||||
int32_t fs_nindir; /* value of NINDIR */
|
||||
int32_t fs_inopb; /* value of INOPB */
|
||||
int32_t fs_old_nspf; /* value of NSPF */
|
||||
/* yet another configuration parameter */
|
||||
int32_t fs_optim; /* optimization preference, see below */
|
||||
/* these fields are derived from the hardware */
|
||||
int32_t fs_old_npsect; /* # sectors/track including spares */
|
||||
int32_t fs_old_interleave; /* hardware sector interleave */
|
||||
int32_t fs_old_trackskew; /* sector 0 skew, per track */
|
||||
/* fs_id takes the space of the unused fs_headswitch and fs_trkseek fields */
|
||||
int32_t fs_id[2]; /* unique file system id */
|
||||
/* sizes determined by number of cylinder groups and their sizes */
|
||||
int32_t fs_old_csaddr; /* blk addr of cyl grp summary area */
|
||||
int32_t fs_cssize; /* size of cyl grp summary area */
|
||||
int32_t fs_cgsize; /* cylinder group size */
|
||||
/* these fields are derived from the hardware */
|
||||
int32_t fs_spare2; /* old fs_ntrak */
|
||||
int32_t fs_old_nsect; /* sectors per track */
|
||||
int32_t fs_old_spc; /* sectors per cylinder */
|
||||
int32_t fs_old_ncyl; /* cylinders in file system */
|
||||
int32_t fs_old_cpg; /* cylinders per group */
|
||||
int32_t fs_ipg; /* inodes per group */
|
||||
int32_t fs_fpg; /* blocks per group * fs_frag */
|
||||
/* this data must be re-computed after crashes */
|
||||
struct csum fs_old_cstotal; /* cylinder summary information */
|
||||
/* these fields are cleared at mount time */
|
||||
int8_t fs_fmod; /* super block modified flag */
|
||||
int8_t fs_clean; /* file system is clean flag */
|
||||
int8_t fs_ronly; /* mounted read-only flag */
|
||||
uint8_t fs_old_flags; /* see FS_ flags below */
|
||||
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
|
||||
u_char fs_volname[MAXVOLLEN]; /* volume name */
|
||||
uint64_t fs_swuid; /* system-wide uid */
|
||||
int32_t fs_pad;
|
||||
/* these fields retain the current block allocation info */
|
||||
int32_t fs_cgrotor; /* last cg searched (UNUSED) */
|
||||
void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */
|
||||
u_int8_t *fs_contigdirs; /* # of contiguously allocated dirs */
|
||||
struct csum *fs_csp; /* cg summary info buffer for fs_cs */
|
||||
int32_t *fs_maxcluster; /* max cluster in each cyl group */
|
||||
u_int *fs_active; /* used by snapshots to track fs */
|
||||
int32_t fs_old_cpc; /* cyl per cycle in postbl */
|
||||
/* this area is otherwise allocated unless fs_old_flags & FS_FLAGS_UPDATED */
|
||||
int32_t fs_maxbsize; /* maximum blocking factor permitted */
|
||||
int64_t fs_sparecon64[17]; /* old rotation block list head */
|
||||
int64_t fs_sblockloc; /* byte offset of standard superblock */
|
||||
struct csum_total fs_cstotal; /* cylinder summary information */
|
||||
int64_t fs_time; /* last time written */
|
||||
int64_t fs_size; /* number of blocks in fs */
|
||||
int64_t fs_dsize; /* number of data blocks in fs */
|
||||
int64_t fs_csaddr; /* blk addr of cyl grp summary area */
|
||||
int64_t fs_pendingblocks; /* blocks in process of being freed */
|
||||
int32_t fs_pendinginodes; /* inodes in process of being freed */
|
||||
int32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
|
||||
/* back to stuff that has been around a while */
|
||||
int32_t fs_avgfilesize; /* expected average file size */
|
||||
int32_t fs_avgfpdir; /* expected # of files per directory */
|
||||
int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */
|
||||
int32_t fs_sparecon32[26]; /* reserved for future constants */
|
||||
uint32_t fs_flags; /* see FS_ flags below */
|
||||
/* back to stuff that has been around a while (again) */
|
||||
int32_t fs_contigsumsize; /* size of cluster summary array */
|
||||
int32_t fs_maxsymlinklen; /* max length of an internal symlink */
|
||||
int32_t fs_old_inodefmt; /* format of on-disk inodes */
|
||||
u_int64_t fs_maxfilesize; /* maximum representable file size */
|
||||
int64_t fs_qbmask; /* ~fs_bmask for use with 64-bit size */
|
||||
int64_t fs_qfmask; /* ~fs_fmask for use with 64-bit size */
|
||||
int32_t fs_state; /* validate fs_clean field (UNUSED) */
|
||||
int32_t fs_old_postblformat; /* format of positional layout tables */
|
||||
int32_t fs_old_nrpos; /* number of rotational positions */
|
||||
int32_t fs_spare5[2]; /* old fs_postbloff */
|
||||
/* old fs_rotbloff */
|
||||
int32_t fs_magic; /* magic number */
|
||||
};
|
||||
|
||||
#define fs_old_postbloff fs_spare5[0]
|
||||
#define fs_old_rotbloff fs_spare5[1]
|
||||
#define fs_old_postbl_start fs_maxbsize
|
||||
#define fs_old_headswitch fs_id[0]
|
||||
#define fs_old_trkseek fs_id[1]
|
||||
#define fs_old_csmask fs_spare1[0]
|
||||
#define fs_old_csshift fs_spare1[1]
|
||||
|
||||
#define FS_42POSTBLFMT -1 /* 4.2BSD rotational table format */
|
||||
#define FS_DYNAMICPOSTBLFMT 1 /* dynamic rotational table format */
|
||||
|
||||
#define old_fs_postbl(fs_, cylno, opostblsave) \
|
||||
((((fs_)->fs_old_postblformat == FS_42POSTBLFMT) || \
|
||||
((fs_)->fs_old_postbloff == offsetof(struct fs, fs_old_postbl_start))) \
|
||||
? ((int16_t *)(opostblsave) + (cylno) * (fs_)->fs_old_nrpos) \
|
||||
: ((int16_t *)((uint8_t *)(fs_) + \
|
||||
(fs_)->fs_old_postbloff) + (cylno) * (fs_)->fs_old_nrpos))
|
||||
#define old_fs_rotbl(fs) \
|
||||
(((fs)->fs_old_postblformat == FS_42POSTBLFMT) \
|
||||
? ((uint8_t *)(&(fs)->fs_magic+1)) \
|
||||
: ((uint8_t *)((uint8_t *)(fs) + (fs)->fs_old_rotbloff)))
|
||||
|
||||
/*
|
||||
* File system identification
|
||||
*/
|
||||
#define FS_UFS1_MAGIC 0x011954 /* UFS1 fast file system magic number */
|
||||
#define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast file system magic number */
|
||||
#define FS_UFS1_MAGIC_SWAPPED 0x54190100
|
||||
#define FS_UFS2_MAGIC_SWAPPED 0x19015419
|
||||
#define FS_OKAY 0x7c269d38 /* superblock checksum */
|
||||
#define FS_42INODEFMT -1 /* 4.2BSD inode format */
|
||||
#define FS_44INODEFMT 2 /* 4.4BSD inode format */
|
||||
|
||||
/*
|
||||
* File system clean flags
|
||||
*/
|
||||
#define FS_ISCLEAN 0x01
|
||||
#define FS_WASCLEAN 0x02
|
||||
|
||||
/*
|
||||
* Preference for optimization.
|
||||
*/
|
||||
#define FS_OPTTIME 0 /* minimize allocation time */
|
||||
#define FS_OPTSPACE 1 /* minimize disk fragmentation */
|
||||
|
||||
/*
|
||||
* File system flags
|
||||
*/
|
||||
#define FS_UNCLEAN 0x01 /* file system not clean at mount (unused) */
|
||||
#define FS_DOSOFTDEP 0x02 /* file system using soft dependencies */
|
||||
#define FS_NEEDSFSCK 0x04 /* needs sync fsck (FreeBSD compat, unused) */
|
||||
#define FS_INDEXDIRS 0x08 /* kernel supports indexed directories */
|
||||
#define FS_ACLS 0x10 /* file system has ACLs enabled */
|
||||
#define FS_MULTILABEL 0x20 /* file system is MAC multi-label */
|
||||
#define FS_FLAGS_UPDATED 0x80 /* flags have been moved to new location */
|
||||
|
||||
/*
|
||||
* File system internal flags, also in fs_flags.
|
||||
* (Pick highest number to avoid conflicts with others)
|
||||
*/
|
||||
#define FS_SWAPPED 0x80000000 /* file system is endian swapped */
|
||||
#define FS_INTERNAL 0x80000000 /* mask for internal flags */
|
||||
|
||||
/*
|
||||
* The size of a cylinder group is calculated by CGSIZE. The maximum size
|
||||
* is limited by the fact that cylinder groups are at most one block.
|
||||
* Its size is derived from the size of the maps maintained in the
|
||||
* cylinder group and the (struct cg) size.
|
||||
*/
|
||||
#define CGSIZE_IF(fs, ipg, fpg) \
|
||||
/* base cg */ (sizeof(struct cg) + sizeof(int32_t) + \
|
||||
/* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) + \
|
||||
/* old boff */ (fs)->fs_old_cpg * sizeof(u_int16_t) + \
|
||||
/* inode map */ howmany((ipg), NBBY) + \
|
||||
/* block map */ howmany((fpg), NBBY) +\
|
||||
/* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \
|
||||
/* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \
|
||||
/* cluster map */ howmany(fragstoblks(fs, (fpg)), NBBY)))
|
||||
|
||||
#define CGSIZE(fs) CGSIZE_IF((fs), (fs)->fs_ipg, (fs)->fs_fpg)
|
||||
|
||||
/*
|
||||
* The minimal number of cylinder groups that should be created.
|
||||
*/
|
||||
#define MINCYLGRPS 4
|
||||
|
||||
|
||||
/*
|
||||
* Convert cylinder group to base address of its global summary info.
|
||||
*/
|
||||
#define fs_cs(fs, indx) fs_csp[indx]
|
||||
|
||||
/*
|
||||
* Cylinder group block for a file system.
|
||||
*/
|
||||
#define CG_MAGIC 0x090255
|
||||
struct cg {
|
||||
int32_t cg_firstfield; /* historic cyl groups linked list */
|
||||
int32_t cg_magic; /* magic number */
|
||||
int32_t cg_old_time; /* time last written */
|
||||
int32_t cg_cgx; /* we are the cgx'th cylinder group */
|
||||
int16_t cg_old_ncyl; /* number of cyl's this cg */
|
||||
int16_t cg_old_niblk; /* number of inode blocks this cg */
|
||||
int32_t cg_ndblk; /* number of data blocks this cg */
|
||||
struct csum cg_cs; /* cylinder summary information */
|
||||
int32_t cg_rotor; /* position of last used block */
|
||||
int32_t cg_frotor; /* position of last used frag */
|
||||
int32_t cg_irotor; /* position of last used inode */
|
||||
int32_t cg_frsum[MAXFRAG]; /* counts of available frags */
|
||||
int32_t cg_old_btotoff; /* (int32) block totals per cylinder */
|
||||
int32_t cg_old_boff; /* (u_int16) free block positions */
|
||||
int32_t cg_iusedoff; /* (u_int8) used inode map */
|
||||
int32_t cg_freeoff; /* (u_int8) free block map */
|
||||
int32_t cg_nextfreeoff; /* (u_int8) next available space */
|
||||
int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */
|
||||
int32_t cg_clusteroff; /* (u_int8) free cluster map */
|
||||
int32_t cg_nclusterblks; /* number of clusters this cg */
|
||||
int32_t cg_niblk; /* number of inode blocks this cg */
|
||||
int32_t cg_initediblk; /* last initialized inode */
|
||||
int32_t cg_sparecon32[3]; /* reserved for future use */
|
||||
int64_t cg_time; /* time last written */
|
||||
int64_t cg_sparecon64[3]; /* reserved for future use */
|
||||
u_int8_t cg_space[1]; /* space for cylinder group maps */
|
||||
/* actually longer */
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure is defined
|
||||
* for compatibility with old file systems.
|
||||
*/
|
||||
struct ocg {
|
||||
int32_t cg_firstfield; /* historic linked list of cyl groups */
|
||||
int32_t cg_unused_1; /* used for incore cyl groups */
|
||||
int32_t cg_time; /* time last written */
|
||||
int32_t cg_cgx; /* we are the cgx'th cylinder group */
|
||||
int16_t cg_ncyl; /* number of cyl's this cg */
|
||||
int16_t cg_niblk; /* number of inode blocks this cg */
|
||||
int32_t cg_ndblk; /* number of data blocks this cg */
|
||||
struct csum cg_cs; /* cylinder summary information */
|
||||
int32_t cg_rotor; /* position of last used block */
|
||||
int32_t cg_frotor; /* position of last used frag */
|
||||
int32_t cg_irotor; /* position of last used inode */
|
||||
int32_t cg_frsum[8]; /* counts of available frags */
|
||||
int32_t cg_btot[32]; /* block totals per cylinder */
|
||||
int16_t cg_b[32][8]; /* positions of free blocks */
|
||||
u_int8_t cg_iused[256]; /* used inode map */
|
||||
int32_t cg_magic; /* magic number */
|
||||
u_int8_t cg_free[1]; /* free block map */
|
||||
/* actually longer */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Macros for access to cylinder group array structures.
|
||||
*/
|
||||
#define old_cg_blktot_old(cgp, ns) \
|
||||
(((struct ocg *)(cgp))->cg_btot)
|
||||
#define old_cg_blks_old(fs, cgp, cylno, ns) \
|
||||
(((struct ocg *)(cgp))->cg_b[cylno])
|
||||
|
||||
#define old_cg_blktot_new(cgp, ns) \
|
||||
((int32_t *)((u_int8_t *)(cgp) + \
|
||||
ufs_rw32((cgp)->cg_old_btotoff, (ns))))
|
||||
#define old_cg_blks_new(fs, cgp, cylno, ns) \
|
||||
((int16_t *)((u_int8_t *)(cgp) + \
|
||||
ufs_rw32((cgp)->cg_old_boff, (ns))) + (cylno) * (fs)->fs_old_nrpos)
|
||||
|
||||
#define old_cg_blktot(cgp, ns) \
|
||||
((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
|
||||
old_cg_blktot_old(cgp, ns) : old_cg_blktot_new(cgp, ns))
|
||||
#define old_cg_blks(fs, cgp, cylno, ns) \
|
||||
((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
|
||||
old_cg_blks_old(fs, cgp, cylno, ns) : old_cg_blks_new(fs, cgp, cylno, ns))
|
||||
|
||||
#define cg_inosused_new(cgp, ns) \
|
||||
((u_int8_t *)((u_int8_t *)(cgp) + \
|
||||
ufs_rw32((cgp)->cg_iusedoff, (ns))))
|
||||
#define cg_blksfree_new(cgp, ns) \
|
||||
((u_int8_t *)((u_int8_t *)(cgp) + \
|
||||
ufs_rw32((cgp)->cg_freeoff, (ns))))
|
||||
#define cg_chkmagic_new(cgp, ns) \
|
||||
(ufs_rw32((cgp)->cg_magic, (ns)) == CG_MAGIC)
|
||||
|
||||
#define cg_inosused_old(cgp, ns) \
|
||||
(((struct ocg *)(cgp))->cg_iused)
|
||||
#define cg_blksfree_old(cgp, ns) \
|
||||
(((struct ocg *)(cgp))->cg_free)
|
||||
#define cg_chkmagic_old(cgp, ns) \
|
||||
(ufs_rw32(((struct ocg *)(cgp))->cg_magic, (ns)) == CG_MAGIC)
|
||||
|
||||
#define cg_inosused(cgp, ns) \
|
||||
((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
|
||||
cg_inosused_old(cgp, ns) : cg_inosused_new(cgp, ns))
|
||||
#define cg_blksfree(cgp, ns) \
|
||||
((ufs_rw32((cgp)->cg_magic, (ns)) != CG_MAGIC) ? \
|
||||
cg_blksfree_old(cgp, ns) : cg_blksfree_new(cgp, ns))
|
||||
#define cg_chkmagic(cgp, ns) \
|
||||
(cg_chkmagic_new(cgp, ns) || cg_chkmagic_old(cgp, ns))
|
||||
|
||||
#define cg_clustersfree(cgp, ns) \
|
||||
((u_int8_t *)((u_int8_t *)(cgp) + \
|
||||
ufs_rw32((cgp)->cg_clusteroff, (ns))))
|
||||
#define cg_clustersum(cgp, ns) \
|
||||
((int32_t *)((u_int8_t *)(cgp) + \
|
||||
ufs_rw32((cgp)->cg_clustersumoff, (ns))))
|
||||
|
||||
|
||||
/*
|
||||
* Turn file system block numbers into disk block addresses.
|
||||
* This maps file system blocks to device size blocks.
|
||||
*/
|
||||
#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb)
|
||||
#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb)
|
||||
|
||||
/*
|
||||
* Cylinder group macros to locate things in cylinder groups.
|
||||
* They calc file system addresses of cylinder group data structures.
|
||||
*/
|
||||
#define cgbase(fs, c) (((daddr_t)(fs)->fs_fpg) * (c))
|
||||
#define cgstart_ufs1(fs, c) \
|
||||
(cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask)))
|
||||
#define cgstart_ufs2(fs, c) cgbase((fs), (c))
|
||||
#define cgstart(fs, c) ((fs)->fs_magic == FS_UFS2_MAGIC \
|
||||
? cgstart_ufs2((fs), (c)) : cgstart_ufs1((fs), (c)))
|
||||
#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
|
||||
#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
|
||||
#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
|
||||
#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
|
||||
|
||||
/*
|
||||
* Macros for handling inode numbers:
|
||||
* inode number to file system block offset.
|
||||
* inode number to cylinder group number.
|
||||
* inode number to file system block address.
|
||||
*/
|
||||
#define ino_to_cg(fs, x) ((x) / (fs)->fs_ipg)
|
||||
#define ino_to_fsba(fs, x) \
|
||||
((daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \
|
||||
(blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
|
||||
#define ino_to_fsbo(fs, x) ((x) % INOPB(fs))
|
||||
|
||||
/*
|
||||
* Give cylinder group number for a file system block.
|
||||
* Give cylinder group block number for a file system block.
|
||||
*/
|
||||
#define dtog(fs, d) ((d) / (fs)->fs_fpg)
|
||||
#define dtogd(fs, d) ((d) % (fs)->fs_fpg)
|
||||
|
||||
/*
|
||||
* Extract the bits for a block from a map.
|
||||
* Compute the cylinder and rotational position of a cyl block addr.
|
||||
*/
|
||||
#define blkmap(fs, map, loc) \
|
||||
(((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
|
||||
#define old_cbtocylno(fs, bno) \
|
||||
(fsbtodb(fs, bno) / (fs)->fs_old_spc)
|
||||
#define old_cbtorpos(fs, bno) \
|
||||
((fs)->fs_old_nrpos <= 1 ? 0 : \
|
||||
(fsbtodb(fs, bno) % (fs)->fs_old_spc / (fs)->fs_old_nsect * (fs)->fs_old_trackskew + \
|
||||
fsbtodb(fs, bno) % (fs)->fs_old_spc % (fs)->fs_old_nsect * (fs)->fs_old_interleave) % \
|
||||
(fs)->fs_old_nsect * (fs)->fs_old_nrpos / (fs)->fs_old_npsect)
|
||||
|
||||
/*
|
||||
* The following macros optimize certain frequently calculated
|
||||
* quantities by using shifts and masks in place of divisions
|
||||
* modulos and multiplications.
|
||||
*/
|
||||
#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \
|
||||
((loc) & (fs)->fs_qbmask)
|
||||
#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
|
||||
((loc) & (fs)->fs_qfmask)
|
||||
#define lfragtosize(fs, frag) /* calculates ((off_t)frag * fs->fs_fsize) */ \
|
||||
(((off_t)(frag)) << (fs)->fs_fshift)
|
||||
#define lblktosize(fs, blk) /* calculates ((off_t)blk * fs->fs_bsize) */ \
|
||||
(((off_t)(blk)) << (fs)->fs_bshift)
|
||||
#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \
|
||||
((loc) >> (fs)->fs_bshift)
|
||||
#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
|
||||
((loc) >> (fs)->fs_fshift)
|
||||
#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
|
||||
(((size) + (fs)->fs_qbmask) & (fs)->fs_bmask)
|
||||
#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
|
||||
(((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
|
||||
#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
|
||||
((frags) >> (fs)->fs_fragshift)
|
||||
#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
|
||||
((blks) << (fs)->fs_fragshift)
|
||||
#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \
|
||||
((fsb) & ((fs)->fs_frag - 1))
|
||||
#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \
|
||||
((fsb) &~ ((fs)->fs_frag - 1))
|
||||
|
||||
/*
|
||||
* Determine the number of available frags given a
|
||||
* percentage to hold in reserve.
|
||||
*/
|
||||
#define freespace(fs, percentreserved) \
|
||||
(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
|
||||
(fs)->fs_cstotal.cs_nffree - \
|
||||
(((off_t)((fs)->fs_dsize)) * (percentreserved) / 100))
|
||||
|
||||
/*
|
||||
* Determining the size of a file block in the file system.
|
||||
*/
|
||||
#define blksize(fs, ip, lbn) \
|
||||
(((lbn) >= NDADDR || (ip)->i_size >= lblktosize(fs, (lbn) + 1)) \
|
||||
? (fs)->fs_bsize \
|
||||
: (fragroundup(fs, blkoff(fs, (ip)->i_size))))
|
||||
|
||||
#define sblksize(fs, size, lbn) \
|
||||
(((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
|
||||
? (fs)->fs_bsize \
|
||||
: (fragroundup(fs, blkoff(fs, (size)))))
|
||||
|
||||
|
||||
/*
|
||||
* Number of inodes in a secondary storage block/fragment.
|
||||
*/
|
||||
#define INOPB(fs) ((fs)->fs_inopb)
|
||||
#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
|
||||
|
||||
/*
|
||||
* Number of indirects in a file system block.
|
||||
*/
|
||||
#define NINDIR(fs) ((fs)->fs_nindir)
|
||||
|
||||
/*
|
||||
* Apple UFS Label:
|
||||
* We check for this to decide to use APPLEUFS_DIRBLKSIZ
|
||||
*/
|
||||
#define APPLEUFS_LABEL_MAGIC 0x4c41424c /* LABL */
|
||||
#define APPLEUFS_LABEL_SIZE 1024
|
||||
#define APPLEUFS_LABEL_OFFSET (BBSIZE - APPLEUFS_LABEL_SIZE) /* located at 7k */
|
||||
#define APPLEUFS_LABEL_VERSION 1
|
||||
#define APPLEUFS_MAX_LABEL_NAME 512
|
||||
|
||||
#if 0
|
||||
struct appleufslabel {
|
||||
u_int32_t ul_magic;
|
||||
u_int16_t ul_checksum;
|
||||
u_int16_t ul_unused0;
|
||||
u_int32_t ul_version;
|
||||
u_int32_t ul_time;
|
||||
u_int16_t ul_namelen;
|
||||
u_char ul_name[APPLEUFS_MAX_LABEL_NAME]; /* Warning: may not be null terminated */
|
||||
u_int16_t ul_unused1;
|
||||
u_int64_t ul_uuid; /* Note this is only 4 byte aligned */
|
||||
u_char ul_reserved[24];
|
||||
u_char ul_unused[460];
|
||||
} __attribute__((__packed__));
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* !_UFS_FFS_FS_H_ */
|
@ -1,22 +0,0 @@
|
||||
/* type.h */
|
||||
|
||||
typedef unsigned char u_char;
|
||||
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int8 u_int8_t;
|
||||
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 u_int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 u_int;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int32 u_int32_t;
|
||||
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int64 u_int64_t;
|
||||
|
||||
typedef __int64 daddr_t;
|
@ -1,689 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* block.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
typedef struct _FFS_RW_CONTEXT {
|
||||
PIRP MasterIrp;
|
||||
KEVENT Event;
|
||||
BOOLEAN Wait;
|
||||
LONG Blocks;
|
||||
ULONG Length;
|
||||
} FFS_RW_CONTEXT, *PFFS_RW_CONTEXT;
|
||||
|
||||
#ifdef _PREFAST_
|
||||
IO_COMPLETION_ROUTINE FFSReadWriteBlockSyncCompletionRoutine;
|
||||
IO_COMPLETION_ROUTINE FFSReadWriteBlockAsyncCompletionRoutine;
|
||||
IO_COMPLETION_ROUTINE FFSMediaEjectControlCompletion;
|
||||
#endif // _PREFAST_
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSReadWriteBlockSyncCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSReadWriteBlockAsyncCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSMediaEjectControlCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Contxt);
|
||||
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSLockUserBuffer)
|
||||
#pragma alloc_text(PAGE, FFSGetUserBuffer)
|
||||
#pragma alloc_text(PAGE, FFSReadSync)
|
||||
#pragma alloc_text(PAGE, FFSReadDisk)
|
||||
#pragma alloc_text(PAGE, FFSDiskIoControl)
|
||||
#pragma alloc_text(PAGE, FFSReadWriteBlocks)
|
||||
#pragma alloc_text(PAGE, FFSMediaEjectControl)
|
||||
#pragma alloc_text(PAGE, FFSDiskShutDown)
|
||||
#endif
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSLockUserBuffer(
|
||||
IN PIRP Irp,
|
||||
IN ULONG Length,
|
||||
IN LOCK_OPERATION Operation)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Irp != NULL);
|
||||
|
||||
if (Irp->MdlAddress != NULL)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp);
|
||||
|
||||
if (Irp->MdlAddress == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
_SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
IoFreeMdl(Irp->MdlAddress);
|
||||
|
||||
Irp->MdlAddress = NULL;
|
||||
|
||||
FFSBreakPoint();
|
||||
|
||||
Status = STATUS_INVALID_USER_BUFFER;
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
PVOID
|
||||
FFSGetUserBuffer(
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Irp != NULL);
|
||||
|
||||
if (Irp->MdlAddress)
|
||||
{
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
#else
|
||||
return MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return Irp->UserBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSReadWriteBlockSyncCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
PFFS_RW_CONTEXT pContext = (PFFS_RW_CONTEXT)Context;
|
||||
|
||||
if (!NT_SUCCESS(Irp->IoStatus.Status))
|
||||
{
|
||||
|
||||
pContext->MasterIrp->IoStatus = Irp->IoStatus;
|
||||
}
|
||||
|
||||
IoFreeMdl(Irp->MdlAddress);
|
||||
IoFreeIrp(Irp);
|
||||
|
||||
if (InterlockedDecrement(&pContext->Blocks) == 0)
|
||||
{
|
||||
pContext->MasterIrp->IoStatus.Information = 0;
|
||||
|
||||
if (NT_SUCCESS(pContext->MasterIrp->IoStatus.Status))
|
||||
{
|
||||
pContext->MasterIrp->IoStatus.Information =
|
||||
pContext->Length;
|
||||
}
|
||||
|
||||
KeSetEvent(&pContext->Event, 0, FALSE);
|
||||
}
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSReadWriteBlockAsyncCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
PFFS_RW_CONTEXT pContext = (PFFS_RW_CONTEXT)Context;
|
||||
|
||||
if (!NT_SUCCESS(Irp->IoStatus.Status))
|
||||
{
|
||||
pContext->MasterIrp->IoStatus = Irp->IoStatus;
|
||||
}
|
||||
|
||||
if (InterlockedDecrement(&pContext->Blocks) == 0)
|
||||
{
|
||||
pContext->MasterIrp->IoStatus.Information = 0;
|
||||
|
||||
if (NT_SUCCESS(pContext->MasterIrp->IoStatus.Status))
|
||||
{
|
||||
pContext->MasterIrp->IoStatus.Information =
|
||||
pContext->Length;
|
||||
}
|
||||
|
||||
IoMarkIrpPending(pContext->MasterIrp);
|
||||
|
||||
ExFreePool(pContext);
|
||||
}
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FFSReadWriteBlocks(
|
||||
IN PFFS_IRP_CONTEXT IrpContext,
|
||||
IN PFFS_VCB Vcb,
|
||||
IN PFFS_BDL FFSBDL,
|
||||
IN ULONG Length,
|
||||
IN ULONG Count,
|
||||
IN BOOLEAN bVerify)
|
||||
{
|
||||
PMDL Mdl;
|
||||
PIRP Irp;
|
||||
PIRP MasterIrp = IrpContext->Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PFFS_RW_CONTEXT pContext = NULL;
|
||||
ULONG i;
|
||||
BOOLEAN bBugCheck = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(MasterIrp);
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
||||
pContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(FFS_RW_CONTEXT), FFS_POOL_TAG);
|
||||
|
||||
if (!pContext)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
RtlZeroMemory(pContext, sizeof(FFS_RW_CONTEXT));
|
||||
|
||||
pContext->Wait = IrpContext->IsSynchronous;
|
||||
pContext->MasterIrp = MasterIrp;
|
||||
pContext->Blocks = Count;
|
||||
pContext->Length = 0;
|
||||
|
||||
if (pContext->Wait)
|
||||
{
|
||||
KeInitializeEvent(&(pContext->Event), NotificationEvent, FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
|
||||
Irp = IoMakeAssociatedIrp(MasterIrp,
|
||||
(CCHAR)(Vcb->TargetDeviceObject->StackSize + 1));
|
||||
if (!Irp)
|
||||
{
|
||||
#ifdef __REACTOS__
|
||||
ExFreePoolWithTag(pContext, FFS_POOL_TAG);
|
||||
pContext = NULL;
|
||||
#endif
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Mdl = IoAllocateMdl((PCHAR)MasterIrp->UserBuffer +
|
||||
FFSBDL[i].Offset,
|
||||
FFSBDL[i].Length,
|
||||
FALSE,
|
||||
FALSE,
|
||||
Irp);
|
||||
|
||||
if (!Mdl)
|
||||
{
|
||||
#ifdef __REACTOS__
|
||||
ExFreePoolWithTag(pContext, FFS_POOL_TAG);
|
||||
pContext = NULL;
|
||||
#endif
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
IoBuildPartialMdl(MasterIrp->MdlAddress,
|
||||
Mdl,
|
||||
(PCHAR)MasterIrp->UserBuffer + FFSBDL[i].Offset,
|
||||
FFSBDL[i].Length);
|
||||
|
||||
IoSetNextIrpStackLocation(Irp);
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
|
||||
IrpSp->MajorFunction = IrpContext->MajorFunction;
|
||||
IrpSp->Parameters.Read.Length = FFSBDL[i].Length;
|
||||
IrpSp->Parameters.Read.ByteOffset.QuadPart = FFSBDL[i].Lba;
|
||||
|
||||
IoSetCompletionRoutine(Irp,
|
||||
IrpContext->IsSynchronous ?
|
||||
&FFSReadWriteBlockSyncCompletionRoutine :
|
||||
&FFSReadWriteBlockAsyncCompletionRoutine,
|
||||
(PVOID) pContext,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
IrpSp = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
IrpSp->MajorFunction = IrpContext->MajorFunction;
|
||||
IrpSp->Parameters.Read.Length = FFSBDL[i].Length;
|
||||
IrpSp->Parameters.Read.ByteOffset.QuadPart = FFSBDL[i].Lba;
|
||||
|
||||
if (bVerify)
|
||||
{
|
||||
SetFlag(IrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME);
|
||||
}
|
||||
|
||||
FFSBDL[i].Irp = Irp;
|
||||
}
|
||||
|
||||
MasterIrp->AssociatedIrp.IrpCount = Count;
|
||||
|
||||
if (IrpContext->IsSynchronous)
|
||||
{
|
||||
MasterIrp->AssociatedIrp.IrpCount += 1;
|
||||
}
|
||||
|
||||
pContext->Length = Length;
|
||||
|
||||
bBugCheck = TRUE;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject,
|
||||
FFSBDL[i].Irp);
|
||||
}
|
||||
|
||||
if (IrpContext->IsSynchronous)
|
||||
{
|
||||
KeWaitForSingleObject(&(pContext->Event),
|
||||
Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
KeClearEvent(&(pContext->Event));
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (IrpContext->IsSynchronous)
|
||||
{
|
||||
if (MasterIrp)
|
||||
Status = MasterIrp->IoStatus.Status;
|
||||
|
||||
if (pContext)
|
||||
ExFreePool(pContext);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
IrpContext->Irp = NULL;
|
||||
Status = STATUS_PENDING;
|
||||
}
|
||||
|
||||
if (_SEH2_AbnormalTermination())
|
||||
{
|
||||
if (bBugCheck)
|
||||
{
|
||||
FFSBugCheck(FFS_BUGCHK_BLOCK, 0, 0, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
if (FFSBDL[i].Irp != NULL)
|
||||
{
|
||||
if (FFSBDL[i].Irp->MdlAddress != NULL)
|
||||
{
|
||||
IoFreeMdl(FFSBDL[i].Irp->MdlAddress);
|
||||
}
|
||||
|
||||
IoFreeIrp(FFSBDL[i].Irp);
|
||||
}
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSReadSync(
|
||||
IN PFFS_VCB Vcb,
|
||||
IN ULONGLONG Offset,
|
||||
IN ULONG Length,
|
||||
OUT PVOID Buffer,
|
||||
IN BOOLEAN bVerify)
|
||||
{
|
||||
KEVENT Event;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
ASSERT(Vcb->TargetDeviceObject != NULL);
|
||||
ASSERT(Buffer != NULL);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildSynchronousFsdRequest(
|
||||
IRP_MJ_READ,
|
||||
Vcb->TargetDeviceObject,
|
||||
Buffer,
|
||||
Length,
|
||||
(PLARGE_INTEGER)(&Offset),
|
||||
&Event,
|
||||
&IoStatus);
|
||||
|
||||
if (!Irp)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (bVerify)
|
||||
{
|
||||
SetFlag(IoGetNextIrpStackLocation(Irp)->Flags,
|
||||
SL_OVERRIDE_VERIFY_VOLUME);
|
||||
}
|
||||
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(
|
||||
&Event,
|
||||
Suspended,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSReadDisk(
|
||||
IN PFFS_VCB Vcb,
|
||||
IN ULONGLONG Offset,
|
||||
IN ULONG Size,
|
||||
IN PVOID Buffer,
|
||||
IN BOOLEAN bVerify)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PUCHAR Buf;
|
||||
ULONG Length;
|
||||
ULONGLONG Lba;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Lba = Offset & (~((ULONGLONG)SECTOR_SIZE - 1));
|
||||
Length = (ULONG)(Size + Offset + SECTOR_SIZE - 1 - Lba) &
|
||||
(~((ULONG)SECTOR_SIZE - 1));
|
||||
|
||||
Buf = ExAllocatePoolWithTag(PagedPool, Length, FFS_POOL_TAG);
|
||||
if (!Buf)
|
||||
{
|
||||
FFSPrint((DBG_ERROR, "FFSReadDisk: no enough memory.\n"));
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
Status = FFSReadSync(Vcb,
|
||||
Lba,
|
||||
Length,
|
||||
Buf,
|
||||
FALSE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSPrint((DBG_ERROR, "FFSReadDisk: Read Block Device error.\n"));
|
||||
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Buffer, &Buf[Offset - Lba], Size);
|
||||
|
||||
errorout:
|
||||
|
||||
if (Buf)
|
||||
ExFreePool(Buf);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSDiskIoControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG IoctlCode,
|
||||
IN PVOID InputBuffer,
|
||||
IN ULONG InputBufferSize,
|
||||
IN OUT PVOID OutputBuffer,
|
||||
IN OUT PULONG OutputBufferSize)
|
||||
{
|
||||
ULONG OutBufferSize = 0;
|
||||
KEVENT Event;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(DeviceObject != NULL);
|
||||
|
||||
if (OutputBufferSize)
|
||||
{
|
||||
OutBufferSize = *OutputBufferSize;
|
||||
}
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildDeviceIoControlRequest(
|
||||
IoctlCode,
|
||||
DeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferSize,
|
||||
OutputBuffer,
|
||||
OutBufferSize,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
|
||||
if (Irp == NULL)
|
||||
{
|
||||
FFSPrint((DBG_ERROR, "FFSDiskIoControl: Building IRQ error!\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
if (OutputBufferSize)
|
||||
{
|
||||
*OutputBufferSize = (ULONG) IoStatus.Information;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSMediaEjectControlCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Contxt)
|
||||
{
|
||||
PKEVENT Event = (PKEVENT)Contxt;
|
||||
|
||||
KeSetEvent(Event, 0, FALSE);
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
VOID
|
||||
FFSMediaEjectControl(
|
||||
IN PFFS_IRP_CONTEXT IrpContext,
|
||||
IN PFFS_VCB Vcb,
|
||||
IN BOOLEAN bPrevent)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PREVENT_MEDIA_REMOVAL Prevent;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource,
|
||||
TRUE);
|
||||
|
||||
if (bPrevent != IsFlagOn(Vcb->Flags, VCB_REMOVAL_PREVENTED))
|
||||
{
|
||||
if (bPrevent)
|
||||
{
|
||||
SetFlag(Vcb->Flags, VCB_REMOVAL_PREVENTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearFlag(Vcb->Flags, VCB_REMOVAL_PREVENTED);
|
||||
}
|
||||
}
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
Prevent.PreventMediaRemoval = bPrevent;
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_MEDIA_REMOVAL,
|
||||
Vcb->TargetDeviceObject,
|
||||
&Prevent,
|
||||
sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
NULL,
|
||||
&IoStatus);
|
||||
|
||||
if (Irp != NULL)
|
||||
{
|
||||
IoSetCompletionRoutine(Irp,
|
||||
FFSMediaEjectControlCompletion,
|
||||
&Event,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSDiskShutDown(
|
||||
PFFS_VCB Vcb)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
|
||||
Vcb->TargetDeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
|
||||
if (Irp)
|
||||
{
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
@ -1,380 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* cleanup.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSCleanup)
|
||||
#endif
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSCleanup(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PFFS_VCB Vcb = 0;
|
||||
BOOLEAN VcbResourceAcquired = FALSE;
|
||||
PFILE_OBJECT FileObject;
|
||||
PFFS_FCB Fcb = 0;
|
||||
BOOLEAN FcbResourceAcquired = FALSE;
|
||||
BOOLEAN FcbPagingIoAcquired = FALSE;
|
||||
PFFS_CCB Ccb;
|
||||
PIRP Irp;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
|
||||
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
|
||||
|
||||
if (!IsFlagOn(Vcb->Flags, VCB_INITIALIZED))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28137, "by design" )
|
||||
#endif
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
VcbResourceAcquired = TRUE;
|
||||
|
||||
FileObject = IrpContext->FileObject;
|
||||
|
||||
Fcb = (PFFS_FCB)FileObject->FsContext;
|
||||
|
||||
if (!Fcb)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
if (Fcb->Identifier.Type == FFSVCB)
|
||||
{
|
||||
if (IsFlagOn(Vcb->Flags, VCB_VOLUME_LOCKED) &&
|
||||
(Vcb->LockFile == FileObject))
|
||||
{
|
||||
ClearFlag(Vcb->Flags, VCB_VOLUME_LOCKED);
|
||||
Vcb->LockFile = NULL;
|
||||
|
||||
FFSClearVpbFlag(Vcb->Vpb, VPB_LOCKED);
|
||||
}
|
||||
|
||||
Vcb->OpenHandleCount--;
|
||||
|
||||
if (!Vcb->OpenHandleCount)
|
||||
{
|
||||
IoRemoveShareAccess(FileObject, &Vcb->ShareAccess);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
/*
|
||||
if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) &&
|
||||
!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE))
|
||||
*/
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28137, "by design" )
|
||||
#endif
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&Fcb->MainResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FcbResourceAcquired = TRUE;
|
||||
}
|
||||
|
||||
Ccb = (PFFS_CCB)FileObject->FsContext2;
|
||||
|
||||
if (!Ccb)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
if (IsFlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE))
|
||||
{
|
||||
if (IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) &&
|
||||
IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK) &&
|
||||
!IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
|
||||
{
|
||||
Status = FFSFlushFile(Fcb);
|
||||
}
|
||||
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ASSERT((Ccb->Identifier.Type == FFSCCB) &&
|
||||
(Ccb->Identifier.Size == sizeof(FFS_CCB)));
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
Fcb->OpenHandleCount--;
|
||||
|
||||
if (!IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED))
|
||||
{
|
||||
Fcb->NonCachedOpenCount--;
|
||||
}
|
||||
|
||||
Vcb->OpenFileHandleCount--;
|
||||
|
||||
if (IsFlagOn(Fcb->Flags, FCB_DELETE_ON_CLOSE))
|
||||
{
|
||||
SetFlag(Fcb->Flags, FCB_DELETE_PENDING);
|
||||
|
||||
if (IsDirectory(Fcb))
|
||||
{
|
||||
FsRtlNotifyFullChangeDirectory(
|
||||
Vcb->NotifySync,
|
||||
&Vcb->NotifyList,
|
||||
Fcb,
|
||||
NULL,
|
||||
FALSE,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDirectory(Fcb))
|
||||
{
|
||||
FsRtlNotifyCleanup(
|
||||
Vcb->NotifySync,
|
||||
&Vcb->NotifyList,
|
||||
Ccb);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Drop any byte range locks this process may have on the file.
|
||||
//
|
||||
FsRtlFastUnlockAll(
|
||||
&Fcb->FileLockAnchor,
|
||||
FileObject,
|
||||
IoGetRequestorProcess(Irp),
|
||||
NULL);
|
||||
|
||||
//
|
||||
// If there are no byte range locks owned by other processes on the
|
||||
// file the fast I/O read/write functions doesn't have to check for
|
||||
// locks so we set IsFastIoPossible to FastIoIsPossible again.
|
||||
//
|
||||
if (!FsRtlGetNextFileLock(&Fcb->FileLockAnchor, TRUE))
|
||||
{
|
||||
if (Fcb->Header.IsFastIoPossible != FastIoIsPossible)
|
||||
{
|
||||
FFSPrint((
|
||||
DBG_INFO, ": %-16.16s %-31s %s\n",
|
||||
FFSGetCurrentProcessName(),
|
||||
"FastIoIsPossible",
|
||||
Fcb->AnsiFileName.Buffer));
|
||||
|
||||
Fcb->Header.IsFastIoPossible = FastIoIsPossible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsFlagOn(FileObject->Flags, FO_CACHE_SUPPORTED) &&
|
||||
(Fcb->NonCachedOpenCount != 0) &&
|
||||
(Fcb->NonCachedOpenCount == Fcb->ReferenceCount) &&
|
||||
(Fcb->SectionObject.DataSectionObject != NULL))
|
||||
{
|
||||
|
||||
if(!IsFlagOn(Vcb->Flags, VCB_READ_ONLY) &&
|
||||
!IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
|
||||
{
|
||||
CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
ExAcquireResourceExclusiveLite(&(Fcb->PagingIoResource), TRUE);
|
||||
ExReleaseResourceLite(&(Fcb->PagingIoResource));
|
||||
|
||||
CcPurgeCacheSection(&Fcb->SectionObject,
|
||||
NULL,
|
||||
0,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
#if !FFS_READ_ONLY
|
||||
if (Fcb->OpenHandleCount == 0)
|
||||
{
|
||||
if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING))
|
||||
{
|
||||
BOOLEAN bDeleted = FALSE;
|
||||
|
||||
//
|
||||
// Have to delete this file...
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28137, "by design" )
|
||||
#endif
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&Fcb->PagingIoResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FcbPagingIoAcquired = TRUE;
|
||||
|
||||
bDeleted = FFSDeleteFile(IrpContext, Vcb, Fcb);
|
||||
|
||||
if (bDeleted)
|
||||
{
|
||||
if (IsDirectory(Fcb))
|
||||
{
|
||||
FFSNotifyReportChange(IrpContext, Vcb, Fcb,
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME,
|
||||
FILE_ACTION_REMOVED);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFSNotifyReportChange(IrpContext, Vcb, Fcb,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||
FILE_ACTION_REMOVED);
|
||||
}
|
||||
}
|
||||
|
||||
if (FcbPagingIoAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Fcb->PagingIoResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
FcbPagingIoAcquired = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
if (bDeleted)
|
||||
{
|
||||
FFSPurgeFile(Fcb, FALSE);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif // !FFS_READ_ONLY
|
||||
|
||||
if (!IsDirectory(Fcb) && FileObject->PrivateCacheMap)
|
||||
{
|
||||
FFSPrint((DBG_INFO, "FFSCleanup: CcUninitializeCacheMap is called for %s.\n",
|
||||
Fcb->AnsiFileName.Buffer));
|
||||
|
||||
CcUninitializeCacheMap(
|
||||
FileObject,
|
||||
(PLARGE_INTEGER)(&(Fcb->Header.FileSize)),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!Fcb->OpenHandleCount)
|
||||
{
|
||||
IoRemoveShareAccess(FileObject, &Fcb->ShareAccess);
|
||||
}
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSCleanup: OpenCount: %u ReferCount: %u %s\n",
|
||||
Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->AnsiFileName.Buffer));
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
if (FileObject)
|
||||
{
|
||||
SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
|
||||
if (FcbPagingIoAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Fcb->PagingIoResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (FcbResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Fcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (VcbResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
FFSQueueRequest(IrpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
IrpContext->Irp->IoStatus.Status = Status;
|
||||
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
@ -1,342 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* close.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSClose)
|
||||
#pragma alloc_text(PAGE, FFSQueueCloseRequest)
|
||||
#pragma alloc_text(PAGE, FFSDeQueueCloseRequest)
|
||||
#endif
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSClose(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PFFS_VCB Vcb = 0;
|
||||
BOOLEAN VcbResourceAcquired = FALSE;
|
||||
PFILE_OBJECT FileObject;
|
||||
PFFS_FCB Fcb = 0;
|
||||
BOOLEAN FcbResourceAcquired = FALSE;
|
||||
PFFS_CCB Ccb;
|
||||
BOOLEAN FreeVcb = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Vcb = (PFFS_VCB) DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
|
||||
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
|
||||
|
||||
ASSERT(IsMounted(Vcb));
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
FFSPrint((DBG_INFO, "FFSClose: PENDING ... Vcb: %xh/%xh\n",
|
||||
Vcb->OpenFileHandleCount, Vcb->ReferenceCount));
|
||||
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
VcbResourceAcquired = TRUE;
|
||||
|
||||
FileObject = IrpContext->FileObject;
|
||||
|
||||
if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE))
|
||||
{
|
||||
Fcb = IrpContext->Fcb;
|
||||
Ccb = IrpContext->Ccb;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fcb = (PFFS_FCB)FileObject->FsContext;
|
||||
|
||||
if (!Fcb)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
Ccb = (PFFS_CCB)FileObject->FsContext2;
|
||||
}
|
||||
|
||||
if (Fcb->Identifier.Type == FFSVCB)
|
||||
{
|
||||
Vcb->ReferenceCount--;
|
||||
|
||||
if (!Vcb->ReferenceCount && FlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
|
||||
{
|
||||
FreeVcb = TRUE;
|
||||
}
|
||||
|
||||
if (Ccb)
|
||||
{
|
||||
FFSFreeCcb(Ccb);
|
||||
if (FileObject)
|
||||
{
|
||||
FileObject->FsContext2 = Ccb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
if (Fcb->Identifier.Type != FFSFCB || Fcb->Identifier.Size != sizeof(FFS_FCB))
|
||||
{
|
||||
#if DBG
|
||||
FFSPrint((DBG_ERROR, "FFSClose: Strange IRP_MJ_CLOSE by system!\n"));
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&FFSGlobal->CountResource,
|
||||
TRUE);
|
||||
|
||||
FFSGlobal->IRPCloseCount++;
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&FFSGlobal->CountResource,
|
||||
ExGetCurrentResourceThread());
|
||||
#endif
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
/*
|
||||
if ((!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) &&
|
||||
(!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)))
|
||||
*/
|
||||
{
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&Fcb->MainResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FcbResourceAcquired = TRUE;
|
||||
}
|
||||
|
||||
if (!Ccb)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ASSERT((Ccb->Identifier.Type == FFSCCB) &&
|
||||
(Ccb->Identifier.Size == sizeof(FFS_CCB)));
|
||||
|
||||
Fcb->ReferenceCount--;
|
||||
Vcb->ReferenceCount--;
|
||||
|
||||
if (!Vcb->ReferenceCount && IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
|
||||
{
|
||||
FreeVcb = TRUE;
|
||||
}
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSClose: OpenHandleCount: %u ReferenceCount: %u %s\n",
|
||||
Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->AnsiFileName.Buffer));
|
||||
|
||||
if (Ccb)
|
||||
{
|
||||
FFSFreeCcb(Ccb);
|
||||
|
||||
if (FileObject)
|
||||
{
|
||||
FileObject->FsContext2 = Ccb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Fcb->ReferenceCount)
|
||||
{
|
||||
//
|
||||
// Remove Fcb from Vcb->FcbList ...
|
||||
//
|
||||
|
||||
RemoveEntryList(&Fcb->Next);
|
||||
|
||||
FFSFreeFcb(Fcb);
|
||||
|
||||
FcbResourceAcquired = FALSE;
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (FcbResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Fcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (VcbResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
FFSQueueCloseRequest(IrpContext);
|
||||
#if 0
|
||||
/*
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
if (IrpContext->Irp != NULL)
|
||||
{
|
||||
IrpContext->Irp->IoStatus.Status = Status;
|
||||
|
||||
FFSCompleteRequest(
|
||||
IrpContext->Irp,
|
||||
(BOOLEAN)!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED),
|
||||
(CCHAR)
|
||||
(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
|
||||
if (FreeVcb)
|
||||
{
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&FFSGlobal->Resource, TRUE);
|
||||
|
||||
FFSClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);
|
||||
|
||||
FFSRemoveVcb(Vcb);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&FFSGlobal->Resource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
FFSFreeVcb(Vcb);
|
||||
}
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
FFSQueueCloseRequest(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
if (!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE))
|
||||
{
|
||||
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE);
|
||||
|
||||
IrpContext->Fcb = (PFFS_FCB)IrpContext->FileObject->FsContext;
|
||||
IrpContext->Ccb = (PFFS_CCB)IrpContext->FileObject->FsContext2;
|
||||
|
||||
IrpContext->FileObject = NULL;
|
||||
}
|
||||
|
||||
// IsSynchronous means we can block (so we don't requeue it)
|
||||
IrpContext->IsSynchronous = TRUE;
|
||||
|
||||
ExInitializeWorkItem(
|
||||
&IrpContext->WorkQueueItem,
|
||||
FFSDeQueueCloseRequest,
|
||||
IrpContext);
|
||||
|
||||
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
|
||||
}
|
||||
|
||||
|
||||
VOID NTAPI
|
||||
FFSDeQueueCloseRequest(
|
||||
IN PVOID Context)
|
||||
{
|
||||
PFFS_IRP_CONTEXT IrpContext;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IrpContext = (PFFS_IRP_CONTEXT) Context;
|
||||
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
FsRtlEnterFileSystem();
|
||||
FFSClose(IrpContext);
|
||||
}
|
||||
_SEH2_EXCEPT (FFSExceptionFilter(IrpContext, _SEH2_GetExceptionInformation()))
|
||||
{
|
||||
FFSExceptionHandler(IrpContext);
|
||||
} _SEH2_END;
|
||||
}
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
FsRtlExitFileSystem();
|
||||
} _SEH2_END;
|
||||
}
|
@ -1,218 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* cmcb.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSAcquireForLazyWrite)
|
||||
#pragma alloc_text(PAGE, FFSReleaseFromLazyWrite)
|
||||
#pragma alloc_text(PAGE, FFSAcquireForReadAhead)
|
||||
#pragma alloc_text(PAGE, FFSReleaseFromReadAhead)
|
||||
#pragma alloc_text(PAGE, FFSNoOpAcquire)
|
||||
#pragma alloc_text(PAGE, FFSNoOpRelease)
|
||||
#endif
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
BOOLEAN NTAPI
|
||||
FFSAcquireForLazyWrite(
|
||||
IN PVOID Context,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
//
|
||||
// On a readonly filesystem this function still has to exist but it
|
||||
// doesn't need to do anything.
|
||||
|
||||
PFFS_FCB Fcb;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Fcb = (PFFS_FCB)Context;
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSAcquireForLazyWrite: %s %s %s\n",
|
||||
FFSGetCurrentProcessName(),
|
||||
"ACQUIRE_FOR_LAZY_WRITE",
|
||||
Fcb->AnsiFileName.Buffer));
|
||||
|
||||
|
||||
if (!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
|
||||
{
|
||||
FFSPrint((DBG_INFO, "FFSAcquireForLazyWrite: Inode=%xh %S\n",
|
||||
Fcb->FFSMcb->Inode, Fcb->FFSMcb->ShortName.Buffer));
|
||||
|
||||
if(!ExAcquireResourceSharedLite(
|
||||
&Fcb->PagingIoResource, Wait))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(IoGetTopLevelIrp() == NULL);
|
||||
|
||||
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
VOID NTAPI
|
||||
FFSReleaseFromLazyWrite(
|
||||
IN PVOID Context)
|
||||
{
|
||||
//
|
||||
// On a readonly filesystem this function still has to exist but it
|
||||
// doesn't need to do anything.
|
||||
PFFS_FCB Fcb;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Fcb = (PFFS_FCB)Context;
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSReleaseFromLazyWrite: %s %s %s\n",
|
||||
FFSGetCurrentProcessName(),
|
||||
"RELEASE_FROM_LAZY_WRITE",
|
||||
Fcb->AnsiFileName.Buffer));
|
||||
|
||||
if (!IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY))
|
||||
{
|
||||
FFSPrint((DBG_INFO, "FFSReleaseFromLazyWrite: Inode=%xh %S\n",
|
||||
Fcb->FFSMcb->Inode, Fcb->FFSMcb->ShortName.Buffer));
|
||||
|
||||
ExReleaseResourceLite(&Fcb->PagingIoResource);
|
||||
}
|
||||
|
||||
ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
|
||||
IoSetTopLevelIrp(NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
BOOLEAN NTAPI
|
||||
FFSAcquireForReadAhead(
|
||||
IN PVOID Context,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
PFFS_FCB Fcb;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Fcb = (PFFS_FCB)Context;
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSAcquireForReadAhead: Inode=%xh %S\n",
|
||||
Fcb->FFSMcb->Inode, Fcb->FFSMcb->ShortName.Buffer));
|
||||
|
||||
if (!ExAcquireResourceSharedLite(
|
||||
&Fcb->MainResource, Wait))
|
||||
return FALSE;
|
||||
|
||||
ASSERT(IoGetTopLevelIrp() == NULL);
|
||||
|
||||
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
VOID NTAPI
|
||||
FFSReleaseFromReadAhead(
|
||||
IN PVOID Context)
|
||||
{
|
||||
PFFS_FCB Fcb;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Fcb = (PFFS_FCB)Context;
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSReleaseFromReadAhead: Inode=%xh %S\n",
|
||||
Fcb->FFSMcb->Inode, Fcb->FFSMcb->ShortName.Buffer));
|
||||
|
||||
IoSetTopLevelIrp(NULL);
|
||||
|
||||
ExReleaseResourceLite(&Fcb->MainResource);
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN NTAPI
|
||||
FFSNoOpAcquire(
|
||||
IN PVOID Fcb,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Fcb);
|
||||
UNREFERENCED_PARAMETER(Wait);
|
||||
|
||||
//
|
||||
// This is a kludge because Cc is really the top level. We it
|
||||
// enters the file system, we will think it is a resursive call
|
||||
// and complete the request with hard errors or verify. It will
|
||||
// have to deal with them, somehow....
|
||||
//
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(IoGetTopLevelIrp() == NULL);
|
||||
|
||||
IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID NTAPI
|
||||
FFSNoOpRelease(
|
||||
IN PVOID Fcb)
|
||||
{
|
||||
//
|
||||
// Clear the kludge at this point.
|
||||
//
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
|
||||
|
||||
IoSetTopLevelIrp(NULL);
|
||||
|
||||
UNREFERENCED_PARAMETER(Fcb);
|
||||
|
||||
return;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,302 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* devctl.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef _PREFAST_
|
||||
IO_COMPLETION_ROUTINE FFSDeviceControlCompletion;
|
||||
#endif // _PREFAST_
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSDeviceControlCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context);
|
||||
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSDeviceControl)
|
||||
#pragma alloc_text(PAGE, FFSDeviceControlNormal)
|
||||
#if FFS_UNLOAD
|
||||
#pragma alloc_text(PAGE, FFSPrepareToUnload)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSDeviceControlCompletion(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSDeviceControlNormal(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
BOOLEAN CompleteRequest = TRUE;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
PFFS_VCB Vcb;
|
||||
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
PIO_STACK_LOCATION NextIrpSp;
|
||||
|
||||
PDEVICE_OBJECT TargetDeviceObject;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
CompleteRequest = TRUE;
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Vcb = (PFFS_VCB)IrpSp->FileObject->FsContext;
|
||||
|
||||
if (!((Vcb) && (Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB))
|
||||
)
|
||||
)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
TargetDeviceObject = Vcb->TargetDeviceObject;
|
||||
|
||||
//
|
||||
// Pass on the IOCTL to the driver below
|
||||
//
|
||||
|
||||
CompleteRequest = FALSE;
|
||||
|
||||
NextIrpSp = IoGetNextIrpStackLocation(Irp);
|
||||
*NextIrpSp = *IrpSp;
|
||||
|
||||
IoSetCompletionRoutine(
|
||||
Irp,
|
||||
FFSDeviceControlCompletion,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
Status = IoCallDriver(TargetDeviceObject, Irp);
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (IrpContext)
|
||||
{
|
||||
if (!CompleteRequest)
|
||||
{
|
||||
IrpContext->Irp = NULL;
|
||||
}
|
||||
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
#if FFS_UNLOAD
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSPrepareToUnload(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
BOOLEAN GlobalDataResourceAcquired = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
if (DeviceObject != FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&FFSGlobal->Resource,
|
||||
TRUE);
|
||||
|
||||
GlobalDataResourceAcquired = TRUE;
|
||||
|
||||
if (FlagOn(FFSGlobal->Flags, FFS_UNLOAD_PENDING))
|
||||
{
|
||||
FFSPrint((DBG_ERROR, "FFSPrepareUnload: Already ready to unload.\n"));
|
||||
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
{
|
||||
PFFS_VCB Vcb;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
ListEntry = FFSGlobal->VcbList.Flink;
|
||||
|
||||
while (ListEntry != &(FFSGlobal->VcbList))
|
||||
{
|
||||
Vcb = CONTAINING_RECORD(ListEntry, FFS_VCB, Next);
|
||||
ListEntry = ListEntry->Flink;
|
||||
|
||||
if (Vcb && (!Vcb->ReferenceCount) &&
|
||||
IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
|
||||
{
|
||||
FFSRemoveVcb(Vcb);
|
||||
FFSClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);
|
||||
|
||||
FFSFreeVcb(Vcb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsListEmpty(&(FFSGlobal->VcbList)))
|
||||
{
|
||||
|
||||
FFSPrint((DBG_ERROR, "FFSPrepareUnload: Mounted volumes exists.\n"));
|
||||
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
IoUnregisterFileSystem(FFSGlobal->DeviceObject);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28175, "allowed to unload" )
|
||||
#endif
|
||||
FFSGlobal->DriverObject->DriverUnload = DriverUnload;
|
||||
|
||||
SetFlag(FFSGlobal->Flags, FFS_UNLOAD_PENDING);
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSPrepareToUnload: Driver is ready to unload.\n"));
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (GlobalDataResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&FFSGlobal->Resource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSDeviceControl(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
ULONG IoControlCode;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
IoControlCode =
|
||||
IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
|
||||
|
||||
switch (IoControlCode)
|
||||
{
|
||||
#if FFS_UNLOAD
|
||||
case IOCTL_PREPARE_TO_UNLOAD:
|
||||
Status = FFSPrepareToUnload(IrpContext);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case IOCTL_SELECT_BSD_PARTITION:
|
||||
Status = FFSSelectBSDPartition(IrpContext);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = FFSDeviceControlNormal(IrpContext);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,252 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* dipatch.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSQueueRequest)
|
||||
#pragma alloc_text(PAGE, FFSDeQueueRequest)
|
||||
#pragma alloc_text(PAGE, FFSDispatchRequest)
|
||||
#pragma alloc_text(PAGE, FFSBuildRequest)
|
||||
#endif
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSQueueRequest(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
// IsSynchronous means we can block (so we don't requeue it)
|
||||
IrpContext->IsSynchronous = TRUE;
|
||||
|
||||
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
|
||||
|
||||
IoMarkIrpPending(IrpContext->Irp);
|
||||
|
||||
ExInitializeWorkItem(
|
||||
&IrpContext->WorkQueueItem,
|
||||
FFSDeQueueRequest,
|
||||
IrpContext);
|
||||
|
||||
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
|
||||
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
|
||||
VOID NTAPI
|
||||
FFSDeQueueRequest(
|
||||
IN PVOID Context)
|
||||
{
|
||||
PFFS_IRP_CONTEXT IrpContext;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IrpContext = (PFFS_IRP_CONTEXT) Context;
|
||||
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
FsRtlEnterFileSystem();
|
||||
|
||||
if (!IrpContext->IsTopLevel)
|
||||
{
|
||||
IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
|
||||
}
|
||||
|
||||
FFSDispatchRequest(IrpContext);
|
||||
}
|
||||
_SEH2_EXCEPT (FFSExceptionFilter(IrpContext, _SEH2_GetExceptionInformation()))
|
||||
{
|
||||
FFSExceptionHandler(IrpContext);
|
||||
} _SEH2_END;
|
||||
}
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
IoSetTopLevelIrp(NULL);
|
||||
|
||||
FsRtlExitFileSystem();
|
||||
} _SEH2_END;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSDispatchRequest(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
switch (IrpContext->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
return FFSCreate(IrpContext);
|
||||
|
||||
case IRP_MJ_CLOSE:
|
||||
return FFSClose(IrpContext);
|
||||
|
||||
case IRP_MJ_READ:
|
||||
return FFSRead(IrpContext);
|
||||
|
||||
#if !FFS_READ_ONLY
|
||||
case IRP_MJ_WRITE:
|
||||
return FFSWrite(IrpContext);
|
||||
#endif // !FFS_READ_ONLY
|
||||
|
||||
case IRP_MJ_FLUSH_BUFFERS:
|
||||
return FFSFlush(IrpContext);
|
||||
|
||||
case IRP_MJ_QUERY_INFORMATION:
|
||||
return FFSQueryInformation(IrpContext);
|
||||
|
||||
case IRP_MJ_SET_INFORMATION:
|
||||
return FFSSetInformation(IrpContext);
|
||||
|
||||
case IRP_MJ_QUERY_VOLUME_INFORMATION:
|
||||
return FFSQueryVolumeInformation(IrpContext);
|
||||
|
||||
#if !FFS_READ_ONLY
|
||||
case IRP_MJ_SET_VOLUME_INFORMATION:
|
||||
return FFSSetVolumeInformation(IrpContext);
|
||||
#endif // !FFS_READ_ONLY
|
||||
|
||||
case IRP_MJ_DIRECTORY_CONTROL:
|
||||
return FFSDirectoryControl(IrpContext);
|
||||
|
||||
case IRP_MJ_FILE_SYSTEM_CONTROL:
|
||||
return FFSFileSystemControl(IrpContext);
|
||||
|
||||
case IRP_MJ_DEVICE_CONTROL:
|
||||
return FFSDeviceControl(IrpContext);
|
||||
|
||||
case IRP_MJ_LOCK_CONTROL:
|
||||
return FFSLockControl(IrpContext);
|
||||
|
||||
case IRP_MJ_CLEANUP:
|
||||
return FFSCleanup(IrpContext);
|
||||
|
||||
case IRP_MJ_SHUTDOWN:
|
||||
return FFSShutDown(IrpContext);
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
case IRP_MJ_PNP:
|
||||
return FFSPnp(IrpContext);
|
||||
#endif //(_WIN32_WINNT >= 0x0500)
|
||||
default:
|
||||
FFSPrint((DBG_ERROR, "FFSDispatchRequest: Unexpected major function: %xh\n",
|
||||
IrpContext->MajorFunction));
|
||||
|
||||
FFSCompleteIrpContext(IrpContext, STATUS_DRIVER_INTERNAL_ERROR);
|
||||
|
||||
return STATUS_DRIVER_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSBuildRequest(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
BOOLEAN AtIrqlPassiveLevel = FALSE;
|
||||
BOOLEAN IsTopLevelIrp = FALSE;
|
||||
PFFS_IRP_CONTEXT IrpContext = NULL;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
_SEH2_TRY
|
||||
{
|
||||
#if DBG
|
||||
FFSDbgPrintCall(DeviceObject, Irp);
|
||||
#endif
|
||||
|
||||
AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
|
||||
if (AtIrqlPassiveLevel)
|
||||
{
|
||||
FsRtlEnterFileSystem();
|
||||
}
|
||||
|
||||
if (!IoGetTopLevelIrp())
|
||||
{
|
||||
IsTopLevelIrp = TRUE;
|
||||
IoSetTopLevelIrp(Irp);
|
||||
}
|
||||
|
||||
IrpContext = FFSAllocateIrpContext(DeviceObject, Irp);
|
||||
|
||||
if (!IrpContext)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
||||
FFSCompleteRequest(Irp, TRUE, IO_NO_INCREMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
|
||||
!AtIrqlPassiveLevel)
|
||||
{
|
||||
FFSBreakPoint();
|
||||
}
|
||||
|
||||
Status = FFSDispatchRequest(IrpContext);
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT (FFSExceptionFilter(IrpContext, _SEH2_GetExceptionInformation()))
|
||||
{
|
||||
Status = FFSExceptionHandler(IrpContext);
|
||||
} _SEH2_END;
|
||||
}
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (IsTopLevelIrp)
|
||||
{
|
||||
IoSetTopLevelIrp(NULL);
|
||||
}
|
||||
|
||||
if (AtIrqlPassiveLevel)
|
||||
{
|
||||
FsRtlExitFileSystem();
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* except.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
//#pragma alloc_text(PAGE, FFSExceptionFilter)
|
||||
//#pragma alloc_text(PAGE, FFSExceptionHandler)
|
||||
#endif
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSExceptionFilter(
|
||||
IN PFFS_IRP_CONTEXT IrpContext,
|
||||
IN PEXCEPTION_POINTERS ExceptionPointer)
|
||||
{
|
||||
NTSTATUS Status, ExceptionCode;
|
||||
PEXCEPTION_RECORD ExceptRecord;
|
||||
|
||||
ExceptRecord = ExceptionPointer->ExceptionRecord;
|
||||
|
||||
ExceptionCode = ExceptRecord->ExceptionCode;
|
||||
|
||||
FFSBreakPoint();
|
||||
|
||||
//
|
||||
// Check IrpContext is valid or not
|
||||
//
|
||||
|
||||
if (IrpContext)
|
||||
{
|
||||
if ((IrpContext->Identifier.Type != FFSICX) ||
|
||||
(IrpContext->Identifier.Size != sizeof(FFS_IRP_CONTEXT)))
|
||||
{
|
||||
IrpContext = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FsRtlIsNtstatusExpected(ExceptionCode))
|
||||
{
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
else
|
||||
{
|
||||
FFSBugCheck(FFS_BUGCHK_EXCEPT, (ULONG_PTR)ExceptRecord,
|
||||
(ULONG_PTR)ExceptionPointer->ContextRecord,
|
||||
(ULONG_PTR)ExceptRecord->ExceptionAddress);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// For the purposes of processing this exception, let's mark this
|
||||
// request as being able to wait, and neither write through nor on
|
||||
// removable media if we aren't posting it.
|
||||
//
|
||||
|
||||
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
|
||||
|
||||
if (FsRtlIsNtstatusExpected(ExceptionCode))
|
||||
{
|
||||
//
|
||||
// If the exception is expected execute our handler
|
||||
//
|
||||
|
||||
FFSPrint((DBG_ERROR, "FFSExceptionFilter: Catching exception %xh\n",
|
||||
ExceptionCode));
|
||||
|
||||
Status = EXCEPTION_EXECUTE_HANDLER;
|
||||
|
||||
if (IrpContext)
|
||||
{
|
||||
IrpContext->ExceptionInProgress = TRUE;
|
||||
IrpContext->ExceptionCode = ExceptionCode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Continue search for an higher level exception handler
|
||||
//
|
||||
|
||||
FFSPrint((DBG_ERROR, "FFSExceptionFilter: Passing on exception %#x\n",
|
||||
ExceptionCode));
|
||||
|
||||
Status = EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
if (IrpContext)
|
||||
{
|
||||
FFSFreeIrpContext(IrpContext);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSExceptionHandler(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
FFSBreakPoint();
|
||||
|
||||
if (IrpContext)
|
||||
{
|
||||
if ((IrpContext->Identifier.Type != FFSICX) ||
|
||||
(IrpContext->Identifier.Size != sizeof(FFS_IRP_CONTEXT)))
|
||||
{
|
||||
FFSBreakPoint();
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
Status = IrpContext->ExceptionCode;
|
||||
|
||||
if (IrpContext->Irp)
|
||||
{
|
||||
//
|
||||
// Check if this error is a result of user actions
|
||||
//
|
||||
|
||||
PIRP Irp = IrpContext->Irp;
|
||||
|
||||
|
||||
if (IoIsErrorUserInduced(Status))
|
||||
{
|
||||
//
|
||||
// Now we will generate a pop-up to user
|
||||
//
|
||||
|
||||
PDEVICE_OBJECT RealDevice;
|
||||
PVPB Vpb = NULL;
|
||||
PETHREAD Thread;
|
||||
|
||||
if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
|
||||
{
|
||||
Vpb = IoGetCurrentIrpStackLocation(Irp)->FileObject->Vpb;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the initial thread
|
||||
//
|
||||
|
||||
Thread = Irp->Tail.Overlay.Thread;
|
||||
RealDevice = IoGetDeviceToVerify(Thread);
|
||||
|
||||
if (RealDevice == NULL)
|
||||
{
|
||||
//
|
||||
// Get current thread
|
||||
//
|
||||
|
||||
Thread = PsGetCurrentThread();
|
||||
RealDevice = IoGetDeviceToVerify(Thread);
|
||||
|
||||
ASSERT(RealDevice != NULL);
|
||||
}
|
||||
|
||||
if (RealDevice != NULL)
|
||||
{
|
||||
//
|
||||
// Now we pop-up the error dialog ...
|
||||
//
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
IoRaiseHardError(Irp, Vpb, RealDevice);
|
||||
|
||||
IoSetDeviceToVerify(Thread, NULL);
|
||||
|
||||
Status = STATUS_PENDING;
|
||||
goto errorout;
|
||||
}
|
||||
}
|
||||
|
||||
IrpContext->Irp->IoStatus.Status = Status;
|
||||
|
||||
FFSCompleteRequest(IrpContext->Irp, FALSE, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
errorout:
|
||||
|
||||
FFSFreeIrpContext(IrpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,112 +0,0 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,5,3,0
|
||||
PRODUCTVERSION 0,5,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x9L
|
||||
#else
|
||||
FILEFLAGS 0x8L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x3L
|
||||
FILESUBTYPE 0x8L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "000004b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "PYRASIS.COM\0"
|
||||
VALUE "FileDescription", "FFS File System Driver for Windows\0"
|
||||
VALUE "FileVersion", "0, 5, 3, 0\0"
|
||||
VALUE "InternalName", "ffs\0"
|
||||
VALUE "LegalCopyright", "2004-2015 (C) Lee Jae-Hong. All rights reserved.\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "ffs.sys\0"
|
||||
VALUE "PrivateBuild", "2015.10.2\0"
|
||||
VALUE "ProductName", "FFS Driver\0"
|
||||
VALUE "ProductVersion", "0, 5, 3, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,312 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* flush.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSFlushFile)
|
||||
#pragma alloc_text(PAGE, FFSFlushFiles)
|
||||
#pragma alloc_text(PAGE, FFSFlushVolume)
|
||||
#pragma alloc_text(PAGE, FFSFlush)
|
||||
#endif
|
||||
|
||||
#ifdef _PREFAST_
|
||||
IO_COMPLETION_ROUTINE FFSFlushCompletionRoutine;
|
||||
#endif // _PREFAST_
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSFlushCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Contxt)
|
||||
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
IoMarkIrpPending(Irp);
|
||||
|
||||
|
||||
if (Irp->IoStatus.Status == STATUS_INVALID_DEVICE_REQUEST)
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSFlushFiles(
|
||||
IN PFFS_VCB Vcb,
|
||||
BOOLEAN bShutDown)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
PFFS_FCB Fcb;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
|
||||
IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
FFSPrint((DBG_INFO, "Flushing Files ...\n"));
|
||||
|
||||
// Flush all Fcbs in Vcb list queue.
|
||||
{
|
||||
for (ListEntry = Vcb->FcbList.Flink;
|
||||
ListEntry != &Vcb->FcbList;
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
Fcb = CONTAINING_RECORD(ListEntry, FFS_FCB, Next);
|
||||
|
||||
if (ExAcquireResourceExclusiveLite(
|
||||
&Fcb->MainResource,
|
||||
TRUE))
|
||||
{
|
||||
IoStatus.Status = FFSFlushFile(Fcb);
|
||||
#if 0
|
||||
/*
|
||||
if (bShutDown)
|
||||
IoStatus.Status = FFSPurgeFile(Fcb, TRUE);
|
||||
else
|
||||
IoStatus.Status = FFSFlushFile(Fcb);
|
||||
*/
|
||||
#endif
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Fcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IoStatus.Status;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSFlushVolume(
|
||||
IN PFFS_VCB Vcb,
|
||||
BOOLEAN bShutDown)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
|
||||
IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSFlushVolume: Flushing Vcb ...\n"));
|
||||
|
||||
ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
|
||||
ExReleaseResourceLite(&Vcb->PagingIoResource);
|
||||
|
||||
CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus);
|
||||
|
||||
return IoStatus.Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSFlushFile(
|
||||
IN PFFS_FCB Fcb)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
if (IsDirectory(Fcb))
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSFlushFile: Flushing File Inode=%xh %S ...\n",
|
||||
Fcb->FFSMcb->Inode, Fcb->FFSMcb->ShortName.Buffer));
|
||||
/*
|
||||
{
|
||||
ULONG ResShCnt, ResExCnt;
|
||||
ResShCnt = ExIsResourceAcquiredSharedLite(&Fcb->PagingIoResource);
|
||||
ResExCnt = ExIsResourceAcquiredExclusiveLite(&Fcb->PagingIoResource);
|
||||
|
||||
FFSPrint((DBG_INFO, "FFSFlushFile: PagingIoRes: %xh:%xh\n", ResShCnt, ResExCnt));
|
||||
}
|
||||
*/
|
||||
CcFlushCache(&(Fcb->SectionObject), NULL, 0, &IoStatus);
|
||||
|
||||
ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
|
||||
|
||||
return IoStatus.Status;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSFlush(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
PFFS_VCB Vcb = 0;
|
||||
PFFS_FCBVCB FcbOrVcb = 0;
|
||||
PFILE_OBJECT FileObject;
|
||||
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
|
||||
BOOLEAN MainResourceAcquired = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
//
|
||||
// This request is not allowed on the main device object
|
||||
//
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
|
||||
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
|
||||
|
||||
ASSERT(IsMounted(Vcb));
|
||||
|
||||
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
|
||||
IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
FileObject = IrpContext->FileObject;
|
||||
|
||||
FcbOrVcb = (PFFS_FCBVCB)FileObject->FsContext;
|
||||
|
||||
ASSERT(FcbOrVcb != NULL);
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28137, "by design" )
|
||||
#endif
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&FcbOrVcb->MainResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
MainResourceAcquired = TRUE;
|
||||
|
||||
if (FcbOrVcb->Identifier.Type == FFSVCB)
|
||||
{
|
||||
Status = FFSFlushFiles((PFFS_VCB)(FcbOrVcb), FALSE);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Status = FFSFlushVolume((PFFS_VCB)(FcbOrVcb), FALSE);
|
||||
|
||||
if (NT_SUCCESS(Status) && IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED))
|
||||
{
|
||||
ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED);
|
||||
}
|
||||
}
|
||||
else if (FcbOrVcb->Identifier.Type == FFSFCB)
|
||||
{
|
||||
Status = FFSFlushFile((PFFS_FCB)(FcbOrVcb));
|
||||
|
||||
if (NT_SUCCESS(Status) && IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED))
|
||||
{
|
||||
ClearFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (MainResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&FcbOrVcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
|
||||
{
|
||||
// Call the disk driver to flush the physial media.
|
||||
NTSTATUS DriverStatus;
|
||||
PIO_STACK_LOCATION NextIrpSp;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
|
||||
NextIrpSp = IoGetNextIrpStackLocation(IrpContext->Irp);
|
||||
|
||||
*NextIrpSp = *IrpSp;
|
||||
|
||||
IoSetCompletionRoutine(IrpContext->Irp,
|
||||
FFSFlushCompletionRoutine,
|
||||
NULL,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
DriverStatus = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);
|
||||
|
||||
Status = (DriverStatus == STATUS_INVALID_DEVICE_REQUEST) ?
|
||||
Status : DriverStatus;
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
}
|
||||
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,453 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* init.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ntifs.h>
|
||||
#ifndef __REACTOS__
|
||||
#include <wdmsec.h>
|
||||
#endif
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
PFFS_GLOBAL FFSGlobal = NULL;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath);
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(INIT, FFSQueryParameters)
|
||||
#pragma alloc_text(INIT, DriverEntry)
|
||||
#if FFS_UNLOAD
|
||||
#pragma alloc_text(PAGE, DriverUnload)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if FFS_UNLOAD
|
||||
|
||||
/*
|
||||
* FUNCTION: Called by the system to unload the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RETURNS: None
|
||||
*/
|
||||
|
||||
VOID NTAPI
|
||||
DriverUnload(
|
||||
IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
UNICODE_STRING DosDeviceName;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
FFSPrint((DBG_FUNC, "ffsdrv: Unloading routine.\n"));
|
||||
|
||||
RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME);
|
||||
IoDeleteSymbolicLink(&DosDeviceName);
|
||||
|
||||
ExDeleteResourceLite(&FFSGlobal->LAResource);
|
||||
ExDeleteResourceLite(&FFSGlobal->CountResource);
|
||||
ExDeleteResourceLite(&FFSGlobal->Resource);
|
||||
|
||||
ExDeletePagedLookasideList(&(FFSGlobal->FFSMcbLookasideList));
|
||||
ExDeleteNPagedLookasideList(&(FFSGlobal->FFSCcbLookasideList));
|
||||
ExDeleteNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList));
|
||||
ExDeleteNPagedLookasideList(&(FFSGlobal->FFSIrpContextLookasideList));
|
||||
|
||||
IoDeleteDevice(FFSGlobal->DeviceObject);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BOOLEAN
|
||||
FFSQueryParameters(
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING ParameterPath;
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
|
||||
ULONG WritingSupport;
|
||||
ULONG CheckingBitmap;
|
||||
ULONG PartitionNumber;
|
||||
|
||||
ParameterPath.Length = 0;
|
||||
|
||||
ParameterPath.MaximumLength =
|
||||
RegistryPath->Length + sizeof(PARAMETERS_KEY) + sizeof(WCHAR);
|
||||
|
||||
ParameterPath.Buffer =
|
||||
(PWSTR) ExAllocatePoolWithTag(PagedPool, ParameterPath.MaximumLength, FFS_POOL_TAG);
|
||||
|
||||
if (!ParameterPath.Buffer)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WritingSupport = 0;
|
||||
CheckingBitmap = 0;
|
||||
PartitionNumber = 0;
|
||||
|
||||
RtlCopyUnicodeString(&ParameterPath, RegistryPath);
|
||||
|
||||
RtlAppendUnicodeToString(&ParameterPath, PARAMETERS_KEY);
|
||||
|
||||
RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
|
||||
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].Name = WRITING_SUPPORT;
|
||||
QueryTable[0].EntryContext = &WritingSupport;
|
||||
|
||||
Status = RtlQueryRegistryValues(
|
||||
RTL_REGISTRY_ABSOLUTE,
|
||||
ParameterPath.Buffer,
|
||||
&QueryTable[0],
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
FFSPrint((DBG_USER, "FFSQueryParameters: WritingSupport=%xh\n", WritingSupport));
|
||||
|
||||
RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
|
||||
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].Name = CHECKING_BITMAP;
|
||||
QueryTable[0].EntryContext = &CheckingBitmap;
|
||||
|
||||
Status = RtlQueryRegistryValues(
|
||||
RTL_REGISTRY_ABSOLUTE,
|
||||
ParameterPath.Buffer,
|
||||
&QueryTable[0],
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
FFSPrint((DBG_USER, "FFSQueryParameters: CheckingBitmap=%xh\n", CheckingBitmap));
|
||||
|
||||
RtlZeroMemory(&QueryTable[0], sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);
|
||||
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
|
||||
QueryTable[0].Name = PARTITION_NUMBER;
|
||||
QueryTable[0].EntryContext = &PartitionNumber;
|
||||
|
||||
Status = RtlQueryRegistryValues(
|
||||
RTL_REGISTRY_ABSOLUTE,
|
||||
ParameterPath.Buffer,
|
||||
&QueryTable[0],
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
FFSPrint((DBG_USER, "FFSQueryParameters: PartitionNumber=%xh\n", PartitionNumber));
|
||||
|
||||
{
|
||||
if (WritingSupport)
|
||||
{
|
||||
SetFlag(FFSGlobal->Flags, FFS_SUPPORT_WRITING);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearFlag(FFSGlobal->Flags, FFS_SUPPORT_WRITING);
|
||||
}
|
||||
|
||||
if (CheckingBitmap)
|
||||
{
|
||||
SetFlag(FFSGlobal->Flags, FFS_CHECKING_BITMAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearFlag(FFSGlobal->Flags, FFS_CHECKING_BITMAP);
|
||||
}
|
||||
|
||||
if (PartitionNumber)
|
||||
{
|
||||
FFSGlobal->PartitionNumber = PartitionNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ExFreePool(ParameterPath.Buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define NLS_OEM_LEAD_BYTE_INFO (*NlsOemLeadByteInfo)
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \
|
||||
(BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \
|
||||
(NLS_MB_CODE_PAGE_TAG && \
|
||||
(NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \
|
||||
)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* NAME: DriverEntry
|
||||
* FUNCTION: Called by the system to initalize the driver
|
||||
*
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PFAST_IO_DISPATCH FastIoDispatch;
|
||||
PCACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
|
||||
PFFS_EXT DeviceExt;
|
||||
UNICODE_STRING DeviceName;
|
||||
#ifndef __REACTOS__
|
||||
UNICODE_STRING Sddl;
|
||||
#endif
|
||||
NTSTATUS Status;
|
||||
#if FFS_UNLOAD
|
||||
UNICODE_STRING DosDeviceName;
|
||||
#endif
|
||||
|
||||
DbgPrint(
|
||||
"ffsdrv --"
|
||||
" Version "
|
||||
FFSDRV_VERSION
|
||||
#if FFS_READ_ONLY
|
||||
" (ReadOnly)"
|
||||
#endif // FFS_READ_ONLY
|
||||
#if DBG
|
||||
" Checked"
|
||||
#else
|
||||
" Free"
|
||||
#endif
|
||||
" - Built at "
|
||||
__DATE__" "
|
||||
__TIME__".\n");
|
||||
|
||||
FFSPrint((DBG_FUNC, "FFS DriverEntry ...\n"));
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
|
||||
#ifndef __REACTOS__
|
||||
RtlInitUnicodeString(&Sddl, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)");
|
||||
|
||||
Status = IoCreateDeviceSecure(
|
||||
DriverObject,
|
||||
sizeof(FFS_EXT),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_DISK_FILE_SYSTEM,
|
||||
0,
|
||||
FALSE,
|
||||
&Sddl,
|
||||
NULL,
|
||||
&DeviceObject);
|
||||
#else
|
||||
|
||||
Status = IoCreateDevice(
|
||||
DriverObject,
|
||||
sizeof(FFS_EXT),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_DISK_FILE_SYSTEM,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
#endif
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSPrint((DBG_ERROR, "IoCreateDevice fs object error.\n"));
|
||||
return Status;
|
||||
}
|
||||
|
||||
DeviceExt = (PFFS_EXT)DeviceObject->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExt, sizeof(FFS_EXT));
|
||||
|
||||
FFSGlobal = &(DeviceExt->FFSGlobal);
|
||||
|
||||
FFSGlobal->Identifier.Type = FFSFGD;
|
||||
FFSGlobal->Identifier.Size = sizeof(FFS_GLOBAL);
|
||||
FFSGlobal->DeviceObject = DeviceObject;
|
||||
FFSGlobal->DriverObject = DriverObject;
|
||||
FFSGlobal->PartitionNumber = 0;
|
||||
|
||||
FFSQueryParameters(RegistryPath);
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = FFSBuildRequest;
|
||||
#if !FFS_READ_ONLY
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FFSBuildRequest;
|
||||
#endif // !FFS_READ_ONLY
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FFSBuildRequest;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = FFSBuildRequest;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = FFSBuildRequest;
|
||||
#if !FFS_READ_ONLY
|
||||
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = FFSBuildRequest;
|
||||
#endif // !FFS_READ_ONLY
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FFSBuildRequest;
|
||||
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FFSBuildRequest;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FFSBuildRequest;
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = FFSBuildRequest;
|
||||
#endif //(_WIN32_WINNT >= 0x0500)
|
||||
|
||||
#if FFS_UNLOAD
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28175, "allowed to unload" )
|
||||
#endif
|
||||
DriverObject->DriverUnload = DriverUnload;
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28175, "allowed to unload" )
|
||||
#endif
|
||||
DriverObject->DriverUnload = NULL;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Initialize the fast I/O entry points
|
||||
//
|
||||
|
||||
FastIoDispatch = &(FFSGlobal->FastIoDispatch);
|
||||
|
||||
FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
|
||||
FastIoDispatch->FastIoCheckIfPossible = FFSFastIoCheckIfPossible;
|
||||
#if DBG
|
||||
FastIoDispatch->FastIoRead = FFSFastIoRead;
|
||||
#if !FFS_READ_ONLY
|
||||
FastIoDispatch->FastIoWrite = FFSFastIoWrite;
|
||||
#endif // !FFS_READ_ONLY
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28155, "allowed in file system drivers" )
|
||||
#endif
|
||||
FastIoDispatch->FastIoRead = FsRtlCopyRead;
|
||||
#if !FFS_READ_ONLY
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28155, "allowed in file system drivers" )
|
||||
#endif
|
||||
FastIoDispatch->FastIoWrite = FsRtlCopyWrite;
|
||||
#endif // !FFS_READ_ONLY
|
||||
#endif
|
||||
FastIoDispatch->FastIoQueryBasicInfo = FFSFastIoQueryBasicInfo;
|
||||
FastIoDispatch->FastIoQueryStandardInfo = FFSFastIoQueryStandardInfo;
|
||||
FastIoDispatch->FastIoLock = FFSFastIoLock;
|
||||
FastIoDispatch->FastIoUnlockSingle = FFSFastIoUnlockSingle;
|
||||
FastIoDispatch->FastIoUnlockAll = FFSFastIoUnlockAll;
|
||||
FastIoDispatch->FastIoUnlockAllByKey = FFSFastIoUnlockAllByKey;
|
||||
FastIoDispatch->FastIoQueryNetworkOpenInfo = FFSFastIoQueryNetworkOpenInfo;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28175, "allowed in file system drivers" )
|
||||
#endif
|
||||
DriverObject->FastIoDispatch = FastIoDispatch;
|
||||
|
||||
switch (MmQuerySystemSize())
|
||||
{
|
||||
case MmSmallSystem:
|
||||
|
||||
FFSGlobal->MaxDepth = 16;
|
||||
break;
|
||||
|
||||
case MmMediumSystem:
|
||||
|
||||
FFSGlobal->MaxDepth = 64;
|
||||
break;
|
||||
|
||||
case MmLargeSystem:
|
||||
|
||||
FFSGlobal->MaxDepth = 256;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the Cache Manager callbacks
|
||||
//
|
||||
|
||||
CacheManagerCallbacks = &(FFSGlobal->CacheManagerCallbacks);
|
||||
CacheManagerCallbacks->AcquireForLazyWrite = FFSAcquireForLazyWrite;
|
||||
CacheManagerCallbacks->ReleaseFromLazyWrite = FFSReleaseFromLazyWrite;
|
||||
CacheManagerCallbacks->AcquireForReadAhead = FFSAcquireForReadAhead;
|
||||
CacheManagerCallbacks->ReleaseFromReadAhead = FFSReleaseFromReadAhead;
|
||||
|
||||
FFSGlobal->CacheManagerNoOpCallbacks.AcquireForLazyWrite = FFSNoOpAcquire;
|
||||
FFSGlobal->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = FFSNoOpRelease;
|
||||
FFSGlobal->CacheManagerNoOpCallbacks.AcquireForReadAhead = FFSNoOpAcquire;
|
||||
FFSGlobal->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = FFSNoOpRelease;
|
||||
|
||||
|
||||
//
|
||||
// Initialize the global data
|
||||
//
|
||||
|
||||
InitializeListHead(&(FFSGlobal->VcbList));
|
||||
ExInitializeResourceLite(&(FFSGlobal->Resource));
|
||||
ExInitializeResourceLite(&(FFSGlobal->CountResource));
|
||||
ExInitializeResourceLite(&(FFSGlobal->LAResource));
|
||||
|
||||
ExInitializeNPagedLookasideList(&(FFSGlobal->FFSIrpContextLookasideList),
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(FFS_IRP_CONTEXT),
|
||||
' SFF',
|
||||
0);
|
||||
|
||||
ExInitializeNPagedLookasideList(&(FFSGlobal->FFSFcbLookasideList),
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(FFS_FCB),
|
||||
' SFF',
|
||||
0);
|
||||
|
||||
ExInitializeNPagedLookasideList(&(FFSGlobal->FFSCcbLookasideList),
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(FFS_CCB),
|
||||
' SFF',
|
||||
0);
|
||||
|
||||
ExInitializePagedLookasideList(&(FFSGlobal->FFSMcbLookasideList),
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(FFS_MCB),
|
||||
' SFF',
|
||||
0);
|
||||
|
||||
#if FFS_UNLOAD
|
||||
RtlInitUnicodeString(&DosDeviceName, DOS_DEVICE_NAME);
|
||||
IoCreateSymbolicLink(&DosDeviceName, &DeviceName);
|
||||
#endif
|
||||
|
||||
#if DBG
|
||||
ProcessNameOffset = FFSGetProcessNameOffset();
|
||||
#endif
|
||||
|
||||
IoRegisterFileSystem(DeviceObject);
|
||||
|
||||
return Status;
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* lock.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSLockControl)
|
||||
#endif
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSLockControl(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
BOOLEAN CompleteRequest;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
PFILE_OBJECT FileObject;
|
||||
PFFS_FCB Fcb;
|
||||
PIRP Irp;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
CompleteRequest = TRUE;
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FileObject = IrpContext->FileObject;
|
||||
|
||||
Fcb = (PFFS_FCB)FileObject->FsContext;
|
||||
|
||||
ASSERT(Fcb != NULL);
|
||||
|
||||
if (Fcb->Identifier.Type == FFSVCB)
|
||||
{
|
||||
CompleteRequest = TRUE;
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ASSERT((Fcb->Identifier.Type == FFSFCB) &&
|
||||
(Fcb->Identifier.Size == sizeof(FFS_FCB)));
|
||||
|
||||
if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
CompleteRequest = TRUE;
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
//
|
||||
// While the file has any byte range locks we set IsFastIoPossible to
|
||||
// FastIoIsQuestionable so that the FastIoCheckIfPossible function is
|
||||
// called to check the locks for any fast I/O read/write operation.
|
||||
//
|
||||
if (Fcb->Header.IsFastIoPossible != FastIoIsQuestionable)
|
||||
{
|
||||
|
||||
FFSPrint((DBG_INFO,
|
||||
"FFSLockControl: %-16.16s %-31s %s\n",
|
||||
FFSGetCurrentProcessName(),
|
||||
"FastIoIsQuestionable",
|
||||
Fcb->AnsiFileName.Buffer));
|
||||
|
||||
Fcb->Header.IsFastIoPossible = FastIoIsQuestionable;
|
||||
}
|
||||
|
||||
//
|
||||
// FsRtlProcessFileLock acquires FileObject->FsContext->Resource while
|
||||
// modifying the file locks and calls IoCompleteRequest when it's done.
|
||||
//
|
||||
|
||||
CompleteRequest = FALSE;
|
||||
|
||||
Status = FsRtlProcessFileLock(
|
||||
&Fcb->FileLockAnchor,
|
||||
Irp,
|
||||
NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSPrint((DBG_ERROR,
|
||||
"FFSLockControl: %-16.16s %-31s *** Status: %s (%#x) ***\n",
|
||||
FFSGetCurrentProcessName(),
|
||||
"IRP_MJ_LOCK_CONTROL",
|
||||
FFSNtStatusToString(Status),
|
||||
Status));
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (!CompleteRequest)
|
||||
{
|
||||
IrpContext->Irp = NULL;
|
||||
}
|
||||
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* misc.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSLog2)
|
||||
#pragma alloc_text(PAGE, FFSSysTime)
|
||||
#pragma alloc_text(PAGE, FFSInodeTime)
|
||||
#pragma alloc_text(PAGE, FFSOEMToUnicode)
|
||||
#pragma alloc_text(PAGE, FFSUnicodeToOEM)
|
||||
#endif
|
||||
|
||||
ULONG
|
||||
FFSLog2(
|
||||
ULONG Value)
|
||||
{
|
||||
ULONG Order = 0;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(Value > 0);
|
||||
|
||||
while (Value)
|
||||
{
|
||||
Order++;
|
||||
Value >>= 1;
|
||||
}
|
||||
|
||||
return (Order - 1);
|
||||
}
|
||||
|
||||
|
||||
LARGE_INTEGER
|
||||
FFSSysTime(
|
||||
IN ULONG i_time)
|
||||
{
|
||||
LARGE_INTEGER SysTime;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
RtlSecondsSince1970ToTime(i_time, &SysTime);
|
||||
|
||||
return SysTime;
|
||||
}
|
||||
|
||||
ULONG
|
||||
FFSInodeTime(
|
||||
IN LARGE_INTEGER SysTime)
|
||||
{
|
||||
ULONG FFSTime;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
RtlTimeToSecondsSince1970(&SysTime, &FFSTime);
|
||||
|
||||
return FFSTime;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSOEMToUnicode(
|
||||
IN OUT PUNICODE_STRING Unicode,
|
||||
IN POEM_STRING Oem)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = RtlOemStringToUnicodeString(
|
||||
Unicode,
|
||||
Oem,
|
||||
FALSE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSBreakPoint();
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
errorout:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
FFSUnicodeToOEM(
|
||||
IN OUT POEM_STRING Oem,
|
||||
IN PUNICODE_STRING Unicode)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = RtlUnicodeStringToOemString(
|
||||
Oem,
|
||||
Unicode,
|
||||
FALSE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSBreakPoint();
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
errorout:
|
||||
|
||||
return Status;
|
||||
}
|
@ -1,463 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* misc.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define DBG_PNP DBG_USER
|
||||
|
||||
#ifdef _PREFAST_
|
||||
IO_COMPLETION_ROUTINE FFSPnpCompletionRoutine;
|
||||
#endif // _PREFAST_
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSPnpCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Contxt);
|
||||
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSPnp)
|
||||
#pragma alloc_text(PAGE, FFSPnpQueryRemove)
|
||||
#pragma alloc_text(PAGE, FFSPnpRemove)
|
||||
#pragma alloc_text(PAGE, FFSPnpCancelRemove)
|
||||
#pragma alloc_text(PAGE, FFSPnpSurpriseRemove)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
NTSTATUS NTAPI
|
||||
FFSPnpCompletionRoutine(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Contxt)
|
||||
{
|
||||
PKEVENT Event = (PKEVENT) Contxt;
|
||||
|
||||
KeSetEvent(Event, 0, FALSE);
|
||||
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
UNREFERENCED_PARAMETER(Contxt);
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSPnp(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
PFFS_VCB Vcb = 0;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
|
||||
if (!((Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB))))
|
||||
{
|
||||
_SEH2_LEAVE; // Status = STATUS_INVALID_PARAMETER
|
||||
}
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
|
||||
|
||||
switch (IrpSp->MinorFunction)
|
||||
{
|
||||
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnp: FFSPnpQueryRemove...\n"));
|
||||
Status = FFSPnpQueryRemove(IrpContext, Vcb);
|
||||
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnp: FFSPnpRemove...\n"));
|
||||
Status = FFSPnpRemove(IrpContext, Vcb);
|
||||
break;
|
||||
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnp: FFSPnpCancelRemove...\n"));
|
||||
Status = FFSPnpCancelRemove(IrpContext, Vcb);
|
||||
break;
|
||||
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnp: FFSPnpSupriseRemove...\n"));
|
||||
Status = FFSPnpSurpriseRemove(IrpContext, Vcb);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
if (Irp)
|
||||
{
|
||||
//
|
||||
// Here we need pass the IRP to the disk driver.
|
||||
//
|
||||
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
}
|
||||
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSPnpQueryRemove(
|
||||
PFFS_IRP_CONTEXT IrpContext,
|
||||
PFFS_VCB Vcb)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
BOOLEAN bDeleted = FALSE;
|
||||
BOOLEAN VcbAcquired = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY {
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove by FFSPnp ...\n"));
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove: FFSFlushVolume ...\n"));
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
CcWaitForCurrentLazyWriterActivity();
|
||||
#endif
|
||||
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource, TRUE);
|
||||
VcbAcquired = TRUE;
|
||||
|
||||
FFSFlushFiles(Vcb, FALSE);
|
||||
|
||||
FFSFlushVolume(Vcb, FALSE);
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove: FFSLockVcb: Vcb=%xh FileObject=%xh ...\n", Vcb, IrpContext->FileObject));
|
||||
Status = FFSLockVcb(Vcb, IrpContext->FileObject);
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove: FFSPurgeVolume ...\n"));
|
||||
FFSPurgeVolume(Vcb, TRUE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
VcbAcquired = FALSE;
|
||||
|
||||
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoSetCompletionRoutine(IrpContext->Irp,
|
||||
FFSPnpCompletionRoutine,
|
||||
&Event,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove: Call lower level driver...\n"));
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject,
|
||||
IrpContext->Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
Status = IrpContext->Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove: FFSCheckDismount ...\n"));
|
||||
bDeleted = FFSCheckDismount(IrpContext, Vcb, TRUE);
|
||||
FFSPrint((DBG_PNP, "FFSPnpQueryRemove: FFSFlushVolume bDelted=%xh ...\n", bDeleted));
|
||||
}
|
||||
|
||||
ASSERT(!(NT_SUCCESS(Status) && !bDeleted));
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (VcbAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
FFSCompleteRequest(
|
||||
IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status) ?
|
||||
IO_DISK_INCREMENT : IO_NO_INCREMENT));
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSPnpRemove(
|
||||
PFFS_IRP_CONTEXT IrpContext,
|
||||
PFFS_VCB Vcb)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
BOOLEAN bDeleted;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpRemove by FFSPnp ...\n"));
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
CcWaitForCurrentLazyWriterActivity();
|
||||
#endif
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource, TRUE);
|
||||
|
||||
Status = FFSLockVcb(Vcb, IrpContext->FileObject);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
//
|
||||
// Setup the Irp. We'll send it to the lower disk driver.
|
||||
//
|
||||
|
||||
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoSetCompletionRoutine(IrpContext->Irp,
|
||||
FFSPnpCompletionRoutine,
|
||||
&Event,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject,
|
||||
IrpContext->Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
|
||||
KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
Status = IrpContext->Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource, TRUE);
|
||||
|
||||
FFSPurgeVolume(Vcb, FALSE);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
bDeleted = FFSCheckDismount(IrpContext, Vcb, TRUE);
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
FFSCompleteRequest(
|
||||
IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
|
||||
IO_DISK_INCREMENT : IO_NO_INCREMENT));
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSPnpSurpriseRemove(
|
||||
PFFS_IRP_CONTEXT IrpContext,
|
||||
PFFS_VCB Vcb)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
BOOLEAN bDeleted;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpSupriseRemove by FFSPnp ...\n"));
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
CcWaitForCurrentLazyWriterActivity();
|
||||
#endif
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource, TRUE);
|
||||
|
||||
Status = FFSLockVcb(Vcb, IrpContext->FileObject);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
//
|
||||
// Setup the Irp. We'll send it to the lower disk driver.
|
||||
//
|
||||
|
||||
IoCopyCurrentIrpStackLocationToNext(IrpContext->Irp);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoSetCompletionRoutine(IrpContext->Irp,
|
||||
FFSPnpCompletionRoutine,
|
||||
&Event,
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject,
|
||||
IrpContext->Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
|
||||
KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
Status = IrpContext->Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource, TRUE);
|
||||
|
||||
FFSPurgeVolume(Vcb, FALSE);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
bDeleted = FFSCheckDismount(IrpContext, Vcb, TRUE);
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
FFSCompleteRequest(
|
||||
IrpContext->Irp, FALSE, (CCHAR)(NT_SUCCESS(Status)?
|
||||
IO_DISK_INCREMENT : IO_NO_INCREMENT));
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSPnpCancelRemove(
|
||||
PFFS_IRP_CONTEXT IrpContext,
|
||||
PFFS_VCB Vcb)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
FFSPrint((DBG_PNP, "FFSPnpCancelRemove by FFSPnp ...\n"));
|
||||
|
||||
ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource, TRUE);
|
||||
|
||||
Status = FFSUnlockVcb(Vcb, IrpContext->FileObject);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
|
||||
IoSkipCurrentIrpStackLocation(IrpContext->Irp);
|
||||
|
||||
Status = IoCallDriver(Vcb->TargetDeviceObject, IrpContext->Irp);
|
||||
|
||||
IrpContext->Irp = NULL;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
#endif //(_WIN32_WINNT >= 0x0500)
|
File diff suppressed because it is too large
Load Diff
@ -1,140 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* read.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSShutDown)
|
||||
#endif
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSShutDown(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
#ifndef __REACTOS__
|
||||
PKEVENT Event;
|
||||
#endif
|
||||
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
PFFS_VCB Vcb;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
BOOLEAN GlobalResourceAcquired = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
#ifdef _MSC_VER
|
||||
#pragma prefast( suppress: 28137, "by design" )
|
||||
#endif
|
||||
if (!ExAcquireResourceExclusiveLite(
|
||||
&FFSGlobal->Resource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
GlobalResourceAcquired = TRUE;
|
||||
|
||||
#ifndef __REACTOS__
|
||||
Event = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), FFS_POOL_TAG);
|
||||
KeInitializeEvent(Event, NotificationEvent, FALSE);
|
||||
#endif
|
||||
|
||||
for (ListEntry = FFSGlobal->VcbList.Flink;
|
||||
ListEntry != &(FFSGlobal->VcbList);
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
Vcb = CONTAINING_RECORD(ListEntry, FFS_VCB, Next);
|
||||
|
||||
if (ExAcquireResourceExclusiveLite(
|
||||
&Vcb->MainResource,
|
||||
TRUE))
|
||||
{
|
||||
|
||||
Status = FFSFlushFiles(Vcb, TRUE);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSBreakPoint();
|
||||
}
|
||||
|
||||
Status = FFSFlushVolume(Vcb, TRUE);
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
FFSBreakPoint();
|
||||
}
|
||||
|
||||
FFSDiskShutDown(Vcb);
|
||||
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
IoUnregisterFileSystem(FFSGlobal->DeviceObject);
|
||||
*/
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (GlobalResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&FFSGlobal->Resource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
FFSQueueRequest(IrpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
@ -1,478 +0,0 @@
|
||||
/*
|
||||
* FFS File System Driver for Windows
|
||||
*
|
||||
* volinfo.c
|
||||
*
|
||||
* 2004.5.6 ~
|
||||
*
|
||||
* Lee Jae-Hong, http://www.pyrasis.com
|
||||
*
|
||||
* See License.txt
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ntifs.h"
|
||||
#include "ffsdrv.h"
|
||||
|
||||
/* Globals */
|
||||
|
||||
extern PFFS_GLOBAL FFSGlobal;
|
||||
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FFSQueryVolumeInformation)
|
||||
#pragma alloc_text(PAGE, FFSSetVolumeInformation)
|
||||
#endif
|
||||
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSQueryVolumeInformation(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
PFFS_VCB Vcb = 0;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
FS_INFORMATION_CLASS FsInformationClass;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
BOOLEAN VcbResourceAcquired = FALSE;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
//
|
||||
// This request is not allowed on the main device object
|
||||
//
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
|
||||
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
|
||||
|
||||
ASSERT(IsMounted(Vcb));
|
||||
|
||||
if (!ExAcquireResourceSharedLite(
|
||||
&Vcb->MainResource,
|
||||
IrpContext->IsSynchronous))
|
||||
{
|
||||
Status = STATUS_PENDING;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
VcbResourceAcquired = TRUE;
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
FsInformationClass =
|
||||
IoStackLocation->Parameters.QueryVolume.FsInformationClass;
|
||||
|
||||
Length = IoStackLocation->Parameters.QueryVolume.Length;
|
||||
|
||||
Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
RtlZeroMemory(Buffer, Length);
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
case FileFsVolumeInformation:
|
||||
{
|
||||
PFILE_FS_VOLUME_INFORMATION FsVolInfo;
|
||||
ULONG VolumeLabelLength;
|
||||
ULONG RequiredLength;
|
||||
|
||||
if (Length < sizeof(FILE_FS_VOLUME_INFORMATION))
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FsVolInfo = (PFILE_FS_VOLUME_INFORMATION)Buffer;
|
||||
|
||||
FsVolInfo->VolumeCreationTime.QuadPart = 0;
|
||||
|
||||
FsVolInfo->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
|
||||
|
||||
VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
|
||||
|
||||
FsVolInfo->VolumeLabelLength = VolumeLabelLength;
|
||||
|
||||
// I don't know what this means
|
||||
FsVolInfo->SupportsObjects = FALSE;
|
||||
|
||||
RequiredLength = sizeof(FILE_FS_VOLUME_INFORMATION)
|
||||
+ VolumeLabelLength - sizeof(WCHAR);
|
||||
|
||||
if (Length < RequiredLength)
|
||||
{
|
||||
Irp->IoStatus.Information =
|
||||
sizeof(FILE_FS_VOLUME_INFORMATION);
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(FsVolInfo->VolumeLabel, Vcb->Vpb->VolumeLabel, Vcb->Vpb->VolumeLabelLength);
|
||||
|
||||
Irp->IoStatus.Information = RequiredLength;
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
case FileFsSizeInformation:
|
||||
{
|
||||
PFILE_FS_SIZE_INFORMATION FsSizeInfo;
|
||||
|
||||
if (Length < sizeof(FILE_FS_SIZE_INFORMATION))
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FsSizeInfo = (PFILE_FS_SIZE_INFORMATION)Buffer;
|
||||
|
||||
{
|
||||
if (FS_VERSION == 1)
|
||||
{
|
||||
FsSizeInfo->TotalAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_old_size / 8);
|
||||
|
||||
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_old_cstotal.cs_nbfree / 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
FsSizeInfo->TotalAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_size / 8);
|
||||
|
||||
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_cstotal.cs_nbfree / 8);
|
||||
}
|
||||
}
|
||||
|
||||
FsSizeInfo->SectorsPerAllocationUnit =
|
||||
Vcb->BlockSize / Vcb->DiskGeometry.BytesPerSector;
|
||||
|
||||
FsSizeInfo->BytesPerSector =
|
||||
Vcb->DiskGeometry.BytesPerSector;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(FILE_FS_SIZE_INFORMATION);
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
case FileFsDeviceInformation:
|
||||
{
|
||||
PFILE_FS_DEVICE_INFORMATION FsDevInfo;
|
||||
|
||||
if (Length < sizeof(FILE_FS_DEVICE_INFORMATION))
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FsDevInfo = (PFILE_FS_DEVICE_INFORMATION)Buffer;
|
||||
|
||||
FsDevInfo->DeviceType =
|
||||
Vcb->TargetDeviceObject->DeviceType;
|
||||
|
||||
FsDevInfo->Characteristics =
|
||||
Vcb->TargetDeviceObject->Characteristics;
|
||||
|
||||
if (FlagOn(Vcb->Flags, VCB_READ_ONLY))
|
||||
{
|
||||
SetFlag(FsDevInfo->Characteristics,
|
||||
FILE_READ_ONLY_DEVICE);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = sizeof(FILE_FS_DEVICE_INFORMATION);
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
case FileFsAttributeInformation:
|
||||
{
|
||||
PFILE_FS_ATTRIBUTE_INFORMATION FsAttrInfo;
|
||||
ULONG RequiredLength;
|
||||
|
||||
if (Length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
FsAttrInfo =
|
||||
(PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
|
||||
|
||||
FsAttrInfo->FileSystemAttributes =
|
||||
FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
|
||||
|
||||
FsAttrInfo->MaximumComponentNameLength = FFS_NAME_LEN;
|
||||
|
||||
FsAttrInfo->FileSystemNameLength = 10;
|
||||
|
||||
RequiredLength = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) +
|
||||
10 - sizeof(WCHAR);
|
||||
|
||||
if (Length < RequiredLength)
|
||||
{
|
||||
Irp->IoStatus.Information =
|
||||
sizeof(FILE_FS_ATTRIBUTE_INFORMATION);
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(
|
||||
FsAttrInfo->FileSystemName,
|
||||
L"FFS\0", 8);
|
||||
|
||||
Irp->IoStatus.Information = RequiredLength;
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
case FileFsFullSizeInformation:
|
||||
{
|
||||
PFILE_FS_FULL_SIZE_INFORMATION PFFFSI;
|
||||
|
||||
if (Length < sizeof(FILE_FS_FULL_SIZE_INFORMATION))
|
||||
{
|
||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
PFFFSI = (PFILE_FS_FULL_SIZE_INFORMATION)Buffer;
|
||||
|
||||
/*
|
||||
typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
|
||||
LARGE_INTEGER TotalAllocationUnits;
|
||||
LARGE_INTEGER CallerAvailableAllocationUnits;
|
||||
LARGE_INTEGER ActualAvailableAllocationUnits;
|
||||
ULONG SectorsPerAllocationUnit;
|
||||
ULONG BytesPerSector;
|
||||
} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
|
||||
*/
|
||||
|
||||
{
|
||||
if (FS_VERSION == 1)
|
||||
{
|
||||
PFFFSI->TotalAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_old_size / 8);
|
||||
|
||||
PFFFSI->CallerAvailableAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_old_cstotal.cs_nbfree / 8);
|
||||
|
||||
PFFFSI->ActualAvailableAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_old_cstotal.cs_nbfree / 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
PFFFSI->TotalAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_size / 8);
|
||||
|
||||
PFFFSI->CallerAvailableAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_cstotal.cs_nbfree / 8);
|
||||
|
||||
PFFFSI->ActualAvailableAllocationUnits.QuadPart =
|
||||
(Vcb->ffs_super_block->fs_cstotal.cs_nbfree / 8);
|
||||
}
|
||||
}
|
||||
|
||||
PFFFSI->SectorsPerAllocationUnit =
|
||||
Vcb->BlockSize / Vcb->DiskGeometry.BytesPerSector;
|
||||
|
||||
PFFFSI->BytesPerSector = Vcb->DiskGeometry.BytesPerSector;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(FILE_FS_FULL_SIZE_INFORMATION);
|
||||
Status = STATUS_SUCCESS;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
#endif // (_WIN32_WINNT >= 0x0500)
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_INFO_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
if (VcbResourceAcquired)
|
||||
{
|
||||
ExReleaseResourceForThreadLite(
|
||||
&Vcb->MainResource,
|
||||
ExGetCurrentResourceThread());
|
||||
}
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
FFSQueueRequest(IrpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
#if !FFS_READ_ONLY
|
||||
|
||||
__drv_mustHoldCriticalRegion
|
||||
NTSTATUS
|
||||
FFSSetVolumeInformation(
|
||||
IN PFFS_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
PFFS_VCB Vcb;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
FS_INFORMATION_CLASS FsInformationClass;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ASSERT(IrpContext != NULL);
|
||||
|
||||
ASSERT((IrpContext->Identifier.Type == FFSICX) &&
|
||||
(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
|
||||
|
||||
DeviceObject = IrpContext->DeviceObject;
|
||||
|
||||
//
|
||||
// This request is not allowed on the main device object
|
||||
//
|
||||
if (DeviceObject == FFSGlobal->DeviceObject)
|
||||
{
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(Vcb != NULL);
|
||||
|
||||
ASSERT((Vcb->Identifier.Type == FFSVCB) &&
|
||||
(Vcb->Identifier.Size == sizeof(FFS_VCB)));
|
||||
|
||||
ASSERT(IsMounted(Vcb));
|
||||
|
||||
if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY))
|
||||
{
|
||||
Status = STATUS_MEDIA_WRITE_PROTECTED;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
Irp = IrpContext->Irp;
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//Notes: SetVolume is not defined in ntddk.h of win2k ddk,
|
||||
// But it's same to QueryVolume ....
|
||||
FsInformationClass =
|
||||
IoStackLocation->Parameters./*SetVolume*/QueryVolume.FsInformationClass;
|
||||
|
||||
switch (FsInformationClass)
|
||||
{
|
||||
case FileFsLabelInformation:
|
||||
{
|
||||
PFILE_FS_LABEL_INFORMATION VolLabelInfo = NULL;
|
||||
ULONG VolLabelLen;
|
||||
UNICODE_STRING LabelName ;
|
||||
|
||||
OEM_STRING OemName;
|
||||
|
||||
VolLabelInfo = (PFILE_FS_LABEL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
VolLabelLen = VolLabelInfo->VolumeLabelLength;
|
||||
|
||||
if(VolLabelLen > (16 * sizeof(WCHAR)))
|
||||
{
|
||||
Status = STATUS_INVALID_VOLUME_LABEL;
|
||||
_SEH2_LEAVE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Vcb->Vpb->VolumeLabel,
|
||||
VolLabelInfo->VolumeLabel,
|
||||
VolLabelLen);
|
||||
|
||||
RtlZeroMemory(Vcb->ffs_super_block->fs_volname, 16);
|
||||
|
||||
LabelName.Buffer = VolLabelInfo->VolumeLabel;
|
||||
LabelName.MaximumLength = (USHORT)16 * sizeof(WCHAR);
|
||||
LabelName.Length = (USHORT)VolLabelLen;
|
||||
|
||||
OemName.Buffer = SUPER_BLOCK->fs_volname;
|
||||
OemName.Length = 0;
|
||||
OemName.MaximumLength = 16;
|
||||
|
||||
FFSUnicodeToOEM(&OemName,
|
||||
&LabelName);
|
||||
|
||||
Vcb->Vpb->VolumeLabelLength =
|
||||
(USHORT)VolLabelLen;
|
||||
|
||||
if (FFSSaveSuper(IrpContext, Vcb))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_INFO_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
|
||||
if (!IrpContext->ExceptionInProgress)
|
||||
{
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
FFSQueueRequest(IrpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFSCompleteIrpContext(IrpContext, Status);
|
||||
}
|
||||
}
|
||||
} _SEH2_END;
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
#endif // !FFS_READ_ONLY
|
File diff suppressed because it is too large
Load Diff
@ -94,12 +94,6 @@ Used Version: 0.69
|
||||
License: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later.html)
|
||||
URL: http://www.ext2fsd.com
|
||||
|
||||
Title: FFS/UFS file system driver for Windows
|
||||
Path: drivers/filesystems/ffs
|
||||
Used Version: 0.5.2
|
||||
License: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later.html)
|
||||
URL: http://www.acc.umu.se/~bosse/
|
||||
|
||||
Title: NFSv4.1 Client for Windows
|
||||
Path: base/services/nfsd
|
||||
Path: dll/3rdparty/libtirpc
|
||||
|
@ -336,7 +336,6 @@ set(baseaddress_ucdfs 0x724e0000)
|
||||
set(baseaddress_uext2 0x724a0000)
|
||||
set(baseaddress_ufat 0x72460000)
|
||||
set(baseaddress_ufatx 0x72440000)
|
||||
set(baseaddress_uffs 0x72420000)
|
||||
set(baseaddress_umpnpmgr 0x723e0000)
|
||||
set(baseaddress_untfs 0x723c0000)
|
||||
set(baseaddress_updspapi 0x72390000)
|
||||
|
@ -336,7 +336,6 @@ set(baseaddress_ucdfs 0x6d920000)
|
||||
set(baseaddress_uext2 0x6d8d0000)
|
||||
set(baseaddress_ufat 0x6d880000)
|
||||
set(baseaddress_ufatx 0x6d850000)
|
||||
set(baseaddress_uffs 0x6d830000)
|
||||
set(baseaddress_umpnpmgr 0x6d7d0000)
|
||||
set(baseaddress_untfs 0x6d7b0000)
|
||||
set(baseaddress_updspapi 0x6d770000)
|
||||
|
@ -336,7 +336,6 @@ set(baseaddress_ucdfs 0x753b0000)
|
||||
set(baseaddress_uext2 0x75380000)
|
||||
set(baseaddress_ufat 0x75350000)
|
||||
set(baseaddress_ufatx 0x75330000)
|
||||
set(baseaddress_uffs 0x75310000)
|
||||
set(baseaddress_umpnpmgr 0x752e0000)
|
||||
set(baseaddress_untfs 0x752c0000)
|
||||
set(baseaddress_updspapi 0x752a0000)
|
||||
|
@ -327,7 +327,6 @@ set(baseaddress_ucdfs 0x7FE9A000000)
|
||||
set(baseaddress_uext2 0x7FE99500000)
|
||||
set(baseaddress_ufat 0x7FE98500000)
|
||||
set(baseaddress_ufatx 0x7FE97500000)
|
||||
set(baseaddress_uffs 0x7FE96500000)
|
||||
set(baseaddress_umpnpmgr 0x7FE95500000)
|
||||
set(baseaddress_untfs 0x7FE94500000)
|
||||
set(baseaddress_updspapi 0x7FE93500000)
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS FFS filesystem library
|
||||
* FILE: include/reactos/libs/fslib/ffslib.h
|
||||
* PURPOSE: Public definitions for FFS filesystem library
|
||||
*/
|
||||
|
||||
#ifndef __FFSLIB_H
|
||||
#define __FFSLIB_H
|
||||
|
||||
#include <fmifs/fmifs.h>
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FfsChkdsk(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PFMIFSCALLBACK Callback,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PVOID pUnknown1,
|
||||
IN PVOID pUnknown2,
|
||||
IN PVOID pUnknown3,
|
||||
IN PVOID pUnknown4,
|
||||
IN PULONG ExitStatus);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FfsFormat(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PFMIFSCALLBACK Callback,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN BOOLEAN BackwardCompatible,
|
||||
IN MEDIA_TYPE MediaType,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN ULONG ClusterSize);
|
||||
|
||||
#endif /* __FFSLIB_H */
|
@ -2,7 +2,6 @@
|
||||
add_subdirectory(btrfslib)
|
||||
add_subdirectory(cdfslib)
|
||||
add_subdirectory(ext2lib)
|
||||
add_subdirectory(ffslib)
|
||||
add_subdirectory(ntfslib)
|
||||
add_subdirectory(vfatlib)
|
||||
add_subdirectory(vfatxlib)
|
||||
|
@ -1,3 +0,0 @@
|
||||
|
||||
add_library(ffslib ffslib.c)
|
||||
add_dependencies(ffslib psdk)
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS FFS library
|
||||
* FILE: lib/fslib/ffslib/ffslib.c
|
||||
* PURPOSE: FFS lib
|
||||
* PROGRAMMERS: Pierre Schweitzer
|
||||
*/
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/umtypes.h>
|
||||
#include <fmifs/fmifs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FfsFormat(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PFMIFSCALLBACK Callback,
|
||||
IN BOOLEAN QuickFormat,
|
||||
IN BOOLEAN BackwardCompatible,
|
||||
IN MEDIA_TYPE MediaType,
|
||||
IN PUNICODE_STRING Label,
|
||||
IN ULONG ClusterSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
FfsChkdsk(
|
||||
IN PUNICODE_STRING DriveRoot,
|
||||
IN PFMIFSCALLBACK Callback,
|
||||
IN BOOLEAN FixErrors,
|
||||
IN BOOLEAN Verbose,
|
||||
IN BOOLEAN CheckOnlyIfDirty,
|
||||
IN BOOLEAN ScanDrive,
|
||||
IN PVOID pUnknown1,
|
||||
IN PVOID pUnknown2,
|
||||
IN PVOID pUnknown3,
|
||||
IN PVOID pUnknown4,
|
||||
IN PULONG ExitStatus)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
*ExitStatus = (ULONG)STATUS_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
Loading…
Reference in New Issue
Block a user