NT4/private/ntos/fsrtl/fsrtlpc.c

509 lines
16 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
FsRtlP.c
Abstract:
This module declares the global data used by the FsRtl Module
Author:
Gary Kimura [GaryKi] 30-Jul-1990
Revision History:
--*/
#include "FsRtlP.h"
#define COMPATIBILITY_MODE_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\FileSystem"
#define COMPATIBILITY_MODE_VALUE_NAME L"Win95TruncatedExtensions"
#define KEY_WORK_AREA ((sizeof(KEY_VALUE_FULL_INFORMATION) + \
sizeof(ULONG)) + 64)
#ifdef FSRTLDBG
LONG FsRtlDebugTraceLevel = 0x0000000f;
LONG FsRtlDebugTraceIndent = 0;
#endif // FSRTLDBG
//
// Local Support routine
//
NTSTATUS
FsRtlGetCompatibilityModeValue (
IN PUNICODE_STRING ValueName,
IN OUT PULONG Value
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FsRtlAllocateResource)
#pragma alloc_text(INIT, FsRtlInitSystem)
#pragma alloc_text(INIT, FsRtlGetCompatibilityModeValue)
#endif
//
// Define the number of resources, a pointer to them and a counter for
// resource selection.
//
#define FSRTL_NUMBER_OF_RESOURCES (16)
PERESOURCE FsRtlPagingIoResources;
ULONG FsRtlPagingIoResourceSelector = 0;
BOOLEAN FsRtlSafeExtensions = TRUE;
//
// The following zone is used to keep all the Fast Mutexes we will need to
// boot contiguous.
//
NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList;
//
// A spinlock used for cached structure allocation
//
KSPIN_LOCK FsRtlStrucSupSpinLock;
//
// The global static legal ANSI character array. Wild characters
// are not considered legal, they should be checked seperately if
// allowed.
//
#define _FAT_ FSRTL_FAT_LEGAL
#define _HPFS_ FSRTL_HPFS_LEGAL
#define _NTFS_ FSRTL_NTFS_LEGAL
#define _WILD_ FSRTL_WILD_CHARACTER
#define _OFS_ FSRTL_OFS_LEGAL
#define _OLE_ FSRTL_OLE_LEGAL
static UCHAR LocalLegalAnsiCharacterArray[128] = {
0, // 0x00 ^@
_OLE_, // 0x01 ^A
_OLE_, // 0x02 ^B
_OLE_, // 0x03 ^C
_OLE_, // 0x04 ^D
_OLE_, // 0x05 ^E
_OLE_, // 0x06 ^F
_OLE_, // 0x07 ^G
_OLE_, // 0x08 ^H
_OLE_, // 0x09 ^I
_OLE_, // 0x0A ^J
_OLE_, // 0x0B ^K
_OLE_, // 0x0C ^L
_OLE_, // 0x0D ^M
_OLE_, // 0x0E ^N
_OLE_, // 0x0F ^O
_OLE_, // 0x10 ^P
_OLE_, // 0x11 ^Q
_OLE_, // 0x12 ^R
_OLE_, // 0x13 ^S
_OLE_, // 0x14 ^T
_OLE_, // 0x15 ^U
_OLE_, // 0x16 ^V
_OLE_, // 0x17 ^W
_OLE_, // 0x18 ^X
_OLE_, // 0x19 ^Y
_OLE_, // 0x1A ^Z
_OLE_, // 0x1B ESC
_OLE_, // 0x1C FS
_OLE_, // 0x1D GS
_OLE_, // 0x1E RS
_OLE_, // 0x1F US
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x20 space
_FAT_ | _HPFS_ | _NTFS_ | _OFS_, // 0x21 !
_WILD_, // 0x22 "
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x23 #
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x24 $
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x25 %
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x26 &
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x27 '
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x28 (
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x29 )
_WILD_, // 0x2A *
_HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2B +
_HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2C ,
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2D -
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x2E .
0, // 0x2F /
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x30 0
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x31 1
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x32 2
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x33 3
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x34 4
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x35 5
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x36 6
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x37 7
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x38 8
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x39 9
_NTFS_ | _OFS_, // 0x3A :
_HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x3B ;
_WILD_, // 0x3C <
_HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x3D =
_WILD_, // 0x3E >
_WILD_, // 0x3F ?
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x40 @
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x41 A
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x42 B
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x43 C
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x44 D
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x45 E
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x46 F
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x47 G
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x48 H
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x49 I
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4A J
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4B K
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4C L
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4D M
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4E N
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x4F O
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x50 P
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x51 Q
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x52 R
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x53 S
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x54 T
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x55 U
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x56 V
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x57 W
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x58 X
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x59 Y
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5A Z
_HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5B [
0, // 0x5C backslash
_HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5D ]
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5E ^
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x5F _
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x60 `
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x61 a
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x62 b
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x63 c
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x64 d
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x65 e
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x66 f
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x67 g
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x68 h
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x69 i
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6A j
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6B k
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6C l
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6D m
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6E n
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x6F o
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x70 p
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x71 q
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x72 r
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x73 s
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x74 t
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x75 u
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x76 v
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x77 w
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x78 x
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x79 y
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7A z
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7B {
_OLE_, // 0x7C |
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7D }
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7E ~
_FAT_ | _HPFS_ | _NTFS_ | _OFS_ | _OLE_, // 0x7F 
};
PUCHAR FsRtlLegalAnsiCharacterArray = &LocalLegalAnsiCharacterArray[0];
//
// This routine is called during phase one initialization.
//
BOOLEAN
FsRtlInitSystem (
)
{
ULONG i;
KAFFINITY ActiveProcessors, CurrentAffinity;
ULONG ZoneSegmentSize;
ULONG Value;
UNICODE_STRING ValueName;
extern FAST_MUTEX FsRtlCreateLockInfo;
extern KSEMAPHORE FsRtlpUncSemaphore;
PAGED_CODE();
//
// Allocate and initialize all the paging Io resources
//
FsRtlPagingIoResources = FsRtlAllocatePool( NonPagedPool,
FSRTL_NUMBER_OF_RESOURCES *
sizeof(ERESOURCE) );
for (i=0; i < FSRTL_NUMBER_OF_RESOURCES; i++) {
ExInitializeResource( &FsRtlPagingIoResources[i] );
}
//
// Initialize the free cached spin lock
//
KeInitializeSpinLock( &FsRtlStrucSupSpinLock );
//
// Initialize the LockInfo creation mutex
//
ExInitializeFastMutex(&FsRtlCreateLockInfo);
//
// Initialize the Fast Mutex lookaside list.
//
ExInitializeNPagedLookasideList( &FsRtlFastMutexLookasideList,
NULL,
NULL,
POOL_RAISE_IF_ALLOCATION_FAILURE,
sizeof( FAST_MUTEX),
'mfSF',
32 );
//
// Initialize the global tunneling structures
//
FsRtlInitializeTunnel();
//
// Initialize each processor's free list of lock structures
//
ActiveProcessors = KeActiveProcessors;
for (CurrentAffinity=1; ActiveProcessors; CurrentAffinity <<= 1) {
if (ActiveProcessors & CurrentAffinity) {
//
// Switch to that processor, and remove it from the
// remaining set of processors
//
ActiveProcessors &= ~CurrentAffinity;
KeSetSystemAffinityThread(CurrentAffinity);
FsRtlInitProcessorLockQueue();
}
}
KeRevertToUserAffinityThread();
//
// Initialize the semaphore used to guard loading of the MUP
//
KeInitializeSemaphore( &FsRtlpUncSemaphore, 1, MAXLONG );
//
// Pull the bit from the registry telling us whether to do a safe
// or dangerous extension truncation.
//
ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME;
ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR);
ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME);
if (NT_SUCCESS(FsRtlGetCompatibilityModeValue( &ValueName, &Value )) &&
(Value != 0)) {
FsRtlSafeExtensions = FALSE;
}
//
// Initialize the FsRtl stack overflow work QueueObject and thread.
//
if (!NT_SUCCESS(FsRtlInitializeWorkerThread())) {
return FALSE;
}
return TRUE;
}
PERESOURCE
FsRtlAllocateResource (
)
/*++
Routine Description:
This routine is used to allocate a resource from the FsRtl pool.
Arguments:
Return Value:
PERESOURCE - A pointer to the provided resource.
--*/
{
PAGED_CODE();
return &FsRtlPagingIoResources[ FsRtlPagingIoResourceSelector++ %
FSRTL_NUMBER_OF_RESOURCES];
}
//
// Local Support routine
//
NTSTATUS
FsRtlGetCompatibilityModeValue (
IN PUNICODE_STRING ValueName,
IN OUT PULONG Value
)
/*++
Routine Description:
Given a unicode value name this routine will go into the registry
location for the Chicago compatibilitymode information and get the
value.
Arguments:
ValueName - the unicode name for the registry value located in the
double space configuration location of the registry.
Value - a pointer to the ULONG for the result.
Return Value:
NTSTATUS
If STATUS_SUCCESSFUL is returned, the location *Value will be
updated with the DWORD value from the registry. If any failing
status is returned, this value is untouched.
--*/
{
HANDLE Handle;
NTSTATUS Status;
ULONG RequestLength;
ULONG ResultLength;
UCHAR Buffer[KEY_WORK_AREA];
UNICODE_STRING KeyName;
OBJECT_ATTRIBUTES ObjectAttributes;
PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
KeyName.Buffer = COMPATIBILITY_MODE_KEY_NAME;
KeyName.Length = sizeof(COMPATIBILITY_MODE_KEY_NAME) - sizeof(WCHAR);
KeyName.MaximumLength = sizeof(COMPATIBILITY_MODE_KEY_NAME);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&Handle,
KEY_READ,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) {
return Status;
}
RequestLength = KEY_WORK_AREA;
KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;
while (1) {
Status = ZwQueryValueKey(Handle,
ValueName,
KeyValueFullInformation,
KeyValueInformation,
RequestLength,
&ResultLength);
ASSERT( Status != STATUS_BUFFER_OVERFLOW );
if (Status == STATUS_BUFFER_OVERFLOW) {
//
// Try to get a buffer big enough.
//
if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) {
ExFreePool(KeyValueInformation);
}
RequestLength += 256;
KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)
ExAllocatePoolWithTag(PagedPool,
RequestLength,
' taF');
if (!KeyValueInformation) {
return STATUS_NO_MEMORY;
}
} else {
break;
}
}
ZwClose(Handle);
if (NT_SUCCESS(Status)) {
if (KeyValueInformation->DataLength != 0) {
PULONG DataPtr;
//
// Return contents to the caller.
//
DataPtr = (PULONG)
((PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
*Value = *DataPtr;
} else {
//
// Treat as if no value was found
//
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
}
if (KeyValueInformation != (PKEY_VALUE_FULL_INFORMATION)Buffer) {
ExFreePool(KeyValueInformation);
}
return Status;
}